Fix bug in Click Detector target motion analysis

Was crashing if not all click in event were loaded.
This commit is contained in:
Douglas Gillespie 2023-01-20 11:57:57 +00:00
parent 269398890e
commit b5cf955cba
8 changed files with 120 additions and 38 deletions

View File

@ -159,22 +159,21 @@ public class TMGroupLocInfo implements GroupLocInfo {
private void copySubDetections(SuperDetection parentDataUnit, DetectionGroupOptions detectionGroupOptions) { private void copySubDetections(SuperDetection parentDataUnit, DetectionGroupOptions detectionGroupOptions) {
synchronized (parentDataUnit.getSubDetectionSyncronisation()) { ArrayList<PamDataUnit> subDets = parentDataUnit.getSubDetections();
int totalUnits = parentDataUnit.getSubDetectionsCount(); int totalUnits = subDets.size();
int keptUnits = totalUnits; int keptUnits = totalUnits;
if (detectionGroupOptions != null) { if (detectionGroupOptions != null) {
if (detectionGroupOptions.getMaxLocalisationPoints() == 0 || if (detectionGroupOptions.getMaxLocalisationPoints() == 0 ||
detectionGroupOptions.getMaxLocalisationPoints() < parentDataUnit.getSubDetectionsCount()) { detectionGroupOptions.getMaxLocalisationPoints() < parentDataUnit.getSubDetectionsCount()) {
keptUnits = detectionGroupOptions.getMaxLocalisationPoints(); keptUnits = detectionGroupOptions.getMaxLocalisationPoints();
}
}
subDetectionList = new Vector<>(keptUnits);
float keepRat = (float) (totalUnits-1) / (float) (keptUnits-1);
for (int i = 0; i < keptUnits; i++) {
int unitIndex = Math.round(i*keepRat);
subDetectionList.add(parentDataUnit.getSubDetection(unitIndex));
} }
} }
subDetectionList = new Vector<>(keptUnits);
float keepRat = (float) (totalUnits-1) / (float) (keptUnits-1);
for (int i = 0; i < keptUnits; i++) {
int unitIndex = Math.round(i*keepRat);
subDetectionList.add(subDets.get(unitIndex));
}
} }
@ -454,7 +453,7 @@ public class TMGroupLocInfo implements GroupLocInfo {
* The real word vectors are relative to the earth surface. Thus they are the bearings vectors * The real word vectors are relative to the earth surface. Thus they are the bearings vectors
* from an array, rotated by the true heading, pitch and roll of the array. * from an array, rotated by the true heading, pitch and roll of the array.
*/ */
protected void calculateWorldVectors() { protected void calculateWorldVectors() {
int nSubDetections=getDetectionCount(); int nSubDetections=getDetectionCount();
rawRealWorldVectors = new PamVector[nSubDetections][]; rawRealWorldVectors = new PamVector[nSubDetections][];
PamVector[] v; PamVector[] v;

View File

@ -368,7 +368,7 @@ public class SuperDetDataBlock<Tunit extends SuperDetection, TSubDet extends Pam
} }
if (!found) { if (!found) {
superDet = null; superDet = null;
System.out.printf("Can't find data unit id %d, UID %d in %s\n", superID, superUID, getDataName()); Debug.out.printf("Can't find data unit id %d, UID %d in %s\n", superID, superUID, getDataName());
} }
} }
if (superDet == null) { if (superDet == null) {
@ -448,6 +448,9 @@ public class SuperDetDataBlock<Tunit extends SuperDetection, TSubDet extends Pam
int iDone = 0; int iDone = 0;
while (duIt.hasNext()) { while (duIt.hasNext()) {
Tunit aData = duIt.next(); // looping through superdetections. Tunit aData = duIt.next(); // looping through superdetections.
// if (aData.getDatabaseIndex() == 131) {
// System.out.println("On event 131");
// }
if (viewLoadObserver != null) { if (viewLoadObserver != null) {
viewLoadObserver.sayProgress(1, aData.getTimeMilliseconds(), firstTime, lastTime, iDone++); viewLoadObserver.sayProgress(1, aData.getTimeMilliseconds(), firstTime, lastTime, iDone++);
} }
@ -479,6 +482,7 @@ public class SuperDetDataBlock<Tunit extends SuperDetection, TSubDet extends Pam
sdInfo.setSubDetection(null); sdInfo.setSubDetection(null);
} }
} }
// aData.weedMissingSubDetections();
} }
} }
return true; return true;

View File

@ -278,23 +278,28 @@ public class SuperDetection<T extends PamDataUnit> extends PamDataUnit<T, SuperD
* @return an array list of sub detection data units * @return an array list of sub detection data units
*/ */
public ArrayList<PamDataUnit<?,?>> getSubDetections() { public ArrayList<PamDataUnit<?,?>> getSubDetections() {
if (subDetections == null) { synchronized (getSubDetectionSyncronisation()) {
return null; if (subDetections == null) {
} return null;
ArrayList<PamDataUnit<?,?>> subDets = new ArrayList<>(getSubDetectionsCount());
for (SubdetectionInfo<T> subInfo:subDetections) {
T subDet = subInfo.getSubDetection();
if (subDet == null) {
continue;
} }
subDets.add(subDet); ArrayList<PamDataUnit<?,?>> subDets = new ArrayList<>(getSubDetectionsCount());
for (SubdetectionInfo<T> subInfo:subDetections) {
T subDet = subInfo.getSubDetection();
if (subDet == null) {
continue;
}
subDets.add(subDet);
}
return subDets;
} }
return subDets;
} }
public T getSubDetection(int ind) { public T getSubDetection(int ind) {
synchronized (subDetectionSyncronisation) { synchronized (subDetectionSyncronisation) {
if (subDetections == null) return null; if (subDetections == null) return null;
if (ind >= subDetections.size()) {
return null;
}
return subDetections.get(ind).getSubDetection(); return subDetections.get(ind).getSubDetection();
} }
} }
@ -484,6 +489,24 @@ public class SuperDetection<T extends PamDataUnit> extends PamDataUnit<T, SuperD
// } // }
} }
/**
* Get a list of sub detections which are actually present.
* @return list of sub detections which have a non-null sub data unit.
*/
public List<SubdetectionInfo<T>> getPresentSubDetections() {
ArrayList<SubdetectionInfo<T>> exList = new ArrayList<>(getSubDetectionsCount());
synchronized (getSubDetectionSyncronisation()) {
for (SubdetectionInfo<T> subInf : subDetections) {
if (subInf.getSubDetection() == null) {
continue;
}
exList.add(subInf);
}
exList.trimToSize();
}
return exList;
}
/** /**
* Get the full list of subdetection info's (which may not all * Get the full list of subdetection info's (which may not all
@ -550,4 +573,21 @@ public class SuperDetection<T extends PamDataUnit> extends PamDataUnit<T, SuperD
} }
} }
/**
* Remove sub detection infos which have no actual sub detection
* loaded. Don't use since super dets are supposed to keep the full
* list even if they don't have loaded subdets.
*/
// public void weedMissingSubDetections() {
// synchronized (getSubDetectionSyncronisation()) {
// ListIterator<SubdetectionInfo<T>> subInfIter = subDetections.listIterator();
// while (subInfIter.hasNext()) {
// SubdetectionInfo<T> subDetInfo = subInfIter.next();
// if (subDetInfo.getSubDetection() == null) {
// subInfIter.remove();
// }
// }
// }
// }
} }

View File

@ -284,5 +284,17 @@ public class OfflineEventDataBlock extends SuperDetDataBlock<OfflineEventDataUni
return (clickDetector.getClickDataBlock() == subDataBlock || clickDetector.getTrackedClicks() == subDataBlock); return (clickDetector.getClickDataBlock() == subDataBlock || clickDetector.getTrackedClicks() == subDataBlock);
} }
// int nName = 0;
// @Override
// public String getDataName() {
// // TODO Auto-generated method stub
// System.out.println("Call into getDataName " + ++nName);
// if (nName == 58) {
//
// System.out.println("Call into getDataName " + ++nName);
// }
// return super.getDataName();
// }
} }

View File

@ -191,9 +191,9 @@ public class ViewerScrollerManager extends AbstractScrollManager implements PamS
*/ */
private void loadDataQueueItem(DataLoadQueData dataLoadQueData, int queuePosition, ViewLoadObserver loadObserver) { private void loadDataQueueItem(DataLoadQueData dataLoadQueData, int queuePosition, ViewLoadObserver loadObserver) {
PamDataBlock dataBlock = dataLoadQueData.getPamDataBlock(); PamDataBlock dataBlock = dataLoadQueData.getPamDataBlock();
if (dataBlock instanceof OfflineEventDataBlock) { // if (dataBlock instanceof OfflineEventDataBlock) {
System.out.println(dataBlock); // System.out.println("in loadDataQueueItem" + dataBlock);
} // }
// 2019-11-12 add a check of the counts to this 'if' statement as well. If the data start time is negative // 2019-11-12 add a check of the counts to this 'if' statement as well. If the data start time is negative
// (which can indicate that this is a 'special' data block and we should be loading all of it rather than just // (which can indicate that this is a 'special' data block and we should be loading all of it rather than just

View File

@ -23,8 +23,12 @@ import Stats.LinFit;
* Step 3 is to rotate all position and angle vectors so that they correspond to * Step 3 is to rotate all position and angle vectors so that they correspond to
* a track as close as possible to the x axis. * a track as close as possible to the x axis.
* @author Doug Gillespie * @author Doug Gillespie
*
* Deprecated. Not used and will probably fall over with system whereby sub detection info
* is present, but not all sub detections are.
* *
*/ */
@Deprecated
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public class EventRotator extends AbstractTargetMotionInformation{ public class EventRotator extends AbstractTargetMotionInformation{

View File

@ -1,9 +1,13 @@
package targetMotionOld; package targetMotionOld;
import pamMaths.PamVector; import pamMaths.PamVector;
import java.util.List;
import PamDetection.AbstractLocalisation; import PamDetection.AbstractLocalisation;
import PamUtils.LatLong; import PamUtils.LatLong;
import PamguardMVC.PamDataUnit; import PamguardMVC.PamDataUnit;
import PamguardMVC.superdet.SubdetectionInfo;
import PamguardMVC.superdet.SuperDetection; import PamguardMVC.superdet.SuperDetection;
import Stats.LinFit; import Stats.LinFit;
@ -74,12 +78,18 @@ public class EventRotator {
private double[] rotatedArrayAngles; private double[] rotatedArrayAngles;
private int referenceHydrophones; private int referenceHydrophones;
/**
* List of present (actual sub detection is not null) sub detections.
*/
private List<SubdetectionInfo<PamDataUnit>> subDetections;
/** /**
* @param pamDetection * @param pamDetection
*/ */
public EventRotator(SuperDetection pamDetection) { public EventRotator(SuperDetection pamDetection) {
super(); super();
this.pamDetection = pamDetection; this.pamDetection = pamDetection;
this.subDetections = pamDetection.getPresentSubDetections();
rotatedWorldVectors = null; rotatedWorldVectors = null;
calculateMetrePoints(); calculateMetrePoints();
} }
@ -90,14 +100,14 @@ public class EventRotator {
*/ */
private void calculateMetrePoints() { private void calculateMetrePoints() {
lastUpdateTime = pamDetection.getLastUpdateTime(); lastUpdateTime = pamDetection.getLastUpdateTime();
nSubDetections = pamDetection.getSubDetectionsCount(); nSubDetections = subDetections.size();
subDetectionOrigins = new PamVector[nSubDetections]; subDetectionOrigins = new PamVector[nSubDetections];
subDetectionHeadings = new PamVector[nSubDetections]; subDetectionHeadings = new PamVector[nSubDetections];
pointTimes = new long[nSubDetections]; pointTimes = new long[nSubDetections];
if (nSubDetections == 0) { if (nSubDetections == 0) {
return; return;
} }
PamDataUnit pd = pamDetection.getSubDetection(0); PamDataUnit pd = subDetections.get(0).getSubDetection();
if (pd == null) { if (pd == null) {
return; return;
} }
@ -110,7 +120,10 @@ public class EventRotator {
LatLong detOrigin; LatLong detOrigin;
for (int i = 0; i < nSubDetections; i++) { for (int i = 0; i < nSubDetections; i++) {
pd = pamDetection.getSubDetection(i); pd = subDetections.get(i).getSubDetection();
if (pd == null) {
continue;
}
localisation = pd.getLocalisation(); localisation = pd.getLocalisation();
if (localisation == null) { if (localisation == null) {
continue; continue;
@ -152,6 +165,9 @@ public class EventRotator {
rotatedOrigins = new PamVector[nSubDetections]; rotatedOrigins = new PamVector[nSubDetections];
rotatedHeadings = new PamVector[nSubDetections]; rotatedHeadings = new PamVector[nSubDetections];
for (int i = 0; i < nSubDetections; i++) { for (int i = 0; i < nSubDetections; i++) {
if (subDetectionOrigins[i] == null) {
continue;
}
subDetectionHeadings[i] = new PamVector(Math.cos(Math.PI/2-rotatedArrayAngles[i]), Math.sin(Math.PI/2-rotatedArrayAngles[i]), 0); subDetectionHeadings[i] = new PamVector(Math.cos(Math.PI/2-rotatedArrayAngles[i]), Math.sin(Math.PI/2-rotatedArrayAngles[i]), 0);
rotatedOrigins[i] = subDetectionOrigins[i].rotate(-referenceAngle); rotatedOrigins[i] = subDetectionOrigins[i].rotate(-referenceAngle);
rotatedArrayAngles[i] = Math.PI/2. - rotatedArrayAngles[i]; rotatedArrayAngles[i] = Math.PI/2. - rotatedArrayAngles[i];
@ -170,7 +186,7 @@ public class EventRotator {
PamDataUnit pd; PamDataUnit pd;
AbstractLocalisation localisation; AbstractLocalisation localisation;
for (int i = 0; i < nSubDetections; i++) { for (int i = 0; i < nSubDetections; i++) {
pd = pamDetection.getSubDetection(i); pd = subDetections.get(i).getSubDetection();
localisation = pd.getLocalisation(); localisation = pd.getLocalisation();
if (localisation == null) { if (localisation == null) {
continue; continue;
@ -187,7 +203,7 @@ public class EventRotator {
PamDataUnit pd; PamDataUnit pd;
AbstractLocalisation localisation; AbstractLocalisation localisation;
for (int i = 0; i < nSubDetections; i++) { for (int i = 0; i < nSubDetections; i++) {
pd = pamDetection.getSubDetection(i); pd = subDetections.get(i).getSubDetection();
localisation = pd.getLocalisation(); localisation = pd.getLocalisation();
if (localisation == null) { if (localisation == null) {
continue; continue;

View File

@ -4,6 +4,7 @@ import java.awt.BorderLayout;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel; import javax.swing.JPanel;
@ -18,6 +19,7 @@ import PamUtils.LatLong;
import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit; import PamguardMVC.PamDataUnit;
import PamguardMVC.dataSelector.DataSelector; import PamguardMVC.dataSelector.DataSelector;
import PamguardMVC.superdet.SubdetectionInfo;
import clickDetector.ClickDataBlock; import clickDetector.ClickDataBlock;
import targetMotionOld.TargetMotionLocaliser; import targetMotionOld.TargetMotionLocaliser;
@ -66,9 +68,14 @@ public class DialogMap3DSwing<T extends GroupDetection> extends DialogMap<T> {
mapDetData.allAvailable = true; mapDetData.allAvailable = true;
mapDetData.select = true; mapDetData.select = true;
int nSub = currentEvent.getSubDetectionsCount(); List<SubdetectionInfo<PamDataUnit>> subDets = currentEvent.getPresentSubDetections();
int nSub = subDets.size();
for (int i = 0; i < nSub; i++) { for (int i = 0; i < nSub; i++) {
PamDataUnit subDet = currentEvent.getSubDetection(i); PamDataUnit subDet = subDets.get(i).getSubDetection();
if (subDet == null) {
continue;
}
MapDetectionData subDetData = mapDetectionsManager.findDetectionData(subDet.getParentDataBlock()); MapDetectionData subDetData = mapDetectionsManager.findDetectionData(subDet.getParentDataBlock());
if (subDetData != null && subDetData != mapDetData) { if (subDetData != null && subDetData != mapDetData) {
mapDetData = subDetData; mapDetData = subDetData;
@ -81,8 +88,8 @@ public class DialogMap3DSwing<T extends GroupDetection> extends DialogMap<T> {
*/ */
LatLong eventCentre = currentEvent.getOriginLatLong(true); LatLong eventCentre = currentEvent.getOriginLatLong(true);
if (nSub >= 2) { if (nSub >= 2) {
LatLong ll1 = currentEvent.getSubDetection(0).getOriginLatLong(true); LatLong ll1 = subDets.get(0).getSubDetection().getOriginLatLong(true);
LatLong ll2 = currentEvent.getSubDetection(nSub-1).getOriginLatLong(true); LatLong ll2 = subDets.get(nSub-1).getSubDetection().getOriginLatLong(true);
if (ll1 != null & ll2 != null) { if (ll1 != null & ll2 != null) {
double lat = (ll1.getLatitude() + ll2.getLatitude())/2.; double lat = (ll1.getLatitude() + ll2.getLatitude())/2.;
double lon = (ll1.getLongitude() + ll2.getLongitude())/2.; double lon = (ll1.getLongitude() + ll2.getLongitude())/2.;