mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2024-11-25 08:32:32 +00:00
Bug fixes for matched filter
The match filter used in the matched click classifier was flipping arrays instead of using the complex conjugate for FFT xcorr. Ooops
This commit is contained in:
parent
5aaedec235
commit
cf4e3ccfe1
@ -103,9 +103,14 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
if (waveformMatchFFT==null || currentSr!=sR) {
|
||||
if (fft==null) fft=new FastFFT();
|
||||
|
||||
|
||||
//System.out.println("interpWaveform: " + waveformMatch.waveform.length + " sR " + waveformMatch.sR);
|
||||
|
||||
//re-sample the waveform if the sample rate is different
|
||||
this.interpWaveformMatch=interpWaveform(this.waveformMatch, sR);
|
||||
|
||||
//System.out.println("interpWaveformMatch: " + interpWaveformMatch.length + " sR " + sR);
|
||||
|
||||
//normalise
|
||||
//this.interpWaveformMatch=PamArrayUtils.normalise(interpWaveformMatch);
|
||||
|
||||
@ -115,9 +120,11 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
// System.out.println("MatchNorm: MATCH");
|
||||
// MTClassifierTest.normalizeTest(interpWaveformMatch);
|
||||
|
||||
//here use the FFT length with the maximum template size.
|
||||
waveformMatchFFT = fft.rfft(PamArrayUtils.flip(interpWaveformMatch),
|
||||
length);
|
||||
waveformMatchFFT = fft.rfft(interpWaveformMatch, length);
|
||||
|
||||
//need to calculate the complex conjugate - note that originally I was flipping the array but this means
|
||||
//the max value does not equal one with identical waveforms...doh.
|
||||
waveformMatchFFT = waveformMatchFFT.conj();
|
||||
// System.out.println("waveformMatch: " + waveformMatch.waveform.length +
|
||||
// " interpWaveformMatch: " + interpWaveformMatch.length + " for " +sR + " sr ");
|
||||
|
||||
@ -155,9 +162,11 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
// MTClassifierTest.printWaveform(inteprWaveformReject);
|
||||
|
||||
//System.out.println("waveformReject: " +inteprWaveformReject.length + " fftLength: " + getFFTLength(sR));
|
||||
waveformRejectFFT = fft.rfft(inteprWaveformReject, length);
|
||||
|
||||
//must flip the waveform for cross correlation - might as well do this here.
|
||||
waveformRejectFFT = fft.rfft(PamArrayUtils.flip(inteprWaveformReject), length);
|
||||
//need to calculate the complex conjugate - note that originally I was flipping the array but this means
|
||||
//the max value does not equal one with identical waveforms...doh.
|
||||
waveformRejectFFT = waveformRejectFFT.conj();
|
||||
}
|
||||
return waveformRejectFFT;
|
||||
}
|
||||
@ -342,11 +351,9 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
//set the stored sR
|
||||
currentSr=sR;
|
||||
|
||||
// System.out.println("Matched click classifier: Waveform click: " + click.length());
|
||||
// System.out.println("Matched click classifier: Waveform click: " + click.length());
|
||||
//System.out.println("Waveform click: len: " + click.length());
|
||||
|
||||
// System.out.println("Waveform Reject max: " + PamArrayUtils.max(this.inteprWaveformReject));
|
||||
// System.out.println("Waveform Reject max: " + PamArrayUtils.max(this.inteprWaveformReject));
|
||||
//System.out.println("Waveform Reject max: " + PamArrayUtils.max(this.inteprWaveformReject)+ " len " + interpWaveformMatch.length);
|
||||
|
||||
//int fftLength = getFFTLength(sR);
|
||||
//int fftLength = this.getFFTLength(sR);
|
||||
@ -363,7 +370,10 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
|
||||
ComplexArray matchResult= new ComplexArray(fftLength);
|
||||
ComplexArray matchTemplate = getWaveformMatchFFT(sR,fftLength);
|
||||
//System.out.println("matchTemplate: Waveform click: " + matchTemplate.length());
|
||||
|
||||
//System.out.println("matchTemplate interp: len: " + interpWaveformMatch.length+ " max: " + PamArrayUtils.max(interpWaveformMatch));
|
||||
//System.out.println("matchTemplate: len: " + waveformMatch.waveform.length+ " max: " + PamArrayUtils.max(waveformMatch.waveform));
|
||||
|
||||
for (int i=0; i<Math.min(matchTemplate.length(), click.length()); i++) {
|
||||
matchResult.set(i, click.get(i).times(matchTemplate.get(i)));
|
||||
}
|
||||
@ -387,13 +397,13 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
|
||||
//System.out.println("Inverse MATCH RESULTS");
|
||||
|
||||
//need to take the real part of the result and multiply by 2 to get same as
|
||||
//ifft function in MATLAB
|
||||
//ifft function in MATLAB - dunno why this is...
|
||||
double[] matchReal = new double[matchResult.length()];
|
||||
double[] rejectReal = new double[rejectResult.length()];
|
||||
|
||||
for (int i=0; i<matchResult.length(); i++) {
|
||||
matchReal[i]=matchResult.getReal(i);
|
||||
rejectReal[i]=rejectResult.getReal(i);
|
||||
matchReal[i]=2*matchResult.getReal(i);
|
||||
rejectReal[i]=2*rejectResult.getReal(i);
|
||||
//System.out.println("iFFt match result: " + matchResult.get(i) + " iFFT rejectResult: " + rejectResult.get(i) );
|
||||
}
|
||||
|
||||
|
@ -72,19 +72,32 @@ public class MTClassifierTest {
|
||||
return struct;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the correlation of several templates
|
||||
* @param testWaveform - the waveform to correlate against.
|
||||
* @param sR - the sample rate of the waveform.
|
||||
* @param templates - the match templates to test.
|
||||
*/
|
||||
private static void testCorrelation(double[] testWaveform, float sR, ArrayList<MatchTemplate> templates) {
|
||||
testCorrelation(testWaveform, sR, templates, MatchedTemplateParams.NORMALIZATION_RMS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test the correlation of several templates
|
||||
* @param testWaveform
|
||||
* @param sR
|
||||
* @param templates
|
||||
* @return
|
||||
* @param testWaveform - the waveform to correlate against.
|
||||
* @param sR - the sample rate of the waveform.
|
||||
* @param templates - the match templates to test.
|
||||
* @param normalisation - the normalisation type to use e.g. MatchedTemplateParams.NORMALIZATION_RMS
|
||||
*/
|
||||
private static void testCorrelation(double[] testWaveform, float sR, ArrayList<MatchTemplate> templates) {
|
||||
private static void testCorrelation(double[] testWaveform, float sR, ArrayList<MatchTemplate> templates, int normalisation) {
|
||||
|
||||
//create the classifier object
|
||||
for (int i=0; i<templates.size(); i++){
|
||||
MTClassifier mtclassifier = new MTClassifier();
|
||||
mtclassifier.normalisation = normalisation;
|
||||
|
||||
//System.out.println("Template " + i + " " + templates.get(i));
|
||||
//add templates if inpout
|
||||
@ -97,8 +110,14 @@ public class MTClassifierTest {
|
||||
|
||||
//System.out.println("Waveform len: " +testWaveform.length + " min: " + PamArrayUtils.min(testWaveform) + " max: " + PamArrayUtils.max(testWaveform));
|
||||
|
||||
|
||||
testWaveform=PamArrayUtils.divide(testWaveform, PamUtils.PamArrayUtils.max(testWaveform));
|
||||
|
||||
testWaveform = MTClassifier.normaliseWaveform(testWaveform, MatchedTemplateParams.NORMALIZATION_RMS);
|
||||
|
||||
System.out.println("Waveform max: " + PamArrayUtils.max(testWaveform) + " len: " + testWaveform.length);
|
||||
|
||||
|
||||
//calculate the click FFT.
|
||||
fft = new FastFFT();
|
||||
//int fftSize = FastFFT.nextBinaryExp(testWaveform.length/2);
|
||||
@ -303,7 +322,10 @@ public class MTClassifierTest {
|
||||
|
||||
}
|
||||
|
||||
public static void testMatchCorr() {
|
||||
/**
|
||||
* Test how the length of the waveform affects the match correlation values
|
||||
*/
|
||||
public static void testMatchCorrLen() {
|
||||
|
||||
String testClicksPath = "/Users/au671271/MATLAB-Drive/MATLAB/PAMGUARD/matchedclickclassifer/DS2clks_test.mat";
|
||||
String templteFilePath= "/Users/au671271/MATLAB-Drive/MATLAB/PAMGUARD/matchedclickclassifer/DS2templates_test.mat";
|
||||
@ -333,6 +355,20 @@ public class MTClassifierTest {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the match corr algorithm by cross correlating a waveform with itself.
|
||||
*/
|
||||
public static void testMatchCorr() {
|
||||
|
||||
String templteFilePath= "/Users/au671271/MATLAB-Drive/MATLAB/PAMGUARD/matchedclickclassifer/DS2templates_test.mat";
|
||||
//float sR = 288000; //sample rate in samples per second.
|
||||
|
||||
ArrayList<MatchTemplate> templates = importTemplates(templteFilePath);
|
||||
|
||||
testCorrelation(templates.get(0).waveform, templates.get(0).sR, templates);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void main(String args[]) {
|
||||
testMatchCorr();
|
||||
|
@ -257,7 +257,7 @@ public class MTSettingsPane extends SettingsPane<MatchedTemplateParams> {
|
||||
|
||||
//click normalisation
|
||||
normBox = new ComboBox<String>();
|
||||
normBox.getItems().addAll("peak to peak", "RMS", "none");
|
||||
normBox.getItems().addAll("peak to peak", "norm", "none");
|
||||
|
||||
PamHBox clickNormPane= new PamHBox();
|
||||
clickNormPane.setSpacing(5);
|
||||
|
Loading…
Reference in New Issue
Block a user