def test_flatfield_pipeline(): L = ave_ff.sink_to_list() mask_setting["setting"] = "none" ff = np.ones((2048, 2048)) # ff = np.random.random((2048, 2048)) ff *= np.random.normal(1, .01, size=(2048, 2048)) geo = Geometry( wavelength=.18e-10, detector="perkin", dist=.18, poni1=.1024 * 2, poni2=.1024 * 2, rot1=0, rot2=0, rot3=0, ) raw_foreground_dark.emit(0.0) raw_background_dark.emit(0.0) raw_background.emit(0.0) is_calibration_img.emit(False) geo_input.emit(geo.getPyFAI()) motors.emit((0, 0)) img_counter.emit(1) q2 = geo.qArray((2048, 2048)) / 10. img = np.exp(-q2 / 25) * 10000 img2 = img * ff raw_foreground.emit(img2) assert len(L) == 1
def __init__(self, dist=1, poni1=0, poni2=0, rot1=0, rot2=0, rot3=0, pixel1=0, pixel2=0, splinefile=None, detector=None, wavelength=None, useqx=True, sample_orientation=1, incident_angle=None, tilt_angle=0): """ """ Geometry.__init__(self, dist, poni1, poni2, rot1, rot2, rot3, pixel1, pixel2, splinefile, detector, wavelength) self.useqx = useqx self.sample_orientation = sample_orientation self.incident_angle = incident_angle self.tilt_angle = tilt_angle # coordinate arrays for reciprocal space transformation self._gia_cen = None self._gia_crn = None self._gia_del = None self._giq_cen = None self._giq_crn = None self._giq_del = None # coordinate arrays for 1d and 2d integration self._absa_cen = None self._absa_crn = None self._absa_del = None self._absq_cen = None self._absq_crn = None self._absq_del = None # masks for missing data self._transformedmask = None # 2D, reciprocal/polar self._chimask = None # 1D, I vs chi
def __updatePyfaiFromFit2d(self): if self.__updatingModel: return self.__updatingModel = True geometry = self.__fit2dGeometry error = None distance = None poni1 = None poni2 = None rotation1 = None rotation2 = None rotation3 = None if geometry is None: error = "No geometry to compute pyFAI geometry." pass elif self.__detector is None: error = "No detector defined. It is needed to compute the pyFAI geometry." elif not geometry.isValid(): error = "The current geometry is not valid to compute the pyFAI one." else: pyFAIGeometry = Geometry(detector=self.__detector) try: f2d_distance = geometry.distance().value() f2d_centerX = geometry.centerX().value() f2d_centerY = geometry.centerY().value() f2d_tiltPlan = geometry.tiltPlan().value() f2d_tilt = geometry.tilt().value() pyFAIGeometry.setFit2D(directDist=f2d_distance, centerX=f2d_centerX, centerY=f2d_centerY, tilt=f2d_tilt, tiltPlanRotation=f2d_tiltPlan) except Exception: error = "This geometry can't be modelized with pyFAI." else: distance = pyFAIGeometry.dist poni1 = pyFAIGeometry.poni1 poni2 = pyFAIGeometry.poni2 rotation1 = pyFAIGeometry.rot1 rotation2 = pyFAIGeometry.rot2 rotation3 = pyFAIGeometry.rot3 self._fit2dError.setVisible(error is not None) self._fit2dError.setText(error) self.__geometry.lockSignals() self.__geometry.distance().setValue(distance) self.__geometry.poni1().setValue(poni1) self.__geometry.poni2().setValue(poni2) self.__geometry.rotation1().setValue(rotation1) self.__geometry.rotation2().setValue(rotation2) self.__geometry.rotation3().setValue(rotation3) self.__geometry.unlockSignals() self.__updatingModel = False
def test_bin_grid(): geo = Geometry( detector='Perkin', pixel1=.0002, pixel2=.0002, dist=.23, poni1=.209, poni2=.207, # poni1=0, poni2=0, # rot1=.0128, rot2=-.015, rot3=-5.2e-8, wavelength=1.43e-11 ) r_array = geo.rArray((2048, 2048)) img = r_array.copy() x, y = core.bin_grid(img, r_array, (geo.pixel1, geo.pixel2)) assert_array_almost_equal(y, x, decimal=2)
def q_from_geometry( shape: Tuple[int, int], geometry: Geometry, reflection: bool, alphai: float, ): """ Calculate the q vector for each pixel in an image Parameters: ----------- image: ndarray, detector image geometry: pyFAI Geometry PONI, Pixel Size, Sample Det dist etc alphai: scalar, deg angle of incedence out_range: list, optional [[left, right],[lower, upper]] for the output image res: list, optional resolution of the output image coord_sys: str 'qp_qz', 'qy_qz' or 'theta_alpha' Returns ------- qimage: ndarray remeshed/warped image xcrd: ndarray x-coords of warped image ycrd: ndarray y-coords of warped image """ assert shape == geometry.detector.shape[-2:] x = np.arange(shape[1]) y = np.arange(shape[0]) px_x, px_y = np.meshgrid(x, y) r_z, r_y, r_x = geometry.calc_pos_zyx(d1=px_y, d2=px_x) if reflection: alphas = alpha(r_x, r_y, r_z) - alphai phis = phi(r_x, r_y, r_z) k_i = k_f = 2 * np.pi / geometry.wavelength * 1e-10 q_x = k_f * np.cos(alphas) * np.cos(phis) - k_i * np.cos(alphai) q_y = k_f * np.cos(alphas) * np.sin(phis) q_z = (k_f * np.sin(alphas) + k_i * np.sin(alphai)) q_r = np.sqrt(q_x**2 + q_y**2) * np.sign(q_y) q_h = q_r q_v = q_z else: alphas = alpha(r_x, r_y, r_z) phis = phi(r_x, r_y, r_z) q_x, q_y, q_z = q_from_angles(phis, alphas, geometry.wavelength) * 1e-10 q_v = q_y q_h = q_x return np.dstack((q_h, q_v))
def __createGeoRefFromGeometry(self, geometryModel): geoRef = Geometry(dist=geometryModel.distance().value(), wavelength=geometryModel.wavelength().value(), poni1=geometryModel.poni1().value(), poni2=geometryModel.poni2().value(), rot1=geometryModel.rotation1().value(), rot2=geometryModel.rotation2().value(), rot3=geometryModel.rotation3().value(), detector=self.__detector) return geoRef
def reset(self): """ """ Geometry.reset(self) self._gia_cen = None self._gia_crn = None self._gia_del = None self._giq_cen = None self._giq_crn = None self._giq_del = None self._absa_cen = None self._absa_crn = None self._absa_del = None self._absq_cen = None self._absq_crn = None self._absq_del = None self._transformedmask = None self._chimask = None
def show_straight_lines(self, ai: pfGeometry, show: bool = True): # show the cake plot as well int2 = ai.integrate2d_ng( data=self.expt_params.image, npt_rad=500, npt_azim=360, unit="q_nm^-1", ) fig, ax = plt.subplots() fig.set_size_inches(8, 8) pfjupyter.plot2d(int2, calibrant=self.calibrant, ax=ax) plt.title("Are those lines straight?") if show: plt.show() else: fig.savefig(self.user_args.straight_lines, bbox_inches="tight") plt.close(fig)
def __createPyfaiGeometry(self): geometry = self.__geometry if not geometry.isValid(): raise RuntimeError("The geometry is not valid") dist = geometry.distance().value() poni1 = geometry.distance().value() poni2 = geometry.distance().value() rot1 = geometry.distance().value() rot2 = geometry.distance().value() rot3 = geometry.distance().value() wavelength = geometry.distance().value() result = Geometry(dist=dist, poni1=poni1, poni2=poni2, rot1=rot1, rot2=rot2, rot3=rot3, detector=self.__detector, wavelength=wavelength) return result
threshold = alpha * std lower = mean - threshold upper = mean + threshold # single out the too low and too high pixels too_low = img < lower[int_q] too_hi = img > upper[int_q] mask = mask * ~too_low * ~too_hi return mask.astype(bool) img_folder = '/mnt/bulk-data/research_data/USC_beamtime/APS_March_2016/S1/temp_exp' cal_folder = '/mnt/bulk-data/research_data/USC_beamtime/APS_March_2016/Calibration/CeO2_25_3_12' geo = Geometry() geo.load(os.path.join(cal_folder, 'CeO2calibration_25-00004_sum.poni')) lamda = geo.wavelength * 10 ** 10 print(lamda) img = TiffStack(os.path.join(img_folder, 'd25_S6_VT-00000.tif'))[0] mask = np.ones(img.shape, dtype=bool) mask *= mask_edge(img.shape, 30) r = geo.rArray((2048, 2048)) q = geo.qArray((2048, 2048)) rmax = np.max(r) qmax = np.max(q) pixel_size = geo.pixel1 distance = geo.dist
threshold = alpha * std lower = mean - threshold upper = mean + threshold print(len(mean), np.max(int_r), np.min(int_r)) # single out the too low and too high pixels too_low = img < lower[int_r] too_hi = img > upper[int_r] mask = mask * ~too_low * ~too_hi return mask.astype(bool) geo = Geometry( detector='Perkin', pixel1=.0002, pixel2=.0002, dist=.23, poni1=.209, poni2=.207, # rot1=.0128, rot2=-.015, rot3=-5.2e-8, wavelength=1.43e-11 ) r = geo.rArray((2048, 2048)) q = geo.qArray((2048, 2048)) pixels = np.arange(0, np.max(r), geo.pixel1) pixel_bottom = pixels pixel_top = pixels + geo.pixel1 tthb = np.arctan(pixel_bottom / geo.dist) ttht = np.arctan(pixel_top / geo.dist) dq = twotheta_to_q(ttht, .143) - twotheta_to_q(tthb, .143) fq = np.linspace(0, np.max(q), len(dq)) b = np.zeros(len(fq)+1) b[1:] = dq + fq
install_qt_kicker() ff = np.ones((2048, 2048)) ff *= np.random.normal(1, .01, size=(2048, 2048)) quad = np.ones((2048, 2048)) quad[1024:, 1024:] *= .5 ff *= quad ff = np.abs(ff) mask_setting["setting"] = "none" k = 5 geo = Geometry( wavelength=.18e-10, detector="perkin", dist=.18, poni1=.1024 * 2, poni2=.1024 * 2, rot1=0, rot2=0, rot3=0, ) raw_foreground_dark.emit(0.0) raw_background_dark.emit(0.0) raw_background.emit(0.0) ave_ff.map(lambda x: ((ff / x) - 1) * 100).map(np.nan_to_num).sink( LiveImage( "image", cmap="viridis", limit_func=lambda x: ( np.nanpercentile(x, .1), np.nanpercentile(x, 99.9),
def remesh(image: np.ndarray, geometry: Geometry, reflection: bool, alphai: float, bins: Tuple[int, int] = None, q_h_range: Tuple[float, float] = None, q_v_range: Tuple[float, float] = None, out_range=None, res=None, coord_sys='qp_qz'): """ Redraw the GI Image in (qp, qz) coordinates. Parameters: ----------- image: ndarray, detector image geometry: pyFAI Geometry PONI, Pixel Size, Sample Det dist etc alphai: scalar, deg angle of incedence out_range: list, optional [[left, right],[lower, upper]] for the output image res: list, optional resolution of the output image coord_sys: str 'qp_qz', 'qy_qz' or 'theta_alpha' Returns ------- qimage: ndarray remeshed/warped image xcrd: ndarray x-coords of warped image ycrd: ndarray y-coords of warped image """ geometry = geometry.__deepcopy__() geometry.setFit2D(geometry.getFit2D()["directDist"], geometry.getFit2D()["centerX"], len(image) - geometry.getFit2D()["centerY"]) assert image.shape == geometry.detector.shape x = np.arange(image.shape[1]) y = np.arange(image.shape[0]) px_x, px_y = np.meshgrid(x, y) r_z, r_y, r_x = geometry.calc_pos_zyx(d1=px_y, d2=px_x) if reflection: alphas = alpha(r_x, r_y, r_z) - alphai phis = phi(r_x, r_y, r_z) k_i = k_f = 2 * np.pi / geometry.wavelength * 1e-10 q_x = k_f * np.cos(alphas) * np.cos(phis) - k_i * np.cos(alphai) q_y = k_f * np.cos(alphas) * np.sin(phis) q_z = -(k_f * np.sin(alphas) + k_i * np.sin(alphai)) q_r = np.sqrt(q_x ** 2 + q_y ** 2) * np.sign(q_y) q_h = q_r q_v = -q_z else: alphas = alpha(r_x, r_y, r_z) phis = phi(r_x, r_y, r_z) q_x, q_y, q_z = q_from_angles(phis, alphas, geometry.wavelength) * 1e-10 q_v = -q_y # -q_y q_h = q_x if bins is None: bins = tuple(image.shape) if q_h_range is None: q_h_range = (q_h.min(), q_h.max()) if q_v_range is None: q_v_range = (q_v.min(), q_v.max()) I, q_h, q_v, _, _ = splitBBox.histoBBox2d(weights=image, pos0=q_h, delta_pos0=np.ones_like(image) * (q_h_range[1] - q_h_range[0]) / bins[0], pos1=q_v, delta_pos1=np.ones_like(image) * (q_v_range[1] - q_v_range[0]) / bins[1], bins=bins, pos0Range=q_h_range, pos1Range=q_v_range, dummy=None, delta_dummy=None, allow_pos0_neg=True, # mask=mask, # dark=dark, # flat=flat, # solidangle=solidangle, # polarization=polarization, # normalization_factor=normalization_factor, # chiDiscAtPi=self.chiDiscAtPi, # empty=dummy if dummy is not None else self._empty ) q_h, q_v = np.meshgrid(q_h, q_v) return I, q_h, q_v
from pyFAI import detectors import fabio filename = '/home/richard/SAXS/YL1031/AGB_5S_USE_2_2m.edf' fit2d = {'centerX': 237.5, 'centerY': 30.500000000000004,#1678 - 'directDist': 283.26979219190343, 'pixelX': 171.99999999999997, 'pixelY': 171.99999999999997, 'splineFile': None, 'tilt': 0.0, 'tiltPlanRotation': 0.0} det = detectors.Pilatus2M g = Geometry(wavelength=0.123984E-09) g.setFit2D(**fit2d) g.detector = det() data = fabio.open(filename).data ai = np.deg2rad(0.14) test_show(data) from pyFAI import calibrant test_show(calibrant.ALL_CALIBRANTS['AgBh'].fake_calibration_image(g)) # default qp-qz, same size as detector I, q_h, q_v = remesh(data, g, False, 0) # img, x, y = test_show(I)
def make_qmask(self): "create the q_mask from the geometry" experiment_setup = self.input.get("experiment_setup", {}) detector_section = self.input.get("detector", {}) pixel_size = detector_section.get("pixel") if pixel_size is None: self.log_error( "Pixel size is mandatory in detector description section") detector = Detector(pixel1=pixel_size, pixel2=pixel_size, max_shape=self.shape) wavelength = experiment_setup.get("wavelength") if wavelength is None: self.log_error( "wavelength is mandatory in experiment_setup section") else: wavelength *= 1e-10 # Convert Å in m distance = experiment_setup.get("detector_distance") if distance is None: self.log_error( "detector_distance is mandatory in experiment_setup section") directbeam_x = experiment_setup.get("directbeam_x") directbeam_y = experiment_setup.get("directbeam_y") if (directbeam_x is None) or (directbeam_y is None): self.log_error( "directbeam_[xy] is mandatory in experiment_setup section") self.unit = experiment_setup.get("unit", self.unit) geometry = Geometry(distance, directbeam_y * pixel_size, directbeam_x * pixel_size, detector=detector, wavelength=wavelength) self.ai = geometry firstq = experiment_setup.get("firstq", 0) widthq = experiment_setup.get("widthq", 0) stepq = experiment_setup.get("stepq", 0) numberq = experiment_setup.get( "numberq", (1 << 16) - 2) # we plan to store the qmask as uint16 if experiment_setup.get("q_mask"): qmask = fabio.open(experiment_setup["q_mask"]).data else: q_array = geometry.center_array(self.shape, unit=self.unit) detector_maskfile = detector_section.get("mask", '') if os.path.exists(detector_maskfile): detector_mask = fabio.open(detector_maskfile).data else: detector_mask = detector.mask if detector_mask is None: detector_mask = numpy.zeros(self.shape, dtype=numpy.int8) beamstop_maskfile = experiment_setup.get("beamstop_mask", "") if os.path.exists(beamstop_maskfile, ""): beamstop_mask = fabio.open(beamstop_maskfile).data else: beamstop_mask = numpy.zeros(self.shape, dtype=numpy.int8) mask = numpy.logical_or(detector_mask, beamstop_mask) if widthq is None: self.log_error( "widthq is mandatory in experiment_setup section") if numexpr is None: qmaskf = (q_array - firstq) / (widthq + stepq) qmaskf[qmaskf < 0] = 0 qmaskf[qmaskf > (numberq + 1)] = 0 qmaskf[(qmaskf % 1) > widthq / (widthq + stepq)] = 0 qmaskf[mask] = 0 qmask = qmaskf.astype(dtype=numpy.uint16) self.log_warning("numexpr is missing, calculation is slower") else: qmaskf = numexpr.evaluate( "(q_array - firstq) / (widthq + stepq)") qmask = numexpr.evaluate( "where(qmaskf<0, 0, where(qmaskf>(numberq+1),0, where((qmaskf%1)>(widthq/(widthq + stepq)), 0, where(mask, 0, qmaskf))))", out=numpy.empty(q_array.shape, dtype=numpy.uint16), casting="unsafe") self.qrange = firstq + widthq / 2.0 + numpy.arange( qmask.max()) * (widthq + stepq) return qmask