def symmetrize(self):
      converter = AGconvert()
      converter.forward(self.orientation) # allows subsequent back-conversion of symmetrized

      # takes member-data orientation; returns symmetrized metrical matrix
      uc = self.orientation.unit_cell()
      avg = self.space_group.average_unit_cell(uc) # assumes direct-space cell
      sym_mm = avg.reciprocal().metrical_matrix()

      converter.validate_and_setG(sym_mm)
      self.orientation = converter.back_as_orientation()
示例#2
0
  def symmetrize(self):
      converter = AGconvert()
      converter.forward(self.orientation) # allows subsequent back-conversion of symmetrized

      # takes member-data orientation; returns symmetrized metrical matrix
      uc = self.orientation.unit_cell()
      avg = self.space_group.average_unit_cell(uc) # assumes direct-space cell
      sym_mm = avg.reciprocal().metrical_matrix()

      converter.validate_and_setG(sym_mm)
      self.orientation = converter.back_as_orientation()
class symmetrize_reduce_enlarge(object):
                        # symmetrize the metrical matrix &
                        # reduce the number of parameters to reflect symmetry
                        # also, provide back transform to increase
                        # number of parameters back to six

  def __init__(self, space_group):

    self.space_group = space_group
    self.constraints = sgtbx.tensor_rank_2_constraints(
      space_group=self.space_group,reciprocal_space=True)

  def set_orientation(self, orientation, length_unit=1.E-10):
    #provide orientation as either an A matrix (Rossmann) or B matrix (Busing & Levy)
    # data type can be either scitbx.matrix.sqr or scitbx::mat3
    # in either the reciprocal or direct space setting
    # or as a cctbx.crystal_orientation.crystal_orientation
    # if space group is not triclinic the orientation matrix should be close to
    #  symmetrized, but exact symmetrization is done by averaging within the constructor.

    # length unit defaults to 1.E-10 meters = 1 Angstrom

    if "direct_matrix" in dir(orientation):
      self.orientation = orientation # data is already a cctbx orientation
    else:
      from cctbx.crystal_orientation import crystal_orientation
      which_setting = [crystal_orientation(orientation,True),
                       crystal_orientation(orientation,False)]
      #kludgy test for space setting: unit cell volume is never < 100 Angstroms^3
      conversion_to_A3 = (length_unit*length_unit*length_unit)/1.E-30
      select = [a.unit_cell().volume()*conversion_to_A3 > 100.
                for a in which_setting]
      self.orientation = which_setting[select.index(True)]


  def symmetrize(self):
      converter = AGconvert()
      converter.forward(self.orientation) # allows subsequent back-conversion of symmetrized

      # takes member-data orientation; returns symmetrized metrical matrix
      uc = self.orientation.unit_cell()
      avg = self.space_group.average_unit_cell(uc) # assumes direct-space cell
      sym_mm = avg.reciprocal().metrical_matrix()

      converter.validate_and_setG(sym_mm)
      self.orientation = converter.back_as_orientation()

  # it is assumed that metrical_matrix and independent are in reciprocal setting
  def reduce(self,metrical_matrix):
    # takes 6-parameter metrical matrix, returns reduced number of independent parameters
    return self.constraints.independent_params(all_params=metrical_matrix)

  def enlarge(self,independent):
    # takes reduced number independent parameters, returns 6-parameter metrical matrix
    u_star = self.constraints.all_params(independent_params=tuple(independent))
    assert len(u_star) == 6
    return u_star

  def forward_independent_parameters(self):
    # returns the independent parameters given the set_orientation() B matrix
    self.Bconverter=AGconvert()
    self.Bconverter.forward(self.orientation)
    return self.reduce(metrical_matrix = self.Bconverter.G)

  def forward_gradients(self):
    #Specifically for refinement of the B-matrix parameters.
    from rstbx.symmetry.constraints.g_gradients import g_gradients
    gradient_engine = g_gradients(agadaptor = self.Bconverter, symred = self)
    return gradient_engine.dB_dp()

  def backward_orientation(self,independent):
    # given new values of the independent parameters, back-calculate and
    # set the new orientation matrix
    new_mm = self.enlarge(independent)
    self.Bconverter.validate_and_setG(new_mm)
    self.orientation = self.Bconverter.back_as_orientation()
    return self.orientation
示例#4
0
  def parameter_based_model_one_frame_detail(self,frame_id,iframe,all_model):
      PIXEL_SZ = 0.11 # mm/pixel
      SIGN = -1.
      if iframe < self.n_refined_frames:
        detector_origin = col((-self.FRAMES["beam_x"][iframe]
                             + SIGN * PIXEL_SZ * self.frame_translations.x[2*iframe],
                             -self.FRAMES["beam_y"][iframe]
                             + SIGN * PIXEL_SZ * self.frame_translations.x[1+2*iframe],
                             0.))
        self.OUTPUT["beam_x"][iframe] = -detector_origin[0]
        self.OUTPUT["beam_y"][iframe] = -detector_origin[1]
      else:
        detector_origin = col((-self.FRAMES["beam_x"][iframe],-self.FRAMES["beam_y"][iframe],0.))

      if not self.bandpass_models.has_key(frame_id):

        reserve_orientation = self.FRAMES["orientation"][iframe]
        effective_orientation = reserve_orientation

        #Not necessary to apply the 3 offset rotations; they have apparently
        #  been applied already.\
        #  .rotate_thru((1,0,0),self.FRAMES["rotation100_rad"][iframe]
        # ).rotate_thru((0,1,0),self.FRAMES["rotation010_rad"][iframe]
        # ).rotate_thru((0,0,1),self.FRAMES["rotation001_rad"][iframe])

        crystal = symmetry(unit_cell=effective_orientation.unit_cell(),space_group = "P1")
        indices = all_model.frame_indices(frame_id)

        parameters = parameters_bp3(
           indices=indices, orientation=effective_orientation,
           incident_beam=col(correction_vectors.INCIDENT_BEAM),
           packed_tophat=col((1.,1.,0.)),
           detector_normal=col(correction_vectors.DETECTOR_NORMAL),
           detector_fast=col((0.,1.,0.)),detector_slow=col((1.,0.,0.)),
           pixel_size=col((PIXEL_SZ,PIXEL_SZ,0)),
           pixel_offset=col((0.,0.,0.0)),
           distance=self.FRAMES["distance"][iframe],
           detector_origin=detector_origin
        )

        #print "PARAMETER check   ", effective_orientation
        #print "PARAMETER distance", self.FRAMES['distance'][iframe]
        #print "PARAMETER origin  ", detector_origin

        ucbp3 = bandpass_gaussian(parameters=parameters)
        ucbp3.set_active_areas( self.tiles ) #self.params.effective_tile_boundaries
        integration_signal_penetration=0.0 # easier to calculate distance derivatives

        ucbp3.set_sensor_model( thickness_mm = 0.5, mu_rho = 8.36644, # CS_PAD detector at 1.3 Angstrom
          signal_penetration = integration_signal_penetration)
        #ucbp3.set_subpixel( flex.double(tp038_trans_values) ) #back off this; let minimizer figure it out.

        half_mosaicity_rad = self.FRAMES["half_mosaicity_deg"][iframe] * pi/180.
        ucbp3.set_mosaicity(half_mosaicity_rad)
        ucbp3.set_bandpass(self.FRAMES["wave_HE_ang"][iframe],self.FRAMES["wave_LE_ang"][iframe])
        ucbp3.set_orientation(effective_orientation)
        ucbp3.set_domain_size(self.FRAMES["domain_size_ang"][iframe])
        ucbp3.set_vector_output_pointers(self.vector_data,
                                         frame_id,iframe<self.n_refined_frames)

        if not self.bandpass_models.has_key("best_index"):
          from labelit.dptbx import lepage
          M = lepage.character(effective_orientation)
          s = len(M.best())
          for index in M.best():
            index['counter'] = s
            s-=1
            if index["max_angular_difference"]==0.0:
              best_index = index
              break

          self.bandpass_models["best_index"] = best_index
          self.bandpass_models["constraints"] = tensor_rank_2_constraints(space_group=best_index['reduced_group'],reciprocal_space=True)
          self.bandpass_models["n_independent"] = self.bandpass_models["constraints"].n_independent_params()

        self.bandpass_models[frame_id]=ucbp3

      if iframe < self.n_refined_frames:
        self.bandpass_models[frame_id].set_detector_origin(detector_origin)
        self.bandpass_models[frame_id].set_distance(
          self.FRAMES["distance"][iframe] + self.frame_distances.x[iframe])
        self.OUTPUT["distance"][iframe] = self.FRAMES["distance"][iframe] + self.frame_distances.x[iframe]
        #half_mosaicity_rad = self.FRAMES["half_mosaicity_deg"][iframe] * pi/180. + \
        #                     self.half_mosaicity_rad.x[iframe]
        #self.bandpass_models[frame_id].set_mosaicity(half_mosaicity_rad)
        reserve_orientation = self.FRAMES["orientation"][iframe]
        effective_orientation =   reserve_orientation.rotate_thru((0,0,1),self.frame_rotz.x[iframe])
        effective_orientation = effective_orientation.rotate_thru((0,1,0),self.frame_roty.x[iframe])
        effective_orientation = effective_orientation.rotate_thru((1,0,0),self.frame_rotx.x[iframe])

        convert = AGconvert()
        convert.forward(effective_orientation)
        u_independent = list(self.bandpass_models["constraints"].independent_params(all_params=convert.G))
        for x in xrange(self.bandpass_models["n_independent"]):
          u_independent[x] *= self.g_factor.x[x+6*iframe]
        u_star = self.bandpass_models["constraints"].all_params(independent_params=tuple(u_independent))
        convert.validate_and_setG(u_star)
        effective_orientation = convert.back_as_orientation()
        self.OUTPUT["orientation"][iframe]=effective_orientation
        self.bandpass_models[frame_id].set_orientation(effective_orientation)
        mean_wave = (self.FRAMES["wave_HE_ang"][iframe] + self.FRAMES["wave_LE_ang"][iframe])/2.
        #mean_wave *= self.mean_energy_factor.x[iframe]
        bandpassHW =(self.FRAMES["wave_LE_ang"][iframe] - self.FRAMES["wave_HE_ang"][iframe])/2.
        self.bandpass_models[frame_id].set_bandpass(mean_wave - bandpassHW, mean_wave + bandpassHW)

      return detector_origin
示例#5
0
class symmetrize_reduce_enlarge(object):
                        # symmetrize the metrical matrix &
                        # reduce the number of parameters to reflect symmetry
                        # also, provide back transform to increase
                        # number of parameters back to six

  def __init__(self, space_group):

    self.space_group = space_group
    self.constraints = sgtbx.tensor_rank_2_constraints(
      space_group=self.space_group,reciprocal_space=True)

  def set_orientation(self, orientation, length_unit=1.E-10):
    #provide orientation as either an A matrix (Rossmann) or B matrix (Busing & Levy)
    # data type can be either scitbx.matrix.sqr or scitbx::mat3
    # in either the reciprocal or direct space setting
    # or as a cctbx.crystal_orientation.crystal_orientation
    # if space group is not triclinic the orientation matrix should be close to
    #  symmetrized, but exact symmetrization is done by averaging within the constructor.

    # length unit defaults to 1.E-10 meters = 1 Angstrom

    if "direct_matrix" in dir(orientation):
      self.orientation = orientation # data is already a cctbx orientation
    else:
      from cctbx.crystal_orientation import crystal_orientation
      which_setting = [crystal_orientation(orientation,True),
                       crystal_orientation(orientation,False)]
      #kludgy test for space setting: unit cell volume is never < 70 Angstroms^3
      conversion_to_A3 = (length_unit*length_unit*length_unit)/1.E-30
      select = [a.unit_cell().volume()*conversion_to_A3 > 70.
                for a in which_setting]
      self.orientation = which_setting[select.index(True)]


  def symmetrize(self):
      converter = AGconvert()
      converter.forward(self.orientation) # allows subsequent back-conversion of symmetrized

      # takes member-data orientation; returns symmetrized metrical matrix
      uc = self.orientation.unit_cell()
      avg = self.space_group.average_unit_cell(uc) # assumes direct-space cell
      sym_mm = avg.reciprocal().metrical_matrix()

      converter.validate_and_setG(sym_mm)
      self.orientation = converter.back_as_orientation()

  # it is assumed that metrical_matrix and independent are in reciprocal setting
  def reduce(self,metrical_matrix):
    # takes 6-parameter metrical matrix, returns reduced number of independent parameters
    return self.constraints.independent_params(all_params=metrical_matrix)

  def enlarge(self,independent):
    # takes reduced number independent parameters, returns 6-parameter metrical matrix
    u_star = self.constraints.all_params(independent_params=tuple(independent))
    assert len(u_star) == 6
    return u_star

  def forward_independent_parameters(self):
    # returns the independent parameters given the set_orientation() B matrix
    self.Bconverter=AGconvert()
    self.Bconverter.forward(self.orientation)
    return self.reduce(metrical_matrix = self.Bconverter.G)

  def forward_gradients(self):
    #Specifically for refinement of the B-matrix parameters.
    from rstbx.symmetry.constraints.g_gradients import g_gradients
    gradient_engine = g_gradients(agadaptor = self.Bconverter, symred = self)
    return gradient_engine.dB_dp()

  def backward_orientation(self,independent):
    # given new values of the independent parameters, back-calculate and
    # set the new orientation matrix
    new_mm = self.enlarge(independent)
    self.Bconverter.validate_and_setG(new_mm)
    self.orientation = self.Bconverter.back_as_orientation()
    return self.orientation