use of uk.ac.sussex.gdsc.smlm.results.DynamicMultipleTargetTracing.DmttConfiguration in project GDSC-SMLM by aherbert.
the class TraceDiffusion method showTraceDialog.
private boolean showTraceDialog(ArrayList<MemoryPeakResults> allResults) {
final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
gd.addHelp(HelpUrls.getUrl("trace-diffusion"));
if (!multiMode) {
ResultsManager.addInput(gd, settings.inputOption, InputSource.MEMORY);
}
clusteringSettings = SettingsManager.readClusteringSettings(0).toBuilder();
gd.addChoice("Mode", TRACE_MODE, clusteringSettings.getTraceDiffusionMode(), new OptionListener<Integer>() {
@Override
public boolean collectOptions(Integer value) {
clusteringSettings.setTraceDiffusionMode(value);
return collectOptions(false);
}
@Override
public boolean collectOptions() {
return collectOptions(true);
}
private boolean collectOptions(boolean silent) {
final ExtendedGenericDialog egd = new ExtendedGenericDialog("Trace diffusion options", null);
// Only 2 modes
if (clusteringSettings.getTraceDiffusionMode() == 1) {
// Dynamic Multiple Target Tracing
final TextField tfD = egd.addAndGetNumericField("Diffusion_coefficient", clusteringSettings.getDiffusionCoefficentMaximum(), 3, 6, "um^2/s");
final TextField tfW = egd.addAndGetNumericField("Temporal_window", clusteringSettings.getTemporalWindow(), 0, 6, "frames");
final TextField tfLdw = egd.addAndGetNumericField("Local_diffusion_weight", clusteringSettings.getLocalDiffusionWeight(), 2);
final TextField tfOiw = egd.addAndGetNumericField("On_intensity_weight", clusteringSettings.getOnIntensityWeight(), 2);
final TextField tfDdf = egd.addAndGetNumericField("Disappearance_decay_factor", clusteringSettings.getDisappearanceDecayFactor(), 0, 6, "frames");
final TextField tfDt = egd.addAndGetNumericField("Disappearance_threshold", clusteringSettings.getDisappearanceThreshold(), 0, 6, "frames");
final Checkbox cbDld = egd.addAndGetCheckbox("Disable_local_diffusion_model", clusteringSettings.getDisableLocalDiffusionModel());
final Checkbox cbDim = egd.addAndGetCheckbox("Disable_intensity_model", clusteringSettings.getDisableIntensityModel());
// Allow reset to defaults
egd.addAndGetButton("Defaults", e -> {
final DmttConfiguration config = DmttConfiguration.newBuilder(1).build();
tfD.setText(String.valueOf(clusteringSettings.getDiffusionCoefficentMaximum()));
tfW.setText(String.valueOf(config.getTemporalWindow()));
tfLdw.setText(String.valueOf(config.getLocalDiffusionWeight()));
tfOiw.setText(String.valueOf(config.getOnIntensityWeight()));
tfDdf.setText(String.valueOf(config.getDisappearanceDecayFactor()));
tfDt.setText(String.valueOf(config.getDisappearanceThreshold()));
cbDld.setState(config.isDisableLocalDiffusionModel());
cbDim.setState(config.isDisableIntensityModel());
});
} else {
// Nearest Neighbour
egd.addNumericField("Distance_Threshold (nm)", clusteringSettings.getDistanceThreshold(), 0);
egd.addNumericField("Distance_Exclusion (nm)", clusteringSettings.getDistanceExclusion(), 0);
}
egd.setSilent(silent);
egd.showDialog(true, gd);
if (egd.wasCanceled()) {
return false;
}
if (clusteringSettings.getTraceDiffusionMode() == 1) {
// Dynamic Multiple Target Tracing
clusteringSettings.setDiffusionCoefficentMaximum(egd.getNextNumber());
clusteringSettings.setTemporalWindow((int) egd.getNextNumber());
clusteringSettings.setLocalDiffusionWeight(egd.getNextNumber());
clusteringSettings.setOnIntensityWeight(egd.getNextNumber());
clusteringSettings.setDisappearanceDecayFactor(egd.getNextNumber());
clusteringSettings.setDisappearanceThreshold((int) egd.getNextNumber());
clusteringSettings.setDisableLocalDiffusionModel(egd.getNextBoolean());
clusteringSettings.setDisableIntensityModel(egd.getNextBoolean());
} else {
// Nearest Neighbour
clusteringSettings.setDistanceThreshold(egd.getNextNumber());
clusteringSettings.setDistanceExclusion(Math.abs(egd.getNextNumber()));
}
return true;
}
});
gd.addSlider("Min_trace_length", 2, 20, clusteringSettings.getMinimumTraceLength());
gd.addCheckbox("Ignore_ends", clusteringSettings.getIgnoreEnds());
gd.addCheckbox("Save_traces", clusteringSettings.getSaveTraces());
gd.showDialog();
if (gd.wasCanceled() || !readTraceDialog(gd)) {
return false;
}
// Update the settings
SettingsManager.writeSettings(clusteringSettings.build());
// Load the results
if (!multiMode) {
final MemoryPeakResults results = ResultsManager.loadInputResults(settings.inputOption, true, null, null);
if (MemoryPeakResults.isEmpty(results)) {
IJ.error(TITLE, "No results could be loaded");
IJ.showStatus("");
return false;
}
if (!checkCalibration(results)) {
return false;
}
allResults.add(results);
}
return true;
}
use of uk.ac.sussex.gdsc.smlm.results.DynamicMultipleTargetTracing.DmttConfiguration in project GDSC-SMLM by aherbert.
the class DynamicMultipleTargetTracingTest method checkBuilderDefaults.
@SeededTest
void checkBuilderDefaults(RandomSeed seed) {
final UniformRandomProvider rng = RngUtils.create(seed.getSeed());
final double diffusionCoefficientMaximum = 1 + rng.nextDouble();
final DmttConfiguration.Builder b = DmttConfiguration.newBuilder(diffusionCoefficientMaximum);
final DmttConfiguration c1 = b.build();
// Check round-trip
for (final DmttConfiguration config : new DmttConfiguration[] { c1, c1.toBuilder().build() }) {
Assertions.assertEquals(diffusionCoefficientMaximum, config.getDiffusionCoefficientMaximum());
Assertions.assertTrue(config.getTemporalWindow() > 1);
Assertions.assertTrue(config.getLocalDiffusionWeight() >= 0);
Assertions.assertTrue(config.getLocalDiffusionWeight() <= 1);
Assertions.assertTrue(config.getOnIntensityWeight() >= 0);
Assertions.assertTrue(config.getOnIntensityWeight() <= 1);
Assertions.assertTrue(config.getDisappearanceDecayFactor() > 0);
Assertions.assertTrue(config.getDisappearanceThreshold() > 0);
Assertions.assertFalse(config.isDisableIntensityModel());
Assertions.assertFalse(config.isDisableLocalDiffusionModel());
}
}
use of uk.ac.sussex.gdsc.smlm.results.DynamicMultipleTargetTracing.DmttConfiguration in project GDSC-SMLM by aherbert.
the class DynamicMultipleTargetTracingTest method testTraceMoleculesDisableLocalDiffusionModel.
/**
* Test trace molecules using 2 molecules. One is fixed and the other moves past it. The tracing
* should assign the fixed molecule correctly as it has a low local diffusion rate.
*/
@Test
void testTraceMoleculesDisableLocalDiffusionModel() {
// The test is not very robust and fails 20% of the time. A fixed seed corrects this.
final UniformRandomProvider rng = RngUtils.create(0x12345L);
final NormalizedGaussianSampler gauss = SamplerUtils.createNormalizedGaussianSampler(rng);
// localisation precision (in pixels)
final double s = 0.1;
final SharedStateContinuousSampler intensity1 = SamplerUtils.createGaussianSampler(rng, 1000, 100);
final SharedStateContinuousSampler intensity2 = SamplerUtils.createGaussianSampler(rng, 500, 50);
final MemoryPeakResults results = new MemoryPeakResults(100);
final CalibrationWriter writer = results.getCalibrationWriterSafe();
// 0.1 um pixels, 1 second exposure time
writer.setDistanceUnit(DistanceUnit.PIXEL);
writer.setNmPerPixel(100);
writer.setExposureTime(1000);
results.setCalibration(writer.getCalibration());
// First molecule diffuses roughly across the field from top-left to bottom-right.
// 5 frames is the default for local stats, 15 frames for trajectory removal.
// Use 20 so we build local stats and can expire a trajectory.
final int size = 20;
for (int i = 0; i < size; i++) {
results.add(new PeakResult(i, (float) (i + gauss.sample() * s), (float) (i + gauss.sample() * s), (float) (intensity1.sample())));
}
// Second molecule is fixed in the centre with a lower intensity (allow
// correct matching when tracks overlap)
final int x = size / 2;
for (int i = 0; i < size; i++) {
results.add(new PeakResult(i, (float) (x + gauss.sample() * s), (float) (x + gauss.sample() * s), (float) (intensity2.sample())));
}
// Add a single molecule that will not connect to anything in the second frame.
// This should create a trajectory that will expire.
results.add(new PeakResult(1, size, size, (float) (intensity1.sample())));
// Move centre to centre each jump => sqrt(2 * 0.1^2) = 0.141 um or 0.02 um^2
// MSD = 4D => D = 0.02 / 4 = 0.005
final DmttConfiguration config = DmttConfiguration.newBuilder(0.005).setDisableLocalDiffusionModel(true).setTemporalWindow(10).build();
final List<Trace> traces = new DynamicMultipleTargetTracing(results).traceMolecules(config);
// Should have 3 traces
Assertions.assertEquals(3, traces.size());
// Assert ids start from 1
for (int i = 0; i < traces.size(); i++) {
Assertions.assertEquals(i + 1, traces.get(i).getId());
}
// Traces should be 2 full length and 1 single peak
Assertions.assertEquals(size, traces.get(0).size());
Assertions.assertEquals(size, traces.get(1).size());
Assertions.assertEquals(1, traces.get(2).size());
// Do an analysis on the actual tracks.
// One should be based in the centre and the other should have parts close to position (i,i)
// for each frame i.
final PeakResult[] peaks = results.toArray();
// Assume traces are initially created using the input order of the results.
final Trace t1 = traces.get(0);
final Trace t2 = traces.get(1);
for (int i = 0; i < size; i++) {
Assertions.assertSame(peaks[i], t1.get(i));
Assertions.assertSame(peaks[i + size], t2.get(i));
}
}
use of uk.ac.sussex.gdsc.smlm.results.DynamicMultipleTargetTracing.DmttConfiguration in project GDSC-SMLM by aherbert.
the class DynamicMultipleTargetTracingTest method testTraceMolecules.
/**
* Test trace molecules using 2 molecules. One is fixed and the other moves across it. The tracing
* should assign the fixed molecule correctly as it has a low local diffusion rate and different
* intensity.
*/
@Test
void testTraceMolecules() {
// The test is not very robust and fails 10% of the time. A fixed seed corrects this.
final UniformRandomProvider rng = RngUtils.create(0x12345L);
final NormalizedGaussianSampler gauss = SamplerUtils.createNormalizedGaussianSampler(rng);
// localisation precision (in pixels)
final double s = 0.1;
final SharedStateContinuousSampler intensity1 = SamplerUtils.createGaussianSampler(rng, 1000, 100);
final SharedStateContinuousSampler intensity2 = SamplerUtils.createGaussianSampler(rng, 500, 50);
final MemoryPeakResults results = new MemoryPeakResults(100);
final CalibrationWriter writer = results.getCalibrationWriterSafe();
// 0.1 um pixels, 1 second exposure time
writer.setDistanceUnit(DistanceUnit.PIXEL);
writer.setNmPerPixel(100);
writer.setExposureTime(1000);
results.setCalibration(writer.getCalibration());
// First molecule diffuses roughly across the field from top-left to bottom-right.
// 5 frames is the default for local stats, 15 frames for trajectory removal.
// Use 20 so we build local stats and can expire a trajectory.
final int size = 20;
for (int i = 0; i < size; i++) {
results.add(new PeakResult(i, (float) (i + gauss.sample() * s), (float) (i + gauss.sample() * s), (float) (intensity1.sample())));
}
// Second molecule is fixed in the centre with a lower intensity (allow
// correct matching when tracks overlap)
final int x = size / 2;
for (int i = 0; i < size; i++) {
results.add(new PeakResult(i, (float) (x + gauss.sample() * s), (float) (x + gauss.sample() * s), (float) (intensity2.sample())));
}
// Add a single molecule that will not connect to anything in the second frame.
// This should create a trajectory that will expire.
results.add(new PeakResult(1, size, size, (float) (intensity1.sample())));
// 1 diffuses top-left to bottom-right.
// 2 is fixed in the centre.
// 3 is in the bottom-right for 1 frame.
//
// 1
// 1
// 1
// 12
// 1
// 1
// 13
//
// Molecule 3 can sometimes connect to the long lifetime molecules once they have been alive
// long enough to create a local probability model. The default lifetime is 5 frames.
// Setting this to 10 frames allows a better local model to be created.
// Move centre to centre each jump => sqrt(2 * 0.1^2) = 0.141 um or 0.02 um^2
// MSD = 4D => D = 0.02 / 4 = 0.005
final DmttConfiguration config = DmttConfiguration.newBuilder(0.005).setTemporalWindow(10).build();
final List<Trace> traces = new DynamicMultipleTargetTracing(results).traceMolecules(config);
// Should have 3 traces
Assertions.assertEquals(3, traces.size());
// Assert ids start from 1
for (int i = 0; i < traces.size(); i++) {
Assertions.assertEquals(i + 1, traces.get(i).getId());
}
// Traces should be 2 full length and 1 single peak
Assertions.assertEquals(size, traces.get(0).size());
Assertions.assertEquals(size, traces.get(1).size());
Assertions.assertEquals(1, traces.get(2).size());
// Do an analysis on the actual tracks.
// One should be based in the centre and the other should have parts close to position (i,i)
// for each frame i.
final PeakResult[] peaks = results.toArray();
// Assume traces are initially created using the input order of the results.
final Trace t1 = traces.get(0);
final Trace t2 = traces.get(1);
for (int i = 0; i < size; i++) {
Assertions.assertSame(peaks[i], t1.get(i));
Assertions.assertSame(peaks[i + size], t2.get(i));
}
}
Aggregations