Replies: 6 comments 4 replies
|
Hi James, If you are just interested in the But if you want to perform the integration, such integrator does not yet exists but it should not be too complicated to adapt the sparse-CSC engine (probably the Cython implementation is the most effective one to start with) to be able to work on such COO data. The code should be single threaded (per frame) but can be parallelized between frames. Basically, the COO format is a list of The CSC-sparse array is composed of 3 arrays called Initialize 2 output containers called *Then loop over all pixels in your sparse frame, calculate its
The average value is then the ratio between |
|
There is an example in https://github.com/jonwright/bslz4_to_sparse/blob/main/test/test_dot.py It calls on a bslz4_to_sparse.chunk2sparseCSC object that is defined in bslz4_to_sparse/init.py This is installed in the ESRF conda. It does need a more user-friendly wrapper....! |
|
Thanks both for taking a look. import pyFAI
from pyFAI.integrator import load_engines
import fabio
import numpy as np
import scipy.sparse
from ImageD11.sinograms import dataset
import ImageD11.sparseframe
# prepare files needed
ponifile = 'path/to/poni'
maskfile = 'path/to/mask'
dsfile = 'path/to/ImageD11/ds'
# prepare pyFAI integrator
ai = pyFAI.load(ponifile)
msk = fabio.open(ds.maskfile).data
npt_rad = 3000
npt_azim = 5000
engine = ai.setup_sparse_integrator(algo='CSR', shape=ai.detector.shape, npt=(npt_rad,npt_azim), mask=msk, unit='2th_deg', split='full')
# get the lut of the engine
lut = (engine._data, engine._indices, engine._indptr)
# convert to CSR matrix format
csr_transformer = scipy.sparse.csr_array(lut)
# now we make the sparse CSR from the ImageD11 data
ds = ImageD11.sinograms.dataset.load(dsfile)
sparse_scan = ImageD11.sparseframe.SparseScan(ds.sparsefile, ds.scans[0])
# sparse_scan is a list of COO over (n_frames, rows, cols)
# convert (rows, cols) to flat index of (total_pixels,)
width = msk.shape[1]
flat_indices = (sparse_scan.row.astype(np.int64) * width + sparse_scan.col).astype(np.int64)
# nnz is "active pixels per frame" in ImageD11 COO list
# convert to indptr
indptr = np.zeros(len(sparse_scan.nnz) + 1, dtype=np.int32)
np.cumsum(sparse_scan.nnz, out=indptr[1:])
# shape of data CSR - (n_frames, total_pixels)
total_pixels = msk.size
shape = (len(sparse_scan.nnz), total_pixels)
# make scipy CSR
csr_data = scipy.sparse.csr_array((sparse_scan.intensity, flat_indices, indptr), shape=shape)
# perform the transform - very very fast!!!
# this happens over all frames at once.
result_sparse = csr_transformer.dot(csr_data.T)
# normalise the transform
# avoiding dividing by zero weights
# dot-product array of ones
weights_vec = csr_transformer.dot(np.ones((msk.size, 1)))
inv_w = np.zeros_like(weights_vec)
np.divide(1.0, weights_vec, out=inv_w, where=weights_vec != 0)
norm_sparse = result_sparse.multiply(inv_w) |
|
It should be just to change weights_vec to use the polarisation and solid angle arrays (masked) that you have in the |
|
I agree with Jon about the normalization, it is the denominator of eq1 in Everything is available in the cached_array's dictonary. Beside this, if you don't want to densify your image (stored as COO), you have to work with a linear transformation which is stored as a CSC sparse matrix, not as a CSR sparse matrix.
|
|
Calculate the arrays like this:
* `ai.array_from_unit(unit="2th_deg")`
* `ai.array_from_unit(unit="chi_deg")`
Cheers,
|
Uh oh!
There was an error while loading. Please reload this page.
Hello all,
At ID11 we are collecting many millions of extremely sparse Eiger frames currently. In the past with Frelon data, we have just integrated dense -> dense images and saved them, but the data volumes were much lower. In ImageD11, we have a SparseFrame format which is basically just a COO format (I think!). Would it be possible in some way to feed this into pyFAI to convert sparse detector pixels into sparse 2d (tth, chi) values?
All reactions