diff --git a/.gitignore b/.gitignore index 75ebcbed..f5edeb95 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ # folders -build/ build*/ log/ logs/ diff --git a/data/run3_json/Cert_Collisions2022_eraC_355862_357482_Golden.json b/data/run3_json/Cert_Collisions2022_eraC_355862_357482_Golden.json new file mode 100644 index 00000000..156b37b1 --- /dev/null +++ b/data/run3_json/Cert_Collisions2022_eraC_355862_357482_Golden.json @@ -0,0 +1,128 @@ +{ + "355862": [[121, 133]], + "355863": [[1, 14]], + "355870": [[31, 67]], + "355871": [[1, 5]], + "355872": [ + [1, 738], + [758, 995], + [997, 1217] + ], + "355892": [[14, 197]], + "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]], + "355998": [[1, 35]], + "355999": [[1, 9]], + "356004": [[1, 19]], + "356005": [[1, 187]], + "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]], + "356322": [[1, 19]], + "356323": [[1, 67], [69, 650]], + "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]], + "356810": [[44, 163]], + "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, 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]] +} \ No newline at end of file diff --git a/include/basefunctions.hxx b/include/basefunctions.hxx index 1babdbaf..d727bc11 100644 --- a/include/basefunctions.hxx +++ b/include/basefunctions.hxx @@ -211,7 +211,6 @@ ROOT::RDF::RNode getvar(ROOT::RDF::RNode df, const std::string &outputname, {position, column}); } - /// Function to writeout a variable from a RVec index to a NanoAOD column. /// /// \param df the dataframe to add the quantity to @@ -232,7 +231,6 @@ ROOT::RDF::RNode getgenvar(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, diff --git a/include/physicsobjects.hxx b/include/physicsobjects.hxx index 36a7d2cc..6e8c2434 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 @@ -243,10 +249,32 @@ ROOT::RDF::RNode CutIP(ROOT::RDF::RNode df, const std::string &eta, const float &abseta_eb_ee, const float &max_dxy_eb, const float &max_dz_eb, const float &max_dxy_ee, const float &max_dz_ee); - ROOT::RDF::RNode CutGap(ROOT::RDF::RNode df, const std::string &eta, const std::string &detasc, const std::string &maskname, const float &end_eb, const float &start_ee); +ROOT::RDF::RNode CutCBIDNoIso(ROOT::RDF::RNode df, const std::string &maskname, + const std::string &nameID, const int &IDvalue); +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, diff --git a/src/genparticles.cxx b/src/genparticles.cxx index 92eecd60..d86f9756 100644 --- a/src/genparticles.cxx +++ b/src/genparticles.cxx @@ -267,7 +267,6 @@ ROOT::RDF::RNode GenDressedLepton(ROOT::RDF::RNode df, } return idx; }; - auto lambda_idx_2 = []( const ROOT::RVec &rvec_pt, const ROOT::RVec &rvec_eta, @@ -413,6 +412,150 @@ ROOT::RDF::RNode WGenFlag(ROOT::RDF::RNode df, const std::string &outputname, namespace genmatching { + 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 + * + * @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; +} +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 { namespace tau { /** * @brief implementation of the genmatching used in tau analyses, based diff --git a/src/physicsobjects.cxx b/src/physicsobjects.cxx index 06f393d8..8abae0f0 100644 --- a/src/physicsobjects.cxx +++ b/src/physicsobjects.cxx @@ -89,7 +89,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 @@ -126,6 +126,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 /// @@ -1643,6 +1681,37 @@ ROOT::RDF::RNode AntiCutCBID(ROOT::RDF::RNode df, const std::string &maskname, const std::string &nameID, const int &IDvalue) { auto df1 = df.Define(maskname, basefunctions::FilterMaxInt(IDvalue), {nameID}); + +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; } @@ -1731,6 +1800,72 @@ ROOT::RDF::RNode CutGap(ROOT::RDF::RNode df, const std::string &eta, 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 } // end namespace physicsobject