def make_detector(): """Make a dummy 4 panel detector with not many pixels to ensure test runs quickly""" pixel_size_x = 0.1 pixel_size_y = 0.1 npixels_per_panel_x = 50 npixels_per_panel_y = 50 distance = 100 fast = matrix.col((1, 0, 0)) slow = matrix.col((0, -1, 0)) s0u = matrix.col((0, 0, -1)) shift_x = -1.0 * npixels_per_panel_x * pixel_size_x * fast shift_y = -1.0 * npixels_per_panel_y * pixel_size_y * slow beam_centre = distance * s0u orig = beam_centre + shift_x + shift_y d = Detector() root = d.hierarchy() root.set_local_frame(fast.elems, slow.elems, orig.elems) local_fast = matrix.col((1.0, 0.0, 0.0)) local_slow = matrix.col((0.0, 1.0, 0.0)) span_x = npixels_per_panel_x * pixel_size_x * local_fast span_y = npixels_per_panel_y * pixel_size_y * local_slow local_origins = [matrix.col((0, 0, 0)), span_x, span_y, span_x + span_y] for i, lo in enumerate(local_origins): p = d.add_panel() p.set_image_size((npixels_per_panel_x, npixels_per_panel_y)) p.set_pixel_size((pixel_size_x, pixel_size_y)) p.set_local_frame(local_fast.elems, local_slow.elems, lo.elems) return d
def _detector(self): """Return a working detector instance.""" cbf = self._get_cbf_handle() d = Detector() for i in xrange(cbf.count_elements()): ele_id = cbf.get_element_id(i) cbf.find_category("diffrn_data_frame") cbf.find_column("detector_element_id") cbf.find_row(ele_id) cbf.find_column("array_id") array_id = cbf.get_value() cbf_detector = cbf.construct_detector(i) p = d.add_panel() p.set_name(array_id) # code adapted below from dxtbx.model.detector.DetectorFactory.imgCIF_H pixel = ( cbf_detector.get_inferred_pixel_size(1), cbf_detector.get_inferred_pixel_size(2), ) fast = cbf_detector.get_detector_axes()[0:3] slow = cbf_detector.get_detector_axes()[3:6] origin = cbf_detector.get_pixel_coordinates_fs(0, 0) size = tuple(reversed(cbf.get_image_size(0))) try: cbf.find_category("array_intensities") cbf.find_column("undefined_value") underload = cbf.get_doublevalue() overload = cbf.get_overload(0) trusted_range = (underload, overload) except Exception: trusted_range = (0.0, 0.0) cbf_detector.__swig_destroy__(cbf_detector) del cbf_detector p.set_local_frame(fast, slow, origin) p.set_pixel_size(tuple(map(float, pixel))) p.set_image_size(size) p.set_trusted_range(tuple(map(float, trusted_range))) # p.set_px_mm_strategy(px_mm) FIXME return d
def _detector(self): '''Return a working detector instance.''' cbf = self._get_cbf_handle() d = Detector() for i in xrange(cbf.count_elements()): ele_id = cbf.get_element_id(i) cbf.find_category("diffrn_data_frame") cbf.find_column("detector_element_id") cbf.find_row(ele_id) cbf.find_column("array_id") array_id = cbf.get_value() cbf_detector = cbf.construct_detector(i) p = d.add_panel() p.set_name(array_id) # code adapted below from dxtbx.model.detector.detector_factory.imgCIF_H pixel = (cbf_detector.get_inferred_pixel_size(1), cbf_detector.get_inferred_pixel_size(2)) fast = cbf_detector.get_detector_axes()[0:3] slow = cbf_detector.get_detector_axes()[3:6] origin = cbf_detector.get_pixel_coordinates_fs(0,0) size = tuple(reversed(cbf.get_image_size(0))) try: cbf.find_category('array_intensities') cbf.find_column('undefined_value') underload = cbf.get_doublevalue() overload = cbf.get_overload(0) trusted_range = (underload, overload) except: # intentional trusted_range = (0.0, 0.0) cbf_detector.__swig_destroy__(cbf_detector) del(cbf_detector) p.set_local_frame(fast, slow, origin) p.set_pixel_size(tuple(map(float, pixel))) p.set_image_size(size) p.set_trusted_range(tuple(map(float, trusted_range))) #p.set_px_mm_strategy(px_mm) FIXME return d
def _detector(self): '''4 panel detector, 55 micron pixels except for pixels at the outer edge of each chip, which are 165 microns wide.''' from scitbx import matrix # expect 55 mu pixels here, but make it general anyway pixel_size = tuple([float(self._header_dictionary['PIXEL_SIZE'])] * 2) image_size = (int(self._header_dictionary['SIZE1']), int(self._header_dictionary['SIZE2'])) panel_size = tuple([int(e / 2) for e in image_size]) # outer pixels have three times the width panel_size_mm = (pixel_size[0] * 3 + (panel_size[0] - 2) * pixel_size[0], pixel_size[1] * 3 + (panel_size[1] - 2) * pixel_size[1]) image_size_mm = (panel_size_mm[0] * 2, panel_size_mm[1] * 2) trusted_range = (-1, 65535) material = 'Si' thickness = 0.3 # assume 300 mu thick # Initialise detector frame fast = matrix.col((1.0, 0.0, 0.0)) slow = matrix.col((0.0, -1.0, 0.0)) beam_centre = (float(self._header_dictionary['BEAM_CENTER_X']), float(self._header_dictionary['BEAM_CENTER_Y'])) bx_px, by_px = beam_centre # the beam centre is in pixels. We want to convert to mm, taking the # different size of outer pixels into account. Use this local function # to do that def px_to_mm(px, px_size_1d, panel_size_1d): mm = 0 if px > 1: # add first outer pixel mm += px_size_1d * 3 else: # or fraction of first outer pixel mm += px * px_size_1d * 3 return mm if px > panel_size_1d - 1: # add full panel of inner pixels mm += (panel_size_1d - 2) * px_size_1d else: # or fraction of inner pixels mm += (px - 1) * px_size_1d return mm if px > panel_size_1d: # add second outer pixel mm += px_size_1d * 3 else: # or fraction of second outer pixel mm += (px - (panel_size_1d - 1)) * px_size_1d * 3 return mm if px > panel_size_1d + 1: # add first outer pixel of second panel mm += px_size_1d * 3 else: # or fraction of first outer pixel of second panel mm += (px - panel_size_1d) * px_size_1d * 3 return mm if px > (2 * panel_size_1d - 1): # add second full panel of inner pixels mm += (panel_size_1d - 2) * px_size_1d # plus remaining fraction of the second outer pixel mm += (px - (2 * panel_size_1d - 1)) * px_size_1d * 3 else: # or fraction of inner pixels of the second panel mm += (px - panel_size_1d - 1) * px_size_1d return mm bx_mm = px_to_mm(bx_px, pixel_size[0], panel_size[0]) by_mm = px_to_mm(by_px, pixel_size[1], panel_size[1]) beam_centre_mm = (bx_mm, by_mm) # the beam centre is defined from the origin along fast, slow. To determine # the lab frame origin we place the beam centre down the -z axis dist = float(self._header_dictionary['DISTANCE']) cntr = matrix.col((0.0, 0.0, -1 * dist)) orig = cntr - bx_mm * fast - by_mm * slow d = Detector() root = d.hierarchy() root.set_local_frame(fast.elems, slow.elems, orig.elems) self.coords = {} panel_idx = 0 # set panel extent in pixel numbers and x, y mm shifts. Note that the # outer pixels are 0.165 mm in size. These are excluded from the panel # extents. pnl_data = [] pnl_data.append({ 'xmin': 1, 'ymin': 1, 'xmax': 255, 'ymax': 255, 'xmin_mm': 1 * 0.165, 'ymin_mm': 1 * 0.165 }) pnl_data.append({ 'xmin': 257, 'ymin': 1, 'xmax': 511, 'ymax': 255, 'xmin_mm': 3 * 0.165 + (511 - 257) * pixel_size[0], 'ymin_mm': 1 * 0.165 }) pnl_data.append({ 'xmin': 1, 'ymin': 257, 'xmax': 255, 'ymax': 511, 'xmin_mm': 1 * 0.165, 'ymin_mm': 3 * 0.165 + (511 - 257) * pixel_size[1] }) pnl_data.append({ 'xmin': 257, 'ymin': 257, 'xmax': 511, 'ymax': 511, 'xmin_mm': 3 * 0.165 + (511 - 257) * pixel_size[0], 'ymin_mm': 3 * 0.165 + (511 - 257) * pixel_size[1] }) # redefine fast, slow for the local frame fast = matrix.col((1.0, 0.0, 0.0)) slow = matrix.col((0.0, 1.0, 0.0)) for ipanel, pd in enumerate(pnl_data): xmin = pd['xmin'] xmax = pd['xmax'] ymin = pd['ymin'] ymax = pd['ymax'] xmin_mm = pd['xmin_mm'] ymin_mm = pd['ymin_mm'] origin_panel = fast * xmin_mm + slow * ymin_mm panel_name = "Panel%d" % panel_idx panel_idx += 1 p = d.add_panel() p.set_type('SENSOR_PAD') p.set_name(panel_name) p.set_raw_image_offset((xmin, ymin)) p.set_image_size((xmax - xmin, ymax - ymin)) p.set_trusted_range(trusted_range) p.set_pixel_size((pixel_size[0], pixel_size[1])) p.set_thickness(thickness) p.set_material('Si') #p.set_mu(mu) #p.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, t0)) p.set_local_frame(fast.elems, slow.elems, origin_panel.elems) p.set_raw_image_offset((xmin, ymin)) self.coords[panel_name] = (xmin, ymin, xmax, ymax) return d
gimmie_Patt=True, add_water=True, add_noise=True, boost=Iboost) print "TIME: %.4f" % (time.time() - t) sims = np.sum([simsAB[k] for k in simsAB], axis=0) np.savez(outputname + "_spotdata.pkl", sims=sims, panel_ids=panel_ids) print "Done!" exit() det2 = Detector() det2_panel_mapping = {} for i_pan, pid in enumerate(panel_ids): det2.add_panel(det[pid]) det2_panel_mapping[i_pan] = pid refl_data = refls_strong = spot_utils.refls_from_sims(sims, det2, beam, thresh=10) refl_panel = refl_data['panel'].as_numpy_array() for i_pan, pid in det2_panel_mapping.items(): sel = refl_panel == i_pan refl_panel[sel] = pid refl_data['panel'] = flex.size_t(refl_panel) ###########
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 not self._multi_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(mu) return detector # got to here means 60-panel version from dxtbx.model.detector import Detector from scitbx import matrix d = Detector() 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_type('SENSOR_PAD') p.set_name(panel_name) p.set_raw_image_offset((xmin, ymin)) 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_mu(mu) p.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, t0)) p.set_local_frame(fast.elems, slow.elems, origin_panel.elems) p.set_raw_image_offset((xmin, ymin)) self.coords[panel_name] = (xmin, ymin, xmax, ymax) return d
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 not self._multi_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(mu) return detector # got to here means 60-panel version from dxtbx.model.detector import Detector from scitbx import matrix d = Detector() 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_type('SENSOR_PAD') p.set_name(panel_name) p.set_raw_image_offset((xmin, ymin)) 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_mu(mu) p.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, t0)) p.set_local_frame( fast.elems, slow.elems, origin_panel.elems) p.set_raw_image_offset((xmin, ymin)) self.coords[panel_name] = (xmin,ymin,xmax,ymax) return d
'px_mm_strategy': { 'type': 'SimplePxMmStrategy' }, 'raw_image_offset': (0, 0), 'slow_axis': (0.0, 1.0, 0.0), 'thickness': 0.0, 'trusted_range': (0.0, 65536.0), 'type': '' } pan1 = copy.deepcopy(pan0) pan1["origin"] = origin1 # combine the panels into a multi-panel detector parts_det = Detector() parts_det.add_panel(Panel.from_dict(pan0)) parts_det.add_panel(Panel.from_dict(pan1)) SIMs = {} for i_pan in range(2): SIM = simtbx.nanoBragg.nanoBragg(parts_det, beam, panel_id=i_pan) SIM.Amatrix = sqr(cryst.get_A()).transpose().elems SIM.default_F = 1 SIM.F000 = 10 SIM.oversample = 2 SIM.Ncells_abc = (5, 5, 5) SIM.add_nanoBragg_spots() SIM.raw_pixels *= 2000 SIMs[i_pan] = SIM # check comparison with whole camera
def _detector(self): """Detector model, allowing for small offsets in the positions of 60 detector modules""" 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 not self._multi_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, f1, s0, s1 in determine_pilatus_mask(detector): detector[0].add_mask(f0 - 1, s0 - 1, f1, s1) detector[0].set_thickness(thickness) detector[0].set_material("Si") detector[0].set_mu(mu) return detector # got to here means 60-panel version from dxtbx.model.detector import Detector from scitbx import matrix d = Detector() 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_type("SENSOR_PAD") p.set_name(panel_name) p.set_raw_image_offset((xmin, ymin)) 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_mu(mu) p.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, t0)) p.set_local_frame(fast.elems, slow.elems, origin_panel.elems) p.set_raw_image_offset((xmin, ymin)) self.coords[panel_name] = (xmin, ymin, xmax, ymax) return d
det det = detector det det[0] #@det.add_panel #det.rotate_around_origin dir(det) det.to_dict() D = det.to_dict() D.keys() D['hierarchy'] from dxtbx.model.detector import Detector Detector() D2 = Detector() for i in [32,34,50]: D2.add_panel( detector[i]) D2 params = [] for i,C in enumerate(Cabc): param = {} param['crystal'] = C param['ENERGIES'] = en_spec param['FLUX']= flux print C.get_unit_cell().parameters() param['shape'] = 'tophat' param['Ncells_abc'] = (10,10,10) param['beam'] = beamA param['order'] = i param['Nmos'] = 500 param['mos_spread'] = 0.125
def main(): # --------- SIM = simtbx.nanoBragg.nanoBragg(whole_det, beam) SIM.Amatrix = sqr(cryst.get_A()).transpose().elems SIM.default_F = 1 SIM.F000 = 10 SIM.oversample = 2 SIM.Ncells_abc = (5, 5, 5) SIM.show_params() SIM.add_nanoBragg_spots() SIM.raw_pixels *= 2000 wholepix = SIM.raw_pixels.as_numpy_array() # --------- # now make 2 smaller detectors # that equal the whole detector above # then append them as a dials multi panel origin0 = (25.6, -12.8, -100) origin1 = (25.6, 0, -100) panel_size = (512, 128) pan0 = { 'fast_axis': (-1.0, 0.0, 0.0), 'gain': 1.0, 'identifier': '', 'image_size': (512, 128), 'mask': [], 'material': '', 'mu': 0.0, 'name': 'panel1', 'origin': origin0, 'pedestal': 0.0, 'pixel_size': (0.1, 0.1), 'px_mm_strategy': { 'type': 'SimplePxMmStrategy' }, 'raw_image_offset': (0, 0), 'slow_axis': (0.0, 1.0, 0.0), 'thickness': 0.0, 'trusted_range': (0.0, 65536.0), 'type': '' } pan1 = copy.deepcopy(pan0) pan1["origin"] = origin1 # combine the panels into a multi-panel detector parts_det = Detector() parts_det.add_panel(Panel.from_dict(pan0)) parts_det.add_panel(Panel.from_dict(pan1)) SIMs = {} for i_pan in range(2): SIM = simtbx.nanoBragg.nanoBragg(parts_det, beam, panel_id=i_pan) SIM.Amatrix = sqr(cryst.get_A()).transpose().elems SIM.default_F = 1 SIM.F000 = 10 SIM.oversample = 2 SIM.Ncells_abc = (5, 5, 5) SIM.add_nanoBragg_spots() SIM.raw_pixels *= 2000 SIMs[i_pan] = SIM # check comparison with whole camera # ---------------------------------- # combine the two panels: pix0 = SIMs[0].raw_pixels.as_numpy_array() pix1 = SIMs[1].raw_pixels.as_numpy_array() # FIXME: not sure why but in this case the first pixel in memory is off by 0.05 # but the others are all close.. pix1[0, 0] = wholepix[128, 0] # pix1[0,0] = 1.217 and pix[128,0] = 1.264 pix01 = np.vstack((pix0, pix1)) assert (np.allclose(wholepix, pix01))
def _detector(self): """Dummy detector""" from scitbx import matrix # 55 mu pixels pixel_size = 0.055, 0.055 trusted_range = (-1, 65535) material = "Si" thickness = 0.3 # assume 300 mu thick. This is actually in the header too # so could take it from there # Initialise detector frame - dummy origin to place detector at the header # distance along the canonical beam direction distance = (float( self._cif_header_dictionary["Detector_distance"].split()[0]) * 1000) fast = matrix.col((1.0, 0.0, 0.0)) slow = matrix.col((0.0, -1.0, 0.0)) cntr = matrix.col((0.0, 0.0, -100.0)) # shifts to go from the centre to the origin off_x = (self._array_size[0] / 2) * pixel_size[0] shift_x = -1.0 * fast * off_x off_y = (self._array_size[1] / 2) * pixel_size[1] shift_y = -1.0 * slow * off_y orig = cntr + shift_x + shift_y d = Detector() root = d.hierarchy() root.set_local_frame(fast.elems, slow.elems, orig.elems) self.coords = {} panel_idx = 0 # set panel extent in pixel numbers and x, y mm shifts. Origins taken from # an XDS.INP pnl_data = [] pnl_data.append({ "xmin": 0, "ymin": 0, "xmax": 516, "ymax": 516, "xmin_mm": 0, "ymin_mm": 0 }) pnl_data.append({ "xmin": 516, "ymin": 0, "xmax": 1032, "ymax": 516, "xmin_mm": (516 + 163.0) * pixel_size[0], "ymin_mm": -3.6969 * pixel_size[1], }) pnl_data.append({ "xmin": 0, "ymin": 516, "xmax": 516, "ymax": 1032, "xmin_mm": -2.5455 * pixel_size[0], "ymin_mm": (516 + 35.0) * pixel_size[1], }) pnl_data.append({ "xmin": 516, "ymin": 516, "xmax": 1032, "ymax": 1032, "xmin_mm": (516 + 165.866) * pixel_size[0], "ymin_mm": (516 + 32.4545) * pixel_size[1], }) # redefine fast, slow for the local frame fast = matrix.col((1.0, 0.0, 0.0)) slow = matrix.col((0.0, 1.0, 0.0)) for ipanel, pd in enumerate(pnl_data): xmin = pd["xmin"] xmax = pd["xmax"] ymin = pd["ymin"] ymax = pd["ymax"] xmin_mm = pd["xmin_mm"] ymin_mm = pd["ymin_mm"] origin_panel = fast * xmin_mm + slow * ymin_mm panel_name = "Panel%d" % panel_idx panel_idx += 1 p = d.add_panel() p.set_type("SENSOR_PAD") p.set_name(panel_name) p.set_raw_image_offset((xmin, ymin)) p.set_image_size((xmax - xmin, ymax - ymin)) p.set_trusted_range(trusted_range) p.set_pixel_size((pixel_size[0], pixel_size[1])) p.set_thickness(thickness) p.set_material("Si") # p.set_mu(mu) # p.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, t0)) p.set_local_frame(fast.elems, slow.elems, origin_panel.elems) p.set_raw_image_offset((xmin, ymin)) p.set_gain(3.0) # exact gain self.coords[panel_name] = (xmin, ymin, xmax, ymax) return d
def _detector(self): """Dummy detector""" from scitbx import matrix # 55 mu pixels pixel_size = 0.055, 0.055 image_size = 512, 512 trusted_range = (-1, 65535) material = "Si" thickness = 0.3 # assume 300 mu thick # Initialise detector frame - dummy origin to place detector at 100 mm # along canonical beam direction fast = matrix.col((1.0, 0.0, 0.0)) slow = matrix.col((0.0, -1.0, 0.0)) cntr = matrix.col((0.0, 0.0, -100.0)) # shifts to go from the centre to the origin - outer pixels are 0.165 mm off_x = (image_size[0] / 2 - 2) * pixel_size[0] off_x += 2 * 0.165 shift_x = -1.0 * fast * off_x off_y = (image_size[1] / 2 - 2) * pixel_size[1] off_y += 2 * 0.165 shift_y = -1.0 * slow * off_y orig = cntr + shift_x + shift_y d = Detector() root = d.hierarchy() root.set_local_frame(fast.elems, slow.elems, orig.elems) self.coords = {} panel_idx = 0 # set panel extent in pixel numbers and x, y mm shifts. Note that the # outer pixels are 0.165 mm in size. These are excluded from the panel # extents. pnl_data = [] pnl_data.append({ "xmin": 1, "ymin": 1, "xmax": 255, "ymax": 255, "xmin_mm": 1 * 0.165, "ymin_mm": 1 * 0.165, }) pnl_data.append({ "xmin": 257, "ymin": 1, "xmax": 511, "ymax": 255, "xmin_mm": 3 * 0.165 + (511 - 257) * pixel_size[0], "ymin_mm": 1 * 0.165, }) pnl_data.append({ "xmin": 1, "ymin": 257, "xmax": 255, "ymax": 511, "xmin_mm": 1 * 0.165, "ymin_mm": 3 * 0.165 + (511 - 257) * pixel_size[1], }) pnl_data.append({ "xmin": 257, "ymin": 257, "xmax": 511, "ymax": 511, "xmin_mm": 3 * 0.165 + (511 - 257) * pixel_size[0], "ymin_mm": 3 * 0.165 + (511 - 257) * pixel_size[1], }) # redefine fast, slow for the local frame fast = matrix.col((1.0, 0.0, 0.0)) slow = matrix.col((0.0, 1.0, 0.0)) for ipanel, pd in enumerate(pnl_data): xmin = pd["xmin"] xmax = pd["xmax"] ymin = pd["ymin"] ymax = pd["ymax"] xmin_mm = pd["xmin_mm"] ymin_mm = pd["ymin_mm"] origin_panel = fast * xmin_mm + slow * ymin_mm panel_name = "Panel%d" % panel_idx panel_idx += 1 p = d.add_panel() p.set_type("SENSOR_PAD") p.set_name(panel_name) p.set_raw_image_offset((xmin, ymin)) p.set_image_size((xmax - xmin, ymax - ymin)) p.set_trusted_range(trusted_range) p.set_pixel_size((pixel_size[0], pixel_size[1])) p.set_thickness(thickness) p.set_material("Si") # p.set_mu(mu) # p.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, t0)) p.set_local_frame(fast.elems, slow.elems, origin_panel.elems) p.set_raw_image_offset((xmin, ymin)) self.coords[panel_name] = (xmin, ymin, xmax, ymax) return d