from typing import List
import pandas as pd
import basf2
import modularAnalysis as ma
import vertex as vx
import variables.utils as vu
from stdV0s import stdKshorts
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__ = [
"BtoDpiDtoKspipiValidationMode",
]
[docs]
@fancy_validation_mode_header
class BtoDpiDtoKspipiValidationMode(ValidationModeBaseClass):
name = "BtoDpiDtoKspipi"
latex_str = r"$B^+ \rightarrow D \pi^+, D \rightarrow K^0_S \pi^+ \pi^-$"
[docs]
def create_basf2_path(self):
main_path = basf2.Path()
# fsp selection
pions = ("pi-:rec", "pionID > 0.6")
ma.fillParticleLists(
decayStringsWithCuts=[pions],
path=main_path,
)
# K_S^0 reconstruction
stdKshorts(prioritiseV0=True, fitter="TreeFit", path=main_path)
# ma.reconstructDecay(
# decayString="K_S0:pipi -> pi-:all pi+:all",
# cut="InvM > 0.4 and InvM < 0.6",
# path=main_path,
# )
# D^0 reconstruction
ma.reconstructDecay(
decayString="D0:Kspipi -> K_S0:merged pi-:all pi+:all",
cut="InvM > 1.75 and InvM < 1.95",
path=main_path,
)
# B meson reconstruction
ma.reconstructDecay(
decayString="B-:KspipiPi -> D0:Kspipi pi-:rec",
cut="Mbc>5.24 and abs(deltaE) < 0.2",
dmID=1,
path=main_path,
)
# merge + MC matching + vertex
ma.matchMCTruth(
"B-:KspipiPi",
path=main_path,
)
vx.treeFit("B-:KspipiPi", 0.001, massConstraint=[421], path=main_path)
vx.TagV(list_name="B-:KspipiPi", confidenceLevel=0.001, constraintType="tube", path=main_path)
# save variables
B_variables = ["isSignal", "Mbc", "deltaE", "beamE"]
K_S0_variables = vu.create_aliases_for_selected(
list_of_variables=["M", "InvM", "p"], decay_string="B- -> [D0 -> ^K_S0 pi+ pi-] pi-", prefix="Ks"
)
D0_variables = vu.create_aliases_for_selected(
list_of_variables=["InvM", "p"], decay_string="B- -> ^D0 pi-", prefix="D0"
)
pi_variables = vu.create_aliases_for_selected(
list_of_variables=["InvM", "p"], decay_string="B- -> D0 ^pi-", prefix="pi"
)
self.variables_to_validation_ntuple(
decay_str="B-:KspipiPi",
variables=B_variables + K_S0_variables + D0_variables + pi_variables,
path=main_path,
)
return main_path
@property
def analysis_validation_histograms(self) -> List[Histogram]:
return [
Histogram(
name="Mbc",
title="",
hist_variable=HistVariable(
df_label=makeROOTCompatible(variable="Mbc"),
label=r"$M_{bc}$",
unit=r"GeV/$c^2$",
bins=50,
scope=(5.24, 5.29),
),
hist_components=[
HistComponent(
label="All",
),
],
),
Histogram(
name="deltaE",
title="",
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="All",
),
],
),
Histogram(
name="beamE",
title="",
hist_variable=HistVariable(
df_label=makeROOTCompatible(variable="beamE"),
label=r"$E(beam)$",
unit=r"GeV",
bins=40,
scope=(10.8, 11.2),
),
hist_components=[
HistComponent(
label="All",
),
],
),
Histogram(
name="mKs",
title="",
hist_variable=HistVariable(
df_label=makeROOTCompatible(variable="Ks_InvM"),
label=r"$m(K_S^0)$",
unit=r"GeV/$c^2$",
bins=80,
scope=(0.48, 0.52),
),
hist_components=[
HistComponent(
label="All",
),
],
),
Histogram(
name="pKs",
title="",
hist_variable=HistVariable(
df_label=makeROOTCompatible(variable="Ks_p"),
label=r"$p(K_S^0)$",
unit=r"GeV/$c$",
bins=175,
scope=(0, 3.5),
),
hist_components=[
HistComponent(
label="All",
),
],
),
Histogram(
name="mD",
title="",
hist_variable=HistVariable(
df_label=makeROOTCompatible(variable="D0_InvM"),
label=r"$m(D)$",
unit=r"GeV/$c^2$",
bins=100,
scope=(1.75, 1.95),
),
hist_components=[
HistComponent(
label="All",
),
],
),
Histogram(
name="pD",
title="",
hist_variable=HistVariable(
df_label=makeROOTCompatible(variable="D0_p"),
label=r"$p(D)$",
unit=r"GeV/$c$",
bins=115,
scope=(1.2, 3.5),
),
hist_components=[
HistComponent(
label="All",
),
],
),
Histogram(
name="pPi",
title="",
hist_variable=HistVariable(
df_label=makeROOTCompatible(variable="pi_p"),
label=r"$p(\pi^-)$",
unit=r"GeV/$c$",
bins=100,
scope=(1.5, 3.5),
),
hist_components=[
HistComponent(
label="All",
),
],
),
]
[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["isSignal"].sum()