package cz.cuni.lf1.lge.ThunderSTORM.rendering;
import cz.cuni.lf1.lge.ThunderSTORM.rendering.ui.HistogramRenderingUI;
import ij.process.FloatProcessor;
import java.util.Random;
/**
* Rendering using a two-dimensional histogram. When average parameter is set as
* > 0, the result is the average of multiple histograms, each made from
* molecule locations jittered according to the uncertainty of localization
* (dx).
*/
public class HistogramRendering extends AbstractRendering implements IncrementalRenderingMethod {
protected int avg;
protected Random rnd = new Random();
private HistogramRendering(Builder builder) {
super(builder);
this.avg = builder.avg;
}
@Override
public String getRendererName() {
return HistogramRenderingUI.name;
}
public static class Builder extends AbstractBuilder<Builder, HistogramRendering> {
protected int avg = 0;
/**
* Sets how many jittered histograms are calculated and averaged to
* create the final image.
*/
public Builder average(int avg) {
if(avg < 0) {
throw new IllegalArgumentException("Average parameter must be positive integer. Passed value: " + avg);
}
this.avg = avg;
return this;
}
@Override
public HistogramRendering build() {
super.validate();
return new HistogramRendering(this);
}
}
@Override
protected void drawPoint(double x, double y, double z, double dx, double dz) {
if(avg >= 1) {
for(int i = 0; i < avg; i++) {
double newX = x + rnd.nextGaussian() * dx;
double newY = y + rnd.nextGaussian() * dx;
double newZ = z + rnd.nextGaussian() * dz;
if(isInBounds(newX, newY)) {
int u = (int) ((newX - xmin) / resolution);
int v = (int) ((newY - ymin) / resolution);
int w = threeDimensions ? ((int) ((newZ - zFrom) / zStep)) : 0;
if(w >= 0 && w < zSlices) {
FloatProcessor image = (FloatProcessor) slices[w];
image.setf(u, v, image.getf(u, v) + 1.0f / avg);
}
}
}
} else {
if(isInBounds(x, y)) {
int u = (int) ((x - xmin) / resolution);
int v = (int) ((y - ymin) / resolution);
int w = threeDimensions ? ((int) ((z - zFrom) / zStep)) : 0;
if(w >= 0 && w < zSlices) {
FloatProcessor img = (FloatProcessor) slices[w];
img.setf(u, v, img.getf(u, v) + 1);
}
}
}
}
}