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
Exemple #2
0
 def __init__(self, element_ids, edges, pfevent): 
     ''' 
         element_ids:  list of the uniqueids of the elements to go in this block [id1,id2,...]
         edges: is a dictionary of edges, it must contain at least all needed edges. It is not a problem if it contains
                additional edges as only the ones needed will be extracted
         pfevent: allows access to the underlying elements given a uniqueid 
                  must provide a get_object function
     '''
     #make a uniqueid for this block
     self.uniqueid = Identifier.make_id(Identifier.PFOBJECTTYPE.BLOCK) 
     self.is_active = True # if a block is subsequently split it will be deactivated
     
     #allow access to the underlying objects
     self.pfevent=pfevent        
     
     #order the elements by element type (ecal, hcal, track) and then by energy
     #this is a bit yucky but needed to make sure the order returned is consistent
     #maybe should live outside of this class        
     self.element_uniqueids = sorted(element_ids, key = lambda  x: (Identifier.type_short_code(x),-self.pfevent.get_object(x).energy) )
     
     #sequential numbering of blocks, not essential but helpful for debugging
     self.block_count = PFBlock.temp_block_count
     PFBlock.temp_block_count += 1
     
     #extract the relevant parts of the complete set of edges and store this within the block
     self.edges = dict()
     for id1, id2 in itertools.combinations(self.element_uniqueids,2):
         key = Edge.make_key(id1,id2)
         self.edges[key] = edges[key]
Exemple #3
0
    def __init__(self, element_ids, edges, pfevent):
        '''
            element_ids:  list of the uniqueids of the elements to go in this block [id1,id2,...]
            edges: is a dictionary of edges, it must contain at least all needed edges.
                   It is not a problem if it contains
                   additional edges as only the ones needed will be extracted
            pfevent: allows access to the underlying elements given a uniqueid
                     must provide a get_object function
        '''
        #make a uniqueid for this block
        self.uniqueid = Identifier.make_id(Identifier.PFOBJECTTYPE.BLOCK)
        self.is_active = True  # if a block is subsequently split it will be deactivated

        #allow access to the underlying objects
        self.pfevent = pfevent

        #comment out energy sorting  for now as not available C++
        sortby = lambda x: Identifier.type_short_code(x)
        self.element_uniqueids = sorted(element_ids, key=sortby)
        #sequential numbering of blocks, not essential but helpful for debugging
        self.block_count = PFBlock.temp_block_count
        PFBlock.temp_block_count += 1

        #extract the relevant parts of the complete set of edges and store this within the block
        self.edges = dict()
        for id1, id2 in itertools.combinations(self.element_uniqueids, 2):
            key = Edge.make_key(id1, id2)
            self.edges[key] = edges[key]
Exemple #4
0
 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
Exemple #5
0
    def __init__(self, element_ids, edges, subtype):
        ''' 
            element_ids:  list of the uniqueids of the elements to go in this block [id1,id2,...]
            edges: is a dictionary of edges, it must contain at least all needed edges.
                   It is not a problem if it contains
                   additional edges as only the ones needed will be extracted
            subtype: used when making unique identifier, will normally be 'r' for reconstructed blocks and 's' for split blocks
           
        '''
        #make a uniqueid for this block
        self.uniqueid = Identifier.make_id(Identifier.PFOBJECTTYPE.BLOCK,
                                           subtype)
        self.element_uniqueids = sorted(
            element_ids, key=lambda x: Identifier.type_letter(x))

        #comment out energy sorting  for now as not available C++
        sortby = lambda x: Identifier.type_letter(x)
        self.element_uniqueids = sorted(element_ids, key=sortby)
        #sequential numbering of blocks, not essential but helpful for debugging
        self.block_count = PFBlock.temp_block_count
        PFBlock.temp_block_count += 1

        #extract the relevant parts of the complete set of edges and store this within the block
        self.edges = dict()
        for id1, id2 in itertools.combinations(self.element_uniqueids, 2):
            key = Edge.make_key(id1, id2)
            self.edges[key] = edges[key]
Exemple #6
0
    def __init__(self, element_ids, edges, index, subtype): 
        ''' 
            @param element_ids:  list of the uniqueids of the elements to go in this block [id1,id2,...]
            @param edges: is a dictionary of edges, it must contain at least all needed edges.
                   It is not a problem if it contains
                   additional edges as only the ones needed will be extracted
            @param index: index into the collection of blocks into which new block will be added
            @param subtype: used when making unique identifier, will normally be 'r' for reconstructed blocks and 's' for split blocks
           
        '''
        #make a uniqueid for this block
        self.uniqueid = IdCoder.make_id(IdCoder.PFOBJECTTYPE.BLOCK, index, subtype, len(element_ids))
        #this will sort by type eg ecal, hcal, track and then by energy (biggest first)
        self.element_uniqueids = sorted(element_ids, reverse=True)
        #sequential numbering of blocks, not essential but helpful for debugging
        self.block_count = PFBlock.temp_block_count
        PFBlock.temp_block_count += 1

        #extract the relevant parts of the complete set of edges and store this within the block
        self.edges = dict()
        for id1, id2 in itertools.combinations(self.element_uniqueids, 2):
            key = Edge.make_key(id1, id2)
            self.edges[key] = edges[key]
Exemple #7
0
    def __init__(self, element_ids, edges, index, subtype):
        ''' 
            @param element_ids:  list of the uniqueids of the elements to go in this block [id1,id2,...]
            @param edges: is a dictionary of edges, it must contain at least all needed edges.
                   It is not a problem if it contains
                   additional edges as only the ones needed will be extracted
            @param index: index into the collection of blocks into which new block will be added
            @param subtype: used when making unique identifier, will normally be 'r' for reconstructed blocks and 's' for split blocks
           
        '''
        #make a uniqueid for this block
        self.uniqueid = Identifier.make_id(Identifier.PFOBJECTTYPE.BLOCK,
                                           index, subtype, len(element_ids))
        #this will sort by type eg ecal, hcal, track and then by energy (biggest first)
        self.element_uniqueids = sorted(element_ids, reverse=True)
        #sequential numbering of blocks, not essential but helpful for debugging
        self.block_count = PFBlock.temp_block_count
        PFBlock.temp_block_count += 1

        #extract the relevant parts of the complete set of edges and store this within the block
        self.edges = dict()
        for id1, id2 in itertools.combinations(self.element_uniqueids, 2):
            key = Edge.make_key(id1, id2)
            self.edges[key] = edges[key]
Exemple #8
0
 def get_edge(self, id1, id2):
     ''' Find the edge corresponding to e1 e2
         Note that make_key deals with whether it is get_edge(e1, e2) or
                                                     get_edge(e2, e1) (either order gives same result)
         '''
     return self.edges[Edge.make_key(id1, id2)]
Exemple #9
0
 def get_edge(self, id1, id2):
     ''' Find the edge corresponding to e1 e2 
         Note that make_key deals with whether it is get_edge(e1, e2) or get_edge(e2, e1) (either order gives same result)
         '''
     return self.edges[Edge.make_key(id1,id2)]