mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2024-11-25 16:42:27 +00:00
Detections output
more work on detections output.
This commit is contained in:
parent
db1cc75bc1
commit
158eedce8c
29
src/PamguardMVC/DataAutomation.java
Normal file
29
src/PamguardMVC/DataAutomation.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package PamguardMVC;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dg50
|
||||||
|
* Levels of automation for the various datas in PAMGuard.
|
||||||
|
* Should be used within DataAutomationInfo to perhaps combine with other info in the future.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public enum DataAutomation {
|
||||||
|
|
||||||
|
AUTOMATIC, MANUAL, MANUALANDAUTOMATIC;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
switch (this) {
|
||||||
|
case AUTOMATIC:
|
||||||
|
return "Automatic";
|
||||||
|
case MANUAL:
|
||||||
|
return "Manual";
|
||||||
|
case MANUALANDAUTOMATIC:
|
||||||
|
return "Manual and automatic";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
44
src/PamguardMVC/DataAutomationInfo.java
Normal file
44
src/PamguardMVC/DataAutomationInfo.java
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package PamguardMVC;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returned by datablocks, though default is null, to give information on how
|
||||||
|
* automatic the process was.
|
||||||
|
* @author dg50
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DataAutomationInfo {
|
||||||
|
|
||||||
|
|
||||||
|
private DataAutomation automation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param automation
|
||||||
|
*/
|
||||||
|
public DataAutomationInfo(DataAutomation automation) {
|
||||||
|
this.setAutomation(automation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the automation
|
||||||
|
*/
|
||||||
|
public DataAutomation getAutomation() {
|
||||||
|
return automation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param automation the automation to set
|
||||||
|
*/
|
||||||
|
public void setAutomation(DataAutomation automation) {
|
||||||
|
this.automation = automation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
if (automation == null) {
|
||||||
|
return "Unknown data automation";
|
||||||
|
}
|
||||||
|
return automation.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -3100,11 +3100,12 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a data provider for Tethys.
|
* Get the level of automation employed by the generation of these data.
|
||||||
* @param tethysDataProvider the tethysDataProvider to set
|
* Should ideally be completed for everything providing data to Tethys.
|
||||||
|
* @return level of automation for this data block.
|
||||||
*/
|
*/
|
||||||
public void setTethysDataProvider(TethysDataProvider tethysDataProvider) {
|
public DataAutomationInfo getDataAutomationInfo() {
|
||||||
this.tethysDataProvider = tethysDataProvider;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,6 +2,8 @@ package RightWhaleEdgeDetector;
|
|||||||
|
|
||||||
import PamView.GroupedDataSource;
|
import PamView.GroupedDataSource;
|
||||||
import PamView.GroupedSourceParameters;
|
import PamView.GroupedSourceParameters;
|
||||||
|
import PamguardMVC.DataAutomation;
|
||||||
|
import PamguardMVC.DataAutomationInfo;
|
||||||
import PamguardMVC.PamProcess;
|
import PamguardMVC.PamProcess;
|
||||||
import PamguardMVC.dataOffline.OfflineDataLoadInfo;
|
import PamguardMVC.dataOffline.OfflineDataLoadInfo;
|
||||||
import PamguardMVC.dataSelector.DataSelectorCreator;
|
import PamguardMVC.dataSelector.DataSelectorCreator;
|
||||||
@ -77,4 +79,9 @@ public class RWEDataBlock extends AbstractWhistleDataBlock<RWEDataUnit> implemen
|
|||||||
return rwTethysDataProvider;
|
return rwTethysDataProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataAutomationInfo getDataAutomationInfo() {
|
||||||
|
return new DataAutomationInfo(DataAutomation.AUTOMATIC);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -846,6 +846,11 @@ public class DBXMLQueries {
|
|||||||
description.setMethod(getElementData(result, "Description.Method"));
|
description.setMethod(getElementData(result, "Description.Method"));
|
||||||
description.setObjectives(getElementData(result, "Description.Objectives"));
|
description.setObjectives(getElementData(result, "Description.Objectives"));
|
||||||
|
|
||||||
|
// get the effort start an end
|
||||||
|
String effStart = getElementData(result, "Effort.Start");
|
||||||
|
String effEnd = getElementData(result, "Effort.End");
|
||||||
|
detections.getEffort().setStart(TethysTimeFuncs.fromGregorianXML(effStart));
|
||||||
|
detections.getEffort().setEnd(TethysTimeFuncs.fromGregorianXML(effEnd));
|
||||||
// try to find the granularity.
|
// try to find the granularity.
|
||||||
String granularityString = getElementData(result, "Effort.Kind.Granularity");
|
String granularityString = getElementData(result, "Effort.Kind.Granularity");
|
||||||
GranularityEnumType granularity = null;
|
GranularityEnumType granularity = null;
|
||||||
|
@ -4,6 +4,8 @@ import java.math.BigInteger;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import PamguardMVC.PamDataBlock;
|
import PamguardMVC.PamDataBlock;
|
||||||
@ -29,9 +31,7 @@ import tethys.species.SpeciesMapItem;
|
|||||||
*/
|
*/
|
||||||
public class BinnedGranularityHandler extends GranularityHandler {
|
public class BinnedGranularityHandler extends GranularityHandler {
|
||||||
|
|
||||||
private double binDurationSeconds;
|
private long binDurationMillis;
|
||||||
|
|
||||||
private long binStartMillis, binEndMillis;
|
|
||||||
|
|
||||||
private TethysDataProvider dataProvider;
|
private TethysDataProvider dataProvider;
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ public class BinnedGranularityHandler extends GranularityHandler {
|
|||||||
TethysExportParams tethysExportParams, StreamExportParams streamExportParams) {
|
TethysExportParams tethysExportParams, StreamExportParams streamExportParams) {
|
||||||
super(tethysControl, dataBlock, tethysExportParams, streamExportParams);
|
super(tethysControl, dataBlock, tethysExportParams, streamExportParams);
|
||||||
|
|
||||||
binDurationSeconds = streamExportParams.binDurationS;
|
binDurationMillis = (long) (streamExportParams.binDurationS*1000.);
|
||||||
dataProvider = dataBlock.getTethysDataProvider(tethysControl);
|
dataProvider = dataBlock.getTethysDataProvider(tethysControl);
|
||||||
speciesManager = dataBlock.getDatablockSpeciesManager();
|
speciesManager = dataBlock.getDatablockSpeciesManager();
|
||||||
|
|
||||||
@ -52,61 +52,74 @@ public class BinnedGranularityHandler extends GranularityHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void prepare(long timeMillis) {
|
public void prepare(long timeMillis) {
|
||||||
long binStart = DetectionsHandler.roundDownBinStart(timeMillis, (long) (binDurationSeconds*1000));
|
// long binStart = DetectionsHandler.roundDownBinStart(timeMillis, binDurationMillis);
|
||||||
startBin(binStart);
|
// startBin(binStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startBin(long timeMillis) {
|
// private void startBin(long timeMillis) {
|
||||||
binStartMillis = timeMillis;
|
// binStartMillis = timeMillis;
|
||||||
binEndMillis = binStartMillis + (long) (binDurationSeconds*1000.);
|
// binEndMillis = binStartMillis + binDurationMillis;
|
||||||
/*
|
// /*
|
||||||
* now make a Detection object for every possible species that
|
// * now make a Detection object for every possible species that
|
||||||
* this might throw out.
|
// * this might throw out.
|
||||||
*/
|
// */
|
||||||
ArrayList<String> speciesCodes = speciesManager.getAllSpeciesCodes();
|
// ArrayList<String> speciesCodes = speciesManager.getAllSpeciesCodes();
|
||||||
String defaultCode = speciesManager.getDefaultSpeciesCode();
|
// String defaultCode = speciesManager.getDefaultSpeciesCode();
|
||||||
Detection det;
|
// Detection det;
|
||||||
currentDetections.put(defaultCode, det = new Detection());
|
// currentDetections.put(defaultCode, det = new Detection());
|
||||||
det.setStart(TethysTimeFuncs.xmlGregCalFromMillis(binStartMillis));
|
// det.setStart(TethysTimeFuncs.xmlGregCalFromMillis(binStartMillis));
|
||||||
det.setEnd(TethysTimeFuncs.xmlGregCalFromMillis(binEndMillis));
|
// det.setEnd(TethysTimeFuncs.xmlGregCalFromMillis(binEndMillis));
|
||||||
det.setCount(BigInteger.ZERO);
|
// det.setCount(BigInteger.ZERO);
|
||||||
det.setChannel(BigInteger.ZERO);
|
// det.setChannel(BigInteger.ZERO);
|
||||||
// add codes at end, just before output.
|
// // add codes at end, just before output.
|
||||||
if (speciesCodes != null) {
|
// if (speciesCodes != null) {
|
||||||
for (String code : speciesCodes) {
|
// for (String code : speciesCodes) {
|
||||||
currentDetections.put(code, det = new Detection());
|
// currentDetections.put(code, det = new Detection());
|
||||||
det.setStart(TethysTimeFuncs.xmlGregCalFromMillis(binStartMillis));
|
// det.setStart(TethysTimeFuncs.xmlGregCalFromMillis(binStartMillis));
|
||||||
det.setEnd(TethysTimeFuncs.xmlGregCalFromMillis(binEndMillis));
|
// det.setEnd(TethysTimeFuncs.xmlGregCalFromMillis(binEndMillis));
|
||||||
det.setCount(BigInteger.ZERO);
|
// det.setCount(BigInteger.ZERO);
|
||||||
det.setChannel(BigInteger.ZERO);
|
// det.setChannel(BigInteger.ZERO);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Detection[] addDataUnit(PamDataUnit dataUnit) {
|
public Detection[] addDataUnit(PamDataUnit dataUnit) {
|
||||||
Detection[] detections = null;
|
Detection[] completeDetections = closeBins(dataUnit.getTimeMilliseconds());
|
||||||
if (dataUnit.getTimeMilliseconds() >= binEndMillis) {
|
// now look for new ones. First get the species of the dataUnit and find it in the hashmap
|
||||||
detections = closeBins(dataUnit.getTimeMilliseconds());
|
String groupName = getCallGroupName(dataUnit);
|
||||||
prepare(dataUnit.getTimeMilliseconds());
|
Detection det = currentDetections.get(groupName);
|
||||||
|
if (det == null) {
|
||||||
|
// need to make a new one.
|
||||||
|
det = new Detection();
|
||||||
|
long binStart = DetectionsHandler.roundDownBinStart(dataUnit.getTimeMilliseconds(), binDurationMillis);
|
||||||
|
det.setStart(TethysTimeFuncs.xmlGregCalFromMillis(binStart));
|
||||||
|
det.setEnd(TethysTimeFuncs.xmlGregCalFromMillis(binStart + binDurationMillis));
|
||||||
|
det.setCount(BigInteger.ONE);
|
||||||
|
det.setChannel(BigInteger.valueOf(dataUnit.getChannelBitmap()));
|
||||||
|
// this should always return something, so am going to crash if it doesn't.
|
||||||
|
// may revisit this later on if we've unassigned things we don't want to label
|
||||||
|
// in which case they should be rejected earlier than this.
|
||||||
|
SpeciesMapItem speciesStuff = speciesManager.getSpeciesItem(dataUnit);
|
||||||
|
SpeciesIDType species = new SpeciesIDType();
|
||||||
|
species.setValue(BigInteger.valueOf(speciesStuff.getItisCode()));
|
||||||
|
det.setSpeciesId(species);
|
||||||
|
if (speciesStuff.getCallType() != null) {
|
||||||
|
det.getCall().add(speciesStuff.getCallType());
|
||||||
}
|
}
|
||||||
String speciesCode = speciesManager.getSpeciesCode(dataUnit);
|
currentDetections.put(groupName, det);
|
||||||
Detection det = currentDetections.get(speciesCode);
|
}
|
||||||
if (det != null) {
|
else {
|
||||||
/*
|
// add to current detection. Set new end time and increment count
|
||||||
* Increase the detection count
|
int count = det.getCount().intValue() + 1;
|
||||||
*/
|
|
||||||
int count = det.getCount().intValue();
|
|
||||||
count++;
|
|
||||||
det.setCount(BigInteger.valueOf(count));
|
det.setCount(BigInteger.valueOf(count));
|
||||||
/*
|
int chan = det.getChannel().intValue();
|
||||||
* Add to the channel map too ...
|
chan |= dataUnit.getChannelBitmap();
|
||||||
*/
|
det.setChannel(BigInteger.valueOf(chan));
|
||||||
int channel = det.getChannel().intValue();
|
|
||||||
channel |= dataUnit.getChannelBitmap();
|
|
||||||
det.setChannel(BigInteger.valueOf(channel));
|
|
||||||
}
|
}
|
||||||
return detections;
|
|
||||||
|
|
||||||
|
return completeDetections;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,33 +128,32 @@ public class BinnedGranularityHandler extends GranularityHandler {
|
|||||||
* @param timeMilliseconds
|
* @param timeMilliseconds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private Detection[] closeBins(long timeMilliseconds) {
|
private synchronized Detection[] closeBins(long timeMilliseconds) {
|
||||||
Set<String> speciesKeys = currentDetections.keySet();
|
Set<String> speciesKeys = currentDetections.keySet();
|
||||||
int n = speciesKeys.size();
|
int n = speciesKeys.size();
|
||||||
int nGood = 0;
|
int nGood = 0;
|
||||||
DataBlockSpeciesMap speciesMap = speciesManager.getDatablockSpeciesMap();
|
DataBlockSpeciesMap speciesMap = speciesManager.getDatablockSpeciesMap();
|
||||||
Detection detections[] = new Detection[n];
|
Detection detections[] = new Detection[n];
|
||||||
for (String key : speciesKeys) {
|
Iterator<Entry<String, Detection>> iter = currentDetections.entrySet().iterator();
|
||||||
Detection det = currentDetections.get(key);
|
while (iter.hasNext()) {
|
||||||
|
Entry<String, Detection> entry = iter.next();
|
||||||
|
Detection det = entry.getValue();
|
||||||
|
long detEnd = TethysTimeFuncs.millisFromGregorianXML(det.getEnd());
|
||||||
|
if (timeMilliseconds < detEnd) {
|
||||||
|
// we're not at the end of the bin, so carry on.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// we've reached the end of the bin, so remove it from the map
|
||||||
|
iter.remove();
|
||||||
|
// now decide if we want to keep it or not.
|
||||||
int callCount = det.getCount().intValue();
|
int callCount = det.getCount().intValue();
|
||||||
if (callCount < Math.max(streamExportParams.minBinCount,1)) {
|
if (callCount < Math.max(streamExportParams.minBinCount,1)) {
|
||||||
continue;
|
continue; // won't add to output list
|
||||||
}
|
|
||||||
SpeciesMapItem speciesStuff = speciesMap.getItem(key); // should be non null!
|
|
||||||
if (speciesStuff == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SpeciesIDType species = new SpeciesIDType();
|
|
||||||
species.setValue(BigInteger.valueOf(speciesStuff.getItisCode()));
|
|
||||||
det.setSpeciesId(species);
|
|
||||||
if (speciesStuff.getCallType() != null) {
|
|
||||||
det.getCall().add(speciesStuff.getCallType());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
detections[nGood++] = det;
|
detections[nGood++] = det;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clean up the end of the array and return detections that have enough calls.
|
* Clean up the end of the array and return detections that have enough calls.
|
||||||
*/
|
*/
|
||||||
|
@ -349,9 +349,9 @@ public class DetectionsHandler {
|
|||||||
/**
|
/**
|
||||||
* Round a bin start so that it's aligned correctly with
|
* Round a bin start so that it's aligned correctly with
|
||||||
* day starts.
|
* day starts.
|
||||||
* @param binStart
|
* @param binStart in milliseconds
|
||||||
* @param binInterval
|
* @param binInterval in milliseconds
|
||||||
* @return
|
* @return rounded time.
|
||||||
*/
|
*/
|
||||||
public static long roundDownBinStart(long binStart, long binInterval) {
|
public static long roundDownBinStart(long binStart, long binInterval) {
|
||||||
binStart/=binInterval;
|
binStart/=binInterval;
|
||||||
@ -441,6 +441,10 @@ public class DetectionsHandler {
|
|||||||
// currentDetections = null;
|
// currentDetections = null;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
Detection dets[] = granularityHandler.cleanup(deployment.getAudioEnd());
|
||||||
|
if (dets != null) {
|
||||||
|
exportCount += dets.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -578,8 +582,9 @@ public class DetectionsHandler {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
TethysDataProvider dataProvider = dataBlock.getTethysDataProvider(tethysControl);
|
||||||
|
|
||||||
String prefix = deployment.deployment.getId();
|
String prefix = deployment.deployment.getId() + "_" + dataProvider.getDetectionsName();
|
||||||
String fullId = "";
|
String fullId = "";
|
||||||
/*
|
/*
|
||||||
* Check the document name isn't already used and increment id as necessary.
|
* Check the document name isn't already used and increment id as necessary.
|
||||||
@ -599,7 +604,6 @@ public class DetectionsHandler {
|
|||||||
detections.setDataSource(dataSource);
|
detections.setDataSource(dataSource);
|
||||||
AlgorithmType algorithm = detections.getAlgorithm();
|
AlgorithmType algorithm = detections.getAlgorithm();
|
||||||
|
|
||||||
TethysDataProvider dataProvider = dataBlock.getTethysDataProvider(tethysControl);
|
|
||||||
if (dataProvider != null) {
|
if (dataProvider != null) {
|
||||||
algorithm = dataProvider.getAlgorithm();
|
algorithm = dataProvider.getAlgorithm();
|
||||||
// detections.setAlgorithm(algorithm);
|
// detections.setAlgorithm(algorithm);
|
||||||
|
@ -6,6 +6,7 @@ import java.util.HashMap;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import PamguardMVC.PamDataBlock;
|
import PamguardMVC.PamDataBlock;
|
||||||
import PamguardMVC.PamDataUnit;
|
import PamguardMVC.PamDataUnit;
|
||||||
@ -54,8 +55,8 @@ public class EncounterGranularityHandler extends GranularityHandler {
|
|||||||
public Detection[] addDataUnit(PamDataUnit dataUnit) {
|
public Detection[] addDataUnit(PamDataUnit dataUnit) {
|
||||||
Detection[] completeDetections = checkCurrentEncounters(dataUnit.getTimeMilliseconds());
|
Detection[] completeDetections = checkCurrentEncounters(dataUnit.getTimeMilliseconds());
|
||||||
// now look for new ones. First get the species of the dataUnit and find it in the hashmap
|
// now look for new ones. First get the species of the dataUnit and find it in the hashmap
|
||||||
String speciesCode = speciesManager.getSpeciesCode(dataUnit);
|
String groupName = getCallGroupName(dataUnit);
|
||||||
Detection det = currentDetections.get(speciesCode);
|
Detection det = currentDetections.get(groupName);
|
||||||
if (det == null) {
|
if (det == null) {
|
||||||
// need to make a new one.
|
// need to make a new one.
|
||||||
det = new Detection();
|
det = new Detection();
|
||||||
@ -73,7 +74,7 @@ public class EncounterGranularityHandler extends GranularityHandler {
|
|||||||
if (speciesStuff.getCallType() != null) {
|
if (speciesStuff.getCallType() != null) {
|
||||||
det.getCall().add(speciesStuff.getCallType());
|
det.getCall().add(speciesStuff.getCallType());
|
||||||
}
|
}
|
||||||
currentDetections.put(speciesCode, det);
|
currentDetections.put(groupName, det);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// add to current detection. Set new end time and increment count
|
// add to current detection. Set new end time and increment count
|
||||||
@ -98,16 +99,18 @@ public class EncounterGranularityHandler extends GranularityHandler {
|
|||||||
Set<String> keys = currentDetections.keySet();
|
Set<String> keys = currentDetections.keySet();
|
||||||
int nGood = 0;
|
int nGood = 0;
|
||||||
Detection[] newDetections = new Detection[currentDetections.size()];
|
Detection[] newDetections = new Detection[currentDetections.size()];
|
||||||
for (String aKey : keys) {
|
Iterator<Entry<String, Detection>> iter = currentDetections.entrySet().iterator();
|
||||||
Detection aDet = currentDetections.get(aKey);
|
while (iter.hasNext()) {
|
||||||
Long detEnd = TethysTimeFuncs.millisFromGregorianXML(aDet.getEnd());
|
Entry<String, Detection> entry = iter.next();
|
||||||
|
Detection aDet = entry.getValue();
|
||||||
|
long detEnd = TethysTimeFuncs.millisFromGregorianXML(aDet.getEnd());
|
||||||
if (timeMilliseconds-detEnd > maxGapMillis) {
|
if (timeMilliseconds-detEnd > maxGapMillis) {
|
||||||
// only keep if it's got a min number of calls.
|
// only keep if it's got a min number of calls.
|
||||||
if (aDet.getCount().intValue() >= streamExportParams.minBinCount) {
|
if (aDet.getCount().intValue() >= streamExportParams.minBinCount) {
|
||||||
newDetections[nGood++] = aDet;
|
newDetections[nGood++] = aDet;
|
||||||
}
|
}
|
||||||
// remove from set. A new one will be created only when required.
|
// remove from set. A new one will be created only when required.
|
||||||
currentDetections.remove(aKey);
|
iter.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import nilus.GranularityEnumType;
|
|||||||
import tethys.TethysControl;
|
import tethys.TethysControl;
|
||||||
import tethys.output.StreamExportParams;
|
import tethys.output.StreamExportParams;
|
||||||
import tethys.output.TethysExportParams;
|
import tethys.output.TethysExportParams;
|
||||||
|
import tethys.species.DataBlockSpeciesManager;
|
||||||
|
|
||||||
public abstract class GranularityHandler {
|
public abstract class GranularityHandler {
|
||||||
|
|
||||||
@ -18,6 +19,8 @@ public abstract class GranularityHandler {
|
|||||||
|
|
||||||
protected StreamExportParams streamExportParams;
|
protected StreamExportParams streamExportParams;
|
||||||
|
|
||||||
|
private DataBlockSpeciesManager speciesManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param tethysControl
|
* @param tethysControl
|
||||||
* @param dataBlock
|
* @param dataBlock
|
||||||
@ -30,6 +33,7 @@ public abstract class GranularityHandler {
|
|||||||
this.dataBlock = dataBlock;
|
this.dataBlock = dataBlock;
|
||||||
this.tethysExportParams = tethysExportParams;
|
this.tethysExportParams = tethysExportParams;
|
||||||
this.streamExportParams = streamExportParams;
|
this.streamExportParams = streamExportParams;
|
||||||
|
speciesManager = dataBlock.getDatablockSpeciesManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,6 +52,23 @@ public abstract class GranularityHandler {
|
|||||||
*/
|
*/
|
||||||
public abstract Detection[] addDataUnit(PamDataUnit dataUnit);
|
public abstract Detection[] addDataUnit(PamDataUnit dataUnit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a grouping name for the call. This may just be the calls species code,
|
||||||
|
* or it may be appended with the channel number. This is used to find bin and
|
||||||
|
* encounter data in HashMaps in
|
||||||
|
* @param dataUnit
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getCallGroupName(PamDataUnit dataUnit) {
|
||||||
|
String groupName = speciesManager.getSpeciesCode(dataUnit);
|
||||||
|
if (groupName == null) {
|
||||||
|
groupName = "NullSpecies";
|
||||||
|
}
|
||||||
|
if (streamExportParams.separateChannels) {
|
||||||
|
groupName += String.format("Chan%d", dataUnit.getChannelBitmap());
|
||||||
|
}
|
||||||
|
return groupName;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Called after end end of all data units to get the last bin / encounter. <p>
|
* Called after end end of all data units to get the last bin / encounter. <p>
|
||||||
*
|
*
|
||||||
|
@ -3,15 +3,20 @@ package tethys.output;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import PamController.PamController;
|
||||||
|
import PamguardMVC.PamDataBlock;
|
||||||
import nilus.DescriptionType;
|
import nilus.DescriptionType;
|
||||||
import nilus.GranularityEnumType;
|
import nilus.GranularityEnumType;
|
||||||
|
import tethys.TethysControl;
|
||||||
import tethys.niluswraps.PDescriptionType;
|
import tethys.niluswraps.PDescriptionType;
|
||||||
|
import tethys.pamdata.TethysDataProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parameters controlling export of a single stream.
|
* Parameters controlling export of a single stream.
|
||||||
* Starts just with a boolean 'selected', but may grow.
|
* Starts just with a boolean 'selected', but may grow.
|
||||||
* These all contain data names rather than references to a Datablock so that
|
* These all contain data names rather than references to a Datablock so that
|
||||||
* they can be serialised.
|
* they can be serialised. However, created with TethysControl and datablock
|
||||||
|
* so that some stuff canbe automatically initialised.
|
||||||
* @author dg50
|
* @author dg50
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -19,24 +24,44 @@ public class StreamExportParams implements Serializable {
|
|||||||
|
|
||||||
public static final long serialVersionUID = 1L;
|
public static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public StreamExportParams(String longDataName, boolean selected) {
|
/**
|
||||||
super();
|
* Datablock long data name (used instead of datablock
|
||||||
this.longDataName = longDataName;
|
* reference so this object and serialise.
|
||||||
this.selected = selected;
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
public String longDataName;
|
public String longDataName;
|
||||||
|
|
||||||
public boolean selected;
|
public boolean selected;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Granularity type, binned, call, encounter, grouped.
|
||||||
|
*/
|
||||||
public GranularityEnumType granularity = GranularityEnumType.CALL;
|
public GranularityEnumType granularity = GranularityEnumType.CALL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bin duration, seconds.
|
||||||
|
*/
|
||||||
public double binDurationS = 60;
|
public double binDurationS = 60;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimum encounter gap, seconds
|
||||||
|
*/
|
||||||
public double encounterGapS = 60;
|
public double encounterGapS = 60;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimum count for a bin to be retained.
|
||||||
|
*/
|
||||||
public int minBinCount = 1;
|
public int minBinCount = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimum count for an encounter to be retained.
|
||||||
|
*/
|
||||||
|
public int minEncounterCount = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keep channels separate when using binned data.
|
||||||
|
*/
|
||||||
|
public boolean separateChannels = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Can't have this here since it isn't serializable.
|
* Can't have this here since it isn't serializable.
|
||||||
*/
|
*/
|
||||||
@ -49,6 +74,25 @@ public class StreamExportParams implements Serializable {
|
|||||||
return detectionDescription;
|
return detectionDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public StreamExportParams(TethysControl tethysControl, PamDataBlock dataBlock, boolean selected) {
|
||||||
|
super();
|
||||||
|
this.longDataName = dataBlock.getLongDataName();
|
||||||
|
this.selected = selected;
|
||||||
|
autoFill(tethysControl, dataBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to put some information automatically into the Methods.
|
||||||
|
* @param dataBlock2
|
||||||
|
* @param tethysControl
|
||||||
|
*/
|
||||||
|
private void autoFill(TethysControl tethysControl, PamDataBlock dataBlock) {
|
||||||
|
// there should always be a data provider or we'd never have got this far.
|
||||||
|
TethysDataProvider dataProvider = dataBlock.getTethysDataProvider(tethysControl);
|
||||||
|
PDescriptionType desc = getDetectionDescription();
|
||||||
|
desc.setMethod(dataProvider.getDetectionsMethod());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the nilus detection description
|
* Get the nilus detection description
|
||||||
* @return
|
* @return
|
||||||
|
@ -151,7 +151,7 @@ public class TethysExportDialog extends PamDialog {
|
|||||||
}
|
}
|
||||||
int nSel = 0;
|
int nSel = 0;
|
||||||
for (DataStreamSet streamSet : dataStreamSets) {
|
for (DataStreamSet streamSet : dataStreamSets) {
|
||||||
StreamExportParams streamOpts = new StreamExportParams(streamSet.dataBlock.getLongDataName(), streamSet.checkBox.isSelected());
|
StreamExportParams streamOpts = new StreamExportParams(tethysControl, streamSet.dataBlock, streamSet.checkBox.isSelected());
|
||||||
exportParams.setStreamParams(streamSet.dataBlock, streamOpts);
|
exportParams.setStreamParams(streamSet.dataBlock, streamOpts);
|
||||||
nSel++;
|
nSel++;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import PamController.PamSettings;
|
|||||||
import PamController.PamguardVersionInfo;
|
import PamController.PamguardVersionInfo;
|
||||||
import PamController.settings.output.xml.PamguardXMLWriter;
|
import PamController.settings.output.xml.PamguardXMLWriter;
|
||||||
import PamUtils.XMLUtils;
|
import PamUtils.XMLUtils;
|
||||||
|
import PamguardMVC.DataAutomationInfo;
|
||||||
import PamguardMVC.DataUnitBaseData;
|
import PamguardMVC.DataUnitBaseData;
|
||||||
import PamguardMVC.PamDataBlock;
|
import PamguardMVC.PamDataBlock;
|
||||||
import PamguardMVC.PamDataUnit;
|
import PamguardMVC.PamDataUnit;
|
||||||
@ -30,6 +31,7 @@ import nilus.Detection;
|
|||||||
import nilus.Detection.Parameters;
|
import nilus.Detection.Parameters;
|
||||||
import nilus.Detection.Parameters.UserDefined;
|
import nilus.Detection.Parameters.UserDefined;
|
||||||
import nilus.DetectionEffortKind;
|
import nilus.DetectionEffortKind;
|
||||||
|
import nilus.GranularityEnumType;
|
||||||
import nilus.Helper;
|
import nilus.Helper;
|
||||||
import nilus.SpeciesIDType;
|
import nilus.SpeciesIDType;
|
||||||
import tethys.TethysControl;
|
import tethys.TethysControl;
|
||||||
@ -90,11 +92,11 @@ public class AutoTethysProvider implements TethysDataProvider {
|
|||||||
return schema;
|
return schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public TethysDataPoint getDataPoint(PamDataUnit pamDataUnit) {
|
// public TethysDataPoint getDataPoint(PamDataUnit pamDataUnit) {
|
||||||
// TODO Auto-generated method stub
|
// // TODO Auto-generated method stub
|
||||||
return null;
|
// return null;
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DescriptionType getDescription(Deployment deployment, TethysExportParams tethysExportParams) {
|
public DescriptionType getDescription(Deployment deployment, TethysExportParams tethysExportParams) {
|
||||||
@ -488,4 +490,49 @@ public class AutoTethysProvider implements TethysDataProvider {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDetectionsMethod() {
|
||||||
|
/*
|
||||||
|
* could really do with knowing what type of detector we're dealing with, i.e. if it's
|
||||||
|
* automatic or manual. For most blocks this is fixed, though some may have a mixture of both !
|
||||||
|
*/
|
||||||
|
DataAutomationInfo dataAutomation = pamDataBlock.getDataAutomationInfo();
|
||||||
|
String method;
|
||||||
|
PamControlledUnit pcu = pamDataBlock.getParentProcess().getPamControlledUnit();
|
||||||
|
if (dataAutomation == null) {
|
||||||
|
method = String.format("Processing using the PAMGuard %s", pcu.getUnitType());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
method = String.format("%s processing using the PAMGuard %s", dataAutomation.getAutomation(), pcu.getUnitType());
|
||||||
|
}
|
||||||
|
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GranularityEnumType[] getAllowedGranularities() {
|
||||||
|
GranularityEnumType[] allowed = {GranularityEnumType.CALL, GranularityEnumType.BINNED, GranularityEnumType.ENCOUNTER};
|
||||||
|
return allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDetectionsName() {
|
||||||
|
PamProcess process = pamDataBlock.getParentProcess();
|
||||||
|
PamControlledUnit pcu = process.getPamControlledUnit();
|
||||||
|
String pcuName = pcu.getUnitName();
|
||||||
|
String blockName = pamDataBlock.getDataName();
|
||||||
|
String documentName;
|
||||||
|
/**
|
||||||
|
* If the datablock name is the same as the unit name, no need to repeat onesself.
|
||||||
|
*/
|
||||||
|
if (pcuName.equals(blockName)) {
|
||||||
|
documentName = new String(pcuName); // copy it, since we're about to modify it!
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
documentName = pcuName + " " + blockName;
|
||||||
|
}
|
||||||
|
documentName = documentName.replace(' ', '_');
|
||||||
|
return documentName;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import nilus.Deployment;
|
|||||||
import nilus.DescriptionType;
|
import nilus.DescriptionType;
|
||||||
import nilus.Detection;
|
import nilus.Detection;
|
||||||
import nilus.DetectionEffortKind;
|
import nilus.DetectionEffortKind;
|
||||||
|
import nilus.GranularityEnumType;
|
||||||
import tethys.niluswraps.PDeployment;
|
import tethys.niluswraps.PDeployment;
|
||||||
import tethys.output.StreamExportParams;
|
import tethys.output.StreamExportParams;
|
||||||
import tethys.output.TethysExportParams;
|
import tethys.output.TethysExportParams;
|
||||||
@ -38,8 +39,14 @@ public interface TethysDataProvider {
|
|||||||
* @param pamDataUnit
|
* @param pamDataUnit
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public TethysDataPoint getDataPoint(PamDataUnit pamDataUnit);
|
// public TethysDataPoint getDataPoint(PamDataUnit pamDataUnit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a standard Method string for each detector. This can be a bit
|
||||||
|
* verbose and might even have a reference to a paper ? Is this the best place for this ?
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getDetectionsMethod();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get DescriptionType object to include in a Tethys Detections document.
|
* Get DescriptionType object to include in a Tethys Detections document.
|
||||||
@ -56,6 +63,22 @@ public interface TethysDataProvider {
|
|||||||
*/
|
*/
|
||||||
public AlgorithmType getAlgorithm();
|
public AlgorithmType getAlgorithm();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of allowed granularity types for this output
|
||||||
|
* @return list of granularities.
|
||||||
|
*/
|
||||||
|
public GranularityEnumType[] getAllowedGranularities();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a name for the detections documents. This will be appended
|
||||||
|
* to the Deployment name and may also have a number after it. <br>
|
||||||
|
* Note that the name isn't really important since all the matching between
|
||||||
|
* different documents is done internally, but it helps to make everything
|
||||||
|
* human readable.
|
||||||
|
* @return A name, similar to datablock.getLongDataName(), but no spaces.
|
||||||
|
*/
|
||||||
|
public String getDetectionsName();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Tethys Detection object from a PamDataUnit.<br>
|
* Create a Tethys Detection object from a PamDataUnit.<br>
|
||||||
|
@ -17,6 +17,7 @@ import javax.swing.JTable;
|
|||||||
import javax.swing.border.TitledBorder;
|
import javax.swing.border.TitledBorder;
|
||||||
import javax.swing.table.AbstractTableModel;
|
import javax.swing.table.AbstractTableModel;
|
||||||
import javax.swing.table.JTableHeader;
|
import javax.swing.table.JTableHeader;
|
||||||
|
import javax.xml.datatype.XMLGregorianCalendar;
|
||||||
|
|
||||||
import PamView.PamGui;
|
import PamView.PamGui;
|
||||||
import PamView.dialog.warn.WarnOnce;
|
import PamView.dialog.warn.WarnOnce;
|
||||||
@ -97,10 +98,12 @@ public class DatablockDetectionsPanel extends TethysGUIPanel implements StreamTa
|
|||||||
case 1:
|
case 1:
|
||||||
return "Name of PAMGuard data stream";
|
return "Name of PAMGuard data stream";
|
||||||
case 2:
|
case 2:
|
||||||
return "Output granularity";
|
return "Effort period";
|
||||||
case 3:
|
case 3:
|
||||||
return "Number of detection elements in document";
|
return "Output granularity";
|
||||||
case 4:
|
case 4:
|
||||||
|
return "Number of detection elements in document";
|
||||||
|
case 5:
|
||||||
return "Document abstract";
|
return "Document abstract";
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -229,7 +232,7 @@ public class DatablockDetectionsPanel extends TethysGUIPanel implements StreamTa
|
|||||||
|
|
||||||
private class TableModel extends AbstractTableModel {
|
private class TableModel extends AbstractTableModel {
|
||||||
|
|
||||||
private String[] colNames = {"Document", "Detector", "Granularity", "Count", "Abstract"};
|
private String[] colNames = {"Document", "Detector", "Effort", "Granularity", "Count", "Abstract"};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRowCount() {
|
public int getRowCount() {
|
||||||
@ -272,6 +275,10 @@ public class DatablockDetectionsPanel extends TethysGUIPanel implements StreamTa
|
|||||||
}
|
}
|
||||||
return pDets.dataBlock.getDataName();
|
return pDets.dataBlock.getDataName();
|
||||||
case 2:
|
case 2:
|
||||||
|
XMLGregorianCalendar start = dets.getEffort().getStart();
|
||||||
|
XMLGregorianCalendar stop = dets.getEffort().getEnd();
|
||||||
|
return start + " to " + stop;
|
||||||
|
case 3:
|
||||||
List<DetectionEffortKind> kinds = dets.getEffort().getKind();
|
List<DetectionEffortKind> kinds = dets.getEffort().getKind();
|
||||||
if (kinds == null) {
|
if (kinds == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -286,9 +293,9 @@ public class DatablockDetectionsPanel extends TethysGUIPanel implements StreamTa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
|
||||||
return pDets.count;
|
|
||||||
case 4:
|
case 4:
|
||||||
|
return pDets.count;
|
||||||
|
case 5:
|
||||||
return dets.getDescription().getAbstract();
|
return dets.getDescription().getAbstract();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -156,7 +156,7 @@ public class DatablockSynchPanel extends TethysGUIPanel {
|
|||||||
|
|
||||||
private class SynchTableModel extends AbstractTableModel {
|
private class SynchTableModel extends AbstractTableModel {
|
||||||
|
|
||||||
String[] columnNames = {"Data Stream", "N PAM Datas", "PAMGuard Time", "Tethys Documents", "Tethys Time", "Options"};
|
String[] columnNames = {"Data Stream", "N PAM Datas", "PAMGuard Time", "Tethys Documents"};//, "Tethys Time", "Options"};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRowCount() {
|
public int getRowCount() {
|
||||||
|
@ -14,6 +14,7 @@ import javax.swing.JPanel;
|
|||||||
import javax.swing.JPopupMenu;
|
import javax.swing.JPopupMenu;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.ListSelectionModel;
|
||||||
import javax.swing.table.AbstractTableModel;
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
|
||||||
import PamController.PamController;
|
import PamController.PamController;
|
||||||
@ -58,6 +59,8 @@ public class TethysDocumentTable implements PamDialogPanel {
|
|||||||
new SwingTableColumnWidths(tethysControl.getUnitName()+"TethysDocumentsTable", mainTable);
|
new SwingTableColumnWidths(tethysControl.getUnitName()+"TethysDocumentsTable", mainTable);
|
||||||
this.setCollectionName(collectionName);
|
this.setCollectionName(collectionName);
|
||||||
mainTable.addMouseListener(new TableMouse());
|
mainTable.addMouseListener(new TableMouse());
|
||||||
|
mainTable.setRowSelectionAllowed(true);
|
||||||
|
mainTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateTableData() {
|
public void updateTableData() {
|
||||||
@ -94,6 +97,7 @@ public class TethysDocumentTable implements PamDialogPanel {
|
|||||||
if (row < 0|| row >= documentNames.size()) {
|
if (row < 0|| row >= documentNames.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String docName = documentNames.get(row);
|
String docName = documentNames.get(row);
|
||||||
JPopupMenu popMenu = new JPopupMenu();
|
JPopupMenu popMenu = new JPopupMenu();
|
||||||
JMenuItem menuItem = new JMenuItem("Show document " + docName);
|
JMenuItem menuItem = new JMenuItem("Show document " + docName);
|
||||||
@ -104,6 +108,11 @@ public class TethysDocumentTable implements PamDialogPanel {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
popMenu.add(menuItem);
|
popMenu.add(menuItem);
|
||||||
|
|
||||||
|
|
||||||
|
int[] rows = mainTable.getSelectedRows();
|
||||||
|
if (rows != null && rows.length == 1) {
|
||||||
|
// docName = documentNames.get(rows[0]);
|
||||||
menuItem = new JMenuItem("Delete document " + docName);
|
menuItem = new JMenuItem("Delete document " + docName);
|
||||||
menuItem.addActionListener(new ActionListener() {
|
menuItem.addActionListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -112,6 +121,18 @@ public class TethysDocumentTable implements PamDialogPanel {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
popMenu.add(menuItem);
|
popMenu.add(menuItem);
|
||||||
|
}
|
||||||
|
else if (rows != null && rows.length > 1) {
|
||||||
|
String mt = String.format("Delete multiple (%d) documents", rows.length);
|
||||||
|
menuItem = new JMenuItem(mt);
|
||||||
|
menuItem.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
deleteDocuments(rows);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
popMenu.add(menuItem);
|
||||||
|
}
|
||||||
|
|
||||||
popMenu.show(e.getComponent(), e.getX(), e.getY());
|
popMenu.show(e.getComponent(), e.getX(), e.getY());
|
||||||
}
|
}
|
||||||
@ -134,6 +155,32 @@ public class TethysDocumentTable implements PamDialogPanel {
|
|||||||
updateTableData();
|
updateTableData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void deleteDocuments(int[] rows) {
|
||||||
|
int ans = WarnOnce.showNamedWarning("deletedoc"+collectionName, PamController.getMainFrame(), "Delete documents",
|
||||||
|
"Are you sure you want to delete multiple documents ", WarnOnce.OK_CANCEL_OPTION);
|
||||||
|
if (ans != WarnOnce.OK_OPTION) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* make a new list before anything is deleted since the
|
||||||
|
* man list will get updated during deletion and be out of date.
|
||||||
|
*/
|
||||||
|
String[] docNames = new String[rows.length];
|
||||||
|
for (int i = 0; i < rows.length; i++) {
|
||||||
|
docNames[i] = documentNames.get(rows[i]);
|
||||||
|
}
|
||||||
|
// now it's safe to delete them.
|
||||||
|
for (int i = 0; i < docNames.length; i++) {
|
||||||
|
try {
|
||||||
|
tethysControl.getDbxmlConnect().removeDocument(collectionName, docNames[i]);
|
||||||
|
} catch (TethysException e) {
|
||||||
|
System.out.println("Failed to delete " + docNames[i]);
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateTableData();
|
||||||
|
}
|
||||||
|
|
||||||
private class TableModel extends AbstractTableModel {
|
private class TableModel extends AbstractTableModel {
|
||||||
|
|
||||||
private String[] columnNames = {"", "Document Id/Name"};
|
private String[] columnNames = {"", "Document Id/Name"};
|
||||||
|
@ -39,6 +39,13 @@ public class DescriptionTypePanel {
|
|||||||
|
|
||||||
private static final int ctrlWidth = 40;
|
private static final int ctrlWidth = 40;
|
||||||
|
|
||||||
|
public static final String objectivesTip = "What are the objectives of this effort? Examples:\r\n"
|
||||||
|
+ "Beamform to increase SNR for detection.\r\n"
|
||||||
|
+ "Detect every click of a rare species.\r\n"
|
||||||
|
+ "Verify data quality.";
|
||||||
|
public static final String abstractTip = "Overview of effort.";
|
||||||
|
public static final String methodTip = "High-level description of the method used.";
|
||||||
|
|
||||||
public DescriptionTypePanel(String bordertitle, boolean requireObjective, boolean requireAbstract, boolean requireMethod) {
|
public DescriptionTypePanel(String bordertitle, boolean requireObjective, boolean requireAbstract, boolean requireMethod) {
|
||||||
this.requireObjective = requireObjective;
|
this.requireObjective = requireObjective;
|
||||||
this.requireAbstract = requireAbstract;
|
this.requireAbstract = requireAbstract;
|
||||||
@ -51,6 +58,16 @@ public class DescriptionTypePanel {
|
|||||||
tObjectives = new JTextArea(12, ctrlWidth);
|
tObjectives = new JTextArea(12, ctrlWidth);
|
||||||
tAbstract = new JTextArea(8, ctrlWidth);
|
tAbstract = new JTextArea(8, ctrlWidth);
|
||||||
tMethod = new JTextArea(9, ctrlWidth);
|
tMethod = new JTextArea(9, ctrlWidth);
|
||||||
|
tObjectives.setLineWrap(true);
|
||||||
|
tObjectives.setWrapStyleWord(true);
|
||||||
|
tAbstract.setLineWrap(true);
|
||||||
|
tAbstract.setWrapStyleWord(true);
|
||||||
|
tMethod.setLineWrap(true);
|
||||||
|
tMethod.setWrapStyleWord(true);
|
||||||
|
|
||||||
|
tObjectives.setToolTipText(objectivesTip);
|
||||||
|
tAbstract.setToolTipText(abstractTip);
|
||||||
|
tMethod.setToolTipText(methodTip);
|
||||||
|
|
||||||
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
|
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
|
||||||
addScrollablePanel(tObjectives, "Objectives");
|
addScrollablePanel(tObjectives, "Objectives");
|
||||||
@ -78,6 +95,11 @@ public class DescriptionTypePanel {
|
|||||||
tAbstract.setText(null);
|
tAbstract.setText(null);
|
||||||
tMethod.setText(null);
|
tMethod.setText(null);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
tObjectives.setText(description.getObjectives());
|
||||||
|
tAbstract.setText(description.getAbstract());
|
||||||
|
tMethod.setText(description.getMethod());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getParams(PDescriptionType description) {
|
public boolean getParams(PDescriptionType description) {
|
||||||
|
@ -39,7 +39,7 @@ public class DetectionsExportWizard extends PamDialog {
|
|||||||
|
|
||||||
streamExportParams = tethysControl.getTethysExportParams().getStreamParams(dataBlock);
|
streamExportParams = tethysControl.getTethysExportParams().getStreamParams(dataBlock);
|
||||||
if (streamExportParams == null) {
|
if (streamExportParams == null) {
|
||||||
streamExportParams = new StreamExportParams(dataBlock.getLongDataName(), false);
|
streamExportParams = new StreamExportParams(tethysControl, dataBlock, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
cardLayout = new CardLayout();
|
cardLayout = new CardLayout();
|
||||||
|
@ -30,6 +30,7 @@ import nilus.GranularityEnumType;
|
|||||||
import tethys.TethysControl;
|
import tethys.TethysControl;
|
||||||
import tethys.niluswraps.PGranularityType;
|
import tethys.niluswraps.PGranularityType;
|
||||||
import tethys.output.StreamExportParams;
|
import tethys.output.StreamExportParams;
|
||||||
|
import tethys.pamdata.TethysDataProvider;
|
||||||
|
|
||||||
public class GranularityCard extends ExportWizardCard {
|
public class GranularityCard extends ExportWizardCard {
|
||||||
|
|
||||||
@ -37,7 +38,9 @@ public class GranularityCard extends ExportWizardCard {
|
|||||||
|
|
||||||
private JTextArea dataSelectionText;
|
private JTextArea dataSelectionText;
|
||||||
|
|
||||||
private JTextField binLength, minCalls, encounterGap;
|
private JTextField binLength, minBinnedCalls, encounterGap, minEncounterCalls;
|
||||||
|
|
||||||
|
private JRadioButton groupChannels, separateChannels;
|
||||||
|
|
||||||
private DataSelector dataSelector;
|
private DataSelector dataSelector;
|
||||||
|
|
||||||
@ -45,51 +48,68 @@ public class GranularityCard extends ExportWizardCard {
|
|||||||
|
|
||||||
private int encounterIndex, binnedIndex;
|
private int encounterIndex, binnedIndex;
|
||||||
|
|
||||||
|
private GranularityEnumType[] allowedGranularities;
|
||||||
|
|
||||||
public GranularityCard(DetectionsExportWizard detectionsExportWizard, TethysControl tethysControl, PamDataBlock dataBlock) {
|
public GranularityCard(DetectionsExportWizard detectionsExportWizard, TethysControl tethysControl, PamDataBlock dataBlock) {
|
||||||
super(tethysControl, "Granularity", dataBlock);
|
super(tethysControl, "Granularity", dataBlock);
|
||||||
this.detectionsExportWizard = detectionsExportWizard;
|
this.detectionsExportWizard = detectionsExportWizard;
|
||||||
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
|
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
|
||||||
|
|
||||||
|
TethysDataProvider tethysDataProvider = dataBlock.getTethysDataProvider(tethysControl);
|
||||||
// granularity
|
// granularity
|
||||||
GranularityEnumType[] grans = GranularityEnumType.values();
|
allowedGranularities = tethysDataProvider.getAllowedGranularities();
|
||||||
granularities = new JRadioButton[grans.length];
|
granularities = new JRadioButton[allowedGranularities.length];
|
||||||
JPanel granPanel = new WestAlignedPanel(new GridBagLayout());
|
JPanel granPanel = new WestAlignedPanel(new GridBagLayout());
|
||||||
GridBagConstraints c = new PamGridBagContraints();
|
GridBagConstraints c = new PamGridBagContraints();
|
||||||
granPanel.setBorder(new TitledBorder("Granularity"));
|
granPanel.setBorder(new TitledBorder("Granularity"));
|
||||||
ButtonGroup granGroup = new ButtonGroup();
|
ButtonGroup granGroup = new ButtonGroup();
|
||||||
GranularityChange gc = new GranularityChange();
|
GranularityChange gc = new GranularityChange();
|
||||||
for (int i = 0; i < grans.length; i++) {
|
for (int i = 0; i < allowedGranularities.length; i++) {
|
||||||
c.gridx = 0;
|
c.gridx = 0;
|
||||||
granularities[i] = new JRadioButton(PGranularityType.prettyString(grans[i]));
|
granularities[i] = new JRadioButton(PGranularityType.prettyString(allowedGranularities[i]));
|
||||||
granularities[i].setToolTipText(PGranularityType.toolTip(grans[i]));
|
granularities[i].setToolTipText(PGranularityType.toolTip(allowedGranularities[i]));
|
||||||
granularities[i].addActionListener(gc);
|
granularities[i].addActionListener(gc);
|
||||||
granPanel.add(granularities[i], c);
|
granPanel.add(granularities[i], c);
|
||||||
granGroup.add(granularities[i]);
|
granGroup.add(granularities[i]);
|
||||||
if (grans[i] == GranularityEnumType.BINNED) {
|
if (allowedGranularities[i] == GranularityEnumType.BINNED) {
|
||||||
binnedIndex = i;
|
binnedIndex = i;
|
||||||
c.gridx++;
|
c.gridx++;
|
||||||
granPanel.add(new JLabel(" bin duration ", JLabel.RIGHT), c);
|
granPanel.add(new JLabel(" Bin duration ", JLabel.RIGHT), c);
|
||||||
c.gridx++;
|
c.gridx++;
|
||||||
granPanel.add(binLength = new JTextField(5), c);
|
granPanel.add(binLength = new JTextField(5), c);
|
||||||
c.gridx++;
|
c.gridx++;
|
||||||
granPanel.add(new JLabel("(s), min Calls", JLabel.LEFT), c);
|
granPanel.add(new JLabel("(s), Min Calls", JLabel.LEFT), c);
|
||||||
c.gridx++;
|
c.gridx++;
|
||||||
granPanel.add(minCalls = new JTextField(5), c);
|
granPanel.add(minBinnedCalls = new JTextField(5), c);
|
||||||
binLength.setToolTipText("Time bin duration in seconds");
|
binLength.setToolTipText("Time bin duration in seconds");
|
||||||
minCalls.setToolTipText("Minimum number of calls for a bin to be output");
|
minBinnedCalls.setToolTipText("Minimum number of calls for a bin to be output");
|
||||||
}
|
}
|
||||||
if (grans[i] == GranularityEnumType.ENCOUNTER) {
|
if (allowedGranularities[i] == GranularityEnumType.ENCOUNTER) {
|
||||||
encounterIndex = i;
|
encounterIndex = i;
|
||||||
c.gridx++;
|
c.gridx++;
|
||||||
granPanel.add(new JLabel(" min gap ", JLabel.RIGHT), c);
|
granPanel.add(new JLabel(" Minimum gap ", JLabel.RIGHT), c);
|
||||||
c.gridx++;
|
c.gridx++;
|
||||||
granPanel.add(encounterGap = new JTextField(5), c);
|
granPanel.add(encounterGap = new JTextField(5), c);
|
||||||
c.gridx++;
|
c.gridx++;
|
||||||
granPanel.add(new JLabel("(s) ", JLabel.LEFT), c);
|
granPanel.add(new JLabel("(s), Min Calls", JLabel.LEFT), c);
|
||||||
|
c.gridx++;
|
||||||
|
granPanel.add(minEncounterCalls = new JTextField(5), c);
|
||||||
encounterGap.setToolTipText("Minimum gap between separate encounters");
|
encounterGap.setToolTipText("Minimum gap between separate encounters");
|
||||||
|
minEncounterCalls.setToolTipText("Minimum number of calls for an encounter to be output");
|
||||||
}
|
}
|
||||||
c.gridy++;
|
c.gridy++;
|
||||||
}
|
}
|
||||||
|
c.gridx = 1;
|
||||||
|
c.gridwidth = 2;
|
||||||
|
granPanel.add(separateChannels = new JRadioButton("Separate channels"), c);
|
||||||
|
c.gridx += c.gridwidth;
|
||||||
|
granPanel.add(groupChannels = new JRadioButton("Group channels"), c);
|
||||||
|
separateChannels.setToolTipText("Use separate bins/encounters for each detection channel");
|
||||||
|
groupChannels.setToolTipText("Combine detections from different channels into the same bins/encounters");
|
||||||
|
ButtonGroup chanGroup = new ButtonGroup();
|
||||||
|
chanGroup.add(separateChannels);
|
||||||
|
chanGroup.add(groupChannels);
|
||||||
|
|
||||||
this.add(granPanel);
|
this.add(granPanel);
|
||||||
|
|
||||||
// data selection
|
// data selection
|
||||||
@ -127,8 +147,12 @@ public class GranularityCard extends ExportWizardCard {
|
|||||||
|
|
||||||
private void enableControls() {
|
private void enableControls() {
|
||||||
binLength.setEnabled(granularities[binnedIndex].isSelected());
|
binLength.setEnabled(granularities[binnedIndex].isSelected());
|
||||||
minCalls.setEnabled(granularities[binnedIndex].isSelected());
|
minBinnedCalls.setEnabled(granularities[binnedIndex].isSelected());
|
||||||
encounterGap.setEnabled(granularities[encounterIndex].isSelected());
|
encounterGap.setEnabled(granularities[encounterIndex].isSelected());
|
||||||
|
minEncounterCalls.setEnabled(granularities[encounterIndex].isSelected());
|
||||||
|
boolean binOrencount = granularities[binnedIndex].isSelected() | granularities[encounterIndex].isSelected();
|
||||||
|
separateChannels.setEnabled(binOrencount);
|
||||||
|
groupChannels.setEnabled(binOrencount);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void newDataSelection() {
|
protected void newDataSelection() {
|
||||||
@ -149,10 +173,9 @@ public class GranularityCard extends ExportWizardCard {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getParams(StreamExportParams streamExportParams) {
|
public boolean getParams(StreamExportParams streamExportParams) {
|
||||||
GranularityEnumType[] grans = GranularityEnumType.values();
|
for (int i = 0; i < allowedGranularities.length; i++) {
|
||||||
for (int i = 0; i < grans.length; i++) {
|
|
||||||
if (granularities[i].isSelected()) {
|
if (granularities[i].isSelected()) {
|
||||||
streamExportParams.granularity = grans[i];
|
streamExportParams.granularity = allowedGranularities[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,10 +187,10 @@ public class GranularityCard extends ExportWizardCard {
|
|||||||
return detectionsExportWizard.showWarning("Invalid bin duration parameter");
|
return detectionsExportWizard.showWarning("Invalid bin duration parameter");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
streamExportParams.minBinCount = Integer.valueOf(minCalls.getText());
|
streamExportParams.minBinCount = Integer.valueOf(minBinnedCalls.getText());
|
||||||
}
|
}
|
||||||
catch (NumberFormatException e) {
|
catch (NumberFormatException e) {
|
||||||
return detectionsExportWizard.showWarning("Invalid minimum call count");
|
return detectionsExportWizard.showWarning("Invalid minimum binned call count");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (streamExportParams.granularity == GranularityEnumType.ENCOUNTER) {
|
if (streamExportParams.granularity == GranularityEnumType.ENCOUNTER) {
|
||||||
@ -177,20 +200,30 @@ public class GranularityCard extends ExportWizardCard {
|
|||||||
catch (NumberFormatException e) {
|
catch (NumberFormatException e) {
|
||||||
return detectionsExportWizard.showWarning("Invalid encounter gap parameter");
|
return detectionsExportWizard.showWarning("Invalid encounter gap parameter");
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
streamExportParams.minEncounterCount = Integer.valueOf(minEncounterCalls.getText());
|
||||||
}
|
}
|
||||||
|
catch (NumberFormatException e) {
|
||||||
|
return detectionsExportWizard.showWarning("Invalid minimum encounter call count");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
streamExportParams.separateChannels = separateChannels.isSelected();
|
||||||
|
|
||||||
return streamExportParams.granularity != null;
|
return streamExportParams.granularity != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setParams(StreamExportParams streamExportParams) {
|
public void setParams(StreamExportParams streamExportParams) {
|
||||||
GranularityEnumType[] grans = GranularityEnumType.values();
|
for (int i = 0; i < granularities.length; i++) {
|
||||||
for (int i = 0; i < grans.length; i++) {
|
granularities[i].setSelected(streamExportParams.granularity == allowedGranularities[i]);
|
||||||
granularities[i].setSelected(streamExportParams.granularity == grans[i]);
|
|
||||||
}
|
}
|
||||||
binLength.setText(String.format("%3.1f", streamExportParams.binDurationS));
|
binLength.setText(String.format("%3.1f", streamExportParams.binDurationS));
|
||||||
minCalls.setText(String.format("%d", streamExportParams.minBinCount));
|
minBinnedCalls.setText(String.format("%d", streamExportParams.minBinCount));
|
||||||
encounterGap.setText(String.format("%3.1f", streamExportParams.encounterGapS));
|
encounterGap.setText(String.format("%3.1f", streamExportParams.encounterGapS));
|
||||||
|
minEncounterCalls.setText(String.format("%d", streamExportParams.minEncounterCount));
|
||||||
|
separateChannels.setSelected(streamExportParams.separateChannels);
|
||||||
|
groupChannels.setSelected(streamExportParams.separateChannels == false);
|
||||||
newDataSelection();
|
newDataSelection();
|
||||||
enableControls();
|
enableControls();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user