def run(args):
  if ("--help" in args or "-h" in args) :
    print "Write a CBF header from a SLAC metrology file. Parameters:"
    master_phil.show(attributes_level=2)
    return

  user_phil = []
  for arg in args:
    if (os.path.isfile(arg)) :
      user_phil.append(libtbx.phil.parse("""metrology_file=\"%s\"""" % arg))
    else :
      try :
        user_phil.append(libtbx.phil.parse(arg))
      except RuntimeError as e :
        raise Sorry("Unrecognized argument '%s' (error: %s)" % (arg, str(e)))

  params = master_phil.fetch(sources=user_phil).extract()
  if (params.metrology_file is None) :
    master_phil.show()
    raise Usage("metrology_file must be defined (either metrology_file=XXX, or the file path alone).")
  assert params.plot is not None
  assert params.out is not None

  print params.metrology_file

  metro = read_slac_metrology(params.metrology_file, plot=params.plot)

  write_cspad_cbf(None, metro, 'cbf', None, params.out, None, 0, header_only=True)
def v2calib2sections(filename):
  """The v2calib2sections() function reads calibration information
  stored in new style SLAC calibration file and returns a
  two-dimensional array of Section objects.  The first index in the
  returned array identifies the quadrant, and the second index
  identifies the section within the quadrant.

  @param dirname Directory with calibration information
  @return        Section objects
  """

  from xfel.cftbx.detector.cspad_cbf_tbx import read_slac_metrology
  from scitbx.matrix import sqr
  from xfel.cxi.cspad_ana.cspad_tbx import pixel_size

  # metro is a dictionary where the keys are levels in the detector
  # hierarchy and the values are 'basis' objects
  metro = read_slac_metrology(filename)

  # 90 degree rotation to get into same frame
  reference_frame = sqr((0,-1, 0, 0,
                         1, 0, 0, 0,
                         0, 0, 1, 0,
                         0, 0, 0, 1))

  d = 0
  d_basis = metro[(d,)]

  sections = []
  for q in xrange(4):
    sections.append([])
    q_basis = metro[(d,q)]
    for s in xrange(8):
      if not (d,q,s) in metro:
        continue

      s_basis = metro[(d,q,s)]

      # collapse the transformations from the detector center to the quadrant center
      # to the sensor center
      transform = reference_frame * \
                  d_basis.as_homogenous_transformation() * \
                  q_basis.as_homogenous_transformation() * \
                  s_basis.as_homogenous_transformation()

      # an homologous transformation is a 4x4 matrix, with a 3x3 rotation in the
      # upper left corner and the translation in the right-most column. The last
      # row is 0,0,0,1
      ori = sqr((transform[0],transform[1],transform[2],
                 transform[4],transform[5],transform[6],
                 transform[8],transform[9],transform[10]))
      angle = ori.r3_rotation_matrix_as_x_y_z_angles(deg=True)[2]

      # move the reference of the sensor so its relative to the upper left of the
      # detector instead of the center of the detector
      center = (1765/2)+(transform[3]/pixel_size),(1765/2)+(transform[7]/pixel_size)

      sections[q].append(Section(angle, center))

  return sections
Exemple #3
0
def v2calib2sections(filename):
    """The v2calib2sections() function reads calibration information
  stored in new style SLAC calibration file and returns a
  two-dimensional array of Section objects.  The first index in the
  returned array identifies the quadrant, and the second index
  identifies the section within the quadrant.

  @param dirname Directory with calibration information
  @return        Section objects
  """

    from xfel.cftbx.detector.cspad_cbf_tbx import read_slac_metrology
    from scitbx.matrix import sqr
    from xfel.cxi.cspad_ana.cspad_tbx import pixel_size

    # metro is a dictionary where the keys are levels in the detector
    # hierarchy and the values are 'basis' objects
    metro = read_slac_metrology(filename)

    # 90 degree rotation to get into same frame
    reference_frame = sqr((0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1))

    d = 0
    d_basis = metro[(d, )]

    sections = []
    for q in range(4):
        sections.append([])
        q_basis = metro[(d, q)]
        for s in range(8):
            if not (d, q, s) in metro:
                continue

            s_basis = metro[(d, q, s)]

            # collapse the transformations from the detector center to the quadrant center
            # to the sensor center
            transform = reference_frame * \
                        d_basis.as_homogenous_transformation() * \
                        q_basis.as_homogenous_transformation() * \
                        s_basis.as_homogenous_transformation()

            # an homologous transformation is a 4x4 matrix, with a 3x3 rotation in the
            # upper left corner and the translation in the right-most column. The last
            # row is 0,0,0,1
            ori = sqr((transform[0], transform[1], transform[2], transform[4],
                       transform[5], transform[6], transform[8], transform[9],
                       transform[10]))
            angle = ori.r3_rotation_matrix_as_x_y_z_angles(deg=True)[2]

            # move the reference of the sensor so its relative to the upper left of the
            # detector instead of the center of the detector
            center = (1765 / 2) + (transform[3] / pixel_size), (1765 / 2) + (
                transform[7] / pixel_size)

            sections[q].append(Section(angle, center))

    return sections
Exemple #4
0
    def _detector(self, index=None):
        if index is None:
            index = 0

        run = self.get_run_from_index(index)
        det = self._get_psana_detector(run)
        geom = det.pyda.geoaccess(run.run())
        cob = read_slac_metrology(geometry=geom, include_asic_offset=True)
        distance = env_distance(
            self.params.detector_address[0], run.env(), self.params.cspad.detz_offset
        )
        d = Detector()
        pg0 = d.hierarchy()
        # first deal with D0
        det_num = 0
        origin = col((cob[(0,)] * col((0, 0, 0, 1)))[0:3])
        fast = col((cob[(0,)] * col((1, 0, 0, 1)))[0:3]) - origin
        slow = col((cob[(0,)] * col((0, 1, 0, 1)))[0:3]) - origin
        origin += col((0.0, 0.0, -distance))
        pg0.set_local_frame(fast.elems, slow.elems, origin.elems)
        pg0.set_name("D%d" % (det_num))
        for quad_num in range(4):
            # Now deal with Qx
            pg1 = pg0.add_group()
            origin = col((cob[(0, quad_num)] * col((0, 0, 0, 1)))[0:3])
            fast = col((cob[(0, quad_num)] * col((1, 0, 0, 1)))[0:3]) - origin
            slow = col((cob[(0, quad_num)] * col((0, 1, 0, 1)))[0:3]) - origin
            pg1.set_local_frame(fast.elems, slow.elems, origin.elems)
            pg1.set_name("D%dQ%d" % (det_num, quad_num))
            for sensor_num in range(8):
                # Now deal with Sy
                pg2 = pg1.add_group()
                origin = col((cob[(0, quad_num, sensor_num)] * col((0, 0, 0, 1)))[0:3])
                fast = (
                    col((cob[(0, quad_num, sensor_num)] * col((1, 0, 0, 1)))[0:3])
                    - origin
                )
                slow = (
                    col((cob[(0, quad_num, sensor_num)] * col((0, 1, 0, 1)))[0:3])
                    - origin
                )
                pg2.set_local_frame(fast.elems, slow.elems, origin.elems)
                pg2.set_name("D%dQ%dS%d" % (det_num, quad_num, sensor_num))
                # Now deal with Az
                for asic_num in range(2):
                    val = "ARRAY_D0Q%dS%dA%d" % (quad_num, sensor_num, asic_num)
                    p = pg2.add_panel()
                    origin = col(
                        (cob[(0, quad_num, sensor_num, asic_num)] * col((0, 0, 0, 1)))[
                            0:3
                        ]
                    )
                    fast = (
                        col(
                            (
                                cob[(0, quad_num, sensor_num, asic_num)]
                                * col((1, 0, 0, 1))
                            )[0:3]
                        )
                        - origin
                    )
                    slow = (
                        col(
                            (
                                cob[(0, quad_num, sensor_num, asic_num)]
                                * col((0, 1, 0, 1))
                            )[0:3]
                        )
                        - origin
                    )
                    p.set_local_frame(fast.elems, slow.elems, origin.elems)
                    p.set_pixel_size(
                        (cspad_cbf_tbx.pixel_size, cspad_cbf_tbx.pixel_size)
                    )
                    p.set_image_size(cspad_cbf_tbx.asic_dimension)
                    p.set_trusted_range(
                        (
                            cspad_tbx.cspad_min_trusted_value,
                            cspad_tbx.cspad_saturated_value,
                        )
                    )
                    p.set_name(val)

        try:
            beam = self._beam(index)
        except Exception:
            print(
                "No beam object initialized. Returning CSPAD detector without parallax corrections"
            )
            return d

        # take into consideration here the thickness of the sensor also the
        # wavelength of the radiation (which we have in the same file...)
        wavelength = beam.get_wavelength()
        thickness = 0.5  # mm, see Hart et al. 2012

        table = attenuation_coefficient.get_table("Si")
        # mu_at_angstrom returns cm^-1
        mu = table.mu_at_angstrom(wavelength) / 10.0  # mu: mm^-1
        t0 = thickness
        for panel in d:
            panel.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, t0))
        return d
Exemple #5
0
    def _detector(self, index=None):
        import psana
        from xfel.cftbx.detector.cspad_cbf_tbx import read_slac_metrology
        from dxtbx.model import Detector
        from scitbx.matrix import col
        from dxtbx.model import ParallaxCorrectedPxMmStrategy
        if index is None: index = 0
        self._env = self._ds.env()
        self._det = psana.Detector(self._src, self._env)
        geom = self._det.pyda.geoaccess(self.events_list[index])
        cob = read_slac_metrology(geometry=geom, include_asic_offset=True)
        d = Detector()
        pg0 = d.hierarchy()
        # first deal with D0
        det_num = 0
        origin = col((cob[(0, )] * col((0, 0, 0, 1)))[0:3])
        fast = col((cob[(0, )] * col((1, 0, 0, 1)))[0:3]) - origin
        slow = col((cob[(0, )] * col((0, 1, 0, 1)))[0:3]) - origin
        origin += col((0., 0., -100.))
        pg0.set_local_frame(fast.elems, slow.elems, origin.elems)
        pg0.set_name('D%d' % (det_num))
        for quad_num in xrange(4):
            # Now deal with Qx
            pg1 = pg0.add_group()
            origin = col((cob[(0, quad_num)] * col((0, 0, 0, 1)))[0:3])
            fast = col((cob[(0, quad_num)] * col((1, 0, 0, 1)))[0:3]) - origin
            slow = col((cob[(0, quad_num)] * col((0, 1, 0, 1)))[0:3]) - origin
            pg1.set_local_frame(fast.elems, slow.elems, origin.elems)
            pg1.set_name('D%dQ%d' % (det_num, quad_num))
            for sensor_num in xrange(8):
                # Now deal with Sy
                pg2 = pg1.add_group()
                origin = col((cob[(0, quad_num, sensor_num)] * col(
                    (0, 0, 0, 1)))[0:3])
                fast = col((cob[(0, quad_num, sensor_num)] * col(
                    (1, 0, 0, 1)))[0:3]) - origin
                slow = col((cob[(0, quad_num, sensor_num)] * col(
                    (0, 1, 0, 1)))[0:3]) - origin
                pg2.set_local_frame(fast.elems, slow.elems, origin.elems)
                pg2.set_name('D%dQ%dS%d' % (det_num, quad_num, sensor_num))
                # Now deal with Az
                for asic_num in xrange(2):
                    val = 'ARRAY_D0Q%dS%dA%d' % (quad_num, sensor_num,
                                                 asic_num)
                    p = pg2.add_panel()
                    origin = col(
                        (cob[(0, quad_num, sensor_num, asic_num)] * col(
                            (0, 0, 0, 1)))[0:3])
                    fast = col((cob[(0, quad_num, sensor_num, asic_num)] * col(
                        (1, 0, 0, 1)))[0:3]) - origin
                    slow = col((cob[(0, quad_num, sensor_num, asic_num)] * col(
                        (0, 1, 0, 1)))[0:3]) - origin
                    p.set_local_frame(fast.elems, slow.elems, origin.elems)
                    p.set_pixel_size(
                        (cspad_cbf_tbx.pixel_size, cspad_cbf_tbx.pixel_size))
                    p.set_image_size(cspad_cbf_tbx.asic_dimension)
                    p.set_trusted_range((cspad_tbx.cspad_min_trusted_value,
                                         cspad_tbx.cspad_saturated_value))
                    p.set_name(val)

        try:
            beam = self._beam(index)
        except Exception:
            print 'No beam object initialized. Returning CSPAD detector without parallax corrections'
            return d

        # take into consideration here the thickness of the sensor also the
        # wavelength of the radiation (which we have in the same file...)
        wavelength = beam.get_wavelength()
        thickness = 0.5  # mm, see Hart et al. 2012
        from cctbx.eltbx import attenuation_coefficient
        table = attenuation_coefficient.get_table("Si")
        # mu_at_angstrom returns cm^-1
        mu = table.mu_at_angstrom(wavelength) / 10.0  # mu: mm^-1
        t0 = thickness
        for panel in d:
            panel.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, t0))
        return d
  if annulus:
    if params.resolution is None:
      print "Generating annular gain mask between %f and %f angstroms, assuming a distance %s mm and wavelength %s angstroms" % \
        (params.annulus_inner, params.annulus_outer, params.distance, params.wavelength)
    else:
      print "Generating annular gain mask between %f and %f angstroms, assuming a distance %s mm and wavelength %s angstroms. Also, pixels higher than %f angstroms will be set to low gain." % \
        (params.annulus_inner, params.annulus_outer, params.distance, params.wavelength, params.resolution)
  elif params.resolution is not None:
    print "Generating circular gain mask %s angstroms, assuming a distance %s mm and wavelength %s angstroms" % \
      (params.resolution, params.distance, params.wavelength)

  from xfel.cftbx.detector.cspad_cbf_tbx import read_slac_metrology, get_cspad_cbf_handle
  from dxtbx.format.FormatCBFCspad import FormatCBFCspadInMemory
  from dxtbx.model import BeamFactory
  metro = read_slac_metrology(path = params.optical_metrology_path)
  cbf = get_cspad_cbf_handle(None, metro, 'cbf', None, "test", None, params.distance, verbose = True, header_only = True)
  img = FormatCBFCspadInMemory(cbf)
  beam = BeamFactory.simple(params.wavelength).get_s0()
  beam_center = (0,0)

  data = numpy.zeros((11840,194))

  if annulus:
    inner = params.distance * math.tan(2*math.sinh(params.wavelength/(2*params.annulus_inner)))
    outer = params.distance * math.tan(2*math.sinh(params.wavelength/(2*params.annulus_outer)))
    print "Inner (mm):", inner
    print "Outer (mm):", outer
  if params.resolution is not None:
    radius = params.distance * math.tan(2*math.sinh(params.wavelength/(2*params.resolution)))
    print "Radius (mm):", radius
            except RuntimeError, e:
                raise Sorry("Unrecognized argument '%s' (error: %s)" %
                            (arg, str(e)))

    params = master_phil.fetch(sources=user_phil).extract()
    if (params.metrology_file is None):
        master_phil.show()
        raise Usage(
            "metrology_file must be defined (either metrology_file=XXX, or the file path alone)."
        )
    assert params.plot is not None
    assert params.out is not None

    print params.metrology_file

    metro = read_slac_metrology(params.metrology_file, plot=params.plot)

    write_cspad_cbf(None,
                    metro,
                    'cbf',
                    None,
                    params.out,
                    None,
                    0,
                    header_only=True)


if (__name__ == "__main__"):
    args = sys.argv[1:]
    run(args)
    print "Write a CBF header from a SLAC metrology file. Parameters:"
    master_phil.show(attributes_level=2)
    return

  user_phil = []
  for arg in args:
    if (os.path.isfile(arg)) :
      user_phil.append(libtbx.phil.parse("""metrology_file=\"%s\"""" % arg))
    else :
      try :
        user_phil.append(libtbx.phil.parse(arg))
      except RuntimeError, e :
        raise Sorry("Unrecognized argument '%s' (error: %s)" % (arg, str(e)))

  params = master_phil.fetch(sources=user_phil).extract()
  if (params.metrology_file is None) :
    master_phil.show()
    raise Usage("metrology_file must be defined (either metrology_file=XXX, or the file path alone).")
  assert params.plot is not None
  assert params.out is not None

  print params.metrology_file

  metro = read_slac_metrology(params.metrology_file, plot=params.plot)

  write_cspad_cbf(None, metro, 'cbf', None, params.out, None, 0, header_only=True)

if (__name__ == "__main__") :
  args = sys.argv[1:]
  run(args)
  if annulus:
    if params.resolution is None:
      print "Generating annular gain mask between %f and %f angstroms, assuming a distance %s mm and wavelength %s angstroms" % \
        (params.annulus_inner, params.annulus_outer, params.distance, params.wavelength)
    else:
      print "Generating annular gain mask between %f and %f angstroms, assuming a distance %s mm and wavelength %s angstroms. Also, pixels higher than %f angstroms will be set to low gain." % \
        (params.annulus_inner, params.annulus_outer, params.distance, params.wavelength, params.resolution)
  elif params.resolution is not None:
    print "Generating circular gain mask %s angstroms, assuming a distance %s mm and wavelength %s angstroms" % \
      (params.resolution, params.distance, params.wavelength)

  from xfel.cftbx.detector.cspad_cbf_tbx import read_slac_metrology, get_cspad_cbf_handle
  from dxtbx.format.FormatCBFCspad import FormatCBFCspadInMemory
  from dxtbx.model.beam import beam_factory
  metro = read_slac_metrology(path = params.optical_metrology_path)
  cbf = get_cspad_cbf_handle(None, metro, 'cbf', None, "test", None, params.distance, verbose = True, header_only = True)
  img = FormatCBFCspadInMemory(cbf)
  beam = beam_factory.simple(params.wavelength).get_s0()
  beam_center = (0,0)

  data = numpy.zeros((11840,194))

  if annulus:
    inner = params.distance * math.tan(2*math.sinh(params.wavelength/(2*params.annulus_inner)))
    outer = params.distance * math.tan(2*math.sinh(params.wavelength/(2*params.annulus_outer)))
    print "Inner (mm):", inner
    print "Outer (mm):", outer
  if params.resolution is not None:
    radius = params.distance * math.tan(2*math.sinh(params.wavelength/(2*params.resolution)))
    print "Radius (mm):", radius