slaclab / psgeom

code for representing the geometry of scattering experiments
Other
2 stars 3 forks source link

IMP: projective assembly code #31

Open tjlane opened 4 years ago

tjlane commented 4 years ago

We would like to be able to view a 2d projection of a 3d detector geometry, with intensity data.

In the past at LCLS this has been done by writing custom rotation/translation/interpolation code for each detector. We would like to write one generic function that can do this efficiently using psgeoms generic detector representation.

tjlane commented 4 years ago

For reference, @valmar 's "quick and dirty" assembly code from cfelpyutils: https://github.com/lucagelisio/cfelpyutils/blob/a626e4569bcb9b1da5fc878ce95f46c4ff972606/cfelpyutils/geometry_utils.py#L175

def apply_geometry_to_data(data, geometry):
    # type: (numpy.ndarray, Dict[str, Any]) -> numpy.ndarray
    """
    Applies CrystFEL geometry information to some data.

    This function takes as input some geometry information read from a `CrystFEL
    <http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html>`_ file, and
    some data on which to apply the information. It returns an array that can be
    displayed using libraries like `matplotlib <https://matplotlib.org/>`_ or
    `PyQtGraph <http://pyqtgraph.org/>`_.

    The shape of the returned array is big enough to display all the pixel values in
    the input data, and is symmetric around the center of the reference system
    (i.e: the beam interaction point).

    These restrictions often cause the returned array to be bigger than the minimum
    size needed to store the physical layout of the pixels in the detector,
    particularly if the detector is not centered at the beam interaction point.

    Arguments:

        data (numpy.ndarray): the data on which the geometry information should be
            applied.

        geometry (Dict[str, Any]): a CrystFEL geometry object (A dictionary returned by
            the :func:`~cfelpyutils.crystfel_utils.load_crystfel_geometry` function).

    Returns:

        numpy.ndarray: an array containing the data with the geometry information
        applied.
    """
    pixel_maps = compute_pix_maps(geometry)
    x_map, y_map = pixel_maps.x, pixel_maps.y
    y_minimum = 2 * int(max(abs(y_map.max()), abs(y_map.min()))) + 2
    x_minimum = 2 * int(max(abs(x_map.max()), abs(x_map.min()))) + 2
    min_shape = (y_minimum, x_minimum)
    visualization_array = numpy.zeros(min_shape, dtype=float)
    visual_pixel_maps = compute_visualization_pix_maps(geometry)
    visualization_array[
        visual_pixel_maps.y.flatten(), visual_pixel_maps.x.flatten()
    ] = data.ravel().astype(visualization_array.dtype)
    return visualization_array