Пример #1
0
def test_offset_px_mm_strategy():
    from dxtbx.model import Panel
    from dxtbx.model import OffsetParallaxCorrectedPxMmStrategy
    from scitbx.array_family import flex

    # for future reference this is the array the same shape
    # as the image in pixels with offsets in pixels

    dx = flex.double(flex.grid(10, 10), 1)
    dy = flex.double(flex.grid(10, 10), 1)

    strategy = OffsetParallaxCorrectedPxMmStrategy(1, 1, dx, dy)

    p = Panel()
    p.set_image_size((10, 10))
    p.set_mu(1)
    p.set_thickness(1)
    p.set_px_mm_strategy(strategy)

    d = p.to_dict()

    pnew = Panel.from_dict(d)
    assert pnew == p

    pnew = pickle.loads(pickle.dumps(pnew))
    assert pnew == p
Пример #2
0
    def run(self):
        from dxtbx.model import Panel
        from dxtbx.model import OffsetParallaxCorrectedPxMmStrategy
        from scitbx.array_family import flex
        import cPickle as pickle

        dx = flex.double(flex.grid(10, 10), 1)
        dy = flex.double(flex.grid(10, 10), 1)

        strategy = OffsetParallaxCorrectedPxMmStrategy(1, 1, dx, dy)

        p = Panel()
        p.set_image_size((10, 10))
        p.set_mu(1)
        p.set_thickness(1)
        p.set_px_mm_strategy(strategy)

        d = p.to_dict()

        pnew = Panel.from_dict(d)

        assert pnew == p

        pnew = pickle.loads(pickle.dumps(pnew))

        assert pnew == p

        print 'OK'
Пример #3
0
def get_optimized_detector(x, SIM):
    from dxtbx.model import Detector, Panel
    new_det = Detector()
    for pid in range(len(SIM.detector)):
        panel = SIM.detector[pid]
        panel_dict = panel.to_dict()
        group_id = SIM.panel_group_from_id[pid]
        if group_id in SIM.panel_groups_refined:
            Oang = x["group%d_RotOrth" % group_id].value
            Fang = x["group%d_RotFast" % group_id].value
            Sang = x["group%d_RotSlow" % group_id].value
            Xdist = x["group%d_ShiftX" % group_id].value
            Ydist = x["group%d_ShiftY" % group_id].value
            Zdist = x["group%d_ShiftZ" % group_id].value

            origin_of_rotation = SIM.panel_reference_from_id[pid]
            SIM.D.reference_origin = origin_of_rotation
            SIM.D.update_dxtbx_geoms(SIM.detector, SIM.beam.nanoBragg_constructor_beam, pid,
                                     Oang, Fang, Sang, Xdist, Ydist, Zdist,
                                     force=False)
            fdet = SIM.D.fdet_vector
            sdet = SIM.D.sdet_vector
            origin = SIM.D.get_origin()
        else:
            fdet = panel.get_fast_axis()
            sdet = panel.get_slow_axis()
            origin = panel.get_origin()
        panel_dict["fast_axis"] = fdet
        panel_dict["slow_axis"] = sdet
        panel_dict["origin"] = origin

        new_det.add_panel(Panel.from_dict(panel_dict))

    return new_det
Пример #4
0
def get_multi_panel_eiger(detdist_mm=200,
                          pixsize_mm=0.075,
                          as_single_panel=False):
    """

    :param detdist_mm: sample to detector in mm
    :param pixsize_mm: pix in mm
    :param as_single_panel: whether to return as just a large single panel camera
    :return: dxtbx detector
    """
    # load a file specifying the gap positions
    # this is a 2D array
    # usually -1 is a gap, so you can create this array by doing
    # is_a_gap = np.array(eiger_image)==-1  (pseudo)
    is_a_gap = h5py.File("eiger_gaps.h5", "r")["is_a_gap"][()]

    # to view:
    #import pylab as plt
    #plt.imshow( is_a_gap)
    #plt.show()
    # its not perfect, some small regions are also flagged, we shall filter them though

    ydim, xdim = is_a_gap.shape

    center_x = xdim / 2. * pixsize_mm
    center_y = ydim / 2. * pixsize_mm
    master_panel_dict = {
        'type': 'SENSOR_PAD',
        'fast_axis': (1.0, 0.0, 0.0),
        'slow_axis': (0.0, -1.0, 0.0),
        'origin': (-center_x, center_y, -detdist_mm),
        'raw_image_offset': (0, 0),
        'image_size': (xdim, ydim),
        'pixel_size':
        (pixsize_mm, pixsize_mm),  # NOTE this will depend on your model
        'trusted_range': (-1.0, 65535.0),
        'thickness': 0.45,
        'material': 'Si',
        'mu': 3.969545947994824,
        'identifier': '',
        'mask': [],
        'gain': 1.0,
        'pedestal': 0.0,
        'px_mm_strategy': {
            'type': 'SimplePxMmStrategy'
        }
    }

    master_panel = Panel.from_dict(master_panel_dict)
    master_det = Detector()
    master_det.add_panel(master_panel)

    if as_single_panel:
        return master_det
    else:
        return panelize_eiger(master_det, is_a_gap)
def get_optimized_detector(x, ref_params, SIM):
    new_det = Detector()
    for pid in range(len(SIM.detector)):
        panel = SIM.detector[pid]
        panel_dict = panel.to_dict()
        group_id = SIM.panel_group_from_id[pid]
        if group_id in SIM.panel_groups_refined:

            Oang_p = ref_params["group%d_RotOrth" % group_id]
            Fang_p = ref_params["group%d_RotFast" % group_id]
            Sang_p = ref_params["group%d_RotSlow" % group_id]
            Xdist_p = ref_params["group%d_ShiftX" % group_id]
            Ydist_p = ref_params["group%d_ShiftY" % group_id]
            Zdist_p = ref_params["group%d_ShiftZ" % group_id]

            Oang = Oang_p.get_val(x[Oang_p.xpos])
            Fang = Fang_p.get_val(x[Fang_p.xpos])
            Sang = Sang_p.get_val(x[Sang_p.xpos])
            Xdist = Xdist_p.get_val(x[Xdist_p.xpos])
            Ydist = Ydist_p.get_val(x[Ydist_p.xpos])
            Zdist = Zdist_p.get_val(x[Zdist_p.xpos])

            origin_of_rotation = SIM.panel_reference_from_id[pid]
            SIM.D.reference_origin = origin_of_rotation
            SIM.D.update_dxtbx_geoms(SIM.detector,
                                     SIM.beam.nanoBragg_constructor_beam,
                                     pid,
                                     Oang,
                                     Fang,
                                     Sang,
                                     Xdist,
                                     Ydist,
                                     Zdist,
                                     force=False)
            fdet = SIM.D.fdet_vector
            sdet = SIM.D.sdet_vector
            origin = SIM.D.get_origin()
        else:
            fdet = panel.get_fast_axis()
            sdet = panel.get_slow_axis()
            origin = panel.get_origin()
        panel_dict["fast_axis"] = fdet
        panel_dict["slow_axis"] = sdet
        panel_dict["origin"] = origin

        new_det.add_panel(Panel.from_dict(panel_dict))

    return new_det
Пример #6
0
def downsample_detector(det, downsamp=1):
    newD = Detector()
    for panel in det:
        fast = panel.get_fast_axis()
        slow = panel.get_slow_axis()
        orig = panel.get_origin()
        panel_dict = panel.to_dict()
        panel_dict['fast'] = fast
        panel_dict['slow'] = slow
        panel_dict['origin'] = orig
        fast_dim, slow_dim = panel.get_image_size()
        panel_dict['image_size'] = int(fast_dim / float(downsamp)), int(
            slow_dim / float(downsamp))
        pixsize = panel.get_pixel_size()[0]
        panel_dict['pixel_size'] = pixsize * downsamp, pixsize * downsamp
        newpanel = Panel.from_dict(panel_dict)
        newD.add_panel(newpanel)

    return newD
Пример #7
0
def panelize_eiger(eiger_dxtbx_model, is_a_gap):
    """
  :param eiger_dxtbx_model: dxtbx geometry for the eiger (single node model)
  :param is_a_gap: a 2D numpy array the same shape as the eiger image (4371, 4150)
    True means the pixel is a gap, False means the pixel is a mask
    Make this by loading an eiger image and selecting all pixels that are equal to -1
    is_a_gap = np.array(eiger_image)==-1
  :return: dxtbx multi panel model for eiger 16M
  """
    multiEiger = Detector()
    # we will make a new detector where wach panel has its own origin, but all share the same fast,slow scan directions
    detector_origin = np.array(eiger_dxtbx_model[0].get_origin())
    F = np.array(eiger_dxtbx_model[0].get_fast_axis())
    S = np.array(eiger_dxtbx_model[0].get_slow_axis())
    pixsize = eiger_dxtbx_model[0].get_pixel_size()[0]
    panel_dict = eiger_dxtbx_model[0].to_dict()

    is_a_panel = np.logical_not(is_a_gap)
    labs, nlabs = label(is_a_panel)

    for i in range(nlabs + 1):
        region = labs == i
        npixels = np.sum(region)
        # there might be some other connected regions that are not panels (bad regions for example)
        if 200000 < npixels < 530000:  # panel size is 529420 pixels, I think
            ypos, xpos = np.where(region)
            jmin, imin = min(ypos), min(
                xpos)  # location of first pixel in the region
            jmax, imax = max(ypos), max(xpos)
            panel_shape = (int(imax - imin), int(jmax - jmin))
            panel_origin = detector_origin + F * imin * pixsize + S * jmin * pixsize
            panel_dict["origin"] = tuple(panel_origin)
            panel_dict["image_size"] = panel_shape
            panel = Panel.from_dict(panel_dict)
            multiEiger.add_panel(panel)

    return multiEiger
Пример #8
0
def test_offset_px_mm_strategy():
    # for future reference this is the array the same shape
    # as the image in pixels with offsets in pixels

    dx = flex.double(flex.grid(10, 10), 1)
    dy = flex.double(flex.grid(10, 10), 1)

    strategy = OffsetParallaxCorrectedPxMmStrategy(1, 1, dx, dy)

    p = Panel()
    p.set_image_size((10, 10))
    p.set_mu(1)
    p.set_thickness(1)
    p.set_px_mm_strategy(strategy)

    d = p.to_dict()

    # Panel.from_dict sets the strategy to ParallaxCorrectedPxMmStrategy rather than
    # OffsetParallaxCorrectedPxMmStrategy as the offsets aren't currently serialized
    pnew = Panel.from_dict(d)
    assert pnew != p

    pnew = pickle.loads(pickle.dumps(pnew))
    assert pnew != p
Пример #9
0
from dxtbx.model import Panel

for i_shift, delta_shift in enumerate(shifts_mm):
    # update the detector model

    if args.panel == "x":
        shifted = OX + delta_shift, OY, OZ
    elif args.panel == "y":
        shifted = OX, OY + delta_shift, OZ
    else:
        delta_shift = delta_shift * 10  # larger shift for Z
        shifted = OX, OY, OZ + delta_shift

    node_d["origin"] = shifted
    det[0] = Panel.from_dict(node_d)

    D.update_dxtbx_geoms(det, B, 0)
    D.add_diffBragg_spots()
    img_forward = D.raw_pixels_roi.as_numpy_array()
    D.raw_pixels_roi *= 0
    D.raw_pixels *= 0
    delta_shift_meters = delta_shift * 1e-3
    fdiff = (img_forward - img) / delta_shift_meters

    bragg = img > 1e-2

    error = (np.abs(fdiff[bragg] - deriv[bragg])).mean()
    all_errors.append(error)

    all_shifts.append(delta_shift_meters)
def update_detector(x, ref_params, SIM, save=None):
    """
    Update the internal geometry of the diffBragg instance
    :param x: refinement parameters as seen by scipy.optimize (e.g. rescaled floats)
    :param ref_params: diffBragg.refiners.Parameters (dict of RangedParameters)
    :param SIM: SIM instance (instance of nanoBragg.sim_data.SimData)
    :param save: optional name to save the detector
    """
    det = SIM.detector
    if save is not None:
        new_det = Detector()
    for pid in range(len(det)):
        panel = det[pid]
        panel_dict = panel.to_dict()

        group_id = SIM.panel_group_from_id[pid]
        if group_id not in SIM.panel_groups_refined:
            fdet = panel.get_fast_axis()
            sdet = panel.get_slow_axis()
            origin = panel.get_origin()
        else:

            Oang_p = ref_params["group%d_RotOrth" % group_id]
            Fang_p = ref_params["group%d_RotFast" % group_id]
            Sang_p = ref_params["group%d_RotSlow" % group_id]
            Xdist_p = ref_params["group%d_ShiftX" % group_id]
            Ydist_p = ref_params["group%d_ShiftY" % group_id]
            Zdist_p = ref_params["group%d_ShiftZ" % group_id]

            Oang = Oang_p.get_val(x[Oang_p.xpos])
            Fang = Fang_p.get_val(x[Fang_p.xpos])
            Sang = Sang_p.get_val(x[Sang_p.xpos])
            Xdist = Xdist_p.get_val(x[Xdist_p.xpos])
            Ydist = Ydist_p.get_val(x[Ydist_p.xpos])
            Zdist = Zdist_p.get_val(x[Zdist_p.xpos])

            origin_of_rotation = SIM.panel_reference_from_id[pid]
            SIM.D.reference_origin = origin_of_rotation
            SIM.D.update_dxtbx_geoms(det,
                                     SIM.beam.nanoBragg_constructor_beam,
                                     pid,
                                     Oang,
                                     Fang,
                                     Sang,
                                     Xdist,
                                     Ydist,
                                     Zdist,
                                     force=False)
            fdet = SIM.D.fdet_vector
            sdet = SIM.D.sdet_vector
            origin = SIM.D.get_origin()

        if save is not None:
            panel_dict["fast_axis"] = fdet
            panel_dict["slow_axis"] = sdet
            panel_dict["origin"] = origin
            new_det.add_panel(Panel.from_dict(panel_dict))

    if save is not None and COMM.rank == 0:
        t = time.time()
        El = ExperimentList()
        E = Experiment()
        E.detector = new_det
        El.append(E)
        El.as_file(save)
        t = time.time() - t
        print("Saved detector model to %s (took %.4f sec)" % (save, t),
              flush=True)
Пример #11
0
def convert_crystfel_to_dxtbx(geom_filename,
                              output_filename,
                              detdist_override=None):
    """
  :param geom_filename: a crystfel geometry file https://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html
  :param output_filename: filename for a dxtbx experiment containing a single detector model (this is a json file)
  :param detdist_override: alter the detector distance stored in the crystfel geometry to this value (in millimeters)
  """
    geom = load_crystfel_geometry(geom_filename)

    dxtbx_det = Detector()

    for panel_name in geom['panels'].keys():
        P = geom['panels'][panel_name]
        FAST = P['fsx'], P['fsy'], P['fsz']
        SLOW = P['ssx'], P['ssy'], P['ssz']

        # dxtbx uses millimeters
        pixsize = 1 / P['res']  # meters
        pixsize_mm = pixsize * 1000
        detdist = P['coffset'] + P['clen']  # meters
        detdist_mm = detdist * 1000
        if detdist_override is not None:
            detdist_mm = detdist_override
        # dxtbx and crystfel both identify the outer corner of the first pixel in memory as the origin of the panel
        origin = P['cnx'] * pixsize_mm, P[
            'cny'] * pixsize_mm, -detdist_mm  # dxtbx assumes crystal as at point 0,0,0

        num_fast_pix = P["max_fs"] - P['min_fs'] + 1
        num_slow_pix = P["max_ss"] - P['min_ss'] + 1

        panel_description = {
            'fast_axis': FAST,
            'gain': 1.0,  # I dont think nanoBragg cares about this parameter
            'identifier': '',
            'image_size': (num_fast_pix, num_slow_pix),
            'mask': [],
            'material': 'Si',
            'mu': 0,  # NOTE for a thick detector set this to appropriate value
            'name': panel_name,
            'origin': origin,
            'pedestal':
            0.0,  # I dont think nanoBragg cares about this parameter
            'pixel_size': (pixsize_mm, pixsize_mm),
            'px_mm_strategy': {
                'type': 'SimplePxMmStrategy'
            },
            'raw_image_offset': (0, 0),  # not sure what this is
            'slow_axis': SLOW,
            'thickness':
            0,  # note for a thick detector set this to appropriate value
            'trusted_range': (-1.0, 1e6),  # set as you wish
            'type': 'SENSOR_PAD'
        }
        dxtbx_node = Panel.from_dict(panel_description)
        dxtbx_det.add_panel(dxtbx_node)

    E = Experiment()
    E.detector = dxtbx_det
    El = ExperimentList()
    El.append(E)
    El.as_file(output_filename)  # this can be loaded into nanoBragg