def surface_intercept_bounds(k, v, diameter): """ Find z-intercepts within bounds We assume that the plane is a circle of fixed diameter, and scale back the intercept to the edge of the circle, This is done along by subtracting a vector that is parrelel to the in-plane projection of the k vector. The magnitude of the subtracted vector is set so the result has magnitude equal to the diameter. If that doesnt result in an intercept then just rescale the original intercept vector so its magnitude is the diameter. This is an approximate way to handle intercepts for circular samples, not recommended for use(!) """ vi = surface_intercept(k, v) r = cartesian_mag(vi) if r <= diameter / 2.: return vi # if r>diameter/2 need to scale it back # Therefore solve the following for mag # vi_new = vi - ks*mag/norm(ks), # mag(vi_new) = diameter/2 # therefore end up with a quadratic: ks = num.array(k[0:2]) a = 1. b = -2. * (v[0] * ks[0] + vi[1] * ks[1]) / cartesian_mag(ks) c = cartesian_mag(vi)**2. - (diameter / 2.)**2. arg = b**2. - 4. * a * c # make sure this method will result in a solution if arg > 0.: mag1 = (-b + num.sqrt(arg)) / (2. * a) mag2 = (-b - num.sqrt(arg)) / (2. * a) vi1 = vi - ks * mag1 / cartesian_mag(ks) vi2 = vi - ks * mag2 / cartesian_mag(ks) # chose soln that makes smallest angle # with the original intercept angle1 = num.fabs(cartesian_angle(vi, vi1)) angle2 = num.fabs(cartesian_angle(vi, vi2)) if angle1 < angle2: return vi1 else: return vi2 # otherwise just rescale the original vector else: vi = vi * (diameter / 2.) / cartesian_mag(vi) return vi
def surface_intercept_bounds(k,v,diameter): """ Find z-intercepts within bounds We assume that the plane is a circle of fixed diameter, and scale back the intercept to the edge of the circle, This is done along by subtracting a vector that is parrelel to the in-plane projection of the k vector. The magnitude of the subtracted vector is set so the result has magnitude equal to the diameter. If that doesnt result in an intercept then just rescale the original intercept vector so its magnitude is the diameter. This is an approximate way to handle intercepts for circular samples, not recommended for use(!) """ vi = surface_intercept(k,v) r = cartesian_mag(vi) if r <= diameter/2.: return vi # if r>diameter/2 need to scale it back # Therefore solve the following for mag # vi_new = vi - ks*mag/norm(ks), # mag(vi_new) = diameter/2 # therefore end up with a quadratic: ks = num.array(k[0:2]) a = 1. b = -2. * (v[0]*ks[0] + vi[1]*ks[1])/cartesian_mag(ks) c = cartesian_mag(vi)**2. - (diameter/2.)**2. arg = b**2. - 4.*a*c # make sure this method will result in a solution if arg > 0.: mag1 = (-b + num.sqrt(arg))/(2.*a) mag2 = (-b - num.sqrt(arg))/(2.*a) vi1 = vi - ks*mag1/cartesian_mag(ks) vi2 = vi - ks*mag2/cartesian_mag(ks) # chose soln that makes smallest angle # with the original intercept angle1 = num.fabs(cartesian_angle(vi,vi1)) angle2 = num.fabs(cartesian_angle(vi,vi2)) if angle1 < angle2: return vi1 else: return vi2 # otherwise just rescale the original vector else: vi = vi * (diameter/2.) / cartesian_mag(vi) return vi
def _calc_omega(self): """ calc omega, this is the angle between Q and the plane which is perpendicular to the axis of the chi circle. Notes: ------ For nu=mu=0 this is the same as the four circle def: omega = 0.5*TTH - TH, where TTH is the detector motor (=del) and TH is the sample circle (=eta). Therefore, for mu=nu=0 and del=0.5*eta, omega = 0, which means that Q is in the plane perpendicular to the chi axis. Note check sign of results??? """ phi = self.angles['phi'] chi = self.angles['chi'] eta = self.angles['eta'] mu = self.angles['mu'] H = num.array([[cosd(eta), sind(eta), 0.], [-sind(eta), cosd(eta), 0.], [0., 0., 1.]], float) M = num.array([[1., 0., 0.], [0., cosd(mu), -sind(mu)], [0., sind(mu), cosd(mu)]], float) # check the mult order here!!!! # T = num.dot(H.transpose(),M.transpose()) T = num.dot(M.transpose(), H.transpose()) Qpp = num.dot(T, self.Q) #omega = -1.*cartesian_angle([Qpp[0], 0, Qpp[2]],Qpp) omega = cartesian_angle([Qpp[0], 0, Qpp[2]], Qpp) self.pangles['omega'] = omega
def _angle(v): # cartesian angle is always btwn 0 and 180 angle = cartesian_angle(v, [1., 0.]) if (v[1] < 0.): return 360. - angle else: return angle
def _angle(v): # cartesian angle is always btwn 0 and 180 angle = cartesian_angle(v,[1.,0.]) if (v[1] < 0.): return 360. - angle else: return angle
def _calc_omega(self): """ calc omega, this is the angle between Q and the plane which is perpendicular to the axis of the chi circle. Notes: ------ For nu=mu=0 this is the same as the four circle def: omega = 0.5*TTH - TH, where TTH is the detector motor (=del) and TH is the sample circle (=eta). Therefore, for mu=nu=0 and del=0.5*eta, omega = 0, which means that Q is in the plane perpendicular to the chi axis. Note check sign of results??? """ phi=self.angles['phi'] chi=self.angles['chi'] eta=self.angles['eta'] mu=self.angles['mu'] H = num.array([[ cosd(eta), sind(eta), 0.], [-sind(eta), cosd(eta), 0.], [ 0., 0., 1.]],float) M = num.array([[ 1., 0., 0. ], [ 0., cosd(mu), -sind(mu)], [ 0., sind(mu), cosd(mu)]],float) # check the mult order here!!!! # T = num.dot(H.transpose(),M.transpose()) T = num.dot(M.transpose(),H.transpose()) Qpp = num.dot(T,self.Q) #omega = -1.*cartesian_angle([Qpp[0], 0, Qpp[2]],Qpp) omega = cartesian_angle([Qpp[0], 0, Qpp[2]],Qpp) self.pangles['omega'] = omega
def _angle(v): # cartesian angle is always btwn 0 and 180 angle = cartesian_angle(v, [1.0, 0.0]) if v[1] < 0.0: return 360.0 - angle else: return angle
def _calc_tau(self): """ Calc tau, this is the angle btwn n and the scattering-plane defined by ki and kr. ie the angle between n and Q Notes: ------ Can also calc from: tau = acos( cosd(alpha) * cosd(tth/2) * cosd(naz - qaz) ... + sind(alpha) * sind(tth/2) ) """ tau = cartesian_angle(self.Q, self.nm) self.pangles['tau'] = tau
def _calc_tau(self): """ Calc tau, this is the angle btwn n and the scattering-plane defined by ki and kr. ie the angle between n and Q Notes: ------ Can also calc from: tau = acos( cosd(alpha) * cosd(tth/2) * cosd(naz - qaz) ... + sind(alpha) * sind(tth/2) ) """ tau = cartesian_angle(self.Q,self.nm) self.pangles['tau'] = tau