use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter in project GDSC-SMLM by aherbert.
the class PeakResultsReader method readMalk.
private MemoryPeakResults readMalk() {
final MemoryPeakResults results = createResults();
if (TextUtils.isNullOrEmpty(name)) {
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;
// Skip the header
while ((line = input.readLine()) != null) {
if (line.isEmpty()) {
continue;
}
if (line.charAt(0) != '#') {
// This is the first record
if (!addMalkResult(results, line)) {
errors = 1;
}
break;
}
}
while ((line = input.readLine()) != null) {
if (line.isEmpty() || line.charAt(0) == '#') {
continue;
}
if (!addMalkResult(results, line) && ++errors >= 10) {
break;
}
reporter.showProgress();
}
} catch (final IOException ex) {
logError(ex);
}
// The calibration may not be null if this was a GDSC MALK file since that has a header.
if (calibration == null) {
calibration = new CalibrationWriter();
// Default assumption is nm
calibration.setDistanceUnit(DistanceUnit.NM);
// MALK uses photons
calibration.setIntensityUnit(IntensityUnit.PHOTON);
results.setCalibration(getCalibration());
}
return results;
}
use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter 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.CalibrationWriter in project GDSC-SMLM by aherbert.
the class TsfPeakResultsReader method createResults.
private MemoryPeakResults createResults() {
// Limit the capacity since we may not need all the spots
int capacity = 1000;
if (spotList.hasNrSpots()) {
capacity = (int) Math.min(100000, spotList.getNrSpots());
}
final MemoryPeakResults results = new MemoryPeakResults(capacity);
// Create the type of Gaussian PSF
if (spotList.hasFitMode()) {
switch(spotList.getFitMode()) {
case ONEAXIS:
results.setPsf(PsfHelper.create(PSFType.ONE_AXIS_GAUSSIAN_2D));
break;
case TWOAXIS:
results.setPsf(PsfHelper.create(PSFType.TWO_AXIS_GAUSSIAN_2D));
break;
case TWOAXISANDTHETA:
results.setPsf(PsfHelper.create(PSFType.TWO_AXIS_AND_THETA_GAUSSIAN_2D));
break;
default:
break;
}
}
// Generic reconstruction
String name;
if (spotList.hasName()) {
name = spotList.getName();
} else {
name = FileUtils.getName(filename);
}
// Append these if not using the defaults
if (channel != 1 || slice != 0 || position != 0 || fluorophoreType != 1) {
name = String.format("%s c=%d, s=%d, p=%d, ft=%d", name, channel, slice, position, fluorophoreType);
}
results.setName(name);
// if (spotList.hasNrPixelsX() && spotList.hasNrPixelsY())
// {
// // Do not do this. The size of the camera may not map to the data bounds due
// // to the support for position offsets.
// results.setBounds(new Rectangle(0, 0, spotList.getNrPixelsX(), spotList.getNrPixelsY()));
// }
final CalibrationWriter cal = new CalibrationWriter();
// Spots are associated with frames
cal.setTimeUnit(TimeUnit.FRAME);
if (spotList.hasPixelSize()) {
cal.setNmPerPixel(spotList.getPixelSize());
}
if (spotList.getEcfCount() >= channel) {
// ECF is per channel
final double ecf = spotList.getEcf(channel - 1);
// QE is per fluorophore type
final double qe = (spotList.getQeCount() >= fluorophoreType) ? spotList.getQe(fluorophoreType - 1) : 1;
// e-/photon / e-/count => count/photon
cal.setCountPerPhoton(qe / ecf);
cal.setQuantumEfficiency(qe);
}
if (isGdsc) {
if (spotList.hasSource()) {
// Deserialise
results.setSource(ImageSource.fromXml(spotList.getSource()));
}
if (spotList.hasRoi()) {
final ROI roi = spotList.getRoi();
if (roi.hasX() && roi.hasY() && roi.hasXWidth() && roi.hasYWidth()) {
results.setBounds(new Rectangle(roi.getX(), roi.getY(), roi.getXWidth(), roi.getYWidth()));
}
}
if (spotList.hasGain()) {
cal.setCountPerPhoton(spotList.getGain());
}
if (spotList.hasExposureTime()) {
cal.setExposureTime(spotList.getExposureTime());
}
if (spotList.hasReadNoise()) {
cal.setReadNoise(spotList.getReadNoise());
}
if (spotList.hasBias()) {
cal.setBias(spotList.getBias());
}
if (spotList.hasCameraType()) {
cal.setCameraType(cameraTypeMap.get(spotList.getCameraType()));
} else {
cal.setCameraType(null);
}
if (spotList.hasConfiguration()) {
results.setConfiguration(spotList.getConfiguration());
}
// Allow restoring the GDSC PSF exactly
if (spotList.hasPSF()) {
try {
final Parser parser = JsonFormat.parser();
final PSF.Builder psfBuilder = PSF.newBuilder();
parser.merge(spotList.getPSF(), psfBuilder);
results.setPsf(psfBuilder.build());
} catch (final InvalidProtocolBufferException ex) {
logger.warning("Unable to deserialise the PSF settings");
}
}
}
if (spotList.hasLocationUnits()) {
cal.setDistanceUnit(locationUnitsMap.get(spotList.getLocationUnits()));
if (!spotList.hasPixelSize() && spotList.getLocationUnits() != LocationUnits.PIXELS) {
logger.warning(() -> "TSF location units are not pixels and no pixel size calibration is available." + " The dataset will be constructed in the native units: " + spotList.getLocationUnits());
}
} else {
cal.setDistanceUnit(null);
}
if (spotList.hasIntensityUnits()) {
cal.setIntensityUnit(intensityUnitsMap.get(spotList.getIntensityUnits()));
if (!spotList.hasGain() && spotList.getIntensityUnits() != IntensityUnits.COUNTS) {
logger.warning(() -> "TSF intensity units are not counts and no gain calibration is available." + " The dataset will be constructed in the native units: " + spotList.getIntensityUnits());
}
} else {
cal.setIntensityUnit(null);
}
if (spotList.hasThetaUnits()) {
cal.setAngleUnit(thetaUnitsMap.get(spotList.getThetaUnits()));
} else {
cal.setAngleUnit(null);
}
results.setCalibration(cal.getCalibration());
return results;
}
use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter in project GDSC-SMLM by aherbert.
the class TraceDiffusion method checkCalibration.
/**
* Check the results have a calibrated exposure time and pixel pitch. If not then show a dialog to
* collect the calibration.
*
* @param results the results
* @return True if calibrated
*/
private static boolean checkCalibration(MemoryPeakResults results) {
if (results.getCalibration() == null || !results.getCalibrationReader().hasExposureTime() || !results.getCalibrationReader().hasNmPerPixel()) {
final CalibrationWriter cal = results.getCalibrationWriterSafe();
final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
gd.addMessage("Uncalibrated results! Please enter the calibration:");
gd.addNumericField("Exposure_time (ms)", cal.getExposureTime(), 2);
gd.addNumericField("Pixel_pitch (nm)", cal.getNmPerPixel(), 2);
gd.showDialog();
if (gd.wasCanceled() || gd.invalidNumber()) {
return false;
}
cal.setExposureTime(gd.getNextNumber());
cal.setNmPerPixel(gd.getNextNumber());
if (cal.getExposureTime() <= 0 || cal.getNmPerPixel() <= 0) {
return false;
}
results.setCalibration(cal.getCalibration());
}
return true;
}
use of uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter in project GDSC-SMLM by aherbert.
the class TrackPopulationAnalysis method checkCalibration.
/**
* Check the results have a calibrated exposure time and pixel pitch. If not then show a dialog to
* collect the calibration.
*
* @param results the results
* @return True if calibrated
*/
private static boolean checkCalibration(MemoryPeakResults results) {
if (results.getCalibration() == null || !results.getCalibrationReader().hasExposureTime() || !results.getCalibrationReader().hasNmPerPixel()) {
final CalibrationWriter cal = results.getCalibrationWriterSafe();
final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
gd.addMessage("Uncalibrated results! Please enter the calibration:");
gd.addNumericField("Exposure_time", cal.getExposureTime(), 2, 6, "ms");
gd.addNumericField("Pixel_pitch", cal.getNmPerPixel(), 2, 6, "nm");
gd.showDialog();
if (gd.wasCanceled() || gd.invalidNumber()) {
return false;
}
cal.setExposureTime(gd.getNextNumber());
cal.setNmPerPixel(gd.getNextNumber());
if (cal.getExposureTime() <= 0 || cal.getNmPerPixel() <= 0) {
return false;
}
results.setCalibration(cal.getCalibration());
}
return true;
}
Aggregations