Handling of TisTos-information in Bender

Bender offers set of methods to handle TisTos-information in (relatively) easy way. This functionality comes from BenderTools.TisTos module. In short, it adds three relates method in the base class Algo:

Method Short description
decisions collect the trigger decisions for the given particle
trgDecs print the collected trigger statistics in readable way
tisTos fill N-tuple with TisTos-information

All of them are (relatively well) documented and one can easily inspect them:

import BenderTools.TisTos
from Bender.Main import Algo
help(Algo.decisions)

How to know what trigger lines are relevant or the given decay/particle?

Often information about the releavant trigger lines are spread in corridors in a form of myths, general beliefs or, in the best case, references to ANA-notes for some similar analysis. However it is very simple to collect this infomation using Bender. The method decisions is our friend here. the usage of this method require some preparatory work for the algorithm, namely one needs to instrument initialize-method:

class TrgLines(Algo):
    """Collect infomation about the trigger lines relevant for certain decays/particles
    """
    def initialize ( self ) :

        sc = Algo.initialize ( self ) ## initialize the base class
        if sc.isFailure() : return sc

        #
        ## container to collect trigger information, e.g. list of fired lines 
        #
        triggers = {}
        triggers ['psi'] = {} ## slot to keep the information for J/psi 
        triggers ['K']   = {} ## slot to keep the information for kaons  
        triggers ['B']   = {} ## slot to keep the information for B-mesons 

        sc = self.tisTos_initialize ( triggers , lines = {} )
        if sc.isFailure() : return sc

        return SUCCESS

Here in this example we want to collect TisTos-information for J/psi, K and the whole B+-meson. Then in the main analyse-method one just needs to invoke the method decisions for each particles in interest:

def analyse( self ) :   ## IMPORTANT! 
  """The main 'analysis' method """
  ...         
  for b in particles :

      psi =b(1) ## the first  daughter: J/psi 
      k   =b(2) ## the second daughter: K 

      ## collect trigger information for J/psi 
      self.decisions   ( psi , self.triggers['psi'] )

      ## collect trigger information for kaons 
      self.decisions   ( k   , self.triggers['K']   )

      ## collect trigger information for B-mesons 
      self.decisions   ( b   , self.triggers['B']   ) 

  ...     
  return SUCCESS

Thats all. Then when jobs runs it dumps to the log-file the running trigger statistics, and the statistics is dumped into the file TrgLines_tistos.txt (<ALGNAME>_tistos.txt in general). The summary table looks like:

******************************************************************************************
 Triggers for  psi
******************************************************************************************
Hlt1_TIS psi   #lines:     7 #events 321   
 (  0.62 +- 0.44 )       Hlt1DiMuonHighMassDecision 
 (  0.62 +- 0.44 )       Hlt1DiMuonLowMassDecision 
 ( 19.00 +- 2.19 )       Hlt1TrackAllL0Decision 
 (  3.74 +- 1.06 )       Hlt1TrackAllL0TightDecision 
 (  4.36 +- 1.14 )       Hlt1TrackMuonDecision 
 (  0.93 +- 0.54 )       Hlt1TrackPhotonDecision 
 (  0.31 +- 0.31 )       Hlt1VertexDisplVertexDecision 
 (100.00 +- 0.31 )       TOTAL 
Hlt1_TOS psi   #lines:     9 #events 321   
 ( 72.90 +- 2.48 )       Hlt1DiMuonHighMassDecision 
 ( 59.81 +- 2.74 )       Hlt1DiMuonLowMassDecision 
 (  0.31 +- 0.31 )       Hlt1DiProtonDecision 
 (  9.03 +- 1.60 )       Hlt1SingleMuonHighPTDecision 
 (  0.31 +- 0.31 )       Hlt1SingleMuonNoIPDecision 
 ( 44.24 +- 2.77 )       Hlt1TrackAllL0Decision 
 ( 10.90 +- 1.74 )       Hlt1TrackAllL0TightDecision 
 ( 74.77 +- 2.42 )       Hlt1TrackMuonDecision 
 (  0.31 +- 0.31 )       Hlt1TrackPhotonDecision 
 (100.00 +- 0.31 )       TOTAL 
Hlt1_TPS psi   #lines:     6 #events 321   
 ( 13.71 +- 1.92 )       Hlt1DiMuonHighMassDecision 
 ( 10.90 +- 1.74 )       Hlt1DiMuonLowMassDecision 
 (  0.31 +- 0.31 )       Hlt1DiProtonDecision 
 (  3.12 +- 0.97 )       Hlt1TrackAllL0Decision 
 (  0.93 +- 0.54 )       Hlt1TrackAllL0TightDecision 
 (  4.67 +- 1.18 )       Hlt1TrackMuonDecision 
 (100.00 +- 0.31 )       TOTAL

Only a short fragment is shown here, one gets similar fragments for all declared particles (psi, K and B) and for all trigger levels (L0, Hlt1 and Hlt2). The full table is accessible here The content of the summaty table is rather intuitive: it summarizes the fire frequences for varios trugegr lines for three regimes TIS, TOS and TPS. Inspecting such table, one immediately concludes that the most relevan Hlt1-TOS-line is Hlt1DiMuonHighMassDecision. Other Hlt1-TOS-lines are less relevant here. But please note that here only very small statistics is used (321 event), and with larger statistics sthe conclusions could be corrected. E.g. due to small statistics here, for Hlt1-TIS-lines the choice is not evident: one clearly see that Hlt1TrackAllL0Decision line is important, but for importance of other lines one csn judge only after the significant increase of the statistics.

What is `_tistos.db` file?Click to expand

Challenge

  1. Add decisions-function for your previous Bender module with n-tuples.
    • (Do not forget to instrument the initialize method)
  2. Run it and observe the output summary table
  3. Identify the relevant L0-TOS, Hlt1-TOS and Hlt2-TOS lines for your decay
    • Does it correspond to your expectations?

Solution

The complete module is accessible here and the corresponsing summary table is here

How to add the TisTos-information to n-tuple/tree?

Now, when we have the lists of the relevant lines, one wants to add infrommation about the decisions of these lines into n-tuple/tree. The method tistos is out friend here. To use this method one needs to instrument initialize-method:

class TisTosTuple(Algo):
    """Enhanced functionality for n-tuples 
    """
    def initialize ( self ) :

        sc = Algo.initialize ( self ) ## initialize the base class
        if sc.isFailure() : return sc

        #
        ## container to collect trigger information, e.g. list of fired lines 
        #
        triggers = {}
        triggers ['psi'] = {} ## slot to keep information for J/psi 

        #
        ## the lines to be investigated in details
        #
        lines    = {}
        lines    [ "psi" ] = {} ## trigger lines for J/psi

        ## six mandatory keys:
        lines    [ "psi" ][   'L0TOS' ] = 'L0(DiMuon|Muon)Decision'
        lines    [ "psi" ][   'L0TIS' ] = 'L0(Hadron|DiMuon|Muon|Electron|Photon)Decision'
        lines    [ "psi" ][ 'Hlt1TOS' ] = 'Hlt1(DiMuon|TrackMuon).*Decision'
        lines    [ "psi" ][ 'Hlt1TIS' ] = 'Hlt1(DiMuon|SingleMuon|Track).*Decision'
        lines    [ "psi" ][ 'Hlt2TOS' ] = 'Hlt2DiMuon.*Decision'
        lines    [ "psi" ][ 'Hlt2TIS' ] = 'Hlt2(Charm|Topo|DiMuon|Single).*Decision'

        sc = self.tisTos_initialize ( triggers , lines )
        if sc.isFailure() : return sc

        return SUCCESS

Here one defines six regex-patterns that describe the six sets of triggers lines: L0, Hlt1, Hlt2 vs TIS, TOS. These expressions are coded according to the infomration, obtainer earlier. The next step is rather trivial: in analyse method one need to invoke the method tistos for the given particle, J/psi in our case:

def analyse( self ) :  
    """The main 'analysis' method"""
    ...
    tup = self.nTuple('MyTuple')
    for b in particles :            
        psi =b(1) ## the first daughter: J/psi             
        ...             
        ## fill n-tuple with TISTOS information for J/psi
        self.tisTos      (
            psi               , ## particle 
            tup               , ## n-tuple
            'psi_'            , ## prefix for variable name in n-tuple
            self.lines['psi'] , ## trigger lines to be inspected
            verbose = True      ## good ooption for those who hates bit-wise operations 
            )            
        tup.write()             
   ... 
   return SUCCESS

This code adds several variables into n-tuple/tree, see log-file or use help(Algo.tistos). Also TisTos-information for global and physics triggers is added.

In details,Click to expand

Challenge

  1. Add tistos-function for your previous Bender module with n-tuples.
    • (Do not forget to instrument the initialize method)
  2. Run it and observe new variables in n-tuple/tree
  3. Make a plot of B-mass for all candidates, and for candiated that are L0-TOS, Hlt-TOS and Hlt2-TOS with respect to the set of selected trigger lines.

Solution

The complete module is accessible here and the corresponsing log-file is here To make the corresponsing plot, e.g. start (i)python:

import ROOT
f = ROOT.TFile('TisTosTuples.root','READ')
t = f.Get('TisTos/MyTuple')
t.Draw ( 'm_b'  ,'' , 'e1' )
t.Draw ( 'm_b' , ' psi_l0tos_tos && psi_l1tos_tos && psi_l2tos_tos' , 'same hist' )

The result is here:alt image text

results matching ""

    No results matching ""