def tst_beam_plane_intersection():
    from dxtbx.model import Panel
    from scitbx import matrix

    # The input parameters (from a GXPARM.XDS file)
    fast_axis = (0.000000, -0.939693, -0.342020)
    slow_axis = (1.000000, 0.000000, 0.000000)
    normal = (0.000000, -0.342020, 0.939693)
    pixel_size = (0.172000, 0.172000)
    pixel_origin = (244.836136, 320.338531)
    image_size = (487, 619)
    distance = 122.124901
    wavelength = 0.689400

    # Calculate the vector to the detector (0, 0) pixel
    origin = ((matrix.col(fast_axis).normalize() * pixel_size[0]) *
              (0 - pixel_origin[0]) +
              (matrix.col(slow_axis).normalize() * pixel_size[1]) *
              (0 - pixel_origin[1]) +
              (distance * matrix.col(normal).normalize()))

    # Create a detector object
    panel = Panel("", "", fast_axis, slow_axis, origin, pixel_size, image_size,
                  (0, 0), 0.0, "")

    # Create the intersection object
    intersection = lambda x: panel.get_ray_intersection(x)

    # Perform a load of tests
    tst_intersection_at_origin(intersection, wavelength, origin)
    tst_intersection_at_corners(intersection, panel, wavelength)
    tst_intersection_away_from_panel(intersection, panel, wavelength)
Beispiel #2
0
def tst_panel():
  '''Test pickling the panel object.'''
  obj1 = Panel()
  obj1.set_local_frame((1, 0, 0), (0, 1, 0), (0, 0, 1))
  obj2 = pickle_then_unpickle(obj1)
  assert(obj1 == obj2)
  print "OK"
Beispiel #3
0
def tst_panel():
    '''Test pickling the panel object.'''
    obj1 = Panel()
    obj1.set_local_frame((1, 0, 0), (0, 1, 0), (0, 0, 1))
    obj2 = pickle_then_unpickle(obj1)
    assert (obj1 == obj2)
    print "OK"
def tst_forward_and_reverse_transform():
    from dxtbx.model import Panel
    from scitbx import matrix

    # The input parameters (from a GXPARM.XDS file)
    fast_axis = (0.000000, -0.939693, -0.342020)
    slow_axis = (1.000000, 0.000000, 0.000000)
    normal = (0.000000, -0.342020, 0.939693)
    pixel_size = (0.172000, 0.172000)
    pixel_origin = (244.836136, 320.338531)
    image_size = (487, 619)
    distance = 122.124901
    wavelength = 0.689400

    # Calculate the vector to the detector (0, 0) pixel
    origin = ((matrix.col(fast_axis).normalize() * pixel_size[0]) *
              (0 - pixel_origin[0]) +
              (matrix.col(slow_axis).normalize() * pixel_size[1]) *
              (0 - pixel_origin[1]) +
              (distance * matrix.col(normal).normalize()))

    # Create a detector object
    panel = Panel("", "", fast_axis, slow_axis, origin, pixel_size, image_size,
                  (0, 0), 0.0, "")

    # Create the intersection object and transform object
    intersection = lambda x: panel.get_ray_intersection(x)
    transform = lambda x: panel.get_lab_coord(x)

    # Do a test
    tst_fwd_rev_random(intersection, transform, panel)
def tst_forward_and_reverse_transform():
  from dxtbx.model import Panel
  from scitbx import matrix

  # The input parameters (from a GXPARM.XDS file)
  fast_axis = (0.000000, -0.939693, -0.342020)
  slow_axis = (1.000000,  0.000000,  0.000000)
  normal = (0.000000, -0.342020,  0.939693)
  pixel_size = (0.172000, 0.172000)
  pixel_origin = (244.836136, 320.338531)
  image_size = (487, 619)
  distance = 122.124901
  wavelength = 0.689400

  # Calculate the vector to the detector (0, 0) pixel
  origin = ((matrix.col(fast_axis).normalize() * pixel_size[0]) *
              (0 - pixel_origin[0]) +
            (matrix.col(slow_axis).normalize() * pixel_size[1]) *
              (0 - pixel_origin[1]) +
            (distance * matrix.col(normal).normalize()))

  # Create a detector object
  panel = Panel("", "", fast_axis, slow_axis, origin, pixel_size,
               image_size, (0, 0), 0.0, "")

  # Create the intersection object and transform object
  intersection = lambda x: panel.get_ray_intersection(x)
  transform = lambda x: panel.get_lab_coord(x)

  # Do a test
  tst_fwd_rev_random(intersection, transform, panel)
Beispiel #6
0
def test_detector():
    '''Test pickling the detector object.'''
    p = Panel()
    p.set_local_frame((1, 0, 0), (0, 1, 0), (0, 0, 1))
    obj1 = Detector(p)
    obj2 = pickle_then_unpickle(obj1)
    assert obj1 == obj2
def tst_beam_plane_intersection():
  from dxtbx.model import Panel
  from scitbx import matrix

  # The input parameters (from a GXPARM.XDS file)
  fast_axis = (0.000000, -0.939693, -0.342020)
  slow_axis = (1.000000,  0.000000,  0.000000)
  normal = (0.000000, -0.342020,  0.939693)
  pixel_size = (0.172000, 0.172000)
  pixel_origin = (244.836136, 320.338531)
  image_size = (487, 619)
  distance = 122.124901
  wavelength = 0.689400

  # Calculate the vector to the detector (0, 0) pixel
  origin = ((matrix.col(fast_axis).normalize() * pixel_size[0]) *
              (0 - pixel_origin[0]) +
            (matrix.col(slow_axis).normalize() * pixel_size[1]) *
              (0 - pixel_origin[1]) +
            (distance * matrix.col(normal).normalize()))

  # Create a detector object
  panel = Panel("", "", fast_axis, slow_axis, origin, pixel_size,
                image_size, (0, 0), 0.0, "")

  # Create the intersection object
  intersection = lambda x: panel.get_ray_intersection(x)

  # Perform a load of tests
  tst_intersection_at_origin(intersection, wavelength, origin)
  tst_intersection_at_corners(intersection, panel, wavelength)
  tst_intersection_away_from_panel(intersection, panel, wavelength)
Beispiel #8
0
def test_panel_mask():
    panel = Panel()
    panel.set_image_size((100, 100))
    panel.add_mask(40, 0, 60, 100)
    panel.add_mask(0, 40, 100, 60)
    panel.set_trusted_range((-1, 10))

    data = flex.double(flex.grid(100, 100))
    data[10, 10] = -1
    data[20, 20] = 10
    data[30, 30] = 100
    data[40, 40] = -10

    m1 = panel.get_untrusted_rectangle_mask()
    m2 = panel.get_trusted_range_mask(data)

    count = 0
    for j in range(100):
        for i in range(40, 60):
            assert m1[j, i] is False
            count += 1
    for i in range(100):
        for j in range(40, 60):
            if i >= 40 and i < 60:
                continue
            assert m1[j, i] is False
            count += 1
    assert m1.count(False) == count, "%d, %d" % (m1.count(False), count)

    assert m2.count(False) == 4
    assert m2[10, 10] is False
    assert m2[20, 20] is False
    assert m2[30, 30] is False
    assert m2[40, 40] is False
Beispiel #9
0
def tst_detector():
  '''Test pickling the detector object.'''
  p = Panel()
  p.set_local_frame((1, 0, 0), (0, 1, 0), (0, 0, 1))
  obj1 = Detector(p)
  obj2 = pickle_then_unpickle(obj1)
  assert(obj1 == obj2)
  print "OK"
Beispiel #10
0
def test_hierarchical_detector():
    '''Test pickling the detector object.'''
    p = Panel()
    p.set_local_frame((1, 0, 0), (0, 1, 0), (0, 0, 1))
    obj1 = Detector()
    root = obj1.hierarchy()
    root.add_panel(p)
    root.add_group()
    obj2 = pickle_then_unpickle(obj1)
    assert obj2.hierarchy()[0] == obj2[0]
    assert obj2.hierarchy()[0] in obj2
    assert obj2.hierarchy()[1].is_group()
    assert obj1 == obj2
Beispiel #11
0
def tst_hierarchical_detector():
  '''Test pickling the detector object.'''
  p = Panel()
  p.set_local_frame((1, 0, 0), (0, 1, 0), (0, 0, 1))
  obj1 = Detector()
  root = obj1.hierarchy()
  root.add_panel(p)
  root.add_group()
  obj2 = pickle_then_unpickle(obj1)
  assert(obj2.hierarchy()[0] == obj2[0])
  assert(obj2.hierarchy()[0] in obj2)
  assert(obj2.hierarchy()[1].is_group())
  assert(obj1 == obj2)
  print "OK"
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
Beispiel #13
0
    def tst_set_models(imageset):
        # Create some other models
        beam = Beam((1, 0, 0), 0.5)
        detector = Detector(
            Panel(
                "UNKNOWN",
                "Panel",
                (1, 0, 0),
                (0, 1, 0),
                (0, 0, 1),
                (0.1, 0.1),
                (1000, 1000),
                (0, 1),
            ))

        # Override sequence models
        imageset.set_beam(beam)
        imageset.set_detector(detector)

        # Ensure this doens't interfere with reading
        for i in imageset:
            pass

        # Get the models back and check they're ok
        beam2 = imageset.get_beam()
        detector2 = imageset.get_detector()
        assert beam2 == beam
        assert detector2 == detector

        # Get the models from an index back and check they're not the same
        beam2 = imageset.get_beam(0)
        detector2 = imageset.get_detector(0)
        assert beam2 != beam
        assert detector2 != detector
Beispiel #14
0
def test_parallax_correction():
    # Attenuation length
    table = attenuation_coefficient.get_table("Si")
    mu = table.mu_at_angstrom(1) / 10.0
    t0 = 0.320

    # Create the detector
    detector = Detector(
        Panel(
            "",  # Type
            "",  # Name
            (10, 0, 0),  # Fast axis
            (0, 10, 0),  # Slow axis
            (0, 0, 200),  # Origin
            (0.172, 0.172),  # Pixel size
            (512, 512),  # Image size
            (0, 1000),  # Trusted range
            0.0,  # Thickness
            "",  # Material
            ParallaxCorrectedPxMmStrategy(mu, t0),
        )
    )
    for i in range(10000):
        mm = (random.uniform(-1000, 1000), random.uniform(-1000, 1000))
        px = detector[0].millimeter_to_pixel(mm)
        mm2 = detector[0].pixel_to_millimeter(px)
        assert abs(matrix.col(mm) - matrix.col(mm2)) < 1e-3
Beispiel #15
0
def create_multipanel_detector(offset, ncols=3, nrows=2):
    reference_detector = create_detector(offset)
    reference_panel = reference_detector[0]
    panel_npix = reference_panel.get_image_size()
    panel_npix = int(panel_npix[0] / ncols), int(panel_npix[1] / nrows)

    multi_panel_detector = Detector()
    for i in range(ncols):
        for j in range(nrows):
            origin_pix = i * panel_npix[0], j * panel_npix[1]
            origin = reference_panel.get_pixel_lab_coord(origin_pix)
            new_panel = Panel(
                reference_panel.get_type(),
                reference_panel.get_name() + str(j + i * nrows),
                reference_panel.get_fast_axis(),
                reference_panel.get_slow_axis(),
                origin,
                reference_panel.get_pixel_size(),
                panel_npix,
                reference_panel.get_trusted_range(),
                reference_panel.get_thickness(),
                reference_panel.get_material(),
                identifier=reference_panel.get_identifier(),
            )
            multi_panel_detector.add_panel(new_panel)

    return multi_panel_detector
Beispiel #16
0
def make_panel_in_array(array_elt, reference_panel):
    """Helper function to make a panel in a coplanar array with each panel size
    1/3 that of a reference panel"""

    px_size = tuple((e / 3.0) for e in reference_panel.get_pixel_size())
    ref_panel_size = reference_panel.get_image_size_mm()
    x_shift = array_elt[0] * ref_panel_size[0] / 3.0
    y_shift = array_elt[1] * ref_panel_size[1] / 3.0
    origin = (
        matrix.col(reference_panel.get_origin())
        + x_shift * matrix.col(reference_panel.get_fast_axis())
        + y_shift * matrix.col(reference_panel.get_slow_axis())
    )
    return Panel(
        type="PAD",
        name="Panel",
        fast_axis=reference_panel.get_fast_axis(),
        slow_axis=reference_panel.get_slow_axis(),
        origin=origin,
        pixel_size=px_size,
        image_size=reference_panel.get_image_size(),
        trusted_range=(0, 1.0e6),
        thickness=0.0,
        material="",
    )
def test_plane_to_lab_transform():
    from dxtbx.model import Panel

    # The input parameters (from a GXPARM.XDS file)
    fast_axis = (0.000000, -0.939693, -0.342020)
    slow_axis = (1.000000, 0.000000, 0.000000)
    normal = (0.000000, -0.342020, 0.939693)
    pixel_size = (0.172000, 0.172000)
    pixel_origin = (244.836136, 320.338531)
    image_size = (487, 619)
    distance = 122.124901

    # Calculate the vector to the detector (0, 0) pixel
    origin = ((matrix.col(fast_axis).normalize() * pixel_size[0]) *
              (0 - pixel_origin[0]) +
              (matrix.col(slow_axis).normalize() * pixel_size[1]) *
              (0 - pixel_origin[1]) +
              (distance * matrix.col(normal).normalize()))

    # Create a detector object
    panel = Panel("", "", fast_axis, slow_axis, origin, pixel_size, image_size,
                  (0, 0), 0.0, "")

    # Create the intersection object
    transform = panel.get_lab_coord

    # Perform a load of tests
    tst_transform_at_origin(transform, panel)
    tst_transform_at_corners(transform, panel)
Beispiel #18
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
Beispiel #20
0
 def create_detector(offset=0):
     # Create the detector
     detector = Detector(
         Panel(
             "",  # Type
             "Panel",  # Name
             (10, 0, 0),  # Fast axis
             (0, 10, 0),  # Slow axis
             (0 + offset, 0 + offset, 200 - offset),
             # Origin
             (0.172, 0.172),  # Pixel size
             (512, 512),  # Image size
             (0, 1000),  # Trusted range
             0.1,  # Thickness
             "Si",  # Material
             identifier="123"))  # Identifier
     return detector
Beispiel #21
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
Beispiel #22
0
def random_panel(lim=(0, 50)):
    """For testing, return a square panel with a randomised position
    and orientation"""

    # start with a randomised origin vector
    o = matrix.col(
        (
            random.uniform(-200, 200),
            random.uniform(-200, 200),
            random.uniform(-200, 200),
        )
    )

    # two orthogonal unit vectors randomly oriented in the normal plane
    # of the origin vector
    u1 = o.ortho().normalize()
    u2 = o.cross(u1).normalize()
    # theta = random.uniform(0, 2. * pi)
    u1 = u1.rotate_around_origin(o, pi / 12)
    u2 = u2.rotate_around_origin(o, pi / 12)

    # offset the plane normal from the origin vector by random rotations
    # of up to 45 degrees for each direction
    u1 = u1.rotate_around_origin(u2, random.uniform(-pi / 2.0, pi / 2.0))
    u2 = u2.rotate_around_origin(u1, random.uniform(-pi / 2.0, pi / 2.0))

    return Panel(
        "PAD",
        "Panel",
        u1,
        u2,
        o,
        (lim[1] / 200, lim[1] / 200),
        (200, 200),
        (0, 2e20),
        0.0,
        "",
    )
Beispiel #23
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
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
Beispiel #25
0
def test_detector():
    from dxtbx.model import ParallaxCorrectedPxMmStrategy

    def create_detector(offset=0):
        # Create the detector
        detector = Detector(
            Panel(
                "",  # Type
                "Panel",  # Name
                (10, 0, 0),  # Fast axis
                (0, 10, 0),  # Slow axis
                (0 + offset, 0 + offset, 200 - offset),
                # Origin
                (0.172, 0.172),  # Pixel size
                (512, 512),  # Image size
                (0, 1000),  # Trusted range
                0.1,  # Thickness
                "Si",  # Material
                identifier="123"))  # Identifier
        return detector

    detector = create_detector()

    # Perform some tests
    tst_get_identifier(detector)
    tst_get_gain(detector)
    tst_set_mosflm_beam_centre(detector)
    tst_get_pixel_lab_coord(detector)
    tst_get_image_size_mm(detector)
    tst_is_value_in_trusted_range(detector)
    tst_is_coord_valid(detector)
    tst_pixel_to_millimeter_to_pixel(detector)
    tst_get_names(detector)
    tst_get_thickness(detector)
    tst_get_material(detector)
    tst_resolution(detector)
    tst_panel_mask()

    # Attenuation length
    from cctbx.eltbx import attenuation_coefficient
    table = attenuation_coefficient.get_table("Si")
    mu = table.mu_at_angstrom(1) / 10.0
    t0 = 0.320

    # Create another detector with different origin
    detector_moved = create_detector(offset=100)
    tst_detectors_are_different(detector, detector_moved)

    detector_moved_copy = create_detector(offset=100)
    tst_detectors_are_same(detector_moved, detector_moved_copy)

    # Create the detector
    detector = Detector(
        Panel(
            "",  # Type
            "",  # Name
            (10, 0, 0),  # Fast axis
            (0, 10, 0),  # Slow axis
            (0, 0, 200),  # Origin
            (0.172, 0.172),  # Pixel size
            (512, 512),  # Image size
            (0, 1000),  # Trusted range
            0.0,  # Thickness
            "",  # Material
            ParallaxCorrectedPxMmStrategy(mu, t0)))

    tst_parallax_correction(detector)
Beispiel #26
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'
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)
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)
Beispiel #29
0
def test_panel():
    """Test pickling the panel object."""
    obj1 = Panel()
    obj1.set_local_frame((1, 0, 0), (0, 1, 0), (0, 0, 1))
    obj2 = pickle_then_unpickle(obj1)
    assert obj1 == obj2
Beispiel #30
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()

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

    pnew = pickle.loads(pickle.dumps(pnew))
    assert pnew == p
Beispiel #31
0
    def _setup_detector(self, detector, beam):
        nx_detector = detector.handle
        nx_module = detector.modules[0].handle

        # Get the detector name and type
        if "type" in nx_detector:
            detector_type = str(nx_detector["type"][()])
        else:
            detector_type = "unknown"
        detector_name = str(nx_detector.name)

        # Get the trusted range of pixel values
        if "saturation_value" in nx_detector:
            trusted_range = (-1, float(nx_detector["saturation_value"][()]))
        else:
            trusted_range = (-1, 99999999)

        # Get the detector thickness
        thickness = nx_detector["sensor_thickness"]
        thickness_value = float(thickness[()])
        thickness_units = thickness.attrs["units"]
        thickness_value = float(convert_units(thickness_value, thickness_units, "mm"))

        # Get the detector material
        material = nx_detector["sensor_material"][()]
        if hasattr(material, "shape"):
            material = "".join(m.decode() for m in material)
        detector_material = clean_string(str(material))
        material = {
            "Si": "Si",
            np.string_("Si"): "Si",
            np.string_("Silicon"): "Si",
            np.string_("Sillicon"): "Si",
            np.string_("CdTe"): "CdTe",
            np.string_("GaAs"): "GaAs",
        }.get(detector_material)
        if not material:
            raise RuntimeError("Unknown material: %s" % detector_material)

        try:
            x_pixel = nx_detector["x_pixel_size"][()] * 1000.0
            y_pixel = nx_detector["y_pixel_size"][()] * 1000.0

            legacy_beam_x = float(x_pixel * nx_detector["beam_center_x"][()])
            legacy_beam_y = float(y_pixel * nx_detector["beam_center_y"][()])
            legacy_distance = float(1000 * nx_detector["detector_distance"][()])
        except KeyError:
            legacy_beam_x = 0
            legacy_beam_y = 0

        # Get the fast pixel size and vector
        fast_pixel_direction = nx_module["fast_pixel_direction"]
        fast_pixel_direction_value = float(fast_pixel_direction[()])
        fast_pixel_direction_units = fast_pixel_direction.attrs["units"]
        fast_pixel_direction_vector = fast_pixel_direction.attrs["vector"]
        fast_pixel_direction_value = convert_units(
            fast_pixel_direction_value, fast_pixel_direction_units, "mm"
        )
        fast_axis = matrix.col(fast_pixel_direction_vector).normalize()

        # Get the slow pixel size and vector
        slow_pixel_direction = nx_module["slow_pixel_direction"]
        slow_pixel_direction_value = float(slow_pixel_direction[()])
        slow_pixel_direction_units = slow_pixel_direction.attrs["units"]
        slow_pixel_direction_vector = slow_pixel_direction.attrs["vector"]
        slow_pixel_direction_value = convert_units(
            slow_pixel_direction_value, slow_pixel_direction_units, "mm"
        )
        slow_axis = matrix.col(slow_pixel_direction_vector).normalize()

        origin = matrix.col((0.0, 0.0, -legacy_distance))
        if origin.elems[0] == 0.0 and origin.elems[1] == 0:
            origin = -(origin + legacy_beam_x * fast_axis + legacy_beam_y * slow_axis)

        # Change of basis to convert from NeXus to IUCr/ImageCIF convention
        cob = matrix.sqr((-1, 0, 0, 0, 1, 0, 0, 0, -1))
        origin = cob * matrix.col(origin)
        fast_axis = cob * fast_axis
        slow_axis = cob * slow_axis

        # Ensure that fast and slow axis are orthogonal
        normal = fast_axis.cross(slow_axis)
        slow_axis = -fast_axis.cross(normal)

        # Compute the attenuation coefficient.
        # This will fail for undefined composite materials
        # mu_at_angstrom returns cm^-1, but need mu in mm^-1
        table = attenuation_coefficient.get_table(material)
        wavelength = beam.get_wavelength()
        mu = table.mu_at_angstrom(wavelength) / 10.0

        # Construct the detector model
        pixel_size = (fast_pixel_direction_value, slow_pixel_direction_value)
        # image size stored slow to fast but dxtbx needs fast to slow
        image_size = tuple(int(x) for x in reversed(nx_module["data_size"][-2:]))
        image_size = (1030, 1064)

        self.model = Detector()
        self.model.add_panel(
            Panel(
                detector_type,
                detector_name,
                tuple(fast_axis),
                tuple(slow_axis),
                tuple(origin),
                pixel_size,
                image_size,
                trusted_range,
                thickness_value,
                material,
                mu,
            )
        )

        # Set the parallax correction
        for panel in self.model:
            panel.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, thickness_value))
            panel.set_type("SENSOR_PAD")

        self._detector_model = self.model
Beispiel #32
0
    def __init__(self, obj, beam):
        from dxtbx.model import Detector, Panel
        from cctbx.eltbx import attenuation_coefficient
        from dxtbx.model import ParallaxCorrectedPxMmStrategy
        from scitbx import matrix

        # Get the handles
        nx_file = obj.handle.file
        nx_detector = obj.handle
        nx_module = obj.modules[0].handle

        # Get the detector name and type
        detector_type = str(nx_detector['type'][()])
        detector_name = str(nx_detector.name)

        # Get the trusted range of pixel values
        trusted_range = (-1, float(nx_detector['saturation_value'][()]))

        # Get the detector thickness
        thickness = nx_detector['sensor_thickness']
        thickness_value = float(thickness[()])
        thickness_units = thickness.attrs['units']
        thickness_value = float(
            convert_units(thickness_value, thickness_units, "mm"))

        # Get the detector material
        material = str(nx_detector['sensor_material'][()])

        # Get the fast pixel size and vector
        fast_pixel_direction = nx_module['fast_pixel_direction']
        fast_pixel_direction_value = float(fast_pixel_direction[()])
        fast_pixel_direction_units = fast_pixel_direction.attrs['units']
        fast_pixel_direction_vector = fast_pixel_direction.attrs['vector']
        fast_pixel_direction_value = convert_units(fast_pixel_direction_value,
                                                   fast_pixel_direction_units,
                                                   "mm")
        fast_axis = matrix.col(fast_pixel_direction_vector).normalize()

        # Get the slow pixel size and vector
        slow_pixel_direction = nx_module['slow_pixel_direction']
        slow_pixel_direction_value = float(slow_pixel_direction[()])
        slow_pixel_direction_units = slow_pixel_direction.attrs['units']
        slow_pixel_direction_vector = slow_pixel_direction.attrs['vector']
        slow_pixel_direction_value = convert_units(slow_pixel_direction_value,
                                                   slow_pixel_direction_units,
                                                   "mm")
        slow_axis = matrix.col(slow_pixel_direction_vector).normalize()

        # Get the origin vector
        module_offset = nx_module['module_offset']
        origin = construct_vector(nx_file, module_offset.name)

        # Ensure that fast and slow axis are orthogonal
        normal = fast_axis.cross(slow_axis)
        slow_axis = -fast_axis.cross(normal)

        # Compute the attenuation coefficient.
        # This will fail for undefined composite materials
        # mu_at_angstrom returns cm^-1, but need mu in mm^-1
        if material == 'Si':
            pass
        elif material == 'Silicon':
            material = 'Si'
        elif material == 'Sillicon':
            material = 'Si'
        elif material == 'CdTe':
            pass
        elif material == 'GaAs':
            pass
        else:
            raise RuntimeError('Unknown material: %s' % material)
        table = attenuation_coefficient.get_table(material)
        wavelength = beam.get_wavelength()
        mu = table.mu_at_angstrom(wavelength) / 10.0

        # Construct the detector model
        pixel_size = (fast_pixel_direction_value, slow_pixel_direction_value)
        image_size = tuple(map(int, nx_module['data_size']))

        self.model = Detector()
        self.model.add_panel(
            Panel(detector_type, detector_name, tuple(fast_axis),
                  tuple(slow_axis), tuple(origin), pixel_size, image_size,
                  trusted_range, thickness_value, material, mu))

        # Set the parallax correction
        for panel in self.model:
            panel.set_px_mm_strategy(
                ParallaxCorrectedPxMmStrategy(mu, thickness_value))
            panel.set_type('SENSOR_PAD')
Beispiel #33
0
dl = (-0.001825172553060027, -0.9999981947571188, -37.76001244640159, 0.9999973206373582, -0.0018259228624977202, 19.59161224494454, -0.0014238901839527113, -0.0005258214562373528, -150.0059)

dl1 = dl[0], dl[3], dl[6]
dl2 = dl[1], dl[4], dl[7]
dl0 = dl[2], dl[5], dl[8]

dp1 = dp[0], dp[3], dp[6]
dp2 = dp[1], dp[4], dp[7]
dp0 = dp[2], dp[5], dp[8]

d1 = (-0.00182517255306, 0.999997320637, -0.00142389018396)
d2 = (0.999998194757, 0.0018259228625, 0.000525821456245)
d0 = (-48.3367467929, -1.3827137802, -149.981643976)

p = Panel()
p.set_parent_frame(dp1, dp2, dp0)
p.set_local_frame(dl1, dl2, dl0)
p.set_frame(d1, d2, d0)


#print repr([10000000000*pp for pp in p.get_parent_d_matrix()])
#for pp in p.get_parent_d_matrix():
#  print '{0:.16f}'.format(pp)

#
#p.set_local_frame(dl1, dl2, dl0)

#d_matrix1 = p.get_d_matrix()

#p = Panel()
Beispiel #34
0
    -150.0059,
)

dl1 = dl[0], dl[3], dl[6]
dl2 = dl[1], dl[4], dl[7]
dl0 = dl[2], dl[5], dl[8]

dp1 = dp[0], dp[3], dp[6]
dp2 = dp[1], dp[4], dp[7]
dp0 = dp[2], dp[5], dp[8]

d1 = (-0.00182517255306, 0.999997320637, -0.00142389018396)
d2 = (0.999998194757, 0.0018259228625, 0.000525821456245)
d0 = (-48.3367467929, -1.3827137802, -149.981643976)

p = Panel()
p.set_parent_frame(dp1, dp2, dp0)
p.set_local_frame(dl1, dl2, dl0)
p.set_frame(d1, d2, d0)

# print repr([10000000000*pp for pp in p.get_parent_d_matrix()])
# for pp in p.get_parent_d_matrix():
#  print '{0:.16f}'.format(pp)

#
# p.set_local_frame(dl1, dl2, dl0)

# d_matrix1 = p.get_d_matrix()

# p = Panel()
# p.set_frame(dl1, dl2, dl0)