/*-
* Copyright 2017 Diamond Light Source Ltd.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package uk.ac.diamond.scisoft.xpdf;
import org.eclipse.dawnsci.analysis.api.metadata.IDiffractionMetadata;
import org.eclipse.january.dataset.Dataset;
import org.eclipse.january.dataset.DoubleDataset;
import uk.ac.diamond.scisoft.analysis.diffraction.powder.IPixelIntegrationCache;
import uk.ac.diamond.scisoft.analysis.diffraction.powder.PixelIntegrationBean;
import uk.ac.diamond.scisoft.analysis.diffraction.powder.PixelIntegrationCache;
import uk.ac.diamond.scisoft.analysis.roi.XAxis;
/**
* A class to hold the immutable fields for the XPDF calibration, and the
* methods for their initialization.
*
* @author Timothy Spain timothy.spain@diamond.ac.uk
*
*/
public class XPDFCalibrationBase {
protected Double calibrationConstant0;
protected XPDFQSquaredIntegrator qSquaredIntegrator;
protected double selfScatteringDenominator;
protected Dataset multipleScatteringCorrection;
protected double nSampleIlluminatedAtoms;
protected XPDFAbsorptionMaps absorptionMaps;
protected XPDFCoordinates coords;
protected XPDFDetector tect;
protected XPDFBeamData beamData;
protected Dataset sampleFluorescence;
protected Dataset sampleSelfScattering;
protected double fixedFluorescence;
protected int dataDimensions;
private IPixelIntegrationCache cachePI;
/**
* Empty constructor.
*/
public XPDFCalibrationBase() {
qSquaredIntegrator = null;
selfScatteringDenominator = 1.0;
multipleScatteringCorrection = null;
nSampleIlluminatedAtoms = 1.0; // there must be at least one
cachePI = null;
}
/**
* Copy constructor.
* @param inCal
* calibration object to be copied.
*/
public XPDFCalibrationBase(XPDFCalibrationBase inCal) {
this.calibrationConstant0 = (inCal.calibrationConstant0 != null) ? inCal.calibrationConstant0 : null;
this.qSquaredIntegrator = (inCal.qSquaredIntegrator != null) ? inCal.qSquaredIntegrator : null;
this.selfScatteringDenominator = inCal.selfScatteringDenominator;
this.multipleScatteringCorrection = (inCal.multipleScatteringCorrection != null) ? inCal.multipleScatteringCorrection.copy(DoubleDataset.class) : null;
this.nSampleIlluminatedAtoms = inCal.nSampleIlluminatedAtoms;
this.tect = (inCal.tect != null) ? new XPDFDetector(inCal.tect): null;
this.beamData = (inCal.beamData != null) ? new XPDFBeamData(inCal.beamData) : null;
this.sampleFluorescence = (inCal.sampleFluorescence != null) ? inCal.sampleFluorescence.clone() : null;
this.dataDimensions = inCal.dataDimensions;
this.coords = (inCal.coords != null) ? new XPDFCoordinates(inCal.coords) : null;
this.sampleSelfScattering = (inCal.sampleSelfScattering != null) ? inCal.sampleSelfScattering : null;
this.absorptionMaps = (inCal.absorptionMaps != null) ? inCal.absorptionMaps : null;
}
/**
* Sets the initial calibration constant to be iterated.
* <p>
* Sets the initial calibration constant. If there is already an array,
* then a new Array is created.
* @param calibrationConstant
* the initial value of the calibration constant.
*/
public void initializeCalibrationConstant(double calibrationConstant) {
calibrationConstant0 = calibrationConstant;
}
/**
* Sets up the q² integrator class to use in the calculation of the constants
* @param qSquaredIntegrator
* a properly constructed q² integrator class to
* be used to integrate scattering in the sample.
*/
public void setqSquaredIntegrator(XPDFQSquaredIntegrator qSquaredIntegrator) {
this.qSquaredIntegrator = new XPDFQSquaredIntegrator(qSquaredIntegrator);
}
/**
* Calculates the denominator used in calculating the calibration constant.
* <p>
* Difference of the Krogh-Moe sum and integral of Thomson self-scattering
* for the sample, used as the denominator of the updating factor of the
* calibration constant.
* @param sample
* Sample for which the properties should be calculated.
* @param coordinates
* Angles and beam energy at which the properties should be calculated.
*/
public void setSelfScatteringDenominatorFromSample(XPDFTargetComponent sample, XPDFCoordinates coordinates) {
selfScatteringDenominator = qSquaredIntegrator.ThomsonIntegral(sample.getSelfScattering(coordinates))
- sample.getKroghMoeSum();
}
/**
* Sets a Dataset for the multiple scattering correction.
* <p>
* Set the multiple scattering correction. Presently takes a zero Dataset
* of the same shape as the angle arrays.
* @param multipleScatteringCorrection
* A zero Dataset.
*/
public void setMultipleScatteringCorrection(Dataset multipleScatteringCorrection) {
this.multipleScatteringCorrection = multipleScatteringCorrection.copy(DoubleDataset.class);
}
/**
* Sets the number of atoms illuminated in the sample.
* @param nSampleIlluminatedAtoms
* the number of atoms illuminated in the sample.
*/
public void setSampleIlluminatedAtoms(double nSampleIlluminatedAtoms) {
this.nSampleIlluminatedAtoms = nSampleIlluminatedAtoms;
}
/**
* Sets the absorption maps.
* <p>
* Set the absorption maps object that holds the maps between the target
* components stored in the list of background subtracted traces. The
* ordinals used in the list and used to index the maps.
* @param absorptionMaps
* The absorption maps in their holding class.
*/
public void setAbsorptionMaps(XPDFAbsorptionMaps absorptionMaps) {
this.absorptionMaps = new XPDFAbsorptionMaps(absorptionMaps);
}
/**
* Sets the coordinates over which to calibrate the data.
* @param inCoords
* the {@link XPDFCoordinates} object to be used.
*/
public void setCoordinates(XPDFCoordinates inCoords) {
this.coords = inCoords;
this.dataDimensions = inCoords.getTwoTheta().getShape().length;
}
/**
* Sets the detector data class to calibrate against.
* @param inTect
* the {@link XPDFDetector} object to be used.
*/
public void setDetector(XPDFDetector inTect) {
this.tect = inTect;
}
/**
* Sets the class which describes the incoming x-ray beam.
* @param inBeam
* the {@link XPDFBeamData} object to be used.
*/
public void setBeamData(XPDFBeamData inBeam) {
this.beamData = inBeam;
}
/**
* Sets the fluorescence at the detector on the same coordinates as the data.
* @param sampleFluor
* the {@link Dataset} containing the fluorescence data
*/
public void setSampleFluorescence(Dataset sampleFluor) {
this.sampleFluorescence = sampleFluor;
}
/**
* Sets the target component which of the sample
* @param sample
* the {@link XPDFTargetComponent} which will provide the sample self-scattering.
*/
public void setSelfScattering(XPDFTargetComponent sample) {
this.sampleSelfScattering = sample.getSelfScattering(coords);
}
/**
* Generates a {@link IPixelIntegrationCache} to be used by the azimuthal integration.
* @param q
* the q axis to integrate on to.
* @param md
* the {@link IDiffractionMetadata} that provides the detector calibration.
* @param shape
* the shape of the data to be integrated.
* @return the new {@link IPixelIntegrationCache}.
*/
// The cache is only cleared when the object dies. Which is fine.
protected IPixelIntegrationCache getPICache(Dataset q, IDiffractionMetadata md, int[] shape) {
if (cachePI == null) {
PixelIntegrationBean pIBean = new PixelIntegrationBean();
pIBean.setUsePixelSplitting(false);
pIBean.setNumberOfBinsRadial(q.getSize());
pIBean.setxAxis(XAxis.Q);
pIBean.setRadialRange(new double[] {(double) q.min(), (double) q.max()});
pIBean.setAzimuthalRange(null);
pIBean.setTo1D(true);
pIBean.setLog(false);
pIBean.setShape(shape);
cachePI = new PixelIntegrationCache(md, pIBean);
}
return cachePI;
}
}