From 81ee63edf587562255526c7a698d2d22471dca66 Mon Sep 17 00:00:00 2001 From: lugrazet <luke.grazette@cern.ch> Date: Thu, 12 Dec 2024 13:49:47 +0000 Subject: [PATCH 1/4] v1r2052 : [QEE] ew_projects_Run3 : Centrally processed W31.34 MC --- ew_projects_run3/ftuple.py | 128 +++++++++ ew_projects_run3/ftuple_helpers.py | 410 +++++++++++++++++++++++++++++ ew_projects_run3/info.yaml | 107 ++++++++ ew_projects_run3/mc/24c3/spruce.py | 87 ++++++ 4 files changed, 732 insertions(+) create mode 100644 ew_projects_run3/ftuple.py create mode 100644 ew_projects_run3/ftuple_helpers.py create mode 100644 ew_projects_run3/info.yaml create mode 100644 ew_projects_run3/mc/24c3/spruce.py diff --git a/ew_projects_run3/ftuple.py b/ew_projects_run3/ftuple.py new file mode 100644 index 0000000000..f2d4025c81 --- /dev/null +++ b/ew_projects_run3/ftuple.py @@ -0,0 +1,128 @@ +from PyConf.reading import (get_particles, get_pvs, get_rec_summary, + get_mc_particles) +from RecoConf.event_filters import require_pvs +from DaVinci import make_config, Options +from DaVinci.algorithms import create_lines_filter +from FunTuple import FunTuple_Particles as Funtuple +from FunTuple import FunTuple_MCParticles as MCFuntuple +from FunTuple import FunTuple_Event as EventFuntuple +from FunTuple import FunctorCollection +import FunTuple.functorcollections as FC +import Functors as F +from .ftuple_helpers import ( + decaytree_variables, mcdecaytree_selection_to_variables, extra_event_info, + selection_to_decay_descriptor, mcdtt_selections_to_decay_descriptor, Spec, + rec_summary_variables, selection_dependent_filtering, trkeff_probes, + decaytreefitter_variables) + +hlt1_tistos_lines = ["Hlt1SingleHighPtMuon", "Hlt1SingleHighPtMuonNoMuID"] +hlt2_tistos_lines = [ + "Hlt2QEE_SingleHighPtMuonFull", "Hlt2QEE_SingleHighPtMuonNoMuIDFull", + "Hlt2QEE_ZToMuMuFull", "Hlt2QEE_ZToMuMu_SingleNoMuIDFull" +] + + +def hlt2_decision_lines(trkeff_methods): + return hlt2_tistos_lines + [ + f"Hlt2TrackEff_ZToMuMu_{trkeff_method}_{probe}_{decision_type}" + for trkeff_method in trkeff_methods for probe in trkeff_probes + for decision_type in ["Tag", "Match"] + ] + + +def make_DTT(selection, line, pvs, spec): + dec_desc = selection_to_decay_descriptor( + trkeff_methods=spec.trkeff_methods)[selection] + data = selection_dependent_filtering( + data=get_particles(f"/Event/{spec.dataLocProcess}/{line}/Particles"), + selection=selection) + + variables = decaytree_variables( + selection=selection, pvs=pvs, data=data, spec=spec) + evtinfo = FC.EventInfo() + evtinfo += extra_event_info(spec=spec) + evtinfo += FC.SelectionInfo( + selection_type="Hlt1", trigger_lines=hlt1_tistos_lines) + + evtinfo += rec_summary_variables(rec_summary=get_rec_summary()) + evtinfo += FC.SelectionInfo( + selection_type="Hlt2", + trigger_lines=hlt2_decision_lines(spec.trkeff_methods)) + + variables["ALL"] += FC.HltTisTos( + selection_type="Hlt1", + trigger_lines=[f"{line}Decision" for line in hlt1_tistos_lines], + data=data) + + if spec.isFull: + variables["ALL"] += FC.HltTisTos( + selection_type="Hlt2", + trigger_lines=[f"{line}Decision" for line in hlt2_tistos_lines], + data=data) + + if spec.isTurCal: + dtf_variables = decaytreefitter_variables( + selection=selection, pvs=pvs, data=data) + for k in dtf_variables.keys(): + variables[k] = variables.get(k, FunctorCollection( + {})) + dtf_variables[k] + + funtuple = Funtuple( + name=selection, + tuple_name="DecayTree", + fields=dec_desc, + variables=variables, + inputs=data, + store_multiple_cand_info=True, + event_variables=evtinfo) + + return funtuple + + +def make_MCDTT(selection, spec): + dec_desc = mcdtt_selections_to_decay_descriptor[selection] + mc_particles = get_mc_particles("/Event/MC/Particles") + + variables = mcdecaytree_selection_to_variables[selection] + variables["ALL"] = FunctorCollection({"ID": F.PARTICLE_ID}) + evtinfo = extra_event_info(spec=spec) + + return MCFuntuple( + name=f"{selection}_mcdtt", + tuple_name="DecayTree", + fields=dec_desc, + variables=variables, + event_variables=evtinfo, + inputs=mc_particles, + ) + + +def make_ET(spec): + return EventFuntuple( + name="EventTuple", + tuple_name="EventTuple", + variables=extra_event_info(spec=spec)) + + +def main(options: Options, stream: str, campaign: str, polarity: str, + sample: str): + spec = Spec(stream, campaign, polarity, sample) + + algs = {} + + for selection, line in spec.selection_line_map.items(): + line_prefilter = create_lines_filter( + name=f"PreFilter_{line}", lines=[line]) + pvs = get_pvs() + algs[selection] = [ + line_prefilter, + require_pvs(pvs), + make_DTT(selection=selection, line=line, pvs=pvs, spec=spec) + ] + if spec.isMC: algs["EventTuple"] = [make_ET(spec=spec)] + if spec.isMC and spec.isFull: + for mcdtt_selection in mcdtt_selections_to_decay_descriptor.keys(): + algs[f"{mcdtt_selection}_MCDecayTree"] = [ + make_MCDTT(selection=mcdtt_selection, spec=spec) + ] + return make_config(options, algs) diff --git a/ew_projects_run3/ftuple_helpers.py b/ew_projects_run3/ftuple_helpers.py new file mode 100644 index 0000000000..89685f8139 --- /dev/null +++ b/ew_projects_run3/ftuple_helpers.py @@ -0,0 +1,410 @@ +from PyConf.reading import get_charged_protoparticles +from PyConf.Algorithms import WeightedRelTableAlg, ThOrParticleSelection +from DaVinciMCTools import MCTruthAndBkgCat +from DecayTreeFitter import DecayTreeFitter +from Hlt2Conf.lines.qee import single_high_pt_muon +from Hlt2Conf.standard_particles import make_ismuon_long_muon +from Hlt2Conf.standard_jets import make_onlytrack_particleflow, make_charged_particles +from Hlt2Conf.algorithms_thor import ParticleFilter +from GaudiKernel.SystemOfUnits import GeV +from FunTuple import FunctorCollection +import Functors as F +from enum import Enum + +_Z_decay_descriptor = { + "Z0": "^(Z0 -> mu- mu+)", + "mum": "Z0 -> ^mu- mu+", + "mup": "Z0 -> mu- ^mu+", +} +_Jpsi_decay_descriptor = { + "Jpsi": "^(J/psi(1S) -> mu- mu+)", + "mum": "J/psi(1S) -> ^mu- mu+", + "mup": "J/psi(1S) -> mu- ^mu+", +} +_Upsilon_decay_descriptor = { + "U1S": "^(Upsilon(1S) -> mu- mu+)", + "mum": "Upsilon(1S) -> ^mu- mu+", + "mup": "Upsilon(1S) -> mu- ^mu+", +} +_Wp_decay_descriptor = { + "mu": '^mu+', +} +_Wm_decay_descriptor = { + "mu": '^mu-', +} +trkeff_probes = ["mum", "mup"] + +FSR_electron_descriptor = ' {e+} {e-} {e+} {e-} ' +mcdtt_selections_to_decay_descriptor = { + "Z": { + "Z": f"^(Z0 => mu- mu+ {FSR_electron_descriptor})", + "mum": f"Z0 => ^mu- mu+ {FSR_electron_descriptor}", + "mup": f"Z0 => mu- ^mu+ {FSR_electron_descriptor}", + }, + "W": { + "W": f"^[W+ => mu+ nu_mu {FSR_electron_descriptor}]CC", + "mu": f"[W+ => ^mu+ nu_mu {FSR_electron_descriptor}]CC", + }, + "Ztau": { + "Z": + f"^(Z0 => (tau+ => mu+ nu_mu nu_tau~ {FSR_electron_descriptor}) (tau- => mu- nu_mu~ nu_tau {FSR_electron_descriptor}))", + "taup": + f"Z0 => ^(tau+ => mu+ nu_mu nu_tau~ {FSR_electron_descriptor}) (tau- => mu- nu_mu~ nu_tau {FSR_electron_descriptor})", + "mup": + f"Z0 => (tau+ => ^mu+ nu_mu nu_tau~ {FSR_electron_descriptor}) (tau- => mu- nu_mu~ nu_tau {FSR_electron_descriptor})", + "taum": + f"Z0 => (tau+ => mu+ nu_mu nu_tau~ {FSR_electron_descriptor}) ^(tau- => mu- nu_mu~ nu_tau {FSR_electron_descriptor})", + "mum": + f"Z0 => (tau+ => mu+ nu_mu nu_tau~ {FSR_electron_descriptor}) (tau- => ^mu- nu_mu~ nu_tau {FSR_electron_descriptor})", + }, + "Wtau": { + "W": + f"^[W+ => (tau+ => mu+ nu_mu nu_tau~ {FSR_electron_descriptor}) nu_tau]CC", + "tau": + f"[W+ => ^(tau+ => mu+ nu_mu nu_tau~ {FSR_electron_descriptor}) nu_tau]CC", + "mu": + f"[W+ => (tau+ => ^mu+ nu_mu nu_tau~ {FSR_electron_descriptor}) nu_tau]CC", + } +} + +_rapidity_functor = 0.5 * F.math.log((F.ENERGY + F.PZ) / (F.ENERGY - F.PZ)) +_mcdecaytree_lepton_variables = FunctorCollection({ + "PT": F.PT, + "ETA": F.ETA, + "PHI": F.PHI +}) +_mcdecaytree_boson_variables = FunctorCollection({ + "M": F.MASS, + "PT": F.PT, + "Y": _rapidity_functor +}) +mcdecaytree_selection_to_variables = { + "W": { + "mu": _mcdecaytree_lepton_variables + }, + "Wtau": { + "mu": _mcdecaytree_lepton_variables, + "tau": _mcdecaytree_lepton_variables + }, + "Z": { + "mum": _mcdecaytree_lepton_variables, + "mup": _mcdecaytree_lepton_variables, + "Z": _mcdecaytree_boson_variables, + }, + "Ztau": { + "mum": _mcdecaytree_lepton_variables, + "mup": _mcdecaytree_lepton_variables, + "taum": _mcdecaytree_lepton_variables, + "taup": _mcdecaytree_lepton_variables, + "Z": _mcdecaytree_boson_variables, + }, +} + + +def selection_to_decay_descriptor(trkeff_methods): + return { + "Z": _Z_decay_descriptor, + "ZMuID": _Z_decay_descriptor, + "Jpsi_Detached": _Jpsi_decay_descriptor, + "Jpsi_Prompt": _Jpsi_decay_descriptor, + "U1S": _Upsilon_decay_descriptor, + "Wp": _Wp_decay_descriptor, + "Wm": _Wm_decay_descriptor, + "WpNoMuID": _Wp_decay_descriptor, + "WmNoMuID": _Wm_decay_descriptor, + "ZSS": { + "Z0": "[Z0 -> mu- mu-]CC", + "mum": "[Z0 -> ^mu- mu-]CC", + "mup": "[Z0 -> mu- ^mu-]CC", + } + } | { + f"ZTrkEff_{trkeff_method}_{probe}": _Z_decay_descriptor + for trkeff_method in trkeff_methods for probe in trkeff_probes + } + + +def rec_summary_variables(rec_summary): + # as per https://gitlab.cern.ch/lhcb/Rec/-/blob/master/Rec/RecAlgs/src/RecSummaryMaker.cpp?ref_type=heads#L71 + _rec_summary_vars = [ + "nPVs", "nLongTracks", "nFTClusters", "nVPClusters", "nEcalClusters", + "hCalTot" + ] + return FunctorCollection({ + var: F.VALUE_OR(-1) @ F.RECSUMMARY_INFO(rec_summary, var) + for var in _rec_summary_vars + }) + + +def decaytree_variables(selection, pvs, spec, data): + variables = {} + variables["ALL"] = FunctorCollection({"PID": F.PARTICLE_ID}) + + muon_FC = FunctorCollection({ + "BPVIP": F.BPVIP(pvs), + "BPVIPCHI2": F.BPVIPCHI2(pvs), + "TRCHI2NDOF": F.CHI2DOF, + "PV_X": F.BPVX(pvs), + "PV_Y": F.BPVY(pvs), + "PV_Z": F.BPVZ(pvs), + "Q": F.CHARGE, + "PX": F.PX, + "PY": F.PY, + "PZ": F.PZ, + "PERR2": F.PERR2(), + "ISMUON": F.ISMUON, + "INMUON": F.INMUON, + "PIDmu": F.PID_MU, + "HCALEOP": F.VALUE_OR(0) @ F.HCALEOP, + "ECALEOP": F.VALUE_OR(0) @ F.ELECTRONSHOWEREOP, + }) + for particle in selection_to_decay_descriptor( + trkeff_methods=spec.trkeff_methods)[selection].keys(): + if "mu" not in particle: # These don't work for muons (no endvertex) + variables[particle] = FunctorCollection({ + "ENDVCHI2": + F.CHI2 @ F.ENDVERTEX, + "ENDVCHI2DOF": + F.CHI2DOF @ F.ENDVERTEX, + }) + else: + variables[particle] = muon_FC + if spec.doIsolation: + variables[particle] += _iso_variables( + data=data, pref=particle, selection=selection) + if particle == "mu": # This needs to only be Single muons (not DiMuons) + variables[particle] += _zveto_variables(data=data) + + if spec.isMC: + # Necessary to prevent duplicated algorithms with different names + unique_selection_name = selection.replace('Wp', 'W').replace('Wm', 'W') + MCTRUTH = MCTruthAndBkgCat( + data, name=f"MCTruthAndBkgCat__{unique_selection_name}") + variables["ALL"] += FunctorCollection({ + "TRUEPX": + MCTRUTH(F.PX), + "TRUEPY": + MCTRUTH(F.PY), + "TRUEPZ": + MCTRUTH(F.PZ), + "TRUEID": + F.VALUE_OR(0) @ MCTRUTH(F.PARTICLE_ID), + }) + return variables + + +def extra_event_info(spec): + """ + Defines several event-level variables for later use. + """ + return FunctorCollection({ + 'year_int': F.ALL() * 2024, + 'isMC': F.ALL() * int(spec.isMC), + 'polarity_sign': F.ALL() * spec.magpolInt + }) + + +def decaytreefitter_variables(selection, pvs, data): + v = {} + dtf__name = "DTF_AllPV" + + dtf = DecayTreeFitter( + input_particles=data, + name="__".join([dtf__name, selection]), + input_pvs=pvs, + fit_all_pvs=True) + + _dtf_FC = lambda d: FunctorCollection({ + f"_{dtf__name}__{key}": dtf(functor) + for key, functor in d.items() + }) + for muon in trkeff_probes: + v[muon] = _dtf_FC({ + "P": F.P, + "PERR2": F.PERR2(), + }) + v["Z0"] = _dtf_FC({ + "MASS": F.MASS, + "CHI2DOF": F.VALUE_OR(-999) @ F.CHI2DOF, + }) + + return v + + +def selection_dependent_filtering(data, selection): + if selection in streams_to_map()[Stream.Turbo]: + # https://gitlab.cern.ch/lhcb/Moore/-/merge_requests/3418#note_7953141 + child_pidmu_cut = lambda i: F.CHILD(i, F.PID_MU) > -10 + return ParticleFilter( + data, + F.FILTER(F.require_all(child_pidmu_cut(1), child_pidmu_cut(2))), + name=f'{selection}__pidmu_filter') + return data + + +def _iso_variables(data, pref, selection): + """ + For each candidate muon: + generate the particles within a cone with following cuts: + - radius 0.5 in (DPHI, DETA) space around signal candidate + - ~SHARE_TRACKS i.e. don't count our signal candidate + Defines: + ISO_C{PT,PX,PY} via _safe_sumcone + """ + # extract muon particlecontainer from the main decay candidate. + mu_decdesc = {"mup": "mu+", "mum": "mu-", "mu": "mu"}[pref] + isDimuon = "W" not in selection + mu_particles = _extract_muons_from_composite_candidate( + data=data, decdesc=mu_decdesc) if isDimuon else data + + with make_charged_particles.bind( + make_protoparticles=get_charged_protoparticles): + input_cands = make_onlytrack_particleflow() + alg = WeightedRelTableAlg( + ReferenceParticles=mu_particles, + InputCandidates=input_cands, + Cut=F.require_all(F.DR2 < (0.5**2), ~F.SHARE_TRACKS())) + return FunctorCollection({ + "ISO050_CPT": _safe_sumcone(alg, F.PT), + "ISO050_CPX": _safe_sumcone(alg, F.PX), + "ISO050_CPY": _safe_sumcone(alg, F.PY), + }) + + +def _zveto_variables(data): + """ + Only makes sense for W-like candidates, i.e. not Z-like. + """ + min_muon_pt = 0.1 * GeV # Just a sanity cut + input_cands = ParticleFilter( + make_ismuon_long_muon(), + F.FILTER(F.require_all(F.PT > min_muon_pt)), + name='ZVeto_muon_filter') + + alg = WeightedRelTableAlg( + ReferenceParticles=data, + InputCandidates=input_cands, + Cut=F.require_all(~F.SHARE_TRACKS())) + + zveto_muon_variables = {"PX": F.PX, "PY": F.PY, "PZ": F.PZ, "Q": F.CHARGE} + + def _zveto_muon_functor_composition(functor, relations): + return F.VALUE_OR(0) @ functor @ F.TO @ F.ENTRY_WITH_MAX_REL_VALUE_OF( + F.PT @ F.TO @ F.FORWARDARG0).bind( + F.RELATIONS.bind(F.TES(relations), F.FORWARDARGS)) + + return FunctorCollection({ + f"OTHERMUON_{var}": _zveto_muon_functor_composition( + functor=functor, relations=alg.OutputRelations) + for var, functor in zveto_muon_variables.items() + }) + + +def _extract_muons_from_composite_candidate(data, decdesc): + """ + Navigates the descendants of a candidate particle + Returns the child muons for that candidate. + """ + return ThOrParticleSelection( + InputParticles=data, + Functor=F.FILTER(F.IS_ID(decdesc)) + @ F.GET_ALL_DESCENDANTS()).OutputSelection + + +def _safe_sumcone(reltable_alg, functor): + """ + Given a relation table and a functor: + Returns SUM(functor) over all particles within that relation table. + Safe refers to giving the physical invalid value of 0 if the relation is empty (i.e. instead of NaN) + """ + return F.VALUE_OR(0) @ F.SUMCONE( + Functor=functor, Relations=reltable_alg.OutputRelations) + + +class Sample(Enum): + MC = 0 + DATA = 1 + + +class Campaign(Enum): + s24c1 = 1 + s24c2 = 2 + s24c3 = 3 + + +class Stream(Enum): + Full = 1 + Turbo = 2 + TurCal = 3 + + +class MagPol(Enum): + MagUp = 1 + MagDown = -1 + + +def _data_loc_process(stream_enum): + return { + Stream.Full: 'Spruce', + Stream.Turbo: 'HLT2', + Stream.TurCal: 'Spruce' + }[stream_enum] + + +def _do_isolation(stream_enum): + return { + Stream.Full: True, + Stream.Turbo: False, + Stream.TurCal: True + }[stream_enum] + + +def _trkeff_methods(campaign_enum): + m_withoutUT = ["VeloMuon", "SeedMuon"] + m_withUT = m_withoutUT + ["MuonUT", "Downstream"] + return { + Campaign.s24c1: m_withoutUT, + Campaign.s24c2: m_withUT, + Campaign.s24c3: m_withUT + }[campaign_enum] + + +def streams_to_map(trkeff_methods=[""]): + return { # Stream : { selection : linename } + Stream.Turbo: { + "Jpsi_Detached": "Hlt2QEE_JpsiToMuMu_Detached", + "Jpsi_Prompt": "Hlt2QEE_JpsiToMuMu_Prompt", + "U1S": "Hlt2QEE_Upsilon1SToMuMu", + }, + Stream.Full: { + "Z": "SpruceQEE_ZToMuMu", + "ZMuID": "SpruceQEE_ZToMuMu_SingleNoMuID", + "Wp": "SpruceQEE_SingleHighPtMuon", + "Wm": "SpruceQEE_SingleHighPtMuon", + "WpNoMuID": "SpruceQEE_SingleHighPtMuonNoMuID", + "WmNoMuID": "SpruceQEE_SingleHighPtMuonNoMuID", + "ZSS": "SpruceQEE_DiMuonSameSign", + }, + Stream.TurCal: { + f"ZTrkEff_{trkeff_method}_{probe}": + f"SpruceTurCalTrackEff_ZToMuMu_{trkeff_method}_{probe}_Tag" + for trkeff_method in trkeff_methods for probe in trkeff_probes + } + } + + +class Spec(): + def __init__(self, stream, campaign, magpol, sample): + stream_enum = Stream[stream] + campaign_enum = Campaign[f's{campaign}'] + magpol_enum = MagPol[magpol] + sample_enum = Sample[sample] + + self.isFull = stream_enum == Stream.Full + self.isTurCal = stream_enum == Stream.TurCal + self.isMC = sample_enum == Sample.MC + self.magpolInt = magpol_enum.value + self.trkeff_methods = _trkeff_methods(campaign_enum) + self.selection_line_map = streams_to_map( + self.trkeff_methods)[stream_enum] + self.dataLocProcess = _data_loc_process(stream_enum) + self.doIsolation = _do_isolation(stream_enum) diff --git a/ew_projects_run3/info.yaml b/ew_projects_run3/info.yaml new file mode 100644 index 0000000000..c4817d2953 --- /dev/null +++ b/ew_projects_run3/info.yaml @@ -0,0 +1,107 @@ +defaults: + inform: + - luke.grazette@cern.ch + wg: QEE + +################ +##### DATA ##### +################ + + +# https://twiki.cern.ch/twiki/bin/viewauth/LHCbInternal/OperationSummary2024 +# sprucing_campaign, moore_v, tuple_v +# 24c1 : Moore/DV latest `2024-patches` release as of 22-Apr-24 +# 24c2 : started withUT ~JuneTS : https://gitlab.cern.ch/lhcb-core/lhcbstacks/-/blob/master/data/stacks/DPA/2024.06.18.yml +# 24c3 : Started post AugMD +{%- set processing_campaigns = [ + ('24c3', '/Real Data/Sprucing24c3', 'v55r12p3', 'v64r9') +]%} + + +############## +##### MC ##### +############## + +{%- set moore_detdesc_platform = 'x86_64_v2-el9-gcc13+detdesc-opt' %} # a `v2` detdesc platform compatible with Moore release. +{%- set davinci_detdesc_platform = 'x86_64_v2-el9-clang16+detdesc-opt' %} # a `v2` detdesc platform compatible with DV release. +{%- set dddb_tag = 'dddb-20240427' %} +{%- set candidate_datasets = { + 'Turbo': [ + ('Jpsi', '24142001'), + ('U1S' , '18112001'), + ], + 'Full': [ + ('Z' , '42112001'), + ('Ztau' , '42100004'), + ('Wtau' , '42300001'), + ('W' , '42311003'), + ('DY' , '42112015'), + ('QcdBgd', '49000011'), + ('ccbar' , '49011014'), + ('bbbar' , '49011015') + ], + 'TurCal': [ + ('Z' , '42112001'), + ] +} %} +{%- set stream_variables = [ + ('Turbo', 'TurboPass'), + ('Full' , 'Spruce'), + ('TurCal', 'Spruce') +] %} +{%- set polarity_variables = [ + ('MagUp' , 'sim10-2024.Q3.4-v1.3-mu100') +] %} + + +{%- for polarity, conddb_tag in polarity_variables %} + {%- set mc_cond_path = '/MC/2024/Beam6800GeV-2024.W31.34-' + polarity + '-Nu6.3-25ns-Pythia8/Sim10d/HLT2-2024.W31.34' %} + {%- for stream, dv_input_process in stream_variables %} + {%- for eventtype, eventcode in candidate_datasets[stream] %} + {%- for campaign, _, moore_v, tuple_v in processing_campaigns %} + + +MC{{campaign}}_{{polarity}}_{{eventtype}}_{{stream}}_Spruce: + application: "Moore/{{moore_v}}@{{moore_detdesc_platform}}" + input: + bk_query: '{{mc_cond_path}}/{{eventcode}}/DST' + output: Spruce.dst + options: + entrypoint: ew_projects_run3.mc.{{campaign}}.spruce:{{stream}} + extra_options: + conddb_tag: {{conddb_tag}} + dddb_tag: {{dddb_tag}} + input_process: "Hlt2" + input_type: "ROOT" + output_type: "ROOT" + simulation: True + data_type: "Upgrade" + process: "Spruce" + +MC{{campaign}}_{{polarity}}_{{eventtype}}_{{stream}}_FTuple: + application: "DaVinci/{{tuple_v}}@{{davinci_detdesc_platform}}" + input: + job_name: MC{{campaign}}_{{polarity}}_{{eventtype}}_{{stream}}_Spruce + output: FTupleQEE.root + options: + entrypoint: ew_projects_run3.ftuple:main + extra_options: + input_raw_format: 0.5 + input_type: ROOT + simulation: True + data_type: "Upgrade" + conddb_tag: {{conddb_tag}} + dddb_tag: {{dddb_tag}} + input_process: {{dv_input_process}} + geometry_version: run3/2024.Q1.2-v00.00 + extra_args: + - -- + - {{stream}} + - {{campaign}} + - {{polarity}} + - MC + + {%- endfor %} + {%- endfor %} + {%- endfor %} +{%- endfor %} diff --git a/ew_projects_run3/mc/24c3/spruce.py b/ew_projects_run3/mc/24c3/spruce.py new file mode 100644 index 0000000000..6aab0f5465 --- /dev/null +++ b/ew_projects_run3/mc/24c3/spruce.py @@ -0,0 +1,87 @@ +from Moore import Options, run_moore +from Moore.streams import DETECTORS, Stream, Streams +from Moore.lines import PassLine, SpruceLine + +from PyConf.reading import get_particles, upfront_reconstruction as upfront_spruce +from Moore.persistence.hlt2_tistos import list_of_full_stream_lines + +from RecoConf.global_tools import stateProvider_with_simplified_geom, trackMasterExtrapolator_with_simplified_geom +from PyConf.Algorithms import VeloRetinaClusterTrackingSIMD +from RecoConf.legacy_rec_hlt1_tracking import make_VeloClusterTrackingSIMD +from RecoConf.decoders import default_VeloCluster_source + +from Hlt2Conf.lines.qee import sprucing_lines as qee_sprucing_lines +from Hlt2Conf.lines.qee.high_mass_dimuon import all_lines as qee_dimuon_lines +from Hlt2Conf.lines.qee.single_high_pt_muon import all_lines as qee_single_muon_lines +from Hlt2Conf.lines.trackeff.ZTrackEfficiency import all_lines as z_trackeff_lines + +# https://gitlab.cern.ch/lhcb-datapkg/SprucingConfig/-/blob/master/SprucingConfig/Spruce24/Sprucing_production_physics_pp_Collision24c2.py +# Removed reco binds as per https://gitlab.cern.ch/lhcb-datapkg/AnalysisProductions/-/merge_requests/1119#note_7859546 + + +def pass_through_line(name="SprucePassThrough"): + """Return a Spruce line that performs no selection but runs and persists the reconstruction + """ + return SpruceLine( + name=name, prescale=1, algs=upfront_spruce(), persistreco=True) + + +def Full(options: Options): + def _make_streams(): + lines = [builder() for builder in qee_sprucing_lines.values()] + lines += [pass_through_line(name="SprucePassThrough__exclusive")] + streams = [Stream(lines=lines, detectors=[])] + return Streams(streams=streams) + + default_VeloCluster_source.global_bind(bank_type="VPRetinaCluster") + make_VeloClusterTrackingSIMD.global_bind( + algorithm=VeloRetinaClusterTrackingSIMD) + + public_tools = [ + trackMasterExtrapolator_with_simplified_geom(), + stateProvider_with_simplified_geom() + ] + full_lines_for_TISTOS = [ + linename for line_dict in [qee_single_muon_lines, qee_dimuon_lines] + for linename in line_dict.keys() + ] + with list_of_full_stream_lines.bind(lines=full_lines_for_TISTOS): + return run_moore(options, _make_streams, public_tools=public_tools) + + +def Turbo(options: Options): + def _make_streams(): + streams = [ + Stream(lines=[PassLine(name="PassLine")], detectors=DETECTORS) + ] + return Streams(streams=streams) + + return run_moore(options, _make_streams, public_tools=[]) + + +def TurCal(options: Options): + def make_turcal_spruceline(hlt2_linename, persistreco=False, prescale=1.): + line_filter = f"{hlt2_linename}Decision" + location = f"/Event/HLT2/{hlt2_linename}/Particles" + spruce_linename = hlt2_linename.replace("Hlt2", "SpruceTurCal") + print(f"{line_filter} {location} {spruce_linename}") + hlt2_particles = get_particles(location) + turcal_spruce_line = SpruceLine( + name=spruce_linename, + hlt2_filter_code=line_filter, + algs=[hlt2_particles], + persistreco=persistreco, + prescale=prescale) + return turcal_spruce_line + + def _make_streams(): + lines = [ + make_turcal_spruceline(linename, persistreco=True) + for linename in z_trackeff_lines.keys() + ] + lines += [pass_through_line(name="SprucePassThrough__turcal")] + streams = [Stream(lines=lines, detectors=DETECTORS)] + return Streams(streams=streams) + + with list_of_full_stream_lines.bind(lines=[]): + return run_moore(options, _make_streams, public_tools=[]) -- GitLab From fe7c81e7033ed829dee517d4a1062663b688fd2c Mon Sep 17 00:00:00 2001 From: lugrazet <luke.grazette@cern.ch> Date: Thu, 12 Dec 2024 13:55:45 +0000 Subject: [PATCH 2/4] Remove sprucing and correct info.yaml accordingly --- ew_projects_run3/info.yaml | 28 ++-------- ew_projects_run3/mc/24c3/spruce.py | 87 ------------------------------ 2 files changed, 3 insertions(+), 112 deletions(-) delete mode 100644 ew_projects_run3/mc/24c3/spruce.py diff --git a/ew_projects_run3/info.yaml b/ew_projects_run3/info.yaml index c4817d2953..0a800982f9 100644 --- a/ew_projects_run3/info.yaml +++ b/ew_projects_run3/info.yaml @@ -9,12 +9,8 @@ defaults: # https://twiki.cern.ch/twiki/bin/viewauth/LHCbInternal/OperationSummary2024 -# sprucing_campaign, moore_v, tuple_v -# 24c1 : Moore/DV latest `2024-patches` release as of 22-Apr-24 -# 24c2 : started withUT ~JuneTS : https://gitlab.cern.ch/lhcb-core/lhcbstacks/-/blob/master/data/stacks/DPA/2024.06.18.yml -# 24c3 : Started post AugMD {%- set processing_campaigns = [ - ('24c3', '/Real Data/Sprucing24c3', 'v55r12p3', 'v64r9') + ('24c3', '/Real Data/Sprucing24c3', 'v64r9') ]%} @@ -22,7 +18,6 @@ defaults: ##### MC ##### ############## -{%- set moore_detdesc_platform = 'x86_64_v2-el9-gcc13+detdesc-opt' %} # a `v2` detdesc platform compatible with Moore release. {%- set davinci_detdesc_platform = 'x86_64_v2-el9-clang16+detdesc-opt' %} # a `v2` detdesc platform compatible with DV release. {%- set dddb_tag = 'dddb-20240427' %} {%- set candidate_datasets = { @@ -58,30 +53,13 @@ defaults: {%- set mc_cond_path = '/MC/2024/Beam6800GeV-2024.W31.34-' + polarity + '-Nu6.3-25ns-Pythia8/Sim10d/HLT2-2024.W31.34' %} {%- for stream, dv_input_process in stream_variables %} {%- for eventtype, eventcode in candidate_datasets[stream] %} - {%- for campaign, _, moore_v, tuple_v in processing_campaigns %} + {%- for campaign, _, tuple_v in processing_campaigns %} -MC{{campaign}}_{{polarity}}_{{eventtype}}_{{stream}}_Spruce: - application: "Moore/{{moore_v}}@{{moore_detdesc_platform}}" - input: - bk_query: '{{mc_cond_path}}/{{eventcode}}/DST' - output: Spruce.dst - options: - entrypoint: ew_projects_run3.mc.{{campaign}}.spruce:{{stream}} - extra_options: - conddb_tag: {{conddb_tag}} - dddb_tag: {{dddb_tag}} - input_process: "Hlt2" - input_type: "ROOT" - output_type: "ROOT" - simulation: True - data_type: "Upgrade" - process: "Spruce" - MC{{campaign}}_{{polarity}}_{{eventtype}}_{{stream}}_FTuple: application: "DaVinci/{{tuple_v}}@{{davinci_detdesc_platform}}" input: - job_name: MC{{campaign}}_{{polarity}}_{{eventtype}}_{{stream}}_Spruce + bk_query: '{{mc_cond_path}}/{{eventcode}}/DST' output: FTupleQEE.root options: entrypoint: ew_projects_run3.ftuple:main diff --git a/ew_projects_run3/mc/24c3/spruce.py b/ew_projects_run3/mc/24c3/spruce.py deleted file mode 100644 index 6aab0f5465..0000000000 --- a/ew_projects_run3/mc/24c3/spruce.py +++ /dev/null @@ -1,87 +0,0 @@ -from Moore import Options, run_moore -from Moore.streams import DETECTORS, Stream, Streams -from Moore.lines import PassLine, SpruceLine - -from PyConf.reading import get_particles, upfront_reconstruction as upfront_spruce -from Moore.persistence.hlt2_tistos import list_of_full_stream_lines - -from RecoConf.global_tools import stateProvider_with_simplified_geom, trackMasterExtrapolator_with_simplified_geom -from PyConf.Algorithms import VeloRetinaClusterTrackingSIMD -from RecoConf.legacy_rec_hlt1_tracking import make_VeloClusterTrackingSIMD -from RecoConf.decoders import default_VeloCluster_source - -from Hlt2Conf.lines.qee import sprucing_lines as qee_sprucing_lines -from Hlt2Conf.lines.qee.high_mass_dimuon import all_lines as qee_dimuon_lines -from Hlt2Conf.lines.qee.single_high_pt_muon import all_lines as qee_single_muon_lines -from Hlt2Conf.lines.trackeff.ZTrackEfficiency import all_lines as z_trackeff_lines - -# https://gitlab.cern.ch/lhcb-datapkg/SprucingConfig/-/blob/master/SprucingConfig/Spruce24/Sprucing_production_physics_pp_Collision24c2.py -# Removed reco binds as per https://gitlab.cern.ch/lhcb-datapkg/AnalysisProductions/-/merge_requests/1119#note_7859546 - - -def pass_through_line(name="SprucePassThrough"): - """Return a Spruce line that performs no selection but runs and persists the reconstruction - """ - return SpruceLine( - name=name, prescale=1, algs=upfront_spruce(), persistreco=True) - - -def Full(options: Options): - def _make_streams(): - lines = [builder() for builder in qee_sprucing_lines.values()] - lines += [pass_through_line(name="SprucePassThrough__exclusive")] - streams = [Stream(lines=lines, detectors=[])] - return Streams(streams=streams) - - default_VeloCluster_source.global_bind(bank_type="VPRetinaCluster") - make_VeloClusterTrackingSIMD.global_bind( - algorithm=VeloRetinaClusterTrackingSIMD) - - public_tools = [ - trackMasterExtrapolator_with_simplified_geom(), - stateProvider_with_simplified_geom() - ] - full_lines_for_TISTOS = [ - linename for line_dict in [qee_single_muon_lines, qee_dimuon_lines] - for linename in line_dict.keys() - ] - with list_of_full_stream_lines.bind(lines=full_lines_for_TISTOS): - return run_moore(options, _make_streams, public_tools=public_tools) - - -def Turbo(options: Options): - def _make_streams(): - streams = [ - Stream(lines=[PassLine(name="PassLine")], detectors=DETECTORS) - ] - return Streams(streams=streams) - - return run_moore(options, _make_streams, public_tools=[]) - - -def TurCal(options: Options): - def make_turcal_spruceline(hlt2_linename, persistreco=False, prescale=1.): - line_filter = f"{hlt2_linename}Decision" - location = f"/Event/HLT2/{hlt2_linename}/Particles" - spruce_linename = hlt2_linename.replace("Hlt2", "SpruceTurCal") - print(f"{line_filter} {location} {spruce_linename}") - hlt2_particles = get_particles(location) - turcal_spruce_line = SpruceLine( - name=spruce_linename, - hlt2_filter_code=line_filter, - algs=[hlt2_particles], - persistreco=persistreco, - prescale=prescale) - return turcal_spruce_line - - def _make_streams(): - lines = [ - make_turcal_spruceline(linename, persistreco=True) - for linename in z_trackeff_lines.keys() - ] - lines += [pass_through_line(name="SprucePassThrough__turcal")] - streams = [Stream(lines=lines, detectors=DETECTORS)] - return Streams(streams=streams) - - with list_of_full_stream_lines.bind(lines=[]): - return run_moore(options, _make_streams, public_tools=[]) -- GitLab From 6a419a6997f0c93e8125851b95ca759cdb41bbe9 Mon Sep 17 00:00:00 2001 From: lugrazet <luke.grazette@cern.ch> Date: Thu, 12 Dec 2024 13:56:37 +0000 Subject: [PATCH 3/4] 24c2 is Block 1 --- ew_projects_run3/info.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ew_projects_run3/info.yaml b/ew_projects_run3/info.yaml index 0a800982f9..ee6f33a2cc 100644 --- a/ew_projects_run3/info.yaml +++ b/ew_projects_run3/info.yaml @@ -10,7 +10,7 @@ defaults: # https://twiki.cern.ch/twiki/bin/viewauth/LHCbInternal/OperationSummary2024 {%- set processing_campaigns = [ - ('24c3', '/Real Data/Sprucing24c3', 'v64r9') + ('24c2', '/Real Data/Sprucing24c3', 'v64r9') ]%} -- GitLab From 0dca3078cf5b0f7267bb4b944fd01cce31da9a8f Mon Sep 17 00:00:00 2001 From: Luke Grazette <l.grazette@warwick.ac.uk> Date: Tue, 7 Jan 2025 14:35:30 +0100 Subject: [PATCH 4/4] Typo with processing_campaign bkk path --- ew_projects_run3/info.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ew_projects_run3/info.yaml b/ew_projects_run3/info.yaml index ee6f33a2cc..56b3a3f77e 100644 --- a/ew_projects_run3/info.yaml +++ b/ew_projects_run3/info.yaml @@ -10,7 +10,7 @@ defaults: # https://twiki.cern.ch/twiki/bin/viewauth/LHCbInternal/OperationSummary2024 {%- set processing_campaigns = [ - ('24c2', '/Real Data/Sprucing24c3', 'v64r9') + ('24c2', '/Real Data/Sprucing24c2', 'v64r9') ]%} -- GitLab