def calc_partiality_anisotropy_set(self, my_uc, rotx, roty, miller_indices,
     ry, rz, r0, re, nu,
     bragg_angle_set, alpha_angle_set, wavelength, crystal_init_orientation,
     spot_pred_x_mm_set, spot_pred_y_mm_set, detector_distance_mm,
     partiality_model, flag_beam_divergence):
   #use III.4 in Winkler et al 1979 (A35; P901) for set of miller indices
   O = sqr(my_uc.orthogonalization_matrix()).transpose()
   R = sqr(crystal_init_orientation.crystal_rotation_matrix()).transpose()
   CO = crystal_orientation(O*R, basis_type.direct)
   CO_rotate = CO.rotate_thru((1,0,0), rotx
                ).rotate_thru((0,1,0), roty)
   A_star = sqr(CO_rotate.reciprocal_matrix())
   S0 = -1*col((0,0,1./wavelength))
   #caculate rs
   rs_set = r0 + (re * flex.tan(bragg_angle_set))
   if flag_beam_divergence:
     rs_set += ((ry * flex.cos(alpha_angle_set))**2 + (rz * flex.sin(alpha_angle_set))**2)**(1/2)
   #calculate rh
   x = A_star.elems * miller_indices.as_vec3_double()
   sd_array = x + S0.elems
   rh_set = sd_array.norms() - (1/wavelength)
   #calculate partiality
   if partiality_model == "Lorentzian":
     partiality_set = ((rs_set**2)/((2*(rh_set**2))+(rs_set**2)))
   elif partiality_model == "Voigt":
     partiality_set = self.voigt(rh_set, rs_set, nu)
   elif partiality_model == "Lognormal":
     partiality_set = self.lognpdf(rh_set, rs_set, nu)
   #calculate delta_xy
   d_ratio = -detector_distance_mm/sd_array.parts()[2]
   calc_xy_array = flex.vec3_double(sd_array.parts()[0]*d_ratio, \
       sd_array.parts()[1]*d_ratio, flex.double([0]*len(d_ratio)))
   pred_xy_array = flex.vec3_double(spot_pred_x_mm_set, spot_pred_y_mm_set, flex.double([0]*len(d_ratio)))
   delta_xy_set = (pred_xy_array - calc_xy_array).norms()
   return partiality_set, delta_xy_set, rs_set, rh_set
예제 #2
0
 def calc_partiality_anisotropy_set(self, my_uc, rotx, roty, miller_indices,
     ry, rz, r0, re, nu,
     bragg_angle_set, alpha_angle_set, wavelength, crystal_init_orientation,
     spot_pred_x_mm_set, spot_pred_y_mm_set, detector_distance_mm,
     partiality_model, flag_beam_divergence):
   #use III.4 in Winkler et al 1979 (A35; P901) for set of miller indices
   O = sqr(my_uc.orthogonalization_matrix()).transpose()
   R = sqr(crystal_init_orientation.crystal_rotation_matrix()).transpose()
   CO = crystal_orientation(O*R, basis_type.direct)
   CO_rotate = CO.rotate_thru((1,0,0), rotx
                ).rotate_thru((0,1,0), roty)
   A_star = sqr(CO_rotate.reciprocal_matrix())
   S0 = -1*col((0,0,1./wavelength))
   #caculate rs
   rs_set = r0 + (re * flex.tan(bragg_angle_set))
   if flag_beam_divergence:
     rs_set += ((ry * flex.cos(alpha_angle_set))**2 + (rz * flex.sin(alpha_angle_set))**2)**(1/2)
   #calculate rh
   x = A_star.elems * miller_indices.as_vec3_double()
   sd_array = x + S0.elems
   rh_set = sd_array.norms() - (1/wavelength)
   #calculate partiality
   if partiality_model == "Lorentzian":
     partiality_set = ((rs_set**2)/((2*(rh_set**2))+(rs_set**2)))
   elif partiality_model == "Voigt":
     partiality_set = self.voigt(rh_set, rs_set, nu)
   elif partiality_model == "Lognormal":
     partiality_set = self.lognpdf(rh_set, rs_set, nu)
   #calculate delta_xy
   d_ratio = -detector_distance_mm/sd_array.parts()[2]
   calc_xy_array = flex.vec3_double(sd_array.parts()[0]*d_ratio, \
       sd_array.parts()[1]*d_ratio, flex.double([0]*len(d_ratio)))
   pred_xy_array = flex.vec3_double(spot_pred_x_mm_set, spot_pred_y_mm_set, flex.double([0]*len(d_ratio)))
   delta_xy_set = (pred_xy_array - calc_xy_array).norms()
   return partiality_set, delta_xy_set, rs_set, rh_set
예제 #3
0
    def energies_adp_iso(self,
                         xray_structure,
                         parameters,
                         use_u_local_only,
                         use_hd,
                         wilson_b=None,
                         compute_gradients=False,
                         tan_b_iso_max=None,
                         u_iso_refinable_params=None,
                         gradients=None):
        """
    Compute target and gradients for isotropic ADPs/B-factors relative to
    restraints.

    :returns: scitbx.restraints.energies object
    """
        result = scitbx.restraints.energies(
            compute_gradients=compute_gradients,
            gradients=gradients,
            gradients_size=xray_structure.scatterers().size(),
            gradients_factory=flex.double,
            normalization=self.normalization)
        if (self.geometry is None):
            result.geometry = None
        else:
            result.geometry = cctbx.adp_restraints.energies_iso(
                geometry_restraints_manager=self.geometry,
                xray_structure=xray_structure,
                parameters=parameters,
                wilson_b=wilson_b,
                use_hd=use_hd,
                use_u_local_only=use_u_local_only,
                compute_gradients=compute_gradients,
                gradients=result.gradients)
            result += result.geometry
        if (self.cartesian_ncs_manager is None):
            result.cartesian_ncs_manager = None
        else:
            result.cartesian_ncs_manager = self.cartesian_ncs_manager.energies_adp_iso(
                u_isos=xray_structure.extract_u_iso_or_u_equiv(),
                average_power=parameters.average_power,
                compute_gradients=compute_gradients,
                gradients=result.gradients)
            result += result.cartesian_ncs_manager
        result.finalize_target_and_gradients()
        if (compute_gradients):
            #XXX highly inefficient code: do something asap by adopting new scatters flags
            if (tan_b_iso_max is not None and tan_b_iso_max != 0):
                u_iso_max = adptbx.b_as_u(tan_b_iso_max)
                if (u_iso_refinable_params is not None):
                    chain_rule_scale = u_iso_max / math.pi / (
                        flex.pow2(u_iso_refinable_params) + 1.0)
                else:
                    u_iso_refinable_params = flex.tan(
                        math.pi *
                        (xray_structure.scatterers().extract_u_iso() /
                         u_iso_max - 1. / 2.))
                    chain_rule_scale = u_iso_max / math.pi / (
                        flex.pow2(u_iso_refinable_params) + 1.0)
            else:
                chain_rule_scale = 1.0
            result.gradients = result.gradients * chain_rule_scale
        return result
예제 #4
0
def superimpose_powder_arcs(image, params):

    #put in some random noise to improve display
    image.read()
    apply_gaussian_noise(image, params)

    pxlsz = image.pixel_size
    distance = image.distance
    wavelength = image.wavelength
    eps = 0.01
    beamx = eps + image.beamx / pxlsz
    beamy = eps + image.beamy / pxlsz
    print(beamx, beamy)

    image.read()
    data = image.linearintdata
    detector_d = flex.double()
    detector_radius = flex.double()

    for x in range(data.focus()[0]):
        dx = x - beamx
        dx_sq = dx * dx

        for y in range(data.focus()[1]):
            dy = y - beamy
            radius = math.sqrt(dx_sq + dy * dy) * pxlsz
            detector_radius.append(radius)
            theta = 0.5 * math.atan(radius / distance)
            resol_d = wavelength / (2. * math.sin(theta))

            if is_pinwheel_region(dx, dy):
                detector_d.append(resol_d)
            else:
                detector_d.append(0.0)
    print(detector_d.size())
    d_order_image = flex.sort_permutation(detector_d, reverse=True)

    #code = "2oh5"
    code = params.viewer.powder_arcs.code
    d_min = 2.0
    sf = get_mmtbx_icalc(code, d_min)
    sf.show_summary()

    cell = sf.unit_cell()
    millers = sf.indices()
    FUDGE_FACTOR = 0.02
    intensities = FUDGE_FACTOR * sf.data()
    spot_d = cell.d(millers)
    spot_two_theta = cell.two_theta(millers, wavelength=wavelength)
    spot_radius = distance * flex.tan(spot_two_theta)

    d_order_spots = flex.sort_permutation(spot_d, reverse=True)
    print(list(d_order_spots))

    spot_ptr_min = 0
    spot_ptr_max = 1

    THREESIGMA = 1.5
    SIGMA = 0.20
    SCALE = 0.003
    for x in range(50000):  #len(detector_d)):
        if x % 10000 == 0: print(x)
        if detector_d[d_order_image[x]] > 2.1:
            pxl_radius = detector_radius[d_order_image[x]]
            #print "pixel radius",pxl_radius,"resolution",detector_d[d_order_image[x]]
            if True:  # data[d_order_image[x]]>0:
                data[d_order_image[x]] = 0
                # increase spot_ptr_max???
                while spot_radius[
                        d_order_spots[spot_ptr_max]] - THREESIGMA < pxl_radius:
                    spot_ptr_max += 1
                    print(
                        x, pxl_radius, "increase spot_ptr_max", spot_ptr_max,
                        spot_radius[d_order_spots[spot_ptr_max]] - THREESIGMA)
                while spot_radius[
                        d_order_spots[spot_ptr_min]] + THREESIGMA < pxl_radius:
                    spot_ptr_min += 1
                    print(x, pxl_radius, "increase spot_ptr_min", spot_ptr_min)
                for sidx in range(spot_ptr_min, spot_ptr_max):
                    spot_rad = spot_radius[d_order_spots[sidx]]
                    delta_rad = spot_rad - pxl_radius
                    #gaussian distribution with SIGMA=1 (1 pixel sigma)
                    #divide through by spot_radius since energy has to be spread around increasing ring
                    #  circumference
                    #print "changing data ",x,d_order_image[x]
                    data[d_order_image[x]] += int(
                        SCALE * (1. /
                                 (math.sqrt(2. * math.pi * SIGMA * SIGMA))) *
                        math.exp(-0.5 * delta_rad * delta_rad /
                                 (SIGMA * SIGMA)) *
                        intensities[d_order_spots[sidx]] / spot_rad)
예제 #5
0
  def energies_adp_iso(self,
        xray_structure,
        parameters,
        use_u_local_only,
        use_hd,
        wilson_b=None,
        compute_gradients=False,
        tan_b_iso_max=None,
        u_iso_refinable_params=None,
        gradients=None):
    """
    Compute target and gradients for isotropic ADPs/B-factors relative to
    restraints.

    :returns: scitbx.restraints.energies object
    """
    result = scitbx.restraints.energies(
      compute_gradients=compute_gradients,
      gradients=gradients,
      gradients_size=xray_structure.scatterers().size(),
      gradients_factory=flex.double,
      normalization=self.normalization)
    if (self.geometry is None):
      result.geometry = None
    else:
      result.geometry = cctbx.adp_restraints.energies_iso(
        geometry_restraints_manager=self.geometry,
        xray_structure=xray_structure,
        parameters=parameters,
        wilson_b=wilson_b,
        use_hd = use_hd,
        use_u_local_only=use_u_local_only,
        compute_gradients=compute_gradients,
        gradients=result.gradients)
      result += result.geometry
    if (self.ncs_groups is not None and \
        self.torsion_ncs_groups is not None):
      raise Sorry("Cannot have both Cartesian and torsion NCS restraints"+\
                  " at the same time.")
    if (self.ncs_groups is None):
      result.ncs_groups = None
    else:
      result.ncs_groups = self.ncs_groups.energies_adp_iso(
        u_isos=xray_structure.extract_u_iso_or_u_equiv(),
        average_power=parameters.average_power,
        compute_gradients=compute_gradients,
        gradients=result.gradients)
      result += result.ncs_groups
    if (self.torsion_ncs_groups is None):
      result.torsion_ncs_groups = None
    else:
      result.torsion_ncs_groups = self.torsion_ncs_groups.energies_adp_iso(
        u_isos=xray_structure.extract_u_iso_or_u_equiv(),
        average_power=parameters.average_power,
        compute_gradients=compute_gradients,
        gradients=result.gradients)
      result += result.torsion_ncs_groups
    result.finalize_target_and_gradients()
    if(compute_gradients):
       #XXX highly inefficient code: do something asap by adopting new scatters flags
       if(tan_b_iso_max is not None and tan_b_iso_max != 0):
          u_iso_max = adptbx.b_as_u(tan_b_iso_max)
          if(u_iso_refinable_params is not None):
             chain_rule_scale = u_iso_max / math.pi / (flex.pow2(u_iso_refinable_params)+1.0)
          else:
             u_iso_refinable_params = flex.tan(math.pi*(xray_structure.scatterers().extract_u_iso()/u_iso_max-1./2.))
             chain_rule_scale = u_iso_max / math.pi / (flex.pow2(u_iso_refinable_params)+1.0)
       else:
          chain_rule_scale = 1.0
       result.gradients = result.gradients * chain_rule_scale
    return result
예제 #6
0
def superimpose_powder_arcs(image,params):

    #put in some random noise to improve display
    image.read()
    apply_gaussian_noise(image,params)

    pxlsz = image.pixel_size
    distance = image.distance
    wavelength = image.wavelength
    eps = 0.01
    beamx = eps+image.beamx/pxlsz
    beamy = eps+image.beamy/pxlsz
    print beamx,beamy

    image.read()
    data = image.linearintdata
    detector_d = flex.double()
    detector_radius = flex.double()

    for x in xrange(data.focus()[0]):
      dx = x-beamx
      dx_sq = dx*dx;

      for y in xrange(data.focus()[1]):
        dy = y-beamy
        radius = math.sqrt(dx_sq+dy*dy)*pxlsz
        detector_radius.append(radius)
        theta = 0.5 * math.atan(radius/distance)
        resol_d = wavelength/(2.*math.sin(theta))

        if is_pinwheel_region(dx,dy):
          detector_d.append(resol_d)
        else:
          detector_d.append(0.0)
    print detector_d.size()
    d_order_image = flex.sort_permutation(detector_d,reverse=True)

    #code = "2oh5"
    code = params.viewer.powder_arcs.code
    d_min = 2.0
    sf = get_mmtbx_icalc(code,d_min)
    sf.show_summary()

    cell = sf.unit_cell()
    millers = sf.indices()
    FUDGE_FACTOR = 0.02
    intensities = FUDGE_FACTOR*sf.data()
    spot_d = cell.d(millers)
    spot_two_theta = cell.two_theta(millers,wavelength=wavelength)
    spot_radius = distance * flex.tan(spot_two_theta)

    d_order_spots = flex.sort_permutation(spot_d,reverse=True)
    print list(d_order_spots)

    spot_ptr_min = 0
    spot_ptr_max = 1

    THREESIGMA=1.5
    SIGMA = 0.20
    SCALE = 0.003
    for x in xrange(50000):#len(detector_d)):
      if x%10000==0: print x
      if detector_d[d_order_image[x]]>2.1:
        pxl_radius = detector_radius[d_order_image[x]]
        #print "pixel radius",pxl_radius,"resolution",detector_d[d_order_image[x]]
        if True:# data[d_order_image[x]]>0:
          data[d_order_image[x]]=0
          # increase spot_ptr_max???
          while spot_radius[d_order_spots[spot_ptr_max]]-THREESIGMA < pxl_radius:
            spot_ptr_max += 1
            print x, pxl_radius,"increase spot_ptr_max" , spot_ptr_max, spot_radius[d_order_spots[spot_ptr_max]]-THREESIGMA
          while spot_radius[d_order_spots[spot_ptr_min]]+THREESIGMA < pxl_radius:
            spot_ptr_min += 1
            print x, pxl_radius,"increase spot_ptr_min" , spot_ptr_min
          for sidx in xrange(spot_ptr_min,spot_ptr_max):
            spot_rad = spot_radius[d_order_spots[sidx]]
            delta_rad = spot_rad-pxl_radius
            #gaussian distribution with SIGMA=1 (1 pixel sigma)
            #divide through by spot_radius since energy has to be spread around increasing ring
            #  circumference
            #print "changing data ",x,d_order_image[x]
            data[d_order_image[x]] += int(SCALE*(1./(math.sqrt(2.*math.pi*SIGMA*SIGMA)))*math.exp(
              -0.5*delta_rad*delta_rad/(SIGMA*SIGMA))*intensities[d_order_spots[sidx]]/spot_rad)