コード例 #1
0
ファイル: convert_gain_map_cbf.py プロジェクト: dials/cctbx
def run(args):
    command_line = (option_parser().option(
        "-o",
        "--output_filename",
        action="store",
        type="string",
        help="Filename for the output cbf file",
        default="gain_map.cbf"
    ).option(
        "-m",
        "--metrology",
        action="store",
        type="string",
        help="CBF or DEF file",
        default=None
    ).option(
        "-d",
        "--distance",
        action="store",
        type="int",
        help=
        "Detector distance put into the gain cbf file. Not needed for processing.",
        default="0"
    ).option(
        "-w",
        "--wavelength",
        action="store",
        type="float",
        help=
        "Incident beam wavelength put into the gain cbf file. Not needed for processing.",
        default="0")).process(args=args)

    output_filename = command_line.options.output_filename
    metrology = command_line.options.metrology
    assert metrology is not None and os.path.isfile(metrology)

    args = command_line.args

    assert len(args) == 1
    if args[0].endswith('.txt') or args[0].endswith('.gain'):
        raw_data = numpy.loadtxt(args[0])
        assert raw_data.shape in [(5920, 388), (11840, 194)]
        tiles = convert_detector(raw_data)
    else:
        raise Usage(
            "Gain input file should be a text file with extension .txt or .gain"
        )

    metro = cbf_file_to_basis_dict(metrology)
    write_cspad_cbf(tiles, metro, 'cbf', None, output_filename,
                    command_line.options.wavelength,
                    command_line.options.distance)
コード例 #2
0
def run(argv=None):
    if argv is None:
        argv = sys.argv[1:]

    command_line = libtbx.option_parser.option_parser(
        usage="%s files" % libtbx.env.dispatcher_name).process(args=argv)

    paths = command_line.args
    if len(paths) <= 0:
        raise Usage("No files specified")

    for path in paths:
        # Load the metrology dictionary, containting basis shifts for each item in the hierarchy
        metro = cbf_file_to_basis_dict(path)

        # Remove from the hiearchy all but the central sensors (sensor 1 of each quadrant).
        # Need to remove the sesnor basis shifts and the corresponding asic shifts
        for quad in range(4):
            for sensor in [0, 2, 3, 4, 5, 6, 7]:
                metro.pop((0, quad, sensor))
                for asic in range(2):
                    metro.pop((0, quad, sensor, asic))

        # Renumber the sensors to 0 instead of 1
        for key in metro:
            if len(key) == 3:
                detector, quad, sensor = key
                metro[(detector, quad, 0)] = metro.pop(key)
            elif len(key) == 4:
                detector, quad, sensor, asic = key
                metro[(detector, quad, 0, asic)] = metro.pop(key)

        # Build the tiles dictionary for only sensor 1 of each quadrant.  Rename that sensor to zero.
        img = dxtbx.load(path)
        tiles = {}
        for quad in range(4):
            src_sensor = 1
            dest_sensor = 0
            for asic in range(2):
                tiles[(0, quad, dest_sensor, asic)] = img.get_raw_data()[
                    (quad * 16) + (src_sensor * 2) +
                    asic]  # FIXME get the panel ID from dxtbx

        destpath = os.path.splitext(path)[0] + "_pinwheel.cbf"

        hierarchy = img.get_detector().hierarchy()
        beam = img.get_beam()

        # write the result.  Have to call abs on the root distance because of a bug with the hierarchy matrix.
        write_cspad_cbf(tiles, metro, 'cbf', None, destpath,
                        beam.get_wavelength(), hierarchy.get_distance())
コード例 #3
0
def run(args):
    command_line = (
        option_parser()
        .option(
            "-o",
            "--output_filename",
            action="store",
            type="string",
            help="Filename for the output cbf file",
            default="gain_map.cbf",
        )
        .option("-m", "--metrology", action="store", type="string", help="CBF or DEF file", default=None)
        .option(
            "-d",
            "--distance",
            action="store",
            type="int",
            help="Detector distance put into the gain cbf file. Not needed for processing.",
            default="0",
        )
        .option(
            "-w",
            "--wavelength",
            action="store",
            type="float",
            help="Incident beam wavelength put into the gain cbf file. Not needed for processing.",
            default="0",
        )
    ).process(args=args)

    output_filename = command_line.options.output_filename
    metrology = command_line.options.metrology
    assert metrology is not None and os.path.isfile(metrology)

    args = command_line.args

    assert len(args) == 1
    if args[0].endswith(".txt") or args[0].endswith(".gain"):
        raw_data = numpy.loadtxt(args[0])
        assert raw_data.shape in [(5920, 388), (11840, 194)]
        tiles = convert_detector(raw_data)
    else:
        raise Usage("Gain input file should be a text file with extension .txt or .gain")

    metro = cbf_file_to_basis_dict(metrology)
    write_cspad_cbf(
        tiles, metro, "cbf", None, output_filename, command_line.options.wavelength, command_line.options.distance
    )
コード例 #4
0
def run(argv=None):
  if argv is None:
    argv = sys.argv[1:]

  command_line = libtbx.option_parser.option_parser(
    usage="%s files" % libtbx.env.dispatcher_name).process(args=argv)

  paths = command_line.args
  if len(paths) <= 0:
    raise Usage("No files specified")

  for path in paths:
    # Load the metrology dictionary, containting basis shifts for each item in the hierarchy
    metro = cbf_file_to_basis_dict(path)

    # Remove from the hiearchy all but the central sensors (sensor 1 of each quadrant).
    # Need to remove the sesnor basis shifts and the corresponding asic shifts
    for quad in range(4):
      for sensor in [0,2,3,4,5,6,7]:
        metro.pop((0,quad,sensor))
        for asic in range(2):
          metro.pop((0,quad,sensor,asic))

    # Renumber the sensors to 0 instead of 1
    for key in metro:
      if len(key) == 3:
        detector, quad, sensor = key
        metro[(detector,quad,0)] = metro.pop(key)
      elif len(key) == 4:
        detector, quad, sensor, asic = key
        metro[(detector,quad,0,asic)] = metro.pop(key)

    # Build the tiles dictionary for only sensor 1 of each quadrant.  Rename that sensor to zero.
    img = dxtbx.load(path)
    tiles = {}
    for quad in range(4):
      src_sensor = 1
      dest_sensor = 0
      for asic in range(2):
        tiles[(0,quad,dest_sensor,asic)] = img.get_raw_data()[(quad*16)+(src_sensor*2)+asic] # FIXME get the panel ID from dxtbx

    destpath = os.path.splitext(path)[0] + "_pinwheel.cbf"

    hierarchy = img.get_detector().hierarchy()
    beam = img.get_beam()

    # write the result.  Have to call abs on the root distance because of a bug with the hierarchy matrix.
    write_cspad_cbf(tiles, metro, 'cbf', None, destpath, beam.get_wavelength(), hierarchy.get_distance())
コード例 #5
0
        from xfel.cftbx.detector.metrology2phil import metrology2phil
        metro = metrology2phil(params.new_metrology, False)

        args = []

        import iotbx.phil
        for arg in args:
            metro = metro.fetch(sources=[iotbx.phil.parse(arg)])
    else:
        assert os.path.isfile(params.new_metrology)
        ext = os.path.splitext(params.new_metrology)[1].lower()
        if ext in ['.def', '.cbf']:
            metro_style = "cbf"

            from xfel.cftbx.detector.cspad_cbf_tbx import cbf_file_to_basis_dict
            metro = cbf_file_to_basis_dict(params.new_metrology)

        else:
            metro_style = "flatfile"

            from xfel.cftbx.detector.cspad_cbf_tbx import read_optical_metrology_from_flat_file, asic_dimension, asic_gap

            metro = read_optical_metrology_from_flat_file(params.new_metrology,
                                                          params.detector,
                                                          img['PIXEL_SIZE'],
                                                          asic_dimension,
                                                          asic_gap,
                                                          plot=params.plot)

    for filename in params.pickle_file:
        # Read the pickle file and pull the tiles out of it
コード例 #6
0
ファイル: cbf_average.py プロジェクト: cctbx/cctbx-playground
def run(argv=None):
  """Compute mean, standard deviation, and maximum projection images
  from a set of CSPAD cbf images given on the command line.

  @param argv Command line argument list
  @return     @c 0 on successful termination, @c 1 on error, and @c 2
              for command line syntax errors
  """

  import libtbx.load_env

  from libtbx import option_parser
  from scitbx.array_family import flex
  from dxtbx.format.Registry import Registry
  from xfel.cftbx.detector.cspad_cbf_tbx import cbf_file_to_basis_dict, write_cspad_cbf
#  from xfel.cxi.cspad_ana import cspad_tbx
#  from iotbx.detectors.cspad_detector_formats import reverse_timestamp

  if argv is None:
    argv = sys.argv
  command_line = (option_parser.option_parser(
    usage="%s [-v] [-a PATH] [-m PATH] [-s PATH] " \
    "image1 image2 [image3 ...]" % libtbx.env.dispatcher_name)
                  .option(None, "--average-path", "-a",
                          type="string",
                          default=None,
                          dest="avg_path",
                          metavar="PATH",
                          help="Write average image to PATH")
                  .option(None, "--maximum-path", "-m",
                          type="string",
                          default=None,
                          dest="max_path",
                          metavar="PATH",
                          help="Write maximum projection image to PATH")
                  .option(None, "--stddev-path", "-s",
                          type="string",
                          default=None,
                          dest="stddev_path",
                          metavar="PATH",
                          help="Write standard deviation image to PATH")
                  .option(None, "--verbose", "-v",
                          action="store_true",
                          default=False,
                          dest="verbose",
                          help="Print more information about progress")
                  ).process(args=argv[1:])

  # Note that it is not an error to omit the output paths, because
  # certain statistics could still be printed, e.g. with the verbose
  # option.
  paths = command_line.args
  if len(paths) == 0:
    command_line.parser.print_usage(file=sys.stderr)
    return 2

  # Loop over all images and accumulate statistics.
  nfail = 0
  nmemb = 0
  for path in paths:
    if command_line.options.verbose:
      sys.stdout.write("Processing %s...\n" % path)

    try:
      # Promote the image to double-precision floating point type.
      # All real-valued flex arrays have the as_double() function.
      # Warn if the header items across the set of images do not match
      # up.  Note that discrepancies regarding the image size are
      # fatal.
      if not 'reader' in locals():
        reader = Registry.find(path)
      img = reader(path)
      if 'detector' in locals():
        test_detector = img.get_detector()
        if len(test_detector) != len(detector):
          sys.stderr.write("Detectors do not have the same number of panels\n")
          return 1
        for t, d in zip(test_detector, detector):
          if t.get_image_size() != d.get_image_size():
            sys.stderr.write("Panel sizes do not match\n")
            return 1
          if t.get_pixel_size() != d.get_pixel_size():
            sys.stderr.write("Pixel sizes do not match\n")
            return 1
          if t.get_d_matrix() != d.get_d_matrix():
            sys.stderr.write("Detector panels are not all in the same location. The average will use the positions of the first image.\n")
        detector = test_detector
      else:
        detector = img.get_detector()

      data = [img.get_raw_data()[i].as_1d().as_double() for i in xrange(len(detector))]
      wavelength = img.get_beam().get_wavelength()
      distance = flex.mean(flex.double([d.get_directed_distance() for d in detector]))

    except Exception:
      nfail += 1
      continue

    # The sum-of-squares image is accumulated using long integers, as
    # this delays the point where overflow occurs.  But really, this
    # is just a band-aid...
    if nmemb == 0:
      max_img = copy.deepcopy(data)
      sum_distance = distance
      sum_img = copy.deepcopy(data)
      ssq_img = [flex.pow2(d) for d in data]
      sum_wavelength = wavelength
      metro = cbf_file_to_basis_dict(path)

    else:
      sel = [(d > max_d).as_1d() for d, max_d in zip(data, max_img)]
      for d, max_d, s in zip(data, max_img, sel): max_d.set_selected(s, d.select(s))

      sum_distance += distance
      for d, sum_d in zip(data, sum_img): sum_d += d
      for d, ssq_d in zip(data, ssq_img): ssq_d += flex.pow2(d)
      sum_wavelength += wavelength

    nmemb += 1

  # Early exit if no statistics were accumulated.
  if command_line.options.verbose:
    sys.stderr.write("Processed %d images (%d failed)\n" % (nmemb, nfail))
  if nmemb == 0:
    return 0

  # Calculate averages for measures where other statistics do not make
  # sense.  Note that avg_img is required for stddev_img.
  avg_img = [sum_d.as_double() / nmemb for sum_d in sum_img]
  avg_distance = sum_distance / nmemb
  avg_wavelength = sum_wavelength / nmemb

  def make_tiles(data, detector):
    """
    Assemble a tiles dictionary as required by write_cspad_cbf, consisting of 4 arrays of shape 8x185x388.
    Assumes the order in the data array matches the order of the enumerated detector panels.
    """
    assert len(data) == 64
    tiles = {}
    s, f = 185, 194

    for q_id in xrange(4):
      tiles[0,q_id] = flex.double((flex.grid(s*8, f*2)))
      for s_id in xrange(8):
        for a_id in xrange(2):
          asic_idx = (q_id*16) + (s_id*2) + a_id
          asic = data[asic_idx]
          asic.reshape(flex.grid((s, f)))

          tiles[0, q_id].matrix_paste_block_in_place(asic, s_id*s, a_id*f)
      tiles[0, q_id].reshape(flex.grid((8, s, f*2)))

    return tiles


  # Output the average image, maximum projection image, and standard
  # deviation image, if requested.
  if command_line.options.avg_path is not None:
    tiles = make_tiles(avg_img, detector)
    write_cspad_cbf(tiles, metro, 'cbf', None, command_line.options.avg_path, avg_wavelength, avg_distance)

  if command_line.options.max_path is not None:
    tiles = make_tiles(max_img, detector)
    write_cspad_cbf(tiles, metro, 'cbf', None, command_line.options.max_path, avg_wavelength, avg_distance)

  if command_line.options.stddev_path is not None:
    stddev_img = [ssq_d.as_double() - sum_d.as_double() * avg_d for ssq_d, sum_d, avg_d in zip(ssq_img, sum_img, avg_img)]

    # Accumulating floating-point numbers introduces errors, which may
    # cause negative variances.  Since a two-pass approach is
    # unacceptable, the standard deviation is clamped at zero.
    for stddev_d in stddev_img:
      stddev_d.set_selected(stddev_d < 0, 0)

    if nmemb == 1:
      stddev_img = [flex.sqrt(stddev_d) for stddev_d in stddev_img]
    else:
      stddev_img = [flex.sqrt(stddev_d / (nmemb - 1)) for stddev_d in stddev_img]

    tiles = make_tiles(stddev_img, detector)
    write_cspad_cbf(tiles, metro, 'cbf', None, command_line.options.stddev_path, avg_wavelength, avg_distance)

  return 0
コード例 #7
0
def run(argv=None):
    """Compute mean, standard deviation, and maximum projection images
  from a set of CSPAD cbf images given on the command line.

  @param argv Command line argument list
  @return     @c 0 on successful termination, @c 1 on error, and @c 2
              for command line syntax errors
  """

    import libtbx.load_env

    from libtbx import option_parser
    from scitbx.array_family import flex
    from dxtbx.format.Registry import Registry
    from xfel.cftbx.detector.cspad_cbf_tbx import cbf_file_to_basis_dict, write_cspad_cbf
    #  from xfel.cxi.cspad_ana import cspad_tbx
    #  from iotbx.detectors.cspad_detector_formats import reverse_timestamp

    if argv is None:
        argv = sys.argv
    command_line = (option_parser.option_parser(
      usage="%s [-v] [-a PATH] [-m PATH] [-s PATH] " \
      "image1 image2 [image3 ...]" % libtbx.env.dispatcher_name)
                    .option(None, "--average-path", "-a",
                            type="string",
                            default=None,
                            dest="avg_path",
                            metavar="PATH",
                            help="Write average image to PATH")
                    .option(None, "--maximum-path", "-m",
                            type="string",
                            default=None,
                            dest="max_path",
                            metavar="PATH",
                            help="Write maximum projection image to PATH")
                    .option(None, "--stddev-path", "-s",
                            type="string",
                            default=None,
                            dest="stddev_path",
                            metavar="PATH",
                            help="Write standard deviation image to PATH")
                    .option(None, "--verbose", "-v",
                            action="store_true",
                            default=False,
                            dest="verbose",
                            help="Print more information about progress")
                    ).process(args=argv[1:])

    # Note that it is not an error to omit the output paths, because
    # certain statistics could still be printed, e.g. with the verbose
    # option.
    paths = command_line.args
    if len(paths) == 0:
        command_line.parser.print_usage(file=sys.stderr)
        return 2

    # Loop over all images and accumulate statistics.
    nfail = 0
    nmemb = 0
    for path in paths:
        if command_line.options.verbose:
            sys.stdout.write("Processing %s...\n" % path)

        try:
            # Promote the image to double-precision floating point type.
            # All real-valued flex arrays have the as_double() function.
            # Warn if the header items across the set of images do not match
            # up.  Note that discrepancies regarding the image size are
            # fatal.
            if not 'reader' in locals():
                reader = Registry.find(path)
            img = reader(path)
            if 'detector' in locals():
                test_detector = img.get_detector()
                if len(test_detector) != len(detector):
                    sys.stderr.write(
                        "Detectors do not have the same number of panels\n")
                    return 1
                for t, d in zip(test_detector, detector):
                    if t.get_image_size() != d.get_image_size():
                        sys.stderr.write("Panel sizes do not match\n")
                        return 1
                    if t.get_pixel_size() != d.get_pixel_size():
                        sys.stderr.write("Pixel sizes do not match\n")
                        return 1
                    if t.get_d_matrix() != d.get_d_matrix():
                        sys.stderr.write(
                            "Detector panels are not all in the same location. The average will use the positions of the first image.\n"
                        )
                detector = test_detector
            else:
                detector = img.get_detector()

            data = [
                img.get_raw_data()[i].as_1d().as_double()
                for i in range(len(detector))
            ]
            wavelength = img.get_beam().get_wavelength()
            distance = flex.mean(
                flex.double([d.get_directed_distance() for d in detector]))

        except Exception:
            nfail += 1
            continue

        # The sum-of-squares image is accumulated using long integers, as
        # this delays the point where overflow occurs.  But really, this
        # is just a band-aid...
        if nmemb == 0:
            max_img = copy.deepcopy(data)
            sum_distance = distance
            sum_img = copy.deepcopy(data)
            ssq_img = [flex.pow2(d) for d in data]
            sum_wavelength = wavelength
            metro = cbf_file_to_basis_dict(path)

        else:
            sel = [(d > max_d).as_1d() for d, max_d in zip(data, max_img)]
            for d, max_d, s in zip(data, max_img, sel):
                max_d.set_selected(s, d.select(s))

            sum_distance += distance
            for d, sum_d in zip(data, sum_img):
                sum_d += d
            for d, ssq_d in zip(data, ssq_img):
                ssq_d += flex.pow2(d)
            sum_wavelength += wavelength

        nmemb += 1

    # Early exit if no statistics were accumulated.
    if command_line.options.verbose:
        sys.stderr.write("Processed %d images (%d failed)\n" % (nmemb, nfail))
    if nmemb == 0:
        return 0

    # Calculate averages for measures where other statistics do not make
    # sense.  Note that avg_img is required for stddev_img.
    avg_img = [sum_d.as_double() / nmemb for sum_d in sum_img]
    avg_distance = sum_distance / nmemb
    avg_wavelength = sum_wavelength / nmemb

    def make_tiles(data, detector):
        """
    Assemble a tiles dictionary as required by write_cspad_cbf, consisting of 4 arrays of shape 8x185x388.
    Assumes the order in the data array matches the order of the enumerated detector panels.
    """
        assert len(data) == 64
        tiles = {}
        s, f = 185, 194

        for q_id in range(4):
            tiles[0, q_id] = flex.double((flex.grid(s * 8, f * 2)))
            for s_id in range(8):
                for a_id in range(2):
                    asic_idx = (q_id * 16) + (s_id * 2) + a_id
                    asic = data[asic_idx]
                    asic.reshape(flex.grid((s, f)))

                    tiles[0, q_id].matrix_paste_block_in_place(
                        asic, s_id * s, a_id * f)
            tiles[0, q_id].reshape(flex.grid((8, s, f * 2)))

        return tiles

    # Output the average image, maximum projection image, and standard
    # deviation image, if requested.
    if command_line.options.avg_path is not None:
        tiles = make_tiles(avg_img, detector)
        write_cspad_cbf(tiles, metro, 'cbf', None,
                        command_line.options.avg_path, avg_wavelength,
                        avg_distance)

    if command_line.options.max_path is not None:
        tiles = make_tiles(max_img, detector)
        write_cspad_cbf(tiles, metro, 'cbf', None,
                        command_line.options.max_path, avg_wavelength,
                        avg_distance)

    if command_line.options.stddev_path is not None:
        stddev_img = [
            ssq_d.as_double() - sum_d.as_double() * avg_d
            for ssq_d, sum_d, avg_d in zip(ssq_img, sum_img, avg_img)
        ]

        # Accumulating floating-point numbers introduces errors, which may
        # cause negative variances.  Since a two-pass approach is
        # unacceptable, the standard deviation is clamped at zero.
        for stddev_d in stddev_img:
            stddev_d.set_selected(stddev_d < 0, 0)

        if nmemb == 1:
            stddev_img = [flex.sqrt(stddev_d) for stddev_d in stddev_img]
        else:
            stddev_img = [
                flex.sqrt(stddev_d / (nmemb - 1)) for stddev_d in stddev_img
            ]

        tiles = make_tiles(stddev_img, detector)
        write_cspad_cbf(tiles, metro, 'cbf', None,
                        command_line.options.stddev_path, avg_wavelength,
                        avg_distance)

    return 0
コード例 #8
0
    from xfel.cftbx.detector.metrology2phil import metrology2phil
    metro = metrology2phil(params.new_metrology,False)

    args = []

    import iotbx.phil
    for arg in args:
      metro = metro.fetch(sources=[iotbx.phil.parse(arg)])
  else:
    assert os.path.isfile(params.new_metrology)
    ext = os.path.splitext(params.new_metrology)[1].lower()
    if ext in ['.def','.cbf']:
      metro_style = "cbf"

      from xfel.cftbx.detector.cspad_cbf_tbx import cbf_file_to_basis_dict
      metro = cbf_file_to_basis_dict(params.new_metrology)

    else:
      metro_style = "flatfile"

      from xfel.cftbx.detector.cspad_cbf_tbx import read_optical_metrology_from_flat_file, asic_dimension, asic_gap

      metro = read_optical_metrology_from_flat_file(params.new_metrology, params.detector, img['PIXEL_SIZE'],
                                                    asic_dimension, asic_gap, plot=params.plot)

  for filename in params.pickle_file:
    # Read the pickle file and pull the tiles out of it
    img = easy_pickle.load(filename)

    tiles = {}
    asics = {}