def get_predictions_accounting_for_centering(self,
                                                 cb_op_to_primitive=None,
                                                 **kwargs):
        # interface requires this function to set current_orientation
        # in the actual setting used for Miller index calculation
        if (self.horizons_phil.known_setting is None or self.horizons_phil.known_setting == self.setting_id ) and \
            self.horizons_phil.integration.model in ["use_case_3_simulated_annealing",
                                                    "use_case_3_simulated_annealing_7",
                                                    "use_case_3_simulated_annealing_9"]:
            if cb_op_to_primitive == None:
                raise Sorry(
                    "Can't use model_3 simulated annealing for non-primitive cells, contact authors."
                )
            if self.horizons_phil.integration.model == "use_case_3_simulated_annealing":
                self.best_params = dict(
                    zip(("half_mosaicity_deg", "wave_HE_ang", "wave_LE_ang",
                         "reserve_orientation", "rotation100_rad",
                         "rotation010_rad", "rotation001_rad"),
                        self.use_case_3_simulated_annealing(
                            self.horizons_phil.integration.
                            use_subpixel_translations)))
            elif self.horizons_phil.integration.model == "use_case_3_simulated_annealing_7":
                self.best_params = dict(
                    zip(("half_mosaicity_deg", "wave_HE_ang", "wave_LE_ang",
                         "reserve_orientation", "rotation100_rad",
                         "rotation010_rad", "rotation001_rad",
                         "domain_size_ang"),
                        self.use_case_3_simulated_annealing_7(
                            self.horizons_phil.integration.
                            use_subpixel_translations)))
            elif self.horizons_phil.integration.model == "use_case_3_simulated_annealing_9":
                self.best_params = dict(
                    zip(("half_mosaicity_deg", "wave_HE_ang", "wave_LE_ang",
                         "reserve_orientation", "rotation100_rad",
                         "rotation010_rad", "rotation001_rad",
                         "domain_size_ang", "ab_factor", "c_factor"),
                        self.use_case_3_simulated_annealing_9(
                            self.horizons_phil.integration.
                            use_subpixel_translations)))
            self.current_orientation = self.best_params["reserve_orientation"]
            self.current_cb_op_to_primitive = cb_op_to_primitive

            BPpredicted = self.bp3_wrapper.ucbp3.selected_predictions_labelit_format(
            )
            BPhkllist = self.bp3_wrapper.ucbp3.selected_hkls()
            self.predicted, self.hkllist = BPpredicted, BPhkllist
            self.partialities = dict(
                indices=BPhkllist.deep_copy(),
                data=self.bp3_wrapper.ucbp3.selected_partialities())
            #self.hi = self.bp3_wrapper.ucbp3.selected_hi_predictions()
            #self.lo = self.bp3_wrapper.ucbp3.selected_lo_predictions()
            #print list(self.partialities)
            #for x in range(len(self.hi)):
            #  print "%4d %4d %4d  %7.1f %7.1f %7.1f %7.1f PARTIAL %7.2f"%(
            #  self.hkllist[x][0], self.hkllist[x][1],self.hkllist[x][2],
            #  self.hi[x][0], self.hi[x][1],
            #  self.lo[x][0], self.lo[x][1], self.partialities[x])

            if self.inputai.active_areas != None:
                self.predicted, self.hkllist = self.inputai.active_areas(
                    self.predicted, self.hkllist, self.pixel_size)
            return

        if self.horizons_phil.integration.model == "user_supplied":

            lower_limit_domain_size = math.pow(
                self.inputai.getOrientation().unit_cell().volume(), 1. / 3.
            ) * self.horizons_phil.integration.mosaic.domain_size_lower_limit  # default 10-unit cell block size minimum reasonable domain
            actual_used_domain_size = kwargs.get("domain_size_ang",
                                                 lower_limit_domain_size)
            if cb_op_to_primitive == None:

                from cxi_user import pre_get_predictions
                self.bp3_wrapper = pre_get_predictions(
                    self.inputai,
                    self.horizons_phil,
                    raw_image=self.imagefiles.images[self.image_number],
                    imageindex=self.frame_numbers[self.image_number],
                    spotfinder=self.spotfinder,
                    limiting_resolution=self.limiting_resolution,
                    domain_size_ang=actual_used_domain_size)
                self.current_orientation = self.inputai.getOrientation()
                self.current_cb_op_to_primitive = cb_op_to_primitive

                BPpredicted = self.bp3_wrapper.ucbp3.selected_predictions_labelit_format(
                )
                BPhkllist = self.bp3_wrapper.ucbp3.selected_hkls()

                self.predicted, self.hkllist = BPpredicted, BPhkllist
                if self.inputai.active_areas != None:
                    self.predicted, self.hkllist = self.inputai.active_areas(
                        self.predicted, self.hkllist, self.pixel_size)
                return

            else:
                self.block_counter += 1
                rot_mat = matrix.sqr(
                    cb_op_to_primitive.c().r().as_double()).transpose()
                centered_orientation = self.inputai.getOrientation()
                self.current_orientation = centered_orientation
                self.current_cb_op_to_primitive = cb_op_to_primitive
                primitive_orientation = centered_orientation.change_basis(
                    rot_mat)
                self.inputai.setOrientation(primitive_orientation)
                from cxi_user import pre_get_predictions
                if self.block_counter < 2:
                    KLUDGE = self.horizons_phil.integration.mosaic.kludge1  # bugfix 1 of 2 for protocol 6, equation 2
                    self.inputai.setMosaicity(KLUDGE *
                                              self.inputai.getMosaicity())
                self.bp3_wrapper = pre_get_predictions(
                    self.inputai,
                    self.horizons_phil,
                    raw_image=self.imagefiles.images[self.image_number],
                    imageindex=self.frame_numbers[self.image_number],
                    spotfinder=self.spotfinder,
                    limiting_resolution=self.limiting_resolution,
                    domain_size_ang=actual_used_domain_size)

                BPpredicted = self.bp3_wrapper.ucbp3.selected_predictions_labelit_format(
                )
                BPhkllist = self.bp3_wrapper.ucbp3.selected_hkls()

                self.actual = actual_used_domain_size
                self.predicted = BPpredicted
                primitive_hkllist = BPhkllist
                #not sure if matrix needs to be transposed first for outputting HKL's???:
                self.hkllist = cb_op_to_primitive.inverse().apply(
                    primitive_hkllist)
                self.inputai.setOrientation(centered_orientation)
                if self.inputai.active_areas != None:
                    self.predicted, self.hkllist = self.inputai.active_areas(
                        self.predicted, self.hkllist, self.pixel_size)
                if self.block_counter < 2:
                    down = self.inputai.getMosaicity() / KLUDGE
                    print "Readjusting mosaicity back down to ", down
                    self.inputai.setMosaicity(down)
                return

        if cb_op_to_primitive == None:

            predicted = self.inputai.predict_all(
                self.image_centers[self.image_number],
                self.limiting_resolution)
            self.predicted = predicted.vec3(
            )  #only good for integrating one frame...
            self.hkllist = predicted.hkl()
            self.current_orientation = self.inputai.getOrientation()
            from cctbx import sgtbx
            self.cb_op_to_primitive = sgtbx.change_of_basis_op()

        else:
            rot_mat = matrix.sqr(
                cb_op_to_primitive.c().r().as_double()).transpose()
            centered_orientation = self.inputai.getOrientation()
            self.current_orientation = centered_orientation
            self.current_cb_op_to_primitive = cb_op_to_primitive
            primitive_orientation = centered_orientation.change_basis(rot_mat)
            self.inputai.setOrientation(primitive_orientation)
            predicted = self.inputai.predict_all(
                self.image_centers[self.image_number],
                self.limiting_resolution)
            self.predicted = predicted.vec3(
            )  #only good for integrating one frame...
            primitive_hkllist = predicted.hkl()
            #not sure if matrix needs to be transposed first for outputting HKL's???:
            self.hkllist = cb_op_to_primitive.inverse().apply(
                primitive_hkllist)
            self.inputai.setOrientation(centered_orientation)
        if self.inputai.active_areas != None:
            self.predicted, self.hkllist = self.inputai.active_areas(
                self.predicted, self.hkllist, self.pixel_size)

        if False:  #development only; compare the two methods:
            from matplotlib import pyplot as plt
            plt.plot([i[0] for i in BPpredicted], [i[1] for i in BPpredicted],
                     "r.")
            plt.plot([i[0] for i in predicted], [i[1] for i in predicted],
                     "b.")
            plt.show()
  def get_predictions_accounting_for_centering(self,experiments,reflections,cb_op_to_primitive,**kwargs):
    # interface requires this function to set current_orientation
    # in the actual setting used for Miller index calculation
    detector = experiments[0].detector
    crystal = experiments[0].crystal

    if self.horizons_phil.integration.model == "user_supplied":

      lower_limit_domain_size = math.pow(
       crystal.get_unit_cell().volume(),
       1./3.)*self.horizons_phil.integration.mosaic.domain_size_lower_limit # default 10-unit cell block size minimum reasonable domain
      actual_used_domain_size = kwargs.get("domain_size_ang",lower_limit_domain_size)

      self.block_counter+=1
      rot_mat = matrix.sqr(cb_op_to_primitive.c().r().as_double()).transpose()

      from cctbx.crystal_orientation import crystal_orientation, basis_type
      centered_orientation = crystal_orientation(crystal.get_A(),basis_type.reciprocal)
      self.current_orientation = centered_orientation
      self.current_cb_op_to_primitive = cb_op_to_primitive
      primitive_orientation = centered_orientation.change_basis(rot_mat)

      self.inputai.setOrientation(primitive_orientation)
      from cxi_user import pre_get_predictions
      if self.block_counter < 2:
        KLUDGE = self.horizons_phil.integration.mosaic.kludge1 # bugfix 1 of 2 for protocol 6, equation 2
        self.inputai.setMosaicity(KLUDGE*self.inputai.getMosaicity())

      oldbase = self.inputai.getBase()

      #print oldbase.xbeam, oldbase.ybeam
      newbeam = detector[0].get_beam_centre(experiments[0].beam.get_s0())
      newdistance = -detector[0].get_beam_centre_lab(experiments[0].beam.get_s0())[2]

      from labelit.dptbx import Parameters
      base = Parameters(xbeam = newbeam[0], ybeam = newbeam[1], #oldbase.xbeam, ybeam = oldbase.ybeam,
                        distance = newdistance, twotheta = 0.0)
      self.inputai.setBase(base)
      self.inputai.setWavelength(experiments[0].beam.get_wavelength())

      self.bp3_wrapper = pre_get_predictions(self.inputai, self.horizons_phil,
        raw_image = self.imagefiles.images[self.image_number],
        imageindex = self.frame_numbers[self.image_number],
        spotfinder = self.spotfinder,
        limiting_resolution = self.limiting_resolution,
        domain_size_ang = actual_used_domain_size,
        )

      BPpredicted = self.bp3_wrapper.ucbp3.selected_predictions_labelit_format()
      BPhkllist = self.bp3_wrapper.ucbp3.selected_hkls()

      self.actual = actual_used_domain_size
      primitive_hkllist = BPhkllist
      #not sure if matrix needs to be transposed first for outputting HKL's???:
      self.hkllist = cb_op_to_primitive.inverse().apply(primitive_hkllist)

      if self.horizons_phil.integration.spot_prediction == "dials":
        from dials.algorithms.spot_prediction import StillsReflectionPredictor
        predictor = StillsReflectionPredictor(experiments[0])
        Rcalc = flex.reflection_table.empty_standard(len(self.hkllist))
        Rcalc['miller_index'] = self.hkllist
        predictor.for_reflection_table(Rcalc, crystal.get_A())
        self.predicted = Rcalc['xyzcal.mm']
        self.dials_spot_prediction = Rcalc
        self.dials_model = experiments

      elif self.horizons_phil.integration.spot_prediction == "ucbp3":
        self.predicted = BPpredicted

      self.inputai.setOrientation(centered_orientation)
      if self.inputai.active_areas != None:
        self.predicted,self.hkllist = self.inputai.active_areas(
                                      self.predicted,self.hkllist,self.pixel_size)
      if self.block_counter < 2:
         down = self.inputai.getMosaicity()/KLUDGE
         print "Readjusting mosaicity back down to ",down
         self.inputai.setMosaicity(down)
      return
    def get_predictions_accounting_for_centering(self, experiments,
                                                 reflections,
                                                 cb_op_to_primitive, **kwargs):
        # interface requires this function to set current_orientation
        # in the actual setting used for Miller index calculation
        detector = experiments[0].detector
        crystal = experiments[0].crystal

        if self.horizons_phil.integration.model == "user_supplied":

            lower_limit_domain_size = math.pow(
                crystal.get_unit_cell().volume(), 1. / 3.
            ) * self.horizons_phil.integration.mosaic.domain_size_lower_limit  # default 10-unit cell block size minimum reasonable domain
            actual_used_domain_size = kwargs.get("domain_size_ang",
                                                 lower_limit_domain_size)

            self.block_counter += 1
            rot_mat = matrix.sqr(
                cb_op_to_primitive.c().r().as_double()).transpose()

            from cctbx.crystal_orientation import crystal_orientation, basis_type
            centered_orientation = crystal_orientation(crystal.get_A(),
                                                       basis_type.reciprocal)
            self.current_orientation = centered_orientation
            self.current_cb_op_to_primitive = cb_op_to_primitive
            primitive_orientation = centered_orientation.change_basis(rot_mat)

            self.inputai.setOrientation(primitive_orientation)
            from cxi_user import pre_get_predictions
            if self.block_counter < 2:
                KLUDGE = self.horizons_phil.integration.mosaic.kludge1  # bugfix 1 of 2 for protocol 6, equation 2
                self.inputai.setMosaicity(KLUDGE * self.inputai.getMosaicity())

            oldbase = self.inputai.getBase()

            #print oldbase.xbeam, oldbase.ybeam
            newbeam = detector[0].get_beam_centre(experiments[0].beam.get_s0())
            newdistance = -detector[0].get_beam_centre_lab(
                experiments[0].beam.get_s0())[2]

            from labelit.dptbx import Parameters
            base = Parameters(
                xbeam=newbeam[0],
                ybeam=newbeam[1],  #oldbase.xbeam, ybeam = oldbase.ybeam,
                distance=newdistance,
                twotheta=0.0)
            self.inputai.setBase(base)
            self.inputai.setWavelength(experiments[0].beam.get_wavelength())

            self.bp3_wrapper = pre_get_predictions(
                self.inputai,
                self.horizons_phil,
                raw_image=self.imagefiles.images[self.image_number],
                imageindex=self.frame_numbers[self.image_number],
                spotfinder=self.spotfinder,
                limiting_resolution=self.limiting_resolution,
                domain_size_ang=actual_used_domain_size,
            )

            BPpredicted = self.bp3_wrapper.ucbp3.selected_predictions_labelit_format(
            )
            BPhkllist = self.bp3_wrapper.ucbp3.selected_hkls()

            self.actual = actual_used_domain_size
            primitive_hkllist = BPhkllist
            #not sure if matrix needs to be transposed first for outputting HKL's???:
            self.hkllist = cb_op_to_primitive.inverse().apply(
                primitive_hkllist)

            if self.horizons_phil.integration.spot_prediction == "dials":
                from dials.algorithms.spot_prediction import StillsReflectionPredictor
                predictor = StillsReflectionPredictor(experiments[0])
                Rcalc = flex.reflection_table.empty_standard(len(self.hkllist))
                Rcalc['miller_index'] = self.hkllist
                predictor.for_reflection_table(Rcalc, crystal.get_A())
                self.predicted = Rcalc['xyzcal.mm']
                self.dials_spot_prediction = Rcalc
                self.dials_model = experiments

            elif self.horizons_phil.integration.spot_prediction == "ucbp3":
                self.predicted = BPpredicted

            self.inputai.setOrientation(centered_orientation)
            if self.inputai.active_areas != None:
                self.predicted, self.hkllist = self.inputai.active_areas(
                    self.predicted, self.hkllist, self.pixel_size)
            if self.block_counter < 2:
                down = self.inputai.getMosaicity() / KLUDGE
                print "Readjusting mosaicity back down to ", down
                self.inputai.setMosaicity(down)
            return
  def get_predictions_accounting_for_centering(self,cb_op_to_primitive=None,**kwargs):
    # interface requires this function to set current_orientation
    # in the actual setting used for Miller index calculation
    if (self.horizons_phil.known_setting is None or self.horizons_phil.known_setting == self.setting_id ) and \
        self.horizons_phil.integration.model in ["use_case_3_simulated_annealing",
                                                "use_case_3_simulated_annealing_7",
                                                "use_case_3_simulated_annealing_9"]:
      if cb_op_to_primitive==None:
        raise Sorry("Can't use model_3 simulated annealing for non-primitive cells, contact authors.")
      if self.horizons_phil.integration.model=="use_case_3_simulated_annealing":
        self.best_params = dict(zip(("half_mosaicity_deg","wave_HE_ang","wave_LE_ang",
         "reserve_orientation","rotation100_rad","rotation010_rad","rotation001_rad"),
         self.use_case_3_simulated_annealing(self.horizons_phil.integration.use_subpixel_translations))
        )
      elif self.horizons_phil.integration.model=="use_case_3_simulated_annealing_7":
        self.best_params = dict(zip(("half_mosaicity_deg","wave_HE_ang","wave_LE_ang",
         "reserve_orientation","rotation100_rad","rotation010_rad","rotation001_rad",
         "domain_size_ang"),
         self.use_case_3_simulated_annealing_7(self.horizons_phil.integration.use_subpixel_translations))
        )
      elif self.horizons_phil.integration.model=="use_case_3_simulated_annealing_9":
        self.best_params = dict(zip(("half_mosaicity_deg","wave_HE_ang","wave_LE_ang",
         "reserve_orientation","rotation100_rad","rotation010_rad","rotation001_rad",
         "domain_size_ang","ab_factor","c_factor"),
         self.use_case_3_simulated_annealing_9(self.horizons_phil.integration.use_subpixel_translations))
        )
      self.current_orientation = self.best_params["reserve_orientation"]
      self.current_cb_op_to_primitive = cb_op_to_primitive

      BPpredicted = self.bp3_wrapper.ucbp3.selected_predictions_labelit_format()
      BPhkllist = self.bp3_wrapper.ucbp3.selected_hkls()
      self.predicted,self.hkllist = BPpredicted, BPhkllist
      self.partialities = dict(indices=BPhkllist.deep_copy(),
                               data=self.bp3_wrapper.ucbp3.selected_partialities())
      #self.hi = self.bp3_wrapper.ucbp3.selected_hi_predictions()
      #self.lo = self.bp3_wrapper.ucbp3.selected_lo_predictions()
      #print list(self.partialities)
      #for x in xrange(len(self.hi)):
      #  print "%4d %4d %4d  %7.1f %7.1f %7.1f %7.1f PARTIAL %7.2f"%(
      #  self.hkllist[x][0], self.hkllist[x][1],self.hkllist[x][2],
      #  self.hi[x][0], self.hi[x][1],
      #  self.lo[x][0], self.lo[x][1], self.partialities[x])

      if self.inputai.active_areas != None:
        self.predicted,self.hkllist = self.inputai.active_areas(
                                      self.predicted,self.hkllist,self.pixel_size)
      return

    if self.horizons_phil.integration.model == "user_supplied":

     lower_limit_domain_size = math.pow(
       self.inputai.getOrientation().unit_cell().volume(),
       1./3.)*self.horizons_phil.integration.mosaic.domain_size_lower_limit # default 10-unit cell block size minimum reasonable domain
     actual_used_domain_size = kwargs.get("domain_size_ang",lower_limit_domain_size)
     if cb_op_to_primitive==None:

      from cxi_user import pre_get_predictions
      self.bp3_wrapper = pre_get_predictions(self.inputai, self.horizons_phil,
        raw_image = self.imagefiles.images[self.image_number],
        imageindex = self.frame_numbers[self.image_number],
        spotfinder = self.spotfinder,
        limiting_resolution = self.limiting_resolution,
        domain_size_ang = actual_used_domain_size)
      self.current_orientation = self.inputai.getOrientation()
      self.current_cb_op_to_primitive = cb_op_to_primitive

      BPpredicted = self.bp3_wrapper.ucbp3.selected_predictions_labelit_format()
      BPhkllist = self.bp3_wrapper.ucbp3.selected_hkls()

      self.predicted,self.hkllist = BPpredicted, BPhkllist
      if self.inputai.active_areas != None:
        self.predicted,self.hkllist = self.inputai.active_areas(
                                      self.predicted,self.hkllist,self.pixel_size)
      return

     else:
      self.block_counter+=1
      rot_mat = matrix.sqr(cb_op_to_primitive.c().r().as_double()).transpose()
      centered_orientation = self.inputai.getOrientation()
      self.current_orientation = centered_orientation
      self.current_cb_op_to_primitive = cb_op_to_primitive
      primitive_orientation = centered_orientation.change_basis(rot_mat)
      self.inputai.setOrientation(primitive_orientation)
      from cxi_user import pre_get_predictions
      if self.block_counter < 2:
        KLUDGE = self.horizons_phil.integration.mosaic.kludge1 # bugfix 1 of 2 for protocol 6, equation 2
        self.inputai.setMosaicity(KLUDGE*self.inputai.getMosaicity())
      self.bp3_wrapper = pre_get_predictions(self.inputai, self.horizons_phil,
        raw_image = self.imagefiles.images[self.image_number],
        imageindex = self.frame_numbers[self.image_number],
        spotfinder = self.spotfinder,
        limiting_resolution = self.limiting_resolution,
        domain_size_ang = actual_used_domain_size)

      BPpredicted = self.bp3_wrapper.ucbp3.selected_predictions_labelit_format()
      BPhkllist = self.bp3_wrapper.ucbp3.selected_hkls()

      self.actual = actual_used_domain_size
      self.predicted = BPpredicted
      primitive_hkllist = BPhkllist
      #not sure if matrix needs to be transposed first for outputting HKL's???:
      self.hkllist = cb_op_to_primitive.inverse().apply(primitive_hkllist)
      self.inputai.setOrientation(centered_orientation)
      if self.inputai.active_areas != None:
        self.predicted,self.hkllist = self.inputai.active_areas(
                                      self.predicted,self.hkllist,self.pixel_size)
      if self.block_counter < 2:
         down = self.inputai.getMosaicity()/KLUDGE
         print "Readjusting mosaicity back down to ",down
         self.inputai.setMosaicity(down)
      return

    if cb_op_to_primitive==None:

      predicted = self.inputai.predict_all(
                  self.image_centers[self.image_number],self.limiting_resolution)
      self.predicted = predicted.vec3() #only good for integrating one frame...
      self.hkllist = predicted.hkl()
      self.current_orientation = self.inputai.getOrientation()
      from cctbx import sgtbx
      self.cb_op_to_primitive = sgtbx.change_of_basis_op()

    else:
      rot_mat = matrix.sqr(cb_op_to_primitive.c().r().as_double()).transpose()
      centered_orientation = self.inputai.getOrientation()
      self.current_orientation = centered_orientation
      self.current_cb_op_to_primitive = cb_op_to_primitive
      primitive_orientation = centered_orientation.change_basis(rot_mat)
      self.inputai.setOrientation(primitive_orientation)
      predicted = self.inputai.predict_all(
                  self.image_centers[self.image_number],self.limiting_resolution)
      self.predicted = predicted.vec3() #only good for integrating one frame...
      primitive_hkllist = predicted.hkl()
      #not sure if matrix needs to be transposed first for outputting HKL's???:
      self.hkllist = cb_op_to_primitive.inverse().apply(primitive_hkllist)
      self.inputai.setOrientation(centered_orientation)
    if self.inputai.active_areas != None:
      self.predicted,self.hkllist = self.inputai.active_areas(
                                    self.predicted,self.hkllist,self.pixel_size)

    if False: #development only; compare the two methods:
      from matplotlib import pyplot as plt
      plt.plot([i[0] for i in BPpredicted],[i[1] for i in BPpredicted],"r.")
      plt.plot([i[0] for i in predicted],[i[1] for i in predicted],"b.")
      plt.show()