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
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
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)
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
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)