package gdsc.smlm.model;
import java.awt.Rectangle;
import gdsc.smlm.function.gaussian.Gaussian2DFunction;
import gdsc.smlm.ij.results.IJImagePeakResults;
import gdsc.smlm.results.MemoryPeakResults;
import org.apache.commons.math3.random.RandomGenerator;
import org.apache.commons.math3.random.Well19937c;
import org.junit.Assert;
import org.junit.Test;
public class SphericalDistributionTest
{
private RandomGenerator rand = new Well19937c(System.currentTimeMillis() + System.identityHashCode(this));
@Test
public void canSampleUsingTransformationMethod()
{
double radius = 10 + rand.nextDouble() * 10;
SphericalDistribution dist = new SphericalDistribution(radius, rand);
dist.setUseRejectionMethod(false);
for (int i = 100; i-- > 0;)
dist.next();
}
@Test
public void canSampleUsingRejectionMethod()
{
double radius = 10 + rand.nextDouble() * 10;
SphericalDistribution dist = new SphericalDistribution(radius, rand);
dist.setUseRejectionMethod(true);
for (int i = 100; i-- > 0;)
dist.next();
}
@Test
public void rejectionMethodIsFasterThanTransformationMethod()
{
double radius = 10 + rand.nextDouble() * 10;
SphericalDistribution dist = new SphericalDistribution(radius, rand);
dist.setUseRejectionMethod(false);
for (int i = 100; i-- > 0;)
dist.next();
dist.setUseRejectionMethod(true);
for (int i = 100; i-- > 0;)
dist.next();
dist.setUseRejectionMethod(false);
long time1 = getRunTime(dist);
dist.setUseRejectionMethod(true);
long time2 = getRunTime(dist);
String msg = String.format("Rejection = %d, Transformation = %d\n", time2, time1);
Assert.assertTrue("Rejection method is slower: " + msg, time1 > time2);
System.out.printf(msg);
}
private long getRunTime(SphericalDistribution dist)
{
long start = System.nanoTime();
for (int i = 1000000; i-- > 0;)
dist.next();
return System.nanoTime() - start;
}
// These are not tests. They draw an image and use classes outside the package.
// Comment out for production code.
//@Test
public void rejectionMethodSamplesEvenly()
{
drawImage(true);
}
//@Test
public void transformationMethodSamplesEvenly()
{
drawImage(false);
}
private void drawImage(boolean useRejctionMethod)
{
MemoryPeakResults results = new MemoryPeakResults();
results.setSortAfterEnd(true);
int radius = 10;
Rectangle bounds = new Rectangle(0, 0, radius * 2, radius * 2);
SphericalDistribution dist = new SphericalDistribution(radius, rand);
dist.setUseRejectionMethod(useRejctionMethod);
float scale = 10;
results.begin();
for (int i = 100000; i-- > 0;)
{
double[] xyz = dist.next();
int peak = (int) (1 + scale*radius + Math.round(scale * xyz[2]));
float[] params = new float[7];
params[Gaussian2DFunction.X_POSITION] = radius + (float) xyz[0];
params[Gaussian2DFunction.Y_POSITION] = radius + (float) xyz[1];
results.addf(peak, 0, 0, 0, 0, 0, params, null);
}
results.end();
IJImagePeakResults image = new IJImagePeakResults((useRejctionMethod) ? "Rejection Method"
: "Transformation Method", bounds, scale);
image.setRollingWindowSize(1);
image.begin();
image.addAll(results.getResults());
// Place breakpoint here in debug mode to view the image.
// It should have an even colour through the stack.
image.end();
}
}