usnistgov / PyHyperScattering

Tools for hyperspectral x-ray and neutron scattering data loading, reduction, slicing, and visualization.
Other
6 stars 8 forks source link

feat: general beamcenter calibration #57

Open pdudenas opened 1 year ago

pdudenas commented 1 year ago

The beam center recorded in SST1 metadata is a decent starting place, but I find refinement is often necessary. I've found that simply minimizing the variance of I(chi) over some q slice is a pretty robust method and doesn't require having sharp peaks. The downside is it's fairly slow, calling integrate_radial. I know @pbeaucage has tinkered around with this problem, and I'm curious if anyone else has. Below is the function that I minimize with scipy.optimize.minimize

def func2(x, image, q_min, q_max, chi_min, chi_max, integrator):
    poni1, poni2, rot1, rot2 = x
    integrator.poni1 = poni1
    integrator.poni2 = poni2
    integrator.rot1 = rot1
    integrator.rot2 = rot2

    image_chi, image_int = integrator.integrate_radial(image, 150, radial_range=(q_min, q_max), azimuth_range=(chi_min, chi_max))
    return np.var(image_int[image_int != 0 ])
pbeaucage commented 1 year ago

This is a faster/better version of what I did. I support shipping this in SST1RSoXS unless anybody else has a better solution.

The real, long-term solution is to take the scans that @EliotGann and I did last beamtime (direct beam on detector with undulator massively detuned) and fit a Gauss2D to those results. I am an advocate for writing a macro that does this and running that macro once a day or something like that until we know how much (if at all) the beamcenter really moves. Based on our diagnosis of the ugly beam shape, I suspect that any vibrations on the mesh will move the beamcenter around potentially significantly.

pdudenas commented 1 year ago

To get back to this, how do you want to integrate this into PyHyper @pbeaucage ? Put it in the RSoXS class so that it's accessible through .rsoxs, have it in it's own file, or somewhere else?

pbeaucage commented 1 year ago

My first vote would be to put it into the much-neglected .util. namespace, similar to the integration checking and mask drawing widgets... I'm not sure that organization makes sense but it's at least consistent with the other things around it.

pdudenas commented 1 year ago

I created a util xarray accessor to hold the beamcentering. You can invoke it with dataArray.util.refine_geometry(energy, q_min, q_max, chi_min, chi_max), which I thought was fairly clean. It will update the poni1 and poni2 in the dataArray attributes if the optimization is successful.

If there are performance concerns with extra accessors, or you just want a class similar to the integration checking and mask utils, I can convert it.

link to code