mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2024-11-22 15:12:28 +00:00
More detection work
This commit is contained in:
parent
4876899b54
commit
27b8456c5a
@ -16,5 +16,10 @@ abstract public class MovingHydrophoneLocator extends SimpleHydrophoneLocator {
|
|||||||
super(pamArray, streamer);
|
super(pamArray, streamer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChangeable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -464,7 +464,7 @@ final public class PamModel implements PamModelInterface, PamSettings {
|
|||||||
|
|
||||||
|
|
||||||
mi = PamModuleInfo.registerControlledUnit(MetaDataContol.class.getName(), MetaDataContol.unitType);
|
mi = PamModuleInfo.registerControlledUnit(MetaDataContol.class.getName(), MetaDataContol.unitType);
|
||||||
mi.setToolTipText("Deployment Meta Data");
|
mi.setToolTipText("Project Meta Data");
|
||||||
mi.setModulesMenuGroup(utilitiesGroup);
|
mi.setModulesMenuGroup(utilitiesGroup);
|
||||||
mi.setMaxNumber(1);
|
mi.setMaxNumber(1);
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ public class RWEBinaryDataSource extends BinaryDataSource {
|
|||||||
binaryObjectData.getDataUnitBaseData().setSampleDuration(duration);
|
binaryObjectData.getDataUnitBaseData().setSampleDuration(duration);
|
||||||
// rweDataUnit = new RWEDataUnit(aSound.timeMilliseconds, channelMap,
|
// rweDataUnit = new RWEDataUnit(aSound.timeMilliseconds, channelMap,
|
||||||
// startSample, duration, aSound);
|
// startSample, duration, aSound);
|
||||||
rweDataUnit = new RWEDataUnit(binaryObjectData.getDataUnitBaseData(), aSound);
|
rweDataUnit = new RWEDataUnit(rweProcess, binaryObjectData.getDataUnitBaseData(), aSound);
|
||||||
rweDataUnit.setSequenceBitmap(sequenceMap);
|
rweDataUnit.setSequenceBitmap(sequenceMap);
|
||||||
double f[] = new double[2];
|
double f[] = new double[2];
|
||||||
f[0] = aSound.minFreq * rweDataBlock.getSampleRate()/rweDataBlock.getFftLength();
|
f[0] = aSound.minFreq * rweDataBlock.getSampleRate()/rweDataBlock.getFftLength();
|
||||||
|
@ -6,26 +6,31 @@ import whistlesAndMoans.AbstractWhistleDataUnit;
|
|||||||
public class RWEDataUnit extends AbstractWhistleDataUnit {
|
public class RWEDataUnit extends AbstractWhistleDataUnit {
|
||||||
|
|
||||||
public RWESound rweSound;
|
public RWESound rweSound;
|
||||||
|
private RWEProcess rweProcess;
|
||||||
|
|
||||||
public RWEDataUnit(long timeMilliseconds, int channelBitmap,
|
public RWEDataUnit(RWEProcess rweProcess, long timeMilliseconds, int channelBitmap,
|
||||||
long startSample, long duration, RWESound rweSound) {
|
long startSample, long duration, RWESound rweSound) {
|
||||||
super(timeMilliseconds, channelBitmap, startSample, duration);
|
super(timeMilliseconds, channelBitmap, startSample, duration);
|
||||||
this.rweSound = rweSound;
|
this.rweSound = rweSound;
|
||||||
|
this.rweProcess = rweProcess;
|
||||||
// TODO Auto-generated constructor stub
|
// TODO Auto-generated constructor stub
|
||||||
}
|
}
|
||||||
|
|
||||||
public RWEDataUnit(DataUnitBaseData basicData, RWESound rweSound) {
|
public RWEDataUnit(RWEProcess rweProcess, DataUnitBaseData basicData, RWESound rweSound) {
|
||||||
super(basicData);
|
super(basicData);
|
||||||
this.rweSound = rweSound;
|
this.rweSound = rweSound;
|
||||||
|
this.rweProcess = rweProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
double[] freqsHz;
|
|
||||||
@Override
|
@Override
|
||||||
public double[] getFreqsHz() {
|
public double[] getFreqsHz() {
|
||||||
if (freqsHz == null) {
|
double[] f = new double[rweSound.sliceCount];
|
||||||
freqsHz = new double[rweSound.sliceCount];
|
RWEDataBlock rweDataBlock = rweProcess.getRweDataBlock();
|
||||||
|
double binToHz = rweDataBlock.getSampleRate() / rweDataBlock.getFftLength();
|
||||||
|
for (int i = 0; i < f.length; i++) {
|
||||||
|
f[i] = (double) rweSound.peakFreq[i] * binToHz;
|
||||||
}
|
}
|
||||||
return null;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -35,8 +40,16 @@ public class RWEDataUnit extends AbstractWhistleDataUnit {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double[] getTimesInSeconds() {
|
public double[] getTimesInSeconds() {
|
||||||
// TODO Auto-generated method stub
|
if (rweSound == null) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
double[] t = new double[rweSound.sliceCount];
|
||||||
|
RWEDataBlock rweDataBlock = rweProcess.getRweDataBlock();
|
||||||
|
double binToT = rweDataBlock.getFftHop() / rweDataBlock.getSampleRate();
|
||||||
|
for (int i = 0; i < t.length; i++) {
|
||||||
|
t[i] = (double) rweSound.sliceList[i] * binToT;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -42,6 +42,10 @@ public class RWEProcess extends PamProcess {
|
|||||||
private FFTDataBlock sourceDataBlock;
|
private FFTDataBlock sourceDataBlock;
|
||||||
private RWEDataBlock rweDataBlock;
|
private RWEDataBlock rweDataBlock;
|
||||||
|
|
||||||
|
public RWEDataBlock getRweDataBlock() {
|
||||||
|
return rweDataBlock;
|
||||||
|
}
|
||||||
|
|
||||||
private Hashtable<Integer, BearingLocaliser> bearingLocalisers;
|
private Hashtable<Integer, BearingLocaliser> bearingLocalisers;
|
||||||
private StandardSymbolManager symbolManager;
|
private StandardSymbolManager symbolManager;
|
||||||
/**
|
/**
|
||||||
@ -211,7 +215,7 @@ public class RWEProcess extends PamProcess {
|
|||||||
// System.out.println(String.format("Detected sound type %d on channel %d",
|
// System.out.println(String.format("Detected sound type %d on channel %d",
|
||||||
// soundType, this.iChannel));
|
// soundType, this.iChannel));
|
||||||
duration = sourceDataBlock.getFftHop() * aSound.duration;
|
duration = sourceDataBlock.getFftHop() * aSound.duration;
|
||||||
rweDataUnit = new RWEDataUnit(aSound.timeMilliseconds,
|
rweDataUnit = new RWEDataUnit(RWEProcess.this, aSound.timeMilliseconds,
|
||||||
1<<iChannel, fftDataUnit.getStartSample()-duration, duration, aSound);
|
1<<iChannel, fftDataUnit.getStartSample()-duration, duration, aSound);
|
||||||
rweDataUnit.sortOutputMaps(sourceDataBlock.getChannelMap(), sourceDataBlock.getSequenceMapObject(), 1<<iChannel);
|
rweDataUnit.sortOutputMaps(sourceDataBlock.getChannelMap(), sourceDataBlock.getSequenceMapObject(), 1<<iChannel);
|
||||||
f[0] = aSound.minFreq * getSampleRate()/sourceDataBlock.getFftLength();
|
f[0] = aSound.minFreq * getSampleRate()/sourceDataBlock.getFftLength();
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package tethys.deployment;
|
package tethys.deployment;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -16,23 +15,26 @@ import Acquisition.DaqStatusDataUnit;
|
|||||||
import Acquisition.DaqSystem;
|
import Acquisition.DaqSystem;
|
||||||
import Array.ArrayManager;
|
import Array.ArrayManager;
|
||||||
import Array.Hydrophone;
|
import Array.Hydrophone;
|
||||||
|
import Array.HydrophoneLocator;
|
||||||
import Array.PamArray;
|
import Array.PamArray;
|
||||||
|
import Array.Streamer;
|
||||||
|
import Array.ThreadingHydrophoneLocator;
|
||||||
import PamController.PamControlledUnit;
|
import PamController.PamControlledUnit;
|
||||||
import PamController.PamController;
|
import PamController.PamController;
|
||||||
import PamUtils.PamCalendar;
|
|
||||||
import PamUtils.PamUtils;
|
|
||||||
import PamguardMVC.PamDataBlock;
|
import PamguardMVC.PamDataBlock;
|
||||||
|
import metadata.MetaDataContol;
|
||||||
|
import metadata.deployment.DeploymentData;
|
||||||
import nilus.Audio;
|
import nilus.Audio;
|
||||||
import nilus.ChannelInfo;
|
import nilus.ChannelInfo;
|
||||||
import nilus.ChannelInfo.Sampling;
|
import nilus.ChannelInfo.Sampling;
|
||||||
import nilus.ChannelInfo.Sampling.Regimen;
|
import nilus.ChannelInfo.Sampling.Regimen;
|
||||||
import nilus.Deployment;
|
import nilus.Deployment;
|
||||||
|
import nilus.Deployment.Instrument;
|
||||||
import nilus.Deployment.SamplingDetails;
|
import nilus.Deployment.SamplingDetails;
|
||||||
import nilus.Deployment.Sensors;
|
import nilus.Deployment.Sensors;
|
||||||
import nilus.DeploymentRecoveryDetails;
|
import nilus.DeploymentRecoveryDetails;
|
||||||
import nilus.GeometryTypeM;
|
import nilus.GeometryTypeM;
|
||||||
import nilus.Helper;
|
import nilus.Helper;
|
||||||
import nilus.MarshalXML;
|
|
||||||
import pamMaths.PamVector;
|
import pamMaths.PamVector;
|
||||||
import tethys.TethysLocationFuncs;
|
import tethys.TethysLocationFuncs;
|
||||||
import tethys.TethysTimeFuncs;
|
import tethys.TethysTimeFuncs;
|
||||||
@ -52,7 +54,7 @@ public class DeploymentHandler {
|
|||||||
public DeploymentOverview createOverview() {
|
public DeploymentOverview createOverview() {
|
||||||
// first find an acquisition module.
|
// first find an acquisition module.
|
||||||
PamControlledUnit aModule = PamController.getInstance().findControlledUnit(AcquisitionControl.class, null);
|
PamControlledUnit aModule = PamController.getInstance().findControlledUnit(AcquisitionControl.class, null);
|
||||||
if (aModule instanceof AcquisitionControl == false) {
|
if (!(aModule instanceof AcquisitionControl)) {
|
||||||
// will return if it's null. Impossible for it to be the wrong type.
|
// will return if it's null. Impossible for it to be the wrong type.
|
||||||
// but it's good practice to check anyway before casting.
|
// but it's good practice to check anyway before casting.
|
||||||
return null;
|
return null;
|
||||||
@ -192,7 +194,7 @@ public class DeploymentHandler {
|
|||||||
|
|
||||||
// first find an acquisition module.
|
// first find an acquisition module.
|
||||||
PamControlledUnit aModule = PamController.getInstance().findControlledUnit(AcquisitionControl.class, null);
|
PamControlledUnit aModule = PamController.getInstance().findControlledUnit(AcquisitionControl.class, null);
|
||||||
if (aModule instanceof AcquisitionControl == false) {
|
if (!(aModule instanceof AcquisitionControl)) {
|
||||||
// will return if it's null. Impossible for it to be the wrong type.
|
// will return if it's null. Impossible for it to be the wrong type.
|
||||||
// but it's good practice to check anyway before casting.
|
// but it's good practice to check anyway before casting.
|
||||||
return null;
|
return null;
|
||||||
@ -289,6 +291,8 @@ public class DeploymentHandler {
|
|||||||
|
|
||||||
TethysLocationFuncs.getTrackAndPositionData(deployment);
|
TethysLocationFuncs.getTrackAndPositionData(deployment);
|
||||||
|
|
||||||
|
getProjectData(deployment);
|
||||||
|
|
||||||
getSamplingDetails(deployment);
|
getSamplingDetails(deployment);
|
||||||
|
|
||||||
getSensorDetails(deployment);
|
getSensorDetails(deployment);
|
||||||
@ -305,6 +309,58 @@ public class DeploymentHandler {
|
|||||||
return deployment;
|
return deployment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add project Metadata to a Deploymnet document. This is currently being
|
||||||
|
* made available in the MetaDataControl module which should be added to PAMGuard
|
||||||
|
* as well as the Tethys output module.
|
||||||
|
* @param deployment
|
||||||
|
*/
|
||||||
|
private boolean getProjectData(Deployment deployment) {
|
||||||
|
PamControlledUnit aUnit = PamController.getInstance().findControlledUnit(MetaDataContol.class, null);
|
||||||
|
if (aUnit instanceof MetaDataContol == false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
MetaDataContol metaControl = (MetaDataContol) aUnit;
|
||||||
|
DeploymentData deploymentData = metaControl.getDeploymentData();
|
||||||
|
deployment.setProject(deploymentData.getProject());
|
||||||
|
deployment.setDeploymentAlias(deploymentData.getDeploymentAlias());
|
||||||
|
deployment.setSite(deploymentData.getSite());
|
||||||
|
deployment.setCruise(deploymentData.getCruise());
|
||||||
|
deployment.setPlatform(deploymentData.getPlatform());
|
||||||
|
deployment.setRegion(deploymentData.getRegion());
|
||||||
|
Instrument instrument = new Instrument();
|
||||||
|
instrument.setType(deploymentData.getInstrumentType());
|
||||||
|
instrument.setInstrumentId(deploymentData.getInstrumentId());
|
||||||
|
// get the geometry type from the array manager.
|
||||||
|
String geomType = getGeometryType();
|
||||||
|
instrument.setGeometryType(geomType);
|
||||||
|
deployment.setInstrument(instrument);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a geometry type string for Tethys based on information in the array manager.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getGeometryType() {
|
||||||
|
PamArray array = ArrayManager.getArrayManager().getCurrentArray();
|
||||||
|
int nStreamer = array.getStreamerCount();
|
||||||
|
for (int i = 0; i < nStreamer; i++) {
|
||||||
|
Streamer streamer = array.getStreamer(i);
|
||||||
|
HydrophoneLocator locator = streamer.getHydrophoneLocator();
|
||||||
|
if (locator == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (locator instanceof ThreadingHydrophoneLocator) {
|
||||||
|
return "cabled";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "rigid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
private boolean getSensorDetails(Deployment deployment) {
|
private boolean getSensorDetails(Deployment deployment) {
|
||||||
PamArray array = ArrayManager.getArrayManager().getCurrentArray();
|
PamArray array = ArrayManager.getArrayManager().getCurrentArray();
|
||||||
Sensors sensors = new Sensors();
|
Sensors sensors = new Sensors();
|
||||||
@ -385,7 +441,7 @@ public class DeploymentHandler {
|
|||||||
channelInfo.setEnd(deployment.getRecoveryDetails().getAudioTimeStamp());
|
channelInfo.setEnd(deployment.getRecoveryDetails().getAudioTimeStamp());
|
||||||
|
|
||||||
BigIntegerConverter biCon = new BigIntegerConverter();
|
BigIntegerConverter biCon = new BigIntegerConverter();
|
||||||
BigInteger chanNum = BigInteger.valueOf((long) i);
|
BigInteger chanNum = BigInteger.valueOf(i);
|
||||||
channelInfo.setChannelNumber(chanNum);
|
channelInfo.setChannelNumber(chanNum);
|
||||||
if (hydroMap != null) {
|
if (hydroMap != null) {
|
||||||
channelInfo.setSensorNumber(hydroMap[i]);
|
channelInfo.setSensorNumber(hydroMap[i]);
|
||||||
|
@ -13,9 +13,12 @@ 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.DataUnitBaseData;
|
||||||
import PamguardMVC.PamDataBlock;
|
import PamguardMVC.PamDataBlock;
|
||||||
import PamguardMVC.PamDataUnit;
|
import PamguardMVC.PamDataUnit;
|
||||||
import PamguardMVC.PamProcess;
|
import PamguardMVC.PamProcess;
|
||||||
|
import PamguardMVC.TFContourData;
|
||||||
|
import PamguardMVC.TFContourProvider;
|
||||||
import generalDatabase.DBSchemaWriter;
|
import generalDatabase.DBSchemaWriter;
|
||||||
import generalDatabase.SQLLogging;
|
import generalDatabase.SQLLogging;
|
||||||
import nilus.AlgorithmType;
|
import nilus.AlgorithmType;
|
||||||
@ -27,6 +30,7 @@ import nilus.SpeciesIDType;
|
|||||||
import tethys.TethysTimeFuncs;
|
import tethys.TethysTimeFuncs;
|
||||||
import tethys.output.StreamExportParams;
|
import tethys.output.StreamExportParams;
|
||||||
import tethys.output.TethysExportParams;
|
import tethys.output.TethysExportParams;
|
||||||
|
import whistleClassifier.WhistleContour;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatically provides Tethys data based on the SQL database interface
|
* Automatically provides Tethys data based on the SQL database interface
|
||||||
@ -182,9 +186,64 @@ public class AutoTethysProvider implements TethysDataProvider {
|
|||||||
*/
|
*/
|
||||||
detection.setChannel(BigInteger.valueOf(dataUnit.getChannelBitmap()));
|
detection.setChannel(BigInteger.valueOf(dataUnit.getChannelBitmap()));
|
||||||
|
|
||||||
|
nilus.Detection.Parameters detParams = new nilus.Detection.Parameters();
|
||||||
|
detection.setParameters(detParams);
|
||||||
|
double[] freqs = dataUnit.getFrequency();
|
||||||
|
if (freqs != null) {
|
||||||
|
detParams.setMinFreqHz(freqs[0]);
|
||||||
|
detParams.setMaxFreqHz(freqs[1]);
|
||||||
|
}
|
||||||
|
double ampli = dataUnit.getAmplitudeDB();
|
||||||
|
detParams.setReceivedLevelDB(ampli);
|
||||||
|
// DataUnitBaseData basicData = dataUnit.getBasicData();
|
||||||
|
gotTonalContour(dataUnit, detParams);
|
||||||
|
|
||||||
return detection;
|
return detection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get tonal sounds contour. Sadly there are two slightly different interfaces in use
|
||||||
|
* in PAMGuard, so try them both.
|
||||||
|
* @param detParams
|
||||||
|
* @return true if a contour was added
|
||||||
|
*/
|
||||||
|
private boolean gotTonalContour(PamDataUnit dataUnit, nilus.Detection.Parameters detParams) {
|
||||||
|
if (dataUnit instanceof TFContourProvider) {
|
||||||
|
TFContourProvider tfcp = (TFContourProvider) dataUnit;
|
||||||
|
TFContourData cd = tfcp.getTFContourData();
|
||||||
|
if (cd != null) {
|
||||||
|
long[] tMillis = cd.getContourTimes();
|
||||||
|
double[] fHz = cd.getRidgeFrequency();
|
||||||
|
nilus.Detection.Parameters.Tonal tonal = new nilus.Detection.Parameters.Tonal();
|
||||||
|
List<Double> offsetS = tonal.getOffsetS();
|
||||||
|
List<Double> hz = tonal.getHz();
|
||||||
|
for (int i = 0; i < tMillis.length; i++) {
|
||||||
|
offsetS.add((double) (tMillis[i]-tMillis[0]) / 1000.);
|
||||||
|
hz.add(fHz[i]);
|
||||||
|
}
|
||||||
|
detParams.setTonal(tonal);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dataUnit instanceof WhistleContour) {
|
||||||
|
WhistleContour wc = (WhistleContour) dataUnit;
|
||||||
|
double[] t = wc.getTimesInSeconds();
|
||||||
|
double[] f = wc.getFreqsHz();
|
||||||
|
if (t != null && f != null) {
|
||||||
|
nilus.Detection.Parameters.Tonal tonal = new nilus.Detection.Parameters.Tonal();
|
||||||
|
List<Double> offsetS = tonal.getOffsetS();
|
||||||
|
List<Double> hz = tonal.getHz();
|
||||||
|
for (int i = 0; i < t.length; i++) {
|
||||||
|
offsetS.add(t[i]-t[0]);
|
||||||
|
hz.add(f[i]);
|
||||||
|
}
|
||||||
|
detParams.setTonal(tonal);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private SpeciesIDType getSpeciesIdType() {
|
private SpeciesIDType getSpeciesIdType() {
|
||||||
SpeciesIDType species = new SpeciesIDType();
|
SpeciesIDType species = new SpeciesIDType();
|
||||||
// species.s
|
// species.s
|
||||||
|
@ -7,9 +7,8 @@ import PamguardMVC.DataUnitBaseData;
|
|||||||
import PamguardMVC.PamDataUnit;
|
import PamguardMVC.PamDataUnit;
|
||||||
import PamguardMVC.TFContourProvider;;
|
import PamguardMVC.TFContourProvider;;
|
||||||
|
|
||||||
public abstract class AbstractWhistleDataUnit
|
public abstract class AbstractWhistleDataUnit extends PamDataUnit<PamDataUnit, PamDataUnit>
|
||||||
extends PamDataUnit<PamDataUnit, PamDataUnit>
|
implements WhistleContour, PamDetection {
|
||||||
implements WhistleContour, PamDetection{
|
|
||||||
|
|
||||||
public AbstractWhistleDataUnit(long timeMilliseconds, int channelBitmap,
|
public AbstractWhistleDataUnit(long timeMilliseconds, int channelBitmap,
|
||||||
long startSample, long duration) {
|
long startSample, long duration) {
|
||||||
|
Loading…
Reference in New Issue
Block a user