use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationProtos.Calibration in project GDSC-SMLM by aherbert.
the class PeakResultsReader method readNStorm.
private MemoryPeakResults readNStorm() {
final MemoryPeakResults results = createResults();
results.setName(FileUtils.getName(filename));
try (FileInputStream fis = new FileInputStream(filename);
BufferedReader input = new BufferedReader(new UnicodeReader(fis, null))) {
final ProgressReporter reporter = createProgressReporter(fis);
String line;
int errors = 0;
// The single line header
final String header = input.readLine();
if (header == null) {
throw new IOException("NStorm header missing");
}
// NStorm files added more column fields for later formats.
// If the header contains 'Photons' then this can be used to determine the gain
boolean readPhotons = header.contains("\tPhotons\t");
while ((line = input.readLine()) != null) {
if (line.isEmpty()) {
continue;
}
final PeakResult result = createNStormResult(line, readPhotons);
if (result != null) {
results.add(result);
// Just read the photons from the first 100
if (readPhotons) {
readPhotons = results.size() < 100;
}
} else if (++errors >= 10) {
break;
}
reporter.showProgress();
}
} catch (final IOException ex) {
logError(ex);
}
// The following relationship holds when length == 1:
// intensity = height * 2 * pi * sd0 * sd1 / pixel_pitch^2
// => Pixel_pitch = sqrt(height * 2 * pi * sd0 * sd1 / intensity)
// Try and create a calibration
final Statistics pixelPitch = new Statistics();
results.forEach(new PeakResultProcedureX() {
static final double TWO_PI = 2 * Math.PI;
@Override
public boolean execute(PeakResult peakResult) {
if (peakResult.getFrame() == peakResult.getEndFrame()) {
final float height = peakResult.getOrigValue();
final float intensity = peakResult.getParameter(PeakResult.INTENSITY);
final float sd0 = peakResult.getParameter(INDEX_SX);
final float sd1 = peakResult.getParameter(INDEX_SY);
pixelPitch.add(Math.sqrt(height * TWO_PI * sd0 * sd1 / intensity));
// Stop when we have enough for a good guess
return (pixelPitch.getN() > 100);
}
return false;
}
});
// Determine the gain using the photons column
final Statistics gain = new Statistics();
results.forEach((PeakResultProcedureX) peakResult -> {
double photons = peakResult.getError();
if (photons != 0) {
peakResult.setError(0);
gain.add(peakResult.getIntensity() / photons);
return false;
}
return true;
});
// TODO - Support all the NSTORM formats: one-axis, two-axis, rotated, 3D.
// Is this information in the header?
// We could support setting the PSF as a Gaussian2D with one/two axis SD.
// This would mean updating all the result params if it is a one axis PSF.
// For now just record it as a 2 axis PSF.
// Create a calibration
calibration = new CalibrationWriter();
// NSTORM data is in counts when the Photons column is present.
// Q. Is it in counts when this column is not present?
calibration.setIntensityUnit(IntensityUnit.COUNT);
calibration.setDistanceUnit(DistanceUnit.NM);
if (pixelPitch.getN() > 0) {
final double nmPerPixel = pixelPitch.getMean();
calibration.setNmPerPixel(nmPerPixel);
}
if (gain.getN() > 0 && gain.getStandardError() < 1e-3) {
calibration.setCountPerPhoton(gain.getMean());
}
results.setCalibration(calibration.getCalibration());
return results;
}
use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationProtos.Calibration in project GDSC-SMLM by aherbert.
the class CalibrationReaderTest method canGetAngleConverter.
@Test
void canGetAngleConverter() {
final Calibration.Builder builder = Calibration.newBuilder();
final AngleCalibration.Builder psfBuilder = builder.getAngleCalibrationBuilder();
psfBuilder.setAngleUnit(AngleUnit.RADIAN);
final Calibration c = builder.build();
final CalibrationReader reader = new CalibrationReader(c);
final TypeConverter<AngleUnit> angleConverter = reader.getAngleConverter(AngleUnit.DEGREE);
Assertions.assertEquals(angleConverter.from(), AngleUnit.RADIAN);
Assertions.assertEquals(angleConverter.to(), AngleUnit.DEGREE);
final TypeConverter<AngleUnit> angleConverter2 = CalibrationHelper.getAngleConverter(c, AngleUnit.DEGREE);
Assertions.assertEquals(angleConverter2.from(), AngleUnit.RADIAN);
Assertions.assertEquals(angleConverter2.to(), AngleUnit.DEGREE);
Assertions.assertEquals(angleConverter.getFunction(), angleConverter2.getFunction());
}
use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationProtos.Calibration in project GDSC-SMLM by aherbert.
the class CalibrationReaderTest method canGetDistanceConverter.
@Test
void canGetDistanceConverter() {
final Calibration.Builder builder = Calibration.newBuilder();
final DistanceCalibration.Builder distanceBuilder = builder.getDistanceCalibrationBuilder();
distanceBuilder.setNmPerPixel(nmPerPixel);
distanceBuilder.setDistanceUnit(DistanceUnit.PIXEL);
final Calibration c = builder.build();
final CalibrationReader reader = new CalibrationReader(c);
final TypeConverter<DistanceUnit> distanceConverter = reader.getDistanceConverter(DistanceUnit.NM);
Assertions.assertEquals(distanceConverter.from(), DistanceUnit.PIXEL);
Assertions.assertEquals(distanceConverter.to(), DistanceUnit.NM);
final TypeConverter<DistanceUnit> distanceConverter2 = CalibrationHelper.getDistanceConverter(c, DistanceUnit.NM);
Assertions.assertEquals(distanceConverter2.from(), DistanceUnit.PIXEL);
Assertions.assertEquals(distanceConverter2.to(), DistanceUnit.NM);
Assertions.assertEquals(distanceConverter.getFunction(), distanceConverter2.getFunction());
}
use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationProtos.Calibration in project GDSC-SMLM by aherbert.
the class TcPalmAnalysis method reportAnalysis.
/**
* Report statistics on the analysis results.
*
* @param settings the settings
* @param clusters the clusters
* @param calibration the data calibration
*/
private static void reportAnalysis(TcPalmAnalysisSettings settings, LocalList<ClusterData> clusters, DataCalibration calibration) {
final WindowOrganiser wo = new WindowOrganiser();
final Consumer<HistogramPlotBuilder> action = builder -> {
/* noop. */
};
plotHistogram(settings.getShowSizeHistogram(), wo, clusters, "Size", c -> c.results.size(), null, action);
plotHistogram(settings.getShowDurationHistogram(), wo, clusters, "Duration (" + calibration.getTimeUnitName() + ")", c -> calibration.timeConverter.convert(c.getDuration()), null, action);
plotHistogram(settings.getShowAreaHistogram(), wo, clusters, "Area (" + calibration.getDistanceUnitName() + "^2)", c -> calibration.convertArea(c.getArea()), null, action);
plotHistogram(settings.getShowDensityHistogram(), wo, clusters, "Density (" + calibration.getDistanceUnitName() + "^-2)", c -> c.results.size() / calibration.convertArea(c.getArea()), Double::isFinite, action);
wo.tile();
}
use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationProtos.Calibration in project GDSC-SMLM by aherbert.
the class SpotFinderPreview method run.
@Override
public void run(ImageProcessor ip) {
if (refreshing) {
return;
}
final Rectangle bounds = ip.getRoi();
// Only do this if the settings changed
final Calibration calibration = fitConfig.getCalibration();
final FitEngineSettings fitEngineSettings = config.getFitEngineSettings();
final PSF psf = fitConfig.getPsf();
boolean newCameraModel = filter == null;
if (!calibration.equals(lastCalibration)) {
newCameraModel = true;
// Set a camera model.
// We have to set the camera type too to avoid configuration errors.
CameraModel cameraModel = CameraModelManager.load(fitConfig.getCameraModelName());
if (cameraModel == null) {
cameraModel = new FakePerPixelCameraModel(0, 1, 1);
fitConfig.setCameraType(CameraType.EMCCD);
} else {
fitConfig.setCameraType(CameraType.SCMOS);
// Support cropped origin selection.
final Rectangle sourceBounds = IJImageSource.getBounds(imp);
cameraModel = PeakFit.cropCameraModel(cameraModel, sourceBounds, null, true);
if (cameraModel == null) {
gd.getPreviewCheckbox().setState(false);
return;
}
}
fitConfig.setCameraModel(cameraModel);
}
if (newCameraModel || !fitEngineSettings.equals(lastFitEngineSettings) || !psf.equals(lastPsf)) {
// Configure a jury filter
if (config.getDataFilterType() == DataFilterType.JURY && !PeakFit.configureDataFilter(config, PeakFit.FLAG_NO_SAVE)) {
gd.getPreviewCheckbox().setState(false);
return;
}
try {
filter = config.createSpotFilter();
} catch (final Exception ex) {
filter = null;
this.imp.setOverlay(overlay);
// Required for ImageJ to disable the preview
throw new IllegalStateException("Unable to create spot filter", ex);
}
ImageJUtils.log(filter.getDescription());
}
lastCalibration = calibration;
lastFitEngineSettings = fitEngineSettings;
lastPsf = psf;
// This code can probably be removed since the crop is done above.
if (fitConfig.getCameraTypeValue() == CameraType.SCMOS_VALUE) {
// Instead just warn if the roi cannot be extracted from the selected model
// or there is a mismatch
final Rectangle modelBounds = fitConfig.getCameraModel().getBounds();
if (modelBounds != null) {
if (!modelBounds.contains(bounds)) {
// @formatter:off
ImageJUtils.log("WARNING: Camera model bounds [x=%d,y=%d,width=%d,height=%d]" + " does not contain image target bounds [x=%d,y=%d,width=%d,height=%d]", modelBounds.x, modelBounds.y, modelBounds.width, modelBounds.height, bounds.x, bounds.y, bounds.width, bounds.height);
// @formatter:on
// Warn if the model bounds are mismatched than the image as this may be an incorrect
// selection for the camera model
} else if (modelBounds.x != 0 || modelBounds.y != 0 || modelBounds.width > ip.getWidth() || modelBounds.height > ip.getHeight()) {
// @formatter:off
ImageJUtils.log("WARNING: Probably an incorrect camera model!\n" + "Model bounds [x=%d,y=%d,width=%d,height=%d]\n" + "do not match the image target bounds [width=%d,height=%d].", modelBounds.x, modelBounds.y, modelBounds.width, modelBounds.height, ip.getWidth(), ip.getHeight());
// @formatter:on
}
}
}
run(ip, filter);
}
Aggregations