From 5a4356d9ec7ccb9a24ac41c2330ea99c188dfabb Mon Sep 17 00:00:00 2001 From: Minseok Oh Date: Wed, 13 Jul 2022 16:08:52 +0200 Subject: [PATCH 1/5] adding gen filters --- include/genparticles.hxx | 7 +++++ src/genparticles.cxx | 60 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/include/genparticles.hxx b/include/genparticles.hxx index e77e5b59..d15539a9 100644 --- a/include/genparticles.hxx +++ b/include/genparticles.hxx @@ -10,6 +10,13 @@ #include #include +namespace genflag { +ROOT::RDF::RNode DYGenFlag(ROOT::RDF::RNode df, const std::string &outputname, + const std::string &genparticles_pdgid, + const std::string &genparticles_statusFlag, + const int &pdgId); +} + namespace genmatching { namespace tau { ROOT::RDF::RNode genmatching(ROOT::RDF::RNode df, const std::string &outputname, diff --git a/src/genparticles.cxx b/src/genparticles.cxx index 5503317b..425a8960 100644 --- a/src/genparticles.cxx +++ b/src/genparticles.cxx @@ -21,8 +21,66 @@ enum class GenMatchingCode : int { IS_FAKE = 6 }; -namespace genmatching { +enum class GenStatusFlag : int { + NONE = -1, + isPrompt = 0, + isDecayedLeptonHadron = 1, + isTauDecayProduct = 2, + isPromptTauDecayProduct = 3, + isDirectTauDecayProduct = 4, + isDirectPromptTauDecayProduct = 5, + isDirectHadronDecayProduct = 6, + isHardProcess = 7, + fromHardProcess = 8, + isHardProcessTauDecayProduct = 9, + isDirectHardProcessTauDecayProduct = 10, + fromHardProcessBeforeFSR = 11, + isFirstCopy = 12, + isLastCopy = 13, + isLastCopyBeforeFSR = 14 +}; + +namespace genflag { +/** + * @brief Function to writeout a boolean flag to select a specific DY decay mode based on gen-level PDG ID + * + * @param df The input dataframe + * @param outputname The name of the output column + * @param genparticles_pdgid The name of the column containing the pdgids of the + genparticles + * @param genparticles_statusFlag The name of the column containing the + statusFlags of the genparticles + * @param pdgId The PDG ID of decayed leptons + * @return a dataframe with the output flag as a column named outputname + */ +ROOT::RDF::RNode DYGenFlag(ROOT::RDF::RNode df, const std::string &outputname, + const std::string &genparticles_pdgid, + const std::string &genparticles_statusFlag, + const int &pdgId) { + auto lambda = [pdgId](const ROOT::RVec &pdgids, const ROOT::RVec &status_flags) { + bool found_0 = false; + bool found_1 = false; + for (unsigned int i = 0; i < pdgids.size(); i++) { + int pdgid = pdgids.at(i); + int status_flag = status_flags.at(i); + if (pdgid == pdgId && IntBits(status_flag).test((int)GenStatusFlag::isHardProcess)) { + found_0 = true; + } else if (pdgid == -pdgId && IntBits(status_flag).test((int)GenStatusFlag::isHardProcess)) { + found_1 = true; + } + if (found_0 && found_1) + break; + } + return (found_0 && found_1); + }; + auto df1 = + df.Define(outputname, lambda, + {genparticles_pdgid, genparticles_statusFlag}); + return df1; +} +} +namespace genmatching { namespace tau { /** * @brief implementation of the genmatching used in tau analyses, based From f62065554a249df3af143f45c63c581ec821eba8 Mon Sep 17 00:00:00 2001 From: Minseok Oh Date: Wed, 10 Aug 2022 22:13:39 +0200 Subject: [PATCH 2/5] producers for individual ID cuts --- include/basefunctions.hxx | 32 +++++++++++ include/physicsobjects.hxx | 32 +++++++++++ src/physicsobjects.cxx | 106 ++++++++++++++++++++++++++++++++++++- 3 files changed, 169 insertions(+), 1 deletion(-) diff --git a/include/basefunctions.hxx b/include/basefunctions.hxx index a6df136a..2786a54c 100644 --- a/include/basefunctions.hxx +++ b/include/basefunctions.hxx @@ -74,6 +74,38 @@ inline ROOT::RDF::RNode rename(ROOT::RDF::RNode df, return df.Define(outputname, [](const T &q) { return q; }, {inputname}); } +/// Function to writeout an addition of two columns +/// +/// \param df the dataframe to add the quantity to +/// \param inputname1 name of the first input column +/// \param inputname2 name of the second input column +/// \param outputname name of the new column +/// +/// \returns a dataframe with the new column + +template +inline ROOT::RDF::RNode add(ROOT::RDF::RNode df, + const std::string &inputname1, + const std::string &inputname2, + const std::string &outputname) { + return df.Define(outputname, [](const T &q1, const T &q2) { return (q1+q2); }, {inputname1, inputname2}); +} + +/// Function to writeout an absolute value of a column +/// +/// \param df the dataframe to add the quantity to +/// \param inputname name of the input column +/// \param outputname name of the new column +/// +/// \returns a dataframe with the new column + +template +inline ROOT::RDF::RNode abs(ROOT::RDF::RNode df, + const std::string &inputname, + const std::string &outputname) { + return df.Define(outputname, [](const T &q) { return abs(q); }, {inputname}); +} + /// Function to writeout a variable from a particle. The particle /// is identified via the index stored in the input vector /// diff --git a/include/physicsobjects.hxx b/include/physicsobjects.hxx index 1ba79ad6..d57f55c4 100644 --- a/include/physicsobjects.hxx +++ b/include/physicsobjects.hxx @@ -16,6 +16,12 @@ ROOT::RDF::RNode CutVariableBarrelEndcap( const float &etaBoundary, const float &lowerThresholdBarrel, const float &upperThresholdBarrel, const float &lowerThresholdEndcap, const float &upperThresholdEndcap); +ROOT::RDF::RNode CutIntVariableBarrelEndcap( + ROOT::RDF::RNode df, const std::string &maskname, + const std::string &etaColumnName, const std::string &cutVarColumnName, + const float &etaBoundary, const int &lowerThresholdBarrel, + const int &upperThresholdBarrel, const int &lowerThresholdEndcap, + const int &upperThresholdEndcap); /// Function to combine a list of masks into a single mask. This is done be /// multiplying all input masks @@ -148,6 +154,32 @@ ROOT::RDF::RNode CutCBID(ROOT::RDF::RNode df, const std::string &maskname, ROOT::RDF::RNode CutIsolation(ROOT::RDF::RNode df, const std::string &maskname, const std::string &isolationName, const float &Threshold); +ROOT::RDF::RNode CutIsolationBarrelEndcap(ROOT::RDF::RNode df, const std::string &maskname, + const std::string &etaColumnName, + const std::string &ptColumnName, + const std::string &isolationName, + const float &etaBoundary, + const float &threshold0Barrel, + const float &threshold1Barrel, + const float &threshold0Endcap, + const float &threshold1Endcap); +ROOT::RDF::RNode CutHoeBarrelEndcap(ROOT::RDF::RNode df, const std::string &maskname, + const std::string &etaColumnName, + const std::string &scEColumnName, + const std::string &rhoColumnName, + const std::string &hoeName, + const float &etaBoundary, + const float &threshold0Barrel, + const float &threshold1Barrel, + const float &threshold2Barrel, + const float &threshold0Endcap, + const float &threshold1Endcap, + const float &threshold2Endcap); +ROOT::RDF::RNode superClusterEnergy(ROOT::RDF::RNode df, + const std::string &ptColumnName, + const std::string &scEtOverPtColumnName, + const std::string &scEtaColumnName, + const std::string &outputname); } // end namespace electron } // namespace physicsobject #endif /* GUARD_PHYSICSOBJECTS_H */ \ No newline at end of file diff --git a/src/physicsobjects.cxx b/src/physicsobjects.cxx index 3546bc35..2371b281 100644 --- a/src/physicsobjects.cxx +++ b/src/physicsobjects.cxx @@ -88,7 +88,7 @@ ROOT::RDF::RNode CutDxy(ROOT::RDF::RNode df, const std::string &quantity, return df1; } /// Function to select objects with eta dependent upper and lower thesholds -/// for a given variable +/// for a given float variable /// /// \param[in] df the input dataframe /// \param[out] maskname the name of the mask to be added as column to the @@ -124,6 +124,44 @@ ROOT::RDF::RNode CutVariableBarrelEndcap( return df1; } +/// Function to select objects with eta dependent upper and lower thesholds +/// for a given integer variable +/// +/// \param[in] df the input dataframe +/// \param[out] maskname the name of the mask to be added as column to the +/// \param[in] etaColumnName name of the eta column in the NanoAOD dataframe +/// \param[in] cutVarColumnName name of the variable column to apply the +/// selection in the NanoAOD dataframe \param[in] etaBoundary boundary of +/// absolute eta for the barrel and endcap regions of the detector \param[in] +/// lowerThresholdBarrel lower threshold for the barrel \param[in] +/// upperThresholdBarrel upper threshold for the barrel \param[in] +/// lowerThresholdEndcap lower threshold for the endcap \param[in] +/// upperThresholdEndcap upper threshold for the barrel +/// +/// \return a dataframe containing the new mask + +ROOT::RDF::RNode CutIntVariableBarrelEndcap( + ROOT::RDF::RNode df, const std::string &maskname, + const std::string &etaColumnName, const std::string &cutVarColumnName, + const float &etaBoundary, const int &lowerThresholdBarrel, + const int &upperThresholdBarrel, const int &lowerThresholdEndcap, + const int &upperThresholdEndcap) { + auto lambda = [etaBoundary, lowerThresholdBarrel, upperThresholdBarrel, + lowerThresholdEndcap, + upperThresholdEndcap](const ROOT::RVec &eta, + const ROOT::RVec &variable) { + ROOT::RVec mask = + (((abs(eta) < etaBoundary) && (variable >= lowerThresholdBarrel) && + (variable < upperThresholdBarrel)) || + ((abs(eta) >= etaBoundary) && (variable >= lowerThresholdEndcap) && + (variable < upperThresholdEndcap))); + return mask; + }; + + auto df1 = df.Define(maskname, lambda, {etaColumnName, cutVarColumnName}); + return df1; +} + /// Function to take a mask and create a new one where a particle candidate is /// set to false /// @@ -928,6 +966,72 @@ ROOT::RDF::RNode CutIsolation(ROOT::RDF::RNode df, const std::string &maskname, return df1; } +ROOT::RDF::RNode CutIsolationBarrelEndcap(ROOT::RDF::RNode df, const std::string &maskname, + const std::string &etaColumnName, + const std::string &ptColumnName, + const std::string &isolationName, + const float &etaBoundary, + const float &threshold0Barrel, + const float &threshold1Barrel, + const float &threshold0Endcap, + const float &threshold1Endcap) { + auto lambda = [etaBoundary, threshold0Barrel, threshold1Barrel, threshold0Endcap, threshold1Endcap]( + const ROOT::RVec &eta, + const ROOT::RVec &pt, + const ROOT::RVec &iso) { + ROOT::RVec mask = + (((abs(eta) < etaBoundary) && (iso < threshold0Barrel + threshold1Barrel/pt)) || + ((abs(eta) >= etaBoundary) && (iso < threshold0Endcap + threshold1Endcap/pt))); + return mask; + }; + + auto df1 = df.Define(maskname, lambda, {etaColumnName, ptColumnName, isolationName}); + return df1; +} + +ROOT::RDF::RNode CutHoeBarrelEndcap(ROOT::RDF::RNode df, const std::string &maskname, + const std::string &etaColumnName, + const std::string &scEColumnName, + const std::string &rhoColumnName, + const std::string &hoeName, + const float &etaBoundary, + const float &threshold0Barrel, + const float &threshold1Barrel, + const float &threshold2Barrel, + const float &threshold0Endcap, + const float &threshold1Endcap, + const float &threshold2Endcap) { + auto lambda = [etaBoundary, threshold0Barrel, threshold1Barrel, threshold2Barrel, threshold0Endcap, threshold1Endcap, threshold2Endcap]( + const ROOT::RVec &eta, + const ROOT::RVec &scE, + const float &rho, + const ROOT::RVec &hoe) { + ROOT::RVec mask = + (((abs(eta) < etaBoundary) && (hoe < threshold0Barrel + threshold1Barrel/scE + threshold2Barrel*rho/scE)) || + ((abs(eta) >= etaBoundary) && (hoe < threshold0Endcap + threshold1Endcap/scE + threshold2Endcap*rho/scE))); + return mask; + }; + + auto df1 = df.Define(maskname, lambda, {etaColumnName, scEColumnName, rhoColumnName, hoeName}); + return df1; +} + +ROOT::RDF::RNode superClusterEnergy(ROOT::RDF::RNode df, + const std::string &ptColumnName, + const std::string &scEtOverPtColumnName, + const std::string &scEtaColumnName, + const std::string &outputname) { + return df.Define(outputname, []( + const ROOT::RVec &pt, + const ROOT::RVec &scEtOverPt, + const ROOT::RVec &scEta + ) { + return (scEtOverPt+1)*pt*cosh(scEta); + }, + {ptColumnName, scEtOverPtColumnName, scEtaColumnName} + ); +} + } // end namespace electron } // namespace physicsobject From 04f99aaeb76f6415c3c9e5b861bcea4988f6d17a Mon Sep 17 00:00:00 2001 From: Minseok Oh Date: Thu, 11 Aug 2022 01:18:38 +0200 Subject: [PATCH 3/5] Ele cut-based ID w/o iso --- code_generation/configuration.py | 2 +- include/physicsobjects.hxx | 2 ++ src/physicsobjects.cxx | 34 ++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/code_generation/configuration.py b/code_generation/configuration.py index 42b613fa..50f85319 100644 --- a/code_generation/configuration.py +++ b/code_generation/configuration.py @@ -581,7 +581,7 @@ def _remove_empty_configkeys(self, config) -> None: Returns: None """ - for key in config: + for key in list(config): if isinstance(config[key], dict): self._remove_empty_configkeys(config[key]) # special case for extended vector producers, here we can have a list, that contains empty dicts diff --git a/include/physicsobjects.hxx b/include/physicsobjects.hxx index d57f55c4..82c5f150 100644 --- a/include/physicsobjects.hxx +++ b/include/physicsobjects.hxx @@ -151,6 +151,8 @@ ROOT::RDF::RNode CutID(ROOT::RDF::RNode df, const std::string &maskname, const std::string &nameID); ROOT::RDF::RNode CutCBID(ROOT::RDF::RNode df, const std::string &maskname, const std::string &nameID, const int &IDvalue); +ROOT::RDF::RNode CutCBIDNoIso(ROOT::RDF::RNode df, const std::string &maskname, + const std::string &nameID, const int &IDvalue); ROOT::RDF::RNode CutIsolation(ROOT::RDF::RNode df, const std::string &maskname, const std::string &isolationName, const float &Threshold); diff --git a/src/physicsobjects.cxx b/src/physicsobjects.cxx index 2371b281..1b82a784 100644 --- a/src/physicsobjects.cxx +++ b/src/physicsobjects.cxx @@ -949,6 +949,40 @@ ROOT::RDF::RNode CutCBID(ROOT::RDF::RNode df, const std::string &maskname, df.Define(maskname, basefunctions::FilterMinInt(IDvalue), {nameID}); return df1; } + +ROOT::RDF::RNode CutCBIDNoIso(ROOT::RDF::RNode df, const std::string &maskname, + const std::string &nameID, const int &IDvalue) { + + // decision for each cut represented by 3 bits (0:fail, 1:veto, 2:loose, 3:medium, 4:tight) + // Electron_vidNestedWPBitmap + //0 - MinPtCut + //1 - GsfEleSCEtaMultiRangeCut + //2 - GsfEleDEtaInSeedCut + //3 - GsfEleDPhiInCut + //4 - GsfEleFull5x5SigmaIEtaIEtaCut + //5 - GsfEleHadronicOverEMEnergyScaledCut + //6 - GsfEleEInverseMinusPInverseCut + //7 - GsfEleRelPFIsoScaledCut + //8 - GsfEleConversionVetoCut + //9 - GsfEleMissingHitsCut + + auto lambda = [IDvalue](const ROOT::RVec &IDBits) { + ROOT::RVec mask = (IDBits > -1); // all true + for (unsigned idx = 0; idx < IDBits.size(); ++idx) { + int pass = 1; + for (int i(0); i<10; i++) { + if (i==7) continue; + if ( ((IDBits.at(idx) >> i*3) & 0x7) < IDvalue) pass = 0; + } + mask.at(idx) = pass; + } + return mask; + }; + + auto df1 = df.Define(maskname, lambda, {nameID}); + return df1; +} + /// Function to cut electrons based on the electron isolation using /// basefunctions::FilterMax /// From 135da705f1481ab967d0857beacf8ab8ff8d13e4 Mon Sep 17 00:00:00 2001 From: Minseok Oh Date: Tue, 30 Aug 2022 13:39:28 +0200 Subject: [PATCH 4/5] adding Run 3 lumi mask --- ...t_Collisions2022_355100_357550_Golden.json | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 data/run3_json/Cert_Collisions2022_355100_357550_Golden.json diff --git a/data/run3_json/Cert_Collisions2022_355100_357550_Golden.json b/data/run3_json/Cert_Collisions2022_355100_357550_Golden.json new file mode 100644 index 00000000..6e4995d9 --- /dev/null +++ b/data/run3_json/Cert_Collisions2022_355100_357550_Golden.json @@ -0,0 +1,141 @@ +{ + "355374": [[59, 84]], + "355381": [[1, 358]], + "355418": [[1, 41]], + "355419": [[1, 98]], + "355429": [[42, 89]], + "355435": [[42, 84]], + "355442": [[1, 22]], + "355443": [[1, 240]], + "355444": [[1, 153]], + "355445": [[1, 242]], + "355454": [[38, 118]], + "355455": [[1, 40]], + "355456": [[1, 501]], + "355559": [[1, 162]], + "355679": [[27, 85]], + "355680": [[1, 1651]], + "355768": [[82, 126]], + "355769": [[1, 541]], + "355862": [[121, 133]], + "355863": [[1, 14]], + "355870": [[31, 67]], + "355871": [[1, 5]], + "355872": [[1, 377]], + "355892": [[14, 46]], + "355912": [[43, 200]], + "355913": [[1, 106]], + "355921": [[38, 442]], + "355933": [[75, 448]], + "355942": [[24, 189], [193, 213]], + "355988": [[43, 80], [85, 90]], + "355989": [[1, 24]], + "356043": [[1, 65]], + "356071": [[37, 191]], + "356074": [[1, 26]], + "356075": [[1, 125]], + "356076": [[1, 153]], + "356077": [[1, 472]], + "356135": [[46, 71]], + "356309": [[61, 184]], + "356316": [[45, 185]], + "356321": [[44, 115]], + "356322": [[1, 19]], + "356323": [[1, 67], [69, 604]], + "356371": [[41, 50], [67, 72]], + "356375": [[35, 77], [101, 125]], + "356378": [ + [8, 208], + [210, 219], + [221, 304] + ], + "356381": [[1, 1193]], + "356383": [[1, 33]], + "356385": [[1, 30]], + "356386": [[1, 122]], + "356426": [[39, 60]], + "356428": [[1, 300]], + "356433": [[1, 310]], + "356434": [[1, 13]], + "356435": [[1, 3], [8, 8]], + "356446": [[10, 623]], + "356523": [[32, 410], [412, 898]], + "356531": [[1, 56]], + "356563": [ + [36, 113], + [117, 164], + [168, 177], + [181, 191], + [193, 194], + [199, 343] + ], + "356568": [[42, 64]], + "356569": [[1, 251]], + "356570": [[1, 98]], + "356576": [[58, 240]], + "356578": [[1, 865]], + "356580": [[1, 51]], + "356582": [[7, 104]], + "356614": [[1, 10], [16, 19], [27, 62]], + "356615": [[1, 1297]], + "356619": [[1, 173]], + "356811": [[1, 44]], + "356812": [[1, 107]], + "356813": [[1, 54]], + "356814": [ + [1, 305], + [307, 309], + [311, 366], + [368, 672] + ], + "356815": [[1, 54], [176, 219]], + "356824": [[1, 66]], + "356908": [[1, 26]], + "356919": [[29, 116]], + "356937": [[20, 138]], + "356946": [[1, 129]], + "356947": [[1, 350]], + "356948": [[1, 88]], + "356949": [[1, 94]], + "356951": [[1, 274]], + "356954": [[1, 364]], + "356955": [[1, 282], [295, 380]], + "356956": [[1, 109]], + "356968": [[81, 252]], + "356969": [[1, 236]], + "356970": [[1, 366]], + "356998": [[1, 5]], + "356999": [[1, 58]], + "357000": [[1, 50]], + "357001": [[1, 183]], + "357079": [[1, 22]], + "357080": [[1, 616]], + "357081": [[1, 759]], + "357101": [[54, 103]], + "357102": [[1, 13], [43, 134]], + "357104": [[1, 4]], + "357106": [[1, 60]], + "357112": [[1, 519]], + "357268": [[70, 143]], + "357271": [[1, 20], [22, 1570]], + "357328": [[44, 105]], + "357329": [[1, 668]], + "357330": [[1, 157]], + "357331": [[1, 23]], + "357332": [[1, 430]], + "357333": [[1, 207]], + "357401": [[48, 664]], + "357406": [[50, 174]], + "357438": [[35, 230]], + "357440": [[1, 354]], + "357441": [[1, 83]], + "357442": [[1, 1373]], + "357447": [[40, 50]], + "357472": [[34, 60]], + "357478": [[43, 50]], + "357479": [[1, 1046]], + "357482": [[1, 5], [21, 220]], + "357538": [[39, 63]], + "357542": [[1, 11], [13, 249]], + "357550": [[1, 36]] +} \ No newline at end of file From e36ef4d28adb8b2203875537a1ea330b47d3957f Mon Sep 17 00:00:00 2001 From: Jost von den Driesch Date: Wed, 16 Aug 2023 12:50:06 +0200 Subject: [PATCH 5/5] update minseok --- .gitignore | 2 +- ...isions2022_eraC_355862_357482_Golden.json} | 41 +-- include/basefunctions.hxx | 20 ++ include/genparticles.hxx | 32 ++ init.sh | 3 +- src/genparticles.cxx | 329 ++++++++++++++++++ 6 files changed, 398 insertions(+), 29 deletions(-) rename data/run3_json/{Cert_Collisions2022_355100_357550_Golden.json => Cert_Collisions2022_eraC_355862_357482_Golden.json} (79%) diff --git a/.gitignore b/.gitignore index 08e0afed..f5edeb95 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ # folders -build/ +build*/ log/ logs/ # ignore all analysis in the config folder apart from the unittest and the template diff --git a/data/run3_json/Cert_Collisions2022_355100_357550_Golden.json b/data/run3_json/Cert_Collisions2022_eraC_355862_357482_Golden.json similarity index 79% rename from data/run3_json/Cert_Collisions2022_355100_357550_Golden.json rename to data/run3_json/Cert_Collisions2022_eraC_355862_357482_Golden.json index 6e4995d9..156b37b1 100644 --- a/data/run3_json/Cert_Collisions2022_355100_357550_Golden.json +++ b/data/run3_json/Cert_Collisions2022_eraC_355862_357482_Golden.json @@ -1,28 +1,14 @@ { - "355374": [[59, 84]], - "355381": [[1, 358]], - "355418": [[1, 41]], - "355419": [[1, 98]], - "355429": [[42, 89]], - "355435": [[42, 84]], - "355442": [[1, 22]], - "355443": [[1, 240]], - "355444": [[1, 153]], - "355445": [[1, 242]], - "355454": [[38, 118]], - "355455": [[1, 40]], - "355456": [[1, 501]], - "355559": [[1, 162]], - "355679": [[27, 85]], - "355680": [[1, 1651]], - "355768": [[82, 126]], - "355769": [[1, 541]], "355862": [[121, 133]], "355863": [[1, 14]], "355870": [[31, 67]], "355871": [[1, 5]], - "355872": [[1, 377]], - "355892": [[14, 46]], + "355872": [ + [1, 738], + [758, 995], + [997, 1217] + ], + "355892": [[14, 197]], "355912": [[43, 200]], "355913": [[1, 106]], "355921": [[38, 442]], @@ -30,6 +16,10 @@ "355942": [[24, 189], [193, 213]], "355988": [[43, 80], [85, 90]], "355989": [[1, 24]], + "355998": [[1, 35]], + "355999": [[1, 9]], + "356004": [[1, 19]], + "356005": [[1, 187]], "356043": [[1, 65]], "356071": [[37, 191]], "356074": [[1, 26]], @@ -39,9 +29,8 @@ "356135": [[46, 71]], "356309": [[61, 184]], "356316": [[45, 185]], - "356321": [[44, 115]], "356322": [[1, 19]], - "356323": [[1, 67], [69, 604]], + "356323": [[1, 67], [69, 650]], "356371": [[41, 50], [67, 72]], "356375": [[35, 77], [101, 125]], "356378": [ @@ -79,6 +68,7 @@ "356614": [[1, 10], [16, 19], [27, 62]], "356615": [[1, 1297]], "356619": [[1, 173]], + "356810": [[44, 163]], "356811": [[1, 44]], "356812": [[1, 107]], "356813": [[1, 54]], @@ -99,7 +89,7 @@ "356949": [[1, 94]], "356951": [[1, 274]], "356954": [[1, 364]], - "356955": [[1, 282], [295, 380]], + "356955": [[1, 380]], "356956": [[1, 109]], "356968": [[81, 252]], "356969": [[1, 236]], @@ -134,8 +124,5 @@ "357472": [[34, 60]], "357478": [[43, 50]], "357479": [[1, 1046]], - "357482": [[1, 5], [21, 220]], - "357538": [[39, 63]], - "357542": [[1, 11], [13, 249]], - "357550": [[1, 36]] + "357482": [[1, 5], [21, 220]] } \ No newline at end of file diff --git a/include/basefunctions.hxx b/include/basefunctions.hxx index 2786a54c..5c20fabb 100644 --- a/include/basefunctions.hxx +++ b/include/basefunctions.hxx @@ -9,6 +9,7 @@ #include "utility/RooFunctorThreadsafe.hxx" #include "utility/utility.hxx" #include +#include enum Channel { MT = 0, ET = 1, TT = 2, EM = 3 }; @@ -159,6 +160,25 @@ ROOT::RDF::RNode getvar(ROOT::RDF::RNode df, const std::string &outputname, {position, column}); } +template +ROOT::RDF::RNode getvarsFromArray(ROOT::RDF::RNode df, const std::string &outputname_prefix, + const unsigned int &n, + const std::string &column) { + std::vector dfs_tmp = {df}; + for (unsigned i=0; i &col) { + return col.at(i, default_value()); + }, + {column} + ); + dfs_tmp.push_back(df_tmp); + } + + return dfs_tmp.back(); +} + /// Function to add a new quantity with a defined value /// /// \param df the dataframe to add the quantity to diff --git a/include/genparticles.hxx b/include/genparticles.hxx index d15539a9..6be5297f 100644 --- a/include/genparticles.hxx +++ b/include/genparticles.hxx @@ -10,11 +10,43 @@ #include #include +namespace genleptons { +ROOT::RDF::RNode GenLepton(ROOT::RDF::RNode df, + const std::string &genparticles_pt, + const std::string &genparticles_eta, + const std::string &genparticles_phi, + const std::string &genparticles_mass, + const std::string &genparticles_pdgid, + const std::string &genparticles_status, + const std::string &genparticles_statusFlag); +ROOT::RDF::RNode GenLeptonPreFSR(ROOT::RDF::RNode df, + const std::string &genparticles_pt, + const std::string &genparticles_eta, + const std::string &genparticles_phi, + const std::string &genparticles_mass, + const std::string &genparticles_pdgid, + const std::string &genparticles_status, + const std::string &genparticles_statusFlag); +ROOT::RDF::RNode GenDressedLepton(ROOT::RDF::RNode df, + const std::string &genparticles_pt, + const std::string &genparticles_eta, + const std::string &genparticles_phi, + const std::string &genparticles_mass, + const std::string &genparticles_pdgid, + const std::string &genparticles_hasTauAnc, + const std::string &genlep_p4_1, + const std::string &genlep_p4_2); +} + namespace genflag { ROOT::RDF::RNode DYGenFlag(ROOT::RDF::RNode df, const std::string &outputname, const std::string &genparticles_pdgid, const std::string &genparticles_statusFlag, const int &pdgId); +ROOT::RDF::RNode WGenFlag(ROOT::RDF::RNode df, const std::string &outputname, + const std::string &genparticles_pdgid, + const std::string &genparticles_statusFlag, + const int &pdgId); } namespace genmatching { diff --git a/init.sh b/init.sh index 7f3e7f1c..6faa2b15 100644 --- a/init.sh +++ b/init.sh @@ -15,6 +15,7 @@ then ### Use a more permanent LCG stack, for now LCG 102 source /cvmfs/sft.cern.ch/lcg/views/LCG_102rc1/x86_64-centos7-gcc11-opt/setup.sh else + source /cvmfs/sft.cern.ch/lcg/views/LCG_102rc1/x86_64-centos7-gcc11-opt/setup.sh echo "You are not running on CentOS7, things will propably break..." fi # add ~/.local/bin to path if it is not already there @@ -41,4 +42,4 @@ else echo "Cloning analysis whtautau into ${SCRIPT_DIR}/analysis_configurations/whtautau" git clone git@github.com:KIT-CMS/WHTauTauAnalysis-CROWN.git ${SCRIPT_DIR}/analysis_configurations/whtautau fi -fi \ No newline at end of file +fi diff --git a/src/genparticles.cxx b/src/genparticles.cxx index 425a8960..10b3eaec 100644 --- a/src/genparticles.cxx +++ b/src/genparticles.cxx @@ -2,6 +2,7 @@ #define GUARD_GENPARTICLES_H #include "../include/utility/Logger.hxx" +#include "../include/defaults.hxx" #include "ROOT/RDataFrame.hxx" #include "ROOT/RVec.hxx" #include "bitset" @@ -40,6 +41,309 @@ enum class GenStatusFlag : int { isLastCopyBeforeFSR = 14 }; +namespace genleptons { +ROOT::RDF::RNode GenLepton(ROOT::RDF::RNode df, + const std::string &genparticles_pt, + const std::string &genparticles_eta, + const std::string &genparticles_phi, + const std::string &genparticles_mass, + const std::string &genparticles_pdgid, + const std::string &genparticles_status, + const std::string &genparticles_statusFlag) { + + auto lambda_idx_1 = []( + const ROOT::RVec &rvec_pdgId, + const ROOT::RVec &rvec_status, + const ROOT::RVec &rvec_status_flag) { + int idx = -99; + for (unsigned int i = 0; i < rvec_pdgId.size(); i++) { + int pdgid = rvec_pdgId.at(i); + int status = rvec_status.at(i); + int status_flag = rvec_status_flag.at(i); + if ((pdgid == 11 || pdgid == 13) && status == 1 && + IntBits(status_flag).test((int)GenStatusFlag::fromHardProcess) && + IntBits(status_flag).test((int)GenStatusFlag::isPrompt) && + !IntBits(status_flag).test((int)GenStatusFlag::isTauDecayProduct)) { + if (idx > -1) { + Logger::get("GenLepton")->critical("ERROR: more than 1 final state lepton with pdgId {}, prev idx {}, new idx {}", pdgid, idx, i); + return -99; + } + idx = i; + } + } + return idx; + }; + + auto lambda_idx_2 = []( + const ROOT::RVec &rvec_pdgId, + const ROOT::RVec &rvec_status, + const ROOT::RVec &rvec_status_flag) { + int idx = -99; + for (unsigned int i = 0; i < rvec_pdgId.size(); i++) { + int pdgid = rvec_pdgId.at(i); + int status = rvec_status.at(i); + int status_flag = rvec_status_flag.at(i); + if ((pdgid == -11 || pdgid == -13) && status == 1 && + IntBits(status_flag).test((int)GenStatusFlag::fromHardProcess) && + IntBits(status_flag).test((int)GenStatusFlag::isPrompt) && + !IntBits(status_flag).test((int)GenStatusFlag::isTauDecayProduct)) { + if (idx > -1) { + Logger::get("GenLepton")->critical("ERROR: more than 1 final state lepton with pdgId {}, prev idx {}, new idx {}", pdgid, idx, i); + return -99; + } + idx = i; + } + } + return idx; + }; + + auto lambda_float = [](const int &idx, const ROOT::RVec &col) { + return col.at(idx, default_float); + }; + auto lambda_int = [](const int &idx, const ROOT::RVec &col) { + return col.at(idx, default_int); + }; + + auto lambd_p4 = [](const float &pt, const float &eta, const float &phi, const float &mass) { + ROOT::Math::PtEtaPhiMVector p4; + if (pt > 0.) { + p4 = ROOT::Math::PtEtaPhiMVector(pt, eta, phi, mass); + } else { + p4 = ROOT::Math::PtEtaPhiMVector( + default_float, default_float, + default_float, default_float + ); + } + return p4; + }; + + auto df1 = df.Define("genlep_idx_1", lambda_idx_1, {genparticles_pdgid, genparticles_status, genparticles_statusFlag}); + auto df2 = df1.Define("genlep_idx_2", lambda_idx_2, {genparticles_pdgid, genparticles_status, genparticles_statusFlag}); + auto df3 = df2.Define("genlep_pt_1", lambda_float, {"genlep_idx_1", genparticles_pt}); + auto df4 = df3.Define("genlep_eta_1", lambda_float, {"genlep_idx_1", genparticles_eta}); + auto df5 = df4.Define("genlep_phi_1", lambda_float, {"genlep_idx_1", genparticles_phi}); + auto df6 = df5.Define("genlep_mass_1", lambda_float, {"genlep_idx_1", genparticles_mass}); + auto df7 = df6.Define("genlep_pdgId_1", lambda_int, {"genlep_idx_1", genparticles_pdgid}); + auto df8 = df7.Define("genlep_pt_2", lambda_float, {"genlep_idx_2", genparticles_pt}); + auto df9 = df8.Define("genlep_eta_2", lambda_float, {"genlep_idx_2", genparticles_eta}); + auto df10 = df9.Define("genlep_phi_2", lambda_float, {"genlep_idx_2", genparticles_phi}); + auto df11 = df10.Define("genlep_mass_2", lambda_float, {"genlep_idx_2", genparticles_mass}); + auto df12 = df11.Define("genlep_pdgId_2", lambda_int, {"genlep_idx_2", genparticles_pdgid}); + auto df13 = df12.Define("genlep_p4_1", lambd_p4, {"genlep_pt_1", "genlep_eta_1", "genlep_phi_1", "genlep_mass_1"}); + auto df14 = df13.Define("genlep_p4_2", lambd_p4, {"genlep_pt_2", "genlep_eta_2", "genlep_phi_2", "genlep_mass_2"}); + + return df14; +} + +ROOT::RDF::RNode GenLeptonPreFSR(ROOT::RDF::RNode df, + const std::string &genparticles_pt, + const std::string &genparticles_eta, + const std::string &genparticles_phi, + const std::string &genparticles_mass, + const std::string &genparticles_pdgid, + const std::string &genparticles_status, + const std::string &genparticles_statusFlag) { + + auto lambda_idx_1 = []( + const ROOT::RVec &rvec_pdgId, + const ROOT::RVec &rvec_status, + const ROOT::RVec &rvec_status_flag) { + int idx = -99; + for (unsigned int i = 0; i < rvec_pdgId.size(); i++) { + int pdgid = rvec_pdgId.at(i); + int status = rvec_status.at(i); + int status_flag = rvec_status_flag.at(i); + if ((pdgid == 11 || pdgid == 13) && + IntBits(status_flag).test((int)GenStatusFlag::isHardProcess) && + IntBits(status_flag).test((int)GenStatusFlag::isPrompt) && + !IntBits(status_flag).test((int)GenStatusFlag::isTauDecayProduct)) { + if (idx > -1) { + Logger::get("GenLepton")->critical("ERROR: more than 1 final state lepton with pdgId {}, prev idx {}, new idx {}", pdgid, idx, i); + return -99; + } + idx = i; + } + } + return idx; + }; + + auto lambda_idx_2 = []( + const ROOT::RVec &rvec_pdgId, + const ROOT::RVec &rvec_status, + const ROOT::RVec &rvec_status_flag) { + int idx = -99; + for (unsigned int i = 0; i < rvec_pdgId.size(); i++) { + int pdgid = rvec_pdgId.at(i); + int status = rvec_status.at(i); + int status_flag = rvec_status_flag.at(i); + if ((pdgid == -11 || pdgid == -13) && + IntBits(status_flag).test((int)GenStatusFlag::isHardProcess) && + IntBits(status_flag).test((int)GenStatusFlag::isPrompt) && + !IntBits(status_flag).test((int)GenStatusFlag::isTauDecayProduct)) { + if (idx > -1) { + Logger::get("GenLepton")->critical("ERROR: more than 1 final state lepton with pdgId {}, prev idx {}, new idx {}", pdgid, idx, i); + return -99; + } + idx = i; + } + } + return idx; + }; + + auto lambda_float = [](const int &idx, const ROOT::RVec &col) { + return col.at(idx, default_float); + }; + auto lambda_int = [](const int &idx, const ROOT::RVec &col) { + return col.at(idx, default_int); + }; + + auto lambd_p4 = [](const float &pt, const float &eta, const float &phi, const float &mass) { + ROOT::Math::PtEtaPhiMVector p4; + if (pt > 0.) { + p4 = ROOT::Math::PtEtaPhiMVector(pt, eta, phi, mass); + } else { + p4 = ROOT::Math::PtEtaPhiMVector( + default_float, default_float, + default_float, default_float + ); + } + return p4; + }; + + auto df1 = df.Define("genlepPreFSR_idx_1", lambda_idx_1, {genparticles_pdgid, genparticles_status, genparticles_statusFlag}); + auto df2 = df1.Define("genlepPreFSR_idx_2", lambda_idx_2, {genparticles_pdgid, genparticles_status, genparticles_statusFlag}); + auto df3 = df2.Define("genlepPreFSR_pt_1", lambda_float, {"genlepPreFSR_idx_1", genparticles_pt}); + auto df4 = df3.Define("genlepPreFSR_eta_1", lambda_float, {"genlepPreFSR_idx_1", genparticles_eta}); + auto df5 = df4.Define("genlepPreFSR_phi_1", lambda_float, {"genlepPreFSR_idx_1", genparticles_phi}); + auto df6 = df5.Define("genlepPreFSR_mass_1", lambda_float, {"genlepPreFSR_idx_1", genparticles_mass}); + auto df7 = df6.Define("genlepPreFSR_pdgId_1", lambda_int, {"genlepPreFSR_idx_1", genparticles_pdgid}); + auto df8 = df7.Define("genlepPreFSR_pt_2", lambda_float, {"genlepPreFSR_idx_2", genparticles_pt}); + auto df9 = df8.Define("genlepPreFSR_eta_2", lambda_float, {"genlepPreFSR_idx_2", genparticles_eta}); + auto df10 = df9.Define("genlepPreFSR_phi_2", lambda_float, {"genlepPreFSR_idx_2", genparticles_phi}); + auto df11 = df10.Define("genlepPreFSR_mass_2", lambda_float, {"genlepPreFSR_idx_2", genparticles_mass}); + auto df12 = df11.Define("genlepPreFSR_pdgId_2", lambda_int, {"genlepPreFSR_idx_2", genparticles_pdgid}); + auto df13 = df12.Define("genlepPreFSR_p4_1", lambd_p4, {"genlepPreFSR_pt_1", "genlepPreFSR_eta_1", "genlepPreFSR_phi_1", "genlepPreFSR_mass_1"}); + auto df14 = df13.Define("genlepPreFSR_p4_2", lambd_p4, {"genlepPreFSR_pt_2", "genlepPreFSR_eta_2", "genlepPreFSR_phi_2", "genlepPreFSR_mass_2"}); + + return df14; +} + +ROOT::RDF::RNode GenDressedLepton(ROOT::RDF::RNode df, + const std::string &genparticles_pt, + const std::string &genparticles_eta, + const std::string &genparticles_phi, + const std::string &genparticles_mass, + const std::string &genparticles_pdgid, + const std::string &genparticles_hasTauAnc, + const std::string &genlep_p4_1, + const std::string &genlep_p4_2) { + + auto lambda_idx_1 = []( + const ROOT::RVec &rvec_pt, + const ROOT::RVec &rvec_eta, + const ROOT::RVec &rvec_phi, + const ROOT::RVec &rvec_mass, + const ROOT::RVec &rvec_pdgId, + const ROOT::RVec &rvec_hasTauAnc, + ROOT::Math::PtEtaPhiMVector &genlep_p4) { + int idx = -99; + float dR_min = 0.3; + + if (genlep_p4.pt() < 0.) { + return idx; + } + + for (unsigned int i = 0; i < rvec_pt.size(); i++) { + ROOT::Math::PtEtaPhiMVector p4 = ROOT::Math::PtEtaPhiMVector(rvec_pt.at(i), rvec_eta.at(i), rvec_phi.at(i), rvec_mass.at(i)); + int pdgid = rvec_pdgId.at(i); + bool hasTauAnc = rvec_hasTauAnc.at(i); + float dR_tmp = (float)ROOT::Math::VectorUtil::DeltaR(p4, genlep_p4); + if ((pdgid == 11 || pdgid == 13) && !hasTauAnc && (dR_tmp < dR_min)) { + idx = i; + dR_min = dR_tmp; + } + } + return idx; + }; + + auto lambda_idx_2 = []( + const ROOT::RVec &rvec_pt, + const ROOT::RVec &rvec_eta, + const ROOT::RVec &rvec_phi, + const ROOT::RVec &rvec_mass, + const ROOT::RVec &rvec_pdgId, + const ROOT::RVec &rvec_hasTauAnc, + ROOT::Math::PtEtaPhiMVector &genlep_p4) { + int idx = -99; + float dR_min = 0.3; + + if (genlep_p4.pt() < 0.) { + return idx; + } + + for (unsigned int i = 0; i < rvec_pt.size(); i++) { + ROOT::Math::PtEtaPhiMVector p4 = ROOT::Math::PtEtaPhiMVector(rvec_pt.at(i), rvec_eta.at(i), rvec_phi.at(i), rvec_mass.at(i)); + int pdgid = rvec_pdgId.at(i); + bool hasTauAnc = rvec_hasTauAnc.at(i); + float dR_tmp = (float)ROOT::Math::VectorUtil::DeltaR(p4, genlep_p4); + if ((pdgid == -11 || pdgid == -13) && !hasTauAnc && (dR_tmp < dR_min)) { + idx = i; + dR_min = dR_tmp; + } + } + return idx; + }; + + auto lambda_float = [](const int &idx, const ROOT::RVec &col) { + return col.at(idx, default_float); + }; + auto lambda_int = [](const int &idx, const ROOT::RVec &col) { + return col.at(idx, default_int); + }; + + auto lambd_p4 = [](const float &pt, const float &eta, const float &phi, const float &mass) { + ROOT::Math::PtEtaPhiMVector p4; + if (pt > 0.) { + p4 = ROOT::Math::PtEtaPhiMVector(pt, eta, phi, mass); + } else { + p4 = ROOT::Math::PtEtaPhiMVector( + default_float, default_float, + default_float, default_float + ); + } + return p4; + }; + + auto lambd_dR = [](ROOT::Math::PtEtaPhiMVector &genlep_p4, ROOT::Math::PtEtaPhiMVector &genDressed_p4) { + if (genlep_p4.pt() < 0. || genDressed_p4.pt() < 0.) { + return (float)99.; + } + + return (float)ROOT::Math::VectorUtil::DeltaR(genDressed_p4, genlep_p4); + }; + + auto df1 = df.Define("genDressed_idx_1", lambda_idx_1, {genparticles_pt, genparticles_eta, genparticles_phi, genparticles_mass, genparticles_pdgid, genparticles_hasTauAnc, genlep_p4_1}); + auto df2 = df1.Define("genDressed_idx_2", lambda_idx_2, {genparticles_pt, genparticles_eta, genparticles_phi, genparticles_mass, genparticles_pdgid, genparticles_hasTauAnc, genlep_p4_2}); + auto df3 = df2.Define("genDressed_pt_1", lambda_float, {"genDressed_idx_1", genparticles_pt}); + auto df4 = df3.Define("genDressed_eta_1", lambda_float, {"genDressed_idx_1", genparticles_eta}); + auto df5 = df4.Define("genDressed_phi_1", lambda_float, {"genDressed_idx_1", genparticles_phi}); + auto df6 = df5.Define("genDressed_mass_1", lambda_float, {"genDressed_idx_1", genparticles_mass}); + auto df7 = df6.Define("genDressed_pdgId_1", lambda_int, {"genDressed_idx_1", genparticles_pdgid}); + auto df8 = df7.Define("genDressed_pt_2", lambda_float, {"genDressed_idx_2", genparticles_pt}); + auto df9 = df8.Define("genDressed_eta_2", lambda_float, {"genDressed_idx_2", genparticles_eta}); + auto df10 = df9.Define("genDressed_phi_2", lambda_float, {"genDressed_idx_2", genparticles_phi}); + auto df11 = df10.Define("genDressed_mass_2", lambda_float, {"genDressed_idx_2", genparticles_mass}); + auto df12 = df11.Define("genDressed_pdgId_2", lambda_int, {"genDressed_idx_2", genparticles_pdgid}); + auto df13 = df12.Define("genDressed_p4_1", lambd_p4, {"genDressed_pt_1", "genDressed_eta_1", "genDressed_phi_1", "genDressed_mass_1"}); + auto df14 = df13.Define("genDressed_p4_2", lambd_p4, {"genDressed_pt_2", "genDressed_eta_2", "genDressed_phi_2", "genDressed_mass_2"}); + auto df15 = df14.Define("genDressed_dR_1", lambd_dR, {genlep_p4_1, "genDressed_p4_1"}); + auto df16 = df15.Define("genDressed_dR_2", lambd_dR, {genlep_p4_2, "genDressed_p4_2"}); + + return df16; +} + +} + namespace genflag { /** * @brief Function to writeout a boolean flag to select a specific DY decay mode based on gen-level PDG ID @@ -78,6 +382,31 @@ ROOT::RDF::RNode DYGenFlag(ROOT::RDF::RNode df, const std::string &outputname, {genparticles_pdgid, genparticles_statusFlag}); return df1; } +ROOT::RDF::RNode WGenFlag(ROOT::RDF::RNode df, const std::string &outputname, + const std::string &genparticles_pdgid, + const std::string &genparticles_statusFlag, + const int &pdgId) { + auto lambda = [pdgId](const ROOT::RVec &pdgids, const ROOT::RVec &status_flags) { + bool found_0 = false; + bool found_1 = false; + for (unsigned int i = 0; i < pdgids.size(); i++) { + int pdgid = pdgids.at(i); + int status_flag = status_flags.at(i); + if (pdgid == pdgId && IntBits(status_flag).test((int)GenStatusFlag::isHardProcess)) { + found_0 = true; + } else if (pdgid == -pdgId && IntBits(status_flag).test((int)GenStatusFlag::isHardProcess)) { + found_1 = true; + } + if (found_0 || found_1) + break; + } + return (found_0 || found_1); + }; + auto df1 = + df.Define(outputname, lambda, + {genparticles_pdgid, genparticles_statusFlag}); + return df1; +} } namespace genmatching {