def sigma(self, G=False, order=1, distribution="gaussian"): local_xtal_g = self.change_the_g(self.xtal.g) #print "g", self.xtal.g, local_xtal_g #lgn=Physics.normalize(local_xtal_g) local_xtal_gphi = Physics.atan2(local_xtal_g[1], local_xtal_g[0]) #local_xtal_gtheta = math.acos(lgn[2]) tB = self.xtal.keV2Bragg(self.photon.e) factor = 2.5 ang_fac = Physics.angular_factor(tB) cosine = abs(self.photon.k[2]/self.photon.knorm) Q = self.xtal.mat_facs[order]*ang_fac if G is None: G=self.g_needed(order) if distribution=="hat": Dtheta = Physics.anglebetween(G, local_xtal_g) # - 2.0 * Physics.anglebetween(self.xtal.g, local_xtal_g) eta = 2.4e-6 + (self.xtal.dim[2] * self.xtal.curvature) / factor weight=Physics.hat1(Dtheta, eta)*cosine/Q elif distribution=="gaussian": Dtheta = Physics.anglebetween(G, local_xtal_g) # - 2.0 * Physics.anglebetween(self.xtal.g, local_xtal_g) weight=Physics.gaussian(Dtheta, self.xtal.eta) else: return 0. return Q*weight/cosine
def __set_g(self, g): self.__g = array(g) self.gnorm = Physics.norm(g) self.gnormalized = Physics.normalize(g) # angular coordinates (azimuth and colatitude) of the g versor self.gtheta = math.acos(self.gnormalized[2]) self.gphi = Physics.atan2(g[1], g[0])
def g_needed(self, order=1): ############################################### local_xtal_g = self.change_the_g(self.xtal.g) #lgn=Physics.normalize(local_xtal_g) local_xtal_gphi = Physics.atan2(local_xtal_g[1], local_xtal_g[0]) ############################################### """Calculates the reciprocal lattice vector that a photon needs to be scattered by a known crystal with planes oriented in a particular direction that is already known""" #When the energy is too low the returned value is None. if self.photon.knorm < self.xtal.gnorm*order: return None # For the calculation see the notes of 09/07/2004 modified the 12/07/04 A = (self.photon.k[0]*math.cos(local_xtal_gphi)+self.photon.k[1]*math.sin(local_xtal_gphi)) B = self.photon.k[2] C = self.xtal.gnorm/2. #A = (self.photon.k[0]*math.cos(self.xtal.gphi)+self.photon.k[1]*math.sin(self.xtal.gphi)) #B = self.photon.k[2] #C = self.xtal.gnorm/2. if abs(A)<=EPSILON: # B can't be 0 together with A unless gnorm=0, so this function should be almost safe # The result can be otained with the calculation in the else block # but this is faster and common (is the case of paraxial photons). if abs(C/B)>1.: return None else: theta=math.acos(-C/B) else: A2B2=A**2+B**2 BC=B*C # Two solutions, but only one satisfies the Laue equation Mean=-BC/A2B2 try: Delta=A*math.sqrt(A2B2-C**2)/A2B2 except ValueError: return None cosp, cosm = Mean+Delta, Mean-Delta thp, thm = math.acos(cosp), math.acos(cosm) sinp, sinm = math.sin(thp), math.sin(thm) checkp = abs(A*sinp + B*cosp + C) checkm = abs(A*sinm + B*cosm + C) # Da ricontrollare if checkp<checkm: theta=thp else: theta=thm return Physics.spherical2cartesian(self.xtal.gnorm, local_xtal_gphi, theta)
def __set_g(self, g): self.__g = array(g) self.gnorm = Physics.norm(g) self.gnormalized = Physics.normalize(g) # angular coordinates of the reciprocal lattice vector g # gtheta is the polar angle (the angle between z axis and g vector) # gphi is the azimuthal angle (in the plane xy, from the x axis) self.gtheta = math.acos(self.gnormalized[2]) self.gphi = Physics.atan2(g[1], g[0])
def local_eranges(self, Emin=1., Emax=1000., sphi=0., stheta=pi, deltasource=0): l = math.sqrt(self.photon.r[0]**2 + self.photon.r[1]**2) #stheta = stheta - self.divergence_stheta(l, deltasource) sphi = self.divergence_sphi(self.photon.r) local_xtal_g = self.change_the_g(self.xtal.g) lgn=Physics.normalize(local_xtal_g) local_xtal_gphi = Physics.atan2(local_xtal_g[1], local_xtal_g[0]) local_xtal_gtheta = math.acos(lgn[2]) order, reached_max_order = 0,False factor = 2.5 Darwin_Width = Physics.darwinwidth(self.xtal.Z, self.xtal.hkl, self.photon.e) if self.xtal.structure == "mosaic": Deltatheta = 1.0 * (self.xtal.fwhm/60/180*pi) else: Deltatheta = Darwin_Width + (self.xtal.dim[2] * self.xtal.curvature) / factor Delta_curvature = self.xtal.curvature * self.xtal.dim[0] thetamin, thetamax = local_xtal_gtheta-Deltatheta/2, local_xtal_gtheta+Deltatheta/2 constant=-Booklet.hc/(2.*self.xtal.d_hkl) eranges=[] while not reached_max_order: order+=1 cosdeltaphi=math.cos(sphi-local_xtal_gphi) sinstheta=math.sin(stheta) cosstheta=math.cos(stheta) sinthetamin=math.sin(thetamin) costhetamin=math.cos(thetamin) sinthetamax=math.sin(thetamax) costhetamax=math.cos(thetamax) Eminim_= constant*order/(cosdeltaphi*sinstheta*sinthetamin+cosstheta*costhetamin) Emaxim_= constant*order/(cosdeltaphi*sinstheta*sinthetamax+cosstheta*costhetamax) if Emaxim_ >= Emax: if Eminim_>=Emax: return eranges else: reached_max_order=True Emaxim_=Emax if Eminim_ <= Emin: if Emaxim_ <= Emin: pass else: Eminim_=Emin eranges.append((Eminim_, Emaxim_)) else: eranges.append((Eminim_, Emaxim_)) return eranges