Fixes and code rationalisation for group 3D loclaiser

This commit is contained in:
Jamie Mac 2023-08-25 09:36:26 +01:00
parent c2e3315cf6
commit e1462537f7
11 changed files with 325 additions and 158 deletions

View File

@ -6,8 +6,9 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-17.0.4.101-hotspot">
<attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>

View File

@ -4,7 +4,7 @@
<groupId>org.pamguard</groupId>
<artifactId>Pamguard</artifactId>
<name>Pamguard Java12+</name>
<version>2.02.09</version>
<version>2.02.09a</version>
<description>Pamguard for Java 12+, using Maven to control dependcies</description>
<url>www.pamguard.org</url>
<organization>

View File

@ -318,7 +318,7 @@
<dependency>
<groupId>io.github.macster110</groupId>
<artifactId>jpamutils</artifactId>
<version>0.0.56</version>
<version>0.0.57</version>
</dependency>
<!--jpam project - Deep learning java library
@ -329,7 +329,7 @@
<dependency>
<groupId>io.github.macster110</groupId>
<artifactId>jdl4pam</artifactId>
<version>0.0.94</version>
<version>0.0.97</version>
</dependency>
<!-- https://mvnrepository.com/artifact/gov.nist.math/jama -->
@ -785,9 +785,9 @@ you may need to copy files from your downloaded PAMGuard source code, e.g. C:\Us
C:\Users\*yourusername*\.m2\repository\pamguard\org\x3\2.2.2
-->
<dependency>
<groupId>pamguard.org</groupId>
<groupId>org.pamguard</groupId>
<artifactId>x3</artifactId>
<version>2.2.2</version>
<version>2.2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/it.sauronsoftware/jave -->

View File

@ -13,6 +13,7 @@ import PamUtils.LatLong;
import PamUtils.PamArrayUtils;
import PamView.TransformShape;
import PamView.GeneralProjector;
import PamguardMVC.PamConstants;
import PamguardMVC.PamDataUnit;
import pamMaths.PamVector;
@ -118,15 +119,19 @@ public class EllipseLocErrorDraw implements LocErrorGraphics {
//this is 2D- need to make a slice through the ellipse and get the localisation points.
double[] errors2D=ellipticalError.getErrorEllipse2D(ErrorEllipse.PLANE_XY_PROJ);
// if (1>0) return null;
if (errors2D==null) return null;
if (errors2D[0] > PamConstants.EARTH_RADIUS_METERS || errors2D[1] > PamConstants.EARTH_RADIUS_METERS) {
return null; //don't draw infintie stuff - causes nasty errors.
}
// System.out.println("Draw ovals on map");
// System.out.println("EllipseLocErrorDraw: draw ellipse:"+errors2D[0]+" "+errors2D[1]+" "+Math.toDegrees(errors2D[2]));
//System.out.println("Plot errors: perp: "+ perpError+ " horz: "+horzError+ " " + errorDirection);
Graphics2D g2d = (Graphics2D)g;
if (errors2D==null) return null;
//draw oval
// //need to work out the size of the horizontal error.
// perpError=Math.max(perpError, 100);

View File

@ -246,6 +246,8 @@ public class MCMCPane extends SettingsPane<MCMCParams2> {
jumpSize[0] = jumpXSpinner.getValue();
jumpSize[1] = jumpYSpinner.getValue();
jumpSize[2] = jumpZSpinner.getValue();
currParams.jumpSize = jumpSize;
//bit messy but works...
currParams.setChainDispersion(startDispersion.getValue(), 3);

View File

@ -28,15 +28,24 @@ import group3dlocaliser.localisation.LinearLocalisation;
import pamMaths.PamVector;
/**
* Hyperbolic localisation using methods described in
* Gillette, M. D., and Silverman, H. F. (2008). <EFBFBD>A linear closed-form algorithm for source localization from time-differences of arrival,<EFBFBD> IEEE Signal Processing Letters, 15, 1<EFBFBD>4.<p>
* Hyperbolic localisation using methods described in Gillette, M. D., and
* Silverman, H. F. (2008). <EFBFBD>A linear closed-form algorithm for source
* localization from time-differences of arrival,<EFBFBD> IEEE Signal Processing
* Letters, 15, 1<EFBFBD>4.
* <p>
*
* Also worth reading Spiesberger, J. L. (2001). <EFBFBD>Hyperbolic location errors due
* to insufficient numbers of receivers,<EFBFBD> The Journal of the Acoustical Society
* of America, 109, 3076<EFBFBD>3079. which gives a clearer explanation of why at least
* 4 recievers are needed for 2D localisation and 5 for 3D localisation.
* <p>
* Worth noting that the equations derived in Gillette 2008 are functionally
* identical to those in Spiesberger 2001 and an earlier work by Speisberger and
* Fristrup:<br>
* Spiesberger, J. L., and Fristrup, K. M. (1990). <EFBFBD>Passive localization of
* calling animals and sensing of their acoustic environment using acoustic
* tomography,<EFBFBD> The american naturalist, 135, 107<EFBFBD>153.
*
* Also worth reading Spiesberger, J. L. (2001). <EFBFBD>Hyperbolic location errors due to insufficient numbers of receivers,<EFBFBD> The Journal of the Acoustical Society of America, 109, 3076<EFBFBD>3079.
* which gives a clearer explanation of why at least 4 recievers are needed for 2D localisation and 5 for 3D localisation.<p>
* Worth noting that the equations derived in Gillette 2008 are functionally identical to those in Spiesberger 2001 and an earlier work by Speisberger and Fristrup:<br>
* Spiesberger, J. L., and Fristrup, K. M. (1990). <EFBFBD>Passive localization of calling animals and sensing of their acoustic environment using acoustic tomography,<EFBFBD>
* The american naturalist, 135, 107<EFBFBD>153.
*
* @author Doug Gillespie
*
*/

View File

@ -36,7 +36,22 @@ import group3dlocaliser.algorithm.LogLikelihoodData;
import pamMaths.PamVector;
import pamViewFX.fxNodes.pamDialogFX.ManagedSettingsPane;
abstract public class TOADBaseAlgorithm extends LocaliserAlgorithm3D {
public enum MultiVariateType {
/**
* Chi2 fucntion
*/
CHI2,
/**
* Log liklilihood function
*/
LOG_LIKILIHOOD;
}
private double sampleRate;
@ -53,7 +68,7 @@ abstract public class TOADBaseAlgorithm extends LocaliserAlgorithm3D {
protected Group3DLocaliserControl group3dLocaliser;
private TOADSettingsPaneWithChannels tspwc;
private static double halflog2pi = Math.log(2.*Math.PI)/2.;
public TOADBaseAlgorithm(Group3DLocaliserControl group3dLocaliser) {
@ -110,9 +125,9 @@ abstract public class TOADBaseAlgorithm extends LocaliserAlgorithm3D {
groupDataUnit.getTimeMilliseconds());
// if (groupDataUnit.getSubDetection(0).getUID() == 9035003222L) {
// if (superDetection.getSubDetection(0).getUID() == 9035004477L) {
// System.out.println("Found it");
// }
// if (superDetection.getSubDetection(0).getUID() == 9035004477L) {
// System.out.println("Found it");
// }
TOADInformation toadInformation = toadCalculator.getTOADInformation(superDetection.getSubDetections(), sampleRate, allChannels, geometry);
boolean toadOK = checkTOADInformation(toadInformation);
@ -150,7 +165,7 @@ abstract public class TOADBaseAlgorithm extends LocaliserAlgorithm3D {
public int countUsableTOADS(TOADInformation toadInformation) {
return countUsableTOADS(toadInformation, toadBaseParams.getMinCorrelation());
}
/**
* Count the number of TOAD values which have a correlation coefficient or 'score'
* >= the minimum.
@ -256,21 +271,24 @@ abstract public class TOADBaseAlgorithm extends LocaliserAlgorithm3D {
return null;
}
/**
* Calculate a Log Likelihood value for the given geometry and set of delays.
* @param geometry
* @param delays
* @return
* Calculates chi2 or log likelihood for a position.
* @param geometry - the geometry of the receivers.
* @param toadInformation - the received time delay information.
* @param position - the position to test.
* @param flag - which value to calculate.
* @return the chi2 or log likilihood value.
*/
public LogLikelihoodData calcLogLikelihood(SnapshotGeometry geometry, TOADInformation toadInformation, double[] position) {
private FitTestValue multivariateFunction(SnapshotGeometry geometry, TOADInformation toadInformation, double[] position, MultiVariateType flag) {
/**
* There is an awful lot of repeated code in this and the Chi2 function. Would be good
* to sort out some time !
*/
// if (1>0) {
// Chi2Data chiRes = calcChi2(geometry, toadInformation, position);
// LogLikelihoodData lld = new LogLikelihoodData(-chiRes.getChi2(), chiRes.getDegreesOfFreedom());
// }
// if (1>0) {
// Chi2Data chiRes = calcChi2(geometry, toadInformation, position);
// LogLikelihoodData lld = new LogLikelihoodData(-chiRes.getChi2(), chiRes.getDegreesOfFreedom());
// }
if (position == null || position.length == 0) {
return null;
@ -341,18 +359,140 @@ abstract public class TOADBaseAlgorithm extends LocaliserAlgorithm3D {
* delay error, but more if you're end on.
*/
errSq += Math.pow(exp*cError/c, 2.);
/*
* Do the full calc -ln(2pi)/2 - .5ln(sig) - .5(diff^2/errSq).
* So note the 0.5 instead of the which is to take the sqrt(errSq) !
*/
llVal -= (halflog2pi + 0.5*Math.log(errSq) + Math.pow(val-exp, 2)/errSq/2);
// llVal -= Math.pow(val-exp, 2)/errSq/2.;
nGood++;
switch (flag) {
case LOG_LIKILIHOOD:
/*
* Do the full calc -ln(2pi)/2 - .5ln(sig) - .5(diff^2/errSq).
* So note the 0.5 instead of the which is to take the sqrt(errSq) !
*/
llVal -= (halflog2pi + 0.5*Math.log(errSq) + Math.pow(val-exp, 2)/errSq/2);
// llVal -= Math.pow(val-exp, 2)/errSq/2.;
nGood++;
break;
case CHI2:
llVal += Math.pow(val-exp, 2)/errSq;
nGood++;
break;
}
}
}
return new LogLikelihoodData(llVal, nGood-nDim);
}
switch (flag) {
case LOG_LIKILIHOOD:
return new LogLikelihoodData(llVal, nGood-nDim);
case CHI2:
return new Chi2Data(llVal, nGood-nDim);
}
//something has gone pretty wrong
return null;
}
/**
* Calculate a Log Likelihood value for the given geometry and set of delays.
* @param geometry
* @param delays
* @return
*/
public LogLikelihoodData calcLogLikelihood(SnapshotGeometry geometry, TOADInformation toadInformation, double[] position) {
return (LogLikelihoodData) multivariateFunction( geometry, toadInformation, position, MultiVariateType.LOG_LIKILIHOOD);
// /**
// * There is an awful lot of repeated code in this and the Chi2 function. Would be good
// * to sort out some time !
// */
// // if (1>0) {
// // Chi2Data chiRes = calcChi2(geometry, toadInformation, position);
// // LogLikelihoodData lld = new LogLikelihoodData(-chiRes.getChi2(), chiRes.getDegreesOfFreedom());
// // }
//
// if (position == null || position.length == 0) {
// return null;
// }
// double[][] delays = toadInformation.getToadSeconds();
// double[][] delayErrors = toadInformation.getToadErrorsSeconds();
//
// double minCorrelationValue = toadBaseParams.getMinCorrelation();
//
// int nDim = position.length;
// int[] hydrophones = toadInformation.getHydrophoneList();
// int[] channels = toadInformation.getChannelList();
// int nChan = channels.length;
// double[] expectedDelays = new double[nChan];
// double c = geometry.getCurrentArray().getSpeedOfSound();
// double cError = geometry.getCurrentArray().getSpeedOfSoundError();
// PamVector centre = geometry.getGeometricCentre();
// double[] channelErrors = new double[nChan];
// double[] streamerErrors = new double[nChan];
// int[] streamerId = new int[nChan];
// double[][] correlationScores = toadInformation.getToadScores();
// PamVector positionVec = new PamVector(position).add(centre);
// // calculate the absolute distance (then time) to each hydrophone used in the delay matrix.
// for (int i = 0; i < nChan; i++) {
// double r = 0;
// /*
// * use the hydrophone LUT from TOAD information to make sure we get the right phone
// * since channel groups may not be in a sensible order.
// */
// PamVector hydrophoneGeom = geometry.getGeometry()[hydrophones[i]];
// PamVector rv = positionVec.sub(hydrophoneGeom);
// expectedDelays[i] = rv.norm(nDim) / c;
// /**
// * Now work out the expected range error along the unit vector position-hydrophone+centre
// */
// PamVector rvu = rv.getUnitVector();
// PamVector hErr = geometry.getHydrophoneErrors()[hydrophones[i]]; //NB. this is not really a vector !
// channelErrors[i] = Math.pow(rvu.sumComponentsSquared(hErr)/c, 2); // square and convert to time now
// PamVector sErr = geometry.getStreamerErrors()[hydrophones[i]]; // this isn't a vector either
// streamerId[i] = geometry.getCurrentArray().getStreamerForPhone(hydrophones[i]);
// if (sErr != null) {
// streamerErrors[i] = Math.pow(rvu.sumComponentsSquared(sErr)/c, 2);
// }
// }
// double llVal = 0.;
// int nGood = 0;
// for (int i = 0; i < nChan; i++) {
// for (int j = i+1; j < nChan; j++) {
// double val = (delays[i][j]);
// if (Double.isNaN(val)) {
// continue;
// }
// if (correlationScores == null || correlationScores[i][j] < minCorrelationValue) {
// continue;
// }
// double exp = expectedDelays[j]-expectedDelays[i];
// // now work out the squared error...
// double errSq = Math.pow(delayErrors[i][j], 2)+channelErrors[i]+channelErrors[j];
//
// // add in the streamer errors if they are in different streamers.
// if (streamerId[i] != streamerId[j]) {
// errSq += streamerErrors[i]+streamerErrors[j];
// }
// /*
// * Finally there is an error due to uncertainty in c, which is
// * obviously proportional to the expected delay. i.e. if you're
// * perpendicular to a hydrophone pair, then there will be zero
// * delay error, but more if you're end on.
// */
// errSq += Math.pow(exp*cError/c, 2.);
// /*
// * Do the full calc -ln(2pi)/2 - .5ln(sig) - .5(diff^2/errSq).
// * So note the 0.5 instead of the which is to take the sqrt(errSq) !
// */
// llVal -= (halflog2pi + 0.5*Math.log(errSq) + Math.pow(val-exp, 2)/errSq/2);
// // llVal -= Math.pow(val-exp, 2)/errSq/2.;
// nGood++;
// }
// }
// return new LogLikelihoodData(llVal, nGood-nDim);
}
/**
* Calculate a chi2 value for the given geometry and set of delays.
* @param geometry array geometry.
@ -361,93 +501,104 @@ abstract public class TOADBaseAlgorithm extends LocaliserAlgorithm3D {
* @return
*/
public Chi2Data calcChi2(SnapshotGeometry geometry, TOADInformation toadInformation, double[] position) {
if (position == null || position.length == 0) {
return null;
}
double[][] delays = toadInformation.getToadSeconds();
double[][] delayErrors = toadInformation.getToadErrorsSeconds();
double minCorrelationValue = toadBaseParams.getMinCorrelation();
int nDim = position.length;
int[] hydrophones = toadInformation.getHydrophoneList();
int[] channels = toadInformation.getChannelList();
int nChan = channels.length;
double[] expectedDelays = new double[nChan];
double c = geometry.getCurrentArray().getSpeedOfSound();
double cError = geometry.getCurrentArray().getSpeedOfSoundError();
PamVector centre = geometry.getGeometricCentre();
double[] channelErrors = new double[nChan];
double[] streamerErrors = new double[nChan];
int[] streamerId = new int[nChan];
double[][] correlationScores = toadInformation.getToadScores();
PamVector positionVec = new PamVector(position).add(centre);
// calculate the absolute distance (then time) to each hydrophone used in the delay matrix.
for (int i = 0; i < nChan; i++) {
double r = 0;
/*
* use the hydrophone LUT from TOAD information to make sure we get the right phone
* since channel groups may not be in a sensible order.
*/
PamVector hydrophoneGeom = geometry.getGeometry()[hydrophones[i]];
PamVector rv = positionVec.sub(hydrophoneGeom);
expectedDelays[i] = rv.norm() / c;
/**
* Now work out the expected range error along the unit vector position-hydrophone+centre
*
* These calculations were incorrect since they look at dot of the
* error against the direction to the source, which is wrong !
* e.g. if error was (1,1,1) it appears as a vector along that bearing, if this
* were dotted with an angle perpendicular to this, then it would give a very
* different answer.
* The correct way to calculate the inter pair error is to add each component of
* the error along the vector joining the two hydrophones. This error should be stored
* as a pair error and then dot producted with the unit vector towards the source.
* Need to rewrite and produce a matrix of channel pair errors!
*/
PamVector rvu = rv.getUnitVector();
PamVector hErr = geometry.getHydrophoneErrors()[hydrophones[i]];
// if (hErr != null) {
channelErrors[i] = Math.pow(rvu.sumComponentsSquared(hErr)/c, 2); // square and convert to time now
// }
PamVector sErr = geometry.getStreamerErrors()[hydrophones[i]];
streamerId[i] = geometry.getCurrentArray().getStreamerForPhone(hydrophones[i]);
if (sErr != null) {
streamerErrors[i] = Math.pow(rvu.sumComponentsSquared(sErr)/c, 2);
}
}
double chiVal = 0.;
int nGood = 0;
for (int i = 0; i < nChan; i++) {
for (int j = i+1; j < nChan; j++) {
double val = (delays[i][j]);
if (Double.isNaN(val)) {
continue;
}
if (correlationScores == null || correlationScores[i][j] < minCorrelationValue) {
continue;
}
double exp = expectedDelays[j]-expectedDelays[i];
// now work out the squared error...
double errSq = Math.pow(delayErrors[i][j], 2)+channelErrors[i]+channelErrors[j];
// add in the streamer errors if they are in different streamers.
if (streamerId[i] != streamerId[j]) {
return (Chi2Data) multivariateFunction( geometry, toadInformation, position, MultiVariateType.CHI2);
//
// if (position == null || position.length == 0) {
// return null;
// }
// double[][] delays = toadInformation.getToadSeconds();
// double[][] delayErrors = toadInformation.getToadErrorsSeconds();
//
// double minCorrelationValue = toadBaseParams.getMinCorrelation();
//
// int nDim = position.length;
// int[] hydrophones = toadInformation.getHydrophoneList();
// int[] channels = toadInformation.getChannelList();
// int nChan = channels.length;
// double[] expectedDelays = new double[nChan];
// double c = geometry.getCurrentArray().getSpeedOfSound();
// double cError = geometry.getCurrentArray().getSpeedOfSoundError();
// PamVector centre = geometry.getGeometricCentre();
// double[] channelErrors = new double[nChan];
// double[] streamerErrors = new double[nChan];
// int[] streamerId = new int[nChan];
// double[][] correlationScores = toadInformation.getToadScores();
// PamVector positionVec = new PamVector(position).add(centre);
// // calculate the absolute distance (then time) to each hydrophone used in the delay matrix.
// for (int i = 0; i < nChan; i++) {
// double r = 0;
// /*
// * use the hydrophone LUT from TOAD information to make sure we get the right phone
// * since channel groups may not be in a sensible order.
// */
// PamVector hydrophoneGeom = geometry.getGeometry()[hydrophones[i]];
// PamVector rv = positionVec.sub(hydrophoneGeom);
//
//
// expectedDelays[i] = rv.norm() / c;
// /**
// * Now work out the expected range error along the unit vector position-hydrophone+centre
// *
// * These calculations were incorrect since they look at dot of the
// * error against the direction to the source, which is wrong !
// * e.g. if error was (1,1,1) it appears as a vector along that bearing, if this
// * were dotted with an angle perpendicular to this, then it would give a very
// * different answer.
// * The correct way to calculate the inter pair error is to add each component of
// * the error along the vector joining the two hydrophones. This error should be stored
// * as a pair error and then dot producted with the unit vector towards the source.
// * Need to rewrite and produce a matrix of channel pair errors!
// */
// PamVector rvu = rv.getUnitVector();
// PamVector hErr = geometry.getHydrophoneErrors()[hydrophones[i]];
// // if (hErr != null) {
// channelErrors[i] = Math.pow(rvu.sumComponentsSquared(hErr)/c, 2); // square and convert to time now
// // }
// PamVector sErr = geometry.getStreamerErrors()[hydrophones[i]];
// streamerId[i] = geometry.getCurrentArray().getStreamerForPhone(hydrophones[i]);
// if (sErr != null) {
// streamerErrors[i] = Math.pow(rvu.sumComponentsSquared(sErr)/c, 2);
// }
// }
// double chiVal = 0.;
// int nGood = 0;
// for (int i = 0; i < nChan; i++) {
// for (int j = i+1; j < nChan; j++) {
// double val = (delays[i][j]);
// if (Double.isNaN(val)) {
// continue;
// }
// if (correlationScores == null || correlationScores[i][j] < minCorrelationValue) {
// continue;
// }
// double exp = expectedDelays[j]-expectedDelays[i];
// // now work out the squared error...
// double errSq = Math.pow(delayErrors[i][j], 2)+channelErrors[i]+channelErrors[j];
//
// // add in the streamer errors if they are in different streamers.
// if (streamerId[i] != streamerId[j]) {
// // errSq += streamerErrors[i]+streamerErrors[j];
// // continue; simulate unsynchronised streamers.
// }
//
// // add in the streamer errors if they are in different streamers.
// if (streamerId[i] != streamerId[j]) {
// errSq += streamerErrors[i]+streamerErrors[j];
// continue; simulate unsynchronised streamers.
}
/*
* Finally there is an error due to uncertainty in c, which is
* obviously proportional to the expected delay. i.e. if you're
* perpendicular to a hydrophone pair, then there will be zero
* delay error, but more if you're end on.
*/
errSq += Math.pow(exp*cError/c, 2.);
chiVal += Math.pow(val-exp, 2)/errSq;
nGood++;
}
}
return new Chi2Data(chiVal, nGood-nDim);
// }
//
// /*
// * Finally there is an error due to uncertainty in c, which is
// * obviously proportional to the expected delay. i.e. if you're
// * perpendicular to a hydrophone pair, then there will be zero
// * delay error, but more if you're end on.
// */
// errSq += Math.pow(exp*cError/c, 2.);
// chiVal += Math.pow(val-exp, 2)/errSq;
// nGood++;
// }
// }
// return new Chi2Data(chiVal, nGood-nDim);
}
/**
* Estimate an elliptical error with axes aligned with largest error coordinate based on the curvature of the Chi2 / likelihood surface.
@ -457,22 +608,22 @@ abstract public class TOADBaseAlgorithm extends LocaliserAlgorithm3D {
* @return Elliptical error
*/
public EllipticalError estimateEllipticalError(SnapshotGeometry geometry, TOADInformation toadInformation, double[] position) {
// Chi2Data centralChi2 = calcChi2(geometry, toadInformation, position);
// Chi2Data centralChi2 = calcChi2(geometry, toadInformation, position);
/**
* Will take the principle axis as a direct line to the detection from the central point of the array
* geometry.
*/
// PamVector arrayCentre = geometry.getGeometricCentre();
// PamVector arrayCentre = geometry.getGeometricCentre();
// position is already relative to the geometric centre of the array.
PamVector posVec = new PamVector(position);
double[] errors = new double[6];
PamVector[] errVecs = new PamVector[3];
// get a unit vector along the direction from the array centre to the calculated coordinate.
errVecs[0] = posVec.getUnitVector();
// if (posVec.getCoordinate(0) > 6 && posVec.getCoordinate(0) < 8 && Math.abs(posVec.getCoordinate(1)) < 5) {
// System.out.println(posVec);
// }
// if (posVec.getCoordinate(0) > 6 && posVec.getCoordinate(0) < 8 && Math.abs(posVec.getCoordinate(1)) < 5) {
// System.out.println(posVec);
// }
/*
* to get secondary axis we can rotate by 90 degrees in any direction apart from
* the principle direction of the vector.
@ -488,7 +639,7 @@ abstract public class TOADBaseAlgorithm extends LocaliserAlgorithm3D {
errVecs[1] = (errVecs[0].vecProd(PamVector.zAxis)).getUnitVector();
errVecs[2] = errVecs[1].vecProd(errVecs[0]);
}
/*
* Error along each principle axis.
*/
@ -499,11 +650,11 @@ abstract public class TOADBaseAlgorithm extends LocaliserAlgorithm3D {
}
// now need to convert the error vectors to heading, pitch and roll.
double[] angles = PamVector.getHeadingPitchRoll(errVecs);
EllipticalError elError = new EllipticalError(angles, errors);
return elError;
}
/**
* Estimate the error in Cartesian coordinates based on the curvature of the Chi2 / likelihood surface.
* @param geometry Array geometry
@ -542,7 +693,7 @@ abstract public class TOADBaseAlgorithm extends LocaliserAlgorithm3D {
return simpleError;
}
/**
* Get the error along the principle direction
* @param geometry current array geometry
@ -586,9 +737,9 @@ abstract public class TOADBaseAlgorithm extends LocaliserAlgorithm3D {
*/
double nDF = Math.max(centralChi2.getDegreesOfFreedom(), 1);
double chiCent = centralChi2.getTestScore();
// if (chiCent == 0) {
// chiCent = 1;
// }
// if (chiCent == 0) {
// chiCent = 1;
// }
double step;
double[] sig = new double[2];
double[] shiftedChi = new double[2];
@ -633,6 +784,9 @@ abstract public class TOADBaseAlgorithm extends LocaliserAlgorithm3D {
public ToadManagedSettingsPane<Serializable> getSourceSettingsPane(Window parent, PamDataBlock<?> detectionSource) {
// return new TOADSourcePane(parent);
// return toadCalculator.getSettingsPane();
System.out.println("Get source settings pane: " +toadCalculator + " " + tspwc);
if (toadCalculator != null && tspwc == null) {
/*
* this gets the algorithm specific settings pane. We want to tab
@ -645,7 +799,6 @@ abstract public class TOADBaseAlgorithm extends LocaliserAlgorithm3D {
return tspwc;
}
return tspwc;
}
@Override

View File

@ -52,7 +52,6 @@ public class TOADSettingsPaneWithChannels<T> extends ToadManagedSettingsPane<T>
@Override
public boolean useParams(T newParams) {
int chMap = channelPanel.getChannelMap();
System.out.println("Get channel map: " + chMap);
toadBaseAlgorithm.getToadBaseParams().setChannelBitmap(chMap);
int nSelChannels = PamUtils.getNumChannels(chMap);
if (nSelChannels < 3) {
@ -64,6 +63,7 @@ public class TOADSettingsPaneWithChannels<T> extends ToadManagedSettingsPane<T>
@Override
public T findParams() {
System.out.println("CHANNELS: Get channel map: " + toadBaseAlgorithm.getToadBaseParams().getChannelBitmap() + " " + PamUtils.getNumChannels(toadBaseAlgorithm.getToadBaseParams().getChannelBitmap()));
channelPanel.setChannelMap(toadBaseAlgorithm.getToadBaseParams().getChannelBitmap());
toadOptionsPane.setParams(toadBaseAlgorithm.getToadBaseParams());
return null;

View File

@ -225,15 +225,16 @@ public class ToadSimplexLocaliser extends TOADBaseAlgorithm {
// SimpleError cartErr = estimateCartesianError(geometry, toadInformation, posVec);
//FIXME - this return super weird results
EllipticalError ellipErr;
if (usell) {
ellipErr = estimateEllipticalError(geometry, toadInformation, posVec);
}
else {
//FIXME - this elliptical error seems to work far better
SimpleMinimisation simpleMin = new SimpleMinimisation(chiFunc, nDimensions, start, firstStep);
ellipErr = new LikilihoodError(simpleMin, posVec);
}
EllipticalError ellipErr = estimateEllipticalError(geometry, toadInformation, posVec);
// if (usell) {
// ellipErr = estimateEllipticalError(geometry, toadInformation, posVec);
// }
// else {
// ellipErr = estimateEllipticalError(geometry, toadInformation, posVec);
//
//// SimpleMinimisation simpleMin = new SimpleMinimisation(chiFunc, nDimensions, start, firstStep);
//// ellipErr = new LikilihoodError(simpleMin, posVec);
// }

View File

@ -447,20 +447,19 @@ public class GroupLocSettingPaneFX extends SettingsPane<Group3DParams>{
return;
}
PamDataBlock<?> currSource = sourcePanel.getSource();
//note that we get the algorithms from the choice box here because these will already have
//been filtered for suitability depending on array geometry.
for (int i=0; i<this.algorithms.getItems().size(); i++) {
LocaliserAlgorithm3D algoProvider = group3dLocaliserControl.findAlgorithm(this.algorithms.getItems().get(i));
LocaliserAlgorithmParams params = currentParams.getAlgorithmParams(algoProvider);
System.out.println("Set params for: " + algoProvider.getName() + " " + params);
// System.out.println("Set params for: " + algoProvider.getName() + " " + params);
//need this here so that the source pane is created - otherwise channels
algoProvider.prepare(currSource);
if (algoProvider.getAlgorithmSettingsPane()!=null) {
@ -472,15 +471,11 @@ public class GroupLocSettingPaneFX extends SettingsPane<Group3DParams>{
//get the source pane paramters
algoProvider.getSourceSettingsPane(null, currSource).setParams();
}
// if (algoProvider.getSourceSettingsPane(null, null).useParams(params){
//
// }
}
LocaliserAlgorithm3D currAlgo = getSelectedAlgorithm();
if (currAlgo == null) {
return;

View File

@ -382,8 +382,9 @@ public class PamVector implements Serializable, Cloneable, PamCoordinate, Manage
* @return magnitude of those dimensions only.
*/
public double norm(int nDim) {
return Math.sqrt(normSquared(2));
return Math.sqrt(normSquared(nDim));
}
/**
*
* @param vec a PamVector