work on species mapping

This commit is contained in:
Douglas Gillespie 2023-07-19 13:56:39 +01:00
parent 527aeccbb8
commit 5c969d8889
14 changed files with 530 additions and 39 deletions

View File

@ -52,6 +52,7 @@ import Acquisition.AcquisitionProcess;
import pamScrollSystem.ViewLoadObserver; import pamScrollSystem.ViewLoadObserver;
import tethys.pamdata.AutoTethysProvider; import tethys.pamdata.AutoTethysProvider;
import tethys.pamdata.TethysDataProvider; import tethys.pamdata.TethysDataProvider;
import tethys.species.DataBlockSpeciesManager;
import dataGram.DatagramProvider; import dataGram.DatagramProvider;
import dataMap.BespokeDataMapGraphic; import dataMap.BespokeDataMapGraphic;
import dataMap.OfflineDataMap; import dataMap.OfflineDataMap;
@ -3103,13 +3104,13 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
this.tethysDataProvider = tethysDataProvider; this.tethysDataProvider = tethysDataProvider;
} }
/** /**
* Get information about species types that may occur within this data * Get information about species types that may occur within this data
* block. * block. Primarily for conversion into Tethys compatible data, but may
* prove to have other uses.
* @return Types of species information available within this datablock. * @return Types of species information available within this datablock.
*/ */
public tethys.species.SpeciesTypes getSpeciesTypes() { public DataBlockSpeciesManager<Tunit> getDatablockSpeciesManager() {
return null; return null;
} }

View File

@ -0,0 +1,35 @@
package clickDetector.ClickClassifiers;
import clickDetector.ClickControl;
import clickDetector.ClickDataBlock;
import clickDetector.ClickDetection;
import tethys.species.DataBlockSpeciesManager;
import tethys.species.DataBlockSpeciesTypes;
public class ClickBlockSpeciesManager extends DataBlockSpeciesManager<ClickDetection> {
private ClickControl clickControl;
public ClickBlockSpeciesManager(ClickControl clickControl, ClickDataBlock clickDataBlock) {
super(clickDataBlock);
this.clickControl = clickControl;
}
@Override
public DataBlockSpeciesTypes getSpeciesTypes() {
ClickTypeMasterManager masterManager = clickControl.getClickTypeMasterManager();
if (masterManager == null) {
return null;
}
String[] speciesList = masterManager.getSpeciesList();
return new DataBlockSpeciesTypes(speciesList);
}
@Override
public String getSpeciesString(ClickDetection dataUnit) {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -3,6 +3,7 @@ package clickDetector;
import java.util.ListIterator; import java.util.ListIterator;
import pamScrollSystem.ViewLoadObserver; import pamScrollSystem.ViewLoadObserver;
import tethys.species.DataBlockSpeciesManager;
//import staticLocaliser.StaticLocaliserControl; //import staticLocaliser.StaticLocaliserControl;
//import staticLocaliser.StaticLocaliserProvider; //import staticLocaliser.StaticLocaliserProvider;
//import staticLocaliser.panels.AbstractLocaliserControl; //import staticLocaliser.panels.AbstractLocaliserControl;
@ -10,6 +11,7 @@ import pamScrollSystem.ViewLoadObserver;
import alarm.AlarmCounterProvider; import alarm.AlarmCounterProvider;
import alarm.AlarmDataSource; import alarm.AlarmDataSource;
import binaryFileStorage.BinaryStore; import binaryFileStorage.BinaryStore;
import clickDetector.ClickClassifiers.ClickBlockSpeciesManager;
import clickDetector.dataSelector.ClickDataSelectCreator; import clickDetector.dataSelector.ClickDataSelectCreator;
import clickDetector.offlineFuncs.OfflineClickLogging; import clickDetector.offlineFuncs.OfflineClickLogging;
import clickDetector.toad.ClickTOADCalculator; import clickDetector.toad.ClickTOADCalculator;
@ -41,6 +43,8 @@ public class ClickDataBlock extends AcousticDataBlock<ClickDetection> implement
private boolean isViewer; private boolean isViewer;
private ClickBlockSpeciesManager clickBlockSpeciesManager;
public ClickDataBlock(ClickControl clickControl, PamProcess parentProcess, int channelMap) { public ClickDataBlock(ClickControl clickControl, PamProcess parentProcess, int channelMap) {
@ -304,5 +308,13 @@ public class ClickDataBlock extends AcousticDataBlock<ClickDetection> implement
} }
} }
@Override
public DataBlockSpeciesManager<ClickDetection> getDatablockSpeciesManager() {
if (clickBlockSpeciesManager == null) {
clickBlockSpeciesManager = new ClickBlockSpeciesManager(clickControl, this);
}
return clickBlockSpeciesManager;
}
} }

View File

@ -0,0 +1,58 @@
package tethys.species;
import PamController.PamController;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import tethys.species.swing.DataBlockSpeciesDialog;
/**
* Manage species conversion for a single datablock.
* @author dg50
*
*/
abstract public class DataBlockSpeciesManager<T extends PamDataUnit> {
private DataBlockSpeciesMap datablockSpeciesMap;
private PamDataBlock<T> dataBlock;
public abstract DataBlockSpeciesTypes getSpeciesTypes();
public abstract String getSpeciesString(T dataUnit);
public DataBlockSpeciesManager(PamDataBlock<T> dataBlock) {
super();
this.dataBlock = dataBlock;
}
public SpeciesMapItem getSpeciesItem(T dataUnit) {
String speciesString = getSpeciesString(dataUnit);
if (speciesString == null) {
return null;
}
DataBlockSpeciesMap speciesMap = getDatablockSpeciesMap();
if (speciesMap == null) {
return null;
}
return speciesMap.getItem(speciesString);
}
public DataBlockSpeciesMap getDatablockSpeciesMap() {
return datablockSpeciesMap;
}
public void setDatablockSpeciesMap(DataBlockSpeciesMap datablockSpeciesMap) {
this.datablockSpeciesMap = datablockSpeciesMap;
}
public void showSpeciesDialog() {
DataBlockSpeciesDialog.showDialog(PamController.getMainFrame(), dataBlock);
}
/**
* @return the dataBlock
*/
public PamDataBlock<T> getDataBlock() {
return dataBlock;
}
}

View File

@ -0,0 +1,37 @@
package tethys.species;
import java.io.Serializable;
import java.util.HashMap;
/**
* Species map for a specified data block
* @author dg50
*
*/
public class DataBlockSpeciesMap implements Serializable {
public static final long serialVersionUID = 1L;
private HashMap<String, SpeciesMapItem> speciesTable = new HashMap<>();
protected HashMap<String, SpeciesMapItem> getSpeciesTable() {
return speciesTable;
}
protected void setSpeciesTable(HashMap<String, SpeciesMapItem> speciesTable) {
this.speciesTable = speciesTable;
}
public void putItem(String key, SpeciesMapItem speciesMapItem) {
speciesTable.put(key, speciesMapItem);
}
public SpeciesMapItem getItem(String key) {
return speciesTable.get(key);
}
public void removeItem(String key) {
speciesTable.remove(key);
}
}

View File

@ -0,0 +1,43 @@
package tethys.species;
import java.util.ArrayList;
/**
* Class to return lists of species codes or names for a datablock.
* This information will then get incorporated into a more complicated translation table to
* provide PAMGuard data on it's way to Tethys with more rigid species code definitions.
* @author dg50
*
*/
public class DataBlockSpeciesTypes {
/**
* List of species names / codes associated with this data block.
*/
private ArrayList<String> speciesNames;
/**
* constructor to use with a array of String names.
* @param speciesList
*/
public DataBlockSpeciesTypes(String[] speciesList) {
if (speciesList == null) {
speciesNames = new ArrayList<>();
}
else {
speciesNames = new ArrayList<String>(speciesList.length);
for (int i = 0; i < speciesList.length; i++) {
speciesNames.add(speciesList[i]);
}
}
}
/**
* @return the speciesNames
*/
public ArrayList<String> getSpeciesNames() {
return speciesNames;
}
}

View File

@ -1,12 +0,0 @@
package tethys.species;
import java.io.Serializable;
/**
* Species map for a specified data block
* @author dg50
*
*/
public class DatablockSpeciesMap implements Serializable {
}

View File

@ -2,18 +2,101 @@ package tethys.species;
import java.io.Serializable; import java.io.Serializable;
/**
* Information linking a name within a PAMGuard datablock to a ITIS species code and call type.
* Also contains common and latin names for display purposes, though these are not essential.
* @author dg50
*
*/
public class SpeciesMapItem implements Serializable, Cloneable { public class SpeciesMapItem implements Serializable, Cloneable {
public static final long serialVersionUID = 1L; public static final long serialVersionUID = 1L;
/**
* ITIS code. May be a real ITIS code or one of the -ve species that we're defining ourselves.
*/
private int itisCode; private int itisCode;
/**
* Species code that was used within PAMGuard. Redundant information, but useful
* for bookkeeping.
*/
private String pamguardName; private String pamguardName;
/**
* Latin name extracted from ITIS database. Can be null if unknown.
* Probably not written to Tethys.
*/
private String latinName; private String latinName;
/**
* Common species name from ITIS database. Can be null if unknown.
* Probably not written to Tethys.
*/
private String commonName; private String commonName;
/**
* Type of call. Descriptive name for type of sound, e.g. 'click', 'whistle', 'D-call',
* etc. to complement the itis species code. Will be written to Tethys.
*/
private String callType; private String callType;
public SpeciesMapItem(int itisCode, String callType, String pamguardName, String latinName, String commonName) {
super();
this.itisCode = itisCode;
this.callType = callType;
this.pamguardName = pamguardName;
this.latinName = latinName;
this.commonName = commonName;
}
public SpeciesMapItem(int itisCode, String callType, String pamguardName) {
super();
this.itisCode = itisCode;
this.callType = callType;
this.pamguardName = pamguardName;
this.latinName = null;
this.commonName = null;
}
/**
* ITIS code. May be a real ITIS code or one of the -ve species that we're defining ourselves.
* @return the itisCode
*/
public int getItisCode() {
return itisCode;
}
/**
* Species code that was used within PAMGuard. Redundant information, but useful
* @return the pamguardName
*/
public String getPamguardName() {
return pamguardName;
}
/**
* Latin name extracted from ITIS database. Can be null if unknown.
* @return the latinName
*/
public String getLatinName() {
return latinName;
}
/**
* Common species name from ITIS database. Can be null if unknown.
* @return the commonName
*/
public String getCommonName() {
return commonName;
}
/**
* Type of call. Descriptive name for type of sound, e.g. 'click', 'whistle', 'D-call',
* @return the callType
*/
public String getCallType() {
return callType;
}
} }

View File

@ -5,7 +5,7 @@ import dbxml.Queries;
import tethys.dbxml.DBQueryResult; import tethys.dbxml.DBQueryResult;
import tethys.dbxml.TethysQueryException; import tethys.dbxml.TethysQueryException;
public class SpeciesTest extends SpeciesTypes { public class SpeciesTest {
String uri = "http://localhost:9779"; String uri = "http://localhost:9779";
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -1,20 +0,0 @@
package tethys.species;
import java.util.ArrayList;
/**
* Class to return lists of species codes or names for a datablock.
* This information will then get incorporated into a more complicated translation table to
* provide PAMGuard data on it's way to Tethys with more rigid species code definitions.
* @author dg50
*
*/
public class SpeciesTypes {
/**
* List of species names / codes associated with this data block.
*/
private ArrayList<String> speciesNames;
}

View File

@ -0,0 +1,47 @@
package tethys.species.swing;
import java.awt.Window;
import PamView.dialog.PamDialog;
import PamguardMVC.PamDataBlock;
public class DataBlockSpeciesDialog extends PamDialog {
private static final long serialVersionUID = 1L;
DataBlockSpeciesPanel speciesPanel;
private DataBlockSpeciesDialog(Window parentFrame, PamDataBlock dataBlock) {
super(parentFrame, dataBlock.getDataName() + " species", false);
speciesPanel = new DataBlockSpeciesPanel(dataBlock);
setDialogComponent(speciesPanel.getDialogComponent());
}
public static void showDialog(Window parentFrame, PamDataBlock dataBlock) {
DataBlockSpeciesDialog speciesDialog = new DataBlockSpeciesDialog(parentFrame, dataBlock);
speciesDialog.setParams();
speciesDialog.setVisible(true);
}
private void setParams() {
speciesPanel.setParams();
}
@Override
public boolean getParams() {
return speciesPanel.getParams();
}
@Override
public void cancelButtonPressed() {
// TODO Auto-generated method stub
}
@Override
public void restoreDefaultSettings() {
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,65 @@
package tethys.species.swing;
import java.awt.BorderLayout;
import java.util.ArrayList;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;
import PamView.dialog.PamDialogPanel;
import PamguardMVC.PamDataBlock;
import tethys.species.DataBlockSpeciesManager;
import tethys.species.DataBlockSpeciesMap;
import tethys.species.DataBlockSpeciesTypes;
import tethys.species.SpeciesMapItem;
public class DataBlockSpeciesPanel implements PamDialogPanel {
private JPanel mainPanel;
private PamDataBlock dataBlock;
private JPanel speciesPanel;
public DataBlockSpeciesPanel(PamDataBlock dataBlock) {
super();
this.dataBlock = dataBlock;
mainPanel = new JPanel(new BorderLayout());
speciesPanel = new JPanel();
mainPanel.add(speciesPanel, BorderLayout.CENTER);
mainPanel.setBorder(new TitledBorder(dataBlock.getDataName()));
}
@Override
public JComponent getDialogComponent() {
return mainPanel;
}
@Override
public void setParams() {
speciesPanel.removeAll();
speciesPanel.setLayout(new BoxLayout(speciesPanel, BoxLayout.Y_AXIS));
DataBlockSpeciesManager speciesManager = dataBlock.getDatablockSpeciesManager();
DataBlockSpeciesTypes speciesTypes = speciesManager.getSpeciesTypes();
ArrayList<String> speciesNames = speciesTypes.getSpeciesNames();
DataBlockSpeciesMap speciesMap = speciesManager.getDatablockSpeciesMap();
for (String aSpecies : speciesNames) {
SpeciesSubPanel subPanel = new SpeciesSubPanel(aSpecies);
speciesPanel.add(subPanel.getDialogComponent());
if (speciesMap != null) {
SpeciesMapItem speciesInfo = speciesMap.getItem(aSpecies);
subPanel.setParams(speciesInfo);
}
}
}
@Override
public boolean getParams() {
// TODO Auto-generated method stub
return false;
}
}

View File

@ -0,0 +1,95 @@
package tethys.species.swing;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.BevelBorder;
import PamView.dialog.PamGridBagContraints;
import tethys.species.SpeciesMapItem;
public class SpeciesSubPanel {
private JPanel mainPanel;
private JLabel pamguardName;
private JTextField itisCode, callType, latinName, commonName;
private JButton searchButton;
public SpeciesSubPanel(String aSpecies) {
mainPanel = new JPanel(new GridBagLayout());
mainPanel.setBorder(new BevelBorder(BevelBorder.RAISED));
GridBagConstraints c = new PamGridBagContraints();
mainPanel.add(new JLabel("Name ", JLabel.RIGHT), c);
c.gridx++;
mainPanel.add(pamguardName = new JLabel(aSpecies), c);
c.gridx++;
mainPanel.add(new JLabel(" ITIS code ", JLabel.RIGHT), c);
c.gridx++;
mainPanel.add(itisCode = new JTextField(3), c);
c.gridx ++;
mainPanel.add(searchButton = new JButton("Find"));
int w1 = 2;
int w2 = 3;
c.gridx = 0;
c.gridy++;
c.gridwidth = w1;
mainPanel.add(new JLabel("Call / sound type ", JLabel.RIGHT), c);
c.gridx+= c.gridwidth;
c.gridwidth = w2;
mainPanel.add(callType = new JTextField(15), c);
c.gridx = 0;
c.gridy++;
c.gridwidth = w1;
mainPanel.add(new JLabel("Scientific name ", JLabel.RIGHT), c);
c.gridx+= c.gridwidth;
c.gridwidth = w2;
mainPanel.add(latinName = new JTextField(15), c);
c.gridx = 0;
c.gridy++;
c.gridwidth = w1;
mainPanel.add(new JLabel("Common name ", JLabel.RIGHT), c);
c.gridx+= c.gridwidth;
c.gridwidth = w2;
mainPanel.add(commonName = new JTextField(15), c);
pamguardName.setToolTipText("Internal name within PAMGuard module");
itisCode.setToolTipText("ITIS species code");
searchButton.setToolTipText("Search for species code");
callType.setToolTipText("Descriptive name for call type or measurement");
latinName.setToolTipText("Scientific name");
commonName.setToolTipText("Common name");
}
public JComponent getDialogComponent() {
return mainPanel;
}
public void setParams(SpeciesMapItem speciesMapItem) {
if (speciesMapItem == null) {
itisCode.setText(null);
callType.setText(null);
latinName.setText(null);
commonName.setText(null);
return;
}
pamguardName.setText(speciesMapItem.getPamguardName());
itisCode.setText(String.format("%d", speciesMapItem.getItisCode()));
callType.setText(speciesMapItem.getCallType());
latinName.setText(speciesMapItem.getLatinName());
commonName.setText(speciesMapItem.getCommonName());
}
public SpeciesMapItem getParams() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -1,6 +1,8 @@
package tethys.swing; package tethys.swing;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent; import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener; import java.awt.event.ComponentListener;
import java.awt.event.KeyAdapter; import java.awt.event.KeyAdapter;
@ -10,7 +12,9 @@ import java.awt.event.MouseEvent;
import java.util.ArrayList; import java.util.ArrayList;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JMenuItem;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.border.TitledBorder; import javax.swing.border.TitledBorder;
@ -25,6 +29,7 @@ import dataMap.OfflineDataMap;
import tethys.TethysControl; import tethys.TethysControl;
import tethys.TethysState; import tethys.TethysState;
import tethys.output.DatablockSynchInfo; import tethys.output.DatablockSynchInfo;
import tethys.species.DataBlockSpeciesManager;
public class DatablockSynchPanel extends TethysGUIPanel { public class DatablockSynchPanel extends TethysGUIPanel {
@ -68,21 +73,63 @@ public class DatablockSynchPanel extends TethysGUIPanel {
private class MouseActions extends MouseAdapter { private class MouseActions extends MouseAdapter {
@Override @Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
selectRow(); int row = selectRow();
if (e.isPopupTrigger() && row >= 0) {
showPopup(e, row);
}
}
@Override
public void mousePressed(MouseEvent e) {
int row = selectRow();
if (e.isPopupTrigger() && row >= 0) {
showPopup(e, row);
}
}
@Override
public void mouseReleased(MouseEvent e) {
int row = selectRow();
if (e.isPopupTrigger() && row >= 0) {
showPopup(e, row);
}
} }
} }
private void selectRow() { private int selectRow() {
int row = synchTable.getSelectedRow(); int row = synchTable.getSelectedRow();
if (row < 0) { if (row < 0) {
return; return row;
} }
DatablockSynchInfo synchInfo = dataBlockSynchInfo.get(row); DatablockSynchInfo synchInfo = dataBlockSynchInfo.get(row);
// datablockDetectionsPanel.setDataBlock(synchInfo.getDataBlock()); // datablockDetectionsPanel.setDataBlock(synchInfo.getDataBlock());
notifyObservers(synchInfo.getDataBlock()); notifyObservers(synchInfo.getDataBlock());
return row;
} }
public void showPopup(MouseEvent e, int row) {
DatablockSynchInfo synchInfo = dataBlockSynchInfo.get(row);
if (synchInfo == null) {
return;
}
PamDataBlock dataBlock = synchInfo.getDataBlock();
DataBlockSpeciesManager speciesManager = dataBlock.getDatablockSpeciesManager();
if (speciesManager == null) {
return;
}
JPopupMenu popMenu = new JPopupMenu();
JMenuItem menuItem = new JMenuItem("Species info ...");
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
speciesManager.showSpeciesDialog();
}
});
popMenu.add(menuItem);
popMenu.show(e.getComponent(), e.getX(), e.getY());
}
@Override @Override
public void updateState(TethysState tethysState) { public void updateState(TethysState tethysState) {
synchTableModel.fireTableDataChanged(); synchTableModel.fireTableDataChanged();