def add_shape_to_detector(
    builder: NexusBuilder,
    detector_group: h5py.Group,
    detector_ids: np.ndarray,
    voxels: np.ndarray,
    vertices: np.ndarray,
    offsets: Tuple[np.ndarray, np.ndarray, np.ndarray],
):
    builder.add_dataset(detector_group, "x_pixel_offset", offsets[0],
                        {"units": "m"})
    builder.add_dataset(detector_group, "y_pixel_offset", offsets[1],
                        {"units": "m"})
    builder.add_dataset(detector_group, "z_pixel_offset", offsets[2],
                        {"units": "m"})

    winding_order = voxels.flatten().astype(np.int32)

    vertices_in_face = 4
    faces = np.arange(0, winding_order.size, vertices_in_face)

    shape_group = builder.add_nx_group(detector_group, "detector_shape",
                                       "NXoff_geometry")
    builder.add_dataset(shape_group, "vertices", vertices.astype(np.float64))
    builder.add_dataset(shape_group, "winding_order", winding_order)
    builder.add_dataset(shape_group, "faces", faces.astype(np.int32))
    builder.add_dataset(shape_group, "detector_faces",
                        detector_ids.astype(np.int32))
    builder.add_dataset(
        detector_group,
        "detector_number",
        np.unique(detector_ids[:, 1]).astype(np.int32),
    )
    transforms_group = builder.add_nx_group(detector_group, "transformations",
                                            "NXtransformations")
    builder.add_transformation(
        transforms_group,
        "translation",
        -4.1,
        "m",
        [0.0, 0.0, 1.0],
        name="translation",
    )
    return transforms_group
Exemple #2
0
def add_voxel_detector(nexus_builder: NexusBuilder, n_voxels: int = 3):
    detector_group = nexus_builder.add_detector_minimal(
        "voxel geometry detector", 1)

    vertices = np.array([[0.0, 0.0, 0.0]])
    off_faces = np.empty((0, 4), dtype=int)
    detector_numbers = np.arange(n_voxels)
    detector_faces = np.empty((0, 2), dtype=int)
    for voxel_number in range(n_voxels):
        # Each voxel is a regular octahedron
        new_vertices = np.array([
            [0.0, 0.0, 1.0 - 2 * voxel_number],
            [1.0, 0.0, 0.0 - 2 * voxel_number],
            [0.0, 1.0, 0.0 - 2 * voxel_number],
            [-1.0, 0.0, 0.0 - 2 * voxel_number],
            [0.0, -1.0, 0.0 - 2 * voxel_number],
            [0.0, 0.0, -1.0 - 2 * voxel_number],
        ])
        vertices = np.append(vertices[:-1, :], new_vertices, axis=0)

        # Number of vertices followed by vertex indices for each face
        # the first column doesn't end up in the NeXus file dataset
        new_off_faces = np.array([
            [3, 1 + 5 * voxel_number, 5 * voxel_number, 4 + 5 * voxel_number],
            [3, 4 + 5 * voxel_number, 5 * voxel_number, 3 + 5 * voxel_number],
            [3, 3 + 5 * voxel_number, 5 * voxel_number, 2 + 5 * voxel_number],
            [3, 2 + 5 * voxel_number, 5 * voxel_number, 1 + 5 * voxel_number],
            [
                3, 1 + 5 * voxel_number, 5 + 5 * voxel_number,
                2 + 5 * voxel_number
            ],
            [
                3, 2 + 5 * voxel_number, 5 + 5 * voxel_number,
                3 + 5 * voxel_number
            ],
            [
                3, 3 + 5 * voxel_number, 5 + 5 * voxel_number,
                4 + 5 * voxel_number
            ],
            [
                3, 4 + 5 * voxel_number, 5 + 5 * voxel_number,
                1 + 5 * voxel_number
            ],
        ])
        off_faces = np.append(off_faces, new_off_faces, axis=0)

        detector_number = detector_numbers[voxel_number]
        # Map 8 faces to each detector number
        new_detector_faces = np.array([
            [detector_number * 8, detector_number],
            [1 + detector_number * 8, detector_number],
            [2 + detector_number * 8, detector_number],
            [3 + detector_number * 8, detector_number],
            [4 + detector_number * 8, detector_number],
            [5 + detector_number * 8, detector_number],
            [6 + detector_number * 8, detector_number],
            [7 + detector_number * 8, detector_number],
        ])
        detector_faces = np.append(detector_faces, new_detector_faces, axis=0)

    nexus_builder.add_shape(detector_group, "detector_shape", vertices,
                            off_faces, detector_faces)
    nexus_builder.add_dataset(detector_group, "detector_number",
                              detector_numbers)

    transform_group = nexus_builder.add_nx_group(detector_group,
                                                 "transformations",
                                                 "NXtransformation")
    position = nexus_builder.add_transformation(
        transform_group,
        "translation",
        np.array([2.0]),
        units="m",
        vector=[1.0, 0.0, 1.0],
        name="position",
    )
    nexus_builder.add_dataset(detector_group, "depends_on", position.name)

    # Record the voxel positions
    x_offsets = 1.1 * np.ones(n_voxels, dtype=float)
    y_offsets = 2.2 * np.ones(n_voxels, dtype=float)
    z_offsets = np.arange(-n_voxels, n_voxels, 2.0, dtype=float)
    nexus_builder.add_dataset(detector_group, "x_pixel_offset", x_offsets)
    nexus_builder.add_dataset(detector_group, "y_pixel_offset", y_offsets)
    nexus_builder.add_dataset(detector_group, "z_pixel_offset", z_offsets)

    write_to_off_file(f"{n_voxels}_voxels.off", vertices.shape[0],
                      off_faces.shape[0], vertices, off_faces)