Пример #1
0
  def get_origin_offset_score(self,trial_origin_offset):
    trial_detector = dps_extended.get_new_detector(self.detector,trial_origin_offset)

    reciprocal_space_vectors = self.raw_spot_positions_mm_to_reciprocal_space(
      self.raw_spot_input, trial_detector, self.inv_wave, self.S0_vector, self.axis,
      self.panelID)

    return self.sum_score_detail(reciprocal_space_vectors)
Пример #2
0
  def get_origin_offset_score(self,trial_origin_offset):
    trial_detector = dps_extended.get_new_detector(self.detector,trial_origin_offset)

    reciprocal_space_vectors = self.raw_spot_positions_mm_to_reciprocal_space(
      self.raw_spot_input, trial_detector, self.inv_wave, self.S0_vector, self.axis,
      self.panelID)

    return self.sum_score_detail(reciprocal_space_vectors)
  def get_origin_offset_score(self, trial_origin_offset, solutions, amax, spots_mm, imageset):
    from rstbx.indexing_api import lattice # import dependency
    from rstbx.indexing_api import dps_extended
    trial_detector = dps_extended.get_new_detector(imageset.get_detector(), trial_origin_offset)

    from dials.algorithms.indexing.indexer import indexer_base
    indexer_base.map_centroids_to_reciprocal_space(
      spots_mm, trial_detector, imageset.get_beam(), imageset.get_goniometer())

    return self.sum_score_detail(spots_mm['rlp'], solutions, amax=amax)
Пример #4
0
def _get_origin_offset_score(trial_origin_offset, solutions, amax, spots_mm,
                             experiment):
    trial_detector = dps_extended.get_new_detector(experiment.detector,
                                                   trial_origin_offset)
    experiment = copy.deepcopy(experiment)
    experiment.detector = trial_detector

    # Key point for this is that the spots must correspond to detector
    # positions not to the correct RS position => reset any fixed rotation
    # to identity

    experiment.goniometer.set_fixed_rotation((1, 0, 0, 0, 1, 0, 0, 0, 1))
    spots_mm.map_centroids_to_reciprocal_space([experiment])
    return _sum_score_detail(spots_mm["rlp"], solutions, amax=amax)
    def get_origin_offset_score(self, trial_origin_offset, solutions, amax,
                                spots_mm, imageset):
        trial_detector = dps_extended.get_new_detector(imageset.get_detector(),
                                                       trial_origin_offset)

        # Key point for this is that the spots must correspond to detector
        # positions not to the correct RS position => reset any fixed rotation
        # to identity - copy in case called from elsewhere

        gonio = copy.deepcopy(imageset.get_goniometer())
        gonio.set_fixed_rotation((1, 0, 0, 0, 1, 0, 0, 0, 1))
        spots_mm.map_centroids_to_reciprocal_space(trial_detector,
                                                   imageset.get_beam(), gonio)

        return self.sum_score_detail(spots_mm["rlp"], solutions, amax=amax)
  def get_origin_offset_score(self, trial_origin_offset, solutions, amax, spots_mm, imageset):
    from rstbx.indexing_api import lattice # import dependency
    from rstbx.indexing_api import dps_extended
    trial_detector = dps_extended.get_new_detector(imageset.get_detector(), trial_origin_offset)

    from dials.algorithms.indexing.indexer import indexer_base
    # Key point for this is that the spots must correspond to detector
    # positions not to the correct RS position => reset any fixed rotation
    # to identity - copy in case called from elsewhere
    import copy
    gonio = copy.deepcopy(imageset.get_goniometer())
    gonio.set_fixed_rotation((1, 0, 0, 0, 1, 0, 0, 0, 1))
    indexer_base.map_centroids_to_reciprocal_space(
      spots_mm, trial_detector, imageset.get_beam(), gonio)

    return self.sum_score_detail(spots_mm['rlp'], solutions, amax=amax)
  def get_origin_offset_score(self, trial_origin_offset, solutions, amax, spots_mm, imageset):
    from rstbx.indexing_api import lattice # import dependency
    from rstbx.indexing_api import dps_extended
    trial_detector = dps_extended.get_new_detector(imageset.get_detector(), trial_origin_offset)

    from dials.algorithms.indexing.indexer import indexer_base
    # Key point for this is that the spots must correspond to detector
    # positions not to the correct RS position => reset any fixed rotation
    # to identity - copy in case called from elsewhere
    import copy
    gonio = copy.deepcopy(imageset.get_goniometer())
    gonio.set_fixed_rotation((1, 0, 0, 0, 1, 0, 0, 0, 1))
    indexer_base.map_centroids_to_reciprocal_space(
      spots_mm, trial_detector, imageset.get_beam(), gonio)

    return self.sum_score_detail(spots_mm['rlp'], solutions, amax=amax)
Пример #8
0
  def optimize_origin_offset_local_scope(self):
      """Local scope: find the optimal origin-offset closest to the current overall detector position
         (local minimum, simple minimization)"""
      # construct two vectors that are perpendicular to the beam.  Gives a basis for refining beam
      if self.axis is None:
        beamr0 = self.S0_vector.cross(matrix.col((1,0,0))).normalize()
      else:
        beamr0 = self.S0_vector.cross(self.axis).normalize()
      beamr1 = beamr0.cross(self.S0_vector).normalize()
      beamr2 = beamr1.cross(self.S0_vector).normalize()

      assert approx_equal(self.S0_vector.dot(beamr1), 0.)
      assert approx_equal(self.S0_vector.dot(beamr2), 0.)
      assert approx_equal(beamr2.dot(beamr1), 0.)
      # so the orthonormal vectors are self.S0_vector, beamr1 and beamr2

      # DO A SIMPLEX MINIMIZATION
      from scitbx.simplex import simplex_opt
      class test_simplex_method(object):
        def __init__(selfOO):
          selfOO.starting_simplex=[]
          selfOO.n = 2
          for ii in range(selfOO.n+1):
            selfOO.starting_simplex.append(flex.random_double(selfOO.n))
          selfOO.optimizer = simplex_opt( dimension=selfOO.n,
                                        matrix  = selfOO.starting_simplex,
                                        evaluator = selfOO,
                                        tolerance=1e-7)
          selfOO.x = selfOO.optimizer.get_solution()

        def target(selfOO, vector):
          trial_origin_offset = vector[0]*0.2*beamr1 + vector[1]*0.2*beamr2
          return -self.get_origin_offset_score(trial_origin_offset)

      MIN = test_simplex_method()
      trial_origin_offset =  MIN.x[0]*0.2*beamr1 + MIN.x[1]*0.2*beamr2
      #print "The Origin Offset best score is",self.get_origin_offset_score(trial_origin_offset)

      if self.horizon_phil.indexing.plot_search_scope:
        scope = self.horizon_phil.indexing.mm_search_scope
        plot_px_sz = self.detector[0].get_pixel_size()[0]
        grid = max(1,int(scope/plot_px_sz))
        scores = flex.double()
        for y in range(-grid,grid+1):
         for x in range(-grid,grid+1):
          new_origin_offset = x*plot_px_sz*beamr1 + y*plot_px_sz*beamr2
          scores.append( self.get_origin_offset_score(new_origin_offset) )

        def show_plot(widegrid,excursi):
          excursi.reshape(flex.grid(widegrid, widegrid))

          def igrid(x): return x - (widegrid//2)
          from matplotlib import pyplot as plt
          plt.figure()
          CS = plt.contour([igrid(i)*plot_px_sz for i in range(widegrid)],
                           [igrid(i)*plot_px_sz for i in range(widegrid)], excursi.as_numpy_array())
          plt.clabel(CS, inline=1, fontsize=10, fmt="%6.3f")
          plt.title("Wide scope search for detector origin offset")
          plt.scatter([0.0],[0.0],color='g',marker='o')
          plt.scatter([0.2*MIN.x[0]] , [0.2*MIN.x[1]],color='r',marker='*')
          plt.axes().set_aspect("equal")
          plt.xlabel("offset (mm) along beamr1 vector")
          plt.ylabel("offset (mm) along beamr2 vector")
          plt.show()

        show_plot(widegrid = 2 * grid + 1, excursi = scores)

      return dps_extended.get_new_detector(self.detector, trial_origin_offset)
Пример #9
0
    def optimize_origin_offset_local_scope(self):
        """Local scope: find the optimal origin-offset closest to the current overall detector position
       (local minimum, simple minimization)"""

        from libtbx.test_utils import approx_equal
        from rstbx.indexing_api import dps_extended

        detector = self.imagesets[0].get_detector()
        beam = self.imagesets[0].get_beam()
        s0 = matrix.col(beam.get_s0())
        # construct two vectors that are perpendicular to the beam.  Gives a basis for refining beam
        axis = matrix.col((1, 0, 0))
        beamr0 = s0.cross(axis).normalize()
        beamr1 = beamr0.cross(s0).normalize()
        beamr2 = beamr1.cross(s0).normalize()

        assert approx_equal(s0.dot(beamr1), 0.)
        assert approx_equal(s0.dot(beamr2), 0.)
        assert approx_equal(beamr2.dot(beamr1), 0.)
        # so the orthonormal vectors are self.S0_vector, beamr1 and beamr2

        if self.horizon_phil.indexing.mm_search_scope:
            scope = self.horizon_phil.indexing.mm_search_scope
            plot_px_sz = self.imagesets[0].get_detector()[0].get_pixel_size(
            )[0]
            plot_px_sz *= self.wide_search_binning
            grid = max(1, int(scope / plot_px_sz))
            widegrid = 2 * grid + 1
            scores = flex.double()
            for y in xrange(-grid, grid + 1):
                for x in xrange(-grid, grid + 1):
                    new_origin_offset = x * plot_px_sz * beamr1 + y * plot_px_sz * beamr2
                    score = 0
                    for i in range(len(self.imagesets)):
                        score += self.get_origin_offset_score(
                            new_origin_offset, self.solution_lists[i],
                            self.amax_lists[i], self.spot_lists[i],
                            self.imagesets[i])
                    scores.append(score)

            def igrid(x):
                return x - (widegrid // 2)

            idxs = [igrid(i) * plot_px_sz for i in xrange(widegrid)]

            # if there are several similarly high scores, then choose the closest
            # one to the current beam centre
            potential_offsets = flex.vec3_double()
            sel = scores > (0.9 * flex.max(scores))
            for i in sel.iselection():
                offset = (idxs[i % widegrid]) * beamr1 + (
                    idxs[i // widegrid]) * beamr2
                potential_offsets.append(offset.elems)
                #print offset.length(), scores[i]
            wide_search_offset = matrix.col(potential_offsets[flex.min_index(
                potential_offsets.norms())])

            #plot_max = flex.max(scores)
            #idx_max = flex.max_index(scores)
            #wide_search_offset = (idxs[idx_max%widegrid])*beamr1 + (idxs[idx_max//widegrid])*beamr2

        else:
            wide_search_offset = None

        # DO A SIMPLEX MINIMIZATION
        from scitbx.simplex import simplex_opt

        class test_simplex_method(object):
            def __init__(selfOO, wide_search_offset=None):
                selfOO.starting_simplex = []
                selfOO.n = 2
                selfOO.wide_search_offset = wide_search_offset
                for ii in range(selfOO.n + 1):
                    selfOO.starting_simplex.append(flex.random_double(
                        selfOO.n))
                selfOO.optimizer = simplex_opt(dimension=selfOO.n,
                                               matrix=selfOO.starting_simplex,
                                               evaluator=selfOO,
                                               tolerance=1e-7)
                selfOO.x = selfOO.optimizer.get_solution()
                selfOO.offset = selfOO.x[0] * 0.2 * beamr1 + selfOO.x[
                    1] * 0.2 * beamr2
                if selfOO.wide_search_offset is not None:
                    selfOO.offset += selfOO.wide_search_offset

            def target(selfOO, vector):
                trial_origin_offset = vector[0] * 0.2 * beamr1 + vector[
                    1] * 0.2 * beamr2
                if selfOO.wide_search_offset is not None:
                    trial_origin_offset += selfOO.wide_search_offset
                target = 0
                for i in range(len(self.imagesets)):
                    target -= self.get_origin_offset_score(
                        trial_origin_offset, self.solution_lists[i],
                        self.amax_lists[i], self.spot_lists[i],
                        self.imagesets[i])
                return target

        MIN = test_simplex_method(wide_search_offset=wide_search_offset)
        new_offset = MIN.offset

        if self.horizon_phil.indexing.plot_search_scope:
            scope = self.horizon_phil.indexing.mm_search_scope
            plot_px_sz = self.imagesets[0].get_detector()[0].get_pixel_size(
            )[0]
            grid = max(1, int(scope / plot_px_sz))
            scores = flex.double()
            for y in xrange(-grid, grid + 1):
                for x in xrange(-grid, grid + 1):
                    new_origin_offset = x * plot_px_sz * beamr1 + y * plot_px_sz * beamr2
                    score = 0
                    for i in range(len(self.imagesets)):
                        score += self.get_origin_offset_score(
                            new_origin_offset, self.solution_lists[i],
                            self.amax_lists[i], self.spot_lists[i],
                            self.imagesets[i])
                    scores.append(score)

            def show_plot(widegrid, excursi):
                excursi.reshape(flex.grid(widegrid, widegrid))
                plot_max = flex.max(excursi)
                idx_max = flex.max_index(excursi)

                def igrid(x):
                    return x - (widegrid // 2)

                idxs = [igrid(i) * plot_px_sz for i in xrange(widegrid)]

                from matplotlib import pyplot as plt
                plt.figure()
                CS = plt.contour(
                    [igrid(i) * plot_px_sz for i in xrange(widegrid)],
                    [igrid(i) * plot_px_sz for i in xrange(widegrid)],
                    excursi.as_numpy_array())
                plt.clabel(CS, inline=1, fontsize=10, fmt="%6.3f")
                plt.title("Wide scope search for detector origin offset")
                plt.scatter([0.0], [0.0], color='g', marker='o')
                plt.scatter([new_offset[0]], [new_offset[1]],
                            color='r',
                            marker='*')
                plt.scatter([idxs[idx_max % widegrid]],
                            [idxs[idx_max // widegrid]],
                            color='k',
                            marker='s')
                plt.axes().set_aspect("equal")
                plt.xlabel("offset (mm) along beamr1 vector")
                plt.ylabel("offset (mm) along beamr2 vector")
                plt.savefig("search_scope.png")

                #changing value
                trial_origin_offset = (idxs[idx_max % widegrid]) * beamr1 + (
                    idxs[idx_max // widegrid]) * beamr2
                return trial_origin_offset

            show_plot(widegrid=2 * grid + 1, excursi=scores)

        return dps_extended.get_new_detector(self.imagesets[0].get_detector(),
                                             new_offset)
Пример #10
0
def optimize_origin_offset_local_scope(
    experiments,
    reflection_lists,
    solution_lists,
    amax_lists,
    mm_search_scope=4,
    wide_search_binning=1,
    plot_search_scope=False,
):
    """Local scope: find the optimal origin-offset closest to the current overall detector position
    (local minimum, simple minimization)"""

    beam = experiments[0].beam
    s0 = matrix.col(beam.get_s0())
    # construct two vectors that are perpendicular to the beam.  Gives a basis for refining beam
    axis = matrix.col((1, 0, 0))
    beamr0 = s0.cross(axis).normalize()
    beamr1 = beamr0.cross(s0).normalize()
    beamr2 = beamr1.cross(s0).normalize()

    assert approx_equal(s0.dot(beamr1), 0.0)
    assert approx_equal(s0.dot(beamr2), 0.0)
    assert approx_equal(beamr2.dot(beamr1), 0.0)
    # so the orthonormal vectors are s0, beamr1 and beamr2

    if mm_search_scope:
        plot_px_sz = experiments[0].detector[0].get_pixel_size()[0]
        plot_px_sz *= wide_search_binning
        grid = max(1, int(mm_search_scope / plot_px_sz))
        widegrid = 2 * grid + 1

        def get_experiment_score_for_coord(x, y):
            new_origin_offset = x * plot_px_sz * beamr1 + y * plot_px_sz * beamr2
            return sum(
                _get_origin_offset_score(
                    new_origin_offset,
                    solution_lists[i],
                    amax_lists[i],
                    reflection_lists[i],
                    experiment,
                ) for i, experiment in enumerate(experiments))

        scores = flex.double(
            get_experiment_score_for_coord(x, y)
            for y in range(-grid, grid + 1) for x in range(-grid, grid + 1))

        def igrid(x):
            return x - (widegrid // 2)

        idxs = [igrid(i) * plot_px_sz for i in range(widegrid)]

        # if there are several similarly high scores, then choose the closest
        # one to the current beam centre
        potential_offsets = flex.vec3_double()
        if scores.all_eq(0):
            raise Sorry("No valid scores")
        sel = scores > (0.9 * flex.max(scores))
        for i in sel.iselection():
            offset = (idxs[i % widegrid]) * beamr1 + (idxs[i //
                                                           widegrid]) * beamr2
            potential_offsets.append(offset.elems)
            # print offset.length(), scores[i]
        wide_search_offset = matrix.col(potential_offsets[flex.min_index(
            potential_offsets.norms())])

    else:
        wide_search_offset = None

    # Do a simplex minimization
    class simplex_minimizer(object):
        def __init__(self, wide_search_offset):
            self.n = 2
            self.wide_search_offset = wide_search_offset
            self.optimizer = simplex_opt(
                dimension=self.n,
                matrix=[flex.random_double(self.n) for _ in range(self.n + 1)],
                evaluator=self,
                tolerance=1e-7,
            )
            self.x = self.optimizer.get_solution()
            self.offset = self.x[0] * 0.2 * beamr1 + self.x[1] * 0.2 * beamr2
            if self.wide_search_offset is not None:
                self.offset += self.wide_search_offset

        def target(self, vector):
            trial_origin_offset = vector[0] * 0.2 * beamr1 + vector[
                1] * 0.2 * beamr2
            if self.wide_search_offset is not None:
                trial_origin_offset += self.wide_search_offset
            target = 0
            for i, experiment in enumerate(experiments):
                target -= _get_origin_offset_score(
                    trial_origin_offset,
                    solution_lists[i],
                    amax_lists[i],
                    reflection_lists[i],
                    experiment,
                )
            return target

    new_offset = simplex_minimizer(wide_search_offset).offset

    if plot_search_scope:
        plot_px_sz = experiments[0].get_detector()[0].get_pixel_size()[0]
        grid = max(1, int(mm_search_scope / plot_px_sz))
        scores = flex.double()
        for y in range(-grid, grid + 1):
            for x in range(-grid, grid + 1):
                new_origin_offset = x * plot_px_sz * beamr1 + y * plot_px_sz * beamr2
                score = 0
                for i, experiment in enumerate(experiments):
                    score += _get_origin_offset_score(
                        new_origin_offset,
                        solution_lists[i],
                        amax_lists[i],
                        reflection_lists[i],
                        experiment,
                    )
                scores.append(score)

        def show_plot(widegrid, excursi):
            excursi.reshape(flex.grid(widegrid, widegrid))
            idx_max = flex.max_index(excursi)

            def igrid(x):
                return x - (widegrid // 2)

            idxs = [igrid(i) * plot_px_sz for i in range(widegrid)]

            from matplotlib import pyplot as plt

            plt.figure()
            CS = plt.contour(
                [igrid(i) * plot_px_sz for i in range(widegrid)],
                [igrid(i) * plot_px_sz for i in range(widegrid)],
                excursi.as_numpy_array(),
            )
            plt.clabel(CS, inline=1, fontsize=10, fmt="%6.3f")
            plt.title("Wide scope search for detector origin offset")
            plt.scatter([0.0], [0.0], color="g", marker="o")
            plt.scatter([new_offset[0]], [new_offset[1]],
                        color="r",
                        marker="*")
            plt.scatter(
                [idxs[idx_max % widegrid]],
                [idxs[idx_max // widegrid]],
                color="k",
                marker="s",
            )
            plt.axes().set_aspect("equal")
            plt.xlabel("offset (mm) along beamr1 vector")
            plt.ylabel("offset (mm) along beamr2 vector")
            plt.savefig("search_scope.png")

            # changing value
            trial_origin_offset = (idxs[idx_max % widegrid]) * beamr1 + (
                idxs[idx_max // widegrid]) * beamr2
            return trial_origin_offset

        show_plot(widegrid=2 * grid + 1, excursi=scores)

    new_experiments = copy.deepcopy(experiments)
    for expt in new_experiments:
        expt.detector = dps_extended.get_new_detector(expt.detector,
                                                      new_offset)
    return new_experiments
Пример #11
0
  def optimize_origin_offset_local_scope(self):
      """Local scope: find the optimal origin-offset closest to the current overall detector position
         (local minimum, simple minimization)"""
      # construct two vectors that are perpendicular to the beam.  Gives a basis for refining beam
      if self.axis is None:
        beamr0 = self.S0_vector.cross(matrix.col((1,0,0))).normalize()
      else:
        beamr0 = self.S0_vector.cross(self.axis).normalize()
      beamr1 = beamr0.cross(self.S0_vector).normalize()
      beamr2 = beamr1.cross(self.S0_vector).normalize()

      assert approx_equal(self.S0_vector.dot(beamr1), 0.)
      assert approx_equal(self.S0_vector.dot(beamr2), 0.)
      assert approx_equal(beamr2.dot(beamr1), 0.)
      # so the orthonormal vectors are self.S0_vector, beamr1 and beamr2

      # DO A SIMPLEX MINIMIZATION
      from scitbx.simplex import simplex_opt
      class test_simplex_method(object):
        def __init__(selfOO):
          selfOO.starting_simplex=[]
          selfOO.n = 2
          for ii in range(selfOO.n+1):
            selfOO.starting_simplex.append(flex.random_double(selfOO.n))
          selfOO.optimizer = simplex_opt( dimension=selfOO.n,
                                        matrix  = selfOO.starting_simplex,
                                        evaluator = selfOO,
                                        tolerance=1e-7)
          selfOO.x = selfOO.optimizer.get_solution()

        def target(selfOO, vector):
          trial_origin_offset = vector[0]*0.2*beamr1 + vector[1]*0.2*beamr2
          return -self.get_origin_offset_score(trial_origin_offset)

      MIN = test_simplex_method()
      trial_origin_offset =  MIN.x[0]*0.2*beamr1 + MIN.x[1]*0.2*beamr2
      #print "The Origin Offset best score is",self.get_origin_offset_score(trial_origin_offset)

      if self.horizon_phil.indexing.plot_search_scope:
        scope = self.horizon_phil.indexing.mm_search_scope
        plot_px_sz = self.detector[0].get_pixel_size()[0]
        grid = max(1,int(scope/plot_px_sz))
        scores = flex.double()
        for y in xrange(-grid,grid+1):
         for x in xrange(-grid,grid+1):
          new_origin_offset = x*plot_px_sz*beamr1 + y*plot_px_sz*beamr2
          scores.append( self.get_origin_offset_score(new_origin_offset) )

        def show_plot(widegrid,excursi):
          excursi.reshape(flex.grid(widegrid, widegrid))

          def igrid(x): return x - (widegrid//2)
          from matplotlib import pyplot as plt
          plt.figure()
          CS = plt.contour([igrid(i)*plot_px_sz for i in xrange(widegrid)],
                           [igrid(i)*plot_px_sz for i in xrange(widegrid)], excursi.as_numpy_array())
          plt.clabel(CS, inline=1, fontsize=10, fmt="%6.3f")
          plt.title("Wide scope search for detector origin offset")
          plt.scatter([0.0],[0.0],color='g',marker='o')
          plt.scatter([0.2*MIN.x[0]] , [0.2*MIN.x[1]],color='r',marker='*')
          plt.axes().set_aspect("equal")
          plt.xlabel("offset (mm) along beamr1 vector")
          plt.ylabel("offset (mm) along beamr2 vector")
          plt.show()

        show_plot(widegrid = 2 * grid + 1, excursi = scores)

      return dps_extended.get_new_detector(self.detector, trial_origin_offset)
  def optimize_origin_offset_local_scope(self):
    """Local scope: find the optimal origin-offset closest to the current overall detector position
       (local minimum, simple minimization)"""

    from libtbx.test_utils import approx_equal
    from rstbx.indexing_api import dps_extended

    detector = self.imagesets[0].get_detector()
    beam = self.imagesets[0].get_beam()
    s0 = matrix.col(beam.get_s0())
    # construct two vectors that are perpendicular to the beam.  Gives a basis for refining beam
    axis = matrix.col((1,0,0))
    beamr0 = s0.cross(axis).normalize()
    beamr1 = beamr0.cross(s0).normalize()
    beamr2 = beamr1.cross(s0).normalize()

    assert approx_equal(s0.dot(beamr1), 0.)
    assert approx_equal(s0.dot(beamr2), 0.)
    assert approx_equal(beamr2.dot(beamr1), 0.)
    # so the orthonormal vectors are self.S0_vector, beamr1 and beamr2

    if self.horizon_phil.indexing.mm_search_scope:
      scope = self.horizon_phil.indexing.mm_search_scope
      plot_px_sz = self.imagesets[0].get_detector()[0].get_pixel_size()[0]
      plot_px_sz *= self.wide_search_binning
      grid = max(1,int(scope/plot_px_sz))
      widegrid = 2 * grid + 1
      scores = flex.double()
      for y in xrange(-grid,grid+1):
        for x in xrange(-grid,grid+1):
          new_origin_offset = x*plot_px_sz*beamr1 + y*plot_px_sz*beamr2
          score = 0
          for i in range(len(self.imagesets)):
            score += self.get_origin_offset_score(new_origin_offset,
                                                  self.solution_lists[i],
                                                  self.amax_lists[i],
                                                  self.spot_lists[i],
                                                  self.imagesets[i])
          scores.append(score)

      def igrid(x): return x - (widegrid//2)

      idxs = [igrid(i)*plot_px_sz for i in xrange(widegrid)]

      # if there are several similarly high scores, then choose the closest
      # one to the current beam centre
      potential_offsets = flex.vec3_double()
      sel = scores > (0.9*flex.max(scores))
      for i in sel.iselection():
        offset = (idxs[i%widegrid])*beamr1 + (idxs[i//widegrid])*beamr2
        potential_offsets.append(offset.elems)
        #print offset.length(), scores[i]
      wide_search_offset = matrix.col(
        potential_offsets[flex.min_index(potential_offsets.norms())])

      #plot_max = flex.max(scores)
      #idx_max = flex.max_index(scores)
      #wide_search_offset = (idxs[idx_max%widegrid])*beamr1 + (idxs[idx_max//widegrid])*beamr2

    else:
      wide_search_offset = None

    # DO A SIMPLEX MINIMIZATION
    from scitbx.simplex import simplex_opt
    class test_simplex_method(object):
      def __init__(selfOO, wide_search_offset=None):
        selfOO.starting_simplex=[]
        selfOO.n = 2
        selfOO.wide_search_offset = wide_search_offset
        for ii in range(selfOO.n+1):
          selfOO.starting_simplex.append(flex.random_double(selfOO.n))
        selfOO.optimizer = simplex_opt(dimension=selfOO.n,
                                       matrix=selfOO.starting_simplex,
                                       evaluator=selfOO,
                                       tolerance=1e-7)
        selfOO.x = selfOO.optimizer.get_solution()
        selfOO.offset = selfOO.x[0]*0.2*beamr1 + selfOO.x[1]*0.2*beamr2
        if selfOO.wide_search_offset is not None:
          selfOO.offset += selfOO.wide_search_offset

      def target(selfOO, vector):
        trial_origin_offset = vector[0]*0.2*beamr1 + vector[1]*0.2*beamr2
        if selfOO.wide_search_offset is not None:
          trial_origin_offset += selfOO.wide_search_offset
        target = 0
        for i in range(len(self.imagesets)):
          target -= self.get_origin_offset_score(trial_origin_offset,
                                                 self.solution_lists[i],
                                                 self.amax_lists[i],
                                                 self.spot_lists[i],
                                                 self.imagesets[i])
        return target

    MIN = test_simplex_method(wide_search_offset=wide_search_offset)
    new_offset = MIN.offset

    if self.horizon_phil.indexing.plot_search_scope:
      scope = self.horizon_phil.indexing.mm_search_scope
      plot_px_sz = self.imagesets[0].get_detector()[0].get_pixel_size()[0]
      grid = max(1,int(scope/plot_px_sz))
      scores = flex.double()
      for y in xrange(-grid,grid+1):
        for x in xrange(-grid,grid+1):
          new_origin_offset = x*plot_px_sz*beamr1 + y*plot_px_sz*beamr2
          score = 0
          for i in range(len(self.imagesets)):
            score += self.get_origin_offset_score(new_origin_offset,
                                                  self.solution_lists[i],
                                                  self.amax_lists[i],
                                                  self.spot_lists[i],
                                                  self.imagesets[i])
          scores.append(score)

      def show_plot(widegrid,excursi):
        excursi.reshape(flex.grid(widegrid, widegrid))
        plot_max = flex.max(excursi)
        idx_max = flex.max_index(excursi)

        def igrid(x): return x - (widegrid//2)
        idxs = [igrid(i)*plot_px_sz for i in xrange(widegrid)]

        from matplotlib import pyplot as plt
        plt.figure()
        CS = plt.contour([igrid(i)*plot_px_sz for i in xrange(widegrid)],
                         [igrid(i)*plot_px_sz for i in xrange(widegrid)], excursi.as_numpy_array())
        plt.clabel(CS, inline=1, fontsize=10, fmt="%6.3f")
        plt.title("Wide scope search for detector origin offset")
        plt.scatter([0.0],[0.0],color='g',marker='o')
        plt.scatter([new_offset[0]] , [new_offset[1]],color='r',marker='*')
        plt.scatter([idxs[idx_max%widegrid]] , [idxs[idx_max//widegrid]],color='k',marker='s')
        plt.axes().set_aspect("equal")
        plt.xlabel("offset (mm) along beamr1 vector")
        plt.ylabel("offset (mm) along beamr2 vector")
        plt.show()

        #changing value
        trial_origin_offset =  (idxs[idx_max%widegrid])*beamr1 + (idxs[idx_max//widegrid])*beamr2
        return trial_origin_offset

      show_plot(widegrid = 2 * grid + 1, excursi = scores)

    return dps_extended.get_new_detector(self.imagesets[0].get_detector(), new_offset)