Use Analysis package

From Charm-Tau Detector
(Difference between revisions)
Jump to: navigation, search
(Created page with "= Introduction = The Analysis module implements all tools needed for: * Selection the final-state-particles reconstructed in the detector * Construction arbitrary decay tree...")
 
 
(10 intermediate revisions by one user not shown)
Line 1: Line 1:
 
= Introduction =
 
= Introduction =
  
The Analysis module implements all tools needed for:
+
The <code>Analysis</code> module implements tools for:
  
* Selection the final-state-particles reconstructed in the detector
+
* Access reconstructed final-state-particles
* Construction arbitrary decay tree
+
* Building particle decay trees
 
* Imposing selection criteria
 
* Imposing selection criteria
* Applying kinematic fit to the decay tree (TODO)
+
* Applying kinematic fit to a decay tree
* Saving flat ntuple for the selected candidates
+
* Saving flat ntuple to a <code>ROOT</code> <code>TTree</code>
  
== The decay language ==
+
== Decay description ==
  
An easy to read and to write string description of particle decay is used in the Analysis package. Particle names correspond to EvtGen naming scheme. The following strings are valid decay expressions:
+
The <code>Analysis</code> module supports string description of particle decays. [https://git.inp.nsk.su/sctau/aurora/-/blob/master/Generation/Generators/EvtGen_i/share/evt.pdl The EvtGen particle naming scheme] is used. The following strings are valid decay expressions:
  
 
  "D0"
 
  "D0"
Line 17: Line 17:
 
  "D0 -> [rho0 -> pi+ pi-] pi0"
 
  "D0 -> [rho0 -> pi+ pi-] pi0"
  
As it is seen from the examples, a decay may or may not contain right-hand side. Left-hand and right-hand sides are separated by arrow "->". Spaces around the arrow are optional.
+
A decay string may or may not contain the arrow and the right-hand side. Spaces around the arrow are optional. Nested decays are expressed with square brackets.
  
== The cuts language ==
+
A particle in the decay string can be '''labeled''':
 +
 
 +
"pi+:lowpt"
 +
 
 +
"lowpt" is a label. Labels allow working with several lists of the same particle type. For example:
 +
 
 +
"D*+ -> [D0 -> K- pi+] pi+:lowpt"
 +
 
 +
A particle in the decay string can be '''selected''' using the "^" symbol:
 +
 
 +
"D0 -> ^K- ^pi+"
 +
 
 +
"K-" and "pi+" are selected here.
 +
 
 +
== Cuts description ==
 +
 
 +
Set of [[Analysis variables|predefined variables]] is included in the <code>Analysis</code> module. There are several types of variables:
 +
 
 +
* ''Particle variables''. A variable is calculated for a given particle, e.g.: <code>M</code> (mass).
 +
* ''Parametric particle variables''. A variable is calculate for a given particle and depends on one or several parameters, e.g. <code>deltaM</code> depends on the beam energy.
 +
* ''Event variables''. A variable is calculated for an event, e.g. <code>ncharged</code> (number of tracks).
 +
 
 +
Selection criteria are imposed with string expressions like:
 +
 
 +
* "M < 0.12"  # the mass less than 0.12 GeV
 +
* "charge == 0" # zero electric charge
 +
* "1.8 < M < 1.9"  # the mass is between 1.8 GeV and 1.9 GeV
 +
* "charge == 0 and M < 0.12"
 +
* "charge == 0 and [M < 0.12 or pt > 0.1]"
 +
 
 +
Square brackets are used to manage the order of logical operations. The following operators are available: ">", ">=", "<", "<=", "==", "!=", "and", "or".
  
 
= AuroraMaster interface =
 
= AuroraMaster interface =
  
The simplest way to write an analysis job option is using the AuroraMaster interface with the Analysis component.
+
An analysis algorithm is being connected to an <code>AuroraMaster</code> instance with the <code>add_analysis</code> method. An <code>AuroraConfig</code> object with analysis configuration must be passed as the <code>cfg</code> parameter:
 +
 
 +
am = AuroraMaster('analysis', 'info')
 +
am.add_analysis(cfg=anaysisCfg)
 +
 
 +
An analysis configuration should contain three items
 +
 
 +
anaysisCfg = AuroraConfig({
 +
    'Particles' : [...],
 +
    'Modifiers' : [...],
 +
    'Tuples' : [...]
 +
})
 +
 
 +
== EventLoader ==
 +
 
 +
The EventLoader algorithm specifies lists of the final-state-particles and corresponding cuts. Its configuration is a list of dictionaries of the following format:
 +
 
 +
[
 +
    {
 +
      'decstr': 'pi+ cc',
 +
      'cutstr': 'pt > 0.10',
 +
    },
 +
    {
 +
      'decstr': 'K+ cc',
 +
      'cutstr': 'pt > 0.10',
 +
    },
 +
    {
 +
      'decstr': 'pi+:lowpt cc',
 +
      'cutstr': 'pt < 0.20',
 +
    },
 +
    {
 +
      'decstr': 'gamma',
 +
      'cutstr': 'E > 0.07',
 +
    },
 +
    ...
 +
]
 +
 
 +
The <code>decstr</code> key correspond to the decay string. "cc" at the end of the decay string means that list of anti-particles will be created, too. The configuration above leads seven lists: "pi+", "pi-", "K+", "K-", "pi+:lowpt", "pi-:lowpt", and "gamma". These lists are available for the further analysis.
 +
 
 +
== Particle combiner ==
 +
 
 +
The <code>ParticleCombiner</code> algorithm is used to construct candidates for intermediate unstable particles like D0 or Lambda_c. An analysis job usually includes several ParticleCombiner algorithms. Combines are configured with the following parameters:
 +
 
 +
[
 +
    {
 +
      'label': 'Dkpi',
 +
      'decstr': 'D0 -> pi+ K-',
 +
      'cutstr': '1.82 < M < 1.90',
 +
      'selfconj': False
 +
    },
 +
    {
 +
      'label': 'Dkk',
 +
      'decstr': 'D0:kk -> K+ K-',
 +
      'cutstr': '1.82 < M < 1.90',
 +
      'selfconj': True
 +
    },
 +
    {
 +
      'label': 'DstDkpi',
 +
      'decstr': 'D*+ -> D0 pi+:lowpt',
 +
      'cutstr': 'deltaM < 0.10',
 +
      'selfconj': False
 +
    },
 +
]
 +
 
 +
The left side of the decay string defines the list of particles to create, and the right side must refer to existing particle lists (created by EventLoader or other ParticleCombiner). If selfconj us false then the charge conjugated list will be created, too ('anti-D0 -> pi- K+' and `D*- -> anti-D0 pi-:lowpt` will be created for the configuration above).
 +
 
 +
== Ntuple configuration ==
 +
 
 +
The last step of the analysis is saving necessary variables in a flat ntuple. Each ntuple algorithm corresponds to a particle list. There can be several ntuple algorithms corresponding to different particle lists. An example configuration is
 +
 
 +
[
 +
    {
 +
      'label': 'd0tup',
 +
      'root': 'D0',
 +
      'ofile': 'tup.root',
 +
      'vars' : [
 +
          {
 +
            'selector': 'root',
 +
            'varlist': ['momentumVars', 'E', 'M'],
 +
          },
 +
          {
 +
            'selector': 'D0 -> ^pi+ ^K-',
 +
            'varlist': ['momentumVars', 'pidVars', 'matchVars', 'charge']
 +
          }
 +
      ]
 +
    },
 +
    {
 +
      'label': 'dsttup',
 +
      'root': 'D*+',
 +
      'ofile': 'tup.root',
 +
      'vars' : [
 +
          {
 +
            'selector': 'root',
 +
            'varlist': ['M', 'deltaM'],
 +
          },
 +
          {
 +
            'selector': 'D*+ -> D0 ^pi+:lowpt',
 +
            'varlist': ['momentumVars', 'pidVars', 'charge']
 +
          }
 +
      ]
 +
    },
 +
]
 +
 
 +
The "label" value defines the name of TTree in the output file. The "root" value must correspond to an existing particle list. The "selector" value is a decay string specifying particles for which variables will be calculated and saved. The "varlist" is a list of named variables. Note that "momentumVars" and "pidVars" names denote groups of variables. Here is the complete list of names variable groups (defined in [https://git.inp.nsk.su/sctau/aurora/-/blob/master/Controls/AuroraMaster/python/analysis.py analysis.py]):
 +
 
 +
VARSETS = {
 +
    'momentumVars': ['px', 'py', 'pz', 'p', 'pt'],
 +
    'pidVars': ['pidkpi', 'pidmupi', 'pidkp', 'pide'],
 +
    'matchVars': ['pdgid_mc', 'px_mc', 'py_mc', 'pz_mc'],
 +
}
 +
 
 +
 
 +
== Convenience methods ==
 +
 
 +
A set of convenience methods are defined in the python Analysis module. These methods ease configuration of the analysis. The example below shows how to define the same configuration as we considered above:
  
= Low level interface =
+
from AuroraMaster.auroramaster import AuroraMaster, AuroraConfig
 +
from AuroraMaster.auroramaster import Analysis as A
 +
am = AuroraMaster('analysis', 'info')
 +
edminputCfg = AuroraConfig({
 +
    'filename': './parsim.root',  # should be in your run directory
 +
    'collections': ['Particles', 'allGenParticles'],
 +
})
 +
am.add_edmi(cfg=edminputCfg)
 +
anaysisCfg = A.analysis(
 +
    fsps=[
 +
        A.fspList('pi+ cc'),
 +
        A.fspList('K+ cc'),
 +
        A.fspList('pi+:lowpt cc', 'pt < 0.20'),
 +
        A.fspList('gamma'),
 +
    ],
 +
    combiners=[
 +
        A.combiner('Dkpi', 'D0 -> pi+ K-', '1.8 < M < 1.9'),
 +
        A.combiner('Dkk', 'D0 -> K+ K-', '1.8 < M < 1.9', selfconj=True),
 +
        A.combiner('DstDkpi', 'D*+ -> D0 pi+:lowpt', 'deltaM < 0.10'),
 +
    ],
 +
    tuples=[
 +
        A.ntuple('tup', 'D0', 'tuple.root', [
 +
            A.vars('root', ['momentumVars', 'E', 'M']),
 +
            A.vars('D0 -> ^pi+ ^K-', ['momentumVars', 'pidVars', 'matchVars']),
 +
          ]
 +
        ),
 +
        A.ntuple('tup', 'D0', 'tuple.root', [
 +
            A.vars('root', ['M', 'deltaM']),
 +
            A.vars('D*+ -> D0 ^pi+:lowpt', ['momentumVars', 'pidVars', 'charge']),
 +
          ]
 +
        ),
 +
    ]
 +
)
 +
am.add_analysis(cfg=anaysisCfg)
 +
am.run(evtmax=10**4)

Latest revision as of 18:25, 4 August 2021

Contents

[edit] Introduction

The Analysis module implements tools for:

  • Access reconstructed final-state-particles
  • Building particle decay trees
  • Imposing selection criteria
  • Applying kinematic fit to a decay tree
  • Saving flat ntuple to a ROOT TTree

[edit] Decay description

The Analysis module supports string description of particle decays. The EvtGen particle naming scheme is used. The following strings are valid decay expressions:

"D0"
"D0 -> K- pi+"
"D0 -> [rho0 -> pi+ pi-] pi0"

A decay string may or may not contain the arrow and the right-hand side. Spaces around the arrow are optional. Nested decays are expressed with square brackets.

A particle in the decay string can be labeled:

"pi+:lowpt"

"lowpt" is a label. Labels allow working with several lists of the same particle type. For example:

"D*+ -> [D0 -> K- pi+] pi+:lowpt"

A particle in the decay string can be selected using the "^" symbol:

"D0 -> ^K- ^pi+"

"K-" and "pi+" are selected here.

[edit] Cuts description

Set of predefined variables is included in the Analysis module. There are several types of variables:

  • Particle variables. A variable is calculated for a given particle, e.g.: M (mass).
  • Parametric particle variables. A variable is calculate for a given particle and depends on one or several parameters, e.g. deltaM depends on the beam energy.
  • Event variables. A variable is calculated for an event, e.g. ncharged (number of tracks).

Selection criteria are imposed with string expressions like:

  • "M < 0.12" # the mass less than 0.12 GeV
  • "charge == 0" # zero electric charge
  • "1.8 < M < 1.9" # the mass is between 1.8 GeV and 1.9 GeV
  • "charge == 0 and M < 0.12"
  • "charge == 0 and [M < 0.12 or pt > 0.1]"

Square brackets are used to manage the order of logical operations. The following operators are available: ">", ">=", "<", "<=", "==", "!=", "and", "or".

[edit] AuroraMaster interface

An analysis algorithm is being connected to an AuroraMaster instance with the add_analysis method. An AuroraConfig object with analysis configuration must be passed as the cfg parameter:

am = AuroraMaster('analysis', 'info')
am.add_analysis(cfg=anaysisCfg)

An analysis configuration should contain three items

anaysisCfg = AuroraConfig({
   'Particles' : [...],
   'Modifiers' : [...],
   'Tuples' : [...]
})

[edit] EventLoader

The EventLoader algorithm specifies lists of the final-state-particles and corresponding cuts. Its configuration is a list of dictionaries of the following format:

[
   {
      'decstr': 'pi+ cc',
      'cutstr': 'pt > 0.10',
   },
   {
      'decstr': 'K+ cc',
      'cutstr': 'pt > 0.10',
   },
   {
      'decstr': 'pi+:lowpt cc',
      'cutstr': 'pt < 0.20',
   },
   {
      'decstr': 'gamma',
      'cutstr': 'E > 0.07',
   },
   ...
]

The decstr key correspond to the decay string. "cc" at the end of the decay string means that list of anti-particles will be created, too. The configuration above leads seven lists: "pi+", "pi-", "K+", "K-", "pi+:lowpt", "pi-:lowpt", and "gamma". These lists are available for the further analysis.

[edit] Particle combiner

The ParticleCombiner algorithm is used to construct candidates for intermediate unstable particles like D0 or Lambda_c. An analysis job usually includes several ParticleCombiner algorithms. Combines are configured with the following parameters:

[
   {
      'label': 'Dkpi',
      'decstr': 'D0 -> pi+ K-',
      'cutstr': '1.82 < M < 1.90',
      'selfconj': False
   },
   {
      'label': 'Dkk',
      'decstr': 'D0:kk -> K+ K-',
      'cutstr': '1.82 < M < 1.90',
      'selfconj': True
   },
   {
      'label': 'DstDkpi',
      'decstr': 'D*+ -> D0 pi+:lowpt',
      'cutstr': 'deltaM < 0.10',
      'selfconj': False
   },
]

The left side of the decay string defines the list of particles to create, and the right side must refer to existing particle lists (created by EventLoader or other ParticleCombiner). If selfconj us false then the charge conjugated list will be created, too ('anti-D0 -> pi- K+' and `D*- -> anti-D0 pi-:lowpt` will be created for the configuration above).

[edit] Ntuple configuration

The last step of the analysis is saving necessary variables in a flat ntuple. Each ntuple algorithm corresponds to a particle list. There can be several ntuple algorithms corresponding to different particle lists. An example configuration is

[
   {
      'label': 'd0tup',
      'root': 'D0',
      'ofile': 'tup.root',
      'vars' : [
         {
            'selector': 'root',
            'varlist': ['momentumVars', 'E', 'M'],
         },
         {
            'selector': 'D0 -> ^pi+ ^K-',
            'varlist': ['momentumVars', 'pidVars', 'matchVars', 'charge']
         }
      ]
   },
   {
      'label': 'dsttup',
      'root': 'D*+',
      'ofile': 'tup.root',
      'vars' : [
         {
            'selector': 'root',
            'varlist': ['M', 'deltaM'],
         },
         {
            'selector': 'D*+ -> D0 ^pi+:lowpt',
            'varlist': ['momentumVars', 'pidVars', 'charge']
         }
      ]
   },
]

The "label" value defines the name of TTree in the output file. The "root" value must correspond to an existing particle list. The "selector" value is a decay string specifying particles for which variables will be calculated and saved. The "varlist" is a list of named variables. Note that "momentumVars" and "pidVars" names denote groups of variables. Here is the complete list of names variable groups (defined in analysis.py):

VARSETS = {
   'momentumVars': ['px', 'py', 'pz', 'p', 'pt'],
   'pidVars': ['pidkpi', 'pidmupi', 'pidkp', 'pide'],
   'matchVars': ['pdgid_mc', 'px_mc', 'py_mc', 'pz_mc'],
}


[edit] Convenience methods

A set of convenience methods are defined in the python Analysis module. These methods ease configuration of the analysis. The example below shows how to define the same configuration as we considered above:

from AuroraMaster.auroramaster import AuroraMaster, AuroraConfig
from AuroraMaster.auroramaster import Analysis as A
am = AuroraMaster('analysis', 'info')
edminputCfg = AuroraConfig({
   'filename': './parsim.root',  # should be in your run directory
   'collections': ['Particles', 'allGenParticles'],
})
am.add_edmi(cfg=edminputCfg)
anaysisCfg = A.analysis(
   fsps=[
       A.fspList('pi+ cc'),
       A.fspList('K+ cc'),
       A.fspList('pi+:lowpt cc', 'pt < 0.20'),
       A.fspList('gamma'),
   ],
   combiners=[
       A.combiner('Dkpi', 'D0 -> pi+ K-', '1.8 < M < 1.9'),
       A.combiner('Dkk', 'D0 -> K+ K-', '1.8 < M < 1.9', selfconj=True),
       A.combiner('DstDkpi', 'D*+ -> D0 pi+:lowpt', 'deltaM < 0.10'),
   ],
   tuples=[
       A.ntuple('tup', 'D0', 'tuple.root', [
           A.vars('root', ['momentumVars', 'E', 'M']),
           A.vars('D0 -> ^pi+ ^K-', ['momentumVars', 'pidVars', 'matchVars']),
          ]
       ),
       A.ntuple('tup', 'D0', 'tuple.root', [
           A.vars('root', ['M', 'deltaM']),
           A.vars('D*+ -> D0 ^pi+:lowpt', ['momentumVars', 'pidVars', 'charge']),
          ]
       ),
   ]
)
am.add_analysis(cfg=anaysisCfg)
am.run(evtmax=10**4)
Personal tools