Esempio n. 1
0
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).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_panel, old_beam_centre = detector.get_ray_intersection(
            beam.get_s0())
        new_panel, new_beam_centre = new_detector.get_ray_intersection(
            beam.get_s0())

        old_beam_centre_px = detector[old_panel].millimeter_to_pixel(
            old_beam_centre)
        new_beam_centre_px = new_detector[new_panel].millimeter_to_pixel(
            new_beam_centre)

        logger.info("Old beam centre: %.2f, %.2f mm" % old_beam_centre +
                    " (%.1f, %.1f px)" % old_beam_centre_px)
        logger.info("New beam centre: %.2f, %.2f mm" % new_beam_centre +
                    " (%.1f, %.1f px)" % new_beam_centre_px)
        logger.info(
            "Shift: %.2f, %.2f mm" %
            (matrix.col(old_beam_centre) - matrix.col(new_beam_centre)).elems +
            " (%.1f, %.1f px)" % (matrix.col(old_beam_centre_px) -
                                  matrix.col(new_beam_centre_px)).elems)
        return new_detector, beam
    elif dps_params.indexing.improve_local_scope == "S0_vector":
        raise NotImplementedError()
Esempio n. 2
0
def discover_better_experimental_model(
    experiments,
    reflections,
    params,
    nproc=1,
    d_min=None,
    mm_search_scope=4.0,
    wide_search_binning=1,
    plot_search_scope=False,
):
    assert len(experiments) == len(reflections)
    assert len(experiments) > 0

    refl_lists = []
    max_cell_list = []

    # The detector/beam of the first experiment is used to define the basis for the
    # optimisation, so assert that the beam intersects with the detector
    detector = experiments[0].detector
    beam = experiments[0].beam
    beam_panel = detector.get_panel_intersection(beam.get_s0())
    if beam_panel == -1:
        raise Sorry("input beam does not intersect detector")

    for expt, refl in zip(experiments, reflections):
        refl = copy.deepcopy(refl)
        refl["imageset_id"] = flex.int(len(refl), 0)
        refl.centroid_px_to_mm([expt])
        refl.map_centroids_to_reciprocal_space([expt])

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

        # derive a max_cell from mm spots
        if params.max_cell is None:
            max_cell = find_max_cell(refl,
                                     max_cell_multiplier=1.3,
                                     step_size=45).max_cell
            max_cell_list.append(max_cell)

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

        refl_lists.append(refl)

    if params.max_cell is None:
        max_cell = flex.median(flex.double(max_cell_list))
    else:
        max_cell = params.max_cell

    with concurrent.futures.ProcessPoolExecutor(max_workers=nproc) as pool:
        solution_lists = []
        amax_list = []
        for result in pool.map(run_dps, experiments, refl_lists,
                               itertools.repeat(max_cell)):
            if result.get("solutions"):
                solution_lists.append(result["solutions"])
                amax_list.append(result["amax"])

    if not solution_lists:
        raise Sorry("No solutions found")

    new_experiments = optimize_origin_offset_local_scope(
        experiments,
        refl_lists,
        solution_lists,
        amax_list,
        mm_search_scope=mm_search_scope,
        wide_search_binning=wide_search_binning,
        plot_search_scope=plot_search_scope,
    )
    new_detector = new_experiments[0].detector
    old_panel, old_beam_centre = detector.get_ray_intersection(beam.get_s0())
    new_panel, new_beam_centre = new_detector.get_ray_intersection(
        beam.get_s0())

    old_beam_centre_px = detector[old_panel].millimeter_to_pixel(
        old_beam_centre)
    new_beam_centre_px = new_detector[new_panel].millimeter_to_pixel(
        new_beam_centre)

    logger.info("Old beam centre: %.2f, %.2f mm" % old_beam_centre +
                " (%.1f, %.1f px)" % old_beam_centre_px)
    logger.info("New beam centre: %.2f, %.2f mm" % new_beam_centre +
                " (%.1f, %.1f px)" % new_beam_centre_px)
    logger.info(
        "Shift: %.2f, %.2f mm" %
        (matrix.col(old_beam_centre) - matrix.col(new_beam_centre)).elems +
        " (%.1f, %.1f px)" %
        (matrix.col(old_beam_centre_px) - matrix.col(new_beam_centre_px)).elems
    )
    return new_experiments
Esempio n. 3
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.search_beam_position \
             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).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)
Esempio n. 4
0
def run():
    from dials.util.options import OptionParser, reflections_and_experiments_from_files
    from dials.util import log

    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()
    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("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:
        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("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=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()