def test_ip_many(self): npoints = 100 scale = 1e-6 radii = np.linspace(0.1 * scale, 0.2 * scale, npoints) angles = np.linspace(0, math.pi, npoints) momenta = np.linspace(200, 500, npoints) mass = 0.5 field = 1e-5 origin = TVector3(0, 0, 0) for radius, angle, momentum in zip(radii, angles, momenta): ip_pos = TVector3(math.cos(angle), math.sin(angle), 0) ip_pos *= radius p3 = TVector3(math.cos(angle - math.pi / 2.), math.sin(angle - math.pi / 2.), 0) p3 *= momentum p4 = TLorentzVector() p4.SetVectM(p3, mass) helix_vertex = copy.deepcopy(ip_pos) delta = copy.deepcopy(p3.Unit()) delta *= radius helix_vertex += delta helix = Helix(field, 1., p4, helix_vertex) # jet direction is 0.1 radians away from particle direction # to obtain a positivive IP sign jet_dir = copy.deepcopy(p3).Unit() jet_dir.RotateZ(0.1) ip_nic = compute_IP(helix, origin, jet_dir) ip_obj = ImpactParameter(helix, origin, jet_dir) verbose = False places = 8 if verbose: print '-' * 50 print math.cos(angle), math.sin(angle), radius print 'obj', ip_obj.value, '({})'.format( abs(ip_obj.value) - radius) print 'nic', ip_nic, '({})'.format(abs(ip_nic) - radius) else: self.assertAlmostEqual(abs(ip_obj.value), radius, places=places) #COLIN->NIC: Nicolo's minimization does not give the right result # could be that it only works for very small distances? # can be tested by uncommenting the following line and # running this test file self.assertAlmostEqual(abs(ip_nic), radius, places=places)
def propagate_one(self, particle, cylinder, field, debug_info=None): helix = Helix(field, particle.q(), particle.p4(), particle.vertex) particle.set_path(helix) is_looper = helix.extreme_point_xy.Mag() < cylinder.rad is_positive = particle.p4().Z() > 0. if not is_looper: try: xm, ym, xp, yp = circle_intersection(helix.center_xy.X(), helix.center_xy.Y(), helix.rho, cylinder.rad ) except ValueError: return # raise PropagationError(particle) # particle.points[cylinder.name+'_m'] = Point(xm,ym,0) # particle.points[cylinder.name+'_p'] = Point(xp,yp,0) phi_m = helix.phi(xm, ym) phi_p = helix.phi(xp, yp) dest_time = helix.time_at_phi(phi_p) destination = helix.point_at_time(dest_time) if destination.Z()*helix.udir.Z()<0.: dest_time = helix.time_at_phi(phi_m) destination = helix.point_at_time(dest_time) if abs(destination.Z())<cylinder.z: particle.points[cylinder.name] = destination else: is_looper = True if is_looper: # extrapolating to endcap destz = cylinder.z if helix.udir.Z() > 0. else -cylinder.z dest_time = helix.time_at_z(destz) destination = helix.point_at_time(dest_time) # destz = cylinder.z if positive else -cylinder.z particle.points[cylinder.name] = destination info = Info() info.is_positive = is_positive info.is_looper = is_looper return info