p1 = col((x2,y1,0))
          p2 = col((x2,y2,0))
          p3 = col((x1,y2,0))

          v1 = p1-p0
          v2 = p3-p0
          vcen = ((v2/2) + (v1/2)) + p0

          ax.add_patch(Polygon((p0[0:2],p1[0:2],p2[0:2],p3[0:2]), closed=True, color='green', fill=False, hatch='/'))
          ax.annotate("%d"%(int(PANEL)), vcen[0:2])
        ax.set_xlim((0, 2000))
        ax.set_ylim((0, 2000))
        ax.set_ylim(ax.get_ylim()[::-1])
      else:

        root = geometry.get_top_geo()

        # get pixel mappings to real space.
        x, y, z = geometry.get_pixel_coords()
        assert x.shape == y.shape == z.shape
        if len(x.shape) == 6:
          x = x.reshape(x.shape[2:6])
          y = y.reshape(y.shape[2:6])
          z = z.reshape(z.shape[2:6])
        else:
          assert len(x.shape) == 4
        sensor_slow = x.shape[2]
        sensor_fast = x.shape[3]
        while True:
          if len(root.get_list_of_children()) == 4 or len(root.get_list_of_children()) == 32:
            break
          p2 = col((x2,y2,0))
          p3 = col((x1,y2,0))

          v1 = p1-p0
          v2 = p3-p0
          vcen = ((v2/2) + (v1/2)) + p0

          ax.add_patch(Polygon((p0[0:2],p1[0:2],p2[0:2],p3[0:2]), closed=True, color='green', fill=False, hatch='/'))
          ax.annotate("%d"%(int(PANEL)), vcen[0:2])
        ax.set_xlim((0, 2000))
        ax.set_ylim((0, 2000))
        ax.set_ylim(ax.get_ylim()[::-1])
      else:
        from xfel.cftbx.detector.cspad_cbf_tbx import basis_from_geo

        root = geometry.get_top_geo()
        root_basis = basis_from_geo(root)

        # get pixel mappings to real space.
        x, y, z = geometry.get_pixel_coords()
        assert x.shape == y.shape == z.shape
        if len(x.shape) == 6:
          x = x.reshape(x.shape[2:6])
          y = y.reshape(y.shape[2:6])
          z = z.reshape(z.shape[2:6])
        elif len(x.shape) == 5:
          x = x.reshape(x.shape[1:5])
          y = y.reshape(y.shape[1:5])
          z = z.reshape(z.shape[1:5])
        else:
          assert len(x.shape) == 4
Beispiel #3
0
def read_slac_metrology(path = None, geometry = None, plot=False, include_asic_offset=False):
  if path is None and geometry is None:
    raise Sorry("Need to provide a geometry object or a path to a geometry file")

  if path is not None and geometry is not None:
    raise Sorry("Cannot provide a geometry object and a geometry file. Ambiguous")

  if geometry is None:
    try:
      from PSCalib.GeometryAccess import GeometryAccess
      geometry = GeometryAccess(path)
    except Exception as e:
      raise Sorry("Can't parse this metrology file")

  metro = {}
  pixel_size = geometry.get_pixel_scale_size()/1000
  null_ori = matrix.col((0,0,1)).axis_and_angle_as_unit_quaternion(0, deg=True)

  # collapse any transformations above those of the quadrants into one X/Y offset,
  # but don't keep Z transformations, as those come from the XTC stream
  root = geometry.get_top_geo()
  root_basis = basis_from_geo(root, use_z=False)
  while len(root.get_list_of_children()) != 4 and len(root.get_list_of_children()) != 32:
    assert len(root.get_list_of_children()) == 1
    root = root.get_list_of_children()[0]
    root_basis *= basis_from_geo(root, use_z=False)

  metro[(0,)] = root_basis

  def add_sensor(quad_id, sensor_id, sensor):
    metro[(0,quad_id,sensor_id)] = basis_from_geo(sensor)

    x, y, z = sensor.get_pixel_coords()
    x/=1000; y/=1000; z/=1000
    assert x.shape == y.shape == z.shape
    sensor_px_slow = x.shape[0]
    sensor_px_fast = x.shape[1]
    assert sensor_px_fast % 2 == 0

    a0ul = sul = matrix.col((x[0,0],y[0,0],z[0,0]))
    a1ur = sur = matrix.col((x[0,sensor_px_fast-1],y[0,sensor_px_fast-1],z[0,sensor_px_fast-1]))
    a1lr = slr = matrix.col((x[sensor_px_slow-1,sensor_px_fast-1],y[sensor_px_slow-1,sensor_px_fast-1],z[sensor_px_slow-1,sensor_px_fast-1]))
    a0ll = sll = matrix.col((x[sensor_px_slow-1,0],y[sensor_px_slow-1,0],z[sensor_px_slow-1,0]))

    a0ur = matrix.col((x[0,sensor_px_fast//2-1],y[0,sensor_px_fast//2-1],z[0,sensor_px_fast//2-1]))
    a0lr = matrix.col((x[sensor_px_slow-1,sensor_px_fast//2-1],y[sensor_px_slow-1,sensor_px_fast//2-1],z[sensor_px_slow-1,sensor_px_fast//2-1]))

    a1ul = matrix.col((x[0,sensor_px_fast//2],y[0,sensor_px_fast//2],z[0,sensor_px_fast//2]))
    a1ll = matrix.col((x[sensor_px_slow-1,sensor_px_fast//2],y[sensor_px_slow-1,sensor_px_fast//2],z[sensor_px_slow-1,sensor_px_fast//2]))

    sensor_center = center([sul,sur,slr,sll])
    asic0_center = center([a0ul,a0ur,a0lr,a0ll])
    asic1_center = center([a1ul,a1ur,a1lr,a1ll])

    asic_trans0 = (asic0_center-sensor_center).length()
    asic_trans1 = (asic1_center-sensor_center).length()

    if include_asic_offset:
      rotated_ori = matrix.col((1,0,0)).axis_and_angle_as_unit_quaternion(180.0, deg=True)
      offset_fast = -pixel_size*((sensor_px_fast) / 4) # 4 because sensor_px_fast is for sensor
      offset_slow = +pixel_size*((sensor_px_slow) / 2) # Sensor is divided into 2 only in fast direction
      metro[(0,quad_id,sensor_id,0)] = basis(orientation=rotated_ori,translation=matrix.col((-asic_trans0,0,0)))
      metro[(0,quad_id,sensor_id,1)] = basis(orientation=rotated_ori,translation=matrix.col((+asic_trans1,0,0)))
      metro[(0,quad_id,sensor_id,0)].translation += matrix.col((offset_fast, offset_slow, 0))
      metro[(0,quad_id,sensor_id,1)].translation += matrix.col((offset_fast, offset_slow, 0))
    else:
      metro[(0,quad_id,sensor_id,0)] = basis(orientation=null_ori,translation=matrix.col((-asic_trans0,0,0)))
      metro[(0,quad_id,sensor_id,1)] = basis(orientation=null_ori,translation=matrix.col((+asic_trans1,0,0)))

  if len(root.get_list_of_children()) == 4:
    for quad_id, quad in enumerate(root.get_list_of_children()):
      metro[(0,quad_id)] = basis_from_geo(quad)
      for sensor_id, sensor in enumerate(quad.get_list_of_children()):
        add_sensor(quad_id, sensor_id, sensor)
  elif len(root.get_list_of_children()) == 32:
    for quad_id in range(4):
      metro[(0,quad_id)] = basis(orientation = null_ori, translation = matrix.col((0,0,0)))
      sensors = root.get_list_of_children()
      for sensor_id in range(8):
        add_sensor(quad_id, sensor_id, sensors[quad_id*4+sensor_id])
  else:
    assert False

  return metro