Ejemplo n.º 1
0
    def make_and_store_cluster(self, ptc, detname, fraction=1., size=None):
        '''adds a cluster in a given detector, with a given fraction of
        the particle energy.
        Stores the cluster in the appropriate collection and records cluster in the history'''
        detector = self.detector.elements[detname]
        propagator(ptc.q()).propagate_one(ptc,
                                          detector.volume.inner,
                                          self.detector.elements['field'].magnitude)
        if size is None:
            size = detector.cluster_size(ptc)
        cylname = detector.volume.inner.name
        if not cylname in ptc.points:
            # TODO Colin particle was not extrapolated here...
            # issue must be solved!
            errormsg = '''
SimulationError : cannot make cluster for particle: 
particle: {ptc}
with vertex rho={rho:5.2f}, z={zed:5.2f}
cannot be extrapolated to : {det}\n'''.format(ptc=ptc,
                                              rho=ptc.vertex.Perp(),
                                              zed=ptc.vertex.Z(),
                                              det=detector.volume.inner)
            self.logger.warning(errormsg)
            raise SimulationError('Particle not extrapolated to the detector, so cannot make a cluster there. No worries for now, problem will be solved :-)')
        clusters = self.cluster_collection(cylname)
        cluster = Cluster(ptc.p4().E()*fraction, ptc.points[cylname], size, cylname, len(clusters), ptc)
        #update collections and history
        ptc.clusters[cylname] = cluster
        clusters[cluster.uniqueid] = cluster 
        self.update_history(ptc.uniqueid, cluster.uniqueid,)          
        pdebugger.info(" ".join(("Made", cluster.__str__())))
        return cluster
Ejemplo n.º 2
0
    def make_cluster(self, ptc, detname, fraction=1.0, size=None):
        """adds a cluster in a given detector, with a given fraction of
        the particle energy."""
        detector = self.detector.elements[detname]
        propagator(ptc.q()).propagate_one(ptc, detector.volume.inner, self.detector.elements["field"].magnitude)
        if size is None:
            size = detector.cluster_size(ptc)
        cylname = detector.volume.inner.name
        if not cylname in ptc.points:
            # TODO Colin particle was not extrapolated here...
            # issue must be solved!
            errormsg = """
SimulationError : cannot make cluster for particle: 
particle: {ptc}
with vertex rho={rho:5.2f}, z={zed:5.2f}
cannot be extrapolated to : {det}\n""".format(
                ptc=ptc, rho=ptc.vertex.Perp(), zed=ptc.vertex.Z(), det=detector.volume.inner
            )
            self.logger.warning(errormsg)
            raise SimulationError(
                "Particle not extrapolated to the detector, so cannot make a cluster there. No worries for now, problem will be solved :-)"
            )
        cluster = Cluster(ptc.p4().E() * fraction, ptc.points[cylname], size, cylname, ptc)
        ptc.clusters[cylname] = cluster
        pdebugger.info(" ".join(("Made", cluster.__str__())))
        return cluster
Ejemplo n.º 3
0
 def simulate_electron(self, ptc):
     '''Simulate an electron corresponding to gen particle ptc.
     
     Uses the methods detector.electron_energy_resolution
     and detector.electron_acceptance to smear the electron track.
     Later on, the particle flow algorithm will use the tracks
     coming from an electron to reconstruct electrons.
     
     This method does not simulate an electron energy deposit in the ECAL.
     '''
     pdebugger.info("Simulating Electron")
     ecal = self.detector.elements['ecal']
     track = self.make_and_store_track(ptc)
     propagator(ptc.q()).propagate_one(
         ptc,
         ecal.volume.inner,
         self.detector.elements['field'].magnitude
     )
     eres = self.detector.electron_energy_resolution(ptc)
     smeared_track = self.make_smeared_track(track, eres)
     if self.detector.electron_acceptance(smeared_track):
             self.smeared_tracks[smeared_track.uniqueid] = smeared_track
             self.update_history(track.uniqueid, smeared_track.uniqueid)  
             ptc.track_smeared = smeared_track 
     else:
         pdebugger.info(str('Rejected {}'.format(smeared_track)))
Ejemplo n.º 4
0
 def propagate_electron(self, ptc):
     pdebugger.info("Propogate Electron")
     ecal = self.detector.elements['ecal']
     propagator(ptc.q()).propagate_one(ptc,
                                       ecal.volume.inner,
                                       self.detector.elements['field'].magnitude)
     return
Ejemplo n.º 5
0
    def make_cluster(self, ptc, detname, fraction=1., size=None):
        '''adds a cluster in a given detector, with a given fraction of
        the particle energy.'''
        detector = self.detector.elements[detname]
        propagator(ptc.q()).propagate_one(
            ptc, detector.volume.inner,
            self.detector.elements['field'].magnitude)
        if size is None:
            size = detector.cluster_size(ptc)
        cylname = detector.volume.inner.name
        if not cylname in ptc.points:
            # TODO Colin particle was not extrapolated here...
            # issue must be solved!
            errormsg = '''
SimulationError : cannot make cluster for particle: 
particle: {ptc}
with vertex rho={rho:5.2f}, z={zed:5.2f}
cannot be extrapolated to : {det}\n'''.format(ptc=ptc,
                                              rho=ptc.vertex.Perp(),
                                              zed=ptc.vertex.Z(),
                                              det=detector.volume.inner)
            self.logger.warning(errormsg)
            raise SimulationError(
                'Particle not extrapolated to the detector, so cannot make a cluster there. No worries for now, problem will be solved :-)'
            )
        cluster = Cluster(ptc.p4().E() * fraction, ptc.points[cylname], size,
                          cylname, ptc)
        ptc.clusters[cylname] = cluster
        pdebugger.info(" ".join(("Made", cluster.__str__())))
        return cluster
Ejemplo n.º 6
0
 def smear_electron(self, ptc):
     pdebugger.info("Smearing Electron")
     ecal = self.detector.elements["ecal"]
     propagator(ptc.q()).propagate_one(ptc, ecal.volume.inner, self.detector.elements["field"].magnitude)
     if ptc.q() != 0:
         pdebugger.info(" ".join(("Made", ptc.track.__str__())))
     smeared = copy.deepcopy(ptc)
     return smeared
Ejemplo n.º 7
0
 def reconstruct_cluster(self,
                         cluster,
                         layer,
                         parent_ids,
                         energy=None,
                         vertex=None):
     '''construct a photon if it is an ecal
        construct a neutral hadron if it is an hcal
     '''
     if self.locked[cluster.uniqueid]:
         return
     if vertex is None:
         vertex = TVector3()
     pdg_id = None
     propagate_to = None
     if layer == 'ecal_in':
         pdg_id = 22  #photon
         propagate_to = [self.detector.elements['ecal'].volume.inner]
     elif layer == 'hcal_in':
         pdg_id = 130  #K0
         propagate_to = [
             self.detector.elements['ecal'].volume.inner,
             self.detector.elements['hcal'].volume.inner
         ]
     else:
         raise ValueError('layer must be equal to ecal_in or hcal_in')
     assert (pdg_id)
     mass, charge = particle_data[pdg_id]
     if energy is None:
         energy = cluster.energy
     if energy < mass:
         return None
     if mass == 0:
         momentum = energy  #avoid sqrt for zero mass
     else:
         momentum = math.sqrt(energy**2 - mass**2)
     p3 = cluster.position.Unit() * momentum
     p4 = TLorentzVector(p3.Px(), p3.Py(), p3.Pz(),
                         energy)  #mass is not accurate here
     particle = Particle(p4,
                         vertex,
                         charge,
                         pdg_id,
                         len(self.particles),
                         subtype='r')
     # alice: this may be a bit strange because we can make a photon
     # with a path where the point is actually that of the hcal?
     # nb this only is problem if the cluster and the assigned layer
     # are different
     propagator(charge).propagate([particle], propagate_to)
     #merge Nov 10th 2016 not sure about following line (was commented out in papasevent branch)
     particle.clusters[
         layer] = cluster  # not sure about this either when hcal is used to make an ecal cluster?
     self.locked[
         cluster.
         uniqueid] = True  #just OK but not nice if hcal used to make ecal.
     pdebugger.info(str('Made {} from {}'.format(particle, cluster)))
     self.insert_particle(parent_ids, particle)
Ejemplo n.º 8
0
    def simulate_hadron(self, ptc):
        """Simulate a hadron, neutral or charged.
        ptc should behave as pfobjects.Particle.
        """
        pdebugger.info("Simulating Hadron")
        # implement beam pipe scattering

        ecal = self.detector.elements["ecal"]
        hcal = self.detector.elements["hcal"]
        beampipe = self.detector.elements["beampipe"]
        frac_ecal = 0.0

        propagator(ptc.q()).propagate_one(ptc, beampipe.volume.inner, self.detector.elements["field"].magnitude)

        propagator(ptc.q()).propagate_one(ptc, beampipe.volume.outer, self.detector.elements["field"].magnitude)

        mscat.multiple_scattering(ptc, beampipe, self.detector.elements["field"].magnitude)

        # re-propagate after multiple scattering in the beam pipe
        # indeed, multiple scattering is applied within the beam pipe,
        # so the extrapolation points to the beam pipe entrance and exit
        # change after multiple scattering.
        propagator(ptc.q()).propagate_one(ptc, beampipe.volume.inner, self.detector.elements["field"].magnitude)
        propagator(ptc.q()).propagate_one(ptc, beampipe.volume.outer, self.detector.elements["field"].magnitude)
        propagator(ptc.q()).propagate_one(ptc, ecal.volume.inner, self.detector.elements["field"].magnitude)

        # these lines moved earlier in order to match cpp logic
        if ptc.q() != 0:
            pdebugger.info(" ".join(("Made", ptc.track.__str__())))
            smeared_track = self.smear_track(ptc.track, self.detector.elements["tracker"])
            if smeared_track:
                ptc.track_smeared = smeared_track

        if "ecal_in" in ptc.path.points:
            # doesn't have to be the case (long-lived particles)
            path_length = ecal.material.path_length(ptc)
            if path_length < sys.float_info.max:
                # ecal path length can be infinite in case the ecal
                # has lambda_I = 0 (fully transparent to hadrons)
                time_ecal_inner = ptc.path.time_at_z(ptc.points["ecal_in"].Z())
                deltat = ptc.path.deltat(path_length)
                time_decay = time_ecal_inner + deltat
                point_decay = ptc.path.point_at_time(time_decay)
                ptc.points["ecal_decay"] = point_decay
                if ecal.volume.contains(point_decay):
                    frac_ecal = random.uniform(0.0, 0.7)
                    cluster = self.make_cluster(ptc, "ecal", frac_ecal)
                    # For now, using the hcal resolution and acceptance
                    # for hadronic cluster
                    # in the ECAL. That's not a bug!
                    smeared = self.smear_cluster(cluster, hcal, acceptance=ecal)
                    if smeared:
                        ptc.clusters_smeared[smeared.layer] = smeared

        cluster = self.make_cluster(ptc, "hcal", 1 - frac_ecal)
        smeared = self.smear_cluster(cluster, hcal)
        if smeared:
            ptc.clusters_smeared[smeared.layer] = smeared
Ejemplo n.º 9
0
 def smear_electron(self, ptc):
     pdebugger.info("Smearing Electron")
     ecal = self.detector.elements['ecal']
     propagator(ptc.q()).propagate_one(
         ptc, ecal.volume.inner, self.detector.elements['field'].magnitude)
     if ptc.q() != 0:
         pdebugger.info(" ".join(("Made", ptc.track.__str__())))
     smeared = copy.deepcopy(ptc)
     return smeared
Ejemplo n.º 10
0
 def simulate_photon(self, ptc):
     pdebugger.info("Simulating Photon")
     detname = 'ecal'
     ecal = self.detector.elements[detname]
     propagator(ptc.q()).propagate_one(ptc, ecal.volume.inner)
     cluster = self.make_and_store_cluster(ptc, detname)
     smeared = self.make_and_store_smeared_cluster(cluster, ecal)
     if smeared:
         ptc.clusters_smeared[smeared.layer] = smeared
Ejemplo n.º 11
0
    def simulate_photon(self, ptc):
        pdebugger.info("Simulating Photon")
        detname = "ecal"
        ecal = self.detector.elements[detname]
        propagator(ptc.q()).propagate_one(ptc, ecal.volume.inner)

        cluster = self.make_cluster(ptc, detname)
        smeared = self.smear_cluster(cluster, ecal)
        if smeared:
            ptc.clusters_smeared[smeared.layer] = smeared
Ejemplo n.º 12
0
 def simulate_electron(self, ptc):
     pdebugger.info("Simulating Electron")
     ecal = self.detector.elements["ecal"]
     propagator(ptc.q()).propagate_one(ptc, ecal.volume.inner, self.detector.elements["field"].magnitude)
     cluster = self.make_cluster(ptc, "ecal")
     smeared_cluster = self.smear_cluster(cluster, ecal)
     if smeared_cluster:
         ptc.clusters_smeared[smeared_cluster.layer] = smeared_cluster
     smeared_track = self.smear_track(ptc.track, self.detector.elements["tracker"])
     if smeared_track:
         ptc.track_smeared = smeared_track
Ejemplo n.º 13
0
 def simulate_electron(self, ptc):
     pdebugger.info("Simulating Electron")
     ecal = self.detector.elements['ecal']
     propagator(ptc.q()).propagate_one(
         ptc, ecal.volume.inner, self.detector.elements['field'].magnitude)
     cluster = self.make_cluster(ptc, 'ecal')
     smeared_cluster = self.smear_cluster(cluster, ecal)
     if smeared_cluster:
         ptc.clusters_smeared[smeared_cluster.layer] = smeared_cluster
     smeared_track = self.smear_track(ptc.track,
                                      self.detector.elements['tracker'])
     if smeared_track:
         ptc.track_smeared = smeared_track
Ejemplo n.º 14
0
 def simulate_hadron(self, ptc):
     '''Simulate a hadron, neutral or charged.
     ptc should behave as pfobjects.Particle.
     '''
     pdebugger.info("Simulating Hadron")
     
     #implement beam pipe scattering
     ecal = self.detector.elements['ecal']
     hcal = self.detector.elements['hcal']
     frac_ecal = 0.
     if ptc.q() != 0 :
         #track is now made outside of the particle and then the particle is told where the track is
         track = self.make_and_store_track(ptc)
         tracker = self.detector.elements['tracker']
         smeared_track = self.make_and_store_smeared_track(
             ptc, 
             track, 
             tracker.resolution,
             tracker.acceptance
         )
     propagator(ptc.q()).propagate_one(ptc,
                                       ecal.volume.inner,
                                       self.detector.elements['field'].magnitude)
     
     if 'ecal_in' in ptc.path.points:
         # doesn't have to be the case (long-lived particles)
         path_length = ecal.material.path_length(ptc)
         if path_length < sys.float_info.max:
             # ecal path length can be infinite in case the ecal
             # has lambda_I = 0 (fully transparent to hadrons)
             time_ecal_inner = ptc.path.time_at_z(ptc.points['ecal_in'].Z())
             deltat = ptc.path.deltat(path_length)
             time_decay = time_ecal_inner + deltat
             point_decay = ptc.path.point_at_time(time_decay)
             ptc.points['ecal_decay'] = point_decay
             if ecal.volume.contains(point_decay):
                 frac_ecal = random.uniform(0., 0.7)
                 cluster = self.make_and_store_cluster(ptc, 'ecal', frac_ecal)
                 # For now, using the hcal resolution and acceptance
                 # for hadronic cluster
                 # in the ECAL. That's not a bug!
                 smeared = self.make_and_store_smeared_cluster(cluster, hcal, acceptance=ecal)
                 if smeared:
                     ptc.clusters_smeared[smeared.layer] = smeared
     cluster = self.make_and_store_cluster(ptc, 'hcal', 1-frac_ecal)
     smeared = self.make_and_store_smeared_cluster(cluster, hcal)
     if smeared:
         ptc.clusters_smeared[smeared.layer] = smeared
Ejemplo n.º 15
0
 def reconstruct_cluster(self, cluster, layer, parent_ids,
                         energy=None, vertex=None):
     '''construct a photon if it is an ecal
        construct a neutral hadron if it is an hcal
     '''
     if self.locked[cluster.uniqueid]:
         return 
     if vertex is None:
         vertex = TVector3()
     pdg_id = None
     propagate_to = None
     if layer=='ecal_in':
         pdg_id = 22 #photon
         propagate_to = [ self.detector.elements['ecal'].volume.inner ]
     elif layer=='hcal_in':
         pdg_id = 130 #K0
         propagate_to = [ self.detector.elements['ecal'].volume.inner,
                          self.detector.elements['hcal'].volume.inner ]
     else:
         raise ValueError('layer must be equal to ecal_in or hcal_in')
     assert(pdg_id)
     mass, charge = particle_data[pdg_id]
     if energy is None:
         energy = cluster.energy
     if energy < mass: 
         return None 
     if mass == 0:
         momentum = energy #avoid sqrt for zero mass
     else:
         momentum = math.sqrt(energy**2 - mass**2)
     p3 = cluster.position.Unit() * momentum
     p4 = TLorentzVector(p3.Px(), p3.Py(), p3.Pz(), energy) #mass is not accurate here
     particle = Particle(p4, vertex, charge, pdg_id)
     particle.set_dagid(IdCoder.make_id(IdCoder.PFOBJECTTYPE.PARTICLE, len(self.particles), 'r', particle.idvalue))
     
     # alice: this may be a bit strange because we can make a photon 
     # with a path where the point is actually that of the hcal?
     # nb this only is problem if the cluster and the assigned layer 
     # are different
     propagator(charge).propagate([particle],
                                  propagate_to)
     #merge Nov 10th 2016 not sure about following line (was commented out in papasevent branch)
     particle.clusters[layer] = cluster  # not sure about this either when hcal is used to make an ecal cluster?
     self.locked[cluster.uniqueid] = True #just OK but not nice if hcal used to make ecal.
     pdebugger.info(str('Made {} from {}'.format(particle, cluster)))
     self.insert_particle(parent_ids, particle)        
Ejemplo n.º 16
0
 def simulate_electron(self, ptc):
     '''Simulate an electron corresponding to gen particle ptc.
     
     Uses the methods detector.electron_energy_resolution
     and detector.electron_acceptance to smear the electron track.
     Later on, the particle flow algorithm will use the tracks
     coming from an electron to reconstruct electrons.
     
     This method does not simulate an electron energy deposit in the ECAL.
     '''
     pdebugger.info("Simulating Electron")
     ecal = self.detector.elements['ecal']
     track = self.make_and_store_track(ptc)
     propagator(ptc.q()).propagate_one(
         ptc, ecal.volume.inner, self.detector.elements['field'].magnitude)
     smeared_track = self.make_and_store_smeared_track(
         ptc, track, self.detector.electron_resolution,
         self.detector.electron_acceptance)
Ejemplo n.º 17
0
 def reconstruct_cluster(self, cluster, layer, energy=None, vertex=None):
     """construct a photon if it is an ecal
        construct a neutral hadron if it is an hcal
     """
     if vertex is None:
         vertex = TVector3()
     pdg_id = None
     propagate_to = None
     if layer == "ecal_in":
         pdg_id = 22  # photon
         propagate_to = [self.detector.elements["ecal"].volume.inner]
     elif layer == "hcal_in":
         pdg_id = 130  # K0
         propagate_to = [self.detector.elements["ecal"].volume.inner, self.detector.elements["hcal"].volume.inner]
     else:
         raise ValueError("layer must be equal to ecal_in or hcal_in")
     assert pdg_id
     mass, charge = particle_data[pdg_id]
     if energy is None:
         energy = cluster.energy
     if energy < mass:
         return None
     if mass == 0:
         momentum = energy  # avoid sqrt for zero mass
     else:
         momentum = math.sqrt(energy ** 2 - mass ** 2)
     p3 = cluster.position.Unit() * momentum
     p4 = TLorentzVector(p3.Px(), p3.Py(), p3.Pz(), energy)  # mass is not accurate here
     particle = Particle(p4, vertex, charge, pdg_id, Identifier.PFOBJECTTYPE.RECPARTICLE)
     # path = StraightLine(p4, vertex)
     # path.points[layer] = cluster.position
     # alice: this may be a bit strange because we can make a photon
     # with a path where the point is actually that of the hcal?
     # nb this only is problem if the cluster and the assigned layer
     # are different
     # particle.set_path(path)
     propagator(charge).propagate([particle], propagate_to)
     particle.clusters[layer] = cluster  # not sure about this either when hcal is used to make an ecal cluster?
     self.locked[cluster.uniqueid] = True  # just OK but not nice if hcal used to make ecal.
     pdebugger.info(str("Made {} from {}".format(particle, cluster)))
     return particle
Ejemplo n.º 18
0
 def simulate_electron(self, ptc):
     '''Simulate an electron corresponding to gen particle ptc.
     
     Uses the methods detector.electron_energy_resolution
     and detector.electron_acceptance to smear the electron track.
     Later on, the particle flow algorithm will use the tracks
     coming from an electron to reconstruct electrons.
     
     This method does not simulate an electron energy deposit in the ECAL.
     '''
     pdebugger.info("Simulating Electron")
     ecal = self.detector.elements['ecal']
     track = self.make_and_store_track(ptc)
     propagator(ptc.q()).propagate_one(
         ptc,
         ecal.volume.inner,
         self.detector.elements['field'].magnitude
     )
     smeared_track = self.make_and_store_smeared_track(
         ptc, track,
         self.detector.electron_resolution,
         self.detector.electron_acceptance
     )
Ejemplo n.º 19
0
 def simulate_electron(self, ptc):
     '''Simulate an electron corresponding to gen particle ptc.
     
     Uses the methods detector.electron_energy_resolution
     and detector.electron_acceptance to smear the electron track.
     Later on, the particle flow algorithm will use the tracks
     coming from an electron to reconstruct electrons.
     
     This method does not simulate an electron energy deposit in the ECAL.
     '''
     pdebugger.info("Simulating Electron")
     ecal = self.detector.elements['ecal']
     track = self.make_and_store_track(ptc)
     propagator(ptc.q()).propagate_one(
         ptc, ecal.volume.inner, self.detector.elements['field'].magnitude)
     eres = self.detector.electron_energy_resolution(ptc)
     smeared_track = self.make_smeared_track(track, eres)
     if self.detector.electron_acceptance(smeared_track):
         self.smeared_tracks[smeared_track.uniqueid] = smeared_track
         self.update_history(track.uniqueid, smeared_track.uniqueid)
         ptc.track_smeared = smeared_track
     else:
         pdebugger.info(str('Rejected {}'.format(smeared_track)))
Ejemplo n.º 20
0
 def simulate_electron(self, ptc):
     '''Simulate an electron corresponding to gen particle ptc.
     
     Uses the methods detector.electron_energy_resolution
     and detector.electron_acceptance to smear the electron track.
     Later on, the particle flow algorithm will use the tracks
     coming from an electron to reconstruct electrons.
     
     This method does not simulate an electron energy deposit in the ECAL.
     '''
     pdebugger.info("Simulating Electron")
     ecal = self.detector.elements['ecal']
     propagator(ptc.q()).propagate_one(
         ptc, ecal.volume.inner, self.detector.elements['field'].magnitude)
     eres = self.detector.electron_energy_resolution(ptc)
     scale_factor = random.gauss(1, eres)
     track = ptc.track
     smeared_track = SmearedTrack(track, track.p3 * scale_factor,
                                  track.charge, track.path)
     pdebugger.info(" ".join(("Made", smeared_track.__str__())))
     if self.detector.electron_acceptance(smeared_track):
         ptc.track_smeared = smeared_track
     else:
         pdebugger.info(str('Rejected {}'.format(smeared_track)))
Ejemplo n.º 21
0
 def propagate(self, ptc):
     """propagate the particle to all detector cylinders"""
     propagator(ptc.q()).propagate([ptc], self.detector.cylinders(), self.detector.elements["field"].magnitude)
Ejemplo n.º 22
0
 def propagate(self, ptc):
     '''propagate the particle to all detector cylinders'''
     propagator(
         ptc.q()).propagate([ptc], self.detector.cylinders(),
                            self.detector.elements['field'].magnitude)
Ejemplo n.º 23
0
 def propagate_electron(self, ptc):
     pdebugger.info("Propogate Electron")
     ecal = self.detector.elements['ecal']
     propagator(ptc.q()).propagate_one(
         ptc, ecal.volume.inner, self.detector.elements['field'].magnitude)
     return
Ejemplo n.º 24
0
    def simulate_hadron(self, ptc):
        '''Simulate a hadron, neutral or charged.
        ptc should behave as pfobjects.Particle.
        '''
        pdebugger.info("Simulating Hadron")
        
        #implement beam pipe scattering
        ecal = self.detector.elements['ecal']
        hcal = self.detector.elements['hcal']
        beampipe = self.detector.elements['beampipe']
        frac_ecal = 0.
        if ptc.q() != 0 :
            #track is now made outside of the particle and then the particle is told where the track is
            track = self.make_and_store_track(ptc)
            resolution = self.detector.elements['tracker'].pt_resolution(track)
            smeared_track = self.make_smeared_track(track, resolution)
            if self.detector.elements['tracker'].acceptance(smeared_track):
                self.smeared_tracks[smeared_track.uniqueid] = smeared_track
                self.update_history(track.uniqueid, smeared_track.uniqueid )   
                ptc.track_smeared = smeared_track 
            else:
                pdebugger.info(str('Rejected {}'.format(smeared_track)))
        
        propagator(ptc.q()).propagate_one(ptc,
                                          beampipe.volume.inner,
                                          self.detector.elements['field'].magnitude)

        propagator(ptc.q()).propagate_one(ptc,
                                          beampipe.volume.outer,
                                          self.detector.elements['field'].magnitude)

        #pdebug next line  must be editted out to match cpp
        #mscat.multiple_scattering(ptc, beampipe, self.detector.elements['field'].magnitude)

        #re-propagate after multiple scattering in the beam pipe
        #indeed, multiple scattering is applied within the beam pipe,
        #so the extrapolation points to the beam pipe entrance and exit
        #change after multiple scattering.
        propagator(ptc.q()).propagate_one(ptc,
                                           beampipe.volume.inner,
                                           self.detector.elements['field'].magnitude)
        propagator(ptc.q()).propagate_one(ptc,
                                           beampipe.volume.outer,
                                           self.detector.elements['field'].magnitude)
        propagator(ptc.q()).propagate_one(ptc,
                                           ecal.volume.inner,
                                           self.detector.elements['field'].magnitude)
        
        if 'ecal_in' in ptc.path.points:
            # doesn't have to be the case (long-lived particles)
            path_length = ecal.material.path_length(ptc)
            if path_length < sys.float_info.max:
                # ecal path length can be infinite in case the ecal
                # has lambda_I = 0 (fully transparent to hadrons)
                time_ecal_inner = ptc.path.time_at_z(ptc.points['ecal_in'].Z())
                deltat = ptc.path.deltat(path_length)
                time_decay = time_ecal_inner + deltat
                point_decay = ptc.path.point_at_time(time_decay)
                ptc.points['ecal_decay'] = point_decay
                if ecal.volume.contains(point_decay):
                    frac_ecal = random.uniform(0., 0.7)
                    cluster = self.make_and_store_cluster(ptc, 'ecal', frac_ecal)
                    # For now, using the hcal resolution and acceptance
                    # for hadronic cluster
                    # in the ECAL. That's not a bug!
                    smeared = self.make_and_store_smeared_cluster(cluster, hcal, acceptance=ecal)
                    if smeared:
                        ptc.clusters_smeared[smeared.layer] = smeared
        cluster = self.make_and_store_cluster(ptc, 'hcal', 1-frac_ecal)
        smeared = self.make_and_store_smeared_cluster(cluster, hcal)
        if smeared:
            ptc.clusters_smeared[smeared.layer] = smeared
Ejemplo n.º 25
0
    def simulate_hadron(self, ptc):
        '''Simulate a hadron, neutral or charged.
        ptc should behave as pfobjects.Particle.
        '''
        pdebugger.info("Simulating Hadron")
        #implement beam pipe scattering

        ecal = self.detector.elements['ecal']
        hcal = self.detector.elements['hcal']
        beampipe = self.detector.elements['beampipe']
        frac_ecal = 0.

        propagator(ptc.q()).propagate_one(
            ptc, beampipe.volume.inner,
            self.detector.elements['field'].magnitude)

        propagator(ptc.q()).propagate_one(
            ptc, beampipe.volume.outer,
            self.detector.elements['field'].magnitude)

        mscat.multiple_scattering(ptc, beampipe,
                                  self.detector.elements['field'].magnitude)

        #re-propagate after multiple scattering in the beam pipe
        #indeed, multiple scattering is applied within the beam pipe,
        #so the extrapolation points to the beam pipe entrance and exit
        #change after multiple scattering.
        propagator(ptc.q()).propagate_one(
            ptc, beampipe.volume.inner,
            self.detector.elements['field'].magnitude)
        propagator(ptc.q()).propagate_one(
            ptc, beampipe.volume.outer,
            self.detector.elements['field'].magnitude)
        propagator(ptc.q()).propagate_one(
            ptc, ecal.volume.inner, self.detector.elements['field'].magnitude)

        # these lines moved earlier in order to match cpp logic
        if ptc.q() != 0:
            pdebugger.info(" ".join(("Made", ptc.track.__str__())))
            smeared_track = self.smear_track(ptc.track,
                                             self.detector.elements['tracker'])
            if smeared_track:
                ptc.track_smeared = smeared_track

        if 'ecal_in' in ptc.path.points:
            # doesn't have to be the case (long-lived particles)
            path_length = ecal.material.path_length(ptc)
            if path_length < sys.float_info.max:
                # ecal path length can be infinite in case the ecal
                # has lambda_I = 0 (fully transparent to hadrons)
                time_ecal_inner = ptc.path.time_at_z(ptc.points['ecal_in'].Z())
                deltat = ptc.path.deltat(path_length)
                time_decay = time_ecal_inner + deltat
                point_decay = ptc.path.point_at_time(time_decay)
                ptc.points['ecal_decay'] = point_decay
                if ecal.volume.contains(point_decay):
                    frac_ecal = random.uniform(0., 0.7)
                    cluster = self.make_cluster(ptc, 'ecal', frac_ecal)
                    # For now, using the hcal resolution and acceptance
                    # for hadronic cluster
                    # in the ECAL. That's not a bug!
                    smeared = self.smear_cluster(cluster,
                                                 hcal,
                                                 acceptance=ecal)
                    if smeared:
                        ptc.clusters_smeared[smeared.layer] = smeared

        cluster = self.make_cluster(ptc, 'hcal', 1 - frac_ecal)
        smeared = self.smear_cluster(cluster, hcal)
        if smeared:
            ptc.clusters_smeared[smeared.layer] = smeared
Ejemplo n.º 26
0
    def simulate_hadron(self, ptc):
        '''Simulate a hadron, neutral or charged.
        ptc should behave as pfobjects.Particle.
        '''
        pdebugger.info("Simulating Hadron")

        #implement beam pipe scattering
        ecal = self.detector.elements['ecal']
        hcal = self.detector.elements['hcal']
        beampipe = self.detector.elements['beampipe']
        frac_ecal = 0.
        if ptc.q() != 0:
            #track is now made outside of the particle and then the particle is told where the track is
            track = self.make_and_store_track(ptc)
            resolution = self.detector.elements['tracker'].pt_resolution(track)
            smeared_track = self.make_smeared_track(track, resolution)
            if self.detector.elements['tracker'].acceptance(smeared_track):
                self.smeared_tracks[smeared_track.uniqueid] = smeared_track
                self.update_history(track.uniqueid, smeared_track.uniqueid)
                ptc.track_smeared = smeared_track
            else:
                pdebugger.info(str('Rejected {}'.format(smeared_track)))

        propagator(ptc.q()).propagate_one(
            ptc, beampipe.volume.inner,
            self.detector.elements['field'].magnitude)

        propagator(ptc.q()).propagate_one(
            ptc, beampipe.volume.outer,
            self.detector.elements['field'].magnitude)

        #pdebug next line  must be editted out to match cpp
        #mscat.multiple_scattering(ptc, beampipe, self.detector.elements['field'].magnitude)

        #re-propagate after multiple scattering in the beam pipe
        #indeed, multiple scattering is applied within the beam pipe,
        #so the extrapolation points to the beam pipe entrance and exit
        #change after multiple scattering.
        propagator(ptc.q()).propagate_one(
            ptc, beampipe.volume.inner,
            self.detector.elements['field'].magnitude)
        propagator(ptc.q()).propagate_one(
            ptc, beampipe.volume.outer,
            self.detector.elements['field'].magnitude)
        propagator(ptc.q()).propagate_one(
            ptc, ecal.volume.inner, self.detector.elements['field'].magnitude)

        if 'ecal_in' in ptc.path.points:
            # doesn't have to be the case (long-lived particles)
            path_length = ecal.material.path_length(ptc)
            if path_length < sys.float_info.max:
                # ecal path length can be infinite in case the ecal
                # has lambda_I = 0 (fully transparent to hadrons)
                time_ecal_inner = ptc.path.time_at_z(ptc.points['ecal_in'].Z())
                deltat = ptc.path.deltat(path_length)
                time_decay = time_ecal_inner + deltat
                point_decay = ptc.path.point_at_time(time_decay)
                ptc.points['ecal_decay'] = point_decay
                if ecal.volume.contains(point_decay):
                    frac_ecal = random.uniform(0., 0.7)
                    cluster = self.make_and_store_cluster(
                        ptc, 'ecal', frac_ecal)
                    # For now, using the hcal resolution and acceptance
                    # for hadronic cluster
                    # in the ECAL. That's not a bug!
                    smeared = self.make_and_store_smeared_cluster(
                        cluster, hcal, acceptance=ecal)
                    if smeared:
                        ptc.clusters_smeared[smeared.layer] = smeared
        cluster = self.make_and_store_cluster(ptc, 'hcal', 1 - frac_ecal)
        smeared = self.make_and_store_smeared_cluster(cluster, hcal)
        if smeared:
            ptc.clusters_smeared[smeared.layer] = smeared