Exemple #1
0
    def _detector(self):
        """Return a working detector instance, with added mask regions."""

        detector = self._detector_factory.imgCIF_H(self._get_cbf_handle(), "PAD")

        for f0, f1, s0, s1 in determine_pilatus_mask(detector):
            detector[0].add_mask(f0 - 1, s0 - 1, f1, s1)

        m = re.search(
            r"^#\s*(\S+)\ssensor, thickness\s*([0-9.]+)\s*m\s*$",
            self._cif_header,
            re.MULTILINE,
        )
        if m:
            # header gives thickness in metres, we store mm
            thickness = float(m.group(2)) * 1000
            material = m.group(1)

            if material == "Silicon":
                material = "Si"

            for panel in detector:
                panel.set_thickness(thickness)
                panel.set_material(material)

            try:
                # a header only CBF file will not have a beam object
                beam = self._beam()

            except Exception:
                beam = None

            if beam:
                # attenuation coefficient depends on the beam wavelength
                wavelength = beam.get_wavelength()

                # this will fail for undefined composite materials
                table = attenuation_coefficient.get_table(material)
                # mu_at_angstrom returns cm^-1
                mu = table.mu_at_angstrom(wavelength) / 10.0

                for panel in detector:
                    panel.set_px_mm_strategy(
                        ParallaxCorrectedPxMmStrategy(mu, thickness)
                    )
                    panel.set_mu(mu)

        m = re.search(r"^#\s*Detector:\s+(.*?)\s*$", self._cif_header, re.MULTILINE)
        if m and m.group(1):
            panel.set_identifier(m.group(1).encode())

        size = detector[0].get_image_size()
        if size == (2463, 2527):
            self.vendortype = "Pilatus-6M"
        elif size == (1475, 1679):
            self.vendortype = "Pilatus-2M"
        elif size == (487, 619):
            self.vendortype = "Pilatus-300K"

        return detector
    def _detector(self):
        '''Return a model for a simple detector, presuming no one has
    one of these on a two-theta stage. Assert that the beam centre is
    provided in the Mosflm coordinate frame.'''
        detector = FormatCBFMini._detector(self)

        for f0, s0, f1, s1 in determine_pilatus_mask(detector):
            detector[0].add_mask(f0, s0, f1, s1)

        return detector
Exemple #3
0
  def _detector(self):
    '''Return a model for a simple detector, presuming no one has
    one of these on a two-theta stage. Assert that the beam centre is
    provided in the Mosflm coordinate frame.'''

    distance = float(
        self._cif_header_dictionary['Detector_distance'].split()[0])

    beam_xy = self._cif_header_dictionary['Beam_xy'].replace(
        '(', '').replace(')', '').replace(',', '').split()[:2]

    wavelength = float(
        self._cif_header_dictionary['Wavelength'].split()[0])

    beam_x, beam_y = map(float, beam_xy)

    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 = dxtbx_overload_scale * 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

    detector = self._detector_factory.simple(
        'PAD', distance * 1000.0, (beam_x * pixel_x * 1000.0,
                                   beam_y * pixel_y * 1000.0), '+x', '-y',
        (1000 * pixel_x, 1000 * 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
    def _detector(self):
        '''Return a working detector instance, with added mask regions.'''

        detector = self._detector_factory.imgCIF_H(self._get_cbf_handle(),
                                                   'PAD')

        for f0, s0, f1, s1 in determine_pilatus_mask(detector):
            detector[0].add_mask(f0, s0, f1, s1)

        import re
        m = re.search('^#\s*(\S+)\ssensor, thickness\s*([0-9.]+)\s*m\s*$', \
                      self._cif_header, re.MULTILINE)
        if m:
            # header gives thickness in metres, we store mm
            thickness = float(m.group(2)) * 1000
            material = m.group(1)

            if material == 'Silicon':
                material = 'Si'

            for panel in detector:
                panel.set_thickness(thickness)
                panel.set_material(material)

            try:
                # a header only CBF file will not have a beam object
                beam = self._beam()

            except Exception:
                beam = None

            if beam:
                # attenuation coefficient depends on the beam wavelength
                wavelength = beam.get_wavelength()

                from cctbx.eltbx import attenuation_coefficient
                from dxtbx.model import ParallaxCorrectedPxMmStrategy
                # this will fail for undefined composite materials
                table = attenuation_coefficient.get_table(material)
                # mu_at_angstrom returns cm^-1
                mu = table.mu_at_angstrom(wavelength) / 10.0

                for panel in detector:
                    panel.set_px_mm_strategy(
                        ParallaxCorrectedPxMmStrategy(mu, thickness))
                    panel.set_mu(mu)

        m = re.search('^#\s*Detector:\s+(.*?)\s*$', \
                      self._cif_header, re.MULTILINE)
        if m and m.group(1):
            panel.set_identifier(m.group(1))

        return detector
  def _detector(self):
    '''Return a working detector instance, with added mask regions.'''

    detector = self._detector_factory.imgCIF_H(self._get_cbf_handle(),
                                               'PAD')

    for f0, s0, f1, s1 in determine_pilatus_mask(detector):
      detector[0].add_mask(f0, s0, f1, s1)

    import re
    m = re.search('^#\s*(\S+)\ssensor, thickness\s*([0-9.]+)\s*m\s*$', \
                  self._cif_header, re.MULTILINE)
    if m:
      # header gives thickness in metres, we store mm
      thickness = float(m.group(2)) * 1000
      material = m.group(1)

      if material == 'Silicon':
        material = 'Si'

      for panel in detector:
        panel.set_thickness(thickness)
        panel.set_material(material)

      try:
        # a header only CBF file will not have a beam object
        beam = self._beam()

      except Exception:
        beam = None

      if beam:
        # attenuation coefficient depends on the beam wavelength
        wavelength = beam.get_wavelength()

        from cctbx.eltbx import attenuation_coefficient
        from dxtbx.model import ParallaxCorrectedPxMmStrategy
        # this will fail for undefined composite materials
        table = attenuation_coefficient.get_table(material)
        # mu_at_angstrom returns cm^-1
        mu = table.mu_at_angstrom(wavelength) / 10.0

        for panel in detector:
          panel.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, thickness))
          panel.set_mu(mu)

    m = re.search('^#\s*Detector:\s+(.*?)\s*$', \
                  self._cif_header, re.MULTILINE)
    if m and m.group(1):
      panel.set_identifier(m.group(1))

    return detector
    def _detector(self):
        """Return a model for a simple detector, presuming no one has
        one of these on a two-theta stage. Assert that the beam centre is
        provided in the Mosflm coordinate frame."""

        if not self._multi_panel:
            detector = FormatCBFMini._detector(self)
            for f0, f1, s0, s1 in determine_pilatus_mask(detector):
                detector[0].add_mask(f0 - 1, s0 - 1, f1, s1)
            return detector

        # got to here means 60-panel version
        d = Detector()

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

        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)

        det = _DetectorDatabase["Pilatus"]

        # Edge dead areas not included, only gaps between modules matter
        n_fast, remainder = divmod(nx, det.module_size_fast)
        assert (n_fast - 1) * det.gap_fast == remainder

        n_slow, remainder = divmod(ny, det.module_size_slow)
        assert (n_slow - 1) * det.gap_slow == remainder

        mx = det.module_size_fast
        my = det.module_size_slow
        dx = det.gap_fast
        dy = det.gap_slow

        xmins = [(mx + dx) * i for i in range(n_fast)]
        xmaxes = [mx + (mx + dx) * i for i in range(n_fast)]
        ymins = [(my + dy) * i for i in range(n_slow)]
        ymaxes = [my + (my + dy) * i for i in range(n_slow)]

        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 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):
        '''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 information...

        detector = self._detector_factory.simple(
            'PAD', distance * 1000.0,
            (beam_x * pixel_x * 1000.0, beam_y * pixel_y * 1000.0), '+x', '-y',
            (1000 * pixel_x, 1000 * 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)

        return detector
    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, 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 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 = root.add_panel()
                p.set_type("SENSOR_PAD")
                p.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, t0))
                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_mu(mu)
                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"""

        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 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 = root.add_panel()
                p.set_type("SENSOR_PAD")
                p.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, t0))
                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_mu(mu)
                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 information...

    detector = self._detector_factory.simple(
        'PAD', distance * 1000.0, (beam_x * pixel_x * 1000.0,
                                   beam_y * pixel_y * 1000.0), '+x', '-y',
        (1000 * pixel_x, 1000 * 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)

    return detector