wtbarnes / mocksipipeline

Pipeline for producing synthetic images from the Multi-Order Spectral Imager (MOXSI)
MIT License
3 stars 1 forks source link

More sophisticated PSF treatment #35

Closed wtbarnes closed 3 months ago

wtbarnes commented 5 months ago

We need to apply a more careful treatment of the point spread function. Currently, we are just applying an appropriately-sized Gaussian blur at the spectral cube level while choosing the orientation carefully such that it matches the orientation of the PSF on the detector. This matters a lot in cases where the PSF is asymmetric (i.e. the slot overlappogram).

Instead, what we want to do is add position variation to each photon as it is mapped down to the detector based on the PSF. This allows us to perform this whole entire process in pixel coordinates which is where the PSF is defined. This just manifests as variations in the position that are the result of treating the PSF as a probability distribution and sampling from it.

Below is an example of how to do this given a PSF kernel,

def sample_psf_2d(kernel, n_samples):
    """
    Sample a PSF to find the position variation for a number of incoming photons
    """
    x_variation = np.arange(kernel.shape[1]) - kernel.center[1] + 0.5*(~kernel.shape[1]%2)
    y_variation = np.arange(kernel.shape[0]) - kernel.center[0] + 0.5*(~kernel.shape[0]%2)
    x_variation_grid, y_variation_grid = np.meshgrid(x_variation, y_variation)
    sample_indices = np.random.choice(kernel.array.size, size=n_samples, p=kernel.array.flatten())
    sample_indices = np.unravel_index(sample_indices, kernel.shape)
    return np.array([x_variation_grid[sample_indices], y_variation_grid[sample_indices]])

This is slightly more complicated if there is a wavelength-dependence to the PSF, but simply means this process has to be done repeatedly for each wavelength using the appropriate kernel.

wtbarnes commented 5 months ago

Here's a task list for completing this: