Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

q-chi 2dintegration for grazing incidence #2320

Open
ljr-1959 opened this issue Nov 4, 2024 · 6 comments
Open

q-chi 2dintegration for grazing incidence #2320

ljr-1959 opened this issue Nov 4, 2024 · 6 comments

Comments

@ljr-1959
Copy link

ljr-1959 commented Nov 4, 2024

Kudo's for adding grazing support.
Am I correct that there are no chigi_deg and chigi_rad AZMUTHAL_UNITS such that one cannot create a q-chi plot for the fiber/grazing geometry? (Equivalent to transform_polar of pygix)
If so, can this please be added. That transform is powerful when constructing pole-figures...
Thanks

@EdgarGF93
Copy link
Collaborator

EdgarGF93 commented Nov 5, 2024

Hello, pyFAI allows now to easily make a qip (in-plane) vs qoop (out-of-plane) representation of the pattern, that is the one that generates the missing wedge. This representation is useful for fiber/grazing-incidence, it's sensitive to incident_angle/tilt_angle, etc.
If you want to make a q-chi plot representation, (if I understand you correctly), this is the classical integrate2d result of pyFAI:

from pyFAI import load
from pyFAI.calibrant import get_calibrant
from pyFAI import detector_factory
from pyFAI.gui.jupyter import plot2d, subplots
from pyFAI.azimuthalIntegrator import AzimuthalIntegrator

ai = AzimuthalIntegrator(dist=0.1, wavelength=1e-10, detector=detector_factory("Pilatus1M"))
cal = get_calibrant('LaB6')
data = cal.fake_calibration_image(ai=ai)
res2d = ai.integrate2d(data=data, npt_rad=1000)

fig, ax = subplots()
plot2d(res2d, ax=ax)
ax.get_images()[0].set_clim(-1,1)

image

But this q is the modulus of the scattering vector, so it's the standard reshaping (or caking), to analyze textures in powder diffraction (so, it's not really specific for grazing-incidence)

If I'm missing something on your request, please tell me :)

@ljr-1959
Copy link
Author

ljr-1959 commented Nov 5, 2024 via email

@EdgarGF93
Copy link
Collaborator

EdgarGF93 commented Jan 17, 2025

Hello again. We are preparing the release of pyFAI 2025 before the end of January. Thanks for pointing out this pygix feature, this could be an interesting new feature for the fiber/grazing incidence module.
Does this look ok to you?c @ljr-1959

Image

@ljr-1959
Copy link
Author

ljr-1959 commented Jan 21, 2025 via email

@EdgarGF93
Copy link
Collaborator

EdgarGF93 commented Jan 26, 2025

Yes, with the new units, you can apply sector units.
For example, with a classic grazing incidence representation (qip-qoop):

from pyFAI.gui.jupyter import plot1d, plot2d, subplots
import matplotlib.pyplot as plt
from pyFAI.test.utilstest import UtilsTest
from pyFAI import load
import fabio

if __name__ == "__main__":
    fi = load(UtilsTest.getimage("LaB6_3.poni"), type_="pyFAI.integrator.fiber.FiberIntegrator")
    data = fabio.open(UtilsTest.getimage("Y6.edf")).data
    air = fabio.open(UtilsTest.getimage("air.edf")).data
    data_clean = data - 0.03 * air
    sample_orientation = 6
        
    res2d_0 = fi.integrate2d_grazing_incidence(data=data_clean, sample_orientation=sample_orientation,
                                            )
    
    res2d_patch_1 = fi.integrate2d_grazing_incidence(data=data_clean, sample_orientation=sample_orientation,
                                            ip_range=[-1,1], oop_range=[0,20],
                                            )
    res2d_patch_2 = fi.integrate2d_grazing_incidence(data=data_clean, sample_orientation=sample_orientation,
                                            ip_range=[-17.5,17.5], oop_range=[5,6.5],
                                            )
    
    
    res1d_0 = fi.integrate1d_grazing_incidence(data=data_clean, sample_orientation=sample_orientation,
                                            ip_range=[-1,1], oop_range=[0,20],
                                            npt_ip=100, npt_oop=500,
                                            vertical_integration=True,
                                            )
    res1d_1 = fi.integrate1d_grazing_incidence(data=data_clean, sample_orientation=sample_orientation,
                                            ip_range=[-17.5,17.5], oop_range=[5,6.5],
                                            npt_ip=500, npt_oop=100,
                                            vertical_integration=False,
                                            ) 
    
    fig, ax = subplots(ncols=4)
    plot2d(result=res2d_0, ax=ax[0])
    img = ax[0].get_images()[0]
    img.set_cmap("viridis")
    img.set_clim(20,200)
    
    plot2d(result=res2d_patch_1, ax=ax[1])
    plot2d(result=res2d_patch_2, ax=ax[1])
    plot2d(result=res2d_0, ax=ax[1])
    
    ax[1].get_images()[0].set_cmap("viridis")
    ax[1].get_images()[1].set_cmap("viridis")
    ax[1].get_images()[2].set_cmap("gray")
    ax[1].get_images()[2].set_alpha(0.5)
    
    plot1d(result=res1d_0, ax=ax[2])
    plot1d(result=res1d_1, ax=ax[3])
    
    plt.show()

The second plot represents the areas (vertical and horizontal) integrated into the 2nd and 3rd plots
Image

And using the polar units, the same, you can slice along these units:

from pyFAI.gui.jupyter import plot1d, plot2d, subplots
import matplotlib.pyplot as plt
from pyFAI import detector_factory
from pyFAI.calibrant import get_calibrant
from pyFAI.integrator.fiber import FiberIntegrator

if __name__ == "__main__":
    det = detector_factory("Eiger_4M")
    cal = get_calibrant("LaB6")
    fi = FiberIntegrator(detector=det, wavelength=1e-10, dist=0.1, poni1=0.05, poni2=0.05)
    data = cal.fake_calibration_image(ai=fi) * 1000 + 100
    
    sample_orientation = 1
    
    res2d= fi.integrate2d_grazing_incidence(data=data, sample_orientation=sample_orientation,
                                            )
        
    res2d_polar = fi.integrate2d_grazing_incidence(data=data, sample_orientation=sample_orientation,
                                                   unit_ip="qtot_nm^-1", unit_oop="chigi_rad",
                                            )
    res1d_0 = fi.integrate1d_grazing_incidence(data=data, sample_orientation=sample_orientation,
                                               unit_ip="qtot_nm^-1", unit_oop="chigi_rad",
                                            ip_range=[0,40], oop_range=[-0.2,0.2],
                                            npt_ip=1000, npt_oop=500,
                                            vertical_integration=False,
                                            )

    res2d_patch = fi.integrate2d_grazing_incidence(data=data, sample_orientation=sample_orientation,
                                               unit_ip="qtot_nm^-1", unit_oop="chigi_rad",
                                            ip_range=[0,40], oop_range=[-0.2,0.2],
                                            )
    
    fig, ax = subplots(ncols=4)
    plot2d(result=res2d, ax=ax[0])
    plot2d(result=res2d_polar, ax=ax[1])
    plot2d(result=res2d_patch, ax=ax[2])
    plot2d(result=res2d_polar, ax=ax[2])
    
    img = ax[0].get_images()[0]
    img.set_cmap("viridis")
    img = ax[1].get_images()[0]
    img.set_cmap("viridis")
    
    ax[2].get_images()[0].set_cmap("viridis")
    ax[2].get_images()[1].set_cmap("gray")
    ax[2].get_images()[1].set_alpha(0.5)
    plot1d(result=res1d_0, ax=ax[3])
    
    plt.show()

With the polar angle, you can also slice sectors and integrate them along one of the units (along the polar angle in this shown case)
Image

@ljr-1959

@EdgarGF93
Copy link
Collaborator

to be fixed in #2380

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants