Source code for vibe.analysis_validation_modes.physics.tautoe3pi

from typing import List
import pandas as pd

import basf2
import basf2 as b2
import modularAnalysis as ma
import variables.collections as vc
import variables.utils as vu
from variables import variables as va

from vibe.core.utils.misc import fancy_validation_mode_header
from vibe.core.validation_mode import ValidationModeBaseClass
from vibe.core.helper.histogram_tools import HistVariable, Histogram, HistComponent
from vibe.core.helper.root_helper import makeROOTCompatible

__all__ = [
    "Tautoe3pi",
]

[docs] @fancy_validation_mode_header class Tautoe3pi(ValidationModeBaseClass): name = "Tautoe3pi" latex_str = r"$\tau^+, \tau^- \rightarrow \pi^+ \pi^- \pi^+ \nu, e^-$"
[docs] def create_basf2_path(self): myPath = basf2.Path() # Define 'good' tracks and photons trackCuts = "dr <= 1.0 and -3.0 <= dz <= 3.0" gammaCuts = "E > 0.50 and -0.8660 < cosTheta < 0.9563" ma.fillParticleList("pi+:track", trackCuts, path=myPath) ma.fillParticleList("gamma:good", gammaCuts, path=myPath) ma.fillParticleList("e+:tag", trackCuts, path=myPath) ma.fillParticleList("mu+:tag", trackCuts, path=myPath) # Reconstruction using 3-1 prong topology. ma.applyEventCuts("countInList(pi+:track) == 4", path=myPath) # PID cuts ma.copyLists("pi+:id", "pi+:track", path=myPath) # Signal: tau -> 3 pi nu ma.reconstructDecay("tau+:signal -> pi+:id pi-:id pi+:id ?nu", "M < 1.8", path=myPath) # Tag decay # Leptonic tag: tau -> l + \bar{nu}_l + nu_tau (missing neutrinos are ignored with '?nu') ma.reconstructDecay("tau-:eTag -> e-:tag ?nu", "", path=myPath, dmID=1) ma.copyLists("tau+:tag", "tau-:eTag", path=myPath) # To store information of the tagging mode va.addAlias("dmIDTag", "daughter(1, extraInfo(decayModeID))") # Tau pair candidates from a virtual photon (vpho) ma.reconstructDecay("vpho:all -> tau+:signal tau-:tag", "", path=myPath) # Event shape and event kinematics ma.buildEventShape( ["pi+:track", "gamma:good"], thrust=True, foxWolfram=False, cleoCones=False, jets=False, harmonicMoments=False, allMoments=False, collisionAxis=False, sphericity=False, path=myPath, ) ma.buildEventKinematics(["pi+:track", "gamma:good"], path=myPath) # Select vpho candidates with signal and tag in opposite sides of the event. va.addAlias( "prod1", "formula(daughter(0, daughter(0, cosToThrustOfEvent))*daughter(1, daughter(0,cosToThrustOfEvent)))" ) va.addAlias( "prod2", "formula(daughter(0, daughter(1, cosToThrustOfEvent))*daughter(1, daughter(0,cosToThrustOfEvent)))" ) va.addAlias( "prod3", "formula(daughter(0, daughter(2, cosToThrustOfEvent))*daughter(1, daughter(0,cosToThrustOfEvent)))" ) ma.applyCuts("vpho:all", "prod1 < 0 and prod2 < 0 and prod3 < 0", path=myPath) # Photons on signal and tag side ma.copyList("gamma:sig", "gamma:good", path=myPath) ma.copyList("gamma:tag", "gamma:good", path=myPath) # 1-prong on positive or negative side of thrust axis va.addAlias("tagInPosThrust", "countInList(vpho:all, daughter(1, daughter(0,cosToThrustOfEvent)) > 0)") va.addAlias("tagInNegThrust", "countInList(vpho:all, daughter(1, daughter(0,cosToThrustOfEvent)) < 0)") positiveThrust = b2.create_path() negativeThrust = b2.create_path() ma.applyCuts("gamma:tag", "cosToThrustOfEvent > 0", path=positiveThrust) ma.applyCuts("gamma:sig", "cosToThrustOfEvent < 0", path=positiveThrust) ma.applyCuts("gamma:tag", "cosToThrustOfEvent < 0", path=negativeThrust) ma.applyCuts("gamma:sig", "cosToThrustOfEvent > 0", path=negativeThrust) # take different paths if tag in cosToThrustOfEvent > or < 0 sigThrustModule = myPath.add_module("VariableToReturnValue", variable="tagInPosThrust") sigThrustModule.if_value("> 0", positiveThrust, b2.AfterConditionPath.CONTINUE) sigThrustModule = myPath.add_module("VariableToReturnValue", variable="tagInNegThrust") sigThrustModule.if_value("> 0", negativeThrust, b2.AfterConditionPath.CONTINUE) # the number of photons and pi0s in 3prong and 1prong hemispheres va.addAlias("nPhotons_signal", "nParticlesInList(gamma:sig)") va.addAlias("nPhotons_tag", "nParticlesInList(gamma:tag)") # Energy in each side va.addAlias("photonE_sig", "totalEnergyOfParticlesInList(gamma:sig)") va.addAlias("photonE_tag", "totalEnergyOfParticlesInList(gamma:tag)") va.addAlias("photonECMS_sig", "useCMSFrame(totalEnergyOfParticlesInList(gamma:sig))") va.addAlias("photonECMS_tag", "useCMSFrame(totalEnergyOfParticlesInList(gamma:tag))") # MC matching of the tau candidates ma.matchMCTruth("tau+:signal", path=myPath) ma.matchMCTruth("tau+:tag", path=myPath) # Information of the generated decay mode ma.labelTauPairMC(path=myPath) va.addAlias("M_12", "daughterInvM(0, 1)") va.addAlias("M_23", "daughterInvM(1, 2)") va.addAlias("M_31", "daughterInvM(0, 2)") va.addAlias("M_123", "daughterInvM(0, 1, 2)") # PID for tag side pid_tag_daughter = vu.create_aliases(vc.pid, "daughter(0, {variable})", "tagSide") # Event variables to store eventVariables = [ "thrust", "visibleEnergyOfEventCMS", "missingMomentumOfEvent", "missingMomentumOfEvent_theta", "missingMomentumOfEventCMS", "missingMomentumOfEventCMS_theta", "totalPhotonsEnergyOfEvent", "missingMass2OfEvent", "nPhotons_signal", "nPhotons_tag", "photonE_sig", "photonE_tag", "photonECMS_sig", "photonECMS_tag", "dmIDTag", "tauPlusMCMode", "tauMinusMCMode", ] mcVariables = ["mcErrors", "genMotherPDG", "mcPDG"] invmass_sig = ["M_12", "M_23", "M_31", "M_123"] kVariables = vc.inv_mass + vc.kinematics variableList = ( vu.create_aliases_for_selected(list_of_variables=eventVariables, decay_string="^vpho") + vu.create_aliases_for_selected( list_of_variables=mcVariables + ["charge"], decay_string="vpho -> ^tau+ ^tau-" ) + vu.create_aliases_for_selected(list_of_variables=invmass_sig, decay_string="vpho -> ^tau+ tau-") + vu.create_aliases_for_selected( list_of_variables=kVariables + ["isSignal"], decay_string="vpho -> [^tau+ -> ^pi+ ^pi- ^pi-] ^tau-" ) + vu.create_aliases_for_selected( list_of_variables=vc.pid, decay_string="vpho -> [tau+ -> ^pi+ ^pi- ^pi+] tau- " ) + vu.create_aliases_for_selected(list_of_variables=pid_tag_daughter, decay_string="vpho -> tau+ ^tau- ") ) self.variables_to_validation_ntuple( decay_str="vpho:all", variables=variableList, path=myPath, ) return myPath
@property def analysis_validation_histograms(self) -> List[Histogram]: return [ Histogram( name="Thrust", title="Thrust of e3pi", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="thrust"), label="Thrust", unit="", bins=60, scope=(0.7, 1.0), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="dmIDTag == 1 and nPhotons_signal==0 and nPhotons_tag==0 and tau_0_isSignal==1", ), ], ), Histogram( name="Visible_Energy", title=r"$E_{vis}$ of e3pi", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="visibleEnergyOfEventCMS"), label=r"$E_{visible}$ in CMS", unit="GeV", bins=50, scope=(0.0, 12.0), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="dmIDTag == 1 and nPhotons_signal==0 and nPhotons_tag==0" and "tau_0_isSignal==1", ), ], ), Histogram( name="M_a1", title=r"$M_{a1}$ of e3pi", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="tau_0_M"), label=r"$M_{a1}$", unit=r"GeV/$c^2$", bins=80, scope=(0.0, 1.8), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="dmIDTag == 1 and nPhotons_signal==0 and nPhotons_tag==0 and tau_0_isSignal==1", ), ], ), Histogram( name="M_12", title=r"$M_{12} & M_{23}$ of e3pi", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="tau_M_12"), label=r"$M_{\pi^{\pm} \pi^{\mp}}$", unit=r"GeV/$c^2$", bins=80, scope=(0.0, 1.8), merged_variable=makeROOTCompatible(variable="tau_M_23"), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="dmIDTag == 1 and nPhotons_signal==0 and nPhotons_tag==0 and tau_0_isSignal==1", ), ], ), Histogram( name="M_31", title=r"$M_{31}$ of e3pi", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="tau_M_31"), label=r"$M_{\pi^{\pm}\pi^{\pm}}$", unit=r"GeV/$c^2$", bins=80, scope=(0.0, 1.8), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="dmIDTag == 1 and nPhotons_signal==0 and nPhotons_tag==0 and tau_0_isSignal==1", ), ], ), Histogram( name="M_123", title=r"$M_{123}$ of e3pi", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="tau_M_123"), label=r"$M_{2\pi^{\mp}\pi^{\pm}}$", unit=r"GeV/$c^2$", bins=80, scope=(0.0, 1.8), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="dmIDTag == 1 and nPhotons_signal==0 and nPhotons_tag==0 and tau_0_isSignal==1", ), ], ), Histogram( name="Momentum_tag-track", title=r"$P_{tag-track}$ of e3pi", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="tau_1_p"), label=r"$Momentum_{tag-track}$", unit="GeV", bins=80, scope=(0.0, 8.0), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="dmIDTag == 1 and nPhotons_signal==0 and nPhotons_tag==0 and tau_0_isSignal==1", ), ], ), ]
[docs] def get_number_of_signal_for_efficiency(self, df: pd.DataFrame) -> float: return df["tau_0_isSignal"].sum()