package uk.ac.diamond.scisoft.xpdf.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.dawb.common.services.ServiceManager; import org.dawnsci.persistence.PersistenceServiceCreator; import org.dawnsci.persistence.ServiceLoader; import org.eclipse.dawnsci.analysis.api.io.IDataHolder; import org.eclipse.dawnsci.analysis.api.persistence.IPersistenceService; import org.eclipse.dawnsci.analysis.api.processing.OperationRank; import org.eclipse.dawnsci.analysis.dataset.slicer.SliceFromSeriesMetadata; import org.eclipse.dawnsci.analysis.dataset.slicer.SliceInformation; import org.eclipse.dawnsci.analysis.dataset.slicer.SourceInformation; import org.eclipse.dawnsci.hdf5.nexus.NexusFileFactoryHDF5; import org.eclipse.january.IMonitor; import org.eclipse.january.dataset.Dataset; import org.eclipse.january.dataset.IDataset; import org.eclipse.january.dataset.Maths; import org.eclipse.january.dataset.SliceND; import org.junit.After; import org.junit.Before; import org.junit.Test; import uk.ac.diamond.scisoft.analysis.io.LoaderFactory; import uk.ac.diamond.scisoft.analysis.io.LoaderServiceImpl; import uk.ac.diamond.scisoft.analysis.processing.LocalServiceManager; import uk.ac.diamond.scisoft.analysis.processing.operations.mask.ImportMaskModel; import uk.ac.diamond.scisoft.analysis.processing.operations.mask.ImportMaskOperation; import uk.ac.diamond.scisoft.analysis.processing.operations.twod.DiffractionMetadataImportModel; import uk.ac.diamond.scisoft.analysis.processing.operations.twod.DiffractionMetadataImportOperation; import uk.ac.diamond.scisoft.xpdf.XPDFGeometryEnum; import uk.ac.diamond.scisoft.xpdf.XPDFMetadataImpl; import uk.ac.diamond.scisoft.xpdf.metadata.XPDFMetadata; import uk.ac.diamond.scisoft.xpdf.operations.XPDFDefineDetectorModel; import uk.ac.diamond.scisoft.xpdf.operations.XPDFDefineDetectorOperation; import uk.ac.diamond.scisoft.xpdf.operations.XPDFInsertBeamMetadataModel; import uk.ac.diamond.scisoft.xpdf.operations.XPDFInsertBeamMetadataOperation; import uk.ac.diamond.scisoft.xpdf.operations.XPDFInsertContainerMetadataModel; import uk.ac.diamond.scisoft.xpdf.operations.XPDFInsertContainerMetadataOperation; import uk.ac.diamond.scisoft.xpdf.operations.XPDFInsertSampleMetadataModel; import uk.ac.diamond.scisoft.xpdf.operations.XPDFInsertSampleMetadataOperation; import uk.ac.diamond.scisoft.xpdf.operations.XPDFIterateCalibrationConstantModel; import uk.ac.diamond.scisoft.xpdf.operations.XPDFIterateCalibrationConstantOperation; import uk.ac.diamond.scisoft.xpdf.operations.XPDFNormalizeTracesModel; import uk.ac.diamond.scisoft.xpdf.operations.XPDFNormalizeTracesOperation; import uk.ac.diamond.scisoft.xpdf.operations.XPDFSubtractBackgroundModel; import uk.ac.diamond.scisoft.xpdf.operations.XPDFSubtractBackgroundOperation; public class XICCO2DTest { @Before public void setUp() throws Exception { // Set factory for test ServiceLoader.setNexusFactory(new NexusFileFactoryHDF5()); // Set up a File Service for ImportMaskMetadata ServiceManager.setService(IPersistenceService.class, PersistenceServiceCreator.createPersistenceService()); LocalServiceManager.setLoaderService(new LoaderServiceImpl()); } @After public void tearDown() throws Exception { } @Test public void testProcess() { String ceriaDataPath = "/dls/science/groups/das/ExampleData/i15-1/2015Oct.Standards/CeO2_NIST_8s_19slices_averaged.tif"; // Load the data IDataset ceriaData = null; try { IDataHolder dh = LoaderFactory.getData(ceriaDataPath); ceriaData = dh.getDataset(0); } catch (Exception e) { fail("Could not load data from " + ceriaDataPath); } // Create the useless monitor for the pretend pipeline IMonitor mon = new IMonitor.Stub(); // Create the Source and Slice metadata SliceFromSeriesMetadata sourceSlice = new SliceFromSeriesMetadata(new SourceInformation(ceriaDataPath, "ceriaData", ceriaData), new SliceInformation(new SliceND(new int[]{2048, 2048}), new SliceND(new int[]{2048, 2048}), new SliceND(new int[]{2048, 2048}), new int[] {0, 1}, 1, 0)); ceriaData.addMetadata(sourceSlice); // Add the mask ImportMaskOperation<FixedMaskModel> maskOp = new ImportMaskOperation<FixedMaskModel>(); maskOp.setModel(new FixedMaskModel()); IDataset maskedData = maskOp.execute(ceriaData, mon).getData(); // Import the detector calibration DiffractionMetadataImportOperation dMIO = new DiffractionMetadataImportOperation(); dMIO.setModel(new FixedDiffractionMetadataImportModel()); maskedData = dMIO.execute(maskedData, mon).getData(); // XPDF Metadata XPDFInsertSampleMetadataOperation xISMO = new XPDFInsertSampleMetadataOperation(); xISMO.setModel(new CeriaSampleMetadataModel()); IDataset dataWithMetadata = xISMO.execute(maskedData, mon).getData(); XPDFInsertContainerMetadataOperation xICMO = new XPDFInsertContainerMetadataOperation(); xICMO.setModel(new OneMMContainerMetadataModel()); dataWithMetadata = xICMO.execute(dataWithMetadata, mon).getData(); XPDFInsertBeamMetadataOperation xIBMO = new XPDFInsertBeamMetadataOperation(); xIBMO.setModel(new I15BeamMetadataModel()); dataWithMetadata = xIBMO.execute(dataWithMetadata, mon).getData(); XPDFDefineDetectorOperation xDDO = new XPDFDefineDetectorOperation(); xDDO.setModel(new DefineCsIDetector()); dataWithMetadata = xDDO.execute(dataWithMetadata, mon).getData(); // XPDF processing XPDFNormalizeTracesOperation xNTO = new XPDFNormalizeTracesOperation(); xNTO.setModel(new YesNormalizeTracesModel()); IDataset normedData = xNTO.execute(dataWithMetadata, mon).getData(); XPDFSubtractBackgroundOperation xSBO = new XPDFSubtractBackgroundOperation(); xSBO.setModel(new YesSubtractBackgroundModel()); IDataset subBak = xSBO.execute(normedData, mon).getData(); // Iterate the calibration constant long startTime = System.currentTimeMillis(); XPDFIterateCalibrationConstantOperation xICCO = new XPDFIterateCalibrationConstantOperation(); xICCO.setModel(new FakeXICCOModel()); IDataset abscor = xICCO.execute(subBak, mon).getData(); long finishTime = System.currentTimeMillis(); long diffTime = finishTime - startTime; System.out.println("XPDFIterateCalcibrationConstantOperation took " + diffTime*0.001 + " s."); // String referenceDataPath = "/dls/science/groups/das/ExampleData/i15-1/2015Oct.Standards/optimization reference/CeO2_NIST_8s_19slices_averaged_processed_160104_154754.nxs"; String referenceDataPath = "/dls/science/groups/das/ExampleData/i15-1/2015Oct.Standards/optimization reference/CeO2_NIST_8s_19slices_averaged_processed_160204_122450.nxs"; IDataset referenceData = null; try { IDataHolder dh = LoaderFactory.getData(referenceDataPath); referenceData = dh.getLazyDataset("/entry/result/data").getSlice(); // IPersistenceService service = (IPersistenceService)ServiceManager.getService(IPersistenceService.class); // IPersistentFile pf = service.getPersistentFile(referenceDataPath); // List<String> dataNames = pf.getDataNames(mon); // List<String> maskNames = pf.getMaskNames(mon); // referenceData = pf.getData("/result/data", mon).getSlice(); // referenceData = pf.getData(pf.getDataNames(mon), mon); } catch (Exception e) { fail("Could not load data from " + referenceDataPath + ", " + e.toString()); } Dataset ratio = Maths.divide(abscor, referenceData); double meanRatio = (double) Maths.abs(ratio).mean(); double meanRationalDifference = meanRatio - 1; double rationalDifferenceLimit = 11e-2; assertTrue("ABSCOR rational difference too large.", meanRationalDifference < rationalDifferenceLimit); // assertTrue("A dummy assertion shouldn't return false.", true); } @Test public void testGetId() { assertEquals("XICCO has the incorrect ID String.", "uk.ac.diamond.scisoft.xpdf.operations.XPDFIterateCalibrationConstantOperation", new XPDFIterateCalibrationConstantOperation().getId()); } @Test public void testGetInputRank() { assertEquals("XICCO input can be of ANY rank.", OperationRank.ANY, new XPDFIterateCalibrationConstantOperation().getInputRank()); } @Test public void testGetOutputRank() { assertEquals("XICCO output should have the SAME rank as the input.", OperationRank.SAME, new XPDFIterateCalibrationConstantOperation().getOutputRank()); } XPDFMetadata createCeriaMetadata() { XPDFMetadata theMetadata = new XPDFMetadataImpl(); return theMetadata; } } class FixedMaskModel extends ImportMaskModel { @Override public String getFilePath() { return "/dls/science/groups/das/ExampleData/i15-1/integration/128991_mask_min1000_max30000.nxs"; } } class FixedDiffractionMetadataImportModel extends DiffractionMetadataImportModel { @Override public String getFilePath() { return "/dls/science/groups/das/ExampleData/i15-1/integration/CeO2_NIST_8s_19slices_averaged_fixedE_calibration.nxs"; } } class CeriaSampleMetadataModel extends XPDFInsertSampleMetadataModel { @Override public String getErrorFilePath() { return ""; } @Override public String getErrorDataset() { return ""; } @Override public double getCountingTime() { return 60.0; } @Override public double getMonitorRelativeFlux() { return 1.0; } @Override public String getMaterial() { return "CeO2"; } @Override public double getDensity() { return 7.65; } @Override public double getPackingFraction() { return 0.6; } @Override public XPDFGeometryEnum getShape() { return XPDFGeometryEnum.CYLINDER; } @Override public double getInner() { return 0.0; } @Override public double getOuter() { return 0.5; } @Override public String getSampleName() { return "Ceria SRM"; } @Override public boolean isAxisAngle() { return true; } } class OneMMContainerMetadataModel extends XPDFInsertContainerMetadataModel { @Override public String getFilePath() { return "/dls/science/groups/das/ExampleData/i15-1/2015Oct.Standards/Empty_1mmQGCT_8s_20slices_averaged.tif"; } @Override public String getDataset() { return "image-01"; } @Override public String getErrorFilePath() { return ""; } @Override public String getErrorDataset() { return ""; } @Override public double getCountingTime() { return 60.0; } @Override public double getMonitorRelativeFlux() { return 1.0; } @Override public String getMaterial() { return "SiO2"; } @Override public double getDensity() { return 2.65; } @Override public double getPackingFraction() { return 1.0; } @Override public XPDFGeometryEnum getShape() { return XPDFGeometryEnum.CYLINDER; } @Override public double getInner() { return 0.5; } @Override public double getOuter() { return 0.51; } @Override public String getContainerName() { return "SiO2 capillary"; } @Override public boolean isUpstream() { return true; } @Override public boolean isDownstream() { return true; } } class I15BeamMetadataModel extends XPDFInsertBeamMetadataModel { @Override public String getFilePath() { return "/dls/science/groups/das/ExampleData/i15-1/2015Oct.Standards/EmptyI15_8s_20slices_averaged.tif"; } @Override public String getDataset() { return "image-01"; } @Override public String getErrorFilePath() { return ""; } @Override public String getErrorDataset() { return ""; } @Override public double getBeamEnergy() { return 76.6; } @Override public double getBeamHeight() { return 0.07; } @Override public double getBeamWidth() { return 0.07; } @Override public double getCountingTime() { return 60.0; } @Override public double getMonitorRelativeFlux() { return 1.0; } } class DefineCsIDetector extends XPDFDefineDetectorModel { @Override public String getDetectorName() { return "Perkin Elmer"; } @Override public String getDetectorMaterial() { return "CsI"; } @Override public double getDensity() { return 4.51; } @Override public double getThickness() { return 0.5; } @Override public double getSolidAngle() { return 0.1; } } class YesNormalizeTracesModel extends XPDFNormalizeTracesModel { @Override public boolean isNormalizeSample() { return true; } @Override public boolean isNormalizeContainers() { return true; } @Override public boolean isNormalizeBeam() { return true; } } class YesSubtractBackgroundModel extends XPDFSubtractBackgroundModel { @Override public boolean isSubtractSampleBackground() { return true; } @Override public boolean isSubtractContainersBackground() { return true; } } class FakeXICCOModel extends XPDFIterateCalibrationConstantModel { @Override public int getnIterations() { return 5; } @Override public boolean isSortContainers() { return false; } @Override public boolean isDoingFluorescence() { return true; // return false; } }