def simplify_blocks(self, block, history_nodes=None): ''' Block: a block which contains list of element ids and set of edges that connect them history_nodes: optional dictionary of Nodes with element identifiers in each node returns a dictionary of new split blocks The goal is to remove, if needed, some links from the block so that each track links to at most one hcal within a block. In some cases this may separate a block into smaller blocks (splitblocks). The BlockSplitter is used to return the new smaller blocks. If history_nodes are provided then the history will be updated. Split blocks will have the tracks and cluster elements as parents, and also the original block as a parent ''' ids = block.element_uniqueids #create a copy of the edges and unlink some of these edges if needed newedges = copy.deepcopy(block.edges) if len(ids) > 1 : for uid in ids : if Identifier.is_track(uid): # for tracks unlink all hcals except the closest hcal linked_ids = block.linked_ids(uid, "hcal_track") # NB already sorted from small to large distance if linked_ids != None and len(linked_ids) > 1: first_hcal = True for id2 in linked_ids: newedge = newedges[Edge.make_key(uid, id2)] if first_hcal: first_dist = newedge.distance first_hcal = False else: if newedge.distance == first_dist: pass newedge.linked = False #create new block(s) splitblocks = BlockSplitter(block.uniqueid, ids, newedges, len(self.splitblocks), 's', history_nodes).blocks return splitblocks
def reconstruct_electrons(self, block): '''Reconstruct electrons in block.''' uids = block.element_uniqueids for uid in uids: if Identifier.is_track(uid) and \ self.is_from_particle(uid, 'ps', 11): parent_ids = [block.uniqueid, uid] track = self.papasevent.get_object(uid) ptc = self.reconstruct_track(track, 11, parent_ids)
def reconstruct_muons(self, block): '''Reconstruct muons in block.''' uids = block.element_uniqueids for uid in uids: if Identifier.is_track(uid) and \ self.is_from_particle(uid, 'ps', 13): parent_ids = [block.uniqueid, uid] self.reconstruct_track(self.papasevent.get_object(uid), 13, parent_ids)
def reconstruct_muons(self, block): '''Reconstruct muons in block.''' uids = block.element_uniqueids for uid in uids: if Identifier.is_track(uid) and \ self.is_from_particle(uid, 'ps', 13): parent_ids = [block.uniqueid, uid] self.reconstruct_track(self.papasevent.get_object(uid), 13, parent_ids)
def reconstruct_electrons(self, block): '''Reconstruct electrons in block.''' uids = block.element_uniqueids for uid in uids: if Identifier.is_track(uid) and \ self.is_from_particle(uid, 'ps', 11): parent_ids = [block.uniqueid, uid] track = self.papasevent.get_object(uid) ptc = self.reconstruct_track(track, 11, parent_ids)
def reconstruct_block(self, block): ''' see class description for summary of reconstruction approach ''' uids = block.element_uniqueids #ids are already stored in sorted order inside block self.locked = dict((uid, False) for uid in uids) # first reconstruct muons and electrons self.reconstruct_muons(block) self.reconstruct_electrons(block) # keeping only the elements that have not been used so far uids = [uid for uid in uids if not self.locked[uid]] if len(uids) == 1: #TODO WARNING!!! LOTS OF MISSING CASES uid = uids[0] parent_ids = [block.uniqueid, uid] if Identifier.is_ecal(uid): self.reconstruct_cluster(self.papasevent.get_object(uid), "ecal_in", parent_ids) elif Identifier.is_hcal(uid): self.reconstruct_cluster(self.papasevent.get_object(uid), "hcal_in", parent_ids) elif Identifier.is_track(uid): self.reconstruct_track(self.papasevent.get_object(uid), 211, parent_ids) else: #TODO for uid in uids: #already sorted to have higher energy things first (see pfblock) if Identifier.is_hcal(uid): self.reconstruct_hcal(block, uid) for uid in uids: #already sorted to have higher energy things first if Identifier.is_track(uid) and not self.locked[uid]: # unused tracks, so not linked to HCAL # reconstructing charged hadrons. # ELECTRONS TO BE DEALT WITH. parent_ids = [block.uniqueid, uid] self.reconstruct_track(self.papasevent.get_object(uid), 211, parent_ids) # tracks possibly linked to ecal->locking cluster for idlink in block.linked_ids(uid, "ecal_track"): #ask colin what happened to possible photons here: self.locked[idlink] = True #TODO add in extra photonsbut decide where they should go? self.unused.extend( [uid for uid in block.element_uniqueids if not self.locked[uid]])
def reconstruct_block(self, block): ''' see class description for summary of reconstruction approach ''' particles = dict() ids = block.element_uniqueids self.locked = dict() for id in ids: self.locked[id] = False self.debugprint = False if (self.debugprint and len(block.element_uniqueids)> 4): print block if len(ids) == 1: #TODO WARNING!!! LOTS OF MISSING CASES id = ids[0] if Identifier.is_ecal(id): self.insert_particle(block, self.reconstruct_cluster(block.pfevent.ecal_clusters[id],"ecal_in")) elif Identifier.is_hcal(id): self.insert_particle(block, self.reconstruct_cluster(block.pfevent.hcal_clusters[id],"hcal_in")) elif Identifier.is_track(id): self.insert_particle(block, self.reconstruct_track(block.pfevent.tracks[id])) # ask Colin about energy balance - what happened to the associated clusters that one would expect? else: #TODO for id in ids : if Identifier.is_hcal(id): self.reconstruct_hcal(block,id) for id in ids : if Identifier.is_track(id) and not self.locked[id]: # unused tracks, so not linked to HCAL # reconstructing charged hadrons. # ELECTRONS TO BE DEALT WITH. self.insert_particle(block, self.reconstruct_track(block.pfevent.tracks[id])) # tracks possibly linked to ecal->locking cluster for idlink in block.linked_ids(id,"ecal_track"): #ask colin what happened to possible photons here: self.locked[idlink] = True
def reconstruct_block(self, block): ''' see class description for summary of reconstruction approach ''' particles = dict() ids = block.element_uniqueids #ids = sorted( ids, key = lambda id: Identifier.type_short_code ) self.locked = dict() for id in ids: self.locked[id] = False self.debugprint = False if (self.debugprint and len(block.element_uniqueids)> 4): print block if len(ids) == 1: #TODO WARNING!!! LOTS OF MISSING CASES id = ids[0] if Identifier.is_ecal(id): self.insert_particle(block, self.reconstruct_cluster(block.pfevent.ecal_clusters[id],"ecal_in")) elif Identifier.is_hcal(id): self.insert_particle(block, self.reconstruct_cluster(block.pfevent.hcal_clusters[id],"hcal_in")) elif Identifier.is_track(id): self.insert_particle(block, self.reconstruct_track(block.pfevent.tracks[id])) # ask Colin about energy balance - what happened to the associated clusters that one would expect? else: #TODO for id in sorted(ids) : #newsort if Identifier.is_hcal(id): self.reconstruct_hcal(block,id) for id in sorted(ids) : #newsort if Identifier.is_track(id) and not self.locked[id]: # unused tracks, so not linked to HCAL # reconstructing charged hadrons. # ELECTRONS TO BE DEALT WITH. self.insert_particle(block, self.reconstruct_track(block.pfevent.tracks[id])) # tracks possibly linked to ecal->locking cluster for idlink in block.linked_ids(id,"ecal_track"): #ask colin what happened to possible photons here: self.locked[idlink] = True
def reconstruct_block(self, block): ''' see class description for summary of reconstruction approach ''' uids = block.element_uniqueids #ids are already stored in sorted order inside block self.locked = dict( (uid, False) for uid in uids ) # first reconstruct muons and electrons self.reconstruct_muons(block) self.reconstruct_electrons(block) # keeping only the elements that have not been used so far uids = [uid for uid in uids if not self.locked[uid]] if len(uids) == 1: #TODO WARNING!!! LOTS OF MISSING CASES uid = uids[0] parent_ids = [block.uniqueid, uid] if Identifier.is_ecal(uid): self.reconstruct_cluster(self.papasevent.get_object(uid), "ecal_in", parent_ids) elif Identifier.is_hcal(uid): self.reconstruct_cluster(self.papasevent.get_object(uid), "hcal_in", parent_ids) elif Identifier.is_track(uid): self.reconstruct_track(self.papasevent.get_object(uid), 211, parent_ids) else: #TODO for uid in uids: #already sorted to have higher energy things first (see pfblock) if Identifier.is_hcal(uid): self.reconstruct_hcal(block, uid) for uid in uids: #already sorted to have higher energy things first if Identifier.is_track(uid) and not self.locked[uid]: # unused tracks, so not linked to HCAL # reconstructing charged hadrons. # ELECTRONS TO BE DEALT WITH. parent_ids = [block.uniqueid, uid] self.reconstruct_track(self.papasevent.get_object(uid), 211, parent_ids) # tracks possibly linked to ecal->locking cluster for idlink in block.linked_ids(uid, "ecal_track"): #ask colin what happened to possible photons here: self.locked[idlink] = True #TODO add in extra photonsbut decide where they should go? self.unused.extend([uid for uid in block.element_uniqueids if not self.locked[uid]])
def simplify_blocks(self, block, history_nodes=None): ''' Block: a block which contains list of element ids and set of edges that connect them history_nodes: optional dictionary of Nodes with element identifiers in each node returns None or a dictionary of new split blocks The goal is to remove, if needed, some links from the block so that each track links to at most one hcal within a block. In some cases this may separate a block into smaller blocks (splitblocks). The BlockSplitter is used to return the new smaller blocks. If history_nodes are provided then the history will be updated. Split blocks will have the tracks and cluster elements as parents, and also the original block as a parent ''' ids=block.element_uniqueids if len(ids)<=1 : #no links to remove return None # work out any links that need to be removed # - for tracks unink all hcals except the closest hcal # - for ecals unlink hcals to_unlink = [] for id in ids : if Identifier.is_track(id): linked = block.linked_edges(id,"hcal_track") # NB already sorted from small to large distance if linked!=None and len(linked)>1 : first_hcal = True for elem in linked: if first_hcal: first_dist=elem.distance first_hcal = False else: if (elem.distance==first_dist): pass to_unlink.append(elem) elif Identifier.is_ecal(id): # this is now handled elsewhere and so could be removed # remove all ecal-hcal links. ecal linked to hcal give rise to a photon anyway. linked = block.linked_edges(id,"ecal_hcal") to_unlink.extend(linked) #if there is something to unlink then use the BlockSplitter splitblocks=None if len(to_unlink): splitblocks= BlockSplitter(block, to_unlink, history_nodes).blocks return splitblocks
def simplify_blocks(self, block, history_nodes=None): ''' Block: a block which contains list of element ids and set of edges that connect them history_nodes: optional dictionary of Nodes with element identifiers in each node returns None or a dictionary of new split blocks The goal is to remove, if needed, some links from the block so that each track links to at most one hcal within a block. In some cases this may separate a block into smaller blocks (splitblocks). The BlockSplitter is used to return the new smaller blocks. If history_nodes are provided then the history will be updated. Split blocks will have the tracks and cluster elements as parents, and also the original block as a parent ''' ids=block.element_uniqueids if len(ids)<=1 : #no links to remove return None # work out any links that need to be removed # - for tracks unink all hcals except the closest hcal # - for ecals unlink hcals to_unlink = [] for id in ids : if Identifier.is_track(id): linked = block.linked_edges(id,"hcal_track") # NB already sorted from small to large distance if linked!=None and len(linked)>1 : first_hcal = True for elem in linked: if first_hcal: first_dist=elem.distance first_hcal = False else: if (elem.distance==first_dist): pass to_unlink.append(elem) #if there is something to unlink then use the BlockSplitter splitblocks=None if len(to_unlink): splitblocks= BlockSplitter(block, to_unlink, history_nodes).blocks return splitblocks
def summary_of_linked_elems(self, id): #find everything that is linked to this id #and write a summary of what is found #the BFS search returns a list of the ids that are connected to the id of interest BFS = BreadthFirstSearchIterative(self.history_nodes[id], "undirected") #collate the string descriptions track_descrips = [] ecal_descrips = [] hcal_descrips = [] #sim_particle_descrips = [] rec_particle_descrips = [] block_descrips = [] for n in BFS.result : z = n.get_value() obj = self.pfevent.get_object(z) descrip = obj.__str__() # if (Identifier.is_particle(z)): # sim_particle_descrips.append(descrip) if (Identifier.is_block(z)): block_descrips.append(descrip) elif (Identifier.is_track(z)): track_descrips.append(descrip) elif (Identifier.is_ecal(z)): ecal_descrips.append(descrip) elif (Identifier.is_hcal(z)): hcal_descrips.append(descrip) elif (Identifier.is_rec_particle(z)): rec_particle_descrips.append(descrip) print "history connected to node:", id print "block", block_descrips print " tracks", track_descrips print " ecals", ecal_descrips print " hcals", hcal_descrips print "rec particles", rec_particle_descrips
def summary_of_linked_elems(self, id): # find everything that is linked to this id # and write a summary of what is found # the BFS search returns a list of the ids that are connected to the id of interest BFS = BreadthFirstSearchIterative(self.history_nodes[id], "undirected") # collate the string descriptions track_descrips = [] ecal_descrips = [] hcal_descrips = [] # sim_particle_descrips = [] rec_particle_descrips = [] block_descrips = [] for n in BFS.result: z = n.get_value() obj = self.pfevent.get_object(z) descrip = obj.__str__() # if (Identifier.is_particle(z)): # sim_particle_descrips.append(descrip) if Identifier.is_block(z): block_descrips.append(descrip) elif Identifier.is_track(z): track_descrips.append(descrip) elif Identifier.is_ecal(z): ecal_descrips.append(descrip) elif Identifier.is_hcal(z): hcal_descrips.append(descrip) elif Identifier.is_rec_particle(z): rec_particle_descrips.append(descrip) print "history connected to node:", id print "block", block_descrips print " tracks", track_descrips print " ecals", ecal_descrips print " hcals", hcal_descrips print "rec particles", rec_particle_descrips
def simplify_blocks(self, block, history_nodes=None): ''' Block: a block which contains list of element ids and set of edges that connect them history_nodes: optional dictionary of Nodes with element identifiers in each node returns a dictionary of new split blocks The goal is to remove, if needed, some links from the block so that each track links to at most one hcal within a block. In some cases this may separate a block into smaller blocks (splitblocks). The BlockSplitter is used to return the new smaller blocks. If history_nodes are provided then the history will be updated. Split blocks will have the tracks and cluster elements as parents, and also the original block as a parent ''' ids = block.element_uniqueids #create a copy of the edges and unlink some of these edges if needed newedges = copy.deepcopy(block.edges) if len(ids) > 1: for uid in ids: if Identifier.is_track(uid): # for tracks unlink all hcals except the closest hcal linked_ids = block.linked_ids( uid, "hcal_track" ) # NB already sorted from small to large distance if linked_ids != None and len(linked_ids) > 1: first_hcal = True for id2 in linked_ids: newedge = newedges[Edge.make_key(uid, id2)] if first_hcal: first_dist = newedge.distance first_hcal = False else: if newedge.distance == first_dist: pass newedge.linked = False #create new block(s) splitblocks = BlockSplitter(block.uniqueid, ids, newedges, len(self.splitblocks), 's', history_nodes).blocks return splitblocks
def count_tracks(self): ''' Counts how many track ids are in the block ''' count = 0 for elem in self.element_uniqueids: count += Identifier.is_track(elem) return count
def count_tracks(self): ''' Counts how many track ids are in the block ''' count = 0 for elem in self.element_uniqueids: count += Identifier.is_track(elem) return count