use of org.apache.commons.math3.random.RandomGenerator in project GDSC-SMLM by aherbert.
the class AiryPSFModel method sample.
/**
* Sample from an Airy distribution
*
* @param n
* The number of samples
* @param x0
* The centre in dimension 0
* @param x1
* The centre in dimension 1
* @param w0
* The Airy width for dimension 0
* @param w1
* The Airy width for dimension 1
* @return The sample x and y values
*/
public double[][] sample(final int n, final double x0, final double x1, final double w0, final double w1) {
this.w0 = w0;
this.w1 = w1;
if (spline == null)
createAiryDistribution();
double[] x = new double[n];
double[] y = new double[n];
final RandomGenerator random = rand.getRandomGenerator();
UnitSphereRandomVectorGenerator vg = new UnitSphereRandomVectorGenerator(2, random);
int c = 0;
for (int i = 0; i < n; i++) {
final double p = random.nextDouble();
if (p > POWER[SAMPLE_RINGS]) {
// TODO - We could add a simple interpolation here using a spline from AiryPattern.power()
continue;
}
final double r = spline.value(p);
// Convert to xy using a random vector generator
final double[] v = vg.nextVector();
x[c] = v[0] * r * w0 + x0;
y[c] = v[1] * r * w1 + x1;
c++;
}
if (c < n) {
x = Arrays.copyOf(x, c);
y = Arrays.copyOf(y, c);
}
return new double[][] { x, y };
}
use of org.apache.commons.math3.random.RandomGenerator in project GDSC-SMLM by aherbert.
the class DiffusionRateTest method run.
/*
* (non-Javadoc)
*
* @see ij.plugin.PlugIn#run(java.lang.String)
*/
public void run(String arg) {
SMLMUsageTracker.recordPlugin(this.getClass(), arg);
if (IJ.controlKeyDown()) {
simpleTest();
return;
}
extraOptions = Utils.isExtraOptions();
if (!showDialog())
return;
lastSimulatedDataset[0] = lastSimulatedDataset[1] = "";
lastSimulatedPrecision = 0;
final int totalSteps = (int) Math.ceil(settings.seconds * settings.stepsPerSecond);
conversionFactor = 1000000.0 / (settings.pixelPitch * settings.pixelPitch);
// Diffusion rate is um^2/sec. Convert to pixels per simulation frame.
final double diffusionRateInPixelsPerSecond = settings.diffusionRate * conversionFactor;
final double diffusionRateInPixelsPerStep = diffusionRateInPixelsPerSecond / settings.stepsPerSecond;
final double precisionInPixels = myPrecision / settings.pixelPitch;
final boolean addError = myPrecision != 0;
Utils.log(TITLE + " : D = %s um^2/sec, Precision = %s nm", Utils.rounded(settings.diffusionRate, 4), Utils.rounded(myPrecision, 4));
Utils.log("Mean-displacement per dimension = %s nm/sec", Utils.rounded(1e3 * ImageModel.getRandomMoveDistance(settings.diffusionRate), 4));
if (extraOptions)
Utils.log("Step size = %s, precision = %s", Utils.rounded(ImageModel.getRandomMoveDistance(diffusionRateInPixelsPerStep)), Utils.rounded(precisionInPixels));
// Convert diffusion co-efficient into the standard deviation for the random walk
final double diffusionSigma = (settings.getDiffusionType() == DiffusionType.LINEAR_WALK) ? // Q. What should this be? At the moment just do 1D diffusion on a random vector
ImageModel.getRandomMoveDistance(diffusionRateInPixelsPerStep) : ImageModel.getRandomMoveDistance(diffusionRateInPixelsPerStep);
Utils.log("Simulation step-size = %s nm", Utils.rounded(settings.pixelPitch * diffusionSigma, 4));
// Move the molecules and get the diffusion rate
IJ.showStatus("Simulating ...");
final long start = System.nanoTime();
final long seed = System.currentTimeMillis() + System.identityHashCode(this);
RandomGenerator[] random = new RandomGenerator[3];
RandomGenerator[] random2 = new RandomGenerator[3];
for (int i = 0; i < 3; i++) {
random[i] = new Well19937c(seed + i * 12436);
random2[i] = new Well19937c(seed + i * 678678 + 3);
}
Statistics[] stats2D = new Statistics[totalSteps];
Statistics[] stats3D = new Statistics[totalSteps];
StoredDataStatistics jumpDistances2D = new StoredDataStatistics(totalSteps);
StoredDataStatistics jumpDistances3D = new StoredDataStatistics(totalSteps);
for (int j = 0; j < totalSteps; j++) {
stats2D[j] = new Statistics();
stats3D[j] = new Statistics();
}
SphericalDistribution dist = new SphericalDistribution(settings.confinementRadius / settings.pixelPitch);
Statistics asymptote = new Statistics();
// Save results to memory
MemoryPeakResults results = new MemoryPeakResults(totalSteps);
Calibration cal = new Calibration(settings.pixelPitch, 1, 1000.0 / settings.stepsPerSecond);
results.setCalibration(cal);
results.setName(TITLE);
int peak = 0;
// Store raw coordinates
ArrayList<Point> points = new ArrayList<Point>(totalSteps);
StoredData totalJumpDistances1D = new StoredData(settings.particles);
StoredData totalJumpDistances2D = new StoredData(settings.particles);
StoredData totalJumpDistances3D = new StoredData(settings.particles);
for (int i = 0; i < settings.particles; i++) {
if (i % 16 == 0) {
IJ.showProgress(i, settings.particles);
if (Utils.isInterrupted())
return;
}
// Increment the frame so that tracing analysis can distinguish traces
peak++;
double[] origin = new double[3];
final int id = i + 1;
MoleculeModel m = new MoleculeModel(id, origin.clone());
if (addError)
origin = addError(origin, precisionInPixels, random);
if (useConfinement) {
// Note: When using confinement the average displacement should asymptote
// at the average distance of a point from the centre of a ball. This is 3r/4.
// See: http://answers.yahoo.com/question/index?qid=20090131162630AAMTUfM
// The equivalent in 2D is 2r/3. However although we are plotting 2D distance
// this is a projection of the 3D position onto the plane and so the particles
// will not be evenly spread (there will be clustering at centre caused by the
// poles)
final double[] axis = (settings.getDiffusionType() == DiffusionType.LINEAR_WALK) ? nextVector() : null;
for (int j = 0; j < totalSteps; j++) {
double[] xyz = m.getCoordinates();
double[] originalXyz = xyz.clone();
for (int n = confinementAttempts; n-- > 0; ) {
if (settings.getDiffusionType() == DiffusionType.GRID_WALK)
m.walk(diffusionSigma, random);
else if (settings.getDiffusionType() == DiffusionType.LINEAR_WALK)
m.slide(diffusionSigma, axis, random[0]);
else
m.move(diffusionSigma, random);
if (!dist.isWithin(m.getCoordinates())) {
// Reset position
for (int k = 0; k < 3; k++) xyz[k] = originalXyz[k];
} else {
// The move was allowed
break;
}
}
points.add(new Point(id, xyz));
if (addError)
xyz = addError(xyz, precisionInPixels, random2);
peak = record(xyz, id, peak, stats2D[j], stats3D[j], jumpDistances2D, jumpDistances3D, origin, results);
}
asymptote.add(distance(m.getCoordinates()));
} else {
if (settings.getDiffusionType() == DiffusionType.GRID_WALK) {
for (int j = 0; j < totalSteps; j++) {
m.walk(diffusionSigma, random);
double[] xyz = m.getCoordinates();
points.add(new Point(id, xyz));
if (addError)
xyz = addError(xyz, precisionInPixels, random2);
peak = record(xyz, id, peak, stats2D[j], stats3D[j], jumpDistances2D, jumpDistances3D, origin, results);
}
} else if (settings.getDiffusionType() == DiffusionType.LINEAR_WALK) {
final double[] axis = nextVector();
for (int j = 0; j < totalSteps; j++) {
m.slide(diffusionSigma, axis, random[0]);
double[] xyz = m.getCoordinates();
points.add(new Point(id, xyz));
if (addError)
xyz = addError(xyz, precisionInPixels, random2);
peak = record(xyz, id, peak, stats2D[j], stats3D[j], jumpDistances2D, jumpDistances3D, origin, results);
}
} else {
for (int j = 0; j < totalSteps; j++) {
m.move(diffusionSigma, random);
double[] xyz = m.getCoordinates();
points.add(new Point(id, xyz));
if (addError)
xyz = addError(xyz, precisionInPixels, random2);
peak = record(xyz, id, peak, stats2D[j], stats3D[j], jumpDistances2D, jumpDistances3D, origin, results);
}
}
}
// Debug: record all the particles so they can be analysed
// System.out.printf("%f %f %f\n", m.getX(), m.getY(), m.getZ());
final double[] xyz = m.getCoordinates();
double d2 = 0;
totalJumpDistances1D.add(d2 = xyz[0] * xyz[0]);
totalJumpDistances2D.add(d2 += xyz[1] * xyz[1]);
totalJumpDistances3D.add(d2 += xyz[2] * xyz[2]);
}
final double time = (System.nanoTime() - start) / 1000000.0;
IJ.showProgress(1);
MemoryPeakResults.addResults(results);
lastSimulatedDataset[0] = results.getName();
lastSimulatedPrecision = myPrecision;
// Convert pixels^2/step to um^2/sec
final double msd2D = (jumpDistances2D.getMean() / conversionFactor) / (results.getCalibration().getExposureTime() / 1000);
final double msd3D = (jumpDistances3D.getMean() / conversionFactor) / (results.getCalibration().getExposureTime() / 1000);
Utils.log("Raw data D=%s um^2/s, Precision = %s nm, N=%d, step=%s s, mean2D=%s um^2, MSD 2D = %s um^2/s, mean3D=%s um^2, MSD 3D = %s um^2/s", Utils.rounded(settings.diffusionRate), Utils.rounded(myPrecision), jumpDistances2D.getN(), Utils.rounded(results.getCalibration().getExposureTime() / 1000), Utils.rounded(jumpDistances2D.getMean() / conversionFactor), Utils.rounded(msd2D), Utils.rounded(jumpDistances3D.getMean() / conversionFactor), Utils.rounded(msd3D));
aggregateIntoFrames(points, addError, precisionInPixels, random2);
IJ.showStatus("Analysing results ...");
if (showDiffusionExample) {
showExample(totalSteps, diffusionSigma, random);
}
// Plot a graph of mean squared distance
double[] xValues = new double[stats2D.length];
double[] yValues2D = new double[stats2D.length];
double[] yValues3D = new double[stats3D.length];
double[] upper2D = new double[stats2D.length];
double[] lower2D = new double[stats2D.length];
double[] upper3D = new double[stats3D.length];
double[] lower3D = new double[stats3D.length];
SimpleRegression r2D = new SimpleRegression(false);
SimpleRegression r3D = new SimpleRegression(false);
final int firstN = (useConfinement) ? fitN : totalSteps;
for (int j = 0; j < totalSteps; j++) {
// Convert steps to seconds
xValues[j] = (double) (j + 1) / settings.stepsPerSecond;
// Convert values in pixels^2 to um^2
final double mean2D = stats2D[j].getMean() / conversionFactor;
final double mean3D = stats3D[j].getMean() / conversionFactor;
final double sd2D = stats2D[j].getStandardDeviation() / conversionFactor;
final double sd3D = stats3D[j].getStandardDeviation() / conversionFactor;
yValues2D[j] = mean2D;
yValues3D[j] = mean3D;
upper2D[j] = mean2D + sd2D;
lower2D[j] = mean2D - sd2D;
upper3D[j] = mean3D + sd3D;
lower3D[j] = mean3D - sd3D;
if (j < firstN) {
r2D.addData(xValues[j], yValues2D[j]);
r3D.addData(xValues[j], yValues3D[j]);
}
}
// TODO - Fit using the equation for 2D confined diffusion:
// MSD = 4s^2 + R^2 (1 - 0.99e^(-1.84^2 Dt / R^2)
// s = localisation precision
// R = confinement radius
// D = 2D diffusion coefficient
// t = time
final PolynomialFunction fitted2D, fitted3D;
if (r2D.getN() > 0) {
// Do linear regression to get diffusion rate
final double[] best2D = new double[] { r2D.getIntercept(), r2D.getSlope() };
fitted2D = new PolynomialFunction(best2D);
final double[] best3D = new double[] { r3D.getIntercept(), r3D.getSlope() };
fitted3D = new PolynomialFunction(best3D);
// For 2D diffusion: d^2 = 4D
// where: d^2 = mean-square displacement
double D = best2D[1] / 4.0;
String msg = "2D Diffusion rate = " + Utils.rounded(D, 4) + " um^2 / sec (" + Utils.timeToString(time) + ")";
IJ.showStatus(msg);
Utils.log(msg);
D = best3D[1] / 6.0;
Utils.log("3D Diffusion rate = " + Utils.rounded(D, 4) + " um^2 / sec (" + Utils.timeToString(time) + ")");
} else {
fitted2D = fitted3D = null;
}
// Create plots
plotMSD(totalSteps, xValues, yValues2D, lower2D, upper2D, fitted2D, 2);
plotMSD(totalSteps, xValues, yValues3D, lower3D, upper3D, fitted3D, 3);
plotJumpDistances(TITLE, jumpDistances2D, 2, 1);
plotJumpDistances(TITLE, jumpDistances3D, 3, 1);
if (idCount > 0)
new WindowOrganiser().tileWindows(idList);
if (useConfinement)
Utils.log("3D asymptote distance = %s nm (expected %.2f)", Utils.rounded(asymptote.getMean() * settings.pixelPitch, 4), 3 * settings.confinementRadius / 4);
}
use of org.apache.commons.math3.random.RandomGenerator in project GDSC-SMLM by aherbert.
the class DiffusionRateTest method simpleTest.
/**
* Perform a simple diffusion test. This can be used to understand the distributions that are generated during
* 3D diffusion.
*/
private void simpleTest() {
if (!showSimpleDialog())
return;
StoredDataStatistics[] stats2 = new StoredDataStatistics[3];
StoredDataStatistics[] stats = new StoredDataStatistics[3];
RandomGenerator[] random = new RandomGenerator[3];
final long seed = System.currentTimeMillis() + System.identityHashCode(this);
for (int i = 0; i < 3; i++) {
stats2[i] = new StoredDataStatistics(simpleParticles);
stats[i] = new StoredDataStatistics(simpleParticles);
random[i] = new Well19937c(seed + i);
}
final double scale = Math.sqrt(2 * simpleD);
final int report = Math.max(1, simpleParticles / 200);
for (int particle = 0; particle < simpleParticles; particle++) {
if (particle % report == 0)
IJ.showProgress(particle, simpleParticles);
double[] xyz = new double[3];
if (linearDiffusion) {
double[] dir = nextVector();
for (int step = 0; step < simpleSteps; step++) {
final double d = ((random[1].nextDouble() > 0.5) ? -1 : 1) * random[0].nextGaussian();
for (int i = 0; i < 3; i++) {
xyz[i] += dir[i] * d;
}
}
} else {
for (int step = 0; step < simpleSteps; step++) {
for (int i = 0; i < 3; i++) {
xyz[i] += random[i].nextGaussian();
}
}
}
for (int i = 0; i < 3; i++) xyz[i] *= scale;
double msd = 0;
for (int i = 0; i < 3; i++) {
msd += xyz[i] * xyz[i];
stats2[i].add(msd);
// Store the actual distances
stats[i].add(xyz[i]);
}
}
IJ.showProgress(1);
for (int i = 0; i < 3; i++) {
plotJumpDistances(TITLE, stats2[i], i + 1);
// Save stats to file for fitting
save(stats2[i], i + 1, "msd");
save(stats[i], i + 1, "d");
}
if (idCount > 0)
new WindowOrganiser().tileWindows(idList);
}
use of org.apache.commons.math3.random.RandomGenerator in project GDSC-SMLM by aherbert.
the class DiffusionRateTest method msdAnalysis.
/**
* Tabulate the observed MSD for different jump distances
*
* @param points
*/
private void msdAnalysis(ArrayList<Point> points) {
if (myMsdAnalysisSteps == 0)
return;
IJ.showStatus("MSD analysis ...");
IJ.showProgress(1, myMsdAnalysisSteps);
// This will only be fast if the list is an array
Point[] list = points.toArray(new Point[points.size()]);
// Compute the base MSD
Point origin = new Point(0, 0, 0);
double sum = origin.distance2(list[0]);
int count = 1;
for (int i = 1; i < list.length; i++) {
Point last = list[i - 1];
Point current = list[i];
if (last.id == current.id) {
sum += last.distance2(current);
} else {
sum += origin.distance2(current);
}
count++;
}
createMsdTable((sum / count) * settings.stepsPerSecond / conversionFactor);
// Create a new set of points that have coordinates that
// are the rolling average over the number of aggregate steps
RollingArray x = new RollingArray(aggregateSteps);
RollingArray y = new RollingArray(aggregateSteps);
int id = 0;
int length = 0;
for (Point p : points) {
if (p.id != id) {
x.reset();
y.reset();
}
id = p.id;
x.add(p.x);
y.add(p.y);
// Only create a point if the full aggregation size is reached
if (x.isFull()) {
list[length++] = new Point(id, x.getAverage(), y.getAverage());
}
}
// Q - is this useful?
final double p = myPrecision / settings.pixelPitch;
final long seed = System.currentTimeMillis() + System.identityHashCode(this);
RandomGenerator rand = new Well19937c(seed);
final int totalSteps = (int) Math.ceil(settings.seconds * settings.stepsPerSecond - aggregateSteps);
final int limit = Math.min(totalSteps, myMsdAnalysisSteps);
final int interval = Utils.getProgressInterval(limit);
final ArrayList<String> results = new ArrayList<String>(totalSteps);
for (int step = 1; step <= myMsdAnalysisSteps; step++) {
if (step % interval == 0)
IJ.showProgress(step, limit);
sum = 0;
count = 0;
for (int i = step; i < length; i++) {
Point last = list[i - step];
Point current = list[i];
if (last.id == current.id) {
if (p == 0) {
sum += last.distance2(current);
count++;
} else {
// is the same if enough samples are present
for (int ii = 1; ii-- > 0; ) {
sum += last.distance2(current, p, rand);
count++;
}
}
}
}
if (count == 0)
break;
results.add(addResult(step, sum, count));
// Flush to auto-space the columns
if (step == 9) {
msdTable.getTextPanel().append(results);
results.clear();
}
}
msdTable.getTextPanel().append(results);
IJ.showProgress(1);
}
use of org.apache.commons.math3.random.RandomGenerator in project GDSC-SMLM by aherbert.
the class FilterTest method directCompareMultiFilterIsFaster.
@Test
public void directCompareMultiFilterIsFaster() {
RandomGenerator randomGenerator = new Well19937c(System.currentTimeMillis() + System.identityHashCode(this));
final MultiFilter f1 = new MultiFilter(0, 0, 0, 0, 0, 0, 0);
final MultiFilter2 f2 = new MultiFilter2(0, 0, 0, 0, 0, 0, 0);
final double[][][] data = new double[1000][][];
for (int i = data.length; i-- > 0; ) {
data[i] = new double[][] { random(f1.getNumberOfParameters(), randomGenerator), random(f1.getNumberOfParameters(), randomGenerator) };
}
TimingService ts = new TimingService();
ts.execute(new TimingTask() {
public Object getData(int i) {
return new MultiFilter[] { (MultiFilter) f1.create(data[i][0]), (MultiFilter) f1.create(data[i][1]) };
}
public Object run(Object data) {
MultiFilter f1 = ((MultiFilter[]) data)[0];
MultiFilter f2 = ((MultiFilter[]) data)[1];
f1.weakest((Filter) f2);
return null;
}
public void check(int i, Object result) {
}
public int getSize() {
return data.length;
}
public String getName() {
return "MultiFilter";
}
});
ts.execute(new TimingTask() {
public Object getData(int i) {
return new MultiFilter[] { (MultiFilter) f1.create(data[i][0]), (MultiFilter) f1.create(data[i][1]) };
}
public Object run(Object data) {
MultiFilter f1 = ((MultiFilter[]) data)[0];
MultiFilter f2 = ((MultiFilter[]) data)[1];
f1.weakest(f2);
return null;
}
public void check(int i, Object result) {
}
public int getSize() {
return data.length;
}
public String getName() {
return "MultiFilter direct";
}
});
ts.execute(new TimingTask() {
public Object getData(int i) {
return new MultiFilter2[] { (MultiFilter2) f2.create(data[i][0]), (MultiFilter2) f2.create(data[i][1]) };
}
public Object run(Object data) {
MultiFilter2 f1 = ((MultiFilter2[]) data)[0];
MultiFilter2 f2 = ((MultiFilter2[]) data)[1];
f1.weakest((Filter) f2);
return null;
}
public void check(int i, Object result) {
}
public int getSize() {
return data.length;
}
public String getName() {
return "MultiFilter2";
}
});
ts.execute(new TimingTask() {
public Object getData(int i) {
return new MultiFilter2[] { (MultiFilter2) f2.create(data[i][0]), (MultiFilter2) f2.create(data[i][1]) };
}
public Object run(Object data) {
MultiFilter2 f1 = ((MultiFilter2[]) data)[0];
MultiFilter2 f2 = ((MultiFilter2[]) data)[1];
f1.weakest(f2);
return null;
}
public void check(int i, Object result) {
}
public int getSize() {
return data.length;
}
public String getName() {
return "MultiFilter2 direct";
}
});
ts.check();
int size = ts.repeat();
ts.repeat(size);
ts.report();
for (int i = 0; i < ts.getSize(); i += 2) {
TimingResult slow = ts.get(i);
TimingResult fast = ts.get(i + 1);
Assert.assertTrue(slow.getMin() > fast.getMin());
}
}
Aggregations