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
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