示例#1
0
  def run(self):
    ''' Parse the options. '''
    from dials.util.options import flatten_experiments, flatten_reflections
    # Parse the command line arguments
    params, options = self.parser.parse_args(show_diff_phil=True)
    self.params = params
    experiments = flatten_experiments(params.input.experiments)
    reflections = flatten_reflections(params.input.reflections)

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

    from dials.algorithms.indexing import index_reflections
    from dials.algorithms.indexing.indexer import indexer_base

    reflections['id'] = flex.int(len(reflections), -1)
    reflections['imageset_id'] = flex.int(len(reflections), 0)
    reflections = indexer_base.map_spots_pixel_to_mm_rad(reflections, exp.detector, exp.scan)

    indexer_base.map_centroids_to_reciprocal_space(
      reflections, exp.detector, exp.beam, exp.goniometer,)

    index_reflections(reflections,
                      experiments, params.d_min,
                      tolerance=0.3)
    indexed_reflections = reflections.select(reflections['miller_index'] != (0,0,0))
    print "Indexed %d reflections out of %d"%(len(indexed_reflections), len(reflections))
    easy_pickle.dump("indexedstrong.pickle", indexed_reflections)
  cmd_line = command_line.argument_interpreter(master_params=master_phil)
  working_phil = cmd_line.process_and_fetch(args=(phil,))
  working_params = working_phil.extract()

  for input in working_params.input:
    print input.experiments, input.reflections

  assert len(working_params.input) > 1
  print len(working_params.input), "datasets specified as input"

  e = enumerate(working_params.input)
  i, line = e.next()
  reflections, exp = load_input(line.experiments, line.reflections)
  assert reflections['id'].all_eq(0)
  from dials.algorithms.indexing.indexer import indexer_base
  reflections = indexer_base.map_spots_pixel_to_mm_rad(reflections, exp.detector, exp.scan)
  experiment_from_crystal=ExperimentFromCrystal(exp.beam, exp.detector)

  experiments=ExperimentList()
  experiments.append(experiment_from_crystal(exp.crystal))

  for i, line in e:

    refs, exp = load_input(line.experiments, line.reflections)
    new_exp = experiment_from_crystal(exp.crystal)
    if check_experiment(new_exp, refs):
      refs['id'] = flex.size_t(len(refs),len(experiments))
      refs = indexer_base.map_spots_pixel_to_mm_rad(refs, exp.detector, exp.scan)
      reflections.extend(refs)
      experiments.append(experiment_from_crystal(exp.crystal))
    else:
def discover_better_experimental_model(
  imagesets, spot_lists, params, dps_params, nproc=1, wide_search_binning=1):
  assert len(imagesets) == len(spot_lists)
  assert len(imagesets) > 0
  # XXX should check that all the detector and beam objects are the same
  from dials.algorithms.indexing.indexer import indexer_base
  spot_lists_mm = [
    indexer_base.map_spots_pixel_to_mm_rad(
      spots, imageset.get_detector(), imageset.get_scan())
    for spots, imageset in zip(spot_lists, imagesets)]

  spot_lists_mm = []
  max_cell_list = []

  detector = imagesets[0].get_detector()
  beam = imagesets[0].get_beam()

  beam_panel = detector.get_panel_intersection(beam.get_s0())

  if beam_panel == -1:
    from libtbx.utils import Sorry
    raise Sorry, 'input beam does not intersect detector'

  for imageset, spots in zip(imagesets, spot_lists):
    if 'imageset_id' not in spots:
      spots['imageset_id'] = spots['id']

    spots_mm = indexer_base.map_spots_pixel_to_mm_rad(
      spots=spots, 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 dps_params.d_min is not None:
      d_spacings = 1/spots_mm['rlp'].norms()
      sel = d_spacings > dps_params.d_min
      spots_mm = spots_mm.select(sel)

    # derive a max_cell from mm spots

    if params.max_cell is None:
      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
      max_cell_list.append(max_cell)

    if (params.max_reflections is not None and
        spots_mm.size() > params.max_reflections):
      logger.info('Selecting subset of %i reflections for analysis'
           %params.max_reflections)
      perm = flex.random_permutation(spots_mm.size())
      sel = perm[:params.max_reflections]
      spots_mm = spots_mm.select(sel)

    spot_lists_mm.append(spots_mm)

  if params.max_cell is None:
    max_cell = flex.median(flex.double(max_cell_list))
  else:
    max_cell = params.max_cell
  args = [(imageset, spots, max_cell, dps_params)
          for imageset, spots in zip(imagesets, spot_lists_mm)]

  from libtbx import easy_mp
  results = easy_mp.parallel_map(
    func=run_dps,
    iterable=args,
    processes=nproc,
    method="multiprocessing",
    preserve_order=True,
    asynchronous=True,
    preserve_exception_message=True)
  solution_lists = [r["solutions"] for r in results]
  amax_list = [r["amax"] for r in results]
  assert len(solution_lists) > 0

  detector = imagesets[0].get_detector()
  beam = imagesets[0].get_beam()

  # perform calculation
  if dps_params.indexing.improve_local_scope == "origin_offset":
    discoverer = better_experimental_model_discovery(
      imagesets, spot_lists_mm, solution_lists, amax_list, dps_params,
      wide_search_binning=wide_search_binning)
    new_detector = discoverer.optimize_origin_offset_local_scope()
    old_beam_centre = detector.get_ray_intersection(beam.get_s0())[1]
    new_beam_centre = new_detector.get_ray_intersection(beam.get_s0())[1]
    logger.info("Old beam centre: %.2f mm, %.2f mm" %old_beam_centre)
    logger.info("New beam centre: %.2f mm, %.2f mm" %new_beam_centre)
    logger.info("Shift: %.2f mm, %.2f mm" %(
      matrix.col(old_beam_centre)-matrix.col(new_beam_centre)).elems)
    return new_detector, beam
  elif dps_params.indexing.improve_local_scope=="S0_vector":
    raise NotImplementedError()
  def run(self):

    print "Parsing input"
    params, options = self.parser.parse_args(show_diff_phil=True)

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

    # Try to obtain the models and data
    if not params.input.experiments:
      raise Sorry("No Experiments found in the input")
    if not params.input.reflections:
      raise Sorry("No reflection data found in the input")
    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")

    # set up global experiments and reflections lists
    from dials.array_family import flex
    reflections = flex.reflection_table()
    global_id = 0
    from dxtbx.model.experiment.experiment_list import ExperimentList
    experiments=ExperimentList()

    if params.reference_detector == "first":
      # Use the first experiment of the first experiment list as the reference detector
      ref_exp = params.input.experiments[0].data[0]
    else:
      # Average all the detectors to generate a reference detector
      assert params.detector_phase.refinement.parameterisation.detector.hierarchy_level == 0
      from scitbx.matrix import col
      panel_fasts = []
      panel_slows = []
      panel_oris = []
      for exp_wrapper in params.input.experiments:
        exp = exp_wrapper.data[0]
        if panel_oris:
          for i, panel in enumerate(exp.detector):
            panel_fasts[i] += col(panel.get_fast_axis())
            panel_slows[i] += col(panel.get_slow_axis())
            panel_oris[i] += col(panel.get_origin())
        else:
          for i, panel in enumerate(exp.detector):
            panel_fasts.append(col(panel.get_fast_axis()))
            panel_slows.append(col(panel.get_slow_axis()))
            panel_oris.append(col(panel.get_origin()))

      ref_exp = copy.deepcopy(params.input.experiments[0].data[0])
      for i, panel in enumerate(ref_exp.detector):
        # Averaging the fast and slow axes can make them be non-orthagonal. Fix by finding
        # the vector that goes exactly between them and rotate
        # around their cross product 45 degrees from that vector in either direction
        vf = panel_fasts[i]/len(params.input.experiments)
        vs = panel_slows[i]/len(params.input.experiments)
        c = vf.cross(vs)
        angle = vf.angle(vs, deg=True)
        v45 = vf.rotate(c, angle/2, deg=True)
        vf = v45.rotate(c, -45, deg=True)
        vs = v45.rotate(c, 45, deg=True)
        panel.set_frame(vf, vs,
                        panel_oris[i]/len(params.input.experiments))

      print "Reference detector (averaged):", str(ref_exp.detector)

    # set the experiment factory that combines a crystal with the reference beam
    # and the reference detector
    experiment_from_crystal=ExperimentFromCrystal(ref_exp.beam, ref_exp.detector)

    # keep track of the number of refl per accepted experiment for a table
    nrefs_per_exp = []

    # loop through the input, building up the global lists
    for ref_wrapper, exp_wrapper in zip(params.input.reflections,
                                        params.input.experiments):
      refs = ref_wrapper.data
      exps = exp_wrapper.data

      # there might be multiple experiments already here. Loop through them
      for i, exp in enumerate(exps):

        # select the relevant reflections
        sel = refs['id'] == i
        sub_ref = refs.select(sel)

        ## DGW commented out as reflections.minimum_number_of_reflections no longer exists
        #if len(sub_ref) < params.crystals_phase.refinement.reflections.minimum_number_of_reflections:
        #  print "skipping experiment", i, "in", exp_wrapper.filename, "due to insufficient strong reflections in", ref_wrapper.filename
        #  continue

        # build an experiment with this crystal plus the reference models
        combined_exp = experiment_from_crystal(exp.crystal)

        # next experiment ID in series
        exp_id = len(experiments)

        # check this experiment
        if not check_experiment(combined_exp, sub_ref):
          print "skipping experiment", i, "in", exp_wrapper.filename, "due to poor RMSDs"
          continue

        # set reflections ID
        sub_ref['id'] = flex.int(len(sub_ref), exp_id)

        # keep number of reflections for the table
        nrefs_per_exp.append(len(sub_ref))

        # obtain mm positions on the reference detector
        sub_ref = indexer_base.map_spots_pixel_to_mm_rad(sub_ref,
          combined_exp.detector, combined_exp.scan)

        # extend refl and experiments lists
        reflections.extend(sub_ref)
        experiments.append(combined_exp)

    # print number of reflections per accepted experiment
    from libtbx.table_utils import simple_table
    header = ["Experiment", "Nref"]
    rows = [(str(i), str(n)) for (i, n) in enumerate(nrefs_per_exp)]
    st = simple_table(rows, header)
    print "Number of reflections per experiment"
    print st.format()

    for cycle in range(params.n_macrocycles):

      print "MACROCYCLE %02d" % (cycle + 1)
      print "=============\n"
      # first run: multi experiment joint refinement of detector with fixed beam and
      # crystals
      print "PHASE 1"

      # SET THIS TEST TO FALSE TO REFINE WHOLE DETECTOR AS SINGLE JOB
      if params.detector_phase.refinement.parameterisation.detector.hierarchy_level > 0:
        experiments = detector_parallel_refiners(params.detector_phase, experiments, reflections)
      else:
        experiments = detector_refiner(params.detector_phase, experiments, reflections)

      # second run
      print "PHASE 2"
      experiments = crystals_refiner(params.crystals_phase, experiments, reflections)

    # Save the refined experiments to file
    output_experiments_filename = params.output.experiments_filename
    print 'Saving refined experiments to {0}'.format(output_experiments_filename)
    from dxtbx.model.experiment.experiment_list import ExperimentListDumper
    dump = ExperimentListDumper(experiments)
    dump.as_json(output_experiments_filename)

    # Write out refined reflections, if requested
    if params.output.reflections_filename:
      print 'Saving refined reflections to {0}'.format(
        params.output.reflections_filename)
      reflections.as_pickle(params.output.reflections_filename)

    return
示例#5
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)
def discover_better_experimental_model(imagesets,
                                       spot_lists,
                                       params,
                                       dps_params,
                                       nproc=1,
                                       wide_search_binning=1):
    assert len(imagesets) == len(spot_lists)
    assert len(imagesets) > 0
    # XXX should check that all the detector and beam objects are the same
    from dials.algorithms.indexing.indexer import indexer_base
    spot_lists_mm = [
        indexer_base.map_spots_pixel_to_mm_rad(spots, imageset.get_detector(),
                                               imageset.get_scan())
        for spots, imageset in zip(spot_lists, imagesets)
    ]

    spot_lists_mm = []
    max_cell_list = []

    detector = imagesets[0].get_detector()
    beam = imagesets[0].get_beam()

    beam_panel = detector.get_panel_intersection(beam.get_s0())

    if beam_panel == -1:
        from libtbx.utils import Sorry
        raise Sorry, 'input beam does not intersect detector'

    for imageset, spots in zip(imagesets, spot_lists):
        if 'imageset_id' not in spots:
            spots['imageset_id'] = spots['id']

        spots_mm = indexer_base.map_spots_pixel_to_mm_rad(
            spots=spots,
            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 dps_params.d_min is not None:
            d_spacings = 1 / spots_mm['rlp'].norms()
            sel = d_spacings > dps_params.d_min
            spots_mm = spots_mm.select(sel)

        # derive a max_cell from mm spots

        if params.max_cell is None:
            from dials.algorithms.indexing.indexer import find_max_cell
            max_cell = find_max_cell(spots_mm,
                                     max_cell_multiplier=1.3,
                                     step_size=10,
                                     nearest_neighbor_percentile=0.05)
            max_cell_list.append(max_cell)

        if (params.max_reflections is not None
                and spots_mm.size() > params.max_reflections):
            logger.info('Selecting subset of %i reflections for analysis' %
                        params.max_reflections)
            perm = flex.random_permutation(spots_mm.size())
            sel = perm[:params.max_reflections]
            spots_mm = spots_mm.select(sel)

        spot_lists_mm.append(spots_mm)

    if params.max_cell is None:
        max_cell = flex.median(flex.double(max_cell_list))
    else:
        max_cell = params.max_cell
    args = [(imageset, spots, max_cell, dps_params)
            for imageset, spots in zip(imagesets, spot_lists_mm)]

    from libtbx import easy_mp
    results = easy_mp.parallel_map(func=run_dps,
                                   iterable=args,
                                   processes=nproc,
                                   method="multiprocessing",
                                   preserve_order=True,
                                   asynchronous=True,
                                   preserve_exception_message=True)
    solution_lists = [r["solutions"] for r in results]
    amax_list = [r["amax"] for r in results]
    assert len(solution_lists) > 0

    detector = imagesets[0].get_detector()
    beam = imagesets[0].get_beam()

    # perform calculation
    if dps_params.indexing.improve_local_scope == "origin_offset":
        discoverer = better_experimental_model_discovery(
            imagesets,
            spot_lists_mm,
            solution_lists,
            amax_list,
            dps_params,
            wide_search_binning=wide_search_binning)
        new_detector = discoverer.optimize_origin_offset_local_scope()
        old_beam_centre = detector.get_ray_intersection(beam.get_s0())[1]
        new_beam_centre = new_detector.get_ray_intersection(beam.get_s0())[1]
        logger.info("Old beam centre: %.2f mm, %.2f mm" % old_beam_centre)
        logger.info("New beam centre: %.2f mm, %.2f mm" % new_beam_centre)
        logger.info(
            "Shift: %.2f mm, %.2f mm" %
            (matrix.col(old_beam_centre) - matrix.col(new_beam_centre)).elems)
        return new_detector, beam
    elif dps_params.indexing.improve_local_scope == "S0_vector":
        raise NotImplementedError()