Exemple #1
0
class PapasDisplay(Analyzer):
    '''Plots a PAPAS event display

    Example configuration:

    from heppy.analyzers.PapasDisplay import PapasDisplay
    papasdisplay = cfg.Analyzer(
        PapasDisplay,
        instance_label = 'papas',
        detector = detector,
        particles = 'papas_sim_particles',
        clusters = ['ecal_clusters', 'hcal_clusters']
        display = True
        )
    '''
    def __init__(self, *args, **kwargs):
        super(PapasDisplay, self).__init__(*args, **kwargs)
        self.detector = self.cfg_ana.detector
        self.is_display = self.cfg_ana.display
        if self.is_display:
            self.init_display()

    def init_display(self):
        self.display = Display(['xy', 'yz'])
        self.gdetector = GDetector(self.detector)
        self.display.register(self.gdetector, layer=0, clearable=False)
        self.is_display = True

    def process(self, event):
        particles = getattr(event, self.cfg_ana.particles)
        if self.is_display:
            self.display.clear()
            self.display.register(GTrajectories(particles), layer=1)
            for clustername in self.cfg_ana.clusters:
                blobs = map(Blob, getattr(event, clustername).values())
                self.display.register(blobs, layer=1, clearable=False)
Exemple #2
0
    from heppy.display.geometry import GDetector
    from heppy.display.pfobjects import GTrajectories

    display_on = True
    detector = cms

    logging.basicConfig(level='WARNING')
    logger = logging.getLogger('Simulator')
    logger.addHandler(logging.StreamHandler(sys.stdout))

    for i in range(1):
        if not i % 100:
            print i
        simulator = Simulator(detector, logger)
        # particles = monojet([211, -211, 130, 22, 22, 22], math.pi/2., math.pi/2., 2, 50)
        particles = [
            # particle(211, math.pi/2., math.pi/2., 100),
            particle(211, math.pi / 2 + 0.5, 0., 40.),
            # particle(130, math.pi/2., math.pi/2.+0., 100.),
            # particle(22, math.pi/2., math.pi/2.+0.0, 10.)
        ]
        simulator.simulate(particles)

    if display_on:
        display = Display(['xy', 'yz', 'ECAL_thetaphi', 'HCAL_thetaphi'])
        gdetector = GDetector(detector)
        display.register(gdetector, 0)
        gtrajectories = GTrajectories(simulator.ptcs)
        display.register(gtrajectories, 1)
        display.draw()
Exemple #3
0
class PapasSim(Analyzer):
    '''Runs PAPAS, the PArametrized Particle Simulation.
    
    #This will need to redocumented once new papasdata structure arrives

    Example configuration:

    from heppy.analyzers.PapasSim import PapasSim
    from heppy.papas.detectors.CMS import CMS
    papas = cfg.Analyzer(
        PapasSim,
        instance_label = 'papas',
        detector = CMS(),
        gen_particles = 'gen_particles_stable',
        sim_particles = 'sim_particles',
        merged_ecals = 'ecal_clusters',
        merged_hcals = 'hcal_clusters',
        tracks = 'tracks',
        #rec_particles = 'sim_rec_particles', # optional - will only do a simulation reconstruction if a name is provided
        output_history = 'history_nodes',
        display_filter_func = lambda ptc: ptc.e()>1.,
        display = False,
        verbose = True
    )
    detector:      Detector model to be used.
    gen_particles: Name of the input gen particle collection
    sim_particles: Name extension for the output sim particle collection.
                   Note that the instance label is prepended to this name.
                   Therefore, in this particular case, the name of the output
                   sim particle collection is "papas_sim_particles".
    merged_ecals: Name for the merged clusters created by simulator
    merged_hcals: Name for the merged clusters created by simulator
    tracks:       Name for smeared tracks created by simulator
    rec_particles: Optional. Name extension for the reconstructed particles created by simulator
                   This is retained for the time being to allow two reconstructions to be compared
                   Reconstruction will occur if this parameter  or rec_particles_no_leptons is provided
                   Same comments as for the sim_particles parameter above.
    rec_particles_no_leptons: Optional. Name extension for the reconstructed particles created by simulator
                   without electrons and muons
                   Reconstruction will occur if this parameter  or rec_particles is provided
                   This is retained for the time being to allow two reconstructions to be compared
                   Same comments as for the sim_particles parameter above.
    smeared: Name for smeared leptons
    history: Optional name for the history nodes, set to None if not needed
    display      : Enable the event display
    verbose      : Enable the detailed printout.

        event must contain
          todo once history is implemented
        event will gain
          ecal_clusters:- smeared merged clusters from simulation
          hcal_clusters:- smeared merged clusters from simulation
          tracks:       - tracks from simulation
          baseline_particles:- simulated particles (excluding electrons and muons)
          sim_particles - simulated particles including electrons and muons
        
    '''
    def __init__(self, *args, **kwargs):
        super(PapasSim, self).__init__(*args, **kwargs)
        self.detector = self.cfg_ana.detector
        self.simulator = Simulator(self.detector, self.mainLogger)
        self.simname = '_'.join(
            [self.instance_label, self.cfg_ana.sim_particles])
        self.tracksname = self.cfg_ana.tracks
        self.mergedecalsname = self.cfg_ana.merged_ecals
        self.mergedhcalsname = self.cfg_ana.merged_hcals
        self.historyname = self.cfg_ana.output_history
        self.is_display = self.cfg_ana.display
        if self.is_display:
            self.init_display()

    def init_display(self):
        self.display = Display(['xy', 'yz'])
        self.gdetector = GDetector(self.detector)
        self.display.register(self.gdetector, layer=0, clearable=False)
        self.is_display = True

    def process(self, event):

        event.simulator = self
        if self.is_display:
            self.display.clear()
        pfsim_particles = []
        gen_particles = getattr(event, self.cfg_ana.gen_particles)
        try:
            self.simulator.simulate(gen_particles)
        except (PropagationError, SimulationError) as err:
            self.mainLogger.error(str(err) + ' -> Event discarded')
            return False
        pfsim_particles = self.simulator.ptcs
        if self.is_display:
            self.display.register(GTrajectories(pfsim_particles), layer=1)
        #these are the particles before simulation
        simparticles = sorted(pfsim_particles,
                              key=lambda ptc: ptc.e(),
                              reverse=True)
        setattr(event, self.simname, simparticles)

        #extract the tracks and clusters (extraction is prior to Colins merging step)
        event.tracks = dict()
        event.ecal_clusters = dict()
        event.hcal_clusters = dict()
        if "tracker" in self.simulator.pfinput.elements:
            for element in self.simulator.pfinput.elements["tracker"]:
                event.tracks[element.uniqueid] = element

        if "ecal_in" in self.simulator.pfinput.elements:
            for element in self.simulator.pfinput.elements["ecal_in"]:
                event.ecal_clusters[element.uniqueid] = element

        if "hcal_in" in self.simulator.pfinput.elements:
            for element in self.simulator.pfinput.elements["hcal_in"]:
                event.hcal_clusters[element.uniqueid] = element

        ruler = Distance()

        #create history node
        #note eventually history will be created by the simulator and passed in
        # as an argument and this will no longer be needed
        uniqueids = list(event.tracks.keys()) + list(
            event.ecal_clusters.keys()) + list(event.hcal_clusters.keys())
        history = dict((idt, Node(idt)) for idt in uniqueids)

        #Now merge the simulated clusters and tracks as a separate pre-stage (prior to new reconstruction)
        # and set the event to point to the merged cluster
        pfevent = PFEvent(event, 'tracks', 'ecal_clusters', 'hcal_clusters')
        merged_ecals = MergedClusterBuilder(pfevent.ecal_clusters, ruler,
                                            history)
        setattr(event, self.mergedecalsname, merged_ecals.merged)
        merged_hcals = MergedClusterBuilder(pfevent.hcal_clusters, ruler,
                                            merged_ecals.history_nodes)
        setattr(event, self.mergedhcalsname, merged_hcals.merged)
        setattr(event, self.historyname, merged_hcals.history_nodes)
Exemple #4
0
    from heppy.display.geometry import GDetector
    from heppy.display.pfobjects import GTrajectories

    display_on = True
    detector = cms

    logging.basicConfig(level="WARNING")
    logger = logging.getLogger("Simulator")
    logger.addHandler(logging.StreamHandler(sys.stdout))

    for i in range(1):
        if not i % 100:
            print i
        simulator = Simulator(detector, logger)
        # particles = monojet([211, -211, 130, 22, 22, 22], math.pi/2., math.pi/2., 2, 50)
        particles = [
            # particle(211, math.pi/2., math.pi/2., 100),
            particle(211, math.pi / 2 + 0.5, 0.0, 40.0),
            # particle(130, math.pi/2., math.pi/2.+0., 100.),
            # particle(22, math.pi/2., math.pi/2.+0.0, 10.)
        ]
        simulator.simulate(particles)

    if display_on:
        display = Display(["xy", "yz", "ECAL_thetaphi", "HCAL_thetaphi"])
        gdetector = GDetector(detector)
        display.register(gdetector, 0)
        gtrajectories = GTrajectories(simulator.ptcs)
        display.register(gtrajectories, 1)
        display.draw()
Exemple #5
0
class PapasDisplay(Analyzer):
    '''Plots a PAPAS event display
    
    Can be used to produce a single event plot or a comparative event plot.

    Example configuration::
        #(single event plot)
        from heppy.analyzers.PapasDisplay import PapasDisplay 
        papasdisplay = cfg.Analyzer(
           PapaDisplay,
           projections = ['xy', 'yz'],
           screennames = ["simulated"],
           particles_type_and_subtypes = ['ps'],
           clusters_type_and_subtypes = [['es', 'hs']],
           detector = detector,
           save = True,
           display = True
        )
        #(comparative event plot)
        from heppy.analyzers.PapasDisplay import PapasDisplay 
        papasdisplay = cfg.Analyzer(
           PapaDisplay,
           projections = ['xy', 'yz'],
           screennames = ["simulated", "reconstructed"],
           particles_type_and_subtypes = ['ps', 'pr'],
           clusters_type_and_subtypes = [['es', 'hs'],['em', 'hm']],
           detector = detector,
           save = True,
           display = True
        )
    
    @param projections: list of projections eg ['xy', 'yz', 'xz' ,'ECAL_thetaphi', 'HCAL_thetaphi']
                 these will be separate windows
    @param subscreens: list of names of panels within each window eg subscreens=["simulated", "reconstructed"]
          each of the projection windows will contain all of the subscreens
          the subscreens can be used to show different aspects of an event, eg simulated particles and reconstructed particles
    @param particles_type_and_subtypes: list of type_and_subtypes of particles (eg ['ps', 'pr']). 
           List must be same length as subscreens. Each element of list says which particles to plot on the corresponding subscreen.
    @param clusters_type_and_subtypes: list of type_and_subtypes of clusters (eg [['es', 'hs'],['em', 'hm']]). 
           The list must be same length as subscreens, and each element should itself be a list. 
           Each element of the list says which clusters to plot on the corresponding subscreen.
           More than one cluster type may be plotted on a single screen.
    @param detector: the detector to be plotted
    @param save: boolean, if True will save graph to png file.
    @param display: boolean, if True will plot graph to screen.
 '''


    def __init__(self, *args, **kwargs):
        super(PapasDisplay, self).__init__(*args, **kwargs)
        self.compare = False
        nscreens = len(self.cfg_ana.screennames)
        if nscreens == 2:
            self.compare = True     
        if (len(self.cfg_ana.particles_type_and_subtypes) != nscreens or
                len(self.cfg_ana.clusters_type_and_subtypes) != nscreens):
            raise Exception("Inconsistent display options: screennames, particles_type_and_subtypes and clusters_type_and_subtypes argument lists must have same length")
        if self.cfg_ana.do_display:
            self.init_display()

    def init_display(self):
        '''Set up the display'''
        self.display = Display(self.cfg_ana.projections, self.cfg_ana.screennames)
        self.gdetector = GDetector(self.cfg_ana.detector)
        self.display.register(self.gdetector, layer=0, clearable=False)

    def process(self, event):
        '''Selects the required particles and clusters and registers them on the display
        @param event: event that must contain a papasevent'''
        if not self.cfg_ana.do_display:
            return
        self.display.clear()
        for i in range(len(self.cfg_ana.screennames)):
            particles_collection = event.papasevent.get_collection(self.cfg_ana.particles_type_and_subtypes[i])
            if particles_collection:
                self.register_particles(particles_collection.values(), i)
            for type_and_subtype in self.cfg_ana.clusters_type_and_subtypes[i]:
                cluster_collection = event.papasevent.get_collection(type_and_subtype)
                if cluster_collection:
                    self.register_clusters(cluster_collection.values(), i)
 
    def register_particles(self, particles, side=0):
        '''
        Adds list of particles into the display
        @param particles:  list of particles to append to display
        @param side:  0 = left, 1 = right
        '''
        self.display.register(GTrajectories(particles), layer=2, sides=[side])
        if self.compare:
            otherside = (side + 1)%2 #opposite side
            self.display.register(GTrajectories(particles, is_grey=True), layer=1, sides=[otherside])
 
    def register_clusters(self, clusters, side=0):
        '''Adds list of clusters into the display
        @param clusters:  list of clusters to append to display
        @param side:  0 = left, 1 = right'''        
        blobs = map(Blob, clusters)   
        self.display.register(blobs, layer=2, clearable=True, sides=[side])
        if self.compare:
            otherside = (side + 1)%2
            mapfunc = partial(Blob, grey=True)
            blobs = map(mapfunc, clusters)
            self.display.register(blobs, layer=1, clearable=True, sides=[otherside])
Exemple #6
0
            pass
        else:
            raise ValueError('implement drawing for projection ' + projection )


class GDetector(object):
    def __init__(self, description):
        self.desc = description
        elems = sorted(self.desc.elements.values(), key= lambda x : x.volume.outer.rad, reverse = True)
        self.elements = [GDetectorElement(elem) for elem in elems]
        #self.elements = [GDetectorElement(elem) for elem in self.desc.elements.values()]
            
    def draw(self, projection):
        for elem in self.elements:
            elem.draw(projection)


            
if __name__ == '__main__':

    from ROOT import TCanvas, TH2F
    from heppy.papas.detectors.CMS import CMS
    from heppy.display.core import Display

    cms = CMS()
    gcms = GDetector(cms)

    display = Display()
    display.register(gcms, 0)
    display.draw()
Exemple #7
0
class PapasSim(Analyzer):
    '''Runs PAPAS, the PArametrized Particle Simulation.

    Example configuration:

    from heppy.analyzers.PapasSim import PapasSim
    from heppy.papas.detectors.CMS import CMS
    papas = cfg.Analyzer(
        PapasSim,
        instance_label = 'papas',
        detector = CMS(),
        gen_particles = 'gen_particles_stable',
        sim_particles = 'sim_particles',
        rec_particles = 'rec_particles',
        display = False,
        verbose = False
    )

    detector:      Detector model to be used.
    gen_particles: Name of the input gen particle collection
    sim_particles: Name extension for the output sim particle collection.
                   Note that the instance label is prepended to this name.
                   Therefore, in this particular case, the name of the output
                   sim particle collection is "papas_sim_particles".
    rec_particles: Name extension for the output reconstructed particle collection.
                   Same comments as for the sim_particles parameter above.
    display      : Enable the event display
    verbose      : Enable the detailed printout.
    '''

    def __init__(self, *args, **kwargs):
        super(PapasSim, self).__init__(*args, **kwargs)
        self.detector = self.cfg_ana.detector
        self.simulator = Simulator(self.detector,
                                   self.mainLogger)
        self.simname = '_'.join([self.instance_label,  self.cfg_ana.sim_particles])
        self.recname = '_'.join([self.instance_label,  self.cfg_ana.rec_particles])
        self.is_display = self.cfg_ana.display
        if self.is_display:
            self.init_display()

    def init_display(self):
        self.display = Display(['xy','yz'])
        self.gdetector = GDetector(self.detector)
        self.display.register(self.gdetector, layer=0, clearable=False)
        self.is_display = True

    def process(self, event):
        event.simulator = self
        if self.is_display:
            self.display.clear()
        pfsim_particles = []
        gen_particles = getattr(event, self.cfg_ana.gen_particles)
        self.simulator.simulate( gen_particles )
        pfsim_particles = self.simulator.ptcs
        if self.is_display:
            self.display.register( GTrajectories(pfsim_particles),
                                   layer=1)
        simparticles = sorted( pfsim_particles,
                               key = lambda ptc: ptc.e(), reverse=True)
        particles = sorted( self.simulator.particles,
                            key = lambda ptc: ptc.e(), reverse=True)
        setattr(event, self.simname, simparticles)
        pfinput = PFInput(simparticles)
        event.tracks = dict()
        event.ECALclusters = dict()
        event.HCALclusters = dict()
        for label, element in pfinput.elements.iteritems():
            if label == 'tracker':
                event.tracks[0,id(element)]=element
            elif label == 'ecal_in':
                event.ECALclusters[1,id(element)]=element
            elif label == 'hcal_in':
                event.HCALclusters[2,id(element)]=element
            else:
                print label
                assert(False)
        setattr(event, self.recname, particles)
Exemple #8
0
class Papas(Analyzer):
    '''Runs PAPAS, the PArametrized Particle Simulation. 

    Papas reads a list of stable generated particles, 
    and creates a list of reconstruted particles. 
    First, the particles are extrapolated in the magnetic field
    through the tracker and to the calorimeters, 
    and the particle deposits are simulated using a parametrized simulation. 
    Then, a particle flow algorithm is used to connect the simulated tracks 
    and calorimeter energy deposits, and to identify and reconstruct 
    final state particles. 

    Example: 

    from heppy.analyzers.Papas import Papas
    from heppy.papas.detectors.CMS import CMS
    papas = cfg.Analyzer(
      Papas,
      instance_label = 'papas',
      detector = CMS(),
      gen_particles = 'gen_particles_stable',
      sim_particles = 'sim_particles',
      rec_particles = 'particles',
      display = False,
      verbose = True
    )

    detector:      Detector model to be used, here CMS.  
    gen_particles: Name of the input gen particle collection
    sim_particles: Name for the output sim particle collection. 
    rec_particles: Name for the output reconstructed particle collection.
    display      : Enable the event display
    verbose      : Enable the detailed printout.
    '''

    def __init__(self, *args, **kwargs):
        super(Papas, self).__init__(*args, **kwargs)
        self.detector = self.cfg_ana.detector
        self.simulator = Simulator(self.detector,
                                   self.mainLogger)
        self.is_display = self.cfg_ana.display
        if self.is_display:
            self.init_display()        
        
    def init_display(self):
        self.display = Display(['xy','yz'])
        self.gdetector = GDetector(self.detector)
        self.display.register(self.gdetector, layer=0, clearable=False)
        self.is_display = True
        
    def process(self, event):
        event.simulator = self 
        if self.is_display:
            self.display.clear()
        pfsim_particles = []
        gen_particles = getattr(event, self.cfg_ana.gen_particles)
        self.simulator.simulate( gen_particles )
        pfsim_particles = self.simulator.ptcs
        if self.is_display:
            particles_for_display = pfsim_particles
            if hasattr(self.cfg_ana, 'display_filter_func'):
                particles_for_display = [ ptc for ptc in pfsim_particles if 
                                          self.cfg_ana.display_filter_func(ptc) ]
            self.display.register( GTrajectories(particles_for_display),
                                   layer=1)
        simparticles = sorted( pfsim_particles,
                               key = lambda ptc: ptc.e(), reverse=True)
        particles = sorted( self.simulator.particles,
                            key = lambda ptc: ptc.e(), reverse=True)
        setattr(event, self.cfg_ana.sim_particles, simparticles)
        setattr(event, self.cfg_ana.rec_particles, particles)
Exemple #9
0
class PapasDisplay(Analyzer):
    '''Plots a PAPAS event display
    
    Can be used to produce a single event plot or a comparative event plot.

    Example configuration::
        #(single event plot)
        from heppy.analyzers.PapasDisplay import PapasDisplay 
        papasdisplay = cfg.Analyzer(
           PapaDisplay,
           projections = ['xy', 'yz'],
           screennames = ["simulated"],
           particles_type_and_subtypes = ['ps'],
           clusters_type_and_subtypes = [['es', 'hs']],
           detector = detector,
           save = True,
           display = True
        )
        #(comparative event plot)
        from heppy.analyzers.PapasDisplay import PapasDisplay 
        papasdisplay = cfg.Analyzer(
           PapaDisplay,
           projections = ['xy', 'yz'],
           screennames = ["simulated", "reconstructed"],
           particles_type_and_subtypes = ['ps', 'pr'],
           clusters_type_and_subtypes = [['es', 'hs'],['em', 'hm']],
           detector = detector,
           save = True,
           display = True
        )
    
    @param projections: list of projections eg ['xy', 'yz', 'xz' ,'ECAL_thetaphi', 'HCAL_thetaphi']
                 these will be separate windows
    @param subscreens: list of names of panels within each window eg subscreens=["simulated", "reconstructed"]
          each of the projection windows will contain all of the subscreens
          the subscreens can be used to show different aspects of an event, eg simulated particles and reconstructed particles
    @param particles_type_and_subtypes: list of type_and_subtypes of particles (eg ['ps', 'pr']). 
           List must be same length as subscreens. Each element of list says which particles to plot on the corresponding subscreen.
    @param clusters_type_and_subtypes: list of type_and_subtypes of clusters (eg [['es', 'hs'],['em', 'hm']]). 
           The list must be same length as subscreens, and each element should itself be a list. 
           Each element of the list says which clusters to plot on the corresponding subscreen.
           More than one cluster type may be plotted on a single screen.
    @param detector: the detector to be plotted
    @param save: boolean, if True will save graph to png file.
    @param display: boolean, if True will plot graph to screen.
 '''


    def __init__(self, *args, **kwargs):
        super(PapasDisplay, self).__init__(*args, **kwargs)
        self.compare = False
        nscreens = len(self.cfg_ana.screennames)
        if nscreens == 2:
            self.compare = True     
        if (len(self.cfg_ana.particles_type_and_subtypes) != nscreens or
                len(self.cfg_ana.clusters_type_and_subtypes) != nscreens):
            raise Exception("Inconsistent display options: screennames, particles_type_and_subtypes and clusters_type_and_subtypes argument lists must have same length")
        if self.cfg_ana.do_display:
            self.init_display()

    def init_display(self):
        '''Set up the display'''
        self.display = Display(self.cfg_ana.projections, self.cfg_ana.screennames)
        self.gdetector = GDetector(self.cfg_ana.detector)
        self.display.register(self.gdetector, layer=0, clearable=False)

    def process(self, event):
        '''Selects the required particles and clusters and registers them on the display
        @param event: event that must contain a papasevent'''
        if not self.cfg_ana.do_display:
            return
        self.display.clear()
        for i in range(len(self.cfg_ana.screennames)):
            particles_collection = event.papasevent.get_collection(self.cfg_ana.particles_type_and_subtypes[i])
            if particles_collection:
                self.register_particles(particles_collection.values(), i)
            for type_and_subtype in self.cfg_ana.clusters_type_and_subtypes[i]:
                clusters = event.papasevent.get_collection(type_and_subtype)
                if clusters:
                    self.register_clusters(clusters.values(), i)
 
    def register_particles(self, particles, side=0):
        '''
        Adds list of particles into the display
        @param particles:  list of particles to append to display
        @param side:  0 = left, 1 = right
        '''
        self.display.register(GTrajectories(particles), layer=2, sides=[side])
        if self.compare:
            otherside = (side + 1)%2 #opposite side
            self.display.register(GTrajectories(particles, is_grey=True), layer=1, sides=[otherside])
 
    def register_clusters(self, clusters, side=0):
        '''Adds list of clusters into the display
        @param clusters:  list of clusters to append to display
        @param side:  0 = left, 1 = right'''        
        blobs = map(Blob, clusters)   
        self.display.register(blobs, layer=2, clearable=True, sides=[side])
        if self.compare:
            otherside = (side + 1)%2
            mapfunc = partial(Blob, grey=True)
            blobs = map(mapfunc, clusters)
            self.display.register(blobs, layer=1, clearable=True, sides=[otherside])
Exemple #10
0
class PapasSim(Analyzer):
    '''Runs PAPAS, the PArametrized Particle Simulation.

    Example configuration: 

    from heppy.analyzers.PapasSim import PapasSim
    from heppy.papas.detectors.CMS import CMS
    papas = cfg.Analyzer(
        PapasSim,
        instance_label = 'papas',
        detector = CMS(),
        gen_particles = 'gen_particles_stable',
        sim_particles = 'sim_particles',
        merged_ecals = 'ecal_clusters',
        merged_hcals = 'hcal_clusters',
        tracks = 'tracks',
        #rec_particles = 'sim_rec_particles', # optional - will only do a simulation reconstruction if a name is provided
        output_history = 'history_nodes', 
        display_filter_func = lambda ptc: ptc.e()>1.,
        display = False,
        verbose = True
    )
    
    detector:      Detector model to be used. 
    gen_particles: Name of the input gen particle collection
    sim_particles: Name extension for the output sim particle collection. 
                   Note that the instance label is prepended to this name. 
                   Therefore, in this particular case, the name of the output 
                   sim particle collection is "papas_sim_particles".
    merged_ecals: Name for the merged clusters created by simulator              
    merged_hcals: Name for the merged clusters created by simulator             
    tracks:       Name for smeared tracks created by simulator              
    
    rec_particles: Optional. Name extension for the reconstructed particles created by simulator
                   This is retained for the time being to allow two reconstructions to be compared
                   Reconstruction will occur if this parameter  or rec_particles_no_leptons is provided
                   Same comments as for the sim_particles parameter above.
    rec_particles_no_leptons: Optional. Name extension for the reconstructed particles created by simulator
                   without electrons and muons
                   Reconstruction will occur if this parameter  or rec_particles is provided
                   This is retained for the time being to allow two reconstructions to be compared
                   Same comments as for the sim_particles parameter above.
    smeared: Name for smeared leptons 
    history: Optional name for the history nodes, set to None if not needed
    display      : Enable the event display
    verbose      : Enable the detailed printout.
    '''

    def __init__(self, *args, **kwargs):
        super(PapasSim, self).__init__(*args, **kwargs)
        self.detector = self.cfg_ana.detector
        self.simulator = Simulator(self.detector, self.mainLogger)
        self.simname = '_'.join([self.instance_label,  self.cfg_ana.sim_particles])
        self.tracksname =  self.cfg_ana.tracks  
        self.mergedecalsname = self.cfg_ana.merged_ecals
        self.mergedhcalsname = self.cfg_ana.merged_hcals
        self.historyname =  self.cfg_ana.output_history
        #decide if reconstruction is needed
        self.do_reconstruct = False
        if hasattr(self.cfg_ana, 'rec_particles') :
            self.do_reconstruct = True
            self.recname = '_'.join([self.instance_label,  self.cfg_ana.rec_particles])
        #if hasattr(self.cfg_ana, 'rec_particles_no_leptons') :
        #    self.do_reconstruct = True
        #    self.rec_noleptonsname = '_'.join([self.instance_label,  self.cfg_ana.rec_particles_no_leptons])        
        
        self.is_display = self.cfg_ana.display
        if self.is_display:
            self.init_display()        

    def init_display(self):
        self.display = Display(['xy','yz'])
        self.gdetector = GDetector(self.detector)
        self.display.register(self.gdetector, layer=0, clearable=False)
        self.is_display = True

    def process(self, event):
        '''
           event must contain the
           
           event will gain
             ecal_clusters:- smeared merged clusters from simulation
             hcal_clusters:- smeared merged clusters from simulation
             tracks:       - tracks from simulation
             baseline_particles:- simulated particles (excluding electrons and muons)
             sim_particles - simulated particles including electrons and muons
             
             
        '''
        event.simulator = self 
        if self.is_display:
            self.display.clear()
        pfsim_particles = []
        gen_particles = getattr(event, self.cfg_ana.gen_particles)
        self.simulator.simulate( gen_particles, self.do_reconstruct)
        pfsim_particles = self.simulator.ptcs
        if self.is_display:
            self.display.register( GTrajectories(pfsim_particles),
                                   layer=1)
        #these are the particles before simulation        
        simparticles = sorted( pfsim_particles,
                               key = lambda ptc: ptc.e(), reverse=True)     
        setattr(event, self.simname, simparticles)
        
        if self.do_reconstruct: # used for verification/ comparison of reconstruction methods
            #these are the reconstructed (via simulation) particles  including electrons and muons
            particles = sorted( self.simulator.particles,
                            key = lambda ptc: ptc.e(), reverse=True)
        
            #these are the reconstructed (via simulation) particles excluding muons and electrons         
            #origparticles = sorted( self.simulator.pfsequence.pfreco.particles,
            #                       key = lambda ptc: ptc.e(), reverse=True)
            if hasattr(self, 'recname')  :
                setattr(event, self.recname, particles)          
            #if hasattr(self, 'rec_noleptonsname')  :
            #    setattr(event, self.rec_noleptonsname, origparticles)
                

        #extract the tracks and clusters (extraction is prior to Colins merging step)
        event.tracks = dict()
        event.ecal_clusters = dict()
        event.hcal_clusters = dict()
        
        
        if "tracker" in self.simulator.pfinput.elements :
            for element in self.simulator.pfinput.elements["tracker"]:
                event.tracks[element.uniqueid] = element
                
        if "ecal_in" in self.simulator.pfinput.elements :        
            for element in self.simulator.pfinput.elements["ecal_in"]:
                event.ecal_clusters[element.uniqueid] = element
                
        if "hcal_in" in self.simulator.pfinput.elements :
            for element in self.simulator.pfinput.elements["hcal_in"]:
                event.hcal_clusters[element.uniqueid] = element
                
        ruler = Distance()

        #create history node
        #note eventually history will be created by the simulator and passed in
        # as an argument and this will no longer be needed
        uniqueids = list(event.tracks.keys()) + list(event.ecal_clusters.keys()) + list(event.hcal_clusters.keys())
        history =  dict( (idt, Node(idt)) for idt in uniqueids )                    
       
        #Now merge the simulated clusters and tracks as a separate pre-stage (prior to new reconstruction)        
        # and set the event to point to the merged cluster
        pfevent =  PFEvent(event, 'tracks', 'ecal_clusters', 'hcal_clusters')
        merged_ecals = MergedClusterBuilder(pfevent.ecal_clusters, ruler, history)
        setattr(event, self.mergedecalsname, merged_ecals.merged)
        merged_hcals = MergedClusterBuilder(pfevent.hcal_clusters, ruler, merged_ecals.history_nodes)
        setattr(event, self.mergedhcalsname, merged_hcals.merged)
        setattr(event,  self.historyname,  merged_hcals.history_nodes)
        
        ####if uncommented this will use the original reconstructions to provide the ready merged tracks and clusters
        #event.ecal_clusters = dict()
        #event.hcal_clusters = dict()        
        #for element in self.simulator.pfsequence.elements :
            #elif element.__class__.__name__ == 'SmearedCluster' and element.layer == 'ecal_in': 
                #event.ecal_clusters[element.uniqueid] = element
            #elif element.__class__.__name__ == 'SmearedCluster' and element.layer == 'hcal_in': 
                #event.hcal_clusters[element.uniqueid] = element
            #else :            
                #print element.__class__.__name__ 
                #assert(False)
       
        ###if uncommented will check that cluster merging is OK   (compare new merging module with Colins merging)    
        #event.origecal_clusters = dict()
        #event.orighcal_clusters = dict()
        #for element in self.simulator.pfsequence.elements :
            #if element.__class__.__name__ == 'SmearedCluster' and element.layer == 'ecal_in': 
                #event.origecal_clusters[element.uniqueid] = element
            #elif element.__class__.__name__ == 'SmearedCluster' and element.layer == 'hcal_in': 
                #event.orighcal_clusters[element.uniqueid] = element
        #ClusterComparer(event.origecal_clusters,event.ecal_clusters)
        #ClusterComparer(event.orighcal_clusters,event.hcal_clusters)
        #event.othertracks =  dict()
        #for element in self.simulator.pfsequence.elements :
            #if element.__class__.__name__ == 'SmearedTrack': 
                #event.othertracks[element.uniqueid] = element        
        #assert (len(event.tracks) == len(event.othertracks))
       
        pass
Exemple #11
0
class PapasSim(Analyzer):
    '''Runs PAPAS, the PArametrized Particle Simulation.
    
    #This will need to redocumented once new papasdata structure arrives

    Example configuration:

    from heppy.analyzers.PapasSim import PapasSim
    from heppy.papas.detectors.CMS import CMS
    papas = cfg.Analyzer(
        PapasSim,
        instance_label = 'papas',
        detector = CMS(),
        gen_particles = 'gen_particles_stable',
        sim_particles = 'sim_particles',
        merged_ecals = 'ecal_clusters',
        merged_hcals = 'hcal_clusters',
        tracks = 'tracks',
        #rec_particles = 'sim_rec_particles', # optional - will only do a simulation reconstruction if a name is provided
        output_history = 'history_nodes',
        display_filter_func = lambda ptc: ptc.e()>1.,
        display = False,
        verbose = True
    )
    detector:      Detector model to be used.
    gen_particles: Name of the input gen particle collection
    sim_particles: Name extension for the output sim particle collection.
                   Note that the instance label is prepended to this name.
                   Therefore, in this particular case, the name of the output
                   sim particle collection is "papas_sim_particles".
    merged_ecals: Name for the merged clusters created by simulator
    merged_hcals: Name for the merged clusters created by simulator
    tracks:       Name for smeared tracks created by simulator
    rec_particles: Optional. Name extension for the reconstructed particles created by simulator
                   This is retained for the time being to allow two reconstructions to be compared
                   Reconstruction will occur if this parameter  or rec_particles_no_leptons is provided
                   Same comments as for the sim_particles parameter above.
    rec_particles_no_leptons: Optional. Name extension for the reconstructed particles created by simulator
                   without electrons and muons
                   Reconstruction will occur if this parameter  or rec_particles is provided
                   This is retained for the time being to allow two reconstructions to be compared
                   Same comments as for the sim_particles parameter above.
    smeared: Name for smeared leptons
    history: Optional name for the history nodes, set to None if not needed
    display      : Enable the event display
    verbose      : Enable the detailed printout.

        event must contain
          todo once history is implemented
        event will gain
          ecal_clusters:- smeared merged clusters from simulation
          hcal_clusters:- smeared merged clusters from simulation
          tracks:       - tracks from simulation
          baseline_particles:- simulated particles (excluding electrons and muons)
          sim_particles - simulated particles including electrons and muons
        
    '''

    def __init__(self, *args, **kwargs):
        super(PapasSim, self).__init__(*args, **kwargs)
        self.detector = self.cfg_ana.detector
        self.simulator = Simulator(self.detector, self.mainLogger)
        self.simname = '_'.join([self.instance_label, self.cfg_ana.sim_particles])
        self.tracksname = self.cfg_ana.tracks
        self.mergedecalsname = self.cfg_ana.merged_ecals
        self.mergedhcalsname = self.cfg_ana.merged_hcals
        self.historyname = self.cfg_ana.output_history
        self.is_display = self.cfg_ana.display
        if self.is_display:
            self.init_display()

    def init_display(self):
        self.display = Display(['xy', 'yz'])
        self.gdetector = GDetector(self.detector)
        self.display.register(self.gdetector, layer=0, clearable=False)
        self.is_display = True

    def process(self, event):
        
        event.simulator = self
        if self.is_display:
            self.display.clear()
        pfsim_particles = []
        gen_particles = getattr(event, self.cfg_ana.gen_particles)
        try:
            self.simulator.simulate(gen_particles)
        except (PropagationError, SimulationError) as err:
            self.mainLogger.error(str(err) + ' -> Event discarded')
            return False
        pfsim_particles = self.simulator.ptcs
        if self.is_display  :
            self.display.register(GTrajectories(pfsim_particles),
                                  layer=1)
        #these are the particles before simulation
        simparticles = sorted(pfsim_particles,
                              key=lambda ptc: ptc.e(), reverse=True)
        setattr(event, self.simname, simparticles)

        #extract the tracks and clusters (extraction is prior to Colins merging step)
        event.tracks = dict()
        event.ecal_clusters = dict()
        event.hcal_clusters = dict()
        if "tracker" in self.simulator.pfinput.elements :
            for element in self.simulator.pfinput.elements["tracker"]:
                event.tracks[element.uniqueid] = element

        if "ecal_in" in self.simulator.pfinput.elements :
            for element in self.simulator.pfinput.elements["ecal_in"]:
                event.ecal_clusters[element.uniqueid] = element

        if "hcal_in" in self.simulator.pfinput.elements :
            for element in self.simulator.pfinput.elements["hcal_in"]:
                event.hcal_clusters[element.uniqueid] = element

        ruler = Distance()

        #create history node
        #note eventually history will be created by the simulator and passed in
        # as an argument and this will no longer be needed
        uniqueids = list(event.tracks.keys()) + list(event.ecal_clusters.keys()) + list(event.hcal_clusters.keys())
        history = dict((idt, Node(idt)) for idt in uniqueids)

        #Now merge the simulated clusters and tracks as a separate pre-stage (prior to new reconstruction)
        # and set the event to point to the merged cluster
        pfevent = PFEvent(event, 'tracks', 'ecal_clusters', 'hcal_clusters')
        merged_ecals = MergedClusterBuilder(pfevent.ecal_clusters, ruler, history)
        setattr(event, self.mergedecalsname, merged_ecals.merged)
        merged_hcals = MergedClusterBuilder(pfevent.hcal_clusters, ruler, merged_ecals.history_nodes)
        setattr(event, self.mergedhcalsname, merged_hcals.merged)
        setattr(event, self.historyname, merged_hcals.history_nodes)