Bug fixes to matched click classifier and TDisplayFX

This commit is contained in:
Jamie Mac 2022-01-28 15:26:50 +00:00
parent 50bb5a6807
commit b2e1afbd74
4 changed files with 63 additions and 13 deletions

View File

@ -184,15 +184,21 @@ public class TDAcousticScroller extends AcousticScrollerFX implements PamSetting
//add a listener so the visible amount changes of the spinner changes value. //add a listener so the visible amount changes of the spinner changes value.
spinner.valueProperty().addListener((obsVal, oldVal, newVal)->{ spinner.valueProperty().addListener((obsVal, oldVal, newVal)->{
if (spinnerCall) return ; //prevent overflow. if (spinnerCall) return ; //prevent overflow
if (newVal<=this.getRangeMillis()) {
/**
* There are two slightly different modes here- in viewer mode we want the spinner to set
* only the visible range. However in real time mode we want it to set the visible time and
* the data keep time.
*/
if (newVal<=this.getRangeMillis() || !isViewer) {
// Debug.out.println("TDAcousticScroller: TimeRangeSpinner: " + newVal); // Debug.out.println("TDAcousticScroller: TimeRangeSpinner: " + newVal);
Platform.runLater(()->{ //why? But seems necessary Platform.runLater(()->{ //why? But seems necessary
super.setVisibleMillis(newVal); super.setVisibleMillis(newVal);
super.setRangeMillis(0, newVal, false);
}); });
} }
else spinner.getValueFactory().decrement(1); //need to use decrement here instead of set time because otherwise arrow buttons else spinner.getValueFactory().decrement(1); //need to use decrement here instead of set time because otherwise arrow buttons
//don't work.
}); });
} }

View File

@ -11,6 +11,9 @@ import com.jmatio.types.MLDouble;
import com.jmatio.types.MLStructure; import com.jmatio.types.MLStructure;
import Filters.SmoothingFilter; import Filters.SmoothingFilter;
import Localiser.DelayMeasurementParams;
import Localiser.algorithms.Correlations;
import Localiser.algorithms.TimeDelayData;
import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.ManagedParameters;
import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PamParameterSet;
import PamModel.parametermanager.PrivatePamParameterData; import PamModel.parametermanager.PrivatePamParameterData;
@ -93,6 +96,15 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
*/ */
transient private WavInterpolator wavInterpolator = new WavInterpolator(); transient private WavInterpolator wavInterpolator = new WavInterpolator();
/**
* The delay measurment parameters.
*/
private transient DelayMeasurementParams delayMeasurementParams = defualtDelayParams();
/**
* Runs the cross correlation algorithm.
*/
private transient Correlations correlations = new Correlations();
/** /**
* Default MT classifier * Default MT classifier
@ -101,6 +113,14 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
fft= new FastFFT(); fft= new FastFFT();
} }
private DelayMeasurementParams defualtDelayParams() {
DelayMeasurementParams delayMeasurementParams = new DelayMeasurementParams();
//delayMeasurementParams.setUpSample(4);
delayMeasurementParams.setFftFilterParams(null);
return delayMeasurementParams;
}
/** /**
* Get the match waveform FFT for the sampleRate. * Get the match waveform FFT for the sampleRate.
* @param fftLength - the FFTlength to use. Bins around waveform peak are used. * @param fftLength - the FFTlength to use. Bins around waveform peak are used.
@ -376,7 +396,7 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
int fftLength = click.length()*2; int fftLength = click.length()*2;
ComplexArray matchResult= new ComplexArray(fftLength); ComplexArray matchResult= new ComplexArray(fftLength);
ComplexArray matchTemplate = getWaveformMatchFFT(sR,fftLength); ComplexArray matchTemplate = getWaveformMatchFFT(sR,fftLength); //remember this is the complex conjugate
//System.out.println("matchTemplate interp: len: " + interpWaveformMatch.length+ " max: " + PamArrayUtils.max(interpWaveformMatch)); //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)); //System.out.println("matchTemplate: len: " + waveformMatch.waveform.length+ " max: " + PamArrayUtils.max(waveformMatch.waveform));
@ -386,7 +406,7 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
} }
ComplexArray rejectResult= new ComplexArray(fftLength); ComplexArray rejectResult= new ComplexArray(fftLength);
ComplexArray rejectTemplate = getWaveformRejectFFT(sR, fftLength); ComplexArray rejectTemplate = getWaveformRejectFFT(sR, fftLength); //remember this is the complex conjugate
for (int i=0; i<Math.min(rejectTemplate.length(), click.length()); i++) { for (int i=0; i<Math.min(rejectTemplate.length(), click.length()); i++) {
rejectResult.set(i, click.get(i).times(rejectTemplate.get(i))); rejectResult.set(i, click.get(i).times(rejectTemplate.get(i)));
} }
@ -396,6 +416,9 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
//System.out.println("Click input: " + click.length() + " click template: " + matchTemplate.length()); //System.out.println("Click input: " + click.length() + " click template: " + matchTemplate.length());
//must use scaling to get the same result as MATLAB //must use scaling to get the same result as MATLAB
if (fft==null) fft= new FastFFT(); if (fft==null) fft= new FastFFT();
fft.ifft(matchResult, fftLength, true); fft.ifft(matchResult, fftLength, true);
@ -424,6 +447,14 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters
double maxmatch=PamArrayUtils.max(matchReal); double maxmatch=PamArrayUtils.max(matchReal);
double maxreject=PamArrayUtils.max(rejectReal); double maxreject=PamArrayUtils.max(rejectReal);
// //TEST
// if (correlations==null) correlations=new Correlations();
// TimeDelayData matchResultTD = correlations.getDelay(click, matchTemplate.conj(), null, sR, fftLength);
// System.out.println("Old xcorr method: " + maxmatch + " new PG method: " + matchResultTD.getDelayScore());
// //TEST
//if set to "none" then reject template will return a NaN - TODO bit messy and inefficient. //if set to "none" then reject template will return a NaN - TODO bit messy and inefficient.
double result; double result;
double maxReject = PamArrayUtils.max(rejectReal); double maxReject = PamArrayUtils.max(rejectReal);

View File

@ -135,13 +135,24 @@ public class MTClassifierTest {
System.out.println(String.format("The match correlation for %d is %.5f", i, matchResult.matchCorr)); System.out.println(String.format("The match correlation for %d is %.5f", i, matchResult.matchCorr));
//
// printFFt(matchClick);
//
// System.out.println("-----------------------");
//
// ComplexArray matchTemplate = mtclassifier.getWaveformMatchFFT(sR, matchClick.length()*2);
//
// printFFt(matchTemplate);
} }
} }
public static void printFFt(ComplexArray complexArray) { public static void printFFt(ComplexArray complexArray) {
for (int i=0; i<complexArray.length(); i++ ) { for (int i=0; i<complexArray.length(); i++ ) {
System.out.println(complexArray.get(i).toString(6)); //System.out.println(complexArray.get(i).toString(6));
System.out.println(complexArray.get(i).real + "," + complexArray.get(i).imag);
} }
} }

View File

@ -65,6 +65,8 @@ public class MTOfflineProcess {
//System.out.println("Click train offline data block " + clickTrainControl.getParentDataBlock()); //System.out.println("Click train offline data block " + clickTrainControl.getParentDataBlock());
mtOfflineGroup.setPrimaryDataBlock(mtContorl.getParentDataBlock()); mtOfflineGroup.setPrimaryDataBlock(mtContorl.getParentDataBlock());
mtOfflineTask.setParentDataBlock(mtContorl.getParentDataBlock()); mtOfflineTask.setParentDataBlock(mtContorl.getParentDataBlock());
//need this to make sure annotations trigger saving.
mtOfflineTask.addAffectedDataBlock(mtContorl.getParentDataBlock());
//if null open the dialog- also create a new offlineTask group if the datablock has changed. //if null open the dialog- also create a new offlineTask group if the datablock has changed.
if (mtOfflineDialog == null) { if (mtOfflineDialog == null) {