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 IdCoder.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_muons(self, block): '''Reconstruct muons in block.''' uids = block.element_uniqueids for uid in uids: if IdCoder.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 IdCoder.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 IdCoder.is_ecal(uid): self.reconstruct_cluster(self.papasevent.get_object(uid), "ecal_in", parent_ids) elif IdCoder.is_hcal(uid): self.reconstruct_cluster(self.papasevent.get_object(uid), "hcal_in", parent_ids) elif IdCoder.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 IdCoder.is_hcal(uid): self.reconstruct_hcal(block, uid) for uid in uids: #already sorted to have higher energy things first if IdCoder.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 count_tracks(self): ''' Counts how many track ids are in the block ''' count = 0 for elem in self.element_uniqueids: count += IdCoder.is_track(elem) return count