Exemplo n.º 1
0
def main():
  from dials.util.options import OptionParser
  from dials.util.options import flatten_datablocks
  import libtbx.load_env

  usage = "%s [options] image_*.cbf" % (
    libtbx.env.dispatcher_name)

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_datablocks=True,
    read_datablocks_from_images=True,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=True)
  datablocks = flatten_datablocks(params.input.datablock)

  if len(datablocks) == 0:
    parser.print_help()
    exit()

  datablock = datablocks[0]
  imageset = datablock.extract_imagesets()[0]
  stability_fft(imageset, params)
Exemplo n.º 2
0
def run(args):
  from dials.util.options import OptionParser
  from dials.util.options import flatten_experiments
  from dials.util.options import flatten_reflections
  import libtbx.load_env

  usage = "%s [options] integrated.pickle experiments.json" % (
    libtbx.env.dispatcher_name)

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_experiments=True,
    read_reflections=True,
    check_format=False,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=False)
  experiments = flatten_experiments(params.input.experiments)
  reflections = flatten_reflections(params.input.reflections)

  if len(experiments) != 1 or len(reflections) != 1:
    parser.print_help()
    exit()

  if not 'shoebox' in reflections[0]:
    print 'Please add shoeboxes to reflection pickle'
    exit()

  results = main(reflections[0], experiments[0], params)

  if results:
    print 'mean result: %.3f' % (sum(results) / len(results))
Exemplo n.º 3
0
def run(args):

  from dials.util.options import OptionParser
  from dials.util.options import flatten_datablocks
  import libtbx.load_env

  usage = "%s [options] image_*.cbf" % (
    libtbx.env.dispatcher_name)

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_datablocks=True,
    read_datablocks_from_images=True,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=True)
  datablocks = flatten_datablocks(params.input.datablock)

  if len(datablocks) == 0 and len(experiments) == 0 and len(reflections) == 0:
    parser.print_help()
    exit()

  assert(len(datablocks) == 1)

  datablock = datablocks[0]
  imagesets = datablock.extract_imagesets()

  assert(len(imagesets) == 1)

  imageset = imagesets[0]

  images = imageset.indices()
  if params.frames:
    images = params.frames

  d_spacings = []
  intensities = []
  sigmas = []

  for indx in images:
    print 'For frame %d:' % indx
    d, I, sig = background(imageset, indx, n_bins=params.n_bins)

    print '%8s %8s %8s' % ('d', 'I', 'sig')
    for j in range(len(I)):
      print '%8.3f %8.3f %8.3f' % (d[j], I[j], sig[j])

    d_spacings.append(d)
    intensities.append(I)
    sigmas.append(sig)

  if params.plot:
    from matplotlib import pyplot
    fig = pyplot.figure()
    for d, I, sig in zip(d_spacings, intensities, sigmas):
      ds2 = 1/flex.pow2(d)
      pyplot.plot(ds2, I)

    pyplot.show()
Exemplo n.º 4
0
class Script(object):
  ''' The debugging visualization program. '''

  def __init__(self):
    '''Initialise the script.'''
    from dials.util.options import OptionParser
    import libtbx.load_env

    # The script usage
    usage  = "usage: %s [options] experiment.json" \
              % libtbx.env.dispatcher_name

    # Create the parser
    self.parser = OptionParser(
      usage=usage,
      epilog=help_message,
      read_reflections=True)

  def run(self):


    from dials.util.options import flatten_reflections
    from dials.viewer.viewer_interface import extract_n_show

    # Parse the command line
    params, options = self.parser.parse_args(show_diff_phil=True)
    table = flatten_reflections(params.input.reflections)
    if len(table) == 0:
      self.parser.print_help()
      return

    extract_n_show(table[0])
def run(args):

  from dials.util.options import OptionParser
  from dials.util.options import flatten_experiments
  from libtbx.utils import Sorry
  import libtbx.load_env

  usage = "%s [options] experiments.json" %libtbx.env.dispatcher_name

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_experiments=True,
    check_format=False,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=True)
  experiments = flatten_experiments(params.input.experiments)
  if len(experiments) <= 1:
    parser.print_help()
    return

  hkl = flex.miller_index(params.hkl)

  from dials.algorithms.indexing.compare_orientation_matrices import \
       show_rotation_matrix_differences
  show_rotation_matrix_differences(experiments.crystals(),
                                   miller_indices=hkl)
Exemplo n.º 6
0
def run(args):
    import libtbx.load_env

    usage = "%s [options] experiment.json indexed.pickle" % libtbx.env.dispatcher_name

    parser = OptionParser(
        usage=usage,
        phil=phil_scope,
        read_reflections=True,
        read_experiments=True,
        check_format=False,
        epilog=help_message,
    )

    params, options = parser.parse_args(show_diff_phil=True)

    reflections = flatten_reflections(params.input.reflections)
    experiments = flatten_experiments(params.input.experiments)
    if len(reflections) == 0 or len(experiments) == 0:
        parser.print_help()
        return
    assert len(reflections) == 1
    assert len(experiments) == 1
    experiment = experiments[0]
    reflections = reflections[0]

    test_P1_crystal_indexing(reflections, experiment, params)
    test_crystal_pointgroup_symmetry(reflections, experiment, params)
def run(args):
  import libtbx.load_env
  from libtbx.utils import Sorry
  from dials.util import log
  usage = "%s [options] datablock.json strong.pickle" %libtbx.env.dispatcher_name

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_datablocks=True,
    read_reflections=True,
    check_format=False,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=False)
  datablocks = flatten_datablocks(params.input.datablock)
  reflections = flatten_reflections(params.input.reflections)

  if len(datablocks) == 0 or len(reflections) == 0:
    parser.print_help()
    exit(0)

  # Configure the logging
  log.config(
    info=params.output.log,
    debug=params.output.debug_log)

  # Log the diff phil
  diff_phil = parser.diff_phil.as_str()
  if diff_phil is not '':
    info('The following parameters have been modified:\n')
    info(diff_phil)

  imagesets = []
  for datablock in datablocks:
    imagesets.extend(datablock.extract_imagesets())

  assert len(imagesets) > 0
  assert len(reflections) == len(imagesets)

  if params.scan_range is not None and len(params.scan_range) > 0:
    reflections = [
      filter_reflections_by_scan_range(refl, params.scan_range)
      for refl in reflections]

  dps_params = dps_phil_scope.extract()
  # for development, we want an exhaustive plot of beam probability map:
  dps_params.indexing.plot_search_scope = params.plot_search_scope
  dps_params.indexing.mm_search_scope = params.mm_search_scope

  new_detector, new_beam = discover_better_experimental_model(
    imagesets, reflections, params, dps_params, nproc=params.nproc,
    wide_search_binning=params.wide_search_binning)
  for imageset in imagesets:
    imageset.set_detector(new_detector)
    imageset.set_beam(new_beam)
  from dxtbx.serialize import dump
  dump.datablock(datablock, params.output.datablock)
Exemplo n.º 8
0
class Script(object):
  ''' The integration program. '''

  def __init__(self):
    '''Initialise the script.'''
    from dials.util.options import OptionParser
    import libtbx.load_env

    # The script usage
    usage  = "usage: %s [options] experiment.json" % libtbx.env.dispatcher_name

    # Create the parser
    self.parser = OptionParser(
      usage=usage,
      phil=phil_scope,
      epilog=help_message,
      read_experiments=True)

  def run(self):
    ''' Analyse the background '''
    from dials.util.command_line import heading
    from dials.util.options import flatten_experiments
    from dials.util import log
    from logging import info, debug
    from time import time
    from libtbx.utils import Sorry

    # Parse the command line
    params, options = self.parser.parse_args(show_diff_phil=False)
    experiments = flatten_experiments(params.input.experiments)
    if len(experiments) == 0:
      self.parser.print_help()
      return

    assert len(experiments) == 1

    # Get the imageset
    imageset = experiments[0].imageset

    total_image = None
    total_mask = None
    for i in range(len(imageset)):
      print i
      image = imageset.get_raw_data(i)
      mask = imageset.get_mask(i)
      if total_image is None:
        total_image = image[0]
        total_mask = mask[0]
      else:
        total_image += image[0]
    total_image /= len(imageset)
    print min(total_image)
    print max(total_image)
    print sum(total_image) / len(total_image)

    from matplotlib import pylab
    pylab.imshow(total_image.as_numpy_array(), vmin=0,vmax=2)
    pylab.show()
Exemplo n.º 9
0
def run(args):

  from dials.util.options import OptionParser
  from dials.util.options import flatten_datablocks
  from dials.util.options import flatten_experiments
  import libtbx.load_env

  usage = "%s [options] datablock.json" %(
    libtbx.env.dispatcher_name)

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_datablocks=True,
    read_experiments=True,
    check_format=True,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=True)
  datablocks = flatten_datablocks(params.input.datablock)
  experiments = flatten_experiments(params.input.experiments)

  if (len(datablocks) == 0 and len(experiments) == 0):
    parser.print_help()
    exit(0)

  if len(datablocks) == 0 and len(experiments) > 0:
    imagesets = experiments.imagesets()
  else:
    imagesets = []
    for datablock in datablocks:
      imagesets.extend(datablock.extract_imagesets())

  assert len(imagesets) == 1
  imageset = imagesets[0]
  gonio = imageset.get_goniometer()
  if not params.detector_distance:
    detector = imageset.get_detector()
    if len(detector) > 1:
      params.detector_distance = detector.hierarchy().get_directed_distance()
    else:
      params.detector_distance = detector[0].get_directed_distance()
  if params.angle:
    assert len(params.angle) == len(gonio.get_angles())
  else:
    for angle in gonio.get_angles():
      params.angle.append(angle)

  import wxtbx.app
  a = wxtbx.app.CCTBXApp(0)
  a.settings = params
  f = ExperimentViewer(
    None, -1, "Experiment viewer", size=(1024,768))
  f.load_imageset(imageset)
  f.Show()
  a.SetTopWindow(f)
  #a.Bind(wx.EVT_WINDOW_DESTROY, lambda evt: tb_icon.Destroy(), f)
  a.MainLoop()
Exemplo n.º 10
0
def run(args):
  from dials.util import log
  import libtbx.load_env
  usage = "%s experiments.json indexed.pickle [options]" %libtbx.env.dispatcher_name


  from dials.util.options import OptionParser
  from dials.util.options import flatten_reflections
  from dials.util.options import flatten_experiments
  from dials.array_family import flex

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_experiments=True,
    read_reflections=True,
    check_format=False,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=False)

  # Configure the logging
  #log.config(info=params.output.log, debug=params.output.debug_log)

  from dials.util.version import dials_version
  logger.info(dials_version())

  # Log the diff phil
  diff_phil = parser.diff_phil.as_str()
  if diff_phil is not '':
    logger.info('The following parameters have been modified:\n')
    logger.info(diff_phil)

  experiments = flatten_experiments(params.input.experiments)
  reflections = flatten_reflections(params.input.reflections)
  assert(len(reflections) == 1)
  reflections = reflections[0]

  if len(experiments) == 0:
    parser.print_help()
    return

  #from dials.command_line import refine
  #params = refine.phil_scope.extract()
  indexed_reflections = reflections.select(reflections['id'] > -1)
  from dials.algorithms.refinement import RefinerFactory
  refiner = RefinerFactory.from_parameters_data_experiments(
    params, indexed_reflections, experiments)
  #refiner.run()
  rmsds = refiner.rmsds()
  import math
  xy_rmsds = math.sqrt(rmsds[0]**2 + rmsds[1]**2)

  print rmsds



  return
Exemplo n.º 11
0
def run(args):
  import libtbx.load_env
  from libtbx.utils import Sorry
  from dials.util import log
  from logging import info
  import cPickle as pickle
  usage = "%s [options] datablock.json strong.pickle" % \
    libtbx.env.dispatcher_name

  # Create the option parser
  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_reflections=True,
    read_datablocks=True,
    check_format=False,
    epilog=help_message)

  # Get the parameters
  params, options = parser.parse_args(show_diff_phil=False)

  # Configure the log
  log.config(
    params.verbosity,
    info='dials.find_hot_pixels.log',
    debug='dials.find_hot_pixels.debug.log')

  # Log the diff phil
  diff_phil = parser.diff_phil.as_str()
  if diff_phil is not '':
    info('The following parameters have been modified:\n')
    info(diff_phil)

  datablocks = flatten_datablocks(params.input.datablock)
  reflections = flatten_reflections(params.input.reflections)

  if len(datablocks) == 0 and len(reflections) == 0:
    parser.print_help()
    exit(0)

  if len(datablocks) > 1:
    raise Sorry("Only one DataBlock can be processed at a time")
  else:
    imagesets = datablocks[0].extract_imagesets()
  if len(reflections) == 0:
    raise Sorry("No reflection lists found in input")
  if len(reflections) > 1:
    raise Sorry("Multiple reflections lists provided in input")

  assert(len(reflections) == 1)
  reflections = reflections[0]

  mask = hot_pixel_mask(imagesets[0], reflections)
  pickle.dump(mask, open(params.output.mask, 'w'), pickle.HIGHEST_PROTOCOL)

  print 'Wrote hot pixel mask to %s' % params.output.mask
  return
Exemplo n.º 12
0
def run(args):

  from dials.util.options import OptionParser
  from dials.util.options import flatten_datablocks
  from dials.util.options import flatten_experiments
  from dials.util.options import flatten_reflections

  parser = OptionParser(
    phil=master_phil,
    read_datablocks=True,
    read_experiments=True,
    read_reflections=True,
    check_format=False)

  params, options = parser.parse_args(show_diff_phil=True)
  datablocks = flatten_datablocks(params.input.datablock)
  experiments = flatten_experiments(params.input.experiments)
  reflections = flatten_reflections(params.input.reflections)[0]
  if len(params.input.reflections) == 2:
    reflections2 = flatten_reflections(params.input.reflections)[1]
  else:
    reflections2 = None

  # find the reflections in the second set that DO NOT match those in the
  # first set
  mask, _ = reflections2.match_with_reference(reflections)
  reflections2 = reflections2.select(~mask)
  print "{0} reflections from the second set do not match the first". \
    format(len(reflections2))
  #reflections2 = reflections2.select(reflections2["miller_index"] == (-7,2,-25))

  if len(datablocks) == 0:
    if len(experiments) > 0:
      imagesets = experiments.imagesets()
    else:
      parser.print_help()
      return
  elif len(datablocks) > 1:
    raise Sorry("Only one DataBlock can be processed at a time")
  else:
    imagesets = datablocks[0].extract_imagesets()

  if len(imagesets) > 1:
    raise Sorry("Only one ImageSet can be processed at a time")
  imageset = imagesets[0]

  import wxtbx.app
  a = wxtbx.app.CCTBXApp(0)
  a.settings = params
  f = PredRelpViewer(
    None, -1, "Prediction reciprocal lattice viewer", size=(1024,768))
  f.load_reflections2(reflections2)
  f.load_models(imageset, reflections)
  f.Show()
  a.SetTopWindow(f)
  #a.Bind(wx.EVT_WINDOW_DESTROY, lambda evt: tb_icon.Destroy(), f)
  a.MainLoop()
Exemplo n.º 13
0
def run(args):

  from dials.util.options import OptionParser
  from dials.util.options import flatten_datablocks
  from dials.util.options import flatten_experiments
  from dials.util.options import flatten_reflections
  import libtbx.load_env

  usage = "%s [options] datablock.json reflections.pickle" %(
    libtbx.env.dispatcher_name)

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_datablocks=True,
    read_experiments=True,
    read_reflections=True,
    check_format=False,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=True)
  datablocks = flatten_datablocks(params.input.datablock)
  experiments = flatten_experiments(params.input.experiments)
  reflections = flatten_reflections(params.input.reflections)

  if (len(datablocks) == 0 and len(experiments) == 0) or len(reflections) == 0:
    parser.print_help()
    exit(0)

  if len(datablocks) == 0 and len(experiments) > 0:
    imagesets = experiments.imagesets()
  else:
    imagesets = []
    for datablock in datablocks:
      imagesets.extend(datablock.extract_imagesets())

  if len(reflections) > 1:
    assert len(reflections) == len(imagesets)
    from scitbx.array_family import flex
    for i in range(len(reflections)):
      reflections[i]['imageset_id'] = flex.int(len(reflections[i]), i)
      if i > 0:
        reflections[0].extend(reflections[i])

  reflections = reflections[0]

  import wxtbx.app
  a = wxtbx.app.CCTBXApp(0)
  a.settings = params
  f = ReciprocalLatticeViewer(
    None, -1, "Reflection data viewer", size=(1024,768))
  f.load_models(imagesets, reflections)
  f.Show()
  a.SetTopWindow(f)
  #a.Bind(wx.EVT_WINDOW_DESTROY, lambda evt: tb_icon.Destroy(), f)
  a.MainLoop()
Exemplo n.º 14
0
class Script(object):
  ''' A class to encapsulate the script. '''

  def __init__(self):
    ''' Initialise the script. '''
    from dials.util.options import OptionParser
    import libtbx.load_env

    # Create the parser
    usage = "usage: %s [options] datablock.json" % libtbx.env.dispatcher_name
    self.parser = OptionParser(
      usage=usage,
      epilog=help_message,
      phil=phil_scope,
      read_datablocks=True)

  def run(self):
    ''' Run the script. '''
    from dials.util.options import flatten_datablocks
    from dxtbx.datablock import DataBlockDumper
    from libtbx.utils import Sorry
    import cPickle as pickle

    # Parse the command line arguments
    params, options = self.parser.parse_args(show_diff_phil=True)
    datablocks = flatten_datablocks(params.input.datablock)

    # Check number of args
    if len(datablocks) == 0:
      self.parser.print_help()
      return

    # Check the mask file is given
    if params.input.mask is None:
      self.parser.print_help()
      return

    # Check nbumber of datablocks
    if len(datablocks) != 1:
      raise Sorry('exactly 1 datablock must be specified')

    # Get the imageset
    datablock = datablocks[0]
    imagesets = datablock.extract_imagesets()
    if len(imagesets) != 1:
      raise Sorry('datablock must contain exactly 1 imageset')
    imageset = imagesets[0]

    # Set the lookup
    imageset.external_lookup.mask.filename = params.input.mask

    # Dump the datablock
    print "Writing datablock to %s" % params.output.datablock
    dump = DataBlockDumper(datablock)
    dump.as_json(filename=params.output.datablock)
Exemplo n.º 15
0
def run(args):
  import libtbx.load_env
  usage = "%s experiments.json [options]" %libtbx.env.dispatcher_name

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_experiments=True,
    check_format=False,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=True)
  experiments = flatten_experiments(params.input.experiments)
  if len(experiments) == 0:
    parser.print_help()
    return
  elif len(experiments) > 1:
    raise Sorry("More than one experiment present")

  assert len(params.miller_index), "Must specify at least one miller_index to predict."

  experiment = experiments[0]

  reflections = flex.reflection_table()
  miller_indices = flex.miller_index()
  entering_flags = flex.bool()
  for mi in params.miller_index:
    miller_indices.append(mi)
    miller_indices.append(mi)
    entering_flags.append(True)
    entering_flags.append(False)
  reflections['miller_index'] = miller_indices
  reflections['entering'] = entering_flags
  reflections['id'] = flex.size_t(len(reflections), 0)

  if params.expand_to_p1:
    from cctbx.miller import expand_to_p1_iselection
    proxy = expand_to_p1_iselection(
      experiment.crystal.get_space_group(),
      anomalous_flag=True,
      indices=miller_indices,
      build_iselection=True)
    reflections = reflections.select(proxy.iselection)
    reflections['miller_index'] = proxy.indices

  from dials.algorithms.refinement.prediction.managed_predictors import ExperimentsPredictor
  predictor = ExperimentsPredictor([experiment])
  predicted = predictor.predict(reflections)

  zmin, zmax = experiment.scan.get_array_range()
  z = predicted['xyzcal.px'].parts()[2]
  predicted = predicted.select((z >= zmin) & (z <= zmax))

  show_predictions(predicted)
Exemplo n.º 16
0
class Script(object):
  ''' A class to encapsulate the script. '''

  def __init__(self):
    ''' Initialise the script. '''
    from dials.util.options import OptionParser
    import libtbx.load_env

    # The script usage
    usage = "usage: %s [options] /path/to/image/reflection/files" % libtbx.env.dispatcher_name
    self.parser = OptionParser(
      epilog=help_message,
      usage=usage,
      phil=phil_scope,
      read_reflections=True)

  def run(self):
    ''' Run the script. '''
    from dials.array_family import flex
    from dials.util.command_line import Command
    from libtbx.utils import Sorry

    # Parse the command line arguments
    params, options = self.parser.parse_args(show_diff_phil=True)
    if len(params.input.reflections) == 0:
      self.parser.print_help()
      return
    if len(params.input.reflections) <= 1:
      raise Sorry('more than 1 reflection table must be specified')
    tables = [p.data for p in params.input.reflections]

    # Get the number of rows and columns
    nrows = [t.nrows() for t in tables]
    ncols = [t.ncols() for t in tables]

    # Merge the reflection lists
    if params.method == "update":
      assert(all(n == nrows[0] for n in nrows[1:]))
      table = tables[0]
      for t in tables[1:]:
        table.update(t)
    elif params.method == "extend":
      assert(all(n == ncols[0] for n in ncols[1:]))
      table = tables[0]
      for t in tables[1:]:
        table.extend(t)
    else:
      raise RuntimeError('unknown method, %s' % params.method)

    # Write the reflections to the file
    Command.start('Writing %d reflections to %s' % (len(table), params.output))
    table.as_pickle(params.output)
    Command.end('Wrote %d reflections to %s' % (len(table), params.output))
Exemplo n.º 17
0
def run(args):

  from dials.util.options import OptionParser
  from dials.util.options import flatten_datablocks
  from dials.util.options import flatten_experiments
  from dials.util.options import flatten_reflections
  from dials.util import log

  usage = "%s [options] datablock.json reflections.pickle" %(
    libtbx.env.dispatcher_name)

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_datablocks=True,
    read_experiments=True,
    read_reflections=True,
    check_format=False,
    epilog=help_message)

  params, options = parser.parse_args()
  datablocks = flatten_datablocks(params.input.datablock)
  experiments = flatten_experiments(params.input.experiments)
  reflections = flatten_reflections(params.input.reflections)

  if (len(datablocks) == 0 and len(experiments) == 0) or len(reflections) == 0:
    parser.print_help()
    exit(0)

  ## Configure the logging
  #log.config(info='dials.rl_png.log')

  # Log the diff phil
  diff_phil = parser.diff_phil.as_str()
  if diff_phil is not '':
    logger.info('The following parameters have been modified:\n')
    logger.info(diff_phil)

  reflections = reflections[0]

  if len(datablocks) == 0 and len(experiments) > 0:
    imagesets = experiments.imagesets()
  else:
    imagesets = []
    for datablock in datablocks:
      imagesets.extend(datablock.extract_imagesets())

  f = ReciprocalLatticeJson(settings=params)
  f.load_models(imagesets, reflections)
  f.as_json(filename=params.output.json, compact=params.output.compact)
  print
Exemplo n.º 18
0
def run(args):

  from dials.util.options import OptionParser
  from dials.util.options import flatten_datablocks
  from dials.util.options import flatten_experiments
  import libtbx.load_env

  usage = "%s [options] datablock.json | experiments.json" %(
    libtbx.env.dispatcher_name)

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_datablocks=True,
    read_experiments=True,
    check_format=False,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=True)
  experiments = flatten_experiments(params.input.experiments)
  datablocks = flatten_datablocks(params.input.datablock)

  if len(experiments) == 0 and len(datablocks) == 0:
    parser.print_help()
    exit(0)

  from dials.command_line.dials_import import ManualGeometryUpdater
  update_geometry = ManualGeometryUpdater(params)


  if len(experiments):
    imagesets = experiments.imagesets()

  elif len(datablocks):

    assert len(datablocks) == 1
    imagesets = datablocks[0].extract_imageset()

  for imageset in imagesets:
    imageset_new = update_geometry(imageset)
    imageset.set_detector(imageset_new.get_detector())
    imageset.set_beam(imageset_new.get_beam())
    imageset.set_goniometer(imageset_new.get_goniometer())
    imageset.set_scan(imageset_new.get_scan())

  from dxtbx.serialize import dump
  if len(experiments):
    print "Saving modified experiments to %s" %params.output.experiments
    dump.experiment_list(experiments, params.output.experiments)
  elif len(datablocks):
    raise NotImplemented
Exemplo n.º 19
0
def run(args):
  import libtbx.load_env
  from dials.array_family import flex
  from dials.util import log
  from dials.util.version import dials_version

  usage = "%s [options] experiment.json indexed.pickle" % \
    libtbx.env.dispatcher_name

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_reflections=True,
    read_experiments=True,
    check_format=False,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=True)

  # Configure the logging
  log.config(info=params.output.log, debug=params.output.debug_log)
  logger.info(dials_version())

  reflections = flatten_reflections(params.input.reflections)
  experiments = flatten_experiments(params.input.experiments)
  if len(reflections) == 0 or len(experiments) == 0:
    parser.print_help()
    return
  assert(len(reflections) == 1)
  assert(len(experiments) == 1)
  experiment = experiments[0]
  reflections = reflections[0]

  # remove reflections with 0, 0, 0 index
  zero = (reflections['miller_index'] == (0, 0, 0))
  logger.info('Removing %d unindexed reflections' % zero.count(True))
  reflections = reflections.select(~zero)

  h, k, l = reflections['miller_index'].as_vec3_double().parts()

  h = h.iround()
  k = k.iround()
  l = l.iround()

  logger.info('Range on h: %d to %d' % (flex.min(h), flex.max(h)))
  logger.info('Range on k: %d to %d' % (flex.min(k), flex.max(k)))
  logger.info('Range on l: %d to %d' % (flex.min(l), flex.max(l)))

  test_P1_crystal_indexing(reflections, experiment, params)
  test_crystal_pointgroup_symmetry(reflections, experiment, params)
Exemplo n.º 20
0
class Script(object):
  ''' A class to encapsulate the script. '''

  def __init__(self):
    ''' Initialise the script. '''
    from dials.util.options import OptionParser
    import libtbx.load_env

    # Create the parser
    usage = "usage: %s [options] reflections.pickle" % libtbx.env.dispatcher_name
    self.parser = OptionParser(
      usage=usage,
      phil=phil_scope,
      read_reflections=True,
      epilog=help_message)

    self.parser.add_option(
      '--xkcd',
      action='store_true',
      dest='xkcd',
      default=False,
      help='Special drawing mode')

  def run(self):
    ''' Run the script. '''
    from dials.util.command_line import Command
    from libtbx.utils import Sorry

    # Parse the command line arguments
    params, options = self.parser.parse_args(show_diff_phil=True)

    if options.xkcd:
      from matplotlib import pyplot
      pyplot.xkcd()

    # Shoe the help
    if len(params.input.reflections) != 1:
      self.parser.print_help()
      exit(0)

    # Analyse the reflections
    analyse = Analyser(
      params.output.directory, grid_size=params.grid_size,
      pixels_per_bin=params.pixels_per_bin,
      centroid_diff_max=params.centroid_diff_max)
    analyse(params.input.reflections[0].data)
Exemplo n.º 21
0
def run(args):
  import libtbx.load_env
  usage = """\
%s datablock.json reflections.pickle [options]""" %libtbx.env.dispatcher_name
  from dials.util.options import OptionParser
  from dials.util.options import flatten_datablocks
  from dials.util.options import flatten_experiments
  from dials.util.options import flatten_reflections
  from scitbx.array_family import flex
  from scitbx import matrix
  from libtbx.phil import command_line
  from libtbx.utils import Sorry
  parser = OptionParser(
    usage=usage,
    phil=master_phil_scope,
    read_datablocks=True,
    read_experiments=True,
    read_reflections=True,
    check_format=False)

  params, options = parser.parse_args(show_diff_phil=True)
  datablocks = flatten_datablocks(params.input.datablock)
  reflections = flatten_reflections(params.input.reflections)
  experiments = flatten_experiments(params.input.experiments)
  if len(datablocks) == 1:
    imageset = datablocks[0].extract_imagesets()[0]
  elif len(datablocks) > 1:
    raise Sorry("Only one DataBlock can be processed at a time")
  elif len(experiments.imagesets()) > 0:
    imageset = experiments.imagesets()[0]
    imageset.set_detector(experiments[0].detector)
    imageset.set_beam(experiments[0].beam)
    imageset.set_goniometer(experiments[0].goniometer)
  else:
    parser.print_help()
    return

  detector = imageset.get_detector()
  scan = imageset.get_scan()

  panel_origin_shifts = {0: (0,0,0)}
  try:
    hierarchy = detector.hierarchy()
  except AttributeError, e:
    hierarchy = None
Exemplo n.º 22
0
def run(args):
  import libtbx.load_env
  from libtbx.utils import Sorry
  usage = "%s [options] datablock.json" %libtbx.env.dispatcher_name

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_datablocks=True,
    check_format=True,
    read_datablocks_from_images=True,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=False)

  ## Configure the logging
  #log.config(
    #params.verbosity, info='dials.estimate_gain.log', debug='dials.estimate_gain.debug.log')

  # Log the diff phil
  diff_phil = parser.diff_phil.as_str()
  if diff_phil is not '':
    print 'The following parameters have been modified:\n'
    print diff_phil

  datablocks = flatten_datablocks(params.input.datablock)

  if len(datablocks) == 0:
    parser.print_help()
    return
  elif len(datablocks) > 1:
    raise Sorry("Only one DataBlock can be processed at a time")
  else:
    imagesets = []
    for datablock in datablocks:
      imagesets.extend(datablock.extract_imagesets())

  assert len(imagesets) == 1
  imageset = imagesets[0]
  estimate_gain(imageset, params.kernel_size, params.output.gain_map)

  return
Exemplo n.º 23
0
class Script(object):
  '''A class for running the script.'''

  def __init__(self):
    '''Initialise the script.'''
    from dials.util.options import OptionParser
    from libtbx.phil import parse
    import libtbx.load_env

    # The script usage
    usage = "usage: %s [options] experiment_one.json experiment_two.json" \
            % libtbx.env.dispatcher_name

    # Create the parser
    self.parser = OptionParser(
      usage=usage,
      phil=phil_scope,
      epilog=help_message,
      check_format=False,
      read_experiments=True)

  def run(self):
    '''Execute the script.'''
    from dials.util.command_line import Command
    from dials.array_family import flex
    from dials.util.options import flatten_experiments

    # Parse the command line
    params, options = self.parser.parse_args(show_diff_phil=True)

    # Check the number of experiments is at least 2
    experiments = flatten_experiments(params.input.experiments)
    if len(experiments) < 2:
      self.parser.print_help()
      return

    detectors = [experiment.detector[0] for experiment in experiments]

    from itertools import combinations

    for pair in combinations(detectors, 2):
      determine_axis(pair, params)
Exemplo n.º 24
0
def run(args):

  from dials.util.options import OptionParser
  from dials.util.options import flatten_datablocks
  import libtbx.load_env

  usage = "%s [options] datablock.json" % (
    libtbx.env.dispatcher_name)

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_datablocks=True,
    read_datablocks_from_images=True,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=True)

  datablocks = flatten_datablocks(params.input.datablock)

  if len(datablocks) == 0:
    parser.print_help()
    exit()

  assert(len(datablocks) == 1)

  datablock = datablocks[0]
  imagesets = datablock.extract_imagesets()

  assert(len(imagesets) == 1)

  imageset = imagesets[0]

  images = params.image

  for j, img_a in enumerate(images[:-1]):
    for img_b in images[j+1:]:
      a = imageset.get_raw_data(img_a)[0]
      b = imageset.get_raw_data(img_b)[0]
      n, cc = image_correlation(a, b)
      print '%5d %5d %7d %.4f' % (img_a, img_b, n, cc)
Exemplo n.º 25
0
def run(args):

  from dials.util.options import OptionParser
  from dials.util.options import flatten_datablocks
  from dials.util.options import flatten_experiments
  from dials.util.options import flatten_reflections
  import libtbx.load_env

  usage = "%s [options] datablock.json reflections.pickle" %(
    libtbx.env.dispatcher_name)

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_datablocks=True,
    read_experiments=True,
    read_reflections=True,
    check_format=False,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=True)
  datablocks = flatten_datablocks(params.input.datablock)
  experiments = flatten_experiments(params.input.experiments)
  reflections = flatten_reflections(params.input.reflections)

  if (len(datablocks) == 0 and len(experiments) == 0) or len(reflections) == 0:
    parser.print_help()
    exit(0)

  reflections = reflections[0]

  if len(datablocks) == 0 and len(experiments) > 0:
    imagesets = experiments.imagesets()
  else:
    imagesets = []
    for datablock in datablocks:
      imagesets.extend(datablock.extract_imagesets())

  spot_resolution_shells(imagesets, reflections, params)
Exemplo n.º 26
0
def run(args):

  from dials.util.options import OptionParser
  from dials.util.options import flatten_experiments
  from dials.util.options import flatten_reflections
  import libtbx.load_env
  from dials.util import best

  usage = "%s [options] experiments.json integrated.pickle" % (
    libtbx.env.dispatcher_name)

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_experiments=True,
    read_reflections=True,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=True)
  experiments = flatten_experiments(params.input.experiments)
  reflections = flatten_reflections(params.input.reflections)

  if len(experiments) == 0 or len(reflections) == 0:
    parser.print_help()
    exit()

  #assert(len(experiments) == 1)

  experiment = experiments[0]
  reflections = reflections[0]
  imageset = experiment.imageset

  best.write_background_file('bestfile.dat', imageset, n_bins=params.n_bins)

  best.write_integrated_hkl('bestfile', reflections)

  best.write_par_file('bestfile.par', experiment)
Exemplo n.º 27
0
def run(args):

  from dials.util.options import OptionParser
  from dials.util.options import flatten_datablocks
  import libtbx.load_env

  usage = "%s [options] datablock.json reference=reference_datablock.json" %(
    libtbx.env.dispatcher_name)

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_datablocks=True,
    check_format=False,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=True)
  datablocks = flatten_datablocks(params.input.datablock)

  if len(datablocks) == 0:
    parser.print_help()
    exit()

  # Load reference geometry
  reference_detector = None
  if params.input.reference is not None:
    from dxtbx.serialize import load
    try:
      reference_experiments = load.experiment_list(
        params.input.reference, check_format=False)
      assert len(reference_experiments.detectors()) == 1
      reference_detector = reference_experiments.detectors()[0]
    except Exception, e:
      reference_datablocks = load.datablock(params.input.reference)
      assert len(reference_datablocks) == 1
      imageset = reference_datablocks[0].extract_imagesets()[0]
      reference_detector = imageset.get_detector()
Exemplo n.º 28
0
def run():
  import sys
  import libtbx.load_env

  from dials.util.options import OptionParser
  from dials.util.options import flatten_datablocks

  usage = "%s [options] image_*.cbf" %libtbx.env.dispatcher_name

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_datablocks=True,
    read_datablocks_from_images=True,
    epilog=help_message
  )

  params, options, args = parser.parse_args(
    show_diff_phil=True, return_unhandled=True)

  n_images = params.merge_n_images
  out_prefix = params.output.image_prefix
  datablocks = flatten_datablocks(params.input.datablock)

  if len(datablocks) == 0:
    parser.print_help()
    return

  if len(datablocks) > 1:
    raise Sorry("Only one DataBlock can be processed at a time")
  else:
    imagesets = datablocks[0].extract_imagesets()
    assert len(imagesets) == 1
    imageset = imagesets[0]

  merge_cbf(imageset, n_images, out_prefix=out_prefix)
Exemplo n.º 29
0
def run(args):
    from dials.util.options import OptionParser
    from dials.util.options import flatten_experiments

    usage = "dials.background [options] image_*.cbf"

    parser = OptionParser(usage=usage,
                          phil=phil_scope,
                          read_experiments=True,
                          epilog=help_message)

    params, options = parser.parse_args(show_diff_phil=True)

    # Ensure we have either a data block or an experiment list
    experiments = flatten_experiments(params.input.experiments)
    if len(experiments) != 1:
        parser.print_help()
        return

    imagesets = experiments.imagesets()

    if len(imagesets) != 1:
        raise Sorry(
            "Please pass an experiment list that contains a single imageset")
    imageset = imagesets[0]

    first, last = imageset.get_scan().get_image_range()
    images = range(first, last + 1)

    if params.images:
        if min(params.images) < first or max(params.images) > last:
            raise Sorry("image outside of scan range")
        images = params.images

    d_spacings = []
    intensities = []
    sigmas = []

    for indx in images:
        print("For image %d:" % indx)
        indx -= first  # indices passed to imageset.get_raw_data start from zero
        d, I, sig = background(
            imageset,
            indx,
            n_bins=params.n_bins,
            corrected=params.corrected,
            mask_params=params.masking,
        )

        print("%8s %8s %8s" % ("d", "I", "sig"))
        for j in range(len(I)):
            print("%8.3f %8.3f %8.3f" % (d[j], I[j], sig[j]))

        d_spacings.append(d)
        intensities.append(I)
        sigmas.append(sig)

    if params.plot:
        from matplotlib import pyplot

        fig = pyplot.figure()
        ax = fig.add_subplot(111)
        ax.set_xlabel(r"resolution ($\AA$)")
        ax.set_ylabel(r"$\langle I_b \rangle$")
        for d, I, sig in zip(d_spacings, intensities, sigmas):
            ds2 = 1 / flex.pow2(d)
            ax.plot(ds2, I)
        xticks = ax.get_xticks()

        x_tick_labs = [
            "" if e <= 0.0 else "{:.2f}".format(math.sqrt(1.0 / e))
            for e in xticks
        ]
        ax.set_xticklabels(x_tick_labs)

        pyplot.show()
Exemplo n.º 30
0
def run(args=None):
    import libtbx.load_env

    from dials.util import Sorry

    usage = "dials.reindex [options] indexed.expt indexed.refl"

    parser = OptionParser(
        usage=usage,
        phil=phil_scope,
        read_reflections=True,
        read_experiments=True,
        check_format=False,
        epilog=help_message,
    )

    params, options = parser.parse_args(args, show_diff_phil=True)

    reflections, experiments = reflections_and_experiments_from_files(
        params.input.reflections, params.input.experiments)
    if len(experiments) == 0 and len(reflections) == 0:
        parser.print_help()
        return
    if params.change_of_basis_op is None:
        raise Sorry("Please provide a change_of_basis_op.")

    reference_crystal = None
    if params.reference.experiments is not None:
        from dxtbx.serialize import load

        reference_experiments = load.experiment_list(
            params.reference.experiments, check_format=False)
        assert len(reference_experiments.crystals()) == 1
        reference_crystal = reference_experiments.crystals()[0]

    if params.reference.reflections is not None:
        # First check that we have everything as expected for the reference reindexing
        # Currently only supports reindexing one dataset at a time
        if params.reference.experiments is None:
            raise Sorry(
                """For reindexing against a reference dataset, a reference
experiments file must also be specified with the option: reference= """)
        if not os.path.exists(params.reference.reflections):
            raise Sorry("Could not locate reference dataset reflection file")
        if len(experiments) != 1 or len(reflections) != 1:
            raise Sorry(
                "Only one dataset can be reindexed to a reference at a time")

        reference_reflections = flex.reflection_table().from_file(
            params.reference.reflections)

        test_reflections = reflections[0]

        if (reference_crystal.get_space_group().type().number() !=
                experiments.crystals()[0].get_space_group().type().number()):
            raise Sorry("Space group of input does not match reference")

        # Set some flags to allow filtering, if wanting to reindex against
        # reference with data that has not yet been through integration
        if (test_reflections.get_flags(
                test_reflections.flags.integrated_sum).count(True) == 0):
            assert (
                "intensity.sum.value"
                in test_reflections), "No 'intensity.sum.value' in reflections"
            test_reflections.set_flags(
                flex.bool(test_reflections.size(), True),
                test_reflections.flags.integrated_sum,
            )
        if (reference_reflections.get_flags(
                reference_reflections.flags.integrated_sum).count(True) == 0):
            assert ("intensity.sum.value" in test_reflections
                    ), "No 'intensity.sum.value in reference reflections"
            reference_reflections.set_flags(
                flex.bool(reference_reflections.size(), True),
                reference_reflections.flags.integrated_sum,
            )

        # Make miller array of the two datasets
        try:
            test_miller_set = filtered_arrays_from_experiments_reflections(
                experiments, [test_reflections])[0]
        except ValueError:
            raise Sorry(
                "No reflections remain after filtering the test dataset")
        try:
            reference_miller_set = filtered_arrays_from_experiments_reflections(
                reference_experiments, [reference_reflections])[0]
        except ValueError:
            raise Sorry(
                "No reflections remain after filtering the reference dataset")

        from dials.algorithms.symmetry.reindex_to_reference import (
            determine_reindex_operator_against_reference, )

        change_of_basis_op = determine_reindex_operator_against_reference(
            test_miller_set, reference_miller_set)

    elif len(experiments) and params.change_of_basis_op is libtbx.Auto:
        if reference_crystal is not None:
            if len(experiments.crystals()) > 1:
                raise Sorry("Only one crystal can be processed at a time")
            from dials.algorithms.indexing.compare_orientation_matrices import (
                difference_rotation_matrix_axis_angle, )

            cryst = experiments.crystals()[0]
            R, axis, angle, change_of_basis_op = difference_rotation_matrix_axis_angle(
                cryst, reference_crystal)
            print(f"Change of basis op: {change_of_basis_op}")
            print("Rotation matrix to transform input crystal to reference::")
            print(R.mathematica_form(format="%.3f", one_row_per_line=True))
            print(
                f"Rotation of {angle:.3f} degrees",
                "about axis (%.3f, %.3f, %.3f)" % axis,
            )

        elif len(reflections):
            assert len(reflections) == 1

            # always re-map reflections to reciprocal space
            refl = reflections.deep_copy()
            refl.centroid_px_to_mm(experiments)
            refl.map_centroids_to_reciprocal_space(experiments)

            # index the reflection list using the input experiments list
            refl["id"] = flex.int(len(refl), -1)
            index = AssignIndicesGlobal(tolerance=0.2)
            index(refl, experiments)
            hkl_expt = refl["miller_index"]
            hkl_input = reflections[0]["miller_index"]

            change_of_basis_op = derive_change_of_basis_op(hkl_input, hkl_expt)

            # reset experiments list since we don't want to reindex this
            experiments = []

    else:
        change_of_basis_op = sgtbx.change_of_basis_op(
            params.change_of_basis_op)

    if len(experiments):
        space_group = params.space_group
        if space_group is not None:
            space_group = space_group.group()
        try:
            experiments = reindex_experiments(experiments,
                                              change_of_basis_op,
                                              space_group=space_group)
        except RuntimeError as e:
            # Only catch specific errors here
            if "Unsuitable value for rational rotation matrix." in str(e):
                original_message = str(e).split(":")[-1].strip()
                sys.exit(
                    f"Error: {original_message} Is your change_of_basis_op valid?"
                )
            raise

        print(
            f"Saving reindexed experimental models to {params.output.experiments}"
        )
        experiments.as_file(params.output.experiments)

    if len(reflections):
        assert len(reflections) == 1
        reflections = reflections[0]

        miller_indices = reflections["miller_index"]

        if params.hkl_offset is not None:
            h, k, l = miller_indices.as_vec3_double().parts()
            h += params.hkl_offset[0]
            k += params.hkl_offset[1]
            l += params.hkl_offset[2]
            miller_indices = flex.miller_index(h.iround(), k.iround(),
                                               l.iround())
        non_integral_indices = change_of_basis_op.apply_results_in_non_integral_indices(
            miller_indices)
        if non_integral_indices.size() > 0:
            print(
                "Removing %i/%i reflections (change of basis results in non-integral indices)"
                % (non_integral_indices.size(), miller_indices.size()))
        sel = flex.bool(miller_indices.size(), True)
        sel.set_selected(non_integral_indices, False)
        miller_indices_reindexed = change_of_basis_op.apply(
            miller_indices.select(sel))
        reflections["miller_index"].set_selected(sel, miller_indices_reindexed)
        reflections["miller_index"].set_selected(~sel, (0, 0, 0))

        print(f"Saving reindexed reflections to {params.output.reflections}")
        reflections.as_file(params.output.reflections)
Exemplo n.º 31
0
def run(args):

    from dials.util.options import OptionParser
    from dials.util.options import flatten_experiments
    import libtbx.load_env

    usage = "%s [options] datablock.json" % (libtbx.env.dispatcher_name)

    parser = OptionParser(usage=usage,
                          phil=phil_scope,
                          read_experiments=True,
                          check_format=False,
                          epilog=help_message)

    params, options = parser.parse_args(show_diff_phil=True)
    experiments = flatten_experiments(params.input.experiments)

    if len(experiments) == 0:
        parser.print_help()
        exit(0)

    imagesets = experiments.imagesets()

    predicted_all = None
    dose = flex.size_t()

    for i_expt, expt in enumerate(experiments):
        if params.space_group is not None:
            expt.crystal.set_space_group(params.space_group.group())
        strategy = Strategy(expt,
                            d_min=params.d_min,
                            unit_cell_scale=params.unit_cell_scale,
                            degrees_per_bin=params.degrees_per_bin,
                            min_frac_new=params.minimum_fraction_new)
        strategy.plot(prefix='strategy1_')

        expt2 = copy.deepcopy(expt)
        scan = expt2.scan
        gonio = expt2.goniometer
        angles = gonio.get_angles()
        theta_max = strategy.theta_max
        fixed_rotation = matrix.sqr(gonio.get_fixed_rotation())
        setting_rotation = matrix.sqr(gonio.get_setting_rotation())
        rotation_axis = matrix.col(gonio.get_rotation_axis_datum())
        rotation_matrix = rotation_axis.axis_and_angle_as_r3_rotation_matrix(
            scan.get_oscillation()[0], deg=True)
        D_p = (setting_rotation * rotation_matrix * fixed_rotation)

        beam = expt2.beam
        s0 = matrix.col(beam.get_unit_s0())

        # rotate crystal by at least 2 * theta_max around axis perpendicular to
        # goniometer rotation axis
        n = rotation_axis.cross(s0)

        solutions = flex.vec3_double()
        rotation_angles = flex.double()
        for sign in (1, -1):
            i = 0
            while True:
                rot_angle = 2 * sign * (theta_max + i)
                i += 1

                R = n.axis_and_angle_as_r3_rotation_matrix(rot_angle, deg=True)

                axes = gonio.get_axes()
                assert len(axes) == 3
                e1, e2, e3 = (matrix.col(e) for e in reversed(axes))

                from dials.algorithms.refinement import rotation_decomposition
                solns = rotation_decomposition.solve_r3_rotation_for_angles_given_axes(
                    R * D_p, e1, e2, e3, return_both_solutions=True, deg=True)
                if solns is not None:
                    solutions.extend(flex.vec3_double(solns))
                    for i in range(len(solns)):
                        rotation_angles.append(rot_angle)
                    break

        for rot_angle, solution in zip(rotation_angles, solutions):
            angles = reversed(solution)
            gonio.set_angles(angles)

            print
            print "Goniometer settings to rotate crystal by %.2f degrees:" % rot_angle
            for name, angle in zip(gonio.get_names(), gonio.get_angles()):
                print "%s: %.2f degrees" % (name, angle)
            print

        strategy2 = Strategy(expt2,
                             d_min=params.d_min,
                             unit_cell_scale=params.unit_cell_scale,
                             degrees_per_bin=params.degrees_per_bin,
                             min_frac_new=params.minimum_fraction_new)
        strategy2.plot(prefix='strategy2_')

        stats = ComputeStats([strategy, strategy2])
        stats.show()
        plot_statistics(stats, prefix='multi_strategy_')

        return
Exemplo n.º 32
0
class Script(object):
    ''' Encapsulate the script in a class. '''
    def __init__(self):
        ''' Initialise the script. '''
        from dials.util.options import OptionParser
        import libtbx.load_env

        # The script usage
        usage  = "usage: %s [options] experiments.json spots.pickle" \
          % libtbx.env.dispatcher_name
        self.parser = OptionParser(usage=usage,
                                   epilog=help_message,
                                   phil=phil_scope,
                                   read_reflections=True,
                                   read_experiments=True,
                                   check_format=False)

    def run(self):
        ''' Run the script. '''
        from dials.algorithms.profile_model.factory import ProfileModelFactory
        from dials.util.command_line import Command
        from dials.array_family import flex
        from dials.util.options import flatten_reflections, flatten_experiments
        from dxtbx.model.experiment_list import ExperimentListDumper
        from libtbx.utils import Sorry
        from dials.util import log

        log.config()

        # Parse the command line
        params, options = self.parser.parse_args(show_diff_phil=True)
        reflections = flatten_reflections(params.input.reflections)
        experiments = flatten_experiments(params.input.experiments)
        if len(reflections) == 0 and len(experiments) == 0:
            self.parser.print_help()
            return
        if len(reflections) != 1:
            raise Sorry('exactly 1 reflection table must be specified')
        if len(experiments) == 0:
            raise Sorry('no experiments were specified')
        if (not 'background.mean'
                in reflections[0]) and params.subtract_background:
            raise Sorry(
                'for subtract_background need background.mean in reflections')

        reflections, _ = self.process_reference(reflections[0], params)

        # Check pixels don't belong to neighbours
        self.filter_reference_pixels(reflections, experiments)

        # Predict the reflections
        logger.info("")
        logger.info("=" * 80)
        logger.info("")
        logger.info("Predicting reflections")
        logger.info("")
        predicted = flex.reflection_table.from_predictions_multi(
            experiments,
            dmin=params.prediction.d_min,
            dmax=params.prediction.d_max,
            margin=params.prediction.margin,
            force_static=params.prediction.force_static,
            padding=params.prediction.padding)

        # Match with predicted
        matched, reflections, unmatched = predicted.match_with_reference(
            reflections)
        assert (len(matched) == len(predicted))
        assert (matched.count(True) <= len(reflections))
        if matched.count(True) == 0:
            raise Sorry('''
        Invalid input for reference reflections.
        Zero reference spots were matched to predictions
      ''')
        elif len(unmatched) != 0:
            logger.info('')
            logger.info('*' * 80)
            logger.info(
                'Warning: %d reference spots were not matched to predictions' %
                (len(unmatched)))
            logger.info('*' * 80)
            logger.info('')

        # Create the profile model
        experiments = ProfileModelFactory.create(params, experiments,
                                                 reflections)
        for model in experiments:
            sigma_b = model.profile.sigma_b(deg=True)
            sigma_m = model.profile.sigma_m(deg=True)
            if type(sigma_b) == type(1.0):
                logger.info('Sigma B: %f' % sigma_b)
                logger.info('Sigma M: %f' % sigma_m)
            else:  # scan varying
                mean_sigma_b = sum(sigma_b) / len(sigma_b)
                mean_sigma_m = sum(sigma_m) / len(sigma_m)
                logger.info('Sigma B: %f' % mean_sigma_b)
                logger.info('Sigma M: %f' % mean_sigma_m)

        # Wrtie the parameters
        Command.start("Writing experiments to %s" % params.output)
        dump = ExperimentListDumper(experiments)
        with open(params.output, "w") as outfile:
            outfile.write(dump.as_json())
        Command.end("Wrote experiments to %s" % params.output)

    def process_reference(self, reference, params):
        ''' Load the reference spots. '''
        from dials.array_family import flex
        from time import time
        from libtbx.utils import Sorry
        if reference is None:
            return None, None
        st = time()
        assert ("miller_index" in reference)
        assert ("id" in reference)
        logger.info('Processing reference reflections')
        logger.info(' read %d strong spots' % len(reference))
        mask = reference.get_flags(reference.flags.indexed)
        rubbish = reference.select(mask == False)
        if mask.count(False) > 0:
            reference.del_selected(mask == False)
            logger.info(' removing %d unindexed reflections' %
                        mask.count(False))
        if len(reference) == 0:
            raise Sorry('''
        Invalid input for reference reflections.
        Expected > %d indexed spots, got %d
      ''' % (0, len(reference)))
        mask = reference.get_flags(reference.flags.centroid_outlier)
        if mask.count(True) > 0:
            rubbish.extend(reference.select(mask))
            reference.del_selected(mask)
            logger.info(
                ' removing %d reflections marked as centroid outliers' %
                mask.count(True))
        mask = reference['miller_index'] == (0, 0, 0)
        if mask.count(True) > 0:
            rubbish.extend(reference.select(mask))
            reference.del_selected(mask)
            logger.info(' removing %d reflections with hkl (0,0,0)' %
                        mask.count(True))
        mask = reference['id'] < 0
        if mask.count(True) > 0:
            raise Sorry('''
        Invalid input for reference reflections.
        %d reference spots have an invalid experiment id
      ''' % mask.count(True))
        logger.info(' using %d indexed reflections' % len(reference))
        logger.info(' found %d junk reflections' % len(rubbish))
        from dials.array_family import flex
        if 'background.mean' in reference and params.subtract_background:
            logger.info(
                ' subtracting background from %d reference reflections' %
                len(reference))
            for spot in reference:
                spot['shoebox'].data -= spot['background.mean']
        logger.info(' time taken: %g' % (time() - st))
        return reference, rubbish

    def filter_reference_pixels(self, reference, experiments):
        '''
    Set any pixel closer to other reflections to background

    '''
        modified_count = 0
        for experiment, indices in reference.iterate_experiments_and_indices(
                experiments):
            subset = reference.select(indices)
            modified = subset['shoebox'].mask_neighbouring(
                subset['miller_index'], experiment.beam, experiment.detector,
                experiment.goniometer, experiment.scan, experiment.crystal)
            modified_count += modified.count(True)
            reference.set_selected(indices, subset)
        logger.info(" masked neighbouring pixels in %d shoeboxes" %
                    modified_count)
        return reference
class Script(object):
    """The integration program."""

    def __init__(self):
        """Initialise the script."""
        from dials.util.options import OptionParser
        import libtbx.load_env

        # The script usage
        usage = "usage: dev.dials.make_polar_background_image [options] models.expt"

        # Create the parser
        self.parser = OptionParser(
            usage=usage, phil=phil_scope, epilog=help_message, read_experiments=True
        )

    def run(self):
        """Perform the integration."""
        from dials.util.options import flatten_experiments
        from dials.util import log
        from dials.array_family import flex

        # Parse the command line
        params, options = self.parser.parse_args(show_diff_phil=False)
        experiments = flatten_experiments(params.input.experiments)
        if len(experiments) == 0:
            self.parser.print_help()
            return

        assert len(experiments) == 1
        imageset = experiments[0].imageset
        beam = experiments[0].beam
        detector = experiments[0].detector
        goniometer = experiments[0].goniometer
        assert len(detector) == 1

        # Configure logging
        log.config()

        from dials.algorithms.background.gmodel import PolarTransform
        import six.moves.cPickle as pickle

        with open(params.model, "rb") as fh:
            model = pickle.load(fh)
        image = model.data(0)
        mask = flex.bool(image.accessor(), True)

        # Do the transformation
        transform = PolarTransform(beam, detector[0], goniometer)
        result = transform.to_polar(image, mask)
        data = result.data()
        mask = result.mask()

        with open(params.output.data, "wb") as fh:
            pickle.dump((data, mask), fh, pickle.HIGHEST_PROTOCOL)

        from matplotlib import pylab

        vmax = sorted(list(data))[int(0.99 * len(data))]
        figure = pylab.figure(figsize=(6, 4))
        pylab.imshow(data.as_numpy_array(), interpolation="none", vmin=0, vmax=vmax)
        ax1 = pylab.gca()
        ax1.get_xaxis().set_visible(False)
        ax1.get_yaxis().set_visible(False)
        cb = pylab.colorbar()
        cb.ax.tick_params(labelsize=8)
        logger.info("Saving polar model %s" % (params.output.image))
        pylab.savefig("%s" % (params.output.image), dpi=600, bbox_inches="tight")
Exemplo n.º 34
0
    %s datablock.json [reflections.pickle]
  """ % libtbx.env.dispatcher_name
    parser = OptionParser(usage=usage_message,
                          phil=phil_scope,
                          read_datablocks=True,
                          read_experiments=True,
                          read_reflections=True,
                          read_datablocks_from_images=True,
                          epilog=help_message)
    params, options = parser.parse_args(show_diff_phil=True)
    datablocks = flatten_datablocks(params.input.datablock)
    experiments = flatten_experiments(params.input.experiments)
    reflections = flatten_reflections(params.input.reflections)

    if len(datablocks) == 0 and len(experiments) == 0:
        parser.print_help()
        exit(0)

    if len(datablocks) > 0:
        assert len(datablocks) == 1
        datablock = datablocks[0]
    else:
        datablock = None

    if params.mask is not None:
        from libtbx import easy_pickle
        params.mask = easy_pickle.load(params.mask)

    runner = Script(params=params,
                    reflections=reflections,
                    datablock=datablock,
Exemplo n.º 35
0
class Script(object):
    """A class for running the script."""
    def __init__(self):
        """Initialise the script."""
        from libtbx.phil import parse

        # The phil scope
        phil_scope = parse(
            """
scale = unit *max_cell ewald_sphere_radius
    .type = choice
    .help = "Choose the scale for the direction vector in orthogonal"
            "coordinates prior to transformation into fractional"
            "coordinates [uvw]"

plot_filename = None
    .type = str
    .help = "Filename for a plot of angle between neighbouring frames"
            "(set to None for no plot)"
""",
            process_includes=True,
        )

        usage = "dials.frame_orientations refined.expt refined.refl"

        # Create the parser
        self.parser = OptionParser(
            usage=usage,
            phil=phil_scope,
            read_experiments=True,
            check_format=False,
            epilog=__doc__,
        )

    def run(self):
        """Execute the script."""

        # Parse the command line
        self.params, _ = self.parser.parse_args(show_diff_phil=True)

        if not self.params.input.experiments:
            self.parser.print_help()
            sys.exit()

        # Try to load the models
        experiments = flatten_experiments(self.params.input.experiments)
        nexp = len(experiments)
        if nexp == 0:
            self.parser.print_help()
            sys.exit("No Experiments found in the input")

        # Set up a plot if requested
        if self.params.plot_filename:
            plt.figure()

        header = [
            "Image",
            "Beam direction (xyz)",
            "Zone axis [uvw]",
            "Angles between beam\nand axes a, b, c (deg)",
            "Angle from\nprevious image (deg)",
        ]
        for iexp, exp in enumerate(experiments):
            print("For Experiment id = {}".format(iexp))
            print(exp.beam)
            print(exp.crystal)
            print(exp.scan)

            if self.params.scale == "ewald_sphere_radius":
                scale = 1.0 / exp.beam.get_wavelength()
            elif self.params.scale == "max_cell":
                uc = exp.crystal.get_unit_cell()
                scale = max(uc.parameters()[0:3])
            else:
                scale = 1.0
            print("Beam direction scaled by {0} = {1:.3f} to "
                  "calculate zone axis\n".format(self.params.scale, scale))

            dat = extract_experiment_data(exp, scale)
            images = dat["images"]
            directions = dat["directions"]
            zone_axes = dat["zone_axes"]
            real_space_axes = dat["real_space_axes"]

            # calculate the angle between the beam and each crystal axis
            axis_angles = []
            for d, rsa in zip(directions, real_space_axes):
                angles = [d.angle(a, deg=True) for a in rsa]
                axis_angles.append("{:.2f} {:.2f} {:.2f}".format(*angles))

            # calculate the orientation offset between each image
            offset = [
                e1.angle(e2, deg=True)
                for e1, e2 in zip(zone_axes[:-1], zone_axes[1:])
            ]
            str_off = ["---"] + ["{:.8f}".format(e) for e in offset]

            rows = []
            for i, d, z, a, o in zip(
                    images,
                    directions,
                    zone_axes,
                    axis_angles,
                    str_off,
            ):
                row = [
                    str(i),
                    "{:.8f} {:.8f} {:.8f}".format(*d.elems),
                    "{:.8f} {:.8f} {:.8f}".format(*z.elems),
                    a,
                    o,
                ]
                rows.append(row)

            # Print the table
            print(tabulate(rows, header))

            # Add to the plot, if requested
            if self.params.plot_filename:
                plt.scatter(images[1:], offset, s=1)

        # Finish and save plot, if requested
        if self.params.plot_filename:
            plt.xlabel("Image number")
            plt.ylabel(r"Angle from previous image $\left(^\circ\right)$")
            plt.title(r"Angle between neighbouring images")
            print("Saving plot to {}".format(self.params.plot_filename))
            plt.savefig(self.params.plot_filename)

        print()
Exemplo n.º 36
0
class Script(object):
    '''A class for running the script.'''
    def __init__(self):
        '''Initialise the script.'''
        from dials.util.options import OptionParser
        import libtbx.load_env

        # The script usage
        usage = "usage: %s [options] [param.phil] "\
                "datablock.json" \
                % libtbx.env.dispatcher_name

        # Initialise the base class
        self.parser = OptionParser(usage=usage,
                                   phil=phil_scope,
                                   epilog=help_message,
                                   read_datablocks=True,
                                   read_reflections=True)

    def run(self):
        '''Execute the script.'''
        from dials.array_family import flex
        from dials.util.options import flatten_datablocks
        from dials.util.options import flatten_reflections
        from time import time
        from dials.util import log
        from libtbx.utils import Sorry
        start_time = time()

        # Parse the command line
        params, options = self.parser.parse_args(show_diff_phil=False)

        # Configure the logging
        log.config(params.verbosity,
                   info=params.output.log,
                   debug=params.output.debug_log)

        from dials.util.version import dials_version
        logger.info(dials_version())

        # Log the diff phil
        diff_phil = self.parser.diff_phil.as_str()
        if diff_phil is not '':
            logger.info('The following parameters have been modified:\n')
            logger.info(diff_phil)

        # Ensure we have a data block
        datablocks = flatten_datablocks(params.input.datablock)
        reflections = flatten_reflections(params.input.reflections)
        if len(datablocks) == 0 and len(reflections) == 0:
            self.parser.print_help()
            return
        elif len(datablocks) != len(reflections):
            raise Sorry(
                "Must have same number of datablocks and reflection tables")

        # Combine the datablocks and reflections
        datablock, reflections = combine(datablocks, reflections, params)

        # Save the reflections to file
        logger.info('\n' + '-' * 80)
        reflections.as_pickle(params.output.reflections)
        logger.info('Saved {0} reflections to {1}'.format(
            len(reflections), params.output.reflections))

        # Save the datablock
        from dxtbx.datablock import DataBlockDumper
        logger.info('Saving datablocks to {0}'.format(params.output.datablock))
        dump = DataBlockDumper(datablocks)
        dump.as_file(params.output.datablock)

        # Print the time
        logger.info("Time Taken: %f" % (time() - start_time))
Exemplo n.º 37
0
def run(args):

    from dials.util.options import OptionParser
    from dials.util.options import flatten_experiments
    from dials.util.options import flatten_datablocks
    from dials.util.options import flatten_reflections
    import libtbx.load_env

    usage = "%s [options] datablock.json | experiments.json | image_*.cbf" % (
        libtbx.env.dispatcher_name)

    parser = OptionParser(usage=usage,
                          phil=phil_scope,
                          read_experiments=True,
                          read_datablocks=True,
                          read_datablocks_from_images=True,
                          read_reflections=True,
                          check_format=False,
                          epilog=help_message)

    params, options = parser.parse_args(show_diff_phil=True)
    experiments = flatten_experiments(params.input.experiments)
    datablocks = flatten_datablocks(params.input.datablock)
    reflections = flatten_reflections(params.input.reflections)

    if len(datablocks) == 0 and len(experiments) == 0 and len(
            reflections) == 0:
        parser.print_help()
        exit()

    for i_expt, expt in enumerate(experiments):
        print "Experiment %i:" % i_expt
        print str(expt.detector)
        print 'Max resolution (at corners): %f' % (
            expt.detector.get_max_resolution(expt.beam.get_s0()))
        print 'Max resolution (inscribed):  %f' % (
            expt.detector.get_max_inscribed_resolution(expt.beam.get_s0()))
        if params.show_panel_distance:
            for ipanel, panel in enumerate(expt.detector):
                from scitbx import matrix
                fast = matrix.col(panel.get_fast_axis())
                slow = matrix.col(panel.get_slow_axis())
                normal = fast.cross(slow).normalize()
                origin = matrix.col(panel.get_origin())
                distance = origin.dot(normal)
                fast_origin = -(origin - distance * normal).dot(fast)
                slow_origin = -(origin - distance * normal).dot(slow)
                print 'Panel %d: distance %.2f origin %.2f %.2f' % \
                  (ipanel, distance, fast_origin, slow_origin)
            print ''
        print ''
        print show_beam(expt.detector, expt.beam)
        if expt.scan is not None:
            print expt.scan
        if expt.goniometer is not None:
            print expt.goniometer
        expt.crystal.show(show_scan_varying=params.show_scan_varying)
        if expt.crystal.num_scan_points:
            from scitbx.array_family import flex
            from cctbx import uctbx
            abc = flex.vec3_double()
            angles = flex.vec3_double()
            for n in range(expt.crystal.num_scan_points):
                a, b, c, alpha, beta, gamma = expt.crystal.get_unit_cell_at_scan_point(
                    n).parameters()
                abc.append((a, b, c))
                angles.append((alpha, beta, gamma))
            a, b, c = abc.mean()
            alpha, beta, gamma = angles.mean()
            mean_unit_cell = uctbx.unit_cell((a, b, c, alpha, beta, gamma))
            print "  Average unit cell: %s" % mean_unit_cell
        print
        if expt.profile is not None:
            print expt.profile

    for datablock in datablocks:
        if datablock.format_class() is not None:
            print 'Format: %s' % datablock.format_class()
        imagesets = datablock.extract_imagesets()
        for imageset in imagesets:
            try:
                print imageset.get_template()
            except Exception:
                pass
            detector = imageset.get_detector()
            print str(detector)
            print 'Max resolution (at corners): %f' % (
                detector.get_max_resolution(imageset.get_beam().get_s0()))
            print 'Max resolution (inscribed):  %f' % (
                detector.get_max_inscribed_resolution(
                    imageset.get_beam().get_s0()))
            if params.show_panel_distance:
                for ipanel, panel in enumerate(detector):
                    from scitbx import matrix
                    fast = matrix.col(panel.get_fast_axis())
                    slow = matrix.col(panel.get_slow_axis())
                    normal = fast.cross(slow)
                    origin = matrix.col(panel.get_origin())
                    distance = origin.dot(normal)
                    fast_origin = -(origin - distance * normal).dot(fast)
                    slow_origin = -(origin - distance * normal).dot(slow)
                    print 'Panel %d: distance %.2f origin %.2f %.2f' % \
                      (ipanel, distance, fast_origin, slow_origin)
                print ''
            print ''
            print show_beam(detector, imageset.get_beam())
            if imageset.get_scan() is not None:
                print imageset.get_scan()
            if imageset.get_goniometer() is not None:
                print imageset.get_goniometer()

    from libtbx.containers import OrderedDict, OrderedSet
    formats = OrderedDict([
        ('miller_index', '%i, %i, %i'),
        ('d', '%.2f'),
        ('dqe', '%.3f'),
        ('id', '%i'),
        ('imageset_id', '%i'),
        ('panel', '%i'),
        ('flags', '%i'),
        ('background.mean', '%.1f'),
        ('background.dispersion', '%.1f'),
        ('background.mse', '%.1f'),
        ('background.sum.value', '%.1f'),
        ('background.sum.variance', '%.1f'),
        ('intensity.prf.value', '%.1f'),
        ('intensity.prf.variance', '%.1f'),
        ('intensity.sum.value', '%.1f'),
        ('intensity.sum.variance', '%.1f'),
        ('intensity.cor.value', '%.1f'),
        ('intensity.cor.variance', '%.1f'),
        ('lp', '%.3f'),
        ('num_pixels.background', '%i'),
        ('num_pixels.background_used', '%i'),
        ('num_pixels.foreground', '%i'),
        ('num_pixels.valid', '%i'),
        ('partial_id', '%i'),
        ('partiality', '%.4f'),
        ('profile.correlation', '%.3f'),
        ('profile.rmsd', '%.3f'),
        ('xyzcal.mm', '%.2f, %.2f, %.2f'),
        ('xyzcal.px', '%.2f, %.2f, %.2f'),
        ('delpsical.rad', '%.3f'),
        ('delpsical2', '%.3f'),
        ('delpsical.weights', '%.3f'),
        ('xyzobs.mm.value', '%.2f, %.2f, %.2f'),
        ('xyzobs.mm.variance', '%.4e, %.4e, %.4e'),
        ('xyzobs.px.value', '%.2f, %.2f, %.2f'),
        ('xyzobs.px.variance', '%.4f, %.4f, %.4f'),
        ('s1', '%.4f, %.4f, %.4f'),
        ('rlp', '%.4f, %.4f, %.4f'),
        ('zeta', '%.3f'),
        ('x_resid', '%.3f'),
        ('x_resid2', '%.3f'),
        ('y_resid', '%.3f'),
        ('y_resid2', '%.3f'),
        ('kapton_absorption_correction', '%.3f'),
        ('kapton_absorption_correction_sigmas', '%.3f'),
    ])

    for rlist in reflections:
        from cctbx.array_family import flex
        print
        print "Reflection list contains %i reflections" % (len(rlist))

        if len(rlist) == 0:
            continue

        rows = [["Column", "min", "max", "mean"]]
        for k, col in rlist.cols():
            if type(col) in (flex.double, flex.int, flex.size_t):
                if type(col) in (flex.int, flex.size_t):
                    col = col.as_double()
                rows.append([
                    k, formats[k] % flex.min(col), formats[k] % flex.max(col),
                    formats[k] % flex.mean(col)
                ])
            elif type(col) in (flex.vec3_double, flex.miller_index):
                if type(col) == flex.miller_index:
                    col = col.as_vec3_double()
                rows.append([
                    k, formats[k] % col.min(), formats[k] % col.max(),
                    formats[k] % col.mean()
                ])

        from libtbx import table_utils
        print table_utils.format(rows,
                                 has_header=True,
                                 prefix="| ",
                                 postfix=" |")

    intensity_keys = ('miller_index', 'd', 'intensity.prf.value',
                      'intensity.prf.variance', 'intensity.sum.value',
                      'intensity.sum.variance', 'background.mean',
                      'profile.correlation', 'profile.rmsd')

    profile_fit_keys = (
        'miller_index',
        'd',
    )

    centroid_keys = ('miller_index', 'd', 'xyzcal.mm', 'xyzcal.px',
                     'xyzobs.mm.value', 'xyzobs.mm.variance',
                     'xyzobs.px.value', 'xyzobs.px.variance')

    keys_to_print = OrderedSet()

    if params.show_intensities:
        for k in intensity_keys:
            keys_to_print.add(k)
    if params.show_profile_fit:
        for k in profile_fit_keys:
            keys_to_print.add(k)
    if params.show_centroids:
        for k in centroid_keys:
            keys_to_print.add(k)
    if params.show_all_reflection_data:
        for k in formats:
            keys_to_print.add(k)

    def format_column(key, data, format_strings=None):
        if isinstance(data, flex.vec3_double):
            c_strings = [
                c.as_string(format_strings[i].strip())
                for i, c in enumerate(data.parts())
            ]
        elif isinstance(data, flex.miller_index):
            c_strings = [
                c.as_string(format_strings[i].strip())
                for i, c in enumerate(data.as_vec3_double().parts())
            ]
        elif isinstance(data, flex.size_t):
            c_strings = [data.as_int().as_string(format_strings[0].strip())]
        else:
            c_strings = [data.as_string(format_strings[0].strip())]

        column = flex.std_string()
        max_element_lengths = [c.max_element_length() for c in c_strings]
        for i in range(len(c_strings[0])):

            column.append(('%%%is' % len(key)) % ', '.join(
                ('%%%is' % max_element_lengths[j]) % c_strings[j][i]
                for j in range(len(c_strings))))
        return column

    if keys_to_print:
        keys = [k for k in keys_to_print if k in rlist]
        rows = [keys]
        max_reflections = len(rlist)
        if params.max_reflections is not None:
            max_reflections = min(len(rlist), params.max_reflections)

        columns = []

        for k in keys:
            columns.append(
                format_column(k,
                              rlist[k],
                              format_strings=formats[k].split(',')))

        print
        print "Printing %i of %i reflections:" % (max_reflections, len(rlist))
        for j in range(len(columns)):
            key = keys[j]
            width = max(len(key), columns[j].max_element_length())
            print("%%%is" % width) % key,
        print
        for i in range(max_reflections):
            for j in range(len(columns)):
                print columns[j][i],
            print

    return
Exemplo n.º 38
0
def run(args):
    import libtbx.load_env
    usage = """\
%s datablock.json reflections.pickle [options]""" % libtbx.env.dispatcher_name
    from dials.util.options import OptionParser
    from dials.util.options import flatten_datablocks
    from dials.util.options import flatten_experiments
    from dials.util.options import flatten_reflections
    from scitbx.array_family import flex
    from scitbx import matrix
    from libtbx.utils import Sorry
    parser = OptionParser(usage=usage,
                          phil=master_phil_scope,
                          read_datablocks=True,
                          read_experiments=True,
                          read_reflections=True,
                          check_format=False)

    params, options = parser.parse_args(show_diff_phil=True)
    datablocks = flatten_datablocks(params.input.datablock)
    reflections = flatten_reflections(params.input.reflections)
    experiments = flatten_experiments(params.input.experiments)
    if len(datablocks) == 1:
        imageset = datablocks[0].extract_imagesets()[0]
    elif len(datablocks) > 1:
        raise Sorry("Only one DataBlock can be processed at a time")
    elif len(experiments.imagesets()) > 0:
        imageset = experiments.imagesets()[0]
        imageset.set_detector(experiments[0].detector)
        imageset.set_beam(experiments[0].beam)
        imageset.set_goniometer(experiments[0].goniometer)
    else:
        parser.print_help()
        return

    detector = imageset.get_detector()
    scan = imageset.get_scan()

    panel_origin_shifts = {0: (0, 0, 0)}
    try:
        hierarchy = detector.hierarchy()
    except AttributeError:
        hierarchy = None
    for i_panel in range(1, len(detector)):
        origin_shift = matrix.col(detector[0].get_origin()) \
          - matrix.col(detector[i_panel].get_origin())
        panel_origin_shifts[i_panel] = origin_shift

    observed_xyz = flex.vec3_double()
    predicted_xyz = flex.vec3_double()

    for reflection_list in reflections:

        if len(params.scan_range):
            sel = flex.bool(len(reflection_list), False)

            xyzcal_px = None
            xyzcal_px = None

            if 'xyzcal.px' in reflection_list:
                xyzcal_px = reflection_list['xyzcal.px']
            if 'xyzobs.px.value' in reflection_list:
                xyzobs_px = reflection_list['xyzobs.px.value']

            if xyzcal_px is not None and not xyzcal_px.norms().all_eq(0):
                centroids_frame = xyzcal_px.parts()[2]
            elif xyzobs_px is not None and not xyzobs_px.norms().all_eq(0):
                centroids_frame = xyzobs_px.parts()[2]
            else:
                raise Sorry("No pixel coordinates given in input reflections.")

            reflections_in_range = False
            for scan_range in params.scan_range:
                if scan_range is None: continue
                range_start, range_end = scan_range
                sel |= ((centroids_frame >= range_start) &
                        (centroids_frame < range_end))
            reflection_list = reflection_list.select(sel)
        if params.first_n_reflections is not None:
            centroid_positions = reflection_list.centroid_position()
            centroids_frame = centroid_positions.parts()[2]
            perm = flex.sort_permutation(centroids_frame)
            perm = perm[:min(reflection_list.size(), params.first_n_reflections
                             )]
            reflection_list = reflection_list.select(perm)
        if params.crystal_id is not None:
            reflection_list = reflection_list.select(
                reflection_list['id'] == params.crystal_id)

        xyzcal_px = None
        xyzcal_px = None
        xyzobs_mm = None
        xyzcal_mm = None

        if 'xyzcal.px' in reflection_list:
            xyzcal_px = reflection_list['xyzcal.px']
        if 'xyzobs.px.value' in reflection_list:
            xyzobs_px = reflection_list['xyzobs.px.value']
        if 'xyzcal.mm' in reflection_list:
            xyzcal_mm = reflection_list['xyzcal.mm']
        if 'xyzobs.mm.value' in reflection_list:
            xyzobs_mm = reflection_list['xyzobs.mm.value']

        panel_ids = reflection_list['panel']
        if xyzobs_mm is None and xyzobs_px is not None:
            xyzobs_mm = flex.vec3_double()
            for i_panel in range(len(detector)):
                xyzobs_px_panel = xyzobs_px.select(panel_ids == i_panel)

                from dials.algorithms.centroid import centroid_px_to_mm_panel
                xyzobs_mm_panel, _, _ = centroid_px_to_mm_panel(
                    detector[i_panel], scan, xyzobs_px_panel,
                    flex.vec3_double(xyzobs_px_panel.size()),
                    flex.vec3_double(xyzobs_px_panel.size()))
                xyzobs_mm.extend(xyzobs_mm_panel)

        if xyzobs_mm is not None:
            observed_xyz.extend(xyzobs_mm)
        if xyzcal_mm is not None:
            predicted_xyz.extend(xyzcal_mm)

    obs_x, obs_y, _ = observed_xyz.parts()
    pred_x, pred_y, _ = predicted_xyz.parts()

    try:
        import matplotlib

        if not params.output.show_plot:
            # http://matplotlib.org/faq/howto_faq.html#generate-images-without-having-a-window-appear
            matplotlib.use('Agg')  # use a non-interactive backend
        from matplotlib import pyplot
    except ImportError:
        raise Sorry("matplotlib must be installed to generate a plot.")

    fig = pyplot.figure()
    fig.set_size_inches(params.output.size_inches)
    fig.set_dpi(params.output.dpi)
    pyplot.axes().set_aspect('equal')
    marker_size = params.output.marker_size
    if obs_x.size():
        pyplot.scatter(obs_x,
                       obs_y,
                       marker='o',
                       c='white',
                       s=marker_size,
                       alpha=1)
    if pred_x.size():
        pyplot.scatter(pred_x, pred_y, marker='+', s=marker_size, c='blue')
    #assert len(detector) == 1
    panel = detector[0]
    #if len(detector) > 1:
    xmin = max([
        detector[i_panel].get_image_size_mm()[0] +
        panel_origin_shifts[i_panel][0] for i_panel in range(len(detector))
    ])
    xmax = max([
        detector[i_panel].get_image_size_mm()[0] +
        panel_origin_shifts[i_panel][0] for i_panel in range(len(detector))
    ])
    ymax = max([
        detector[i_panel].get_image_size_mm()[1] +
        panel_origin_shifts[i_panel][1] for i_panel in range(len(detector))
    ])
    ymax = max([
        detector[i_panel].get_image_size_mm()[1] +
        panel_origin_shifts[i_panel][1] for i_panel in range(len(detector))
    ])
    try:
        beam_centre = hierarchy.get_beam_centre(imageset.get_beam().get_s0())
    except Exception:
        beam_centre = detector[0].get_beam_centre(imageset.get_beam().get_s0())
    pyplot.scatter([beam_centre[0]], [beam_centre[1]],
                   marker='+',
                   c='blue',
                   s=100)
    pyplot.xlim(0, xmax)
    pyplot.ylim(0, ymax)
    pyplot.gca().invert_yaxis()
    pyplot.title('Centroid x,y-coordinates')
    pyplot.xlabel('x-coordinate (mm)')
    pyplot.ylabel('y-coordinate (mm)')
    if params.output.file_name is not None:
        pyplot.savefig(params.output.file_name,
                       size_inches=params.output.size_inches,
                       dpi=params.output.dpi,
                       bbox_inches='tight')
    if params.output.show_plot:
        pyplot.show()
Exemplo n.º 39
0
def run(args):

    from dials.util.options import OptionParser
    from dials.util.options import flatten_datablocks
    from dials.util.options import flatten_experiments
    from dials.util.options import flatten_reflections
    from dials.util import log
    import libtbx.load_env

    usage = "%s [options] datablock.json reflections.pickle" % (
        libtbx.env.dispatcher_name)

    parser = OptionParser(usage=usage,
                          phil=phil_scope,
                          read_datablocks=True,
                          read_experiments=True,
                          read_reflections=True,
                          check_format=False,
                          epilog=help_message)

    params, options = parser.parse_args()
    datablocks = flatten_datablocks(params.input.datablock)
    experiments = flatten_experiments(params.input.experiments)
    reflections = flatten_reflections(params.input.reflections)

    if (len(datablocks) == 0
            and len(experiments) == 0) or len(reflections) == 0:
        parser.print_help()
        exit(0)

    # Configure the logging
    log.config(info='dials.rl_png.log')

    # Log the diff phil
    diff_phil = parser.diff_phil.as_str()
    if diff_phil is not '':
        logger.info('The following parameters have been modified:\n')
        logger.info(diff_phil)

    reflections = reflections[0]

    if len(datablocks) == 0 and len(experiments) > 0:
        imagesets = experiments.imagesets()
    else:
        imagesets = []
        for datablock in datablocks:
            imagesets.extend(datablock.extract_imagesets())

    f = ReciprocalLatticePng(settings=params)
    f.load_models(imagesets, reflections, None)

    imageset = imagesets[0]
    rotation_axis = matrix.col(imageset.get_goniometer().get_rotation_axis())
    s0 = matrix.col(imageset.get_beam().get_s0())

    e1 = rotation_axis.normalize()
    e2 = s0.normalize()
    e3 = e1.cross(e2).normalize()
    #print e1
    #print e2
    #print e3

    f.viewer.plot('rl_rotation_axis.png', n=e1.elems)
    f.viewer.plot('rl_beam_vector', n=e2.elems)
    f.viewer.plot('rl_e3.png', n=e3.elems)

    n_solutions = params.basis_vector_search.n_solutions

    if len(experiments):
        for i, c in enumerate(experiments.crystals()):
            A = matrix.sqr(c.get_A())
            astar = A[:3]
            bstar = A[3:6]
            cstar = A[6:9]

            direct_matrix = A.inverse()
            a = direct_matrix[:3]
            b = direct_matrix[3:6]
            c = direct_matrix[6:9]

            prefix = ''
            if len(experiments.crystals()) > 1:
                prefix = '%i_' % (i + 1)

            f.viewer.plot('rl_%sa.png' % prefix, n=a)
            f.viewer.plot('rl_%sb.png' % prefix, n=b)
            f.viewer.plot('rl_%sc.png' % prefix, n=c)

    elif n_solutions:
        from dials.command_line.discover_better_experimental_model \
             import run_dps, dps_phil_scope

        hardcoded_phil = dps_phil_scope.extract()
        hardcoded_phil.d_min = params.d_min

        imageset = imagesets[0]
        from dials.algorithms.indexing.indexer import indexer_base

        if 'imageset_id' not in reflections:
            reflections['imageset_id'] = reflections['id']

        spots_mm = indexer_base.map_spots_pixel_to_mm_rad(
            spots=reflections,
            detector=imageset.get_detector(),
            scan=imageset.get_scan())

        indexer_base.map_centroids_to_reciprocal_space(
            spots_mm,
            detector=imageset.get_detector(),
            beam=imageset.get_beam(),
            goniometer=imageset.get_goniometer())

        if params.d_min is not None:
            d_spacings = 1 / spots_mm['rlp'].norms()
            sel = d_spacings > params.d_min
            spots_mm = spots_mm.select(sel)

        # derive a max_cell from mm spots

        from dials.algorithms.indexing.indexer import find_max_cell
        max_cell = find_max_cell(spots_mm,
                                 max_cell_multiplier=1.3,
                                 step_size=45,
                                 nearest_neighbor_percentile=0.05).max_cell

        result = run_dps((imageset, spots_mm, max_cell, hardcoded_phil))
        solutions = [matrix.col(v) for v in result['solutions']]
        for i in range(min(n_solutions, len(solutions))):
            v = solutions[i]
            #if i > 0:
            #for v1 in solutions[:i-1]:
            #angle = v.angle(v1, deg=True)
            #print angle
            f.viewer.plot('rl_solution_%s.png' % (i + 1), n=v.elems)
Exemplo n.º 40
0
class Script(object):
    """ Encapsulate the script in a class. """
    def __init__(self):
        """ Initialise the script. """
        from dials.util.options import OptionParser

        usage = "usage: dials.create_profile_model [options] models.expt spots.refl"
        self.parser = OptionParser(
            usage=usage,
            epilog=help_message,
            phil=phil_scope,
            read_reflections=True,
            read_experiments=True,
            check_format=False,
        )

    def run(self):
        """ Run the script. """
        from dials.algorithms.profile_model.factory import ProfileModelFactory
        from dials.util.command_line import Command
        from dials.array_family import flex
        from dials.util.options import flatten_reflections, flatten_experiments
        from dials.util import Sorry
        from dials.util import log

        log.config()

        # Parse the command line
        params, options = self.parser.parse_args(show_diff_phil=True)
        reflections = flatten_reflections(params.input.reflections)
        experiments = flatten_experiments(params.input.experiments)
        if len(reflections) == 0 and len(experiments) == 0:
            self.parser.print_help()
            return
        if len(reflections) != 1:
            raise Sorry("exactly 1 reflection table must be specified")
        if len(experiments) == 0:
            raise Sorry("no experiments were specified")
        if ("background.mean"
                not in reflections[0]) and params.subtract_background:
            raise Sorry(
                "for subtract_background need background.mean in reflections")

        reflections, _ = self.process_reference(reflections[0], params)

        # Check pixels don't belong to neighbours
        self.filter_reference_pixels(reflections, experiments)

        # Predict the reflections
        logger.info("")
        logger.info("=" * 80)
        logger.info("")
        logger.info("Predicting reflections")
        logger.info("")
        predicted = flex.reflection_table.from_predictions_multi(
            experiments,
            dmin=params.prediction.d_min,
            dmax=params.prediction.d_max,
            margin=params.prediction.margin,
            force_static=params.prediction.force_static,
            padding=params.prediction.padding,
        )

        # Match with predicted
        matched, reflections, unmatched = predicted.match_with_reference(
            reflections)
        assert len(matched) == len(predicted)
        assert matched.count(True) <= len(reflections)
        if matched.count(True) == 0:
            raise Sorry("""
        Invalid input for reference reflections.
        Zero reference spots were matched to predictions
      """)
        elif len(unmatched) != 0:
            logger.info("")
            logger.info("*" * 80)
            logger.info(
                "Warning: %d reference spots were not matched to predictions" %
                (len(unmatched)))
            logger.info("*" * 80)
            logger.info("")

        # Create the profile model
        experiments = ProfileModelFactory.create(params, experiments,
                                                 reflections)
        for model in experiments:
            sigma_b = model.profile.sigma_b(deg=True)
            sigma_m = model.profile.sigma_m(deg=True)
            if model.profile.is_scan_varying():  # scan varying
                mean_sigma_b = sum(sigma_b) / len(sigma_b)
                mean_sigma_m = sum(sigma_m) / len(sigma_m)
                logger.info("Sigma B: %f", mean_sigma_b)
                logger.info("Sigma M: %f", mean_sigma_m)
            else:
                logger.info("Sigma B: %f", sigma_b)
                logger.info("Sigma M: %f", sigma_m)

        # Write the parameters
        Command.start("Writing experiments to %s" % params.output)
        experiments.as_file(params.output)
        Command.end("Wrote experiments to %s" % params.output)

    def process_reference(self, reference, params):
        """ Load the reference spots. """
        from time import time
        from dials.util import Sorry

        if reference is None:
            return None, None
        st = time()
        assert "miller_index" in reference
        assert "id" in reference
        logger.info("Processing reference reflections")
        logger.info(" read %d strong spots" % len(reference))
        mask = reference.get_flags(reference.flags.indexed)
        rubbish = reference.select(~mask)
        if mask.count(False) > 0:
            reference.del_selected(~mask)
            logger.info(" removing %d unindexed reflections" %
                        mask.count(False))
        if len(reference) == 0:
            raise Sorry("""
        Invalid input for reference reflections.
        Expected > %d indexed spots, got %d
      """ % (0, len(reference)))
        mask = reference.get_flags(reference.flags.centroid_outlier)
        if mask.count(True) > 0:
            rubbish.extend(reference.select(mask))
            reference.del_selected(mask)
            logger.info(
                " removing %d reflections marked as centroid outliers" %
                mask.count(True))
        mask = reference["miller_index"] == (0, 0, 0)
        if mask.count(True) > 0:
            rubbish.extend(reference.select(mask))
            reference.del_selected(mask)
            logger.info(" removing %d reflections with hkl (0,0,0)" %
                        mask.count(True))
        mask = reference["id"] < 0
        if mask.count(True) > 0:
            raise Sorry("""
        Invalid input for reference reflections.
        %d reference spots have an invalid experiment id
      """ % mask.count(True))
        logger.info(" using %d indexed reflections" % len(reference))
        logger.info(" found %d junk reflections" % len(rubbish))

        if "background.mean" in reference and params.subtract_background:
            logger.info(
                " subtracting background from %d reference reflections" %
                len(reference))
            for spot in reference:
                spot["shoebox"].data -= spot["background.mean"]
        logger.info(" time taken: %g" % (time() - st))
        return reference, rubbish

    def filter_reference_pixels(self, reference, experiments):
        """
        Set any pixel closer to other reflections to background

        """
        modified_count = 0
        for experiment, indices in reference.iterate_experiments_and_indices(
                experiments):
            subset = reference.select(indices)
            modified = subset["shoebox"].mask_neighbouring(
                subset["miller_index"],
                experiment.beam,
                experiment.detector,
                experiment.goniometer,
                experiment.scan,
                experiment.crystal,
            )
            modified_count += modified.count(True)
            reference.set_selected(indices, subset)
        logger.info(" masked neighbouring pixels in %d shoeboxes" %
                    modified_count)
        return reference
Exemplo n.º 41
0
def run(args):

  from dials.util.options import OptionParser
  from dials.util.options import flatten_experiments
  from dials.util.options import flatten_reflections
  import libtbx.load_env

  usage = "%s [options] datablock.json" %(
    libtbx.env.dispatcher_name)

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_experiments=True,
    read_reflections=True,
    check_format=True,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=True)
  experiments = flatten_experiments(params.input.experiments)
  reflections = flatten_reflections(params.input.reflections)

  if (len(reflections) == 0 or len(experiments) == 0):
    parser.print_help()
    exit(0)

  reflections = reflections[0]
  assert len(experiments) == 1

  experiment = experiments[0]

  from dials.command_line.check_strategy import filter_shadowed_reflections
  sel = filter_shadowed_reflections(experiments, reflections)
  print "%i/%i (%.2f%%) shadowed reflections" %(
    sel.count(True), sel.size(), 100*sel.count(True)/sel.size())

  if params.negate:
    sel = ~sel
  shadowed = reflections.select(sel)
  shadowed.as_pickle(params.output.reflections)

  if params.output.filter_hkl is not None:

    from rstbx.cftbx.coordinate_frame_helpers import align_reference_frame
    from scitbx import matrix
    detector = experiment.detector

    if len(detector) > 1:
      fast = detector[0].get_parent_fast_axis()
      slow = detector[0].get_parent_slow_axis()
      Rd = align_reference_frame(fast, (1,0,0), slow, (0,1,0))
      origin = Rd * matrix.col(detector[0].get_parent_origin())
    else:
      fast = detector[0].get_fast_axis()
      slow = detector[0].get_slow_axis()
      Rd = align_reference_frame(fast, (1,0,0), slow, (0,1,0))
      origin = Rd * matrix.col(detector[0].get_origin())

    with open(params.output.filter_hkl, 'wb') as f:

      for ref in shadowed:
        p = detector[ref['panel']]
        ox, oy = p.get_raw_image_offset()
        h, k, l = ref['miller_index']
        x, y, z = ref['xyzcal.px']
        dx, dy, dz = (2, 2, 2)
        print >> f, "%i %i %i %.1f %.1f %.1f %.1f %.1f %.1f" %(
          h, k, l, x+ox, y+oy, z, dx, dy, dz)
Exemplo n.º 42
0
class Script(object):
    def __init__(self):
        """Initialise the script."""
        from dials.util.options import OptionParser
        import libtbx.load_env

        # The script usage
        usage = ("usage: %s [options] [param.phil] "
                 "experiments1.expt experiments2.expt reflections1.refl "
                 "reflections2.refl..." % libtbx.env.dispatcher_name)

        # Create the parser
        self.parser = OptionParser(
            usage=usage,
            phil=phil_scope,
            read_reflections=True,
            read_experiments=True,
            check_format=False,
            epilog=help_message,
        )

    def run(self):
        """Execute the script."""
        params, options = self.parser.parse_args(show_diff_phil=True)
        self.run_with_preparsed(params, options)

    def run_with_preparsed(self, params, options):
        """Run combine_experiments, but allow passing in of parameters"""
        from dials.util.options import flatten_experiments

        # Try to load the models and data
        if len(params.input.experiments) == 0:
            print("No Experiments found in the input")
            self.parser.print_help()
            return
        if len(params.input.reflections) == 0:
            print("No reflection data found in the input")
            self.parser.print_help()
            return
        try:
            assert len(params.input.reflections) == len(
                params.input.experiments)
        except AssertionError:
            raise Sorry(
                "The number of input reflections files does not match the "
                "number of input experiments")

        flat_exps = flatten_experiments(params.input.experiments)

        ref_beam = params.reference_from_experiment.beam
        ref_goniometer = params.reference_from_experiment.goniometer
        ref_scan = params.reference_from_experiment.scan
        ref_crystal = params.reference_from_experiment.crystal
        ref_detector = params.reference_from_experiment.detector

        if ref_beam is not None:
            try:
                ref_beam = flat_exps[ref_beam].beam
            except IndexError:
                raise Sorry("{} is not a valid experiment ID".format(ref_beam))

        if ref_goniometer is not None:
            try:
                ref_goniometer = flat_exps[ref_goniometer].goniometer
            except IndexError:
                raise Sorry(
                    "{} is not a valid experiment ID".format(ref_goniometer))

        if ref_scan is not None:
            try:
                ref_scan = flat_exps[ref_scan].scan
            except IndexError:
                raise Sorry("{} is not a valid experiment ID".format(ref_scan))

        if ref_crystal is not None:
            try:
                ref_crystal = flat_exps[ref_crystal].crystal
            except IndexError:
                raise Sorry(
                    "{} is not a valid experiment ID".format(ref_crystal))

        if ref_detector is not None:
            assert not params.reference_from_experiment.average_detector
            try:
                ref_detector = flat_exps[ref_detector].detector
            except IndexError:
                raise Sorry(
                    "{} is not a valid experiment ID".format(ref_detector))
        elif params.reference_from_experiment.average_detector:
            # Average all of the detectors together
            from scitbx.matrix import col

            def average_detectors(target, panelgroups, depth):
                # Recursive function to do the averaging

                if (params.reference_from_experiment.average_hierarchy_level is
                        None or depth == params.reference_from_experiment.
                        average_hierarchy_level):
                    n = len(panelgroups)
                    sum_fast = col((0.0, 0.0, 0.0))
                    sum_slow = col((0.0, 0.0, 0.0))
                    sum_ori = col((0.0, 0.0, 0.0))

                    # Average the d matrix vectors
                    for pg in panelgroups:
                        sum_fast += col(pg.get_local_fast_axis())
                        sum_slow += col(pg.get_local_slow_axis())
                        sum_ori += col(pg.get_local_origin())
                    sum_fast /= n
                    sum_slow /= n
                    sum_ori /= n

                    # Re-orthagonalize the slow and the fast vectors by rotating around the cross product
                    c = sum_fast.cross(sum_slow)
                    a = sum_fast.angle(sum_slow, deg=True) / 2
                    sum_fast = sum_fast.rotate(c, a - 45, deg=True)
                    sum_slow = sum_slow.rotate(c, -(a - 45), deg=True)

                    target.set_local_frame(sum_fast, sum_slow, sum_ori)

                if target.is_group():
                    # Recurse
                    for i, target_pg in enumerate(target):
                        average_detectors(target_pg,
                                          [pg[i] for pg in panelgroups],
                                          depth + 1)

            ref_detector = flat_exps[0].detector
            average_detectors(ref_detector.hierarchy(),
                              [e.detector.hierarchy() for e in flat_exps], 0)

        combine = CombineWithReference(
            beam=ref_beam,
            goniometer=ref_goniometer,
            scan=ref_scan,
            crystal=ref_crystal,
            detector=ref_detector,
            params=params,
        )

        # set up global experiments and reflections lists
        from dials.array_family import flex

        reflections = flex.reflection_table()
        global_id = 0
        skipped_expts = 0
        from dxtbx.model.experiment_list import ExperimentList

        experiments = ExperimentList()

        # loop through the input, building up the global lists
        nrefs_per_exp = []
        for ref_wrapper, exp_wrapper in zip(params.input.reflections,
                                            params.input.experiments):
            refs = ref_wrapper.data
            exps = exp_wrapper.data
            for i, exp in enumerate(exps):
                sel = refs["id"] == i
                sub_ref = refs.select(sel)
                n_sub_ref = len(sub_ref)
                if (params.output.min_reflections_per_experiment is not None
                        and n_sub_ref <
                        params.output.min_reflections_per_experiment):
                    skipped_expts += 1
                    continue

                nrefs_per_exp.append(n_sub_ref)
                sub_ref["id"] = flex.int(len(sub_ref), global_id)
                if params.output.delete_shoeboxes and "shoebox" in sub_ref:
                    del sub_ref["shoebox"]
                reflections.extend(sub_ref)
                try:
                    experiments.append(combine(exp))
                except ComparisonError as e:
                    # When we failed tolerance checks, give a useful error message
                    (path,
                     index) = find_experiment_in(exp, params.input.experiments)
                    raise Sorry(
                        "Model didn't match reference within required tolerance for experiment {} in {}:"
                        "\n{}\nAdjust tolerances or set compare_models=False to ignore differences."
                        .format(index, path, str(e)))

                global_id += 1

        if (params.output.min_reflections_per_experiment is not None
                and skipped_expts > 0):
            print("Removed {0} experiments with fewer than {1} reflections".
                  format(skipped_expts,
                         params.output.min_reflections_per_experiment))

        # print number of reflections per experiment
        from libtbx.table_utils import simple_table

        header = ["Experiment", "Number of reflections"]
        rows = [(str(i), str(n)) for (i, n) in enumerate(nrefs_per_exp)]
        st = simple_table(rows, header)
        print(st.format())

        # save a random subset if requested
        if (params.output.n_subset is not None
                and len(experiments) > params.output.n_subset):
            subset_exp = ExperimentList()
            subset_refls = flex.reflection_table()
            if params.output.n_subset_method == "random":
                n_picked = 0
                indices = list(range(len(experiments)))
                while n_picked < params.output.n_subset:
                    idx = indices.pop(random.randint(0, len(indices) - 1))
                    subset_exp.append(experiments[idx])
                    refls = reflections.select(reflections["id"] == idx)
                    refls["id"] = flex.int(len(refls), n_picked)
                    subset_refls.extend(refls)
                    n_picked += 1
                print(
                    "Selecting a random subset of {0} experiments out of {1} total."
                    .format(params.output.n_subset, len(experiments)))
            elif params.output.n_subset_method == "n_refl":
                if params.output.n_refl_panel_list is None:
                    refls_subset = reflections
                else:
                    sel = flex.bool(len(reflections), False)
                    for p in params.output.n_refl_panel_list:
                        sel |= reflections["panel"] == p
                    refls_subset = reflections.select(sel)
                refl_counts = flex.int()
                for expt_id in range(len(experiments)):
                    refl_counts.append(
                        len(refls_subset.select(
                            refls_subset["id"] == expt_id)))
                sort_order = flex.sort_permutation(refl_counts, reverse=True)
                for expt_id, idx in enumerate(
                        sort_order[:params.output.n_subset]):
                    subset_exp.append(experiments[idx])
                    refls = reflections.select(reflections["id"] == idx)
                    refls["id"] = flex.int(len(refls), expt_id)
                    subset_refls.extend(refls)
                print(
                    "Selecting a subset of {0} experiments with highest number of reflections out of {1} total."
                    .format(params.output.n_subset, len(experiments)))

            elif params.output.n_subset_method == "significance_filter":
                from dials.algorithms.integration.stills_significance_filter import (
                    SignificanceFilter, )

                params.output.significance_filter.enable = True
                sig_filter = SignificanceFilter(params.output)
                refls_subset = sig_filter(experiments, reflections)
                refl_counts = flex.int()
                for expt_id in range(len(experiments)):
                    refl_counts.append(
                        len(refls_subset.select(
                            refls_subset["id"] == expt_id)))
                sort_order = flex.sort_permutation(refl_counts, reverse=True)
                for expt_id, idx in enumerate(
                        sort_order[:params.output.n_subset]):
                    subset_exp.append(experiments[idx])
                    refls = reflections.select(reflections["id"] == idx)
                    refls["id"] = flex.int(len(refls), expt_id)
                    subset_refls.extend(refls)

            experiments = subset_exp
            reflections = subset_refls

        def save_in_batches(experiments,
                            reflections,
                            exp_name,
                            refl_name,
                            batch_size=1000):
            from dxtbx.command_line.image_average import splitit

            for i, indices in enumerate(
                    splitit(list(range(len(experiments))),
                            (len(experiments) // batch_size) + 1)):
                batch_expts = ExperimentList()
                batch_refls = flex.reflection_table()
                for sub_id, sub_idx in enumerate(indices):
                    batch_expts.append(experiments[sub_idx])
                    sub_refls = reflections.select(
                        reflections["id"] == sub_idx)
                    sub_refls["id"] = flex.int(len(sub_refls), sub_id)
                    batch_refls.extend(sub_refls)
                exp_filename = os.path.splitext(exp_name)[0] + "_%03d.expt" % i
                ref_filename = os.path.splitext(
                    refl_name)[0] + "_%03d.refl" % i
                self._save_output(batch_expts, batch_refls, exp_filename,
                                  ref_filename)

        def combine_in_clusters(experiments_l, reflections_l, exp_name,
                                refl_name, end_count):
            result = []
            for cluster, experiment in enumerate(experiments_l):
                cluster_expts = ExperimentList()
                cluster_refls = flex.reflection_table()
                for i, expts in enumerate(experiment):
                    refls = reflections_l[cluster][i]
                    refls["id"] = flex.int(len(refls), i)
                    cluster_expts.append(expts)
                    cluster_refls.extend(refls)
                exp_filename = os.path.splitext(exp_name)[0] + (
                    "_cluster%d.expt" % (end_count - cluster))
                ref_filename = os.path.splitext(refl_name)[0] + (
                    "_cluster%d.refl" % (end_count - cluster))
                result.append(
                    (cluster_expts, cluster_refls, exp_filename, ref_filename))
            return result

        # cluster the resulting experiments if requested
        if params.clustering.use:
            clustered = Cluster(
                experiments,
                reflections,
                dendrogram=params.clustering.dendrogram,
                threshold=params.clustering.threshold,
                n_max=params.clustering.max_crystals,
            )
            n_clusters = len(clustered.clustered_frames)

            def not_too_many(keeps):
                if params.clustering.max_clusters is not None:
                    return len(keeps) < params.clustering.max_clusters
                return True

            keep_frames = []
            sorted_keys = sorted(clustered.clustered_frames.keys())
            while len(clustered.clustered_frames) > 0 and not_too_many(
                    keep_frames):
                keep_frames.append(
                    clustered.clustered_frames.pop(sorted_keys.pop(-1)))
            if params.clustering.exclude_single_crystal_clusters:
                keep_frames = [k for k in keep_frames if len(k) > 1]
            clustered_experiments = [[f.experiment for f in frame_cluster]
                                     for frame_cluster in keep_frames]
            clustered_reflections = [[f.reflections for f in frame_cluster]
                                     for frame_cluster in keep_frames]
            list_of_combined = combine_in_clusters(
                clustered_experiments,
                clustered_reflections,
                params.output.experiments_filename,
                params.output.reflections_filename,
                n_clusters,
            )
            for saveable_tuple in list_of_combined:
                if params.output.max_batch_size is None:
                    self._save_output(*saveable_tuple)
                else:
                    save_in_batches(*saveable_tuple,
                                    batch_size=params.output.max_batch_size)
        else:
            if params.output.max_batch_size is None:
                self._save_output(
                    experiments,
                    reflections,
                    params.output.experiments_filename,
                    params.output.reflections_filename,
                )
            else:
                save_in_batches(
                    experiments,
                    reflections,
                    params.output.experiments_filename,
                    params.output.reflections_filename,
                    batch_size=params.output.max_batch_size,
                )
        return

    def _save_output(self, experiments, reflections, exp_name, refl_name):
        # save output

        print("Saving combined experiments to {}".format(exp_name))
        experiments.as_file(exp_name)
        print("Saving combined reflections to {}".format(refl_name))
        reflections.as_file(refl_name)
Exemplo n.º 43
0
class Script(object):
    """A class for running the script."""
    def __init__(self):
        """Initialise the script."""
        from dials.util.options import OptionParser
        import libtbx.load_env

        # The script usage
        usage = (
            "usage: %s [options] experiment_one.expt experiment_two.expt" %
            libtbx.env.dispatcher_name)

        # Create the parser
        self.parser = OptionParser(
            usage=usage,
            phil=phil_scope,
            epilog=help_message,
            check_format=False,
            read_experiments=True,
        )

    def run(self):
        """Execute the script."""
        from dials.util.options import flatten_experiments

        # Parse the command line
        params, options = self.parser.parse_args(show_diff_phil=True)

        # Check the number of experiments is at least 2
        experiments = flatten_experiments(params.input.experiments)
        if len(experiments) < 2:
            self.parser.print_help()
            return

        detectors = [experiment.detector[0] for experiment in experiments]

        from itertools import combinations

        for pair in combinations(detectors, 2):
            determine_axis(pair, params)

        from scitbx import matrix
        from scitbx.math import r3_rotation_axis_and_angle_from_matrix

        crystals = [experiment.crystal for experiment in experiments]
        goniometers = [experiment.goniometer for experiment in experiments]

        FUs = []

        for c, g in zip(crystals, goniometers):
            u = matrix.sqr(c.get_U())
            f = matrix.sqr(g.get_fixed_rotation())
            FUs.append(f * u)

        for pair in combinations(FUs, 2):
            R = pair[1] * pair[0].inverse()
            rot = r3_rotation_axis_and_angle_from_matrix(R)
            angle = rot.angle(deg=True)
            axis = matrix.col(rot.axis)
            if abs(angle) < 10:
                continue
            print("Axis: %8.5f %8.5f %8.5f" % axis.elems,
                  "angle: %7.4f" % angle)
Exemplo n.º 44
0
def run(args=None):
    usage = "dials.align_crystal [options] models.expt"
    parser = OptionParser(
        usage=usage,
        phil=phil_scope,
        read_experiments=True,
        check_format=False,
        epilog=help_message,
    )

    params, options = parser.parse_args(args, show_diff_phil=True)
    experiments = flatten_experiments(params.input.experiments)

    if len(experiments) == 0:
        parser.print_help()
        exit(0)

    expt = experiments[0]

    if params.space_group is not None:
        expt.crystal.set_space_group(params.space_group.group())

    if len(params.align.crystal.vector):
        frame = None
        assert len(params.align.crystal.vector) % 2 == 0
        vectors = []

        name_to_vectors = {
            "a": (a, "direct"),
            "b": (b, "direct"),
            "c": (c, "direct"),
            "a*": (a_star, "reciprocal"),
            "b*": (b_star, "reciprocal"),
            "c*": (c_star, "reciprocal"),
        }

        for v in params.align.crystal.vector:
            v = v.strip()
            if v in name_to_vectors:
                v, frame_ = name_to_vectors[v]
                assert frame is None or frame == frame_
                frame = frame_
            else:
                v = v.replace(",", " ").strip().split()
                assert len(v) == 3
                v = matrix.col([float(v_) for v_ in v])
                if frame is None:
                    frame = params.align.crystal.frame

            vectors.append(v)
        vectors = [
            (vectors[2 * i], vectors[2 * i + 1]) for i in range(len(vectors) // 2)
        ]
    elif params.align.crystal.frame == "direct":
        frame = params.align.crystal.frame
        vectors = ((a, b), (a, c), (b, a), (b, c), (c, a), (c, b))

    else:
        frame = "reciprocal"
        vectors = (
            (a_star, b_star),  # a*, b*
            (a_star, c_star),  # a*, c*
            (b_star, a_star),  # b*, a*
            (b_star, c_star),  # b*, c*
            (c_star, a_star),  # c*, a*
            (c_star, b_star),  # c*, b*
        )

    try:
        result = align_crystal(expt, vectors, frame=frame, mode=params.align.mode)
        print(result)
    except ValueError as e:
        sys.exit(e)
    if params.output.json is not None:
        result.as_json(filename=params.output.json)
Exemplo n.º 45
0
def run(args=None):
    usage = "dials.spot_counts_per_image [options] imported.expt strong.refl"

    parser = OptionParser(
        usage=usage,
        read_reflections=True,
        read_experiments=True,
        phil=phil_scope,
        check_format=False,
        epilog=help_message,
    )

    params, options = parser.parse_args(args, show_diff_phil=False)
    reflections, experiments = reflections_and_experiments_from_files(
        params.input.reflections, params.input.experiments)

    if not reflections and not experiments:
        parser.print_help()
        return

    # FIXME may want to change this to allow many to be passed i.e.
    # from parallel runs
    if len(reflections) != 1:
        sys.exit("Only one reflection list may be passed")
    reflections = reflections[0]

    reflections.centroid_px_to_mm(experiments)
    reflections.map_centroids_to_reciprocal_space(experiments)

    if params.id is not None:
        reflections = reflections.select(reflections["id"] == params.id)

    all_stats = []
    for i, expt in enumerate(experiments):
        refl = reflections.select(reflections["id"] == i)
        stats = per_image_analysis.stats_per_image(
            expt, refl, resolution_analysis=params.resolution_analysis)
        all_stats.append(stats)

    # transpose stats
    summary_table = {}
    for s in all_stats:
        for k, value in s._asdict().items():
            summary_table.setdefault(k, [])
            summary_table[k].extend(value)
    stats = per_image_analysis.StatsMultiImage(**summary_table)
    print(stats)

    overall_stats = per_image_analysis.stats_for_reflection_table(
        reflections, resolution_analysis=params.resolution_analysis)
    rows = [
        ("Overall statistics", ""),
        ("#spots", "%i" % overall_stats.n_spots_total),
        ("#spots_no_ice", "%i" % overall_stats.n_spots_no_ice),
        ("d_min", f"{overall_stats.estimated_d_min:.2f}"),
        (
            "d_min (distl method 1)",
            "%.2f (%.2f)" % (overall_stats.d_min_distl_method_1,
                             overall_stats.noisiness_method_1),
        ),
        (
            "d_min (distl method 2)",
            "%.2f (%.2f)" % (overall_stats.d_min_distl_method_2,
                             overall_stats.noisiness_method_2),
        ),
    ]
    print(tabulate(rows, headers="firstrow"))

    if params.json:
        if params.split_json:
            for k, v in stats._asdict().items():
                start, end = params.json.split(".")
                with open(f"{start}_{k}.{end}", "w") as fp:
                    json.dump(v, fp)
        if params.joint_json:
            with open(params.json, "w") as fp:
                json.dump(stats._asdict(), fp)
    if params.plot:
        import matplotlib

        matplotlib.use("Agg")
        per_image_analysis.plot_stats(stats, filename=params.plot)
Exemplo n.º 46
0
class Script(object):
    def __init__(self):
        """Initialise the script."""

        # The script usage
        usage = (
            "usage: dials.rs_mapper map_file=output.ccp4 [max_resolution=6] [grid_size=192] "
            "[reverse_phi=False] [param.phil] "
            "{image1.file [image2.file ...]} | imported.expt")

        # Initialise the base class
        self.parser = OptionParser(usage=usage,
                                   phil=phil_scope,
                                   epilog=help_message,
                                   read_experiments=True)

    def run(self):
        # Parse the command line
        params, options = self.parser.parse_args(show_diff_phil=True)

        if not params.rs_mapper.map_file:
            raise RuntimeError("Please specify output map file (map_file=)")
        else:
            self.map_file = params.rs_mapper.map_file

        # Ensure we have either a data block or an experiment list
        self.experiments = flatten_experiments(params.input.experiments)
        if len(self.experiments) != 1:
            self.parser.print_help()
            print("Please pass either an experiment list\n")
            return

        self.reverse_phi = params.rs_mapper.reverse_phi
        self.grid_size = params.rs_mapper.grid_size
        self.max_resolution = params.rs_mapper.max_resolution
        self.ignore_mask = params.rs_mapper.ignore_mask

        self.grid = flex.double(
            flex.grid(self.grid_size, self.grid_size, self.grid_size), 0)
        self.counts = flex.int(
            flex.grid(self.grid_size, self.grid_size, self.grid_size), 0)

        for experiment in self.experiments:
            self.process_imageset(experiment.imageset)

        recviewer.normalize_voxels(self.grid, self.counts)

        # Let's use 1/(100A) as the unit so that the absolute numbers in the
        # "cell dimensions" field of the ccp4 map are typical for normal
        # MX maps. The values in 1/A would give the "cell dimensions" around
        # or below 1 and some MX programs would not handle it well.
        box_size = 100 * 2.0 / self.max_resolution
        uc = uctbx.unit_cell((box_size, box_size, box_size, 90, 90, 90))
        ccp4_map.write_ccp4_map(
            self.map_file,
            uc,
            sgtbx.space_group("P1"),
            (0, 0, 0),
            self.grid.all(),
            self.grid,
            flex.std_string(["cctbx.miller.fft_map"]),
        )

    def process_imageset(self, imageset):
        rec_range = 1 / self.max_resolution

        if len(imageset.get_detector()) != 1:
            raise Sorry("This program does not support multi-panel detectors.")

        panel = imageset.get_detector()[0]
        beam = imageset.get_beam()
        s0 = beam.get_s0()
        pixel_size = panel.get_pixel_size()
        xlim, ylim = imageset.get_raw_data(0)[0].all()
        if pixel_size[0] != pixel_size[1]:
            raise Sorry("This program does not support non-square pixels.")

        # cache transformation
        xy = recviewer.get_target_pixels(panel, s0, xlim, ylim,
                                         self.max_resolution)
        s1 = panel.get_lab_coord(xy * pixel_size[0])
        s1 = s1 / s1.norms() * (1 / beam.get_wavelength())
        S = s1 - s0

        for i in range(len(imageset)):
            axis = imageset.get_goniometer().get_rotation_axis()
            osc_range = imageset.get_scan(i).get_oscillation_range()
            print("Oscillation range: %.2f - %.2f" %
                  (osc_range[0], osc_range[1]))
            angle = (osc_range[0] + osc_range[1]) / 2 / 180 * math.pi
            if not self.reverse_phi:
                # the pixel is in S AFTER rotation. Thus we have to rotate BACK.
                angle *= -1
            rotated_S = S.rotate_around_origin(axis, angle)

            data = imageset.get_raw_data(i)[0]
            if not self.ignore_mask:
                mask = imageset.get_mask(i)[0]
                data.set_selected(~mask, 0)

            recviewer.fill_voxels(data, self.grid, self.counts, rotated_S, xy,
                                  rec_range)
Exemplo n.º 47
0
def run(args):
    from dials.util import log
    from dials.util.options import OptionParser, reflections_and_experiments_from_files

    usage = "dials.detect_blanks [options] models.expt observations.refl"

    parser = OptionParser(
        usage=usage,
        phil=phil_scope,
        read_experiments=True,
        read_reflections=True,
        check_format=False,
        epilog=help_message,
    )

    params, options = parser.parse_args(args)
    reflections, experiments = reflections_and_experiments_from_files(
        params.input.reflections, params.input.experiments)

    if len(experiments) == 0 or len(reflections) == 0:
        parser.print_help()
        exit(0)

    # Configure the logging
    log.config(logfile="dials.detect_blanks.log")

    # Log the diff phil
    diff_phil = parser.diff_phil.as_str()
    if diff_phil != "":
        logger.info("The following parameters have been modified:\n")
        logger.info(diff_phil)

    reflections = reflections[0]

    imagesets = experiments.imagesets()

    if any(experiment.is_still() for experiment in experiments):
        sys.exit("dials.detect_blanks can only be used with rotation data")

    assert len(imagesets) == 1
    imageset = imagesets[0]
    scan = imageset.get_scan()

    integrated_sel = reflections.get_flags(reflections.flags.integrated)
    indexed_sel = reflections.get_flags(reflections.flags.indexed)
    centroid_outlier_sel = reflections.get_flags(
        reflections.flags.centroid_outlier)
    strong_sel = reflections.get_flags(reflections.flags.strong)
    indexed_sel &= ~centroid_outlier_sel

    logger.info(f"Analysis of {strong_sel.count(True)} strong reflections:")
    strong_results = detect_blanks.blank_counts_analysis(
        reflections.select(strong_sel),
        scan,
        phi_step=params.phi_step,
        fractional_loss=params.counts_fractional_loss,
    )
    for blank_start, blank_end in strong_results["blank_regions"]:
        logger.info(
            f"Potential blank images: {blank_start + 1} -> {blank_end}")

    indexed_results = None
    if indexed_sel.count(True) > 0:
        logger.info(
            f"Analysis of {indexed_sel.count(True)} indexed reflections:")
        indexed_results = detect_blanks.blank_counts_analysis(
            reflections.select(indexed_sel),
            scan,
            phi_step=params.phi_step,
            fractional_loss=params.counts_fractional_loss,
        )
        for blank_start, blank_end in indexed_results["blank_regions"]:
            logger.info(
                f"Potential blank images: {blank_start + 1} -> {blank_end}")

    integrated_results = None
    if integrated_sel.count(True) > 0:
        logger.info(
            f"Analysis of {integrated_sel.count(True)} integrated reflections:"
        )
        integrated_results = detect_blanks.blank_integrated_analysis(
            reflections.select(integrated_sel),
            scan,
            phi_step=params.phi_step,
            fractional_loss=params.misigma_fractional_loss,
        )
        for blank_start, blank_end in integrated_results["blank_regions"]:
            logger.info(
                f"Potential blank images: {blank_start + 1} -> {blank_end}")

    d = {
        "strong": strong_results,
        "indexed": indexed_results,
        "integrated": integrated_results,
    }

    if params.output.json is not None:
        with open(params.output.json, "w") as fh:
            json.dump(d, fh)

    if params.output.plot:
        from matplotlib import pyplot

        plots = [(strong_results, "-")]
        if indexed_results:
            plots.append((indexed_results, "--"))
        if integrated_results:
            plots.append((integrated_results, ":"))

        for results, linestyle in plots:
            xs = results["data"][0]["x"]
            ys = results["data"][0]["y"]
            xmax = max(xs)
            ymax = max(ys)
            xs = [x / xmax for x in xs]
            ys = [y / ymax for y in ys]
            blanks = results["data"][0]["blank"]
            pyplot.plot(xs, ys, color="blue", linestyle=linestyle)
            pyplot.plot(
                *zip(*[(x, y) for x, y, blank in zip(xs, ys, blanks)
                       if blank]),
                color="red",
                linestyle=linestyle,
            )
        pyplot.ylim(0)
        pyplot.show()
        pyplot.clf()
Exemplo n.º 48
0
class Script(object):
    """A class for running the script."""

    def __init__(self):
        """Initialise the script."""
        # The script usage
        usage = (
            "usage: dials.two_theta_refine [options] [param.phil] "
            "models.expt observations.refl"
        )

        # Create the parser
        self.parser = OptionParser(
            usage=usage,
            phil=working_phil,
            read_reflections=True,
            read_experiments=True,
            check_format=False,
            epilog=help_message,
        )

    @staticmethod
    def check_input(reflections):
        """Check the input is suitable for refinement. So far just check keys in
        the reflection table. Maybe later check experiments have overlapping models
        etc."""

        msg = (
            "The supplied reflection table does not have the required data "
            + "column: {0}"
        )
        for key in ["xyzobs.mm.value", "xyzobs.mm.variance"]:
            if key not in reflections:
                msg = msg.format(key)
                sys.exit(msg)

        # FIXME add other things to be checked here
        return

    @staticmethod
    def combine_crystals(experiments):
        """Replace all crystals in the experiments list with the first crystal"""

        new_experiments = ExperimentList()
        ref_crystal = experiments[0].crystal
        for exp in experiments:
            new_experiments.append(
                Experiment(
                    beam=exp.beam,
                    detector=exp.detector,
                    scan=exp.scan,
                    goniometer=exp.goniometer,
                    crystal=ref_crystal,
                    imageset=exp.imageset,
                    identifier=exp.identifier,
                )
            )
        return new_experiments

    @staticmethod
    def filter_integrated_centroids(reflections):
        """Filter reflections to include only those with the integrated and the
        strong flag set, but only if there are apparently some integrated
        reflections"""

        orig_len = len(reflections)
        mask = reflections.get_flags(reflections.flags.integrated)
        if mask.count(True) == 0:
            return reflections
        reflections = reflections.select(mask)
        mask = reflections.get_flags(reflections.flags.strong)
        reflections = reflections.select(mask)

        logger.info(
            "{0} out of {1} reflections remain after filtering to keep only strong"
            " and integrated centroids".format(len(reflections), orig_len)
        )
        return reflections

    @staticmethod
    def convert_to_P1(reflections, experiments):
        """Convert the input crystals to P 1 and reindex the reflections"""
        for iexp, exp in enumerate(experiments):
            sel = reflections["id"] == iexp
            xl = exp.crystal
            sg = xl.get_space_group()
            op = sg.info().change_of_basis_op_to_primitive_setting()
            exp.crystal = xl.change_basis(op)
            exp.crystal.set_space_group(sgtbx.space_group("P 1"))
            hkl_reindexed = op.apply(reflections["miller_index"].select(sel))
            reflections["miller_index"].set_selected(sel, hkl_reindexed)
        return reflections, experiments

    @staticmethod
    def create_refiner(params, reflections, experiments):
        # Only parameterise the crystal unit cell
        det_params = None
        beam_params = None
        xlo_params = None
        xluc_params = []
        for crystal in experiments.crystals():
            exp_ids = experiments.indices(crystal)
            xluc_params.append(
                CrystalUnitCellParameterisation(crystal, experiment_ids=exp_ids)
            )

        # Two theta prediction equation parameterisation
        pred_param = TwoThetaPredictionParameterisation(
            experiments, det_params, beam_params, xlo_params, xluc_params
        )
        param_reporter = ParameterReporter(
            det_params, beam_params, xlo_params, xluc_params
        )

        # ReflectionManager, currently without outlier rejection
        # Note: If not all reflections are used, then the filtering must be
        # communicated to generate_cif/mmcif() to be included in the CIF file!
        refman = TwoThetaReflectionManager(
            reflections, experiments, outlier_detector=None
        )

        # Reflection predictor
        ref_predictor = TwoThetaExperimentsPredictor(experiments)

        # Two theta target
        target = TwoThetaTarget(experiments, ref_predictor, refman, pred_param)

        # Switch on correlation matrix tracking if a correlation plot is requested
        journal = None
        if params.output.correlation_plot.filename is not None:
            journal = refinery_phil_scope.extract().refinery.journal
            journal.track_parameter_correlation = True

        # Minimisation engine - hardcoded to LevMar for now.
        refinery = Refinery(
            target=target,
            prediction_parameterisation=pred_param,
            log=None,
            tracking=journal,
            max_iterations=20,
        )

        # Refiner
        refiner = Refiner(
            experiments=experiments,
            pred_param=pred_param,
            param_reporter=param_reporter,
            refman=refman,
            target=target,
            refinery=refinery,
        )

        return refiner

    @staticmethod
    def cell_param_table(crystal):
        """Construct a table of cell parameters and their ESDs"""

        cell = crystal.get_unit_cell().parameters()
        esd = crystal.get_cell_parameter_sd()
        vol = crystal.get_unit_cell().volume()
        vol_esd = crystal.get_cell_volume_sd()
        header = ["Parameter", "Value", "Estimated sd"]
        rows = []
        names = ["a", "b", "c", "alpha", "beta", "gamma"]
        for n, p, e in zip(names, cell, esd):
            rows.append([n, "%9.5f" % p, "%9.5f" % e])
        rows.append(["\nvolume", "\n%9.5f" % vol, "\n%9.5f" % vol_esd])
        return tabulate(rows, header)

    @staticmethod
    def generate_p4p(crystal, beam, filename):
        logger.info("Saving P4P info to %s", filename)
        cell = crystal.get_unit_cell().parameters()
        esd = crystal.get_cell_parameter_sd()
        vol = crystal.get_unit_cell().volume()
        vol_esd = crystal.get_cell_volume_sd()

        open(filename, "w").write(
            "\n".join(
                [
                    "TITLE    Auto-generated .p4p file from dials.two_theta_refine",
                    "CELL     %.4f %.4f %.4f %.4f %.4f %.4f %.4f"
                    % tuple(cell + (vol,)),
                    "CELLSD   %.4f %.4f %.4f %.4f %.4f %.4f %.4f"
                    % tuple(esd + (vol_esd,)),
                    "SOURCE   SYNCH   %.6f" % beam.get_wavelength(),
                    "",
                ]
            )
        )
        return

    @staticmethod
    def generate_cif(crystal, refiner, filename):
        logger.info("Saving CIF information to %s", filename)

        block = iotbx.cif.model.block()
        block["_audit_creation_method"] = dials_version()
        block["_audit_creation_date"] = datetime.date.today().isoformat()
        #   block["_publ_section_references"] = '' # once there is a reference...

        for cell, esd, cifname in zip(
            crystal.get_unit_cell().parameters(),
            crystal.get_cell_parameter_sd(),
            [
                "length_a",
                "length_b",
                "length_c",
                "angle_alpha",
                "angle_beta",
                "angle_gamma",
            ],
        ):
            block["_cell_%s" % cifname] = format_float_with_standard_uncertainty(
                cell, esd
            )
        block["_cell_volume"] = format_float_with_standard_uncertainty(
            crystal.get_unit_cell().volume(), crystal.get_cell_volume_sd()
        )

        used_reflections = refiner.get_matches()
        block["_cell_measurement_reflns_used"] = len(used_reflections)
        block["_cell_measurement_theta_min"] = (
            flex.min(used_reflections["2theta_obs.rad"]) * 180 / math.pi / 2
        )
        block["_cell_measurement_theta_max"] = (
            flex.max(used_reflections["2theta_obs.rad"]) * 180 / math.pi / 2
        )
        block["_diffrn_reflns_number"] = len(used_reflections)
        miller_span = miller.index_span(used_reflections["miller_index"])
        min_h, min_k, min_l = miller_span.min()
        max_h, max_k, max_l = miller_span.max()
        block["_diffrn_reflns_limit_h_min"] = min_h
        block["_diffrn_reflns_limit_h_max"] = max_h
        block["_diffrn_reflns_limit_k_min"] = min_k
        block["_diffrn_reflns_limit_k_max"] = max_k
        block["_diffrn_reflns_limit_l_min"] = min_l
        block["_diffrn_reflns_limit_l_max"] = max_l
        block["_diffrn_reflns_theta_min"] = (
            flex.min(used_reflections["2theta_obs.rad"]) * 180 / math.pi / 2
        )
        block["_diffrn_reflns_theta_max"] = (
            flex.max(used_reflections["2theta_obs.rad"]) * 180 / math.pi / 2
        )

        cif = iotbx.cif.model.cif()
        cif["two_theta_refine"] = block
        with open(filename, "w") as fh:
            cif.show(out=fh)

    @staticmethod
    def generate_mmcif(crystal, refiner, filename):
        logger.info("Saving mmCIF information to %s", filename)

        block = iotbx.cif.model.block()
        block["_audit.creation_method"] = dials_version()
        block["_audit.creation_date"] = datetime.date.today().isoformat()
        #   block["_publ.section_references"] = '' # once there is a reference...

        for cell, esd, cifname in zip(
            crystal.get_unit_cell().parameters(),
            crystal.get_cell_parameter_sd(),
            [
                "length_a",
                "length_b",
                "length_c",
                "angle_alpha",
                "angle_beta",
                "angle_gamma",
            ],
        ):
            block["_cell.%s" % cifname] = "%.8f" % cell
            block["_cell.%s_esd" % cifname] = "%.8f" % esd
        block["_cell.volume"] = "%f" % crystal.get_unit_cell().volume()
        block["_cell.volume_esd"] = "%f" % crystal.get_cell_volume_sd()

        used_reflections = refiner.get_matches()
        block["_cell_measurement.reflns_used"] = len(used_reflections)
        block["_cell_measurement.theta_min"] = (
            flex.min(used_reflections["2theta_obs.rad"]) * 180 / math.pi / 2
        )
        block["_cell_measurement.theta_max"] = (
            flex.max(used_reflections["2theta_obs.rad"]) * 180 / math.pi / 2
        )
        block["_diffrn_reflns.number"] = len(used_reflections)
        miller_span = miller.index_span(used_reflections["miller_index"])
        min_h, min_k, min_l = miller_span.min()
        max_h, max_k, max_l = miller_span.max()
        block["_diffrn_reflns.limit_h_min"] = min_h
        block["_diffrn_reflns.limit_h_max"] = max_h
        block["_diffrn_reflns.limit_k_min"] = min_k
        block["_diffrn_reflns.limit_k_max"] = max_k
        block["_diffrn_reflns.limit_l_min"] = min_l
        block["_diffrn_reflns.limit_l_max"] = max_l
        block["_diffrn_reflns.theta_min"] = (
            flex.min(used_reflections["2theta_obs.rad"]) * 180 / math.pi / 2
        )
        block["_diffrn_reflns.theta_max"] = (
            flex.max(used_reflections["2theta_obs.rad"]) * 180 / math.pi / 2
        )

        cif = iotbx.cif.model.cif()
        cif["two_theta_refine"] = block
        with open(filename, "w") as fh:
            cif.show(out=fh)

    def run(self):
        """Execute the script."""

        # Parse the command line
        params, _ = self.parser.parse_args(show_diff_phil=False)

        # set up global reflections list
        reflections = flex.reflection_table()

        # loop through the input, building up the global lists
        reflections_list, input_experiments = reflections_and_experiments_from_files(
            params.input.reflections, params.input.experiments
        )

        experiments = copy.deepcopy(input_experiments)
        reflections_list = parse_multiple_datasets(reflections_list)
        for refs in reflections_list:
            reflections.extend(refs)

        # Try to load the models and data
        nexp = len(experiments)
        if nexp == 0:
            print("No Experiments found in the input")
            self.parser.print_help()
            return
        if not reflections:
            print("No reflection data found in the input")
            self.parser.print_help()
            return

        self.check_input(reflections)

        # Configure the logging
        log.config(logfile=params.output.log)
        logger.info(dials_version())

        # Log the diff phil
        diff_phil = self.parser.diff_phil.as_str()
        if diff_phil != "":
            logger.info("The following parameters have been modified:\n")
            logger.info(diff_phil)

        # Convert to P 1?
        if params.refinement.triclinic:
            reflections, experiments = self.convert_to_P1(reflections, experiments)

        # Combine crystals?
        if params.refinement.combine_crystal_models and len(experiments) > 1:
            logger.info("Combining {0} crystal models".format(len(experiments)))
            experiments = self.combine_crystals(experiments)

        # Filter integrated centroids?
        if params.refinement.filter_integrated_centroids:
            reflections = self.filter_integrated_centroids(reflections)

        # Filter data if scaled to remove outliers
        if "inverse_scale_factor" in reflections:
            try:
                reflections = filter_reflection_table(reflections, ["scale"])
            except ValueError as e:
                logger.warn(e)
                logger.info(
                    "Filtering on scaled data failed, proceeding with integrated data."
                )

        # Get the refiner
        logger.info("Configuring refiner")
        refiner = self.create_refiner(params, reflections, experiments)

        # Refine the geometry
        if nexp == 1:
            logger.info("Performing refinement of a single Experiment...")
        else:
            logger.info("Performing refinement of {} Experiments...".format(nexp))
        refiner.run()

        # get the refined experiments
        experiments = copy.deepcopy(input_experiments)
        for expt, refined_expt in zip(experiments, refiner.get_experiments()):
            expt.crystal.set_recalculated_unit_cell(
                refined_expt.crystal.get_unit_cell()
            )
            expt.crystal.set_recalculated_cell_parameter_sd(
                refined_expt.crystal.get_cell_parameter_sd()
            )
            expt.crystal.set_recalculated_cell_volume_sd(
                refined_expt.crystal.get_cell_volume_sd()
            )
        crystals = refiner.get_experiments().crystals()

        if len(crystals) == 1:
            # output the refined model for information
            logger.info("")
            logger.info("Final refined crystal model:")
            logger.info(crystals[0])
            logger.info(self.cell_param_table(crystals[0]))

        # Save the refined experiments to file
        output_experiments_filename = params.output.experiments
        logger.info(
            "Saving refined experiments to {}".format(output_experiments_filename)
        )
        experiments.as_file(output_experiments_filename)

        # Create correlation plots
        if params.output.correlation_plot.filename is not None:
            create_correlation_plots(refiner, params.output)

        if params.output.cif is not None:
            self.generate_cif(crystals[0], refiner, filename=params.output.cif)

        if params.output.p4p is not None:
            self.generate_p4p(
                crystals[0], experiments[0].beam, filename=params.output.p4p
            )

        if params.output.mmcif is not None:
            self.generate_mmcif(crystals[0], refiner, filename=params.output.mmcif)
Exemplo n.º 49
0
class Script(object):
    """A class for running the script."""
    def __init__(self):
        """Initialise the script."""
        # The script usage
        usage = "usage: dials.complete_full_sphere [options] "

        # Create the parser
        self.parser = OptionParser(
            usage=usage,
            phil=phil_scope,
            epilog=help_message,
            check_format=True,
            read_experiments=True,
        )

    def run(self, args=None):
        params, options = self.parser.parse_args(args, show_diff_phil=True)
        log.config(logfile="dials.complete_full_sphere.log")

        model_shadow = params.shadow

        experiments = flatten_experiments(params.input.experiments)

        if len(experiments) != 1:
            self.parser.print_help()
            return

        expt = experiments[0]

        axes = expt.goniometer.get_axes()

        if len(axes) != 3:
            sys.exit("This will only work with 3-axis goniometers")

        if not expt.imageset.reader().get_format():
            sys.exit("This will only work with images available")

        if not expt.imageset.reader().get_format(
        ).get_goniometer_shadow_masker():
            model_shadow = False

        beam = expt.beam
        det = expt.detector

        if params.resolution:
            resolution = params.resolution
        else:
            resolution = det.get_max_inscribed_resolution(expt.beam.get_s0())

        # at this point, predict all of the reflections in the scan possible (i.e.
        # extend scan to 360 degrees) - this points back to expt

        self.make_scan_360(expt.scan)

        # now get a full set of all unique miller indices
        all_indices = miller.build_set(
            crystal_symmetry=crystal.symmetry(
                space_group=expt.crystal.get_space_group(),
                unit_cell=expt.crystal.get_unit_cell(),
            ),
            anomalous_flag=True,
            d_min=resolution,
        )

        if model_shadow:
            obs, shadow = self.predict_to_miller_set_with_shadow(
                expt, resolution)
        else:
            obs = self.predict_to_miller_set(expt, resolution)

        logger.info("Fraction of unique observations at datum: %.1f%%" %
                    (100.0 * len(obs.indices()) / len(all_indices.indices())))

        missing = all_indices.lone_set(other=obs)

        logger.info("%d unique reflections in blind region" %
                    len(missing.indices()))

        e1 = matrix.col(axes[0])
        e2 = matrix.col(axes[1])
        e3 = matrix.col(axes[2])

        s0n = matrix.col(beam.get_s0()).normalize()

        # rotate blind region about beam by +/- two theta
        two_theta = 2.0 * math.asin(0.5 * beam.get_wavelength() / resolution)
        R_ptt = s0n.axis_and_angle_as_r3_rotation_matrix(two_theta)
        R_ntt = s0n.axis_and_angle_as_r3_rotation_matrix(-two_theta)

        # now decompose to e3, e2, e1
        sol_plus = rotation_decomposition.solve_r3_rotation_for_angles_given_axes(
            R_ptt, e3, e2, e1, return_both_solutions=True, deg=True)

        sol_minus = rotation_decomposition.solve_r3_rotation_for_angles_given_axes(
            R_ntt, e3, e2, e1, return_both_solutions=True, deg=True)

        solutions = []
        if sol_plus:
            solutions.extend(sol_plus)
        if sol_minus:
            solutions.extend(sol_minus)

        if not solutions:
            sys.exit("Impossible two theta: %.3f," %
                     (two_theta * 180.0 / math.pi))

        logger.info("Maximum two theta: %.3f," % (two_theta * 180.0 / math.pi))
        logger.info("%d solutions found" % len(solutions))

        names = tuple([
            n.replace("GON_", "").lower() for n in expt.goniometer.get_names()
        ])

        logger.info(" %8s %8s %8s  coverage expt.expt" % names)
        self.write_expt(experiments, "solution_0.expt")
        for j, s in enumerate(solutions):
            expt.goniometer.set_angles(s)
            if model_shadow:
                obs, shadow = self.predict_to_miller_set_with_shadow(
                    expt, resolution)
            else:
                obs = self.predict_to_miller_set(expt, resolution)
            new = missing.common_set(obs)
            fout = "solution_%d.expt" % (j + 1)
            f = len(new.indices()) / len(missing.indices())

            logger.info("%8.3f %8.3f %8.3f %4.2f %s" %
                        (s[0], s[1], s[2], f, fout))
            self.write_expt(experiments, fout)

    def make_scan_360(self, scan):
        epochs = scan.get_epochs()
        exposure_times = scan.get_exposure_times()
        image_range = scan.get_image_range()
        oscillation = scan.get_oscillation()

        current = 1 + image_range[1] - image_range[0]
        turn = int(round(360.0 / oscillation[1]))
        extra = turn - current

        for j in range(extra):
            epochs.append(0.0)
            exposure_times.append(0.0)
        image_range = image_range[0], image_range[1] + extra

        scan.set_image_range(image_range)
        scan.set_epochs(epochs)
        scan.set_exposure_times(exposure_times)
        return scan

    def predict_to_miller_set(self, expt, resolution):
        predicted = flex.reflection_table.from_predictions(expt,
                                                           dmin=resolution)
        hkl = predicted["miller_index"]

        # now get a full set of all unique miller indices
        obs = miller.set(
            crystal_symmetry=crystal.symmetry(
                space_group=expt.crystal.get_space_group(),
                unit_cell=expt.crystal.get_unit_cell(),
            ),
            anomalous_flag=True,
            indices=hkl,
        ).unique_under_symmetry()

        return obs

    def predict_to_miller_set_with_shadow(self, expt, resolution):
        predicted = flex.reflection_table.from_predictions(expt,
                                                           dmin=resolution)

        # transmogrify this to an ExperimentList from an Experiment
        experiments = ExperimentList()
        experiments.append(expt)
        predicted["id"] = flex.int(predicted.size(), 0)
        shadowed = filter_shadowed_reflections(experiments,
                                               predicted,
                                               experiment_goniometer=True)
        predicted = predicted.select(~shadowed)

        hkl = predicted["miller_index"]

        # now get a full set of all unique miller indices
        obs = miller.set(
            crystal_symmetry=crystal.symmetry(
                space_group=expt.crystal.get_space_group(),
                unit_cell=expt.crystal.get_unit_cell(),
            ),
            anomalous_flag=True,
            indices=hkl,
        ).unique_under_symmetry()

        return obs, shadowed

    def write_expt(self, experiments, filename):
        experiments.as_file(filename)
Exemplo n.º 50
0
def run(args):
    usage = "dev.dials.csv [options] imported.expt strong.refl output.csv=rl.csv"

    parser = OptionParser(
        usage=usage,
        phil=phil_scope,
        read_experiments=True,
        read_reflections=True,
        check_format=False,
    )

    params, options = parser.parse_args(show_diff_phil=False)
    reflections, experiments = reflections_and_experiments_from_files(
        params.input.reflections, params.input.experiments)

    if not experiments or not reflections:
        parser.print_help()
        exit(0)

    spots = []

    for reflection in reflections:
        unique_ids = set(reflection["id"])
        for unique_id in sorted(unique_ids):
            spots.append(reflection.select(reflection["id"] == unique_id))
        if not reflection:  # If there are no reflections then export an empty list
            spots.append(reflection)

    assert len(experiments) == len(spots)

    if params.output.compress:
        fout = gzip.GzipFile(params.output.csv, "w")
        if six.PY3:
            # GzipFile() always provides binary access only.
            # Replace the file object with one that allows writing text:
            fout = io.TextIOWrapper(fout)
            # Rely on garbage collection to close the underlying GzipFile.
    else:
        fout = open(params.output.csv, "w")

    fout.write("# x,y,z,experiment_id,imageset_id\n")

    dp = params.output.dp

    if dp <= 0:
        fmt = "%f,%f,%f,%d,%d\n"
    else:
        fmt = "%%.%df,%%.%df,%%.%df,%%d,%%d\n" % (dp, dp, dp)

    print("Using format:", fmt.strip())

    for k, (expt, refl) in enumerate(zip(experiments, spots)):
        if "imageset_id" not in refl:
            refl["imageset_id"] = refl["id"]

        refl.centroid_px_to_mm(ExperimentList([expt]))
        refl.map_centroids_to_reciprocal_space(ExperimentList([expt]))
        rlp = refl["rlp"]

        for _rlp in rlp:
            fout.write(fmt % (_rlp[0], _rlp[1], _rlp[2], k, k))

        print("Appended %d spots to %s" % (len(rlp), params.output.csv))

    fout.close()
Exemplo n.º 51
0
class Script(object):
    '''A class for running the script.'''
    def __init__(self):
        from dials.util.options import OptionParser
        import libtbx.load_env

        usage = 'usage: %s [options] experiments.json indexed.pickle' \
                % libtbx.env.dispatcher_name

        self.parser = OptionParser(usage=usage,
                                   phil=phil_scope,
                                   epilog=help_message,
                                   check_format=False,
                                   read_experiments=True,
                                   read_reflections=True)

    def run(self):
        from dials.array_family import flex  # import dependency
        from scitbx import matrix
        from dials.util.options import flatten_experiments
        from dials.util.options import flatten_reflections

        params, options = self.parser.parse_args(show_diff_phil=True)

        experiments = flatten_experiments(params.input.experiments)
        reflections = flatten_reflections(params.input.reflections)

        if len(experiments) == 0:
            self.parser.print_help()
            return

        if len(reflections) != 1:
            self.parser.print_help()
            return

        reflections = reflections[0]

        print 'Read %d reflections' % len(reflections)

        indexed = reflections.select(
            reflections.get_flags(reflections.flags.indexed))

        print 'Kept %d indexed reflections' % len(indexed)

        for name in sorted(indexed.keys()):
            print 'Found column %s' % name

        for reflection in indexed[:3]:
            print reflection

        # verify that these experiments correspond to exactly one imageset, one
        # detector, one beam (obviously)
        for experiment in experiments[1:]:
            assert experiment.imageset == experiments[0].imageset
            assert experiment.beam == experiments[0].beam
            assert experiment.detector == experiments[0].detector

        # now perform some calculations - the only things different from one
        # experiment to the next will be crystal models
        crystals = [experiment.crystal for experiment in experiments]
        detector = experiments[0].detector
        beam = experiments[0].beam
        imageset = experiments[0].imageset

        # derived quantities
        wavelength = beam.get_wavelength()
        s0 = matrix.col(beam.get_s0())

        # in here do some jiggery-pokery to cope with this being interpreted as
        # a rotation image in here i.e. if scan is not None; derive goniometer
        # matrix else set this to identity

        scan = experiments[0].scan
        goniometer = experiments[0].goniometer

        if scan and goniometer:
            angle = scan.get_angle_from_array_index(
                0.5 * sum(imageset.get_array_range()))
            axis = matrix.col(goniometer.get_rotation_axis_datum())
            F = matrix.sqr(goniometer.get_fixed_rotation())
            S = matrix.sqr(goniometer.get_setting_rotation())
            R = S * axis.axis_and_angle_as_r3_rotation_matrix(angle,
                                                              deg=True) * F
        else:
            R = matrix.sqr((1, 0, 0, 0, 1, 0, 0, 0, 1))

        assert (len(detector) == 1)
Exemplo n.º 52
0
class Script:
    """A class for running the script."""
    def __init__(self):
        """Initialise the script."""
        # The script usage
        usage = ("usage: dials.predict [options] [param.phil] "
                 "{sequence.expt | image1.file [image2.file ...]}")

        # Create the parser
        self.parser = OptionParser(
            usage=usage,
            phil=phil_scope,
            epilog=help_message,
            check_format=True,
            read_experiments=True,
        )

    def run(self, args=None):
        """Execute the script."""
        # Parse the command line
        params, options = self.parser.parse_args(args, show_diff_phil=True)

        # Check the number of experiments
        experiments = flatten_experiments(params.input.experiments)
        if len(experiments) == 0:
            self.parser.print_help()
            return

        predicted_all = flex.reflection_table()

        for i_expt, expt in enumerate(experiments):
            if params.buffer_size > 0:
                # Hack to make the predicter predict reflections outside of the range
                # of the scan
                scan = expt.scan
                image_range = scan.get_image_range()
                oscillation = scan.get_oscillation()
                scan.set_image_range((
                    image_range[0] - params.buffer_size,
                    image_range[1] + params.buffer_size,
                ))
                scan.set_oscillation((
                    oscillation[0] - params.buffer_size * oscillation[1],
                    oscillation[1],
                ))

            # Populate the reflection table with predictions
            predicted = flex.reflection_table.from_predictions(
                expt, force_static=params.force_static, dmin=params.d_min)
            predicted["id"] = flex.int(len(predicted), i_expt)
            predicted_all.extend(predicted)

        # if we are not ignoring shadows, look for reflections in the masked
        # region, see https://github.com/dials/dials/issues/349

        if not params.ignore_shadows:
            shadowed = filter_shadowed_reflections(experiments,
                                                   predicted_all,
                                                   experiment_goniometer=True)
            predicted_all = predicted_all.select(~shadowed)

        try:
            predicted_all.compute_bbox(experiments)
        except Exception:
            pass

        # Save the reflections to file
        Command.start(
            f"Saving {len(predicted_all)} reflections to {params.output}")
        predicted_all.as_file(params.output)
        Command.end(
            f"Saved {len(predicted_all)} reflections to {params.output}")
Exemplo n.º 53
0
def run(args):
    import libtbx.load_env
    from libtbx.utils import Sorry
    usage = "%s [options] experiments.json indexed.pickle" % libtbx.env.dispatcher_name

    parser = OptionParser(usage=usage,
                          phil=phil_scope,
                          read_reflections=True,
                          read_experiments=True,
                          check_format=False,
                          epilog=help_message)

    params, options = parser.parse_args(show_diff_phil=True)

    reflections = flatten_reflections(params.input.reflections)
    experiments = flatten_experiments(params.input.experiments)
    if len(experiments) == 0 and len(reflections) == 0:
        parser.print_help()
        return
    elif len(experiments.crystals()) > 1:
        raise Sorry("Only one crystal can be processed at a time")
    if params.change_of_basis_op is None:
        raise Sorry("Please provide a change_of_basis_op.")

    reference_crystal = None
    if params.reference is not None:
        from dxtbx.serialize import load
        reference_experiments = load.experiment_list(params.reference,
                                                     check_format=False)
        assert len(reference_experiments.crystals()) == 1
        reference_crystal = reference_experiments.crystals()[0]

    if len(experiments) and params.change_of_basis_op is libtbx.Auto:
        if reference_crystal is not None:
            from dials.algorithms.indexing.compare_orientation_matrices \
                 import difference_rotation_matrix_axis_angle

            cryst = experiments.crystals()[0]
            R, axis, angle, change_of_basis_op = difference_rotation_matrix_axis_angle(
                cryst, reference_crystal)
            print "Change of basis op: %s" % change_of_basis_op
            print "Rotation matrix to transform input crystal to reference::"
            print R.mathematica_form(format="%.3f", one_row_per_line=True)
            print "Rotation of %.3f degrees" % angle, "about axis (%.3f, %.3f, %.3f)" % axis

        elif len(reflections):
            assert len(reflections) == 1

            # always re-map reflections to reciprocal space
            from dials.algorithms.indexing import indexer
            refl_copy = flex.reflection_table()
            for i, imageset in enumerate(experiments.imagesets()):
                if 'imageset_id' in reflections[0]:
                    sel = (reflections[0]['imageset_id'] == i)
                else:
                    sel = (reflections[0]['id'] == i)
                refl = indexer.indexer_base.map_spots_pixel_to_mm_rad(
                    reflections[0].select(sel), imageset.get_detector(),
                    imageset.get_scan())

                indexer.indexer_base.map_centroids_to_reciprocal_space(
                    refl, imageset.get_detector(), imageset.get_beam(),
                    imageset.get_goniometer())
                refl_copy.extend(refl)

            # index the reflection list using the input experiments list
            refl_copy['id'] = flex.int(len(refl_copy), -1)
            from dials.algorithms.indexing import index_reflections
            index_reflections(refl_copy, experiments, tolerance=0.2)
            hkl_expt = refl_copy['miller_index']
            hkl_input = reflections[0]['miller_index']

            change_of_basis_op = derive_change_of_basis_op(hkl_input, hkl_expt)

            # reset experiments list since we don't want to reindex this
            experiments = []

    else:
        change_of_basis_op = sgtbx.change_of_basis_op(
            params.change_of_basis_op)

    if len(experiments):
        experiment = experiments[0]
        cryst_orig = copy.deepcopy(experiment.crystal)
        cryst_reindexed = cryst_orig.change_basis(change_of_basis_op)
        if params.space_group is not None:
            a, b, c = cryst_reindexed.get_real_space_vectors()
            cryst_reindexed = crystal_model(
                a, b, c, space_group=params.space_group.group())
        experiment.crystal.update(cryst_reindexed)

        print "Old crystal:"
        print cryst_orig
        print
        print "New crystal:"
        print cryst_reindexed
        print

        print "Saving reindexed experimental models to %s" % params.output.experiments
        dump.experiment_list(experiments, params.output.experiments)

    if len(reflections):
        assert (len(reflections) == 1)
        reflections = reflections[0]

        miller_indices = reflections['miller_index']

        if params.hkl_offset is not None:
            h, k, l = miller_indices.as_vec3_double().parts()
            h += params.hkl_offset[0]
            k += params.hkl_offset[1]
            l += params.hkl_offset[2]
            miller_indices = flex.miller_index(h.iround(), k.iround(),
                                               l.iround())
        non_integral_indices = change_of_basis_op.apply_results_in_non_integral_indices(
            miller_indices)
        if non_integral_indices.size() > 0:
            print "Removing %i/%i reflections (change of basis results in non-integral indices)" % (
                non_integral_indices.size(), miller_indices.size())
        sel = flex.bool(miller_indices.size(), True)
        sel.set_selected(non_integral_indices, False)
        miller_indices_reindexed = change_of_basis_op.apply(
            miller_indices.select(sel))
        reflections['miller_index'].set_selected(sel, miller_indices_reindexed)
        reflections['miller_index'].set_selected(~sel, (0, 0, 0))

        print "Saving reindexed reflections to %s" % params.output.reflections
        easy_pickle.dump(params.output.reflections, reflections)
Exemplo n.º 54
0
class Script(object):
    """A class for running the script."""
    def __init__(self):
        """Initialise the script."""
        from dials.util.options import OptionParser

        usage = ("usage: dials.slice_sequence [options] [param.phil] "
                 "models.expt observations.refl")

        # Create the parser
        self.parser = OptionParser(
            usage=usage,
            phil=phil_scope,
            read_reflections=True,
            read_experiments=True,
            check_format=False,
            epilog=help_message,
        )

    def run(self, args=None):
        """Execute the script."""

        from dials.util.options import reflections_and_experiments_from_files

        # Parse the command line
        params, options = self.parser.parse_args(args, show_diff_phil=True)
        reflections, experiments = reflections_and_experiments_from_files(
            params.input.reflections, params.input.experiments)

        # Try to load the models and data
        slice_exps = len(experiments) > 0
        slice_refs = len(reflections) > 0

        # Catch case of nothing to do
        if not slice_exps and not slice_refs:
            print("No suitable input provided")
            self.parser.print_help()
            return

        if reflections:
            if len(reflections) > 1:
                raise Sorry(
                    "Only one reflections list can be imported at present")
            reflections = reflections[0]

            # calculate frame numbers if needed
            if experiments:
                reflections = calculate_frame_numbers(reflections, experiments)

            # if we still don't have the right column give up
            if "xyzobs.px.value" not in reflections:
                raise Sorry(
                    "These reflections do not have frame numbers set, and "
                    "there are no experiments provided to calculate these.")

        # set trivial case where no scan range is provided at all
        if not params.image_range:
            params.image_range = [None]

        # check if slicing into blocks
        if params.block_size is not None:
            if slice_exps:
                if len(experiments) > 1:
                    raise Sorry(
                        "For slicing into blocks please provide a single "
                        "scan only")
                scan = experiments[0].scan

            # Having extracted the scan, calculate the blocks
            params.image_range = calculate_block_ranges(
                scan, params.block_size)

            # Do the slicing then recombine
            if slice_exps:
                sliced = [
                    slice_experiments(experiments, [sr])[0]
                    for sr in params.image_range
                ]
                sliced_experiments = ExperimentList()
                for exp in sliced:
                    sliced_experiments.append(exp)

            # slice reflections if present
            if slice_refs:
                sliced = [
                    slice_reflections(reflections, [sr])
                    for sr in params.image_range
                ]
                sliced_reflections = sliced[0]
                for i, rt in enumerate(sliced[1:]):
                    rt["id"] += i + 1  # set id
                    sliced_reflections.extend(rt)

        else:
            # slice each dataset into the requested subset
            if slice_exps:
                sliced_experiments = slice_experiments(experiments,
                                                       params.image_range)
            if slice_refs:
                sliced_reflections = slice_reflections(reflections,
                                                       params.image_range)

        # Save sliced experiments
        if slice_exps:
            output_experiments_filename = params.output.experiments_filename
            if output_experiments_filename is None:
                # take first filename as template
                bname = basename(params.input.experiments[0].filename)
                bname = splitext(bname)[0]
                if not bname:
                    bname = "experiments"
                if len(params.image_range
                       ) == 1 and params.image_range[0] is not None:
                    ext = "_{0}_{1}.expt".format(*params.image_range[0])
                else:
                    ext = "_sliced.expt"
                output_experiments_filename = bname + ext
            print("Saving sliced experiments to {}".format(
                output_experiments_filename))

            sliced_experiments.as_file(output_experiments_filename)

        # Save sliced reflections
        if slice_refs:
            output_reflections_filename = params.output.reflections_filename
            if output_reflections_filename is None:
                # take first filename as template
                bname = basename(params.input.reflections[0].filename)
                bname = splitext(bname)[0]
                if not bname:
                    bname = "reflections"
                if len(params.image_range
                       ) == 1 and params.image_range[0] is not None:
                    ext = "_{0}_{1}.refl".format(*params.image_range[0])
                else:
                    ext = "_sliced.refl"
                output_reflections_filename = bname + ext

            print("Saving sliced reflections to {0}".format(
                output_reflections_filename))
            sliced_reflections.as_file(output_reflections_filename)

        return
Exemplo n.º 55
0
class Script(object):
    """A class for running the script."""

    def __init__(self, phil=phil_scope):
        """Initialise the script."""
        from dials.util.options import OptionParser
        import libtbx.load_env

        # The script usage
        usage = (
            "usage: %s [options] [param.phil] "
            "{models.expt | image1.file [image2.file ...]}" % libtbx.env.dispatcher_name
        )

        # Initialise the base class
        self.parser = OptionParser(
            usage=usage,
            phil=phil,
            epilog=help_message,
            read_experiments_from_images=True,
            read_experiments=True,
        )

    def run(self, args=None):
        """Execute the script."""
        from dials.array_family import flex
        from dials.util.options import flatten_experiments
        from time import time
        from dials.util import log

        start_time = time()

        # Parse the command line
        params, options = self.parser.parse_args(args=args, show_diff_phil=False)

        if __name__ == "__main__":
            # Configure the logging
            log.config(
                params.verbosity, info=params.output.log, debug=params.output.debug_log
            )

        from dials.util.version import dials_version

        logger.info(dials_version())

        # Log the diff phil
        diff_phil = self.parser.diff_phil.as_str()
        if diff_phil != "":
            logger.info("The following parameters have been modified:\n")
            logger.info(diff_phil)

        # Ensure we have a data block
        experiments = flatten_experiments(params.input.experiments)
        if len(experiments) == 0:
            self.parser.print_help()
            return

        # Loop through all the imagesets and find the strong spots
        reflections = flex.reflection_table.from_observations(experiments, params)

        # Add n_signal column - before deleting shoeboxes
        from dials.algorithms.shoebox import MaskCode

        good = MaskCode.Foreground | MaskCode.Valid
        reflections["n_signal"] = reflections["shoebox"].count_mask_values(good)

        # Delete the shoeboxes
        if not params.output.shoeboxes:
            del reflections["shoebox"]

        # ascii spot count per image plot
        from dials.util.ascii_art import spot_counts_per_image_plot

        for i, experiment in enumerate(experiments):
            ascii_plot = spot_counts_per_image_plot(
                reflections.select(reflections["id"] == i)
            )
            if len(ascii_plot):
                logger.info("\nHistogram of per-image spot count for imageset %i:" % i)
                logger.info(ascii_plot)

        # Save the reflections to file
        logger.info("\n" + "-" * 80)
        reflections.as_file(params.output.reflections)
        logger.info(
            "Saved {} reflections to {}".format(
                len(reflections), params.output.reflections
            )
        )

        # Save the experiments
        if params.output.experiments:
            logger.info("Saving experiments to {}".format(params.output.experiments))
            experiments.as_file(params.output.experiments)

        # Print some per image statistics
        if params.per_image_statistics:
            from dials.algorithms.spot_finding import per_image_analysis
            from six.moves import cStringIO as StringIO

            s = StringIO()
            for i, experiment in enumerate(experiments):
                print("Number of centroids per image for imageset %i:" % i, file=s)
                imageset = experiment.imageset
                stats = per_image_analysis.stats_imageset(
                    imageset,
                    reflections.select(reflections["id"] == i),
                    resolution_analysis=False,
                )
                per_image_analysis.print_table(stats, out=s)
            logger.info(s.getvalue())

        # Print the time
        logger.info("Time Taken: %f" % (time() - start_time))

        if params.output.experiments:
            return experiments, reflections
        else:
            return reflections
Exemplo n.º 56
0
def run(args=None):
    from dials.util import log
    from dials.util.options import OptionParser, reflections_and_experiments_from_files

    usage = "dials.rl_png [options] experiments.json observations.refl"

    parser = OptionParser(
        usage=usage,
        phil=phil_scope,
        read_experiments=True,
        read_reflections=True,
        check_format=False,
        epilog=help_message,
    )

    params, options = parser.parse_args(args)
    reflections, experiments = reflections_and_experiments_from_files(
        params.input.reflections, params.input.experiments)

    if len(experiments) == 0 or len(reflections) == 0:
        parser.print_help()
        exit(0)

    # Configure the logging
    log.config(logfile="dials.rl_png.log")

    # Log the diff phil
    diff_phil = parser.diff_phil.as_str()
    if diff_phil != "":
        logger.info("The following parameters have been modified:\n")
        logger.info(diff_phil)

    reflections = reflections[0]

    f = ReciprocalLatticePng(settings=params)
    f.load_models(experiments, reflections)

    rotation_axis = matrix.col(experiments[0].goniometer.get_rotation_axis())
    s0 = matrix.col(experiments[0].beam.get_s0())

    e1 = rotation_axis.normalize()
    e2 = s0.normalize()
    e3 = e1.cross(e2).normalize()

    f.viewer.plot("rl_rotation_axis.png", n=e1.elems)
    f.viewer.plot("rl_beam_vector", n=e2.elems)
    f.viewer.plot("rl_e3.png", n=e3.elems)

    n_solutions = params.basis_vector_search.n_solutions

    if experiments.crystals().count(None) < len(experiments):
        for i, c in enumerate(experiments.crystals()):
            A = matrix.sqr(c.get_A())

            direct_matrix = A.inverse()
            a = direct_matrix[:3]
            b = direct_matrix[3:6]
            c = direct_matrix[6:9]

            prefix = ""
            if len(experiments.crystals()) > 1:
                prefix = "%i_" % (i + 1)

            f.viewer.plot(f"rl_{prefix}a.png", n=a)
            f.viewer.plot(f"rl_{prefix}b.png", n=b)
            f.viewer.plot(f"rl_{prefix}c.png", n=c)

    elif n_solutions:
        if "imageset_id" not in reflections:
            reflections["imageset_id"] = reflections["id"]

        reflections.centroid_px_to_mm(experiments)

        reflections.map_centroids_to_reciprocal_space(experiments)

        if params.d_min is not None:
            d_spacings = 1 / reflections["rlp"].norms()
            sel = d_spacings > params.d_min
            reflections = reflections.select(sel)

        # derive a max_cell from mm spots
        max_cell = find_max_cell(reflections,
                                 max_cell_multiplier=1.3,
                                 step_size=45).max_cell

        result = run_dps(experiments[0], reflections, max_cell)
        if result:
            solutions = [matrix.col(v) for v in result["solutions"]]
            for i in range(min(n_solutions, len(solutions))):
                v = solutions[i]
                f.viewer.plot(f"rl_solution_{i + 1}.png", n=v.elems)
Exemplo n.º 57
0
def run(args):

    from dials.util.options import OptionParser
    from dials.util.options import flatten_datablocks
    from dials.util.options import flatten_experiments
    from dials.util.options import flatten_reflections
    from dials.util import log
    import libtbx.load_env

    usage = "%s [options] datablock.json reflections.pickle" % (
        libtbx.env.dispatcher_name)

    parser = OptionParser(usage=usage,
                          phil=phil_scope,
                          read_datablocks=True,
                          read_experiments=True,
                          read_reflections=True,
                          check_format=False,
                          epilog=help_message)

    params, options = parser.parse_args()
    datablocks = flatten_datablocks(params.input.datablock)
    experiments = flatten_experiments(params.input.experiments)
    reflections = flatten_reflections(params.input.reflections)

    if (len(datablocks) == 0
            and len(experiments) == 0) or len(reflections) == 0:
        parser.print_help()
        exit(0)

    # Configure the logging
    log.config(info='dials.detect_blanks.log')

    # Log the diff phil
    diff_phil = parser.diff_phil.as_str()
    if diff_phil is not '':
        logger.info('The following parameters have been modified:\n')
        logger.info(diff_phil)

    reflections = reflections[0]

    if len(datablocks) == 0 and len(experiments) > 0:
        imagesets = experiments.imagesets()
    else:
        imagesets = []
        for datablock in datablocks:
            imagesets.extend(datablock.extract_imagesets())

    assert len(imagesets) == 1
    imageset = imagesets[0]
    scan = imageset.get_scan()

    integrated_sel = reflections.get_flags(reflections.flags.integrated)
    indexed_sel = reflections.get_flags(reflections.flags.indexed)
    centroid_outlier_sel = reflections.get_flags(
        reflections.flags.centroid_outlier)
    strong_sel = reflections.get_flags(reflections.flags.strong)
    indexed_sel &= (~centroid_outlier_sel)

    logger.info('Analysis of %i strong reflections:' % strong_sel.count(True))
    strong_results = blank_counts_analysis(
        reflections.select(strong_sel),
        scan,
        phi_step=params.phi_step,
        fractional_loss=params.counts_fractional_loss)
    for blank_start, blank_end in strong_results['blank_regions']:
        logger.info('Potential blank images: %i -> %i' %
                    (blank_start + 1, blank_end))

    indexed_results = None
    if indexed_sel.count(True) > 0:
        logger.info('Analysis of %i indexed reflections:' %
                    indexed_sel.count(True))
        indexed_results = blank_counts_analysis(
            reflections.select(indexed_sel),
            scan,
            phi_step=params.phi_step,
            fractional_loss=params.counts_fractional_loss)
        for blank_start, blank_end in indexed_results['blank_regions']:
            logger.info('Potential blank images: %i -> %i' %
                        (blank_start + 1, blank_end))

    integrated_results = None
    if integrated_sel.count(True) > 0:
        logger.info('Analysis of %i integrated reflections:' %
                    integrated_sel.count(True))
        integrated_results = blank_integrated_analysis(
            reflections.select(integrated_sel),
            scan,
            phi_step=params.phi_step,
            fractional_loss=params.misigma_fractional_loss)
        for blank_start, blank_end in integrated_results['blank_regions']:
            logger.info('Potential blank images: %i -> %i' %
                        (blank_start + 1, blank_end))

    d = {
        'strong': strong_results,
        'indexed': indexed_results,
        'integrated': integrated_results
    }

    if params.output.json is not None:
        import json
        with open(params.output.json, 'wb') as f:
            json.dump(d, f)

    if params.output.plot:
        from matplotlib import pyplot

        plots = [(strong_results, '-')]
        if indexed_results:
            plots.append((indexed_results, '--'))
        if integrated_results:
            plots.append((integrated_results, ':'))

        for results, linestyle in plots:
            xs = results['data'][0]['x']
            ys = results['data'][0]['y']
            xmax = max(xs)
            ymax = max(ys)
            xs = [x / xmax for x in xs]
            ys = [y / ymax for y in ys]
            blanks = results['data'][0]['blank']
            pyplot.plot(xs, ys, color='blue', linestyle=linestyle)
            pyplot.plot(*zip(*[(x, y) for x, y, blank in zip(xs, ys, blanks)
                               if blank]),
                        color='red',
                        linestyle=linestyle)
        pyplot.ylim(0)
        pyplot.show()
        pyplot.clf()
Exemplo n.º 58
0
class Script(object):
    ''' The integration program. '''
    def __init__(self):
        '''Initialise the script.'''
        from dials.util.options import OptionParser
        import libtbx.load_env

        # The script usage
        usage = "usage: %s [options] experiment.json" % libtbx.env.dispatcher_name

        # Create the parser
        self.parser = OptionParser(usage=usage,
                                   phil=phil_scope,
                                   epilog=help_message,
                                   read_experiments=True,
                                   read_reflections=True)

    def run(self):
        ''' Perform the integration. '''
        from dials.util.command_line import heading
        from dials.util.options import flatten_reflections, flatten_experiments
        from dials.util import log
        from time import time
        from libtbx.utils import Sorry

        # Check the number of arguments is correct
        start_time = time()

        # Parse the command line
        params, options = self.parser.parse_args(show_diff_phil=False)
        reference = flatten_reflections(params.input.reflections)
        experiments = flatten_experiments(params.input.experiments)
        if len(reference) == 0 and len(experiments) == 0:
            self.parser.print_help()
            return
        if len(reference) == 0:
            reference = None
        elif len(reference) != 1:
            raise Sorry('more than 1 reflection file was given')
        else:
            reference = reference[0]
        if len(experiments) == 0:
            raise Sorry('no experiment list was specified')

        # Save phil parameters
        if params.output.phil is not None:
            with open(params.output.phil, "w") as outfile:
                outfile.write(self.parser.diff_phil.as_str())

        # Configure logging
        log.config(params.verbosity,
                   info=params.output.log,
                   debug=params.output.debug_log)

        from dials.util.version import dials_version
        logger.info(dials_version())

        # Log the diff phil
        diff_phil = self.parser.diff_phil.as_str()
        if diff_phil is not '':
            logger.info('The following parameters have been modified:\n')
            logger.info(diff_phil)

        # Print if we're using a mask
        for i, exp in enumerate(experiments):
            mask = exp.imageset.external_lookup.mask
            if mask.filename is not None:
                if mask.data:
                    logger.info('Using external mask: %s' % mask.filename)
                    logger.info(' Mask has %d pixels masked' %
                                mask.data.count(False))

        # Print the experimental models
        for i, exp in enumerate(experiments):
            logger.debug("Models for experiment %d" % i)
            logger.debug("")
            logger.debug(str(exp.beam))
            logger.debug(str(exp.detector))
            if exp.goniometer:
                logger.debug(str(exp.goniometer))
            if exp.scan:
                logger.debug(str(exp.scan))
            logger.debug(str(exp.crystal))

        logger.info("=" * 80)
        logger.info("")
        logger.info(heading("Initialising"))
        logger.info("")

        # Load the data
        reference, rubbish = self.process_reference(reference)
        logger.info("")

        # Initialise the integrator
        from dials.algorithms.profile_model.factory import ProfileModelFactory
        from dials.algorithms.integration.integrator import IntegratorFactory
        from dials.array_family import flex

        # Modify experiment list if scan range is set.
        experiments, reference = self.split_for_scan_range(
            experiments, reference, params.scan_range)

        # Predict the reflections
        logger.info("")
        logger.info("=" * 80)
        logger.info("")
        logger.info(heading("Predicting reflections"))
        logger.info("")
        predicted = flex.reflection_table.from_predictions_multi(
            experiments,
            dmin=params.prediction.d_min,
            dmax=params.prediction.d_max,
            margin=params.prediction.margin,
            force_static=params.prediction.force_static)

        # Match reference with predicted
        if reference:
            matched, reference, unmatched = predicted.match_with_reference(
                reference)
            assert (len(matched) == len(predicted))
            assert (matched.count(True) <= len(reference))
            if matched.count(True) == 0:
                raise Sorry('''
          Invalid input for reference reflections.
          Zero reference spots were matched to predictions
        ''')
            elif len(unmatched) != 0:
                logger.info('')
                logger.info('*' * 80)
                logger.info(
                    'Warning: %d reference spots were not matched to predictions'
                    % (len(unmatched)))
                logger.info('*' * 80)
                logger.info('')
            rubbish.extend(unmatched)

            if len(experiments) > 1:
                # filter out any experiments without matched reference reflections
                # f_: filtered
                from dxtbx.model.experiment.experiment_list import ExperimentList
                f_reference = flex.reflection_table()
                f_predicted = flex.reflection_table()
                f_rubbish = flex.reflection_table()
                f_experiments = ExperimentList()
                good_expt_count = 0

                def refl_extend(src, dest, eid):
                    tmp = src.select(src['id'] == eid)
                    tmp['id'] = flex.int(len(tmp), good_expt_count)
                    dest.extend(tmp)

                for expt_id, experiment in enumerate(experiments):
                    if len(reference.select(reference['id'] == expt_id)) != 0:
                        refl_extend(reference, f_reference, expt_id)
                        refl_extend(predicted, f_predicted, expt_id)
                        refl_extend(rubbish, f_rubbish, expt_id)
                        f_experiments.append(experiment)
                        good_expt_count += 1
                    else:
                        logger.info(
                            "Removing experiment %d: no reference reflections matched to predictions"
                            % expt_id)

                reference = f_reference
                predicted = f_predicted
                experiments = f_experiments
                rubbish = f_rubbish

        # Select a random sample of the predicted reflections
        if not params.sampling.integrate_all_reflections:
            predicted = self.sample_predictions(experiments, predicted, params)

        # Compute the profile model
        if (params.create_profile_model and reference is not None
                and "shoebox" in reference):
            experiments = ProfileModelFactory.create(params, experiments,
                                                     reference)
        else:
            for expr in experiments:
                if expr.profile is None:
                    raise Sorry('No profile information in experiment list')
                expr.profile.params = params.profile
        del reference

        # Compute the bounding box
        predicted.compute_bbox(experiments)

        # Create the integrator
        logger.info("")
        integrator = IntegratorFactory.create(params, experiments, predicted)

        # Integrate the reflections
        reflections = integrator.integrate()

        # Append rubbish data onto the end
        if rubbish is not None and params.output.include_bad_reference:
            mask = flex.bool(len(rubbish), True)
            rubbish.unset_flags(mask, rubbish.flags.integrated_sum)
            rubbish.unset_flags(mask, rubbish.flags.integrated_prf)
            rubbish.set_flags(mask, rubbish.flags.bad_reference)
            reflections.extend(rubbish)

        # Save the reflections
        self.save_reflections(reflections, params.output.reflections)
        self.save_experiments(experiments, params.output.experiments)

        # Write a report if requested
        if params.output.report is not None:
            integrator.report().as_file(params.output.report)

        # Print the total time taken
        logger.info("\nTotal time taken: %f" % (time() - start_time))

    def process_reference(self, reference):
        ''' Load the reference spots. '''
        from dials.array_family import flex
        from time import time
        from libtbx.utils import Sorry
        if reference is None:
            return None, None
        st = time()
        assert ("miller_index" in reference)
        assert ("id" in reference)
        logger.info('Processing reference reflections')
        logger.info(' read %d strong spots' % len(reference))
        mask = reference.get_flags(reference.flags.indexed)
        rubbish = reference.select(mask == False)
        if mask.count(False) > 0:
            reference.del_selected(mask == False)
            logger.info(' removing %d unindexed reflections' %
                        mask.count(True))
        if len(reference) == 0:
            raise Sorry('''
        Invalid input for reference reflections.
        Expected > %d indexed spots, got %d
      ''' % (0, len(reference)))
        mask = reference.get_flags(reference.flags.centroid_outlier)
        if mask.count(True) > 0:
            rubbish.extend(reference.select(mask))
            reference.del_selected(mask)
            logger.info(
                ' removing %d reflections marked as centroid outliers' %
                mask.count(True))
        mask = reference['miller_index'] == (0, 0, 0)
        if mask.count(True) > 0:
            rubbish.extend(reference.select(mask))
            reference.del_selected(mask)
            logger.info(' removing %d reflections with hkl (0,0,0)' %
                        mask.count(True))
        mask = reference['id'] < 0
        if mask.count(True) > 0:
            raise Sorry('''
        Invalid input for reference reflections.
        %d reference spots have an invalid experiment id
      ''' % mask.count(True))
        logger.info(' using %d indexed reflections' % len(reference))
        logger.info(' found %d junk reflections' % len(rubbish))
        logger.info(' time taken: %g' % (time() - st))
        return reference, rubbish

    def save_reflections(self, reflections, filename):
        ''' Save the reflections to file. '''
        from time import time
        st = time()
        logger.info('Saving %d reflections to %s' %
                    (len(reflections), filename))
        reflections.as_pickle(filename)
        logger.info(' time taken: %g' % (time() - st))

    def save_experiments(self, experiments, filename):
        ''' Save the profile model parameters. '''
        from time import time
        from dxtbx.model.experiment.experiment_list import ExperimentListDumper
        st = time()
        logger.info('Saving the experiments to %s' % filename)
        dump = ExperimentListDumper(experiments)
        with open(filename, "w") as outfile:
            outfile.write(dump.as_json())
        logger.info(' time taken: %g' % (time() - st))

    def sample_predictions(self, experiments, predicted, params):
        ''' Select a random sample of the predicted reflections to integrate. '''
        from dials.array_family import flex
        nref_per_degree = params.sampling.reflections_per_degree
        min_sample_size = params.sampling.minimum_sample_size
        max_sample_size = params.sampling.maximum_sample_size

        # this code is very similar to David's code in algorithms/refinement/reflection_manager.py!

        # constants
        from math import pi
        RAD2DEG = 180. / pi
        DEG2RAD = pi / 180.

        working_isel = flex.size_t()
        for iexp, exp in enumerate(experiments):

            sel = predicted['id'] == iexp
            isel = sel.iselection()
            #refs = self._reflections.select(sel)
            nrefs = sample_size = len(isel)

            # set sample size according to nref_per_degree (per experiment)
            if exp.scan and nref_per_degree:
                sweep_range_rad = exp.scan.get_oscillation_range(deg=False)
                width = abs(sweep_range_rad[1] - sweep_range_rad[0]) * RAD2DEG
                sample_size = int(nref_per_degree * width)
            else:
                sweep_range_rad = None

            # adjust sample size if below the chosen limit
            sample_size = max(sample_size, min_sample_size)

            # set maximum sample size if requested
            if max_sample_size:
                sample_size = min(sample_size, max_sample_size)

            # determine subset and collect indices
            if sample_size < nrefs:
                isel = isel.select(flex.random_selection(nrefs, sample_size))
            working_isel.extend(isel)

        # create subset
        return predicted.select(working_isel)

    def split_for_scan_range(self, experiments, reference, scan_range):
        ''' Update experiments when scan range is set. '''
        from dxtbx.model.experiment.experiment_list import ExperimentList
        from dxtbx.model.experiment.experiment_list import Experiment
        from dials.array_family import flex

        # Only do anything is the scan range is set
        if scan_range is not None and len(scan_range) > 0:

            # Ensure that all experiments have the same imageset and scan
            iset = [e.imageset for e in experiments]
            scan = [e.scan for e in experiments]
            assert (all(x == iset[0] for x in iset))
            assert (all(x == scan[0] for x in scan))

            # Get the imageset and scan
            iset = experiments[0].imageset
            scan = experiments[0].scan

            # Get the array range
            if scan is not None:
                frame10, frame11 = scan.get_array_range()
                assert (scan.get_num_images() == len(iset))
            else:
                frame10, frame11 = (0, len(iset))

            # Create the new lists
            new_experiments = ExperimentList()
            new_reference_all = reference.split_by_experiment_id()
            new_reference = flex.reflection_table()
            for i in range(len(new_reference_all) - len(experiments)):
                new_reference_all.append(flex.reflection_table())
            assert (len(new_reference_all) == len(experiments))

            # Loop through all the scan ranges and create a new experiment list with
            # the requested scan ranges.
            for frame00, frame01 in scan_range:
                assert (frame01 > frame00)
                assert (frame00 >= frame10)
                assert (frame01 <= frame11)
                index0 = frame00 - frame10
                index1 = index0 + (frame01 - frame00)
                assert (index0 < index1)
                assert (index0 >= 0)
                assert (index1 <= len(iset))
                new_iset = iset[index0:index1]
                if scan is None:
                    new_scan = None
                else:
                    new_scan = scan[index0:index1]
                for i, e1 in enumerate(experiments):
                    e2 = Experiment()
                    e2.beam = e1.beam
                    e2.detector = e1.detector
                    e2.goniometer = e1.goniometer
                    e2.crystal = e1.crystal
                    e2.imageset = new_iset
                    e2.scan = new_scan
                    new_reference_all[i]['id'] = flex.int(
                        len(new_reference_all[i]), len(new_experiments))
                    new_reference.extend(new_reference_all[i])
                    new_experiments.append(e2)
            experiments = new_experiments
            reference = new_reference

            # Print some information
            logger.info(
                'Modified experiment list to integrate over requested scan range'
            )
            for frame00, frame01 in scan_range:
                logger.info(' scan_range = %d -> %d' % (frame00, frame01))
            logger.info('')

        # Return the experiments
        return experiments, reference
Exemplo n.º 59
0
def run(args):

  from dials.util.options import OptionParser
  from dials.util.options import flatten_experiments
  import libtbx.load_env

  usage = "%s [options] datablock.json" %(
    libtbx.env.dispatcher_name)

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_experiments=True,
    check_format=False,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=True)
  experiments = flatten_experiments(params.input.experiments)

  if len(experiments) == 0:
    parser.print_help()
    exit(0)

  imagesets = experiments.imagesets()

  expt = experiments[0]

  frame = None

  if len(params.align.crystal.vector):
    assert len(params.align.crystal.vector) %2 == 0
    vectors = []

    name_to_vectors = {
      'a': (a, 'direct'),
      'b': (b, 'direct'),
      'c': (c, 'direct'),
      'a*': (a_star, 'reciprocal'),
      'b*': (b_star, 'reciprocal'),
      'c*': (c_star, 'reciprocal'),
    }

    for v in params.align.crystal.vector:
      v = v.strip()
      if v in name_to_vectors:
        v, frame_ = name_to_vectors[v]
        assert frame is None or frame == frame_
        frame = frame_
      else:
        v = v.replace(',', ' ').strip().split()
        assert len(v) == 3
        v = matrix.col([float(v_) for v_ in v])
        if frame is None:
          frame = params.align.crystal.frame

      vectors.append(v)
    vectors = [(vectors[2*i], vectors[2*i+1])
               for i in range(len(vectors)//2)]
  else:
    frame = 'reciprocal'
    vectors = ((a_star, b_star), # a*, b*
               (a_star, c_star), # a*, c*
               (b_star, a_star), # b*, a*
               (b_star, c_star), # b*, c*
               (c_star, a_star), # c*, a*
               (c_star, b_star), # c*, b*
              )


  result = align_crystal(expt, vectors, frame=frame, mode=params.align.mode)
  result.show()
  if params.output.json is not None:
    result.as_json(filename=params.output.json)
Exemplo n.º 60
0
class Script(object):
    '''A class for running the script.'''
    def __init__(self):
        '''Initialise the script.'''
        from dials.util.options import OptionParser
        import libtbx.load_env

        # The script usage
        usage  = "usage: %s [options] [param.phil] " \
                 "experiments.json reflections.pickle" \
                   % libtbx.env.dispatcher_name

        # Create the parser
        self.parser = OptionParser(usage=usage,
                                   phil=working_phil,
                                   read_reflections=True,
                                   read_experiments=True,
                                   check_format=False,
                                   epilog=help_message)

    @staticmethod
    def check_input(reflections):
        '''Check the input is suitable for refinement. So far just check keys in
    the reflection table. Maybe later check experiments have overlapping models
    etc.'''

        msg = "The supplied reflection table does not have the required data " + \
          "column: {0}"
        for key in ["xyzobs.mm.value", "xyzobs.mm.variance"]:
            if key not in reflections:
                msg = msg.format(key)
                raise Sorry(msg)

        # FIXME add other things to be checked here
        return

    @staticmethod
    def combine_crystals(experiments):
        '''Replace all crystals in the experiments list with the first crystal'''

        from dxtbx.model.experiment_list import Experiment, ExperimentList
        new_experiments = ExperimentList()
        ref_crystal = experiments[0].crystal
        for exp in experiments:
            new_experiments.append(
                Experiment(beam=exp.beam,
                           detector=exp.detector,
                           scan=exp.scan,
                           goniometer=exp.goniometer,
                           crystal=ref_crystal,
                           imageset=exp.imageset))
        return new_experiments

    @staticmethod
    def filter_integrated_centroids(reflections):
        '''Filter reflections to include only those with the integrated and the
    strong flag set, but only if there are apparently some integrated
    reflections'''

        orig_len = len(reflections)
        inc = flex.bool(orig_len, False)
        mask = reflections.get_flags(reflections.flags.integrated)
        if mask.count(True) == 0: return reflections
        reflections = reflections.select(mask)
        mask = reflections.get_flags(reflections.flags.strong)
        reflections = reflections.select(mask)

        logger.info(
            '{0} out of {1} reflections remain after filtering to keep only strong'
            ' and integrated centroids'.format(len(reflections), orig_len))
        return reflections

    @staticmethod
    def convert_to_P1(reflections, experiments):
        '''Convert the input crystals to P 1 and reindex the reflections'''
        from cctbx.sgtbx import space_group
        for iexp, exp in enumerate(experiments):
            sel = reflections['id'] == iexp
            xl = exp.crystal
            sg = xl.get_space_group()
            op = sg.info().change_of_basis_op_to_primitive_setting()
            exp.crystal = xl.change_basis(op)
            exp.crystal.set_space_group(space_group("P 1"))
            hkl_reindexed = op.apply(reflections['miller_index'].select(sel))
            reflections['miller_index'].set_selected(sel, hkl_reindexed)
        return reflections, experiments

    @staticmethod
    def create_refiner(params, reflections, experiments):

        from dials.algorithms.refinement.parameterisation.crystal_parameters import \
            CrystalUnitCellParameterisation
        from dials.algorithms.refinement.parameterisation.parameter_report import \
            ParameterReporter
        from dials.algorithms.refinement.two_theta_refiner import \
          TwoThetaReflectionManager, TwoThetaTarget, TwoThetaExperimentsPredictor, \
          TwoThetaPredictionParameterisation

        verb = params.refinement.verbosity

        # Only parameterise the crystal unit cell
        det_params = None
        beam_params = None
        xlo_params = None
        xluc_params = []
        for icrystal, crystal in enumerate(experiments.crystals()):
            exp_ids = experiments.indices(crystal)
            xluc_params.append(
                CrystalUnitCellParameterisation(crystal,
                                                experiment_ids=exp_ids))

        # Two theta prediction equation parameterisation
        pred_param = TwoThetaPredictionParameterisation(
            experiments, det_params, beam_params, xlo_params, xluc_params)
        param_reporter = ParameterReporter(det_params, beam_params, xlo_params,
                                           xluc_params)

        # ReflectionManager, currently without outlier rejection
        # Note: If not all reflections are used, then the filtering must be
        # communicated to generate_cif/mmcif() to be included in the CIF file!
        refman = TwoThetaReflectionManager(reflections,
                                           experiments,
                                           outlier_detector=None,
                                           verbosity=verb)

        # Reflection predictor
        ref_predictor = TwoThetaExperimentsPredictor(experiments)

        # Two theta target
        target = TwoThetaTarget(experiments, ref_predictor, refman, pred_param)

        # Do a correlation plot?
        tpc = params.output.correlation_plot.filename is not None

        # Minimisation engine - FIXME not many choices exposed yet. Do we want
        # more cowbell?
        from dials.algorithms.refinement.engine \
          import LevenbergMarquardtIterations as Refinery
        refinery = Refinery(target=target,
                            prediction_parameterisation=pred_param,
                            log=None,
                            verbosity=verb,
                            track_step=False,
                            track_gradient=False,
                            track_parameter_correlation=tpc,
                            max_iterations=20)

        # Refiner
        from dials.algorithms.refinement.refiner import Refiner
        refiner = Refiner(reflections=reflections,
                          experiments=experiments,
                          pred_param=pred_param,
                          param_reporter=param_reporter,
                          refman=refman,
                          target=target,
                          refinery=refinery,
                          verbosity=verb)

        return refiner

    @staticmethod
    def cell_param_table(crystal):
        '''Construct a table of cell parameters and their ESDs'''

        from libtbx.table_utils import simple_table
        cell = crystal.get_unit_cell().parameters()
        esd = crystal.get_cell_parameter_sd()
        vol = crystal.get_unit_cell().volume()
        vol_esd = crystal.get_cell_volume_sd()
        header = ["Parameter", "Value", "Estimated sd"]
        rows = []
        names = ["a", "b", "c", "alpha", "beta", "gamma"]
        for n, p, e in zip(names, cell, esd):
            rows.append([n, "%9.5f" % p, "%9.5f" % e])
        rows.append(["\nvolume", "\n%9.5f" % vol, "\n%9.5f" % vol_esd])
        st = simple_table(rows, header)
        return st.format()

    @staticmethod
    def generate_p4p(crystal, beam, file):
        logger.info('Saving P4P info to %s' % file)
        cell = crystal.get_unit_cell().parameters()
        esd = crystal.get_cell_parameter_sd()
        vol = crystal.get_unit_cell().volume()
        vol_esd = crystal.get_cell_volume_sd()

        open(file, 'w').write('\n'.join([
            'TITLE    Auto-generated .p4p file from dials.two_theta_refine',
            'CELL     %.4f %.4f %.4f %.4f %.4f %.4f %.4f' % tuple(cell +
                                                                  (vol, )),
            'CELLSD   %.4f %.4f %.4f %.4f %.4f %.4f %.4f' % tuple(esd +
                                                                  (vol_esd, )),
            'SOURCE   SYNCH   %.6f' % beam.get_wavelength(), ''
        ]))
        return

    @staticmethod
    def generate_cif(crystal, refiner, file):
        logger.info('Saving CIF information to %s' % file)
        from cctbx import miller
        import datetime
        import iotbx.cif.model
        import math

        block = iotbx.cif.model.block()
        block["_audit_creation_method"] = dials_version()
        block["_audit_creation_date"] = datetime.date.today().isoformat()
        #   block["_publ_section_references"] = '' # once there is a reference...

        for cell, esd, cifname in zip(
                crystal.get_unit_cell().parameters(),
                crystal.get_cell_parameter_sd(), [
                    'length_a', 'length_b', 'length_c', 'angle_alpha',
                    'angle_beta', 'angle_gamma'
                ]):
            block['_cell_%s' %
                  cifname] = format_float_with_standard_uncertainty(cell, esd)
        block['_cell_volume'] = format_float_with_standard_uncertainty(
            crystal.get_unit_cell().volume(), crystal.get_cell_volume_sd())

        used_reflections = refiner.get_matches()
        block['_cell_measurement_reflns_used'] = len(used_reflections)
        block['_cell_measurement_theta_min'] = flex.min(
            used_reflections['2theta_obs.rad']) * 180 / math.pi / 2
        block['_cell_measurement_theta_max'] = flex.max(
            used_reflections['2theta_obs.rad']) * 180 / math.pi / 2
        block['_diffrn_reflns_number'] = len(used_reflections)
        miller_span = miller.index_span(used_reflections['miller_index'])
        min_h, min_k, min_l = miller_span.min()
        max_h, max_k, max_l = miller_span.max()
        block['_diffrn_reflns_limit_h_min'] = min_h
        block['_diffrn_reflns_limit_h_max'] = max_h
        block['_diffrn_reflns_limit_k_min'] = min_k
        block['_diffrn_reflns_limit_k_max'] = max_k
        block['_diffrn_reflns_limit_l_min'] = min_l
        block['_diffrn_reflns_limit_l_max'] = max_l
        block['_diffrn_reflns_theta_min'] = flex.min(
            used_reflections['2theta_obs.rad']) * 180 / math.pi / 2
        block['_diffrn_reflns_theta_max'] = flex.max(
            used_reflections['2theta_obs.rad']) * 180 / math.pi / 2

        cif = iotbx.cif.model.cif()
        cif['two_theta_refine'] = block
        with open(file, 'w') as fh:
            cif.show(out=fh)

    @staticmethod
    def generate_mmcif(crystal, refiner, file):
        logger.info('Saving mmCIF information to %s' % file)
        from cctbx import miller
        import datetime
        import iotbx.cif.model
        import math

        block = iotbx.cif.model.block()
        block["_audit.creation_method"] = dials_version()
        block["_audit.creation_date"] = datetime.date.today().isoformat()
        #   block["_publ.section_references"] = '' # once there is a reference...

        for cell, esd, cifname in zip(
                crystal.get_unit_cell().parameters(),
                crystal.get_cell_parameter_sd(), [
                    'length_a', 'length_b', 'length_c', 'angle_alpha',
                    'angle_beta', 'angle_gamma'
                ]):
            block['_cell.%s' % cifname] = "%.8f" % cell
            block['_cell.%s_esd' % cifname] = "%.8f" % esd
        block['_cell.volume'] = "%f" % crystal.get_unit_cell().volume()
        block['_cell.volume_esd'] = "%f" % crystal.get_cell_volume_sd()

        used_reflections = refiner.get_matches()
        block['_cell_measurement.reflns_used'] = len(used_reflections)
        block['_cell_measurement.theta_min'] = flex.min(
            used_reflections['2theta_obs.rad']) * 180 / math.pi / 2
        block['_cell_measurement.theta_max'] = flex.max(
            used_reflections['2theta_obs.rad']) * 180 / math.pi / 2
        block['_diffrn_reflns.number'] = len(used_reflections)
        miller_span = miller.index_span(used_reflections['miller_index'])
        min_h, min_k, min_l = miller_span.min()
        max_h, max_k, max_l = miller_span.max()
        block['_diffrn_reflns.limit_h_min'] = min_h
        block['_diffrn_reflns.limit_h_max'] = max_h
        block['_diffrn_reflns.limit_k_min'] = min_k
        block['_diffrn_reflns.limit_k_max'] = max_k
        block['_diffrn_reflns.limit_l_min'] = min_l
        block['_diffrn_reflns.limit_l_max'] = max_l
        block['_diffrn_reflns.theta_min'] = flex.min(
            used_reflections['2theta_obs.rad']) * 180 / math.pi / 2
        block['_diffrn_reflns.theta_max'] = flex.max(
            used_reflections['2theta_obs.rad']) * 180 / math.pi / 2

        cif = iotbx.cif.model.cif()
        cif['two_theta_refine'] = block
        with open(file, 'w') as fh:
            cif.show(out=fh)

    def run(self):
        '''Execute the script.'''
        from dials.algorithms.refinement.two_theta_refiner import \
          TwoThetaReflectionManager, TwoThetaTarget, \
          TwoThetaPredictionParameterisation

        start_time = time()

        # Parse the command line
        params, options = self.parser.parse_args(show_diff_phil=False)

        # set up global experiments and reflections lists
        from dials.array_family import flex
        reflections = flex.reflection_table()
        global_id = 0
        from dxtbx.model.experiment_list import ExperimentList
        experiments = ExperimentList()

        # loop through the input, building up the global lists
        nrefs_per_exp = []
        for ref_wrapper, exp_wrapper in zip(params.input.reflections,
                                            params.input.experiments):
            refs = ref_wrapper.data
            exps = exp_wrapper.data
            for i, exp in enumerate(exps):
                sel = refs['id'] == i
                sub_ref = refs.select(sel)
                nrefs_per_exp.append(len(sub_ref))
                sub_ref['id'] = flex.int(len(sub_ref), global_id)
                reflections.extend(sub_ref)
                experiments.append(exp)
                global_id += 1

        # Try to load the models and data
        nexp = len(experiments)
        if nexp == 0:
            print "No Experiments found in the input"
            self.parser.print_help()
            return
        if len(reflections) == 0:
            print "No reflection data found in the input"
            self.parser.print_help()
            return

        self.check_input(reflections)

        # Configure the logging
        log.config(info=params.output.log, debug=params.output.debug_log)
        logger.info(dials_version())

        # Log the diff phil
        diff_phil = self.parser.diff_phil.as_str()
        if diff_phil is not '':
            logger.info('The following parameters have been modified:\n')
            logger.info(diff_phil)

        # Convert to P 1?
        if params.refinement.triclinic:
            reflections, experiments = self.convert_to_P1(
                reflections, experiments)

        # Combine crystals?
        if params.refinement.combine_crystal_models and len(experiments) > 1:
            logger.info('Combining {0} crystal models'.format(
                len(experiments)))
            experiments = self.combine_crystals(experiments)

        # Filter integrated centroids?
        if params.refinement.filter_integrated_centroids:
            reflections = self.filter_integrated_centroids(reflections)

        # Get the refiner
        logger.info('Configuring refiner')
        refiner = self.create_refiner(params, reflections, experiments)

        # Refine the geometry
        if nexp == 1:
            logger.info('Performing refinement of a single Experiment...')
        else:
            logger.info(
                'Performing refinement of {0} Experiments...'.format(nexp))

        # Refine and get the refinement history
        history = refiner.run()

        # get the refined experiments
        experiments = refiner.get_experiments()
        crystals = experiments.crystals()

        if len(crystals) == 1:
            # output the refined model for information
            logger.info('')
            logger.info('Final refined crystal model:')
            logger.info(crystals[0])
            logger.info(self.cell_param_table(crystals[0]))

        # Save the refined experiments to file
        output_experiments_filename = params.output.experiments
        logger.info('Saving refined experiments to {0}'.format(
            output_experiments_filename))
        from dxtbx.model.experiment_list import ExperimentListDumper
        dump = ExperimentListDumper(experiments)
        dump.as_json(output_experiments_filename)

        # Correlation plot
        if params.output.correlation_plot.filename is not None:
            from os.path import splitext
            root, ext = splitext(params.output.correlation_plot.filename)
            if not ext: ext = ".pdf"

            steps = params.output.correlation_plot.steps
            if steps is None: steps = [history.get_nrows() - 1]

            # extract individual column names or indices
            col_select = params.output.correlation_plot.col_select

            num_plots = 0
            for step in steps:
                fname_base = root
                if len(steps) > 1: fname_base += "_step%02d" % step

                corrmats, labels = refiner.get_parameter_correlation_matrix(
                    step, col_select)
                if [corrmats, labels].count(None) == 0:
                    from dials.algorithms.refinement.refinement_helpers import corrgram

                    for resid_name, corrmat in corrmats.items():
                        plot_fname = fname_base + ext
                        plt = corrgram(corrmat, labels)
                        if plt is not None:
                            logger.info(
                                'Saving parameter correlation plot to {}'.
                                format(plot_fname))
                            plt.savefig(plot_fname)
                            plt.close()
                            num_plots += 1
                    mat_fname = fname_base + ".pickle"
                    with open(mat_fname, 'wb') as handle:
                        for k, corrmat in corrmats.items():
                            corrmats[k] = corrmat.as_scitbx_matrix()
                        logger.info(
                            'Saving parameter correlation matrices to {0}'.
                            format(mat_fname))
                        pickle.dump({
                            'corrmats': corrmats,
                            'labels': labels
                        }, handle)

            if num_plots == 0:
                msg = "Sorry, no parameter correlation plots were produced. Please set " \
                      "track_parameter_correlation=True to ensure correlations are " \
                      "tracked, and make sure correlation_plot.col_select is valid."
                logger.info(msg)

        if params.output.cif is not None:
            self.generate_cif(crystals[0], refiner, file=params.output.cif)

        if params.output.p4p is not None:
            self.generate_p4p(crystals[0],
                              experiments[0].beam,
                              file=params.output.p4p)

        if params.output.mmcif is not None:
            self.generate_mmcif(crystals[0], refiner, file=params.output.mmcif)

        # Log the total time taken
        logger.info("\nTotal time taken: {0:.2f}s".format(time() - start_time))