Source code for vibe.analysis_validation_modes.physics.btoDstlnu_validation_mode

from typing import List
import pandas as pd

import basf2
import modularAnalysis as ma
import vertex as vx
from variables import variables as vm

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__ = [
    "BtoDstLNuValidationMode",
]

# D* are reconstructed from the slow pion
# in their decay to D pi

[docs] @fancy_validation_mode_header class BtoDstLNuValidationMode(ValidationModeBaseClass): name = "BtoDstLNu" latex_str = r"B^0 \rightarrow D^{*-} \ell \nu, D^{*-} \rightarrow \bar{D^0} \pi^+"
[docs] def create_basf2_path(self): main_path = basf2.Path() # fsp selection electrons = ("e-:rec", "useCMSFrame(p) > 1.0 and electronID > 0.8") muons = ("mu-:rec", "useCMSFrame(p) > 1.0 and muonID > 0.8") pions = ("pi-:rec", "pionID > 0.6") ma.fillParticleLists( decayStringsWithCuts=[electrons, muons, pions], path=main_path, ) ma.addInclusiveDstarReconstruction( DstarCut="M > 1.96 and M < 2.06", decayString="D*+:pi -> pi+:rec", slowPionCut="", path=main_path, ) # B0 reconstruction ma.reconstructDecay( decayString="B0:e_rec -> D*-:pi e+:rec", cut="", dmID=1, path=main_path, ) ma.reconstructDecay( decayString="B0:mu_rec -> D*-:pi mu+:rec", cut="", dmID=2, path=main_path, ) # merge + MC matching + vertex ma.copyLists( outputListName="B0:sl_rec", inputListNames=["B0:e_rec", "B0:mu_rec"], path=main_path, ) ma.matchMCTruth( "B0:sl_rec", path=main_path, ) vx.treeFit( "B0:sl_rec", 0.001, ipConstraint=True, path=main_path, ) ma.buildRestOfEvent("B0:sl_rec", path=main_path) # define ROE mask cuts tracksCut = "abs(d0) < 10.0 and abs(z0) < 20.0" clustersCut1 = "[clusterE1E9 > 0.4 or E > 0.075] and [[E > 0.062 and abs(clusterTiming)<18 and clusterReg==1] or " clustersCut2 = ( "[E > 0.060 and abs(clusterTiming)<20 and clusterReg==2]" " or [E > 0.056 and abs(clusterTiming)<44 and clusterReg==3]]" ) clustersCut = clustersCut1 + clustersCut2 # define and append ROE masks m0 = ("m0", "", "") m1 = ("m1", tracksCut, clustersCut) ma.appendROEMasks("B0:sl_rec", [m0, m1], path=main_path) ma.buildEventShape(inputListNames=["B0:sl_rec"], path=main_path) ma.buildEventKinematics(inputListNames=["B0:sl_rec"], path=main_path) # save variables B_vars = [ "isSignal", "Mbc", "deltaE", "beamE", "p", "E", "mcPDG", "decayTypeRecoil", "cosThetaBetweenParticleAndNominalB", "isSignalAcceptMissingNeutrino", ("Mbc_corr_noCuts", "weMbc(m0, 0)"), ("Mbc_corr_nominalMask", "weMbc(m1, 0)"), ("DeltaE_corr_noCuts", "weDeltae(m0, 0)"), ("DeltaE_corr_nominalMask", "weDeltae(m1, 0)"), ] Dst_vars = [ ("Dst_p", "daughter(0, p)"), ("Dst_E", "daughter(0, E)"), ("Dst_M", "daughter(0, M)"), ("Dst_PDG", "daughter(0, PDG)"), ("Dst_mcPDG", "daughter(0, mcPDG)"), ] lep_vars = [ ("lep_p", "daughter(1, p)"), ("lep_E", "daughter(1, E)"), ("lep_PDG", "daughter(1, PDG)"), ("lep_mcPDG", "daughter(1, mcPDG)"), ("lep_eID", "daughter(1, electronID)"), ("lep_muID", "daughter(1, muonID)"), # leptonic system variables ("q2_noCuts", "weQ2lnuSimple(m0, 0)"), ("q2_nominalMask", "weQ2lnuSimple(m1, 0)"), ] ROE_vars = [ ("MM2_noCuts", "weMissM2(m0, 0)"), ("MM2_nominalMask", "weMissM2(m1, 0)"), ("ROE_Q_noCuts", "roeCharge(m0)"), ("ROE_Q_nominalMask", "roeCharge(m1)"), ] pion_vars = [("pion_pionID", "daughter(0, daughter(0, pionID))")] list_vars_alias = [] list_vars = B_vars + Dst_vars + lep_vars + ROE_vars + pion_vars for var in list_vars: if type(var) == tuple: alias, name = var vm.addAlias(alias, name) list_vars_alias.append(alias) else: list_vars_alias.append(var) self.variables_to_validation_ntuple( decay_str="B0:sl_rec", variables=list_vars_alias, path=main_path, ) return main_path
@property def analysis_validation_histograms(self) -> List[Histogram]: return [ Histogram( name="Mbc", title=r"$B \rightarrow D^* \ell \nu$", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="Mbc"), label=r"$M_{bc}$", unit=r"GeV", bins=50, scope=(5.24, 5.29), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="isSignalAcceptMissingNeutrino == 1", color="purple", ), HistComponent( label="Background", additional_cut_str="isSignalAcceptMissingNeutrino != 1", color="cyan", ), ], ), Histogram( name="Mbc_corr_noCuts", title=r"$B \rightarrow D^* \ell \nu$", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="Mbc_corr_noCuts"), label=r"$M_{bc} corrected$", unit=r"GeV", bins=50, scope=(5.24, 5.29), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="isSignalAcceptMissingNeutrino == 1", color="purple", ), HistComponent( label="Background", additional_cut_str="isSignalAcceptMissingNeutrino != 1", color="cyan", ), ], ), Histogram( name="Mbc_corr_nominalMask", title=r"$B \rightarrow D^* \ell \nu$", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="Mbc_corr_nominalMask"), label=r"$M_{bc} corrected, cleaned ROE$", unit=r"GeV", bins=50, scope=(5.24, 5.29), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="isSignalAcceptMissingNeutrino == 1", color="purple", ), HistComponent( label="Background", additional_cut_str="isSignalAcceptMissingNeutrino != 1", color="cyan", ), ], ), Histogram( name="deltaE", title=r"$B \rightarrow D^* \ell \nu$", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="deltaE"), label=r"$\Delta E$", unit=r"GeV", bins=100, scope=(-0.2, 0.2), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="isSignalAcceptMissingNeutrino == 1", color="purple", ), HistComponent( label="Background", additional_cut_str="isSignalAcceptMissingNeutrino != 1", color="cyan", ), ], ), Histogram( name="DeltaE_corr_noCuts", title=r"$B \rightarrow D^* \ell \nu$", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="DeltaE_corr_noCuts"), label=r"$\Delta E corrected$", unit=r"GeV", bins=100, scope=(-0.2, 0.2), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="isSignalAcceptMissingNeutrino == 1", color="purple", ), HistComponent( label="Background", additional_cut_str="isSignalAcceptMissingNeutrino != 1", color="cyan", ), ], ), Histogram( name="DeltaE_corr_nominalMask", title=r"$B \rightarrow D^* \ell \nu$", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="DeltaE_corr_nominalMask"), label=r"$\Delta E corrected, cleaned ROE$", unit=r"GeV", bins=100, scope=(-0.2, 0.2), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="isSignalAcceptMissingNeutrino == 1", color="purple", ), HistComponent( label="Background", additional_cut_str="isSignalAcceptMissingNeutrino != 1", color="cyan", ), ], ), Histogram( name="lep_p", title=r"$B \rightarrow D^* \ell \nu$", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="lep_p"), label=r"$p_{\ell}$", unit="GeV", bins=100, scope=(0.5, 10), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="isSignalAcceptMissingNeutrino == 1", color="purple", ), HistComponent( label="Background", additional_cut_str="isSignalAcceptMissingNeutrino != 1", color="cyan", ), ], ), Histogram( name="q2_noCuts", title=r"$B \rightarrow D^* \ell \nu$", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="q2_noCuts"), label=r"$q^2$ no cuts", unit=r"Gev$^2$", bins=100, scope=(0, 25), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="isSignalAcceptMissingNeutrino == 1", color="purple", ), HistComponent( label="Background", additional_cut_str="isSignalAcceptMissingNeutrino != 1", color="cyan", ), ], ), Histogram( name="q2_nominalMask", title=r"$B \rightarrow D^* \ell \nu$", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="q2_nominalMask"), label=r"$q^2$ cleaned ROE", unit=r"Gev$^2$", bins=100, scope=(0, 25), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="isSignalAcceptMissingNeutrino == 1", color="purple", ), HistComponent( label="Background", additional_cut_str="isSignalAcceptMissingNeutrino != 1", color="cyan", ), ], ), Histogram( name="MM2_noCuts", title=r"$B \rightarrow D^* \ell \nu$", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="MM2_noCuts"), label=r"$MM^2$ no cuts", unit=r"Gev$^2$", bins=100, scope=(-5, 15), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="isSignalAcceptMissingNeutrino == 1", color="purple", ), HistComponent( label="Background", additional_cut_str="isSignalAcceptMissingNeutrino != 1", color="cyan", ), ], ), Histogram( name="MM2_nominalMask", title=r"$B \rightarrow D^* \ell \nu$", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="MM2_nominalMask"), label=r"$MM^2$ cleaned ROE", unit=r"Gev$^2$", bins=100, scope=(-5, 15), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="isSignalAcceptMissingNeutrino == 1", color="purple", ), HistComponent( label="Background", additional_cut_str="isSignalAcceptMissingNeutrino != 1", color="cyan", ), ], ), Histogram( name="ROE_Q_noCuts", title=r"$B \rightarrow D^* \ell \nu$", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="ROE_Q_noCuts"), label=r"$Q_{\mathrm{ROE}} no cuts$", unit="", bins=5, scope=(-2.5, 2.5), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="isSignalAcceptMissingNeutrino == 1", color="purple", ), HistComponent( label="Background", additional_cut_str="isSignalAcceptMissingNeutrino != 1", color="cyan", ), ], ), Histogram( name="ROE_Q_nominalMask", title=r"$B \rightarrow D^* \ell \nu$", hist_variable=HistVariable( df_label=makeROOTCompatible(variable="ROE_Q_nominalMask"), label=r"$Q_{\mathrm{ROE}} cleaned ROE$", unit="", bins=5, scope=(-2.5, 2.5), ), hist_components=[ HistComponent( label="Signal", additional_cut_str="isSignalAcceptMissingNeutrino == 1", color="purple", ), HistComponent( label="Background", additional_cut_str="isSignalAcceptMissingNeutrino != 1", color="cyan", ), ], ), ]
[docs] def offline_df_manipulation(self, df: pd.DataFrame) -> pd.DataFrame: df = df.sample(frac=1.0).groupby(by=["__event__"]).head(1) # Applying rand BCS offline return df
[docs] def get_number_of_signal_for_efficiency(self, df: pd.DataFrame) -> float: return df["isSignalAcceptMissingNeutrino"].sum()