Skip to content

Commit

Permalink
Merge pull request #1815 from kif/1808_calib2
Browse files Browse the repository at this point in the history
Alternative visulalization of geometry
  • Loading branch information
kif authored Feb 24, 2023
2 parents 05b68fc + ba5373a commit fc21530
Show file tree
Hide file tree
Showing 13 changed files with 151 additions and 125 deletions.
4 changes: 2 additions & 2 deletions pyFAI/app/calib2.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
__contact__ = "[email protected]"
__license__ = "MIT"
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
__date__ = "21/01/2020"
__date__ = "24/02/2023"
__status__ = "production"

import os
Expand Down Expand Up @@ -569,7 +569,7 @@ def main():
silx.config.DEFAULT_PLOT_BACKEND = "opengl"

# Make sure matplotlib is loaded first by silx
import silx.gui.plot.matplotlib
import silx.gui.utils.matplotlib
from pyFAI.gui.CalibrationWindow import CalibrationWindow
from pyFAI.gui.CalibrationContext import CalibrationContext

Expand Down
18 changes: 10 additions & 8 deletions pyFAI/azimuthalIntegrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
__contact__ = "[email protected]"
__license__ = "MIT"
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
__date__ = "22/02/2023"
__date__ = "24/02/2023"
__status__ = "stable"
__docformat__ = 'restructuredtext'

Expand Down Expand Up @@ -2218,7 +2218,7 @@ def integrate2d_ng(self, data, npt_rad, npt_azim=360,
norm2d = None
var2d = None

if method.algo_lower in ("csr", "lut"):
if method.algo_lower in ("csr", "csc", "lut"):
intpl = None
cython_method = IntegrationMethod.select_method(method.dimension, method.split_lower, method.algo_lower, "cython")[0]
if cython_method not in self.engines:
Expand Down Expand Up @@ -2936,14 +2936,14 @@ def sigma_clip_legacy(self, data, npt_rad=1024, npt_azim=512,
:param metadata: any other metadata,
:type metadata: JSON serializable dict
:param safe: unset to save some checks on sparse matrix shape/content.
:return: Integrate1D-like result
:kwargs: unused, just for signature compatibility when used within Worker.
:return: Integrate1D like result like
Nota: The initial 2D-integration requires pixel splitting
"""
#compatibility layer with sigma_clip_ng
# compatibility layer with sigma_clip_ng
if "npt" in kwargs:
npt_rad = kwargs["npt"]

# We use NaN as dummies
if dummy is None:
dummy = numpy.NaN
Expand Down Expand Up @@ -2971,7 +2971,8 @@ def sigma_clip_legacy(self, data, npt_rad=1024, npt_azim=512,
dummy=dummy, delta_dummy=delta_dummy,
correctSolidAngle=correctSolidAngle,
polarization_factor=polarization_factor,
normalization_factor=normalization_factor,safe=safe)
normalization_factor=normalization_factor,
safe=safe)
image = res2d.intensity
if (method.impl_lower == "opencl"):
if (method.algo_lower == "csr") and \
Expand Down Expand Up @@ -3086,8 +3087,9 @@ def sigma_clip_ng(self, data,
``|I - <I>| < thres * σ(I)``
This enforces a symmetric, bell-shaped distibution (i.e. gaussian-like) and is very good at extracting
background or amorphous isotropic scattering out of Bragg peaks.
This enforces a symmetric, bell-shaped distibution (i.e. gaussian-like)
and is very good at extracting background or amorphous isotropic scattering
out of Bragg peaks.
:param data: input image as numpy array
:param npt_rad: number of radial points
Expand Down
4 changes: 2 additions & 2 deletions pyFAI/ext/splitBBoxCSC.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Serial implementation based on a sparse CSC matrix multiplication

__author__ = "Jérôme Kieffer"
__contact__ = "[email protected]"
__date__ = "08/09/2022"
__date__ = "31/01/2023"
__status__ = "stable"
__license__ = "MIT"

Expand Down Expand Up @@ -184,7 +184,7 @@ class HistoBBox2d(CscIntegrator, SplitBBoxIntegrator):
self.bin_centers1 = numpy.linspace(self.pos1_min + 0.5 * self.delta1,
self.pos1_max - 0.5 * self.delta1,
self.bins[1])
csc = self.calc_lut_2d().to_csr()
csc = sparse.csr_matrix(self.calc_lut_2d().to_csr()).tocsc()
#Call the constructor of the parent class
CscIntegrator.__init__(self, (csc.data, csc.indices, csc.indptr), self.size, numpy.prod(bins), empty or 0.0)
self.lut_checksum = crc32(self.data)
Expand Down
4 changes: 2 additions & 2 deletions pyFAI/ext/splitPixelFullCSC.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Sparse matrix represented using the CompressedSparseColumn.

__author__ = "Jérôme Kieffer"
__contact__ = "[email protected]"
__date__ = "09/09/2022"
__date__ = "31/01/2023"
__status__ = "stable"
__license__ = "MIT"

Expand Down Expand Up @@ -169,7 +169,7 @@ class FullSplitCSC_2d(CscIntegrator, FullSplitIntegrator):

csc = sparse.csr_matrix(self.calc_lut_2d().to_csr()).tocsc()
#Call the constructor of the parent class
CscIntegrator.__init__(self, (csc.data, csc.indices, csc.indptr), self.pos.shape[0], self.bins, empty or 0.0)
CscIntegrator.__init__(self, (csc.data, csc.indices, csc.indptr), self.pos.shape[0], numpy.prod(bins), empty or 0.0)

self.lut_checksum = crc32(self.data)
self.lut_nbytes = sum([i.nbytes for i in self.lut])
Expand Down
4 changes: 2 additions & 2 deletions pyFAI/gui/dialog/GeometryDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
#
# ###########################################################################*/

__authors__ = ["V. Valls"]
__authors__ = ["V. Valls", "J. Kieffer"]
__license__ = "MIT"
__date__ = "03/02/2023"
__date__ = "24/02/2023"

from silx.gui import qt
from ..model.GeometryModel import GeometryModel
Expand Down
4 changes: 3 additions & 1 deletion pyFAI/gui/dialog/IntegrationMethodDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

__authors__ = ["V. Valls"]
__license__ = "MIT"
__date__ = "16/10/2020"
__date__ = "31/01/2023"

from silx.gui import qt
from silx.gui import icons
Expand All @@ -46,6 +46,7 @@ class IntegrationMethodWidget(qt.QWidget):
"histogram": "Histogram",
"lut": "LUT",
"csr": "CSR",
"csc": "CSC",
"python": "Python",
"cython": "Cython",
"opencl": "OpenCL",
Expand All @@ -66,6 +67,7 @@ class IntegrationMethodWidget(qt.QWidget):
"histogram": "Direct integration method with the lowest memory footprint but slower",
"lut": "Sparse matrix based integration using a look-up table. Long initalization time and highest memory usage. Often slower than CSR",
"csr": "Sparse matrix based integration using a a CSR (compressed sparse row) representation. Long initalization time and high memory usage, but the fastest for processing",
"csc": "Sparse matrix based integration using a a CSC (compressed sparse column) representation. Long initalization time and high memory usage. Single-threaded but faster processsing than histogram",
"python": "Use a pure Python/numpy/scipy implementation. Slow but portable",
"cython": "Use a Cython/C/C++ implementation. Fast and reliable default methods",
"opencl": "Use an OpenCL implementation based on hardware accelerators. Fastest but hardware/driver dependant",
Expand Down
64 changes: 39 additions & 25 deletions pyFAI/gui/tasks/IntegrationTask.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# coding: utf-8
# /*##########################################################################
#
# Copyright (C) 2016-2018 European Synchrotron Radiation Facility
# Copyright (C) 2016-2023 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
Expand All @@ -23,9 +23,9 @@
#
# ###########################################################################*/

__authors__ = ["V. Valls"]
__authors__ = ["V. Valls", "J. Kieffer"]
__license__ = "MIT"
__date__ = "05/05/2022"
__date__ = "24/02/2023"

import logging
import numpy
Expand All @@ -40,6 +40,8 @@
from pyFAI.azimuthalIntegrator import AzimuthalIntegrator
from ..utils import unitutils
from ..model.DataModel import DataModel
# from ..model.GeometryModel import GeometryModel
# from ..model.Fit2dGeometryModel import Fit2dGeometryModel
from ..widgets.QuantityLabel import QuantityLabel
from ..CalibrationContext import CalibrationContext
from ... import units as core_units
Expand All @@ -56,6 +58,7 @@
from pyFAI import method_registry
from ..dialog import MessageBox
from pyFAI.io import ponifile
import pyFAI.geometry

_logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -100,13 +103,13 @@ def setValue(self, value):

class IntegrationProcess(object):

def __init__(self, model):
self.__isValid = self._init(model)
def __init__(self, model, altGeometry=None):
self.__isValid = self._init(model, altGeometry)
self.__resetZoomPolicy = None
self.__method = None
self.__errorMessage = None

def _init(self, model):
def _init(self, model, altGeometry=None):
self.__isValid = True
if model is None:
return False
Expand All @@ -117,7 +120,10 @@ def _init(self, model):
detector = model.experimentSettingsModel().detector()
if detector is None:
return
geometry = model.fittedGeometry()
if altGeometry:
geometry = altGeometry
else:
geometry = model.fittedGeometry()
if not geometry.isValid():
return False
self.__nPointsAzimuthal = model.integrationSettingsModel().nPointsAzimuthal().value()
Expand Down Expand Up @@ -905,15 +911,15 @@ def _initGui(self):

self.__integrationUpToDate = True
self.__integrationResetZoomPolicy = None
method = method_registry.Method(666, "bbox", "csr", "cython", None)
method = method_registry.Method(666, "bbox", "histogram", "cython", None)
self.__setMethod(method)

positiveValidator = validators.IntegerAndEmptyValidator(self)
positiveValidator.setBottom(1)

self._radialPoints.setValidator(positiveValidator)
self._azimuthalPoints.setValidator(positiveValidator)
self._radialUnit.setUnits(pyFAI.units.RADIAL_UNITS.values())
self._radialUnit.setUnits(core_units.RADIAL_UNITS.values())
self.__polarizationModel = None
self._polarizationFactorCheck.clicked[bool].connect(self.__polarizationFactorChecked)
self.widgetShow.connect(self.__widgetShow)
Expand Down Expand Up @@ -985,7 +991,8 @@ def __widgetShow(self):
self._integrateButton.executeCallable()

def __integrate(self):
self.__integrationProcess = IntegrationProcess(self.model())
geometry = self._geometryTabs.geometryModel()
self.__integrationProcess = IntegrationProcess(self.model(), geometry)
self.__integrationProcess.setMethod(self.__method)

if self.__integrationResetZoomPolicy is not None:
Expand Down Expand Up @@ -1058,13 +1065,16 @@ def __fittedGeometryChanged(self):
poniFile = self.model().experimentSettingsModel().poniFile()
with poniFile.lockContext():
poniFile.setSynchronized(False)
# Update displayed data:
self.__updateDisplayedGeometry()

def __saveAsPoni(self):
# FIXME test the validity of the geometry before opening the dialog
dialog = createSaveDialog(self, "Save as PONI file", poni=True)
# Disable the warning as the data is append to the file
dialog.setOption(qt.QFileDialog.DontConfirmOverwrite, True)
poniFile = self.model().experimentSettingsModel().poniFile()
model = self.model()
poniFile = model.experimentSettingsModel().poniFile()
previousPoniFile = poniFile.value()
if previousPoniFile is not None:
dialog.selectFile(previousPoniFile)
Expand All @@ -1080,21 +1090,19 @@ def __saveAsPoni(self):
with poniFile.lockContext():
poniFile.setValue(filename)

pyfaiGeometry = pyFAI.geometry.Geometry()

geometry = self.model().fittedGeometry()
pyfaiGeometry.dist = geometry.distance().value()
pyfaiGeometry.poni1 = geometry.poni1().value()
pyfaiGeometry.poni2 = geometry.poni2().value()
pyfaiGeometry.rot1 = geometry.rotation1().value()
pyfaiGeometry.rot2 = geometry.rotation2().value()
pyfaiGeometry.rot3 = geometry.rotation3().value()
pyfaiGeometry.wavelength = geometry.wavelength().value()

experimentSettingsModel = self.model().experimentSettingsModel()
geometry = self._geometryTabs.geometryModel()
experimentSettingsModel = model.experimentSettingsModel()
detector = experimentSettingsModel.detector()
pyfaiGeometry.detector = detector

pyfaiGeometry = pyFAI.geometry.Geometry(
dist=geometry.distance().value(),
poni1=geometry.poni1().value(),
poni2=geometry.poni2().value(),
rot1=geometry.rotation1().value(),
rot2=geometry.rotation2().value(),
rot3=geometry.rotation3().value(),
wavelength=geometry.wavelength().value(),
detector=detector
)
try:
writer = ponifile.PoniFile(pyfaiGeometry)
with open(filename, "wt") as fd:
Expand All @@ -1104,3 +1112,9 @@ def __saveAsPoni(self):
poniFile.setSynchronized(True)
except Exception as e:
MessageBox.exception(self, "Error while saving poni file", e, _logger)

def __updateDisplayedGeometry(self):
"Called after the fit"
experimentSettingsModel = self.model().experimentSettingsModel()
self._geometryTabs.setDetector(experimentSettingsModel.detector())
self._geometryTabs.setGeometryModel(self.model().fittedGeometry())
Loading

0 comments on commit fc21530

Please sign in to comment.