def _detector(self): '''Return a working detector instance.''' if self._panel_origin is not None: from dxtbx.model.detector import HierarchicalDetector detector = HierarchicalDetector() root = detector.hierarchy() root.set_frame(self._fast_axis, self._slow_axis, self._detector_origin) i_panel = 0 for p_offset, p_size, origin, fast, slow in zip( self._panel_offset, self._panel_size, self._panel_origin, self._panel_fast, self._panel_slow): # ensure mutual orthogonality in presence of numerical rounding errors normal = fast.cross(slow) slow = normal.cross(fast) p = detector.add_panel() root.add_panel(p) p.set_type('unknown') p.set_raw_image_offset(p_offset) p.set_image_size(p_size) p.set_name('Panel%d' %i_panel) p.set_pixel_size(self._pixel_size) p.set_frame(fast.elems, slow.elems, origin.elems) i_panel += 1 return detector return self._detector_factory.complex( self._detector_factory.sensor('unknown'), self._detector_origin, self._fast_axis, self._slow_axis, self._pixel_size, self._image_size, (0, 1.e9))
def _detector(self): """Detector model, allowing for small offsets in the positions of 60 detector modules""" # Module positional offsets in x, y, in pixels - for the moment ignoring the # rotational offsets as these are not well defined. To be honest these # positional offsets are also not well defined as I do not know how they # should be applied... x = { (0, 0): -0.477546, (0, 1): 0.130578, (0, 2): 0.045041, (0, 3): -0.439872, (0, 4): -0.382077, (1, 0): 0.087405, (1, 1): 0.249597, (1, 2): 0.184265, (1, 3): 0.158342, (1, 4): 0.025225, (2, 0): -0.179892, (2, 1): -0.010974, (2, 2): -0.139207, (2, 3): 0.282851, (2, 4): -0.442219, (3, 0): -0.185027, (3, 1): 0.218601, (3, 2): 0.092585, (3, 3): 0.35862, (3, 4): -0.29161, (4, 0): 0.145368, (4, 1): 0.609289, (4, 2): 0.396265, (4, 3): 0.41625, (4, 4): 0.07152, (5, 0): 0.247142, (5, 1): 0.046563, (5, 2): 0.248714, (5, 3): -0.044628, (5, 4): -0.391509, (6, 0): 0.516643, (6, 1): 0.358453, (6, 2): 0.069219, (6, 3): 0.095861, (6, 4): -0.167403, (7, 0): -0.381352, (7, 1): -0.35338, (7, 2): 0.348656, (7, 3): 0.024543, (7, 4): 0.328706, (8, 0): 0.150886, (8, 1): 0.244987, (8, 2): -0.102911, (8, 3): 0.16633, (8, 4): 0.386622, (9, 0): 0.037924, (9, 1): 0.314392, (9, 2): 0.238818, (9, 3): 0.815028, (9, 4): -0.048818, (10, 0): -0.670524, (10, 1): -0.304119, (10, 2): 0.252284, (10, 3): -0.05485, (10, 4): -0.355264, (11, 0): -0.404947, (11, 1): -0.020622, (11, 2): 0.648473, (11, 3): -0.277175, (11, 4): -0.711951, } y = { (0, 0): -0.494797, (0, 1): -0.212976, (0, 2): 0.085351, (0, 3): 0.35494, (0, 4): 0.571189, (1, 0): -0.421708, (1, 1): 0.061914, (1, 2): 0.238996, (1, 3): 0.146692, (1, 4): 0.407145, (2, 0): -0.313212, (2, 1): -0.225025, (2, 2): 0.031613, (2, 3): -0.047839, (2, 4): 0.42716, (3, 0): -0.361193, (3, 1): 0.057663, (3, 2): 0.022357, (3, 3): 0.062717, (3, 4): 0.150611, (4, 0): 0.035511, (4, 1): -0.271567, (4, 2): 0.007761, (4, 3): -0.124021, (4, 4): 0.093017, (5, 0): -0.238897, (5, 1): -0.179724, (5, 2): -0.113608, (5, 3): 0.017841, (5, 4): -0.012933, (6, 0): -0.166337, (6, 1): -0.272922, (6, 2): -0.194665, (6, 3): -0.058535, (6, 4): -0.405404, (7, 0): -0.318824, (7, 1): -0.311276, (7, 2): -0.205223, (7, 3): -0.292664, (7, 4): -0.474762, (8, 0): -0.039504, (8, 1): -0.239887, (8, 2): -0.343485, (8, 3): -0.459429, (8, 4): -0.426901, (9, 0): -0.187805, (9, 1): 0.282727, (9, 2): -0.601164, (9, 3): -0.467605, (9, 4): -0.589271, (10, 0): 0.028311, (10, 1): -0.391571, (10, 2): -0.463112, (10, 3): -0.358092, (10, 4): -0.285396, (11, 0): 0.01863, (11, 1): -0.380099, (11, 2): -0.234953, (11, 3): -0.593992, (11, 4): -0.801247, } distance = float(self._cif_header_dictionary["Detector_distance"].split()[0]) beam_xy = self._cif_header_dictionary["Beam_xy"].replace("(", "").replace(")", "").replace(",", "").split()[:2] beam_x, beam_y = map(float, beam_xy) wavelength = float(self._cif_header_dictionary["Wavelength"].split()[0]) pixel_xy = self._cif_header_dictionary["Pixel_size"].replace("m", "").replace("x", "").split() pixel_x, pixel_y = map(float, pixel_xy) thickness = float(self._cif_header_dictionary["Silicon"].split()[2]) * 1000.0 nx = int(self._cif_header_dictionary["X-Binary-Size-Fastest-Dimension"]) ny = int(self._cif_header_dictionary["X-Binary-Size-Second-Dimension"]) overload = int(self._cif_header_dictionary["Count_cutoff"].split()[0]) underload = -1 # take into consideration here the thickness of the sensor also the # wavelength of the radiation (which we have in the same file...) from cctbx.eltbx import attenuation_coefficient table = attenuation_coefficient.get_table("Si") mu = table.mu_at_angstrom(wavelength) / 10.0 t0 = thickness # FIXME would also be very nice to be able to take into account the # misalignment of the individual modules given the calibration... # single detector or multi-module detector pixel_x *= 1000.0 pixel_y *= 1000.0 distance *= 1000.0 if single_panel: detector = self._detector_factory.simple( "PAD", distance, (beam_x * pixel_x, beam_y * pixel_y), "+x", "-y", (pixel_x, pixel_y), (nx, ny), (underload, overload), [], ParallaxCorrectedPxMmStrategy(mu, t0), ) for f0, s0, f1, s1 in determine_pilatus_mask(detector): detector[0].add_mask(f0, s0, f1, s1) detector[0].set_thickness(thickness) detector[0].set_material("Si") detector[0].set_mu(table.mu_at_angstrom(wavelength)) return detector # got to here means 60-panel version from dxtbx.model.detector import HierarchicalDetector from scitbx import matrix d = HierarchicalDetector() beam_centre = matrix.col((beam_x * pixel_x, beam_y * pixel_y, 0)) fast = matrix.col((1.0, 0.0, 0.0)) slow = matrix.col((0.0, -1.0, 0.0)) s0 = matrix.col((0, 0, -1)) origin = (distance * s0) - (fast * beam_centre[0]) - (slow * beam_centre[1]) root = d.hierarchy() root.set_local_frame(fast.elems, slow.elems, origin.elems) xmins = [0, 494, 988, 1482, 1976] xmaxes = [487, 981, 1475, 1969, 2463] ymins = [0, 212, 424, 636, 848, 1060, 1272, 1484, 1696, 1908, 2120, 2332] ymaxes = [195, 407, 619, 831, 1043, 1255, 1467, 1679, 1891, 2103, 2315, 2527] self.coords = {} fast = matrix.col((1.0, 0.0, 0.0)) slow = matrix.col((0.0, 1.0, 0.0)) panel_idx = 0 for ymin, ymax in zip(ymins, ymaxes): for xmin, xmax in zip(xmins, xmaxes): xmin_mm = xmin * pixel_x ymin_mm = ymin * pixel_y origin_panel = fast * xmin_mm + slow * ymin_mm panel_name = "Panel%d" % panel_idx panel_idx += 1 p = d.add_panel() p.set_name(panel_name) p.set_image_size((xmax - xmin, ymax - ymin)) p.set_trusted_range((underload, overload)) p.set_pixel_size((pixel_x, pixel_y)) p.set_thickness(thickness) p.set_material("Si") p.set_local_frame(fast.elems, slow.elems, origin_panel.elems) self.coords[panel_name] = (xmin, ymin, xmax, ymax) root.add_panel(p) return d
def _detector(self): # module positions from detector blueprints - modelling at the moment as # 24 modules, each consisting of 5 sensors (the latter is ignored) from dxtbx.model.detector import HierarchicalDetector from scitbx import matrix import math x = matrix.col((1, 0, 0)) y = matrix.col((0, 1, 0)) z = matrix.col((0, 0, 1)) obs_beam_y = 2587 ideal_beam_y = 2594 beam_shift_y = 0.172 * (2594 - 2587) distance = float( self._cif_header_dictionary['Detector_distance'].split()[0]) * 1000.0 wavelength = float( self._cif_header_dictionary['Wavelength'].split()[0]) thickness = float( self._cif_header_dictionary['Silicon'].split()[2]) * 1000.0 detector = HierarchicalDetector() root = detector.hierarchy() root.set_frame( (1, 0, 0), (0, 1, 0), (0, 0, - (250 + distance))) from cctbx.eltbx import attenuation_coefficient table = attenuation_coefficient.get_table("Si") mu = table.mu_at_angstrom(wavelength) / 10.0 t0 = thickness px_mm = ParallaxCorrectedPxMmStrategy(mu, t0) for j in range(24): angle = math.pi * (-12.2 + 0.5 * 7.903 + j * (7.903 + 0.441)) / 180.0 fast = matrix.col((-1, 0, 0)) slow = matrix.col((0, math.sin(angle), - math.cos(angle))) normal = fast.cross(slow) # for longer wavelength data sets move 192.3 below to 184.9 if wavelength < 1.128: off_x = 191.9 else: off_x = 184.9 if group_rows: origin = 250.0 * normal - off_x * fast - 16.8 * slow + 250 * z + \ beam_shift_y * y p = detector.add_panel() # OBS! you need to set the panel to a root before set local frame... root.add_panel(p) p.set_name('row-%02d' % j) p.set_image_size((2463, 195)) p.set_trusted_range((-1, 1000000)) p.set_pixel_size((0.172, 0.172)) p.set_local_frame( fast.elems, slow.elems, origin.elems) p.set_px_mm_strategy(px_mm) else: row_origin = 250.0 * normal - off_x * fast - 16.8 * slow + 250 * z + \ beam_shift_y * y for i in range(5): p = detector.add_panel() origin = row_origin + i * (487+7) * 0.172 * fast # OBS! you need to set the panel to a root before set local frame... root.add_panel(p) p.set_name('row-%02d' % j) p.set_image_size((487, 195)) p.set_trusted_range((-1, 1000000)) p.set_pixel_size((0.172, 0.172)) p.set_local_frame( fast.elems, slow.elems, origin.elems) p.set_px_mm_strategy(px_mm) return detector
def _detector(self, index=None): from dxtbx.model.detector import HierarchicalDetector from scitbx import matrix import math # Ignore this for now. # TODO: must consider when a new MPCCD with 300um thickness # is released. self.wavelength = 1.77 # A, this must be got from _beam # thickness = 60 # um # # from cctbx.eltbx import attenuation_coefficient # table = attenuation_coefficient.get_table("Si") # mu = table.mu_at_angstrom(wavelength) / 10.0 # t0 = thickness # px_mm = ParallaxCorrectedPxMmStrategy(mu, t0) detector = HierarchicalDetector() root = detector.hierarchy() root.set_frame( (1, 0, 0), (0, 1, 0), (0, 0, - self.distance)) if self.RECONST_MODE: return self._detector_factory.simple( sensor = 'PAD', distance = self.distance, beam_centre = (self.RECONST_SIZE * self.pixel_size / 2, self.RECONST_SIZE * self.pixel_size / 2), fast_direction = '+x', slow_direction = '-y', pixel_size = (self.pixel_size, self.pixel_size), image_size = (self.RECONST_SIZE, self.RECONST_SIZE), trusted_range = (-1, 1000000), mask = []) # a list of dead rectangles for i in range(8): angle = math.pi * self.panel_rotations[i] / 180.0 fast = matrix.col((math.cos(angle), math.sin(angle), 0)) slow = matrix.col((-math.sin(angle), math.cos(angle), 0)) normal = fast.cross(slow) origin = matrix.col((-self.panel_origins[i][0], self.panel_origins[i][1], self.panel_origins[i][2])) / 1000.0 p = detector.add_panel() # OBS! you need to set the panel to a root before set local frame... root.add_panel(p) p.set_name('panel-%01d' % i) p.set_image_size((512, 1024)) p.set_trusted_range((-1, 1000000)) p.set_pixel_size((self.pixel_size, self.pixel_size)) p.set_local_frame( fast.elems, slow.elems, origin.elems) xmin, ymin = 0, i * 1024 p.set_raw_image_offset((xmin, ymin)) # p.set_px_mm_strategy(px_mm) return detector