from typing import List, Optional
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, particle_list: Optional[str] = None) -> float:
return df["isSignal"].sum()