diff --git a/.clang-format b/.clang-format index c5979d77ba1..33e5d4f9d0c 100644 --- a/.clang-format +++ b/.clang-format @@ -39,7 +39,60 @@ PenaltyBreakFirstLessLess: 120 PenaltyBreakString: 1000 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 200 -SortIncludes: false +SortIncludes: CaseSensitive +IncludeBlocks: Regroup +IncludeCategories: + # O2Physics, PWG + - Regex: ^(<|")PWG[A-Z]{2}/.*\.h + Priority: 2 + CaseSensitive: true + # O2Physics, non-PWG + - Regex: ^(<|")(Common|ALICE3|DPG|EventFiltering|Tools|Tutorials)/.*\.h + Priority: 3 + CaseSensitive: true + # O2 + - Regex: ^(<|")(Algorithm|CCDB|Common[A-Z]|DataFormats|DCAFitter|Detectors|EMCAL|Field|Framework|FT0|FV0|GlobalTracking|ITS|MathUtils|MFT|MCH|MID|PHOS|PID|ReconstructionDataFormats|SimulationDataFormat|TOF|TPC|ZDC).*/.*\.h + Priority: 4 + CaseSensitive: true + # ROOT + - Regex: ^(<|")(T[A-Z]|Math/|Roo[A-Z])[[:alnum:]/]+\.h + Priority: 5 + CaseSensitive: true + # known third-party: KFParticle + - Regex: ^(<|")KF[A-Z][[:alnum:]]+\.h + Priority: 6 + CaseSensitive: true + # known third-party: FastJet + - Regex: ^(<|")fastjet/ + Priority: 6 + CaseSensitive: true + # known third-party: ONNX runtime + - Regex: ^(<|")onnxruntime + Priority: 6 + CaseSensitive: true + # incomplete path to DataModel + - Regex: ^(<|").*DataModel/ + Priority: 1 + CaseSensitive: true + # other third-party + - Regex: ^(<|")([[:alnum:]_]+/)+[[:alnum:]_]+\.h + Priority: 6 + CaseSensitive: true + # other local-looking file + - Regex: ^".*\. + Priority: 1 + CaseSensitive: true + # C system + - Regex: ^(<|")[[:lower:]_]+\.h(>|") + Priority: 102 + CaseSensitive: true + # C++ system + - Regex: ^(<|")[[:lower:]_/]+(>|") + Priority: 101 + CaseSensitive: true + # rest + - Regex: .* + Priority: 100 SpaceBeforeAssignmentOperators: true SpaceBeforeParens: ControlStatements SpaceInEmptyParentheses: false diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dd9ef707b95..ebff84266f2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,10 +7,10 @@ repos: - id: trailing-whitespace - id: end-of-file-fixer - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v18.1.3 # clang-format version + rev: v20.1.5 # clang-format version hooks: - id: clang-format - repo: https://github.com/cpplint/cpplint - rev: 2.0.0 + rev: 2.0.2 hooks: - id: cpplint diff --git a/ALICE3/Core/DelphesO2LutWriter.cxx b/ALICE3/Core/DelphesO2LutWriter.cxx index 6f079c7ece1..41a307c8377 100644 --- a/ALICE3/Core/DelphesO2LutWriter.cxx +++ b/ALICE3/Core/DelphesO2LutWriter.cxx @@ -19,19 +19,22 @@ /// @email: preghenella@bo.infn.it /// -#include +#include "ALICE3/Core/DelphesO2LutWriter.h" #include "ALICE3/Core/DelphesO2TrackSmearer.h" -#include "ALICE3/Core/DelphesO2LutWriter.h" -#include "iostream" -#include "TMatrixD.h" -#include "TVectorD.h" -#include "TMatrixDSymEigen.h" -#include "TDatabasePDG.h" -#include "TLorentzVector.h" #include "ALICE3/Core/FastTracker.h" #include "ALICE3/Core/TrackUtilities.h" +#include "TAxis.h" +#include "TDatabasePDG.h" +#include "TLorentzVector.h" +#include "TMatrixD.h" +#include "TMatrixDSymEigen.h" +#include "TVectorD.h" + +#include +#include + // #define USE_FWD_PARAM #ifdef USE_FWD_PARAM #include "fwdRes.C" @@ -55,7 +58,8 @@ bool DelphesO2LutWriter::fatSolve(lutEntry_t& lutEntry, const float mass, int itof, int otof, - int q) + int q, + const float nch) { lutEntry.valid = false; @@ -63,9 +67,9 @@ bool DelphesO2LutWriter::fatSolve(lutEntry_t& lutEntry, tlv.SetPtEtaPhiM(pt, eta, 0., mass); o2::track::TrackParCov trkIn; o2::upgrade::convertTLorentzVectorToO2Track(q, tlv, {0., 0., 0.}, trkIn); - o2::track::TrackParCov trkOut; - if (fat.FastTrack(trkIn, trkOut, 1) < 0) { + const int status = fat.FastTrack(trkIn, trkOut, nch); + if (status <= 0) { Printf(" --- fatSolve: FastTrack failed --- \n"); tlv.Print(); return false; @@ -234,6 +238,9 @@ void DelphesO2LutWriter::lutWrite(const char* filename, int pdg, float field, in lutEntry_t lutEntry; // write entries + int nCalls = 0; + int successfullCalls = 0; + int failedCalls = 0; for (int inch = 0; inch < nnch; ++inch) { Printf(" --- writing nch = %d/%d", inch, nnch); auto nch = lutHeader.nchmap.eval(inch); @@ -242,6 +249,7 @@ void DelphesO2LutWriter::lutWrite(const char* filename, int pdg, float field, in for (int irad = 0; irad < nrad; ++irad) { Printf(" --- writing irad = %d/%d", irad, nrad); for (int ieta = 0; ieta < neta; ++ieta) { + nCalls++; Printf(" --- writing ieta = %d/%d", ieta, neta); auto eta = lutHeader.etamap.eval(ieta); lutEntry.eta = lutHeader.etamap.eval(ieta); @@ -252,6 +260,7 @@ void DelphesO2LutWriter::lutWrite(const char* filename, int pdg, float field, in if (std::fabs(eta) <= etaMaxBarrel) { // full lever arm ends at etaMaxBarrel Printf("Solving in the barrel"); // printf(" --- fatSolve: pt = %f, eta = %f, mass = %f, field=%f \n", lutEntry.pt, lutEntry.eta, lutHeader.mass, lutHeader.field); + successfullCalls++; if (!fatSolve(lutEntry, lutEntry.pt, lutEntry.eta, lutHeader.mass, itof, otof, q)) { // printf(" --- fatSolve: error \n"); lutEntry.valid = false; @@ -260,6 +269,8 @@ void DelphesO2LutWriter::lutWrite(const char* filename, int pdg, float field, in for (int i = 0; i < 15; ++i) { lutEntry.covm[i] = 0.; } + successfullCalls--; + failedCalls++; } } else { Printf("Solving outside the barrel"); @@ -267,6 +278,7 @@ void DelphesO2LutWriter::lutWrite(const char* filename, int pdg, float field, in lutEntry.eff = 1.; lutEntry.eff2 = 1.; bool retval = true; + successfullCalls++; if (useFlatDipole) { // Using the parametrization at the border of the barrel retval = fatSolve(lutEntry, lutEntry.pt, etaMaxBarrel, lutHeader.mass, itof, otof, q); } else if (usePara) { @@ -288,6 +300,8 @@ void DelphesO2LutWriter::lutWrite(const char* filename, int pdg, float field, in for (int i = 0; i < 15; ++i) { lutEntry.covm[i] = 0.; } + successfullCalls--; + failedCalls++; } } Printf("Diagonalizing"); @@ -298,6 +312,8 @@ void DelphesO2LutWriter::lutWrite(const char* filename, int pdg, float field, in } } } + Printf(" --- finished writing LUT file %s", filename); + Printf(" --- successfull calls: %d/%d, failed calls: %d/%d", successfullCalls, nCalls, failedCalls, nCalls); lutFile.close(); } @@ -331,10 +347,13 @@ void DelphesO2LutWriter::diagonalise(lutEntry_t& lutEntry) TGraph* DelphesO2LutWriter::lutRead(const char* filename, int pdg, int what, int vs, float nch, float radius, float eta, float pt) { + Printf(" --- reading LUT file %s", filename); + // vs static const int kNch = 0; static const int kEta = 1; static const int kPt = 2; + // what static const int kEfficiency = 0; static const int kEfficiency2 = 1; static const int kEfficiencyInnerTOF = 2; @@ -360,6 +379,58 @@ TGraph* DelphesO2LutWriter::lutRead(const char* filename, int pdg, int what, int } auto nbins = lutMap.nbins; auto g = new TGraph(); + g->SetName(Form("lut_%s_%d_vs_%d_what_%d", filename, pdg, vs, what)); + g->SetTitle(Form("LUT for %s, pdg %d, vs %d, what %d", filename, pdg, vs, what)); + switch (vs) { + case kNch: + Printf(" --- vs = kNch"); + g->GetXaxis()->SetTitle("Nch"); + break; + case kEta: + Printf(" --- vs = kEta"); + g->GetXaxis()->SetTitle("#eta"); + break; + case kPt: + Printf(" --- vs = kPt"); + g->GetXaxis()->SetTitle("p_{T} (GeV/c)"); + break; + default: + Printf(" --- error: unknown vs %d", vs); + return nullptr; + } + switch (what) { + case kEfficiency: + Printf(" --- what = kEfficiency"); + g->GetYaxis()->SetTitle("Efficiency (%)"); + break; + case kEfficiency2: + Printf(" --- what = kEfficiency2"); + g->GetYaxis()->SetTitle("Efficiency2 (%)"); + break; + case kEfficiencyInnerTOF: + Printf(" --- what = kEfficiencyInnerTOF"); + g->GetYaxis()->SetTitle("Inner TOF Efficiency (%)"); + break; + case kEfficiencyOuterTOF: + Printf(" --- what = kEfficiencyOuterTOF"); + g->GetYaxis()->SetTitle("Outer TOF Efficiency (%)"); + break; + case kPtResolution: + Printf(" --- what = kPtResolution"); + g->GetYaxis()->SetTitle("p_{T} Resolution (%)"); + break; + case kRPhiResolution: + Printf(" --- what = kRPhiResolution"); + g->GetYaxis()->SetTitle("R#phi Resolution (#mum)"); + break; + case kZResolution: + Printf(" --- what = kZResolution"); + g->GetYaxis()->SetTitle("Z Resolution (#mum)"); + break; + default: + Printf(" --- error: unknown what %d", what); + return nullptr; + } bool canBeInvalid = true; for (int i = 0; i < nbins; ++i) { diff --git a/ALICE3/Core/DelphesO2LutWriter.h b/ALICE3/Core/DelphesO2LutWriter.h index e4b979a46cd..25faf7f382c 100644 --- a/ALICE3/Core/DelphesO2LutWriter.h +++ b/ALICE3/Core/DelphesO2LutWriter.h @@ -55,7 +55,8 @@ class DelphesO2LutWriter const float mass = 0.13957000, int itof = 0, int otof = 0, - int q = 1); + int q = 1, + const float nch = 1); bool fwdSolve(float* covm, float pt = 0.1, float eta = 0.0, float mass = 0.13957000); bool fwdPara(lutEntry_t& lutEntry, float pt = 0.1, float eta = 0.0, float mass = 0.13957000, float Bfield = 0.5); void lutWrite(const char* filename = "lutCovm.dat", int pdg = 211, float field = 0.2, int itof = 0, int otof = 0); diff --git a/ALICE3/Core/DetLayer.cxx b/ALICE3/Core/DetLayer.cxx index 392356b1e5a..fa49e4d811e 100644 --- a/ALICE3/Core/DetLayer.cxx +++ b/ALICE3/Core/DetLayer.cxx @@ -17,3 +17,75 @@ /// #include "DetLayer.h" + +#include +#include + +namespace o2::fastsim +{ + +// Parametric constructor +DetLayer::DetLayer(const TString& name_, + float r_, + float z_, + float x0_, + float xrho_, + float resRPhi_, + float resZ_, + float eff_, + int type_) + : name(name_), + r(r_), + z(z_), + x0(x0_), + xrho(xrho_), + resRPhi(resRPhi_), + resZ(resZ_), + eff(eff_), + type(type_) +{ +} + +DetLayer::DetLayer(const DetLayer& other) + : name(other.name), r(other.r), z(other.z), x0(other.x0), xrho(other.xrho), resRPhi(other.resRPhi), resZ(other.resZ), eff(other.eff), type(other.type) +{ +} + +std::string DetLayer::toString() const +{ + std::string out = ""; + out.append("DetLayer: "); + out.append(name.Data()); + out.append(" | r: "); + out.append(std::to_string(r)); + out.append(" cm | z: "); + out.append(std::to_string(z)); + out.append(" cm | x0: "); + out.append(std::to_string(x0)); + out.append(" cm | xrho: "); + out.append(std::to_string(xrho)); + out.append(" g/cm^3 | resRPhi: "); + out.append(std::to_string(resRPhi)); + out.append(" cm | resZ: "); + out.append(std::to_string(resZ)); + out.append(" cm | eff: "); + out.append(std::to_string(eff)); + out.append(" | type: "); + switch (type) { + case layerInert: + out.append("Inert"); + break; + case layerSilicon: + out.append("Silicon"); + break; + case layerGas: + out.append("Gas/TPC"); + break; + default: + out.append("Unknown"); + break; + } + return out; +} + +} // namespace o2::fastsim diff --git a/ALICE3/Core/DetLayer.h b/ALICE3/Core/DetLayer.h index 6b9fea14c06..e70d719a6e4 100644 --- a/ALICE3/Core/DetLayer.h +++ b/ALICE3/Core/DetLayer.h @@ -21,10 +21,57 @@ #include "TString.h" +#include + namespace o2::fastsim { struct DetLayer { + public: + // Default constructor + DetLayer() = default; + // Parametric constructor + DetLayer(const TString& name_, float r_, float z_, float x0_, float xrho_, + float resRPhi_ = 0.0f, float resZ_ = 0.0f, float eff_ = 0.0f, int type_ = layerInert); + // Copy constructor + DetLayer(const DetLayer& other); + + // Setters + void setName(const TString& name_) { name = name_; } + void setRadius(float r_) { r = r_; } + void setZ(float z_) { z = z_; } + void setRadiationLength(float x0_) { x0 = x0_; } + void setDensity(float xrho_) { xrho = xrho_; } + void setResolutionRPhi(float resRPhi_) { resRPhi = resRPhi_; } + void setResolutionZ(float resZ_) { resZ = resZ_; } + void setEfficiency(float eff_) { eff = eff_; } + void setType(int type_) { type = type_; } + + // Getters + float getRadius() const { return r; } + float getZ() const { return z; } + float getRadiationLength() const { return x0; } + float getDensity() const { return xrho; } + float getResolutionRPhi() const { return resRPhi; } + float getResolutionZ() const { return resZ; } + float getEfficiency() const { return eff; } + int getType() const { return type; } + const TString& getName() const { return name; } + + // Check layer type + bool isInert() const { return type == layerInert; } + bool isSilicon() const { return type == layerSilicon; } + bool isGas() const { return type == layerGas; } + + // Utilities + std::string toString() const; + friend std::ostream& operator<<(std::ostream& os, const DetLayer& layer) + { + os << layer.toString(); + return os; + } + + private: // TString for holding name TString name; @@ -44,7 +91,10 @@ struct DetLayer { float eff; // detection efficiency // layer type - int type; // 0: undefined/inert, 1: silicon, 2: gas/tpc + int type; // 0: undefined/inert, 1: silicon, 2: gas/tpc + static constexpr int layerInert = 0; // inert/undefined layer + static constexpr int layerSilicon = 1; // silicon layer + static constexpr int layerGas = 2; // gas/tpc layer }; } // namespace o2::fastsim diff --git a/ALICE3/Core/FastTracker.cxx b/ALICE3/Core/FastTracker.cxx index 6b22461c187..1d06958504b 100644 --- a/ALICE3/Core/FastTracker.cxx +++ b/ALICE3/Core/FastTracker.cxx @@ -30,7 +30,6 @@ FastTracker::FastTracker() magneticField = 20; // in kiloGauss applyZacceptance = false; applyMSCorrection = true; - applyMSCorrection = true; applyElossCorrection = true; applyEffCorrection = true; covMatFactor = 0.99f; @@ -57,7 +56,11 @@ FastTracker::FastTracker() void FastTracker::AddLayer(TString name, float r, float z, float x0, float xrho, float resRPhi, float resZ, float eff, int type) { - DetLayer newLayer{name.Data(), r, z, x0, xrho, resRPhi, resZ, eff, type}; + DetLayer newLayer(name, r, z, x0, xrho, resRPhi, resZ, eff, type); + // Check that efficient layers are not inert layers + if (newLayer.getEfficiency() > 0.0f && newLayer.isInert()) { + LOG(error) << "Layer " << name << " with efficiency > 0.0 should not be inert"; + } layers.push_back(newLayer); } @@ -66,7 +69,7 @@ DetLayer FastTracker::GetLayer(int layer, bool ignoreBarrelLayers) const int layerIdx = layer; if (ignoreBarrelLayers) { for (int il = 0, trackingLayerIdx = 0; trackingLayerIdx <= layer; il++) { - if (layers[il].type == 0) + if (layers[il].isInert()) continue; trackingLayerIdx++; layerIdx = il; @@ -79,11 +82,12 @@ int FastTracker::GetLayerIndex(std::string name) const { int i = 0; for (const auto& layer : layers) { - if (layer.name == name) { + if (layer.getName() == name) { return i; } i++; } + LOG(error) << "Layer with name " << name << " not found in FastTracker layers"; return -1; } @@ -93,8 +97,7 @@ void FastTracker::Print() LOG(info) << "+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+"; LOG(info) << " Printing detector layout with " << layers.size() << " effective elements: "; for (uint32_t il = 0; il < layers.size(); il++) { - LOG(info) << " Layer #" << il << "\t" << layers[il].name.Data() << "\tr = " << Form("%.2f", layers[il].r) << "cm\tz = " << layers[il].z << "\t" - << "x0 = " << layers[il].x0 << "\txrho = " << layers[il].xrho << "\tresRPhi = " << layers[il].resRPhi << "\tresZ = " << layers[il].resZ << "\teff = " << layers[il].eff; + LOG(info) << " Layer #" << il << "\t" << layers[il]; } LOG(info) << "+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+-~-<*>-~-+"; } @@ -310,6 +313,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa const int xrhosteps = 100; const bool applyAngularCorrection = true; + goodHitProbability.clear(); for (int i = 0; i < kMaxNumberOfDetectors; ++i) goodHitProbability.push_back(-1.); goodHitProbability[0] = 1.; @@ -321,32 +325,35 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa new (&outputTrack)(o2::track::TrackParCov)(inputTrack); for (uint32_t il = 0; il < layers.size(); il++) { // check if layer is doable - if (layers[il].r < initialRadius) + if (layers[il].getRadius() < initialRadius) continue; // this layer should not be attempted, but go ahead // check if layer is reached float targetX = 1e+3; bool ok = true; - inputTrack.getXatLabR(layers[il].r, targetX, magneticField); - if (targetX > 999) + inputTrack.getXatLabR(layers[il].getRadius(), targetX, magneticField); + if (targetX > 999.f) { + LOGF(debug, "Failed to find intercept for layer %d at radius %.2f cm", il, layers[il].getRadius()); break; // failed to find intercept + } ok = inputTrack.propagateTo(targetX, magneticField); - if (ok && applyMSCorrection && layers[il].x0 > 0) { - ok = inputTrack.correctForMaterial(layers[il].x0, 0, applyAngularCorrection); + if (ok && applyMSCorrection && layers[il].getRadiationLength() > 0) { + ok = inputTrack.correctForMaterial(layers[il].getRadiationLength(), 0, applyAngularCorrection); } - if (ok && applyElossCorrection && layers[il].xrho > 0) { // correct in small steps + if (ok && applyElossCorrection && layers[il].getDensity() > 0) { // correct in small steps for (int ise = xrhosteps; ise--;) { - ok = inputTrack.correctForMaterial(0, -layers[il].xrho / xrhosteps, applyAngularCorrection); + ok = inputTrack.correctForMaterial(0, -layers[il].getDensity() / xrhosteps, applyAngularCorrection); if (!ok) break; } } + LOGF(debug, "Propagation was %s up to layer %d", ok ? "successful" : "unsuccessful", il); // was there a problem on this layer? if (!ok && il > 0) { // may fail to reach target layer due to the eloss float rad2 = inputTrack.getX() * inputTrack.getX() + inputTrack.getY() * inputTrack.getY(); - float maxR = layers[il - 1].r + kTrackingMargin * 2; + float maxR = layers[il - 1].getRadius() + kTrackingMargin * 2; float minRad = (fMinRadTrack > 0 && fMinRadTrack < maxR) ? fMinRadTrack : maxR; if (rad2 - minRad * minRad < kTrackingMargin * kTrackingMargin) { // check previously reached layer return -5; // did not reach min requested layer @@ -354,16 +361,20 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa break; } } - if (std::abs(inputTrack.getZ()) > layers[il].z && applyZacceptance) { + if (std::abs(inputTrack.getZ()) > layers[il].getZ() && applyZacceptance) { break; // out of acceptance bounds } - if (layers[il].type == 0) + if (layers[il].isInert()) { + LOG(info) << "Skipping inert layer: " << layers[il].getName() << " at radius " << layers[il].getRadius() << " cm"; continue; // inert layer, skip + } // layer is reached - if (firstLayerReached < 0) + if (firstLayerReached < 0) { + LOGF(debug, "First layer reached: %d", il); firstLayerReached = il; + } lastLayerReached = il; nIntercepts++; } @@ -415,7 +426,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa for (int il = lastLayerReached; il >= firstLayerReached; il--) { float targetX = 1e+3; - inputTrack.getXatLabR(layers[il].r, targetX, magneticField); + inputTrack.getXatLabR(layers[il].getRadius(), targetX, magneticField); if (targetX > 999) continue; // failed to find intercept @@ -423,7 +434,7 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa continue; // failed to propagate } - if (std::abs(inputTrack.getZ()) > layers[il].z && applyZacceptance) { + if (std::abs(inputTrack.getZ()) > layers[il].getZ() && applyZacceptance) { continue; // out of acceptance bounds but continue inwards } @@ -441,46 +452,46 @@ int FastTracker::FastTrack(o2::track::TrackParCov inputTrack, o2::track::TrackPa if (!inwardTrack.propagateTo(xyz1[0], magneticField)) continue; - if (layers[il].type != 0) { // only update covm for tracker hits + if (!layers[il].isInert()) { // only update covm for tracker hits const o2::track::TrackParametrization::dim2_t hitpoint = { static_cast(xyz1[1]), static_cast(xyz1[2])}; - const o2::track::TrackParametrization::dim3_t hitpointcov = {layers[il].resRPhi * layers[il].resRPhi, 0.f, layers[il].resZ * layers[il].resZ}; + const o2::track::TrackParametrization::dim3_t hitpointcov = {layers[il].getResolutionRPhi() * layers[il].getResolutionRPhi(), 0.f, layers[il].getResolutionZ() * layers[il].getResolutionZ()}; inwardTrack.update(hitpoint, hitpointcov); inwardTrack.checkCovariance(); } - if (applyMSCorrection && layers[il].x0 > 0) { - if (!inputTrack.correctForMaterial(layers[il].x0, 0, applyAngularCorrection)) { + if (applyMSCorrection && layers[il].getRadiationLength() > 0) { + if (!inputTrack.correctForMaterial(layers[il].getRadiationLength(), 0, applyAngularCorrection)) { return -6; } - if (!inwardTrack.correctForMaterial(layers[il].x0, 0, applyAngularCorrection)) { + if (!inwardTrack.correctForMaterial(layers[il].getRadiationLength(), 0, applyAngularCorrection)) { return -6; } } - if (applyElossCorrection && layers[il].xrho > 0) { + if (applyElossCorrection && layers[il].getDensity() > 0) { for (int ise = xrhosteps; ise--;) { // correct in small steps - if (!inputTrack.correctForMaterial(0, layers[il].xrho / xrhosteps, applyAngularCorrection)) { + if (!inputTrack.correctForMaterial(0, layers[il].getDensity() / xrhosteps, applyAngularCorrection)) { return -7; } - if (!inwardTrack.correctForMaterial(0, layers[il].xrho / xrhosteps, applyAngularCorrection)) { + if (!inwardTrack.correctForMaterial(0, layers[il].getDensity() / xrhosteps, applyAngularCorrection)) { return -7; } } } - if (layers[il].type == 1) + if (layers[il].isSilicon()) nSiliconPoints++; // count silicon hits - if (layers[il].type == 2) + if (layers[il].isGas()) nGasPoints++; // count TPC/gas hits hits.push_back(thisHit); - if (applyEffCorrection && layers[il].type != 0) { // good hit probability calculation - double sigYCmb = o2::math_utils::sqrt(inwardTrack.getSigmaY2() + layers[il].resRPhi * layers[il].resRPhi); - double sigZCmb = o2::math_utils::sqrt(inwardTrack.getSigmaZ2() + layers[il].resZ * layers[il].resZ); - goodHitProbability[il] = ProbGoodChiSqHit(layers[il].r * 100, sigYCmb * 100, sigZCmb * 100); + if (applyEffCorrection && !layers[il].isInert()) { // good hit probability calculation + double sigYCmb = o2::math_utils::sqrt(inwardTrack.getSigmaY2() + layers[il].getResolutionRPhi() * layers[il].getResolutionRPhi()); + double sigZCmb = o2::math_utils::sqrt(inwardTrack.getSigmaZ2() + layers[il].getResolutionZ() * layers[il].getResolutionZ()); + goodHitProbability[il] = ProbGoodChiSqHit(layers[il].getRadius() * 100, sigYCmb * 100, sigZCmb * 100); goodHitProbability[0] *= goodHitProbability[il]; } } diff --git a/ALICE3/Core/FastTracker.h b/ALICE3/Core/FastTracker.h index f88b6c5ae85..702caa9e84b 100644 --- a/ALICE3/Core/FastTracker.h +++ b/ALICE3/Core/FastTracker.h @@ -39,10 +39,10 @@ class FastTracker void AddLayer(TString name, float r, float z, float x0, float xrho, float resRPhi = 0.0f, float resZ = 0.0f, float eff = 0.0f, int type = 0); DetLayer GetLayer(const int layer, bool ignoreBarrelLayers = true) const; int GetLayerIndex(const std::string name) const; - void SetRadiationLength(const std::string layerName, float x0) { layers[GetLayerIndex(layerName)].x0 = x0; } - void SetRadius(const std::string layerName, float r) { layers[GetLayerIndex(layerName)].r = r; } - void SetResolutionRPhi(const std::string layerName, float resRPhi) { layers[GetLayerIndex(layerName)].resRPhi = resRPhi; } - void SetResolutionZ(const std::string layerName, float resZ) { layers[GetLayerIndex(layerName)].resZ = resZ; } + void SetRadiationLength(const std::string layerName, float x0) { layers[GetLayerIndex(layerName)].setRadiationLength(x0); } + void SetRadius(const std::string layerName, float r) { layers[GetLayerIndex(layerName)].setRadius(r); } + void SetResolutionRPhi(const std::string layerName, float resRPhi) { layers[GetLayerIndex(layerName)].setResolutionRPhi(resRPhi); } + void SetResolutionZ(const std::string layerName, float resZ) { layers[GetLayerIndex(layerName)].setResolutionZ(resZ); } void SetResolution(const std::string layerName, float resRPhi, float resZ) { SetResolutionRPhi(layerName, resRPhi); diff --git a/ALICE3/DataModel/OTFMulticharm.h b/ALICE3/DataModel/OTFMulticharm.h index 7dbde7bdc9a..c04ad88b4bf 100644 --- a/ALICE3/DataModel/OTFMulticharm.h +++ b/ALICE3/DataModel/OTFMulticharm.h @@ -10,10 +10,11 @@ // or submit itself to any jurisdiction. /// -/// \file OTFStrangeness.h +/// \file OTFMulticharm.h /// \author David Dobrigkeit Chinellato +/// \author Jesper Karlsson Gumprecht /// \since 05/08/2024 -/// \brief Set of tables for the ALICE3 strangeness information +/// \brief Set of tables for the ALICE3 multi-charm information /// #ifndef ALICE3_DATAMODEL_OTFMULTICHARM_H_ @@ -31,45 +32,72 @@ DECLARE_SOA_INDEX_COLUMN_FULL(XiCPion1, xiCPion1, int, Tracks, "_Pi1XiC"); DECLARE_SOA_INDEX_COLUMN_FULL(XiCPion2, xiCPion2, int, Tracks, "_Pi2XiC"); DECLARE_SOA_INDEX_COLUMN_FULL(XiCCPion, xiCCPion, int, Tracks, "_PiXiCC"); -// topo vars -DECLARE_SOA_COLUMN(DCAXiCDaughters, dcaXiCDaughters, float); -DECLARE_SOA_COLUMN(DCAXiCCDaughters, dcaXiCCDaughters, float); - -DECLARE_SOA_COLUMN(MXiC, mXiC, float); -DECLARE_SOA_COLUMN(MXiCC, mXiCC, float); +DECLARE_SOA_COLUMN(XicMass, xicMass, float); +DECLARE_SOA_COLUMN(XiccMass, xiccMass, float); // kine vars DECLARE_SOA_COLUMN(Pt, pt, float); DECLARE_SOA_COLUMN(Eta, eta, float); -// tracking counters -DECLARE_SOA_COLUMN(NSiliconHitsXi, nSiliconHitsXi, int); -DECLARE_SOA_COLUMN(NSiliconHitsPiFromXi, nSiliconHitsPiFromXi, int); -DECLARE_SOA_COLUMN(NSiliconHitsPiFromLa, nSiliconHitsPiFromLa, int); -DECLARE_SOA_COLUMN(NSiliconHitsPrFromLa, nSiliconHitsPrFromLa, int); -DECLARE_SOA_COLUMN(NSiliconHitsPiC1, nSiliconHitsPiC1, int); -DECLARE_SOA_COLUMN(NSiliconHitsPiC2, nSiliconHitsPiC2, int); -DECLARE_SOA_COLUMN(NSiliconHitsPiCC, nSiliconHitsPiCC, int); - -DECLARE_SOA_COLUMN(NTPCHitsPiFromXi, nTPCHitsPiFromXi, int); -DECLARE_SOA_COLUMN(NTPCHitsPiFromLa, nTPCHitsPiFromLa, int); -DECLARE_SOA_COLUMN(NTPCHitsPrFromLa, nTPCHitsPrFromLa, int); -DECLARE_SOA_COLUMN(NTPCHitsPiC1, nTPCHitsPiC1, int); -DECLARE_SOA_COLUMN(NTPCHitsPiC2, nTPCHitsPiC2, int); -DECLARE_SOA_COLUMN(NTPCHitsPiCC, nTPCHitsPiCC, int); - -// DCA to PV variables -DECLARE_SOA_COLUMN(DCAToPVXi, dcaToPVXi, float); -DECLARE_SOA_COLUMN(DCAToPVXiC, dcaToPVXiC, float); -DECLARE_SOA_COLUMN(DCAToPVXiCC, dcaToPVXiCC, float); - -DECLARE_SOA_COLUMN(DCAToPVPiFromXi, dcaToPVPiFromXi, float); -DECLARE_SOA_COLUMN(DCAToPVPiFromLa, dcaToPVPiFromLa, float); -DECLARE_SOA_COLUMN(DCAToPVPrFromLa, dcaToPVPrFromLa, float); - -DECLARE_SOA_COLUMN(DCAToPVPiC1, dcaToPVPiC1, float); -DECLARE_SOA_COLUMN(DCAToPVPiC2, dcaToPVPiC2, float); -DECLARE_SOA_COLUMN(DCAToPVPiCC, dcaToPVPiCC, float); +// topo vars +DECLARE_SOA_COLUMN(XiDCAz, xiDCAz, float); +DECLARE_SOA_COLUMN(XiDCAxy, xiDCAxy, float); +DECLARE_SOA_COLUMN(XicDauDCA, xicDauDCA, float); +DECLARE_SOA_COLUMN(XicDCAxy, xicDCAxy, float); +DECLARE_SOA_COLUMN(XicDCAz, xicDCAz, float); +DECLARE_SOA_COLUMN(XiccDauDCA, xiccDauDCA, float); +DECLARE_SOA_COLUMN(XiccDCAxy, xiccDCAxy, float); +DECLARE_SOA_COLUMN(XiccDCAz, xiccDCAz, float); + +DECLARE_SOA_COLUMN(PiFromXiDCAxy, piFromXiDCAxy, float); +DECLARE_SOA_COLUMN(PiFromLaDCAxy, piFromLaDCAxy, float); +DECLARE_SOA_COLUMN(PrFromLaDCAxy, prFromLaDCAxy, float); +DECLARE_SOA_COLUMN(PiFromXiDCAz, piFromXiDCAz, float); +DECLARE_SOA_COLUMN(PiFromLaDCAz, piFromLaDCAz, float); +DECLARE_SOA_COLUMN(PrFromLaDCAz, prFromLaDCAz, float); + +DECLARE_SOA_COLUMN(Pi1cDCAxy, pi1cDCAxy, float); +DECLARE_SOA_COLUMN(Pi2cDCAxy, pi2cDCAxy, float); +DECLARE_SOA_COLUMN(PiccDCAxy, piccDCAxy, float); +DECLARE_SOA_COLUMN(Pi1cDCAz, pi1cDCAz, float); +DECLARE_SOA_COLUMN(Pi2cDCAz, pi2cDCAz, float); +DECLARE_SOA_COLUMN(PiccDCAz, piccDCAz, float); + +// Lengths +DECLARE_SOA_COLUMN(XicDecayRadius2D, xicDecayRadius2D, float); +DECLARE_SOA_COLUMN(XiccDecayRadius2D, xiccDecayRadius2D, float); +DECLARE_SOA_COLUMN(XicProperLength, xicProperLength, float); +DECLARE_SOA_COLUMN(XicDistanceFromPV, xicDistanceFromPV, float); +DECLARE_SOA_COLUMN(XiccProperLength, xiccProperLength, float); + +// PID +DECLARE_SOA_COLUMN(Pi1cTofDeltaInner, pi1cTofDeltaInner, float); +DECLARE_SOA_COLUMN(Pi1cTofNSigmaInner, pi1cTofNSigmaInner, float); +DECLARE_SOA_COLUMN(Pi1cTofDeltaOuter, pi1cTofDeltaOuter, float); +DECLARE_SOA_COLUMN(Pi1cTofNSigmaOuter, pi1cTofNSigmaOuter, float); +DECLARE_SOA_COLUMN(Pi2cTofDeltaInner, pi2cTofDeltaInner, float); +DECLARE_SOA_COLUMN(Pi2cTofNSigmaInner, pi2cTofNSigmaInner, float); +DECLARE_SOA_COLUMN(Pi2cTofDeltaOuter, pi2cTofDeltaOuter, float); +DECLARE_SOA_COLUMN(Pi2cTofNSigmaOuter, pi2cTofNSigmaOuter, float); +DECLARE_SOA_COLUMN(PiccTofDeltaInner, piccTofDeltaInner, float); +DECLARE_SOA_COLUMN(PiccTofNSigmaInner, piccTofNSigmaInner, float); +DECLARE_SOA_COLUMN(PiccTofDeltaOuter, piccTofDeltaOuter, float); +DECLARE_SOA_COLUMN(PiccTofNSigmaOuter, piccTofNSigmaOuter, float); + +// Daughter info +DECLARE_SOA_COLUMN(PosPt, posPt, float); +DECLARE_SOA_COLUMN(PosEta, posEta, float); +DECLARE_SOA_COLUMN(NegPt, negPt, float); +DECLARE_SOA_COLUMN(NegEta, negEta, float); +DECLARE_SOA_COLUMN(BachPt, bachPt, float); +DECLARE_SOA_COLUMN(BachEta, bachEta, float); +DECLARE_SOA_COLUMN(BachPhi, bachPhi, float); +DECLARE_SOA_COLUMN(Pi1cPt, pi1cPt, float); +DECLARE_SOA_COLUMN(Pi1cEta, pi1cEta, float); +DECLARE_SOA_COLUMN(Pi2cPt, pi2cPt, float); +DECLARE_SOA_COLUMN(Pi2cEta, pi2cEta, float); +DECLARE_SOA_COLUMN(PiccPt, piccPt, float); +DECLARE_SOA_COLUMN(PiccEta, piccEta, float); } // namespace otfmulticharm DECLARE_SOA_TABLE(MCharmIndices, "AOD", "MCharmIndices", @@ -80,36 +108,72 @@ DECLARE_SOA_TABLE(MCharmIndices, "AOD", "MCharmIndices", otfmulticharm::XiCCPionId); DECLARE_SOA_TABLE(MCharmCores, "AOD", "MCharmCores", - otfmulticharm::DCAXiCDaughters, - otfmulticharm::DCAXiCCDaughters, - otfmulticharm::MXiC, - otfmulticharm::MXiCC, + otfmulticharm::XicDauDCA, + otfmulticharm::XiccDauDCA, + otfmulticharm::XicMass, + otfmulticharm::XiccMass, otfmulticharm::Pt, otfmulticharm::Eta, - otfmulticharm::NSiliconHitsXi, - otfmulticharm::NSiliconHitsPiFromXi, - otfmulticharm::NSiliconHitsPiFromLa, - otfmulticharm::NSiliconHitsPrFromLa, - otfmulticharm::NSiliconHitsPiC1, - otfmulticharm::NSiliconHitsPiC2, - otfmulticharm::NSiliconHitsPiCC, - otfmulticharm::NTPCHitsPiFromXi, - otfmulticharm::NTPCHitsPiFromLa, - otfmulticharm::NTPCHitsPrFromLa, - otfmulticharm::NTPCHitsPiC1, - otfmulticharm::NTPCHitsPiC2, - otfmulticharm::NTPCHitsPiCC, - - otfmulticharm::DCAToPVXi, - otfmulticharm::DCAToPVXiC, - otfmulticharm::DCAToPVXiCC, - otfmulticharm::DCAToPVPiFromXi, - otfmulticharm::DCAToPVPiFromLa, - otfmulticharm::DCAToPVPrFromLa, - otfmulticharm::DCAToPVPiC1, - otfmulticharm::DCAToPVPiC2, - otfmulticharm::DCAToPVPiCC); + otfmulticharm::XiDCAxy, + otfmulticharm::XicDCAxy, + otfmulticharm::XiccDCAxy, + otfmulticharm::XiDCAz, + otfmulticharm::XicDCAz, + otfmulticharm::XiccDCAz, + + otfmulticharm::PiFromXiDCAxy, + otfmulticharm::PiFromLaDCAxy, + otfmulticharm::PrFromLaDCAxy, + otfmulticharm::PiFromXiDCAz, + otfmulticharm::PiFromLaDCAz, + otfmulticharm::PrFromLaDCAz, + + otfmulticharm::Pi1cDCAxy, + otfmulticharm::Pi2cDCAxy, + otfmulticharm::PiccDCAxy, + otfmulticharm::Pi1cDCAz, + otfmulticharm::Pi2cDCAz, + otfmulticharm::PiccDCAz, + + otfmulticharm::XicDecayRadius2D, + otfmulticharm::XiccDecayRadius2D, + otfmulticharm::XicProperLength, + otfmulticharm::XicDistanceFromPV, + otfmulticharm::XiccProperLength, + + otfmulticharm::Pi1cTofDeltaInner, + otfmulticharm::Pi1cTofNSigmaInner, + otfmulticharm::Pi1cTofDeltaOuter, + otfmulticharm::Pi1cTofNSigmaOuter, + + otfmulticharm::Pi2cTofDeltaInner, + otfmulticharm::Pi2cTofNSigmaInner, + otfmulticharm::Pi2cTofDeltaOuter, + otfmulticharm::Pi2cTofNSigmaOuter, + + otfmulticharm::PiccTofDeltaInner, + otfmulticharm::PiccTofNSigmaInner, + otfmulticharm::PiccTofDeltaOuter, + otfmulticharm::PiccTofNSigmaOuter, + + otfmulticharm::BachPt, + otfmulticharm::BachEta, + + otfmulticharm::PosPt, + otfmulticharm::PosEta, + + otfmulticharm::NegPt, + otfmulticharm::NegEta, + + otfmulticharm::Pi1cPt, + otfmulticharm::Pi1cEta, + + otfmulticharm::Pi2cPt, + otfmulticharm::Pi2cEta, + + otfmulticharm::PiccPt, + otfmulticharm::PiccEta); } // namespace o2::aod diff --git a/ALICE3/TableProducer/CMakeLists.txt b/ALICE3/TableProducer/CMakeLists.txt index 8548ecd9897..d0b7afce076 100644 --- a/ALICE3/TableProducer/CMakeLists.txt +++ b/ALICE3/TableProducer/CMakeLists.txt @@ -41,8 +41,8 @@ o2physics_add_dpl_workflow(alice3-decayfinder PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DCAFitter COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(alice3-multicharm - SOURCES alice3-multicharm.cxx +o2physics_add_dpl_workflow(alice3-multicharm-table + SOURCES alice3-multicharmTable.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DCAFitter COMPONENT_NAME Analysis) diff --git a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx index 989295f8c54..c858f5a753e 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -23,48 +23,42 @@ /// \author Roberto Preghenella preghenella@bo.infn.it /// -#include -#include -#include -#include -#include - -#include -#include -#include -#include +#include "ALICE3/Core/DelphesO2TrackSmearer.h" +#include "ALICE3/Core/DetLayer.h" +#include "ALICE3/Core/FastTracker.h" +#include "ALICE3/Core/TrackUtilities.h" +#include "ALICE3/DataModel/OTFStrangeness.h" +#include "ALICE3/DataModel/collisionAlice3.h" +#include "ALICE3/DataModel/tracksAlice3.h" +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "CommonConstants/MathConstants.h" +#include "DCAFitter/DCAFitterN.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsVertexing/PVertexer.h" +#include "DetectorsVertexing/PVertexerHelpers.h" +#include "Field/MagneticField.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" #include "Framework/HistogramRegistry.h" -#include -#include "DCAFitter/DCAFitterN.h" -#include "Common/Core/RecoDecay.h" #include "Framework/O2DatabasePDGPlugin.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/DCA.h" -#include "DetectorsBase/Propagator.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DetectorsVertexing/PVertexer.h" -#include "DetectorsVertexing/PVertexerHelpers.h" #include "SimulationDataFormat/InteractionSampler.h" -#include "Field/MagneticField.h" -#include "ITSMFTSimulation/Hit.h" -#include "ITStracking/Configuration.h" -#include "ITStracking/IOUtils.h" -#include "ITStracking/Tracker.h" -#include "ITStracking/Vertexer.h" -#include "ITStracking/VertexerTraits.h" +#include +#include +#include +#include +#include -#include "ALICE3/Core/DelphesO2TrackSmearer.h" -#include "ALICE3/Core/FastTracker.h" -#include "ALICE3/Core/DetLayer.h" -#include "ALICE3/Core/TrackUtilities.h" -#include "ALICE3/DataModel/collisionAlice3.h" -#include "ALICE3/DataModel/tracksAlice3.h" -#include "ALICE3/DataModel/OTFStrangeness.h" +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -808,14 +802,14 @@ struct OnTheFlyTracker { std::array posClusterCandidate; trackParCov.getXYZGlo(posClusterCandidate); float r{std::hypot(posClusterCandidate[0], posClusterCandidate[1])}; - float phi{std::atan2(-posClusterCandidate[1], -posClusterCandidate[0]) + o2::its::constants::math::Pi}; + float phi{std::atan2(-posClusterCandidate[1], -posClusterCandidate[0]) + o2::constants::math::PI}; o2::fastsim::DetLayer currentTrackingLayer = fastTracker.GetLayer(i); - if (currentTrackingLayer.resRPhi > 1e-8 && currentTrackingLayer.resZ > 1e-8) { // catch zero (though should not really happen...) - phi = gRandom->Gaus(phi, std::asin(currentTrackingLayer.resRPhi / r)); + if (currentTrackingLayer.getResolutionRPhi() > 1e-8 && currentTrackingLayer.getResolutionZ() > 1e-8) { // catch zero (though should not really happen...) + phi = gRandom->Gaus(phi, std::asin(currentTrackingLayer.getResolutionRPhi() / r)); posClusterCandidate[0] = r * std::cos(phi); posClusterCandidate[1] = r * std::sin(phi); - posClusterCandidate[2] = gRandom->Gaus(posClusterCandidate[2], currentTrackingLayer.resZ); + posClusterCandidate[2] = gRandom->Gaus(posClusterCandidate[2], currentTrackingLayer.getResolutionZ()); } if (std::isnan(phi)) @@ -833,7 +827,7 @@ struct OnTheFlyTracker { const o2::track::TrackParametrization::dim2_t hitpoint = { static_cast(xyz1[1]), static_cast(xyz1[2])}; - const o2::track::TrackParametrization::dim3_t hitpointcov = {currentTrackingLayer.resRPhi * currentTrackingLayer.resRPhi, 0.f, currentTrackingLayer.resZ * currentTrackingLayer.resZ}; + const o2::track::TrackParametrization::dim3_t hitpointcov = {currentTrackingLayer.getResolutionRPhi() * currentTrackingLayer.getResolutionRPhi(), 0.f, currentTrackingLayer.getResolutionZ() * currentTrackingLayer.getResolutionZ()}; cascadeTrack.update(hitpoint, hitpointcov); thisCascade.foundClusters++; // add to findable } diff --git a/ALICE3/TableProducer/alice3-decayfinder.cxx b/ALICE3/TableProducer/alice3-decayfinder.cxx index b0aeba5272d..2d12ea9ed14 100644 --- a/ALICE3/TableProducer/alice3-decayfinder.cxx +++ b/ALICE3/TableProducer/alice3-decayfinder.cxx @@ -77,6 +77,7 @@ struct alice3decayFinder { Configurable magneticField{"magneticField", 20.0f, "Magnetic field (in kilogauss)"}; Configurable doDCAplotsD{"doDCAplotsD", true, "do daughter prong DCA plots for D mesons"}; Configurable doDCAplotsLc{"doDCAplotsLc", true, "do daughter prong DCA plots for Lc baryons"}; + Configurable doTopoPlotsForSAndB{"doTopoPlotsForSAndB", true, "do topological variable distributions for S and B separately"}; Configurable mcSameMotherCheck{"mcSameMotherCheck", true, "check if tracks come from the same MC mother"}; Configurable dcaDaughtersSelection{"dcaDaughtersSelection", 1000.0f, "DCA between daughters (cm)"}; @@ -85,14 +86,25 @@ struct alice3decayFinder { Configurable kaFromD_dcaXYconstant{"kaFromD_dcaXYconstant", -1.0f, "[0] in |DCAxy| > [0]+[1]/pT"}; Configurable kaFromD_dcaXYpTdep{"kaFromD_dcaXYpTdep", 0.0, "[1] in |DCAxy| > [0]+[1]/pT"}; - Configurable DCosPA{"DCosPA", 0.99, " Cos of pointing angle: pt < 3 GeV"}; - Configurable DCosPAHighPt{"DCosPAHighPt", 0.995, " Cos of pointing angle: 3 GeV < pt"}; - Configurable DCosPAxy{"DCosPAxy", 0.99, " Cos of pointing angle xy: pt < 3 GeV"}; - Configurable DCosPAxyHighPt{"DCosPAxyHighPt", 0.995, " Cos of pointing angle xy: 3 GeV < pt"}; - Configurable DCosThetaStarLowPt{"DCosThetaStarLowPt", 0.8, "Cos theta; pt < 9"}; - Configurable DCosThetaStarHighPt{"DCosThetaStarHighPt", 0.9, "Cos theta; 9 < pt < 16"}; - Configurable DCosThetaStarVHighPt{"DCosThetaStarVHighPt", 1.0, "Cos theta; 16 < pt"}; - Configurable DDauDecayLength{"DDauDecayLength", 3, "|Normalized dau decay length| > [0]"}; + Configurable DCosPA{"DCosPA", 0.99, " Cos of pointing angle: low pt"}; + Configurable DCosPAHighPt{"DCosPAHighPt", 0.995, " Cos of pointing angle: high pt"}; + Configurable DCosPAxy{"DCosPAxy", 0.99, " Cos of pointing angle xy: low pt"}; + Configurable DCosPAxyHighPt{"DCosPAxyHighPt", 0.995, " Cos of pointing angle xy: DCosPAxyHighPt pt"}; + Configurable DCosThetaStarLowPt{"DCosThetaStarLowPt", 0.8, "Cos theta; low pt"}; + Configurable DCosThetaStarHighPt{"DCosThetaStarHighPt", 0.9, "Cos theta; high pt"}; + Configurable DCosThetaStarVHighPt{"DCosThetaStarVHighPt", 1.0, "Cos theta; very high pt"}; + Configurable DDecayLengthSquaredCut{"DDecayLengthSquaredCut", 0., "Flat component of squared decay length cut (only for LoI legacy)"}; + Configurable DMinDecayLength{"DMinDecayLength", 0., "Minimum D decay length (3D)"}; + Configurable DMaxDecayLength{"DMaxDecayLength", 10., "Maximum D decay length (3D)"}; + Configurable DMinDecayLengthXY{"DMinDecayLengthXY", 0., "Minimum D decay length (xy)"}; + Configurable DMaxDecayLengthXY{"DMaxDecayLengthXY", 10., "Maximum D decay length (xy)"}; + Configurable DMinNormDecayLength{"DMinNormDecayLength", 3, "Minimum normalized decay length"}; + Configurable DMaxNormDecayLength{"DMaxNormDecayLength", 3, "Maximum normalized decay length"}; + Configurable minPtPi{"minPtPi", 0., "Minimum pT of daughter pion track"}; + Configurable minPtK{"minPtK", 0., "Minimum pT of daughter kaon track"}; + Configurable maxImpParPi{"maxImpParPi", 1., "Maximum impact paramter of daughter pion track"}; + Configurable maxImpParK{"maxImpParK", 1., "Maximum impact paramter of daughter kaon track"}; + Configurable maxImpParProduct{"maxImpParProduct", 0., "Maximum daughter impact paramter product"}; Configurable piFromLc_dcaXYconstant{"piFromLc_dcaXYconstant", -1.0f, "[0] in |DCAxy| > [0]+[1]/pT"}; Configurable piFromLc_dcaXYpTdep{"piFromLc_dcaXYpTdep", 0.0, "[1] in |DCAxy| > [0]+[1]/pT"}; @@ -101,7 +113,11 @@ struct alice3decayFinder { Configurable prFromLc_dcaXYconstant{"prFromLc_dcaXYconstant", -1.0f, "[0] in |DCAxy| > [0]+[1]/pT"}; Configurable prFromLc_dcaXYpTdep{"prFromLc_dcaXYpTdep", 0.0, "[1] in |DCAxy| > [0]+[1]/pT"}; + Configurable lowPtDLimit{"lowPtDLimit", 3.5, "Upper boundary of low pT D range, for topological selection (GeV/c)"}; + Configurable highPtDLimit{"highPtDLimit", 16, "Upper boundary of high pT D range, for topological selection (GeV/c)"}; + ConfigurableAxis axisEta{"axisEta", {8, -4.0f, +4.0f}, "#eta"}; + ConfigurableAxis axisY{"axisY", {12, -6.0f, +6.0f}, "y"}; ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for QA histograms"}; ConfigurableAxis axisDCA{"axisDCA", {200, -100, 100}, "DCA (#mum)"}; ConfigurableAxis axisDCADaughters{"axisDCADaughters", {200, 0, 100}, "DCA (#mum)"}; @@ -168,6 +184,8 @@ struct alice3decayFinder { std::array Pdaug; // positive track std::array Ndaug; // negative track float pt; + float ptdaugPos; + float ptdaugNeg; float phi; float eta; float y; @@ -222,6 +240,8 @@ struct alice3decayFinder { // return mass and kinematic variables dmeson.mass = RecoDecay::m(array{array{posP[0], posP[1], posP[2]}, array{negP[0], negP[1], negP[2]}}, array{posMass, negMass}); dmeson.pt = std::hypot(posP[0] + negP[0], posP[1] + negP[1]); + dmeson.ptdaugPos = std::hypot(posP[0], posP[1]); + dmeson.ptdaugNeg = std::hypot(negP[0], negP[1]); dmeson.phi = RecoDecay::phi(array{posP[0] + negP[0], posP[1] + negP[1]}); dmeson.eta = RecoDecay::eta(array{posP[0] + negP[0], posP[1] + negP[1], posP[2] + negP[2]}); dmeson.y = RecoDecay::y(std::array{posP[0] + negP[0], posP[1] + negP[1], posP[2] + negP[2]}, dmeson.mass); @@ -247,6 +267,7 @@ struct alice3decayFinder { dmeson.mcTruth = 2; // D0bar } } + return true; } @@ -342,25 +363,86 @@ struct alice3decayFinder { if (doprocessFindDmesons) { histos.add("h2dGenD", "h2dGenD", kTH2F, {axisPt, axisEta}); + histos.add("h2dGenD_KpiOnly", "h2dGenD_KpiOnly", kTH2F, {axisPt, axisEta}); histos.add("h2dGenDbar", "h2dGenDbar", kTH2F, {axisPt, axisEta}); - histos.add("h3dRecD", "h2dRecD", kTH3F, {axisPt, axisEta, axisDMass}); - histos.add("h3dRecDbar", "h2dRecDbar", kTH3F, {axisPt, axisEta, axisDMass}); + histos.add("h2dGenDbar_KpiOnly", "h2dGenDbar_KpiOnly", kTH2F, {axisPt, axisEta}); + histos.add("h3dRecD", "h3dRecD", kTH3F, {axisPt, axisEta, axisDMass}); + histos.add("h3dRecDSig", "h3dRecDSig", kTH3F, {axisPt, axisEta, axisDMass}); + histos.add("h3dRecDRefl", "h3dRecDRefl", kTH3F, {axisPt, axisEta, axisDMass}); + histos.add("h3dRecDBkg", "h3dRecDBkg", kTH3F, {axisPt, axisEta, axisDMass}); + histos.add("h3dRecDbar", "h3dRecDbar", kTH3F, {axisPt, axisEta, axisDMass}); + histos.add("h3dRecDbarSig", "h3dRecDbarSig", kTH3F, {axisPt, axisEta, axisDMass}); + histos.add("h3dRecDbarRefl", "h3dRecDbarRefl", kTH3F, {axisPt, axisEta, axisDMass}); + histos.add("h3dRecDbarBkg", "h3dRecDbarBkg", kTH3F, {axisPt, axisEta, axisDMass}); + + histos.add("hDGenForEfficiency", "hDGenForEfficiency", kTH2F, {axisPt, axisY}); // 2D vs pT, Y, filling generated D0 and D0bar + histos.add("hDRecForEfficiency", "hDRecForEfficiency", kTH2F, {axisPt, axisY}); // 2D vs pT, Y, filling reconstructed D0 and D0bar with correct MC matching histos.add("hMassD", "hMassD", kTH1F, {axisDMass}); + histos.add("hMassDSig", "hMassDSig", kTH1F, {axisDMass}); + histos.add("hMassDRefl", "hMassDRefl", kTH1F, {axisDMass}); + histos.add("hMassDBkg", "hMassDBkg", kTH1F, {axisDMass}); histos.add("hMassDbar", "hMassDbar", kTH1F, {axisDMass}); + histos.add("hMassDbarSig", "hMassDbarSig", kTH1F, {axisDMass}); + histos.add("hMassDbarRefl", "hMassDbarRefl", kTH1F, {axisDMass}); + histos.add("hMassDbarBkg", "hMassDbarBkg", kTH1F, {axisDMass}); - histos.add("hDCosPA", "hDCosPA", kTH1F, {{200, 0, 1}}); - histos.add("hDCosPAxy", "hDCosPAxy", kTH1F, {{200, 0, 1}}); + histos.add("hDCosPA", "hDCosPA", kTH1F, {{800, -1, 1}}); + histos.add("hDCosPAxy", "hDCosPAxy", kTH1F, {{800, -1, 1}}); histos.add("hDCosThetaStar", "hDCosThetaStar", kTH1F, {{200, -1, 1}}); - histos.add("hDDauDecayLength", "hDDauDecayLength", kTH1F, {{100, 0, 10}}); + histos.add("hDDecayLength", "hDDecayLength", kTH1F, {{100, 0, 0.5}}); + histos.add("hDDecayLengthXY", "hDDecayLengthXY", kTH1F, {{100, 0, 0.5}}); + histos.add("hDNormDecayLength", "hDNormDecayLength", kTH1F, {{100, 0, 10}}); + histos.add("hImpParPi", "hImpParPi", kTH1F, {{200, -0.4, 0.4}}); + histos.add("hImpParK", "hImpParK", kTH1F, {{200, -0.4, 0.4}}); + histos.add("hImpParProduct", "hImpParProduct", kTH1F, {{400, -0.04, 0.04}}); + + histos.add("hDCosPA_Selected", "hDCosPA_Selected", kTH1F, {{800, -1, 1}}); + histos.add("hDCosPAxy_Selected", "hDCosPAxy_Selected", kTH1F, {{800, -1, 1}}); + histos.add("hDCosThetaStar_Selected", "hDCosThetaStar_Selected", kTH1F, {{200, -1, 1}}); + histos.add("hDDecayLength_Selected", "hDDecayLength_Selected", kTH1F, {{100, 0, 0.5}}); + histos.add("hDDecayLengthXY_Selected", "hDDecayLengthXY_Selected", kTH1F, {{100, 0, 0.5}}); + histos.add("hDNormDecayLength_Selected", "hDNormDecayLength_Selected", kTH1F, {{100, 0, 10}}); + histos.add("hImpParPi_Selected", "hImpParPi_Selected", kTH1F, {{200, -0.4, 0.4}}); + histos.add("hImpParK_Selected", "hImpParK_Selected", kTH1F, {{200, -0.4, 0.4}}); + histos.add("hImpParProduct_Selected", "hImpParProduct_Selected", kTH1F, {{400, -0.04, 0.04}}); + + if (doTopoPlotsForSAndB) { + histos.add("hDCosPA_Signal", "hDCosPA_Signal", kTH1F, {{800, -1, 1}}); + histos.add("hDCosPAxy_Signal", "hDCosPAxy_Signal", kTH1F, {{800, -1, 1}}); + histos.add("hDCosThetaStar_Signal", "hDCosThetaStar_Signal", kTH1F, {{200, -1, 1}}); + histos.add("hDDecayLength_Signal", "hDDecayLength_Signal", kTH1F, {{100, 0, 0.5}}); + histos.add("hDDecayLengthXY_Signal", "hDDecayLengthXY_Signal", kTH1F, {{100, 0, 0.5}}); + histos.add("hDNormDecayLength_Signal", "hDNormDecayLength_Signal", kTH1F, {{100, 0, 10}}); + histos.add("hImpParPi_Signal", "hImpParPi_Signal", kTH1F, {{200, -0.4, 0.4}}); + histos.add("hImpParK_Signal", "hImpParK_Signal", kTH1F, {{200, -0.4, 0.4}}); + histos.add("hImpParProduct_Signal", "hImpParProduct_Signal", kTH1F, {{400, -0.04, 0.04}}); + histos.add("hDCosPA_Bkg", "hDCosPA_Bkg", kTH1F, {{800, -1, 1}}); + histos.add("hDCosPAxy_Bkg", "hDCosPAxy_Bkg", kTH1F, {{800, -1, 1}}); + histos.add("hDCosThetaStar_Bkg", "hDCosThetaStar_Bkg", kTH1F, {{200, -1, 1}}); + histos.add("hDDecayLength_Bkg", "hDDecayLength_Bkg", kTH1F, {{100, 0, 0.5}}); + histos.add("hDDecayLengthXY_Bkg", "hDDecayLengthXY_Bkg", kTH1F, {{100, 0, 0.5}}); + histos.add("hDNormDecayLength_Bkg", "hDNormDecayLength_Bkg", kTH1F, {{100, 0, 10}}); + histos.add("hImpParPi_Bkg", "hImpParPi_Bkg", kTH1F, {{200, -0.4, 0.4}}); + histos.add("hImpParK_Bkg", "hImpParK_Bkg", kTH1F, {{200, -0.4, 0.4}}); + histos.add("hImpParProduct_Bkg", "hImpParProduct_Bkg", kTH1F, {{400, -0.04, 0.04}}); + } if (doDCAplotsD) { histos.add("hDCADDaughters", "hDCADDaughters", kTH1D, {axisDCADaughters}); - histos.add("hDCADbarDaughters", "hDCADbarDaughters", kTH1D, {axisDCA}); + histos.add("hDCADbarDaughters", "hDCADbarDaughters", kTH1D, {axisDCADaughters}); + histos.add("hDCADDaughters_Selected", "hDCADDaughters_Selected", kTH1D, {axisDCADaughters}); + histos.add("hDCADbarDaughters_Selected", "hDCADbarDaughters_Selected", kTH1D, {axisDCADaughters}); histos.add("h2dDCAxyVsPtPiPlusFromD", "h2dDCAxyVsPtPiPlusFromD", kTH2F, {axisPt, axisDCA}); histos.add("h2dDCAxyVsPtPiMinusFromD", "h2dDCAxyVsPtPiMinusFromD", kTH2F, {axisPt, axisDCA}); histos.add("h2dDCAxyVsPtKaPlusFromD", "h2dDCAxyVsPtKaPlusFromD", kTH2F, {axisPt, axisDCA}); histos.add("h2dDCAxyVsPtKaMinusFromD", "h2dDCAxyVsPtKaMinusFromD", kTH2F, {axisPt, axisDCA}); + if (doTopoPlotsForSAndB) { + histos.add("hDCADDaughters_Signal", "hDCADDaughters_Signal", kTH1D, {axisDCADaughters}); + histos.add("hDCADDaughters_Bkg", "hDCADDaughters_Bkg", kTH1D, {axisDCADaughters}); + histos.add("hDCADbarDaughters_Signal", "hDCADbarDaughters_Signal", kTH1D, {axisDCADaughters}); + histos.add("hDCADbarDaughters_Bkg", "hDCADbarDaughters_Bkg", kTH1D, {axisDCADaughters}); + } } } if (doprocessFindLcBaryons) { @@ -390,10 +472,40 @@ struct alice3decayFinder { { // no grouping for MC particles -> as intended if (doprocessFindDmesons) { - for (auto const& mcParticle : trueD) + for (auto const& mcParticle : trueD) { histos.fill(HIST("h2dGenD"), mcParticle.pt(), mcParticle.eta()); - for (auto const& mcParticle : trueDbar) + auto daughters = mcParticle.template daughters_as(); + if (daughters.size() != 2) + continue; + // int daugID[2]; + int daugPDG[2], i = 0; + for (const auto& dau : daughters) { + // daugID[i] = dau.globalIndex(); + daugPDG[i] = dau.pdgCode(); + i++; + } + if ((std::fabs(daugPDG[0]) == 321 && std::fabs(daugPDG[1]) == 211) || (std::fabs(daugPDG[0]) == 211 && std::fabs(daugPDG[1]) == 321)) { + histos.fill(HIST("h2dGenD_KpiOnly"), mcParticle.pt(), mcParticle.eta()); + histos.fill(HIST("hDGenForEfficiency"), mcParticle.pt(), mcParticle.y()); // in common for D and Dbar + } + } + for (auto const& mcParticle : trueDbar) { histos.fill(HIST("h2dGenDbar"), mcParticle.pt(), mcParticle.eta()); + auto daughters = mcParticle.template daughters_as(); + if (daughters.size() != 2) + continue; + // int daugID[2]; + int daugPDG[2], i = 0; + for (const auto& dau : daughters) { + // daugID[i] = dau.globalIndex(); + daugPDG[i] = dau.pdgCode(); + i++; + } + if ((std::fabs(daugPDG[0]) == 321 && std::fabs(daugPDG[1]) == 211) || (std::fabs(daugPDG[0]) == 211 && std::fabs(daugPDG[1]) == 321)) { + histos.fill(HIST("h2dGenDbar_KpiOnly"), mcParticle.pt(), mcParticle.eta()); + histos.fill(HIST("hDGenForEfficiency"), mcParticle.pt(), mcParticle.y()); // in common for D and Dbar + } + } } if (doprocessFindLcBaryons) { for (auto const& mcParticle : trueLc) @@ -426,6 +538,7 @@ struct alice3decayFinder { // D0 mesons for (auto const& posTrackRow : tracksPiPlusFromDgrouped) { for (auto const& negTrackRow : tracksKaMinusFromDgrouped) { + if (mcSameMotherCheck && !checkSameMother(posTrackRow, negTrackRow)) continue; if (!buildDecayCandidateTwoBody(posTrackRow, negTrackRow, o2::constants::physics::MassPionCharged, o2::constants::physics::MassKaonCharged, mcParticles)) @@ -437,37 +550,122 @@ struct alice3decayFinder { const float dmesonCtau = 0.012301; dmeson.normalizedDecayLength = ((dmeson.mass * std::fabs(std::hypot(collision.posX(), collision.posY(), collision.posZ()) - std::hypot(dmeson.posSV[0], dmeson.posSV[1], dmeson.posSV[2]))) / std::hypot(dmeson.P[0], dmeson.P[1], dmeson.P[2])) / dmesonCtau; + auto impParXY_daugPos = RecoDecay::impParXY(std::array{collision.posX(), collision.posY(), collision.posZ()}, std::array{dmeson.posSV[0], dmeson.posSV[1], dmeson.posSV[2]}, std::array{dmeson.Pdaug[0], dmeson.Pdaug[1], dmeson.Pdaug[2]}); + auto impParXY_daugNeg = RecoDecay::impParXY(std::array{collision.posX(), collision.posY(), collision.posZ()}, std::array{dmeson.posSV[0], dmeson.posSV[1], dmeson.posSV[2]}, std::array{dmeson.Ndaug[0], dmeson.Ndaug[1], dmeson.Ndaug[2]}); + auto decayLength = std::hypot(collision.posX() - dmeson.posSV[0], collision.posY() - dmeson.posSV[1], collision.posZ() - dmeson.posSV[2]); + auto decayLengthXY = std::hypot(collision.posX() - dmeson.posSV[0], collision.posY() - dmeson.posSV[1]); + + // fill plots of topological variables before topological selection histos.fill(HIST("hDCosPA"), dmeson.cosPA); histos.fill(HIST("hDCosPAxy"), dmeson.cosPAxy); histos.fill(HIST("hDCosThetaStar"), dmeson.cosThetaStar); - histos.fill(HIST("hDDauDecayLength"), dmeson.normalizedDecayLength); + histos.fill(HIST("hDDecayLength"), decayLength); + histos.fill(HIST("hDDecayLengthXY"), decayLengthXY); + histos.fill(HIST("hDNormDecayLength"), dmeson.normalizedDecayLength); + histos.fill(HIST("hImpParPi"), impParXY_daugPos); + histos.fill(HIST("hImpParK"), impParXY_daugNeg); + histos.fill(HIST("hImpParProduct"), impParXY_daugPos * impParXY_daugNeg); + if (doDCAplotsD) + histos.fill(HIST("hDCADDaughters"), dmeson.dcaDau * 1e+4); + + if (doTopoPlotsForSAndB) { // fill plots of topological variables for S and B separately (reflections not considered here) + if (dmeson.mcTruth == 1) { // true D0 + histos.fill(HIST("hDCosPA_Signal"), dmeson.cosPA); + histos.fill(HIST("hDCosPAxy_Signal"), dmeson.cosPAxy); + histos.fill(HIST("hDCosThetaStar_Signal"), dmeson.cosThetaStar); + histos.fill(HIST("hDDecayLength_Signal"), decayLength); + histos.fill(HIST("hDDecayLengthXY_Signal"), decayLengthXY); + histos.fill(HIST("hDNormDecayLength_Signal"), dmeson.normalizedDecayLength); + histos.fill(HIST("hImpParPi_Signal"), impParXY_daugPos); + histos.fill(HIST("hImpParK_Signal"), impParXY_daugNeg); + histos.fill(HIST("hImpParProduct_Signal"), impParXY_daugPos * impParXY_daugNeg); + if (doDCAplotsD) + histos.fill(HIST("hDCADDaughters_Signal"), dmeson.dcaDau * 1e+4); + } else if (!dmeson.mcTruth) { // bkg D0 + histos.fill(HIST("hDCosPA_Bkg"), dmeson.cosPA); + histos.fill(HIST("hDCosPAxy_Bkg"), dmeson.cosPAxy); + histos.fill(HIST("hDCosThetaStar_Bkg"), dmeson.cosThetaStar); + histos.fill(HIST("hDDecayLength_Bkg"), decayLength); + histos.fill(HIST("hDDecayLengthXY_Bkg"), decayLengthXY); + histos.fill(HIST("hDNormDecayLength_Bkg"), dmeson.normalizedDecayLength); + histos.fill(HIST("hImpParPi_Bkg"), impParXY_daugPos); + histos.fill(HIST("hImpParK_Bkg"), impParXY_daugNeg); + histos.fill(HIST("hImpParProduct_Bkg"), impParXY_daugPos * impParXY_daugNeg); + if (doDCAplotsD) + histos.fill(HIST("hDCADDaughters_Bkg"), dmeson.dcaDau * 1e+4); + } + } if (dmeson.dcaDau > dcaDaughtersSelection) continue; - if (dmeson.pt <= 3 && dmeson.cosPA < DCosPA) + if (dmeson.pt <= lowPtDLimit && dmeson.cosPA < DCosPA) continue; - else if (dmeson.pt > 3 && dmeson.cosPA < DCosPAHighPt) + else if (dmeson.pt > lowPtDLimit && dmeson.cosPA < DCosPAHighPt) continue; - if (dmeson.pt <= 3 && dmeson.cosPAxy < DCosPAxy) + if (dmeson.pt <= lowPtDLimit && dmeson.cosPAxy < DCosPAxy) continue; - else if (dmeson.pt > 3 && dmeson.cosPAxy < DCosPAxyHighPt) + else if (dmeson.pt > lowPtDLimit && dmeson.cosPAxy < DCosPAxyHighPt) continue; - if (dmeson.pt <= 9 && std::fabs(dmeson.cosThetaStar) > DCosThetaStarLowPt) + if (dmeson.pt <= lowPtDLimit && std::fabs(dmeson.cosThetaStar) > DCosThetaStarLowPt) + continue; + else if (dmeson.pt <= highPtDLimit && std::fabs(dmeson.cosThetaStar) > DCosThetaStarHighPt) continue; - else if (dmeson.pt <= 16 && std::fabs(dmeson.cosThetaStar) > DCosThetaStarHighPt) + else if (dmeson.pt > highPtDLimit && std::fabs(dmeson.cosThetaStar) > DCosThetaStarVHighPt) continue; - else if (dmeson.pt > 16 && std::fabs(dmeson.cosThetaStar) > DCosThetaStarVHighPt) + + if (dmeson.normalizedDecayLength < DMinNormDecayLength || dmeson.normalizedDecayLength > DMaxNormDecayLength) continue; - if (dmeson.normalizedDecayLength > DDauDecayLength) + if (dmeson.ptdaugPos < minPtPi) // track1 (positive) is the pion + continue; + if (dmeson.ptdaugNeg < minPtK) // track2 (negative) is the kaon + continue; + + if (impParXY_daugPos > maxImpParPi) + continue; + if (impParXY_daugNeg > maxImpParK) + continue; + if (impParXY_daugPos * impParXY_daugNeg > maxImpParProduct) continue; - histos.fill(HIST("hDCADDaughters"), dmeson.dcaDau * 1e+4); + if (decayLength < DMinDecayLength || decayLength > DMaxDecayLength) + continue; + if (decayLengthXY < DMinDecayLengthXY || decayLengthXY > DMaxDecayLengthXY) + continue; + auto decayLengthSquaredCut = std::min((std::hypot(dmeson.P[0], dmeson.P[1], dmeson.P[2]) * 0.0066) + 0.01, (double)DDecayLengthSquaredCut); + if (decayLength * decayLength < decayLengthSquaredCut * decayLengthSquaredCut) + continue; + + // fill plots of topological variables after topological selection + histos.fill(HIST("hDCosPA_Selected"), dmeson.cosPA); + histos.fill(HIST("hDCosPAxy_Selected"), dmeson.cosPAxy); + histos.fill(HIST("hDCosThetaStar_Selected"), dmeson.cosThetaStar); + histos.fill(HIST("hDDecayLength_Selected"), decayLength); + histos.fill(HIST("hDDecayLengthXY_Selected"), decayLengthXY); + histos.fill(HIST("hDNormDecayLength_Selected"), dmeson.normalizedDecayLength); + histos.fill(HIST("hImpParPi_Selected"), impParXY_daugPos); + histos.fill(HIST("hImpParK_Selected"), impParXY_daugNeg); + histos.fill(HIST("hImpParProduct_Selected"), impParXY_daugPos * impParXY_daugNeg); + if (doDCAplotsD) + histos.fill(HIST("hDCADDaughters_Selected"), dmeson.dcaDau * 1e+4); + + // filling of mass plots for selected candidates histos.fill(HIST("hMassD"), dmeson.mass); histos.fill(HIST("h3dRecD"), dmeson.pt, dmeson.eta, dmeson.mass); + if (dmeson.mcTruth == 1) { // true D0 meson, reco as D0 (= correct matching) + histos.fill(HIST("h3dRecDSig"), dmeson.pt, dmeson.eta, dmeson.mass); + histos.fill(HIST("hMassDSig"), dmeson.mass); + histos.fill(HIST("hDRecForEfficiency"), dmeson.pt, dmeson.y); // for efficiency + } else if (dmeson.mcTruth == 2) { // true D0bar meson, reco as D0 (= reflection) + histos.fill(HIST("hMassDRefl"), dmeson.mass); + histos.fill(HIST("h3dRecDRefl"), dmeson.pt, dmeson.eta, dmeson.mass); + } else { // background, reco as D0 + histos.fill(HIST("hMassDBkg"), dmeson.mass); + histos.fill(HIST("h3dRecDBkg"), dmeson.pt, dmeson.eta, dmeson.mass); + } // store D0 in output table candidateD0meson(collision.globalIndex(), @@ -483,9 +681,11 @@ struct alice3decayFinder { mcTruthOutcome(dmeson.mcTruth); } } + // D0bar mesons for (auto const& posTrackRow : tracksKaPlusFromDgrouped) { for (auto const& negTrackRow : tracksPiMinusFromDgrouped) { + if (mcSameMotherCheck && !checkSameMother(posTrackRow, negTrackRow)) continue; if (!buildDecayCandidateTwoBody(posTrackRow, negTrackRow, o2::constants::physics::MassKaonCharged, o2::constants::physics::MassPionCharged, mcParticles)) @@ -497,37 +697,122 @@ struct alice3decayFinder { const float dmesonCtau = 0.012301; dmeson.normalizedDecayLength = ((dmeson.mass * std::fabs(std::hypot(collision.posX(), collision.posY(), collision.posZ()) - std::hypot(dmeson.posSV[0], dmeson.posSV[1], dmeson.posSV[2]))) / std::hypot(dmeson.P[0], dmeson.P[1], dmeson.P[2])) / dmesonCtau; + auto impParXY_daugPos = RecoDecay::impParXY(std::array{collision.posX(), collision.posY(), collision.posZ()}, std::array{dmeson.posSV[0], dmeson.posSV[1], dmeson.posSV[2]}, std::array{dmeson.Pdaug[0], dmeson.Pdaug[1], dmeson.Pdaug[2]}); + auto impParXY_daugNeg = RecoDecay::impParXY(std::array{collision.posX(), collision.posY(), collision.posZ()}, std::array{dmeson.posSV[0], dmeson.posSV[1], dmeson.posSV[2]}, std::array{dmeson.Ndaug[0], dmeson.Ndaug[1], dmeson.Ndaug[2]}); + auto decayLength = std::hypot(collision.posX() - dmeson.posSV[0], collision.posY() - dmeson.posSV[1], collision.posZ() - dmeson.posSV[2]); + auto decayLengthXY = std::hypot(collision.posX() - dmeson.posSV[0], collision.posY() - dmeson.posSV[1]); + + // fill plots of topological variables before topological selection histos.fill(HIST("hDCosPA"), dmeson.cosPA); histos.fill(HIST("hDCosPAxy"), dmeson.cosPAxy); histos.fill(HIST("hDCosThetaStar"), dmeson.cosThetaStar); - histos.fill(HIST("hDDauDecayLength"), dmeson.normalizedDecayLength); + histos.fill(HIST("hDDecayLength"), decayLength); + histos.fill(HIST("hDDecayLengthXY"), decayLengthXY); + histos.fill(HIST("hDNormDecayLength"), dmeson.normalizedDecayLength); + histos.fill(HIST("hImpParPi"), impParXY_daugNeg); + histos.fill(HIST("hImpParK"), impParXY_daugPos); + histos.fill(HIST("hImpParProduct"), impParXY_daugPos * impParXY_daugNeg); + if (doDCAplotsD) + histos.fill(HIST("hDCADbarDaughters"), dmeson.dcaDau * 1e+4); + + if (doTopoPlotsForSAndB) { // fill plots of topological variables for S and B separately (reflections not considered here) + if (dmeson.mcTruth == 2) { // true D0bar + histos.fill(HIST("hDCosPA_Signal"), dmeson.cosPA); + histos.fill(HIST("hDCosPAxy_Signal"), dmeson.cosPAxy); + histos.fill(HIST("hDCosThetaStar_Signal"), dmeson.cosThetaStar); + histos.fill(HIST("hDDecayLength_Signal"), decayLength); + histos.fill(HIST("hDDecayLengthXY_Signal"), decayLengthXY); + histos.fill(HIST("hDNormDecayLength_Signal"), dmeson.normalizedDecayLength); + histos.fill(HIST("hImpParPi_Signal"), impParXY_daugNeg); + histos.fill(HIST("hImpParK_Signal"), impParXY_daugPos); + histos.fill(HIST("hImpParProduct_Signal"), impParXY_daugPos * impParXY_daugNeg); + if (doDCAplotsD) + histos.fill(HIST("hDCADbarDaughters_Signal"), dmeson.dcaDau * 1e+4); + } else if (!dmeson.mcTruth) { // bkg D0bar + histos.fill(HIST("hDCosPA_Bkg"), dmeson.cosPA); + histos.fill(HIST("hDCosPAxy_Bkg"), dmeson.cosPAxy); + histos.fill(HIST("hDCosThetaStar_Bkg"), dmeson.cosThetaStar); + histos.fill(HIST("hDDecayLength_Bkg"), decayLength); + histos.fill(HIST("hDDecayLengthXY_Bkg"), decayLengthXY); + histos.fill(HIST("hDNormDecayLength_Bkg"), dmeson.normalizedDecayLength); + histos.fill(HIST("hImpParPi_Bkg"), impParXY_daugNeg); + histos.fill(HIST("hImpParK_Bkg"), impParXY_daugPos); + histos.fill(HIST("hImpParProduct_Bkg"), impParXY_daugPos * impParXY_daugNeg); + } + if (doDCAplotsD) + histos.fill(HIST("hDCADbarDaughters_Bkg"), dmeson.dcaDau * 1e+4); + } if (dmeson.dcaDau > dcaDaughtersSelection) continue; - if (dmeson.pt <= 3 && dmeson.cosPA < DCosPA) + if (dmeson.pt <= lowPtDLimit && dmeson.cosPA < DCosPA) + continue; + else if (dmeson.pt > lowPtDLimit && dmeson.cosPA < DCosPAHighPt) + continue; + + if (dmeson.pt <= lowPtDLimit && dmeson.cosPAxy < DCosPAxy) continue; - else if (dmeson.pt > 3 && dmeson.cosPA < DCosPAHighPt) + else if (dmeson.pt > lowPtDLimit && dmeson.cosPAxy < DCosPAxyHighPt) continue; - if (dmeson.pt <= 3 && dmeson.cosPAxy < DCosPAxy) + if (dmeson.pt <= highPtDLimit && std::fabs(dmeson.cosThetaStar) > DCosThetaStarLowPt) + continue; + else if (dmeson.pt <= highPtDLimit && std::fabs(dmeson.cosThetaStar) > DCosThetaStarHighPt) continue; - else if (dmeson.pt > 3 && dmeson.cosPAxy < DCosPAxyHighPt) + else if (dmeson.pt > highPtDLimit && std::fabs(dmeson.cosThetaStar) > DCosThetaStarVHighPt) continue; - if (dmeson.pt <= 9 && std::fabs(dmeson.cosThetaStar) > DCosThetaStarLowPt) + if (dmeson.normalizedDecayLength < DMinNormDecayLength || dmeson.normalizedDecayLength > DMaxNormDecayLength) continue; - else if (dmeson.pt <= 16 && std::fabs(dmeson.cosThetaStar) > DCosThetaStarHighPt) + + if (dmeson.ptdaugPos < minPtK) // track1 is the kaon continue; - else if (dmeson.pt > 16 && std::fabs(dmeson.cosThetaStar) > DCosThetaStarVHighPt) + if (dmeson.ptdaugNeg < minPtPi) // track2 is the pion continue; - if (dmeson.normalizedDecayLength > DDauDecayLength) + if (impParXY_daugPos > maxImpParK) + continue; + if (impParXY_daugNeg > maxImpParPi) + continue; + if (impParXY_daugPos * impParXY_daugNeg > maxImpParProduct) continue; - histos.fill(HIST("hDCADbarDaughters"), dmeson.dcaDau * 1e+4); + if (decayLength < DMinDecayLength || decayLength > DMaxDecayLength) + continue; + if (decayLengthXY < DMinDecayLengthXY || decayLengthXY > DMaxDecayLengthXY) + continue; + auto decayLengthSquaredCut = std::min((std::hypot(dmeson.P[0], dmeson.P[1], dmeson.P[2]) * 0.0066) + 0.01, (double)DDecayLengthSquaredCut); + if (decayLength * decayLength < decayLengthSquaredCut * decayLengthSquaredCut) + continue; + + // fill plots of topological variables after topological selection + histos.fill(HIST("hDCosPA_Selected"), dmeson.cosPA); + histos.fill(HIST("hDCosPAxy_Selected"), dmeson.cosPAxy); + histos.fill(HIST("hDCosThetaStar_Selected"), dmeson.cosThetaStar); + histos.fill(HIST("hDDecayLength_Selected"), decayLength); + histos.fill(HIST("hDDecayLengthXY_Selected"), decayLengthXY); + histos.fill(HIST("hDNormDecayLength_Selected"), dmeson.normalizedDecayLength); + histos.fill(HIST("hImpParK_Selected"), impParXY_daugPos); + histos.fill(HIST("hImpParPi_Selected"), impParXY_daugNeg); + histos.fill(HIST("hImpParProduct_Selected"), impParXY_daugPos * impParXY_daugNeg); + if (doDCAplotsD) + histos.fill(HIST("hDCADbarDaughters_Selected"), dmeson.dcaDau * 1e+4); + + // filling of mass plots for selected candidates histos.fill(HIST("hMassDbar"), dmeson.mass); histos.fill(HIST("h3dRecDbar"), dmeson.pt, dmeson.eta, dmeson.mass); + if (dmeson.mcTruth == 2) { // true D0bar meson, reco as D0bar (= correct matching) + histos.fill(HIST("h3dRecDbarSig"), dmeson.pt, dmeson.eta, dmeson.mass); + histos.fill(HIST("hMassDbarSig"), dmeson.mass); + histos.fill(HIST("hDRecForEfficiency"), dmeson.pt, dmeson.y); // for efficiency + } else if (dmeson.mcTruth == 1) { // true D0 meson, reco as D0bar (= reflection) + histos.fill(HIST("hMassDbarRefl"), dmeson.mass); + histos.fill(HIST("h3dRecDbarRefl"), dmeson.pt, dmeson.eta, dmeson.mass); + } else { // background, reco as D0 + histos.fill(HIST("hMassDbarBkg"), dmeson.mass); + histos.fill(HIST("h3dRecDbarBkg"), dmeson.pt, dmeson.eta, dmeson.mass); + } // store D0bar in output table candidateD0meson(collision.globalIndex(), diff --git a/ALICE3/TableProducer/alice3-multicharm.cxx b/ALICE3/TableProducer/alice3-multicharmTable.cxx similarity index 90% rename from ALICE3/TableProducer/alice3-multicharm.cxx rename to ALICE3/TableProducer/alice3-multicharmTable.cxx index 74948cfdf11..62713161343 100644 --- a/ALICE3/TableProducer/alice3-multicharm.cxx +++ b/ALICE3/TableProducer/alice3-multicharmTable.cxx @@ -17,41 +17,43 @@ // HF decays. Work in progress: use at your own risk! // -#include -#include -#include -#include -#include -#include +#include "PWGLF/DataModel/LFParticleIdentification.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "Framework/runDataProcessing.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "DCAFitter/DCAFitterN.h" -#include "ReconstructionDataFormats/Track.h" +#include "ALICE3/DataModel/A3DecayFinderTables.h" +#include "ALICE3/DataModel/OTFMulticharm.h" +#include "ALICE3/DataModel/OTFStrangeness.h" +#include "ALICE3/DataModel/OTFTOF.h" +#include "ALICE3/DataModel/RICH.h" +#include "ALICE3/DataModel/tracksAlice3.h" #include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/LFParticleIdentification.h" #include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" + #include "CCDB/BasicCCDBManager.h" +#include "CommonConstants/PhysicsConstants.h" +#include "DCAFitter/DCAFitterN.h" #include "DataFormatsCalibration/MeanVertexObject.h" -#include "ALICE3/DataModel/OTFTOF.h" -#include "ALICE3/DataModel/RICH.h" -#include "ALICE3/DataModel/A3DecayFinderTables.h" -#include "ALICE3/DataModel/OTFStrangeness.h" -#include "ALICE3/DataModel/OTFMulticharm.h" -#include "ALICE3/DataModel/tracksAlice3.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" #include "DetectorsVertexing/PVertexer.h" #include "DetectorsVertexing/PVertexerHelpers.h" -#include "CommonConstants/PhysicsConstants.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -71,7 +73,7 @@ using tofTracks = soa::Join; using richTracks = soa::Join; using alice3tracks = soa::Join; -struct alice3multicharm { +struct alice3multicharmTable { SliceCache cache; Produces multiCharmIdx; @@ -131,8 +133,6 @@ struct alice3multicharm { ConfigurableAxis axisDecayLength{"axisDecayLength", {2000, 0, 2000}, "Decay lenght (#mum)"}; ConfigurableAxis axisTOFTrack{"axisTOFTrack", {1000, 0, 5000}, "TOF track time"}; - ConfigurableAxis axisPiMass{"axisPiMass", {200, 0.089f, 0.189f}, "Pi Inv Mass (GeV/c^{2})"}; - ConfigurableAxis axisPrMass{"axisPrMass", {200, 0.838f, 1.038f}, "Pr Inv Mass (GeV/c^{2})"}; ConfigurableAxis axisXiMass{"axisXiMass", {200, 1.221f, 1.421f}, "Xi Inv Mass (GeV/c^{2})"}; ConfigurableAxis axisXiCMass{"axisXiCMass", {200, 2.368f, 2.568f}, "XiC Inv Mass (GeV/c^{2})"}; ConfigurableAxis axisXiCCMass{"axisXiCCMass", {200, 3.521f, 3.721f}, "XiCC Inv Mass (GeV/c^{2})"}; @@ -414,15 +414,7 @@ struct alice3multicharm { histos.add("hEtaXiCC", "hEtaXiCC", kTH1D, {axisEta}); histos.add("hPtXiCC", "hPtXiCC", kTH1D, {axisPt}); - histos.add("h3dXicc", "h3dXicc", kTH3D, {axisPt, axisEta, axisXiCCMass}); - histos.add("h3dXic", "h3dXic", kTH3D, {axisPt, axisEta, axisXiCMass}); - histos.add("h3dXi", "h3dXi", kTH3D, {axisPt, axisEta, axisXiMass}); - histos.add("h3dPicc", "h3dPicc", kTH3D, {axisPt, axisEta, axisPiMass}); - histos.add("h3dPi1c", "h3dPi1c", kTH3D, {axisPt, axisEta, axisPiMass}); - histos.add("h3dPi2c", "h3dPi2c", kTH3D, {axisPt, axisEta, axisPiMass}); - histos.add("h3dBach", "h3dBach", kTH3D, {axisPt, axisEta, axisPiMass}); - histos.add("h3dPos", "h3dPos", kTH3D, {axisPt, axisEta, axisPrMass}); - histos.add("h3dNeg", "h3dNeg", kTH3D, {axisPt, axisEta, axisPiMass}); + histos.add("h3dMassXiCC", "h3dMassXiCC", kTH3D, {axisPt, axisEta, axisXiCCMass}); histos.add("hDCAXiCDaughters", "hDCAXiCDaughters", kTH1D, {axisDCAXiCDaughters}); histos.add("hDCAXiCCDaughters", "hDCAXiCCDaughters", kTH1D, {axisDCAXiCCDaughters}); @@ -526,11 +518,6 @@ struct alice3multicharm { auto piFromLa = xiCand.negTrack_as(); // de-reference neg track auto prFromLa = xiCand.posTrack_as(); // de-reference pos track - histos.fill(HIST("h3dXi"), xi.pt(), xi.eta(), xiCand.mXi()); - histos.fill(HIST("h3dBach"), piFromXi.pt(), piFromXi.eta(), o2::constants::physics::MassPionCharged); - histos.fill(HIST("h3dNeg"), piFromLa.pt(), piFromLa.eta(), o2::constants::physics::MassPionCharged); - histos.fill(HIST("h3dPos"), prFromLa.pt(), prFromLa.eta(), o2::constants::physics::MassProton); - if (!bitcheck(xi.decayMap(), kTrueXiFromXiC)) continue; @@ -554,11 +541,11 @@ struct alice3multicharm { continue; // too low momentum histos.fill(HIST("hPi1cPt"), pi1c.pt()); - double pi1cTOFDiffInner = std::fabs(pi1c.innerTOFTrackTimeReco() - pi1c.innerTOFExpectedTimePi()); + float pi1cTOFDiffInner = std::fabs(pi1c.innerTOFTrackTimeReco() - pi1c.innerTOFExpectedTimePi()); + float pi1cTOFDiffOuter = std::fabs(pi1c.outerTOFTrackTimeReco() - pi1c.outerTOFExpectedTimePi()); if (pi1cTOFDiffInner > piFromXiC_tofDiffInner) continue; // did not arrive at expected time - histos.fill(HIST("h3dPi1c"), pi1c.pt(), pi1c.eta(), o2::constants::physics::MassPionCharged); histos.fill(HIST("hInnerTOFTrackTimeRecoPi1c"), pi1cTOFDiffInner); // second pion from XiC decay for starts here for (auto const& pi2c : tracksPiFromXiCgrouped) { @@ -575,13 +562,12 @@ struct alice3multicharm { continue; // too low momentum histos.fill(HIST("hPi2cPt"), pi2c.pt()); - double pi2cTOFDiffInner = std::fabs(pi2c.innerTOFTrackTimeReco() - pi2c.innerTOFExpectedTimePi()); + float pi2cTOFDiffInner = std::fabs(pi2c.innerTOFTrackTimeReco() - pi2c.innerTOFExpectedTimePi()); + float pi2cTOFDiffOuter = std::fabs(pi2c.outerTOFTrackTimeReco() - pi2c.outerTOFExpectedTimePi()); if (pi2cTOFDiffInner > piFromXiC_tofDiffInner) continue; // did not arrive at expected time histos.fill(HIST("hInnerTOFTrackTimeRecoPi2c"), pi2cTOFDiffInner); - histos.fill(HIST("h3dPi2c"), pi2c.pt(), pi2c.eta(), o2::constants::physics::MassPionCharged); - // if I am here, it means this is a triplet to be considered for XiC vertexing. // will now attempt to build a three-body decay candidate with these three track rows. @@ -603,7 +589,7 @@ struct alice3multicharm { thisXiCcandidate.prong0mom[2] + thisXiCcandidate.prong1mom[2] + thisXiCcandidate.prong2mom[2]}; o2::track::TrackParCov xicTrack(thisXiCcandidate.xyz, momentumC, thisXiCcandidate.parentTrackCovMatrix, +1); - double xicDecayRadius2D = std::hypot(thisXiCcandidate.xyz[0], thisXiCcandidate.xyz[1]); + float xicDecayRadius2D = std::hypot(thisXiCcandidate.xyz[0], thisXiCcandidate.xyz[1]); if (xicDecayRadius2D < minXiCRadius) continue; // do not take if radius too small, likely a primary combination @@ -631,7 +617,7 @@ struct alice3multicharm { histos.fill(HIST("hDCAxyXiC"), std::fabs(xicdcaXY * 1e+4)); histos.fill(HIST("hDCAzXiC"), std::fabs(xicdcaZ * 1e+4)); histos.fill(HIST("hMassXiC"), thisXiCcandidate.mass); - histos.fill(HIST("h3dXic"), thisXiCcandidate.pt, thisXiCcandidate.eta, thisXiCcandidate.mass); + // attempt XiCC finding uint32_t nCombinationsCC = 0; for (auto const& picc : tracksPiFromXiCCgrouped) { @@ -646,12 +632,12 @@ struct alice3multicharm { histos.fill(HIST("hPiccPt"), picc.pt()); - double piccTOFDiffInner = std::fabs(picc.innerTOFTrackTimeReco() - picc.innerTOFExpectedTimePi()); + float piccTOFDiffInner = std::fabs(picc.innerTOFTrackTimeReco() - picc.innerTOFExpectedTimePi()); + float piccTOFDiffOuter = std::fabs(picc.outerTOFTrackTimeReco() - picc.outerTOFExpectedTimePi()); if (piccTOFDiffInner > piFromXiCC_tofDiffInner) continue; // did not arrive at expected time histos.fill(HIST("hInnerTOFTrackTimeRecoPicc"), piccTOFDiffInner); - histos.fill(HIST("h3dPicc"), picc.pt(), picc.eta(), o2::constants::physics::MassPionCharged); o2::track::TrackParCov piccTrack = getTrackParCov(picc); nCombinationsCC++; @@ -667,40 +653,40 @@ struct alice3multicharm { thisXiCCcandidate.prong0mom[2] + thisXiCCcandidate.prong1mom[2]}; o2::track::TrackParCov xiccTrack(thisXiCCcandidate.xyz, momentumCC, thisXiCCcandidate.parentTrackCovMatrix, +2); - double xiccDecayRadius2D = std::hypot(thisXiCCcandidate.xyz[0], thisXiCCcandidate.xyz[1]); + float xiccDecayRadius2D = std::hypot(thisXiCCcandidate.xyz[0], thisXiCCcandidate.xyz[1]); if (xiccDecayRadius2D < minXiCCRadius) continue; // do not take if radius too small, likely a primary combination histos.fill(HIST("hMinXiCCDecayRadius"), xiccDecayRadius2D * 1e+4); - double totalMomentumC = std::hypot(momentumC[0], momentumC[1], momentumC[2]); - double decayLengthXiC = std::hypot( + float totalMomentumC = std::hypot(momentumC[0], momentumC[1], momentumC[2]); + float decayLengthXiC = std::hypot( thisXiCcandidate.xyz[0] - thisXiCCcandidate.xyz[0], thisXiCcandidate.xyz[1] - thisXiCCcandidate.xyz[1], thisXiCcandidate.xyz[2] - thisXiCCcandidate.xyz[2]); - double xicProperLength = decayLengthXiC * thisXiCcandidate.mass / totalMomentumC; + float xicProperLength = decayLengthXiC * thisXiCcandidate.mass / totalMomentumC; if (xicProperLength < xicMinProperLength || xicProperLength > xicMaxProperLength) continue; // likely background histos.fill(HIST("hProperLengthXiC"), xicProperLength * 1e+4); - double xicDistanceFromPV = std::hypot( + float xicDistanceFromPV = std::hypot( thisXiCcandidate.xyz[0] - collision.posX(), thisXiCcandidate.xyz[1] - collision.posY(), thisXiCcandidate.xyz[2] - collision.posZ()); - double xicDecayDistanceFromPV = xicDistanceFromPV * thisXiCcandidate.mass / totalMomentumC; + float xicDecayDistanceFromPV = xicDistanceFromPV * thisXiCcandidate.mass / totalMomentumC; if (xicDecayDistanceFromPV < xicMinDecayDistanceFromPV) continue; // too close to PV histos.fill(HIST("hMinxicDecayDistanceFromPV"), xicDecayDistanceFromPV * 1e+4); - double totalMomentumCC = std::hypot(momentumCC[0], momentumCC[1], momentumCC[2]); - double decayLengthXiCC = std::hypot( + float totalMomentumCC = std::hypot(momentumCC[0], momentumCC[1], momentumCC[2]); + float decayLengthXiCC = std::hypot( thisXiCCcandidate.xyz[0] - collision.posX(), thisXiCCcandidate.xyz[1] - collision.posY(), thisXiCCcandidate.xyz[2] - collision.posZ()); - double xiccProperLength = decayLengthXiCC * thisXiCCcandidate.mass / totalMomentumCC; + float xiccProperLength = decayLengthXiCC * thisXiCCcandidate.mass / totalMomentumCC; if (xiccProperLength < xiccMinProperLength || xiccProperLength > xicMaxProperLength) continue; // likely background @@ -729,22 +715,43 @@ struct alice3multicharm { histos.fill(HIST("hMassXiCC"), thisXiCCcandidate.mass); histos.fill(HIST("hPtXiCC"), thisXiCCcandidate.pt); histos.fill(HIST("hEtaXiCC"), thisXiCCcandidate.eta); - histos.fill(HIST("h3dXicc"), thisXiCCcandidate.pt, thisXiCCcandidate.eta, thisXiCCcandidate.mass); + histos.fill(HIST("h3dMassXiCC"), thisXiCCcandidate.pt, thisXiCCcandidate.eta, thisXiCCcandidate.mass); // produce multi-charm table for posterior analysis if (fillDerivedTable) { + multiCharmIdx( + xiCand.globalIndex(), + pi1c.globalIndex(), pi2c.globalIndex(), + picc.globalIndex()); + multiCharmCore( thisXiCcandidate.dca, thisXiCCcandidate.dca, thisXiCcandidate.mass, thisXiCCcandidate.mass, thisXiCCcandidate.pt, thisXiCCcandidate.eta, - xi.nSiliconHits(), piFromXi.nSiliconHits(), - piFromLa.nSiliconHits(), prFromLa.nSiliconHits(), - pi1c.nSiliconHits(), pi2c.nSiliconHits(), picc.nSiliconHits(), - piFromXi.nTPCHits(), piFromLa.nTPCHits(), prFromLa.nTPCHits(), - pi1c.nTPCHits(), pi2c.nTPCHits(), picc.nTPCHits(), - xi.dcaXY(), xicdcaXY, xiccdcaXY, - piFromXi.dcaXY(), piFromLa.dcaXY(), prFromLa.dcaXY(), - pi1c.dcaXY(), pi2c.dcaXY(), picc.dcaXY()); + xi.dcaXY(), xi.dcaZ(), + xicdcaXY, xicdcaZ, + xiccdcaXY, xiccdcaZ, + piFromXi.dcaXY(), piFromXi.dcaZ(), + piFromLa.dcaXY(), piFromLa.dcaZ(), + prFromLa.dcaXY(), prFromLa.dcaZ(), + pi1c.dcaXY(), pi1c.dcaZ(), + pi2c.dcaXY(), pi2c.dcaZ(), + picc.dcaXY(), picc.dcaZ(), + xicDecayRadius2D, xiccDecayRadius2D, + xicProperLength, xicDecayDistanceFromPV, + xiccProperLength, + pi1cTOFDiffInner, pi1c.nSigmaPionInnerTOF(), + pi1cTOFDiffOuter, pi1c.nSigmaPionOuterTOF(), + pi2cTOFDiffInner, pi2c.nSigmaPionInnerTOF(), + pi2cTOFDiffOuter, pi2c.nSigmaPionOuterTOF(), + piccTOFDiffInner, picc.nSigmaPionInnerTOF(), + piccTOFDiffOuter, picc.nSigmaPionOuterTOF(), + piFromXi.pt(), piFromXi.eta(), + prFromLa.pt(), prFromLa.eta(), + piFromLa.pt(), piFromLa.eta(), + pi1c.pt(), pi1c.eta(), + pi2c.pt(), pi2c.eta(), + picc.pt(), picc.eta()); } } histos.fill(HIST("hCombinationsXiCC"), nCombinationsCC); @@ -756,13 +763,13 @@ struct alice3multicharm { //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* //*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<* - PROCESS_SWITCH(alice3multicharm, processGenerated, "fill MC-only histograms", true); - PROCESS_SWITCH(alice3multicharm, processFindXiCC, "find XiCC baryons", true); + PROCESS_SWITCH(alice3multicharmTable, processGenerated, "fill MC-only histograms", true); + PROCESS_SWITCH(alice3multicharmTable, processFindXiCC, "find XiCC baryons", true); //*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<* }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc)}; } diff --git a/ALICE3/Tasks/CMakeLists.txt b/ALICE3/Tasks/CMakeLists.txt index 0b2e9972aa5..8fb4c79ea12 100644 --- a/ALICE3/Tasks/CMakeLists.txt +++ b/ALICE3/Tasks/CMakeLists.txt @@ -39,6 +39,11 @@ o2physics_add_dpl_workflow(alice3-pid-ftof-qa PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(alice3-pid-separation-power + SOURCES alice3SeparationPower.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(alice3-cdeuteron SOURCES alice3-cdeuteron.cxx PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore @@ -52,4 +57,14 @@ o2physics_add_dpl_workflow(alice3-dilepton o2physics_add_dpl_workflow(alice3-taskcorrelationddbar SOURCES alice3-taskcorrelationDDbar.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) \ No newline at end of file + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(alice3-multicharm + SOURCES alice3-multicharm.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(alice3-efficiency + SOURCES alice3Efficiency.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/ALICE3/Tasks/alice3-multicharm.cxx b/ALICE3/Tasks/alice3-multicharm.cxx new file mode 100644 index 00000000000..7b12f45e17e --- /dev/null +++ b/ALICE3/Tasks/alice3-multicharm.cxx @@ -0,0 +1,237 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// *+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* +// Decay finder task for ALICE 3 +// *+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* +// +// Uses specific ALICE 3 PID and performance for studying +// HF decays. Work in progress: use at your own risk! +// + +#include "PWGLF/DataModel/LFParticleIdentification.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + +#include "ALICE3/DataModel/A3DecayFinderTables.h" +#include "ALICE3/DataModel/OTFMulticharm.h" +#include "ALICE3/DataModel/OTFStrangeness.h" +#include "ALICE3/DataModel/OTFTOF.h" +#include "ALICE3/DataModel/RICH.h" +#include "ALICE3/DataModel/tracksAlice3.h" +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CommonConstants/PhysicsConstants.h" +#include "DCAFitter/DCAFitterN.h" +#include "DataFormatsCalibration/MeanVertexObject.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsVertexing/PVertexer.h" +#include "DetectorsVertexing/PVertexerHelpers.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using multicharmtracks = soa::Join; + +struct alice3multicharm { + SliceCache cache; + + ConfigurableAxis axisEta{"axisEta", {80, -4.0f, +4.0f}, "#eta"}; + ConfigurableAxis axisXiccMass{"axisXiccMass", {200, 3.521f, 3.721f}, "Xicc Inv Mass (GeV/c^{2})"}; + ConfigurableAxis axisDCA{"axisDCA", {400, 0, 400}, "DCA (#mum)"}; + ConfigurableAxis axisRadiusLarge{"axisRadiusLarge", {1000, 0, 20}, "Decay radius (cm)"}; + ConfigurableAxis axisRadius{"axisRadius", {10000, 0, 10000}, "Decay radius (#mum)"}; + ConfigurableAxis axisTofTrackDelta{"axisTofTrackDelta", {1000, 0, 5000}, "TOF track time"}; + ConfigurableAxis axisDecayLength{"axisDecayLength", {2000, 0, 2000}, "Decay lenght (#mum)"}; + ConfigurableAxis axisDcaDaughters{"axisDcaDaughters", {200, 0, 100}, "DCA (mum)"}; + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for QA histograms"}; + + Configurable xiMinDCAxy{"xiMinDCAxy", -1, "[0] in |DCAxy| > [0]+[1]/pT"}; + Configurable xiMinDCAz{"xiMinDCAz", -1, "[0] in |DCAz| > [0]+[1]/pT"}; + Configurable xiMinRadius{"xiMinRadius", -1, "Minimum R2D for Xic decay (cm)"}; + + Configurable picMinDCAxy{"picMinDCAxy", -1, "[0] in |DCAz| > [0]+[1]/pT"}; + Configurable picMinDCAz{"picMinDCAz", -1, "[0] in |DCAxy| > [0]+[1]/pT"}; + Configurable picMaxTofDiffInner{"picTofDiffInner", 1e+4, "|signal - expected| (ps)"}; + Configurable picMinPt{"picMinPt", -1, "Minimum pT for Xic pions"}; + + Configurable piccMinDCAxy{"piccMinDCAxy", -1, "[0] in |DCAxy| > [0]+[1]/pT"}; + Configurable piccMinDCAz{"piccMinDCAz", -1, "[0] in |DCAz| > [0]+[1]/pT"}; + Configurable piccMaxTofDiffInner{"piccMaxTofDiffInner", 1e+4, "|signal - expected| (ps)"}; + Configurable piccMinPt{"piccMinPt", -1, "Minimum pT for Xicc pions"}; + + Configurable xicMaxDauDCA{"xicMaxDauDCA", 1e+4, "DCA between Xic daughters (cm)"}; + Configurable xicMinDCAxy{"xicMinDCAxy", -1, "[0] in |DCAz| > [0]+[1]/pT"}; + Configurable xicMinDCAz{"xicMinDCAz", -1, "[0] in |DCAxy| > [0]+[1]/pT"}; + Configurable xiccMaxDCAxy{"xiccMaxDCAxy", 1e+4, "Maximum DCAxy"}; + Configurable xiccMaxDCAz{"xiccMaxDCAz", 1e+4, "Maximum DCAz"}; + Configurable xicMinRadius{"xicMinRadius", -1, "Minimum R2D for Xic decay (cm)"}; + Configurable xicMinDecayDistanceFromPV{"xicMinDecayDistanceFromPV", -1, "Minimum distance for Xic decay from PV (cm)"}; + Configurable xicMinProperLength{"xicMinProperLength", -1, "Minimum proper length for Xic decay (cm)"}; + Configurable xicMaxProperLength{"xicMaxProperLength", 1e+4, "Minimum proper length for Xic decay (cm)"}; + + Configurable xiccMaxDauDCA{"xiccMaxDauDCA", 1e+4, "DCA between Xicc daughters (cm)"}; + Configurable xiccMinRadius{"xiccMinRadius", -1, "Minimum R2D for Xicc decay (cm)"}; + Configurable xiccMinProperLength{"xiccMinProperLength", -1, "Minimum proper length for Xicc decay (cm)"}; + Configurable xiccMaxProperLength{"xiccMaxProperLength", 1e+4, "Minimum proper length for Xicc decay (cm)"}; + + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + void init(InitContext&) + { + histos.add("SelectionQA/hDCAXicDaughters", "hDCAXicDaughters; DCA between Xic daughters (#mum)", kTH1D, {axisDcaDaughters}); + histos.add("SelectionQA/hDCAXiccDaughters", "hDCAXiccDaughters; DCA between Xicc daughters (#mum)", kTH1D, {axisDcaDaughters}); + histos.add("SelectionQA/hDCAxyXi", "hDCAxyXi; Xi DCAxy to PV (#mum)", kTH1D, {axisDCA}); + histos.add("SelectionQA/hDCAzXi", "hDCAzXi; Xi DCAz to PV (#mum)", kTH1D, {axisDCA}); + histos.add("SelectionQA/hDCAxyXic", "hDCAxyXic; Xic DCAxy to PV (#mum)", kTH1D, {axisDCA}); + histos.add("SelectionQA/hDCAzXic", "hDCAzXic; Xic DCAz to PV (#mum)", kTH1D, {axisDCA}); + histos.add("SelectionQA/hDCAxyXicc", "hDCAxyXicc; Xicc DCAxy to PV (#mum)", kTH1D, {axisDCA}); + histos.add("SelectionQA/hDCAzXicc", "hDCAzXicc; Xicc DCAz to PV (#mum)", kTH1D, {axisDCA}); + histos.add("SelectionQA/hPi1cPt", "hPi1cPt; Pi1c pT (Gev/#it(c))", kTH1D, {axisPt}); + histos.add("SelectionQA/hPi2cPt", "hPi2cPt; Pi2c pT (Gev/#it(c))", kTH1D, {axisPt}); + histos.add("SelectionQA/hPiccPt", "hPiccPt; Picc pT (Gev/#it(c))", kTH1D, {axisPt}); + histos.add("SelectionQA/hXicDecayRadius", "hXicDecayRadius; Distance (#mum)", kTH1D, {axisRadius}); + histos.add("SelectionQA/hXiccDecayRadius", "hXiccDecayRadius; Distance (#mum)", kTH1D, {axisRadius}); + histos.add("SelectionQA/hXicDecayDistanceFromPV", "hXicDecayDistanceFromPV; Distance (#mum)", kTH1D, {axisDecayLength}); + histos.add("SelectionQA/hProperLengthXic", "hProperLengthXic; Distance (#mum)", kTH1D, {axisDecayLength}); + histos.add("SelectionQA/hProperLengthXicc", "hProperLengthXicc; Distance (#mum)", kTH1D, {axisDecayLength}); + histos.add("SelectionQA/hInnerTofTimeDeltaPi1c", "hInnerTofTimeDeltaPi1c; Reco - expected pion (ps)", kTH1D, {axisTofTrackDelta}); + histos.add("SelectionQA/hInnerTofTimeDeltaPi2c", "hInnerTofTimeDeltaPi2c; Reco - expected pion (ps)", kTH1D, {axisTofTrackDelta}); + histos.add("SelectionQA/hInnerTofTimeDeltaPicc", "hInnerTofTimeDeltaPicc; Reco - expected pion (ps)", kTH1D, {axisTofTrackDelta}); + + histos.add("XiccProngs/h3dPos", "h3dPos; Xicc pT (GeV/#it(c)); Pos pT (GeV/#it(c)); Pos #eta", kTH3D, {axisPt, axisPt, axisEta}); + histos.add("XiccProngs/h3dNeg", "h3dNeg; Xicc pT (GeV/#it(c)); Neg pT (GeV/#it(c)); Neg #eta", kTH3D, {axisPt, axisPt, axisEta}); + histos.add("XiccProngs/h3dBach", "h3dBach; Xicc pT (GeV/#it(c)); Bach pT (GeV/#it(c)); Bach #eta", kTH3D, {axisPt, axisPt, axisEta}); + histos.add("XiccProngs/h3dPi1c", "h3dPi1c; Xicc pT (GeV/#it(c)); Pi1c pT (GeV/#it(c)); Pi1c #eta", kTH3D, {axisPt, axisPt, axisEta}); + histos.add("XiccProngs/h3dPi2c", "h3dPi2c; Xicc pT (GeV/#it(c)); Pi2c pT (GeV/#it(c)); Pi2c #eta", kTH3D, {axisPt, axisPt, axisEta}); + histos.add("XiccProngs/h3dPicc", "h3dPicc; Xicc pT (GeV/#it(c)); Picc pT (GeV/#it(c)); Picc #eta", kTH3D, {axisPt, axisPt, axisEta}); + histos.add("h3dXicc", "h3dXicc; Xicc pT (GeV/#it(c)); Xicc #eta; Xicc mass (GeV/#it(c)^{2})", kTH3D, {axisPt, axisEta, axisXiccMass}); + } + + void processXicc(multicharmtracks const& multiCharmTracks) + { + for (const auto& xiccCand : multiCharmTracks) { + if (xiccCand.xicDauDCA() > xicMaxDauDCA || xiccCand.xiccDauDCA() > xiccMaxDauDCA) + continue; + + if (std::fabs(xiccCand.xiDCAxy()) < xiMinDCAxy || std::fabs(xiccCand.xiDCAz()) < xiMinDCAz) + continue; + + if (std::fabs(xiccCand.pi1cDCAxy()) < picMinDCAxy || std::fabs(xiccCand.pi1cDCAz()) < picMinDCAz) + continue; + + if (std::fabs(xiccCand.pi2cDCAxy()) < picMinDCAxy || std::fabs(xiccCand.pi2cDCAz()) < picMinDCAz) + continue; + + if (std::fabs(xiccCand.piccDCAxy()) < piccMinDCAxy || std::fabs(xiccCand.piccDCAz()) < piccMinDCAz) + continue; + + if (std::fabs(xiccCand.xicDCAxy()) < xicMinDCAxy || std::fabs(xiccCand.xicDCAz()) < xicMinDCAz) + continue; + + if (std::fabs(xiccCand.pi1cDCAxy()) < picMinDCAxy || std::fabs(xiccCand.pi1cDCAz()) < picMinDCAz) + continue; + + if (std::fabs(xiccCand.pi2cDCAxy()) < picMinDCAxy || std::fabs(xiccCand.pi2cDCAz()) < picMinDCAz) + continue; + + if (std::fabs(xiccCand.xiccDCAxy()) > xiccMaxDCAxy || std::fabs(xiccCand.xiccDCAz()) > xiccMaxDCAz) + continue; + + // Cut on time delta as LoI for now + if (xiccCand.pi1cTofDeltaInner() > picMaxTofDiffInner) + continue; + + if (xiccCand.pi2cTofDeltaInner() > picMaxTofDiffInner) + continue; + + if (xiccCand.piccTofDeltaInner() > piccMaxTofDiffInner) + continue; + + if (xiccCand.pi1cPt() < picMinPt || xiccCand.pi2cPt() < picMinPt) + continue; + + if (xiccCand.piccPt() < piccMinPt) + continue; + + if (xiccCand.xicDecayRadius2D() < xicMinRadius) + continue; + + if (xiccCand.xiccDecayRadius2D() < xiccMinRadius) + continue; + + if (xiccCand.xicProperLength() < xicMinProperLength || xiccCand.xicProperLength() > xicMaxProperLength) + continue; + + if (xiccCand.xiccProperLength() < xiccMinProperLength || xiccCand.xiccProperLength() > xiccMaxProperLength) + continue; + + if (xiccCand.xicDistanceFromPV() < xicMinDecayDistanceFromPV) + continue; + + histos.fill(HIST("SelectionQA/hDCAXicDaughters"), xiccCand.xicDauDCA() * 1e+4); + histos.fill(HIST("SelectionQA/hDCAXiccDaughters"), xiccCand.xiccDauDCA() * 1e+4); + histos.fill(HIST("SelectionQA/hDCAxyXi"), std::fabs(xiccCand.xiDCAxy() * 1e+4)); + histos.fill(HIST("SelectionQA/hDCAzXi"), std::fabs(xiccCand.xiDCAz() * 1e+4)); + histos.fill(HIST("SelectionQA/hDCAxyXic"), std::fabs(xiccCand.xicDCAxy() * 1e+4)); + histos.fill(HIST("SelectionQA/hDCAzXic"), std::fabs(xiccCand.xicDCAz() * 1e+4)); + histos.fill(HIST("SelectionQA/hDCAxyXicc"), std::fabs(xiccCand.xiccDCAxy() * 1e+4)); + histos.fill(HIST("SelectionQA/hDCAzXicc"), std::fabs(xiccCand.xiccDCAz() * 1e+4)); + histos.fill(HIST("SelectionQA/hPi1cPt"), xiccCand.pi1cPt()); + histos.fill(HIST("SelectionQA/hPi2cPt"), xiccCand.pi2cPt()); + histos.fill(HIST("SelectionQA/hPiccPt"), xiccCand.piccPt()); + histos.fill(HIST("SelectionQA/hXicDecayRadius"), xiccCand.xicDecayRadius2D() * 1e+4); + histos.fill(HIST("SelectionQA/hXiccDecayRadius"), xiccCand.xiccDecayRadius2D() * 1e+4); + histos.fill(HIST("SelectionQA/hXicDecayDistanceFromPV"), xiccCand.xicDistanceFromPV() * 1e+4); + histos.fill(HIST("SelectionQA/hProperLengthXic"), xiccCand.xicProperLength() * 1e+4); + histos.fill(HIST("SelectionQA/hProperLengthXicc"), xiccCand.xiccProperLength() * 1e+4); + histos.fill(HIST("SelectionQA/hInnerTofTimeDeltaPi1c"), xiccCand.pi1cTofDeltaInner()); + histos.fill(HIST("SelectionQA/hInnerTofTimeDeltaPi2c"), xiccCand.pi2cTofDeltaInner()); + histos.fill(HIST("SelectionQA/hInnerTofTimeDeltaPicc"), xiccCand.piccTofDeltaInner()); + + histos.fill(HIST("XiccProngs/h3dNeg"), xiccCand.pt(), xiccCand.negPt(), xiccCand.negEta()); + histos.fill(HIST("XiccProngs/h3dPos"), xiccCand.pt(), xiccCand.posPt(), xiccCand.posEta()); + histos.fill(HIST("XiccProngs/h3dBach"), xiccCand.pt(), xiccCand.bachPt(), xiccCand.bachEta()); + histos.fill(HIST("XiccProngs/h3dPi1c"), xiccCand.pt(), xiccCand.pi1cPt(), xiccCand.pi1cEta()); + histos.fill(HIST("XiccProngs/h3dPi2c"), xiccCand.pt(), xiccCand.pi2cPt(), xiccCand.pi2cEta()); + histos.fill(HIST("XiccProngs/h3dPicc"), xiccCand.pt(), xiccCand.piccPt(), xiccCand.piccEta()); + histos.fill(HIST("h3dXicc"), xiccCand.pt(), xiccCand.eta(), xiccCand.xiccMass()); + } + } + + PROCESS_SWITCH(alice3multicharm, processXicc, "find Xicc baryons", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/ALICE3/Tasks/alice3Efficiency.cxx b/ALICE3/Tasks/alice3Efficiency.cxx new file mode 100644 index 00000000000..0f247305d00 --- /dev/null +++ b/ALICE3/Tasks/alice3Efficiency.cxx @@ -0,0 +1,104 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +/// +/// \file alice3Efficiency.cxx +/// +/// \brief This task produces the efficiency +/// +/// \author Nicolò Jacazio, Universita del Piemonte Orientale (IT) +/// \since May 27, 2025 +/// + +#include "Framework/AnalysisTask.h" +#include "Framework/ConfigParamRegistry.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include "TEfficiency.h" +#include "THashList.h" + +#include +#include + +using namespace o2; +using namespace o2::framework; +std::map effVsPt; +std::map effVsEta; + +struct alice3Efficiency { + Configurable> pdgCodes{"pdgCodes", {211}, "List of PDG codes to consider for efficiency calculation"}; + OutputObj outList{"output"}; + Configurable> etaRange{"etaRange", {-5.f, 5.f}, "Eta range for efficiency calculation"}; + void init(o2::framework::InitContext&) + { + outList.setObject(new THashList); + auto createEff = [&](const char* baseName, const char* axisTitle, int pdg, int nBins, double min, double max) { + auto eff = new TEfficiency(Form("%s_pdg%d", baseName, pdg), + Form("Efficiency for PDG %d; %s; Efficiency", pdg, axisTitle), + nBins, min, max); + outList->Add(eff); + return eff; + }; + for (auto pdg : pdgCodes.value) { + effVsPt[pdg] = createEff("efficiency", "p_{T} (GeV/c)", pdg, 100, 0, 10); + effVsEta[pdg] = createEff("efficiency_eta", "#eta", pdg, 100, -5, 5); + } + } + + void process(soa::Join const& tracks, + aod::McParticles const& mcParticles) + { + std::map> pdgIndices; + + // Lambda function to select particles after all cuts + auto isParticleSelected = [&](const o2::aod::McParticle& p) { + if (!p.isPhysicalPrimary()) { + return false; + } + if (p.eta() < etaRange.value.first) { + return false; + } + if (p.eta() > etaRange.value.second) { + return false; + } + return true; + }; + for (const auto& track : tracks) { + if (!track.has_mcParticle()) { + continue; + } + const auto& mcParticle = track.mcParticle(); + if (!isParticleSelected(mcParticle)) { + continue; + } + pdgIndices[mcParticle.pdgCode()].push_back(mcParticle.globalIndex()); + } + + for (auto& mc : mcParticles) { + if (effVsPt.find(mc.pdgCode()) == effVsPt.end()) { + continue; + } + if (!isParticleSelected(mc)) { + continue; + } + std::vector& indices = pdgIndices[mc.pdgCode()]; + // Fill efficiency histogram + const bool found = std::find(indices.begin(), indices.end(), mc.globalIndex()) != indices.end(); + effVsPt[mc.pdgCode()]->Fill(found, mc.pt()); + effVsEta[mc.pdgCode()]->Fill(found, mc.eta()); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& ctx) +{ + return WorkflowSpec{adaptAnalysisTask(ctx)}; +} diff --git a/ALICE3/Tasks/alice3SeparationPower.cxx b/ALICE3/Tasks/alice3SeparationPower.cxx new file mode 100644 index 00000000000..c01cbdaf767 --- /dev/null +++ b/ALICE3/Tasks/alice3SeparationPower.cxx @@ -0,0 +1,108 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +/// +/// \file alice3SeparationPower.cxx +/// +/// \brief This task produces the separation power of the ALICE3 detector +/// +/// \author Nicolò Jacazio, Universita del Piemonte Orientale (IT) +/// \since May 13, 2025 +/// + +#include "ALICE3/DataModel/OTFRICH.h" +#include "ALICE3/DataModel/OTFTOF.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" + +#include "THashList.h" +#include "TProfile2D.h" + +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; + +std::array separationInnerTOF; +std::array separationOuterTOF; +std::array separationRICH; +struct alice3SeparationPower { + + ConfigurableAxis etaAxis{"etaAxis", {100, -1.f, 1.f}, "Binning in eta"}; + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + OutputObj listSeparation{"separationPower"}; + void init(o2::framework::InitContext&) + { + listSeparation.setObject(new THashList); + for (int i = 0; i < 5; i++) { + auto createEfficiency = [&](const char* name, const char* title) { + TProfile2D* eff = new TProfile2D(Form("%s_%d", name, i), + Form("%s_%d;%s", title, i, "#it{p}_{T} (GeV/#it{c});#it{#eta}"), + 100, 0.f, 10.f, + 100, 0.f, 10.f); + listSeparation->Add(eff); + return eff; + }; + separationInnerTOF[i] = createEfficiency("separationInnerTOF", "separationInnerTOF"); + separationOuterTOF[i] = createEfficiency("separationOuterTOF", "separationOuterTOF"); + separationRICH[i] = createEfficiency("separationRICH", "separationRICH"); + } + } + + void process(soa::Join::iterator const& /*collision*/, + soa::Join const& tracks, + aod::McParticles const&, + aod::McCollisions const&) + { + for (const auto& track : tracks) { + if (!track.has_mcParticle()) { + continue; + } + // Check that all the nsigmas are numbers (sanity check) + for (int i = 0; i < 5; i++) { + if (std::isnan(track.nSigmaInnerTOF(i)) || std::isnan(track.nSigmaOuterTOF(i))) { + LOG(fatal) << "Unrecognized nsigma for " << i << " " << track.nSigmaInnerTOF(i) << " " << track.nSigmaOuterTOF(i); + } + } + + const auto& mcParticle = track.mcParticle(); + // Separation electron pion + switch (std::abs(mcParticle.pdgCode())) { + { + case 211: // electron-pion separation + separationInnerTOF[0]->Fill(track.pt(), track.eta(), track.nSigmaInnerTOF(0)); + separationOuterTOF[0]->Fill(track.pt(), track.eta(), track.nSigmaOuterTOF(0)); + // separationRICH[0]->Fill(track.pt(), track.eta(), track.nSigmaElectronRich() ); + break; + case 321: // pion-kaon separation + separationInnerTOF[1]->Fill(track.pt(), track.eta(), track.nSigmaInnerTOF(1)); + separationOuterTOF[1]->Fill(track.pt(), track.eta(), track.nSigmaInnerTOF(1)); + // separationRICH[1]->Fill(track.pt(), track.eta(), track.nSigmaPionRich() ); + break; + case 2212: // kaon-proton separation + separationInnerTOF[2]->Fill(track.pt(), track.eta(), track.nSigmaInnerTOF(2)); + separationOuterTOF[2]->Fill(track.pt(), track.eta(), track.nSigmaInnerTOF(2)); + // separationRICH[2]->Fill((track.nSigmaKaonRich() > 3.f), track.pt(), track.eta()); + default: + break; + } + } + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; } diff --git a/CODEOWNERS b/CODEOWNERS index 43f250fdd0b..3891598e0e8 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -41,8 +41,8 @@ /PWGHF @alibuild @vkucera @fcolamar @fgrosa @fcatalan92 @mfaggin @mmazzilli @deepathoms @NicoleBastid @hahassan7 @jpxrk @apalasciano @zhangbiao-phy @gluparel # PWG-LF /PWGLF @alibuild @sustripathy @skundu692 -/PWGLF/Tasks/GlobalEventProperties @alibuild @sustripathy @skundu692 @gbencedi @abmodak -/PWGLF/TableProducer/GlobalEventProperties @alibuild @sustripathy @skundu692 @gbencedi @abmodak +/PWGLF/Tasks/GlobalEventProperties @alibuild @sustripathy @skundu692 @gbencedi @abmodak @omvazque +/PWGLF/TableProducer/GlobalEventProperties @alibuild @sustripathy @skundu692 @gbencedi @abmodak @omvazque /PWGLF/Tasks/Nuspex @alibuild @sustripathy @skundu692 @fmazzasc @chiarapinto @maciacco /PWGLF/TableProducer/Nuspex @alibuild @sustripathy @skundu692 @fmazzasc @chiarapinto @maciacco /PWGLF/Tasks/Resonances @alibuild @sustripathy @skundu692 @dmallick2 @smaff92 diff --git a/CPPLINT.cfg b/CPPLINT.cfg index 7f7d3c357c3..96a8077f685 100644 --- a/CPPLINT.cfg +++ b/CPPLINT.cfg @@ -1 +1 @@ -filter=-build/c++11,-build/namespaces,-readability/fn_size,-readability/todo,-runtime/references,-whitespace/blank_line,-whitespace/braces,-whitespace/comments,-whitespace/indent_namespace,-whitespace/line_length,-whitespace/semicolon,-whitespace/todo +filter=-build/c++11,-build/include_order,-build/namespaces,-readability/fn_size,-readability/todo,-runtime/references,-whitespace/blank_line,-whitespace/braces,-whitespace/comments,-whitespace/indent_namespace,-whitespace/line_length,-whitespace/semicolon,-whitespace/todo diff --git a/Common/CCDB/macros/upload_event_selection_params.C b/Common/CCDB/macros/upload_event_selection_params.C index 5d63cf49be8..8296dc0f78a 100644 --- a/Common/CCDB/macros/upload_event_selection_params.C +++ b/Common/CCDB/macros/upload_event_selection_params.C @@ -9,12 +9,15 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "CCDB/CcdbApi.h" +#include "EventSelectionParams.h" + #include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" + #include "TString.h" -#include "map" -#include "string" -#include "EventSelectionParams.h" + +#include +#include using std::map; using std::string; diff --git a/Common/CCDB/macros/upload_event_selection_params_run3.C b/Common/CCDB/macros/upload_event_selection_params_run3.C index b439959fe1c..a5eff518fe7 100644 --- a/Common/CCDB/macros/upload_event_selection_params_run3.C +++ b/Common/CCDB/macros/upload_event_selection_params_run3.C @@ -9,11 +9,14 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +#include "EventSelectionParams.h" + #include "CCDB/CcdbApi.h" + #include "TString.h" -#include "map" -#include "string" -#include "EventSelectionParams.h" + +#include +#include using std::map; using std::string; diff --git a/Common/TableProducer/CMakeLists.txt b/Common/TableProducer/CMakeLists.txt index 042bd643d3e..1d6918d6121 100644 --- a/Common/TableProducer/CMakeLists.txt +++ b/Common/TableProducer/CMakeLists.txt @@ -62,6 +62,11 @@ o2physics_add_dpl_workflow(track-propagation PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(track-dca-cov-filler-run2 + SOURCES trackDcaCovFillerRun2.cxx + PUBLIC_LINK_LIBRARIES O2::DetectorsBase O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(track-propagation-tester SOURCES trackPropagationTester.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::trackSelectionRequest diff --git a/Common/TableProducer/eventSelection.cxx b/Common/TableProducer/eventSelection.cxx index e2aa27f6efe..3c989f1848a 100644 --- a/Common/TableProducer/eventSelection.cxx +++ b/Common/TableProducer/eventSelection.cxx @@ -95,15 +95,6 @@ struct BcSelectionTask { bool isGoodITSLayersAll = true; // default value void init(InitContext&) { - if (metadataInfo.isFullyDefined() && !doprocessRun2 && !doprocessRun3) { // Check if the metadata is initialized (only if not forced from the workflow configuration) - LOG(info) << "Autosetting the processing mode (Run2 or Run3) based on metadata"; - if (metadataInfo.isRun3()) { - doprocessRun3.value = true; - } else { - doprocessRun2.value = true; - } - } - // ccdb->setURL("http://ccdb-test.cern.ch:8080"); ccdb->setURL("http://alice-ccdb.cern.ch"); ccdb->setCaching(true); @@ -580,14 +571,6 @@ struct EventSelectionTask { void init(InitContext&) { if (metadataInfo.isFullyDefined()) { // Check if the metadata is initialized (only if not forced from the workflow configuration) - if (!doprocessRun2 && !doprocessRun3) { - LOG(info) << "Autosetting the processing mode (Run2 or Run3) based on metadata"; - if (metadataInfo.isRun3()) { - doprocessRun3.value = true; - } else { - doprocessRun2.value = true; - } - } if (isMC == -1) { LOG(info) << "Autosetting the MC mode based on metadata"; if (metadataInfo.isMC()) { @@ -1186,15 +1169,6 @@ struct LumiTask { void init(InitContext&) { - if (metadataInfo.isFullyDefined() && !doprocessRun3 && !doprocessRun3) { // Check if the metadata is initialized (only if not forced from the workflow configuration) - LOG(info) << "Autosetting the processing mode (Run2 or Run3) based on metadata"; - if (metadataInfo.isRun3()) { - doprocessRun3.value = true; - } else { - doprocessRun2.value = true; - } - } - histos.add("hCounterTVX", "", kTH1D, {{1, 0., 1.}}); histos.add("hCounterTCE", "", kTH1D, {{1, 0., 1.}}); histos.add("hCounterZEM", "", kTH1D, {{1, 0., 1.}}); @@ -1249,7 +1223,7 @@ struct LumiTask { LOGP(debug, "Dummy process function for Run 2"); } - PROCESS_SWITCH(LumiTask, processRun2, "Process Run2 lumi task", false); + PROCESS_SWITCH(LumiTask, processRun2, "Process Run2 lumi task", true); void processRun3(BCsWithBcSelsRun3 const& bcs, aod::FT0s const&) { @@ -1277,12 +1251,12 @@ struct LumiTask { csZNC = -1; // Temporary workaround to get visible cross section. TODO: store run-by-run visible cross sections in CCDB if (beamZ1 == 1 && beamZ2 == 1) { - if (std::fabs(sqrts - 900.) < 20.) { // o2-linter: disable=magic-number (TODO store and extract cross sections from ccdb) - csTVX = 0.0357e6; // ub - } else if (std::fabs(sqrts - 5360.) < 20.) { // pp-ref // o2-linter: disable=magic-number (TODO store and extract cross sections from ccdb) - csTVX = 0.0503e6; // ub - } else if (std::fabs(sqrts - 13600.) < 20.) { // o2-linter: disable=magic-number (TODO store and extract cross sections from ccdb) - csTVX = 0.0594e6; // ub + if (std::fabs(sqrts - 900.) < 100.) { // o2-linter: disable=magic-number (TODO store and extract cross sections from ccdb) + csTVX = 0.0357e6; // ub + } else if (std::fabs(sqrts - 5360.) < 100.) { // pp-ref // o2-linter: disable=magic-number (TODO store and extract cross sections from ccdb) + csTVX = 0.0503e6; // ub + } else if (std::fabs(sqrts - 13600.) < 300.) { // o2-linter: disable=magic-number (TODO store and extract cross sections from ccdb) + csTVX = 0.0594e6; // ub } else { LOGP(warn, "Cross section for pp @ {} GeV is not defined", sqrts); } @@ -1346,13 +1320,14 @@ struct LumiTask { mOrbits.push_back(record.intRecord.orbit); mCounterTVX.push_back(classIdTVX >= 0 ? record.scalers[classIdTVX].lmBefore : 0); mCounterTCE.push_back(classIdTCE >= 0 ? record.scalers[classIdTCE].lmBefore : 0); - if (run >= 543437 && run < 544448) { // o2-linter: disable=magic-number (ZNC class not defined for this run range) - mCounterZNC.push_back(record.scalersInps[25]); // see ZNC=1ZNC input index in https://indico.cern.ch/event/1153630/contributions/4844362/ + if (run >= 543437 && run < 544448 && record.scalersInps.size() >= 26) { // o2-linter: disable=magic-number (ZNC class not defined for this run range) + mCounterZNC.push_back(record.scalersInps[25]); // see ZNC=1ZNC input index in https://indico.cern.ch/event/1153630/contributions/4844362/ } else { mCounterZNC.push_back(classIdZNC >= 0 ? record.scalers[classIdZNC].l1Before : 0); } // ZEM class not defined, using inputs instead - mCounterZEM.push_back(record.scalersInps[24]); // see ZEM=1ZED input index in https://indico.cern.ch/event/1153630/contributions/4844362/ + uint32_t indexZEM = 24; // see ZEM=1ZED input index in https://indico.cern.ch/event/1153630/contributions/4844362/ + mCounterZEM.push_back(record.scalersInps.size() >= indexZEM + 1 ? record.scalersInps[indexZEM] : 0); } // calculate pileup corrections diff --git a/Common/TableProducer/occupancyTableProducer.cxx b/Common/TableProducer/occupancyTableProducer.cxx index 2e4a01ddbb1..95d1ca72dea 100644 --- a/Common/TableProducer/occupancyTableProducer.cxx +++ b/Common/TableProducer/occupancyTableProducer.cxx @@ -1692,7 +1692,7 @@ struct TrackMeanOccTableProducer { } } - using MyTracksQA = aod::TracksQA_002; + using MyTracksQA = aod::TracksQAVersion; // using MyTracksQA = aod::TracksQA_002; // Process the Data int dfCount = 0; diff --git a/Common/TableProducer/trackDcaCovFillerRun2.cxx b/Common/TableProducer/trackDcaCovFillerRun2.cxx new file mode 100644 index 00000000000..ca56615dfee --- /dev/null +++ b/Common/TableProducer/trackDcaCovFillerRun2.cxx @@ -0,0 +1,181 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file trackDcaCovFillerRun2.cxx +/// \author Aimeric Landou , CERN +/// \brief Fills DCA and DCA Cov tables for Run 2 tracks +// Run 2 AO2Ds cannot have their dcacov filled by the current track-propagation workflow as the workflow isn't designed for them, given Run 2 tracks are already propagated to the PV. +// This task fills the DCA Cov (and DCA) tables for Run 2 tracks by "propagating" the tracks (though given they are already at the PV it doesn't actually do the propagation) and retrieving the DCA and DCA cov given by the propagateToDCABxByBz function + +#include "TableHelper.h" + +#include "Common/Tools/TrackTuner.h" + +#include "DataFormatsParameters/GRPObject.h" + +#include + +using namespace o2; +using namespace o2::framework; +// using namespace o2::framework::expressions; + +struct TrackDcaCovFillerRun2 { + Produces tracksDCA; + Produces tracksDCACov; + + // Produces tunertable; + + Service ccdb; + + bool fillTracksDCA = false; + bool fillTracksDCACov = false; + int runNumber = -1; + + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; + + const o2::dataformats::MeanVertexObject* mMeanVtx = nullptr; + o2::parameters::GRPMagField* grpmag = nullptr; + o2::base::MatLayerCylSet* lut = nullptr; + + Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "CCDB path of the grp file (run2)"}; + Configurable mVtxPath{"mVtxPath", "GLO/Calib/MeanVertex", "Path of the mean vertex file"}; + + HistogramRegistry registry{"registry"}; + + void init(o2::framework::InitContext& initContext) + { + // Checking if the tables are requested in the workflow and enabling them + fillTracksDCA = isTableRequiredInWorkflow(initContext, "TracksDCA"); + fillTracksDCACov = isTableRequiredInWorkflow(initContext, "TracksDCACov"); + + ccdb->setURL(ccdburl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + } + + void initCCDB(aod::BCsWithTimestamps::iterator const& bc) + { + if (runNumber == bc.runNumber()) { + return; + } + + // Run 2 GRP object + o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp(ccdbPathGrp, bc.timestamp()); + if (grpo == nullptr) { + LOGF(fatal, "Run 2 GRP object (type o2::parameters::GRPObject) is not available in CCDB for run=%d at timestamp=%llu", bc.runNumber(), bc.timestamp()); + } + o2::base::Propagator::initFieldFromGRP(grpo); + LOGF(info, "Setting magnetic field to %d kG for run %d from its GRP CCDB object (type o2::parameters::GRPObject)", grpo->getNominalL3Field(), bc.runNumber()); + + mMeanVtx = ccdb->getForTimeStamp(mVtxPath, bc.timestamp()); + runNumber = bc.runNumber(); + } + + // Running variables + std::array mDcaInfo; + o2::dataformats::DCA mDcaInfoCov; + o2::dataformats::VertexBase mVtx; + o2::track::TrackParametrization mTrackPar; + o2::track::TrackParametrizationWithError mTrackParCov; + + template + void fillTrackTables(TTrack const& tracks, + TParticle const&, + aod::Collisions const&, + aod::BCsWithTimestamps const& bcs) + { + if (bcs.size() == 0) { + return; + } + initCCDB(bcs.begin()); + + if constexpr (fillCovMat) { + if (fillTracksDCACov) { + tracksDCACov.reserve(tracks.size()); + } + } else { + if (fillTracksDCA) { + tracksDCA.reserve(tracks.size()); + } + } + + for (auto const& track : tracks) { + if constexpr (fillCovMat) { + if (fillTracksDCA || fillTracksDCACov) { + mDcaInfoCov.set(999, 999, 999, 999, 999); + } + setTrackParCov(track, mTrackParCov); + } else { + if (fillTracksDCA) { + mDcaInfo[0] = 999; + mDcaInfo[1] = 999; + } + setTrackPar(track, mTrackPar); + } + + if (track.has_collision()) { + auto const& collision = track.collision(); + if constexpr (fillCovMat) { + mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); + mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, mTrackParCov, 2.f, matCorr, &mDcaInfoCov); + } else { + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, mTrackPar, 2.f, matCorr, &mDcaInfo); + } + } else { + if constexpr (fillCovMat) { + mVtx.setPos({mMeanVtx->getX(), mMeanVtx->getY(), mMeanVtx->getZ()}); + mVtx.setCov(mMeanVtx->getSigmaX() * mMeanVtx->getSigmaX(), 0.0f, mMeanVtx->getSigmaY() * mMeanVtx->getSigmaY(), 0.0f, 0.0f, mMeanVtx->getSigmaZ() * mMeanVtx->getSigmaZ()); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, mTrackParCov, 2.f, matCorr, &mDcaInfoCov); + } else { + o2::base::Propagator::Instance()->propagateToDCABxByBz({mMeanVtx->getX(), mMeanVtx->getY(), mMeanVtx->getZ()}, mTrackPar, 2.f, matCorr, &mDcaInfo); + } + } + + if constexpr (fillCovMat) { + if (fillTracksDCA) { + tracksDCA(mDcaInfoCov.getY(), mDcaInfoCov.getZ()); + } + if (fillTracksDCACov) { + tracksDCACov(mDcaInfoCov.getSigmaY2(), mDcaInfoCov.getSigmaZ2()); + } + } else { + if (fillTracksDCA) { + tracksDCA(mDcaInfo[0], mDcaInfo[1]); + } + } + } + } + + void processCovariance(soa::Join const& tracks, aod::Collisions const& collisions, aod::BCsWithTimestamps const& bcs) + { + fillTrackTables, /*Particle*/ soa::Join, /*isMc = */ false, /*fillCovMat =*/true>(tracks, tracks, collisions, bcs); + } + PROCESS_SWITCH(TrackDcaCovFillerRun2, processCovariance, "Process with covariance", false); + + void processStandard(soa::Join const& tracks, aod::Collisions const& collisions, aod::BCsWithTimestamps const& bcs) + { + fillTrackTables, /*Particle*/ soa::Join, /*isMc = */ false, /*fillCovMat =*/false>(tracks, tracks, collisions, bcs); + } + PROCESS_SWITCH(TrackDcaCovFillerRun2, processStandard, "Process without covariance", true); +}; + +//**************************************************************************************** +/** + * Workflow definition. + */ +//**************************************************************************************** +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + return workflow; +} diff --git a/Common/Tasks/CMakeLists.txt b/Common/Tasks/CMakeLists.txt index a63d0146e34..64d4f7e6611 100644 --- a/Common/Tasks/CMakeLists.txt +++ b/Common/Tasks/CMakeLists.txt @@ -87,4 +87,9 @@ o2physics_add_dpl_workflow(centrality-study o2physics_add_dpl_workflow(flow-test SOURCES flowTest.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(muon-qa + SOURCES qaMuon.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::Field O2::DetectorsBase O2::DetectorsCommonDataFormats O2::MathUtils O2::MCHTracking O2::DataFormatsMCH O2::GlobalTracking O2::MCHBase O2::MCHGeometryTransformer O2::CommonUtils COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/Common/Tasks/qaMuon.cxx b/Common/Tasks/qaMuon.cxx new file mode 100644 index 00000000000..3c96a06bddc --- /dev/null +++ b/Common/Tasks/qaMuon.cxx @@ -0,0 +1,2584 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +/// \brief The task for muon QA +/// \author Andrea Ferrero +/// \author Paul Veen +/// \author Chi Zhang + +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/FwdTrackReAlignTables.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CCDBTimeStampUtils.h" +#include "CommonUtils/ConfigurableParam.h" +#include "CommonUtils/NameConf.h" +#include "DataFormatsMCH/Cluster.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GRPGeomHelper.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Field/MagneticField.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "GlobalTracking/MatchGlobalFwd.h" +#include "MCHBase/TrackerParam.h" +#include "MCHGeometryTransformer/Transformations.h" +#include "MCHTracking/Track.h" +#include "MCHTracking/TrackExtrap.h" +#include "MCHTracking/TrackFitter.h" +#include "MCHTracking/TrackParam.h" +#include "MathUtils/Cartesian.h" +#include "ReconstructionDataFormats/TrackFwd.h" + +#include "Math/Vector4D.h" +#include "TGeoGlobalMagField.h" + +#include + +using namespace std; +using namespace o2; +using namespace o2::aod; +using namespace o2::mch; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using MyEvents = soa::Join; +using MyMuonsWithCov = soa::Join; +using MyMFTs = aod::MFTTracks; + +using SMatrix55 = ROOT::Math::SMatrix>; +using SMatrix5 = ROOT::Math::SVector; + +using MuonPair = std::pair, std::pair>; +using GlobalMuonPair = std::pair>, std::pair>>; + +const int fgNCh = 10; +const int fgNDetElemCh[fgNCh] = {4, 4, 4, 4, 18, 18, 26, 26, 26, 26}; +const int fgSNDetElemCh[fgNCh + 1] = {0, 4, 8, 12, 16, 34, 52, 78, 104, 130, 156}; +const float zAtAbsEnd = -505.; + +constexpr double firstMFTPlaneZ = o2::mft::constants::mft::LayerZCoordinate()[0]; +constexpr double lastMFTPlaneZ = o2::mft::constants::mft::LayerZCoordinate()[9]; + +std::array zRefPlane{ + firstMFTPlaneZ, + lastMFTPlaneZ, + -90.0, + -300.0, + //-505.0, + -520.0}; + +std::vector> referencePlanes{ + {"MFT-begin", 10.0}, + {"MFT-end", 15.0}, + {"Absorber-begin", 20.0}, + {"Absorber-mid", 75.0}, + //{"Absorber-end", 100.0}, + {"MCH-begin", 100.0}}; + +enum MuonExtrapolation { + // Index used to set different options for muon propagation + kToVtx = 0, // propagtion to vertex by default + kToDCA, + kToAbsEnd, + kToZ +}; + +struct VarColl { + int64_t globalIndex = 0; + float x = 0.f; + float y = 0.f; + float z = 0.f; + float covXX = 0.f; + float covYY = 0.f; + int64_t bc = 0; + int multMFT = 0; +}; + +struct VarTrack { + int64_t collisionId = -1; + int64_t globalIndex = 0; + int nClusters = 0; // Only MCH + int sign = 0; + int64_t bc = 0; + int trackType = 0; + float trackTime = 0.f; + + // Basic kinematics + float x = 0.f; + float y = 0.f; + float z = 0.f; + float eta = 0.f; + float phi = 0.f; + float tgl = 0.f; + + float px = 0.f; + float py = 0.f; + float pz = 0.f; + float pT = 0.f; + float p = 0.f; + + // Propagation related infos + float dcaX = 0.f; + float dcaY = 0.f; + float pDca = 0.f; + float rabs = 0.f; + float chi2 = 0.f; + float chi2matching = 0.f; +}; + +struct VarClusters { + vector> posClusters; // (x,y,z) + vector> errorClusters; // (ex,ey) + vector DEIDs; +}; + +struct muonQa { + //// Variables for enabling QA options + struct : ConfigurableGroup { + Configurable fEnableQAMatching{"cfgEnableQAMatching", false, "Enable MCH-MFT matching QA checks"}; + Configurable fEnableQAResidual{"cfgEnableQAResidual", false, "Enable residual QA checks"}; + Configurable fEnableQADCA{"cfgEnableQADCA", false, "Enable DCA QA checks"}; + Configurable fEnableQADimuon{"cfgEnableQADimuon", false, "Enable dimuon QA checks"}; + } configQAs; + + //// Variables for selecting muon tracks + struct : ConfigurableGroup { + Configurable fPMchLow{"cfgPMchLow", 0.0f, ""}; + Configurable fPtMchLow{"cfgPtMchLow", 0.7f, ""}; + Configurable fEtaMchLow{"cfgEtaMchLow", -4.0f, ""}; + Configurable fEtaMchUp{"cfgEtaMchUp", -2.5f, ""}; + Configurable fRabsLow{"cfgRabsLow", 17.6f, ""}; + Configurable fRabsUp{"cfgRabsUp", 89.5f, ""}; + Configurable fSigmaPdcaUp{"cfgPdcaUp", 6.f, ""}; + Configurable fTrackChi2MchUp{"cfgTrackChi2MchUp", 5.f, ""}; + Configurable fMatchingChi2MchMidUp{"cfgMatchingChi2MchMidUp", 999.f, ""}; + } configMuons; + + //// Variables for selecting mft tracks + struct : ConfigurableGroup { + Configurable fEtaMftLow{"cfgEtaMftlow", -3.6f, ""}; + Configurable fEtaMftUp{"cfgEtaMftup", -2.5f, ""}; + Configurable fTrackNClustMftLow{"cfgTrackNClustMftLow", 7, ""}; + Configurable fTrackChi2MftUp{"cfgTrackChi2MftUp", 999.f, ""}; + } configMFTs; + + //// Variables for selecting global tracks + Configurable fMatchingChi2MftMchUp{"cfgMatchingChi2MftMchUp", 50.f, ""}; + + //// Variables for alignment corrections + Configurable fEnableMFTAlignmentCorrections{"cfgEnableMFTAlignmentCorrections", false, ""}; + + //// Variables for re-alignment setup + struct : ConfigurableGroup { + Configurable fDoRealign{"cfgDoRealign", false, "Switch to apply re-alignment"}; + Configurable fChamberResolutionX{"cfgChamberResolutionX", 0.4, "Chamber resolution along X configuration for refit"}; // 0.4cm pp, 0.2cm PbPb + Configurable fChamberResolutionY{"cfgChamberResolutionY", 0.4, "Chamber resolution along Y configuration for refit"}; // 0.4cm pp, 0.2cm PbPb + Configurable fSigmaCutImprove{"cfgSigmaCutImprove", 6., "Sigma cut for track improvement"}; + } configRealign; + + /// Variables to event mixing criteria + struct : ConfigurableGroup { + Configurable fEventMaxDeltaNMFT{"cfgEventMaxDeltaNMFT", 1, ""}; + Configurable fEventMaxDeltaVtxZ{"cfgEventMaxDeltaVtxZ", 1.f, ""}; + Configurable fEventMinDeltaBc{"cfgEventMinDeltaBc", 500, ""}; + } configMixing; + + //// Variables for ccdb + struct : ConfigurableGroup { + Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + Configurable geoPathRealign{"geoPathRealign", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + Configurable nolaterthan{"ccdb-no-later-than-ref", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object of reference basis"}; + Configurable nolaterthanRealign{"ccdb-no-later-than-new", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object of new basis"}; + } configCCDB; + + //// Variables for histograms configuration + Configurable fNCandidatesMax{"nCandidatesMax", 5, ""}; + + parameters::GRPMagField* grpmag = nullptr; + TrackFitter trackFitter; // Track fitter from MCH tracking library + + globaltracking::MatchGlobalFwd mMatching; + int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. + double mImproveCutChi2; // Chi2 cut for track improvement. + Service ccdb; + o2::field::MagneticField* fieldB = nullptr; + double Bz; // Bz for MFT + + geo::TransformationCreator transformation; + map transformRef; // reference geometry w.r.t track data + map transformNew; // new geometry + TGeoManager* geoNew = nullptr; + TGeoManager* geoRef = nullptr; + + Preslice perMuon = aod::fwdtrkcl::fwdtrackId; + Preslice fwdtracksPerCollision = aod::fwdtrack::collisionId; + Preslice mftPerCollision = aod::fwdtrack::collisionId; + + HistogramRegistry registry{"registry", {}}; + HistogramRegistry registryDCA{"registryDCA", {}}; + HistogramRegistry registryResiduals{"registryResiduals", {}}; + HistogramRegistry registryResidualsMFT{"registryResidualsMFT", {}}; + HistogramRegistry registryResidualsMCH{"registryResidualsMCH", {}}; + HistogramRegistry registryDimuon{"registryDimuon", {}}; + + std::array quadrants = {"Q0", "Q1", "Q2", "Q3"}; + + std::array, 3>, 4>, 2> dcaHistos; + std::array, 3>, 4>, 2> dcaHistosMixedEvents; + + std::array, 4>, 6> trackResidualsHistos; + std::array, 4>, 6> trackResidualsHistosMixedEvents; + + std::array, 10>, 4> residualsHistos; + std::array, 10>, 4> residualsHistosMixedEvents; + + std::array, 10>, 2>, 2> residualsHistosPerDE; + std::array, 10>, 2>, 2> residualsHistosPerDEMixedEvents; + + std::array, 10>, 2>, 2> mchResidualsHistosPerDE; + std::array, 10>, 2>, 2> mchResidualsHistosPerDEMixedEvents; + + VarTrack fgValuesMCH; + VarTrack fgValuesMCHpv; + VarTrack fgValuesMFT; + VarTrack fgValuesGlobal; + vector fgValuesCandidates; + + void CreateBasicHistograms() + { + // ====================== + // Muons plots + // ====================== + + AxisSpec chi2Axis = {1000, 0, 1000, "chi2"}; + AxisSpec momentumAxis = {1000, 0, 1000, "p (GeV/c)"}; + AxisSpec transverseMomentumAxis = {1000, 0, 100, "p_{T} (GeV/c)"}; + AxisSpec etaAxis = {80, -5, -1, "#eta"}; + AxisSpec rAbsAxis = {100, 0., 100.0, "R_{abs} (cm)"}; + AxisSpec dcaAxis = {400, 0.0, 20.0, "DCA"}; + AxisSpec pdcaAxis = {5000, 0.0, 5000.0, "p #times DCA"}; + AxisSpec phiAxis = {360, -180.0, 180.0, "#phi (degrees)"}; + + registry.add("muons/TrackChi2", "MCH track #chi^{2}", {HistType::kTH1F, {chi2Axis}}); + registry.add("muons/TrackP", "MCH track momentum", {HistType::kTH1F, {momentumAxis}}); + registry.add("muons/TrackPt", "MCH track transverse momentum", {HistType::kTH1F, {transverseMomentumAxis}}); + registry.add("muons/TrackEta", "MCH track #eta", {HistType::kTH1F, {etaAxis}}); + registry.add("muons/TrackRabs", "MCH track R_{abs}", {HistType::kTH1F, {rAbsAxis}}); + registry.add("muons/TrackDCA", "MCH track DCA", {HistType::kTH1F, {dcaAxis}}); + registry.add("muons/TrackPDCA", "MCH track p #times DCA", {HistType::kTH1F, {pdcaAxis}}); + registry.add("muons/TrackPhi", "MCH track #phi", {HistType::kTH1F, {phiAxis}}); + + // ====================== + // Global muons plots + // ====================== + int nTrackTypes = static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::MCHStandaloneTrack) + 1; + AxisSpec trackTypeAxis = {static_cast(nTrackTypes), 0.0, static_cast(nTrackTypes), "track type"}; + registry.add("global-muons/nTracksPerType", "Number of tracks per type", {HistType::kTH1F, {trackTypeAxis}}); + + AxisSpec nCandidatesAxis = {static_cast(fNCandidatesMax), 0.0, static_cast(fNCandidatesMax), "match candidate rank"}; + registry.add("global-muons/NCandidates", "Number of MFT-MCH match candidates", {HistType::kTH1F, {nCandidatesAxis}}); + registry.add("global-muons/MatchChi2", "MFT-MCH match chi2", {HistType::kTH2F, {chi2Axis, nCandidatesAxis}}); + + registry.add("global-muons/TrackChi2", "Muon track #chi^{2}", {HistType::kTH1F, {chi2Axis}}); + registry.add("global-muons/TrackP", "Muon track momentum", {HistType::kTH1F, {momentumAxis}}); + registry.add("global-muons/TrackPt", "Muon track transverse momentum", {HistType::kTH1F, {transverseMomentumAxis}}); + registry.add("global-muons/TrackEta", "Muon track #eta", {HistType::kTH1F, {etaAxis}}); + registry.add("global-muons/TrackRabs", "Muon track R_{abs}", {HistType::kTH1F, {rAbsAxis}}); + registry.add("global-muons/TrackDCA", "Muon track DCA", {HistType::kTH1F, {dcaAxis}}); + registry.add("global-muons/TrackPDCA", "Muon track p #times DCA", {HistType::kTH1F, {pdcaAxis}}); + registry.add("global-muons/TrackPhi", "Muon track #phi", {HistType::kTH1F, {phiAxis}}); + + // ====================== + // Global muon plots with matching cuts + // ====================== + + if (configQAs.fEnableQAMatching) { + AxisSpec dbcAxis = {1000, -500, 500, "#Delta_{BC}"}; + registry.add("global-matches/BCdifference", "MCH-MFT BC difference", {HistType::kTH1F, {dbcAxis}}); + + AxisSpec nClustersAxis = {20, 0, 20, "# of MFT clusters per track"}; + + registry.add("global-matches/MatchChi2", "MFT-MCH match chi2", {HistType::kTH1F, {chi2Axis}}); + + registry.add("global-matches/TrackChi2_MFT", "MFT track #chi^{2}", {HistType::kTH1F, {chi2Axis}}); + registry.add("global-matches/TrackNclusters_MFT", "MFT track Nclusters", {HistType::kTH1F, {nClustersAxis}}); + + registry.add("global-matches/TrackChi2", "Muon track #chi^{2}", {HistType::kTH1F, {chi2Axis}}); + registry.add("global-matches/TrackP", "Muon track momentum", {HistType::kTH1F, {momentumAxis}}); + registry.add("global-matches/TrackPt", "Muon track transverse momentum", {HistType::kTH1F, {transverseMomentumAxis}}); + registry.add("global-matches/TrackEta", "Muon track #eta", {HistType::kTH1F, {etaAxis}}); + registry.add("global-matches/TrackRabs", "Muon track R_{abs}", {HistType::kTH1F, {rAbsAxis}}); + registry.add("global-matches/TrackDCA", "Muon track DCA", {HistType::kTH1F, {dcaAxis}}); + registry.add("global-matches/TrackPDCA", "Muon track p #times DCA", {HistType::kTH1F, {pdcaAxis}}); + registry.add("global-matches/TrackPhi", "Muon track #phi", {HistType::kTH1F, {phiAxis}}); + + registry.add("global-matches/TrackP_glo", "Global muon track momentum", {HistType::kTH1F, {momentumAxis}}); + registry.add("global-matches/TrackPt_glo", "Global muon track transverse momentum", {HistType::kTH1F, {transverseMomentumAxis}}); + registry.add("global-matches/TrackEta_glo", "Global muon track #eta", {HistType::kTH1F, {etaAxis}}); + registry.add("global-matches/TrackDCA_glo", "Global muon track DCA", {HistType::kTH1F, {dcaAxis}}); + registry.add("global-matches/TrackPhi_glo", "Global muon track #phi", {HistType::kTH1F, {phiAxis}}); + } + + AxisSpec momentumCorrelationAxis = {100, 0, 100, "momentum (GeV/c)"}; + AxisSpec momentumDeltaAxis = {100, -1, 1, "#DeltaP (GeV/c)"}; + // Momentum correlations + registry.add("global-muons/MomentumCorrelation_Global_vs_Muon", + "P_{global} vs. P_{MCH}", + {HistType::kTH2F, {momentumCorrelationAxis, momentumCorrelationAxis}}); + registry.add("global-muons/MomentumDifference_Global_vs_Muon", + "(P_{global} - P_{MCH}) / P_{MCH} vs. P_{MCH}", + {HistType::kTH2F, {momentumCorrelationAxis, momentumDeltaAxis}}); + registry.add("global-muons/MomentumCorrelation_subleading_vs_leading", + "P_{subleading_match} vs. P_{leading_match}", + {HistType::kTH2F, {momentumCorrelationAxis, momentumCorrelationAxis}}); + registry.add("global-muons/MomentumDifference_subleading_vs_leading", + "(P_{subleading_match} - P_{leading_match}) / P_{leading_match} vs. P_{leading_match}", + {HistType::kTH2F, {momentumCorrelationAxis, momentumDeltaAxis}}); + + // AxisSpec etaAxis = {100, -5.0, -2.0, "#eta"}; + AxisSpec etaCorrelationAxis = {80, -5.0, -1.0, "#eta"}; + AxisSpec etaDeltaAxis = {100, -0.2, 0.2, "#Delta#eta"}; + // Eta correlations + registry.add("global-muons/EtaCorrelation_Global_vs_Muon", + "#eta_{global} vs. #eta_{MCH}", + {HistType::kTH2F, {etaCorrelationAxis, etaCorrelationAxis}}); + registry.add("global-muons/EtaDifference_Global_vs_Muon", + "(#eta_{global} - #eta_{MCH}) / #eta_{MCH} vs. #eta_{MCH}", + {HistType::kTH2F, {etaCorrelationAxis, etaDeltaAxis}}); + registry.add("global-muons/EtaCorrelation_subleading_vs_leading", + "#eta_{subleading_match} vs. #eta_{leading_match}", + {HistType::kTH2F, {etaCorrelationAxis, etaCorrelationAxis}}); + registry.add("global-muons/EtaDifference_subleading_vs_leading", + "(#eta_{subleading_match} - #eta_{leading_match}) / #eta_{leading_match} vs. #eta_{leading_match}", + {HistType::kTH2F, {etaCorrelationAxis, etaDeltaAxis}}); + } + + void CreateDetailedHistograms() + { + AxisSpec dcaxMFTAxis = {400, -0.5, 0.5, "DCA_{x} (cm)"}; + AxisSpec dcayMFTAxis = {400, -0.5, 0.5, "DCA_{y} (cm)"}; + AxisSpec dcaxMCHAxis = {400, -10.0, 10.0, "DCA_{x} (cm)"}; + AxisSpec dcayMCHAxis = {400, -10.0, 10.0, "DCA_{y} (cm)"}; + AxisSpec dcazAxis = {20, -10.0, 10.0, "DCA_{z} (cm)"}; + AxisSpec dxAxis = {600, -30.0, 30.0, "#Delta x (cm)"}; + AxisSpec dyAxis = {600, -30.0, 30.0, "#Delta y (cm)"}; + AxisSpec thetaxAxis = {10, 0.0, 20.0, "#theta_{x} (degrees)"}; + AxisSpec dThetaxAxis = {500, -5.0, 5.0, "#Delta#theta_{x} (degrees)"}; + AxisSpec thetayAxis = {10, 0.0, 20.0, "#theta_{y} (degrees)"}; + AxisSpec dThetayAxis = {500, -5.0, 5.0, "#Delta#theta_{y} (degrees)"}; + AxisSpec phiAxis = {360, -180.0, 180.0, "#phi (degrees)"}; + AxisSpec dPhiAxis = {200, -20.0, 20.0, "#Delta#phi (degrees)"}; + + if (configQAs.fEnableQAResidual) { + for (size_t i = 0; i < referencePlanes.size(); i++) { + const auto& refPLane = referencePlanes[i]; + AxisSpec xAxis = {10, 0, refPLane.second, "|x| (cm)"}; + AxisSpec yAxis = {10, 0, refPLane.second, "|y| (cm)"}; + for (size_t j = 0; j < quadrants.size(); j++) { + const auto& quadrant = quadrants[j]; + std::string histPath = std::string("Alignment/same-event/Residuals/ReferencePlanes/") + refPLane.first + "/" + quadrant + "/"; + trackResidualsHistos[i][j]["dx_vs_x"] = registry.add((histPath + "dx_vs_x").c_str(), std::format("#Delta x vs. |x| - {}", quadrant).c_str(), {HistType::kTH2F, {xAxis, dxAxis}}); + trackResidualsHistos[i][j]["dx_vs_y"] = registry.add((histPath + "dx_vs_y").c_str(), std::format("#Delta x vs. |y| - {}", quadrant).c_str(), {HistType::kTH2F, {yAxis, dxAxis}}); + trackResidualsHistos[i][j]["dy_vs_x"] = registry.add((histPath + "dy_vs_x").c_str(), std::format("#Delta y vs. |x| - {}", quadrant).c_str(), {HistType::kTH2F, {xAxis, dyAxis}}); + trackResidualsHistos[i][j]["dy_vs_y"] = registry.add((histPath + "dy_vs_y").c_str(), std::format("#Delta y vs. |y| - {}", quadrant).c_str(), {HistType::kTH2F, {yAxis, dyAxis}}); + + trackResidualsHistos[i][j]["dthetax_vs_x"] = registry.add((histPath + "dthetax_vs_x").c_str(), std::format("#Delta #theta_x vs. |x| - {}", quadrant).c_str(), {HistType::kTH2F, {xAxis, dThetaxAxis}}); + trackResidualsHistos[i][j]["dthetax_vs_y"] = registry.add((histPath + "dthetax_vs_y").c_str(), std::format("#Delta #theta_x vs. |y| - {}", quadrant).c_str(), {HistType::kTH2F, {yAxis, dThetaxAxis}}); + trackResidualsHistos[i][j]["dthetax_vs_thetax"] = registry.add((histPath + "dthetax_vs_thetax").c_str(), std::format("#Delta #theta_x vs. |#theta_x| - {}", quadrant).c_str(), {HistType::kTH2F, {thetaxAxis, dThetaxAxis}}); + + trackResidualsHistos[i][j]["dthetay_vs_x"] = registry.add((histPath + "dthetay_vs_x").c_str(), std::format("#Delta #theta_y vs. |x| - {}", quadrant).c_str(), {HistType::kTH2F, {xAxis, dThetayAxis}}); + trackResidualsHistos[i][j]["dthetay_vs_y"] = registry.add((histPath + "dthetay_vs_y").c_str(), std::format("#Delta #theta_y vs. |y| - {}", quadrant).c_str(), {HistType::kTH2F, {yAxis, dThetayAxis}}); + trackResidualsHistos[i][j]["dthetay_vs_thetay"] = registry.add((histPath + "dthetay_vs_thetay").c_str(), std::format("#Delta #theta_y vs. |#theta_y| - {}", quadrant).c_str(), {HistType::kTH2F, {thetayAxis, dThetayAxis}}); + + // mixed events + histPath = std::string("Alignment/mixed-event/Residuals/ReferencePlanes/") + refPLane.first + "/" + quadrant + "/"; + trackResidualsHistosMixedEvents[i][j]["dx_vs_x"] = registry.add((histPath + "dx_vs_x").c_str(), std::format("#Delta x vs. |x| - {}", quadrant).c_str(), {HistType::kTH2F, {xAxis, dxAxis}}); + trackResidualsHistosMixedEvents[i][j]["dx_vs_y"] = registry.add((histPath + "dx_vs_y").c_str(), std::format("#Delta x vs. |y| - {}", quadrant).c_str(), {HistType::kTH2F, {yAxis, dxAxis}}); + trackResidualsHistosMixedEvents[i][j]["dy_vs_x"] = registry.add((histPath + "dy_vs_x").c_str(), std::format("#Delta y vs. |x| - {}", quadrant).c_str(), {HistType::kTH2F, {xAxis, dyAxis}}); + trackResidualsHistosMixedEvents[i][j]["dy_vs_y"] = registry.add((histPath + "dy_vs_y").c_str(), std::format("#Delta y vs. |y| - {}", quadrant).c_str(), {HistType::kTH2F, {yAxis, dyAxis}}); + + trackResidualsHistosMixedEvents[i][j]["dthetax_vs_x"] = registry.add((histPath + "dthetax_vs_x").c_str(), std::format("#Delta #theta_x vs. |x| - {}", quadrant).c_str(), {HistType::kTH2F, {xAxis, dThetaxAxis}}); + trackResidualsHistosMixedEvents[i][j]["dthetax_vs_y"] = registry.add((histPath + "dthetax_vs_y").c_str(), std::format("#Delta #theta_x vs. |y| - {}", quadrant).c_str(), {HistType::kTH2F, {yAxis, dThetaxAxis}}); + trackResidualsHistosMixedEvents[i][j]["dthetax_vs_thetax"] = registry.add((histPath + "dthetax_vs_thetax").c_str(), std::format("#Delta #theta_x vs. |#theta_x| - {}", quadrant).c_str(), {HistType::kTH2F, {thetaxAxis, dThetaxAxis}}); + + trackResidualsHistosMixedEvents[i][j]["dthetay_vs_x"] = registry.add((histPath + "dthetay_vs_x").c_str(), std::format("#Delta #theta_y vs. |x| - {}", quadrant).c_str(), {HistType::kTH2F, {xAxis, dThetayAxis}}); + trackResidualsHistosMixedEvents[i][j]["dthetay_vs_y"] = registry.add((histPath + "dthetay_vs_y").c_str(), std::format("#Delta #theta_y vs. |y| - {}", quadrant).c_str(), {HistType::kTH2F, {yAxis, dThetayAxis}}); + trackResidualsHistosMixedEvents[i][j]["dthetay_vs_thetay"] = registry.add((histPath + "dthetay_vs_thetay").c_str(), std::format("#Delta #theta_y vs. |#theta_y| - {}", quadrant).c_str(), {HistType::kTH2F, {thetayAxis, dThetayAxis}}); + } + } + + for (size_t j = 0; j < quadrants.size(); j++) { + const auto& quadrant = quadrants[j]; + AxisSpec xAxis = {20, 0, 200, "|x| (cm)"}; + AxisSpec yAxis = {10, 0, 200, "|y| (cm)"}; + for (int chamber = 0; chamber < 10; chamber++) { + std::string histPath = std::string("Alignment/same-event/Residuals/MFT/") + quadrant + "/CH" + std::to_string(chamber + 1) + "/"; + // Delta x at cluster + residualsHistos[j][chamber]["dx_vs_x"] = registryResiduals.add((histPath + "dx_vs_x").c_str(), "Cluster x residual vs. x", {HistType::kTH2F, {xAxis, dxAxis}}); + residualsHistos[j][chamber]["dx_vs_y"] = registryResiduals.add((histPath + "dx_vs_y").c_str(), "Cluster x residual vs. y", {HistType::kTH2F, {yAxis, dxAxis}}); + residualsHistos[j][chamber]["dy_vs_x"] = registryResiduals.add((histPath + "dy_vs_x").c_str(), "Cluster y residual vs. x", {HistType::kTH2F, {xAxis, dyAxis}}); + residualsHistos[j][chamber]["dy_vs_y"] = registryResiduals.add((histPath + "dy_vs_y").c_str(), "Cluster y residual vs. y", {HistType::kTH2F, {yAxis, dyAxis}}); + + // mixed events + histPath = std::string("Alignment/mixed-event/Residuals/MFT/") + quadrant + "/CH" + std::to_string(chamber + 1) + "/"; + // Delta x at cluster + residualsHistosMixedEvents[j][chamber]["dx_vs_x"] = registryResiduals.add((histPath + "dx_vs_x").c_str(), "Cluster x residual vs. x", {HistType::kTH2F, {xAxis, dxAxis}}); + residualsHistosMixedEvents[j][chamber]["dx_vs_y"] = registryResiduals.add((histPath + "dx_vs_y").c_str(), "Cluster x residual vs. y", {HistType::kTH2F, {yAxis, dxAxis}}); + residualsHistosMixedEvents[j][chamber]["dy_vs_x"] = registryResiduals.add((histPath + "dy_vs_x").c_str(), "Cluster y residual vs. x", {HistType::kTH2F, {xAxis, dyAxis}}); + residualsHistosMixedEvents[j][chamber]["dy_vs_y"] = registryResiduals.add((histPath + "dy_vs_y").c_str(), "Cluster y residual vs. y", {HistType::kTH2F, {yAxis, dyAxis}}); + } + } + + for (size_t i = 0; i < 2; i++) { + std::string topBottom = (i == 0) ? "top" : "bottom"; + AxisSpec deAxis = {26, 0, 26, "DE index"}; + AxisSpec phiAxis = {16, -180, 180, "#phi (degrees)"}; + for (size_t j = 0; j < 2; j++) { + std::string sign = (j == 0) ? "positive" : "negative"; + for (int chamber = 0; chamber < 10; chamber++) { + std::string histPath = std::string("Alignment/same-event/Residuals/MFT/MFT_") + topBottom + "/" + sign + "/CH" + std::to_string(chamber + 1) + "/"; + // Delta x and y at cluster + residualsHistosPerDE[i][j][chamber]["dx_vs_de"] = registryResidualsMFT.add((histPath + "dx_vs_de").c_str(), "Cluster x residual vs. DE index", {HistType::kTH2F, {deAxis, dxAxis}}); + residualsHistosPerDE[i][j][chamber]["dy_vs_de"] = registryResidualsMFT.add((histPath + "dy_vs_de").c_str(), "Cluster y residual vs. DE index", {HistType::kTH2F, {deAxis, dxAxis}}); + + residualsHistosPerDE[i][j][chamber]["dx_vs_phi"] = registryResidualsMFT.add((histPath + "dx_vs_phi").c_str(), "Cluster x residual vs. cluster #phi", {HistType::kTH2F, {phiAxis, dxAxis}}); + residualsHistosPerDE[i][j][chamber]["dy_vs_phi"] = registryResidualsMFT.add((histPath + "dy_vs_phi").c_str(), "Cluster y residual vs. cluster #phi", {HistType::kTH2F, {phiAxis, dxAxis}}); + + // mixed events + histPath = std::string("Alignment/mixed-event/Residuals/MFT/MFT_") + topBottom + "/" + sign + "/CH" + std::to_string(chamber + 1) + "/"; + // Delta x and y at cluster + residualsHistosPerDEMixedEvents[i][j][chamber]["dx_vs_de"] = registryResidualsMFT.add((histPath + "dx_vs_de").c_str(), "Cluster x residual vs. DE index", {HistType::kTH2F, {deAxis, dxAxis}}); + residualsHistosPerDEMixedEvents[i][j][chamber]["dy_vs_de"] = registryResidualsMFT.add((histPath + "dy_vs_de").c_str(), "Cluster y residual vs. DE index", {HistType::kTH2F, {deAxis, dxAxis}}); + + residualsHistosPerDEMixedEvents[i][j][chamber]["dx_vs_phi"] = registryResidualsMFT.add((histPath + "dx_vs_phi").c_str(), "Cluster x residual vs. cluster #phi", {HistType::kTH2F, {phiAxis, dxAxis}}); + residualsHistosPerDEMixedEvents[i][j][chamber]["dy_vs_phi"] = registryResidualsMFT.add((histPath + "dy_vs_phi").c_str(), "Cluster y residual vs. cluster #phi", {HistType::kTH2F, {phiAxis, dxAxis}}); + } + } + } + + for (size_t i = 0; i < 2; i++) { + std::string topBottom = (i == 0) ? "top" : "bottom"; + AxisSpec deAxis = {26, 0, 26, "DE index"}; + for (size_t j = 0; j < 2; j++) { + std::string sign = (j == 0) ? "positive" : "negative"; + for (int chamber = 0; chamber < 10; chamber++) { + std::string histPath = std::string("Alignment/same-event/Residuals/MCH/MCH_") + topBottom + "/" + sign + "/CH" + std::to_string(chamber + 1) + "/"; + // Delta x and y at cluster + mchResidualsHistosPerDE[i][j][chamber]["dx_vs_de"] = registryResidualsMCH.add((histPath + "dx_vs_de").c_str(), "Cluster x residual vs. DE index", {HistType::kTH2F, {deAxis, dxAxis}}); + mchResidualsHistosPerDE[i][j][chamber]["dy_vs_de"] = registryResidualsMCH.add((histPath + "dy_vs_de").c_str(), "Cluster y residual vs. DE index", {HistType::kTH2F, {deAxis, dxAxis}}); + + // mixed events + histPath = std::string("Alignment/mixed-event/Residuals/MCH/MCH_") + topBottom + "/" + sign + "/CH" + std::to_string(chamber + 1) + "/"; + // Delta x and y at cluster + mchResidualsHistosPerDEMixedEvents[i][j][chamber]["dx_vs_de"] = registryResidualsMCH.add((histPath + "dx_vs_de").c_str(), "Cluster x residual vs. DE index", {HistType::kTH2F, {deAxis, dxAxis}}); + mchResidualsHistosPerDEMixedEvents[i][j][chamber]["dy_vs_de"] = registryResidualsMCH.add((histPath + "dy_vs_de").c_str(), "Cluster y residual vs. DE index", {HistType::kTH2F, {deAxis, dxAxis}}); + } + } + } + } + + if (configQAs.fEnableQADCA) { + for (size_t j = 0; j < quadrants.size(); j++) { + const auto& quadrant = quadrants[j]; + std::string histPath = std::string("Alignment/same-event/DCA/MFT/") + quadrant + "/"; + dcaHistos[0][j][0]["DCA_x"] = registryDCA.add((histPath + "DCA_x").c_str(), std::format("DCA(x) - {}", quadrant).c_str(), {HistType::kTH1F, {dcaxMFTAxis}}); + dcaHistos[0][j][1]["DCA_x"] = registryDCA.add((histPath + "DCA_x_pos").c_str(), std::format("DCA(x) - {} charge > 0", quadrant).c_str(), {HistType::kTH1F, {dcaxMFTAxis}}); + dcaHistos[0][j][2]["DCA_x"] = registryDCA.add((histPath + "DCA_x_neg").c_str(), std::format("DCA(x) - {} charge < 0", quadrant).c_str(), {HistType::kTH1F, {dcaxMFTAxis}}); + dcaHistos[0][j][0]["DCA_y"] = registryDCA.add((histPath + "DCA_y").c_str(), std::format("DCA(y) - {}", quadrant).c_str(), {HistType::kTH1F, {dcayMFTAxis}}); + dcaHistos[0][j][1]["DCA_y"] = registryDCA.add((histPath + "DCA_y_pos").c_str(), std::format("DCA(y) - {} charge > 0", quadrant).c_str(), {HistType::kTH1F, {dcayMFTAxis}}); + dcaHistos[0][j][2]["DCA_y"] = registryDCA.add((histPath + "DCA_y_neg").c_str(), std::format("DCA(y) - {} charge < 0", quadrant).c_str(), {HistType::kTH1F, {dcayMFTAxis}}); + dcaHistos[0][j][0]["DCA_x_vs_z"] = registryDCA.add((histPath + "DCA_x_vs_z").c_str(), std::format("DCA(x) vs. z - {}", quadrant).c_str(), {HistType::kTH2F, {dcazAxis, dcaxMFTAxis}}); + dcaHistos[0][j][0]["DCA_y_vs_z"] = registryDCA.add((histPath + "DCA_y_vs_z").c_str(), std::format("DCA(y) vs. z - {}", quadrant).c_str(), {HistType::kTH2F, {dcazAxis, dcayMFTAxis}}); + + histPath = std::string("Alignment/same-event/DCA/MCH/") + quadrant + "/"; + dcaHistos[1][j][0]["DCA_x"] = registryDCA.add((histPath + "DCA_x").c_str(), std::format("DCA(x) - {}", quadrant).c_str(), {HistType::kTH1F, {dcaxMCHAxis}}); + dcaHistos[1][j][1]["DCA_x"] = registryDCA.add((histPath + "DCA_x_pos").c_str(), std::format("DCA(x) - {} charge > 0", quadrant).c_str(), {HistType::kTH1F, {dcaxMCHAxis}}); + dcaHistos[1][j][2]["DCA_x"] = registryDCA.add((histPath + "DCA_x_neg").c_str(), std::format("DCA(x) - {} charge < 0", quadrant).c_str(), {HistType::kTH1F, {dcaxMCHAxis}}); + dcaHistos[1][j][0]["DCA_y"] = registryDCA.add((histPath + "DCA_y").c_str(), std::format("DCA(y) - {}", quadrant).c_str(), {HistType::kTH1F, {dcayMCHAxis}}); + dcaHistos[1][j][1]["DCA_y"] = registryDCA.add((histPath + "DCA_y_pos").c_str(), std::format("DCA(y) - {} charge > 0", quadrant).c_str(), {HistType::kTH1F, {dcayMCHAxis}}); + dcaHistos[1][j][2]["DCA_y"] = registryDCA.add((histPath + "DCA_y_neg").c_str(), std::format("DCA(y) - {} charge < 0", quadrant).c_str(), {HistType::kTH1F, {dcayMCHAxis}}); + + histPath = std::string("Alignment/mixed-event/DCA/MFT/") + quadrant + "/"; + dcaHistosMixedEvents[0][j][0]["DCA_x"] = registryDCA.add((histPath + "DCA_x").c_str(), std::format("DCA(x) - {}", quadrant).c_str(), {HistType::kTH1F, {dcaxMFTAxis}}); + dcaHistosMixedEvents[0][j][1]["DCA_x"] = registryDCA.add((histPath + "DCA_x_pos").c_str(), std::format("DCA(x) - {} charge > 0", quadrant).c_str(), {HistType::kTH1F, {dcaxMFTAxis}}); + dcaHistosMixedEvents[0][j][2]["DCA_x"] = registryDCA.add((histPath + "DCA_x_neg").c_str(), std::format("DCA(x) - {} charge < 0", quadrant).c_str(), {HistType::kTH1F, {dcaxMFTAxis}}); + dcaHistosMixedEvents[0][j][0]["DCA_y"] = registryDCA.add((histPath + "DCA_y").c_str(), std::format("DCA(y) - {}", quadrant).c_str(), {HistType::kTH1F, {dcayMFTAxis}}); + dcaHistosMixedEvents[0][j][1]["DCA_y"] = registryDCA.add((histPath + "DCA_y_pos").c_str(), std::format("DCA(y) - {} charge > 0", quadrant).c_str(), {HistType::kTH1F, {dcayMFTAxis}}); + dcaHistosMixedEvents[0][j][2]["DCA_y"] = registryDCA.add((histPath + "DCA_y_neg").c_str(), std::format("DCA(y) - {} charge < 0", quadrant).c_str(), {HistType::kTH1F, {dcayMFTAxis}}); + dcaHistosMixedEvents[0][j][0]["DCA_x_vs_z"] = registryDCA.add((histPath + "DCA_x_vs_z").c_str(), std::format("DCA(x) vs. z - {}", quadrant).c_str(), {HistType::kTH2F, {dcazAxis, dcaxMFTAxis}}); + dcaHistosMixedEvents[0][j][0]["DCA_y_vs_z"] = registryDCA.add((histPath + "DCA_y_vs_z").c_str(), std::format("DCA(y) vs. z - {}", quadrant).c_str(), {HistType::kTH2F, {dcazAxis, dcayMFTAxis}}); + + histPath = std::string("Alignment/mixed-event/DCA/MCH/") + quadrant + "/"; + dcaHistosMixedEvents[1][j][0]["DCA_x"] = registryDCA.add((histPath + "DCA_x").c_str(), std::format("DCA(x) - {}", quadrant).c_str(), {HistType::kTH1F, {dcaxMCHAxis}}); + dcaHistosMixedEvents[1][j][1]["DCA_x"] = registryDCA.add((histPath + "DCA_x_pos").c_str(), std::format("DCA(x) - {} charge > 0", quadrant).c_str(), {HistType::kTH1F, {dcaxMCHAxis}}); + dcaHistosMixedEvents[1][j][2]["DCA_x"] = registryDCA.add((histPath + "DCA_x_neg").c_str(), std::format("DCA(x) - {} charge < 0", quadrant).c_str(), {HistType::kTH1F, {dcaxMCHAxis}}); + dcaHistosMixedEvents[1][j][0]["DCA_y"] = registryDCA.add((histPath + "DCA_y").c_str(), std::format("DCA(y) - {}", quadrant).c_str(), {HistType::kTH1F, {dcayMCHAxis}}); + dcaHistosMixedEvents[1][j][1]["DCA_y"] = registryDCA.add((histPath + "DCA_y_pos").c_str(), std::format("DCA(y) - {} charge > 0", quadrant).c_str(), {HistType::kTH1F, {dcayMCHAxis}}); + dcaHistosMixedEvents[1][j][2]["DCA_y"] = registryDCA.add((histPath + "DCA_y_neg").c_str(), std::format("DCA(y) - {} charge < 0", quadrant).c_str(), {HistType::kTH1F, {dcayMCHAxis}}); + } + } + + if (configQAs.fEnableQADimuon) { + AxisSpec invMassAxis = {400, 1, 5, "M_{#mu^{+}#mu^{-}} (GeV/c^{2})"}; + AxisSpec invMassCorrelationAxis = {80, 0, 8, "M_{#mu^{+}#mu^{-}} (GeV/c^{2})"}; + AxisSpec invMassAxisFull = {5000, 0, 100, "M_{#mu^{+}#mu^{-}} (GeV/c^{2})"}; + // MCH-MID tracks with MCH acceptance cuts + registryDimuon.add("dimuon/same-event/invariantMass_MuonKine_MuonCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxisFull}}); + // MCH-MID tracks with MCH acceptance cuts and combinations from the top and bottom halfs of MCH + registryDimuon.add("dimuon/same-event/invariantMass_MuonKine_MuonCuts_TT", "#mu^{+}#mu^{-} invariant mass, top-top", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_TT", "#mu^{+}#mu^{-} invariant mass, top-top", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/same-event/invariantMass_MuonKine_MuonCuts_TB", "#mu^{+}#mu^{-} invariant mass, top-bottom or bottom-top", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_TB", "#mu^{+}#mu^{-} invariant mass, top-bottom or bottom-top", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/same-event/invariantMass_MuonKine_MuonCuts_BB", "#mu^{+}#mu^{-} invariant mass, bottom-bottom", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_BB", "#mu^{+}#mu^{-} invariant mass, bottom-bottom", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_TT", "#mu^{+}#mu^{-} invariant mass, top-top", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_TT", "#mu^{+}#mu^{-} invariant mass, top-top", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_TB", "#mu^{+}#mu^{-} invariant mass, top-bottom or bottom-top", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_TB", "#mu^{+}#mu^{-} invariant mass, top-bottom or bottom-top", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_BB", "#mu^{+}#mu^{-} invariant mass, bottom-bottom", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_BB", "#mu^{+}#mu^{-} invariant mass, bottom-bottom", {HistType::kTH1F, {invMassAxisFull}}); + // MCH-MID tracks with MFT acceptance cuts and combinations from the top and bottom halfs of MCH + registryDimuon.add("dimuon/same-event/invariantMass_MuonKine_GlobalMuonCuts_TT", "#mu^{+}#mu^{-} invariant mass, top-top", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_MuonKine_GlobalMuonCuts_TT", "#mu^{+}#mu^{-} invariant mass, top-top", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/same-event/invariantMass_MuonKine_GlobalMuonCuts_TB", "#mu^{+}#mu^{-} invariant mass, top-bottom or bottom-top", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_MuonKine_GlobalMuonCuts_TB", "#mu^{+}#mu^{-} invariant mass, top-bottom or bottom-top", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/same-event/invariantMass_MuonKine_GlobalMuonCuts_BB", "#mu^{+}#mu^{-} invariant mass, bottom-bottom", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_MuonKine_GlobalMuonCuts_BB", "#mu^{+}#mu^{-} invariant mass, bottom-bottom", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_MuonKine_GlobalMuonCuts_TT", "#mu^{+}#mu^{-} invariant mass, top-top", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMassFull_MuonKine_GlobalMuonCuts_TT", "#mu^{+}#mu^{-} invariant mass, top-top", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_MuonKine_GlobalMuonCuts_TB", "#mu^{+}#mu^{-} invariant mass, top-bottom or bottom-top", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMassFull_MuonKine_GlobalMuonCuts_TB", "#mu^{+}#mu^{-} invariant mass, top-bottom or bottom-top", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_MuonKine_GlobalMuonCuts_BB", "#mu^{+}#mu^{-} invariant mass, bottom-bottom", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMassFull_MuonKine_GlobalMuonCuts_BB", "#mu^{+}#mu^{-} invariant mass, bottom-bottom", {HistType::kTH1F, {invMassAxisFull}}); + // MCH-MID tracks with MCH acceptance cuts and combinations from the left and right halfs of MCH + registryDimuon.add("dimuon/same-event/invariantMass_MuonKine_MuonCuts_LL", "#mu^{+}#mu^{-} invariant mass, left-left", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_LL", "#mu^{+}#mu^{-} invariant mass, left-left", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/same-event/invariantMass_MuonKine_MuonCuts_LR", "#mu^{+}#mu^{-} invariant mass, left-right or right-left", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_LR", "#mu^{+}#mu^{-} invariant mass, left-right or right-left", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/same-event/invariantMass_MuonKine_MuonCuts_RR", "#mu^{+}#mu^{-} invariant mass, right-right", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_RR", "#mu^{+}#mu^{-} invariant mass, right-right", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_LL", "#mu^{+}#mu^{-} invariant mass, left-left", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_LL", "#mu^{+}#mu^{-} invariant mass, left-left", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_LR", "#mu^{+}#mu^{-} invariant mass, left-right or left-right", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_LR", "#mu^{+}#mu^{-} invariant mass, left-right or right-left", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_RR", "#mu^{+}#mu^{-} invariant mass, right-right", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_RR", "#mu^{+}#mu^{-} invariant mass, right-right", {HistType::kTH1F, {invMassAxisFull}}); + // MCH-MID tracks with MFT acceptance cuts + registryDimuon.add("dimuon/same-event/invariantMass_MuonKine_GlobalMuonCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_MuonKine_GlobalMuonCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_MuonKine_GlobalMuonCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMassFull_MuonKine_GlobalMuonCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxisFull}}); + // MCH-MID tracks with MFT acceptance cuts and combinations from the left and right halfs of MCH + registryDimuon.add("dimuon/same-event/invariantMass_MuonKine_GlobalMuonCuts_LL", "#mu^{+}#mu^{-} invariant mass, left-left", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_MuonKine_GlobalMuonCuts_LL", "#mu^{+}#mu^{-} invariant mass, left-left", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/same-event/invariantMass_MuonKine_GlobalMuonCuts_LR", "#mu^{+}#mu^{-} invariant mass, left-right or right-left", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_MuonKine_GlobalMuonCuts_LR", "#mu^{+}#mu^{-} invariant mass, left-right or right-left", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/same-event/invariantMass_MuonKine_GlobalMuonCuts_RR", "#mu^{+}#mu^{-} invariant mass, right-right", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_MuonKine_GlobalMuonCuts_RR", "#mu^{+}#mu^{-} invariant mass, right-right", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_MuonKine_GlobalMuonCuts_LL", "#mu^{+}#mu^{-} invariant mass, left-left", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMassFull_MuonKine_GlobalMuonCuts_LL", "#mu^{+}#mu^{-} invariant mass, left-left", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_MuonKine_GlobalMuonCuts_LR", "#mu^{+}#mu^{-} invariant mass, left-right or right-left", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMassFull_MuonKine_GlobalMuonCuts_LR", "#mu^{+}#mu^{-} invariant mass, left-right or right-left", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_MuonKine_GlobalMuonCuts_RR", "#mu^{+}#mu^{-} invariant mass, right-right", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMassFull_MuonKine_GlobalMuonCuts_RR", "#mu^{+}#mu^{-} invariant mass right-right", {HistType::kTH1F, {invMassAxisFull}}); + // Good MFT-MCH-MID tracks with MCH parameters and MFT acceptance cuts + registryDimuon.add("dimuon/same-event/invariantMass_MuonKine_GlobalMatchesCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_MuonKine_GlobalMatchesCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_MuonKine_GlobalMatchesCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMassFull_MuonKine_GlobalMatchesCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxisFull}}); + // Good MFT-MCH-MID tracks with global parameters MFT acceptance cuts + registryDimuon.add("dimuon/same-event/invariantMass_GlobalMuonKine_GlobalMatchesCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_GlobalMuonKine_GlobalMatchesCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_GlobalMuonKine_GlobalMatchesCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMassFull_GlobalMuonKine_GlobalMatchesCuts", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxisFull}}); + // Good MFT-MCH-MID tracks with re-scaled MFT kinematics and MFT acceptance cuts + registryDimuon.add("dimuon/same-event/invariantMass_ScaledMftKine_GlobalMatchesCuts", "M_{#mu^{+}#mu^{-}} - rescaled MFT momentum", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_ScaledMftKine_GlobalMatchesCuts", "M_{#mu^{+}#mu^{-}} - rescaled MFT momentum", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_ScaledMftKine_GlobalMatchesCuts", "M_{#mu^{+}#mu^{-}} - rescaled MFT momentum", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMassFull_ScaledMftKine_GlobalMatchesCuts", "M_{#mu^{+}#mu^{-}} - rescaled MFT momentum", {HistType::kTH1F, {invMassAxisFull}}); + // combinations of tracks from top and bottom halfs of MFT + registryDimuon.add("dimuon/same-event/invariantMass_ScaledMftKine_GlobalMatchesCuts_TT", "M_{#mu^{+}#mu^{-}} - rescaled MFT momentum, top-top", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMass_ScaledMftKine_GlobalMatchesCuts_TB", "M_{#mu^{+}#mu^{-}} - rescaled MFT momentum, top-bottom", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMass_ScaledMftKine_GlobalMatchesCuts_BT", "M_{#mu^{+}#mu^{-}} - rescaled MFT momentum, bottom-top", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMass_ScaledMftKine_GlobalMatchesCuts_BB", "M_{#mu^{+}#mu^{-}} - rescaled MFT momentum, bottom-bottom", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_ScaledMftKine_GlobalMatchesCuts_TT", "M_{#mu^{+}#mu^{-}} - rescaled MFT momentum, top-top", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_ScaledMftKine_GlobalMatchesCuts_TB", "M_{#mu^{+}#mu^{-}} - rescaled MFT momentum, top-bottom", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_ScaledMftKine_GlobalMatchesCuts_BT", "M_{#mu^{+}#mu^{-}} - rescaled MFT momentum, bottom-top", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/mixed-event/invariantMass_ScaledMftKine_GlobalMatchesCuts_BB", "M_{#mu^{+}#mu^{-}} - rescaled MFT momentum, bottom-bottom", {HistType::kTH1F, {invMassAxis}}); + // combinations with sub-leading matches + registryDimuon.add("dimuon/same-event/invariantMass_GlobalMuonKine_GlobalMatchesCuts_leading_subleading", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_GlobalMuonKine_GlobalMatchesCuts_leading_subleading", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/same-event/invariantMass_GlobalMuonKine_GlobalMatchesCuts_subleading_leading", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_GlobalMuonKine_GlobalMatchesCuts_subleading_leading", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxisFull}}); + registryDimuon.add("dimuon/same-event/invariantMass_GlobalMuonKine_GlobalMatchesCuts_subleading_subleading", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxis}}); + registryDimuon.add("dimuon/same-event/invariantMassFull_GlobalMuonKine_GlobalMatchesCuts_subleading_subleading", "#mu^{+}#mu^{-} invariant mass", {HistType::kTH1F, {invMassAxisFull}}); + + // invariant mass correlations + registryDimuon.add("dimuon/same-event/invariantMass_MuonKine_vs_GlobalMuonKine", "M_{#mu^{+}#mu^{-}} - muon tracks vs. global tracks", {HistType::kTH2F, {invMassCorrelationAxis, invMassCorrelationAxis}}); + registryDimuon.add("dimuon/same-event/invariantMass_ScaledMftKine_vs_GlobalMuonKine", "M_{#mu^{+}#mu^{-}} - rescaled MFT tracks vs. global tracks", {HistType::kTH2F, {invMassCorrelationAxis, invMassCorrelationAxis}}); + registryDimuon.add("dimuon/same-event/invariantMass_GlobalMuonKine_subleading_vs_leading", "M_{#mu^{+}#mu^{-}} - subleading vs. leading matches", {HistType::kTH2F, {invMassCorrelationAxis, invMassCorrelationAxis}}); + } + } + + void doTransformMFT(o2::mch::TrackParam& track) + { + double zCH10 = -1437.6; + double z = track.getZ(); + // double dZ = zMCH - z; + double x = track.getNonBendingCoor(); + double y = track.getBendingCoor(); + double xSlope = track.getNonBendingSlope(); + double ySlope = track.getBendingSlope(); + + double xShiftMCH = (y > 0) ? 0.8541 : -1.5599; + double xCorrection = xShiftMCH * z / zCH10; + track.setNonBendingCoor(x + xCorrection); + double xSlopeCorrection = xShiftMCH / zCH10; + track.setNonBendingSlope(xSlope + xSlopeCorrection); + + double yShiftMCH = (y > 0) ? 3.0311 : 0.7588; + double yCorrection = yShiftMCH * z / zCH10; + track.setBendingCoor(y + yCorrection); + double ySlopeCorrection = yShiftMCH / zCH10; + track.setBendingSlope(ySlope + ySlopeCorrection); + } + + template + void TransformMFT(TTrack& track) + { + if constexpr (static_cast(GlobalFwdFillMap)) { + auto mchTrack = mMatching.FwdtoMCH(track); + doTransformMFT(mchTrack); + + auto transformedTrack = mMatching.MCHtoFwd(mchTrack); + track.setParameters(transformedTrack.getParameters()); + track.setZ(transformedTrack.getZ()); + track.setCovariances(transformedTrack.getCovariances()); + } else { + o2::dataformats::GlobalFwdTrack fwdtrack; + fwdtrack.setParameters(track.getParameters()); + fwdtrack.setZ(track.getZ()); + fwdtrack.setCovariances(track.getCovariances()); + auto mchTrack = mMatching.FwdtoMCH(fwdtrack); + doTransformMFT(mchTrack); + + auto transformedTrack = mMatching.MCHtoFwd(mchTrack); + track.setParameters(transformedTrack.getParameters()); + track.setZ(transformedTrack.getZ()); + track.setCovariances(transformedTrack.getCovariances()); + } + } + + int GetDetElemId(int iDetElemNumber) + { + // make sure detector number is valid + if (!(iDetElemNumber >= fgSNDetElemCh[0] && + iDetElemNumber < fgSNDetElemCh[10])) { + LOGF(fatal, "Invalid detector element number: %d", iDetElemNumber); + } + /// get det element number from ID + // get chamber and element number in chamber + int iCh = 0; + int iDet = 0; + for (int i = 1; i <= 10; i++) { + if (iDetElemNumber < fgSNDetElemCh[i]) { + iCh = i; + iDet = iDetElemNumber - fgSNDetElemCh[i - 1]; + break; + } + } + + // make sure detector index is valid + if (!(iCh > 0 && iCh <= 10 && iDet < fgNDetElemCh[iCh - 1])) { + LOGF(fatal, "Invalid detector element id: %d", 100 * iCh + iDet); + } + + // add number of detectors up to this chamber + return 100 * iCh + iDet; + } + + int GetQuadrantPhi(double phi) + { + if (phi >= 0 && phi < 90) { + return 0; + } + if (phi >= 90 && phi <= 180) { + return 1; + } + if (phi >= -180 && phi < -90) { + return 2; + } + if (phi >= -90 && phi < 0) { + return 3; + } + return -1; + } + + template + int GetQuadrantTrack(TTrack const& track) + { + double phi = static_cast(track.phi()) * 180 / TMath::Pi(); + return GetQuadrantPhi(phi); + } + + bool RemoveTrack(mch::Track& track) + { + // Refit track with re-aligned clusters + bool removeTrack = false; + try { + trackFitter.fit(track, false); + } catch (exception const& e) { + removeTrack = true; + return removeTrack; + } + + auto itStartingParam = std::prev(track.rend()); + + while (true) { + + try { + trackFitter.fit(track, true, false, (itStartingParam == track.rbegin()) ? nullptr : &itStartingParam); + } catch (exception const&) { + removeTrack = true; + break; + } + + double worstLocalChi2 = -1.0; + + track.tagRemovableClusters(0x1F, false); + + auto itWorstParam = track.end(); + + for (auto itParam = track.begin(); itParam != track.end(); ++itParam) { + if (itParam->getLocalChi2() > worstLocalChi2) { + worstLocalChi2 = itParam->getLocalChi2(); + itWorstParam = itParam; + } + } + + if (worstLocalChi2 < mImproveCutChi2) { + break; + } + + if (!itWorstParam->isRemovable()) { + removeTrack = true; + track.removable(); + break; + } + + auto itNextParam = track.removeParamAtCluster(itWorstParam); + auto itNextToNextParam = (itNextParam == track.end()) ? itNextParam : std::next(itNextParam); + itStartingParam = track.rbegin(); + + if (track.getNClusters() < 10) { + removeTrack = true; + break; + } else { + while (itNextToNextParam != track.end()) { + if (itNextToNextParam->getClusterPtr()->getChamberId() != itNextParam->getClusterPtr()->getChamberId()) { + itStartingParam = std::make_reverse_iterator(++itNextParam); + break; + } + ++itNextToNextParam; + } + } + } + + if (!removeTrack) { + for (auto& param : track) { + param.setParameters(param.getSmoothParameters()); + param.setCovariances(param.getSmoothCovariances()); + } + } + + return removeTrack; + } + + template + bool pDCACut(Var const& fgValues, Var const& fgValuesPV, double nSigmaPDCA) + { + static const double sigmaPDCA23 = 80.; + static const double sigmaPDCA310 = 54.; + static const double relPRes = 0.0004; + static const double slopeRes = 0.0005; + + double thetaAbs = TMath::ATan(fgValues.rabs / 505.) * TMath::RadToDeg(); + double p = fgValuesPV.p; + + double pDCA = fgValues.pDca; + double sigmaPDCA = (thetaAbs < 3) ? sigmaPDCA23 : sigmaPDCA310; + double nrp = nSigmaPDCA * relPRes * p; + double pResEffect = sigmaPDCA / (1. - nrp / (1. + nrp)); + double slopeResEffect = 535. * slopeRes * p; + double sigmaPDCAWithRes = TMath::Sqrt(pResEffect * pResEffect + slopeResEffect * slopeResEffect); + + if (pDCA > nSigmaPDCA * sigmaPDCAWithRes) { + return false; + } + + return true; + } + + template + bool IsMixedEvent(Var const& fgValues1, Var const& fgValues2) + { + if (fgValues1.bc == fgValues2.bc) { + return false; + } + + uint64_t bcDiff = (fgValues2.bc > fgValues1.bc) ? (fgValues2.bc - fgValues1.bc) : (fgValues1.bc - fgValues2.bc); + // in the event mixing case, we require a minimum BC gap between the collisions + if (bcDiff < configMixing.fEventMinDeltaBc) + return false; + + // we also require that the collisions have similar Z positions and multiplicity of MFT tracks + if (std::fabs(fgValues2.z - fgValues1.z) > configMixing.fEventMaxDeltaVtxZ) { + return false; + } + + if (std::abs(fgValues2.multMFT - fgValues1.multMFT) > configMixing.fEventMaxDeltaNMFT) { + return false; + } + + return true; + } + + template + bool IsGoodMuon(Var const& fgValues, Var const& fgValuesPV, float fTrackChi2MchUp, float fPMchLow, float fPtMchLow, float fEtaMchLow, float fEtaMchUp, float fRabsLow, float fRabsUp, float fSigmaPdcaUp) + { + // chi2 cut + if (fgValues.chi2 > fTrackChi2MchUp) + return false; + + // momentum cut + if (fgValues.p < fPMchLow) { + return false; // skip low-momentum tracks + } + + // transverse momentum cut + if (fgValues.pT < fPtMchLow) { + return false; // skip low-momentum tracks + } + + // Eta cut + if ((fgValues.eta < fEtaMchLow || fgValues.eta > fEtaMchUp)) { + return false; + } + + // RAbs cut + if ((fgValues.rabs < fRabsLow || fgValues.rabs > fRabsUp)) { + return false; + } + + // pDCA cut + if (!pDCACut(fgValues, fgValuesPV, fSigmaPdcaUp)) { + return false; + } + + return true; + } + + template + bool IsGoodMuon(Var const& fgValues, Var const& fgValuesPV) + { + return IsGoodMuon(fgValues, fgValuesPV, configMuons.fTrackChi2MchUp, configMuons.fPMchLow, configMuons.fPtMchLow, configMuons.fEtaMchLow, configMuons.fEtaMchUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp); + } + + template + bool IsGoodGlobalMuon(Var const& fgValues, Var const& fgValuesPV) + { + return IsGoodMuon(fgValues, fgValuesPV, configMuons.fTrackChi2MchUp, configMuons.fPMchLow, configMuons.fPtMchLow, configMFTs.fEtaMftLow, configMFTs.fEtaMftUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp); + } + + template + bool IsGoodMFT(Var const& fgValues, float fTrackChi2MftUp, int fTrackNClustMftLow) + { + // chi2 cut + if (fgValues.chi2 > fTrackChi2MftUp) { + return false; + } + + // number of clusters cut + if (fgValues.nClusters < fTrackNClustMftLow) { + return false; + } + + return true; + } + + template + bool IsGoodGlobalMatching(Var const& fgValues, float fTrackChi2MftUp, int fTrackNClustMftLow, float fMatchingChi2MftMchUp) + { + if (!IsGoodMFT(fgValues, fTrackChi2MftUp, fTrackNClustMftLow)) { + return false; + } + + if (fgValues.chi2matching > fMatchingChi2MftMchUp) { + return false; + } + + return true; + } + + template + bool IsGoodGlobalMatching(Var const& fgValues) + { + return IsGoodGlobalMatching(fgValues, configMFTs.fTrackChi2MftUp, configMFTs.fTrackNClustMftLow, fMatchingChi2MftMchUp); + } + + template + double GetMuMuInvariantMass(VarT const& track1, VarT const& track2) + { + ROOT::Math::PxPyPzMVector muon1{ + track1.px, + track1.py, + track1.pz, + o2::constants::physics::MassMuon}; + + ROOT::Math::PxPyPzMVector muon2{ + track2.px, + track2.py, + track2.pz, + o2::constants::physics::MassMuon}; + + auto dimuon = muon1 + muon2; + + return dimuon.M(); + } + + template + void GetMuonPairs(TMuons const& muons, TCandidates const& matchingCandidates, const std::map& collisionInfos, + std::vector& muonPairs, + std::vector& globalMuonPairs) + { + // muon tracks - outer loop over collisions + for (auto& [collisionIndex1, collisionInfo1] : collisionInfos) { + + // outer loop over muon tracks + auto muonCollision1 = muons.sliceBy(fwdtracksPerCollision, collisionInfo1.globalIndex); + for (auto muon1 : muonCollision1) { + + if (muon1.trackType() <= 2) { + continue; + } + auto mchIndex1 = muon1.globalIndex(); + + // inner loop over collisions + for (auto& [collisionIndex2, collisionInfo2] : collisionInfos) { + // avoid double-counting of collisions + if (collisionIndex2 < collisionIndex1) + continue; + + bool sameEvent = (collisionIndex1 == collisionIndex2); + bool mixedEvent = IsMixedEvent(collisionInfo1, collisionInfo2); + + if (!sameEvent && !mixedEvent) + continue; + + // inner loop over muon tracks + auto muonCollision2 = muons.sliceBy(fwdtracksPerCollision, collisionInfo2.globalIndex); + for (auto muon2 : muonCollision2) { + if (muon2.trackType() <= 2) { + continue; + } + auto mchIndex2 = muon2.globalIndex(); + + // avoid double-counting of muon pairs if we are not mixing events + if (sameEvent && mchIndex2 <= mchIndex1) + continue; + + MuonPair muonPair{{collisionIndex1, mchIndex1}, {collisionIndex2, mchIndex2}}; + muonPairs.emplace_back(muonPair); + } + } + } + } + + // global muon tracks - outer loop over collisions + for (auto& [collisionIndex1, collisionInfo1] : collisionInfos) { + + // outer loop over global muon tracks + auto muonCollision1 = muons.sliceBy(fwdtracksPerCollision, collisionInfo1.globalIndex); + for (auto muon1 : muonCollision1) { + + if (muon1.trackType() <= 2) { + continue; + } + auto mchIndex1 = muon1.globalIndex(); + auto matchingCandidateIt1 = matchingCandidates.find(mchIndex1); + if (matchingCandidateIt1 == matchingCandidates.end()) { + continue; + } + + // inner loop over collisions + for (auto& [collisionIndex2, collisionInfo2] : collisionInfos) { + // avoid double-counting of collisions + if (collisionIndex2 < collisionIndex1) + continue; + + bool sameEvent = (collisionIndex1 == collisionIndex2); + bool mixedEvent = IsMixedEvent(collisionInfo1, collisionInfo2); + + if (!sameEvent && !mixedEvent) + continue; + + // outer loop over global muon tracks + auto muonCollision2 = muons.sliceBy(fwdtracksPerCollision, collisionInfo2.globalIndex); + for (auto muon2 : muonCollision2) { + + if (muon2.trackType() <= 2) { + continue; + } + auto mchIndex2 = muon2.globalIndex(); + auto matchingCandidateIt2 = matchingCandidates.find(mchIndex2); + if (matchingCandidateIt2 == matchingCandidates.end()) { + continue; + } + + // avoid double-counting of muon pairs if we are not mixing events + if (sameEvent && mchIndex2 <= mchIndex1) + continue; + + GlobalMuonPair muonPair{{collisionIndex1, matchingCandidateIt1->second}, {collisionIndex2, matchingCandidateIt2->second}}; + globalMuonPairs.emplace_back(muonPair); + } + } + } + } + } + + template + void FillCollision(TEvent const& collision, Var& fgValues) + { + fgValues.globalIndex = collision.globalIndex(); + fgValues.x = collision.posX(); + fgValues.y = collision.posY(); + fgValues.z = collision.posZ(); + fgValues.covXX = collision.covXX(); + fgValues.covYY = collision.covYY(); + } + + template + void FillTrack(mch::Track const& muon, Var& fgValues) + { + mch::TrackParam trackParam = mch::TrackParam(muon.first()); + auto proptrack = mMatching.MCHtoFwd(trackParam); + + fgValues.pT = proptrack.getPt(); + fgValues.x = proptrack.getX(); + fgValues.y = proptrack.getY(); + fgValues.z = proptrack.getZ(); + fgValues.eta = proptrack.getEta(); + fgValues.tgl = proptrack.getTgl(); + fgValues.phi = proptrack.getPhi(); + + fgValues.p = proptrack.getP(); + fgValues.px = proptrack.getPx(); + fgValues.py = proptrack.getPy(); + fgValues.pz = proptrack.getPz(); + + fgValues.chi2 = trackParam.getTrackChi2(); + fgValues.nClusters = muon.getNClusters(); + fgValues.sign = trackParam.getCharge(); + } + + template + void FillTrack(TTrack const& muon, Var& fgValues) + { + fgValues.collisionId = muon.collisionId(); + fgValues.globalIndex = muon.globalIndex(); + fgValues.trackTime = muon.trackTime(); + + fgValues.pT = muon.pt(); + fgValues.x = muon.x(); + fgValues.y = muon.y(); + fgValues.z = muon.z(); + fgValues.eta = muon.eta(); + fgValues.tgl = muon.tgl(); + fgValues.phi = muon.phi(); + + fgValues.p = muon.p(); + fgValues.px = muon.px(); + fgValues.py = muon.py(); + fgValues.pz = muon.pz(); + + fgValues.chi2 = muon.chi2(); + fgValues.nClusters = muon.nClusters(); + fgValues.sign = muon.sign(); + + if constexpr (static_cast(MuonFillMap)) { + // Direct info from AO2D without re-propagation + fgValues.pDca = muon.pDca(); + fgValues.rabs = muon.rAtAbsorberEnd(); + fgValues.trackType = muon.trackType(); + } + } + + template + bool FillClusters(TMCHTrack const& muon, TFwdCls const& mchcls, Var& fgValues, mch::Track& convertedTrack) + { + int removable = 0; + auto clustersSliced = mchcls.sliceBy(perMuon, muon.globalIndex()); // Slice clusters by muon id + vector> posClusters; + + int clIndex = -1; + // Get re-aligned clusters associated to current track + for (auto const& cluster : clustersSliced) { + clIndex += 1; + + math_utils::Point3D local; + math_utils::Point3D master; + + mch::Cluster* clusterMCH = new mch::Cluster(); + master.SetXYZ(cluster.x(), cluster.y(), cluster.z()); + + if (configRealign.fDoRealign) { + // Transformation from reference geometry frame to new geometry frame + transformRef[cluster.deId()].MasterToLocal(master, local); + transformNew[cluster.deId()].LocalToMaster(local, master); + } + + clusterMCH->x = master.x(); + clusterMCH->y = master.y(); + clusterMCH->z = master.z(); + + uint32_t ClUId = mch::Cluster::buildUniqueId(static_cast(cluster.deId() / 100) - 1, cluster.deId(), clIndex); + clusterMCH->uid = ClUId; + clusterMCH->ex = cluster.isGoodX() ? 0.2 : 10.0; + clusterMCH->ey = cluster.isGoodY() ? 0.2 : 10.0; + + // Fill temporary values + vector posCls = {clusterMCH->x, clusterMCH->y, clusterMCH->z}; + vector eCls = {clusterMCH->ex, clusterMCH->ey}; + posClusters.emplace_back(posCls); + fgValues.errorClusters.emplace_back(eCls); + fgValues.DEIDs.emplace_back(cluster.deId()); + + // Add transformed cluster into temporary variable + convertedTrack.createParamAtCluster(*clusterMCH); + } + + if (configRealign.fDoRealign) { + // Refit the re-aligned track + if (convertedTrack.getNClusters() != 0) { + removable = RemoveTrack(convertedTrack); + } else { + LOGF(fatal, "Muon track %d has no associated clusters.", muon.globalIndex()); + } + + for (auto it = convertedTrack.begin(); it != convertedTrack.end(); it++) { + vector pos = {static_cast(it->getNonBendingCoor()), static_cast(it->getBendingCoor()), static_cast(it->getZ())}; + fgValues.posClusters.emplace_back(pos); + } + + } else { + fgValues.posClusters = posClusters; + } + + return !removable; + } + + template + void FillMatchingCandidates(TMuon const& muon, TMCH const& mchtrack, TMap& matchingCandidates) + { + uint64_t muonId = muon.globalIndex(); + uint64_t mchId = mchtrack.globalIndex(); + + //// Save matching candidates index pairs + auto matchingCandidateIt = matchingCandidates.find(mchId); + if (matchingCandidateIt != matchingCandidates.end()) { + matchingCandidateIt->second.push_back(muonId); + } else { + matchingCandidates[mchId].push_back(muonId); + } + } + + template + void FillPropagation(mch::Track const& muon, VarC const& collision, VarT& fgValues, int endPoint = kToVtx, int endZ = 0) + { + o2::dataformats::GlobalFwdTrack propmuon; + mch::TrackParam trackParam = mch::TrackParam(muon.first()); + fgValues.chi2 = trackParam.getTrackChi2(); + fgValues.nClusters = muon.getNClusters(); + fgValues.sign = trackParam.getCharge(); + + if (endPoint == kToVtx) { + o2::mch::TrackExtrap::extrapToVertex(trackParam, collision.x, collision.y, collision.z, collision.covXX, collision.covYY); + } + if (endPoint == kToDCA) { + o2::mch::TrackExtrap::extrapToVertexWithoutBranson(trackParam, collision.z); + } + if (endPoint == kToAbsEnd) { + o2::mch::TrackExtrap::extrapToZ(trackParam, zAtAbsEnd); + } + if (endPoint == kToZ) { + o2::mch::TrackExtrap::extrapToZ(trackParam, endZ); + } + + auto proptrack = mMatching.MCHtoFwd(trackParam); + propmuon.setParameters(proptrack.getParameters()); + propmuon.setZ(proptrack.getZ()); + propmuon.setCovariances(proptrack.getCovariances()); + + //// Fill propagation informations + if (endPoint == kToVtx || endPoint == kToZ) { + fgValues.pT = propmuon.getPt(); + fgValues.x = propmuon.getX(); + fgValues.y = propmuon.getY(); + fgValues.z = propmuon.getZ(); + fgValues.eta = propmuon.getEta(); + fgValues.tgl = propmuon.getTgl(); + fgValues.phi = propmuon.getPhi(); + + fgValues.p = propmuon.getP(); + fgValues.px = propmuon.getP() * sin(M_PI / 2 - atan(propmuon.getTgl())) * cos(propmuon.getPhi()); + fgValues.py = propmuon.getP() * sin(M_PI / 2 - atan(propmuon.getTgl())) * sin(propmuon.getPhi()); + fgValues.pz = propmuon.getP() * cos(M_PI / 2 - atan(propmuon.getTgl())); + } + + if (endPoint == kToDCA) { + fgValues.dcaX = (propmuon.getX() - collision.x); + fgValues.dcaY = (propmuon.getY() - collision.y); + float dcaXY = std::sqrt(fgValues.dcaX * fgValues.dcaX + fgValues.dcaY * fgValues.dcaY); + + mch::TrackParam trackParam = mch::TrackParam(muon.first()); + float p = trackParam.p(); + fgValues.pDca = p * dcaXY; + } + + if (endPoint == kToAbsEnd) { + double xAbs = propmuon.getX(); + double yAbs = propmuon.getY(); + fgValues.rabs = std::sqrt(xAbs * xAbs + yAbs * yAbs); + } + } + + template + void FillPropagation(TTrack const& muon, VarC const& collision, VarT const& fgValuesMCH, VarT& fgValues, int endPoint = kToVtx, int endZ = 0) + { + o2::dataformats::GlobalFwdTrack propmuon; + double chi2 = muon.chi2(); + fgValues.chi2 = chi2; + fgValues.nClusters = muon.nClusters(); + fgValues.sign = muon.sign(); + + if constexpr (static_cast(MuonFillMap)) { + o2::dataformats::GlobalFwdTrack track; + + SMatrix5 tpars(muon.x(), muon.y(), muon.phi(), muon.tgl(), muon.signed1Pt()); + std::vector v1{muon.cXX(), muon.cXY(), muon.cYY(), muon.cPhiX(), muon.cPhiY(), + muon.cPhiPhi(), muon.cTglX(), muon.cTglY(), muon.cTglPhi(), muon.cTglTgl(), + muon.c1PtX(), muon.c1PtY(), muon.c1PtPhi(), muon.c1PtTgl(), muon.c1Pt21Pt2()}; + SMatrix55 tcovs(v1.begin(), v1.end()); + o2::track::TrackParCovFwd fwdtrack{muon.z(), tpars, tcovs, chi2}; + + track.setParameters(tpars); + track.setZ(fwdtrack.getZ()); + track.setCovariances(tcovs); + auto mchTrack = mMatching.FwdtoMCH(track); + + if (endPoint == kToVtx) { + o2::mch::TrackExtrap::extrapToVertex(mchTrack, collision.x, collision.y, collision.z, collision.covXX, collision.covYY); + } + if (endPoint == kToDCA) { + o2::mch::TrackExtrap::extrapToVertexWithoutBranson(mchTrack, collision.z); + } + if (endPoint == kToAbsEnd) { + o2::mch::TrackExtrap::extrapToZ(mchTrack, zAtAbsEnd); + } + if (endPoint == kToZ) { + o2::mch::TrackExtrap::extrapToZ(mchTrack, endZ); + } + + auto proptrack = mMatching.MCHtoFwd(mchTrack); + propmuon.setParameters(proptrack.getParameters()); + propmuon.setZ(proptrack.getZ()); + propmuon.setCovariances(proptrack.getCovariances()); + + } else { + + o2::dataformats::GlobalFwdTrack track; + + if constexpr (static_cast(Scaled)) { + double pMCH = fgValuesMCH.p; + int sign = fgValuesMCH.sign; + + double px = pMCH * sin(M_PI / 2 - atan(muon.tgl())) * cos(muon.phi()); + double py = pMCH * sin(M_PI / 2 - atan(muon.tgl())) * sin(muon.phi()); + // double pz = pMCH * cos(M_PI / 2 - atan(mft.tgl())); + double pt = std::sqrt(std::pow(px, 2) + std::pow(py, 2)); + + double chi2 = muon.chi2(); + double signed1Pt = endPoint == kToDCA ? muon.signed1Pt() : sign / pt; + SMatrix5 tpars(muon.x(), muon.y(), muon.phi(), muon.tgl(), signed1Pt); + std::vector v1{0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0}; + SMatrix55 tcovs(v1.begin(), v1.end()); + o2::track::TrackParCovFwd fwdtrack{muon.z(), tpars, tcovs, chi2}; + track.setParameters(tpars); + track.setZ(fwdtrack.getZ()); + track.setCovariances(tcovs); + } else { + SMatrix5 tpars(muon.x(), muon.y(), muon.phi(), muon.tgl(), muon.signed1Pt()); + std::vector v1{muon.cXX(), muon.cXY(), muon.cYY(), muon.cPhiX(), muon.cPhiY(), + muon.cPhiPhi(), muon.cTglX(), muon.cTglY(), muon.cTglPhi(), muon.cTglTgl(), + muon.c1PtX(), muon.c1PtY(), muon.c1PtPhi(), muon.c1PtTgl(), muon.c1Pt21Pt2()}; + SMatrix55 tcovs(v1.begin(), v1.end()); + o2::track::TrackParCovFwd fwdtrack{muon.z(), tpars, tcovs, chi2}; + track.setParameters(tpars); + track.setZ(fwdtrack.getZ()); + track.setCovariances(tcovs); + } + + if (endPoint == kToVtx) { + if (fEnableMFTAlignmentCorrections) { + TransformMFT<0>(track); + } + auto geoMan = o2::base::GeometryManager::meanMaterialBudget(muon.x(), muon.y(), muon.z(), collision.x, collision.y, collision.z); + auto x2x0 = static_cast(geoMan.meanX2X0); + track.propagateToVtxhelixWithMCS(collision.z, {collision.x, collision.y}, {collision.covXX, collision.covYY}, Bz, x2x0); + } + if (endPoint == kToDCA) { + if (fEnableMFTAlignmentCorrections) { + TransformMFT<0>(track); + } + track.propagateToZ(collision.z, Bz); + } + if (endPoint == kToZ) { + auto mchTrackExt = mMatching.FwdtoMCH(track); + if (fEnableMFTAlignmentCorrections) { + doTransformMFT(mchTrackExt); + } + o2::mch::TrackExtrap::extrapToZ(mchTrackExt, endZ); + track = mMatching.MCHtoFwd(mchTrackExt); + } + + propmuon.setParameters(track.getParameters()); + propmuon.setZ(track.getZ()); + propmuon.setCovariances(track.getCovariances()); + } + + //// Fill propagation informations + if (endPoint == kToVtx || endPoint == kToZ) { + fgValues.pT = propmuon.getPt(); + fgValues.x = propmuon.getX(); + fgValues.y = propmuon.getY(); + fgValues.z = propmuon.getZ(); + fgValues.eta = propmuon.getEta(); + fgValues.tgl = propmuon.getTgl(); + fgValues.phi = propmuon.getPhi(); + + fgValues.p = propmuon.getP(); + fgValues.px = propmuon.getP() * sin(M_PI / 2 - atan(propmuon.getTgl())) * cos(propmuon.getPhi()); + fgValues.py = propmuon.getP() * sin(M_PI / 2 - atan(propmuon.getTgl())) * sin(propmuon.getPhi()); + fgValues.pz = propmuon.getP() * cos(M_PI / 2 - atan(propmuon.getTgl())); + } + + if (endPoint == kToDCA) { + fgValues.dcaX = (propmuon.getX() - collision.x); + fgValues.dcaY = (propmuon.getY() - collision.y); + float dcaXY = std::sqrt(fgValues.dcaX * fgValues.dcaX + fgValues.dcaY * fgValues.dcaY); + + if constexpr (static_cast(MuonFillMap)) { + float p = muon.p(); + fgValues.pDca = p * dcaXY; + } + } + + if (endPoint == kToAbsEnd) { + double xAbs = propmuon.getX(); + double yAbs = propmuon.getY(); + fgValues.rabs = std::sqrt(xAbs * xAbs + yAbs * yAbs); + } + } + + template + void FillMatching(TTrack const& track, Var& fgValuesMCH, Var& fgValuesMFT) + { + fgValuesMCH.chi2matching = track.chi2MatchMCHMID(); + fgValuesMFT.chi2matching = track.chi2MatchMCHMFT(); + } + + template + void FillMuonHistograms(Var const& fgValuesMCH, Var const& fgValuesMCHpv, Var const& fgValuesMFT, Var const& fgValuesGlobal, VarVector const& fgValuesCandidates) + { + if constexpr (static_cast(MuonFillMap)) { + // Muon histograms + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, 1.E10, configMuons.fPMchLow, configMuons.fPtMchLow, configMuons.fEtaMchLow, configMuons.fEtaMchUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + registry.get(HIST("muons/TrackChi2"))->Fill(fgValuesMCH.chi2); + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, 0., configMuons.fPtMchLow, configMuons.fEtaMchLow, configMuons.fEtaMchUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + registry.get(HIST("muons/TrackP"))->Fill(fgValuesMCH.p); + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, configMuons.fPMchLow, 0., configMuons.fEtaMchLow, configMuons.fEtaMchUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + registry.get(HIST("muons/TrackPt"))->Fill(fgValuesMCH.pT); + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, configMuons.fPMchLow, configMuons.fPtMchLow, -1.E10, 1.E10, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + registry.get(HIST("muons/TrackEta"))->Fill(fgValuesMCH.eta); + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, configMuons.fPMchLow, configMuons.fPtMchLow, configMuons.fEtaMchLow, configMuons.fEtaMchUp, 0., 1.E10, configMuons.fSigmaPdcaUp)) { + registry.get(HIST("muons/TrackRabs"))->Fill(fgValuesMCH.rabs); + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, configMuons.fPMchLow, configMuons.fPtMchLow, configMuons.fEtaMchLow, configMuons.fEtaMchUp, configMuons.fRabsLow, configMuons.fRabsUp, 1.E10)) { + registry.get(HIST("muons/TrackPDCA"))->Fill(fgValuesMCH.pDca); + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, configMuons.fPMchLow, configMuons.fPtMchLow, configMuons.fEtaMchLow, configMuons.fEtaMchUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + registry.get(HIST("muons/TrackPhi"))->Fill(fgValuesMCH.phi * 180.0 / TMath::Pi()); + registry.get(HIST("muons/TrackDCA"))->Fill(std::sqrt(fgValuesMCH.dcaX * fgValuesMCH.dcaX + fgValuesMCH.dcaY * fgValuesMCH.dcaY)); + } + } + + if constexpr (static_cast(GlobalMuonFillMap)) { + // Global muon histograms + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, 1.E10, configMuons.fPMchLow, configMuons.fPtMchLow, configMFTs.fEtaMftLow, configMFTs.fEtaMftUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + registry.get(HIST("global-muons/TrackChi2"))->Fill(fgValuesMCH.chi2); + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, 0., configMuons.fPtMchLow, configMFTs.fEtaMftLow, configMFTs.fEtaMftUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + registry.get(HIST("global-muons/TrackP"))->Fill(fgValuesMCH.p); + + // Momentum correlations + registry.get(HIST("global-muons/MomentumCorrelation_Global_vs_Muon"))->Fill(fgValuesMCH.p, fgValuesGlobal.p); + if (fgValuesMCH.p != 0) { + registry.get(HIST("global-muons/MomentumDifference_Global_vs_Muon"))->Fill(fgValuesMCH.p, (fgValuesGlobal.p - fgValuesMCH.p) / fgValuesMCH.p); + } + + if (fgValuesCandidates.size() >= 2) { + registry.get(HIST("global-muons/MomentumCorrelation_subleading_vs_leading"))->Fill(fgValuesCandidates[0].p, fgValuesCandidates[1].p); + if (fgValuesCandidates[0].p != 0) { + registry.get(HIST("global-muons/MomentumDifference_subleading_vs_leading"))->Fill(fgValuesCandidates[0].p, (fgValuesCandidates[1].p - fgValuesCandidates[0].p) / fgValuesCandidates[0].p); + } + } + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, configMuons.fPMchLow, 0., configMFTs.fEtaMftLow, configMFTs.fEtaMftUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + registry.get(HIST("global-muons/TrackPt"))->Fill(fgValuesMCH.pT); + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, configMuons.fPMchLow, configMuons.fPtMchLow, -1.E10, 1.E10, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + registry.get(HIST("global-muons/TrackEta"))->Fill(fgValuesMCH.eta); + + // Eta correlations + registry.get(HIST("global-muons/EtaCorrelation_Global_vs_Muon"))->Fill(fgValuesMCH.eta, fgValuesGlobal.eta); + if (fgValuesMCH.eta != 0) { + registry.get(HIST("global-muons/EtaDifference_Global_vs_Muon"))->Fill(fgValuesMCH.eta, (fgValuesGlobal.eta - fgValuesMCH.eta) / fgValuesMCH.eta); + } + + if (fgValuesCandidates.size() >= 2) { + registry.get(HIST("global-muons/EtaCorrelation_subleading_vs_leading"))->Fill(fgValuesCandidates[0].eta, fgValuesCandidates[1].eta); + if (fgValuesCandidates[0].eta != 0) { + registry.get(HIST("global-muons/EtaDifference_subleading_vs_leading"))->Fill(fgValuesCandidates[0].eta, (fgValuesCandidates[1].eta - fgValuesCandidates[0].eta) / fgValuesCandidates[0].eta); + } + } + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, configMuons.fPMchLow, configMuons.fPtMchLow, configMFTs.fEtaMftLow, configMFTs.fEtaMftUp, 0., 1.E10, configMuons.fSigmaPdcaUp)) { + registry.get(HIST("global-muons/TrackRabs"))->Fill(fgValuesMCH.rabs); + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, configMuons.fPMchLow, configMuons.fPtMchLow, configMFTs.fEtaMftLow, configMFTs.fEtaMftUp, configMuons.fRabsLow, configMuons.fRabsUp, 1.E10)) { + registry.get(HIST("global-muons/TrackPDCA"))->Fill(fgValuesMCH.pDca); + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, configMuons.fPMchLow, configMuons.fPtMchLow, configMFTs.fEtaMftLow, configMFTs.fEtaMftUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + registry.get(HIST("global-muons/TrackPhi"))->Fill(fgValuesMCH.phi * 180.0 / TMath::Pi()); + registry.get(HIST("global-muons/TrackDCA"))->Fill(std::sqrt(fgValuesMCH.dcaX * fgValuesMCH.dcaX + fgValuesMCH.dcaY * fgValuesMCH.dcaY)); + } + } + + if constexpr (static_cast(GlobalMatchingFillMap)) { + // Global muon histograms + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, 1.E10, configMuons.fPMchLow, configMuons.fPtMchLow, configMFTs.fEtaMftLow, configMFTs.fEtaMftUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + if (IsGoodGlobalMatching(fgValuesMFT, configMFTs.fTrackChi2MftUp, configMFTs.fTrackNClustMftLow, fMatchingChi2MftMchUp)) { + registry.get(HIST("global-matches/TrackChi2"))->Fill(fgValuesMCH.chi2); + } + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, 0., configMuons.fPtMchLow, configMFTs.fEtaMftLow, configMFTs.fEtaMftUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + if (IsGoodGlobalMatching(fgValuesMFT, configMFTs.fTrackChi2MftUp, configMFTs.fTrackNClustMftLow, fMatchingChi2MftMchUp)) { + registry.get(HIST("global-matches/TrackP"))->Fill(fgValuesMCH.p); + } + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, configMuons.fPMchLow, 0., configMFTs.fEtaMftLow, configMFTs.fEtaMftUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + if (IsGoodGlobalMatching(fgValuesMFT, configMFTs.fTrackChi2MftUp, configMFTs.fTrackNClustMftLow, fMatchingChi2MftMchUp)) { + registry.get(HIST("global-matches/TrackPt"))->Fill(fgValuesMCH.pT); + } + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, configMuons.fPMchLow, configMuons.fPtMchLow, -1.E10, 1.E10, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + if (IsGoodGlobalMatching(fgValuesMFT, configMFTs.fTrackChi2MftUp, configMFTs.fTrackNClustMftLow, fMatchingChi2MftMchUp)) { + registry.get(HIST("global-matches/TrackEta"))->Fill(fgValuesMCH.eta); + } + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, configMuons.fPMchLow, configMuons.fPtMchLow, configMFTs.fEtaMftLow, configMFTs.fEtaMftUp, 0., 1.E10, configMuons.fSigmaPdcaUp)) { + if (IsGoodGlobalMatching(fgValuesMFT, configMFTs.fTrackChi2MftUp, configMFTs.fTrackNClustMftLow, fMatchingChi2MftMchUp)) { + registry.get(HIST("global-matches/TrackRabs"))->Fill(fgValuesMCH.rabs); + } + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, configMuons.fPMchLow, configMuons.fPtMchLow, configMFTs.fEtaMftLow, configMFTs.fEtaMftUp, configMuons.fRabsLow, configMuons.fRabsUp, 1.E10)) { + if (IsGoodGlobalMatching(fgValuesMFT, configMFTs.fTrackChi2MftUp, configMFTs.fTrackNClustMftLow, fMatchingChi2MftMchUp)) { + registry.get(HIST("global-matches/TrackPDCA"))->Fill(fgValuesMCH.pDca); + } + } + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, configMuons.fPMchLow, configMuons.fPtMchLow, configMFTs.fEtaMftLow, configMFTs.fEtaMftUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + if (IsGoodGlobalMatching(fgValuesMFT, configMFTs.fTrackChi2MftUp, configMFTs.fTrackNClustMftLow, fMatchingChi2MftMchUp)) { + registry.get(HIST("global-matches/TrackPhi"))->Fill(fgValuesMCH.phi * 180.0 / TMath::Pi()); + registry.get(HIST("global-matches/TrackDCA"))->Fill(std::sqrt(fgValuesMCH.dcaX * fgValuesMCH.dcaX + fgValuesMCH.dcaY * fgValuesMCH.dcaY)); + + registry.get(HIST("global-matches/TrackP_glo"))->Fill(fgValuesGlobal.p); + registry.get(HIST("global-matches/TrackPt_glo"))->Fill(fgValuesGlobal.pT); + registry.get(HIST("global-matches/TrackEta_glo"))->Fill(fgValuesGlobal.eta); + registry.get(HIST("global-matches/TrackPhi_glo"))->Fill(fgValuesGlobal.phi * 180.0 / TMath::Pi()); + registry.get(HIST("global-matches/TrackDCA_glo"))->Fill(std::sqrt(fgValuesGlobal.dcaX * fgValuesGlobal.dcaX + fgValuesGlobal.dcaY * fgValuesGlobal.dcaY)); + } + if (IsGoodGlobalMatching(fgValuesMFT, 1.E10, configMFTs.fTrackNClustMftLow, fMatchingChi2MftMchUp)) { + registry.get(HIST("global-matches/TrackChi2_MFT"))->Fill(fgValuesMFT.chi2); + } + if (IsGoodGlobalMatching(fgValuesMFT, configMFTs.fTrackChi2MftUp, 0, fMatchingChi2MftMchUp)) { + registry.get(HIST("global-matches/TrackNclusters_MFT"))->Fill(fgValuesMFT.nClusters); + } + if (IsGoodGlobalMatching(fgValuesMFT, configMFTs.fTrackChi2MftUp, configMFTs.fTrackNClustMftLow, 1.E10)) { + registry.get(HIST("global-matches/MatchChi2"))->Fill(fgValuesMFT.chi2matching); + } + } + } + } + + template + void FillTrackResidualHistograms(VarVector const& fgVectorsMCH, VarVector const& fgVectorsMFT, int quadrant, bool same, bool mixed) + { + std::vector> xPos; + std::vector> yPos; + std::vector> thetax; + std::vector> thetay; + for (int zi = 0; zi < int(zRefPlane.size()); zi++) { + xPos.emplace_back(std::array{fgVectorsMCH[zi].x, fgVectorsMFT[zi].x}); + yPos.emplace_back(std::array{fgVectorsMCH[zi].y, fgVectorsMFT[zi].y}); + thetax.emplace_back(std::array{ + std::atan2(fgVectorsMCH[zi].px, -1.0 * fgVectorsMCH[zi].pz) * 180 / TMath::Pi(), + std::atan2(fgVectorsMFT[zi].px, -1.0 * fgVectorsMFT[zi].pz) * 180 / TMath::Pi()}); + thetay.emplace_back(std::array{ + std::atan2(fgVectorsMCH[zi].py, -1.0 * fgVectorsMCH[zi].pz) * 180 / TMath::Pi(), + std::atan2(fgVectorsMFT[zi].py, -1.0 * fgVectorsMFT[zi].pz) * 180 / TMath::Pi()}); + } + + for (int i = 0; i < int(zRefPlane.size()); i++) { + if (same) { + std::get>(trackResidualsHistos[i][quadrant]["dx_vs_x"])->Fill(std::fabs(xPos[i][1]), xPos[i][0] - xPos[i][1]); + std::get>(trackResidualsHistos[i][quadrant]["dx_vs_y"])->Fill(std::fabs(yPos[i][1]), xPos[i][0] - xPos[i][1]); + std::get>(trackResidualsHistos[i][quadrant]["dy_vs_x"])->Fill(std::fabs(xPos[i][1]), yPos[i][0] - yPos[i][1]); + std::get>(trackResidualsHistos[i][quadrant]["dy_vs_y"])->Fill(std::fabs(yPos[i][1]), yPos[i][0] - yPos[i][1]); + + std::get>(trackResidualsHistos[i][quadrant]["dthetax_vs_x"])->Fill(std::fabs(xPos[i][1]), thetax[i][0] - thetax[i][1]); + std::get>(trackResidualsHistos[i][quadrant]["dthetax_vs_y"])->Fill(std::fabs(yPos[i][1]), thetax[i][0] - thetax[i][1]); + std::get>(trackResidualsHistos[i][quadrant]["dthetax_vs_thetax"])->Fill(std::fabs(thetax[i][1]), thetax[i][0] - thetax[i][1]); + std::get>(trackResidualsHistos[i][quadrant]["dthetay_vs_x"])->Fill(std::fabs(xPos[i][1]), thetay[i][0] - thetay[i][1]); + std::get>(trackResidualsHistos[i][quadrant]["dthetay_vs_y"])->Fill(std::fabs(yPos[i][1]), thetay[i][0] - thetay[i][1]); + std::get>(trackResidualsHistos[i][quadrant]["dthetay_vs_thetay"])->Fill(std::fabs(thetay[i][1]), thetay[i][0] - thetay[i][1]); + } + if (mixed) { + std::get>(trackResidualsHistosMixedEvents[i][quadrant]["dx_vs_x"])->Fill(std::fabs(xPos[i][1]), xPos[i][0] - xPos[i][1]); + std::get>(trackResidualsHistosMixedEvents[i][quadrant]["dx_vs_y"])->Fill(std::fabs(yPos[i][1]), xPos[i][0] - xPos[i][1]); + std::get>(trackResidualsHistosMixedEvents[i][quadrant]["dy_vs_x"])->Fill(std::fabs(xPos[i][1]), yPos[i][0] - yPos[i][1]); + std::get>(trackResidualsHistosMixedEvents[i][quadrant]["dy_vs_y"])->Fill(std::fabs(yPos[i][1]), yPos[i][0] - yPos[i][1]); + + std::get>(trackResidualsHistosMixedEvents[i][quadrant]["dthetax_vs_x"])->Fill(std::fabs(xPos[i][1]), thetax[i][0] - thetax[i][1]); + std::get>(trackResidualsHistosMixedEvents[i][quadrant]["dthetax_vs_y"])->Fill(std::fabs(yPos[i][1]), thetax[i][0] - thetax[i][1]); + std::get>(trackResidualsHistosMixedEvents[i][quadrant]["dthetax_vs_thetax"])->Fill(std::fabs(thetax[i][1]), thetax[i][0] - thetax[i][1]); + std::get>(trackResidualsHistosMixedEvents[i][quadrant]["dthetay_vs_x"])->Fill(std::fabs(xPos[i][1]), thetay[i][0] - thetay[i][1]); + std::get>(trackResidualsHistosMixedEvents[i][quadrant]["dthetay_vs_y"])->Fill(std::fabs(yPos[i][1]), thetay[i][0] - thetay[i][1]); + std::get>(trackResidualsHistosMixedEvents[i][quadrant]["dthetay_vs_thetay"])->Fill(std::fabs(thetay[i][1]), thetay[i][0] - thetay[i][1]); + } + } + } + + template + void FillDCAHistograms(VarT const& fgValues, VarC const& fgValuesColl, int sign, int quadrant, bool same, bool mixed) + { + if constexpr (static_cast(MuonFillMap)) { + if (same) { + std::get>(dcaHistos[1][quadrant][0]["DCA_x"])->Fill(fgValues.dcaX); + std::get>(dcaHistos[1][quadrant][0]["DCA_y"])->Fill(fgValues.dcaY); + std::get>(dcaHistos[1][quadrant][sign]["DCA_x"])->Fill(fgValues.dcaX); + std::get>(dcaHistos[1][quadrant][sign]["DCA_y"])->Fill(fgValues.dcaY); + } + if (mixed) { + std::get>(dcaHistosMixedEvents[1][quadrant][0]["DCA_x"])->Fill(fgValues.dcaX); + std::get>(dcaHistosMixedEvents[1][quadrant][0]["DCA_y"])->Fill(fgValues.dcaY); + std::get>(dcaHistosMixedEvents[1][quadrant][sign]["DCA_x"])->Fill(fgValues.dcaX); + std::get>(dcaHistosMixedEvents[1][quadrant][sign]["DCA_y"])->Fill(fgValues.dcaY); + } + } + + if constexpr (static_cast(GlobalMuonFillMap)) { + if (same) { + std::get>(dcaHistos[0][quadrant][0]["DCA_x"])->Fill(fgValues.dcaX); + std::get>(dcaHistos[0][quadrant][0]["DCA_y"])->Fill(fgValues.dcaY); + std::get>(dcaHistos[0][quadrant][sign]["DCA_x"])->Fill(fgValues.dcaX); + std::get>(dcaHistos[0][quadrant][sign]["DCA_y"])->Fill(fgValues.dcaY); + std::get>(dcaHistos[0][quadrant][0]["DCA_x_vs_z"])->Fill(fgValuesColl.z, fgValues.dcaX); + std::get>(dcaHistos[0][quadrant][0]["DCA_y_vs_z"])->Fill(fgValuesColl.z, fgValues.dcaY); + } + + if (mixed) { + std::get>(dcaHistosMixedEvents[0][quadrant][0]["DCA_x"])->Fill(fgValues.dcaX); + std::get>(dcaHistosMixedEvents[0][quadrant][0]["DCA_y"])->Fill(fgValues.dcaY); + std::get>(dcaHistosMixedEvents[0][quadrant][sign]["DCA_x"])->Fill(fgValues.dcaX); + std::get>(dcaHistosMixedEvents[0][quadrant][sign]["DCA_y"])->Fill(fgValues.dcaY); + std::get>(dcaHistosMixedEvents[0][quadrant][0]["DCA_x_vs_z"])->Fill(fgValuesColl.z, fgValues.dcaX); + std::get>(dcaHistosMixedEvents[0][quadrant][0]["DCA_y_vs_z"])->Fill(fgValuesColl.z, fgValues.dcaY); + } + } + } + + template + void FillResidualHistograms(Var const& fgValuesProp, Var const& fgValuesMCH, Var const& fgValuesMCHpv, Var const& fgValuesMFT, float xCls, float yCls, int topBottom, int posNeg, int quadrant, int chamber, int deIndex, bool same, bool mixed) + { + std::array xPos{xCls, fgValuesProp.x}; + std::array yPos{yCls, fgValuesProp.y}; + double phiClus = std::atan2(yCls, xCls) * 180 / TMath::Pi(); + + if constexpr (static_cast(MuonFillMap)) { + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, 20., configMuons.fPtMchLow, configMFTs.fEtaMftLow, configMFTs.fEtaMftUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + if (same) { + std::get>(mchResidualsHistosPerDE[topBottom][posNeg][chamber]["dx_vs_de"])->Fill(deIndex, xPos[0] - xPos[1]); + std::get>(mchResidualsHistosPerDE[topBottom][posNeg][chamber]["dy_vs_de"])->Fill(deIndex, yPos[0] - yPos[1]); + } + if (mixed) { + std::get>(mchResidualsHistosPerDEMixedEvents[topBottom][posNeg][chamber]["dx_vs_de"])->Fill(deIndex, xPos[0] - xPos[1]); + std::get>(mchResidualsHistosPerDEMixedEvents[topBottom][posNeg][chamber]["dy_vs_de"])->Fill(deIndex, yPos[0] - yPos[1]); + } + } + } + + if constexpr (static_cast(MFTFillMap)) { + if (IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, 20., configMuons.fPtMchLow, configMFTs.fEtaMftLow, configMFTs.fEtaMftUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + if (IsGoodMFT(fgValuesMFT, configMFTs.fTrackChi2MftUp, configMFTs.fTrackNClustMftLow)) { + if (same) { + std::get>(residualsHistos[quadrant][chamber]["dx_vs_x"])->Fill(std::fabs(xPos[1]), xPos[0] - xPos[1]); + std::get>(residualsHistos[quadrant][chamber]["dx_vs_y"])->Fill(std::fabs(yPos[1]), xPos[0] - xPos[1]); + std::get>(residualsHistos[quadrant][chamber]["dy_vs_x"])->Fill(std::fabs(xPos[1]), yPos[0] - yPos[1]); + std::get>(residualsHistos[quadrant][chamber]["dy_vs_y"])->Fill(std::fabs(yPos[1]), yPos[0] - yPos[1]); + + // residuals vs. DE index + std::get>(residualsHistosPerDE[topBottom][posNeg][chamber]["dx_vs_de"])->Fill(deIndex, xPos[0] - xPos[1]); + std::get>(residualsHistosPerDE[topBottom][posNeg][chamber]["dy_vs_de"])->Fill(deIndex, yPos[0] - yPos[1]); + + // residuals vs. cluster phi + std::get>(residualsHistosPerDE[topBottom][posNeg][chamber]["dx_vs_phi"])->Fill(phiClus, xPos[0] - xPos[1]); + std::get>(residualsHistosPerDE[topBottom][posNeg][chamber]["dy_vs_phi"])->Fill(phiClus, yPos[0] - yPos[1]); + } + if (mixed) { + std::get>(residualsHistosMixedEvents[quadrant][chamber]["dx_vs_x"])->Fill(std::fabs(xPos[1]), xPos[0] - xPos[1]); + std::get>(residualsHistosMixedEvents[quadrant][chamber]["dx_vs_y"])->Fill(std::fabs(yPos[1]), xPos[0] - xPos[1]); + std::get>(residualsHistosMixedEvents[quadrant][chamber]["dy_vs_x"])->Fill(std::fabs(xPos[1]), yPos[0] - yPos[1]); + std::get>(residualsHistosMixedEvents[quadrant][chamber]["dy_vs_y"])->Fill(std::fabs(yPos[1]), yPos[0] - yPos[1]); + + // residuals vs. DE index + std::get>(residualsHistosPerDEMixedEvents[topBottom][posNeg][chamber]["dx_vs_de"])->Fill(deIndex, xPos[0] - xPos[1]); + std::get>(residualsHistosPerDEMixedEvents[topBottom][posNeg][chamber]["dy_vs_de"])->Fill(deIndex, yPos[0] - yPos[1]); + + // residuals vs. cluster phi + std::get>(residualsHistosPerDEMixedEvents[topBottom][posNeg][chamber]["dx_vs_phi"])->Fill(phiClus, xPos[0] - xPos[1]); + std::get>(residualsHistosPerDEMixedEvents[topBottom][posNeg][chamber]["dy_vs_phi"])->Fill(phiClus, yPos[0] - yPos[1]); + } + } + } + } + } + + template + void resetVar(Var& fgValues) + { + fgValues = {}; + } + + void initCCDB(aod::BCsWithTimestamps const& bcs) + { + // Update CCDB informations + if (bcs.size() > 0 && fCurrentRun != bcs.begin().runNumber()) { + // Load magnetic field information from CCDB/local + ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + grpmag = ccdb->getForTimeStamp(configCCDB.grpmagPath, bcs.begin().timestamp()); + if (grpmag != nullptr) { + base::Propagator::initFieldFromGRP(grpmag); + TrackExtrap::setField(); + TrackExtrap::useExtrapV2(); + fieldB = static_cast(TGeoGlobalMagField::Instance()->GetField()); // for MFT + double centerMFT[3] = {0, 0, -61.4}; // or use middle point between Vtx and MFT? + Bz = fieldB->getBz(centerMFT); // Get field at centre of MFT + } else { + LOGF(fatal, "GRP object is not available in CCDB at timestamp=%llu", bcs.begin().timestamp()); + } + + // Load geometry information from CCDB/local + LOGF(info, "Loading reference aligned geometry from CCDB no later than %d", configCCDB.nolaterthan.value); + ccdb->setCreatedNotAfter(configCCDB.nolaterthan); // this timestamp has to be consistent with what has been used in reco + geoRef = ccdb->getForTimeStamp(configCCDB.geoPath, bcs.begin().timestamp()); + ccdb->clearCache(configCCDB.geoPath); + if (geoRef != nullptr) { + transformation = geo::transformationFromTGeoManager(*geoRef); + } else { + LOGF(fatal, "Reference aligned geometry object is not available in CCDB at timestamp=%llu", bcs.begin().timestamp()); + } + for (int i = 0; i < 156; i++) { + int iDEN = GetDetElemId(i); + transformRef[iDEN] = transformation(iDEN); + } + + if (configRealign.fDoRealign) { + LOGF(info, "Loading new aligned geometry from CCDB no later than %d", configCCDB.nolaterthanRealign.value); + ccdb->setCreatedNotAfter(configCCDB.nolaterthanRealign); // make sure this timestamp can be resolved regarding the reference one + geoNew = ccdb->getForTimeStamp(configCCDB.geoPathRealign, bcs.begin().timestamp()); + ccdb->clearCache(configCCDB.geoPathRealign); + if (geoNew != nullptr) { + transformation = geo::transformationFromTGeoManager(*geoNew); + } else { + LOGF(fatal, "New aligned geometry object is not available in CCDB at timestamp=%llu", bcs.begin().timestamp()); + } + for (int i = 0; i < 156; i++) { + int iDEN = GetDetElemId(i); + transformNew[iDEN] = transformation(iDEN); + } + } + + fCurrentRun = bcs.begin().runNumber(); + } + } + + void init(InitContext const&) + { + fCurrentRun = 0; + + // Configuration for CCDB server + ccdb->setURL(configCCDB.ccdburl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + + // Configuration for track fitter + const auto& trackerParam = TrackerParam::Instance(); + trackFitter.setBendingVertexDispersion(trackerParam.bendingVertexDispersion); + trackFitter.setChamberResolution(configRealign.fChamberResolutionX, configRealign.fChamberResolutionY); + trackFitter.smoothTracks(true); + trackFitter.useChamberResolution(); + mImproveCutChi2 = 2. * configRealign.fSigmaCutImprove * configRealign.fSigmaCutImprove; + + CreateBasicHistograms(); + CreateDetailedHistograms(); + } + + template + void runDCA(TEventMap const& collisions, TMFTTracks const& mfts, TTrack const& muon, mch::Track const& mchrealigned, VarC& fgValuesColl, VarT& fgValuesMCH, VarT& fgValuesMCHpv, VarT& fgValuesMFT) + { + if constexpr (static_cast(MuonFillMap)) { + + // track selection + if (!IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, 30., 4., configMFTs.fEtaMftLow, configMFTs.fEtaMftUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + return; + } + + // Loop over collisions + for (auto& [collisionId, fgValuesColltmp] : collisions) { + + bool sameEvent = (fgValuesColltmp.bc == fgValuesColl.bc); + bool mixedEvent = IsMixedEvent(fgValuesColltmp, fgValuesColl); + + if (!sameEvent && !mixedEvent) { + continue; + } + + // Fill propagation of MCH track to DCA + if (configRealign.fDoRealign) { + FillPropagation(mchrealigned, fgValuesColltmp, fgValuesMCH, kToDCA); + } else { + FillPropagation<1>(muon, fgValuesColltmp, VarTrack{}, fgValuesMCH, kToDCA); + } + + double phi = fgValuesMCH.phi * 180 / TMath::Pi(); + int quadrant = GetQuadrantPhi(phi); + int sign = (fgValuesMCH.sign > 0) ? 1 : 2; + + // Fill DCA QA histograms + FillDCAHistograms<1, 0>(fgValuesMCH, fgValuesColltmp, sign, quadrant, sameEvent, mixedEvent); + } + } + + if constexpr (static_cast(GlobalMuonFillMap)) { + auto mftsThisCollision = mfts.sliceBy(mftPerCollision, fgValuesColl.globalIndex); + for (auto const& mft : mftsThisCollision) { + + // Fill MFT track + VarTrack fgValuesMFTtmp; + FillTrack<0>(mft, fgValuesMFTtmp); + + if (fgValuesMFT.trackTime != fgValuesMFTtmp.trackTime) { + continue; // if not time compatible + } + + if (!IsGoodMFT(fgValuesMFTtmp, configMFTs.fTrackChi2MftUp, configMFTs.fTrackNClustMftLow)) { + continue; + } + + int quadrant = GetQuadrantTrack(mft); + if (quadrant < 0) { + continue; + } + + int sign = (fgValuesMFTtmp.sign > 0) ? 1 : 2; + + for (auto& [collisionId, fgValuesColltmp] : collisions) { + + bool sameEvent = (fgValuesColltmp.bc == fgValuesColl.bc); + bool mixedEvent = IsMixedEvent(fgValuesColltmp, fgValuesColl); + + if (!sameEvent && !mixedEvent) { + continue; + } + + // Propagate MFT track to DCA + FillPropagation<0, 1>(mft, fgValuesColltmp, VarTrack{}, fgValuesMFTtmp, kToDCA); + + // Fill DCA QA histograms + FillDCAHistograms<0, 1>(fgValuesMFTtmp, fgValuesColltmp, sign, quadrant, sameEvent, mixedEvent); + } + resetVar(fgValuesMFTtmp); + } + } + } + + template + void runResidual(TEventMap const& collisions, TMuons const& muons, TMFTTracks const& mfts, TMuonCls const& clusters, TMCHTrack const& mchtrack, mch::Track const& mchrealigned, TMFTTrack const& mfttrack, VarC const& fgValuesColl, VarT const& fgValuesMCH, VarT const& fgValuesMCHpv, VarT const& fgValuesMFT) + { + if (!IsGoodMuon(fgValuesMCH, fgValuesMCHpv, configMuons.fTrackChi2MchUp, 20., configMuons.fPtMchLow, configMFTs.fEtaMftLow, configMFTs.fEtaMftUp, configMuons.fRabsLow, configMuons.fRabsUp, configMuons.fSigmaPdcaUp)) { + return; + } + + double phi = fgValuesMCH.phi * 180 / TMath::Pi(); + int quadrant = GetQuadrantPhi(phi); + + //// MCH-MFT track residuals + if (mfttrack.has_collision()) { + auto& fgValuesCollMatched = collisions.at(mfttrack.collisionId()); + + // Do extrapolation for muons to all reference planes + vector mchTrackExtrap; + for (double z : zRefPlane) { + VarTrack fgValues; + if (configRealign.fDoRealign) { + FillPropagation(mchrealigned, VarColl{}, fgValues, kToZ, z); + } else { + FillPropagation<1>(mchtrack, VarColl{}, VarTrack{}, fgValues, kToZ, z); + } + mchTrackExtrap.emplace_back(fgValues); + } + + // Loop over MFT tracks + for (auto const& mft : mfts) { + + if (!mft.has_collision()) { + continue; + } + + // Fill MFT track + VarTrack fgValuesMFTtmp; + FillTrack<0>(mft, fgValuesMFTtmp); + + // Track selection + if (!IsGoodMFT(fgValuesMFTtmp, configMFTs.fTrackChi2MftUp, configMFTs.fTrackNClustMftLow)) { + continue; + } + + auto& fgValuesCollMFT = collisions.at(mft.collisionId()); + + bool sameEvent = (fgValuesCollMFT.bc == fgValuesCollMatched.bc); + bool mixedEvent = IsMixedEvent(fgValuesCollMFT, fgValuesColl); + if (!sameEvent && !mixedEvent) { + continue; + } + + // Do extrapolation for MFTs to all reference planes + vector mftTrackExtrap; + for (double z : zRefPlane) { + VarTrack fgValues; + FillPropagation<0, 1>(mft, fgValuesCollMFT, mchTrackExtrap[1], fgValues, kToZ, z); + mftTrackExtrap.emplace_back(fgValues); + } + + //// Fill QA histograms for alignment checks + FillTrackResidualHistograms(mchTrackExtrap, mftTrackExtrap, quadrant, sameEvent, mixedEvent); + + resetVar(fgValuesMFTtmp); + } + } + + //// Track-Cluster residuals + for (auto const& muon : muons) { + if (static_cast(muon.trackType()) <= 2) { + continue; + } + if (!muon.has_collision()) { + continue; + } + auto& fgValuesCollMCH = collisions.at(muon.collisionId()); + + bool sameEvent = (fgValuesCollMCH.bc == fgValuesColl.bc); + bool mixedEvent = IsMixedEvent(fgValuesCollMCH, fgValuesColl); + if (!sameEvent && !mixedEvent) { + continue; + } + + //// Fill MCH clusters: do re-alignment if asked + mch::Track mchrealignedTmp; + VarClusters fgValuesClsTmp; + if (!FillClusters(muon, clusters, fgValuesClsTmp, mchrealignedTmp)) { + continue; // Refit is not valid + } + + // Loop over attached clusters + for (int iCls = 0; iCls < int(fgValuesClsTmp.posClusters.size()); iCls++) { + + double phiCls = std::atan2(fgValuesClsTmp.posClusters[iCls][1], fgValuesClsTmp.posClusters[iCls][0]) * 180 / TMath::Pi(); + int quadrantCls = GetQuadrantPhi(phiCls); + int DEId = fgValuesClsTmp.DEIDs[iCls]; + int chamber = DEId / 100 - 1; + int deIndex = DEId % 100; + + //// MCH residuals + //// Propagate MCH track to given cluster + VarTrack fgValuesMCHprop; + if (configRealign.fDoRealign) { + FillPropagation(mchrealigned, VarColl{}, fgValuesMCHprop, kToZ, fgValuesClsTmp.posClusters[iCls][2]); + } else { + FillPropagation<1>(mchtrack, VarColl{}, VarTrack{}, fgValuesMCHprop, kToZ, fgValuesClsTmp.posClusters[iCls][2]); + } + + //// Fill residual QA histograms + int topBottom = (fgValuesMCH.y >= 0) ? 0 : 1; + int posNeg = (fgValuesMCH.sign >= 0) ? 0 : 1; + FillResidualHistograms<1, 0>(fgValuesMCHprop, fgValuesMCH, fgValuesMCHpv, fgValuesMFT, fgValuesClsTmp.posClusters[iCls][0], fgValuesClsTmp.posClusters[iCls][1], topBottom, posNeg, quadrantCls, chamber, deIndex, sameEvent, mixedEvent); + resetVar(fgValuesMCHprop); + + //// MFT residuals + if (IsGoodMFT(fgValuesMFT, configMFTs.fTrackChi2MftUp, configMFTs.fTrackNClustMftLow)) { + //// Propagate MFT track to given cluster + VarTrack fgValuesMFTprop; + FillPropagation<0, 1>(mfttrack, VarColl{}, fgValuesMCH, fgValuesMFTprop, kToZ, fgValuesClsTmp.posClusters[iCls][2]); + + //// Fill residual QA histograms for MFT + topBottom = (mfttrack.y() >= 0) ? 0 : 1; + posNeg = (fgValuesMCH.sign >= 0) ? 0 : 1; + FillResidualHistograms<0, 1>(fgValuesMFTprop, fgValuesMCH, fgValuesMCHpv, fgValuesMFT, fgValuesClsTmp.posClusters[iCls][0], fgValuesClsTmp.posClusters[iCls][1], topBottom, posNeg, quadrantCls, chamber, deIndex, sameEvent, mixedEvent); + resetVar(fgValuesMFTprop); + } + } + } + } + + template + void runEventSelection(TEvents const& collisions, TBcs const& bcs, TFwdTracks const& muons, TMFTTracks const& mfts, TMap& collisionSel) + { + for (auto const& collision : collisions) { + + uint64_t collisionIndex = collision.globalIndex(); + auto muonsThisCollision = muons.sliceBy(fwdtracksPerCollision, collisionIndex); + auto mftsThisCollision = mfts.sliceBy(mftPerCollision, collisionIndex); + + if (muonsThisCollision.size() < 1 && mftsThisCollision.size() < 1) { + continue; + } + + auto& fgValuesColl = collisionSel[collisionIndex]; + FillCollision(collision, fgValuesColl); + fgValuesColl.bc = bcs.rawIteratorAt(collision.bcId()).globalBC(); + fgValuesColl.multMFT = mftsThisCollision.size(); + } + } + + template + void runMuonQA(TEventMap const& collisions, TCandidateMap& matchingCandidates, TFwdTracks const& muons, TMFTTracks const& mfts, TMuonCls const& clusters) + { + //// First loop over all muon tracks + for (auto const& muon : muons) { + + //// Get collision information if associated + VarColl fgValuesColl; + if (muon.has_collision()) { + fgValuesColl = collisions.at(muon.collisionId()); + } else { + continue; + } + + if (static_cast(muon.trackType()) <= 2) { // MFT-MCH-MID(0) or MFT-MCH(2) + + registry.get(HIST("global-muons/nTracksPerType"))->Fill(static_cast(muon.trackType())); + + // auto mfttrack = muon.template matchMFTTrack_as(); // unused parameter? + auto mchtrack = muon.template matchMCHTrack_as(); + + // Fill global matching candidates: global muons per MCH track + FillMatchingCandidates(muon, mchtrack, matchingCandidates); + + } else { // MCH-MID(3) or MCH(4) + + // Fill MCH tracks + FillTrack<1>(muon, fgValuesMCH); + + // Propagate MCH to PV + FillPropagation<1>(muon, fgValuesColl, fgValuesMCH, fgValuesMCHpv); // copied in a separate variable + + //// Fill MCH clusters: re-align clusters if required + mch::Track mchrealigned; + VarClusters fgValuesCls; + if (!FillClusters(muon, clusters, fgValuesCls, mchrealigned)) { + continue; // if refit was not passed + } + + //// Update MCH tracks kinematics if using realigned muons + if (configRealign.fDoRealign) { + + // Update track info + FillTrack(mchrealigned, fgValuesMCH); + + // Update propagate of MCH to PV + FillPropagation(mchrealigned, fgValuesColl, fgValuesMCHpv); + + // Update pDCA and Rabs values + FillPropagation(mchrealigned, fgValuesColl, fgValuesMCH, kToAbsEnd); + FillPropagation(mchrealigned, fgValuesColl, fgValuesMCH, kToDCA); + } + + //// Fill muon QA histograms + FillMuonHistograms<1, 0, 0>(fgValuesMCH, fgValuesMCHpv, fgValuesMFT, VarTrack{}, nullptr); + + //// Fill muon DCA QA checks + if (configQAs.fEnableQADCA) { + runDCA<1, 0>(collisions, mfts, muon, mchrealigned, fgValuesColl, fgValuesMCH, fgValuesMCHpv, fgValuesMFT); + } + } + + resetVar(fgValuesMFT); + resetVar(fgValuesMCH); + resetVar(fgValuesMCHpv); + } + + //// Second loop over global muon tracks + for (auto& [mchIndex, globalMuonsVector] : matchingCandidates) { + + //// sort matching candidates in ascending order based on the matching chi2 + auto compareChi2 = [&muons](uint64_t trackIndex1, uint64_t trackIndex2) -> bool { + auto const& track1 = muons.rawIteratorAt(trackIndex1); + auto const& track2 = muons.rawIteratorAt(trackIndex2); + + return (track1.chi2MatchMCHMFT() < track2.chi2MatchMCHMFT()); + }; + std::sort(globalMuonsVector.begin(), globalMuonsVector.end(), compareChi2); + + //// Get tracks + auto muontrack = muons.rawIteratorAt(globalMuonsVector[0]); + auto mchtrack = muontrack.template matchMCHTrack_as(); + auto mfttrack = muontrack.template matchMFTTrack_as(); + + //// Fill matching chi2 + FillMatching(muontrack, fgValuesMCH, fgValuesMFT); + + //// Fill global informations + registry.get(HIST("global-muons/NCandidates"))->Fill(int(globalMuonsVector.size())); + for (size_t candidateIndex = 0; candidateIndex < globalMuonsVector.size(); candidateIndex++) { + auto const& muon = muons.rawIteratorAt(globalMuonsVector[candidateIndex]); + registry.get(HIST("global-muons/MatchChi2"))->Fill(muon.chi2MatchMCHMFT(), candidateIndex); + } + + //// Fill collision information if avalaible + auto& fgValuesCollGlo = collisions.at(muontrack.collisionId()); + VarColl fgValuesCollMCH; // in principal should be the same as global muon + if (mchtrack.has_collision()) { + fgValuesCollMCH = collisions.at(mchtrack.collisionId()); + } + + //// Fill MCH and MFT tracks: basic info copied from input tables + FillTrack<1>(mchtrack, fgValuesMCH); + FillTrack<0>(mfttrack, fgValuesMFT); + FillTrack<1>(muontrack, fgValuesGlobal); + + //// Propagate MCH to PV + FillPropagation<1>(mchtrack, fgValuesCollMCH, VarTrack{}, fgValuesMCHpv); // saved in separate variable fgValuesMCHpv + + //// Fill MCH clusters: re-align clusters if required + mch::Track mchrealigned; + VarClusters fgValuesCls; + if (!FillClusters(mchtrack, clusters, fgValuesCls, mchrealigned)) { + continue; // if refit was not passed + } + + //// Update MCH tracks kinematics if using realigned muons + if (configRealign.fDoRealign) { + // Update track info + FillTrack(mchrealigned, fgValuesMCH); + + // Update propagation of MCH to PV + FillPropagation(mchrealigned, fgValuesCollMCH, fgValuesMCHpv); + + // Update pDCA and Rabs values + FillPropagation(mchrealigned, fgValuesCollMCH, fgValuesMCH, kToAbsEnd); + FillPropagation(mchrealigned, fgValuesCollMCH, fgValuesMCH, kToDCA); + } + + //// Fill global muon candidates info + for (int i = 0; i < int(globalMuonsVector.size()); i++) { + VarTrack fgValuesTmp; + auto muonCandidate = muons.rawIteratorAt(globalMuonsVector[i]); + FillTrack<0>(muonCandidate, fgValuesTmp); + fgValuesCandidates.emplace_back(fgValuesTmp); + } + + //// Fill global muons QA : fill global matching QA if required + if (configQAs.fEnableQAMatching) { + + // Propagate global muon tracks to DCA: treat it as MFT using p from MCH? + FillPropagation<0, 1>(muontrack, fgValuesCollGlo, fgValuesMCH, fgValuesGlobal, kToDCA); + + // Fill bc difference of matched MCH and MFT + if (muontrack.has_collision() && mfttrack.has_collision()) { + fgValuesMCH.bc = collisions.at(muontrack.collisionId()).bc; + fgValuesMFT.bc = collisions.at(mfttrack.collisionId()).bc; + int64_t dbc = fgValuesMCH.bc - fgValuesMFT.bc; + registry.get(HIST("global-matches/BCdifference"))->Fill(dbc); + } + + // Fill QA histograms including global matching + FillMuonHistograms<0, 1, 1>(fgValuesMCH, fgValuesMCHpv, fgValuesMFT, fgValuesGlobal, fgValuesCandidates); + + } else { + // Fill QA histograms + FillMuonHistograms<0, 1, 0>(fgValuesMCH, fgValuesMCHpv, fgValuesMFT, fgValuesGlobal, fgValuesCandidates); + } + + //// Fill residual QA checks if requireds + if (configQAs.fEnableQAResidual) { + runResidual(collisions, muons, mfts, clusters, mchtrack, mchrealigned, mfttrack, fgValuesCollGlo, fgValuesMCH, fgValuesMCHpv, fgValuesMFT); + } + + //// Fill MFT DCA QA checks if required + if (configQAs.fEnableQADCA) { + runDCA<0, 1>(collisions, mfts, nullptr, mch::Track(), fgValuesCollGlo, fgValuesMCH, fgValuesMCHpv, fgValuesMFT); + } + + fgValuesCandidates.clear(); + resetVar(fgValuesMFT); + resetVar(fgValuesMCH); + resetVar(fgValuesMCHpv); + resetVar(fgValuesGlobal); + } + } + + template + void runDimuonQA(TEventMap const& collisions, TCandidateMap const& matchingCandidates, TFwdTracks const& muonTracks, TMuonCls const& clusters) + { + std::vector muonPairs; + std::vector globalMuonPairs; + + GetMuonPairs(muonTracks, matchingCandidates, collisions, muonPairs, globalMuonPairs); + + for (auto& [muon1, muon2] : muonPairs) { + auto collisionIndex1 = muon1.first; + auto const& collision1 = collisions.at(collisionIndex1); + auto collisionIndex2 = muon2.first; + auto const& collision2 = collisions.at(collisionIndex2); + + auto mchIndex1 = muon1.second; + auto mchIndex2 = muon2.second; + auto const& muonTrack1 = muonTracks.rawIteratorAt(mchIndex1); + auto const& muonTrack2 = muonTracks.rawIteratorAt(mchIndex2); + + VarTrack fgValuesMuon1, fgValuesMuonPV1; + VarTrack fgValuesMuon2, fgValuesMuonPV2; + mch::Track mchrealigned1, mchrealigned2; + VarClusters fgValuesCls1, fgValuesCls2; + if (!FillClusters(muonTrack1, clusters, fgValuesCls1, mchrealigned1) || !FillClusters(muonTrack2, clusters, fgValuesCls2, mchrealigned2)) { + continue; // Refit is not valid + } + + if (configRealign.fDoRealign) { + + FillTrack(mchrealigned1, fgValuesMuon1); + FillTrack(mchrealigned2, fgValuesMuon2); + + // Propagate MCH to PV + FillPropagation(mchrealigned1, collision1, fgValuesMuonPV1); + FillPropagation(mchrealigned2, collision2, fgValuesMuonPV2); + + // Recalculate pDCA and Rabs values + FillPropagation(mchrealigned1, collision1, fgValuesMuon1, kToAbsEnd); + FillPropagation(mchrealigned1, collision1, fgValuesMuon1, kToDCA); + FillPropagation(mchrealigned2, collision2, fgValuesMuon2, kToAbsEnd); + FillPropagation(mchrealigned2, collision2, fgValuesMuon2, kToDCA); + } else { + FillTrack<1>(muonTrack1, fgValuesMuon1); + FillTrack<1>(muonTrack2, fgValuesMuon2); + + // Propagate MCH to PV + FillPropagation<1>(muonTrack1, collision1, fgValuesMuon1, fgValuesMuonPV1); + FillPropagation<1>(muonTrack2, collision2, fgValuesMuon1, fgValuesMuonPV2); + } + + int sign1 = muonTrack1.sign(); + int sign2 = muonTrack2.sign(); + + // only consider opposite-sign pairs + if ((sign1 * sign2) >= 0) + continue; + + int Quadrant1 = GetQuadrantPhi(muonTrack1.phi() * 180.0 / TMath::Pi()); + int Quadrant2 = GetQuadrantPhi(muonTrack2.phi() * 180.0 / TMath::Pi()); + int TopBottom1 = (Quadrant1 == 0 || Quadrant1 == 1) ? 0 : 1; + int TopBottom2 = (Quadrant2 == 0 || Quadrant2 == 1) ? 0 : 1; + int LeftRight1 = (Quadrant1 == 0 || Quadrant1 == 2) ? 0 : 1; + int LeftRight2 = (Quadrant2 == 0 || Quadrant2 == 2) ? 0 : 1; + + bool goodMuonTracks = (IsGoodMuon(fgValuesMuon1, fgValuesMuonPV1) && IsGoodMuon(fgValuesMuon2, fgValuesMuonPV2)); + bool goodGlobalMuonTracks = (IsGoodGlobalMuon(fgValuesMuon1, fgValuesMuonPV1) && IsGoodGlobalMuon(fgValuesMuon2, fgValuesMuonPV2)); + + bool sameEvent = (collisionIndex1 == collisionIndex2); + + double mass = GetMuMuInvariantMass(fgValuesMuonPV1, fgValuesMuonPV2); + if (goodMuonTracks) { + if (sameEvent) { + // same-event case + registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_MuonCuts"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts"))->Fill(mass); + + if (TopBottom1 == 0 && TopBottom2 == 0) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_MuonCuts_TT"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_TT"))->Fill(mass); + } else if ((TopBottom1 == 0 && TopBottom2 == 1) || (TopBottom1 == 1 && TopBottom2 == 0)) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_MuonCuts_TB"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_TB"))->Fill(mass); + } else if (TopBottom1 == 1 && TopBottom2 == 1) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_MuonCuts_BB"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_BB"))->Fill(mass); + } + + if (LeftRight1 == 0 && LeftRight2 == 0) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_MuonCuts_LL"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_LL"))->Fill(mass); + } else if ((LeftRight1 == 0 && LeftRight2 == 1) || (LeftRight1 == 1 && LeftRight2 == 0)) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_MuonCuts_LR"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_LR"))->Fill(mass); + } else if (LeftRight1 == 1 && LeftRight2 == 1) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_MuonCuts_RR"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_MuonCuts_RR"))->Fill(mass); + } + } else { + // event-mixing case + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts"))->Fill(mass); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts"))->Fill(mass); + + if (TopBottom1 == 0 && TopBottom2 == 0) { + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_TT"))->Fill(mass); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_TT"))->Fill(mass); + } else if ((TopBottom1 == 0 && TopBottom2 == 1) || (TopBottom1 == 1 && TopBottom2 == 0)) { + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_TB"))->Fill(mass); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_TB"))->Fill(mass); + } else if (TopBottom1 == 1 && TopBottom2 == 1) { + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_BB"))->Fill(mass); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_BB"))->Fill(mass); + } + + if (LeftRight1 == 0 && LeftRight2 == 0) { + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_LL"))->Fill(mass); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_LL"))->Fill(mass); + } else if ((LeftRight1 == 0 && LeftRight2 == 1) || (LeftRight1 == 1 && LeftRight2 == 0)) { + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_LR"))->Fill(mass); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_LR"))->Fill(mass); + } else if (LeftRight1 == 1 && LeftRight2 == 1) { + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_MuonCuts_RR"))->Fill(mass); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_MuonCuts_RR"))->Fill(mass); + } + } + } + + if (goodGlobalMuonTracks) { + if (sameEvent) { + // same-event case + registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_GlobalMuonCuts"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_GlobalMuonCuts"))->Fill(mass); + + if (TopBottom1 == 0 && TopBottom2 == 0) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_GlobalMuonCuts_TT"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_GlobalMuonCuts_TT"))->Fill(mass); + } else if ((TopBottom1 == 0 && TopBottom2 == 1) || (TopBottom1 == 1 && TopBottom2 == 0)) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_GlobalMuonCuts_TB"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_GlobalMuonCuts_TB"))->Fill(mass); + } else if (TopBottom1 == 1 && TopBottom2 == 1) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_GlobalMuonCuts_BB"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_GlobalMuonCuts_BB"))->Fill(mass); + } + + if (LeftRight1 == 0 && LeftRight2 == 0) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_GlobalMuonCuts_LL"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_GlobalMuonCuts_LL"))->Fill(mass); + } else if ((LeftRight1 == 0 && LeftRight2 == 1) || (LeftRight1 == 1 && LeftRight2 == 0)) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_GlobalMuonCuts_LR"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_GlobalMuonCuts_LR"))->Fill(mass); + } else if (LeftRight1 == 1 && LeftRight2 == 1) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_GlobalMuonCuts_RR"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_GlobalMuonCuts_RR"))->Fill(mass); + } + } else { + // event-mixing case + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_GlobalMuonCuts"))->Fill(mass); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_GlobalMuonCuts"))->Fill(mass); + + if (TopBottom1 == 0 && TopBottom2 == 0) { + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_GlobalMuonCuts_TT"))->Fill(mass); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_GlobalMuonCuts_TT"))->Fill(mass); + } else if ((TopBottom1 == 0 && TopBottom2 == 1) || (TopBottom1 == 1 && TopBottom2 == 0)) { + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_GlobalMuonCuts_TB"))->Fill(mass); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_GlobalMuonCuts_TB"))->Fill(mass); + } else if (TopBottom1 == 1 && TopBottom2 == 1) { + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_GlobalMuonCuts_BB"))->Fill(mass); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_GlobalMuonCuts_BB"))->Fill(mass); + } + + if (LeftRight1 == 0 && LeftRight2 == 0) { + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_GlobalMuonCuts_LL"))->Fill(mass); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_GlobalMuonCuts_LL"))->Fill(mass); + } else if ((LeftRight1 == 0 && LeftRight2 == 1) || (LeftRight1 == 1 && LeftRight2 == 0)) { + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_GlobalMuonCuts_LR"))->Fill(mass); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_GlobalMuonCuts_LR"))->Fill(mass); + } else if (LeftRight1 == 1 && LeftRight2 == 1) { + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_GlobalMuonCuts_RR"))->Fill(mass); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_GlobalMuonCuts_RR"))->Fill(mass); + } + } + } + } + + for (auto& [muon1, muon2] : globalMuonPairs) { + auto collisionIndex1 = muon1.first; + auto collisionIndex2 = muon2.first; + auto& globalTracksVector1 = muon1.second; + auto& globalTracksVector2 = muon2.second; + + auto const& collision1 = collisions.at(collisionIndex1); + auto const& collision2 = collisions.at(collisionIndex2); + + auto const& muonTrack1 = muonTracks.rawIteratorAt(globalTracksVector1[0]); + auto const& muonTrack2 = muonTracks.rawIteratorAt(globalTracksVector2[0]); + auto const& mftTrack1 = muonTrack1.template matchMFTTrack_as(); + auto const& mftTrack2 = muonTrack2.template matchMFTTrack_as(); + auto const& mchTrack1 = muonTrack1.template matchMCHTrack_as(); + auto const& mchTrack2 = muonTrack2.template matchMCHTrack_as(); + + VarTrack fgValuesMuon1, fgValuesMuonPV1, fgValuesMCH1, fgValuesMCHpv1, fgValuesMFT1, fgValuesMFTpv1; + VarTrack fgValuesMuon2, fgValuesMuonPV2, fgValuesMCH2, fgValuesMCHpv2, fgValuesMFT2, fgValuesMFTpv2; + + // Fill MCH and MFT tracks + FillTrack<1>(mchTrack1, fgValuesMCH1); + FillTrack<0>(mftTrack1, fgValuesMFT1); + FillTrack<1>(muonTrack1, fgValuesMuon1); + FillTrack<1>(mchTrack2, fgValuesMCH2); + FillTrack<0>(mftTrack2, fgValuesMFT2); + FillTrack<1>(muonTrack2, fgValuesMuon2); + + //// Fill matching chi2 + FillMatching(muonTrack1, fgValuesMCH1, fgValuesMFT1); + FillMatching(muonTrack2, fgValuesMCH2, fgValuesMFT2); + + mch::Track mchrealigned1, mchrealigned2; + VarClusters fgValuesCls1, fgValuesCls2; + if (!FillClusters(muonTrack1, clusters, fgValuesCls1, mchrealigned1) || !FillClusters(muonTrack2, clusters, fgValuesCls2, mchrealigned2)) { + continue; // Refit is not valid + } + + if (configRealign.fDoRealign) { + + FillTrack(mchrealigned1, fgValuesMCH1); + FillTrack(mchrealigned2, fgValuesMCH2); + + // Propagate MCH to PV + FillPropagation(mchrealigned1, collision1, fgValuesMCHpv1); + FillPropagation(mchrealigned2, collision2, fgValuesMCHpv2); + + // Recalculate pDCA and Rabs values + FillPropagation(mchrealigned1, collision1, fgValuesMCH1, kToAbsEnd); + FillPropagation(mchrealigned1, collision1, fgValuesMCH1, kToDCA); + FillPropagation(mchrealigned2, collision2, fgValuesMCH2, kToAbsEnd); + FillPropagation(mchrealigned2, collision2, fgValuesMCH2, kToDCA); + + } else { + FillTrack<1>(mchTrack1, fgValuesMCH1); + FillTrack<1>(mchTrack2, fgValuesMCH2); + + // Propagate MCH to PV + FillPropagation<1>(mchTrack1, collision1, fgValuesMCH1, fgValuesMCHpv1); + FillPropagation<1>(mchTrack2, collision2, fgValuesMCH2, fgValuesMCHpv2); + } + + // Propagate global muon tracks to PV + FillPropagation<0>(muonTrack1, collision1, fgValuesMCH1, fgValuesMuonPV1); + FillPropagation<0>(muonTrack2, collision2, fgValuesMCH2, fgValuesMuonPV2); + + // Propagate MFT tracks to PV + FillPropagation<0, 1>(mftTrack1, collision1, fgValuesMCH1, fgValuesMFTpv1); + FillPropagation<0, 1>(mftTrack2, collision2, fgValuesMCH2, fgValuesMFTpv2); + + int sign1 = mchTrack1.sign(); + int sign2 = mchTrack2.sign(); + + // only consider opposite-sign pairs + if ((sign1 * sign2) >= 0) + continue; + + // indexes indicating whether the positive and negative tracks come from the top or bottom halves of MFT + int posTopBottom = (sign1 > 0) ? ((muonTrack1.y() >= 0) ? 0 : 1) : ((muonTrack2.y() >= 0) ? 0 : 1); + int negTopBottom = (sign1 < 0) ? ((muonTrack1.y() >= 0) ? 0 : 1) : ((muonTrack2.y() >= 0) ? 0 : 1); + + bool goodGlobalMuonTracks = (IsGoodGlobalMuon(fgValuesMCH1, fgValuesMCHpv1) && IsGoodGlobalMuon(fgValuesMCH2, fgValuesMCHpv2)); + bool goodGlobalMuonMatches = (IsGoodGlobalMatching(fgValuesMFT1) && IsGoodGlobalMatching(fgValuesMFT2)); + + bool sameEvent = (collisionIndex1 == collisionIndex2); + + if (goodGlobalMuonTracks && goodGlobalMuonMatches) { + + double massMCH = GetMuMuInvariantMass(fgValuesMCHpv1, fgValuesMCHpv2); + double mass = GetMuMuInvariantMass(fgValuesMuonPV1, fgValuesMuonPV2); + double massScaled = GetMuMuInvariantMass(fgValuesMFTpv1, fgValuesMFTpv2); + + if (sameEvent) { + // same-event case + registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_GlobalMatchesCuts"))->Fill(massMCH); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_MuonKine_GlobalMatchesCuts"))->Fill(massMCH); + registryDimuon.get(HIST("dimuon/same-event/invariantMass_GlobalMuonKine_GlobalMatchesCuts"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_GlobalMuonKine_GlobalMatchesCuts"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMass_ScaledMftKine_GlobalMatchesCuts"))->Fill(massScaled); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_ScaledMftKine_GlobalMatchesCuts"))->Fill(massScaled); + + if (posTopBottom == 0 && negTopBottom == 0) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_ScaledMftKine_GlobalMatchesCuts_TT"))->Fill(massScaled); + } else if (posTopBottom == 0 && negTopBottom == 1) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_ScaledMftKine_GlobalMatchesCuts_TB"))->Fill(massScaled); + } else if (posTopBottom == 1 && negTopBottom == 0) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_ScaledMftKine_GlobalMatchesCuts_BT"))->Fill(massScaled); + } else if (posTopBottom == 1 && negTopBottom == 1) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_ScaledMftKine_GlobalMatchesCuts_BB"))->Fill(massScaled); + } + + // mass correlation + registryDimuon.get(HIST("dimuon/same-event/invariantMass_MuonKine_vs_GlobalMuonKine"))->Fill(mass, massMCH); + registryDimuon.get(HIST("dimuon/same-event/invariantMass_ScaledMftKine_vs_GlobalMuonKine"))->Fill(mass, massScaled); + } else { + // event-mixing case + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_MuonKine_GlobalMatchesCuts"))->Fill(massMCH); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_MuonKine_GlobalMatchesCuts"))->Fill(massMCH); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_GlobalMuonKine_GlobalMatchesCuts"))->Fill(mass); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_GlobalMuonKine_GlobalMatchesCuts"))->Fill(mass); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_ScaledMftKine_GlobalMatchesCuts"))->Fill(massScaled); + registryDimuon.get(HIST("dimuon/mixed-event/invariantMassFull_ScaledMftKine_GlobalMatchesCuts"))->Fill(massScaled); + + if (posTopBottom == 0 && negTopBottom == 0) { + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_ScaledMftKine_GlobalMatchesCuts_TT"))->Fill(massScaled); + } else if (posTopBottom == 0 && negTopBottom == 1) { + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_ScaledMftKine_GlobalMatchesCuts_TB"))->Fill(massScaled); + } else if (posTopBottom == 1 && negTopBottom == 0) { + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_ScaledMftKine_GlobalMatchesCuts_BT"))->Fill(massScaled); + } else if (posTopBottom == 1 && negTopBottom == 1) { + registryDimuon.get(HIST("dimuon/mixed-event/invariantMass_ScaledMftKine_GlobalMatchesCuts_BB"))->Fill(massScaled); + } + } + } + + // plots for sub-leading matches are only filled in the same-event case + if (sameEvent) { + if (globalTracksVector1.size() > 1) { + VarTrack fgValuesMuonb1, fgValuesMuonbpv1, fgValuesMFTb1; + auto const& muonTrack1b = muonTracks.rawIteratorAt(globalTracksVector1[1]); + FillTrack<1>(muonTrack1b, fgValuesMuonb1); + FillPropagation<0>(muonTrack1b, collision1, fgValuesMCH1, fgValuesMuonbpv1); + + goodGlobalMuonTracks = (IsGoodGlobalMuon(fgValuesMCH1, fgValuesMCHpv1) && IsGoodGlobalMuon(fgValuesMCH2, fgValuesMCHpv2)); + goodGlobalMuonMatches = (IsGoodGlobalMatching(fgValuesMFTb1) && IsGoodGlobalMatching(fgValuesMFT2)); + double mass = GetMuMuInvariantMass(fgValuesMuonbpv1, fgValuesMuonPV2); + if (goodGlobalMuonTracks && goodGlobalMuonMatches) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_GlobalMuonKine_GlobalMatchesCuts_subleading_leading"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_GlobalMuonKine_GlobalMatchesCuts_subleading_leading"))->Fill(mass); + } + } + + if (globalTracksVector2.size() > 1) { + VarTrack fgValuesMuonb2, fgValuesMuonbpv2, fgValuesMFTb2; + auto const& muonTrack2b = muonTracks.rawIteratorAt(globalTracksVector2[1]); + FillTrack<1>(muonTrack2b, fgValuesMuonb2); + FillPropagation<0>(muonTrack2b, collision2, fgValuesMCH2, fgValuesMuonbpv2); + + goodGlobalMuonTracks = (IsGoodGlobalMuon(fgValuesMCH1, fgValuesMCHpv1) && IsGoodGlobalMuon(fgValuesMCH2, fgValuesMCHpv2)); + goodGlobalMuonMatches = (IsGoodGlobalMatching(fgValuesMFTb2) && IsGoodGlobalMatching(fgValuesMFT1)); + double mass = GetMuMuInvariantMass(fgValuesMuonbpv2, fgValuesMuonPV1); + if (goodGlobalMuonTracks && goodGlobalMuonMatches) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_GlobalMuonKine_GlobalMatchesCuts_leading_subleading"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_GlobalMuonKine_GlobalMatchesCuts_leading_subleading"))->Fill(mass); + } + } + + if (globalTracksVector1.size() > 1 && globalTracksVector2.size() > 1) { + VarTrack fgValuesMuonb1, fgValuesMuonbpv1, fgValuesMFTb1; + VarTrack fgValuesMuonb2, fgValuesMuonbpv2, fgValuesMFTb2; + auto const& muonTrack1b = muonTracks.rawIteratorAt(globalTracksVector1[1]); + auto const& muonTrack2b = muonTracks.rawIteratorAt(globalTracksVector2[1]); + + FillTrack<1>(muonTrack1b, fgValuesMuonb1); + FillPropagation<0>(muonTrack1b, collision1, fgValuesMCH1, fgValuesMuonbpv1); + + FillTrack<1>(muonTrack2b, fgValuesMuonb2); + FillPropagation<0>(muonTrack2b, collision2, fgValuesMCH2, fgValuesMuonbpv2); + + goodGlobalMuonTracks = (IsGoodGlobalMuon(fgValuesMCH1, fgValuesMCHpv1) && IsGoodGlobalMuon(fgValuesMCH2, fgValuesMCHpv2)); + goodGlobalMuonMatches = (IsGoodGlobalMatching(fgValuesMFTb1) && IsGoodGlobalMatching(fgValuesMFTb2)); + double mass = GetMuMuInvariantMass(fgValuesMuonbpv1, fgValuesMuonbpv2); + double massLeading = GetMuMuInvariantMass(fgValuesMuonPV1, fgValuesMuonPV2); + if (goodGlobalMuonTracks && goodGlobalMuonMatches) { + registryDimuon.get(HIST("dimuon/same-event/invariantMass_GlobalMuonKine_GlobalMatchesCuts_subleading_subleading"))->Fill(mass); + registryDimuon.get(HIST("dimuon/same-event/invariantMassFull_GlobalMuonKine_GlobalMatchesCuts_subleading_subleading"))->Fill(mass); + + // mass correlation + registryDimuon.get(HIST("dimuon/same-event/invariantMass_GlobalMuonKine_subleading_vs_leading"))->Fill(massLeading, mass); + } + } + } + } + } + + void processMuonQa(MyEvents const& collisions, aod::BCsWithTimestamps const& bcs, MyMuonsWithCov const& muontracks, MyMFTs const& mfttracks, aod::FwdTrkCls const& muonclusters) + { + std::map collisionSel; + std::map> matchingCandidates; + + initCCDB(bcs); + + runEventSelection(collisions, bcs, muontracks, mfttracks, collisionSel); + + runMuonQA(collisionSel, matchingCandidates, muontracks, mfttracks, muonclusters); + + if (configQAs.fEnableQADimuon) { + runDimuonQA(collisionSel, matchingCandidates, muontracks, muonclusters); + } + } + PROCESS_SWITCH(muonQa, processMuonQa, "Process to run muon QA", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/DPG/Tasks/AOTEvent/dEdxVsOccupancyWithTrackQAinfo.cxx b/DPG/Tasks/AOTEvent/dEdxVsOccupancyWithTrackQAinfo.cxx index 36af0603ee8..a9e90a1b33a 100644 --- a/DPG/Tasks/AOTEvent/dEdxVsOccupancyWithTrackQAinfo.cxx +++ b/DPG/Tasks/AOTEvent/dEdxVsOccupancyWithTrackQAinfo.cxx @@ -14,31 +14,32 @@ /// /// \author Igor Altsybeev -#include -#include "map" - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Common/DataModel/EventSelection.h" #include "Common/CCDB/EventSelectionParams.h" #include "Common/CCDB/ctpRateFetcher.h" -#include "CCDB/BasicCCDBManager.h" -#include "Framework/HistogramRegistry.h" -#include "CommonDataFormat/BunchFilling.h" -#include "DataFormatsParameters/GRPLHCIFData.h" -#include "DataFormatsParameters/GRPECSObject.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CommonDataFormat/BunchFilling.h" #include "DataFormatsParameters/AggregatedRunInfo.h" +#include "DataFormatsParameters/GRPECSObject.h" +#include "DataFormatsParameters/GRPLHCIFData.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" #include "TH1F.h" #include "TH2F.h" #include "TH3.h" +#include +#include + using namespace o2; using namespace o2::framework; using namespace o2::aod::evsel; diff --git a/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx b/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx index c6dbbe1a17a..8f08e7e4545 100644 --- a/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx +++ b/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx @@ -14,30 +14,31 @@ /// /// \author Igor Altsybeev -#include -#include "map" - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Common/DataModel/EventSelection.h" #include "Common/CCDB/EventSelectionParams.h" -#include "CCDB/BasicCCDBManager.h" -#include "Framework/HistogramRegistry.h" -#include "CommonDataFormat/BunchFilling.h" -#include "DataFormatsParameters/GRPLHCIFData.h" -#include "DataFormatsParameters/GRPECSObject.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CommonDataFormat/BunchFilling.h" #include "DataFormatsParameters/AggregatedRunInfo.h" +#include "DataFormatsParameters/GRPECSObject.h" +#include "DataFormatsParameters/GRPLHCIFData.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" #include "TH1F.h" #include "TH2F.h" #include "TH3.h" +#include +#include + using namespace o2; using namespace o2::framework; using namespace o2::aod::evsel; diff --git a/DPG/Tasks/AOTTrack/qaEventTrack.cxx b/DPG/Tasks/AOTTrack/qaEventTrack.cxx index 847ec4f0388..8bc884208cb 100644 --- a/DPG/Tasks/AOTTrack/qaEventTrack.cxx +++ b/DPG/Tasks/AOTTrack/qaEventTrack.cxx @@ -23,21 +23,22 @@ #include "qaEventTrack.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "ReconstructionDataFormats/DCA.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" #include "Common/Core/trackUtilities.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectionDefaults.h" #include "Common/TableProducer/PID/pidTOFBase.h" -#include "string" -#include "vector" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/DCA.h" + +#include +#include using namespace o2; using namespace o2::framework; diff --git a/DPG/Tasks/AOTTrack/qaImpPar.cxx b/DPG/Tasks/AOTTrack/qaImpPar.cxx index 1f7494c9395..78d1847cdf8 100644 --- a/DPG/Tasks/AOTTrack/qaImpPar.cxx +++ b/DPG/Tasks/AOTTrack/qaImpPar.cxx @@ -10,33 +10,32 @@ // or submit itself to any jurisdiction. /// \author Mattia Faggin , Padova University and INFN -#include - -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "ReconstructionDataFormats/DCA.h" +#include "Common/Core/TrackSelection.h" #include "Common/Core/trackUtilities.h" // for propagation to primary vertex - #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/PIDResponse.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "CommonUtils/NameConf.h" -#include "Framework/AnalysisDataModel.h" -#include "Common/Core/TrackSelection.h" -#include "DetectorsVertexing/PVertexer.h" -#include "ReconstructionDataFormats/Vertex.h" +#include "Common/DataModel/TrackSelectionTables.h" + #include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "Framework/RunningWorkflowInfo.h" #include "CCDB/CcdbApi.h" -#include "DataFormatsCalibration/MeanVertexObject.h" #include "CommonConstants/GeomConstants.h" +#include "CommonUtils/NameConf.h" +#include "DataFormatsCalibration/MeanVertexObject.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsVertexing/PVertexer.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" +#include "ReconstructionDataFormats/DCA.h" +#include "ReconstructionDataFormats/Vertex.h" -#include "iostream" -#include "vector" -#include "set" +#include +#include +#include +#include using namespace o2::framework; using namespace o2::framework::expressions; diff --git a/DPG/Tasks/AOTTrack/qaMatchEff.cxx b/DPG/Tasks/AOTTrack/qaMatchEff.cxx index ddcdf65766e..895e0bd33b4 100644 --- a/DPG/Tasks/AOTTrack/qaMatchEff.cxx +++ b/DPG/Tasks/AOTTrack/qaMatchEff.cxx @@ -32,9 +32,9 @@ #include "Framework/RunningWorkflowInfo.h" #include "Framework/runDataProcessing.h" // -#include "string" -#include "vector" -#include "set" +#include +#include +#include // namespace extConfPar { diff --git a/DPG/Tasks/CMakeLists.txt b/DPG/Tasks/CMakeLists.txt index 959ed3e5637..642f8d6e772 100644 --- a/DPG/Tasks/CMakeLists.txt +++ b/DPG/Tasks/CMakeLists.txt @@ -18,3 +18,4 @@ add_subdirectory(FDD) add_subdirectory(MFT) add_subdirectory(Monitor) add_subdirectory(FT0) +add_subdirectory(ITS) diff --git a/DPG/Tasks/ITS/CMakeLists.txt b/DPG/Tasks/ITS/CMakeLists.txt new file mode 100644 index 00000000000..2850271fb41 --- /dev/null +++ b/DPG/Tasks/ITS/CMakeLists.txt @@ -0,0 +1,18 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. + +o2physics_add_dpl_workflow(its-impact-parameter-studies + SOURCES itsImpParStudies.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + O2::ReconstructionDataFormats + O2::DetectorsCommonDataFormats + O2::DetectorsVertexing + COMPONENT_NAME Analysis) diff --git a/DPG/Tasks/ITS/itsImpParStudies.cxx b/DPG/Tasks/ITS/itsImpParStudies.cxx new file mode 100644 index 00000000000..6ed71d41aa5 --- /dev/null +++ b/DPG/Tasks/ITS/itsImpParStudies.cxx @@ -0,0 +1,698 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +/// \author Samuele Cattaruzzi + +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" // for propagation to primary vertex +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" +#include "CommonConstants/GeomConstants.h" +#include "CommonUtils/NameConf.h" +#include "DataFormatsCalibration/MeanVertexObject.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsVertexing/PVertexer.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" +#include "ReconstructionDataFormats/DCA.h" +#include "ReconstructionDataFormats/Vertex.h" + +#include "iostream" +#include "set" +#include "vector" +#include + +using namespace o2::framework; +using namespace o2::framework::expressions; + +// void customize(std::vector& workflowOptions) +//{ +// ConfigParamSpec optionDoMC{"doMC", VariantType::Bool, false, {"Fill MC histograms."}}; +// workflowOptions.push_back(optionDoMC); +// } + +#include "Framework/runDataProcessing.h" + +/// QA task for impact parameter distribution monitoring +struct ItsImpactParStudies { + + /// Input parameters + Configurable fDebug{"fDebug", false, "Debug flag enabling outputs"}; + Configurable fEnablePulls{"fEnablePulls", false, "Enable storage of pulls"}; + ConfigurableAxis binningImpPar{"binningImpPar", {200, -500.f, 500.f}, "Impact parameter binning"}; + ConfigurableAxis binningPulls{"binningPulls", {200, -10.f, 10.f}, "Pulls binning"}; + ConfigurableAxis binningPt{"binningPt", {100, 0.f, 10.f}, "Pt binning"}; + ConfigurableAxis binningEta{"binningEta", {40, -2.f, 2.f}, "Eta binning"}; + ConfigurableAxis binningPhi{"binningPhi", {24, 0.f, o2::constants::math::TwoPI}, "Phi binning"}; + ConfigurableAxis binningPDG{"binningPDG", {5, -1.5f, 3.5f}, "PDG species binning (-1: not matched, 0: unknown, 1: pi, 2: K, 3: p)"}; + ConfigurableAxis binningCharge{"binningCharge", {2, -2.f, 2.f}, "charge binning (-1: negative; +1: positive)"}; + ConfigurableAxis binningIuPosX{"binningIuPosX", {100, -10.f, 10.f}, "Track IU x position"}; + ConfigurableAxis binningIuPosY{"binningIuPosY", {100, -10.f, 10.f}, "Track IU y position"}; + ConfigurableAxis binningIuPosZ{"binningIuPosZ", {100, -10.f, 10.f}, "Track IU z position"}; + ConfigurableAxis binningClusterSize{"binningClusterSize", {16, -0.5, 15.5}, "Cluster size, four bits per a layer"}; + ConfigurableAxis binsNumPvContrib{"binsNumPvContrib", {200, 0, 200}, "Number of original PV contributors"}; + Configurable keepOnlyPhysPrimary{"keepOnlyPhysPrimary", false, "Consider only phys. primary particles (MC)"}; + Configurable keepOnlyPvContrib{"keepOnlyPvContrib", false, "Consider only PV contributor tracks"}; + // Configurable numberContributorsMin{"numberContributorsMin", 0, "Minimum number of contributors for the primary vertex"}; + Configurable useTriggerkINT7{"useTriggerkINT7", false, "Use kINT7 trigger"}; + Configurable usesel8{"usesel8", true, "Use or not the sel8() (T0A & T0C) event selection"}; + Configurable addTrackIUinfo{"addTrackIUinfo", false, "Add track parameters at inner most update"}; + Configurable trackSelection{"trackSelection", 1, "Track selection: 0 -> No Cut, 1 -> kGlobalTrack, 2 -> kGlobalTrackWoPtEta, 3 -> kGlobalTrackWoDCA, 4 -> kQualityTracks, 5 -> kInAcceptanceTracks"}; + Configurable zVtxMax{"zVtxMax", 10.f, "Maximum value for |z_vtx|"}; + // Configurable keepOnlyGlobalTracks{"keepOnlyGlobalTracks", 1, "Keep only global tracks or not"}; + Configurable ptMin{"ptMin", 0.1f, "Minimum track pt [GeV/c]"}; + Configurable nSigmaTPCPionMin{"nSigmaTPCPionMin", -99999.f, "Minimum nSigma value in TPC, pion hypothesis"}; + Configurable nSigmaTPCPionMax{"nSigmaTPCPionMax", 99999.f, "Maximum nSigma value in TPC, pion hypothesis"}; + Configurable nSigmaTPCKaonMin{"nSigmaTPCKaonMin", -99999.f, "Minimum nSigma value in TPC, kaon hypothesis"}; + Configurable nSigmaTPCKaonMax{"nSigmaTPCKaonMax", 99999.f, "Maximum nSigma value in TPC, kaon hypothesis"}; + Configurable nSigmaTPCProtonMin{"nSigmaTPCProtonMin", -99999.f, "Minimum nSigma value in TPC, proton hypothesis"}; + Configurable nSigmaTPCProtonMax{"nSigmaTPCProtonMax", 99999.f, "Maximum nSigma value in TPC, proton hypothesis"}; + Configurable nSigmaTOFPionMin{"nSigmaTOFPionMin", -99999.f, "Minimum nSigma value in TOF, pion hypothesis"}; + Configurable nSigmaTOFPionMax{"nSigmaTOFPionMax", 99999.f, "Maximum nSigma value in TOF, pion hypothesis"}; + Configurable nSigmaTOFKaonMin{"nSigmaTOFKaonMin", -99999.f, "Minimum nSigma value in TOF, kaon hypothesis"}; + Configurable nSigmaTOFKaonMax{"nSigmaTOFKaonMax", 99999.f, "Maximum nSigma value in TOF, kaon hypothesis"}; + Configurable nSigmaTOFProtonMin{"nSigmaTOFProtonMin", -99999.f, "Minimum nSigma value in TOF, proton hypothesis"}; + Configurable nSigmaTOFProtonMax{"nSigmaTOFProtonMax", 99999.f, "Maximum nSigma value in TOF, proton hypothesis"}; + // PV refit + Configurable ccdburl{"ccdburl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable ccdbPathLut{"ccdbpath_lut", "GLO/Param/MatLUT", "Path for LUT parametrization"}; + // Configurable ccdbpath_geo{"ccdbpath_geo", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + Configurable ccdbPathGrp{"ccdbpath_grp", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable doPVrefit{"doPVrefit", true, "Do PV refit"}; + Configurable fillHistoPVrefit{"fillHistoPVrefit", false, "Do PV refit"}; + Configurable nBinsDeltaXPVrefit{"nBins_DeltaX_PVrefit", 1000, "Number of bins of DeltaX for PV refit"}; + Configurable nBinsDeltaYPVrefit{"nBins_DeltaY_PVrefit", 1000, "Number of bins of DeltaY for PV refit"}; + Configurable nBinsDeltaZPVrefit{"nBins_DeltaZ_PVrefit", 1000, "Number of bins of DeltaZ for PV refit"}; + Configurable minDeltaXPVrefit{"minDeltaX_PVrefit", -0.5, "Min. DeltaX value for PV refit (cm)"}; + Configurable maxDeltaXPVrefit{"maxDeltaX_PVrefit", 0.5, "Max. DeltaX value for PV refit (cm)"}; + Configurable minDeltaYPVrefit{"minDeltaY_PVrefit", -0.5, "Min. DeltaY value for PV refit (cm)"}; + Configurable maxDeltaYPVrefit{"maxDeltaY_PVrefit", 0.5, "Max. DeltaY value for PV refit (cm)"}; + Configurable minDeltaZPVrefit{"minDeltaZ_PVrefit", -0.5, "Min. DeltaZ value for PV refit (cm)"}; + Configurable maxDeltaZPVrefit{"maxDeltaZ_PVrefit", 0.5, "Max. DeltaZ value for PV refit (cm)"}; + Configurable minPVcontrib{"minPVcontrib", 0, "Minimum number of PV contributors"}; + Configurable maxPVcontrib{"maxPVcontrib", 10000, "Maximum number of PV contributors"}; + Configurable removeDiamondConstraint{"removeDiamondConstraint", true, "Remove the diamond constraint for the PV refit"}; + Configurable keepAllTracksPVrefit{"keepAllTracksPVrefit", false, "Keep all tracks for PV refit (for debug)"}; + Configurable useCustomITSHitMap{"use_customITSHitMap", false, "Use custom ITS hitmap selection"}; + Configurable customITShitmap{"customITShitmap", 0, "Custom ITS hitmap (consider the binary representation)"}; + Configurable customITShitmap_exclude{"customITShitmap_exclude", 0, "Custom ITS hitmap of layers to be excluded (consider the binary representation)"}; + Configurable nCustomMinITShits{"n_customMinITShits", 0, "Minimum number of layers crossed by a track among those in \"customITShitmap\""}; + Configurable customForceITSTPCmatching{"custom_forceITSTPCmatching", false, "Consider or not only ITS-TPC macthed tracks when using custom ITS hitmap"}; + Configurable downsamplingFraction{"downsamplingFraction", 1.1, "Fraction of tracks to be used to fill the output objects"}; + + /// Custom cut selection objects + TrackSelection selector_ITShitmap; + + /// Selections with Filter (from o2::framework::expressions) + // Primary vertex |z_vtx| ptMin; + + /// Histogram registry (from o2::framework) + HistogramRegistry histograms{"HistogramsImpParQA"}; + bool isPIDPionApplied; + bool isPIDKaonApplied; + bool isPIDProtonApplied; + + // Needed for PV refitting + Service ccdb; + o2::base::MatLayerCylSet* lut = nullptr; + // o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + int mRunNumber; + + ///////////////////////////////////////////////////////////// + /// Process functions /// + ///////////////////////////////////////////////////////////// + + /// Data + using CollisionRecoTable = o2::soa::Join; + using TrackTable = o2::soa::Join; + using TrackFullTable = o2::soa::Join; + using TrackTableIU = o2::soa::Join; + void processData(o2::soa::Filtered::iterator const& collision, + const TrackTable& tracksUnfiltered, + const o2::soa::Filtered& tracks, + const TrackTableIU& tracksIU, + o2::aod::BCsWithTimestamps const&) + { + /// here call the template processReco function + auto bc = collision.bc_as(); + processReco(collision, tracksUnfiltered, tracks, tracksIU, 0, bc); + } + PROCESS_SWITCH(ItsImpactParStudies, processData, "process data", true); + + /// MC + using CollisionMCRecoTable = o2::soa::Join; + using TrackMCFullTable = o2::soa::Join; + void processMC(o2::soa::Filtered::iterator const& collision, + TrackTable const& tracksUnfiltered, + o2::soa::Filtered const& tracks, + const TrackTableIU& tracksIU, + const o2::aod::McParticles& mcParticles, + const o2::aod::McCollisions&, + o2::aod::BCsWithTimestamps const&) + { + /// here call the template processReco function + auto bc = collision.bc_as(); + processReco(collision, tracksUnfiltered, tracks, tracksIU, mcParticles, bc); + } + PROCESS_SWITCH(ItsImpactParStudies, processMC, "process MC", false); + + /// core template process function + /// template + /// void processReco(const C& collision, const TrackTable& unfilteredTracks, const T& tracks, + /// const T_MC& mcParticles, + /// o2::aod::BCsWithTimestamps const& bcs); + + ///////////////////////////////////////////////////////////// + + /// init function - declare and define histograms + void init(InitContext&) + { + // Primary vertex + const AxisSpec collisionXAxis{100, -20.f, 20.f, "X (cm)"}; + const AxisSpec collisionYAxis{100, -20.f, 20.f, "Y (cm)"}; + const AxisSpec collisionZAxis{100, -20.f, 20.f, "Z (cm)"}; + const AxisSpec collisionXOrigAxis{1000, -20.f, 20.f, "X original PV (cm)"}; + const AxisSpec collisionYOrigAxis{1000, -20.f, 20.f, "Y original PV (cm)"}; + const AxisSpec collisionZOrigAxis{1000, -20.f, 20.f, "Z original PV (cm)"}; + const AxisSpec collisionNumberContributorAxis{1000, 0, 1000, "Number of contributors"}; + const AxisSpec collisionDeltaX_PVrefit{nBinsDeltaXPVrefit, minDeltaXPVrefit, maxDeltaXPVrefit, "#Delta x_{PV} (cm)"}; + const AxisSpec collisionDeltaY_PVrefit{nBinsDeltaYPVrefit, minDeltaYPVrefit, maxDeltaYPVrefit, "#Delta y_{PV} (cm)"}; + const AxisSpec collisionDeltaZ_PVrefit{nBinsDeltaZPVrefit, minDeltaZPVrefit, maxDeltaZPVrefit, "#Delta z_{PV} (cm)"}; + + histograms.add("Reco/vertices", "", kTH1D, {{2, 0.5f, 2.5f, ""}}); + histograms.get(HIST("Reco/vertices"))->GetXaxis()->SetBinLabel(1, "All PV"); + histograms.get(HIST("Reco/vertices"))->GetXaxis()->SetBinLabel(2, "PV refit doable"); + histograms.add("Reco/vertices_perTrack", "", kTH1D, {{3, 0.5f, 3.5f, ""}}); + histograms.get(HIST("Reco/vertices_perTrack"))->GetXaxis()->SetBinLabel(1, "All PV"); + histograms.get(HIST("Reco/vertices_perTrack"))->GetXaxis()->SetBinLabel(2, "PV refit doable"); + histograms.get(HIST("Reco/vertices_perTrack"))->GetXaxis()->SetBinLabel(3, "PV refit #chi^{2}!=-1"); + histograms.add("Reco/vertexZ", "", kTH1D, {collisionZAxis}); + histograms.add("Reco/numberContributors", "", kTH1D, {collisionNumberContributorAxis}); + if (doPVrefit && fillHistoPVrefit) { + histograms.add("Reco/nContrib_vs_DeltaX_PVrefit", "", kTH2D, {collisionNumberContributorAxis, collisionDeltaX_PVrefit}); + histograms.add("Reco/nContrib_vs_DeltaY_PVrefit", "", kTH2D, {collisionNumberContributorAxis, collisionDeltaY_PVrefit}); + histograms.add("Reco/nContrib_vs_DeltaZ_PVrefit", "", kTH2D, {collisionNumberContributorAxis, collisionDeltaZ_PVrefit}); + histograms.add("Reco/nContrib_vs_Chi2PVrefit", "", kTH2D, {collisionNumberContributorAxis, {102, -1.5, 100.5, "#chi^{2} PV refit"}}); + histograms.add("Reco/X_PVrefitChi2minus1", "PV refit with #chi^{2}==-1", kTH2D, {collisionXAxis, collisionXOrigAxis}); + histograms.add("Reco/Y_PVrefitChi2minus1", "PV refit with #chi^{2}==-1", kTH2D, {collisionYAxis, collisionYOrigAxis}); + histograms.add("Reco/Z_PVrefitChi2minus1", "PV refit with #chi^{2}==-1", kTH2D, {collisionZAxis, collisionZOrigAxis}); + histograms.add("Reco/nContrib_PVrefitNotDoable", "N. contributors for PV refit not doable", kTH1D, {collisionNumberContributorAxis}); + histograms.add("Reco/nContrib_PVrefitChi2minus1", "N. contributors original PV for PV refit #chi^{2}==-1", kTH1D, {collisionNumberContributorAxis}); + } + + // Needed for PV refitting + ccdb->setURL(ccdburl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbPathLut)); + + mRunNumber = -1; + + /// Custom cut selection objects - ITS layers that must be present + std::set set_customITShitmap; // = {}; + constexpr std::size_t NLayersIts = 7; + if (useCustomITSHitMap) { + for (std::size_t indexItsLayer = 0; indexItsLayer < NLayersIts; indexItsLayer++) { + if ((customITShitmap & (1 << indexItsLayer)) > 0) { + set_customITShitmap.insert(static_cast(indexItsLayer)); + } + } + LOG(info) << "### customITShitmap: " << customITShitmap; + LOG(info) << "### nCustomMinITShits: " << nCustomMinITShits; + LOG(info) << "### set_customITShitmap.size(): " << set_customITShitmap.size(); + LOG(info) << "### Custom ITS hitmap checked: "; + for (std::set::iterator it = set_customITShitmap.begin(); it != set_customITShitmap.end(); it++) { + LOG(info) << "Layer " << static_cast(*it) << " "; + } + LOG(info) << "############"; + + selector_ITShitmap.SetRequireHitsInITSLayers(nCustomMinITShits, set_customITShitmap); + } + /// Custom cut selection objects - ITS layers that must be absent + std::set set_customITShitmap_exclude; // = {}; + if (useCustomITSHitMap) { + for (std::size_t indexItsLayer = 0; indexItsLayer < NLayersIts; indexItsLayer++) { + if ((customITShitmap_exclude & (1 << indexItsLayer)) > 0) { + set_customITShitmap_exclude.insert(static_cast(indexItsLayer)); + } + } + LOG(info) << "### customITShitmap_exclude: " << customITShitmap_exclude; + LOG(info) << "### set_customITShitmap_exclude.size(): " << set_customITShitmap_exclude.size(); + LOG(info) << "### ITS layers to be excluded: "; + for (std::set::iterator it = set_customITShitmap_exclude.begin(); it != set_customITShitmap_exclude.end(); it++) { + LOG(info) << "Layer " << static_cast(*it) << " "; + } + LOG(info) << "############"; + + selector_ITShitmap.SetRequireNoHitsInITSLayers(set_customITShitmap_exclude); + } + + // tracks + const AxisSpec trackPtAxis{binningPt, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec trackPaxis{binningPt, "#it{p} (GeV/#it{c})"}; + const AxisSpec trackEtaAxis{binningEta, "#it{#eta}"}; + const AxisSpec trackPhiAxis{binningPhi, "#varphi"}; + const AxisSpec trackIUposXaxis{binningIuPosX, "x (cm)"}; + const AxisSpec trackIUposYaxis{binningIuPosY, "y (cm)"}; + const AxisSpec trackIUposZaxis{binningIuPosZ, "z (cm)"}; + const AxisSpec trackIUclusterSize{binningClusterSize, "cluster size"}; + const AxisSpec trackImpParRPhiAxis{binningImpPar, "#it{d}_{r#it{#varphi}} (#mum)"}; + const AxisSpec trackImpParZAxis{binningImpPar, "#it{d}_{z} (#mum)"}; + const AxisSpec trackImpParRPhiPullsAxis{binningPulls, "#it{d}_{r#it{#varphi}} / #sigma(#it{d}_{r#it{#varphi}})"}; + const AxisSpec trackImpParZPullsAxis{binningPulls, "#it{d}_{z} / #sigma(#it{d}_{z})"}; + const AxisSpec trackNSigmaTPCPionAxis{20, -10.f, 10.f, "Number of #sigma TPC #pi^{#pm}"}; + const AxisSpec trackNSigmaTPCKaonAxis{20, -10.f, 10.f, "Number of #sigma TPC K^{#pm}"}; + const AxisSpec trackNSigmaTPCProtonAxis{20, -10.f, 10.f, "Number of #sigma TPC proton"}; + const AxisSpec trackNSigmaTOFPionAxis{20, -10.f, 10.f, "Number of #sigma TOF #pi^{#pm}"}; + const AxisSpec trackNSigmaTOFKaonAxis{20, -10.f, 10.f, "Number of #sigma TOF K^{#pm}"}; + const AxisSpec trackNSigmaTOFProtonAxis{20, -10.f, 10.f, "Number of #sigma TOF proton"}; + const AxisSpec trackPDGAxis{binningPDG, "species (-1: not matched, 0: unknown, 1: pi, 2: K, 3: p)"}; + const AxisSpec trackChargeAxis{binningCharge, "charge binning (-1: negative; +1: positive)"}; + const AxisSpec axisVertexNumContrib{binsNumPvContrib, "Number of original PV contributors"}; + const AxisSpec trackIsPvContrib{2, -0.5f, 1.5f, "is PV contributor: 1=yes, 0=no"}; + + histograms.add("Reco/pt", "", kTH1D, {trackPtAxis}); + histograms.add("Reco/itsHits", "Number of hits vs ITS layer;layer ITS", kTH2D, {{8, -1.5, 6.5, "ITS layer"}, {8, -0.5, 7.5, "Number of hits"}}); + + if (addTrackIUinfo) { + histograms.add("Reco/h4ClusterSizeIU", "", kTHnSparseD, {trackPaxis, trackImpParRPhiAxis, trackIUposXaxis, trackIUposYaxis, trackIUposZaxis, trackIUclusterSize}); + histograms.add("Reco/h4ImpParZIU", "", kTHnSparseD, {trackPaxis, trackImpParZAxis, trackIUposXaxis, trackIUposYaxis, trackIUposZaxis}); + } + + isPIDPionApplied = ((nSigmaTPCPionMin > -10.001 && nSigmaTPCPionMax < 10.001) || (nSigmaTOFPionMin > -10.001 && nSigmaTOFPionMax < 10.001)); + if (isPIDPionApplied) { + if (addTrackIUinfo) { + histograms.add("Reco/h4ClusterSizeIU_Pion", "", kTHnSparseD, {trackPaxis, trackImpParRPhiAxis, trackIUposXaxis, trackIUposYaxis, trackIUposZaxis, trackIUclusterSize}); + } + } + isPIDKaonApplied = ((nSigmaTPCKaonMin > -10.001 && nSigmaTPCKaonMax < 10.001) || (nSigmaTOFKaonMin > -10.001 && nSigmaTOFKaonMax < 10.001)); + if (isPIDKaonApplied) { + if (addTrackIUinfo) { + histograms.add("Reco/h4ClusterSizeIU_Kaon", "", kTHnSparseD, {trackPaxis, trackImpParRPhiAxis, trackIUposXaxis, trackIUposYaxis, trackIUposZaxis, trackIUclusterSize}); + } + } + isPIDProtonApplied = ((nSigmaTPCProtonMin > -10.001 && nSigmaTPCProtonMax < 10.001) || (nSigmaTOFProtonMin > -10.001 && nSigmaTOFProtonMax < 10.001)); + if (isPIDProtonApplied) { + if (addTrackIUinfo) { + histograms.add("Reco/h4ClusterSizeIU_Proton", "", kTHnSparseD, {trackPaxis, trackImpParRPhiAxis, trackIUposXaxis, trackIUposYaxis, trackIUposZaxis, trackIUclusterSize}); + } + } + histograms.add("Reco/hNSigmaTPCPion", "", kTH2D, {trackPtAxis, trackNSigmaTPCPionAxis}); + histograms.add("Reco/hNSigmaTPCKaon", "", kTH2D, {trackPtAxis, trackNSigmaTPCKaonAxis}); + histograms.add("Reco/hNSigmaTPCProton", "", kTH2D, {trackPtAxis, trackNSigmaTPCProtonAxis}); + histograms.add("Reco/hNSigmaTOFPion", "", kTH2D, {trackPtAxis, trackNSigmaTOFPionAxis}); + histograms.add("Reco/hNSigmaTOFKaon", "", kTH2D, {trackPtAxis, trackNSigmaTOFKaonAxis}); + histograms.add("Reco/hNSigmaTOFProton", "", kTH2D, {trackPtAxis, trackNSigmaTOFProtonAxis}); + histograms.add("Reco/hNSigmaTPCPion_afterPID", "", kTH2D, {trackPtAxis, trackNSigmaTPCPionAxis}); + histograms.add("Reco/hNSigmaTPCKaon_afterPID", "", kTH2D, {trackPtAxis, trackNSigmaTPCKaonAxis}); + histograms.add("Reco/hNSigmaTPCProton_afterPID", "", kTH2D, {trackPtAxis, trackNSigmaTPCProtonAxis}); + histograms.add("Reco/hNSigmaTOFPion_afterPID", "", kTH2D, {trackPtAxis, trackNSigmaTOFPionAxis}); + histograms.add("Reco/hNSigmaTOFKaon_afterPID", "", kTH2D, {trackPtAxis, trackNSigmaTOFKaonAxis}); + histograms.add("Reco/hNSigmaTOFProton_afterPID", "", kTH2D, {trackPtAxis, trackNSigmaTOFProtonAxis}); + + histograms.add("MC/vertexZ_MCColl", "", kTH1D, {collisionZAxis}); + histograms.add("MC/ptMC", "", kTH1D, {trackPtAxis}); + } + + /// core template process function + template + void processReco(const C& collision, const TrackTable& unfilteredTracks, const T& tracks, + const TrackTableIU& tracksIU, const T_MC& /*mcParticles*/, + o2::aod::BCsWithTimestamps::iterator const& bc) + { + constexpr float toMicrometers = 10000.f; // Conversion from [cm] to [mum] + + /// trigger selection + if (useTriggerkINT7) { + // from Tutorial/src/multiplicityEventTrackSelection.cxx + if (!collision.alias_bit(kINT7)) { + return; + } + } + /// offline event selections + if (usesel8 && !collision.sel8()) { + return; + } + + histograms.fill(HIST("Reco/vertices"), 1); + histograms.fill(HIST("Reco/vertexZ"), collision.posZ()); + histograms.fill(HIST("Reco/numberContributors"), collision.numContrib()); + if constexpr (IS_MC) { + if (collision.has_mcCollision()) { + histograms.fill(HIST("MC/vertexZ_MCColl"), collision.mcCollision().posZ()); + } + } + + /////////////////////////////////// + /// For PV refit /// + /////////////////////////////////// + /// retrieve the tracks contributing to the primary vertex fitting + std::vector vec_globID_contr = {}; + std::vector vec_TrkContributos = {}; + if (fDebug) { + LOG(info) << "\n === New collision"; + } + const int nTrk = unfilteredTracks.size(); + int nContrib = 0; + int nNonContrib = 0; + for (const auto& unfilteredTrack : unfilteredTracks) { + if (!unfilteredTrack.isPVContributor()) { + /// the track di not contribute to fit the primary vertex + nNonContrib++; + continue; + } + vec_globID_contr.push_back(unfilteredTrack.globalIndex()); + vec_TrkContributos.push_back(getTrackParCov(unfilteredTrack)); + nContrib++; + if (fDebug) { + LOG(info) << "---> a contributor! stuff saved"; + LOG(info) << "vec_contrib size: " << vec_TrkContributos.size() << ", nContrib: " << nContrib; + } + } + if (fDebug) { + LOG(info) << "===> nTrk: " << nTrk << ", nContrib: " << nContrib << ", nNonContrib: " << nNonContrib; + } + + if (vec_TrkContributos.size() != collision.numContrib()) { + LOG(info) << "!!! something wrong in the number of contributor tracks for PV fit !!! " << vec_TrkContributos.size() << " vs. " << collision.numContrib(); + return; + } + + std::vector vec_useTrk_PVrefit(vec_globID_contr.size(), true); + + /// Prepare the vertex refitting + // Get the magnetic field for the Propagator + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + // auto bc = collision.bc_as(); + if (mRunNumber != bc.runNumber()) { + o2::parameters::GRPMagField* grpo = ccdb->getForTimeStamp(ccdbPathGrp, bc.timestamp()); + if (grpo != nullptr) { + o2::base::Propagator::initFieldFromGRP(grpo); + o2::base::Propagator::Instance()->setMatLUT(lut); + LOG(info) << "Setting magnetic field to current " << grpo->getL3Current() << " A for run " << bc.runNumber() << " from its GRP CCDB object"; + } else { + LOGF(fatal, "GRP object is not available in CCDB for run=%d at timestamp=%llu", bc.runNumber(), bc.timestamp()); + } + mRunNumber = bc.runNumber(); + } + // build the VertexBase to initialize the vertexer + o2::dataformats::VertexBase Pvtx; + Pvtx.setX(collision.posX()); + Pvtx.setY(collision.posY()); + Pvtx.setZ(collision.posZ()); + Pvtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + // configure PVertexer + o2::vertexing::PVertexer vertexer; + if (removeDiamondConstraint) { + o2::conf::ConfigurableParam::updateFromString("pvertexer.useMeanVertexConstraint=false"); // we want to refit w/o MeanVertex constraint + } + vertexer.init(); + bool PVrefit_doable = vertexer.prepareVertexRefit(vec_TrkContributos, Pvtx); + if (!PVrefit_doable) { + LOG(info) << "Not enough tracks accepted for the refit"; + if (doPVrefit) { + histograms.fill(HIST("Reco/nContrib_PVrefitNotDoable"), collision.numContrib()); + } + } else { + histograms.fill(HIST("Reco/vertices"), 2); + } + + if (fDebug) { + LOG(info) << "prepareVertexRefit = " << PVrefit_doable << " Ncontrib= " << vec_TrkContributos.size() << " Ntracks= " << collision.numContrib() << " Vtx= " << Pvtx.asString(); + } + /////////////////////////////////// + /////////////////////////////////// + + /// loop over tracks + float pt = -999.f; + float p = -999.f; + bool isPvContributor = false; + float impParRPhi = -999.f; + float impParZ = -999.f; + float tpcNSigmaPion = -999.f; + float tpcNSigmaKaon = -999.f; + float tpcNSigmaProton = -999.f; + float tofNSigmaPion = -999.f; + float tofNSigmaKaon = -999.f; + float tofNSigmaProton = -999.f; + float trackIuPosX = -999.f; + float trackIuPosY = -999.f; + float trackIuPosZ = -999.f; + std::array posXYZ = {-999.f, -999.f, -999.f}; + int clusterSizeInLayer0 = -1; + int ntr = tracks.size(); + int cnt = 0; + for (const auto& track : tracks) { + + isPvContributor = track.isPVContributor(); + if (keepOnlyPvContrib && !isPvContributor) { + /// let's skip all tracks that were not PV contributors originally + /// this let us ignore tracks flagged as ambiguous + continue; + } + + /// Specific MC selections + if constexpr (IS_MC) { + if (keepOnlyPhysPrimary) { + /// we want only physical primary particles + if (!track.has_mcParticle()) { + continue; + } + auto particle = track.mcParticle(); + if (keepOnlyPhysPrimary && particle.isPhysicalPrimary()) { + continue; + } + histograms.fill(HIST("MC/ptMC"), particle.pt()); + } else { + if (track.has_mcParticle()) { + auto particle = track.mcParticle(); + histograms.fill(HIST("MC/ptMC"), particle.pt()); + } + } + } + + /// Using the Filter instead + /// if ((keepOnlyGlobalTracks) && (!track.isGlobalTrack())) { + /// /// not a global track (FB 4 with tight DCA cuts) + /// continue; + ///} + + /// apply custom ITS hitmap selections, if asked + if (useCustomITSHitMap && !selector_ITShitmap.IsSelected(track, TrackSelection::TrackCuts::kITSHits)) { + /// skip this track and go on, because it does not satisfy the ITS hit requirements + continue; + } + if (useCustomITSHitMap && customForceITSTPCmatching && (!track.hasITS() || !track.hasTPC())) { + // if (useCustomITSHitMap && customForceITSTPCmatching && track.hasITS()) { ///ATTEMPT: REMOVE TRACKS WITH ITS + /// skip this track because it is not global (no matching ITS-TPC) + continue; + } + int itsNhits = 0; + for (unsigned int i = 0; i < 7; i++) { + if (track.itsClusterMap() & (1 << i)) { + itsNhits += 1; + } + } + bool trkHasITS = false; + for (unsigned int i = 0; i < 7; i++) { + if (track.itsClusterMap() & (1 << i)) { + trkHasITS = true; + histograms.fill(HIST("Reco/itsHits"), i, itsNhits); + } + } + if (!trkHasITS) { + histograms.fill(HIST("Reco/itsHits"), -1, itsNhits); + } + + pt = track.pt(); + p = track.p(); + tpcNSigmaPion = track.tpcNSigmaPi(); + tpcNSigmaKaon = track.tpcNSigmaKa(); + tpcNSigmaProton = track.tpcNSigmaPr(); + tofNSigmaPion = track.tofNSigmaPi(); + tofNSigmaKaon = track.tofNSigmaKa(); + tofNSigmaProton = track.tofNSigmaPr(); + + histograms.fill(HIST("Reco/pt"), pt); + histograms.fill(HIST("Reco/hNSigmaTPCPion"), pt, tpcNSigmaPion); + histograms.fill(HIST("Reco/hNSigmaTPCKaon"), pt, tpcNSigmaKaon); + histograms.fill(HIST("Reco/hNSigmaTPCProton"), pt, tpcNSigmaProton); + histograms.fill(HIST("Reco/hNSigmaTOFPion"), pt, tofNSigmaPion); + histograms.fill(HIST("Reco/hNSigmaTOFKaon"), pt, tofNSigmaKaon); + histograms.fill(HIST("Reco/hNSigmaTOFProton"), pt, tofNSigmaProton); + + histograms.fill(HIST("Reco/vertices_perTrack"), 1); + if (PVrefit_doable) { + histograms.fill(HIST("Reco/vertices_perTrack"), 2); + } + /// PV refitting, if the tracks contributed to this at the beginning + o2::dataformats::VertexBase PVbase_recalculated; + bool recalc_imppar = false; + if (doPVrefit && PVrefit_doable) { + auto it_trk = std::find(vec_globID_contr.begin(), vec_globID_contr.end(), track.globalIndex()); /// track global index + // if( it_trk==vec_globID_contr.end() ) { + // /// not found: this track did not contribute to the initial PV fitting + // continue; + // } + if (it_trk != vec_globID_contr.end()) { + /// this track contributed to the PV fit: let's do the refit without it + const int entry = std::distance(vec_globID_contr.begin(), it_trk); + if (!keepAllTracksPVrefit) { + vec_useTrk_PVrefit[entry] = false; /// remove the track from the PV refitting + } + auto Pvtx_refitted = vertexer.refitVertex(vec_useTrk_PVrefit, Pvtx); // vertex refit + if (fDebug) { + LOG(info) << "refit " << cnt << "/" << ntr << " result = " << Pvtx_refitted.asString(); + } + + /// enable the dca recalculation for the current PV contributor, after removing it from the PV refit + recalc_imppar = true; + + if (Pvtx_refitted.getChi2() < 0 && fillHistoPVrefit) { + LOG(info) << "---> Refitted vertex has bad chi2 = " << Pvtx_refitted.getChi2(); + histograms.fill(HIST("Reco/X_PVrefitChi2minus1"), Pvtx_refitted.getX(), collision.posX()); + histograms.fill(HIST("Reco/Y_PVrefitChi2minus1"), Pvtx_refitted.getY(), collision.posY()); + histograms.fill(HIST("Reco/Z_PVrefitChi2minus1"), Pvtx_refitted.getZ(), collision.posZ()); + histograms.fill(HIST("Reco/nContrib_PVrefitChi2minus1"), collision.numContrib()); + recalc_imppar = false; + } else if (fillHistoPVrefit) { + histograms.fill(HIST("Reco/vertices_perTrack"), 3); + } + // histograms.fill(HIST("Reco/nContrib_vs_Chi2PVrefit"), /*Pvtx_refitted.getNContributors()*/collision.numContrib()-1, Pvtx_refitted.getChi2()); + histograms.fill(HIST("Reco/nContrib_vs_Chi2PVrefit"), vec_useTrk_PVrefit.size() - 1, Pvtx_refitted.getChi2()); + + vec_useTrk_PVrefit[entry] = true; /// restore the track for the next PV refitting + + if (recalc_imppar) { + // fill the histograms for refitted PV with good Chi2 + const double DeltaX = Pvtx.getX() - Pvtx_refitted.getX(); + const double DeltaY = Pvtx.getY() - Pvtx_refitted.getY(); + const double DeltaZ = Pvtx.getZ() - Pvtx_refitted.getZ(); + if (fillHistoPVrefit) { + histograms.fill(HIST("Reco/nContrib_vs_DeltaX_PVrefit"), collision.numContrib(), DeltaX); + histograms.fill(HIST("Reco/nContrib_vs_DeltaY_PVrefit"), collision.numContrib(), DeltaY); + histograms.fill(HIST("Reco/nContrib_vs_DeltaZ_PVrefit"), collision.numContrib(), DeltaZ); + } + // fill the newly calculated PV + PVbase_recalculated.setX(Pvtx_refitted.getX()); + PVbase_recalculated.setY(Pvtx_refitted.getY()); + PVbase_recalculated.setZ(Pvtx_refitted.getZ()); + PVbase_recalculated.setCov(Pvtx_refitted.getSigmaX2(), Pvtx_refitted.getSigmaXY(), Pvtx_refitted.getSigmaY2(), Pvtx_refitted.getSigmaXZ(), Pvtx_refitted.getSigmaYZ(), Pvtx_refitted.getSigmaZ2()); + } + + cnt++; + } + } /// end 'if (doPVrefit && PVrefit_doable)' + + /// impact parameter to the PV + // value calculated wrt global PV (not recalculated) ---> coming from trackextension workflow + impParRPhi = toMicrometers * track.dcaXY(); // dca.getY(); + impParZ = toMicrometers * track.dcaZ(); // dca.getY(); + // updated value after PV recalculation + if (recalc_imppar) { + if (fEnablePulls) { + auto trackParCov = getTrackParCov(track); + o2::dataformats::DCA dcaInfoCov{999, 999, 999, 999, 999}; + if (o2::base::Propagator::Instance()->propagateToDCABxByBz(PVbase_recalculated, trackParCov, 2.f, matCorr, &dcaInfoCov)) { + impParRPhi = dcaInfoCov.getY() * toMicrometers; + impParZ = dcaInfoCov.getZ() * toMicrometers; + } + } else { + auto trackPar = getTrackPar(track); + std::array dcaInfo{-999., -999.}; + if (o2::base::Propagator::Instance()->propagateToDCABxByBz({PVbase_recalculated.getX(), PVbase_recalculated.getY(), PVbase_recalculated.getZ()}, trackPar, 2.f, matCorr, &dcaInfo)) { + impParRPhi = dcaInfo[0] * toMicrometers; + impParZ = dcaInfo[1] * toMicrometers; + } + } + } + + /// retrive track position at inner most update + if (addTrackIUinfo) { + for (const auto& trackIU : tracksIU) { + if (trackIU.globalIndex() == track.globalIndex()) { + o2::track::TrackParCov trackIuParCov = getTrackParCov(trackIU); + trackIuParCov.getXYZGlo(posXYZ); + trackIuPosX = posXYZ[0]; + trackIuPosY = posXYZ[1]; + trackIuPosZ = posXYZ[2]; + clusterSizeInLayer0 = trackIU.itsClsSizeInLayer(0); + } + } + } + + /// all tracks + if ((pt * 1000 - static_cast(pt * 1000)) > downsamplingFraction) { + // downsampling - do not consider the current track + continue; + } + + if (addTrackIUinfo) { + histograms.fill(HIST("Reco/h4ClusterSizeIU"), p, impParRPhi, trackIuPosX, trackIuPosY, trackIuPosZ, clusterSizeInLayer0); + histograms.fill(HIST("Reco/h4ImpParZIU"), p, impParZ, trackIuPosX, trackIuPosY, trackIuPosZ); + } + + if (isPIDPionApplied && nSigmaTPCPionMin < tpcNSigmaPion && tpcNSigmaPion < nSigmaTPCPionMax && nSigmaTOFPionMin < tofNSigmaPion && tofNSigmaPion < nSigmaTOFPionMax) { + /// PID selected pions + if (addTrackIUinfo) { + histograms.fill(HIST("Reco/h4ClusterSizeIU_Pion"), p, impParRPhi, trackIuPosX, trackIuPosY, trackIuPosZ, clusterSizeInLayer0); + } + histograms.fill(HIST("Reco/hNSigmaTPCPion_afterPID"), pt, tpcNSigmaPion); + histograms.fill(HIST("Reco/hNSigmaTOFPion_afterPID"), pt, tofNSigmaPion); + } + if (isPIDKaonApplied && nSigmaTPCKaonMin < tpcNSigmaKaon && tpcNSigmaKaon < nSigmaTPCKaonMax && nSigmaTOFKaonMin < tofNSigmaKaon && tofNSigmaKaon < nSigmaTOFKaonMax) { + /// PID selected kaons + if (addTrackIUinfo) { + histograms.fill(HIST("Reco/h4ClusterSizeIU_Kaon"), p, impParRPhi, trackIuPosX, trackIuPosY, trackIuPosZ, clusterSizeInLayer0); + } + histograms.fill(HIST("Reco/hNSigmaTPCKaon_afterPID"), pt, tpcNSigmaKaon); + histograms.fill(HIST("Reco/hNSigmaTOFKaon_afterPID"), pt, tofNSigmaKaon); + } + if (isPIDProtonApplied && nSigmaTPCProtonMin < tpcNSigmaProton && tpcNSigmaProton < nSigmaTPCProtonMax && nSigmaTOFProtonMin < tofNSigmaProton && tofNSigmaProton < nSigmaTOFProtonMax) { + /// PID selected Protons + if (addTrackIUinfo) { + histograms.fill(HIST("Reco/h4ClusterSizeIU_Proton"), p, impParRPhi, trackIuPosX, trackIuPosY, trackIuPosZ, clusterSizeInLayer0); + } + histograms.fill(HIST("Reco/hNSigmaTPCProton_afterPID"), pt, tpcNSigmaProton); + histograms.fill(HIST("Reco/hNSigmaTOFProton_afterPID"), pt, tofNSigmaProton); + } + } + } /// end processReco +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec w{ + adaptAnalysisTask(cfgc)}; + return w; +} diff --git a/EventFiltering/PWGCF/CFFilterAll.cxx b/EventFiltering/PWGCF/CFFilterAll.cxx index 4df821ec669..efc7625b215 100644 --- a/EventFiltering/PWGCF/CFFilterAll.cxx +++ b/EventFiltering/PWGCF/CFFilterAll.cxx @@ -61,8 +61,8 @@ enum CFTriggers { kPPRho, kPD, kLD, - kRhoD, kPhiD, + kRhoD, kNTriggers }; @@ -115,13 +115,13 @@ const uint32_t nLimitNames = 2; const float limitTable[nLimitNames][nFilterNames]{ {0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.5f, 0.5f, 0.5f, 0.5f}, - {1.2f, 1.2f, 1.2f, 1.2f, 1.2f, 1.2f, 1.0f, 1.0f, 1.0f, 1.0f}}; + {1.4f, 1.4f, 1.4f, 1.4f, 1.4f, 1.4f, 1.0f, 1.0f, 1.0f, 1.0f}}; using FullCollisions = soa::Join; using FullCollision = FullCollisions::iterator; using FullTracks = soa::Join zvtx{"zvtx", 12.f, "Max. z-Vertex (cm)"}; + Configurable zvtx{"zvtx", 10.f, "Max. z-Vertex (cm)"}; Configurable eventSel{"eventSel", true, "Use sel8"}; } EventSelection; @@ -287,9 +287,9 @@ struct CFFilterAll { ConfigurableAxis transRad{"transRad", {100, 0, 100}, "Binning Transverse Radius"}; ConfigurableAxis decayVtx{"decayVtx", {100, 0, 100}, "Binning Decay Vertex"}; - ConfigurableAxis invMassPhi{"invMassPhi", {700, 0.8, 1.5}, "Binning Invariant Mass Phi"}; + ConfigurableAxis invMassPhi{"invMassPhi", {600, 0.7, 1.3}, "Binning Invariant Mass Phi"}; - ConfigurableAxis invMassRho{"invMassRho", {600, 0.6, 1.2}, "Binning Invariant Mass Rho"}; + ConfigurableAxis invMassRho{"invMassRho", {600, 0.47, 1.07}, "Binning Invariant Mass Rho"}; ConfigurableAxis q3{"q3", {300, 0, 3}, "Binning Decay Q3"}; ConfigurableAxis kstar{"kstar", {300, 0, 3}, "Binning Decay Kstar"}; @@ -298,8 +298,8 @@ struct CFFilterAll { // define histogram registry // because we have so many histograms, we need to have 2 registries - HistogramRegistry registryParticleQA{"ParticleQA", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry registryTriggerQA{"TriggerQA", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry registryParticleQA{"ParticleQA", {}, OutputObjHandlingPolicy::AnalysisObject}; // for particle histograms + HistogramRegistry registryTriggerQA{"TriggerQA", {}, OutputObjHandlingPolicy::AnalysisObject}; // for trigger histograms // helper object flor building lambdas o2::pwglf::strangenessBuilderHelper mStraHelper; @@ -654,7 +654,7 @@ struct CFFilterAll { registryParticleQA.add("TrackQA/After/AntiDeuteron/fNsigmaIts", "NSigmaITS;p (GeV/c);n#sigma_{ITS}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); registryParticleQA.add("TrackQA/After/AntiDeuteron/fNsigmaTpc", "NSigmaTPC;p (GeV/c);n#sigma_{TPC}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); registryParticleQA.add("TrackQA/After/AntiDeuteron/fNsigmaTof", "NSigmaTOF;p (GeV/c);n#sigma_{TOF}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); - registryParticleQA.add("TrackQA/After/AntiDeuteron/fNsigmaTpcTof", "NSigmaTPCTOF;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigma}}); + registryParticleQA.add("TrackQA/After/AntiDeuteron/fNsigmaTpcTof", "NSigmaTPCTOF;p (GeV/c);n#sigma_{comb}", {HistType::kTH2F, {Binning.momentum, Binning.nsigmaComb}}); registryParticleQA.add("TrackQA/After/AntiDeuteron/fItsSignal", "ITS Signal;p (GeV/c); (cm)", {HistType::kTH2F, {Binning.momentum, Binning.itsSignal}}); registryParticleQA.add("TrackQA/After/AntiDeuteron/fTpcSignal", "TPC Signal;p (GeV/c);TPC Signal", {HistType::kTH2F, {Binning.momentum, Binning.tpcSignal}}); @@ -779,248 +779,248 @@ struct CFFilterAll { registryTriggerQA.add("PPP/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("PPP/all/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("PPP/all/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("PPP/all/fProtonPtVsQ3", "Proton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PPP/all/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPP/all/fProtonQ3VsPt", "Q_{3} vs Proton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PPP/all/fAntiProtonQ3VsPt", "Q_{3} vs AntiProton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); registryTriggerQA.add("PPP/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PPP/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("PPP/loose/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("PPP/loose/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("PPP/loose/fProtonPtVsQ3", "Proton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PPP/loose/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPP/loose/fProtonQ3VsPt", "Q_{3} vs Proton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PPP/loose/fAntiProtonQ3VsPt", "Q_{3} vs AntiProton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); registryTriggerQA.add("PPP/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PPP/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("PPP/tight/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("PPP/tight/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("PPP/tight/fProtonPtVsQ3", "Proton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PPP/tight/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPP/tight/fProtonQ3VsPt", "Q_{3} vs Proton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PPP/tight/fAntiProtonQ3VsPt", "Q_{3} vs AntiProton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); // for ppl registryTriggerQA.add("PPL/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PPL/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("PPL/all/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("PPL/all/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("PPL/all/fProtonPtVsQ3", "Proton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PPL/all/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PPL/all/fLambdaPtVsQ3", "Lambda p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PPL/all/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPL/all/fProtonQ3VsPt", "Q_{3} vs Proton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PPL/all/fAntiProtonQ3VsPt", "Q_{3} vs AntiProton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PPL/all/fLambdaQ3VsPt", "Q_{3} vs Lambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PPL/all/fAntiLambdaQ3VsPt", "Q_{3} vs AntiLambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); registryTriggerQA.add("PPL/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PPL/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("PPL/loose/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("PPL/loose/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("PPL/loose/fProtonPtVsQ3", "Proton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PPL/loose/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PPL/loose/fLambdaPtVsQ3", "Lambda p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PPL/loose/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPL/loose/fProtonQ3VsPt", "Q_{3} vs Proton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PPL/loose/fAntiProtonQ3VsPt", "Q_{3} vs AntiProton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PPL/loose/fLambdaQ3VsPt", "Q_{3} vs Lambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PPL/loose/fAntiLambdaQ3VsPt", "Q_{3} vs AntiLambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); registryTriggerQA.add("PPL/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PPL/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("PPL/tight/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("PPL/tight/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("PPL/tight/fProtonPtVsQ3", "Proton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PPL/tight/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PPL/tight/fLambdaPtVsQ3", "Lambda p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PPL/tight/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q_{3};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PPL/tight/fProtonQ3VsPt", "Q_{3} vs Proton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PPL/tight/fAntiProtonQ3VsPt", "Q_{3} vs AntiProton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PPL/tight/fLambdaQ3VsPt", "Q_{3} vs Lambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PPL/tight/fAntiLambdaQ3VsPt", "Q_{3} vs AntiLambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); // for pll registryTriggerQA.add("PLL/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PLL/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("PLL/all/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("PLL/all/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("PLL/all/fProtonPtVsQ3", "Proton p_{T}Q3 vs pT", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PLL/all/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PLL/all/fLambdaPtVsQ3", "Lambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PLL/all/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PLL/all/fProtonQ3VsPt", "Q_{3} vs Proton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PLL/all/fAntiProtonQ3VsPt", "Q3 vs AntiProton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PLL/all/fLambdaQ3VsPt", "Q3 vs Lambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PLL/all/fAntiLambdaQ3VsPt", "Q3 vs AntiLambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); registryTriggerQA.add("PLL/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PLL/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("PLL/loose/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("PLL/loose/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("PLL/loose/fProtonPtVsQ3", "Proton p_{T}Q3 vs pT", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PLL/loose/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PLL/loose/fLambdaPtVsQ3", "Lambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PLL/loose/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PLL/loose/fProtonQ3VsPt", "Q3 vs pT vs Proton p;Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PLL/loose/fAntiProtonQ3VsPt", "Q3 vs AntiProton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PLL/loose/fLambdaQ3VsPt", "Q3 vs Lambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PLL/loose/fAntiLambdaQ3VsPt", "Q3 vs AntiLambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); registryTriggerQA.add("PLL/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PLL/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("PLL/tight/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("PLL/tight/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("PLL/tight/fProtonPtVsQ3", "Proton p_{T}Q3 vs pT", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PLL/tight/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PLL/tight/fLambdaPtVsQ3", "Lambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("PLL/tight/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("PLL/tight/fProtonQ3VsPt", "Q3 vs pT vs Proton p;Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PLL/tight/fAntiProtonQ3VsPt", "Q3 vs AntiProton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PLL/tight/fLambdaQ3VsPt", "Q3 vs Lambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("PLL/tight/fAntiLambdaQ3VsPt", "Q3 vs AntiLambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); // for lll registryTriggerQA.add("LLL/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("LLL/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("LLL/all/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("LLL/all/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("LLL/all/fLambdaPtVsQ3", "Lambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("LLL/all/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("LLL/all/fLambdaQ3VsPt", "Q3 vs Lambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("LLL/all/fAntiLambdaQ3VsPt", "Q3 vs AntiLambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); registryTriggerQA.add("LLL/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("LLL/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("LLL/loose/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("LLL/loose/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("LLL/loose/fLambdaPtVsQ3", "Lambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("LLL/loose/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("LLL/loose/fLambdaQ3VsPt", "Q3 vs Lambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("LLL/loose/fAntiLambdaQ3VsPt", "Q3 vs AntiLambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); registryTriggerQA.add("LLL/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("LLL/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("LLL/tight/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("LLL/tight/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("LLL/tight/fLambdaPtVsQ3", "Lambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); - registryTriggerQA.add("LLL/tight/fAntiLambdaPtVsQ3", "AntiLambda p_{T} vs Q3", {HistType::kTH2F, {Binning.momentum, Binning.q3}}); + registryTriggerQA.add("LLL/tight/fLambdaQ3VsPt", "Q3 vs Lambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); + registryTriggerQA.add("LLL/tight/fAntiLambdaQ3VsPt", "Q3 vs AntiLambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.q3, Binning.momentum}}); // for ppPhi registryTriggerQA.add("PPPhi/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PPPhi/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("PPPhi/all/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("PPPhi/all/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("PPPhi/all/fProtonPtVsQ3", "Proton p_{T} vs Q_{3}", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPPhi/all/fAntiProtonPtVsQ3", "AntiLambda p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPPhi/all/fPhiPtVsQ3", "#phi p_{T} vs Q_{3};p_{T} (GeV/c); Q_{3} (GeV/c)", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPPhi/all/fPhiInvMassVsQ3", "#phi mass vs Q_{3};M_{K^{+}K^{-}} (GeV/c^{2});Q_{3} (GeV/c)", HistType::kTH2F, {Binning.invMassPhi, Binning.q3}); + registryTriggerQA.add("PPPhi/all/fProtonQ3VsPt", "Q_{3} vs Proton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPPhi/all/fAntiProtonQ3VsPt", "Q3 vs AntiLambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPPhi/all/fPhiQ3VsPt", "Q_{3} vs #phi p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPPhi/all/fPhiQ3VsInvMass", "Q_{3} vs #phi mass;Q_{3} (GeV/c);M_{K^{+}K^{-}} (GeV/c^{2})", HistType::kTH2F, {Binning.q3, Binning.invMassPhi}); registryTriggerQA.add("PPPhi/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PPPhi/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("PPPhi/loose/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("PPPhi/loose/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("PPPhi/loose/fProtonPtVsQ3", "Proton p_{T} vs Q_{3}", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPPhi/loose/fAntiProtonPtVsQ3", "AntiLambda p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPPhi/loose/fPhiPtVsQ3", "#phi p_{T} vs Q_{3};p_{T} (GeV/c); Q_{3} (GeV/c)", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPPhi/loose/fPhiInvMassVsQ3", "#phi mass vs Q_{3};M_{K^{+}K^{-}} (GeV/c^{2});Q_{3} (GeV/c)", HistType::kTH2F, {Binning.invMassPhi, Binning.q3}); + registryTriggerQA.add("PPPhi/loose/fProtonQ3VsPt", "Q_{3} vs Proton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPPhi/loose/fAntiProtonQ3VsPt", "Q3 vs AntiLambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPPhi/loose/fPhiQ3VsPt", "Q_{3} vs #phi p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPPhi/loose/fPhiQ3VsInvMass", "Q_{3} vs #phi mass;Q_{3} (GeV/c);M_{K^{+}K^{-}} (GeV/c^{2})", HistType::kTH2F, {Binning.q3, Binning.invMassPhi}); registryTriggerQA.add("PPPhi/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PPPhi/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("PPPhi/tight/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("PPPhi/tight/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);Entries", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("PPPhi/tight/fProtonPtVsQ3", "Proton p_{T} vs Q_{3}", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPPhi/tight/fAntiProtonPtVsQ3", "AntiLambda p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPPhi/tight/fPhiPtVsQ3", "#phi p_{T} vs Q_{3};p_{T} (GeV/c); Q_{3} (GeV/c)", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPPhi/tight/fPhiInvMassVsQ3", "#phi mass vs Q_{3};M_{K^{+}K^{-}} (GeV/c^{2});Q_{3} (GeV/c)", HistType::kTH2F, {Binning.invMassPhi, Binning.q3}); + registryTriggerQA.add("PPPhi/tight/fProtonQ3VsPt", "Q_{3} vs Proton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPPhi/tight/fAntiProtonQ3VsPt", "Q3 vs AntiLambda p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPPhi/tight/fPhiQ3VsPt", "Q_{3} vs #phi p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPPhi/tight/fPhiQ3VsInvMass", "Q_{3} vs #phi mass;Q_{3} (GeV/c);M_{K^{+}K^{-}} (GeV/c^{2})", HistType::kTH2F, {Binning.q3, Binning.invMassPhi}); // for ppRho registryTriggerQA.add("PPRho/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PPRho/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("PPRho/all/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("PPRho/all/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("PPRho/all/fProtonPtVsQ3", "Proton p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPRho/all/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPRho/all/fRhoPtVsQ3", "#rho p_{T} vs Q3;Q_{3} (GeV/c);SE", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPRho/all/fRhoInvMassVsQ3", "#rho mass vs Q_{3};M_{#pi^{+}#pi^{-}} (GeV/c^{2});Q_{3} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.q3}); + registryTriggerQA.add("PPRho/all/fProtonQ3VsPt", "Q3 vs Proton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPRho/all/fAntiProtonQ3VsPt", "Q3 vs AntiProton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPRho/all/fRhoQ3VsPt", "Q3 vs #rho p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPRho/all/fRhoQ3VsInvMass", "Q_{3} vs #rho mass;Q_{3} (GeV/c);M_{#pi^{+}#pi^{-}} (GeV/c^{2})", HistType::kTH2F, {Binning.q3, Binning.invMassRho}); registryTriggerQA.add("PPRho/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PPRho/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("PPRho/loose/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("PPRho/loose/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("PPRho/loose/fProtonPtVsQ3", "Proton p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPRho/loose/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPRho/loose/fRhoPtVsQ3", "#rho p_{T} vs Q3;Q_{3} (GeV/c);SE", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPRho/loose/fRhoInvMassVsQ3", "#rho mass vs Q_{3};M_{#pi^{+}#pi^{-}} (GeV/c^{2});Q_{3} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.q3}); + registryTriggerQA.add("PPRho/loose/fProtonQ3VsPt", "Q3 vs Proton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPRho/loose/fAntiProtonQ3VsPt", "Q3 vs AntiProton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPRho/loose/fRhoQ3VsPt", "Q3 vs #rho p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPRho/loose/fRhoQ3VsInvMass", "Q_{3} vs #rho mass;Q_{3} (GeV/c);M_{#pi^{+}#pi^{-}} (GeV/c^{2})", HistType::kTH2F, {Binning.q3, Binning.invMassRho}); registryTriggerQA.add("PPRho/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PPRho/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); registryTriggerQA.add("PPRho/tight/fSE_particle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); registryTriggerQA.add("PPRho/tight/fSE_antiparticle", "Same Event distribution;Q_{3} (GeV/c);SE", HistType::kTH1F, {Binning.q3}); - registryTriggerQA.add("PPRho/tight/fProtonPtVsQ3", "Proton p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPRho/tight/fAntiProtonPtVsQ3", "AntiProton p_{T} vs Q3", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPRho/tight/fRhoPtVsQ3", "#rho p_{T} vs Q3;Q_{3} (GeV/c);SE", HistType::kTH2F, {Binning.momentum, Binning.q3}); - registryTriggerQA.add("PPRho/tight/fRhoInvMassVsQ3", "#rho mass vs Q_{3};M_{#pi^{+}#pi^{-}} (GeV/c^{2});Q_{3} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.q3}); + registryTriggerQA.add("PPRho/tight/fProtonQ3VsPt", "Q3 vs Proton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPRho/tight/fAntiProtonQ3VsPt", "Q3 vs AntiProton p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPRho/tight/fRhoQ3VsPt", "Q3 vs #rho p_{T};Q_{3} (GeV/c);p_{T} (GeV/c)", HistType::kTH2F, {Binning.q3, Binning.momentum}); + registryTriggerQA.add("PPRho/tight/fRhoQ3VsInvMass", "Q_{3} vs #rho mass;Q_{3} (GeV/c);M_{#pi^{+}#pi^{-}} (GeV/c^{2})", HistType::kTH2F, {Binning.q3, Binning.invMassRho}); // for pd registryTriggerQA.add("PD/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PD/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); - registryTriggerQA.add("PD/all/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("PD/all/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("PD/all/fProtonPtVskstar", "Proton p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PD/all/fAntiProtonPtVskstar", "AntiProton p_{T} vs k^{*};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PD/all/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PD/all/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PD/all/fSE_particle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PD/all/fSE_antiparticle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PD/all/fProtonKstarVsPt", "k* vs Proton p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PD/all/fAntiProtonKstarVsPt", "k* vs AntiProton p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PD/all/fDeuteronKstarVsPt", "k* vs Deuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PD/all/fAntiDeuteronKstarVsPt", "k* vs AntiDeuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); registryTriggerQA.add("PD/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PD/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); - registryTriggerQA.add("PD/loose/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("PD/loose/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("PD/loose/fProtonPtVskstar", "Proton p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PD/loose/fAntiProtonPtVskstar", "AntiProton p_{T} vs k^{*};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PD/loose/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PD/loose/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PD/loose/fSE_particle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PD/loose/fSE_antiparticle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PD/loose/fProtonKstarVsPt", "k* vs Proton p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PD/loose/fAntiProtonKstarVsPt", "k* vs AntiProton p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PD/loose/fDeuteronKstarVsPt", "k* Deuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PD/loose/fAntiDeuteronKstarVsPt", "k* vs AntiDeuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); registryTriggerQA.add("PD/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PD/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); - registryTriggerQA.add("PD/tight/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("PD/tight/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("PD/tight/fProtonPtVskstar", "Proton p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PD/tight/fAntiProtonPtVskstar", "AntiProton p_{T} vs k^{*};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PD/tight/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PD/tight/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("PD/tight/fSE_particle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PD/tight/fSE_antiparticle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PD/tight/fProtonKstarVsPt", "k* vs Proton p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PD/tight/fAntiProtonKstarVsPt", "k* vs AntiProton p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PD/tight/fDeuteronKstarVsPt", "k* vs Deuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PD/tight/fAntiDeuteronKstarVsPt", "k* vs AntiDeuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); // for ld registryTriggerQA.add("LD/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("LD/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); - registryTriggerQA.add("LD/all/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("LD/all/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("LD/all/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("LD/all/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("LD/all/fLambdaPtVskstar", "Lambda p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("LD/all/fAntiLambdaPtVskstar", "AntiLambda p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("LD/all/fSE_particle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("LD/all/fSE_antiparticle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("LD/all/fDeuteronKstarVsPt", "k* vs Deuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("LD/all/fAntiDeuteronKstarVsPt", "k* vs AntiDeuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("LD/all/fLambdaKstarVsPt", "k* vs Lambda p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("LD/all/fAntiLambdaKstarVsPt", "k* vs AntiLambda p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); registryTriggerQA.add("LD/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("LD/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); - registryTriggerQA.add("LD/loose/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("LD/loose/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("LD/loose/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("LD/loose/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("LD/loose/fLambdaPtVskstar", "Lambda p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("LD/loose/fAntiLambdaPtVskstar", "AntiLambda p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("LD/loose/fSE_particle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("LD/loose/fSE_antiparticle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("LD/loose/fDeuteronKstarVsPt", "k* vs Deuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("LD/loose/fAntiDeuteronKstarVsPt", "k* vs AntiDeuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("LD/loose/fLambdaKstarVsPt", "k* vs Lambda p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("LD/loose/fAntiLambdaKstarVsPt", "k* vs AntiLambda p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); registryTriggerQA.add("LD/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("LD/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); - registryTriggerQA.add("LD/tight/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("LD/tight/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("LD/tight/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("LD/tight/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};Q_{3} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("LD/tight/fLambdaPtVskstar", "Lambda p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("LD/tight/fAntiLambdaPtVskstar", "AntiLambda p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); + registryTriggerQA.add("LD/tight/fSE_particle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("LD/tight/fSE_antiparticle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("LD/tight/fDeuteronKstarVsPt", "k* vs Deuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("LD/tight/fAntiDeuteronKstarVsPt", "k* vs AntiDeuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("LD/tight/fLambdaKstarVsPt", "k* vs Lambda p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("LD/tight/fAntiLambdaKstarVsPt", "k* vs AntiLambda p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); // for phid registryTriggerQA.add("PhiD/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PhiD/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); - registryTriggerQA.add("PhiD/all/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("PhiD/all/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("PhiD/all/fPhiPtVskstar", "Phi p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PhiD/all/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PhiD/all/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PhiD/all/fPhiInvMassVskstar", "#phi mass vs k^{*};M_{K^{+}K^{-}} (GeV/c^{2});k^{*} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.kstar}); + registryTriggerQA.add("PhiD/all/fSE_particle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PhiD/all/fSE_antiparticle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PhiD/all/fPhiKstarVsPt", "k* vs Phi p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PhiD/all/fDeuteronKstarVsPt", "k* vs Deuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PhiD/all/fAntiDeuteronKstarVsPt", "k* vs AntiDeuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PhiD/all/fPhiKstarVsInvMass", "k* vs #phi mass;k* (GeV/c);M_{K^{+}K^{-}} (GeV/c^{2});", HistType::kTH2F, {Binning.kstar, Binning.invMassPhi}); registryTriggerQA.add("PhiD/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PhiD/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); - registryTriggerQA.add("PhiD/loose/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("PhiD/loose/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("PhiD/loose/fPhiPtVskstar", "Phi p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PhiD/loose/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PhiD/loose/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PhiD/loose/fPhiInvMassVskstar", "#phi mass vs k^{*};M_{K^{+}K^{-}} (GeV/c^{2});k^{*} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.kstar}); + registryTriggerQA.add("PhiD/loose/fSE_particle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PhiD/loose/fSE_antiparticle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PhiD/loose/fPhiKstarVsPt", "k* vs Phi p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PhiD/loose/fDeuteronKstarVsPt", "k* vs Deuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PhiD/loose/fAntiDeuteronKstarVsPt", "k* vs AntiDeuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PhiD/loose/fPhiKstarVsInvMass", "k* vs #phi mass;k* (GeV/c);M_{K^{+}K^{-}} (GeV/c^{2})", HistType::kTH2F, {Binning.kstar, Binning.invMassPhi}); registryTriggerQA.add("PhiD/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("PhiD/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); - registryTriggerQA.add("PhiD/tight/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("PhiD/tight/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("PhiD/tight/fPhiPtVskstar", "Phi p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PhiD/tight/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PhiD/tight/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("PhiD/tight/fPhiInvMassVskstar", "#phi mass vs k^{*};M_{K^{+}K^{-}} (GeV/c^{2});k^{*} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.kstar}); + registryTriggerQA.add("PhiD/tight/fSE_particle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PhiD/tight/fSE_antiparticle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("PhiD/tight/fPhiKstarVsPt", "k* vs Phi p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PhiD/tight/fDeuteronKstarVsPt", "k* vs Deuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PhiD/tight/fAntiDeuteronKstarVsPt", "k* vs AntiDeuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("PhiD/tight/fPhiKstarVsInvMass", "k* vs #phi mass;k* (GeV/c);M_{K^{+}K^{-}} (GeV/c^{2})", HistType::kTH2F, {Binning.kstar, Binning.invMassPhi}); // for rhod registryTriggerQA.add("RhoD/all/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("RhoD/all/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); - registryTriggerQA.add("RhoD/all/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("RhoD/all/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("RhoD/all/fRhoPtVskstar", "Rho p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("RhoD/all/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("RhoD/all/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("RhoD/all/fRhoInvMassVskstar", "#rho mass vs k^{*};M_{#pi^{+}#pi^{-}} (GeV/c^{2});k^{*} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.kstar}); + registryTriggerQA.add("RhoD/all/fSE_particle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("RhoD/all/fSE_antiparticle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("RhoD/all/fRhoKstarVsPt", "k* vs Rho p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("RhoD/all/fDeuteronKstarVsPt", "k* vs Deuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("RhoD/all/fAntiDeuteronKstarVsPt", "k* vs AntiDeuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("RhoD/all/fRhoKstarVsInvMass", "k* vs #rho mass;k* (GeV/c);M_{#pi^{+}#pi^{-}} (GeV/c^{2})", HistType::kTH2F, {Binning.kstar, Binning.invMassRho}); registryTriggerQA.add("RhoD/loose/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("RhoD/loose/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); - registryTriggerQA.add("RhoD/loose/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("RhoD/loose/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("RhoD/loose/fRhoPtVskstar", "Rho p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("RhoD/loose/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("RhoD/loose/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("RhoD/loose/fRhoInvMassVskstar", "#rho mass vs k^{*};M_{#pi^{+}#pi^{-}} (GeV/c^{2});k^{*} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.kstar}); + registryTriggerQA.add("RhoD/loose/fSE_particle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("RhoD/loose/fSE_antiparticle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("RhoD/loose/fRhoKstarVsPt", "k* vs Rho p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("RhoD/loose/fDeuteronKstarVsPt", "k* vs Deuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("RhoD/loose/fAntiDeuteronKstarVsPt", "k* vs AntiDeuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("RhoD/loose/fRhoKstarVsInvMass", "k* vs #rho mass;k* (GeV/c);M_{#pi^{+}#pi^{-}} (GeV/c^{2})", HistType::kTH2F, {Binning.kstar, Binning.invMassRho}); registryTriggerQA.add("RhoD/tight/fMultiplicity", "Multiplicity;Mult;Entries", HistType::kTH1F, {Binning.multiplicity}); registryTriggerQA.add("RhoD/tight/fZvtx", "Zvtx;Z_{vtx};Entries", HistType::kTH1F, {Binning.zvtx}); - registryTriggerQA.add("RhoD/tight/fSE_particle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("RhoD/tight/fSE_antiparticle", "Same Event distribution;k^{*} (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); - registryTriggerQA.add("RhoD/tight/fRhoPtVskstar", "Rho p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("RhoD/tight/fDeuteronPtVskstar", "Deuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("RhoD/tight/fAntiDeuteronPtVskstar", "AntiDeuteron p_{T} vs k^{*};k^{*} (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.momentum, Binning.kstar}}); - registryTriggerQA.add("RhoD/tight/fRhoInvMassVskstar", "#rho mass vs k^{*};M_{#pi^{+}#pi^{-}} (GeV/c^{2});k^{*} (GeV/c)", HistType::kTH2F, {Binning.invMassRho, Binning.kstar}); + registryTriggerQA.add("RhoD/tight/fSE_particle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("RhoD/tight/fSE_antiparticle", "Same Event distribution;k* (GeV/c);Entries", HistType::kTH1F, {Binning.kstar}); + registryTriggerQA.add("RhoD/tight/fRhoKstarVsPt", "k* vs Rho p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("RhoD/tight/fDeuteronKstarVsPt", "k* vs Deuteron p_{T};k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("RhoD/tight/fAntiDeuteronKstarVsPt", "AntiDeuteron p_{T} vs k*;k* (GeV/c);p_{T} (GeV/c)", {HistType::kTH2F, {Binning.kstar, Binning.momentum}}); + registryTriggerQA.add("RhoD/tight/fRhoKstarVsInvMass", "k* vs #rho mass;k* (GeV/c);M_{#pi^{+}#pi^{-}} (GeV/c^{2})", HistType::kTH2F, {Binning.kstar, Binning.invMassRho}); } void initCCDB(int run) @@ -1122,19 +1122,19 @@ struct CFFilterAll { if (trackName == std::string("Pion")) { nsigmaITS = track.itsNSigmaPi(); nsigmaTPC = track.tpcNSigmaPi(); - nsigmaTPCTOF = RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPi(), track.tofNSigmaPi()); + nsigmaTPCTOF = std::hypot(track.tpcNSigmaPi(), track.tofNSigmaPi()); } else if (trackName == std::string("Kaon")) { nsigmaITS = track.itsNSigmaKa(); nsigmaTPC = track.tpcNSigmaKa(); - nsigmaTPCTOF = RecoDecay::sqrtSumOfSquares(track.tpcNSigmaKa(), track.tofNSigmaKa()); + nsigmaTPCTOF = std::hypot(track.tpcNSigmaKa(), track.tofNSigmaKa()); } else if (trackName == std::string("Proton")) { nsigmaITS = track.itsNSigmaPr(); nsigmaTPC = track.tpcNSigmaPr(); - nsigmaTPCTOF = RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPr(), track.tofNSigmaPr()); + nsigmaTPCTOF = std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr()); } else if (trackName == std::string("Deuteron")) { nsigmaITS = track.itsNSigmaDe(); nsigmaTPC = track.tpcNSigmaDe(); - nsigmaTPCTOF = RecoDecay::sqrtSumOfSquares(track.tpcNSigmaDe(), track.tofNSigmaDe()); + nsigmaTPCTOF = std::hypot(track.tpcNSigmaDe(), track.tofNSigmaDe()); } else { LOG(fatal) << "Unsupported track type"; } @@ -1343,22 +1343,22 @@ struct CFFilterAll { registryParticleQA.fill(HIST("TrackQA/Before/Pion/fNsigmaITS"), track.p(), track.itsNSigmaPi()); registryParticleQA.fill(HIST("TrackQA/Before/Pion/fNsigmaTPC"), track.p(), track.tpcNSigmaPi()); registryParticleQA.fill(HIST("TrackQA/Before/Pion/fNsigmaTOF"), track.p(), track.tofNSigmaPi()); - registryParticleQA.fill(HIST("TrackQA/Before/Pion/fNsigmaTPCTOF"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPi(), track.tofNSigmaPi())); + registryParticleQA.fill(HIST("TrackQA/Before/Pion/fNsigmaTPCTOF"), track.p(), std::hypot(track.tpcNSigmaPi(), track.tofNSigmaPi())); registryParticleQA.fill(HIST("TrackQA/Before/Kaon/fNsigmaITS"), track.p(), track.itsNSigmaKa()); registryParticleQA.fill(HIST("TrackQA/Before/Kaon/fNsigmaTPC"), track.p(), track.tpcNSigmaKa()); registryParticleQA.fill(HIST("TrackQA/Before/Kaon/fNsigmaTOF"), track.p(), track.tofNSigmaKa()); - registryParticleQA.fill(HIST("TrackQA/Before/Kaon/fNsigmaTPCTOF"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaKa(), track.tofNSigmaKa())); + registryParticleQA.fill(HIST("TrackQA/Before/Kaon/fNsigmaTPCTOF"), track.p(), std::hypot(track.tpcNSigmaKa(), track.tofNSigmaKa())); registryParticleQA.fill(HIST("TrackQA/Before/Proton/fNsigmaITS"), track.p(), track.itsNSigmaPr()); registryParticleQA.fill(HIST("TrackQA/Before/Proton/fNsigmaTPC"), track.p(), track.tpcNSigmaPr()); registryParticleQA.fill(HIST("TrackQA/Before/Proton/fNsigmaTOF"), track.p(), track.tofNSigmaPr()); - registryParticleQA.fill(HIST("TrackQA/Before/Proton/fNsigmaTPCTOF"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPr(), track.tofNSigmaPr())); + registryParticleQA.fill(HIST("TrackQA/Before/Proton/fNsigmaTPCTOF"), track.p(), std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr())); registryParticleQA.fill(HIST("TrackQA/Before/Deuteron/fNsigmaITS"), track.p(), track.itsNSigmaDe()); registryParticleQA.fill(HIST("TrackQA/Before/Deuteron/fNsigmaTPC"), track.p(), track.tpcNSigmaDe()); registryParticleQA.fill(HIST("TrackQA/Before/Deuteron/fNsigmaTOF"), track.p(), track.tofNSigmaDe()); - registryParticleQA.fill(HIST("TrackQA/Before/Deuteron/fNsigmaTPCTOF"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaDe(), track.tofNSigmaDe())); + registryParticleQA.fill(HIST("TrackQA/Before/Deuteron/fNsigmaTPCTOF"), track.p(), std::hypot(track.tpcNSigmaDe(), track.tofNSigmaDe())); if (checkTrack(track, std::string("Pion")) && checkTrackPid(track, std::string("Pion"))) { vecPion.emplace_back(track.pt(), track.eta(), track.phi(), o2::constants::physics::MassPionCharged); @@ -1373,7 +1373,7 @@ struct CFFilterAll { registryParticleQA.fill(HIST("TrackQA/After/Pion/fNsigmaIts"), track.p(), track.itsNSigmaPi()); registryParticleQA.fill(HIST("TrackQA/After/Pion/fNsigmaTpc"), track.p(), track.tpcNSigmaPi()); registryParticleQA.fill(HIST("TrackQA/After/Pion/fNsigmaTof"), track.p(), track.tofNSigmaPi()); - registryParticleQA.fill(HIST("TrackQA/After/Pion/fNsigmaTpcTof"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPi(), track.tofNSigmaPi())); + registryParticleQA.fill(HIST("TrackQA/After/Pion/fNsigmaTpcTof"), track.p(), std::hypot(track.tpcNSigmaPi(), track.tofNSigmaPi())); registryParticleQA.fill(HIST("TrackQA/After/Pion/fItsSignal"), track.p(), itsSignal(track)); registryParticleQA.fill(HIST("TrackQA/After/Pion/fTpcSignal"), track.p(), track.tpcSignal()); @@ -1407,7 +1407,7 @@ struct CFFilterAll { registryParticleQA.fill(HIST("TrackQA/After/Kaon/fNsigmaIts"), track.p(), track.itsNSigmaKa()); registryParticleQA.fill(HIST("TrackQA/After/Kaon/fNsigmaTpc"), track.p(), track.tpcNSigmaKa()); registryParticleQA.fill(HIST("TrackQA/After/Kaon/fNsigmaTof"), track.p(), track.tofNSigmaKa()); - registryParticleQA.fill(HIST("TrackQA/After/Kaon/fNsigmaTpcTof"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaKa(), track.tofNSigmaKa())); + registryParticleQA.fill(HIST("TrackQA/After/Kaon/fNsigmaTpcTof"), track.p(), std::hypot(track.tpcNSigmaKa(), track.tofNSigmaKa())); registryParticleQA.fill(HIST("TrackQA/After/Kaon/fItsSignal"), track.p(), itsSignal(track)); registryParticleQA.fill(HIST("TrackQA/After/Kaon/fTpcSignal"), track.p(), track.tpcSignal()); @@ -1441,7 +1441,7 @@ struct CFFilterAll { registryParticleQA.fill(HIST("TrackQA/After/Proton/fNsigmaIts"), track.p(), track.itsNSigmaPr()); registryParticleQA.fill(HIST("TrackQA/After/Proton/fNsigmaTpc"), track.p(), track.tpcNSigmaPr()); registryParticleQA.fill(HIST("TrackQA/After/Proton/fNsigmaTof"), track.p(), track.tofNSigmaPr()); - registryParticleQA.fill(HIST("TrackQA/After/Proton/fNsigmaTpcTof"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPr(), track.tofNSigmaPr())); + registryParticleQA.fill(HIST("TrackQA/After/Proton/fNsigmaTpcTof"), track.p(), std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr())); registryParticleQA.fill(HIST("TrackQA/After/Proton/fItsSignal"), track.p(), itsSignal(track)); registryParticleQA.fill(HIST("TrackQA/After/Proton/fTpcSignal"), track.p(), track.tpcSignal()); @@ -1475,7 +1475,7 @@ struct CFFilterAll { registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fNsigmaIts"), track.p(), track.itsNSigmaDe()); registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fNsigmaTpc"), track.p(), track.tpcNSigmaDe()); registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fNsigmaTof"), track.p(), track.tofNSigmaDe()); - registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fNsigmaTpcTof"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaDe(), track.tofNSigmaDe())); + registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fNsigmaTpcTof"), track.p(), std::hypot(track.tpcNSigmaDe(), track.tofNSigmaDe())); registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fItsSignal"), track.p(), itsSignal(track)); registryParticleQA.fill(HIST("TrackQA/After/Deuteron/fTpcSignal"), track.p(), track.tpcSignal()); @@ -1509,22 +1509,22 @@ struct CFFilterAll { registryParticleQA.fill(HIST("TrackQA/Before/AntiPion/fNsigmaITS"), track.p(), track.itsNSigmaPi()); registryParticleQA.fill(HIST("TrackQA/Before/AntiPion/fNsigmaTPC"), track.p(), track.tpcNSigmaPi()); registryParticleQA.fill(HIST("TrackQA/Before/AntiPion/fNsigmaTOF"), track.p(), track.tofNSigmaPi()); - registryParticleQA.fill(HIST("TrackQA/Before/AntiPion/fNsigmaTPCTOF"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPi(), track.tofNSigmaPi())); + registryParticleQA.fill(HIST("TrackQA/Before/AntiPion/fNsigmaTPCTOF"), track.p(), std::hypot(track.tpcNSigmaPi(), track.tofNSigmaPi())); registryParticleQA.fill(HIST("TrackQA/Before/AntiKaon/fNsigmaITS"), track.p(), track.itsNSigmaKa()); registryParticleQA.fill(HIST("TrackQA/Before/AntiKaon/fNsigmaTPC"), track.p(), track.tpcNSigmaKa()); registryParticleQA.fill(HIST("TrackQA/Before/AntiKaon/fNsigmaTOF"), track.p(), track.tofNSigmaKa()); - registryParticleQA.fill(HIST("TrackQA/Before/AntiKaon/fNsigmaTPCTOF"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaKa(), track.tofNSigmaKa())); + registryParticleQA.fill(HIST("TrackQA/Before/AntiKaon/fNsigmaTPCTOF"), track.p(), std::hypot(track.tpcNSigmaKa(), track.tofNSigmaKa())); registryParticleQA.fill(HIST("TrackQA/Before/AntiProton/fNsigmaITS"), track.p(), track.itsNSigmaPr()); registryParticleQA.fill(HIST("TrackQA/Before/AntiProton/fNsigmaTPC"), track.p(), track.tpcNSigmaPr()); registryParticleQA.fill(HIST("TrackQA/Before/AntiProton/fNsigmaTOF"), track.p(), track.tofNSigmaPr()); - registryParticleQA.fill(HIST("TrackQA/Before/AntiProton/fNsigmaTPCTOF"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPr(), track.tofNSigmaPr())); + registryParticleQA.fill(HIST("TrackQA/Before/AntiProton/fNsigmaTPCTOF"), track.p(), std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr())); registryParticleQA.fill(HIST("TrackQA/Before/AntiDeuteron/fNsigmaITS"), track.p(), track.itsNSigmaDe()); registryParticleQA.fill(HIST("TrackQA/Before/AntiDeuteron/fNsigmaTPC"), track.p(), track.tpcNSigmaDe()); registryParticleQA.fill(HIST("TrackQA/Before/AntiDeuteron/fNsigmaTOF"), track.p(), track.tofNSigmaDe()); - registryParticleQA.fill(HIST("TrackQA/Before/AntiDeuteron/fNsigmaTPCTOF"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaDe(), track.tofNSigmaDe())); + registryParticleQA.fill(HIST("TrackQA/Before/AntiDeuteron/fNsigmaTPCTOF"), track.p(), std::hypot(track.tpcNSigmaDe(), track.tofNSigmaDe())); if (checkTrack(track, std::string("Pion")) && checkTrackPid(track, std::string("Pion"))) { vecAntiPion.emplace_back(track.pt(), track.eta(), track.phi(), o2::constants::physics::MassPionCharged); @@ -1539,7 +1539,7 @@ struct CFFilterAll { registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fNsigmaIts"), track.p(), track.itsNSigmaPi()); registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fNsigmaTpc"), track.p(), track.tpcNSigmaPi()); registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fNsigmaTof"), track.p(), track.tofNSigmaPi()); - registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fNsigmaTpcTof"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPi(), track.tofNSigmaPi())); + registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fNsigmaTpcTof"), track.p(), std::hypot(track.tpcNSigmaPi(), track.tofNSigmaPi())); registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fItsSignal"), track.p(), itsSignal(track)); registryParticleQA.fill(HIST("TrackQA/After/AntiPion/fTpcSignal"), track.p(), track.tpcSignal()); @@ -1573,7 +1573,7 @@ struct CFFilterAll { registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fNsigmaIts"), track.p(), track.itsNSigmaKa()); registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fNsigmaTpc"), track.p(), track.tpcNSigmaKa()); registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fNsigmaTof"), track.p(), track.tofNSigmaKa()); - registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fNsigmaTpcTof"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaKa(), track.tofNSigmaKa())); + registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fNsigmaTpcTof"), track.p(), std::hypot(track.tpcNSigmaKa(), track.tofNSigmaKa())); registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fItsSignal"), track.p(), itsSignal(track)); registryParticleQA.fill(HIST("TrackQA/After/AntiKaon/fTpcSignal"), track.p(), track.tpcSignal()); @@ -1607,7 +1607,7 @@ struct CFFilterAll { registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fNsigmaIts"), track.p(), track.itsNSigmaPr()); registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fNsigmaTpc"), track.p(), track.tpcNSigmaPr()); registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fNsigmaTof"), track.p(), track.tofNSigmaPr()); - registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fNsigmaTpcTof"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaPr(), track.tofNSigmaPr())); + registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fNsigmaTpcTof"), track.p(), std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr())); registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fItsSignal"), track.p(), itsSignal(track)); registryParticleQA.fill(HIST("TrackQA/After/AntiProton/fTpcSignal"), track.p(), track.tpcSignal()); @@ -1641,7 +1641,7 @@ struct CFFilterAll { registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fNsigmaIts"), track.p(), track.itsNSigmaDe()); registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fNsigmaTpc"), track.p(), track.tpcNSigmaDe()); registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fNsigmaTof"), track.p(), track.tofNSigmaDe()); - registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fNsigmaTpcTof"), track.p(), RecoDecay::sqrtSumOfSquares(track.tpcNSigmaDe(), track.tofNSigmaDe())); + registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fNsigmaTpcTof"), track.p(), std::hypot(track.tpcNSigmaDe(), track.tofNSigmaDe())); registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fItsSignal"), track.p(), itsSignal(track)); registryParticleQA.fill(HIST("TrackQA/After/AntiDeuteron/fTpcSignal"), track.p(), track.tpcSignal()); @@ -1677,7 +1677,7 @@ struct CFFilterAll { continue; } - float lambdaPt = RecoDecay::sqrtSumOfSquares(mStraHelper.v0.momentum[0], mStraHelper.v0.momentum[1]); + float lambdaPt = std::hypot(mStraHelper.v0.momentum[0], mStraHelper.v0.momentum[1]); float lambdaPos = std::hypot(mStraHelper.v0.position[0] - col.posX(), mStraHelper.v0.position[1] - col.posY(), mStraHelper.v0.position[2] - col.posZ()); float lambdaRadius = std::hypot(mStraHelper.v0.position[0], mStraHelper.v0.position[1]); float lambdaEta = RecoDecay::eta(std::array{mStraHelper.v0.momentum[0], mStraHelper.v0.momentum[1], mStraHelper.v0.momentum[2]}); @@ -1844,25 +1844,25 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("PPP/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPP/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPP/all/fSE_particle"), q3); - registryTriggerQA.fill(HIST("PPP/all/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPP/all/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPP/all/fProtonPtVsQ3"), vecProton.at(p3).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/all/fProtonQ3VsPt"), q3, vecProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPP/all/fProtonQ3VsPt"), q3, vecProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPP/all/fProtonQ3VsPt"), q3, vecProton.at(p3).Pt()); if (q3 < TriggerSelections.limits->get("Loose Limit", "PPP")) { signalLooseLimit[cf_trigger::kPPP] += 1; registryTriggerQA.fill(HIST("PPP/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPP/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPP/loose/fSE_particle"), q3); - registryTriggerQA.fill(HIST("PPP/loose/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPP/loose/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPP/loose/fProtonPtVsQ3"), vecProton.at(p3).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/loose/fProtonQ3VsPt"), q3, vecProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPP/loose/fProtonQ3VsPt"), q3, vecProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPP/loose/fProtonQ3VsPt"), q3, vecProton.at(p3).Pt()); if (q3 < TriggerSelections.limits->get("Tight Limit", "PPP")) { signalTightLimit[cf_trigger::kPPP] += 1; registryTriggerQA.fill(HIST("PPP/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPP/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPP/tight/fSE_particle"), q3); - registryTriggerQA.fill(HIST("PPP/tight/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPP/tight/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPP/tight/fProtonPtVsQ3"), vecProton.at(p3).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/tight/fProtonQ3VsPt"), q3, vecProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPP/tight/fProtonQ3VsPt"), q3, vecProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPP/tight/fProtonQ3VsPt"), q3, vecProton.at(p3).Pt()); } } } @@ -1875,25 +1875,25 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("PPP/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPP/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPP/all/fSE_antiparticle"), q3); - registryTriggerQA.fill(HIST("PPP/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPP/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPP/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p3).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/all/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPP/all/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPP/all/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p3).Pt()); if (q3 < TriggerSelections.limits->get("Loose Limit", "PPP")) { signalLooseLimit[cf_trigger::kPPP] += 1; registryTriggerQA.fill(HIST("PPP/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPP/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPP/loose/fSE_antiparticle"), q3); - registryTriggerQA.fill(HIST("PPP/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPP/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPP/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p3).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/loose/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPP/loose/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPP/loose/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p3).Pt()); if (q3 < TriggerSelections.limits->get("Tight Limit", "PPP")) { signalTightLimit[cf_trigger::kPPP] += 1; registryTriggerQA.fill(HIST("PPP/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPP/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPP/tight/fSE_antiparticle"), q3); - registryTriggerQA.fill(HIST("PPP/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPP/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPP/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p3).Pt(), q3); + registryTriggerQA.fill(HIST("PPP/tight/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPP/tight/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPP/tight/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p3).Pt()); } } } @@ -1912,25 +1912,25 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("PPL/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPL/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPL/all/fSE_particle"), q3); - registryTriggerQA.fill(HIST("PPL/all/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPL/all/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPL/all/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/all/fProtonQ3VsPt"), q3, vecProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPL/all/fProtonQ3VsPt"), q3, vecProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPL/all/fLambdaQ3VsPt"), q3, vecLambda.at(l1).Pt()); if (q3 < TriggerSelections.limits->get("Loose Limit", "PPL")) { signalLooseLimit[cf_trigger::kPPL] += 1; registryTriggerQA.fill(HIST("PPL/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPL/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPL/loose/fSE_particle"), q3); - registryTriggerQA.fill(HIST("PPL/loose/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPL/loose/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPL/loose/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/loose/fProtonQ3VsPt"), q3, vecProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPL/loose/fProtonQ3VsPt"), q3, vecProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPL/loose/fLambdaQ3VsPt"), q3, vecLambda.at(l1).Pt()); if (q3 < TriggerSelections.limits->get("Tight Limit", "PPL")) { signalTightLimit[cf_trigger::kPPL] += 1; registryTriggerQA.fill(HIST("PPL/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPL/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPL/tight/fSE_particle"), q3); - registryTriggerQA.fill(HIST("PPL/tight/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPL/tight/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPL/tight/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/tight/fProtonQ3VsPt"), q3, vecProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPL/tight/fProtonQ3VsPt"), q3, vecProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPL/tight/fLambdaQ3VsPt"), q3, vecLambda.at(l1).Pt()); } } } @@ -1945,26 +1945,26 @@ struct CFFilterAll { q3 = getQ3(vecAntiProton.at(p1), vecAntiProton.at(p2), vecAntiLambda.at(l1)); registryTriggerQA.fill(HIST("PPL/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPL/all/fZvtx"), col.posZ()); - registryTriggerQA.fill(HIST("PPL/all/fSE_particle"), q3); - registryTriggerQA.fill(HIST("PPL/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPL/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPL/all/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/all/fSE_antiparticle"), q3); + registryTriggerQA.fill(HIST("PPL/all/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPL/all/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPL/all/fAntiLambdaQ3VsPt"), q3, vecAntiLambda.at(l1).Pt()); if (q3 < TriggerSelections.limits->get("Loose Limit", "PPL")) { signalLooseLimit[cf_trigger::kPPL] += 1; registryTriggerQA.fill(HIST("PPL/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPL/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPL/loose/fSE_antiparticle"), q3); - registryTriggerQA.fill(HIST("PPL/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPL/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPL/loose/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/loose/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPL/loose/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPL/loose/fAntiLambdaQ3VsPt"), q3, vecAntiLambda.at(l1).Pt()); if (q3 < TriggerSelections.limits->get("Tight Limit", "PPL")) { signalTightLimit[cf_trigger::kPPL] += 1; registryTriggerQA.fill(HIST("PPL/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPL/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPL/tight/fSE_antiparticle"), q3); - registryTriggerQA.fill(HIST("PPL/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPL/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPL/tight/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); + registryTriggerQA.fill(HIST("PPL/tight/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPL/tight/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPL/tight/fAntiLambdaQ3VsPt"), q3, vecAntiLambda.at(l1).Pt()); } } } @@ -1986,25 +1986,25 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("PLL/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PLL/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PLL/all/fSE_particle"), q3); - registryTriggerQA.fill(HIST("PLL/all/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); - registryTriggerQA.fill(HIST("PLL/all/fLambdaPtVsQ3"), vecLambda.at(l2).Pt(), q3); - registryTriggerQA.fill(HIST("PLL/all/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/all/fLambdaQ3VsPt"), q3, vecLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("PLL/all/fLambdaQ3VsPt"), q3, vecLambda.at(l2).Pt()); + registryTriggerQA.fill(HIST("PLL/all/fProtonQ3VsPt"), q3, vecProton.at(p1).Pt()); if (q3 < TriggerSelections.limits->get("Loose Limit", "PLL")) { signalLooseLimit[cf_trigger::kPLL] += 1; registryTriggerQA.fill(HIST("PLL/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PLL/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PLL/loose/fSE_particle"), q3); - registryTriggerQA.fill(HIST("PLL/loose/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); - registryTriggerQA.fill(HIST("PLL/loose/fLambdaPtVsQ3"), vecLambda.at(l2).Pt(), q3); - registryTriggerQA.fill(HIST("PLL/loose/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/loose/fLambdaQ3VsPt"), q3, vecLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("PLL/loose/fLambdaQ3VsPt"), q3, vecLambda.at(l2).Pt()); + registryTriggerQA.fill(HIST("PLL/loose/fProtonQ3VsPt"), q3, vecProton.at(p1).Pt()); if (q3 < TriggerSelections.limits->get("Tight Limit", "PLL")) { signalTightLimit[cf_trigger::kPLL] += 1; registryTriggerQA.fill(HIST("PLL/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PLL/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PLL/tight/fSE_particle"), q3); - registryTriggerQA.fill(HIST("PLL/tight/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); - registryTriggerQA.fill(HIST("PLL/tight/fLambdaPtVsQ3"), vecLambda.at(l2).Pt(), q3); - registryTriggerQA.fill(HIST("PLL/tight/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/tight/fLambdaQ3VsPt"), q3, vecLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("PLL/tight/fLambdaQ3VsPt"), q3, vecLambda.at(l2).Pt()); + registryTriggerQA.fill(HIST("PLL/tight/fProtonQ3VsPt"), q3, vecProton.at(p1).Pt()); } } } @@ -2023,25 +2023,25 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("PLL/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PLL/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PLL/all/fSE_antiparticle"), q3); - registryTriggerQA.fill(HIST("PLL/all/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); - registryTriggerQA.fill(HIST("PLL/all/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l2).Pt(), q3); - registryTriggerQA.fill(HIST("PLL/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/all/fAntiLambdaQ3VsPt"), q3, vecAntiLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("PLL/all/fAntiLambdaQ3VsPt"), q3, vecAntiLambda.at(l2).Pt()); + registryTriggerQA.fill(HIST("PLL/all/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p1).Pt()); if (q3 < TriggerSelections.limits->get("Loose Limit", "PLL")) { signalLooseLimit[cf_trigger::kPLL] += 1; registryTriggerQA.fill(HIST("PLL/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PLL/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PLL/loose/fSE_antiparticle"), q3); - registryTriggerQA.fill(HIST("PLL/loose/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); - registryTriggerQA.fill(HIST("PLL/loose/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l2).Pt(), q3); - registryTriggerQA.fill(HIST("PLL/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/loose/fAntiLambdaQ3VsPt"), q3, vecAntiLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("PLL/loose/fAntiLambdaQ3VsPt"), q3, vecAntiLambda.at(l2).Pt()); + registryTriggerQA.fill(HIST("PLL/loose/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p1).Pt()); if (q3 < TriggerSelections.limits->get("Tight Limit", "PLL")) { signalTightLimit[cf_trigger::kPLL] += 1; registryTriggerQA.fill(HIST("PLL/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PLL/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PLL/tight/fSE_antiparticle"), q3); - registryTriggerQA.fill(HIST("PLL/tight/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); - registryTriggerQA.fill(HIST("PLL/tight/fAntiLambdaPtVsQ3"), vecAntiLambda.at(l2).Pt(), q3); - registryTriggerQA.fill(HIST("PLL/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); + registryTriggerQA.fill(HIST("PLL/tight/fAntiLambdaQ3VsPt"), q3, vecAntiLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("PLL/tight/fAntiLambdaQ3VsPt"), q3, vecAntiLambda.at(l2).Pt()); + registryTriggerQA.fill(HIST("PLL/tight/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p1).Pt()); } } } @@ -2062,25 +2062,25 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("LLL/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("LLL/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("LLL/all/fSE_particle"), q3); - registryTriggerQA.fill(HIST("LLL/all/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); - registryTriggerQA.fill(HIST("LLL/all/fLambdaPtVsQ3"), vecLambda.at(l2).Pt(), q3); - registryTriggerQA.fill(HIST("LLL/all/fLambdaPtVsQ3"), vecLambda.at(l3).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/all/fLambdaQ3VsPt"), q3, vecLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("LLL/all/fLambdaQ3VsPt"), q3, vecLambda.at(l2).Pt()); + registryTriggerQA.fill(HIST("LLL/all/fLambdaQ3VsPt"), q3, vecLambda.at(l3).Pt()); if (q3 < TriggerSelections.limits->get("Loose Limit", "LLL")) { signalLooseLimit[cf_trigger::kLLL] += 1; registryTriggerQA.fill(HIST("LLL/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("LLL/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("LLL/loose/fSE_particle"), q3); - registryTriggerQA.fill(HIST("LLL/loose/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); - registryTriggerQA.fill(HIST("LLL/loose/fLambdaPtVsQ3"), vecLambda.at(l2).Pt(), q3); - registryTriggerQA.fill(HIST("LLL/loose/fLambdaPtVsQ3"), vecLambda.at(l3).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/loose/fLambdaQ3VsPt"), q3, vecLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("LLL/loose/fLambdaQ3VsPt"), q3, vecLambda.at(l2).Pt()); + registryTriggerQA.fill(HIST("LLL/loose/fLambdaQ3VsPt"), q3, vecLambda.at(l3).Pt()); if (q3 < TriggerSelections.limits->get("Tight Limit", "LLL")) { signalTightLimit[cf_trigger::kLLL] += 1; registryTriggerQA.fill(HIST("LLL/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("LLL/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("LLL/tight/fSE_particle"), q3); - registryTriggerQA.fill(HIST("LLL/tight/fLambdaPtVsQ3"), vecLambda.at(l1).Pt(), q3); - registryTriggerQA.fill(HIST("LLL/tight/fLambdaPtVsQ3"), vecLambda.at(l2).Pt(), q3); - registryTriggerQA.fill(HIST("LLL/tight/fLambdaPtVsQ3"), vecLambda.at(l3).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/tight/fLambdaQ3VsPt"), q3, vecLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("LLL/tight/fLambdaQ3VsPt"), q3, vecLambda.at(l2).Pt()); + registryTriggerQA.fill(HIST("LLL/tight/fLambdaQ3VsPt"), q3, vecLambda.at(l3).Pt()); } } } @@ -2098,25 +2098,25 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("LLL/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("LLL/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("LLL/all/fSE_antiparticle"), q3); - registryTriggerQA.fill(HIST("LLL/all/fLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); - registryTriggerQA.fill(HIST("LLL/all/fLambdaPtVsQ3"), vecAntiLambda.at(l2).Pt(), q3); - registryTriggerQA.fill(HIST("LLL/all/fLambdaPtVsQ3"), vecAntiLambda.at(l3).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/all/fLambdaQ3VsPt"), q3, vecAntiLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("LLL/all/fLambdaQ3VsPt"), q3, vecAntiLambda.at(l2).Pt()); + registryTriggerQA.fill(HIST("LLL/all/fLambdaQ3VsPt"), q3, vecAntiLambda.at(l3).Pt()); if (q3 < TriggerSelections.limits->get("Loose Limit", "LLL")) { signalLooseLimit[cf_trigger::kLLL] += 1; registryTriggerQA.fill(HIST("LLL/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("LLL/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("LLL/loose/fSE_antiparticle"), q3); - registryTriggerQA.fill(HIST("LLL/loose/fLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); - registryTriggerQA.fill(HIST("LLL/loose/fLambdaPtVsQ3"), vecAntiLambda.at(l2).Pt(), q3); - registryTriggerQA.fill(HIST("LLL/loose/fLambdaPtVsQ3"), vecAntiLambda.at(l3).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/loose/fLambdaQ3VsPt"), q3, vecAntiLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("LLL/loose/fLambdaQ3VsPt"), q3, vecAntiLambda.at(l2).Pt()); + registryTriggerQA.fill(HIST("LLL/loose/fLambdaQ3VsPt"), q3, vecAntiLambda.at(l3).Pt()); if (q3 < TriggerSelections.limits->get("Tight Limit", "LLL")) { signalTightLimit[cf_trigger::kLLL] += 1; registryTriggerQA.fill(HIST("LLL/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("LLL/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("LLL/tight/fSE_antiparticle"), q3); - registryTriggerQA.fill(HIST("LLL/tight/fLambdaPtVsQ3"), vecAntiLambda.at(l1).Pt(), q3); - registryTriggerQA.fill(HIST("LLL/tight/fLambdaPtVsQ3"), vecAntiLambda.at(l2).Pt(), q3); - registryTriggerQA.fill(HIST("LLL/tight/fLambdaPtVsQ3"), vecAntiLambda.at(l3).Pt(), q3); + registryTriggerQA.fill(HIST("LLL/tight/fLambdaQ3VsPt"), q3, vecAntiLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("LLL/tight/fLambdaQ3VsPt"), q3, vecAntiLambda.at(l2).Pt()); + registryTriggerQA.fill(HIST("LLL/tight/fLambdaQ3VsPt"), q3, vecAntiLambda.at(l3).Pt()); } } } @@ -2135,29 +2135,29 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("PPPhi/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPPhi/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPPhi/all/fSE_particle"), q3); - registryTriggerQA.fill(HIST("PPPhi/all/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/all/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/all/fPhiPtVsQ3"), vecPhi.at(phi1).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/all/fPhiInvMassVsQ3"), vecPhi.at(phi1).M(), q3); + registryTriggerQA.fill(HIST("PPPhi/all/fProtonQ3VsPt"), q3, vecProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPPhi/all/fProtonQ3VsPt"), q3, vecProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPPhi/all/fPhiQ3VsPt"), q3, vecPhi.at(phi1).Pt()); + registryTriggerQA.fill(HIST("PPPhi/all/fPhiQ3VsInvMass"), q3, vecPhi.at(phi1).M()); if (q3 < TriggerSelections.limits->get("Loose Limit", "PPPhi")) { signalLooseLimit[cf_trigger::kPPPhi] += 1; registryTriggerQA.fill(HIST("PPPhi/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPPhi/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPPhi/loose/fSE_particle"), q3); - registryTriggerQA.fill(HIST("PPPhi/loose/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/loose/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/loose/fPhiPtVsQ3"), vecPhi.at(phi1).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/loose/fPhiInvMassVsQ3"), vecPhi.at(phi1).M(), q3); + registryTriggerQA.fill(HIST("PPPhi/loose/fProtonQ3VsPt"), q3, vecProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPPhi/loose/fProtonQ3VsPt"), q3, vecProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPPhi/loose/fPhiQ3VsPt"), q3, vecPhi.at(phi1).Pt()); + registryTriggerQA.fill(HIST("PPPhi/loose/fPhiQ3VsInvMass"), q3, vecPhi.at(phi1).M()); if (q3 < TriggerSelections.limits->get("Tight Limit", "PPPhi") && vecPhi.at(phi1).M() > PhiSelections.tightInvMassLow.value && vecPhi.at(phi1).M() < PhiSelections.tightInvMassUp.value) { signalTightLimit[cf_trigger::kPPPhi] += 1; registryTriggerQA.fill(HIST("PPPhi/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPPhi/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPPhi/tight/fSE_particle"), q3); - registryTriggerQA.fill(HIST("PPPhi/tight/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/tight/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/tight/fPhiPtVsQ3"), vecPhi.at(phi1).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/tight/fPhiInvMassVsQ3"), vecPhi.at(phi1).M(), q3); + registryTriggerQA.fill(HIST("PPPhi/tight/fProtonQ3VsPt"), q3, vecProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPPhi/tight/fProtonQ3VsPt"), q3, vecProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPPhi/tight/fPhiQ3VsPt"), q3, vecPhi.at(phi1).Pt()); + registryTriggerQA.fill(HIST("PPPhi/tight/fPhiQ3VsInvMass"), q3, vecPhi.at(phi1).M()); } } } @@ -2173,29 +2173,29 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("PPPhi/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPPhi/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPPhi/all/fSE_antiparticle"), q3); - registryTriggerQA.fill(HIST("PPPhi/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/all/fPhiPtVsQ3"), vecPhi.at(phi1).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/all/fPhiInvMassVsQ3"), vecPhi.at(phi1).M(), q3); + registryTriggerQA.fill(HIST("PPPhi/all/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPPhi/all/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPPhi/all/fPhiQ3VsPt"), q3, vecPhi.at(phi1).Pt()); + registryTriggerQA.fill(HIST("PPPhi/all/fPhiQ3VsInvMass"), q3, vecPhi.at(phi1).M()); if (q3 < TriggerSelections.limits->get("Loose Limit", "PPPhi")) { signalLooseLimit[cf_trigger::kPPPhi] += 1; registryTriggerQA.fill(HIST("PPPhi/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPPhi/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPPhi/loose/fSE_antiparticle"), q3); - registryTriggerQA.fill(HIST("PPPhi/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/loose/fPhiPtVsQ3"), vecPhi.at(phi1).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/loose/fPhiInvMassVsQ3"), vecPhi.at(phi1).M(), q3); + registryTriggerQA.fill(HIST("PPPhi/loose/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPPhi/loose/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPPhi/loose/fPhiQ3VsPt"), q3, vecPhi.at(phi1).Pt()); + registryTriggerQA.fill(HIST("PPPhi/loose/fPhiQ3VsInvMass"), q3, vecPhi.at(phi1).M()); if (q3 < TriggerSelections.limits->get("Tight Limit", "PPPhi") && vecPhi.at(phi1).M() > PhiSelections.tightInvMassLow.value && vecPhi.at(phi1).M() < PhiSelections.tightInvMassUp.value) { signalTightLimit[cf_trigger::kPPPhi] += 1; registryTriggerQA.fill(HIST("PPPhi/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPPhi/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPPhi/tight/fSE_antiparticle"), q3); - registryTriggerQA.fill(HIST("PPPhi/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/tight/fPhiPtVsQ3"), vecPhi.at(phi1).Pt(), q3); - registryTriggerQA.fill(HIST("PPPhi/tight/fPhiInvMassVsQ3"), vecPhi.at(phi1).M(), q3); + registryTriggerQA.fill(HIST("PPPhi/tight/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPPhi/tight/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPPhi/tight/fPhiQ3VsPt"), q3, vecPhi.at(phi1).Pt()); + registryTriggerQA.fill(HIST("PPPhi/tight/fPhiQ3VsInvMass"), q3, vecPhi.at(phi1).M()); } } } @@ -2214,29 +2214,29 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("PPRho/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPRho/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPRho/all/fSE_particle"), q3); - registryTriggerQA.fill(HIST("PPRho/all/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/all/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/all/fRhoPtVsQ3"), vecRho.at(r1).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/all/fRhoInvMassVsQ3"), vecRho.at(r1).M(), q3); + registryTriggerQA.fill(HIST("PPRho/all/fProtonQ3VsPt"), q3, vecProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPRho/all/fProtonQ3VsPt"), q3, vecProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPRho/all/fRhoQ3VsPt"), q3, vecRho.at(r1).Pt()); + registryTriggerQA.fill(HIST("PPRho/all/fRhoQ3VsInvMass"), q3, vecRho.at(r1).M()); if (q3 < TriggerSelections.limits->get("Loose Limit", "PPRho")) { signalLooseLimit[cf_trigger::kPPRho] += 1; registryTriggerQA.fill(HIST("PPRho/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPRho/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPRho/loose/fSE_particle"), q3); - registryTriggerQA.fill(HIST("PPRho/loose/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/loose/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/loose/fRhoPtVsQ3"), vecRho.at(r1).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/loose/fRhoInvMassVsQ3"), vecRho.at(r1).M(), q3); + registryTriggerQA.fill(HIST("PPRho/loose/fProtonQ3VsPt"), q3, vecProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPRho/loose/fProtonQ3VsPt"), q3, vecProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPRho/loose/fRhoQ3VsPt"), q3, vecRho.at(r1).Pt()); + registryTriggerQA.fill(HIST("PPRho/loose/fRhoQ3VsInvMass"), q3, vecRho.at(r1).M()); if (q3 < TriggerSelections.limits->get("Tight Limit", "PPRho") && vecRho.at(r1).M() > RhoSelections.tightInvMassLow.value && vecRho.at(r1).M() < RhoSelections.tightInvMassUp.value) { signalTightLimit[cf_trigger::kPPRho] += 1; registryTriggerQA.fill(HIST("PPRho/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPRho/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPRho/tight/fSE_particle"), q3); - registryTriggerQA.fill(HIST("PPRho/tight/fProtonPtVsQ3"), vecProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/tight/fProtonPtVsQ3"), vecProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/tight/fRhoPtVsQ3"), vecRho.at(r1).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/tight/fRhoInvMassVsQ3"), vecRho.at(r1).M(), q3); + registryTriggerQA.fill(HIST("PPRho/tight/fProtonQ3VsPt"), q3, vecProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPRho/tight/fProtonQ3VsPt"), q3, vecProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPRho/tight/fRhoQ3VsPt"), q3, vecRho.at(r1).Pt()); + registryTriggerQA.fill(HIST("PPRho/tight/fRhoQ3VsInvMass"), q3, vecRho.at(r1).M()); } } } @@ -2252,29 +2252,29 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("PPRho/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPRho/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPRho/all/fSE_antiparticle"), q3); - registryTriggerQA.fill(HIST("PPRho/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/all/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/all/fRhoPtVsQ3"), vecRho.at(r1).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/all/fRhoInvMassVsQ3"), vecRho.at(r1).M(), q3); + registryTriggerQA.fill(HIST("PPRho/all/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPRho/all/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPRho/all/fRhoQ3VsPt"), q3, vecRho.at(r1).Pt()); + registryTriggerQA.fill(HIST("PPRho/all/fRhoQ3VsInvMass"), q3, vecRho.at(r1).M()); if (q3 < TriggerSelections.limits->get("Loose Limit", "PPRho")) { signalLooseLimit[cf_trigger::kPPRho] += 1; registryTriggerQA.fill(HIST("PPRho/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPRho/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPRho/loose/fSE_antiparticle"), q3); - registryTriggerQA.fill(HIST("PPRho/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/loose/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/loose/fRhoPtVsQ3"), vecRho.at(r1).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/loose/fRhoInvMassVsQ3"), vecRho.at(r1).M(), q3); + registryTriggerQA.fill(HIST("PPRho/loose/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPRho/loose/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPRho/loose/fRhoQ3VsPt"), q3, vecRho.at(r1).Pt()); + registryTriggerQA.fill(HIST("PPRho/loose/fRhoQ3VsInvMass"), q3, vecRho.at(r1).M()); if (q3 < TriggerSelections.limits->get("Tight Limit", "PPRho") && vecRho.at(r1).M() > RhoSelections.tightInvMassLow.value && vecRho.at(r1).M() < RhoSelections.tightInvMassUp.value) { signalTightLimit[cf_trigger::kPPRho] += 1; registryTriggerQA.fill(HIST("PPRho/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PPRho/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PPRho/tight/fSE_antiparticle"), q3); - registryTriggerQA.fill(HIST("PPRho/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p1).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/tight/fAntiProtonPtVsQ3"), vecAntiProton.at(p2).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/tight/fRhoPtVsQ3"), vecRho.at(r1).Pt(), q3); - registryTriggerQA.fill(HIST("PPRho/tight/fRhoInvMassVsQ3"), vecRho.at(r1).M(), q3); + registryTriggerQA.fill(HIST("PPRho/tight/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PPRho/tight/fAntiProtonQ3VsPt"), q3, vecAntiProton.at(p2).Pt()); + registryTriggerQA.fill(HIST("PPRho/tight/fRhoQ3VsPt"), q3, vecRho.at(r1).Pt()); + registryTriggerQA.fill(HIST("PPRho/tight/fRhoQ3VsInvMass"), q3, vecRho.at(r1).M()); } } } @@ -2292,22 +2292,22 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("PD/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PD/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PD/all/fSE_particle"), kstar); - registryTriggerQA.fill(HIST("PD/all/fProtonPtVskstar"), vecProton.at(p1).Pt(), kstar); - registryTriggerQA.fill(HIST("PD/all/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("PD/all/fProtonKstarVsPt"), kstar, vecProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PD/all/fDeuteronKstarVsPt"), kstar, vecDeuteron.at(d1).Pt()); if (kstar < TriggerSelections.limits->get("Loose Limit", "PD")) { signalLooseLimit[cf_trigger::kPD] += 1; registryTriggerQA.fill(HIST("PD/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PD/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PD/loose/fSE_particle"), kstar); - registryTriggerQA.fill(HIST("PD/loose/fProtonPtVskstar"), vecProton.at(p1).Pt(), kstar); - registryTriggerQA.fill(HIST("PD/loose/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("PD/loose/fProtonKstarVsPt"), kstar, vecProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PD/loose/fDeuteronKstarVsPt"), kstar, vecDeuteron.at(d1).Pt()); if (kstar < TriggerSelections.limits->get("Tight Limit", "PD")) { signalTightLimit[cf_trigger::kPD] += 1; registryTriggerQA.fill(HIST("PD/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PD/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PD/tight/fSE_particle"), kstar); - registryTriggerQA.fill(HIST("PD/tight/fProtonPtVskstar"), vecProton.at(p1).Pt(), kstar); - registryTriggerQA.fill(HIST("PD/tight/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("PD/tight/fProtonKstarVsPt"), kstar, vecProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PD/tight/fDeuteronKstarVsPt"), kstar, vecDeuteron.at(d1).Pt()); } } } @@ -2321,22 +2321,22 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("PD/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PD/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PD/all/fSE_antiparticle"), kstar); - registryTriggerQA.fill(HIST("PD/all/fAntiProtonPtVskstar"), vecAntiProton.at(p1).Pt(), kstar); - registryTriggerQA.fill(HIST("PD/all/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("PD/all/fAntiProtonKstarVsPt"), kstar, vecAntiProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PD/all/fAntiDeuteronKstarVsPt"), kstar, vecAntiDeuteron.at(d1).Pt()); if (kstar < TriggerSelections.limits->get("Loose Limit", "PD")) { signalLooseLimit[cf_trigger::kPD] += 1; registryTriggerQA.fill(HIST("PD/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PD/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PD/loose/fSE_antiparticle"), kstar); - registryTriggerQA.fill(HIST("PD/loose/fAntiProtonPtVskstar"), vecAntiProton.at(p1).Pt(), kstar); - registryTriggerQA.fill(HIST("PD/loose/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("PD/loose/fAntiProtonKstarVsPt"), kstar, vecAntiProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PD/loose/fAntiDeuteronKstarVsPt"), kstar, vecAntiDeuteron.at(d1).Pt()); if (kstar < TriggerSelections.limits->get("Tight Limit", "PD")) { signalTightLimit[cf_trigger::kPD] += 1; registryTriggerQA.fill(HIST("PD/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PD/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PD/tight/fSE_antiparticle"), kstar); - registryTriggerQA.fill(HIST("PD/tight/fAntiProtonPtVskstar"), vecAntiProton.at(p1).Pt(), kstar); - registryTriggerQA.fill(HIST("PD/tight/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("PD/tight/fAntiProtonKstarVsPt"), kstar, vecAntiProton.at(p1).Pt()); + registryTriggerQA.fill(HIST("PD/tight/fAntiDeuteronKstarVsPt"), kstar, vecAntiDeuteron.at(d1).Pt()); } } } @@ -2353,22 +2353,22 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("LD/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("LD/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("LD/all/fSE_particle"), kstar); - registryTriggerQA.fill(HIST("LD/all/fLambdaPtVskstar"), vecLambda.at(l1).Pt(), kstar); - registryTriggerQA.fill(HIST("LD/all/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("LD/all/fLambdaKstarVsPt"), kstar, vecLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("LD/all/fDeuteronKstarVsPt"), kstar, vecDeuteron.at(d1).Pt()); if (kstar < TriggerSelections.limits->get("Loose Limit", "LD")) { signalLooseLimit[cf_trigger::kLD] += 1; registryTriggerQA.fill(HIST("LD/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("LD/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("LD/loose/fSE_particle"), kstar); - registryTriggerQA.fill(HIST("LD/loose/fLambdaPtVskstar"), vecLambda.at(l1).Pt(), kstar); - registryTriggerQA.fill(HIST("LD/loose/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("LD/loose/fLambdaKstarVsPt"), kstar, vecLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("LD/loose/fDeuteronKstarVsPt"), kstar, vecDeuteron.at(d1).Pt()); if (kstar < TriggerSelections.limits->get("Tight Limit", "LD")) { signalTightLimit[cf_trigger::kLD] += 1; registryTriggerQA.fill(HIST("LD/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("LD/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("LD/tight/fSE_particle"), kstar); - registryTriggerQA.fill(HIST("LD/tight/fLambdaPtVskstar"), vecLambda.at(l1).Pt(), kstar); - registryTriggerQA.fill(HIST("LD/tight/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("LD/tight/fLambdaKstarVsPt"), kstar, vecLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("LD/tight/fDeuteronKstarVsPt"), kstar, vecDeuteron.at(d1).Pt()); } } } @@ -2382,22 +2382,22 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("LD/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("LD/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("LD/all/fSE_antiparticle"), kstar); - registryTriggerQA.fill(HIST("LD/all/fAntiLambdaPtVskstar"), vecAntiLambda.at(l1).Pt(), kstar); - registryTriggerQA.fill(HIST("LD/all/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("LD/all/fAntiLambdaKstarVsPt"), kstar, vecAntiLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("LD/all/fAntiDeuteronKstarVsPt"), kstar, vecAntiDeuteron.at(d1).Pt()); if (kstar < TriggerSelections.limits->get("Loose Limit", "LD")) { signalLooseLimit[cf_trigger::kLD] += 1; registryTriggerQA.fill(HIST("LD/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("LD/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("LD/loose/fSE_antiparticle"), kstar); - registryTriggerQA.fill(HIST("LD/loose/fAntiLambdaPtVskstar"), vecAntiLambda.at(l1).Pt(), kstar); - registryTriggerQA.fill(HIST("LD/loose/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("LD/loose/fAntiLambdaKstarVsPt"), kstar, vecAntiLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("LD/loose/fAntiDeuteronKstarVsPt"), kstar, vecAntiDeuteron.at(d1).Pt()); if (kstar < TriggerSelections.limits->get("Tight Limit", "LD")) { signalTightLimit[cf_trigger::kLD] += 1; registryTriggerQA.fill(HIST("LD/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("LD/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("LD/tight/fSE_antiparticle"), kstar); - registryTriggerQA.fill(HIST("LD/tight/fAntiLambdaPtVskstar"), vecAntiLambda.at(l1).Pt(), kstar); - registryTriggerQA.fill(HIST("LD/tight/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); + registryTriggerQA.fill(HIST("LD/tight/fAntiLambdaKstarVsPt"), kstar, vecAntiLambda.at(l1).Pt()); + registryTriggerQA.fill(HIST("LD/tight/fAntiDeuteronKstarVsPt"), kstar, vecAntiDeuteron.at(d1).Pt()); } } } @@ -2414,26 +2414,26 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("PhiD/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PhiD/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PhiD/all/fSE_particle"), kstar); - registryTriggerQA.fill(HIST("PhiD/all/fPhiPtVskstar"), vecPhi.at(phi1).Pt(), kstar); - registryTriggerQA.fill(HIST("PhiD/all/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); - registryTriggerQA.fill(HIST("PhiD/all/fPhiInvMassVskstar"), vecPhi.at(phi1).M(), kstar); + registryTriggerQA.fill(HIST("PhiD/all/fPhiKstarVsPt"), kstar, vecPhi.at(phi1).Pt()); + registryTriggerQA.fill(HIST("PhiD/all/fDeuteronKstarVsPt"), kstar, vecDeuteron.at(d1).Pt()); + registryTriggerQA.fill(HIST("PhiD/all/fPhiKstarVsInvMass"), kstar, vecPhi.at(phi1).M()); if (kstar < TriggerSelections.limits->get("Loose Limit", "PhiD")) { signalLooseLimit[cf_trigger::kPhiD] += 1; registryTriggerQA.fill(HIST("PhiD/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PhiD/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PhiD/loose/fSE_particle"), kstar); - registryTriggerQA.fill(HIST("PhiD/loose/fPhiPtVskstar"), vecPhi.at(phi1).Pt(), kstar); - registryTriggerQA.fill(HIST("PhiD/loose/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); - registryTriggerQA.fill(HIST("PhiD/loose/fPhiInvMassVskstar"), vecPhi.at(phi1).M(), kstar); + registryTriggerQA.fill(HIST("PhiD/loose/fPhiKstarVsPt"), kstar, vecPhi.at(phi1).Pt()); + registryTriggerQA.fill(HIST("PhiD/loose/fDeuteronKstarVsPt"), kstar, vecDeuteron.at(d1).Pt()); + registryTriggerQA.fill(HIST("PhiD/loose/fPhiKstarVsInvMass"), kstar, vecPhi.at(phi1).M()); if (kstar < TriggerSelections.limits->get("Tight Limit", "PhiD") && vecPhi.at(phi1).M() > PhiSelections.tightInvMassLow.value && vecPhi.at(phi1).M() < PhiSelections.tightInvMassUp.value) { signalTightLimit[cf_trigger::kPhiD] += 1; registryTriggerQA.fill(HIST("PhiD/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PhiD/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PhiD/tight/fSE_particle"), kstar); - registryTriggerQA.fill(HIST("PhiD/tight/fPhiPtVskstar"), vecPhi.at(phi1).Pt(), kstar); - registryTriggerQA.fill(HIST("PhiD/tight/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); - registryTriggerQA.fill(HIST("PhiD/tight/fPhiInvMassVskstar"), vecPhi.at(phi1).M(), kstar); + registryTriggerQA.fill(HIST("PhiD/tight/fPhiKstarVsPt"), kstar, vecPhi.at(phi1).Pt()); + registryTriggerQA.fill(HIST("PhiD/tight/fDeuteronKstarVsPt"), kstar, vecDeuteron.at(d1).Pt()); + registryTriggerQA.fill(HIST("PhiD/tight/fPhiKstarVsInvMass"), kstar, vecPhi.at(phi1).M()); } } } @@ -2447,26 +2447,26 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("PhiD/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PhiD/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PhiD/all/fSE_antiparticle"), kstar); - registryTriggerQA.fill(HIST("PhiD/all/fPhiPtVskstar"), vecPhi.at(phi1).Pt(), kstar); - registryTriggerQA.fill(HIST("PhiD/all/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); - registryTriggerQA.fill(HIST("PhiD/all/fPhiInvMassVskstar"), vecPhi.at(phi1).M(), kstar); + registryTriggerQA.fill(HIST("PhiD/all/fPhiKstarVsPt"), kstar, vecPhi.at(phi1).Pt()); + registryTriggerQA.fill(HIST("PhiD/all/fAntiDeuteronKstarVsPt"), kstar, vecAntiDeuteron.at(d1).Pt()); + registryTriggerQA.fill(HIST("PhiD/all/fPhiKstarVsInvMass"), kstar, vecPhi.at(phi1).M()); if (kstar < TriggerSelections.limits->get("Loose Limit", "PhiD")) { signalLooseLimit[cf_trigger::kPhiD] += 1; registryTriggerQA.fill(HIST("PhiD/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PhiD/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PhiD/loose/fSE_antiparticle"), kstar); - registryTriggerQA.fill(HIST("PhiD/loose/fPhiPtVskstar"), vecPhi.at(phi1).Pt(), kstar); - registryTriggerQA.fill(HIST("PhiD/loose/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); - registryTriggerQA.fill(HIST("PhiD/loose/fPhiInvMassVskstar"), vecPhi.at(phi1).M(), kstar); + registryTriggerQA.fill(HIST("PhiD/loose/fPhiKstarVsPt"), kstar, vecPhi.at(phi1).Pt()); + registryTriggerQA.fill(HIST("PhiD/loose/fAntiDeuteronKstarVsPt"), kstar, vecAntiDeuteron.at(d1).Pt()); + registryTriggerQA.fill(HIST("PhiD/loose/fPhiKstarVsInvMass"), kstar, vecPhi.at(phi1).M()); if (kstar < TriggerSelections.limits->get("Tight Limit", "PhiD") && vecPhi.at(phi1).M() > PhiSelections.tightInvMassLow.value && vecPhi.at(phi1).M() < PhiSelections.tightInvMassUp.value) { signalTightLimit[cf_trigger::kPhiD] += 1; registryTriggerQA.fill(HIST("PhiD/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("PhiD/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("PhiD/tight/fSE_antiparticle"), kstar); - registryTriggerQA.fill(HIST("PhiD/tight/fPhiPtVskstar"), vecPhi.at(phi1).Pt(), kstar); - registryTriggerQA.fill(HIST("PhiD/tight/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); - registryTriggerQA.fill(HIST("PhiD/tight/fPhiInvMassVskstar"), vecPhi.at(phi1).M(), kstar); + registryTriggerQA.fill(HIST("PhiD/tight/fPhiKstarVsPt"), kstar, vecPhi.at(phi1).Pt()); + registryTriggerQA.fill(HIST("PhiD/tight/fAntiDeuteronKstarVsPt"), kstar, vecAntiDeuteron.at(d1).Pt()); + registryTriggerQA.fill(HIST("PhiD/tight/fPhiKstarVsInvMass"), kstar, vecPhi.at(phi1).M()); } } } @@ -2483,26 +2483,26 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("RhoD/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("RhoD/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("RhoD/all/fSE_particle"), kstar); - registryTriggerQA.fill(HIST("RhoD/all/fRhoPtVskstar"), vecRho.at(r1).Pt(), kstar); - registryTriggerQA.fill(HIST("RhoD/all/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); - registryTriggerQA.fill(HIST("RhoD/all/fRhoInvMassVskstar"), vecRho.at(r1).M(), kstar); + registryTriggerQA.fill(HIST("RhoD/all/fRhoKstarVsPt"), kstar, vecRho.at(r1).Pt()); + registryTriggerQA.fill(HIST("RhoD/all/fDeuteronKstarVsPt"), kstar, vecDeuteron.at(d1).Pt()); + registryTriggerQA.fill(HIST("RhoD/all/fRhoKstarVsInvMass"), kstar, vecRho.at(r1).M()); if (kstar < TriggerSelections.limits->get("Loose Limit", "RhoD")) { signalLooseLimit[cf_trigger::kRhoD] += 1; registryTriggerQA.fill(HIST("RhoD/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("RhoD/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("RhoD/loose/fSE_particle"), kstar); - registryTriggerQA.fill(HIST("RhoD/loose/fRhoPtVskstar"), vecRho.at(r1).Pt(), kstar); - registryTriggerQA.fill(HIST("RhoD/loose/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); - registryTriggerQA.fill(HIST("RhoD/loose/fRhoInvMassVskstar"), vecRho.at(r1).M(), kstar); + registryTriggerQA.fill(HIST("RhoD/loose/fRhoKstarVsPt"), kstar, vecRho.at(r1).Pt()); + registryTriggerQA.fill(HIST("RhoD/loose/fDeuteronKstarVsPt"), kstar, vecDeuteron.at(d1).Pt()); + registryTriggerQA.fill(HIST("RhoD/loose/fRhoKstarVsInvMass"), kstar, vecRho.at(r1).M()); if (kstar < TriggerSelections.limits->get("Tight Limit", "RhoD") && vecRho.at(r1).M() > RhoSelections.tightInvMassLow.value && vecRho.at(r1).M() < RhoSelections.tightInvMassUp.value) { signalTightLimit[cf_trigger::kRhoD] += 1; registryTriggerQA.fill(HIST("RhoD/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("RhoD/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("RhoD/tight/fSE_particle"), kstar); - registryTriggerQA.fill(HIST("RhoD/tight/fRhoPtVskstar"), vecRho.at(r1).Pt(), kstar); - registryTriggerQA.fill(HIST("RhoD/tight/fDeuteronPtVskstar"), vecDeuteron.at(d1).Pt(), kstar); - registryTriggerQA.fill(HIST("RhoD/tight/fRhoInvMassVskstar"), vecRho.at(r1).M(), kstar); + registryTriggerQA.fill(HIST("RhoD/tight/fRhoKstarVsPt"), kstar, vecRho.at(r1).Pt()); + registryTriggerQA.fill(HIST("RhoD/tight/fDeuteronKstarVsPt"), kstar, vecDeuteron.at(d1).Pt()); + registryTriggerQA.fill(HIST("RhoD/tight/fRhoKstarVsInvMass"), kstar, vecRho.at(r1).M()); } } } @@ -2516,26 +2516,26 @@ struct CFFilterAll { registryTriggerQA.fill(HIST("RhoD/all/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("RhoD/all/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("RhoD/all/fSE_antiparticle"), kstar); - registryTriggerQA.fill(HIST("RhoD/all/fRhoPtVskstar"), vecRho.at(r1).Pt(), kstar); - registryTriggerQA.fill(HIST("RhoD/all/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); - registryTriggerQA.fill(HIST("RhoD/all/fRhoInvMassVskstar"), vecRho.at(r1).M(), kstar); + registryTriggerQA.fill(HIST("RhoD/all/fRhoKstarVsPt"), kstar, vecRho.at(r1).Pt()); + registryTriggerQA.fill(HIST("RhoD/all/fAntiDeuteronKstarVsPt"), kstar, vecAntiDeuteron.at(d1).Pt()); + registryTriggerQA.fill(HIST("RhoD/all/fRhoKstarVsInvMass"), kstar, vecRho.at(r1).M()); if (kstar < TriggerSelections.limits->get("Loose Limit", "RhoD")) { signalLooseLimit[cf_trigger::kRhoD] += 1; registryTriggerQA.fill(HIST("RhoD/loose/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("RhoD/loose/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("RhoD/loose/fSE_antiparticle"), kstar); - registryTriggerQA.fill(HIST("RhoD/loose/fRhoPtVskstar"), vecRho.at(r1).Pt(), kstar); - registryTriggerQA.fill(HIST("RhoD/loose/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); - registryTriggerQA.fill(HIST("RhoD/loose/fRhoInvMassVskstar"), vecRho.at(r1).M(), kstar); + registryTriggerQA.fill(HIST("RhoD/loose/fRhoKstarVsPt"), kstar, vecRho.at(r1).Pt()); + registryTriggerQA.fill(HIST("RhoD/loose/fAntiDeuteronKstarVsPt"), kstar, vecAntiDeuteron.at(d1).Pt()); + registryTriggerQA.fill(HIST("RhoD/loose/fRhoKstarVsInvMass"), kstar, vecRho.at(r1).M()); if (kstar < TriggerSelections.limits->get("Tight Limit", "RhoD") && vecRho.at(r1).M() > RhoSelections.tightInvMassLow.value && vecRho.at(r1).M() < RhoSelections.tightInvMassUp.value) { signalTightLimit[cf_trigger::kRhoD] += 1; registryTriggerQA.fill(HIST("RhoD/tight/fMultiplicity"), col.multNTracksPV()); registryTriggerQA.fill(HIST("RhoD/tight/fZvtx"), col.posZ()); registryTriggerQA.fill(HIST("RhoD/tight/fSE_antiparticle"), kstar); - registryTriggerQA.fill(HIST("RhoD/tight/fRhoPtVskstar"), vecRho.at(r1).Pt(), kstar); - registryTriggerQA.fill(HIST("RhoD/tight/fAntiDeuteronPtVskstar"), vecAntiDeuteron.at(d1).Pt(), kstar); - registryTriggerQA.fill(HIST("RhoD/tight/fRhoInvMassVskstar"), vecRho.at(r1).M(), kstar); + registryTriggerQA.fill(HIST("RhoD/tight/fRhoKstarVsPt"), kstar, vecRho.at(r1).Pt()); + registryTriggerQA.fill(HIST("RhoD/tight/fAntiDeuteronKstarVsPt"), kstar, vecAntiDeuteron.at(d1).Pt()); + registryTriggerQA.fill(HIST("RhoD/tight/fRhoKstarVsInvMass"), kstar, vecRho.at(r1).M()); } } } diff --git a/EventFiltering/macros/getMenu.C b/EventFiltering/macros/getMenu.C new file mode 100644 index 00000000000..692ebe396f3 --- /dev/null +++ b/EventFiltering/macros/getMenu.C @@ -0,0 +1,31 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "CCDB/BasicCCDBManager.h" + +#include +#include + +#include + +void getMenu(int runNumber, std::string baseCCDBPath = "Users/m/mpuccio/EventFiltering/OTS/Chunked/") +{ + auto& ccdb = o2::ccdb::BasicCCDBManager::instance(); + TH1* counters = ccdb.getForRun(baseCCDBPath + "FilterCounters", runNumber); + TAxis* axis = counters->GetXaxis(); + + std::vector binLabels(axis->GetNbins() - 2); // skip first and last bins + std::cout << "Menu for run " << runNumber << ":\n"; + for (int i = 2; i < axis->GetNbins(); ++i) { + binLabels[i - 1] = axis->GetBinLabel(i); + std::cout << "Id " << i - 2 << ": " << axis->GetBinLabel(i) << "\n"; + } +} diff --git a/PWGCF/EbyEFluctuations/Tasks/netchargeFluctuations.cxx b/PWGCF/EbyEFluctuations/Tasks/netchargeFluctuations.cxx index b927b083066..0d19d9a48ba 100644 --- a/PWGCF/EbyEFluctuations/Tasks/netchargeFluctuations.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/netchargeFluctuations.cxx @@ -9,94 +9,634 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -// author Nida Malik (nida.malik@cern.ch) -// Department of Physics, Aligarh Muslim University, India -// to study the net charge fluctuations by observable, #nu_dyn +/// \file netchargeFluctuations.cxx +/// \brief Calculate net-charge fluctuations using nu_dyn observable +/// For charged particles +/// For RUN-3 +/// +/// \author Nida Malik +#include "PWGCF/Core/CorrelationContainer.h" +#include "PWGCF/Core/PairCuts.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/FT0Corrected.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/Centrality.h" -#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "CommonConstants/MathConstants.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" + +#include "TProfile.h" +#include "TProfile2D.h" +#include "TRandom3.h" + +#include // Include for std::vector + using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using namespace std; +using namespace o2::constants::physics; + +namespace o2 +{ +namespace aod +{ +namespace net_charge +{ +DECLARE_SOA_COLUMN(PosCharge, posCharge, float); +DECLARE_SOA_COLUMN(NegCharge, negCharge, float); +DECLARE_SOA_COLUMN(PosSqCharge, posSqCharge, float); +DECLARE_SOA_COLUMN(NegSqCharge, negSqCharge, float); +DECLARE_SOA_COLUMN(TermPCharge, termPCharge, float); +DECLARE_SOA_COLUMN(TermNCharge, termNCharge, float); +DECLARE_SOA_COLUMN(PosNegCharge, posNegCharge, float); +DECLARE_SOA_COLUMN(Centrality, centrality, float); +} // namespace net_charge -namespace o2::aod +namespace net_charge_gen { -using MyCollisions = soa::Join; -using MyCollision = MyCollisions::iterator; +DECLARE_SOA_COLUMN(PosCharge, posCharge, float); +DECLARE_SOA_COLUMN(NegCharge, negCharge, float); +DECLARE_SOA_COLUMN(PosSqCharge, posSqCharge, float); +DECLARE_SOA_COLUMN(NegSqCharge, negSqCharge, float); +DECLARE_SOA_COLUMN(TermPCharge, termPCharge, float); +DECLARE_SOA_COLUMN(TermNCharge, termNCharge, float); +DECLARE_SOA_COLUMN(PosNegCharge, posNegCharge, float); +DECLARE_SOA_COLUMN(Centrality, centrality, float); +} // namespace net_charge_gen -using MyTracks = soa::Join; +DECLARE_SOA_TABLE(NetCharge, "AOD", "NETChargefluct", + net_charge::PosCharge, + net_charge::NegCharge, + net_charge::PosSqCharge, + net_charge::NegSqCharge, + net_charge::TermPCharge, + net_charge::TermNCharge, + net_charge::PosNegCharge, + net_charge::Centrality); + +DECLARE_SOA_TABLE(NetChargeGen, "AOD", "NETfluctGen", + net_charge_gen::PosCharge, + net_charge_gen::NegCharge, + net_charge_gen::PosSqCharge, + net_charge_gen::NegSqCharge, + net_charge_gen::TermPCharge, + net_charge_gen::TermNCharge, + net_charge_gen::PosNegCharge, + net_charge_gen::Centrality); + +using MyCollisionsRun2 = soa::Join; +using MyCollisionRun2 = MyCollisionsRun2::iterator; +using MyCollisionsRun3 = soa::Join; +using MyCollisionRun3 = MyCollisionsRun3::iterator; +using MyTracks = soa::Join; using MyTrack = MyTracks::iterator; -} // namespace o2::aod + +using MyMCCollisionsRun2 = soa::Join; +using MyMCCollisionRun2 = MyMCCollisionsRun2::iterator; + +using MyMCCollisionsRun3 = soa::Join; +using MyMCCollisionRun3 = MyMCCollisionsRun3::iterator; + +using MyMCTracks = soa::Join; +using MyMCTrack = MyMCTracks::iterator; +} // namespace aod +} // namespace o2 + +enum RunType { + kRun3 = 0, + kRun2 +}; struct NetchargeFluctuations { - HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + Produces netCharge; + Produces netChargeGen; + Service pdgService; + + HistogramRegistry histogramRegistry{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // Configurables + Configurable vertexZcut{"vertexZcut", 10.f, "Vertex Z"}; + Configurable etaCut{"etaCut", 0.8, "Eta cut"}; + Configurable ptMinCut{"ptMinCut", 0.2, "Pt min cut"}; + Configurable ptMaxCut{"ptMaxCut", 5.0, "Pt max cut"}; + Configurable dcaXYCut{"dcaXYCut", 0.12, "DCA XY cut"}; + Configurable dcaZCut{"dcaZCut", 0.3, "DCA Z cut"}; + Configurable tpcCrossCut{"tpcCrossCut", 70, "TPC crossrows cut"}; + Configurable itsChiCut{"itsChiCut", 70, "ITS chi2 cluster cut"}; + Configurable tpcChiCut{"tpcChiCut", 70, "TPC chi2 cluster cut"}; + + // Event selections + Configurable cSel8Trig{"cSel8Trig", true, "Sel8 (T0A + T0C) Selection Run3"}; // sel8 + Configurable cInt7Trig{"cInt7Trig", true, "kINT7 MB Trigger"}; // kINT7 + Configurable cSel7Trig{"cSel7Trig", true, "Sel7 (V0A + V0C) Selection Run2"}; // sel7 + Configurable cTFBorder{"cTFBorder", false, "Timeframe Border Selection"}; // pileup + Configurable cNoItsROBorder{"cNoItsROBorder", false, "No ITSRO Border Cut"}; // pileup + Configurable cItsTpcVtx{"cItsTpcVtx", false, "ITS+TPC Vertex Selection"}; // pileup + Configurable cPileupReject{"cPileupReject", false, "Pileup rejection"}; // pileup + Configurable cZVtxTimeDiff{"cZVtxTimeDiff", false, "z-vtx time diff selection"}; // pileup + Configurable cIsGoodITSLayers{"cIsGoodITSLayers", false, "Good ITS Layers All"}; // pileup + + // Initialization + float cent = 0.; + float mult = 0.; void init(o2::framework::InitContext&) { - AxisSpec vtxZAxis = {100, -20, 20, "Z (cm)"}; - AxisSpec dcaAxis = {1000, -100, 100, "DCA_{xy} (cm)"}; - AxisSpec dcazAxis = {1000, -100, 100, "DCA_{z} (cm)"}; - AxisSpec ptAxis = {40, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec etaAxis = {30, -1.5, 1.5, "#eta"}; - AxisSpec centAxis = {100, 0., 100., "centrality"}; - AxisSpec multAxis = {2000, 0., 2000., "multiplicity"}; - - histos.add("hVertexZ_bef", "", kTH1F, {vtxZAxis}); - histos.add("hVertexZ_aft", "", kTH1F, {vtxZAxis}); - histos.add("hVertexZ_aft_sel", "", kTH1D, {vtxZAxis}); - histos.add("hDCAxy_bef", "", kTH1D, {dcaAxis}); - histos.add("hDCAxy_aft", "", kTH1D, {dcaAxis}); - histos.add("hDCAz_bef", "", kTH1D, {dcazAxis}); - histos.add("hDCAz_aft", "", kTH1D, {dcazAxis}); - histos.add("hCentrality", "", kTH1D, {centAxis}); - histos.add("hMultiplicity", "", kTH1D, {multAxis}); - histos.add("hEta", "", kTH1F, {etaAxis}); - histos.add("hPt", "", kTH1F, {ptAxis}); + const AxisSpec vtxzAxis = {80, -20, 20, "V_{Z} (cm)"}; + const AxisSpec dcaAxis = {250, -0.5, 0.5, "DCA_{xy} (cm)"}; + const AxisSpec dcazAxis = {250, -0.5, 0.5, "DCA_{z} (cm)"}; + const AxisSpec ptAxis = {70, 0.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec etaAxis = {20, -1., 1., "#eta"}; + const AxisSpec centAxis = {100, 0., 100., "centrality"}; + const AxisSpec multAxis = {200, 0., 10000., "FT0M Amplitude"}; + const AxisSpec tpcChiAxis = {140, 0., 7., "Chi2"}; + const AxisSpec itsChiAxis = {80, 0., 40., "Chi2"}; + const AxisSpec crossedRowAxis = {160, 0., 160., "TPC Crossed rows"}; + const AxisSpec eventsAxis = {10, 0, 10, ""}; + const AxisSpec signAxis = {20, -10, 10, ""}; + + histogramRegistry.add("hVtxZ_before", "", kTH1F, {vtxzAxis}); + histogramRegistry.add("hDcaXY_before", "", kTH1F, {dcaAxis}); + histogramRegistry.add("hDcaZ_before", "", kTH1F, {dcazAxis}); + histogramRegistry.add("hTPCchi2perCluster_before", "", kTH1D, {tpcChiAxis}); + histogramRegistry.add("hITSchi2perCluster_before", "", kTH1D, {itsChiAxis}); + histogramRegistry.add("hTPCCrossedrows_before", "", kTH1D, {crossedRowAxis}); + histogramRegistry.add("hPtDcaXY_before", "", kTH2D, {ptAxis, dcaAxis}); + histogramRegistry.add("hPtDcaZ_before", "", kTH2D, {ptAxis, dcazAxis}); + histogramRegistry.add("hVtxZ_after", "", kTH1F, {vtxzAxis}); + histogramRegistry.add("hDcaXY_after", "", kTH1F, {dcaAxis}); + histogramRegistry.add("hDcaZ_after", "", kTH1F, {dcazAxis}); + histogramRegistry.add("hTPCchi2perCluster_after", "", kTH1D, {tpcChiAxis}); + histogramRegistry.add("hITSchi2perCluster_after", "", kTH1D, {itsChiAxis}); + histogramRegistry.add("hTPCCrossedrows_after", "", kTH1D, {crossedRowAxis}); + histogramRegistry.add("hPtDcaXY_after", "", kTH2D, {ptAxis, dcaAxis}); + histogramRegistry.add("hPtDcaZ_after", "", kTH2D, {ptAxis, dcazAxis}); + histogramRegistry.add("hEta", "", kTH1F, {etaAxis}); + histogramRegistry.add("hPt", "", kTH1F, {ptAxis}); + histogramRegistry.add("hCentrality", "", kTH1F, {centAxis}); + histogramRegistry.add("hMultiplicity", "", kTH1F, {multAxis}); + histogramRegistry.add("rec_hVtxZ_before", "", kTH1F, {vtxzAxis}); + histogramRegistry.add("gen_hVtxZ_before", "", kTH1F, {vtxzAxis}); + histogramRegistry.add("rec_hDcaXY_before", "", kTH1D, {dcaAxis}); + histogramRegistry.add("rec_hDcaZ_before", "", kTH1D, {dcazAxis}); + histogramRegistry.add("rec_hTPCchi2perCluster_before", "TPC #Chi^{2}/Cluster", kTH1D, {tpcChiAxis}); + histogramRegistry.add("rec_hITSchi2perCluster_before", "ITS #Chi^{2}/Cluster", kTH1D, {itsChiAxis}); + histogramRegistry.add("rec_hTPCCrossedrows_before", "Crossed TPC rows", kTH1D, {crossedRowAxis}); + histogramRegistry.add("rec_hVtxZ_after", "", kTH1F, {vtxzAxis}); + histogramRegistry.add("gen_hVtxZ_after", "", kTH1F, {vtxzAxis}); + histogramRegistry.add("rec_hDcaXY_after", "", kTH1D, {dcaAxis}); + histogramRegistry.add("rec_hDcaZ_after", "", kTH1D, {dcazAxis}); + histogramRegistry.add("rec_hTPCchi2perCluster_after", "TPC #Chi^{2}/Cluster", kTH1D, {tpcChiAxis}); + histogramRegistry.add("rec_hITSchi2perCluster_after", "ITS #Chi^{2}/Cluster", kTH1D, {itsChiAxis}); + histogramRegistry.add("rec_hTPCCrossedrows_after", "Crossed TPC rows", kTH1D, {crossedRowAxis}); + histogramRegistry.add("gen_hEta", "", kTH1F, {etaAxis}); + histogramRegistry.add("rec_hEta", "", kTH1F, {etaAxis}); + histogramRegistry.add("gen_hSign", "", kTH1F, {signAxis}); + histogramRegistry.add("gen_hPt", "", kTH1F, {ptAxis}); + histogramRegistry.add("rec_hPt", "", kTH1F, {ptAxis}); + histogramRegistry.add("rec_hPtDcaXY_after", "hPtDCAxy", kTH2D, {ptAxis, dcaAxis}); + histogramRegistry.add("rec_hPtDcaZ_after", "hPtDCAz", kTH2D, {ptAxis, dcazAxis}); + histogramRegistry.add("rec_hCentrality", "", kTH1D, {centAxis}); + histogramRegistry.add("gen_hCentrality", "", kTH1D, {centAxis}); + histogramRegistry.add("rec_hMultiplicity", "", kTH1D, {multAxis}); + histogramRegistry.add("gen_hMultiplicity", "", kTH1D, {multAxis}); } - void process(aod::MyCollision const& coll, aod::MyTracks const& inputTracks) + template + bool selCollision(C const& coll) { - histos.fill(HIST("hVertexZ_bef"), coll.posZ()); + if (std::abs(coll.posZ()) > vertexZcut) { + return false; + } // Reject the collisions with large vertex-z - if (std::fabs(coll.posZ()) > 10.f) { - return; + if constexpr (run == kRun3) { + + if (cSel8Trig && !coll.sel8()) { + return false; + } // require min bias trigger + cent = coll.centFT0M(); // centrality for run3 + mult = coll.multFT0M(); // multiplicity for run3 + } else { + if (cInt7Trig && !coll.alias_bit(kINT7)) { + return false; + } + if (cSel7Trig && !coll.sel7()) { + return false; + } + cent = coll.centRun2V0M(); // centrality for run2 + mult = coll.multFV0M(); // multiplicity for run2 + } + + if (cNoItsROBorder && !coll.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + return false; + } + + if (cTFBorder && !coll.selection_bit(aod::evsel::kNoTimeFrameBorder)) { + return false; + } + + if (cPileupReject && !coll.selection_bit(aod::evsel::kNoSameBunchPileup)) { + return false; } - histos.fill(HIST("hVertexZ_aft"), coll.posZ()); - if (!coll.sel7()) { + if (cZVtxTimeDiff && !coll.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { + return false; + } + + if (cItsTpcVtx && !coll.selection_bit(aod::evsel::kIsVertexITSTPC)) { + return false; + } + + return true; // if all checks pass, accept the collision + } + + template + bool selTrack(T const& track) + { + if (!track.isGlobalTrack()) { + return false; + } // accept only global tracks + + if (std::fabs(track.dcaXY()) > dcaXYCut) { + return false; + } + + if (std::fabs(track.dcaZ()) > dcaZCut) { + return false; + } + + if (std::fabs(track.eta()) >= etaCut) { + return false; + } + + if (track.pt() <= ptMinCut || track.pt() >= ptMaxCut) { + return false; + } + + if (track.tpcNClsCrossedRows() < tpcCrossCut) { + return false; + } + + if (track.itsChi2NCl() > itsChiCut) { + return false; + } + + if (track.tpcChi2NCl() > tpcChiCut) { + return false; + } + + return true; // if all checks pass, accept the collision + } + + template + void calculation(C const& coll, T const& tracks) + { + histogramRegistry.fill(HIST("hVtxZ_before"), coll.posZ()); + + if (!selCollision(coll)) { return; } - histos.fill(HIST("hVertexZ_aft_sel"), coll.posZ()); - histos.fill(HIST("hCentrality"), coll.centRun2V0M()); - histos.fill(HIST("hMultiplicity"), coll.multFV0M()); - for (auto const& track : inputTracks) { - if (std::fabs(track.eta()) > 0.8) + histogramRegistry.fill(HIST("hVtxZ_after"), coll.posZ()); + histogramRegistry.fill(HIST("hCentrality"), cent); + histogramRegistry.fill(HIST("hMultiplicity"), mult); + + int fpos = 0, fneg = 0, posneg = 0, termn = 0, termp = 0; + + for (const auto& track : tracks) { + histogramRegistry.fill(HIST("hTPCchi2perCluster_before"), track.tpcChi2NCl()); + histogramRegistry.fill(HIST("hITSchi2perCluster_before"), track.itsChi2NCl()); + histogramRegistry.fill(HIST("hTPCCrossedrows_before"), track.tpcNClsCrossedRows()); + histogramRegistry.fill(HIST("hDcaXY_before"), track.dcaXY()); + histogramRegistry.fill(HIST("hDcaZ_before"), track.dcaZ()); + histogramRegistry.fill(HIST("hPtDcaXY_before"), track.pt(), track.dcaXY()); + histogramRegistry.fill(HIST("hPtDcaZ_before"), track.pt(), track.dcaZ()); + + if (!selTrack(track)) { continue; - if (!(track.pt() > 0.2 && track.pt() < 2.)) + } + if (track.sign() == 0) continue; + histogramRegistry.fill(HIST("hDcaXY_after"), track.dcaXY()); + histogramRegistry.fill(HIST("hDcaZ_after"), track.dcaZ()); + histogramRegistry.fill(HIST("hPt"), track.pt()); + histogramRegistry.fill(HIST("hEta"), track.eta()); + histogramRegistry.fill(HIST("hPtDcaXY_after"), track.pt(), track.dcaXY()); + histogramRegistry.fill(HIST("hPtDcaZ_after"), track.pt(), track.dcaZ()); + histogramRegistry.fill(HIST("hTPCCrossedrows_after"), track.tpcNClsCrossedRows()); + histogramRegistry.fill(HIST("hTPCchi2perCluster_after"), track.tpcChi2NCl()); + histogramRegistry.fill(HIST("hITSchi2perCluster_after"), track.itsChi2NCl()); + + if (track.sign() == 1) { + fpos += 1; + termp = fpos * (fpos - 1); + } + + if (track.sign() == -1) { + fneg += 1; + termn = fneg * (fneg - 1); + } + + posneg = fpos * fneg; + netCharge(fpos, fneg, fpos * fpos, fneg * fneg, termp, termn, posneg, cent); + } // tracks + + return; + } + + template + void histosMcRecoGen(C const& coll, T const& inputTracks, M const& mcCollisions, P const& mcParticles) + { + (void)mcCollisions; + if (!coll.has_mcCollision()) { + return; + } + + histogramRegistry.fill(HIST("gen_hVtxZ_before"), coll.mcCollision().posZ()); + histogramRegistry.fill(HIST("rec_hVtxZ_before"), coll.posZ()); + + if (cNoItsROBorder && !coll.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + return; + } + if (cTFBorder && !coll.selection_bit(aod::evsel::kNoTimeFrameBorder)) { + return; + } + if (cPileupReject && !coll.selection_bit(aod::evsel::kNoSameBunchPileup)) { + return; + } + if (cZVtxTimeDiff && !coll.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { + return; + } + if (cItsTpcVtx && !coll.selection_bit(aod::evsel::kIsVertexITSTPC)) { + return; + } + + if (std::abs(coll.posZ()) > vertexZcut) { + return; + } + + if constexpr (run == kRun3) { + if (cSel8Trig && !coll.sel8()) { + return; + } - histos.fill(HIST("hDCAxy_bef"), track.dcaXY()); - histos.fill(HIST("hDCAz_bef"), track.dcaZ()); + cent = coll.centFT0M(); // centrality for run3 + mult = coll.multFT0M(); + } else { + if (cSel7Trig && !coll.sel7()) { + return; + } + cent = coll.centRun2V0M(); // centrality for run2 + mult = coll.multFV0M(); // multiplicity for run2 + } + + histogramRegistry.fill(HIST("rec_hVtxZ_after"), coll.posZ()); + histogramRegistry.fill(HIST("rec_hCentrality"), cent); + histogramRegistry.fill(HIST("rec_hMultiplicity"), mult); + + int posRec = 0, negRec = 0, posNegRec = 0, termNRec = 0, termPRec = 0; + int posGen = 0, negGen = 0, posNegGen = 0, termNGen = 0, termPGen = 0; + + const auto& mccolgen = coll.template mcCollision_as(); + if (std::abs(mccolgen.posZ()) > vertexZcut) { + return; + } + + const auto& mcpartgen = mcParticles.sliceByCached(aod::mcparticle::mcCollisionId, mccolgen.globalIndex(), cache); + histogramRegistry.fill(HIST("gen_hVtxZ_after"), mccolgen.posZ()); + + for (const auto& track : inputTracks) { if (!track.isGlobalTrack()) continue; + if (std::fabs(track.dcaXY()) > dcaXYCut) + continue; + if (std::fabs(track.dcaZ()) > dcaZCut) + continue; + if (std::fabs(track.eta()) > etaCut) + continue; + if ((track.pt() <= ptMinCut) || (track.pt() >= ptMaxCut)) + continue; + if (track.sign() == 0) { + continue; + } - histos.fill(HIST("hDCAxy_aft"), track.dcaXY()); - histos.fill(HIST("hDCAz_aft"), track.dcaZ()); - histos.fill(HIST("hPt"), track.pt()); - histos.fill(HIST("hEta"), track.eta()); - } + histogramRegistry.fill(HIST("rec_hPt"), track.pt()); + histogramRegistry.fill(HIST("rec_hEta"), track.eta()); + + if (track.sign() == 1) { + posRec += 1; + termPRec = posRec * (posRec - 1); + } + + if (track.sign() == -1) { + negRec += 1; + termNRec = negRec * (negRec - 1); + } + + posNegRec = posRec * negRec; + + netCharge(posRec, negRec, posRec * posRec, negRec * negRec, + termPRec, termNRec, posNegRec, cent); + } // loop over inputTracks (reco) + + for (const auto& mcpart : mcpartgen) { + if (!mcpart.isPhysicalPrimary()) { + continue; + } + int pid = mcpart.pdgCode(); + auto sign = 0; + auto* pd = pdgService->GetParticle(pid); + if (pd != nullptr) { + sign = pd->Charge() / 3.; + } + if (sign == 0) { + continue; + } + // auto pdgServicecode = mcpart.pdgCode(); + if (std::abs(pid) != kElectron && std::abs(pid) != kMuonMinus && std::abs(pid) != kPiPlus && std::abs(pid) != kKPlus && std::abs(pid) != kProton) { + continue; + } + + if (std::fabs(mcpart.eta()) > etaCut) + continue; + if ((mcpart.pt() <= ptMinCut) || (mcpart.pt() >= ptMaxCut)) + continue; + histogramRegistry.fill(HIST("gen_hPt"), mcpart.pt()); + histogramRegistry.fill(HIST("gen_hEta"), mcpart.eta()); + histogramRegistry.fill(HIST("gen_hSign"), sign); + + if (sign == 1) { + posGen += 1; + termPGen = posGen * (posGen - 1); + } + + if (sign == -1) { + negGen += 1; + termNGen = negGen * (negGen - 1); + } + + posNegGen = posGen * negGen; + + netChargeGen(posGen, negGen, posGen * posGen, negGen * negGen, + termPGen, termNGen, posNegGen, cent); + + } // particle + } // void + + SliceCache cache; + Preslice mcTrack = o2::aod::mcparticle::mcCollisionId; + + void processDataRun3(aod::MyCollisionRun3 const& coll, aod::MyTracks const& tracks) + { + calculation(coll, tracks); } -}; + + PROCESS_SWITCH(NetchargeFluctuations, processDataRun3, "Process for Run3 DATA", false); + + void processDataRun2(aod::MyCollisionRun2 const& coll, aod::MyTracks const& tracks) + { + calculation(coll, tracks); + } + + PROCESS_SWITCH(NetchargeFluctuations, processDataRun2, "Process for Run2 DATA", false); + + void processMcRun3(aod::MyMCCollisionRun3 const& coll, aod::MyMCTracks const& inputTracks, + aod::McCollisions const& mcCollisions, aod::McParticles const& mcParticles) + { + histosMcRecoGen(coll, inputTracks, mcCollisions, mcParticles); + } + + PROCESS_SWITCH(NetchargeFluctuations, processMcRun3, "Process reconstructed", true); + + void processMcRun2(aod::MyMCCollisionRun2 const& coll, aod::MyMCTracks const& inputTracks, + aod::McCollisions const& mcCollisions, aod::McParticles const& mcParticles) + { + histosMcRecoGen(coll, inputTracks, mcCollisions, mcParticles); + } + + PROCESS_SWITCH(NetchargeFluctuations, processMcRun2, "Process reconstructed", false); + +}; // struct + +struct NetchargeAnalysis { + Configurable cfSubSample{"cfSubSample", 30, "Number of subsamples"}; + HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; + std::vector>> net; + std::vector>> subSample; + std::vector>> genSubSample; + TRandom3* fRndm = new TRandom3(0); + + void init(o2::framework::InitContext&) + { + std::vector centBinning = {0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; + AxisSpec centAxis = {centBinning, "centrality"}; + + registry.add("data/pos_vs_cent", "", {HistType::kTProfile, {centAxis}}); + registry.add("data/neg_vs_cent", "", {HistType::kTProfile, {centAxis}}); + registry.add("data/termp_vs_cent", "", {HistType::kTProfile, {centAxis}}); + registry.add("data/termn_vs_cent", "", {HistType::kTProfile, {centAxis}}); + registry.add("data/pos_sq_vs_cent", "", {HistType::kTProfile, {centAxis}}); + registry.add("data/neg_sq_vs_cent", "", {HistType::kTProfile, {centAxis}}); + registry.add("data/posneg_vs_cent", "", {HistType::kTProfile, {centAxis}}); + + registry.add("gen/pos_vs_cent", "", {HistType::kTProfile, {centAxis}}); + registry.add("gen/neg_vs_cent", "", {HistType::kTProfile, {centAxis}}); + registry.add("gen/termp_vs_cent", "", {HistType::kTProfile, {centAxis}}); + registry.add("gen/termn_vs_cent", "", {HistType::kTProfile, {centAxis}}); + registry.add("gen/pos_sq_vs_cent", "", {HistType::kTProfile, {centAxis}}); + registry.add("gen/neg_sq_vs_cent", "", {HistType::kTProfile, {centAxis}}); + registry.add("gen/posneg_vs_cent", "", {HistType::kTProfile, {centAxis}}); + + subSample.resize(cfSubSample); + genSubSample.resize(cfSubSample); + + for (int i = 0; i < cfSubSample; ++i) { + subSample[i].resize(7); + genSubSample[i].resize(7); + + subSample[i][0] = std::get>(registry.add(Form("data/subSample_%d/pos_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); + subSample[i][1] = std::get>(registry.add(Form("data/subSample_%d/neg_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); + subSample[i][2] = std::get>(registry.add(Form("data/subSample_%d/termp_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); + subSample[i][3] = std::get>(registry.add(Form("data/subSample_%d/termn_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); + subSample[i][4] = std::get>(registry.add(Form("data/subSample_%d/pos_sq_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); + subSample[i][5] = std::get>(registry.add(Form("data/subSample_%d/neg_sq_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); + subSample[i][6] = std::get>(registry.add(Form("data/subSample_%d/posneg_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); + + genSubSample[i][0] = std::get>(registry.add(Form("gen/genSubSample_%d/pos_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); + genSubSample[i][1] = std::get>(registry.add(Form("gen/genSubSample_%d/neg_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); + genSubSample[i][2] = std::get>(registry.add(Form("gen/genSubSample_%d/termp_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); + genSubSample[i][3] = std::get>(registry.add(Form("gen/genSubSample_%d/termn_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); + genSubSample[i][4] = std::get>(registry.add(Form("gen/genSubSample_%d/pos_sq_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); + genSubSample[i][5] = std::get>(registry.add(Form("gen/genSubSample_%d/neg_sq_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); + genSubSample[i][6] = std::get>(registry.add(Form("gen/genSubSample_%d/posneg_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); + } + + } // void + + void processData(aod::NetCharge::iterator const& event_netcharge) + { + registry.get(HIST("data/pos_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.posCharge()); + registry.get(HIST("data/neg_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.negCharge()); + registry.get(HIST("data/termp_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.termPCharge()); + registry.get(HIST("data/termn_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.termNCharge()); + registry.get(HIST("data/pos_sq_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.posSqCharge()); + registry.get(HIST("data/neg_sq_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.negSqCharge()); + registry.get(HIST("data/posneg_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.posNegCharge()); + + int sampleIndex = static_cast(cfSubSample * fRndm->Rndm()); + subSample[sampleIndex][0]->Fill(event_netcharge.centrality(), event_netcharge.posCharge()); + subSample[sampleIndex][1]->Fill(event_netcharge.centrality(), event_netcharge.negCharge()); + subSample[sampleIndex][2]->Fill(event_netcharge.centrality(), event_netcharge.termPCharge()); + subSample[sampleIndex][3]->Fill(event_netcharge.centrality(), event_netcharge.termNCharge()); + subSample[sampleIndex][4]->Fill(event_netcharge.centrality(), event_netcharge.posSqCharge()); + subSample[sampleIndex][5]->Fill(event_netcharge.centrality(), event_netcharge.negSqCharge()); + subSample[sampleIndex][6]->Fill(event_netcharge.centrality(), event_netcharge.posNegCharge()); + } // void + PROCESS_SWITCH(NetchargeAnalysis, processData, "Process reconstructed and Data", true); + + void processGen(aod::NetChargeGen::iterator const& event_netcharge) + { + registry.get(HIST("gen/pos_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.posCharge()); + registry.get(HIST("gen/neg_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.negCharge()); + registry.get(HIST("gen/termp_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.termPCharge()); + registry.get(HIST("gen/termn_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.termNCharge()); + registry.get(HIST("gen/pos_sq_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.posSqCharge()); + registry.get(HIST("gen/neg_sq_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.negSqCharge()); + registry.get(HIST("gen/posneg_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.posNegCharge()); + + int sampleIndex = static_cast(cfSubSample * fRndm->Rndm()); + genSubSample[sampleIndex][0]->Fill(event_netcharge.centrality(), event_netcharge.posCharge()); + genSubSample[sampleIndex][1]->Fill(event_netcharge.centrality(), event_netcharge.negCharge()); + genSubSample[sampleIndex][2]->Fill(event_netcharge.centrality(), event_netcharge.termPCharge()); + genSubSample[sampleIndex][3]->Fill(event_netcharge.centrality(), event_netcharge.termNCharge()); + genSubSample[sampleIndex][4]->Fill(event_netcharge.centrality(), event_netcharge.posSqCharge()); + genSubSample[sampleIndex][5]->Fill(event_netcharge.centrality(), event_netcharge.negSqCharge()); + genSubSample[sampleIndex][6]->Fill(event_netcharge.centrality(), event_netcharge.posNegCharge()); + } // void + PROCESS_SWITCH(NetchargeAnalysis, processGen, "Process generated", true); + +}; // struct Netcharge_analysis + WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; - return workflow; + return WorkflowSpec{ + {adaptAnalysisTask(cfgc)}, + {adaptAnalysisTask(cfgc)} + + }; } diff --git a/PWGCF/Femto/TableProducer/PiDeuteronFemto.cxx b/PWGCF/Femto/TableProducer/PiDeuteronFemto.cxx index 6874bdcc607..9acef964220 100644 --- a/PWGCF/Femto/TableProducer/PiDeuteronFemto.cxx +++ b/PWGCF/Femto/TableProducer/PiDeuteronFemto.cxx @@ -152,8 +152,6 @@ struct PiDeuteronFemto { Configurable settingCutVertex{"settingCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable settingCutPinMinDe{"settingCutPinMinDe", 0.0f, "Minimum Pin for De"}; Configurable settingCutEta{"settingCutEta", 0.8f, "Eta cut on daughter track"}; - Configurable settingCutDCAxy{"settingCutDCAxy", 2.0f, "DCAxy range for tracks"}; - Configurable settingCutDCAz{"settingCutDCAz", 2.0f, "DCAz range for tracks"}; Configurable settingCutChi2tpcLow{"settingCutChi2tpcLow", 0.0f, "Low cut on TPC chi2"}; Configurable settingCutChi2tpcHigh{"settingCutChi2tpcHigh", 999.f, "High cut on TPC chi2"}; Configurable settingCutInvMass{"settingCutInvMass", 0.0f, "Invariant mass upper limit"}; @@ -170,6 +168,18 @@ struct PiDeuteronFemto { Configurable settingCutNsigmaTOFTPCPi{"settingCutNsigmaTOFTPCPi", 3.0f, "Value of the Pion TOF TPC Nsigma cut"}; Configurable settingNoMixedEvents{"settingNoMixedEvents", 5, "Number of mixed events per event"}; Configurable settingEnableBkgUS{"settingEnableBkgUS", false, "Enable US background"}; + + Configurable settingFillTable{"settingFillTable", false, "Enable table filling"}; + Configurable settingCutPiptMin{"settingCutPiptMin", 0.14f, "Minimum PT cut on Pi"}; + Configurable settingCutPiptMax{"settingCutPiptMax", 4.0f, "Maximum PT cut on Pi"}; + Configurable settingCutDeptMin{"settingCutDeptMin", 0.6f, "Minimum PT cut on De"}; + Configurable settingCutDeptMax{"settingCutDeptMax", 1.6f, "Maximum PT cut on De"}; + Configurable settingCutPiDCAxyMin{"settingCutPiDCAxyMin", 0.3f, "DCAxy Min for Pi"}; + Configurable settingCutPiDCAzMin{"settingCutPiDCAzMin", 0.3f, "DCAz Min for Pi"}; + Configurable settingCutDeDCAzMin{"settingCutDeDCAzMin", 0.2f, "DCAxy Min for De"}; + Configurable settingCutNsigTPCPrMin{"settingCutNsigTPCPrMin", 3.0f, "Minimum TPC Pr Nsigma cut on Pi"}; + Configurable settingCutNsigTOFPrMin{"settingCutNsigTOFPrMin", 3.0f, "Minimum TOF Pr Nsigma cut on Pi"}; + Configurable settingSaveUSandLS{"settingSaveUSandLS", true, "Save All Pairs"}; Configurable settingFillMultiplicity{"settingFillMultiplicity", false, "Fill multiplicity table"}; @@ -214,30 +224,33 @@ struct PiDeuteronFemto { HistogramRegistry mQaRegistry{ "QA", - { - {"hVtxZ", "Vertex distribution in Z;Z (cm)", {HistType::kTH1F, {{400, -20.0, 20.0}}}}, - {"hNcontributor", "Number of primary vertex contributor", {HistType::kTH1F, {{2000, 0.0f, 2000.0f}}}}, - {"hTrackSel", "Accepted tracks", {HistType::kTH1F, {{Selections::kAll, -0.5, static_cast(Selections::kAll) - 0.5}}}}, - {"hEvents", "; Events;", {HistType::kTH1F, {{3, -0.5, 2.5}}}}, - {"hEmptyPool", "svPoolCreator did not find track pairs false/true", {HistType::kTH1F, {{2, -0.5, 1.5}}}}, - {"hdcaxyDe", ";DCA_{xy} (cm)", {HistType::kTH1F, {{200, -1.0f, 1.0f}}}}, - {"hdcazDe", ";DCA_{z} (cm)", {HistType::kTH1F, {{200, -1.0f, 1.0f}}}}, - {"hNClsDeITS", ";N_{ITS} Cluster", {HistType::kTH1F, {{20, -10.0f, 10.0f}}}}, - {"hNClsPiITS", ";N_{ITS} Cluster", {HistType::kTH1F, {{20, -10.0f, 10.0f}}}}, - {"hDePitInvMass", "; M(De + p) (GeV/#it{c}^{2})", {HistType::kTH1F, {{300, 3.74f, 4.34f}}}}, - {"hDePt", "#it{p}_{T} distribution; #it{p}_{T} (GeV/#it{c})", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, - {"hPiPt", "Pt distribution; #it{p}_{T} (GeV/#it{c})", {HistType::kTH1F, {{120, -3.0f, 3.0f}}}}, - {"h2dEdxDecandidates", "dEdx distribution; #it{p} (GeV/#it{c}); dE/dx (a.u.)", {HistType::kTH2F, {{200, -5.0f, 5.0f}, {100, 0.0f, 2000.0f}}}}, - {"h2NsigmaDeTPC", "NsigmaDe TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(De)", {HistType::kTH2F, {{20, -5.0f, 5.0f}, {200, -5.0f, 5.0f}}}}, - {"h2NsigmaDeTPC_preselection", "NsigmaDe TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(De)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, - {"h2NsigmaDeTPC_preselecComp", "NsigmaDe TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(De)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, - {"h2NSigmaDeITS_preselection", "NsigmaDe ITS distribution; signed #it{p}_{T} (GeV/#it{c}); n#sigma_{ITS} De", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {120, -3.0f, 3.0f}}}}, - {"h2NSigmaDeITS", "NsigmaDe ITS distribution; signed #it{p}_{T} (GeV/#it{c}); n#sigma_{ITS} De", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {120, -3.0f, 3.0f}}}}, - {"h2NsigmaPiTPC", "NsigmaPi TPC distribution; #it{p}_{T}(GeV/#it{c}); n#sigma_{TPC}(p)", {HistType::kTH2F, {{20, -5.0f, 5.0f}, {200, -5.0f, 5.0f}}}}, - {"h2NsigmaPiTPC_preselection", "NsigmaDe TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(De)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, - {"h2NsigmaPiTOF", "NsigmaPi TOF distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(p)", {HistType::kTH2F, {{20, -5.0f, 5.0f}, {200, -5.0f, 5.0f}}}}, - {"h2NsigmaPiTOF_preselection", "NsigmaPi TOF distribution; #iit{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(p)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, - }, + {{"hVtxZ", "Vertex distribution in Z;Z (cm)", {HistType::kTH1F, {{400, -20.0, 20.0}}}}, + {"hNcontributor", "Number of primary vertex contributor", {HistType::kTH1F, {{2000, 0.0f, 2000.0f}}}}, + {"hTrackSel", "Accepted tracks", {HistType::kTH1F, {{Selections::kAll, -0.5, static_cast(Selections::kAll) - 0.5}}}}, + {"hEvents", "; Events;", {HistType::kTH1F, {{3, -0.5, 2.5}}}}, + {"hEmptyPool", "svPoolCreator did not find track pairs false/true", {HistType::kTH1F, {{2, -0.5, 1.5}}}}, + {"hdcaxyDe", ";DCA_{xy} (cm)", {HistType::kTH1F, {{200, -1.0f, 1.0f}}}}, + {"hdcazDe", ";DCA_{z} (cm)", {HistType::kTH1F, {{200, -1.0f, 1.0f}}}}, + {"hNClsDeITS", ";N_{ITS} Cluster", {HistType::kTH1F, {{20, -10.0f, 10.0f}}}}, + {"hNClsPiITS", ";N_{ITS} Cluster", {HistType::kTH1F, {{20, -10.0f, 10.0f}}}}, + {"hDePitInvMass", "; M(De + p) (GeV/#it{c}^{2})", {HistType::kTH1F, {{300, 3.74f, 4.34f}}}}, + {"hDePt", "#it{p}_{T} distribution; #it{p}_{T} (GeV/#it{c})", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, + {"hPiPt", "Pt distribution; #it{p}_{T} (GeV/#it{c})", {HistType::kTH1F, {{120, -3.0f, 3.0f}}}}, + {"h2dEdxDecandidates", "dEdx distribution; #it{p} (GeV/#it{c}); dE/dx (a.u.)", {HistType::kTH2F, {{200, -5.0f, 5.0f}, {100, 0.0f, 2000.0f}}}}, + {"h2NsigmaDeTPC", "NsigmaDe TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(De)", {HistType::kTH2F, {{20, -5.0f, 5.0f}, {200, -5.0f, 5.0f}}}}, + {"h2NsigmaDeTPC_preselection", "NsigmaDe TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(De)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, + {"h2NsigmaDeTPC_preselecComp", "NsigmaDe TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(De)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, + {"h2NSigmaDeITS_preselection", "NsigmaDe ITS distribution; signed #it{p}_{T} (GeV/#it{c}); n#sigma_{ITS} De", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {120, -3.0f, 3.0f}}}}, + {"h2NSigmaDeITS", "NsigmaDe ITS distribution; signed #it{p}_{T} (GeV/#it{c}); n#sigma_{ITS} De", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {120, -3.0f, 3.0f}}}}, + {"h2NsigmaPiTPC", "NsigmaPi TPC distribution; #it{p}_{T}(GeV/#it{c}); n#sigma_{TPC}(p)", {HistType::kTH2F, {{20, -5.0f, 5.0f}, {200, -5.0f, 5.0f}}}}, + {"h2NsigmaPiTPC_preselection", "NsigmaDe TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(De)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, + {"h2NsigmaPiTOF", "NsigmaPi TOF distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(p)", {HistType::kTH2F, {{20, -5.0f, 5.0f}, {200, -5.0f, 5.0f}}}}, + {"h2NsigmaPiTOF_preselection", "NsigmaPi TOF distribution; #iit{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(p)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, + {"hkStar_LS_M", ";kStar (GeV/c)", {HistType::kTH1F, {{300, 0.0f, 3.0f}}}}, + {"hkStar_LS_A", ";kStar (GeV/c)", {HistType::kTH1F, {{300, 0.0f, 3.0f}}}}, + {"hkStar_US_M", ";kStar (GeV/c)", {HistType::kTH1F, {{300, 0.0f, 3.0f}}}}, + {"hkStar_US_A", ";kStar (GeV/c)", {HistType::kTH1F, {{300, 0.0f, 3.0f}}}}, + {"hisBkgEM", "; isBkgEM;", {HistType::kTH1F, {{3, -1, 2}}}}}, OutputObjHandlingPolicy::AnalysisObject, false, true}; @@ -683,6 +696,81 @@ struct PiDeuteronFemto { mQaRegistry.fill(HIST("hdcazDe"), piDecand.dcazDe); mQaRegistry.fill(HIST("hNClsDeITS"), piDecand.nClsItsDe); mQaRegistry.fill(HIST("hNClsPiITS"), piDecand.nClsItsPi); + mQaRegistry.fill(HIST("hisBkgEM"), piDecand.isBkgEM); + } + + double computePrTPCnsig(double InnerParamTPCHad, double SignalTPCHad) + { + double m_BBparamsProton[6] = {-54.42066571222577, 0.2857381250239097, 1.247140602468868, 0.6297483918147729, 2.985438833884555, 0.09}; + + float TPCinnerParam = InnerParamTPCHad; + float expTPCSignal = o2::tpc::BetheBlochAleph((TPCinnerParam / 0.9382721), m_BBparamsProton[0], m_BBparamsProton[1], m_BBparamsProton[2], m_BBparamsProton[3], m_BBparamsProton[4]); + double resoTPC{expTPCSignal * m_BBparamsProton[5]}; + return ((SignalTPCHad - expTPCSignal) / resoTPC); + } + + double tofNSigmaCalculation(double MassTOFHad, double ptHad) + { + double fExpTOFMassHad = 0.9487; // Proton mass in TOF + const float kp0 = 1.22204e-02; + const float kp1 = 7.48467e-01; + + double fSigmaTOFMassHad = (kp0 * TMath::Exp(kp1 * TMath::Abs(ptHad))) * fExpTOFMassHad; + double fNSigmaTOFHad = (MassTOFHad - fExpTOFMassHad) / fSigmaTOFMassHad; + return fNSigmaTOFHad; + } + + double computeKstar(const PiDecandidate& piDecand) + { + TLorentzVector he3, hadron; + float massHe3 = 2.80839; + float massHad = 0.1395704; + he3.SetPtEtaPhiM(abs(piDecand.recoPtDe()), piDecand.recoEtaDe(), piDecand.recoPhiDe(), massHe3); + hadron.SetPtEtaPhiM(abs(piDecand.recoPtPi()), piDecand.recoEtaPi(), piDecand.recoPhiPi(), massHad); + + TLorentzVector p_total_lab = he3 + hadron; + TVector3 v_cm = p_total_lab.BoostVector(); + TLorentzVector p1_cm = he3; + TLorentzVector p2_cm = hadron; + p1_cm.Boost(-v_cm); + p2_cm.Boost(-v_cm); + TLorentzVector p_diff_cm = p1_cm - p2_cm; + double kStar = sqrt(p_diff_cm.X() * p_diff_cm.X() + p_diff_cm.Y() * p_diff_cm.Y() + p_diff_cm.Z() * p_diff_cm.Z()); + return kStar / 2.0; + } + + void fillKstar(const PiDecandidate& piDecand) + { + double PrTPCnsigma = computePrTPCnsig(piDecand.momPiTPC, piDecand.tpcSignalPi); + double PrTOFnsigma = tofNSigmaCalculation(piDecand.massTOFPi, piDecand.recoPtPi()); + if (abs(PrTPCnsigma) < settingCutNsigTPCPrMin) + return; + if (abs(PrTOFnsigma) < settingCutNsigTOFPrMin) + return; + float DeDCAxyMin = 0.015 + 0.0305 / TMath::Power(piDecand.recoPtDe(), 1.1); + if (abs(piDecand.dcaxyDe) > DeDCAxyMin || abs(piDecand.dcazDe) > settingCutDeDCAzMin || abs(piDecand.dcaxyPi) > settingCutPiDCAxyMin || abs(piDecand.dcazPi) > settingCutPiDCAzMin) + return; + if (std::abs(piDecand.recoPtPi()) < settingCutPiptMin || std::abs(piDecand.recoPtPi()) > settingCutPiptMax) + return; + if (std::abs(piDecand.recoPtDe()) < settingCutDeptMin || std::abs(piDecand.recoPtDe()) > settingCutDeptMax) + return; + + fillHistograms(piDecand); + + double kstar = computeKstar(piDecand); + if (piDecand.isBkgUS == 0) { + if (piDecand.recoPtDe() > 0) { + mQaRegistry.fill(HIST("hkStar_LS_M"), kstar); + } else { + mQaRegistry.fill(HIST("hkStar_LS_A"), kstar); + } + } else { + if (piDecand.recoPtDe() > 0) { + mQaRegistry.fill(HIST("hkStar_US_M"), kstar); + } else { + mQaRegistry.fill(HIST("hkStar_US_A"), kstar); + } + } } // ================================================================================================================== @@ -700,9 +788,14 @@ struct PiDeuteronFemto { if (!fillCandidateInfo(deTrack, piTrack, collBracket, collisions, piDecand, tracks, isMixedEvent)) { continue; } - fillHistograms(piDecand); + + fillKstar(piDecand); + auto collision = collisions.rawIteratorAt(piDecand.collisionID); - fillTable(piDecand, collision); + + if (settingFillTable) { + fillTable(piDecand, collision); + } } } diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h index a55c896fb6b..ec40ea035e6 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h @@ -64,13 +64,14 @@ class FemtoUniverseMath return 0.5 * trackRelK.P(); } + /// Boost particles from LAB Frame to Pair Rest Frame (for lambda daughters) /// \tparam T type of tracks /// \param part1 Particle 1 /// \param mass1 Mass of particle 1 /// \param part2 Particle 2 /// \param mass2 Mass of particle 2 template - static float getthetastar(const T& part1, const float mass1, const T& part2, const float mass2) + static ROOT::Math::PxPyPzMVector boostPRF(const T& part1, const float mass1, const T& part2, const float mass2) { const ROOT::Math::PtEtaPhiMVector vecpart1(part1.pt(), part1.eta(), part1.phi(), mass1); const ROOT::Math::PtEtaPhiMVector vecpart2(part2.pt(), part2.eta(), part2.phi(), mass2); @@ -88,10 +89,7 @@ class FemtoUniverseMath partOneCMS = boostPRF(partOneCMS); partTwoCMS = boostPRF(partTwoCMS); - const ROOT::Math::PtEtaPhiMVector partOneCMSGeo(partOneCMS); - const ROOT::Math::PtEtaPhiMVector partTwoCMSGeo(partTwoCMS); - - return (partOneCMSGeo.Theta() - partTwoCMSGeo.Theta()); + return partOneCMS; } /// Compute the qij of a pair of particles diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index 00ed3161ce7..e9a07329468 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -2336,6 +2336,47 @@ struct FemtoUniverseProducerTask { } PROCESS_SWITCH(FemtoUniverseProducerTask, processTruthAndFullMCCasc, "Provide both MC truth and reco for tracks and Cascades", false); + void processTruthAndFullMCCentRun3Casc( + aod::McCollisions const& mccols, + aod::McParticles const& mcParticles, + aod::FemtoFullCollisionCentRun3MCs const& collisions, + soa::Filtered> const& tracks, + soa::Join const& fullCascades, + aod::BCsWithTimestamps const&) + { + + // recos + std::set recoMcIds; + for (const auto& col : collisions) { + auto groupedTracks = tracks.sliceBy(perCollisionTracks, col.globalIndex()); + auto groupedCascParts = fullCascades.sliceBy(perCollisionCascs, col.globalIndex()); + getMagneticFieldTesla(col.bc_as()); + const auto colcheck = fillCollisionsCentRun3(col); + if (colcheck) { + fillTracks(groupedTracks); + fillCascade(col, groupedCascParts, groupedTracks); + } + for (const auto& track : groupedTracks) { + if (trackCuts.isSelectedMinimal(track)) + recoMcIds.insert(track.mcParticleId()); + } + } + + // truth + for (const auto& mccol : mccols) { + auto groupedCollisions = collisions.sliceBy(recoCollsPerMCCollCentPbPb, mccol.globalIndex()); + for (const auto& col : groupedCollisions) { + const auto colcheck = fillMCTruthCollisionsCentRun3(col); // fills the reco collisions for mc collision + if (colcheck) { + auto groupedMCParticles = mcParticles.sliceBy(perMCCollision, mccol.globalIndex()); + outputCollExtra(1.0, 1.0); + fillParticles(groupedMCParticles, recoMcIds); // fills mc particles + } + } + } + } + PROCESS_SWITCH(FemtoUniverseProducerTask, processTruthAndFullMCCentRun3Casc, "Provide both MC truth and reco for tracks and cascades with centrality", false); + Preslice> perCollisionD0s = aod::track::collisionId; void processTrackD0MC(aod::McCollisions const& mccols, aod::TracksWMc const&, diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx index 955af5a6876..1207d1ff10f 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx @@ -14,22 +14,27 @@ /// \author Luca Barioglio, TU München, luca.barioglio@cern.ch /// \author Zuzanna Chochulska, WUT Warsaw & CTU Prague, zchochul@cern.ch -#include -#include -#include -#include +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" +#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" + +#include "DataFormatsParameters/GRPObject.h" +#include "Framework/ASoAHelpers.h" #include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" #include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" +#include "Framework/O2DatabasePDGPlugin.h" #include "Framework/RunningWorkflowInfo.h" #include "Framework/StepTHn.h" -#include "DataFormatsParameters/GRPObject.h" +#include "Framework/runDataProcessing.h" -#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" -#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" +#include + +#include + +#include +#include using namespace o2; using namespace o2::analysis::femto_universe; @@ -37,72 +42,85 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::soa; -struct femtoUniverseDebugV0 { +struct FemtoUniverseDebugV0 { + + Service pdg; + SliceCache cache; - Configurable ConfPDGCodeV0{"ConfPDGCodePartOne", 3122, "V0 - PDG code"}; - Configurable ConfPDGCodeChildPos{"ConfPDGCodeChildPos", 2212, "Positive Child - PDG code"}; - Configurable ConfPDGCodeChildNeg{"ConfPDGCodeChildNeg", 211, "Negative Child- PDG code"}; - Configurable ConfCutV0{"ConfCutV0", 338, "V0 - Selection bit from cutCulator"}; - ConfigurableAxis ConfV0TempFitVarBins{"ConfV0TempFitVarBins", {300, 0.95, 1.}, "V0: binning of the TempFitVar in the pT vs. TempFitVar plot"}; - ConfigurableAxis ConfV0TempFitVarpTBins{"ConfV0TempFitVarpTBins", {20, 0.5, 4.05}, "V0: pT binning of the pT vs. TempFitVar plot"}; - - Configurable ConfCutChildPos{"ConfCutChildPos", 150, "Positive Child of V0 - Selection bit from cutCulator"}; - Configurable ConfCutChildNeg{"ConfCutChildNeg", 149, "Negative Child of V0 - Selection bit from cutCulator"}; - Configurable ConfChildPosPidnSigmaMax{"ConfChildPosPidnSigmaMax", 3.f, "Positive Child of V0 - Selection bit from cutCulator"}; - Configurable ConfChildNegPidnSigmaMax{"ConfChildNegPidnSigmaMax", 3.f, "Negative Child of V0 - Selection bit from cutCulator"}; - Configurable ConfChildPosIndex{"ConfChildPosIndex", 1, "Positive Child of V0 - Index from cutCulator"}; - Configurable ConfChildNegIndex{"ConfChildNegIndex", 0, "Negative Child of V0 - Index from cutCulator"}; - Configurable> ConfChildPIDnSigmaMax{"ConfChildPIDnSigmaMax", std::vector{4.f, 3.f}, "V0 child sel: Max. PID nSigma TPC"}; - Configurable ConfChildnSpecies{"ConfChildnSpecies", 2, "Number of particle spieces (for V0 children) with PID info"}; - ConfigurableAxis ConfChildTempFitVarBins{"ConfChildTempFitVarBins", {300, -0.15, 0.15}, "V0 child: binning of the TempFitVar in the pT vs. TempFitVar plot"}; - ConfigurableAxis ConfChildTempFitVarpTBins{"ConfChildTempFitVarpTBins", {20, 0.5, 4.05}, "V0 child: pT binning of the pT vs. TempFitVar plot"}; + Configurable confPDGCodeV0{"confPDGCodeV0", 3122, "V0 -- PDG code"}; + Configurable confPDGCodePositiveChild{"confPDGCodePositiveChild", 2212, "Positive Child -- PDG code"}; + Configurable confPDGCodeNegativeChild{"confPDGCodeNegativeChild", 211, "Negative Child -- PDG code"}; + Configurable confCutV0{"confCutV0", 338, "V0 -- Selection bit from cutCulator"}; + ConfigurableAxis confV0TempFitVarBins{"confV0TempFitVarBins", {300, 0.95, 1.}, "V0: binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis confV0TempFitVarpTBins{"confV0TempFitVarpTBins", {20, 0.5, 4.05}, "V0: pT binning of the pT vs. TempFitVar plot"}; + + Configurable confCutPositiveChild{"confCutPositiveChild", 150, "Positive Child of V0 -- Selection bit from cutCulator"}; + Configurable confCutNegativeChild{"confCutNegativeChild", 149, "Negative Child of V0 -- Selection bit from cutCulator"}; + Configurable confPositiveChildPIDnSigmaMax{"confPositiveChildPIDnSigmaMax", 3.f, "Positive Child of V0 -- Selection bit from cutCulator"}; + Configurable confNegativeChildPIDnSigmaMax{"confNegativeChildPIDnSigmaMax", 3.f, "Negative Child of V0 -- Selection bit from cutCulator"}; + Configurable confPositiveChildIndex{"confPositiveChildIndex", 1, "Positive Child of V0 -- Index from cutCulator"}; + Configurable confNegativeChildIndex{"confNegativeChildIndex", 0, "Negative Child of V0 -- Index from cutCulator"}; + Configurable> confChildPIDnSigmaMax{"confChildPIDnSigmaMax", std::vector{4.f, 3.f}, "V0 child selection: max. PID nSigma TPC"}; + Configurable confChildnSpecies{"confChildnSpecies", 2, "Number of particle spieces (for V0 children) with PID info"}; + ConfigurableAxis confChildTempFitVarBins{"confChildTempFitVarBins", {300, -0.15, 0.15}, "V0 child: binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis confChildTempFitVarpTBins{"confChildTempFitVarpTBins", {20, 0.5, 4.05}, "V0 child: pT binning of the pT vs. TempFitVar plot"}; using FemtoFullParticles = soa::Join; - Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kV0)) && ((aod::femtouniverseparticle::cut & ConfCutV0) == ConfCutV0); + Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kV0)) && ((aod::femtouniverseparticle::cut & confCutV0) == confCutV0); Preslice perCol = aod::femtouniverseparticle::fdCollisionId; /// Histogramming FemtoUniverseEventHisto eventHisto; - FemtoUniverseParticleHisto posChildHistos; - FemtoUniverseParticleHisto negChildHistos; + FemtoUniverseParticleHisto positiveChildHistos; + FemtoUniverseParticleHisto negativeChildHistos; FemtoUniverseParticleHisto V0Histos; /// Histogram output HistogramRegistry EventRegistry{"Event", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry V0Registry{"FullV0QA", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry thetaRegistry{"ThetaQA", {}, OutputObjHandlingPolicy::AnalysisObject}; void init(InitContext&) { eventHisto.init(&EventRegistry); - posChildHistos.init(&V0Registry, ConfChildTempFitVarpTBins, ConfChildTempFitVarBins, false, ConfPDGCodeChildPos.value, true); - negChildHistos.init(&V0Registry, ConfChildTempFitVarpTBins, ConfChildTempFitVarBins, false, ConfPDGCodeChildNeg, true); - V0Histos.init(&V0Registry, ConfV0TempFitVarpTBins, ConfV0TempFitVarBins, false, ConfPDGCodeV0.value, true); + positiveChildHistos.init(&V0Registry, confChildTempFitVarpTBins, confChildTempFitVarBins, false, confPDGCodePositiveChild.value, true); + negativeChildHistos.init(&V0Registry, confChildTempFitVarpTBins, confChildTempFitVarBins, false, confPDGCodeNegativeChild, true); + V0Histos.init(&V0Registry, confV0TempFitVarpTBins, confV0TempFitVarBins, false, confPDGCodeV0.value, true); + + thetaRegistry.add("Theta/hTheta", " ; p (GeV/#it{c}); cos(#theta)", kTH2F, {{100, 0, 10}, {110, -1.1, 1.1}}); } - /// Porduce QA plots for V0 selection in FemtoUniverse framework + /// Produce QA plots for V0 selection in FemtoUniverse framework void process(o2::aod::FdCollision const& col, FemtoFullParticles const& parts) { auto groupPartsOne = partsOne->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); eventHisto.fillQA(col); - for (auto& part : groupPartsOne) { + for (const auto& part : groupPartsOne) { if (!part.has_children()) { continue; } - const auto& posChild = parts.iteratorAt(part.index() - 2); - const auto& negChild = parts.iteratorAt(part.index() - 1); - if (posChild.globalIndex() != part.childrenIds()[0] || negChild.globalIndex() != part.childrenIds()[1]) { + const auto& positiveChild = parts.iteratorAt(part.index() - 2); + const auto& negativeChild = parts.iteratorAt(part.index() - 1); + if (positiveChild.globalIndex() != part.childrenIds()[0] || negativeChild.globalIndex() != part.childrenIds()[1]) { LOG(warn) << "Indices of V0 children do not match"; continue; } - // check cuts on V0 children - if ((posChild.partType() == uint8_t(aod::femtouniverseparticle::ParticleType::kV0Child) && (posChild.cut() & ConfCutChildPos) == ConfCutChildPos) && - (negChild.partType() == uint8_t(aod::femtouniverseparticle::ParticleType::kV0Child) && (negChild.cut() & ConfCutChildNeg) == ConfCutChildNeg) && - isFullPIDSelected(posChild.pidCut(), posChild.p(), 999.f, ConfChildPosIndex.value, ConfChildnSpecies.value, ConfChildPIDnSigmaMax.value, ConfChildPosPidnSigmaMax.value, 1.f) && - isFullPIDSelected(negChild.pidCut(), negChild.p(), 999.f, ConfChildNegIndex.value, ConfChildnSpecies.value, ConfChildPIDnSigmaMax.value, ConfChildNegPidnSigmaMax.value, 1.f)) { + + // Check cuts on V0 children + if (positiveChild.partType() == uint8_t(aod::femtouniverseparticle::ParticleType::kV0Child) && + negativeChild.partType() == uint8_t(aod::femtouniverseparticle::ParticleType::kV0Child) && + isFullPIDSelected(positiveChild.pidCut(), positiveChild.p(), 999.f, confPositiveChildIndex.value, confChildnSpecies.value, confChildPIDnSigmaMax.value, confPositiveChildPIDnSigmaMax.value, 1.f) && + isFullPIDSelected(negativeChild.pidCut(), negativeChild.p(), 999.f, confNegativeChildIndex.value, confChildnSpecies.value, confChildPIDnSigmaMax.value, confNegativeChildPIDnSigmaMax.value, 1.f)) { + auto positiveChildMass = pdg->Mass(confPDGCodePositiveChild); + auto negativeChildMass = pdg->Mass(confPDGCodeNegativeChild); + auto positiveChildBoosted = FemtoUniverseMath::boostPRF(positiveChild, positiveChildMass, negativeChild, negativeChildMass); + auto cosineTheta = (positiveChildBoosted.Px() * part.px() + positiveChildBoosted.Py() * part.py() + positiveChildBoosted.Pz() * part.pz()) / (positiveChildBoosted.P() * part.p()); + V0Histos.fillQA(part); - posChildHistos.fillQA(posChild); - negChildHistos.fillQA(negChild); + positiveChildHistos.fillQA(positiveChild); + negativeChildHistos.fillQA(negativeChild); + thetaRegistry.fill(HIST("Theta/hTheta"), part.p(), cosineTheta); } } } @@ -112,7 +130,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), }; return workflow; } diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx index 92e42134f0a..5397acf05dc 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx @@ -160,6 +160,7 @@ struct FemtoUniverseEfficiencyBase { trackHistoPartOneRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarDCABins, 0, confPDGCodePartOne, confIsDebug); registryMCOrigin.add("part1/hPt", " ;#it{p}_{T} (GeV/c); Entries", {HistType::kTH1F, {{240, 0, 6}}}); registryPDG.add("part1/PDGvspT", "PDG;#it{p}_{T} (GeV/c); PDG", {HistType::kTH2F, {{500, 0, 5}, {16001, -8000.5, 8000.5}}}); + registryPDG.add("part1/PDGvspTall", "PDG;#it{p}_{T} (GeV/c); PDG", {HistType::kTH2F, {{500, 0, 5}, {16001, -8000.5, 8000.5}}}); if (confParticleTypePartOne == uint8_t(aod::femtouniverseparticle::ParticleType::kV0)) { trackHistoV0OneRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarCPABins, 0, confPDGCodePartOne, confIsDebug); trackHistoV0OneChildPosRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarDCABins, 0, 0, confIsDebug, "posChildV0_1"); @@ -169,6 +170,7 @@ struct FemtoUniverseEfficiencyBase { } registryPDG.add("part2/PDGvspT", "PDG;#it{p}_{T} (GeV/c); PDG", {HistType::kTH2F, {{500, 0, 5}, {16001, -8000.5, 8000.5}}}); + registryPDG.add("part2/PDGvspTall", "PDG;#it{p}_{T} (GeV/c); PDG", {HistType::kTH2F, {{500, 0, 5}, {16001, -8000.5, 8000.5}}}); if (!confIsSame) { trackHistoPartTwoGen.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarPDGBins, 0, confPDGCodePartTwo, false); trackHistoPartTwoRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarDCABins, 0, confPDGCodePartTwo, confIsDebug); @@ -373,6 +375,8 @@ struct FemtoUniverseEfficiencyBase { continue; } + registryPDG.fill(HIST("part1/PDGvspTall"), part.pt(), mcParticle.pdgMCTruth()); + if (!(std::abs(mcParticle.pdgMCTruth()) == std::abs(confPDGCodePartOne))) { continue; } @@ -397,6 +401,8 @@ struct FemtoUniverseEfficiencyBase { continue; } + registryPDG.fill(HIST("part2/PDGvspTall"), part.pt(), mcParticle.pdgMCTruth()); + if (!(std::abs(mcParticle.pdgMCTruth()) == std::abs(confPDGCodePartTwo))) { continue; } diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx index e4ebe2db60a..026cabb1367 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx @@ -631,6 +631,8 @@ struct femtoUniversePairTaskTrackCascadeExtended { // MC truth void processSameEventMCgen(const FilteredFDCollision& col, [[maybe_unused]] const FemtoFullParticles& parts) { + const int multCol = confUseCent ? col.multV0M() : col.multNtr(); + auto groupPartsOne = partsOneMCgen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); auto groupPartsTwo = partsTwoMCgen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); @@ -665,7 +667,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { int pdgCodeCasc = static_cast(p2.pidCut()); if ((confCascType1 == 0 && pdgCodeCasc != 3334) || (confCascType1 == 2 && pdgCodeCasc != -3334) || (confCascType1 == 1 && pdgCodeCasc != 3312) || (confCascType1 == 3 && pdgCodeCasc != -3312)) continue; - sameEventCont.setPair(p1, p2, col.multNtr(), confUse3D, 1.0f); + sameEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); } } } @@ -676,6 +678,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { ColumnBinningPolicy colBinning{{confVtxBins, confMultBins}, true}; for (const auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + const int multCol = confUseCent ? collision1.multV0M() : collision1.multNtr(); auto groupPartsOne = partsOneMCgen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); auto groupPartsTwo = partsTwoMCgen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); @@ -692,7 +695,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { int pdgCodeCasc = static_cast(p2.pidCut()); if ((confCascType1 == 0 && pdgCodeCasc != 3334) || (confCascType1 == 2 && pdgCodeCasc != -3334) || (confCascType1 == 1 && pdgCodeCasc != 3312) || (confCascType1 == 3 && pdgCodeCasc != -3312)) continue; - mixedEventCont.setPair(p1, p2, collision1.multNtr(), confUse3D, 1.0f); + mixedEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); } } } diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx index 28d1295c124..977342a3939 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx @@ -150,7 +150,8 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { ConfigurableAxis ConfTempFitVarpTBins{"ConfTempFitVarpTBins", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot"}; /// Correlation part - ConfigurableAxis ConfMultBins{"ConfMultBins", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity or centrality"}; // \todo to be obtained from the hash task + ConfigurableAxis ConfMultBinsCent{"ConfMultBinsCent", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - centrality"}; // \todo to be obtained from the hash task + ConfigurableAxis ConfMultBinsMult{"ConfMultBinsMult", {VARIABLE_WIDTH, 0.0f, 400.0f, 800.0f, 1200.0f, 1600.0f, 2000.0f, 2500.0f, 3000.0f, 3500.0f, 4000.0f, 4500.0f, 5000.0f, 6000.0f, 7000.0f, 8000.0f, 9000.0f, 10000.0f, 11000.0f, 12000.0f, 13000.0f, 14000.0f, 15000.0f, 16000.0f, 17000.0f, 18000.0f, 99999.f}, "Mixing bins - centrality"}; ConfigurableAxis ConfMultKstarBins{"ConfMultKstarBins", {VARIABLE_WIDTH, 0.0f, 200.0f}, "Bins for kstar analysis in multiplicity or centrality bins (10 is maximum)"}; ConfigurableAxis ConfKtKstarBins{"ConfKtKstarBins", {VARIABLE_WIDTH, 0.1f, 0.2f, 0.3f, 0.4f}, "Bins for kstar analysis in kT bins"}; ConfigurableAxis ConfVtxBins{"ConfVtxBins", {VARIABLE_WIDTH, -10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "Mixing bins - z-vertex"}; @@ -158,8 +159,8 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { ConfigurableAxis ConfmTBins3D{"ConfmTBins3D", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; ConfigurableAxis ConfmultBins3D{"ConfmultBins3D", {VARIABLE_WIDTH, 0.0f, 20.0f, 30.0f, 40.0f, 99999.0f}, "multiplicity Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; - ColumnBinningPolicy colBinningCent{{ConfVtxBins, ConfMultBins}, true}; - ColumnBinningPolicy colBinningNtr{{ConfVtxBins, ConfMultBins}, true}; + ColumnBinningPolicy colBinningCent{{ConfVtxBins, ConfMultBinsCent}, true}; + ColumnBinningPolicy colBinningNtr{{ConfVtxBins, ConfMultBinsMult}, true}; ConfigurableAxis ConfkstarBins{"ConfkstarBins", {60, 0.0, 0.3}, "binning kstar"}; ConfigurableAxis ConfkTBins{"ConfkTBins", {150, 0., 9.}, "binning kT"}; diff --git a/PWGCF/Flow/Tasks/flowEsePHe3.cxx b/PWGCF/Flow/Tasks/flowEsePHe3.cxx index 61582f233b3..73a92bea4ef 100644 --- a/PWGCF/Flow/Tasks/flowEsePHe3.cxx +++ b/PWGCF/Flow/Tasks/flowEsePHe3.cxx @@ -27,66 +27,237 @@ #include // o2Physics includes. -#include "Framework/ASoA.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StaticFor.h" - -#include "Common/DataModel/Qvectors.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/Core/EventPlaneHelper.h" #include "Common/Core/TrackSelection.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/PIDResponseITS.h" +#include "Common/DataModel/Qvectors.h" +#include "Common/DataModel/TrackSelectionTables.h" #include "CommonConstants/PhysicsConstants.h" +#include "DataFormatsTPC/BetheBlochAleph.h" +#include "Framework/ASoA.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/StaticFor.h" +#include "Framework/runDataProcessing.h" using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::constants::physics; namespace o2::aod { -namespace flow_ese_p_he3 +namespace ese_var_table { -DECLARE_SOA_COLUMN(NPidFlag, nPidFlag, int8_t); // unqualified -1, hadron 0, proton 1, he3 2, proton+he3 3 -} // namespace flow_ese_p_he3 -DECLARE_SOA_TABLE(PHe3ESEFlags, "AOD", "PHe3ESEFlags", flow_ese_p_he3::NPidFlag); +DECLARE_SOA_COLUMN(EseVtz, eseVtz, float); +DECLARE_SOA_COLUMN(EseCentFT0C, eseCentFT0C, float); +DECLARE_SOA_COLUMN(EsePsi2FT0C, esePsi2FT0C, float); +DECLARE_SOA_COLUMN(Eseq2Tar, eseq2Tar, float); +DECLARE_SOA_COLUMN(Eseq2Ref, eseq2Ref, float); +DECLARE_SOA_COLUMN(EseTarSign, eseTarSign, int8_t); +DECLARE_SOA_COLUMN(EseTarTPCInnerParam, eseTarTPCInnerParam, float); +DECLARE_SOA_COLUMN(EseTarTPCSignal, eseTarTPCSignal, float); +DECLARE_SOA_COLUMN(EseTarPt, eseTarPt, float); +DECLARE_SOA_COLUMN(EseTarEta, eseTarEta, float); +DECLARE_SOA_COLUMN(EseTarPhi, eseTarPhi, float); +DECLARE_SOA_COLUMN(EseTarDCAxy, eseTarDCAxy, float); +DECLARE_SOA_COLUMN(EseTarDCAz, eseTarDCAz, float); +DECLARE_SOA_COLUMN(EseTarTPCNcls, eseTarTPCNcls, uint8_t); +DECLARE_SOA_COLUMN(EseTarITSNcls, eseTarITSNcls, uint8_t); +DECLARE_SOA_COLUMN(EseTarTPCChi2NDF, eseTarTPCChi2NDF, float); +DECLARE_SOA_COLUMN(EseTarITSChi2NDF, eseTarITSChi2NDF, float); +DECLARE_SOA_COLUMN(EseTarTPCNSigma, eseTarTPCNSigma, float); +DECLARE_SOA_COLUMN(EseTarTOFNSigma, eseTarTOFNSigma, float); +DECLARE_SOA_COLUMN(EseTarITSNSigma, eseTarITSNSigma, float); +DECLARE_SOA_COLUMN(EseTarITSClusSize, eseTarITSClusSize, uint32_t); +} // namespace ese_var_table + +DECLARE_SOA_TABLE(ESETable, "AOD", "ESETable", + ese_var_table::EseVtz, + ese_var_table::EseCentFT0C, + ese_var_table::EsePsi2FT0C, + ese_var_table::Eseq2Tar, + ese_var_table::Eseq2Ref, + ese_var_table::EseTarSign, + ese_var_table::EseTarTPCInnerParam, + ese_var_table::EseTarTPCSignal, + ese_var_table::EseTarPt, + ese_var_table::EseTarEta, + ese_var_table::EseTarPhi, + ese_var_table::EseTarDCAxy, + ese_var_table::EseTarDCAz, + ese_var_table::EseTarTPCNcls, + ese_var_table::EseTarITSNcls, + ese_var_table::EseTarTPCChi2NDF, + ese_var_table::EseTarITSChi2NDF, + ese_var_table::EseTarTPCNSigma, + ese_var_table::EseTarTOFNSigma, + ese_var_table::EseTarITSNSigma, + ese_var_table::EseTarITSClusSize); } // namespace o2::aod -namespace pid_flags -{ -// constexpr int8_t kUnqualified = -1; -// constexpr int8_t kUnPOIHadron = 0; -constexpr int8_t kProton = 1; -constexpr int8_t kHe3 = 2; -constexpr int8_t kProtonHe3 = 3; -} // namespace pid_flags - -namespace event_selection -{ -constexpr int kFT0AV0ASigma = 5; -} +struct ESECandidate { + float vtz; + float centFT0C; + float psi2FT0C; + float q2Tar; + float q2Ref; + int8_t signTar; + float tpcInnerParamTar; + float tpcSignalTar; + float ptTar; + float etaTar; + float phiTar; + float dcaXYTar; + float dcaZTar; + uint8_t tpcNclsTar; + uint8_t itsNclsTar; + float tpcChi2NDFTar; + float itsChi2NDFTar; + float tpcNSigmaTar; + float tofNSigmaTar; + float itsNSigmaTar; + uint32_t itsClusSizeTar; +}; -namespace fourier_mode +namespace ese_parameters { -// constexpr int kMode1 = 1; -constexpr int kMode2 = 2; -// constexpr int kMode3 = 3; -} // namespace fourier_mode +constexpr uint8_t kProton = 0; +constexpr uint8_t kDeuteron = 1; +constexpr uint8_t kTriton = 2; +constexpr uint8_t kHe3 = 3; +constexpr uint8_t kAlpha = 4; +constexpr int kFT0AV0ASigma = 5; +constexpr int kRMSMode = 0; +constexpr int kTPCMode = 1; +constexpr int kTOFOnlyMode = 2; +constexpr float Amplitudelow = 1e-8; +constexpr float Charges[5]{1.f, 1.f, 1.f, 2.f, 2.f}; +constexpr float Masses[5]{MassProton, MassDeuteron, MassTriton, MassHelium3, MassAlpha}; +constexpr double BetheBlochDefault[5][6]{ + {-136.71, 0.441, 0.2269, 1.347, 0.8035, 0.09}, + {-136.71, 0.441, 0.2269, 1.347, 0.8035, 0.09}, + {-239.99, 1.155, 1.099, 1.137, 1.006, 0.09}, + {-321.34, 0.6539, 1.591, 0.8225, 2.363, 0.09}, + {-586.66, 1.859, 4.435, 0.282, 3.201, 0.09}}; +constexpr double BbMomScalingDefault[5][2]{// 0:poscharged 1:negcharged + {1., 1.}, + {1., 1.}, + {1., 1.}, + {1., 1.}, + {1., 1.}}; +constexpr int Open3DPIDPlots[3][1]{ + {0}, + {0}, + {0}}; +constexpr int OpenEvSel[10][1]{ + {1}, + {1}, + {1}, + {1}, + {1}, + {1}, + {1}, + {1}, + {0}, + {1}}; +constexpr int OpenTrackSel[7][1]{ + {1}, + {1}, + {1}, + {1}, + {1}, + {1}, + {1}}; +constexpr double TPCnSigmaCutDefault[5][2]{ + {-3., 3.}, + {-3., 3.}, + {-3., 3.}, + {-3., 3.}, + {-3., 3.}}; +constexpr double ITSnSigmaCutDefault[5][2]{ + {-3., 3.}, + {-3., 3.}, + {-3., 3.}, + {-3., 3.}, + {-3., 3.}}; +constexpr double PtPreselection[5][2]{ + {0.15, 99.}, + {0.15, 99.}, + {0.15, 99.}, + {0.15, 99.}, + {0.15, 99.}}; +static const std::vector names{"proton", "deuteron", "triton", "He3", "alpha"}; +static const std::vector chargeLabelNames{"Positive", "Negative"}; +static const std::vector betheBlochParNames{"p0", "p1", "p2", "p3", "p4", "resolution"}; +static const std::vector plot3DPIDNames{"TOF vs ITS", "ITS vs TPC", "TOF vs TPC"}; +static const std::vector openEventSelNames{"EvSelkIsGoodZvtxFT0vsPV", "EvSelkNoSameBunchPileup", "EvSelkNoCollInTimeRangeStandard", "EvSelkIsGoodITSLayersAll", "EvSelkNoCollInRofStandard", "EvSelkNoHighMultCollInPrevRof", "EvSelOccupancy", "EvSelMultCorrelationPVTracks", "EvSelMultCorrelationGlobalTracks", "EvSelV0AT0ACut"}; +static const std::vector openTrackSelNames{"passedITSNCls", "passedITSChi2NDF", "passedITSHits", "passedTPCChi2NDF", "passedTPCCrossedRowsOverNCls", "passedDCAxy", "passedDCAz"}; +static const std::vector plot3DConfigNames{"Open related 3D nSigma plots"}; +static const std::vector openEventSelConfigNames{"Open related event selection options"}; +static const std::vector openTrackSelConfigNames{"Open track selection from TrackSelection table"}; +static const std::vector pidTPCnSigmaNames{"n#sigma_{TPC} Low", "n#sigma_{TPC} High"}; +static const std::vector pidITSnSigmaNames{"n#sigma_{ITS} Low", "n#sigma_{ITS} High"}; +static const std::vector pidPtNames{"p_{T} Low", "p_{T} High"}; +std::vector eseCandidates; +// Tar ptr +std::shared_ptr hPIDQATar1D[12]; +std::shared_ptr hPIDQATar2D[4]; +std::shared_ptr hPIDQATar3D[3]; +std::shared_ptr hv2Tar[2]; +std::shared_ptr hESEQATar1D[2]; +std::shared_ptr hESEQATar2D; +std::shared_ptr hESETar; +// Ref ptr +std::shared_ptr hPIDQARef1D[12]; +std::shared_ptr hPIDQARef2D[4]; +std::shared_ptr hPIDQARef3D[3]; +std::shared_ptr hv2Ref[2]; +std::shared_ptr hESEQARef1D[2]; +std::shared_ptr hESEQARef2D; +} // namespace ese_parameters -using TracksPID = soa::Join; -struct FillPIDcolums { +using TracksPIDFull = soa::Join; - HistogramRegistry histosQA{"histosQAPID", {}, OutputObjHandlingPolicy::AnalysisObject}; +struct FlowEsePHe3 { + EventPlaneHelper helperEP; + o2::aod::ITSResponse itsResponse; + HistogramRegistry histsESE{"histsESE", {}, OutputObjHandlingPolicy::AnalysisObject}; + // process POI control + Configurable cfgTarName{"cfgTarName", "kHe3", "Name of the v2 particle: kProton, kDeuteron, kTriton, kHe3, kAlpha"}; + Configurable cfgRefName{"cfgRefName", "kProton", "Name of the q2 reference particle: kProton, kDeuteron, kTriton, kHe3, kAlpha"}; + // total control config + Configurable cfgOpenAllowCrossTrack{"cfgOpenAllowCrossTrack", false, "Allow one track to be identified as different kind of PID particles"}; + Configurable cfgOpenFullEventQA{"cfgOpenFullEventQA", true, "Open full QA plots for event QA"}; + Configurable cfgOpenPIDQA{"cfgOpenPIDQA", true, "Open PID QA plots"}; + Configurable cfgOpenv2{"cfgOpenv2", true, "Open v2(EP)and q calculation for Proton and He3"}; + Configurable cfgOpenESE{"cfgOpenESE", true, "Open ESE plots"}; + Configurable cfgOpenESEQA{"cfgOpenESEQA", true, "Open ESE QA plots"}; + Configurable> cfgOpen3DPIDPlots{"cfgOpen3DPIDPlots", {ese_parameters::Open3DPIDPlots[0], 3, 1, ese_parameters::plot3DPIDNames, ese_parameters::plot3DConfigNames}, "3D PID QA Plots switch configuration"}; + // Qvec configs + Configurable cfgDetName{"cfgDetName", "FT0C", "The name of detector to be analyzed"}; + Configurable cfgRefAName{"cfgRefAName", "TPCpos", "The name of detector for reference A"}; + Configurable cfgRefBName{"cfgRefBName", "TPCneg", "The name of detector for reference B"}; + Configurable cfgnTotalSystem{"cfgnTotalSystem", 7, "total qvector number"}; + // pre event selection(filter) + Configurable cfgVtzCut{"cfgVtzCut", 10.0f, "Accepted z-vertex range"}; + Configurable cfgCentMin{"cfgCentMin", 0.0f, "Centrality min"}; + Configurable cfgCentMax{"cfgCentMax", 100.0f, "Centrality max"}; + // event selection configs + Configurable cfgCutOccupancyLow{"cfgCutOccupancyLow", 0, "Low boundary cut on TPC occupancy"}; + Configurable cfgCutOccupancyHigh{"cfgCutOccupancyHigh", 3000, "High boundary cut on TPC occupancy"}; + Configurable> cfgOpenEvSel{"cfgOpenEvSel", {ese_parameters::OpenEvSel[0], 10, 1, ese_parameters::openEventSelNames, ese_parameters::openEventSelConfigNames}, "Event selection switch configuration"}; + // track selection configs + Configurable> cfgOpenTrackSel{"cfgOpenTrackSel", {ese_parameters::OpenTrackSel[0], 7, 1, ese_parameters::openTrackSelNames, ese_parameters::openTrackSelConfigNames}, "Track selection switch configuration"}; Configurable cfgMinPtPID{"cfgMinPtPID", 0.15, "Minimum track #P_{t} for PID"}; Configurable cfgMaxPtPID{"cfgMaxPtPID", 99.9, "Maximum track #P_{t} for PID"}; Configurable cfgMaxEtaPID{"cfgMaxEtaPID", 0.8, "Maximum track #eta for PID"}; @@ -101,516 +272,152 @@ struct FillPIDcolums { Configurable cfgMaxDCAxy{"cfgMaxDCAxy", 99, "Maxium DCAxy for standard PID tracking"}; Configurable cfgMaxDCAz{"cfgMaxDCAz", 2, "Maxium DCAz for standard PID tracking"}; Configurable cfgPtMaxforTPCOnlyPIDPrton{"cfgPtMaxforTPCOnlyPIDPrton", 0.4, "Maxmium track pt for TPC only PID, at RMS PID mode for proton"}; - Configurable cfgPtMaxforTPCOnlyPIDHe3{"cfgPtMaxforTPCOnlyPIDHe3", 0.5, "Maxmium track pt for TPC only PID, at RMS PID mode for he3"}; - - Configurable cfgProtonPIDMode{"cfgProtonPIDMode", 2, "Proton PID mode: 0 for TPC + RMS(TPC,TOF), 1 for TPC only, 2 for TOF only"}; - Configurable cfgHe3PIDMode{"cfgHe3PIDMode", 1, "He3 PID mode: 0 for TPC + RMS(TPC,TOF), 1 for TPC only, 2 for TOF only"}; - - Configurable cfgOpenpassedITSNCls{"cfgOpenpassedITSNCls", false, "useTrackSelectionTables passedITSNCls for basic track selection"}; - Configurable cfgOpenpassedITSChi2NDF{"cfgOpenpassedITSChi2NDF", false, "useTrackSelectionTables passedITSChi2NDF for basic track selection"}; - Configurable cfgOpenpassedITSHits{"cfgOpenpassedITSHits", false, "useTrackSelectionTables passedITSHits for basic track selection"}; - Configurable cfgOpenpassedTPCChi2NDF{"cfgOpenpassedTPCChi2NDF", false, "useTrackSelectionTables passedTPCChi2NDF for basic track selection"}; - Configurable cfgOpenpassedTPCCrossedRowsOverNCls{"cfgOpenpassedTPCCrossedRowsOverNCls", false, "useTrackSelectionTables passedTPCCrossedRowsOverNCls for basic track selection"}; - Configurable cfgOpenpassedDCAxy{"cfgOpenpassedDCAxy", false, "useTrackSelectionTables passedDCAxy for basic track selection"}; - Configurable cfgOpenpassedDCAz{"cfgOpenpassedDCAz", false, "useTrackSelectionTables passedDCAz for basic track selection"}; - - Configurable cfgQuietMode{"cfgQuietMode", false, "open quiet mode for saving cpu cost and only do some basic QA plots"}; - Configurable cfgOpenPIDITSProton{"cfgOpenPIDITSProton", true, "open ITS assistance cut for proton PID"}; - Configurable cfgOpenPIDITSHe3{"cfgOpenPIDITSHe3", false, "open ITS assistance cut for He3 PID"}; - Configurable cfgOpenPIDByPtProtonMain{"cfgOpenPIDByPtProtonMain", false, "Selection Proton by pt its pt binnings for main selection"}; - Configurable cfgOpenPIDByPtHe3Main{"cfgOpenPIDByPtHe3Main", false, "Selection He3 by pt its pt binnings for main selection"}; - Configurable cfgOpenPIDByPtProtonITS{"cfgOpenPIDByPtProtonITS", false, "Selection Proton by pt its pt binnings for ITS selection"}; - Configurable cfgOpenPIDByPtHe3ITS{"cfgOpenPIDByPtHe3ITS", false, "Selection He3 by pt its pt binnings for ITS selection"}; - Configurable cfgOpenHe3ITSPtCut{"cfgOpenHe3ITSPtCut", true, "Do He3 ITS contamination cut"}; - Configurable cfgOpenAllowCrossTrack{"cfgOpenAllowCrossTrack", false, "Allow one track to be identified as different kind of PID particles"}; - - Configurable cfgOpenPlotnSigmaTOFITSPt{"cfgOpenPlotnSigmaTOFITSPt", true, "plot nSigmaTOF vs nSigmaITS vs Pt"}; - Configurable cfgOpenPlotnSigmaITSTPCPt{"cfgOpenPlotnSigmaITSTPCPt", true, "plot nSigmaITS vs nSigmaTOF vs Pt"}; - Configurable cfgOpenPlotnSigmaTOFTPCPt{"cfgOpenPlotnSigmaTOFTPCPt", true, "plot nSigmaTOF vs nSigmaTPC vs Pt"}; - - Configurable> cfgPtCutProton{"cfgPtCutProton", {0.15, 99.}, "Pt limit for Proton"}; - Configurable> cfgPtCutHe3{"cfgPtCutHe3", {0.15, 99.}, "Pt limit for He3"}; - Configurable> cfgnSigmaCutTPCProton{"cfgnSigmaCutTPCProton", {-3, 3}, "TPC nsigma cut limit for Proton"}; - Configurable> cfgnSigmaCutTPCHe3{"cfgnSigmaCutTPCHe3", {-2, 2}, "TPC nsigma cut limit for He3"}; + // PID configs + Configurable> cfgPtPreselection{"cfgPtPreselection", {ese_parameters::PtPreselection[0], 5, 2, ese_parameters::names, ese_parameters::pidPtNames}, "Pt preselection for light nuclei"}; Configurable> cfgnSigmaCutTOFProton{"cfgnSigmaCutTOFProton", {-1.5, 1.5}, "TOF nsigma cut limit for Proton"}; - Configurable> cfgnSigmaCutTOFHe3{"cfgnSigmaCutTOFHe3", {-1.5, 1.5}, "TOF nsigma cut limit for He3"}; - Configurable> cfgnSigmaCutITSProton{"cfgnSigmaCutITSProton", {-3, 3}, "ITS nsigma cut limit for Proton"}; - Configurable> cfgnSigmaCutITSHe3{"cfgnSigmaCutITSHe3", {-3, 3}, "ITS nsigma cut limit for He3"}; Configurable> cfgnSigmaCutRMSProton{"cfgnSigmaCutRMSProton", {-3, 3}, "RMS nsigma cut limit for Proton"}; - Configurable> cfgnSigmaCutRMSHe3{"cfgnSigmaCutRMSHe3", {-3, 3}, "RMS nsigma cut limit for He3"}; - - Configurable> cfgPtBinProtonPID{"cfgPtBinProtonPID", {0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 3.0, 3.5, 4.0, 5.0, 6.0}, "pt bin for pion PIDnsigma"}; - Configurable> cfgPtBinHe3PID{"cfgPtBinHe3PID", {2, 2.2, 2.4, 2.6, 2.8, 3, 3.2, 3.6, 4, 4.4, 4.8, 5.2, 5.6, 6, 6.4, 7.2, 8, 10}, "pt bin for pion PIDnsigma"}; - - Configurable> cfgnSigmaTPCProtonPtUpper{"cfgnSigmaTPCProtonPtUpper", {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, "nSigmaTPC cut upper limit anchored to proton pt bins"}; - Configurable> cfgnSigmaTOFProtonPtUpper{"cfgnSigmaTOFProtonPtUpper", {1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5}, "nSigmaTOF cut upper limit anchored to proton pt bins"}; - Configurable> cfgnSigmaITSProtonPtUpper{"cfgnSigmaITSProtonPtUpper", {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, "nSigmaITS cut upper limit anchored to proton pt bins"}; - Configurable> cfgnSigmaRMSProtonPtUpper{"cfgnSigmaRMSProtonPtUpper", {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, "nSigmaRMS cut upper limit anchored to proton pt bins"}; - Configurable> cfgnSigmaTPCProtonPtLower{"cfgnSigmaTPCProtonPtLower", {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3}, "nSigmaTPC cut lower limit anchored to proton pt bins"}; - Configurable> cfgnSigmaTOFProtonPtLower{"cfgnSigmaTOFProtonPtLower", {-1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5}, "nSigmaTOF cut lower limit anchored to proton pt bins"}; - Configurable> cfgnSigmaITSProtonPtLower{"cfgnSigmaITSProtonPtLower", {-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, "nSigmaITS cut lower limit anchored to proton pt bins"}; - Configurable> cfgnSigmaRMSProtonPtLower{"cfgnSigmaRMSProtonPtLower", {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3}, "nSigmaRMS cut lower limit anchored to proton pt bins"}; - Configurable> cfgnSigmaTPCHe3PtUpper{"cfgnSigmaTPCHe3PtUpper", {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, "nSigmaTPC cut upper limit anchored to He3 pt bins"}; - Configurable> cfgnSigmaTOFHe3PtUpper{"cfgnSigmaTOFHe3PtUpper", {1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5}, "nSigmaTOF cut upper limit anchored to He3 pt bins"}; - Configurable> cfgnSigmaITSHe3PtUpper{"cfgnSigmaITSHe3PtUpper", {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, "nSigmaITS cut upper limit anchored to He3 pt bins"}; - Configurable> cfgnSigmaRMSHe3PtUpper{"cfgnSigmaRMSHe3PtUpper", {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, "nSigmaRMS cut upper limit anchored to He3 pt bins"}; - Configurable> cfgnSigmaTPCHe3PtLower{"cfgnSigmaTPCHe3PtLower", {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3}, "nSigmaTPC cut lower limit anchored to He3 pt bins"}; - Configurable> cfgnSigmaTOFHe3PtLower{"cfgnSigmaTOFHe3PtLower", {-1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5}, "nSigmaTOF cut lower limit anchored to He3 pt bins"}; - Configurable> cfgnSigmaITSHe3PtLower{"cfgnSigmaITSHe3PtLower", {-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, "nSigmaITS cut lower limit anchored to He3 pt bins"}; - Configurable> cfgnSigmaRMSHe3PtLower{"cfgnSigmaRMSHe3PtLower", {-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3}, "nSigmaRMS cut lower limit anchored to He3 pt bins"}; - + Configurable cfgUseSelfnSigmaTPCProton{"cfgUseSelfnSigmaTPCProton", false, "Use self nSigma TPC for Proton PID"}; + Configurable cfgProtonPIDMode{"cfgProtonPIDMode", 2, "Proton PID mode: 0 for TPC + RMS(TPC,TOF), 1 for TPC only, 2 for TOF only"}; + Configurable> cfgnSigmaTPC{"cfgnSigmaTPC", {ese_parameters::TPCnSigmaCutDefault[0], 5, 2, ese_parameters::names, ese_parameters::pidTPCnSigmaNames}, "TPC nSigma selection for light nuclei"}; + Configurable> cfgnSigmaITS{"cfgnSigmaITS", {ese_parameters::ITSnSigmaCutDefault[0], 5, 2, ese_parameters::names, ese_parameters::pidITSnSigmaNames}, "ITS nSigma selection for light nuclei"}; + // PID BBself paras config + Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {ese_parameters::BetheBlochDefault[0], 5, 6, ese_parameters::names, ese_parameters::betheBlochParNames}, "TPC Bethe-Bloch parameterisation for light nuclei"}; + Configurable> cfgMomentumScalingBetheBloch{"cfgMomentumScalingBetheBloch", {ese_parameters::BbMomScalingDefault[0], 5, 2, ese_parameters::names, ese_parameters::chargeLabelNames}, "TPC Bethe-Bloch momentum scaling for light nuclei"}; + Configurable cfgCompensatePIDinTracking{"cfgCompensatePIDinTracking", true, "If true, divide tpcInnerParam by the electric charge"}; + // Axias configs ConfigurableAxis cfgrigidityBins{"cfgrigidityBins", {200, -10.f, 10.f}, "Binning for rigidity #it{p}^{TPC}/#it{z}"}; ConfigurableAxis cfgdedxBins{"cfgdedxBins", {1000, 0.f, 1000.f}, "Binning for dE/dx"}; ConfigurableAxis cfgnSigmaBinsTPC{"cfgnSigmaBinsTPC", {200, -5.f, 5.f}, "Binning for n sigma TPC"}; ConfigurableAxis cfgnSigmaBinsTOF{"cfgnSigmaBinsTOF", {200, -5.f, 5.f}, "Binning for n sigma TOF"}; ConfigurableAxis cfgnSigmaBinsITS{"cfgnSigmaBinsITS", {200, -5.f, 5.f}, "Binning for n sigma ITS"}; - ConfigurableAxis cfgnSigmaBinsRMS{"cfgnSigmaBinsRMS", {100, 0.f, 10.f}, "Combination Binning for TPC&TOF nsigma"}; - ConfigurableAxis cfgaxisptPID{"cfgaxisptPID", {120, 0, 12}, "Binning for P_{t} PID"}; - ConfigurableAxis cfgaxispPID{"cfgaxispPID", {50, 0, 5}, "Binning for P PID"}; + ConfigurableAxis cfgaxispt{"cfgaxispt", {100, 0, 10}, "Binning for P_{t}"}; ConfigurableAxis cfgaxisetaPID{"cfgaxisetaPID", {90, -0.9, 0.9}, "Binning for Pt QA"}; ConfigurableAxis cfgaxisDCAz{"cfgaxisDCAz", {200, -1, 1}, "Binning for DCAz"}; ConfigurableAxis cfgaxisDCAxy{"cfgaxisDCAxy", {100, -0.5, 0.5}, "Binning for DCAxy"}; - ConfigurableAxis cfgaxisChi2Ncls{"cfgaxisChi2Ncls", {100, 0, 100}, "Binning for Chi2Ncls TPC/ITS"}; + ConfigurableAxis cfgaxisChi2Ncls{"cfgaxisChi2Ncls", {100, 0, 30}, "Binning for Chi2Ncls TPC/ITS"}; + ConfigurableAxis cfgaxisQvecF{"cfgaxisQvecF", {300, -1, 1}, ""}; + ConfigurableAxis cfgaxisCent{"cfgaxisCent", {90, 0, 90}, ""}; + ConfigurableAxis cfgaxisNch{"cfgaxisNch", {4000, 0, 4000}, "N_{ch}"}; + ConfigurableAxis cfgaxisT0C{"cfgaxisT0C", {70, 0, 70000}, "N_{ch} (T0C)"}; + ConfigurableAxis cfgaxisT0A{"cfgaxisT0A", {200, 0, 200000}, "N_{ch} (T0A)"}; + ConfigurableAxis cfgaxisNchPV{"cfgaxisNchPV", {4000, 0, 4000}, "N_{ch} (PV)"}; + ConfigurableAxis cfgaxisq2{"cfgaxisq2", {120, 0, 12}, "Binning for P_{t} PID"}; + ConfigurableAxis cfgaxiscos{"cfgaxiscos", {102, -1.02, 1.02}, ""}; - // Function for He3 TPC-ITS mismatching cuts referd to by chiara's slides - TF1* fNSigmaITSPt = nullptr; + uint8_t poiTar; + uint8_t poiRef; + int detId; + int refAId; + int refBId; + int detInd; + int refAInd; + int refBInd; + // Function for He3 purity cut refered from luca's slides + TF1* fMultPVCutLow = nullptr; + TF1* fMultPVCutHigh = nullptr; + TF1* fMultCutLow = nullptr; + TF1* fMultCutHigh = nullptr; + TF1* fT0AV0AMean = nullptr; + TF1* fT0AV0ASigma = nullptr; - template - bool trackSelBasic(const TrackType track) - { - if ((track.pt() < cfgMinPtPID) || (track.pt() > cfgMaxPtPID)) - return false; - if (std::abs(track.eta()) > cfgMaxEtaPID) - return false; - if (cfgOpenpassedITSNCls) { - if (!track.passedITSNCls()) - return false; - } else { - if (track.itsNCls() < cfgMinITSCls || track.itsNCls() > cfgMaxITSCls) - return false; - } - if (cfgOpenpassedITSChi2NDF) { - if (!track.passedITSChi2NDF()) - return false; - } else { - if (track.itsChi2NCl() < cfgMinChi2NClITS || track.itsChi2NCl() > cfgMaxChi2NClITS) - return false; - } - if (cfgOpenpassedITSHits) { - if (!track.passedITSHits()) - return false; - } - if (cfgOpenpassedTPCChi2NDF) { - if (!track.passedTPCChi2NDF()) - return false; - } else { - if (track.tpcChi2NCl() < cfgMinTPCChi2NCl || track.tpcChi2NCl() > cfgMaxTPCChi2NCl) - return false; - } - if (cfgOpenpassedTPCCrossedRowsOverNCls) { - if (!track.passedTPCCrossedRowsOverNCls()) - return false; - } - if (cfgOpenpassedDCAxy) { - if (!track.passedDCAxy()) - return false; - } else { - if (std::abs(track.dcaXY()) > cfgMaxDCAxy) - return false; - } - if (cfgOpenpassedDCAz) { - if (!track.passedDCAz()) - return false; - } else { - if (std::abs(track.dcaZ()) > cfgMaxDCAz) - return false; - } - if (track.tpcNClsFound() < cfgMinTPCCls || track.tpcNClsFound() > cfgMaxTPCCls) - return false; - return true; - } + Filter collisionFilter = (nabs(aod::collision::posZ) < cfgVtzCut) && (aod::cent::centFT0C > cfgCentMin) && (aod::cent::centFT0C < cfgCentMax); - template - bool pidProtonSel(const TrackType track, float nSigmaLower, float nSigmaUpper) - { // proton == 1 , He3 == 2 - if (track.pt() < cfgPtCutProton.value[0] || track.pt() > cfgPtCutProton.value[1]) - return false; - float nSigmaUse = -999; - switch (cfgProtonPIDMode) { - case 0: // RMS - nSigmaUse = (track.pt() > cfgPtMaxforTPCOnlyPIDPrton) ? std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr()) : track.tpcNSigmaPr(); - break; - case 1: // TPC only - nSigmaUse = track.tpcNSigmaPr(); - break; - case 2: // TOF only - nSigmaUse = track.tofNSigmaPr(); - break; - } - if (nSigmaUse < nSigmaLower || nSigmaUse > nSigmaUpper) { - return false; - } else { - return true; - } - } + Produces eseTable; template - bool pidHe3Sel(const TrackType track, float nSigmaLower, float nSigmaUpper) - { // proton == 1 , He3 == 2 - if (track.pt() < cfgPtCutHe3.value[0] || track.pt() > cfgPtCutHe3.value[1]) - return false; - float nSigmaUse = -999; - switch (cfgHe3PIDMode) { - case 0: // RMS - nSigmaUse = (track.pt() > cfgPtMaxforTPCOnlyPIDHe3) ? std::hypot(track.tpcNSigmaHe(), track.tofNSigmaHe()) : track.tpcNSigmaHe(); - break; - case 1: // TPC only - nSigmaUse = track.tpcNSigmaHe(); - break; - case 2: // TOF only - nSigmaUse = track.tofNSigmaHe(); - break; - } - if (nSigmaUse < nSigmaLower || nSigmaUse > nSigmaUpper) { - return false; - } else { - return true; + float getNSigmaTPCSelfBB(const TrackType track, uint8_t POI) + { + bool heliumPID = track.pidForTracking() == o2::track::PID::Helium3 || track.pidForTracking() == o2::track::PID::Alpha; + float correctedTpcInnerParam = (heliumPID && cfgCompensatePIDinTracking) ? track.tpcInnerParam() / 2 : track.tpcInnerParam(); + const int iC{track.sign() < 0}; + switch (POI) { + case ese_parameters::kProton: { + const double bgScaling[2]{ese_parameters::Charges[0] * cfgMomentumScalingBetheBloch->get(0u, 0u) / ese_parameters::Masses[0], ese_parameters::Charges[0] * cfgMomentumScalingBetheBloch->get(0u, 1u) / ese_parameters::Masses[0]}; + double expBethe{tpc::BetheBlochAleph(static_cast(correctedTpcInnerParam * bgScaling[iC]), cfgBetheBlochParams->get(0u, 0u), cfgBetheBlochParams->get(0u, 1u), cfgBetheBlochParams->get(0u, 2u), cfgBetheBlochParams->get(0u, 3u), cfgBetheBlochParams->get(0u, 4u))}; + double expSigma{expBethe * cfgBetheBlochParams->get(0u, 5u)}; + double nSigmaTPC{static_cast((track.tpcSignal() - expBethe) / expSigma)}; + return nSigmaTPC; + } + case ese_parameters::kDeuteron: { + const double bgScaling[2]{ese_parameters::Charges[1] * cfgMomentumScalingBetheBloch->get(1u, 0u) / ese_parameters::Masses[1], ese_parameters::Charges[1] * cfgMomentumScalingBetheBloch->get(1u, 1u) / ese_parameters::Masses[1]}; + double expBethe{tpc::BetheBlochAleph(static_cast(correctedTpcInnerParam * bgScaling[iC]), cfgBetheBlochParams->get(1u, 0u), cfgBetheBlochParams->get(1u, 1u), cfgBetheBlochParams->get(1u, 2u), cfgBetheBlochParams->get(1u, 3u), cfgBetheBlochParams->get(1u, 4u))}; + double expSigma{expBethe * cfgBetheBlochParams->get(1u, 5u)}; + double nSigmaTPC{static_cast((track.tpcSignal() - expBethe) / expSigma)}; + return nSigmaTPC; + } + case ese_parameters::kTriton: { + const double bgScaling[2]{ese_parameters::Charges[2] * cfgMomentumScalingBetheBloch->get(2u, 0u) / ese_parameters::Masses[2], ese_parameters::Charges[2] * cfgMomentumScalingBetheBloch->get(2u, 1u) / ese_parameters::Masses[2]}; + double expBethe{tpc::BetheBlochAleph(static_cast(correctedTpcInnerParam * bgScaling[iC]), cfgBetheBlochParams->get(2u, 0u), cfgBetheBlochParams->get(2u, 1u), cfgBetheBlochParams->get(2u, 2u), cfgBetheBlochParams->get(2u, 3u), cfgBetheBlochParams->get(2u, 4u))}; + double expSigma{expBethe * cfgBetheBlochParams->get(2u, 5u)}; + double nSigmaTPC{static_cast((track.tpcSignal() - expBethe) / expSigma)}; + return nSigmaTPC; + } + case ese_parameters::kHe3: { + const double bgScaling[2]{ese_parameters::Charges[3] * cfgMomentumScalingBetheBloch->get(3u, 0u) / ese_parameters::Masses[3], ese_parameters::Charges[3] * cfgMomentumScalingBetheBloch->get(3u, 1u) / ese_parameters::Masses[3]}; + double expBethe{tpc::BetheBlochAleph(static_cast(correctedTpcInnerParam * bgScaling[iC]), cfgBetheBlochParams->get(3u, 0u), cfgBetheBlochParams->get(3u, 1u), cfgBetheBlochParams->get(3u, 2u), cfgBetheBlochParams->get(3u, 3u), cfgBetheBlochParams->get(3u, 4u))}; + double expSigma{expBethe * cfgBetheBlochParams->get(3u, 5u)}; + double nSigmaTPC{static_cast((track.tpcSignal() - expBethe) / expSigma)}; + return nSigmaTPC; + } + case ese_parameters::kAlpha: { + const double bgScaling[2]{ese_parameters::Charges[4] * cfgMomentumScalingBetheBloch->get(4u, 0u) / ese_parameters::Masses[4], ese_parameters::Charges[4] * cfgMomentumScalingBetheBloch->get(4u, 1u) / ese_parameters::Masses[4]}; + double expBethe{tpc::BetheBlochAleph(static_cast(correctedTpcInnerParam * bgScaling[iC]), cfgBetheBlochParams->get(4u, 0u), cfgBetheBlochParams->get(4u, 1u), cfgBetheBlochParams->get(4u, 2u), cfgBetheBlochParams->get(4u, 3u), cfgBetheBlochParams->get(4u, 4u))}; + double expSigma{expBethe * cfgBetheBlochParams->get(4u, 5u)}; + double nSigmaTPC{static_cast((track.tpcSignal() - expBethe) / expSigma)}; + return nSigmaTPC; + } + default: + return -99.f; } } template - int crossTrackID(const TrackType track) + float getNSigmaTOF(const TrackType track, uint8_t POI) { - if (track.tpcNSigmaPr() < track.tpcNSigmaHe()) { - return 0; - } else { - return 1; + switch (POI) { + case ese_parameters::kProton: { + return track.tofNSigmaPr(); + } + case ese_parameters::kDeuteron: { + return track.tofNSigmaDe(); + } + case ese_parameters::kTriton: { + return track.tofNSigmaTr(); + } + case ese_parameters::kHe3: { + return track.tofNSigmaHe(); + } + case ese_parameters::kAlpha: { + return track.tofNSigmaAl(); + } + default: + return -99.f; } } - void init(InitContext const&) + template + float getNSigmaITS(const TrackType track, uint8_t POI) { - if (cfgOpenHe3ITSPtCut) { - fNSigmaITSPt = new TF1("fNSigmaITSPt", "[0]/pow(x,0.5) - [2]", 0.02, 1000); - fNSigmaITSPt->SetParameters(4.6, 0.5, 4.5); - } - AxisSpec axisITSNcls = {10, -1.5, 8.5, "ITSNcls"}; - AxisSpec axisTPCNcls = {160, 0, 160, "TPCNcls"}; - if (!cfgQuietMode) { - histosQA.add("QA/hist_dEdxTPC_All", ";#it{p}^{TPC}/#it{z} (GeV/c);d#it{E}/d#it{x}", {HistType::kTH2F, {cfgrigidityBins, cfgdedxBins}}); - histosQA.add("QA/Proton/hist_dEdxTPC_Pr", ";#it{p}^{TPC}/#it{z} (GeV/c);d#it{E}/d#it{x}", {HistType::kTH2F, {cfgrigidityBins, cfgdedxBins}}); - histosQA.add("QA/He3/hist_dEdxTPC_He3", ";#it{p}^{TPC}/#it{z} (GeV/c);d#it{E}/d#it{x}", {HistType::kTH2F, {cfgrigidityBins, cfgdedxBins}}); - histosQA.add("QA/hist_pt_All", ";#it{p}_{T};counts", {HistType::kTH1F, {cfgaxisptPID}}); - histosQA.add("QA/Proton/hist_pt_Pr", ";#it{p}_{T};counts", {HistType::kTH1F, {cfgaxisptPID}}); - histosQA.add("QA/He3/hist_pt_He3", ";#it{p}_{T};counts", {HistType::kTH1F, {cfgaxisptPID}}); - histosQA.add("QA/hist_eta_All", ";#it{#eta};counts", {HistType::kTH1F, {cfgaxisetaPID}}); - histosQA.add("QA/Proton/hist_eta_Pr", ";#it{#eta};counts", {HistType::kTH1F, {cfgaxisetaPID}}); - histosQA.add("QA/He3/hist_eta_He3", ";#it{#eta};counts", {HistType::kTH1F, {cfgaxisetaPID}}); - histosQA.add("QA/hist_ITSNcls_All", ";ITSNcls;counts", {HistType::kTH1F, {axisITSNcls}}); - histosQA.add("QA/Proton/hist_ITSNcls_Pr", ";ITSNcls;counts", {HistType::kTH1F, {axisITSNcls}}); - histosQA.add("QA/He3/hist_ITSNcls_He3", ";ITSNcls;counts", {HistType::kTH1F, {axisITSNcls}}); - histosQA.add("QA/hist_TPCNcls_All", ";TPCNcls;counts", {HistType::kTH1F, {axisTPCNcls}}); - histosQA.add("QA/Proton/hist_TPCNcls_Pr", ";TPCNcls;counts", {HistType::kTH1F, {axisTPCNcls}}); - histosQA.add("QA/He3/hist_TPCNcls_He3", ";TPCNcls;counts", {HistType::kTH1F, {axisTPCNcls}}); - histosQA.add("QA/hist_ITSChi2NDF_All", ";ITS#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); - histosQA.add("QA/Proton/hist_ITSChi2NDF_Pr", ";ITS#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); - histosQA.add("QA/He3/hist_ITSChi2NDF_He3", ";ITS#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); - histosQA.add("QA/hist_TPCChi2NDF_All", ";TPC#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); - histosQA.add("QA/Proton/hist_TPCChi2NDF_Pr", ";TPC#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); - histosQA.add("QA/He3/hist_TPCChi2NDF_He3", ";TPC#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); - histosQA.add("QA/hist_DCAxy_All", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAxy}}); - histosQA.add("QA/Proton/hist_DCAxy_Pr", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAxy}}); - histosQA.add("QA/He3/hist_DCAxy_He3", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAxy}}); - histosQA.add("QA/hist_DCAz_All", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAz}}); - histosQA.add("QA/Proton/hist_DCAz_Pr", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAz}}); - histosQA.add("QA/He3/hist_DCAz_He3", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAz}}); - histosQA.add("QA/Proton/hist_nSigmaTPC_Pr", ";n_{#sigma}TPC", {HistType::kTH1F, {cfgnSigmaBinsTPC}}); - histosQA.add("QA/Proton/hist_nSigmaTPCPt_Pr", ";#it{p}_{T};n_{#sigma}TPC", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsTPC}}); - histosQA.add("QA/Proton/hist_nSigmaTOF_Pr", ";n_{#sigma}TOF", {HistType::kTH1F, {cfgnSigmaBinsTOF}}); - histosQA.add("QA/Proton/hist_nSigmaTOFPt_Pr", ";#it{p}_{T};n_{#sigma}TOF", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsTOF}}); - histosQA.add("QA/Proton/hist_nSigmaITS_Pr", ";n_{#sigma}ITS", {HistType::kTH1F, {cfgnSigmaBinsITS}}); - histosQA.add("QA/Proton/hist_nSigmaITSPt_Pr", ";#it{p}_{T};n_{#sigma}ITS", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsITS}}); - histosQA.add("QA/Proton/hist_nSigmaRMS_Pr", ";n_{#sigma}RMS", {HistType::kTH1F, {cfgnSigmaBinsRMS}}); - histosQA.add("QA/Proton/hist_nSigmaRMSPt_Pr", ";#it{p}_{T};n_{#sigma}RMS", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsRMS}}); - histosQA.add("QA/He3/hist_nSigmaTPC_He3", ";n_{#sigma}TPC", {HistType::kTH1F, {cfgnSigmaBinsTPC}}); - histosQA.add("QA/He3/hist_nSigmaTPCPt_He3", ";#it{p}_{T};n_{#sigma}TPC", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsTPC}}); - histosQA.add("QA/He3/hist_nSigmaTOF_He3", ";n_{#sigma}TOF", {HistType::kTH1F, {cfgnSigmaBinsTOF}}); - histosQA.add("QA/He3/hist_nSigmaTOFPt_He3", ";#it{p}_{T};n_{#sigma}TOF", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsTOF}}); - histosQA.add("QA/He3/hist_nSigmaITS_He3", ";n_{#sigma}ITS", {HistType::kTH1F, {cfgnSigmaBinsITS}}); - histosQA.add("QA/He3/hist_nSigmaITSPt_He3", ";#it{p}_{T};n_{#sigma}ITS", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsITS}}); - histosQA.add("QA/He3/hist_nSigmaRMS_He3", ";n_{#sigma}RMS", {HistType::kTH1F, {cfgnSigmaBinsRMS}}); - histosQA.add("QA/He3/hist_nSigmaRMSPt_He3", ";#it{p}_{T};n_{#sigma}RMS", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsRMS}}); - if (cfgOpenHe3ITSPtCut) { - histosQA.add("QA/He3/hist_nSigmaITSPt_He3_unCuted", ";#it{p}_{T};n_{#sigma}ITS", {HistType::kTH2F, {cfgaxisptPID, cfgnSigmaBinsITS}}); + switch (POI) { + case ese_parameters::kProton: { + return itsResponse.nSigmaITS(track); } - if (cfgOpenPlotnSigmaTOFITSPt) { - histosQA.add("QA/Proton/hist_nSigmaTOFITSPt_Pr", ";n_{#sigma}TOF;n_{#sigma}ITS;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsITS, cfgaxisptPID}}); - histosQA.add("QA/He3/hist_nSigmaTOFITSPt_He3", ";n_{#sigma}TOF;n_{#sigma}ITS;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsITS, cfgaxisptPID}}); + case ese_parameters::kDeuteron: { + return itsResponse.nSigmaITS(track); } - if (cfgOpenPlotnSigmaITSTPCPt) { - histosQA.add("QA/Proton/hist_nSigmaITSTPCPt_Pr", ";n_{#sigma}ITS;n_{#sigma}TPC;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsITS, cfgnSigmaBinsTPC, cfgaxisptPID}}); - histosQA.add("QA/He3/hist_nSigmaITSTPCPt_He3", ";n_{#sigma}ITS;n_{#sigma}TPC;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsITS, cfgnSigmaBinsTPC, cfgaxisptPID}}); + case ese_parameters::kTriton: { + return itsResponse.nSigmaITS(track); } - if (cfgOpenPlotnSigmaTOFTPCPt) { - histosQA.add("QA/Proton/hist_nSigmaTOFTPCPt_Pr", ";n_{#sigma}TOF;n_{#sigma}TPC;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsTPC, cfgaxisptPID}}); - histosQA.add("QA/He3/hist_nSigmaTOFTPCPt_He3", ";n_{#sigma}TOF;n_{#sigma}TPC;#it{p}_{T}", {HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsTPC, cfgaxisptPID}}); + case ese_parameters::kHe3: { + return itsResponse.nSigmaITS(track); } - } - } - Produces pidEsePHe3Table; - void process(TracksPID const& tracks) - { - auto tracksWithITSPid = soa::Attach(tracks); - int8_t pidFlag; - for (const auto& track : tracksWithITSPid) { - histosQA.fill(HIST("QA/hist_dEdxTPC_All"), track.sign() * track.tpcInnerParam(), track.tpcSignal()); - histosQA.fill(HIST("QA/hist_pt_All"), track.pt()); - histosQA.fill(HIST("QA/hist_eta_All"), track.eta()); - histosQA.fill(HIST("QA/hist_ITSNcls_All"), track.itsNCls()); - histosQA.fill(HIST("QA/hist_TPCNcls_All"), track.tpcNClsFound()); - histosQA.fill(HIST("QA/hist_ITSChi2NDF_All"), track.itsChi2NCl()); - histosQA.fill(HIST("QA/hist_TPCChi2NDF_All"), track.tpcChi2NCl()); - histosQA.fill(HIST("QA/hist_DCAxy_All"), track.dcaXY()); - histosQA.fill(HIST("QA/hist_DCAz_All"), track.dcaZ()); - if (!trackSelBasic(track)) { - pidFlag = -1; - } else { - int currentPtBinPr = -1, currentPtBinHe3 = -1; - if (cfgOpenPIDByPtProtonMain || (cfgOpenPIDByPtProtonITS && cfgOpenPIDITSProton)) { - for (int i = 0; i < static_cast(cfgPtBinProtonPID.value.size()) - 1; ++i) { - if (track.pt() >= cfgPtBinProtonPID.value[i] && track.pt() < cfgPtBinProtonPID.value[i + 1]) { - currentPtBinPr = i; - break; - } - } - } - if (cfgOpenPIDByPtHe3Main || (cfgOpenPIDByPtHe3ITS && cfgOpenPIDITSHe3)) { - for (int i = 0; i < static_cast(cfgPtBinHe3PID.value.size()) - 1; ++i) { - if (track.pt() >= cfgPtBinHe3PID.value[i] && track.pt() < cfgPtBinHe3PID.value[i + 1]) { - currentPtBinHe3 = i; - break; - } - } - } - float nSigmaTPCCutPrPtLower = (currentPtBinPr == -1) ? cfgnSigmaCutTPCProton.value[0] : cfgnSigmaTPCProtonPtLower.value[currentPtBinPr]; - float nSigmaTPCCutPrPtUpper = (currentPtBinPr == -1) ? cfgnSigmaCutTPCProton.value[1] : cfgnSigmaTPCProtonPtUpper.value[currentPtBinPr]; - float nSigmaTOFCutPrPtLower = (currentPtBinPr == -1) ? cfgnSigmaCutTOFProton.value[0] : cfgnSigmaTOFProtonPtLower.value[currentPtBinPr]; - float nSigmaTOFCutPrPtUpper = (currentPtBinPr == -1) ? cfgnSigmaCutTOFProton.value[1] : cfgnSigmaTOFProtonPtUpper.value[currentPtBinPr]; - float nSigmaRMSCutPrPtLower = (currentPtBinPr == -1) ? cfgnSigmaCutRMSProton.value[0] : cfgnSigmaRMSProtonPtLower.value[currentPtBinPr]; - float nSigmaRMSCutPrPtUpper = (currentPtBinPr == -1) ? cfgnSigmaCutRMSProton.value[1] : cfgnSigmaRMSProtonPtUpper.value[currentPtBinPr]; - float nSigmaITSCutPrPtLower = (currentPtBinPr == -1) ? cfgnSigmaCutITSProton.value[0] : cfgnSigmaITSProtonPtLower.value[currentPtBinPr]; - float nSigmaITSCutPrPtUpper = (currentPtBinPr == -1) ? cfgnSigmaCutITSProton.value[1] : cfgnSigmaITSProtonPtUpper.value[currentPtBinPr]; - float nSigmaTPCCutHe3PtLower = (currentPtBinHe3 == -1) ? cfgnSigmaCutTPCHe3.value[0] : cfgnSigmaTPCHe3PtLower.value[currentPtBinHe3]; - float nSigmaTPCCutHe3PtUpper = (currentPtBinHe3 == -1) ? cfgnSigmaCutTPCHe3.value[1] : cfgnSigmaTPCHe3PtUpper.value[currentPtBinHe3]; - float nSigmaTOFCutHe3PtLower = (currentPtBinHe3 == -1) ? cfgnSigmaCutTOFHe3.value[0] : cfgnSigmaTOFHe3PtLower.value[currentPtBinHe3]; - float nSigmaTOFCutHe3PtUpper = (currentPtBinHe3 == -1) ? cfgnSigmaCutTOFHe3.value[1] : cfgnSigmaTOFHe3PtUpper.value[currentPtBinHe3]; - float nSigmaRMSCutHe3PtLower = (currentPtBinHe3 == -1) ? cfgnSigmaCutRMSHe3.value[0] : cfgnSigmaRMSHe3PtLower.value[currentPtBinHe3]; - float nSigmaRMSCutHe3PtUpper = (currentPtBinHe3 == -1) ? cfgnSigmaCutRMSHe3.value[1] : cfgnSigmaRMSHe3PtUpper.value[currentPtBinHe3]; - float nSigmaITSCutHe3PtLower = (currentPtBinHe3 == -1) ? cfgnSigmaCutITSHe3.value[0] : cfgnSigmaITSHe3PtLower.value[currentPtBinHe3]; - float nSigmaITSCutHe3PtUpper = (currentPtBinHe3 == -1) ? cfgnSigmaCutITSHe3.value[1] : cfgnSigmaITSHe3PtUpper.value[currentPtBinHe3]; - float nSigmaMainLowerPr = -999, nSigmaMainUpperPr = -999; - float nSigmaMainLowerHe3 = -999, nSigmaMainUpperHe3 = -999; - switch (cfgProtonPIDMode) { - case 0: - nSigmaMainLowerPr = nSigmaRMSCutPrPtLower; - nSigmaMainUpperPr = nSigmaRMSCutPrPtUpper; - break; - case 1: - nSigmaMainLowerPr = nSigmaTPCCutPrPtLower; - nSigmaMainUpperPr = nSigmaTPCCutPrPtUpper; - break; - case 2: - nSigmaMainLowerPr = nSigmaTOFCutPrPtLower; - nSigmaMainUpperPr = nSigmaTOFCutPrPtUpper; - break; - } - switch (cfgHe3PIDMode) { - case 0: - nSigmaMainLowerHe3 = nSigmaRMSCutHe3PtLower; - nSigmaMainUpperHe3 = nSigmaRMSCutHe3PtUpper; - break; - case 1: - nSigmaMainLowerHe3 = nSigmaTPCCutHe3PtLower; - nSigmaMainUpperHe3 = nSigmaTPCCutHe3PtUpper; - break; - case 2: - nSigmaMainLowerHe3 = nSigmaTOFCutHe3PtLower; - nSigmaMainUpperHe3 = nSigmaTOFCutHe3PtUpper; - break; - } - bool kIsPr = false, kIsHe3 = false; - // Identify Proton - if (pidProtonSel(track, nSigmaMainLowerPr, nSigmaMainUpperPr)) { - kIsPr = true; - if (cfgOpenPIDITSProton) { - if (track.itsNSigmaPr() < nSigmaITSCutPrPtLower || track.itsNSigmaPr() > nSigmaITSCutPrPtUpper) { - kIsPr = false; - } - } - } - // Identify He3 - if (pidHe3Sel(track, nSigmaMainLowerHe3, nSigmaMainUpperHe3)) { - kIsHe3 = true; - if (cfgOpenPIDITSHe3) { - if (track.itsNSigmaHe() < nSigmaITSCutHe3PtLower || track.itsNSigmaHe() > nSigmaITSCutHe3PtUpper) { - kIsHe3 = false; - } - } - } - // Cross track rejection - if (!cfgOpenAllowCrossTrack) { - if (kIsPr && kIsHe3) { - switch (crossTrackID(track)) { - case 0: - kIsPr = true; - kIsHe3 = false; - break; - case 1: - kIsPr = false; - kIsHe3 = true; - break; - } - } - } - // Filter He3 contaimination - if (cfgOpenHe3ITSPtCut && kIsHe3) { - if (!cfgQuietMode) { - histosQA.fill(HIST("QA/He3/hist_nSigmaITSPt_He3_unCuted"), track.pt(), track.itsNSigmaHe()); - } - if (track.itsNSigmaHe() < fNSigmaITSPt->Eval(track.pt())) { - kIsHe3 = false; - } - } - pidFlag = (kIsHe3 << 1) | kIsPr; - // Fill QA histograms - if (!cfgQuietMode) { - if (kIsPr) { - histosQA.fill(HIST("QA/Proton/hist_dEdxTPC_Pr"), track.sign() * track.tpcInnerParam(), track.tpcSignal()); - histosQA.fill(HIST("QA/Proton/hist_pt_Pr"), track.pt()); - histosQA.fill(HIST("QA/Proton/hist_eta_Pr"), track.eta()); - histosQA.fill(HIST("QA/Proton/hist_ITSNcls_Pr"), track.itsNCls()); - histosQA.fill(HIST("QA/Proton/hist_TPCNcls_Pr"), track.tpcNClsFound()); - histosQA.fill(HIST("QA/Proton/hist_ITSChi2NDF_Pr"), track.itsChi2NCl()); - histosQA.fill(HIST("QA/Proton/hist_TPCChi2NDF_Pr"), track.tpcChi2NCl()); - histosQA.fill(HIST("QA/Proton/hist_DCAxy_Pr"), track.dcaXY()); - histosQA.fill(HIST("QA/Proton/hist_DCAz_Pr"), track.dcaZ()); - histosQA.fill(HIST("QA/Proton/hist_nSigmaTPC_Pr"), track.tpcNSigmaPr()); - histosQA.fill(HIST("QA/Proton/hist_nSigmaTPCPt_Pr"), track.pt(), track.tpcNSigmaPr()); - histosQA.fill(HIST("QA/Proton/hist_nSigmaTOF_Pr"), track.tofNSigmaPr()); - histosQA.fill(HIST("QA/Proton/hist_nSigmaTOFPt_Pr"), track.pt(), track.tofNSigmaPr()); - histosQA.fill(HIST("QA/Proton/hist_nSigmaITS_Pr"), track.itsNSigmaPr()); - histosQA.fill(HIST("QA/Proton/hist_nSigmaITSPt_Pr"), track.pt(), track.itsNSigmaPr()); - histosQA.fill(HIST("QA/Proton/hist_nSigmaRMS_Pr"), std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr())); - histosQA.fill(HIST("QA/Proton/hist_nSigmaRMSPt_Pr"), track.pt(), std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr())); - if (cfgOpenPlotnSigmaTOFITSPt) { - histosQA.fill(HIST("QA/Proton/hist_nSigmaTOFITSPt_Pr"), track.tofNSigmaPr(), track.itsNSigmaPr(), track.pt()); - } - if (cfgOpenPlotnSigmaITSTPCPt) { - histosQA.fill(HIST("QA/Proton/hist_nSigmaITSTPCPt_Pr"), track.itsNSigmaPr(), track.tpcNSigmaPr(), track.pt()); - } - if (cfgOpenPlotnSigmaTOFTPCPt) { - histosQA.fill(HIST("QA/Proton/hist_nSigmaTOFTPCPt_Pr"), track.tofNSigmaPr(), track.tpcNSigmaPr(), track.pt()); - } - } - if (kIsHe3) { - histosQA.fill(HIST("QA/He3/hist_dEdxTPC_He3"), track.sign() * track.tpcInnerParam(), track.tpcSignal()); - histosQA.fill(HIST("QA/He3/hist_pt_He3"), track.pt()); - histosQA.fill(HIST("QA/He3/hist_eta_He3"), track.eta()); - histosQA.fill(HIST("QA/He3/hist_ITSNcls_He3"), track.itsNCls()); - histosQA.fill(HIST("QA/He3/hist_TPCNcls_He3"), track.tpcNClsFound()); - histosQA.fill(HIST("QA/He3/hist_ITSChi2NDF_He3"), track.itsChi2NCl()); - histosQA.fill(HIST("QA/He3/hist_TPCChi2NDF_He3"), track.tpcChi2NCl()); - histosQA.fill(HIST("QA/He3/hist_DCAxy_He3"), track.dcaXY()); - histosQA.fill(HIST("QA/He3/hist_DCAz_He3"), track.dcaZ()); - histosQA.fill(HIST("QA/He3/hist_nSigmaTPC_He3"), track.tpcNSigmaHe()); - histosQA.fill(HIST("QA/He3/hist_nSigmaTPCPt_He3"), track.pt(), track.tpcNSigmaHe()); - histosQA.fill(HIST("QA/He3/hist_nSigmaTOF_He3"), track.tofNSigmaHe()); - histosQA.fill(HIST("QA/He3/hist_nSigmaTOFPt_He3"), track.pt(), track.tofNSigmaHe()); - histosQA.fill(HIST("QA/He3/hist_nSigmaITS_He3"), track.itsNSigmaHe()); - histosQA.fill(HIST("QA/He3/hist_nSigmaITSPt_He3"), track.pt(), track.itsNSigmaHe()); - histosQA.fill(HIST("QA/He3/hist_nSigmaRMS_He3"), std::hypot(track.tpcNSigmaHe(), track.tofNSigmaHe())); - histosQA.fill(HIST("QA/He3/hist_nSigmaRMSPt_He3"), track.pt(), std::hypot(track.tpcNSigmaHe(), track.tofNSigmaHe())); - if (cfgOpenPlotnSigmaTOFITSPt) { - histosQA.fill(HIST("QA/He3/hist_nSigmaTOFITSPt_He3"), track.tofNSigmaHe(), track.itsNSigmaHe(), track.pt()); - } - if (cfgOpenPlotnSigmaITSTPCPt) { - histosQA.fill(HIST("QA/He3/hist_nSigmaITSTPCPt_He3"), track.itsNSigmaHe(), track.tpcNSigmaHe(), track.pt()); - } - if (cfgOpenPlotnSigmaTOFTPCPt) { - histosQA.fill(HIST("QA/He3/hist_nSigmaTOFTPCPt_He3"), track.tofNSigmaHe(), track.tpcNSigmaHe(), track.pt()); - } - } - } + case ese_parameters::kAlpha: { + return itsResponse.nSigmaITS(track); } - pidEsePHe3Table(pidFlag); + default: + return -99.f; } } -}; - -struct FlowEsePHe3 { - HistogramRegistry histos{"histosmain", {}, OutputObjHandlingPolicy::AnalysisObject}; - - Configurable> cfgnMods{"cfgnMods", {2}, "Modulation of interest"}; - Configurable cfgDetName{"cfgDetName", "FT0C", "The name of detector to be analyzed"}; - Configurable cfgRefAName{"cfgRefAName", "TPCpos", "The name of detector for reference A"}; - Configurable cfgRefBName{"cfgRefBName", "TPCneg", "The name of detector for reference B"}; - Configurable cfgnTotalSystem{"cfgnTotalSystem", 7, "total qvector number"}; - - Configurable cfgVtzCut{"cfgVtzCut", 10.0f, "Accepted z-vertex range"}; - Configurable cfgCentMin{"cfgCentMin", 0.0f, "Centrality min"}; - Configurable cfgCentMax{"cfgCentMax", 100.0f, "Centrality max"}; - - Configurable cfgCutOccupancyLow{"cfgCutOccupancyLow", 0, "Low boundary cut on TPC occupancy"}; - Configurable cfgCutOccupancyHigh{"cfgCutOccupancyHigh", 3000, "High boundary cut on TPC occupancy"}; - Configurable cfgUseAdditionalEventCut{"cfgUseAdditionalEventCut", true, "Use additional event cut beyond sel8"}; - Configurable cfgOpenEvSelkIsGoodZvtxFT0vsPV{"cfgOpenEvSelkIsGoodZvtxFT0vsPV", true, "removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference, use this cut at low multiplicities with caution"}; - Configurable cfgOpenEvSelkNoSameBunchPileup{"cfgOpenEvSelkNoSameBunchPileup", true, "rejects collisions which are associated with the same found-by-T0 bunch crossing"}; - Configurable cfgOpenEvSelkNoCollInTimeRangeStandard{"cfgOpenEvSelkNoCollInTimeRangeStandard", true, "no collisions in specified time range"}; - Configurable cfgOpenEvSelkIsGoodITSLayersAll{"cfgOpenEvSelkIsGoodITSLayersAll", true, "cut time intervals with dead ITS staves"}; - Configurable cfgOpenEvSelkNoCollInRofStandard{"cfgOpenEvSelkNoCollInRofStandard", true, "no other collisions in this Readout Frame with per-collision multiplicity above threshold"}; - Configurable cfgOpenEvSelkNoHighMultCollInPrevRof{"cfgOpenEvSelkNoHighMultCollInPrevRof", true, "veto an event if FT0C amplitude in previous ITS ROF is above threshold"}; - Configurable cfgOpenEvSelOccupancy{"cfgOpenEvSelOccupancy", true, "Occupancy cut"}; - Configurable cfgOpenEvSelMultCorrelationPVTracks{"cfgOpenEvSelMultCorrelationPVTracks", true, "Multiplicity correlation cut for PVtracks vs centrality(FT0C)"}; - Configurable cfgOpenEvSelMultCorrelationGlobalTracks{"cfgOpenEvSelMultCorrelationGlobalTracks", false, "Multiplicity correlation cut for Globaltracks vs centrality(FT0C)"}; - Configurable cfgOpenEvSelV0AT0ACut{"cfgOpenEvSelV0AT0ACut", true, "V0A T0A 5 sigma cut"}; - Configurable cfgOpenFullEventQA{"cfgOpenFullEventQA", true, "Open full QA plots for event QA"}; - Configurable cfgOpenv2q{"cfgOpenv2q", true, "Open v2(EP)and q calculation for Proton and He3"}; - Configurable cfgOpenESE{"cfgOpenESE", true, "Open ESE process"}; - Configurable cfgOpenESEChargeSeperation{"cfgOpenESEChargeSeperation", true, "Open ESE for postive and negative charge repectivily"}; - Configurable cfgOpenESEProton{"cfgOpenESEProton", true, "Open ESE Proton process"}; - Configurable cfgOpenESEHe3{"cfgOpenESEHe3", true, "Open ESE He3 process"}; - - ConfigurableAxis cfgaxisQvecF{"cfgaxisQvecF", {300, -1, 1}, ""}; - ConfigurableAxis cfgaxisCent{"cfgaxisCent", {90, 0, 90}, ""}; - ConfigurableAxis cfgaxispt{"cfgaxispt", {100, 0, 10}, ""}; - ConfigurableAxis cfgaxisCentForQA{"cfgaxisCentForQA", {100, 0, 100}, "centrality for event QA"}; - ConfigurableAxis cfgaxisNch{"cfgaxisNch", {4000, 0, 4000}, "N_{ch}"}; - ConfigurableAxis cfgaxisT0C{"cfgaxisT0C", {70, 0, 70000}, "N_{ch} (T0C)"}; - ConfigurableAxis cfgaxisT0A{"cfgaxisT0A", {200, 0, 200000}, "N_{ch} (T0A)"}; - ConfigurableAxis cfgaxisNchPV{"cfgaxisNchPV", {4000, 0, 4000}, "N_{ch} (PV)"}; - ConfigurableAxis cfgaxisq2{"cfgaxisq2", {120, 0, 12}, "Binning for P_{t} PID"}; - - EventPlaneHelper helperEP; - SliceCache cache; - - int detId; - int refAId; - int refBId; - // Additional Event selection cuts - Copy from flowGenericFramework.cxx - TF1* fMultPVCutLow = nullptr; - TF1* fMultPVCutHigh = nullptr; - TF1* fMultCutLow = nullptr; - TF1* fMultCutHigh = nullptr; - TF1* fT0AV0AMean = nullptr; - TF1* fT0AV0ASigma = nullptr; - - Filter collisionFilter = (nabs(aod::collision::posZ) < cfgVtzCut) && (aod::cent::centFT0C > cfgCentMin) && (aod::cent::centFT0C < cfgCentMax); - Filter properPIDfilter = aod::flow_ese_p_he3::nPidFlag >= (int8_t)0; // Only POI - - Partition>> protonTrackSet = ((aod::flow_ese_p_he3::nPidFlag == pid_flags::kProton) || (aod::flow_ese_p_he3::nPidFlag == pid_flags::kProtonHe3)); - Partition>> he3TrackSet = ((aod::flow_ese_p_he3::nPidFlag == pid_flags::kHe3) || (aod::flow_ese_p_he3::nPidFlag == pid_flags::kProtonHe3)); template int getDetId(const T& name) @@ -637,160 +444,409 @@ struct FlowEsePHe3 { } } + template + uint8_t getPOI(const T& POI) + { + if (POI.value == "kProton") { + return ese_parameters::kProton; + } else if (POI.value == "kDeuteron") { + return ese_parameters::kDeuteron; + } else if (POI.value == "kTriton") { + return ese_parameters::kTriton; + } else if (POI.value == "kHe3") { + return ese_parameters::kHe3; + } else if (POI.value == "kAlpha") { + return ese_parameters::kAlpha; + } else { + LOGF(warning, "Unknown POI: %s", POI.value.c_str()); + return 0; + } + } + + float calculateq2(const float qx, const float qy, const int multi) + { + if (multi <= 0) { + return 0.f; + } else { + return std::hypot(qx, qy) / std::sqrt(static_cast(multi)); + } + } + template - bool selEvent(const CollType& collision, const int multTrk, const float centrality) + bool eventSelBasic(const CollType& collision, const int64_t multTrk, const float centrality, bool fillQA) { - histos.fill(HIST("QA/histEventCountDetail"), 0.5); - if (cfgOpenEvSelkIsGoodZvtxFT0vsPV && !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { + if (!collision.sel8()) return false; + if (fillQA) { + histsESE.fill(HIST("EventQA/histEventCount"), 0.5); } - if (cfgOpenEvSelkIsGoodZvtxFT0vsPV) { - histos.fill(HIST("QA/histEventCountDetail"), 1.5); + if (cfgOpenEvSel->get(0u) && !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { + return false; + } + if (fillQA && cfgOpenEvSel->get(0u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 1.5); } - if (cfgOpenEvSelkNoSameBunchPileup && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { + if (cfgOpenEvSel->get(1u) && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { return false; } - if (cfgOpenEvSelkNoSameBunchPileup) { - histos.fill(HIST("QA/histEventCountDetail"), 2.5); + if (fillQA && cfgOpenEvSel->get(1u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 2.5); } - if (cfgOpenEvSelkNoCollInTimeRangeStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + if (cfgOpenEvSel->get(2u) && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { return false; } - if (cfgOpenEvSelkNoCollInTimeRangeStandard) { - histos.fill(HIST("QA/histEventCountDetail"), 3.5); + if (fillQA && cfgOpenEvSel->get(2u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 3.5); } - if (cfgOpenEvSelkIsGoodITSLayersAll && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + if (cfgOpenEvSel->get(3u) && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { return false; } - if (cfgOpenEvSelkIsGoodITSLayersAll) { - histos.fill(HIST("QA/histEventCountDetail"), 4.5); + if (fillQA && cfgOpenEvSel->get(3u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 4.5); } - if (cfgOpenEvSelkNoCollInRofStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + if (cfgOpenEvSel->get(4u) && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { return false; } - if (cfgOpenEvSelkNoCollInRofStandard) { - histos.fill(HIST("QA/histEventCountDetail"), 5.5); + if (fillQA && cfgOpenEvSel->get(4u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 5.5); } - if (cfgOpenEvSelkNoHighMultCollInPrevRof && !collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { + if (cfgOpenEvSel->get(5u) && !collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { return false; } - if (cfgOpenEvSelkNoHighMultCollInPrevRof) { - histos.fill(HIST("QA/histEventCountDetail"), 6.5); + if (fillQA && cfgOpenEvSel->get(5u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 6.5); } auto multNTracksPV = collision.multNTracksPV(); auto occupancy = collision.trackOccupancyInTimeRange(); - if (cfgOpenEvSelOccupancy && (occupancy < cfgCutOccupancyLow || occupancy > cfgCutOccupancyHigh)) { + if (cfgOpenEvSel->get(6u) && (occupancy < cfgCutOccupancyLow || occupancy > cfgCutOccupancyHigh)) { return false; } - if (cfgOpenEvSelOccupancy) { - histos.fill(HIST("QA/histEventCountDetail"), 7.5); + if (fillQA && cfgOpenEvSel->get(6u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 7.5); } - if (cfgOpenEvSelMultCorrelationPVTracks) { + if (cfgOpenEvSel->get(7u)) { if (multNTracksPV < fMultPVCutLow->Eval(centrality)) return false; if (multNTracksPV > fMultPVCutHigh->Eval(centrality)) return false; } - if (cfgOpenEvSelMultCorrelationPVTracks) { - histos.fill(HIST("QA/histEventCountDetail"), 8.5); + if (fillQA && cfgOpenEvSel->get(7u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 8.5); } - if (cfgOpenEvSelMultCorrelationGlobalTracks) { + if (cfgOpenEvSel->get(8u)) { if (multTrk < fMultCutLow->Eval(centrality)) return false; if (multTrk > fMultCutHigh->Eval(centrality)) return false; } - if (cfgOpenEvSelMultCorrelationGlobalTracks) { - histos.fill(HIST("QA/histEventCountDetail"), 9.5); + if (fillQA && cfgOpenEvSel->get(8u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 9.5); } - if (cfgOpenEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > event_selection::kFT0AV0ASigma * fT0AV0ASigma->Eval(collision.multFT0A()))) { + if (cfgOpenEvSel->get(9u) && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > ese_parameters::kFT0AV0ASigma * fT0AV0ASigma->Eval(collision.multFT0A()))) { return false; } - if (cfgOpenEvSelV0AT0ACut) { - histos.fill(HIST("QA/histEventCountDetail"), 10.5); + if (fillQA && cfgOpenEvSel->get(9u)) { + histsESE.fill(HIST("EventQA/histEventCount"), 10.5); + } + if (fillQA) { + histsESE.fill(HIST("EventQA/histVtz"), collision.posZ()); + histsESE.fill(HIST("EventQA/histCent"), centrality); + } + return true; + } + + template + bool trackSelBasic(const TrackType track) + { + if ((track.pt() < cfgMinPtPID) || (track.pt() > cfgMaxPtPID)) + return false; + if (std::abs(track.eta()) > cfgMaxEtaPID) + return false; + if (cfgOpenTrackSel->get(0u)) { + if (!track.passedITSNCls()) + return false; + } else { + if (track.itsNCls() < cfgMinITSCls || track.itsNCls() > cfgMaxITSCls) + return false; + } + if (cfgOpenTrackSel->get(1u)) { + if (!track.passedITSChi2NDF()) + return false; + } else { + if (track.itsChi2NCl() < cfgMinChi2NClITS || track.itsChi2NCl() > cfgMaxChi2NClITS) + return false; + } + if (cfgOpenTrackSel->get(2u)) { + if (!track.passedITSHits()) + return false; + } + if (cfgOpenTrackSel->get(3u)) { + if (!track.passedTPCChi2NDF()) + return false; + } else { + if (track.tpcChi2NCl() < cfgMinTPCChi2NCl || track.tpcChi2NCl() > cfgMaxTPCChi2NCl) + return false; + } + if (cfgOpenTrackSel->get(4u)) { + if (!track.passedTPCCrossedRowsOverNCls()) + return false; + } + if (cfgOpenTrackSel->get(5u)) { + if (!track.passedDCAxy()) + return false; + } else { + if (std::abs(track.dcaXY()) > cfgMaxDCAxy) + return false; + } + if (cfgOpenTrackSel->get(6u)) { + if (!track.passedDCAz()) + return false; + } else { + if (std::abs(track.dcaZ()) > cfgMaxDCAz) + return false; } + if (track.tpcNClsFound() < cfgMinTPCCls || track.tpcNClsFound() > cfgMaxTPCCls) + return false; return true; } template - void fillHistosQvec(const CollType& collision, int nmode) + void fillEventQAhistBe(const CollType collision, const int multTrk, const float centrality) { - int detInd = detId * 4 + cfgnTotalSystem * 4 * (nmode - 2); - int refAInd = refAId * 4 + cfgnTotalSystem * 4 * (nmode - 2); - int refBInd = refBId * 4 + cfgnTotalSystem * 4 * (nmode - 2); - if (nmode == fourier_mode::kMode2) { - if (collision.qvecAmp()[detId] > 1e-8) { - histos.fill(HIST("QA/histQvec_CorrL0_V2"), collision.qvecRe()[detInd], collision.qvecIm()[detInd], collision.centFT0C()); - histos.fill(HIST("QA/histQvec_CorrL1_V2"), collision.qvecRe()[detInd + 1], collision.qvecIm()[detInd + 1], collision.centFT0C()); - histos.fill(HIST("QA/histQvec_CorrL2_V2"), collision.qvecRe()[detInd + 2], collision.qvecIm()[detInd + 2], collision.centFT0C()); - histos.fill(HIST("QA/histQvec_CorrL3_V2"), collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], collision.centFT0C()); - histos.fill(HIST("QA/histEvtPl_CorrL0_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd], collision.qvecIm()[detInd], nmode), collision.centFT0C()); - histos.fill(HIST("QA/histEvtPl_CorrL1_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 1], collision.qvecIm()[detInd + 1], nmode), collision.centFT0C()); - histos.fill(HIST("QA/histEvtPl_CorrL2_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 2], collision.qvecIm()[detInd + 2], nmode), collision.centFT0C()); - histos.fill(HIST("QA/histEvtPl_CorrL3_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), collision.centFT0C()); - } - if (collision.qvecAmp()[detId] > 1e-8 && collision.qvecAmp()[refAId] > 1e-8 && collision.qvecAmp()[refBId] > 1e-8) { - histos.fill(HIST("QA/histQvecRes_SigRefAV2"), collision.centFT0C(), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], nmode), nmode)); - histos.fill(HIST("QA/histQvecRes_SigRefBV2"), collision.centFT0C(), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], nmode), nmode)); - histos.fill(HIST("QA/histQvecRes_RefARefBV2"), collision.centFT0C(), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], nmode), nmode)); - } + histsESE.fill(HIST("EventQA/hist_globalTracks_centT0C_before"), centrality, multTrk); + histsESE.fill(HIST("EventQA/hist_PVTracks_centT0C_before"), centrality, collision.multNTracksPV()); + histsESE.fill(HIST("EventQA/hist_globalTracks_PVTracks_before"), collision.multNTracksPV(), multTrk); + histsESE.fill(HIST("EventQA/hist_globalTracks_multT0A_before"), collision.multFT0A(), multTrk); + histsESE.fill(HIST("EventQA/hist_globalTracks_multV0A_before"), collision.multFV0A(), multTrk); + histsESE.fill(HIST("EventQA/hist_multV0A_multT0A_before"), collision.multFT0A(), collision.multFV0A()); + histsESE.fill(HIST("EventQA/hist_multT0C_centT0C_before"), centrality, collision.multFT0C()); + } + + template + void fillEventQAhistAf(const CollType collision, const int multTrk, const float centrality) + { + histsESE.fill(HIST("EventQA/hist_globalTracks_centT0C_after"), centrality, multTrk); + histsESE.fill(HIST("EventQA/hist_PVTracks_centT0C_after"), centrality, collision.multNTracksPV()); + histsESE.fill(HIST("EventQA/hist_globalTracks_PVTracks_after"), collision.multNTracksPV(), multTrk); + histsESE.fill(HIST("EventQA/hist_globalTracks_multT0A_after"), collision.multFT0A(), multTrk); + histsESE.fill(HIST("EventQA/hist_globalTracks_multV0A_after"), collision.multFV0A(), multTrk); + histsESE.fill(HIST("EventQA/hist_multV0A_multT0A_after"), collision.multFT0A(), collision.multFV0A()); + histsESE.fill(HIST("EventQA/hist_multT0C_centT0C_after"), centrality, collision.multFT0C()); + } + + template + void fillTrackQAhist(const TrackType track) + { + bool heliumPID = track.pidForTracking() == o2::track::PID::Helium3 || track.pidForTracking() == o2::track::PID::Alpha; + float correctedTpcInnerParam = (heliumPID && cfgCompensatePIDinTracking) ? track.tpcInnerParam() / 2 : track.tpcInnerParam(); + histsESE.fill(HIST("TrackQA/hist_dEdxTPC_All"), track.sign() * correctedTpcInnerParam, track.tpcSignal()); + histsESE.fill(HIST("TrackQA/hist_pt_All"), track.pt()); + histsESE.fill(HIST("TrackQA/hist_eta_All"), track.eta()); + histsESE.fill(HIST("TrackQA/hist_phi_All"), track.phi()); + histsESE.fill(HIST("TrackQA/hist_DCAxy_All"), track.dcaXY()); + histsESE.fill(HIST("TrackQA/hist_DCAz_All"), track.dcaZ()); + histsESE.fill(HIST("TrackQA/hist_ITSNcls_All"), track.itsNCls()); + histsESE.fill(HIST("TrackQA/hist_TPCNcls_All"), track.tpcNClsFound()); + histsESE.fill(HIST("TrackQA/hist_ITSChi2NDF_All"), track.itsChi2NCl()); + histsESE.fill(HIST("TrackQA/hist_TPCChi2NDF_All"), track.tpcChi2NCl()); + } + + template + void fillHistosQvec(const CollType& collision) + { + int detInd = detId * 4 + cfgnTotalSystem * 4 * (2 - 2); + int refAInd = refAId * 4 + cfgnTotalSystem * 4 * (2 - 2); + int refBInd = refBId * 4 + cfgnTotalSystem * 4 * (2 - 2); + if (collision.qvecAmp()[detId] > ese_parameters::Amplitudelow) { + histsESE.fill(HIST("PlanQA/histQvec_CorrL0_V2"), collision.qvecRe()[detInd], collision.qvecIm()[detInd], collision.centFT0C()); + histsESE.fill(HIST("PlanQA/histQvec_CorrL1_V2"), collision.qvecRe()[detInd + 1], collision.qvecIm()[detInd + 1], collision.centFT0C()); + histsESE.fill(HIST("PlanQA/histQvec_CorrL2_V2"), collision.qvecRe()[detInd + 2], collision.qvecIm()[detInd + 2], collision.centFT0C()); + histsESE.fill(HIST("PlanQA/histQvec_CorrL3_V2"), collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], collision.centFT0C()); + histsESE.fill(HIST("PlanQA/histEvtPl_CorrL0_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd], collision.qvecIm()[detInd], 2), collision.centFT0C()); + histsESE.fill(HIST("PlanQA/histEvtPl_CorrL1_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 1], collision.qvecIm()[detInd + 1], 2), collision.centFT0C()); + histsESE.fill(HIST("PlanQA/histEvtPl_CorrL2_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 2], collision.qvecIm()[detInd + 2], 2), collision.centFT0C()); + histsESE.fill(HIST("PlanQA/histEvtPl_CorrL3_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], 2), collision.centFT0C()); + } + if (collision.qvecAmp()[detId] > ese_parameters::Amplitudelow && collision.qvecAmp()[refAId] > ese_parameters::Amplitudelow && collision.qvecAmp()[refBId] > ese_parameters::Amplitudelow) { + histsESE.fill(HIST("PlanQA/histQvecRes_SigRefAV2"), collision.centFT0C(), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], 2), helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], 2), 2)); + histsESE.fill(HIST("PlanQA/histQvecRes_SigRefBV2"), collision.centFT0C(), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], 2), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], 2), 2)); + histsESE.fill(HIST("PlanQA/histQvecRes_RefARefBV2"), collision.centFT0C(), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], 2), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], 2), 2)); } } template - float calculateq2(const TrackType tracks, float psi2, float cent, int pidmode) // pidmode 1 for proton , 2 for he3 + bool pidSel(const TrackType& track, uint8_t POI) { - int multi = tracks.size(); - if (multi > 0) { - float q2x = 0, q2y = 0; - for (const auto& track : tracks) { - q2x += std::cos(2 * track.phi()); - q2y += std::sin(2 * track.phi()); - if (pidmode == pid_flags::kProton) { - if (track.sign() > 0) { - histos.fill(HIST("V2/histCosV2EP_Pr_Pos"), track.pt(), cent, std::cos(2 * (track.phi() - psi2))); - } else { - histos.fill(HIST("V2/histCosV2EP_Pr_Neg"), track.pt(), cent, std::cos(2 * (track.phi() - psi2))); + if (track.pt() < cfgPtPreselection->get(POI, 0u) || track.pt() > cfgPtPreselection->get(POI, 1u)) { + return false; + } + float nSigmaTPC = 0.f; + float nSigmaITS = 0.f; + switch (POI) { + case ese_parameters::kProton: + if (cfgProtonPIDMode == ese_parameters::kRMSMode) { // RMS mode + float nSigmaUse = (track.pt() > cfgPtMaxforTPCOnlyPIDPrton) ? std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr()) : track.tpcNSigmaPr(); + if (nSigmaUse < cfgnSigmaCutRMSProton.value[0] || nSigmaUse > cfgnSigmaCutRMSProton.value[1]) { + return false; } - } - if (pidmode == pid_flags::kHe3) { - if (track.sign() > 0) { - histos.fill(HIST("V2/histCosV2EP_He3_Pos"), track.pt(), cent, std::cos(2 * (track.phi() - psi2))); - } else { - histos.fill(HIST("V2/histCosV2EP_He3_Neg"), track.pt(), cent, std::cos(2 * (track.phi() - psi2))); + } else if (cfgProtonPIDMode == ese_parameters::kTPCMode) { // TPC mode + nSigmaTPC = (cfgUseSelfnSigmaTPCProton ? getNSigmaTPCSelfBB(track, ese_parameters::kProton) : track.tpcNSigmaPr()); + } else if (cfgProtonPIDMode == ese_parameters::kTOFOnlyMode) { // TOF only mode + if (!track.hasTOF()) + return false; + if (track.tofNSigmaPr() < cfgnSigmaCutTOFProton.value[0] || track.tofNSigmaPr() > cfgnSigmaCutTOFProton.value[1]) { + return false; } } - } - return std::hypot(q2x, q2y) / std::sqrt(multi); - } else { - return 0; + nSigmaITS = itsResponse.nSigmaITS(track); + break; + + case ese_parameters::kDeuteron: + nSigmaTPC = getNSigmaTPCSelfBB(track, ese_parameters::kDeuteron); + nSigmaITS = itsResponse.nSigmaITS(track); + break; + + case ese_parameters::kTriton: + nSigmaTPC = getNSigmaTPCSelfBB(track, ese_parameters::kTriton); + nSigmaITS = itsResponse.nSigmaITS(track); + break; + + case ese_parameters::kHe3: + nSigmaTPC = getNSigmaTPCSelfBB(track, ese_parameters::kHe3); + nSigmaITS = itsResponse.nSigmaITS(track); + break; + + case ese_parameters::kAlpha: + nSigmaTPC = getNSigmaTPCSelfBB(track, ese_parameters::kAlpha); + nSigmaITS = itsResponse.nSigmaITS(track); + break; + + default: + LOGF(error, "Unknown POI: %d", POI); + return false; } + if (nSigmaTPC < cfgnSigmaTPC->get(POI, 0u) || nSigmaTPC > cfgnSigmaTPC->get(POI, 1u)) { + return false; + } + if (nSigmaITS < cfgnSigmaITS->get(POI, 0u) || nSigmaITS > cfgnSigmaITS->get(POI, 1u)) { + return false; + } + return true; } - template - void processESE(const TrackType tracks, float psi2, float q2, float cent, int pidmode, bool spcharge) // pidmode 1 for proton , 2 for he3 + template + void fillESECandidates(Tcoll const& collision, Ttrks const& tracks, float& q2Tarx, float& q2Tary, int& multiTar, float& q2Refx, float& q2Refy, int& multiRef) { - for (const auto& track : tracks) { - if (pidmode == pid_flags::kProton) { - if (spcharge) { + float psi2 = helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], 2); + float q2Tarinit{0.f}; + float q2Refinit{0.f}; + for (const auto& track : tracks) { // loop on tracks + if (!trackSelBasic(track)) { + continue; + } + // we fill the track info QA in the main process + fillTrackQAhist(track); + bool kIsTar{false}; + bool kIsRef{false}; + kIsTar = pidSel(track, poiTar); + kIsRef = pidSel(track, poiRef); + if (!cfgOpenAllowCrossTrack && kIsTar && kIsRef) { + if (getNSigmaTPCSelfBB(track, poiTar) < getNSigmaTPCSelfBB(track, poiRef)) { + kIsRef = false; + } else { + kIsTar = false; + } + } + if (kIsTar) { + multiTar++; + q2Tarx += std::cos(2 * track.phi()); + q2Tary += std::sin(2 * track.phi()); + bool heliumPID = track.pidForTracking() == o2::track::PID::Helium3 || track.pidForTracking() == o2::track::PID::Alpha; + float correctedTpcInnerParam = (heliumPID && cfgCompensatePIDinTracking) ? track.tpcInnerParam() / 2 : track.tpcInnerParam(); + float nSigmaTPCTar{(poiTar == ese_parameters::kProton && !cfgUseSelfnSigmaTPCProton) ? track.tpcNSigmaPr() : getNSigmaTPCSelfBB(track, poiTar)}; + float nSigmaTOFTar{getNSigmaTOF(track, poiTar)}; + float nSigmaITSTar{getNSigmaITS(track, poiTar)}; + if (cfgOpenPIDQA) { + ese_parameters::hPIDQATar1D[0]->Fill(track.pt()); + ese_parameters::hPIDQATar1D[1]->Fill(track.eta()); + ese_parameters::hPIDQATar1D[2]->Fill(track.phi()); + ese_parameters::hPIDQATar1D[3]->Fill(track.itsNCls()); + ese_parameters::hPIDQATar1D[4]->Fill(track.tpcNClsFound()); + ese_parameters::hPIDQATar1D[5]->Fill(track.itsChi2NCl()); + ese_parameters::hPIDQATar1D[6]->Fill(track.tpcChi2NCl()); + ese_parameters::hPIDQATar1D[7]->Fill(track.dcaXY()); + ese_parameters::hPIDQATar1D[8]->Fill(track.dcaZ()); + ese_parameters::hPIDQATar1D[9]->Fill(nSigmaTPCTar); + ese_parameters::hPIDQATar1D[10]->Fill(nSigmaTOFTar); + ese_parameters::hPIDQATar1D[11]->Fill(nSigmaITSTar); + ese_parameters::hPIDQATar2D[0]->Fill(track.sign() * correctedTpcInnerParam, track.tpcSignal()); + ese_parameters::hPIDQATar2D[1]->Fill(nSigmaTPCTar, track.pt()); + ese_parameters::hPIDQATar2D[2]->Fill(nSigmaTOFTar, track.pt()); + ese_parameters::hPIDQATar2D[3]->Fill(nSigmaITSTar, track.pt()); + if (cfgOpen3DPIDPlots->get(0u)) { + ese_parameters::hPIDQATar3D[0]->Fill(nSigmaTOFTar, nSigmaITSTar, track.pt()); + } + if (cfgOpen3DPIDPlots->get(1u)) { + ese_parameters::hPIDQATar3D[1]->Fill(nSigmaITSTar, nSigmaTPCTar, track.pt()); + } + if (cfgOpen3DPIDPlots->get(2u)) { + ese_parameters::hPIDQATar3D[2]->Fill(nSigmaTOFTar, nSigmaTPCTar, track.pt()); + } + } + if (cfgOpenv2) { if (track.sign() > 0) { - histos.fill(HIST("ESE/hist_v2PosPr_Cent_Pt_q2He3"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); + ese_parameters::hv2Tar[0]->Fill(track.pt(), collision.centFT0C(), std::cos(2 * (track.phi() - psi2))); } else { - histos.fill(HIST("ESE/hist_v2NegPr_Cent_Pt_q2He3"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); + ese_parameters::hv2Tar[1]->Fill(track.pt(), collision.centFT0C(), std::cos(2 * (track.phi() - psi2))); } - } else { - histos.fill(HIST("ESE/hist_v2Pr_Cent_Pt_q2He3"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); } + ese_parameters::eseCandidates.emplace_back(ESECandidate{ + collision.posZ(), collision.centFT0C(), psi2, q2Tarinit, q2Refinit, static_cast(track.sign()), correctedTpcInnerParam, track.tpcSignal(), track.pt(), track.eta(), track.phi(), + track.dcaXY(), track.dcaZ(), static_cast(track.tpcNClsFound()), track.itsNCls(), track.tpcChi2NCl(), track.itsChi2NCl(), + nSigmaTPCTar, nSigmaTOFTar, nSigmaITSTar, track.itsClusterSizes()}); } - if (pidmode == pid_flags::kHe3) { - if (spcharge) { + if (kIsRef) { + multiRef++; + q2Refx += std::cos(2 * track.phi()); + q2Refy += std::sin(2 * track.phi()); + bool heliumPID = track.pidForTracking() == o2::track::PID::Helium3 || track.pidForTracking() == o2::track::PID::Alpha; + float correctedTpcInnerParam = (heliumPID && cfgCompensatePIDinTracking) ? track.tpcInnerParam() / 2 : track.tpcInnerParam(); + float nSigmaTPCRef{(poiRef == ese_parameters::kProton && !cfgUseSelfnSigmaTPCProton) ? track.tpcNSigmaPr() : getNSigmaTPCSelfBB(track, poiRef)}; + float nSigmaTOFRef{getNSigmaTOF(track, poiRef)}; + float nSigmaITSRef{getNSigmaITS(track, poiRef)}; + if (cfgOpenPIDQA) { + ese_parameters::hPIDQARef1D[0]->Fill(track.pt()); + ese_parameters::hPIDQARef1D[1]->Fill(track.eta()); + ese_parameters::hPIDQARef1D[2]->Fill(track.phi()); + ese_parameters::hPIDQARef1D[3]->Fill(track.itsNCls()); + ese_parameters::hPIDQARef1D[4]->Fill(track.tpcNClsFound()); + ese_parameters::hPIDQARef1D[5]->Fill(track.itsChi2NCl()); + ese_parameters::hPIDQARef1D[6]->Fill(track.tpcChi2NCl()); + ese_parameters::hPIDQARef1D[7]->Fill(track.dcaXY()); + ese_parameters::hPIDQARef1D[8]->Fill(track.dcaZ()); + ese_parameters::hPIDQARef1D[9]->Fill(nSigmaTPCRef); + ese_parameters::hPIDQARef1D[10]->Fill(nSigmaTOFRef); + ese_parameters::hPIDQARef1D[11]->Fill(nSigmaITSRef); + ese_parameters::hPIDQARef2D[0]->Fill(track.sign() * correctedTpcInnerParam, track.tpcSignal()); + ese_parameters::hPIDQARef2D[1]->Fill(nSigmaTPCRef, track.pt()); + ese_parameters::hPIDQARef2D[2]->Fill(nSigmaTOFRef, track.pt()); + ese_parameters::hPIDQARef2D[3]->Fill(nSigmaITSRef, track.pt()); + if (cfgOpen3DPIDPlots->get(0u)) { + ese_parameters::hPIDQARef3D[0]->Fill(nSigmaTOFRef, nSigmaITSRef, track.pt()); + } + if (cfgOpen3DPIDPlots->get(1u)) { + ese_parameters::hPIDQARef3D[1]->Fill(nSigmaITSRef, nSigmaTPCRef, track.pt()); + } + if (cfgOpen3DPIDPlots->get(2u)) { + ese_parameters::hPIDQARef3D[2]->Fill(nSigmaTOFRef, nSigmaTPCRef, track.pt()); + } + } + if (cfgOpenv2) { if (track.sign() > 0) { - histos.fill(HIST("ESE/hist_v2PosHe3_Cent_Pt_q2Pr"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); + ese_parameters::hv2Ref[0]->Fill(track.pt(), collision.centFT0C(), std::cos(2 * (track.phi() - psi2))); } else { - histos.fill(HIST("ESE/hist_v2NegHe3_Cent_Pt_q2Pr"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); + ese_parameters::hv2Ref[1]->Fill(track.pt(), collision.centFT0C(), std::cos(2 * (track.phi() - psi2))); } - } else { - histos.fill(HIST("ESE/hist_v2He3_Cent_Pt_q2Pr"), track.pt(), cent, q2, std::cos(2 * (track.phi() - psi2))); } } } @@ -798,6 +854,8 @@ struct FlowEsePHe3 { void init(InitContext const&) { + poiTar = getPOI(cfgTarName); + poiRef = getPOI(cfgRefName); detId = getDetId(cfgDetName); refAId = getDetId(cfgRefAName); refBId = getDetId(cfgRefBName); @@ -807,169 +865,186 @@ struct FlowEsePHe3 { refAId = 4; refBId = 5; } - if (cfgUseAdditionalEventCut) { - fMultPVCutLow = new TF1("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x - 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); - fMultPVCutLow->SetParameters(3257.29, -121.848, 1.98492, -0.0172128, 6.47528e-05, 154.756, -1.86072, -0.0274713, 0.000633499, -3.37757e-06); - fMultPVCutHigh = new TF1("fMultPVCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x + 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); - fMultPVCutHigh->SetParameters(3257.29, -121.848, 1.98492, -0.0172128, 6.47528e-05, 154.756, -1.86072, -0.0274713, 0.000633499, -3.37757e-06); + detInd = detId * 4 + cfgnTotalSystem * 4 * (2 - 2); + refAInd = refAId * 4 + cfgnTotalSystem * 4 * (2 - 2); + refBInd = refBId * 4 + cfgnTotalSystem * 4 * (2 - 2); - fMultCutLow = new TF1("fMultCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); - fMultCutLow->SetParameters(1654.46, -47.2379, 0.449833, -0.0014125, 150.773, -3.67334, 0.0530503, -0.000614061, 3.15956e-06); - fMultCutHigh = new TF1("fMultCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 3.*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); - fMultCutHigh->SetParameters(1654.46, -47.2379, 0.449833, -0.0014125, 150.773, -3.67334, 0.0530503, -0.000614061, 3.15956e-06); + fMultPVCutLow = new TF1("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x - 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); + fMultPVCutLow->SetParameters(3257.29, -121.848, 1.98492, -0.0172128, 6.47528e-05, 154.756, -1.86072, -0.0274713, 0.000633499, -3.37757e-06); + fMultPVCutHigh = new TF1("fMultPVCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x + 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); + fMultPVCutHigh->SetParameters(3257.29, -121.848, 1.98492, -0.0172128, 6.47528e-05, 154.756, -1.86072, -0.0274713, 0.000633499, -3.37757e-06); + fMultCutLow = new TF1("fMultCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); + fMultCutLow->SetParameters(1654.46, -47.2379, 0.449833, -0.0014125, 150.773, -3.67334, 0.0530503, -0.000614061, 3.15956e-06); + fMultCutHigh = new TF1("fMultCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 3.*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); + fMultCutHigh->SetParameters(1654.46, -47.2379, 0.449833, -0.0014125, 150.773, -3.67334, 0.0530503, -0.000614061, 3.15956e-06); + fT0AV0AMean = new TF1("fT0AV0AMean", "[0]+[1]*x", 0, 200000); + fT0AV0AMean->SetParameters(-1601.0581, 9.417652e-01); + fT0AV0ASigma = new TF1("fT0AV0ASigma", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 200000); + fT0AV0ASigma->SetParameters(463.4144, 6.796509e-02, -9.097136e-07, 7.971088e-12, -2.600581e-17); - fT0AV0AMean = new TF1("fT0AV0AMean", "[0]+[1]*x", 0, 200000); - fT0AV0AMean->SetParameters(-1601.0581, 9.417652e-01); - fT0AV0ASigma = new TF1("fT0AV0ASigma", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 200000); - fT0AV0ASigma->SetParameters(463.4144, 6.796509e-02, -9.097136e-07, 7.971088e-12, -2.600581e-17); - } + AxisSpec axisITSNcls = {10, -1.5, 8.5, "ITSNcls"}; + AxisSpec axisTPCNcls = {160, 0, 160, "TPCNcls"}; AxisSpec axisEvtPl = {100, -1.0 * constants::math::PI, constants::math::PI}; - AxisSpec axisvertexz = {100, -15., 15., "vrtx_{Z} [cm]"}; - histos.add("QA/histEventCount", "", {HistType::kTH1F, {{3, 0.0, 3.0}}}); - histos.get(HIST("QA/histEventCount"))->GetXaxis()->SetBinLabel(1, "Filtered event"); - histos.get(HIST("QA/histEventCount"))->GetXaxis()->SetBinLabel(2, "after sel8"); - histos.get(HIST("QA/histEventCount"))->GetXaxis()->SetBinLabel(3, "after additional event cut"); - if (cfgUseAdditionalEventCut) { - histos.add("QA/histEventCountDetail", "Number of Event;; Count", {HistType::kTH1F, {{11, 0, 11}}}); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(1, "after sel8"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(2, "kIsGoodZvtxFT0vsPV"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(3, "kNoSameBunchPileup"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(4, "kNoCollInTimeRangeStandard"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(5, "kIsGoodITSLayersAll"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(6, "kNoCollInRofStandard"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(7, "kNoHighMultCollInPrevRof"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(8, "occupancy"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(9, "MultCorrelationPVTracks"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(10, "MultCorrelationGlobalTracks"); - histos.get(HIST("QA/histEventCountDetail"))->GetXaxis()->SetBinLabel(11, "cfgEvSelV0AT0ACut"); - } + AxisSpec axisPhi = {200, -2.1 * constants::math::PI, 2.1 * constants::math::PI}; + AxisSpec axisCentForQA = {100, 0, 100}; + AxisSpec axisCharge = {4, -2, 2, "Charge"}; + // hists for event level QA + histsESE.add("EventQA/histEventCount", ";Event Count;Counts", {HistType::kTH1F, {{100, 0, 100}}}); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(1, "after sel8"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(2, "kIsGoodZvtxFT0vsPV"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(3, "kNoSameBunchPileup"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(4, "kNoCollInTimeRangeStandard"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(5, "kIsGoodITSLayersAll"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(6, "kNoCollInRofStandard"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(7, "kNoHighMultCollInPrevRof"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(8, "occupancy"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(9, "MultCorrelationPVTracks"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(10, "MultCorrelationGlobalTracks"); + histsESE.get(HIST("EventQA/histEventCount"))->GetXaxis()->SetBinLabel(11, "cfgEvSelV0AT0ACut"); + histsESE.add("EventQA/histVtz", ";#it{Vtz} (cm);Counts", {HistType::kTH1F, {{200, -20., +20.}}}); + histsESE.add("EventQA/histCent", ";Centrality (%);Counts", {HistType::kTH1F, {{100, 0., 100.}}}); if (cfgOpenFullEventQA) { - histos.add("QA/hist_globalTracks_centT0C_before", "before cut;Centrality T0C;mulplicity global tracks", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisNch}}); - histos.add("QA/hist_PVTracks_centT0C_before", "before cut;Centrality T0C;mulplicity PV tracks", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisNchPV}}); - histos.add("QA/hist_globalTracks_PVTracks_before", "before cut;mulplicity PV tracks;mulplicity global tracks", {HistType::kTH2D, {cfgaxisNchPV, cfgaxisNch}}); - histos.add("QA/hist_globalTracks_multT0A_before", "before cut;mulplicity T0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); - histos.add("QA/hist_globalTracks_multV0A_before", "before cut;mulplicity V0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); - histos.add("QA/hist_multV0A_multT0A_before", "before cut;mulplicity T0A;mulplicity V0A", {HistType::kTH2D, {cfgaxisT0A, cfgaxisT0A}}); - histos.add("QA/hist_multT0C_centT0C_before", "before cut;Centrality T0C;mulplicity T0C", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisT0C}}); - histos.add("QA/hist_globalTracks_centT0C_after", "after cut;Centrality T0C;mulplicity global tracks", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisNch}}); - histos.add("QA/hist_PVTracks_centT0C_after", "after cut;Centrality T0C;mulplicity PV tracks", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisNchPV}}); - histos.add("QA/hist_globalTracks_PVTracks_after", "after cut;mulplicity PV tracks;mulplicity global tracks", {HistType::kTH2D, {cfgaxisNchPV, cfgaxisNch}}); - histos.add("QA/hist_globalTracks_multT0A_after", "after cut;mulplicity T0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); - histos.add("QA/hist_globalTracks_multV0A_after", "after cut;mulplicity V0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); - histos.add("QA/hist_multV0A_multT0A_after", "after cut;mulplicity T0A;mulplicity V0A", {HistType::kTH2D, {cfgaxisT0A, cfgaxisT0A}}); - histos.add("QA/hist_multT0C_centT0C_after", "after cut;Centrality T0C;mulplicity T0C", {HistType::kTH2D, {cfgaxisCentForQA, cfgaxisT0C}}); - } - histos.add("QA/histVertexZRec", ";vrtx_{Z} [cm];counts", {HistType::kTH1F, {axisvertexz}}); - histos.add("QA/histCentrality", ";Centrality;counts", {HistType::kTH1F, {cfgaxisCentForQA}}); - histos.add("QA/histProtonNum", "ProtonNum;counts", {HistType::kTH1F, {{100, 0, 100}}}); - histos.add("QA/histHe3Num", "He3Num;counts", {HistType::kTH1F, {{20, 0, 20}}}); - histos.add("QA/histQvec_CorrL0_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); - histos.add("QA/histQvec_CorrL1_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); - histos.add("QA/histQvec_CorrL2_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); - histos.add("QA/histQvec_CorrL3_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); - histos.add("QA/histEvtPl_CorrL0_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); - histos.add("QA/histEvtPl_CorrL1_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); - histos.add("QA/histEvtPl_CorrL2_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); - histos.add("QA/histEvtPl_CorrL3_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); - histos.add("QA/histQvecRes_SigRefAV2", ";Centrality;Cos(Sig-RefA)", {HistType::kTProfile, {cfgaxisCent}}); - histos.add("QA/histQvecRes_SigRefBV2", ";Centrality;Cos(Sig-RefB)", {HistType::kTProfile, {cfgaxisCent}}); - histos.add("QA/histQvecRes_RefARefBV2", ";Centrality;Cos(RefA-RefB)", {HistType::kTProfile, {cfgaxisCent}}); - if (cfgOpenv2q) { - histos.add("V2/histCosV2EP_Pr_Pos", ";#it{p}_{T};Centrality", {HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}}); - histos.add("V2/histCosV2EP_Pr_Neg", ";#it{p}_{T};Centrality", {HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}}); - histos.add("V2/histCosV2EP_He3_Pos", ";#it{p}_{T};Centrality", {HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}}); - histos.add("V2/histCosV2EP_He3_Neg", ";#it{p}_{T};Centrality", {HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}}); - histos.add("q2/hist_q2_Cen_Pr", ";q_{2} (TPC);Centrality", {HistType::kTH2F, {cfgaxisq2, cfgaxisCent}}); - histos.add("q2/hist_q2_Cen_He3", ";q_{2} (TPC);Centrality", {HistType::kTH2F, {cfgaxisq2, cfgaxisCent}}); - histos.add("q2/hist_q2_Pr", ";q_{2} (TPC);counts", {HistType::kTH1F, {cfgaxisq2}}); - histos.add("q2/hist_q2_He3", ";q_{2} (TPC);counts", {HistType::kTH1F, {cfgaxisq2}}); + histsESE.add("EventQA/hist_globalTracks_centT0C_before", "before cut;Centrality T0C;mulplicity global tracks", {HistType::kTH2D, {axisCentForQA, cfgaxisNch}}); + histsESE.add("EventQA/hist_PVTracks_centT0C_before", "before cut;Centrality T0C;mulplicity PV tracks", {HistType::kTH2D, {axisCentForQA, cfgaxisNchPV}}); + histsESE.add("EventQA/hist_globalTracks_PVTracks_before", "before cut;mulplicity PV tracks;mulplicity global tracks", {HistType::kTH2D, {cfgaxisNchPV, cfgaxisNch}}); + histsESE.add("EventQA/hist_globalTracks_multT0A_before", "before cut;mulplicity T0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); + histsESE.add("EventQA/hist_globalTracks_multV0A_before", "before cut;mulplicity V0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); + histsESE.add("EventQA/hist_multV0A_multT0A_before", "before cut;mulplicity T0A;mulplicity V0A", {HistType::kTH2D, {cfgaxisT0A, cfgaxisT0A}}); + histsESE.add("EventQA/hist_multT0C_centT0C_before", "before cut;Centrality T0C;mulplicity T0C", {HistType::kTH2D, {axisCentForQA, cfgaxisT0C}}); + histsESE.add("EventQA/hist_globalTracks_centT0C_after", "after cut;Centrality T0C;mulplicity global tracks", {HistType::kTH2D, {axisCentForQA, cfgaxisNch}}); + histsESE.add("EventQA/hist_PVTracks_centT0C_after", "after cut;Centrality T0C;mulplicity PV tracks", {HistType::kTH2D, {axisCentForQA, cfgaxisNchPV}}); + histsESE.add("EventQA/hist_globalTracks_PVTracks_after", "after cut;mulplicity PV tracks;mulplicity global tracks", {HistType::kTH2D, {cfgaxisNchPV, cfgaxisNch}}); + histsESE.add("EventQA/hist_globalTracks_multT0A_after", "after cut;mulplicity T0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); + histsESE.add("EventQA/hist_globalTracks_multV0A_after", "after cut;mulplicity V0A;mulplicity global tracks", {HistType::kTH2D, {cfgaxisT0A, cfgaxisNch}}); + histsESE.add("EventQA/hist_multV0A_multT0A_after", "after cut;mulplicity T0A;mulplicity V0A", {HistType::kTH2D, {cfgaxisT0A, cfgaxisT0A}}); + histsESE.add("EventQA/hist_multT0C_centT0C_after", "after cut;Centrality T0C;mulplicity T0C", {HistType::kTH2D, {axisCentForQA, cfgaxisT0C}}); } - if (cfgOpenESE) { - if (cfgOpenESEChargeSeperation) { - if (cfgOpenESEProton) { - histos.add("ESE/hist_v2PosPr_Cent_Pt_q2He3", ";#it{p}_{T};q_{2}(He3);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); - histos.add("ESE/hist_v2NegPr_Cent_Pt_q2He3", ";#it{p}_{T};q_{2}(He3);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); - } - if (cfgOpenESEHe3) { - histos.add("ESE/hist_v2PosHe3_Cent_Pt_q2Pr", ";#it{p}_{T};q_{2}(Proton);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); - histos.add("ESE/hist_v2NegHe3_Cent_Pt_q2Pr", ";#it{p}_{T};q_{2}(Proton);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); - } - } else { - if (cfgOpenESEProton) { - histos.add("ESE/hist_v2Pr_Cent_Pt_q2He3", ";#it{p}_{T};q_{2}(He3);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); - } - if (cfgOpenESEHe3) { - histos.add("ESE/hist_v2He3_Cent_Pt_q2Pr", ";#it{p}_{T};q_{2}(Proton);Centrality", HistType::kTProfile3D, {cfgaxispt, cfgaxisq2, cfgaxisCent}); - } + histsESE.add("PlanQA/histQvec_CorrL0_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); + histsESE.add("PlanQA/histQvec_CorrL1_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); + histsESE.add("PlanQA/histQvec_CorrL2_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); + histsESE.add("PlanQA/histQvec_CorrL3_V2", ";#it{Q_{x}};#it{Q_{y}};Centrality", {HistType::kTH3F, {cfgaxisQvecF, cfgaxisQvecF, cfgaxisCent}}); + histsESE.add("PlanQA/histEvtPl_CorrL0_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); + histsESE.add("PlanQA/histEvtPl_CorrL1_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); + histsESE.add("PlanQA/histEvtPl_CorrL2_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); + histsESE.add("PlanQA/histEvtPl_CorrL3_V2", ";EventPlane angle;Centrality", {HistType::kTH2F, {axisEvtPl, cfgaxisCent}}); + histsESE.add("PlanQA/histQvecRes_SigRefAV2", ";Centrality;Cos(Sig-RefA)", {HistType::kTProfile, {cfgaxisCent}}); + histsESE.add("PlanQA/histQvecRes_SigRefBV2", ";Centrality;Cos(Sig-RefB)", {HistType::kTProfile, {cfgaxisCent}}); + histsESE.add("PlanQA/histQvecRes_RefARefBV2", ";Centrality;Cos(RefA-RefB)", {HistType::kTProfile, {cfgaxisCent}}); + // hists for track level QA + histsESE.add("TrackQA/hist_dEdxTPC_All", ";#it{p}^{TPC}/#it{z} (GeV/c);d#it{E}/d#it{x}", {HistType::kTH2F, {cfgrigidityBins, cfgdedxBins}}); + histsESE.add("TrackQA/hist_pt_All", ";#it{p}_{T};counts", {HistType::kTH1F, {cfgaxispt}}); + histsESE.add("TrackQA/hist_eta_All", ";#it{#eta};counts", {HistType::kTH1F, {cfgaxisetaPID}}); + histsESE.add("TrackQA/hist_phi_All", ";#it{#phi};counts", {HistType::kTH1F, {axisPhi}}); + histsESE.add("TrackQA/hist_ITSNcls_All", ";ITSNcls;counts", {HistType::kTH1F, {axisITSNcls}}); + histsESE.add("TrackQA/hist_TPCNcls_All", ";TPCNcls;counts", {HistType::kTH1F, {axisTPCNcls}}); + histsESE.add("TrackQA/hist_ITSChi2NDF_All", ";ITS#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); + histsESE.add("TrackQA/hist_TPCChi2NDF_All", ";TPC#it{#chi^{2}}/NDF;counts", {HistType::kTH1F, {cfgaxisChi2Ncls}}); + histsESE.add("TrackQA/hist_DCAxy_All", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAxy}}); + histsESE.add("TrackQA/hist_DCAz_All", ";#it{DCA_{xy}};counts", {HistType::kTH1F, {cfgaxisDCAz}}); + // v2 and ESEPlots + /// QA plots + if (cfgOpenPIDQA) { + ese_parameters::hPIDQATar2D[0] = histsESE.add(Form("ESE/TrackQA/hist_dEdxTPC_%s", cfgTarName.value.c_str()), ";#it{p}^{TPC}/#it{z} (GeV/c);d#it{E}/d#it{x}", HistType::kTH2F, {cfgrigidityBins, cfgdedxBins}); + ese_parameters::hPIDQATar1D[0] = histsESE.add(Form("ESE/TrackQA/hist_pt_%s", cfgTarName.value.c_str()), ";#it{p}_{T};counts", HistType::kTH1F, {cfgaxispt}); + ese_parameters::hPIDQATar1D[1] = histsESE.add(Form("ESE/TrackQA/hist_eta_%s", cfgTarName.value.c_str()), ";#it{#eta};counts", HistType::kTH1F, {cfgaxisetaPID}); + ese_parameters::hPIDQATar1D[2] = histsESE.add(Form("ESE/TrackQA/hist_phi_%s", cfgTarName.value.c_str()), ";#it{#phi};counts", HistType::kTH1F, {axisPhi}); + ese_parameters::hPIDQATar1D[3] = histsESE.add(Form("ESE/TrackQA/hist_ITSNcls_%s", cfgTarName.value.c_str()), ";ITSNcls;counts", HistType::kTH1F, {axisITSNcls}); + ese_parameters::hPIDQATar1D[4] = histsESE.add(Form("ESE/TrackQA/hist_TPCNcls_%s", cfgTarName.value.c_str()), ";TPCNcls;counts", HistType::kTH1F, {axisTPCNcls}); + ese_parameters::hPIDQATar1D[5] = histsESE.add(Form("ESE/TrackQA/hist_ITSChi2NDF_%s", cfgTarName.value.c_str()), ";ITS#it{#chi^{2}}/NDF;counts", HistType::kTH1F, {cfgaxisChi2Ncls}); + ese_parameters::hPIDQATar1D[6] = histsESE.add(Form("ESE/TrackQA/hist_TPCChi2NDF_%s", cfgTarName.value.c_str()), ";TPC#it{#chi^{2}}/NDF;counts", HistType::kTH1F, {cfgaxisChi2Ncls}); + ese_parameters::hPIDQATar1D[7] = histsESE.add(Form("ESE/TrackQA/hist_DCAxy_%s", cfgTarName.value.c_str()), ";#it{DCA_{xy}};counts", HistType::kTH1F, {cfgaxisDCAxy}); + ese_parameters::hPIDQATar1D[8] = histsESE.add(Form("ESE/TrackQA/hist_DCAz_%s", cfgTarName.value.c_str()), ";#it{DCA_{xy}};counts", HistType::kTH1F, {cfgaxisDCAz}); + ese_parameters::hPIDQATar1D[9] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTPC_%s", cfgTarName.value.c_str()), ";n#sigmaTPC;counts", HistType::kTH1F, {cfgnSigmaBinsTPC}); + ese_parameters::hPIDQATar2D[1] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTPC_pt_%s", cfgTarName.value.c_str()), ";#it{p}_{T};n#sigmaTPC", HistType::kTH2F, {cfgaxispt, cfgnSigmaBinsTPC}); + ese_parameters::hPIDQATar1D[10] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTOF_%s", cfgTarName.value.c_str()), ";n#sigmaTOF;counts", HistType::kTH1F, {cfgnSigmaBinsTOF}); + ese_parameters::hPIDQATar2D[2] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTOF_pt_%s", cfgTarName.value.c_str()), ";#it{p}_{T};n#sigmaTOF", HistType::kTH2F, {cfgaxispt, cfgnSigmaBinsTOF}); + ese_parameters::hPIDQATar1D[11] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaITS_%s", cfgTarName.value.c_str()), ";n#sigmaITS;counts", HistType::kTH1F, {cfgnSigmaBinsITS}); + ese_parameters::hPIDQATar2D[3] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaITS_pt_%s", cfgTarName.value.c_str()), ";#it{p}_{T};n#sigmaITS", HistType::kTH2F, {cfgaxispt, cfgnSigmaBinsITS}); + ese_parameters::hPIDQARef2D[0] = histsESE.add(Form("ESE/TrackQA/hist_dEdxTPC_%s", cfgRefName.value.c_str()), ";#it{p}^{TPC}/#it{z} (GeV/c);d#it{E}/d#it{x}", HistType::kTH2F, {cfgrigidityBins, cfgdedxBins}); + ese_parameters::hPIDQARef1D[0] = histsESE.add(Form("ESE/TrackQA/hist_pt_%s", cfgRefName.value.c_str()), ";#it{p}_{T};counts", HistType::kTH1F, {cfgaxispt}); + ese_parameters::hPIDQARef1D[1] = histsESE.add(Form("ESE/TrackQA/hist_eta_%s", cfgRefName.value.c_str()), ";#it{#eta};counts", HistType::kTH1F, {cfgaxisetaPID}); + ese_parameters::hPIDQARef1D[2] = histsESE.add(Form("ESE/TrackQA/hist_phi_%s", cfgRefName.value.c_str()), ";#it{#phi};counts", HistType::kTH1F, {axisPhi}); + ese_parameters::hPIDQARef1D[3] = histsESE.add(Form("ESE/TrackQA/hist_ITSNcls_%s", cfgRefName.value.c_str()), ";ITSNcls;counts", HistType::kTH1F, {axisITSNcls}); + ese_parameters::hPIDQARef1D[4] = histsESE.add(Form("ESE/TrackQA/hist_TPCNcls_%s", cfgRefName.value.c_str()), ";TPCNcls;counts", HistType::kTH1F, {axisTPCNcls}); + ese_parameters::hPIDQARef1D[5] = histsESE.add(Form("ESE/TrackQA/hist_ITSChi2NDF_%s", cfgRefName.value.c_str()), ";ITS#it{#chi^{2}}/NDF;counts", HistType::kTH1F, {cfgaxisChi2Ncls}); + ese_parameters::hPIDQARef1D[6] = histsESE.add(Form("ESE/TrackQA/hist_TPCChi2NDF_%s", cfgRefName.value.c_str()), ";TPC#it{#chi^{2}}/NDF;counts", HistType::kTH1F, {cfgaxisChi2Ncls}); + ese_parameters::hPIDQARef1D[7] = histsESE.add(Form("ESE/TrackQA/hist_DCAxy_%s", cfgRefName.value.c_str()), ";#it{DCA_{xy}};counts", HistType::kTH1F, {cfgaxisDCAxy}); + ese_parameters::hPIDQARef1D[8] = histsESE.add(Form("ESE/TrackQA/hist_DCAz_%s", cfgRefName.value.c_str()), ";#it{DCA_{xy}};counts", HistType::kTH1F, {cfgaxisDCAz}); + ese_parameters::hPIDQARef1D[9] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTPC_%s", cfgRefName.value.c_str()), ";n#sigmaTPC;counts", HistType::kTH1F, {cfgnSigmaBinsTPC}); + ese_parameters::hPIDQARef2D[1] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTPC_pt_%s", cfgRefName.value.c_str()), ";#it{p}_{T};n#sigmaTPC", HistType::kTH2F, {cfgaxispt, cfgnSigmaBinsTPC}); + ese_parameters::hPIDQARef1D[10] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTOF_%s", cfgRefName.value.c_str()), ";n#sigmaTOF;counts", HistType::kTH1F, {cfgnSigmaBinsTOF}); + ese_parameters::hPIDQARef2D[2] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTOF_pt_%s", cfgRefName.value.c_str()), ";#it{p}_{T};n#sigmaTOF", HistType::kTH2F, {cfgaxispt, cfgnSigmaBinsTOF}); + ese_parameters::hPIDQARef1D[11] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaITS_%s", cfgRefName.value.c_str()), ";n#sigmaITS;counts", HistType::kTH1F, {cfgnSigmaBinsITS}); + ese_parameters::hPIDQARef2D[3] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaITS_pt_%s", cfgRefName.value.c_str()), ";#it{p}_{T};n#sigmaITS", HistType::kTH2F, {cfgaxispt, cfgnSigmaBinsITS}); + if (cfgOpen3DPIDPlots->get(0u)) { + ese_parameters::hPIDQATar3D[0] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTOFITSPt_%s", cfgTarName.value.c_str()), ";n_{#sigma}TOF;n_{#sigma}ITS;#it{p}_{T}", HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsITS, cfgaxispt}); + ese_parameters::hPIDQARef3D[0] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTOFITSPt_%s", cfgRefName.value.c_str()), ";n_{#sigma}TOF;n_{#sigma}ITS;#it{p}_{T}", HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsITS, cfgaxispt}); + } + if (cfgOpen3DPIDPlots->get(1u)) { + ese_parameters::hPIDQATar3D[1] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaITSTPCPt_%s", cfgTarName.value.c_str()), ";n_{#sigma}ITS;n_{#sigma}TPC;#it{p}_{T}", HistType::kTH3F, {cfgnSigmaBinsITS, cfgnSigmaBinsTPC, cfgaxispt}); + ese_parameters::hPIDQARef3D[1] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaITSTPCPt_%s", cfgRefName.value.c_str()), ";n_{#sigma}ITS;n_{#sigma}TPC;#it{p}_{T}", HistType::kTH3F, {cfgnSigmaBinsITS, cfgnSigmaBinsTPC, cfgaxispt}); + } + if (cfgOpen3DPIDPlots->get(2u)) { + ese_parameters::hPIDQATar3D[2] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTOFTPCPt_%s", cfgTarName.value.c_str()), ";n_{#sigma}TOF;n_{#sigma}TPC;#it{p}_{T}", HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsTPC, cfgaxispt}); + ese_parameters::hPIDQARef3D[2] = histsESE.add(Form("ESE/TrackQA/hist_nSigmaTOFTPCPt_%s", cfgRefName.value.c_str()), ";n_{#sigma}TOF;n_{#sigma}TPC;#it{p}_{T}", HistType::kTH3F, {cfgnSigmaBinsTOF, cfgnSigmaBinsTPC, cfgaxispt}); } } + // v2 plots + if (cfgOpenv2) { + ese_parameters::hv2Tar[0] = histsESE.add(Form("ESE/V2/hist_%sPosV2", cfgTarName.value.c_str()), ";#it{p}_{T};Centrality (%)", HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}); + ese_parameters::hv2Tar[1] = histsESE.add(Form("ESE/V2/hist_%sNegV2", cfgTarName.value.c_str()), ";#it{p}_{T};Centrality (%)", HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}); + ese_parameters::hv2Ref[0] = histsESE.add(Form("ESE/V2/hist_%sPosV2", cfgRefName.value.c_str()), ";#it{p}_{T};Centrality (%)", HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}); + ese_parameters::hv2Ref[1] = histsESE.add(Form("ESE/V2/hist_%sNegV2", cfgRefName.value.c_str()), ";#it{p}_{T};Centrality (%)", HistType::kTProfile2D, {cfgaxispt, cfgaxisCent}); + } + // ESE plots + if (cfgOpenESEQA) { + ese_parameters::hESEQATar1D[0] = histsESE.add(Form("ESE/ESEQA/hist_%sNum", cfgTarName.value.c_str()), ";Num_{Proton}/Event;counts", HistType::kTH1F, {{100, 0, 100}}); + ese_parameters::hESEQATar1D[1] = histsESE.add(Form("ESE/ESEQA/hist_%sq2", cfgTarName.value.c_str()), ";#it{q}_{2};counts", HistType::kTH1F, {cfgaxisq2}); + ese_parameters::hESEQATar2D = histsESE.add(Form("ESE/ESEQA/hist_%sq2_Cent", cfgTarName.value.c_str()), ";#it{q}_{2};Centrality (%)", HistType::kTH2F, {cfgaxisq2, cfgaxisCent}); + ese_parameters::hESEQARef1D[0] = histsESE.add(Form("ESE/ESEQA/hist_%sNum", cfgRefName.value.c_str()), ";Num_{He3}/Event;counts", HistType::kTH1F, {{10, 0, 10}}); + ese_parameters::hESEQARef1D[1] = histsESE.add(Form("ESE/ESEQA/hist_%sq2", cfgRefName.value.c_str()), ";#it{q}_{2};counts", HistType::kTH1F, {cfgaxisq2}); + ese_parameters::hESEQARef2D = histsESE.add(Form("ESE/ESEQA/hist_%sq2_Cent", cfgRefName.value.c_str()), ";#it{q}_{2};Centrality (%)", HistType::kTH2F, {cfgaxisq2, cfgaxisCent}); + } + if (cfgOpenESE) { + ese_parameters::hESETar = histsESE.add(Form("ESE/ESE/histESE_%s", cfgTarName.value.c_str()), ";#it{p}_{T};Centrality (%);#it{q}_{2};cos(#phi-#Psi_{2});Charge", HistType::kTHnSparseF, {cfgaxispt, cfgaxisCent, cfgaxisq2, cfgaxiscos, axisCharge}); + } } - void process(soa::Filtered>::iterator const& collision, soa::Filtered> const& tracks) + void process(soa::Filtered>::iterator const& collision, TracksPIDFull const& tracks) { - const auto cent = collision.centFT0C(); - histos.fill(HIST("QA/histEventCount"), 0.5); - if (!collision.sel8()) - return; - if (tracks.size() < 1) - return; - histos.fill(HIST("QA/histEventCount"), 1.5); - if (cfgOpenFullEventQA) { - histos.fill(HIST("QA/hist_globalTracks_centT0C_before"), cent, tracks.size()); - histos.fill(HIST("QA/hist_PVTracks_centT0C_before"), cent, collision.multNTracksPV()); - histos.fill(HIST("QA/hist_globalTracks_PVTracks_before"), collision.multNTracksPV(), tracks.size()); - histos.fill(HIST("QA/hist_globalTracks_multT0A_before"), collision.multFT0A(), tracks.size()); - histos.fill(HIST("QA/hist_globalTracks_multV0A_before"), collision.multFV0A(), tracks.size()); - histos.fill(HIST("QA/hist_multV0A_multT0A_before"), collision.multFT0A(), collision.multFV0A()); - histos.fill(HIST("QA/hist_multT0C_centT0C_before"), cent, collision.multFT0C()); - } - if (cfgUseAdditionalEventCut && !selEvent(collision, tracks.size(), cent)) { + ese_parameters::eseCandidates.clear(); + const float centrality{collision.centFT0C()}; + const int64_t multTrk{tracks.size()}; + if (cfgOpenFullEventQA) + fillEventQAhistBe(collision, multTrk, centrality); + if (!eventSelBasic(collision, multTrk, centrality, true)) return; + if (cfgOpenFullEventQA) + fillEventQAhistAf(collision, multTrk, centrality); + float q2Tarx{0.}; + float q2Tary{0.}; + float q2Refx{0.}; + float q2Refy{0.}; + int multiTar{0}; + int multiRef{0}; + fillESECandidates(collision, tracks, q2Tarx, q2Tary, multiTar, q2Refx, q2Refy, multiRef); + float q2Tar{calculateq2(q2Tarx, q2Tary, multiTar)}; + float q2Ref{calculateq2(q2Refx, q2Refy, multiRef)}; + if (cfgOpenESEQA) { + ese_parameters::hESEQATar1D[0]->Fill(multiTar); + ese_parameters::hESEQATar1D[1]->Fill(q2Tar); + ese_parameters::hESEQATar2D->Fill(q2Tar, centrality); + ese_parameters::hESEQARef1D[0]->Fill(multiRef); + ese_parameters::hESEQARef1D[1]->Fill(q2Ref); + ese_parameters::hESEQARef2D->Fill(q2Ref, centrality); } - histos.fill(HIST("QA/histEventCount"), 2.5); - histos.fill(HIST("QA/histCentrality"), cent); - histos.fill(HIST("QA/histVertexZRec"), collision.posZ()); - if (cfgOpenFullEventQA) { - histos.fill(HIST("QA/hist_globalTracks_centT0C_after"), cent, tracks.size()); - histos.fill(HIST("QA/hist_PVTracks_centT0C_after"), cent, collision.multNTracksPV()); - histos.fill(HIST("QA/hist_globalTracks_PVTracks_after"), collision.multNTracksPV(), tracks.size()); - histos.fill(HIST("QA/hist_globalTracks_multT0A_after"), collision.multFT0A(), tracks.size()); - histos.fill(HIST("QA/hist_globalTracks_multV0A_after"), collision.multFV0A(), tracks.size()); - histos.fill(HIST("QA/hist_multV0A_multT0A_after"), collision.multFT0A(), collision.multFV0A()); - histos.fill(HIST("QA/hist_multT0C_centT0C_after"), cent, collision.multFT0C()); - } - auto tracksPr = protonTrackSet->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - auto tracksHe3 = he3TrackSet->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - int multiPr = tracksPr.size(); - int multiHe3 = tracksHe3.size(); - // LOGF(info, Form("Collison ID + 1; Proton Num:%d; He3 Num:%d;\n", multiPr, multiHe3)); - histos.fill(HIST("QA/histProtonNum"), multiPr); - histos.fill(HIST("QA/histHe3Num"), multiHe3); - if (multiPr < 1 && multiHe3 < 1) - return; // Reject Collisions without enough POI - for (auto i = 0; i < static_cast(cfgnMods->size()); i++) { - int detIndGlobal = detId * 4 + cfgnTotalSystem * 4 * (cfgnMods->at(i) - 2); - float psiNGlobal = helperEP.GetEventPlane(collision.qvecRe()[detIndGlobal + 3], collision.qvecIm()[detIndGlobal + 3], cfgnMods->at(i)); - if (cfgnMods->at(i) == fourier_mode::kMode2) { - // LOGF(info, "Process q2\n"); - float q2Proton = calculateq2(tracksPr, psiNGlobal, cent, 1); - float q2He3 = calculateq2(tracksHe3, psiNGlobal, cent, 2); - histos.fill(HIST("q2/hist_q2_Pr"), q2Proton); - histos.fill(HIST("q2/hist_q2_He3"), q2He3); - histos.fill(HIST("q2/hist_q2_Cen_Pr"), q2Proton, cent); - histos.fill(HIST("q2/hist_q2_Cen_He3"), q2He3, cent); - if (cfgOpenESE && multiPr > 0 && multiHe3 > 0) { - // LOGF(info, "Process ESE\n"); - if (cfgOpenESEProton) { - processESE(tracksPr, psiNGlobal, q2Proton, cent, 1, cfgOpenESEChargeSeperation); - } - if (cfgOpenESEHe3) { - processESE(tracksHe3, psiNGlobal, q2He3, cent, 2, cfgOpenESEChargeSeperation); - } - } - // LOGF(info, "Process for this event over\n"); + if (multiTar == 0) + return; + for (const auto& c : ese_parameters::eseCandidates) { + eseTable(c.vtz, c.centFT0C, c.psi2FT0C, q2Tar, q2Ref, c.signTar, c.tpcInnerParamTar, c.tpcSignalTar, c.ptTar, c.etaTar, c.phiTar, c.dcaXYTar, c.dcaZTar, c.tpcNclsTar, c.itsNclsTar, c.tpcChi2NDFTar, c.itsChi2NDFTar, c.tpcNSigmaTar, c.tofNSigmaTar, c.itsNSigmaTar, c.itsClusSizeTar); + if (cfgOpenESE) { + ese_parameters::hESETar->Fill(c.ptTar, c.centFT0C, q2Ref, std::cos(2 * (c.phiTar - c.psi2FT0C)), c.signTar); } - fillHistosQvec(collision, cfgnMods->at(i)); } } }; @@ -977,7 +1052,6 @@ struct FlowEsePHe3 { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), }; } diff --git a/PWGCF/Flow/Tasks/flowPtEfficiency.cxx b/PWGCF/Flow/Tasks/flowPtEfficiency.cxx index 0e272eb78a1..78dbc0fc731 100644 --- a/PWGCF/Flow/Tasks/flowPtEfficiency.cxx +++ b/PWGCF/Flow/Tasks/flowPtEfficiency.cxx @@ -145,18 +145,22 @@ struct FlowPtEfficiency { void init(InitContext const&) { + const AxisSpec axisVertex{20, -10, 10, "Vtxz (cm)"}; + const AxisSpec axisEta{20, -1., 1., "#eta"}; const AxisSpec axisCounter{1, 0, +1, ""}; // create histograms registry.add("eventCounter", "eventCounter", kTH1F, {axisCounter}); registry.add("hPtMCRec", "Monte Carlo Reco", {HistType::kTH1D, {axisPt}}); registry.add("hPtNchMCRec", "Reco production; pT (GeV/c); multiplicity", {HistType::kTH2D, {axisPt, axisNch}}); registry.add("hBVsPtVsPhiRec", "hBVsPtVsPhiRec", HistType::kTH3D, {axisB, axisPhi, axisPt}); + registry.add("hEtaPtVzRec", "hEtaPtVz Reconstructed", HistType::kTH3D, {axisEta, axisPt, axisVertex}); registry.add("mcEventCounter", "Monte Carlo Truth EventCounter", kTH1F, {axisCounter}); registry.add("hPtMCGen", "Monte Carlo Truth", {HistType::kTH1D, {axisPt}}); registry.add("hPtNchMCGen", "Truth production; pT (GeV/c); multiplicity", {HistType::kTH2D, {axisPt, axisNch}}); registry.add("numberOfRecoCollisions", "numberOfRecoCollisions", kTH1F, {{10, -0.5f, 9.5f}}); registry.add("hBVsPtVsPhiTrue", "hBVsPtVsPhiTrue", HistType::kTH3D, {axisB, axisPhi, axisPt}); + registry.add("hEtaPtVzTrue", "hEtaPtVz True", HistType::kTH3D, {axisEta, axisPt, axisVertex}); if (cfgFlowEnabled) { registry.add("hImpactParameterReco", "hImpactParameterReco", {HistType::kTH1D, {axisB}}); @@ -406,6 +410,7 @@ struct FlowPtEfficiency { if (isStable(mcParticle.pdgCode())) { registry.fill(HIST("hPtMCRec"), track.pt()); registry.fill(HIST("hPtNchMCRec"), track.pt(), tracks.size()); + registry.fill(HIST("hEtaPtVzRec"), track.eta(), track.pt(), vtxz); if (cfgFlowEnabled) { float deltaPhi = RecoDecay::constrainAngle(track.phi() - evPhi); @@ -462,6 +467,7 @@ struct FlowPtEfficiency { float lRandom = fRndm->Rndm(); float wacc = 1.0f; float weff = 1.0f; + float vtxz = mcCollision.posZ(); if (collisions.size() > -1) { registry.fill(HIST("mcEventCounter"), 0.5); @@ -477,8 +483,10 @@ struct FlowPtEfficiency { for (const auto& mcParticle : mcParticles) { if (mcParticle.isPhysicalPrimary() && isStable(mcParticle.pdgCode())) { registry.fill(HIST("hPtMCGen"), mcParticle.pt()); - if (collisions.size() > 0) + if (collisions.size() > 0) { registry.fill(HIST("hPtNchMCGen"), mcParticle.pt(), numberOfTracks[0]); + } + registry.fill(HIST("hEtaPtVzTrue"), mcParticle.eta(), mcParticle.pt(), vtxz); if (cfgFlowEnabled) { float deltaPhi = RecoDecay::constrainAngle(mcParticle.phi() - evPhi); diff --git a/PWGCF/Flow/Tasks/flowSP.cxx b/PWGCF/Flow/Tasks/flowSP.cxx index 05ff0d67522..db8bb0df404 100644 --- a/PWGCF/Flow/Tasks/flowSP.cxx +++ b/PWGCF/Flow/Tasks/flowSP.cxx @@ -187,8 +187,8 @@ struct FlowSP { evSel_MultCuts, evSel_kIsGoodITSLayersAll, evSel_isSelectedZDC, - nEventSelections, - evSel_CentCuts + evSel_CentCuts, + nEventSelections }; enum TrackSelections { diff --git a/PWGCF/Flow/Tasks/flowTask.cxx b/PWGCF/Flow/Tasks/flowTask.cxx index 91c7402cf90..5431a84bd47 100644 --- a/PWGCF/Flow/Tasks/flowTask.cxx +++ b/PWGCF/Flow/Tasks/flowTask.cxx @@ -113,6 +113,16 @@ struct FlowTask { Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVertex) && (aod::cent::centFT0C > cfgCentFT0CMin) && (aod::cent::centFT0C < cfgCentFT0CMax); Filter trackFilter = ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + using FilteredCollisions = soa::Filtered>; + using FilteredTracks = soa::Filtered>; + // Filter for MCcollisions + Filter mccollisionFilter = nabs(aod::mccollision::posZ) < cfgCutVertex; + using FilteredMcCollisions = soa::Filtered; + // Filter for MCParticle + Filter particleFilter = (nabs(aod::mcparticle::eta) < cfgCutEta) && (aod::mcparticle::pt > cfgCutPtMin) && (aod::mcparticle::pt < cfgCutPtMax); + using FilteredMcParticles = soa::Filtered; + + using FilteredSmallGroupMcCollisions = soa::SmallGroups>; // Corrections TH1D* mEfficiency = nullptr; @@ -127,6 +137,7 @@ struct FlowTask { // Define output OutputObj fFC{FlowContainer("FlowContainer")}; + OutputObj fFCgen{FlowContainer("FlowContainer_gen")}; OutputObj fWeights{GFWWeights("weights")}; HistogramRegistry registry{"registry"}; @@ -143,6 +154,10 @@ struct FlowTask { // Count the total number of enum kCount_CentEstimators }; + enum DataType { + kReco, + kGen + }; int mRunNumber{-1}; uint64_t mSOR{0}; double mMinSeconds{-1.}; @@ -157,9 +172,6 @@ struct FlowTask { TF1* funcV3; TF1* funcV4; - using AodCollisions = soa::Filtered>; - using AodTracks = soa::Filtered>; - // Track selection TrackSelection myTrackSel; TF1* fPhiCutLow = nullptr; @@ -222,6 +234,11 @@ struct FlowTask { registry.add("hMult", "Multiplicity distribution", {HistType::kTH1D, {{3000, 0.5, 3000.5}}}); std::string hCentTitle = "Centrality distribution, Estimator " + std::to_string(cfgCentEstimator); registry.add("hCent", hCentTitle.c_str(), {HistType::kTH1D, {{90, 0, 90}}}); + if (doprocessMCGen) { + registry.add("MCGen/MChVtxZ", "Vexter Z distribution", {HistType::kTH1D, {axisVertex}}); + registry.add("MCGen/MChMult", "Multiplicity distribution", {HistType::kTH1D, {{3000, 0.5, 3000.5}}}); + registry.add("MCGen/MChCent", hCentTitle.c_str(), {HistType::kTH1D, {{90, 0, 90}}}); + } if (!cfgUseSmallMemory) { registry.add("BeforeSel8_globalTracks_centT0C", "before sel8;Centrality T0C;mulplicity global tracks", {HistType::kTH2D, {axisCentForQA, axisNch}}); registry.add("BeforeCut_globalTracks_centT0C", "before cut;Centrality T0C;mulplicity global tracks", {HistType::kTH2D, {axisCentForQA, axisNch}}); @@ -256,6 +273,11 @@ struct FlowTask { registry.add("hDCAz", "DCAz after cuts; DCAz (cm); Pt", {HistType::kTH2D, {{200, -0.5, 0.5}, {200, 0, 5}}}); registry.add("hDCAxy", "DCAxy after cuts; DCAxy (cm); Pt", {HistType::kTH2D, {{200, -0.5, 0.5}, {200, 0, 5}}}); registry.add("hTrackCorrection2d", "Correlation table for number of tracks table; uncorrected track; corrected track", {HistType::kTH2D, {axisNch, axisNch}}); + if (doprocessMCGen) { + registry.add("MCGen/MChPhi", "#phi distribution", {HistType::kTH1D, {axisPhi}}); + registry.add("MCGen/MChEta", "#eta distribution", {HistType::kTH1D, {axisEta}}); + registry.add("MCGen/MChPtRef", "p_{T} distribution after cut", {HistType::kTH1D, {axisPtHist}}); + } o2::framework::AxisSpec axis = axisPt; int nPtBins = axis.binEdges.size() - 1; @@ -327,6 +349,11 @@ struct FlowTask { fFC->SetName("FlowContainer"); fFC->SetXAxis(fPtAxis); fFC->Initialize(oba, axisIndependent, cfgNbootstrap); + if (doprocessMCGen) { + fFCgen->SetName("FlowContainer_gen"); + fFCgen->SetXAxis(fPtAxis); + fFCgen->Initialize(oba, axisIndependent, cfgNbootstrap); + } delete oba; // eta region @@ -471,6 +498,7 @@ struct FlowTask { return; } + template void fillFC(const GFW::CorrConfig& corrconf, const double& cent, const double& rndm) { double dnx, val; @@ -479,8 +507,9 @@ struct FlowTask { if (dnx == 0) return; val = fGFW->Calculate(corrconf, 0, kFALSE).real() / dnx; - if (std::fabs(val) < 1) - fFC->FillProfile(corrconf.Head.c_str(), cent, val, dnx, rndm); + if (std::fabs(val) < 1) { + (dt == kGen) ? fFCgen->FillProfile(corrconf.Head.c_str(), cent, val, dnx, rndm) : fFC->FillProfile(corrconf.Head.c_str(), cent, val, dnx, rndm); + } return; } for (auto i = 1; i <= fPtAxis->GetNbins(); i++) { @@ -488,8 +517,9 @@ struct FlowTask { if (dnx == 0) continue; val = fGFW->Calculate(corrconf, i - 1, kFALSE).real() / dnx; - if (std::fabs(val) < 1) - fFC->FillProfile(Form("%s_pt_%i", corrconf.Head.c_str(), i), cent, val, dnx, rndm); + if (std::fabs(val) < 1) { + (dt == kGen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconf.Head.c_str(), i), cent, val, dnx, rndm) : fFC->FillProfile(Form("%s_pt_%i", corrconf.Head.c_str(), i), cent, val, dnx, rndm); + } } return; } @@ -610,7 +640,8 @@ struct FlowTask { registry.fill(HIST("hEventCountSpecific"), 8.5); // V0A T0A 5 sigma cut - if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > 5 * fT0AV0ASigma->Eval(collision.multFT0A()))) + float sigma = 5.0; + if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > sigma * fT0AV0ASigma->Eval(collision.multFT0A()))) return 0; if (cfgEvSelV0AT0ACut) registry.fill(HIST("hEventCountSpecific"), 9.5); @@ -641,7 +672,8 @@ struct FlowTask { registry.fill(HIST("hEventCountTentative"), 7.5); if (!((multNTracksPV < fMultPVCutLow->Eval(centrality)) || (multNTracksPV > fMultPVCutHigh->Eval(centrality)) || (multTrk < fMultCutLow->Eval(centrality)) || (multTrk > fMultCutHigh->Eval(centrality)))) registry.fill(HIST("hEventCountTentative"), 8.5); - if (!(std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > 5 * fT0AV0ASigma->Eval(collision.multFT0A()))) + float sigma = 5.0; + if (!(std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > sigma * fT0AV0ASigma->Eval(collision.multFT0A()))) registry.fill(HIST("hEventCountTentative"), 9.5); } @@ -675,7 +707,30 @@ struct FlowTask { gCurrentHadronicRate = gHadronicRate[mRunNumber]; } - void process(AodCollisions::iterator const& collision, aod::BCsWithTimestamps const&, AodTracks const& tracks) + template + float getCentrality(TCollision const& collision) + { + float cent; + switch (cfgCentEstimator) { + case kCentFT0C: + cent = collision.centFT0C(); + break; + case kCentFT0CVariant1: + cent = collision.centFT0CVariant1(); + break; + case kCentFT0M: + cent = collision.centFT0M(); + break; + case kCentFV0A: + cent = collision.centFV0A(); + break; + default: + cent = collision.centFT0C(); + } + return cent; + } + + void process(FilteredCollisions::iterator const& collision, aod::BCsWithTimestamps const&, FilteredTracks const& tracks) { registry.fill(HIST("hEventCount"), 0.5); if (!cfgUseSmallMemory && tracks.size() >= 1) { @@ -703,23 +758,8 @@ struct FlowTask { registry.fill(HIST("BeforeCut_multV0A_multT0A"), collision.multFT0A(), collision.multFV0A()); registry.fill(HIST("BeforeCut_multT0C_centT0C"), collision.centFT0C(), collision.multFT0C()); } - float cent; - switch (cfgCentEstimator) { - case kCentFT0C: - cent = collision.centFT0C(); - break; - case kCentFT0CVariant1: - cent = collision.centFT0CVariant1(); - break; - case kCentFT0M: - cent = collision.centFT0M(); - break; - case kCentFV0A: - cent = collision.centFV0A(); - break; - default: - cent = collision.centFT0C(); - } + float cent = getCentrality(collision); + if (cfgUseTentativeEventCounter) eventCounterQA(collision, tracks.size(), cent); if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), cent)) @@ -844,9 +884,56 @@ struct FlowTask { // Filling Flow Container for (uint l_ind = 0; l_ind < corrconfigs.size(); l_ind++) { - fillFC(corrconfigs.at(l_ind), independent, lRandom); + fillFC(corrconfigs.at(l_ind), independent, lRandom); + } + } + + void processMCGen(FilteredMcCollisions::iterator const& mcCollision, FilteredSmallGroupMcCollisions const& collisions, FilteredMcParticles const& mcParticles) + { + if (collisions.size() != 1) + return; + + float cent = -1.; + for (const auto& collision : collisions) { + cent = getCentrality(collision); + } + + float lRandom = fRndm->Rndm(); + float vtxz = mcCollision.posZ(); + registry.fill(HIST("MCGen/MChVtxZ"), vtxz); + registry.fill(HIST("MCGen/MChMult"), mcParticles.size()); + registry.fill(HIST("MCGen/MChCent"), cent); + float independent = cent; + if (cfgUseNch) + independent = static_cast(mcParticles.size()); + + fGFW->Clear(); + + for (const auto& mcParticle : mcParticles) { + if (!mcParticle.isPhysicalPrimary()) + continue; + bool withinPtPOI = (cfgCutPtPOIMin < mcParticle.pt()) && (mcParticle.pt() < cfgCutPtPOIMax); // within POI pT range + bool withinPtRef = (cfgCutPtRefMin < mcParticle.pt()) && (mcParticle.pt() < cfgCutPtRefMax); // within RF pT range + + if (withinPtRef) { + registry.fill(HIST("MCGen/MChPhi"), mcParticle.phi()); + registry.fill(HIST("MCGen/MChEta"), mcParticle.eta()); + registry.fill(HIST("MCGen/MChPtRef"), mcParticle.pt()); + } + if (withinPtRef) + fGFW->Fill(mcParticle.eta(), fPtAxis->FindBin(mcParticle.pt()) - 1, mcParticle.phi(), 1., 1); + if (withinPtPOI) + fGFW->Fill(mcParticle.eta(), fPtAxis->FindBin(mcParticle.pt()) - 1, mcParticle.phi(), 1., 2); + if (withinPtPOI && withinPtRef) + fGFW->Fill(mcParticle.eta(), fPtAxis->FindBin(mcParticle.pt()) - 1, mcParticle.phi(), 1., 4); + } + + // Filling Flow Container + for (uint l_ind = 0; l_ind < corrconfigs.size(); l_ind++) { + fillFC(corrconfigs.at(l_ind), independent, lRandom); } } + PROCESS_SWITCH(FlowTask, processMCGen, "Process analysis for MC generated events", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/Flow/Tasks/flowZdcTask.cxx b/PWGCF/Flow/Tasks/flowZdcTask.cxx index 5ae64c9ff39..136fd033eee 100644 --- a/PWGCF/Flow/Tasks/flowZdcTask.cxx +++ b/PWGCF/Flow/Tasks/flowZdcTask.cxx @@ -14,30 +14,32 @@ /// \since 10/01/2024 /// \brief task to evaluate flow and neutron skin with information from ZDC -#include -#include -#include -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/HistogramRegistry.h" - -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" +#include #include "TList.h" -#include -#include +#include #include +#include +#include #include #include -#include -#include + +#include +#include +#include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; @@ -98,7 +100,10 @@ struct FlowZdcTask { Configurable isApplyFT0CbasedOccupancy{"isApplyFT0CbasedOccupancy", false, "T0C Occu cut?"}; Configurable isTDCcut{"isTDCcut", false, "Use TDC cut?"}; Configurable isZEMcut{"isZEMcut", true, "Use ZEM cut?"}; + Configurable useMidRapNchSel{"useMidRapNchSel", true, "Use mid-rapidit Nch selection"}; + Configurable applyEff{"applyEff", true, "Apply track-by-track efficiency correction"}; + Configurable nSigmaNchCut{"nSigmaNchCut", 1., "nSigma Nch selection"}; Configurable minNchSel{"minNchSel", 5., "min Nch Selection"}; Configurable znBasedCut{"znBasedCut", 100, "ZN-based cut"}; Configurable zemCut{"zemCut", 1000., "ZEM cut"}; @@ -106,6 +111,11 @@ struct FlowZdcTask { Configurable minOccCut{"minOccCut", 0, "min Occu cut"}; Configurable maxOccCut{"maxOccCut", 500, "max Occu cut"}; Configurable minITSnCls{"minITSnCls", 5, "min ITSnCls"}; + Configurable minPt{"minPt", 0.1, "minimum pt of the tracks"}; + Configurable maxPt{"maxPt", 3., "maximum pt of the tracks"}; + Configurable maxPtSpectra{"maxPtSpectra", 50., "maximum pt of the tracks"}; + Configurable minEta{"minEta", -0.8, "minimum eta"}; + Configurable maxEta{"maxEta", +0.8, "maximum eta"}; // axis configs ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for histograms"}; ConfigurableAxis axisPhi{"axisPhi", {60, 0.0, constants::math::TwoPI}, "phi axis for histograms"}; @@ -138,9 +148,12 @@ struct FlowZdcTask { using CollisionDataTable = soa::Join; using TrackDataTable = soa::Join; using FilTrackDataTable = soa::Filtered; - std::complex qTPC; // init q TPC - std::complex qZNA{0, 0}; // init qZNA - std::complex qZNC{0, 0}; // init qZNC + + // CCDB paths + Configurable paTH{"paTH", "Users/s/sahernan/test", "base path to the ccdb object"}; + Configurable paTHmeanNch{"paTHmeanNch", "Users/s/shernan/test", "base path to the ccdb object"}; + Configurable paTHsigmaNch{"paTHsigmaNch", "Users/s/shernan/testSigma", "base path to the ccdb object"}; + Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; enum EvCutLabel { All = 1, @@ -164,8 +177,7 @@ struct FlowZdcTask { // Begin Histogram Registry HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - OutputObj pCosPsiDifferences{TProfile("pCosPsiDifferences", "Differences in cos(psi) vs Centrality;Centrality;Mean cos(psi) Difference", 200, 0, 100, -1, 1)}; - OutputObj pSinPsiDifferences{TProfile("pSinPsiDifferences", "Differences in sin(psi) vs Centrality;Centrality;Mean sin(psi) Difference", 200, 0, 100, -1, 1)}; + Service ccdb; OutputObj pZNvsFT0Ccent{TProfile("pZNvsFT0Ccent", "ZN Energy vs FT0C Centrality", 100, 0, 100, 0, 500)}; OutputObj pZPvsFT0Ccent{TProfile("pZPvsFT0Ccent", "ZP Energy vs FT0C Centrality", 100, 0, 100, 0, 500)}; OutputObj pZNratiovscent{TProfile("pZNratiovscent", "Ratio ZNC/ZNA vs FT0C Centrality", 100, 0, 100, 0, 5)}; @@ -322,6 +334,7 @@ struct FlowZdcTask { histos.add("ZEM2Vstdc", ";t_{ZEM2};ZEM2;", kTH2F, {{{30, -15., 15.}, {30, -0.5, 2000.5}}}); histos.add("debunch", ";t_{ZDC}-t_{ZDA};t_{ZDC}+t_{ZDA}", kTH2F, {{{nBinsTDC, minTdc, maxTdc}, {nBinsTDC, minTdc, maxTdc}}}); + histos.add("Nch", "Nch", kTH1F, {{nBinsNch, minNch, maxNch}}); histos.add("NchVsFT0C", ";T0C (#times 1/100, -3.3 < #eta < -2.1);#it{N}_{ch} (|#eta|<0.8);", kTH2F, {{{nBinsAmpFT0, 0., 950.}, {nBinsNch, minNch, maxNch}}}); histos.add("NchVsFT0M", ";T0A+T0C (#times 1/100, -3.3 < #eta < -2.1 and 3.5 < #eta < 4.9);#it{N}_{ch} (|#eta|<0.8);", kTH2F, {{{nBinsAmpFT0, 0., 3000.}, {nBinsNch, minNch, maxNch}}}); histos.add("NchVsFT0A", ";T0A (#times 1/100, 3.5 < #eta < 4.9);#it{N}_{ch} (|#eta|<0.8);", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsNch, minNch, maxNch}}}); @@ -336,6 +349,24 @@ struct FlowZdcTask { histos.add("ZNVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA+ZNC;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minNch, maxZn}}}); histos.add("ZNDifVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA-ZNC;", kTH2F, {{{nBinsNch, minNch, maxNch}, {100, -50., 50.}}}); } + LOG(info) << "\tccdbNoLaterThan=" << ccdbNoLaterThan.value; + LOG(info) << "\tapplyEff=" << applyEff.value; + LOG(info) << "\tpaTH=" << paTH.value; + LOG(info) << "\tuseMidRapNchSel=" << useMidRapNchSel.value; + LOG(info) << "\tpaTHmeanNch=" << paTHmeanNch.value; + LOG(info) << "\tpaTHsigmaNch=" << paTHsigmaNch.value; + LOG(info) << "\tminPt=" << minPt.value; + LOG(info) << "\tmaxPt=" << maxPt.value; + LOG(info) << "\tmaxPtSpectra=" << maxPtSpectra.value; + + ccdb->setURL("http://alice-ccdb.cern.ch"); + // Enabling object caching, otherwise each call goes to the CCDB server + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(false); + // Not later than now, will be replaced by the value of the train creation + // This avoids that users can replace objects **while** a train is running + ccdb->setCreatedNotAfter(ccdbNoLaterThan.value); } template bool isEventSelected(EventCuts const& col) @@ -479,6 +510,7 @@ struct FlowZdcTask { histos.fill(HIST("hEventCounter"), EvCutLabel::Zem); } + const double normT0M{(aT0A + aT0C) / 100.}; float znA = zdc.amplitudeZNA() / cfgCollisionEnergy; float znC = zdc.amplitudeZNC() / cfgCollisionEnergy; float zpA = zdc.amplitudeZPA() / cfgCollisionEnergy; @@ -501,28 +533,71 @@ struct FlowZdcTask { } // Track Selection if (track.isGlobalTrack()) { - glbTracks++; - meanpt += track.pt(); - et += std::sqrt(std::pow(track.pt(), 2.) + std::pow(o2::constants::physics::MassPionCharged, 2.)); + continue; } + glbTracks++; } + bool skipEvent{false}; + if (useMidRapNchSel) { + auto hMeanNch = ccdb->getForTimeStamp(paTHmeanNch.value, foundBC.timestamp()); + auto hSigmaNch = ccdb->getForTimeStamp(paTHsigmaNch.value, foundBC.timestamp()); + if (!hMeanNch) { + LOGF(info, "hMeanNch NOT LOADED!"); + return; + } + if (!hSigmaNch) { + LOGF(info, "hSigmaNch NOT LOADED!"); + return; + } + const int binT0M{hMeanNch->FindBin(normT0M)}; + const double meanNch{hMeanNch->GetBinContent(binT0M)}; + const double sigmaNch{hSigmaNch->GetBinContent(binT0M)}; + const double nSigmaSelection{nSigmaNchCut * sigmaNch}; + const double diffMeanNch{meanNch - glbTracks}; + + if (!(std::abs(diffMeanNch) < nSigmaSelection)) { + histos.fill(HIST("ExcludedEvtVsNch"), glbTracks); + } else { + skipEvent = true; + } + } + if (!skipEvent) { + return; + } + + for (const auto& track : tracks) { + // Track Selection + if (!track.isGlobalTrack()) { + continue; + } + if ((track.pt() < minPt) || (track.pt() > maxPtSpectra)) { + continue; + } + + histos.fill(HIST("ZposVsEta"), collision.posZ(), track.eta()); + histos.fill(HIST("EtaVsPhi"), track.eta(), track.phi()); + histos.fill(HIST("dcaXYvspT"), track.dcaXY(), track.pt()); + et += std::sqrt(std::pow(track.pt(), 2.) + std::pow(o2::constants::physics::MassPionCharged, 2.)); + meanpt += track.pt(); + } histos.fill(HIST("zPos"), collision.posZ()); histos.fill(HIST("T0Ccent"), collision.centFT0C()); - histos.fill(HIST("ZNCcvsZNCsum"), sumZNC / 2.81, zdc.energyCommonZNC() / 2.81); - histos.fill(HIST("ZNAcvsZNAsum"), sumZNA / 2.81, zdc.energyCommonZNA() / 2.81); - histos.fill(HIST("ZPCcvsZPCsum"), sumZPC / 2.81, zdc.energyCommonZPC() / 2.81); - histos.fill(HIST("ZPAcvsZPAsum"), sumZPA / 2.81, zdc.energyCommonZPA() / 2.81); + histos.fill(HIST("ZNCcvsZNCsum"), sumZNC / cfgCollisionEnergy, zdc.energyCommonZNC() / cfgCollisionEnergy); + histos.fill(HIST("ZNAcvsZNAsum"), sumZNA / cfgCollisionEnergy, zdc.energyCommonZNA() / cfgCollisionEnergy); + histos.fill(HIST("ZPCcvsZPCsum"), sumZPC / cfgCollisionEnergy, zdc.energyCommonZPC() / cfgCollisionEnergy); + histos.fill(HIST("ZPAcvsZPAsum"), sumZPA / cfgCollisionEnergy, zdc.energyCommonZPA() / cfgCollisionEnergy); + histos.fill(HIST("Nch"), glbTracks); histos.fill(HIST("ZNA"), znA); histos.fill(HIST("ZNC"), znC); histos.fill(HIST("ZPA"), zpA); histos.fill(HIST("ZPC"), zpC); - histos.fill(HIST("ZNASector"), sumZNA); - histos.fill(HIST("ZNCSector"), sumZNC); - histos.fill(HIST("ZPASector"), sumZPA); - histos.fill(HIST("ZPCSector"), sumZPC); + histos.fill(HIST("ZNASector"), sumZNA / cfgCollisionEnergy); + histos.fill(HIST("ZNCSector"), sumZNC / cfgCollisionEnergy); + histos.fill(HIST("ZPASector"), sumZPA / cfgCollisionEnergy); + histos.fill(HIST("ZPCSector"), sumZPC / cfgCollisionEnergy); histos.fill(HIST("ZN"), znA + znC); histos.fill(HIST("ZNAVsZNC"), znC, znA); histos.fill(HIST("ZNAVsZPA"), zpA, znA); @@ -573,10 +648,6 @@ struct FlowZdcTask { int globalTracks = tracks.size(); if (globalTracks < 1) return; - // this is the q vector for the TPC data. it is a complex function - double qTpcReal = 0.0; // Initialize qTPC_real - double qTpcIm = 0.0; // init qTPC_imaginary - std::complex qTPC(0, 0); // Starting with a q-vector of zero int nTot{0}; // Tracks are already filtered with GlobalTrack || GlobalTrackSDD for (const auto& track : tracks) { double phi = track.phi(); @@ -584,7 +655,6 @@ struct FlowZdcTask { histos.fill(HIST("etaHistogram"), track.eta()); histos.fill(HIST("phiHistogram"), track.phi()); histos.fill(HIST("ptHistogram"), track.pt()); - qTPC += std::complex(std::cos(2.0 * phi), std::sin(2.0 * phi)); } // end track loop 1 double pT{0}; for (const auto& track : tracks) { @@ -598,16 +668,9 @@ struct FlowZdcTask { histos.fill(HIST("multvsCent"), cent, nTot); histos.fill(HIST("hYield"), nTot, pT); histos.fill(HIST("multHistogram"), nTot); - qTpcReal = qTPC.real() / nTot; // normalize these vectors by the total number of particles - qTpcIm = qTPC.imag() / nTot; - - histos.fill(HIST("REqHistogram"), qTpcReal); - histos.fill(HIST("IMqHistogram"), qTpcIm); histos.fill(HIST("TPCmultiplicity"), multTPC); histos.fill(HIST("hGlobalTracks"), globalTracks); - - histos.fill(HIST("revsimag"), qTpcReal, qTpcIm); } void processZdcCollAssoc( AodCollisions::iterator const& collision, diff --git a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx index 43bd99639ba..c7d268057e4 100644 --- a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx +++ b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx @@ -75,6 +75,8 @@ std::vector centbinning(90); int nBootstrap = 10; GFWRegions regions; GFWCorrConfigs configs; +std::vector multGlobalCorrCutPars; +std::vector multPVCorrCutPars; } // namespace o2::analysis::gfw struct FlowGenericFramework { @@ -92,9 +94,12 @@ struct FlowGenericFramework { O2_DEFINE_CONFIGURABLE(cfgUseGapMethod, bool, false, "Use gap method in vn-pt calculations") O2_DEFINE_CONFIGURABLE(cfgEfficiency, std::string, "", "CCDB path to efficiency object") O2_DEFINE_CONFIGURABLE(cfgAcceptance, std::string, "", "CCDB path to acceptance object") - O2_DEFINE_CONFIGURABLE(cfgDCAxy, float, 0.2, "Cut on DCA in the transverse direction (cm)"); + O2_DEFINE_CONFIGURABLE(cfgDCAxyNSigma, float, 7, "Cut on number of sigma deviations from expected DCA in the transverse direction"); O2_DEFINE_CONFIGURABLE(cfgDCAz, float, 2, "Cut on DCA in the longitudinal direction (cm)"); - O2_DEFINE_CONFIGURABLE(cfgNcls, float, 70, "Cut on number of TPC clusters found"); + O2_DEFINE_CONFIGURABLE(cfgNTPCCls, float, 70, "Cut on number of TPC clusters found"); + O2_DEFINE_CONFIGURABLE(cfgMinNITSCls, float, 5, "Cut on minimum number of ITS clusters found"); + O2_DEFINE_CONFIGURABLE(cfgChi2PrITSCls, float, 36, "Cut on chi^2 per ITS clusters found"); + O2_DEFINE_CONFIGURABLE(cfgChi2PrTPCCls, float, 2.5, "Cut on chi^2 per TPC clusters found"); O2_DEFINE_CONFIGURABLE(cfgPtmin, float, 0.2, "minimum pt (GeV/c)"); O2_DEFINE_CONFIGURABLE(cfgPtmax, float, 10, "maximum pt (GeV/c)"); O2_DEFINE_CONFIGURABLE(cfgEta, float, 0.8, "eta cut"); @@ -114,6 +119,10 @@ struct FlowGenericFramework { O2_DEFINE_CONFIGURABLE(cfgUseDensityDependentCorrection, bool, false, "Use density dependent efficiency correction based on Run 2 measurements"); Configurable> cfgTrackDensityP0{"cfgTrackDensityP0", std::vector{0.7217476707, 0.7384792571, 0.7542625668, 0.7640680200, 0.7701951667, 0.7755299053, 0.7805901710, 0.7849446786, 0.7957356586, 0.8113039262, 0.8211968966, 0.8280558878, 0.8329342135}, "parameter 0 for track density efficiency correction"}; Configurable> cfgTrackDensityP1{"cfgTrackDensityP1", std::vector{-2.169488e-05, -2.191913e-05, -2.295484e-05, -2.556538e-05, -2.754463e-05, -2.816832e-05, -2.846502e-05, -2.843857e-05, -2.705974e-05, -2.477018e-05, -2.321730e-05, -2.203315e-05, -2.109474e-05}, "parameter 1 for track density efficiency correction"}; + Configurable> cfgMultGlobalCutPars{"cfgMultGlobalCutPars", std::vector{2272.16, -76.6932, 1.01204, -0.00631545, 1.59868e-05, 136.336, -4.97006, 0.121199, -0.0015921, 7.66197e-06}, "Global multiplicity cut parameter values"}; + Configurable> cfgMultPVCutPars{"cfgMultPVCutPars", std::vector{3074.43, -106.192, 1.46176, -0.00968364, 2.61923e-05, 182.128, -7.43492, 0.193901, -0.00256715, 1.22594e-05}, "PV multiplicity cut parameter values"}; + O2_DEFINE_CONFIGURABLE(cfgMultCorrHighCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultCorrLowCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x - 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); Configurable cfgGFWBinning{"cfgGFWBinning", {40, 16, 72, 300, 0, 3000, 0.2, 10.0, 0.2, 3.0, {0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4, 4.5, 5, 5.5, 6, 7, 8, 9, 10}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90}}, "Configuration for binning"}; Configurable cfgRegions{"cfgRegions", {{"refN", "refP", "refFull"}, {-0.8, 0.4, -0.8}, {-0.4, 0.8, 0.8}, {0, 0, 0}, {1, 1, 1}}, "Configurations for GFW regions"}; @@ -161,7 +170,8 @@ struct FlowGenericFramework { kCentFT0C = 0, kCentFT0CVariant1, kCentFT0M, - kCentFV0A + kCentFV0A, + kCentNTPV }; // Define global variables @@ -231,6 +241,8 @@ struct FlowGenericFramework { o2::analysis::gfw::nchup = cfgGFWBinning->GetNchMax(); o2::analysis::gfw::centbinning = cfgGFWBinning->GetCentBinning(); cfgGFWBinning->Print(); + o2::analysis::gfw::multGlobalCorrCutPars = cfgMultGlobalCutPars; + o2::analysis::gfw::multPVCorrCutPars = cfgMultPVCutPars; AxisSpec phiAxis = {o2::analysis::gfw::phibins, o2::analysis::gfw::philow, o2::analysis::gfw::phiup, "#phi"}; AxisSpec etaAxis = {o2::analysis::gfw::etabins, -cfgEta, cfgEta, "#eta"}; @@ -250,6 +262,9 @@ struct FlowGenericFramework { case kCentFV0A: sCentralityEstimator = "FV0A"; break; + case kCentNTPV: + sCentralityEstimator = "NTPV"; + break; default: sCentralityEstimator = "FT0C"; } @@ -265,7 +280,8 @@ struct FlowGenericFramework { AxisSpec t0cAxis = {70, 0, 70000, "N_{ch} (T0C)"}; AxisSpec t0aAxis = {200, 0, 200, "N_{ch}"}; AxisSpec multpvAxis = {4000, 0, 4000, "N_{ch} (PV)"}; - AxisSpec multAxis = (cfgUseNch) ? nchAxis : centAxis; + AxisSpec multAxis = (doprocessOnTheFly && !cfgUseNch) ? bAxis : (cfgUseNch) ? nchAxis + : centAxis; AxisSpec dcaZAXis = {200, -2, 2, "DCA_{z} (cm)"}; AxisSpec dcaXYAXis = {200, -1, 1, "DCA_{xy} (cm)"}; ccdb->setURL("http://alice-ccdb.cern.ch"); @@ -362,15 +378,24 @@ struct FlowGenericFramework { fFCpt->initialise(multAxis, cfgMpar, o2::analysis::gfw::configs, cfgNbootstrap); // Event selection - Alex if (cfgUseAdditionalEventCut) { - fMultPVCutLow = new TF1("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x - 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); - fMultPVCutLow->SetParameters(3257.29, -121.848, 1.98492, -0.0172128, 6.47528e-05, 154.756, -1.86072, -0.0274713, 0.000633499, -3.37757e-06); - fMultPVCutHigh = new TF1("fMultPVCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x + 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); - fMultPVCutHigh->SetParameters(3257.29, -121.848, 1.98492, -0.0172128, 6.47528e-05, 154.756, -1.86072, -0.0274713, 0.000633499, -3.37757e-06); - - fMultCutLow = new TF1("fMultCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); - fMultCutLow->SetParameters(1654.46, -47.2379, 0.449833, -0.0014125, 150.773, -3.67334, 0.0530503, -0.000614061, 3.15956e-06); - fMultCutHigh = new TF1("fMultCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 3.*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); - fMultCutHigh->SetParameters(1654.46, -47.2379, 0.449833, -0.0014125, 150.773, -3.67334, 0.0530503, -0.000614061, 3.15956e-06); + fMultPVCutLow = new TF1("fMultPVCutLow", cfgMultCorrLowCutFunction->c_str(), 0, 100); + fMultPVCutLow->SetParameters(&(o2::analysis::gfw::multPVCorrCutPars[0])); + fMultPVCutHigh = new TF1("fMultPVCutHigh", cfgMultCorrHighCutFunction->c_str(), 0, 100); + fMultPVCutHigh->SetParameters(&(o2::analysis::gfw::multPVCorrCutPars[0])); + fMultCutLow = new TF1("fMultCutLow", cfgMultCorrLowCutFunction->c_str(), 0, 100); + fMultCutLow->SetParameters(&(o2::analysis::gfw::multGlobalCorrCutPars[0])); + fMultCutHigh = new TF1("fMultCutHigh", cfgMultCorrHighCutFunction->c_str(), 0, 100); + fMultCutHigh->SetParameters(&(o2::analysis::gfw::multGlobalCorrCutPars[0])); + /* + fMultPVCutLow = new TF1("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x - 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); + fMultPVCutLow->SetParameters(3257.29, -121.848, 1.98492, -0.0172128, 6.47528e-05, 154.756, -1.86072, -0.0274713, 0.000633499, -3.37757e-06); + fMultPVCutHigh = new TF1("fMultPVCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x + 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); + fMultPVCutHigh->SetParameters(3257.29, -121.848, 1.98492, -0.0172128, 6.47528e-05, 154.756, -1.86072, -0.0274713, 0.000633499, -3.37757e-06); + + fMultCutLow = new TF1("fMultCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); + fMultCutLow->SetParameters(1654.46, -47.2379, 0.449833, -0.0014125, 150.773, -3.67334, 0.0530503, -0.000614061, 3.15956e-06); + fMultCutHigh = new TF1("fMultCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 3.*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); + fMultCutHigh->SetParameters(1654.46, -47.2379, 0.449833, -0.0014125, 150.773, -3.67334, 0.0530503, -0.000614061, 3.15956e-06); */ } if (cfgUseDensityDependentCorrection) { std::vector pTEffBins = {0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.4, 1.8, 2.2, 2.6, 3.0}; @@ -600,6 +625,13 @@ struct FlowGenericFramework { return 1; } + template + bool trackSelected(TTrack track) + { + if (cfgDCAxyNSigma && (std::fabs(track.dcaXY()) > cfgDCAxyNSigma / 7. * (0.0105f + 0.0035f / track.pt()))) + return false; + return ((track.tpcNClsFound() >= cfgNTPCCls) && (track.itsNCls() >= cfgMinNITSCls)); + } enum DataType { kReco, kGen @@ -797,7 +829,10 @@ struct FlowGenericFramework { if (cfgFillQA) fillTrackQA(track, vtxz); - if (mcParticle.eta() < o2::analysis::gfw::etalow || mcParticle.eta() > o2::analysis::gfw::etaup || mcParticle.pt() < o2::analysis::gfw::ptlow || mcParticle.pt() > o2::analysis::gfw::ptup || track.tpcNClsFound() < cfgNcls) + if (mcParticle.eta() < o2::analysis::gfw::etalow || mcParticle.eta() > o2::analysis::gfw::etaup || mcParticle.pt() < o2::analysis::gfw::ptlow || mcParticle.pt() > o2::analysis::gfw::ptup) + return; + + if (!trackSelected(track)) return; int pidIndex = 0; @@ -852,7 +887,8 @@ struct FlowGenericFramework { } else { if (cfgFillQA) fillTrackQA(track, vtxz); - if (track.tpcNClsFound() < cfgNcls) + + if (!trackSelected(track)) return; int pidIndex = 0; @@ -989,11 +1025,11 @@ struct FlowGenericFramework { } o2::framework::expressions::Filter collisionFilter = nabs(aod::collision::posZ) < cfgVtxZ; - o2::framework::expressions::Filter trackFilter = nabs(aod::track::eta) < cfgEta && aod::track::pt > cfgPtmin&& aod::track::pt < cfgPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && nabs(aod::track::dcaXY) < cfgDCAxy&& nabs(aod::track::dcaZ) < cfgDCAz; + o2::framework::expressions::Filter trackFilter = nabs(aod::track::eta) < cfgEta && aod::track::pt > cfgPtmin&& aod::track::pt < cfgPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::itsChi2NCl < cfgChi2PrITSCls) && (aod::track::tpcChi2NCl < cfgChi2PrTPCCls) && nabs(aod::track::dcaZ) < cfgDCAz; using GFWTracks = soa::Filtered>; - void processData(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, GFWTracks const& tracks) + void processData(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, GFWTracks const& tracks) { auto bc = collision.bc_as(); int run = bc.runNumber(); @@ -1044,6 +1080,9 @@ struct FlowGenericFramework { case kCentFV0A: centrality = collision.centFV0A(); break; + case kCentNTPV: + centrality = collision.centNTPV(); + break; default: centrality = collision.centFT0C(); } diff --git a/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx b/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx index cb57211fcaf..2d35169f9e8 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx @@ -49,7 +49,8 @@ struct ThreeParticleCorrelations { float pionPtMin = 0.3, pionPtMax = 2.3, kaonPtMin = 0.5, kaonPtMax = 2.5, protonPtMin = 0.5, protonPtMax = 2.5; float pionPtMid = 1.5, kaonPtMid1 = 1.5, kaonPtMid2 = 2.0, protonPtMid = 0.7; - float dEtaMin = 0.02, dPhiStarMin = 0.1; + float dEtaMax = 0.05, dEtaMin = 0.022; + float dPhiStarMinOS = 0.075, dPhiStarMinSS = 0.12; float rMin = 0.8, rMax = 2.5; // Lambda invariant mass fit @@ -68,10 +69,6 @@ struct ThreeParticleCorrelations { Filter mcCollZvtx = nabs(aod::mccollision::posZ) < zvtxMax; Filter evSelect = aod::evsel::sel8 == true; - // V0 filters - Filter v0Pt = aod::v0data::pt > v0PtMin&& aod::v0data::pt < v0PtMax; - Filter v0Eta = nabs(aod::v0data::eta) < v0EtaMax; - // Track filters Filter trackPt = aod::track::pt > trackPtMin&& aod::track::pt < trackPtMax; Filter trackEta = nabs(aod::track::eta) < trackEtaMax; @@ -83,17 +80,19 @@ struct ThreeParticleCorrelations { // Table aliases - Data using MyFilteredCollisions = soa::Filtered>; using MyFilteredCollision = MyFilteredCollisions::iterator; - using MyFilteredV0s = soa::Filtered; using MyFilteredTracks = soa::Filtered>; - // Table aliases - MC + // Table aliases - MC Gen using MyFilteredMCGenCollisions = soa::Filtered>; using MyFilteredMCGenCollision = MyFilteredMCGenCollisions::iterator; using MyFilteredMCParticles = soa::Filtered; - using MyFilteredMCRecCollision = soa::Filtered>::iterator; - using MyFilteredMCV0s = soa::Filtered>; + + // Table aliases - MC Rec + using MCRecCollisions = soa::Join; + using MyFilteredMCRecCollisions = soa::Filtered; + using MyMCV0s = soa::Join; using MyFilteredMCTracks = soa::Filtered>; @@ -110,6 +109,7 @@ struct ThreeParticleCorrelations { // Mixed-events binning policy SliceCache cache; Preslice perCol = aod::mcparticle::mcCollisionId; + PresliceUnsorted perMCCol = aod::mccollisionlabel::mcCollisionId; ConfigurableAxis confCentBins{"confCentBins", {VARIABLE_WIDTH, 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f}, "ME Centrality binning"}; ConfigurableAxis confZvtxBins{"confZvtxBins", {VARIABLE_WIDTH, -7.0f, -5.0f, -3.0f, -1.0f, 0.0f, 1.0f, 3.0f, 5.0f, 7.0f}, "ME Zvtx binning"}; @@ -118,7 +118,7 @@ struct ThreeParticleCorrelations { BinningType collBinning{{confCentBins, confZvtxBins}, true}; BinningTypeMC collBinningMC{{confCentBins, confZvtxBins}, true}; - Pair pairData{collBinning, 5, -1, &cache}; + Pair pairData{collBinning, 5, -1, &cache}; SameKindPair pairMC{collBinningMC, 5, -1, &cache}; // Process configurables @@ -198,14 +198,31 @@ struct ThreeParticleCorrelations { rQARegistry.add("hInvMassAntiLambda_MC", "hInvMassAntiLambda_MC", {HistType::kTH3D, {{lambdaInvMassAxis}, {v0PtAxis}, {centralityAxis}}}); // PhiStar - rPhiStarRegistry.add("hSEProtonPreCut_OS", "hSEProtonPreCut_OS", {HistType::kTH2D, {{80, -0.2, 0.2}, {40, -0.1, 0.1}}}); - rPhiStarRegistry.add("hSEProtonPreCut_SS", "hSEProtonPreCut_SS", {HistType::kTH2D, {{80, -0.2, 0.2}, {40, -0.1, 0.1}}}); - rPhiStarRegistry.add("hSEProtonPostCut_OS", "hSEProtonPostCut_OS", {HistType::kTH2D, {{80, -0.2, 0.2}, {40, -0.1, 0.1}}}); - rPhiStarRegistry.add("hSEProtonPostCut_SS", "hSEProtonPostCut_SS", {HistType::kTH2D, {{80, -0.2, 0.2}, {40, -0.1, 0.1}}}); - rPhiStarRegistry.add("hMEProtonPreCut_OS", "hMEProtonPreCut_OS", {HistType::kTH2D, {{80, -0.2, 0.2}, {40, -0.1, 0.1}}}); - rPhiStarRegistry.add("hMEProtonPreCut_SS", "hMEProtonPreCut_SS", {HistType::kTH2D, {{80, -0.2, 0.2}, {40, -0.1, 0.1}}}); - rPhiStarRegistry.add("hMEProtonPostCut_OS", "hMEProtonPostCut_OS", {HistType::kTH2D, {{80, -0.2, 0.2}, {40, -0.1, 0.1}}}); - rPhiStarRegistry.add("hMEProtonPostCut_SS", "hMEProtonPostCut_SS", {HistType::kTH2D, {{80, -0.2, 0.2}, {40, -0.1, 0.1}}}); + rPhiStarRegistry.add("hSEProtonPreCut_OS", "hSEProtonPreCut_OS", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hSEProtonPreCut_SS", "hSEProtonPreCut_SS", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hSEProtonPreCut_SSP", "hSEProtonPreCut_SSP", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hSEProtonPreCut_SSN", "hSEProtonPreCut_SSN", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hSEProtonPostCut_OS", "hSEProtonPostCut_OS", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hSEProtonPostCut_SS", "hSEProtonPostCut_SS", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hSEProtonPostCut_SSP", "hSEProtonPostCut_SSP", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hSEProtonPostCut_SSN", "hSEProtonPostCut_SSN", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hSEPhiStarMean_OS", "hSEPhiStarMean_OS", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hSEPhiStarMean_SS", "hSEPhiStarMean_SS", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hSEPhiStarMean_SSP", "hSEPhiStarMean_SSP", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hSEPhiStarMean_SSN", "hSEPhiStarMean_SSN", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + + rPhiStarRegistry.add("hMEProtonPreCut_OS", "hMEProtonPreCut_OS", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hMEProtonPreCut_SS", "hMEProtonPreCut_SS", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hMEProtonPreCut_SSP", "hMEProtonPreCut_SSP", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hMEProtonPreCut_SSN", "hMEProtonPreCut_SSN", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hMEProtonPostCut_OS", "hMEProtonPostCut_OS", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hMEProtonPostCut_SS", "hMEProtonPostCut_SS", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hMEProtonPostCut_SSP", "hMEProtonPostCut_SSP", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hMEProtonPostCut_SSN", "hMEProtonPostCut_SSN", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hMEPhiStarMean_OS", "hMEPhiStarMean_OS", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hMEPhiStarMean_SS", "hMEPhiStarMean_SS", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hMEPhiStarMean_SSP", "hMEPhiStarMean_SSP", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); + rPhiStarRegistry.add("hMEPhiStarMean_SSN", "hMEPhiStarMean_SSN", {HistType::kTH2D, {{121, -0.3025, 0.3025}, {101, -0.0505, 0.0505}}}); // Efficiency rMCRegistry.add("hGenerated", "hGenerated", {HistType::kTH3D, {{trackPtAxis}, {trackEtaAxis}, {centralityAxis}}}); @@ -300,7 +317,7 @@ struct ThreeParticleCorrelations { //========================================================================================================================================================================================================================================================================== - void processSame(MyFilteredCollision const& collision, MyFilteredV0s const& v0s, MyFilteredTracks const& tracks, aod::BCsWithTimestamps const&) + void processSame(MyFilteredCollision const& collision, aod::V0Datas const& v0s, MyFilteredTracks const& tracks, aod::BCsWithTimestamps const&) { if (!acceptEvent(collision, true)) { @@ -412,12 +429,11 @@ struct ThreeParticleCorrelations { // End of the Same-Event correlations } - void processMixed(MyFilteredCollisions const&, MyFilteredV0s const&, MyFilteredTracks const&, aod::BCsWithTimestamps const&) + void processMixed(MyFilteredCollisions const&, aod::V0Datas const&, MyFilteredTracks const&, aod::BCsWithTimestamps const&) { // Start of the Mixed-Event correlations for (const auto& [coll_1, v0_1, coll_2, track_2] : pairData) { - if (!acceptEvent(coll_1, false) || !acceptEvent(coll_2, false)) { return; } @@ -481,9 +497,17 @@ struct ThreeParticleCorrelations { // End of the Mixed-Event Correlations } - void processMCSame(MyFilteredMCGenCollision const& collision, MyFilteredMCParticles const&) + void processMCSame(MyFilteredMCGenCollision const& collision, MyFilteredMCParticles const&, soa::SmallGroups const& recCollisions) { + if (recCollisions.size() == 1) { + for (const auto& recCollision : recCollisions) { + if (!acceptEvent(recCollision, false)) { + return; + } + } + } + rQARegistry.fill(HIST("hEventCentrality_MC"), collision.bestCollisionCentFT0C()); auto groupMCTriggers = mcTriggers->sliceByCached(aod::mcparticle::mcCollisionId, collision.globalIndex(), cache); auto groupMCAssociates = mcAssociates->sliceByCached(aod::mcparticle::mcCollisionId, collision.globalIndex(), cache); @@ -541,14 +565,28 @@ struct ThreeParticleCorrelations { // End of the MC Same-Event Correlations } - void processMCMixed(MyFilteredMCGenCollisions const&, MyFilteredMCParticles const&) + void processMCMixed(MyFilteredMCGenCollisions const&, MyFilteredMCParticles const&, MyFilteredMCRecCollisions const& recCollisions) { // Start of the MC Mixed-events Correlations for (const auto& [coll_1, v0_1, coll_2, particle_2] : pairMC) { + auto recCollsA1 = recCollisions.sliceBy(perMCCol, coll_1.globalIndex()); + auto recCollsA2 = recCollisions.sliceBy(perMCCol, coll_2.globalIndex()); + if (recCollsA1.size() == 1 && recCollsA2.size() == 1) { + for (const auto& recColl_1 : recCollsA1) { + if (!acceptEvent(recColl_1, false)) { + return; + } + } + for (const auto& recColl_2 : recCollsA2) { + if (!acceptEvent(recColl_2, false)) { + return; + } + } + } + auto groupMCTriggers = mcTriggers->sliceByCached(aod::mcparticle::mcCollisionId, coll_1.globalIndex(), cache); auto groupMCAssociates = mcAssociates->sliceByCached(aod::mcparticle::mcCollisionId, coll_2.globalIndex(), cache); - for (const auto& [trigger, associate] : soa::combinations(soa::CombinationsFullIndexPolicy(groupMCTriggers, groupMCAssociates))) { if (trigger.isPhysicalPrimary() && associate.isPhysicalPrimary()) { @@ -579,9 +617,17 @@ struct ThreeParticleCorrelations { // End of the MC Mixed-events Correlations } - void processMCGen(MyFilteredMCGenCollision const& collision, MyFilteredMCParticles const&) + void processMCGen(MyFilteredMCGenCollision const& collision, MyFilteredMCParticles const&, soa::SmallGroups const& recCollisions) { + if (recCollisions.size() == 1) { + for (const auto& recCollision : recCollisions) { + if (!acceptEvent(recCollision, false)) { + return; + } + } + } + auto groupMCTracks = mcTracks->sliceByCached(aod::mcparticle::mcCollisionId, collision.globalIndex(), cache); auto groupMCV0s = mcV0s->sliceByCached(aod::mcparticle::mcCollisionId, collision.globalIndex(), cache); @@ -621,7 +667,7 @@ struct ThreeParticleCorrelations { // End of the Monte-Carlo generated QA } - void processMCRec(MyFilteredMCRecCollision const& collision, MyFilteredMCV0s const& v0s, MyFilteredMCTracks const& tracks, aod::McCollisions const&, aod::McParticles const&) + void processMCRec(MyFilteredMCRecCollisions::iterator const& collision, MyMCV0s const& v0s, MyFilteredMCTracks const& tracks, aod::McCollisions const&, aod::McParticles const&) { if (!acceptEvent(collision, false) || !collision.has_mcCollision()) { @@ -712,7 +758,7 @@ struct ThreeParticleCorrelations { for (const auto& v0 : v0s) { - if (!v0.has_mcParticle()) { + if (!v0.has_mcParticle() || v0.pt() < v0PtMin || v0.pt() > v0PtMax || std::abs(v0.eta()) > v0EtaMax) { continue; } auto particle = v0.mcParticle(); @@ -850,26 +896,31 @@ struct ThreeParticleCorrelations { } if (!collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { // kNoSameBunchPileup - return false; + return kFALSE; } if (FillHist) { rQARegistry.fill(HIST("hNEvents"), 1.5); } if (!collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { // kIsGoodZvtxFT0vsPV - return false; + return kFALSE; } if (FillHist) { rQARegistry.fill(HIST("hNEvents"), 2.5); } - return true; + return kTRUE; } template bool v0Filters(const V0Cand& v0, bool MCRec) // V0 filter { + if (v0.pt() < v0PtMin || v0.pt() > v0PtMax) + return kFALSE; + if (std::abs(v0.eta()) > v0EtaMax) + return kFALSE; + if (!MCRec) { // Data if (v0Sign(v0) == 1) { const auto& posDaughter = v0.template posTrack_as(); @@ -1030,6 +1081,7 @@ struct ThreeParticleCorrelations { bool radialDistanceFilter(const V0Cand& v0, const TrackCand& track, double B, bool Mix) { + bool pass = true; if (confRDSwitch) { auto proton = v0.template posTrack_as(); @@ -1038,8 +1090,8 @@ struct ThreeParticleCorrelations { } double dEta = proton.eta() - track.eta(); - if (std::abs(dEta) > dEtaMin) { - return kTRUE; + if (std::abs(dEta) > dEtaMax) { + return pass; } double dPhiStar; @@ -1047,6 +1099,9 @@ struct ThreeParticleCorrelations { double phaseProton = (-0.3 * B * proton.sign()) / (2 * proton.pt()); double phaseTrack = (-0.3 * B * track.sign()) / (2 * track.pt()); + double dPhiStarMean = 0; + + // Start of the TPC radius loop for (double r = rMin; r <= rMax; r += 0.01) { dPhiStar = RecoDecay::constrainAngle(dPhi + std::asin(phaseProton * r) - std::asin(phaseTrack * r), -constants::math::PIHalf); @@ -1056,6 +1111,11 @@ struct ThreeParticleCorrelations { rPhiStarRegistry.fill(HIST("hSEProtonPreCut_OS"), dPhiStar, dEta); } else if (proton.sign() * track.sign() == 1) { // SS (Electric charge) rPhiStarRegistry.fill(HIST("hSEProtonPreCut_SS"), dPhiStar, dEta); + if (proton.sign() == 1) { // Positive + rPhiStarRegistry.fill(HIST("hSEProtonPreCut_SSP"), dPhiStar, dEta); + } else if (proton.sign() == -1) { // Negative + rPhiStarRegistry.fill(HIST("hSEProtonPreCut_SSN"), dPhiStar, dEta); + } } } else { // Mixed-event @@ -1063,20 +1123,38 @@ struct ThreeParticleCorrelations { rPhiStarRegistry.fill(HIST("hMEProtonPreCut_OS"), dPhiStar, dEta); } else if (proton.sign() * track.sign() == 1) { // SS (Electric charge) rPhiStarRegistry.fill(HIST("hMEProtonPreCut_SS"), dPhiStar, dEta); + if (proton.sign() == 1) { // Positive + rPhiStarRegistry.fill(HIST("hMEProtonPreCut_SSP"), dPhiStar, dEta); + } else if (proton.sign() == -1) { // Negative + rPhiStarRegistry.fill(HIST("hMEProtonPreCut_SSN"), dPhiStar, dEta); + } } } } - if (std::abs(dPhiStar) < dPhiStarMin) { - return kFALSE; + if (std::abs(dEta) < dEtaMin) { + if (proton.sign() * track.sign() == -1) { // OS (Electric charge) + if (std::abs(dPhiStar) < dPhiStarMinOS) { + pass = false; + } + } else if (proton.sign() * track.sign() == 1) { // SS (Electric charge) + if (std::abs(dPhiStar) < dPhiStarMinSS) { + pass = false; + } + } } - if (r == rMin) { + if (r == rMin && pass) { if (!Mix) { // Same-event if (proton.sign() * track.sign() == -1) { // OS (Electric charge) rPhiStarRegistry.fill(HIST("hSEProtonPostCut_OS"), dPhiStar, dEta); } else if (proton.sign() * track.sign() == 1) { // SS (Electric charge) rPhiStarRegistry.fill(HIST("hSEProtonPostCut_SS"), dPhiStar, dEta); + if (proton.sign() == 1) { // Positive + rPhiStarRegistry.fill(HIST("hSEProtonPostCut_SSP"), dPhiStar, dEta); + } else if (proton.sign() == -1) { // Negative + rPhiStarRegistry.fill(HIST("hSEProtonPostCut_SSN"), dPhiStar, dEta); + } } } else { // Mixed-event @@ -1084,13 +1162,46 @@ struct ThreeParticleCorrelations { rPhiStarRegistry.fill(HIST("hMEProtonPostCut_OS"), dPhiStar, dEta); } else if (proton.sign() * track.sign() == 1) { // SS (Electric charge) rPhiStarRegistry.fill(HIST("hMEProtonPostCut_SS"), dPhiStar, dEta); + if (proton.sign() == 1) { // Positive + rPhiStarRegistry.fill(HIST("hMEProtonPostCut_SSP"), dPhiStar, dEta); + } else if (proton.sign() == -1) { // Negative + rPhiStarRegistry.fill(HIST("hMEProtonPostCut_SSN"), dPhiStar, dEta); + } } } } + + dPhiStarMean += (dPhiStar / 170); + } + // End of the TPC radius loop + + if (!Mix) { // Same-event + if (proton.sign() * track.sign() == -1) { // OS (Electric charge) + rPhiStarRegistry.fill(HIST("hSEPhiStarMean_OS"), dPhiStarMean, dEta); + } else if (proton.sign() * track.sign() == 1) { // SS (Electric charge) + rPhiStarRegistry.fill(HIST("hSEPhiStarMean_SS"), dPhiStarMean, dEta); + if (proton.sign() == 1) { // Positive + rPhiStarRegistry.fill(HIST("hSEPhiStarMean_SSP"), dPhiStarMean, dEta); + } else if (proton.sign() == -1) { // Negative + rPhiStarRegistry.fill(HIST("hSEPhiStarMean_SSN"), dPhiStarMean, dEta); + } + } + + } else { // Mixed-event + if (proton.sign() * track.sign() == -1) { // OS (Electric charge) + rPhiStarRegistry.fill(HIST("hMEPhiStarMean_OS"), dPhiStarMean, dEta); + } else if (proton.sign() * track.sign() == 1) { // SS (Electric charge) + rPhiStarRegistry.fill(HIST("hMEPhiStarMean_SS"), dPhiStarMean, dEta); + if (proton.sign() == 1) { // Positive + rPhiStarRegistry.fill(HIST("hMEPhiStarMean_SSP"), dPhiStarMean, dEta); + } else if (proton.sign() == -1) { // Negative + rPhiStarRegistry.fill(HIST("hMEPhiStarMean_SSN"), dPhiStarMean, dEta); + } + } } } - return kTRUE; + return pass; } }; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx b/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx index 09e74854914..489c99bdbff 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx @@ -11,7 +11,7 @@ /// \file corrSparse.cxx /// \brief Provides a sparse with usefull two particle correlation info -/// \author Thor Jensen (thor.kjaersgaard.jensen@cern.ch) and Debojit Sarkar (debojit.sarkar@cern.ch) +/// \author Thor Jensen (thor.kjaersgaard.jensen@cern.ch) #include #include "TRandom3.h" @@ -253,15 +253,15 @@ struct CorrSparse { for (auto const& track2 : tracks2) { - if (track1.pt() <= track2.pt()) - continue; // skip if the trigger pt is less than the associate pt - if (processMFT) { if constexpr (std::is_same_v) { if (!isAcceptedMftTrack(track2)) { continue; } } + } else { + if (track1.pt() <= track2.pt()) + continue; // skip if the trigger pt is less than the associate pt } float deltaPhi = RecoDecay::constrainAngle(track1.phi() - track2.phi(), -PIHalf); diff --git a/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx b/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx index 05fea7fd4ab..f9588c4c7d8 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx @@ -14,50 +14,44 @@ /// \author Zhiyong Lu (zhiyong.lu@cern.ch) /// \since May/03/2025 -#include -#include "TRandom3.h" -#include "TF1.h" -#include -#include - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/StepTHn.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "CommonConstants/MathConstants.h" -#include "Common/Core/RecoDecay.h" - -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/Centrality.h" -#include "PWGCF/DataModel/CorrelationsDerived.h" -#include "Common/DataModel/CollisionAssociationTables.h" #include "PWGCF/Core/CorrelationContainer.h" #include "PWGCF/Core/PairCuts.h" -#include "PWGCF/GenericFramework/Core/GFWPowerArray.h" +#include "PWGCF/DataModel/CorrelationsDerived.h" #include "PWGCF/GenericFramework/Core/GFW.h" #include "PWGCF/GenericFramework/Core/GFWCumulant.h" +#include "PWGCF/GenericFramework/Core/GFWPowerArray.h" #include "PWGCF/GenericFramework/Core/GFWWeights.h" -#include "DataFormatsParameters/GRPObject.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CommonConstants/MathConstants.h" #include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" +#include + +#include "TF1.h" +#include "TRandom3.h" +#include + +#include +#include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -namespace o2::aod -{ -namespace di_hadron_cor -{ -DECLARE_SOA_COLUMN(Multiplicity, multiplicity, int); -} -DECLARE_SOA_TABLE(Multiplicity, "AOD", "MULTIPLICITY", - di_hadron_cor::Multiplicity); - -} // namespace o2::aod // define the filtered collisions and tracks #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; @@ -84,8 +78,7 @@ struct DiHadronCor { O2_DEFINE_CONFIGURABLE(cfgRadiusHigh, float, 2.5, "High radius for merging cut") O2_DEFINE_CONFIGURABLE(cfgSampleSize, double, 10, "Sample size for mixed event") O2_DEFINE_CONFIGURABLE(cfgCentEstimator, int, 0, "0:FT0C; 1:FT0CVariant1; 2:FT0M; 3:FT0A") - O2_DEFINE_CONFIGURABLE(cfgCentFT0CMin, float, 0.0f, "Minimum centrality (FT0C) to cut events in filter") - O2_DEFINE_CONFIGURABLE(cfgCentFT0CMax, float, 100.0f, "Maximum centrality (FT0C) to cut events in filter") + O2_DEFINE_CONFIGURABLE(cfgCentTableUnavailable, bool, false, "if a dataset does not provide centrality information") O2_DEFINE_CONFIGURABLE(cfgUseAdditionalEventCut, bool, false, "Use additional event cut on mult correlations") O2_DEFINE_CONFIGURABLE(cfgUseTentativeEventCounter, bool, false, "After sel8(), count events regardless of real event selection") O2_DEFINE_CONFIGURABLE(cfgEvSelkNoSameBunchPileup, bool, false, "rejects collisions which are associated with the same found-by-T0 bunch crossing") @@ -100,34 +93,49 @@ struct DiHadronCor { O2_DEFINE_CONFIGURABLE(cfgCutOccupancyHigh, int, 2000, "High cut on TPC occupancy") O2_DEFINE_CONFIGURABLE(cfgCutOccupancyLow, int, 0, "Low cut on TPC occupancy") O2_DEFINE_CONFIGURABLE(cfgEfficiency, std::string, "", "CCDB path to efficiency object") + O2_DEFINE_CONFIGURABLE(cfgLocalEfficiency, bool, false, "Use local efficiency object") + O2_DEFINE_CONFIGURABLE(cfgVerbosity, bool, false, "Verbose output") SliceCache cache; - SliceCache cacheNch; ConfigurableAxis axisVertex{"axisVertex", {10, -10, 10}, "vertex axis for histograms"}; - ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 80, 100}, "multiplicity axis for histograms"}; - ConfigurableAxis axisCentrality{"axisCentrality", {VARIABLE_WIDTH, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90}, "centrality axis for histograms"}; - ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "pt axis for histograms"}; + ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 10, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260}, "multiplicity axis for histograms"}; + ConfigurableAxis axisCentrality{"axisCentrality", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, "centrality axis for histograms"}; + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.2, 0.5, 1, 1.5, 2, 3, 4, 6, 10}, "pt axis for histograms"}; ConfigurableAxis axisDeltaPhi{"axisDeltaPhi", {72, -PIHalf, PIHalf * 3}, "delta phi axis for histograms"}; ConfigurableAxis axisDeltaEta{"axisDeltaEta", {48, -2.4, 2.4}, "delta eta axis for histograms"}; - ConfigurableAxis axisPtTrigger{"axisPtTrigger", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "pt trigger axis for histograms"}; - ConfigurableAxis axisPtAssoc{"axisPtAssoc", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "pt associated axis for histograms"}; + ConfigurableAxis axisPtTrigger{"axisPtTrigger", {VARIABLE_WIDTH, 0.2, 0.5, 1, 1.5, 2, 3, 4, 6, 10}, "pt trigger axis for histograms"}; + ConfigurableAxis axisPtAssoc{"axisPtAssoc", {VARIABLE_WIDTH, 0.2, 0.5, 1, 1.5, 2, 3, 4, 6, 10}, "pt associated axis for histograms"}; ConfigurableAxis axisVtxMix{"axisVtxMix", {VARIABLE_WIDTH, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "vertex axis for mixed event histograms"}; - ConfigurableAxis axisMultMix{"axisMultMix", {VARIABLE_WIDTH, 0, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 80, 100}, "multiplicity / centrality axis for mixed event histograms"}; + ConfigurableAxis axisMultMix{"axisMultMix", {VARIABLE_WIDTH, 0, 10, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260}, "multiplicity / centrality axis for mixed event histograms"}; ConfigurableAxis axisSample{"axisSample", {cfgSampleSize, 0, cfgSampleSize}, "sample axis for histograms"}; ConfigurableAxis axisVertexEfficiency{"axisVertexEfficiency", {10, -10, 10}, "vertex axis for efficiency histograms"}; ConfigurableAxis axisEtaEfficiency{"axisEtaEfficiency", {20, -1.0, 1.0}, "eta axis for efficiency histograms"}; - ConfigurableAxis axisPtEfficiency{"axisPtEfficiency", {VARIABLE_WIDTH, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0}, "pt axis for efficiency histograms"}; + ConfigurableAxis axisPtEfficiency{"axisPtEfficiency", {VARIABLE_WIDTH, 0.2, 0.5, 1, 1.5, 2, 3, 4, 6, 10}, "pt axis for efficiency histograms"}; // make the filters and cuts. - Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVtxZ) && (aod::evsel::sel8) == true && (aod::cent::centFT0C > cfgCentFT0CMin) && (aod::cent::centFT0C < cfgCentFT0CMax); + Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVtxZ); Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + using FilteredCollisions = soa::Filtered>; + using FilteredTracks = soa::Filtered>; + using FilteredTracksWithMCLabels = soa::Filtered>; + + // Filter for MCParticle + Filter particleFilter = (nabs(aod::mcparticle::eta) < cfgCutEta) && (aod::mcparticle::pt > cfgCutPtMin) && (aod::mcparticle::pt < cfgCutPtMax); + using FilteredMcParticles = soa::Filtered; + + // Filter for MCcollisions + Filter mccollisionFilter = nabs(aod::mccollision::posZ) < cfgCutVtxZ; + using FilteredMcCollisions = soa::Filtered; + + using SmallGroupMcCollisions = soa::SmallGroups>; + + Preslice perCollision = aod::track::collisionId; + PresliceUnsorted collisionPerMCCollision = aod::mccollisionlabel::mcCollisionId; // Corrections - TH1D* mEfficiency = nullptr; - GFWWeights* mAcceptance = nullptr; - TObjArray* mAcceptanceList = nullptr; + TH3D* mEfficiency = nullptr; bool correctionsLoaded = false; // Define the outputs @@ -150,6 +158,9 @@ struct DiHadronCor { MixedEvent = 3 }; + // persistent caches + std::vector efficiencyAssociatedCache; + // Additional Event selection cuts - Copy from flowGenericFramework.cxx TF1* fMultPVCutLow = nullptr; TF1* fMultPVCutHigh = nullptr; @@ -159,18 +170,16 @@ struct DiHadronCor { TF1* fT0AV0AMean = nullptr; TF1* fT0AV0ASigma = nullptr; - using AodCollisions = soa::Filtered>; // aod::CentFT0Cs - using AodTracks = soa::Filtered>; - void init(InitContext&) { + if (cfgCentTableUnavailable && !cfgSelCollByNch) { + LOGF(fatal, "Centrality table is unavailable, cannot select collisions by centrality"); + } const AxisSpec axisPhi{72, 0.0, constants::math::TwoPI, "#varphi"}; const AxisSpec axisEta{40, -1., 1., "#eta"}; ccdb->setURL("http://alice-ccdb.cern.ch"); ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - auto now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); ccdb->setCreatedNotAfter(now); @@ -224,6 +233,7 @@ struct DiHadronCor { registry.add("deltaEta_deltaPhi_mixed", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); registry.add("Phi", "Phi", {HistType::kTH1D, {axisPhi}}); registry.add("Eta", "Eta", {HistType::kTH1D, {axisEta}}); + registry.add("EtaCorrected", "EtaCorrected", {HistType::kTH1D, {axisEta}}); registry.add("pT", "pT", {HistType::kTH1D, {axisPtTrigger}}); registry.add("pTCorrected", "pTCorrected", {HistType::kTH1D, {axisPtTrigger}}); registry.add("Nch", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); @@ -232,10 +242,29 @@ struct DiHadronCor { registry.add("Centrality", hCentTitle.c_str(), {HistType::kTH1D, {axisCentrality}}); registry.add("Centrality_used", hCentTitle.c_str(), {HistType::kTH1D, {axisCentrality}}); // histogram to see how many events are in the same and mixed event registry.add("zVtx", "zVtx", {HistType::kTH1D, {axisVertex}}); + registry.add("zVtx_used", "zVtx_used", {HistType::kTH1D, {axisVertex}}); registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); registry.add("eventcount", "bin", {HistType::kTH1F, {{4, 0, 4, "bin"}}}); // histogram to see how many events are in the same and mixed event + if (doprocessMCSame && doprocessOntheflySame) { + LOGF(fatal, "Full simulation and on-the-fly processing of same event not supported"); + } + if (doprocessMCMixed && doprocessOntheflyMixed) { + LOGF(fatal, "Full simulation and on-the-fly processing of mixed event not supported"); + } + if (doprocessMCSame || doprocessOntheflySame) { + registry.add("MCTrue/MCeventcount", "MCeventcount", {HistType::kTH1F, {{4, 0, 4, "bin"}}}); // histogram to see how many events are in the same and mixed event + registry.add("MCTrue/MCCentrality", hCentTitle.c_str(), {HistType::kTH1D, {axisCentrality}}); + registry.add("MCTrue/MCNch", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); + registry.add("MCTrue/MCzVtx", "MCzVtx", {HistType::kTH1D, {axisVertex}}); + registry.add("MCTrue/MCPhi", "MCPhi", {HistType::kTH1D, {axisPhi}}); + registry.add("MCTrue/MCEta", "MCEta", {HistType::kTH1D, {axisEta}}); + registry.add("MCTrue/MCpT", "MCpT", {HistType::kTH1D, {axisPtTrigger}}); + registry.add("MCTrue/MCTrig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); + registry.add("MCTrue/MCdeltaEta_deltaPhi_same", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); // check to see the delta eta and delta phi distribution + registry.add("MCTrue/MCdeltaEta_deltaPhi_mixed", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); + } std::vector corrAxis = {{axisSample, "Sample"}, {axisVertex, "z-vtx (cm)"}, @@ -244,9 +273,9 @@ struct DiHadronCor { {axisDeltaPhi, "#Delta#varphi (rad)"}, {axisDeltaEta, "#Delta#eta"}}; std::vector effAxis = { - {axisVertexEfficiency, "z-vtx (cm)"}, - {axisPtEfficiency, "p_{T} (GeV/c)"}, {axisEtaEfficiency, "#eta"}, + {axisPtEfficiency, "p_{T} (GeV/c)"}, + {axisVertexEfficiency, "z-vtx (cm)"}, }; std::vector userAxis; @@ -298,12 +327,36 @@ struct DiHadronCor { return ((track.tpcNClsFound() >= cfgCutTPCclu) && (track.itsNCls() >= cfgCutITSclu)); } - void loadCorrections(uint64_t timestamp) + template + bool genTrackSelected(TTrack track) + { + if (!track.isPhysicalPrimary()) { + return false; + } + if (!track.producedByGenerator()) { + return false; + } + if (std::abs(track.eta()) > cfgCutEta) { + return false; + } + if (std::abs(track.pt()) < cfgCutPtMin || std::abs(track.pt()) > cfgCutPtMax) { + return false; + } + return true; + } + + void loadEfficiency(uint64_t timestamp) { - if (correctionsLoaded) + if (correctionsLoaded) { return; + } if (cfgEfficiency.value.empty() == false) { - mEfficiency = ccdb->getForTimeStamp(cfgEfficiency, timestamp); + if (cfgLocalEfficiency > 0) { + TFile* fEfficiencyTrigger = TFile::Open(cfgEfficiency.value.c_str(), "READ"); + mEfficiency = reinterpret_cast(fEfficiencyTrigger->Get("ccdb_object")); + } else { + mEfficiency = ccdb->getForTimeStamp(cfgEfficiency, timestamp); + } if (mEfficiency == nullptr) { LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgEfficiency.value.c_str()); } @@ -312,13 +365,17 @@ struct DiHadronCor { correctionsLoaded = true; } - bool setCurrentParticleWeights(float& weight_nue, float pt) + bool getEfficiencyCorrection(float& weight_nue, float eta, float pt, float posZ) { float eff = 1.; - if (mEfficiency) - eff = mEfficiency->GetBinContent(mEfficiency->FindBin(pt)); - else + if (mEfficiency) { + int etaBin = mEfficiency->GetXaxis()->FindBin(eta); + int ptBin = mEfficiency->GetYaxis()->FindBin(pt); + int zBin = mEfficiency->GetZaxis()->FindBin(posZ); + eff = mEfficiency->GetBinContent(etaBin, ptBin, zBin); + } else { eff = 1.0; + } if (eff == 0) return false; weight_nue = 1. / eff; @@ -329,20 +386,16 @@ struct DiHadronCor { template void fillYield(TCollision collision, TTracks tracks) // function to fill the yield and etaphi histograms. { - float cent = getCentrality(collision); - registry.fill(HIST("Centrality"), cent); - - registry.fill(HIST("Nch"), tracks.size()); - registry.fill(HIST("zVtx"), collision.posZ()); - float weff1 = 1; + float vtxz = collision.posZ(); for (auto const& track1 : tracks) { if (!trackSelected(track1)) continue; - if (!setCurrentParticleWeights(weff1, track1.pt())) + if (!getEfficiencyCorrection(weff1, track1.eta(), track1.pt(), vtxz)) continue; registry.fill(HIST("Phi"), RecoDecay::constrainAngle(track1.phi(), 0.0)); registry.fill(HIST("Eta"), track1.eta()); + registry.fill(HIST("EtaCorrected"), track1.eta(), weff1); registry.fill(HIST("pT"), track1.pt()); registry.fill(HIST("pTCorrected"), track1.pt(), weff1); } @@ -372,37 +425,48 @@ struct DiHadronCor { return dPhiStar; } - // template void fillCorrelations(TTracks tracks1, TTracksAssoc tracks2, float posZ, int system, int magneticField, float cent) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms { + // Cache efficiency for particles (too many FindBin lookups) + if (mEfficiency) { + efficiencyAssociatedCache.clear(); + efficiencyAssociatedCache.reserve(tracks2.size()); + for (const auto& track2 : tracks2) { + float weff = 1.; + getEfficiencyCorrection(weff, track2.eta(), track2.pt(), posZ); + efficiencyAssociatedCache.push_back(weff); + } + } if (system == SameEvent) { - registry.fill(HIST("Centrality_used"), cent); + if (!cfgCentTableUnavailable) + registry.fill(HIST("Centrality_used"), cent); registry.fill(HIST("Nch_used"), tracks1.size()); } int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); - float weff1 = 1; - float weff2 = 1; + float triggerWeight = 1.0f; + float associatedWeight = 1.0f; // loop over all tracks for (auto const& track1 : tracks1) { if (!trackSelected(track1)) continue; - if (!setCurrentParticleWeights(weff1, track1.pt())) + if (!getEfficiencyCorrection(triggerWeight, track1.eta(), track1.pt(), posZ)) continue; if (system == SameEvent) { - registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.pt()); + registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.pt(), triggerWeight); } for (auto const& track2 : tracks2) { if (!trackSelected(track2)) continue; - if (!setCurrentParticleWeights(weff2, track2.pt())) - continue; + if (mEfficiency) { + associatedWeight = efficiencyAssociatedCache[track2.filteredIndex()]; + } if (track1.pt() <= track2.pt()) continue; // skip if the trigger pt is less than the associate pt @@ -435,12 +499,55 @@ struct DiHadronCor { // fill the right sparse and histograms if (system == SameEvent) { - same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta); - registry.fill(HIST("deltaEta_deltaPhi_same"), deltaPhi, deltaEta); + same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, triggerWeight * associatedWeight); + registry.fill(HIST("deltaEta_deltaPhi_same"), deltaPhi, deltaEta, triggerWeight * associatedWeight); } else if (system == MixedEvent) { - mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta); - registry.fill(HIST("deltaEta_deltaPhi_mixed"), deltaPhi, deltaEta); + mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, triggerWeight * associatedWeight); + registry.fill(HIST("deltaEta_deltaPhi_mixed"), deltaPhi, deltaEta, triggerWeight * associatedWeight); + } + } + } + } + template + void fillMCCorrelations(TTracks tracks1, TTracksAssoc tracks2, float posZ, int system) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms + { + int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + + float triggerWeight = 1.0f; + float associatedWeight = 1.0f; + // loop over all tracks + for (auto const& track1 : tracks1) { + if (step >= CorrelationContainer::kCFStepTrackedOnlyPrim && !track1.isPhysicalPrimary()) + continue; + if (doprocessOntheflySame && !genTrackSelected(track1)) + continue; + + if (system == SameEvent && (doprocessMCSame || doprocessOntheflySame)) + registry.fill(HIST("MCTrue/MCTrig_hist"), fSampleIndex, posZ, track1.pt(), triggerWeight); + + for (auto const& track2 : tracks2) { + + if (step >= CorrelationContainer::kCFStepTrackedOnlyPrim && !track2.isPhysicalPrimary()) + continue; + if (doprocessOntheflyMixed && !genTrackSelected(track2)) + continue; + + if (track1.pt() <= track2.pt()) + continue; // skip if the trigger pt is less than the associate pt + + float deltaPhi = RecoDecay::constrainAngle(track1.phi() - track2.phi(), -PIHalf); + float deltaEta = track1.eta() - track2.eta(); + + // fill the right sparse and histograms + if (system == SameEvent) { + same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, triggerWeight * associatedWeight); + if (doprocessMCSame || doprocessOntheflySame) + registry.fill(HIST("MCTrue/MCdeltaEta_deltaPhi_same"), deltaPhi, deltaEta, triggerWeight * associatedWeight); + } else if (system == MixedEvent) { + mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, triggerWeight * associatedWeight); + if (doprocessMCMixed || doprocessOntheflyMixed) + registry.fill(HIST("MCTrue/MCdeltaEta_deltaPhi_mixed"), deltaPhi, deltaEta, triggerWeight * associatedWeight); } } } @@ -510,7 +617,8 @@ struct DiHadronCor { registry.fill(HIST("hEventCountSpecific"), 8.5); // V0A T0A 5 sigma cut - if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > 5 * fT0AV0ASigma->Eval(collision.multFT0A()))) + float sigma = 5.0; + if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > sigma * fT0AV0ASigma->Eval(collision.multFT0A()))) return 0; if (fillCounter && cfgEvSelV0AT0ACut) registry.fill(HIST("hEventCountSpecific"), 9.5); @@ -518,35 +626,43 @@ struct DiHadronCor { return 1; } - void processSame(AodCollisions::iterator const& collision, AodTracks const& tracks, aod::BCsWithTimestamps const&) + void processSame(FilteredCollisions::iterator const& collision, FilteredTracks const& tracks, aod::BCsWithTimestamps const&) { - + if (!collision.sel8()) + return; auto bc = collision.bc_as(); - float cent = getCentrality(collision); + float cent = -1.; + if (!cfgCentTableUnavailable) + cent = getCentrality(collision); if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), cent, true)) return; - registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin - - loadCorrections(bc.timestamp()); - fillYield(collision, tracks); + if (!cfgCentTableUnavailable) + registry.fill(HIST("Centrality"), cent); + registry.fill(HIST("Nch"), tracks.size()); + registry.fill(HIST("zVtx"), collision.posZ()); if (cfgSelCollByNch && (tracks.size() < cfgCutMultMin || tracks.size() >= cfgCutMultMax)) { return; } - if (!cfgSelCollByNch && (cent < cfgCutCentMin || cent >= cfgCutCentMax)) { + if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent < cfgCutCentMin || cent >= cfgCutCentMax)) { return; } + loadEfficiency(bc.timestamp()); + registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin + fillYield(collision, tracks); + + same->fillEvent(tracks.size(), CorrelationContainer::kCFStepReconstructed); fillCorrelations(tracks, tracks, collision.posZ(), SameEvent, getMagneticField(bc.timestamp()), cent); } PROCESS_SWITCH(DiHadronCor, processSame, "Process same event", true); // the process for filling the mixed events - void processMixed(AodCollisions const& collisions, AodTracks const& tracks, aod::BCsWithTimestamps const&) + void processMixed(FilteredCollisions const& collisions, FilteredTracks const& tracks, aod::BCsWithTimestamps const&) { - auto getTracksSize = [&tracks, this](AodCollisions::iterator const& collision) { + auto getTracksSize = [&tracks, this](FilteredCollisions::iterator const& collision) { auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); auto mult = associatedTracks.size(); return mult; @@ -557,11 +673,10 @@ struct DiHadronCor { MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; auto tracksTuple = std::make_tuple(tracks, tracks); - Pair pair{binningOnVtxAndMult, cfgMixEventNumMin, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + Pair pair{binningOnVtxAndMult, cfgMixEventNumMin, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip for (auto const& [collision1, tracks1, collision2, tracks2] : pair) { - registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin - auto bc = collision1.bc_as(); - loadCorrections(bc.timestamp()); + if (!collision1.sel8() || !collision2.sel8()) + continue; if (cfgSelCollByNch && (tracks1.size() < cfgCutMultMin || tracks1.size() >= cfgCutMultMax)) continue; @@ -569,24 +684,234 @@ struct DiHadronCor { if (cfgSelCollByNch && (tracks2.size() < cfgCutMultMin || tracks2.size() >= cfgCutMultMax)) continue; - float cent1 = getCentrality(collision1); - float cent2 = getCentrality(collision2); + float cent1 = -1; + float cent2 = -1; + if (!cfgCentTableUnavailable) { + cent1 = getCentrality(collision1); + cent2 = getCentrality(collision2); + } if (cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), cent1, false)) continue; if (cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), cent2, false)) continue; - if (!cfgSelCollByNch && (cent1 < cfgCutCentMin || cent1 >= cfgCutCentMax)) + if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent1 < cfgCutCentMin || cent1 >= cfgCutCentMax)) continue; - if (!cfgSelCollByNch && (cent2 < cfgCutCentMin || cent2 >= cfgCutCentMax)) + if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent2 < cfgCutCentMin || cent2 >= cfgCutCentMax)) continue; + registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin + auto bc = collision1.bc_as(); + loadEfficiency(bc.timestamp()); + fillCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, getMagneticField(bc.timestamp()), cent1); } } PROCESS_SWITCH(DiHadronCor, processMixed, "Process mixed events", true); + + int getSpecies(int pdgCode) + { + switch (std::abs(pdgCode)) { + case PDG_t::kPiPlus: // pion + return 0; + case PDG_t::kKPlus: // Kaon + return 1; + case PDG_t::kProton: // proton + return 2; + default: // NOTE. The efficiency histogram is hardcoded to contain 4 species. Anything special will have the last slot. + return 3; + } + } + + void processMCEfficiency(FilteredMcCollisions::iterator const& mcCollision, aod::BCsWithTimestamps const&, soa::SmallGroups> const& collisions, FilteredMcParticles const& mcParticles, FilteredTracksWithMCLabels const& tracks) + { + if (cfgSelCollByNch && (tracks.size() < cfgCutMultMin || tracks.size() >= cfgCutMultMax)) { + return; + } + // Primaries + for (const auto& mcParticle : mcParticles) { + if (mcParticle.isPhysicalPrimary()) { + same->getTrackHistEfficiency()->Fill(CorrelationContainer::MC, mcParticle.eta(), mcParticle.pt(), getSpecies(mcParticle.pdgCode()), 0., mcCollision.posZ()); + } + } + for (const auto& collision : collisions) { + auto groupedTracks = tracks.sliceBy(perCollision, collision.globalIndex()); + if (cfgVerbosity) { + LOGF(info, " Reconstructed collision at vtx-z = %f", collision.posZ()); + LOGF(info, " which has %d tracks", groupedTracks.size()); + } + + for (const auto& track : groupedTracks) { + if (track.has_mcParticle()) { + const auto& mcParticle = track.mcParticle(); + if (mcParticle.isPhysicalPrimary()) { + same->getTrackHistEfficiency()->Fill(CorrelationContainer::RecoPrimaries, mcParticle.eta(), mcParticle.pt(), getSpecies(mcParticle.pdgCode()), 0., mcCollision.posZ()); + } + same->getTrackHistEfficiency()->Fill(CorrelationContainer::RecoAll, mcParticle.eta(), mcParticle.pt(), getSpecies(mcParticle.pdgCode()), 0., mcCollision.posZ()); + } else { + // fake track + same->getTrackHistEfficiency()->Fill(CorrelationContainer::Fake, track.eta(), track.pt(), 0, 0., mcCollision.posZ()); + } + } + } + } + PROCESS_SWITCH(DiHadronCor, processMCEfficiency, "MC: Extract efficiencies", false); + + void processMCSame(FilteredMcCollisions::iterator const& mcCollision, FilteredMcParticles const& mcParticles, SmallGroupMcCollisions const& collisions) + { + if (cfgVerbosity) { + LOGF(info, "processMCSame. MC collision: %d, particles: %d, collisions: %d", mcCollision.globalIndex(), mcParticles.size(), collisions.size()); + } + + float cent = -1; + if (!cfgCentTableUnavailable) { + for (const auto& collision : collisions) { + cent = getCentrality(collision); + } + } + + if (cfgSelCollByNch && (mcParticles.size() < cfgCutMultMin || mcParticles.size() >= cfgCutMultMax)) { + return; + } + if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent < cfgCutCentMin || cent >= cfgCutCentMax)) { + return; + } + + registry.fill(HIST("MCTrue/MCeventcount"), SameEvent); // because its same event i put it in the 1 bin + if (!cfgCentTableUnavailable) + registry.fill(HIST("MCTrue/MCCentrality"), cent); + registry.fill(HIST("MCTrue/MCNch"), mcParticles.size()); + registry.fill(HIST("MCTrue/MCzVtx"), mcCollision.posZ()); + for (const auto& mcParticle : mcParticles) { + if (mcParticle.isPhysicalPrimary()) { + registry.fill(HIST("MCTrue/MCPhi"), mcParticle.phi()); + registry.fill(HIST("MCTrue/MCEta"), mcParticle.eta()); + registry.fill(HIST("MCTrue/MCpT"), mcParticle.pt()); + } + } + + same->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepAll); + fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent); + + if (collisions.size() == 0) { + return; + } + + same->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepTrackedOnlyPrim); + fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent); + } + PROCESS_SWITCH(DiHadronCor, processMCSame, "Process MC same event", false); + + void processMCMixed(FilteredMcCollisions const& mcCollisions, FilteredMcParticles const& mcParticles, SmallGroupMcCollisions const& collisions) + { + auto getTracksSize = [&mcParticles, this](FilteredMcCollisions::iterator const& mcCollision) { + auto associatedTracks = mcParticles.sliceByCached(o2::aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), this->cache); + auto mult = associatedTracks.size(); + return mult; + }; + + using MixedBinning = FlexibleBinningPolicy, o2::aod::mccollision::PosZ, decltype(getTracksSize)>; + + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; + + auto tracksTuple = std::make_tuple(mcParticles, mcParticles); + Pair pair{binningOnVtxAndMult, cfgMixEventNumMin, -1, mcCollisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto const& [collision1, tracks1, collision2, tracks2] : pair) { + + if (cfgSelCollByNch && (tracks1.size() < cfgCutMultMin || tracks1.size() >= cfgCutMultMax)) + continue; + + if (cfgSelCollByNch && (tracks2.size() < cfgCutMultMin || tracks2.size() >= cfgCutMultMax)) + continue; + + auto groupedCollisions = collisions.sliceBy(collisionPerMCCollision, collision1.globalIndex()); + if (cfgVerbosity > 0) { + LOGF(info, "Found %d related collisions", groupedCollisions.size()); + } + float cent = -1; + if (!cfgCentTableUnavailable) { + for (const auto& collision : groupedCollisions) { + cent = getCentrality(collision); + } + } + + if (!cfgSelCollByNch && !cfgCentTableUnavailable && groupedCollisions.size() != 0 && (cent < cfgCutCentMin || cent >= cfgCutCentMax)) + continue; + + registry.fill(HIST("MCTrue/MCeventcount"), MixedEvent); // fill the mixed event in the 3 bin + + fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent); + + if (groupedCollisions.size() == 0) { + continue; + } + + fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent); + } + } + PROCESS_SWITCH(DiHadronCor, processMCMixed, "Process MC mixed events", false); + + void processOntheflySame(aod::McCollisions::iterator const& mcCollision, aod::McParticles const& mcParticles) + { + if (cfgVerbosity) { + LOGF(info, "processOntheflySame. MC collision: %d, particles: %d", mcCollision.globalIndex(), mcParticles.size()); + } + + if (cfgSelCollByNch && (mcParticles.size() < cfgCutMultMin || mcParticles.size() >= cfgCutMultMax)) { + return; + } + + registry.fill(HIST("MCTrue/MCeventcount"), SameEvent); // because its same event i put it in the 1 bin + registry.fill(HIST("MCTrue/MCNch"), mcParticles.size()); + registry.fill(HIST("MCTrue/MCzVtx"), mcCollision.posZ()); + for (const auto& mcParticle : mcParticles) { + if (mcParticle.isPhysicalPrimary()) { + registry.fill(HIST("MCTrue/MCPhi"), mcParticle.phi()); + registry.fill(HIST("MCTrue/MCEta"), mcParticle.eta()); + registry.fill(HIST("MCTrue/MCpT"), mcParticle.pt()); + } + } + + same->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepAll); + fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent); + + same->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepTrackedOnlyPrim); + fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent); + } + PROCESS_SWITCH(DiHadronCor, processOntheflySame, "Process on-the-fly same event", false); + + void processOntheflyMixed(aod::McCollisions const& mcCollisions, aod::McParticles const& mcParticles) + { + auto getTracksSize = [&mcParticles, this](aod::McCollisions::iterator const& mcCollision) { + auto associatedTracks = mcParticles.sliceByCached(o2::aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), this->cache); + auto mult = associatedTracks.size(); + return mult; + }; + + using MixedBinning = FlexibleBinningPolicy, o2::aod::mccollision::PosZ, decltype(getTracksSize)>; + + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; + + auto tracksTuple = std::make_tuple(mcParticles, mcParticles); + Pair pair{binningOnVtxAndMult, cfgMixEventNumMin, -1, mcCollisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto const& [collision1, tracks1, collision2, tracks2] : pair) { + + if (cfgSelCollByNch && (tracks1.size() < cfgCutMultMin || tracks1.size() >= cfgCutMultMax)) + continue; + + if (cfgSelCollByNch && (tracks2.size() < cfgCutMultMin || tracks2.size() >= cfgCutMultMax)) + continue; + + registry.fill(HIST("MCTrue/MCeventcount"), MixedEvent); // fill the mixed event in the 3 bin + + fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent); + + fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent); + } + } + PROCESS_SWITCH(DiHadronCor, processOntheflyMixed, "Process on-the-fly mixed events", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx b/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx index 1e212aacf95..9a299ed8950 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx @@ -34,7 +34,6 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::constants::physics; using namespace o2::constants::math; -// using namespace o2::ml; namespace o2::aod { @@ -72,14 +71,9 @@ DECLARE_SOA_COLUMN(Rap, rap, float); DECLARE_SOA_COLUMN(Mass, mass, float); DECLARE_SOA_COLUMN(PosTrackId, posTrackId, int64_t); DECLARE_SOA_COLUMN(NegTrackId, negTrackId, int64_t); -DECLARE_SOA_COLUMN(V0Type, v0Type, int8_t); DECLARE_SOA_COLUMN(CosPA, cosPA, float); DECLARE_SOA_COLUMN(DcaDau, dcaDau, float); -DECLARE_SOA_COLUMN(DcaPion, dcaPion, float); -DECLARE_SOA_COLUMN(DcaProton, dcaProton, float); -DECLARE_SOA_COLUMN(DcaLambda, dcaLambda, float); -DECLARE_SOA_COLUMN(DecayLength, decayLength, float); -DECLARE_SOA_COLUMN(RXY, rXY, float); +DECLARE_SOA_COLUMN(V0Type, v0Type, int8_t); DECLARE_SOA_COLUMN(V0PrmScd, v0PrmScd, int8_t); DECLARE_SOA_COLUMN(CorrFact, corrFact, float); } // namespace lambdatrack @@ -95,14 +89,9 @@ DECLARE_SOA_TABLE(LambdaTracks, "AOD", "LAMBDATRACKS", o2::soa::Index<>, lambdatrack::Mass, lambdatrack::PosTrackId, lambdatrack::NegTrackId, - lambdatrack::V0Type, lambdatrack::CosPA, lambdatrack::DcaDau, - lambdatrack::DcaPion, - lambdatrack::DcaProton, - lambdatrack::DcaLambda, - lambdatrack::DecayLength, - lambdatrack::RXY, + lambdatrack::V0Type, lambdatrack::V0PrmScd, lambdatrack::CorrFact); using LambdaTrack = LambdaTracks::iterator; @@ -169,13 +158,11 @@ enum TrackLabels { kLambdaNotPrPiMinus, kAntiLambdaNotAntiPrPiPlus, kPassTrueLambdaSel, - kEffCorrPt, - kEffCorrPtRap, - kEffCorrPtRapPhi, + kEffCorrPtCent, + kEffCorrPtRapCent, kNoEffCorr, - kPFCorrPt, - kPFCorrPtRap, - kPFCorrPtRapPhi, + kPFCorrPtCent, + kPFCorrPtRapCent, kNoPFCorr, kGenTotAccLambda, kGenLambdaNoDau, @@ -297,11 +284,7 @@ struct LambdaTableProducer { Configurable cGenPrimaryLambda{"cGenPrimaryLambda", true, "Primary Generated Lambda"}; Configurable cGenSecondaryLambda{"cGenSecondaryLambda", false, "Secondary Generated Lambda"}; Configurable cGenDecayChannel{"cGenDecayChannel", true, "Gen Level Decay Channel Flag"}; - - // Mc Matching - Configurable cSelMcMatchValue{"cSelMcMatchValue", 0.4, "Mc Matching Percentage"}; - Configurable cDoEventMcMatching{"cDoEventMcMatching", true, "Do Event Mc Matching Flag"}; - Configurable cDoTrackMcMatching{"cDoTrackMcMatching", false, "Do Track Mc Matching Flag"}; + Configurable cRecoMomResoFlag{"cRecoMomResoFlag", false, "Check effect of momentum space smearing on balance function"}; // Efficiency Correction Configurable cCorrectionFlag{"cCorrectionFlag", false, "Correction Flag"}; @@ -321,21 +304,18 @@ struct LambdaTableProducer { HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; // initialize corr_factor objects - std::vector> vCorrFactStrings = {{"hEffVsPtLambda", "hEffVsPtAntiLambda"}, - {"hEffVsPtYLambda", "hEffVsPtYAntiLambda"}, - {"hEffVsPtEtaLambda", "hEffVsPtEtaAntiLambda"}, - {"hEffVsPtYPhiLambda", "hEffVsPtYPhiAntiLambda"}, - {"hEffVsPtEtaPhiLambda", "hEffVsPtEtaPhiAntiLambda"}}; + std::vector> vCorrFactStrings = {{"hEffVsPtCentLambda", "hEffVsPtCentAntiLambda"}, + {"hEffVsPtYCentLambda", "hEffVsPtYCentAntiLambda"}, + {"hEffVsPtEtaCentLambda", "hEffVsPtEtaCentAntiLambda"}}; // initialize corr_factor objects - std::vector> vPrimFracStrings = {{"hPrimFracVsPtLambda", "hPrimFracVsPtAntiLambda"}, - {"hPrimFracVsPtYLambda", "hPrimFracVsPtYAntiLambda"}, - {"hPrimFracVsPtEtaLambda", "hPrimFracVsPtEtaAntiLambda"}, - {"hPrimFracVsPtYPhiLambda", "hPrimFracVsPtYPhiAntiLambda"}, - {"hPrimFracVsPtEtaPhiLambda", "hPrimFracVsPtEtaPhiAntiLambda"}}; + std::vector> vPrimFracStrings = {{"hPrimFracVsPtCentLambda", "hPrimFracVsPtCentAntiLambda"}, + {"hPrimFracVsPtYCentLambda", "hPrimFracVsPtYCentAntiLambda"}, + {"hPrimFracVsPtEtaCentLambda", "hPrimFracVsPtEtaCentAntiLambda"}}; // Initialize Global Variables float cent = 0.; + float pt = 0., eta = 0., rap = 0., phi = 0.; bool bSecondaryLambdaFlag = false; void init(InitContext const&) @@ -344,9 +324,6 @@ struct LambdaTableProducer { ccdb->setURL(cUrlCCDB.value); ccdb->setCaching(true); - // Set ONNX Model - // network.initModel(cMLModelPathCCDB.value, true) - // initialize axis specifications const AxisSpec axisCols(5, 0.5, 5.5, ""); const AxisSpec axisTrks(30, 0.5, 30.5, ""); @@ -400,11 +377,6 @@ struct LambdaTableProducer { histos.add("QA/Lambda/h1f_V0_ctau", "V_{0} c#tau", kTH1F, {axisCTau}); histos.add("QA/Lambda/h1f_V0_gctau", "V_{0} #gammac#tau", kTH1F, {axisGCTau}); - histos.add("QA/Lambda/h2f_V0_ptpt", "Rec vs Truth p_{T}", kTH2F, {axisV0Pt, axisV0Pt}); - histos.add("QA/Lambda/h2f_V0_etaeta", "Rec vs Truth #eta", kTH2F, {axisV0Eta, axisV0Eta}); - histos.add("QA/Lambda/h2f_V0_raprap", "Rec vs Truth y", kTH2F, {axisV0Rap, axisV0Rap}); - histos.add("QA/Lambda/h2f_V0_phiphi", "Rec vs Truth #phi", kTH2F, {axisV0Phi, axisV0Phi}); - histos.add("QA/Lambda/h1f_pos_prong_pt", "Pos-Prong p_{T}", kTH1F, {axisTrackPt}); histos.add("QA/Lambda/h1f_neg_prong_pt", "Neg-Prong p_{T}", kTH1F, {axisTrackPt}); histos.add("QA/Lambda/h1f_pos_prong_eta", "Pos-Prong #eta-distribution", kTH1F, {axisV0Eta}); @@ -488,13 +460,11 @@ struct LambdaTableProducer { histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kPassV0KinCuts, "kPassV0KinCuts"); histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kPassV0TopoSel, "kPassV0TopoSel"); histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kAllSelPassed, "kAllSelPassed"); - histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kEffCorrPt, "kEffCorrPt"); - histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kEffCorrPtRap, "kEffCorrPtRap"); - histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kEffCorrPtRapPhi, "kEffCorrPtRapPhi"); + histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kEffCorrPtCent, "kEffCorrPtCent"); + histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kEffCorrPtRapCent, "kEffCorrPtRapCent"); histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kNoEffCorr, "kNoEffCorr"); - histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kPFCorrPt, "kPFCorrPt"); - histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kPFCorrPtRap, "kPFCorrPtRap"); - histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kPFCorrPtRapPhi, "kPFCorrPtRapPhi"); + histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kPFCorrPtCent, "kPFCorrPtCent"); + histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kPFCorrPtRapCent, "kPFCorrPtRapCent"); histos.get(HIST("Tracks/h1f_tracks_info"))->GetXaxis()->SetBinLabel(TrackLabels::kNoPFCorr, "kNoPFCorr"); } @@ -834,42 +804,6 @@ struct LambdaTableProducer { return true; } - template - bool getMcMatch(T const& vrec, T const& vgen) - { - float v = std::abs(1. - (vgen / vrec)); - - if (v >= cSelMcMatchValue) { - return false; - } - - return true; - } - - template - bool passMcMatching(V const& v0) - { - auto mcpart = v0.template mcParticle_as(); - - if (!getMcMatch(v0.pt(), mcpart.pt())) { - return false; - } - - if (!getMcMatch(v0.eta(), mcpart.eta())) { - return false; - } - - if (!getMcMatch(v0.yLambda(), mcpart.y())) { - return false; - } - - if (!getMcMatch(v0.phi(), mcpart.phi())) { - return false; - } - - return true; - } - template float getCorrectionFactors(V const& v0) { @@ -888,26 +822,23 @@ struct LambdaTableProducer { } // initialize efficiency factor and primary fraction values - float effFact = 1., primFrac = 1.; + float effCorrFact = 1., primFrac = 1.; float rap = (cDoEtaAnalysis) ? v0.eta() : v0.yLambda(); // Get Efficiency Factor if (cGetEffFact) { TObject* objEff = reinterpret_cast(ccdbObj->FindObject(Form("%s", vCorrFactStrings[cCorrFactHist][part].c_str()))); TH1F* histEff = reinterpret_cast(objEff->Clone()); - if (histEff->GetDimension() == OneDimCorr) { - histos.fill(HIST("Tracks/h1f_tracks_info"), kEffCorrPt); - effFact = histEff->GetBinContent(histEff->FindBin(v0.pt())); - } else if (histEff->GetDimension() == TwoDimCorr) { - histos.fill(HIST("Tracks/h1f_tracks_info"), kEffCorrPtRap); - effFact = histEff->GetBinContent(histEff->FindBin(v0.pt(), rap)); + if (histEff->GetDimension() == TwoDimCorr) { + histos.fill(HIST("Tracks/h1f_tracks_info"), kEffCorrPtCent); + effCorrFact = histEff->GetBinContent(histEff->FindBin(cent, v0.pt())); } else if (histEff->GetDimension() == ThreeDimCorr) { - histos.fill(HIST("Tracks/h1f_tracks_info"), kEffCorrPtRapPhi); - effFact = histEff->GetBinContent(histEff->FindBin(v0.pt(), rap, v0.phi())); + histos.fill(HIST("Tracks/h1f_tracks_info"), kEffCorrPtRapCent); + effCorrFact = histEff->GetBinContent(histEff->FindBin(cent, v0.pt(), rap)); } else { histos.fill(HIST("Tracks/h1f_tracks_info"), kNoEffCorr); LOGF(warning, "CCDB OBJECT IS NOT A HISTOGRAM !!!"); - effFact = 1.; + effCorrFact = 1.; } delete histEff; } @@ -917,15 +848,12 @@ struct LambdaTableProducer { if (cGetPrimFrac) { TObject* objPrm = reinterpret_cast(ccdbObj->FindObject(Form("%s", vPrimFracStrings[cPrimFracHist][part].c_str()))); TH1F* histPrm = reinterpret_cast(objPrm->Clone()); - if (histPrm->GetDimension() == OneDimCorr) { - histos.fill(HIST("Tracks/h1f_tracks_info"), kPFCorrPt); - primFrac = histPrm->GetBinContent(histPrm->FindBin(v0.pt())); - } else if (histPrm->GetDimension() == TwoDimCorr) { - histos.fill(HIST("Tracks/h1f_tracks_info"), kPFCorrPtRap); - primFrac = histPrm->GetBinContent(histPrm->FindBin(v0.pt(), rap)); + if (histPrm->GetDimension() == TwoDimCorr) { + histos.fill(HIST("Tracks/h1f_tracks_info"), kPFCorrPtCent); + primFrac = histPrm->GetBinContent(histPrm->FindBin(cent, v0.pt())); } else if (histPrm->GetDimension() == ThreeDimCorr) { - histos.fill(HIST("Tracks/h1f_tracks_info"), kPFCorrPtRapPhi); - primFrac = histPrm->GetBinContent(histPrm->FindBin(v0.pt(), rap, v0.phi())); + histos.fill(HIST("Tracks/h1f_tracks_info"), kPFCorrPtRapCent); + primFrac = histPrm->GetBinContent(histPrm->FindBin(cent, v0.pt(), rap)); } else { histos.fill(HIST("Tracks/h1f_tracks_info"), kNoPFCorr); LOGF(warning, "CCDB OBJECT IS NOT A HISTOGRAM !!!"); @@ -934,19 +862,7 @@ struct LambdaTableProducer { delete histPrm; } - return primFrac / effFact; - } - - template - void fillMCMatchingHistos(V const& v0) - { - static constexpr std::string_view SubDir[] = {"QA/Lambda/", "QA/AntiLambda/"}; - auto mcpart = v0.template mcParticle_as(); - - histos.fill(HIST(SubDir[part]) + HIST("h2f_V0_ptpt"), v0.pt(), mcpart.pt()); - histos.fill(HIST(SubDir[part]) + HIST("h2f_V0_etaeta"), v0.eta(), mcpart.eta()); - histos.fill(HIST(SubDir[part]) + HIST("h2f_V0_raprap"), v0.yLambda(), mcpart.y()); - histos.fill(HIST(SubDir[part]) + HIST("h2f_V0_phiphi"), v0.phi(), mcpart.phi()); + return primFrac * effCorrFact; } template @@ -1034,8 +950,7 @@ struct LambdaTableProducer { // initialize v0track objects ParticleType v0Type = kLambda; PrmScdType v0PrmScdType = kPrimary; - float mass = 0., ctau = 0., corr_fact = 1.; - float dcapiontopv = 0., dcaprotontopv = 0.; + float mass = 0., corr_fact = 1.; for (auto const& v0 : v0tracks) { // check for corresponding MCGen Particle @@ -1059,24 +974,16 @@ struct LambdaTableProducer { continue; } - // Get Lambda DcaDauToPV, decay length and mass - if (v0Type == kLambda) { - dcapiontopv = v0.dcanegtopv(); - dcaprotontopv = v0.dcapostopv(); - } else { - dcapiontopv = v0.dcapostopv(); - dcaprotontopv = v0.dcanegtopv(); - } - ctau = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassLambda0; - mass = (v0Type == kLambda) ? v0.mLambda() : v0.mAntiLambda(); - - // Machine-Learning Model (To be implemented in future...) - // std::vector modelInput = {v0.pt(), v0.yLambda(), v0.phi(), mass, v0.v0cosPA(), v0.dcaV0daughters(), dcapiontopv, dcaprotontopv, v0.dcav0topv(), ctau, v0.v0radius()} - // float* modelOutput = network.evalModel(modelInput); - + // we have v0 as lambda histos.fill(HIST("Tracks/h1f_tracks_info"), kAllSelPassed); - // we have v0 as lambda + // Get Lambda mass and kinematic variables + mass = (v0Type == kLambda) ? v0.mLambda() : v0.mAntiLambda(); + pt = v0.pt(); + eta = v0.eta(); + rap = v0.yLambda(); + phi = v0.phi(); + // do MC analysis if constexpr (dmc == kMC) { histos.fill(HIST("Tracks/h2f_tracks_pid_before_sel"), v0.mcParticle().pdgCode(), v0.pt()); @@ -1087,19 +994,22 @@ struct LambdaTableProducer { if (cSelectTrueLambda && !selTrueMcRecLambda(v0, tracks)) { // check for true Lambda/Anti-Lambda continue; } - if (cDoTrackMcMatching && !passMcMatching(v0)) { // Do Mc Matching - continue; - } - - // Fill MC Matching Histos (MC Matching Cuts to be implemented soon...) - if (v0Type == kLambda) { - fillMCMatchingHistos(v0); - } else { - fillMCMatchingHistos(v0); - } histos.fill(HIST("Tracks/h1f_tracks_info"), kPassTrueLambdaSel); histos.fill(HIST("Tracks/h2f_tracks_pid_after_sel"), v0.mcParticle().pdgCode(), v0.pt()); + + if (cRecoMomResoFlag) { + auto mc = v0.template mcParticle_as(); + pt = mc.pt(); + eta = mc.eta(); + rap = mc.y(); + phi = mc.phi(); + float y = (cDoEtaAnalysis) ? eta : rap; + // apply kinematic selection (On Truth) + if (!kinCutSelection(pt, std::abs(y), cMinV0Pt, cMaxV0Pt, cMaxV0Rap)) { + continue; + } + } } histos.fill(HIST("Tracks/h2f_armpod_after_sel"), v0.alpha(), v0.qtarm()); @@ -1120,10 +1030,8 @@ struct LambdaTableProducer { // Fill Lambda/AntiLambda Table lambdaTrackTable(lambdaCollisionTable.lastIndex(), v0.px(), v0.py(), v0.pz(), - v0.pt(), v0.eta(), v0.phi(), v0.yLambda(), mass, - v0.template posTrack_as().index(), v0.template negTrack_as().index(), - (int8_t)v0Type, v0.v0cosPA(), v0.dcaV0daughters(), dcapiontopv, dcaprotontopv, v0.dcav0topv(), ctau, - v0.v0radius(), v0PrmScdType, corr_fact); + pt, eta, phi, rap, mass, v0.template posTrack_as().index(), v0.template negTrack_as().index(), + v0.v0cosPA(), v0.dcaV0daughters(), (int8_t)v0Type, v0PrmScdType, corr_fact); } } @@ -1132,7 +1040,7 @@ struct LambdaTableProducer { void fillLambdaMcGenTables(C const& mcCollision, M const& mcParticles) { // Fill McGen Collision Table - lambdaMCGenCollisionTable(mcCollision.centFT0M(), mcCollision.posX(), mcCollision.posY(), mcCollision.posZ()); + lambdaMCGenCollisionTable(cent, mcCollision.posX(), mcCollision.posY(), mcCollision.posZ()); // initialize track objects ParticleType v0Type = kLambda; @@ -1252,23 +1160,15 @@ struct LambdaTableProducer { if (!collisions.begin().has_mcCollision() || !selCollision(collisions.begin()) || collisions.begin().mcCollisionId() != mcCollision.globalIndex()) { return; } - // MC Matching - if (cDoEventMcMatching) { - // Vz Matching - if (!getMcMatch(collisions.begin().posZ(), mcCollision.posZ())) { - return; - } - } histos.fill(HIST("McGen/h1f_collisions_info"), kPassSelCol); histos.fill(HIST("McGen/h2f_collision_posZ"), mcCollision.posZ(), collisions.begin().posZ()); - histos.fill(HIST("McGen/h2f_collision_cent"), mcCollision.centFT0M(), cent); auto v0Tracks = V0s.sliceBy(perCollision, collisions.begin().globalIndex()); fillLambdaRecoTables(collisions.begin(), v0Tracks, tracks); fillLambdaMcGenTables(mcCollision, mcParticles); } SliceCache cache; - Preslice> perCollision = aod::track::collisionId; + Preslice> perCollision = aod::v0data::collisionId; using CollisionsRun3 = soa::Join; using CollisionsRun2 = soa::Join; @@ -1290,7 +1190,7 @@ struct LambdaTableProducer { PROCESS_SWITCH(LambdaTableProducer, processDataRun2, "Process for Run2 DATA", false); - void processMCRun3(soa::Join::iterator const& mcCollision, + void processMCRun3(aod::McCollisions::iterator const& mcCollision, soa::SmallGroups> const& collisions, McV0Tracks const& V0s, TracksMC const& tracks, aod::McParticles const& mcParticles) @@ -1300,7 +1200,7 @@ struct LambdaTableProducer { PROCESS_SWITCH(LambdaTableProducer, processMCRun3, "Process for Run3 MC RecoGen", false); - void processMCRun2(soa::Join::iterator const& mcCollision, + void processMCRun2(aod::McCollisions::iterator const& mcCollision, soa::SmallGroups> const& collisions, McV0Tracks const& V0s, TracksMC const& tracks, aod::McParticles const& mcParticles) @@ -1475,19 +1375,24 @@ struct LambdaTracksExtProducer { }; struct LambdaR2Correlation { - // Global Configurables - Configurable cNPtBins{"cNPtBins", 10, "N pT Bins"}; + Configurable cNPtBins{"cNPtBins", 34, "N pT Bins"}; Configurable cMinPt{"cMinPt", 0.8, "pT Min"}; - Configurable cMaxPt{"cMaxPt", 2.8, "pT Max"}; - Configurable cNRapBins{"cNRapBins", 12, "N Rapidity Bins"}; - Configurable cMinRap{"cMinRap", -0.6, "Minimum Rapidity"}; - Configurable cMaxRap{"cMaxRap", 0.6, "Maximum Rapidity"}; + Configurable cMaxPt{"cMaxPt", 4.2, "pT Max"}; + Configurable cNRapBins{"cNRapBins", 20, "N Rapidity Bins"}; + Configurable cMinRap{"cMinRap", -0.5, "Minimum Rapidity"}; + Configurable cMaxRap{"cMaxRap", 0.5, "Maximum Rapidity"}; Configurable cNPhiBins{"cNPhiBins", 36, "N Phi Bins"}; + Configurable cAnaSecondaries{"cAnaSecondaries", false, "Analysze Secondaries"}; + Configurable cAnaPairs{"cAnaPairs", false, "Analyze Pairs Flag"}; + Configurable cAnaSecondaryPairs{"cAnaSecondaryPairs", false, "Analyze Secondary Pairs Flag"}; // Eta/Rap Analysis Configurable cDoEtaAnalysis{"cDoEtaAnalysis", false, "Eta/Rap Analysis Flag"}; + // Centrality Axis + ConfigurableAxis cMultBins{"cMultBins", {VARIABLE_WIDTH, 0.0f, 10.0f, 30.0f, 50.f, 80.0f, 100.f}, "Variable Mult-Bins"}; + // Histogram Registry. HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -1501,6 +1406,7 @@ struct LambdaR2Correlation { float rapbinwidth = 0.; float phibinwidth = 0.; float q = 0., e = 0., qinv = 0.; + float cent = 0.; void init(InitContext const&) { @@ -1519,7 +1425,7 @@ struct LambdaR2Correlation { const AxisSpec axisCheck(1, 0, 1, ""); const AxisSpec axisPosZ(220, -11, 11, "V_{z} (cm)"); - const AxisSpec axisCent(105, 0, 105, "FT0M (%)"); + const AxisSpec axisCent(cMultBins, "FT0M (%)"); const AxisSpec axisMult(10, 0, 10, "N_{#Lambda}"); const AxisSpec axisMass(100, 1.06, 1.16, "M_{#Lambda} (GeV/#it{c}^{2})"); const AxisSpec axisPt(cNPtBins, cMinPt, cMaxPt, "p_{T} (GeV/#it{c})"); @@ -1529,11 +1435,6 @@ struct LambdaR2Correlation { const AxisSpec axisRapPhi(knrapphibins, kminrapphi, kmaxrapphi, "y #varphi"); const AxisSpec axisQinv(100, 0, 10, "q_{inv} (GeV/#it{c})"); - const AxisSpec axisEfPt(cNPtBins, cMinPt, cMaxPt, "p_{T}"); - const AxisSpec axisEfEta(cNRapBins, cMinRap, cMaxRap, "#eta"); - const AxisSpec axisEfRap(cNRapBins, cMinRap, cMaxRap, "y"); - const AxisSpec axisEfPhi(cNPhiBins, 0., TwoPI, "#varphi"); - // Create Histograms. // Event histos.add("Event/Reco/h1f_collision_posz", "V_{Z} Distribution", kTH1F, {axisPosZ}); @@ -1543,65 +1444,63 @@ struct LambdaR2Correlation { // Efficiency Histograms // Single Particle Efficiencies - histos.add("Reco/Primary/Efficiency/h1f_n1_pt_LaP", "#rho_{1}^{#Lambda}", kTH1F, {axisEfPt}); - histos.add("Reco/Primary/Efficiency/h1f_n1_pt_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH1F, {axisEfPt}); - histos.add("Reco/Primary/Efficiency/h3f_n1_ptetaphi_LaP", "#rho_{1}^{#Lambda}", kTH3F, {axisEfPt, axisEfEta, axisEfPhi}); - histos.add("Reco/Primary/Efficiency/h3f_n1_ptetaphi_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH3F, {axisEfPt, axisEfEta, axisEfPhi}); - histos.add("Reco/Primary/Efficiency/h3f_n1_ptrapphi_LaP", "#rho_{1}^{#Lambda}", kTH3F, {axisEfPt, axisEfRap, axisEfPhi}); - histos.add("Reco/Primary/Efficiency/h3f_n1_ptrapphi_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH3F, {axisEfPt, axisEfRap, axisEfPhi}); + histos.add("Reco/Primary/Efficiency/h2f_n1_centpt_LaP", "#rho_{1}^{#Lambda}", kTH2F, {axisCent, axisPt}); + histos.add("Reco/Primary/Efficiency/h2f_n1_centpt_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH2F, {axisCent, axisPt}); + histos.add("Reco/Primary/Efficiency/h3f_n1_centpteta_LaP", "#rho_{1}^{#Lambda}", kTH3F, {axisCent, axisPt, axisEta}); + histos.add("Reco/Primary/Efficiency/h3f_n1_centpteta_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH3F, {axisCent, axisPt, axisEta}); + histos.add("Reco/Primary/Efficiency/h3f_n1_centptrap_LaP", "#rho_{1}^{#Lambda}", kTH3F, {axisCent, axisPt, axisRap}); + histos.add("Reco/Primary/Efficiency/h3f_n1_centptrap_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH3F, {axisCent, axisPt, axisRap}); // Single and Two Particle Densities // 1D Histograms - histos.add("Reco/Primary/h1d_n1_mass_LaP", "#rho_{1}^{#Lambda}", kTH1D, {axisMass}); - histos.add("Reco/Primary/h1d_n1_mass_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH1D, {axisMass}); - histos.add("Reco/Primary/h1d_n1_pt_LaP", "#rho_{1}^{#Lambda}", kTH1D, {axisPt}); - histos.add("Reco/Primary/h1d_n1_pt_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH1D, {axisPt}); - histos.add("Reco/Primary/h1d_n1_eta_LaP", "#rho_{1}^{#Lambda}", kTH1D, {axisEta}); - histos.add("Reco/Primary/h1d_n1_eta_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH1D, {axisEta}); - histos.add("Reco/Primary/h1d_n1_rap_LaP", "#rho_{1}^{#Lambda}", kTH1D, {axisRap}); - histos.add("Reco/Primary/h1d_n1_rap_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH1D, {axisRap}); - histos.add("Reco/Primary/h1d_n1_phi_LaP", "#rho_{1}^{#Lambda}", kTH1D, {axisPhi}); - histos.add("Reco/Primary/h1d_n1_phi_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH1D, {axisPhi}); + histos.add("Reco/Primary/h2f_n1_pt_LaP", "#rho_{1}^{#Lambda}", kTH2F, {axisCent, axisPt}); + histos.add("Reco/Primary/h2f_n1_pt_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH2F, {axisCent, axisPt}); + histos.add("Reco/Primary/h2f_n1_eta_LaP", "#rho_{1}^{#Lambda}", kTH2F, {axisCent, axisEta}); + histos.add("Reco/Primary/h2f_n1_eta_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH2F, {axisCent, axisEta}); + histos.add("Reco/Primary/h2f_n1_rap_LaP", "#rho_{1}^{#Lambda}", kTH2F, {axisCent, axisRap}); + histos.add("Reco/Primary/h2f_n1_rap_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH2F, {axisCent, axisRap}); + histos.add("Reco/Primary/h2f_n1_phi_LaP", "#rho_{1}^{#Lambda}", kTH2F, {axisCent, axisPhi}); + histos.add("Reco/Primary/h2f_n1_phi_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH2F, {axisCent, axisPhi}); // rho1 for R2 RapPhi - histos.add("Reco/Primary/h2d_n1_rapphi_LaP", "#rho_{1}^{#Lambda}", kTH2D, {axisRap, axisPhi}); - histos.add("Reco/Primary/h2d_n1_rapphi_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH2D, {axisRap, axisPhi}); + histos.add("Reco/Primary/h3f_n1_rapphi_LaP", "#rho_{1}^{#Lambda}", kTH3F, {axisCent, axisRap, axisPhi}); + histos.add("Reco/Primary/h3f_n1_rapphi_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH3F, {axisCent, axisRap, axisPhi}); // rho1 for Q_{inv} - histos.add("Reco/Primary/h2d_n1_pteta_LaP", "#rho_{1}^{#Lambda}", kTH2D, {axisPt, axisEta}); - histos.add("Reco/Primary/h2d_n1_pteta_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH2D, {axisPt, axisEta}); - - // Clone Singles Histogram - histos.addClone("Reco/Primary/", "Reco/Secondary/"); - - // rho2 for numerator of R2 - histos.add("Reco/PP/h2d_n2_ptpt_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH2D, {axisPt, axisPt}); - histos.add("Reco/PP/h2d_n2_ptpt_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH2D, {axisPt, axisPt}); - histos.add("Reco/PP/h2d_n2_ptpt_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH2D, {axisPt, axisPt}); - histos.add("Reco/PP/h2d_n2_etaeta_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH2D, {axisEta, axisEta}); - histos.add("Reco/PP/h2d_n2_etaeta_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH2D, {axisEta, axisEta}); - histos.add("Reco/PP/h2d_n2_etaeta_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH2D, {axisEta, axisEta}); - histos.add("Reco/PP/h2d_n2_raprap_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH2D, {axisRap, axisRap}); - histos.add("Reco/PP/h2d_n2_raprap_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH2D, {axisRap, axisRap}); - histos.add("Reco/PP/h2d_n2_raprap_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH2D, {axisRap, axisRap}); - histos.add("Reco/PP/h2d_n2_phiphi_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH2D, {axisPhi, axisPhi}); - histos.add("Reco/PP/h2d_n2_phiphi_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH2D, {axisPhi, axisPhi}); - histos.add("Reco/PP/h2d_n2_phiphi_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH2D, {axisPhi, axisPhi}); - - // rho2 for R2 Rap1Phi1Rap2Phi2 - histos.add("Reco/PP/h2d_n2_rapphi_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH2D, {axisRapPhi, axisRapPhi}); - histos.add("Reco/PP/h2d_n2_rapphi_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH2D, {axisRapPhi, axisRapPhi}); - histos.add("Reco/PP/h2d_n2_rapphi_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH2D, {axisRapPhi, axisRapPhi}); - - // rho2 for R2 Qinv - histos.add("Reco/PP/h1d_n2_qinv_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH1D, {axisQinv}); - histos.add("Reco/PP/h1d_n2_qinv_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH1D, {axisQinv}); - histos.add("Reco/PP/h1d_n2_qinv_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH1D, {axisQinv}); - - // Clone Pairs Histograms - histos.addClone("Reco/PP/", "Reco/PS/"); - histos.addClone("Reco/PP/", "Reco/SP/"); - histos.addClone("Reco/PP/", "Reco/SS/"); + histos.add("Reco/Primary/h3f_n1_pteta_LaP", "#rho_{1}^{#Lambda}", kTH3F, {axisCent, axisPt, axisEta}); + histos.add("Reco/Primary/h3f_n1_pteta_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH3F, {axisCent, axisPt, axisEta}); + + // Clone Singles Primary/Secondary Histogram + if (cAnaSecondaries) { + histos.addClone("Reco/Primary/", "Reco/Secondary/"); + } + + if (cAnaPairs) { + // rho2 for numerator of R2 + histos.add("Reco/PP/h3f_n2_raprap_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH3F, {axisCent, axisRap, axisRap}); + histos.add("Reco/PP/h3f_n2_raprap_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH3F, {axisCent, axisRap, axisRap}); + histos.add("Reco/PP/h3f_n2_raprap_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH3F, {axisCent, axisRap, axisRap}); + histos.add("Reco/PP/h3f_n2_phiphi_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH3F, {axisCent, axisPhi, axisPhi}); + histos.add("Reco/PP/h3f_n2_phiphi_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH3F, {axisCent, axisPhi, axisPhi}); + histos.add("Reco/PP/h3f_n2_phiphi_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH3F, {axisCent, axisPhi, axisPhi}); + + // rho2 for R2 Rap1Phi1Rap2Phi2 + histos.add("Reco/PP/h3f_n2_rapphi_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH3F, {axisCent, axisRapPhi, axisRapPhi}); + histos.add("Reco/PP/h3f_n2_rapphi_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH3F, {axisCent, axisRapPhi, axisRapPhi}); + histos.add("Reco/PP/h3f_n2_rapphi_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH3F, {axisCent, axisRapPhi, axisRapPhi}); + + // rho2 for R2 Qinv + histos.add("Reco/PP/h2f_n2_qinv_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH2F, {axisCent, axisQinv}); + histos.add("Reco/PP/h2f_n2_qinv_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH2F, {axisCent, axisQinv}); + histos.add("Reco/PP/h2f_n2_qinv_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH2F, {axisCent, axisQinv}); + + // Clone Pairs Histograms + if (cAnaSecondaryPairs) { + histos.addClone("Reco/PP/", "Reco/PS/"); + histos.addClone("Reco/PP/", "Reco/SP/"); + histos.addClone("Reco/PP/", "Reco/SS/"); + } + } // MCGen if (doprocessMCGen) { @@ -1629,24 +1528,22 @@ struct LambdaR2Correlation { float corfac = p1.corrFact() * p2.corrFact(); // fill rho2 histograms - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[psp]) + HIST("h2d_n2_ptpt_") + HIST(SubDirHist[part_pair]), p1.pt(), p2.pt(), corfac); - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[psp]) + HIST("h2d_n2_etaeta_") + HIST(SubDirHist[part_pair]), p1.eta(), p2.eta(), corfac); - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[psp]) + HIST("h2d_n2_raprap_") + HIST(SubDirHist[part_pair]), p1.rap(), p2.rap(), corfac); - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[psp]) + HIST("h2d_n2_phiphi_") + HIST(SubDirHist[part_pair]), p1.phi(), p2.phi(), corfac); + histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[psp]) + HIST("h3f_n2_raprap_") + HIST(SubDirHist[part_pair]), cent, rap1, rap2, corfac); + histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[psp]) + HIST("h3f_n2_phiphi_") + HIST(SubDirHist[part_pair]), cent, p1.phi(), p2.phi(), corfac); if (rapbin1 >= 0 && rapbin2 >= 0 && phibin1 >= 0 && phibin2 >= 0 && rapbin1 < nrapbins && rapbin2 < nrapbins && phibin1 < nphibins && phibin2 < nphibins) { int rapphix = rapbin1 * nphibins + phibin1; int rapphiy = rapbin2 * nphibins + phibin2; - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[psp]) + HIST("h2d_n2_rapphi_") + HIST(SubDirHist[part_pair]), rapphix + 0.5, rapphiy + 0.5, corfac); + histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[psp]) + HIST("h3f_n2_rapphi_") + HIST(SubDirHist[part_pair]), cent, rapphix + 0.5, rapphiy + 0.5, corfac); } // qinv histograms q = RecoDecay::p((p1.px() - p2.px()), (p1.py() - p2.py()), (p1.pz() - p2.pz())); e = RecoDecay::e(p1.px(), p1.py(), p1.pz(), MassLambda0) - RecoDecay::e(p2.px(), p2.py(), p2.pz(), MassLambda0); qinv = std::sqrt(-RecoDecay::m2(q, e)); - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[psp]) + HIST("h1d_n2_qinv_") + HIST(SubDirHist[part_pair]), qinv, corfac); + histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[psp]) + HIST("h2f_n2_qinv_") + HIST(SubDirHist[part_pair]), cent, qinv, corfac); } template @@ -1663,22 +1560,21 @@ struct LambdaR2Correlation { ++ntrk; // Efficiency Plots - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("Efficiency/h1f_n1_pt_") + HIST(SubDirHist[part]), track.pt()); - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("Efficiency/h3f_n1_ptetaphi_") + HIST(SubDirHist[part]), track.pt(), track.eta(), track.phi()); - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("Efficiency/h3f_n1_ptrapphi_") + HIST(SubDirHist[part]), track.pt(), track.rap(), track.phi()); + histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("Efficiency/h2f_n1_centpt_") + HIST(SubDirHist[part]), cent, track.pt()); + histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("Efficiency/h3f_n1_centpteta_") + HIST(SubDirHist[part]), cent, track.pt(), track.eta()); + histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("Efficiency/h3f_n1_centptrap_") + HIST(SubDirHist[part]), cent, track.pt(), track.rap()); // QA Plots - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("h1d_n1_mass_") + HIST(SubDirHist[part]), track.mass()); - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("h1d_n1_pt_") + HIST(SubDirHist[part]), track.pt(), track.corrFact()); - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("h1d_n1_eta_") + HIST(SubDirHist[part]), track.eta(), track.corrFact()); - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("h1d_n1_phi_") + HIST(SubDirHist[part]), track.phi(), track.corrFact()); - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("h1d_n1_rap_") + HIST(SubDirHist[part]), track.rap(), track.corrFact()); + histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("h2f_n1_pt_") + HIST(SubDirHist[part]), cent, track.pt(), track.corrFact()); + histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("h2f_n1_eta_") + HIST(SubDirHist[part]), cent, track.eta(), track.corrFact()); + histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("h2f_n1_phi_") + HIST(SubDirHist[part]), cent, track.phi(), track.corrFact()); + histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("h2f_n1_rap_") + HIST(SubDirHist[part]), cent, track.rap(), track.corrFact()); // Rho1 for N1RapPhi - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("h2d_n1_rapphi_") + HIST(SubDirHist[part]), track.rap(), track.phi(), track.corrFact()); + histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("h3f_n1_rapphi_") + HIST(SubDirHist[part]), cent, track.rap(), track.phi(), track.corrFact()); // Rho1 for Q_{inv} Bkg Estimation - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("h2d_n1_pteta_") + HIST(SubDirHist[part]), track.pt(), track.eta(), track.corrFact()); + histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("h3f_n1_pteta_") + HIST(SubDirHist[part]), cent, track.pt(), track.eta(), track.corrFact()); } // fill multiplicity histograms @@ -1719,6 +1615,8 @@ struct LambdaR2Correlation { histos.fill(HIST("Event/Reco/h1f_collision_posz"), collision.posZ()); histos.fill(HIST("Event/Reco/h1f_ft0m_mult_percentile"), collision.cent()); + cent = collision.cent(); + auto lambdaPrimTracks = partPrimLambdaTracks->sliceByCached(aod::lambdatrack::lambdaCollisionId, collision.globalIndex(), cache); auto antiLambdaPrimTracks = partPrimAntiLambdaTracks->sliceByCached(aod::lambdatrack::lambdaCollisionId, collision.globalIndex(), cache); auto lambdaSecdTracks = partSecdLambdaTracks->sliceByCached(aod::lambdatrack::lambdaCollisionId, collision.globalIndex(), cache); @@ -1726,20 +1624,31 @@ struct LambdaR2Correlation { analyzeSingles(lambdaPrimTracks); analyzeSingles(antiLambdaPrimTracks); - analyzeSingles(lambdaSecdTracks); - analyzeSingles(antiLambdaSecdTracks); - analyzePairs(lambdaPrimTracks, antiLambdaPrimTracks); - analyzePairs(lambdaPrimTracks, lambdaPrimTracks); - analyzePairs(antiLambdaPrimTracks, antiLambdaPrimTracks); - analyzePairs(lambdaPrimTracks, antiLambdaSecdTracks); - analyzePairs(lambdaPrimTracks, lambdaSecdTracks); - analyzePairs(antiLambdaPrimTracks, antiLambdaSecdTracks); - analyzePairs(lambdaSecdTracks, antiLambdaPrimTracks); - analyzePairs(lambdaSecdTracks, lambdaPrimTracks); - analyzePairs(antiLambdaSecdTracks, antiLambdaPrimTracks); - analyzePairs(lambdaSecdTracks, antiLambdaSecdTracks); - analyzePairs(lambdaSecdTracks, lambdaSecdTracks); - analyzePairs(antiLambdaSecdTracks, antiLambdaSecdTracks); + + if (cAnaSecondaries) { + analyzeSingles(lambdaSecdTracks); + analyzeSingles(antiLambdaSecdTracks); + } + + if (cAnaPairs) { + // Primary Pairs Only + analyzePairs(lambdaPrimTracks, antiLambdaPrimTracks); + analyzePairs(lambdaPrimTracks, lambdaPrimTracks); + analyzePairs(antiLambdaPrimTracks, antiLambdaPrimTracks); + + // Secondary Pairs + if (cAnaSecondaryPairs) { + analyzePairs(lambdaPrimTracks, antiLambdaSecdTracks); + analyzePairs(lambdaPrimTracks, lambdaSecdTracks); + analyzePairs(antiLambdaPrimTracks, antiLambdaSecdTracks); + analyzePairs(lambdaSecdTracks, antiLambdaPrimTracks); + analyzePairs(lambdaSecdTracks, lambdaPrimTracks); + analyzePairs(antiLambdaSecdTracks, antiLambdaPrimTracks); + analyzePairs(lambdaSecdTracks, antiLambdaSecdTracks); + analyzePairs(lambdaSecdTracks, lambdaSecdTracks); + analyzePairs(antiLambdaSecdTracks, antiLambdaSecdTracks); + } + } } PROCESS_SWITCH(LambdaR2Correlation, processDataReco, "Process for Data and MCReco", true); @@ -1758,6 +1667,8 @@ struct LambdaR2Correlation { histos.fill(HIST("Event/McGen/h1f_collision_posz"), mcgencol.posZ()); histos.fill(HIST("Event/McGen/h1f_ft0m_mult_percentile"), mcgencol.cent()); + cent = mcgencol.cent(); + auto lambdaPrimTracks = partMcPrimLambdaTracks->sliceByCached(aod::lambdamcgentrack::lambdaMcGenCollisionId, mcgencol.globalIndex(), cachemc); auto antiLambdaPrimTracks = partMcPrimAntiLambdaTracks->sliceByCached(aod::lambdamcgentrack::lambdaMcGenCollisionId, mcgencol.globalIndex(), cachemc); auto lambdaSecdTracks = partMcSecdLambdaTracks->sliceByCached(aod::lambdamcgentrack::lambdaMcGenCollisionId, mcgencol.globalIndex(), cachemc); @@ -1765,20 +1676,31 @@ struct LambdaR2Correlation { analyzeSingles(lambdaPrimTracks); analyzeSingles(antiLambdaPrimTracks); - analyzeSingles(lambdaSecdTracks); - analyzeSingles(antiLambdaSecdTracks); - analyzePairs(lambdaPrimTracks, antiLambdaPrimTracks); - analyzePairs(lambdaPrimTracks, lambdaPrimTracks); - analyzePairs(antiLambdaPrimTracks, antiLambdaPrimTracks); - analyzePairs(lambdaPrimTracks, antiLambdaSecdTracks); - analyzePairs(lambdaPrimTracks, lambdaSecdTracks); - analyzePairs(antiLambdaPrimTracks, antiLambdaSecdTracks); - analyzePairs(lambdaSecdTracks, antiLambdaPrimTracks); - analyzePairs(lambdaSecdTracks, lambdaPrimTracks); - analyzePairs(antiLambdaSecdTracks, antiLambdaPrimTracks); - analyzePairs(lambdaSecdTracks, antiLambdaSecdTracks); - analyzePairs(lambdaSecdTracks, lambdaSecdTracks); - analyzePairs(antiLambdaSecdTracks, antiLambdaSecdTracks); + + if (cAnaSecondaries) { + analyzeSingles(lambdaSecdTracks); + analyzeSingles(antiLambdaSecdTracks); + } + + if (cAnaPairs) { + // Primary Pairs Only + analyzePairs(lambdaPrimTracks, antiLambdaPrimTracks); + analyzePairs(lambdaPrimTracks, lambdaPrimTracks); + analyzePairs(antiLambdaPrimTracks, antiLambdaPrimTracks); + + // Secondary Pairs + if (cAnaSecondaryPairs) { + analyzePairs(lambdaPrimTracks, antiLambdaSecdTracks); + analyzePairs(lambdaPrimTracks, lambdaSecdTracks); + analyzePairs(antiLambdaPrimTracks, antiLambdaSecdTracks); + analyzePairs(lambdaSecdTracks, antiLambdaPrimTracks); + analyzePairs(lambdaSecdTracks, lambdaPrimTracks); + analyzePairs(antiLambdaSecdTracks, antiLambdaPrimTracks); + analyzePairs(lambdaSecdTracks, antiLambdaSecdTracks); + analyzePairs(lambdaSecdTracks, lambdaSecdTracks); + analyzePairs(antiLambdaSecdTracks, antiLambdaSecdTracks); + } + } } PROCESS_SWITCH(LambdaR2Correlation, processMCGen, "Process for MC Generated", false); diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index 03d978bcb22..1feb6d88b0d 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -59,8 +59,8 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) AnalysisCut* qualityCuts = new AnalysisCut("qualityCuts", "quality cuts"); qualityCuts->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); - qualityCuts->AddCut(VarManager::kTPCchi2, 0.0, 5.0); - qualityCuts->AddCut(VarManager::kTPCncls, 60, 161.); + qualityCuts->AddCut(VarManager::kTPCchi2, 0.0, 4.0); + qualityCuts->AddCut(VarManager::kTPCncls, 70, 161.); qualityCuts->AddCut(VarManager::kTrackDCAz, -0.5, 0.5); AnalysisCut* pidCuts = new AnalysisCut("pidCuts", "pid cuts"); @@ -82,8 +82,8 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) AnalysisCut* qualityCuts = new AnalysisCut("qualityCuts", "quality cuts"); qualityCuts->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); - qualityCuts->AddCut(VarManager::kTPCchi2, 0.0, 5.0); - qualityCuts->AddCut(VarManager::kTPCncls, 60, 161.); + qualityCuts->AddCut(VarManager::kTPCchi2, 0.0, 4.0); + qualityCuts->AddCut(VarManager::kTPCncls, 70, 161.); qualityCuts->AddCut(VarManager::kTrackDCAz, -0.5, 0.5); AnalysisCut* pidCuts = new AnalysisCut("pidCuts", "pid cuts"); @@ -105,8 +105,8 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) AnalysisCut* qualityCuts = new AnalysisCut("qualityCuts", "quality cuts"); qualityCuts->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); - qualityCuts->AddCut(VarManager::kTPCchi2, 0.0, 5.0); - qualityCuts->AddCut(VarManager::kTPCncls, 60, 161.); + qualityCuts->AddCut(VarManager::kTPCchi2, 0.0, 4.0); + qualityCuts->AddCut(VarManager::kTPCncls, 70, 161.); qualityCuts->AddCut(VarManager::kTrackDCAz, -0.5, 0.5); AnalysisCut* pidCuts = new AnalysisCut("pidCuts", "pid cuts"); @@ -127,8 +127,8 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) AnalysisCut* qualityCuts = new AnalysisCut("qualityCuts", "quality cuts"); qualityCuts->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); - qualityCuts->AddCut(VarManager::kTPCchi2, 0.0, 5.0); - qualityCuts->AddCut(VarManager::kTPCncls, 60, 161.); + qualityCuts->AddCut(VarManager::kTPCchi2, 0.0, 4.0); + qualityCuts->AddCut(VarManager::kTPCncls, 70, 161.); qualityCuts->AddCut(VarManager::kTrackDCAz, -0.5, 0.5); AnalysisCut* pidCuts = new AnalysisCut("pidCuts", "pid cuts"); @@ -150,8 +150,8 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) AnalysisCut* qualityCuts = new AnalysisCut("qualityCuts", "quality cuts"); qualityCuts->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); - qualityCuts->AddCut(VarManager::kTPCchi2, 0.0, 5.0); - qualityCuts->AddCut(VarManager::kTPCncls, 60, 161.); + qualityCuts->AddCut(VarManager::kTPCchi2, 0.0, 4.0); + qualityCuts->AddCut(VarManager::kTPCncls, 70, 161.); qualityCuts->AddCut(VarManager::kTrackDCAz, -0.5, 0.5); AnalysisCut* pidCuts = new AnalysisCut("pidCuts", "pid cuts"); @@ -3665,79 +3665,10 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("emu_electron_test1")) { + if (!nameStr.compare("emu_electron_test")) { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); - cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); - cut->AddCut(GetAnalysisCut("electronPIDnsigmaOpen")); - return cut; - } - - if (!nameStr.compare("emu_electron_test2")) { - cut->AddCut(GetAnalysisCut("jpsiStandardKine2")); - cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); - cut->AddCut(GetAnalysisCut("electronPIDnsigmaOpen")); - return cut; - } - - if (!nameStr.compare("emu_electron_test3")) { - cut->AddCut(GetAnalysisCut("jpsiKineSkimmed")); - cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); - cut->AddCut(GetAnalysisCut("electronPIDnsigmaOpen")); - return cut; - } - - if (!nameStr.compare("emu_electron_test1_loosensigma")) { - cut->AddCut(GetAnalysisCut("jpsiStandardKine")); - cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); - cut->AddCut(GetAnalysisCut("electronPIDnsigmaVeryVeryLoose2")); - return cut; - } - - if (!nameStr.compare("emu_electron_test2_loosensigma")) { - cut->AddCut(GetAnalysisCut("jpsiStandardKine2")); - cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); - cut->AddCut(GetAnalysisCut("electronPIDnsigmaVeryVeryLoose2")); - return cut; - } - - if (!nameStr.compare("emu_electron_test3_loosensigma")) { - cut->AddCut(GetAnalysisCut("jpsiKineSkimmed")); - cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); - cut->AddCut(GetAnalysisCut("electronPIDnsigmaVeryVeryLoose2")); - return cut; - } - - if (!nameStr.compare("emu_electron_test1_tightnsigma")) { - cut->AddCut(GetAnalysisCut("jpsiStandardKine")); - cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); - cut->AddCut(GetAnalysisCut("electronPIDnsigmaLoose")); - return cut; - } - - if (!nameStr.compare("emu_electron_test2_tightnsigma")) { - cut->AddCut(GetAnalysisCut("jpsiStandardKine2")); - cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); - cut->AddCut(GetAnalysisCut("electronPIDnsigmaLoose")); - return cut; - } - - if (!nameStr.compare("emu_electron_test3_tightnsigma")) { - cut->AddCut(GetAnalysisCut("jpsiKineSkimmed")); - cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); - cut->AddCut(GetAnalysisCut("electronPIDnsigmaLoose")); - return cut; - } - - if (!nameStr.compare("emu_electron_specialTest")) { - cut->AddCut(GetAnalysisCut("jpsiStandardKineForEMu")); - cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); - cut->AddCut(GetAnalysisCut("electronPIDnsigmaVeryVeryLoose2")); - return cut; - } - - if (!nameStr.compare("emu_electron_specialTest2")) { - cut->AddCut(GetAnalysisCut("jpsiStandardKineForEMu")); - cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); + cut->AddCut(GetAnalysisCut("electronTrackQuality_Maolin")); + cut->AddCut(GetAnalysisCut("electronPIDnsigmaEMu")); return cut; } @@ -4009,6 +3940,16 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } + if (!nameStr.compare("eventStandardSel8multAnalysis")) { + cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); + cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); + cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); + cut->AddCut(VarManager::kIsNoITSROFBorder, 0.5, 1.5); + cut->AddCut(VarManager::kIsNoSameBunch, 0.5, 1.5); + cut->AddCut(VarManager::kIsVertexITSTPC, 0.5, 1.5); + return cut; + } + if (!nameStr.compare("eventStandardSel8VtxQuality1")) { // kIsSel8 = kIsTriggerTVX && kNoITSROFrameBorder && kNoTimeFrameBorder cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); @@ -4288,12 +4229,6 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiStandardKineForEMu")) { - cut->AddCut(VarManager::kPt, 5.0, 1000.0); - cut->AddCut(VarManager::kEta, -0.9, 0.9); - return cut; - } - if (!nameStr.compare("lmeePrefilterKine")) { cut->AddCut(VarManager::kPt, 0., 20.0); cut->AddCut(VarManager::kEta, -1.2, 1.2); @@ -4734,6 +4669,17 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } + if (!nameStr.compare("electronTrackQuality_Maolin")) { + cut->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); + cut->AddCut(VarManager::kITSchi2, 0.0, 15.0); + cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); + cut->AddCut(VarManager::kTPCncls, 70, 161.); + cut->AddCut(VarManager::kTPCnclsCR, 70, 161); + cut->AddCut(VarManager::kTrackDCAxy, -2.0, 2.0); + cut->AddCut(VarManager::kTrackDCAz, -2.0, 2.0); + return cut; + } + if (!nameStr.compare("pionQualityCut1")) { cut->AddCut(VarManager::kPt, 0.15, 1000.0); cut->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); @@ -5542,13 +5488,6 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("electronPIDnsigmaVeryVeryLoose2")) { - cut->AddCut(VarManager::kTPCnSigmaEl, -4.0, 4.0); - cut->AddCut(VarManager::kTPCnSigmaPr, 1.5, 3000.0); - cut->AddCut(VarManager::kTPCnSigmaPi, 1.5, 3000.0); - return cut; - } - if (!nameStr.compare("electronPIDnsigmaVeryLoose")) { cut->AddCut(VarManager::kTPCnSigmaEl, -4.0, 4.0); cut->AddCut(VarManager::kTPCnSigmaPr, 2.5, 3000.0); @@ -5625,6 +5564,14 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } + if (!nameStr.compare("electronPIDnsigmaEMu")) { + cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 3.0); + cut->AddCut(VarManager::kTPCnSigmaPr, 3.5, 3000.0); + cut->AddCut(VarManager::kTPCnSigmaPi, 3.5, 3000.0); + cut->AddCut(VarManager::kTPCnSigmaKa, 3.5, 3000.0); + return cut; + } + if (!nameStr.compare("kaonPIDnsigma")) { cut->AddCut(VarManager::kTPCnSigmaKa, -3.0, 3.0); return cut; diff --git a/PWGDQ/Core/HistogramsLibrary.cxx b/PWGDQ/Core/HistogramsLibrary.cxx index 96227af31ce..9fdb5b0cae5 100644 --- a/PWGDQ/Core/HistogramsLibrary.cxx +++ b/PWGDQ/Core/HistogramsLibrary.cxx @@ -90,10 +90,10 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "MultFDDA", "MultFDDA", false, 300, 0.0, 300.0, VarManager::kMultFDDA); hm->AddHistogram(histClass, "MultFDDC", "MultFDDC", false, 50, 0.0, 50.0, VarManager::kMultFDDC); hm->AddHistogram(histClass, "MultTracklets", "MultTracklets", false, 250, 0.0, 250.0, VarManager::kMultTracklets); - hm->AddHistogram(histClass, "VtxNContribReal", "Vtx n contributors", false, 200, 0.0, 200.0, VarManager::kVtxNcontribReal); + hm->AddHistogram(histClass, "VtxNContribReal", "Vtx n contributors", false, 150, 0.0, 150.0, VarManager::kVtxNcontribReal); hm->AddHistogram(histClass, "VtxNContrib", "Vtx n contributors", false, 100, 0.0, 100.0, VarManager::kVtxNcontrib); - hm->AddHistogram(histClass, "MultNTracksPVeta1", "MultNTracksPVeta1", false, 200, 0, 200.0, VarManager::kMultNTracksPVeta1); - hm->AddHistogram(histClass, "MultNTracksPVetaHalf", "MultNTracksPVetaHalf", false, 200, 0, 200.0, VarManager::kMultNTracksPVetaHalf); + hm->AddHistogram(histClass, "MultNTracksPVeta1", "MultNTracksPVeta1", false, 150, 0, 150.0, VarManager::kMultNTracksPVeta1); + hm->AddHistogram(histClass, "MultNTracksPVetaHalf", "MultNTracksPVetaHalf", false, 150, 0, 150.0, VarManager::kMultNTracksPVetaHalf); hm->AddHistogram(histClass, "MultTPC_MultFV0A", "MultTPC vs MultFV0A", false, 100, 0, 500.0, VarManager::kMultTPC, 100, 0, 500.0, VarManager::kMultFV0A); hm->AddHistogram(histClass, "MultTPC_MultFT0A", "MultTPC vs MultFT0A", false, 100, 0, 500.0, VarManager::kMultTPC, 100, 0, 200.0, VarManager::kMultFT0A); hm->AddHistogram(histClass, "MultTPC_MultFT0C", "MultTPC vs MultFT0C", false, 100, 0, 500.0, VarManager::kMultTPC, 100, 0, 300.0, VarManager::kMultFT0C); @@ -112,7 +112,9 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "VtxZ_MultTPCWithPV", "VtxZ vs MultTPCWithPV", false, 240, -12.0, 12.0, VarManager::kVtxZ, 400, 0, 400.0, VarManager::kMultNTracksHasTPC); hm->AddHistogram(histClass, "VtxZ_MultITSTPCWithPV", "VtxZ vs MultITSTPCWithPV", false, 240, -12.0, 12.0, VarManager::kVtxZ, 400, 0, 400.0, VarManager::kMultNTracksITSTPC); hm->AddHistogram(histClass, "VtxZ_MultITSOnly", "VtxZ vs MultITSOnly", false, 240, -12.0, 12.0, VarManager::kVtxZ, 400, 0, 400.0, VarManager::kMultNTracksITSOnly); - hm->AddHistogram(histClass, "VtxZ_VtxNcontribReal", "VtxZ vs VtxNcontribReal", false, 240, -12.0, 12.0, VarManager::kVtxZ, 200, 0, 200.0, VarManager::kVtxNcontribReal); + hm->AddHistogram(histClass, "VtxZ_VtxNcontribReal", "VtxZ vs VtxNcontribReal", false, 100, -10.0, 10.0, VarManager::kVtxZ, 150, 0, 150.0, VarManager::kVtxNcontribReal); + hm->AddHistogram(histClass, "VtxZ_MultNTracksPVeta1", "VtxZ vs MultNTracksPVeta1", false, 100, -10.0, 10.0, VarManager::kVtxZ, 150, 0, 150.0, VarManager::kMultNTracksPVeta1); + hm->AddHistogram(histClass, "VtxZ_MultNTracksPVetaHalf", "VtxZ vs MultNTracksPVetaHalf", false, 100, -10.0, 10.0, VarManager::kVtxZ, 150, 0, 150.0, VarManager::kMultNTracksPVetaHalf); } else { hm->AddHistogram(histClass, "MultTPC", "MultTPC", false, 200, 0.0, 50000.0, VarManager::kMultTPC); @@ -938,7 +940,9 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Y_Pt", "", false, 100, -5.0, 5.0, VarManager::kRap, 20, 0.0, 20.0, VarManager::kPt); } if (subGroupStr.Contains("mult_pvcontrib")) { - hm->AddHistogram(histClass, "Mass_VtxNcontribReal", "Mass vs VtxNcontribReal", false, 200, 2.0, 5.0, VarManager::kMass, 200, 0, 200.0, VarManager::kVtxNcontribReal); + hm->AddHistogram(histClass, "Mass_VtxNcontribReal", "Mass vs VtxNcontribReal", false, 200, 2.0, 5.0, VarManager::kMass, 150, 0, 150.0, VarManager::kVtxNcontribReal); + hm->AddHistogram(histClass, "Mass_MultNTracksPVetaHalf", "Mass vs MultNTracksPVetaHalf", false, 200, 2.0, 5.0, VarManager::kMass, 150, 0, 150.0, VarManager::kMultNTracksPVetaHalf); + hm->AddHistogram(histClass, "Mass_MultNTracksPVeta1", "Mass vs MultNTracksPVeta1", false, 200, 2.0, 5.0, VarManager::kMass, 150, 0, 150.0, VarManager::kMultNTracksPVeta1); } if (subGroupStr.Contains("barrel")) { hm->AddHistogram(histClass, "Mass", "", false, 500, 0.0, 5.0, VarManager::kMass); @@ -1030,6 +1034,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "LxyProj_Mass_Pt", "", false, 50, 2.0, 4.0, VarManager::kMass, 10, 0.0, 20.0, VarManager::kPt, 1000, -1.0, 1.0, VarManager::kVertexingLxyProjected); hm->AddHistogram(histClass, "LzProj_Mass_Pt", "", false, 50, 2.0, 4.0, VarManager::kMass, 10, 0.0, 20.0, VarManager::kPt, 1000, -1.0, 1.0, VarManager::kVertexingLzProjected); hm->AddHistogram(histClass, "CosPointingAngle", "", false, 200, -1.0, 1.0, VarManager::kCosPointingAngle); + hm->AddHistogram(histClass, "VtxingChi2PCA", "", false, 100, 0.0, 10.0, VarManager::kVertexingChi2PCA); } if (subGroupStr.Contains("kalman-filter")) { @@ -1249,6 +1254,18 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Mass_Pt_cosThetaPP_phiPP", "", 4, varspTPP, binspT, xminpT, xmaxpT, 0, -1, kFALSE); hm->AddHistogram(histClass, "Mass_y_cosThetaPP_phiPP", "", 4, varsrapPP, binsy, xminy, xmaxy, 0, -1, kFALSE); } + if (subGroupStr.Contains("dimuon-polarization-lowmass-pp")) { + int varspTPP[4] = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaPP, VarManager::kPhiPP}; + int varsrapPP[4] = {VarManager::kMass, VarManager::kRap, VarManager::kCosThetaPP, VarManager::kPhiPP}; + int binspT[4] = {100, 20, 20, 20}; + int binsy[4] = {100, 10, 20, 20}; + double xminpT[4] = {0.2, 0., -1., -3.14}; + double xmaxpT[4] = {1.5, 20., 1., +3.14}; + double xminy[4] = {0.2, 2.5, -1., -3.14}; + double xmaxy[4] = {1.5, 4.0, 1., +3.14}; + hm->AddHistogram(histClass, "Mass_Pt_cosThetaPP_phiPP", "", 4, varspTPP, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + hm->AddHistogram(histClass, "Mass_y_cosThetaPP_phiPP", "", 4, varsrapPP, binsy, xminy, xmaxy, 0, -1, kFALSE); + } if (subGroupStr.Contains("upsilon-polarization-he")) { int varspTHE[4] = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaHE, VarManager::kPhiHE}; int varsrapHE[4] = {VarManager::kMass, VarManager::kRap, VarManager::kCosThetaHE, VarManager::kPhiHE}; diff --git a/PWGDQ/Core/VarManager.h b/PWGDQ/Core/VarManager.h index 1da8fa30562..31c1f69a275 100644 --- a/PWGDQ/Core/VarManager.h +++ b/PWGDQ/Core/VarManager.h @@ -1106,15 +1106,19 @@ class VarManager : public TObject // Check whether all the needed objects for TPC postcalibration are available if (fgCalibs.find(kTPCElectronMean) != fgCalibs.end() && fgCalibs.find(kTPCElectronSigma) != fgCalibs.end()) { fgRunTPCPostCalibration[0] = true; + fgUsedVars[kTPCnSigmaEl_Corr] = true; } if (fgCalibs.find(kTPCPionMean) != fgCalibs.end() && fgCalibs.find(kTPCPionSigma) != fgCalibs.end()) { fgRunTPCPostCalibration[1] = true; + fgUsedVars[kTPCnSigmaPi_Corr] = true; } if (fgCalibs.find(kTPCKaonMean) != fgCalibs.end() && fgCalibs.find(kTPCKaonSigma) != fgCalibs.end()) { fgRunTPCPostCalibration[2] = true; + fgUsedVars[kTPCnSigmaKa_Corr] = true; } if (fgCalibs.find(kTPCProtonMean) != fgCalibs.end() && fgCalibs.find(kTPCProtonSigma) != fgCalibs.end()) { fgRunTPCPostCalibration[3] = true; + fgUsedVars[kTPCnSigmaPr_Corr] = true; } } static TObject* GetCalibrationObject(CalibObjects calib) @@ -2376,7 +2380,7 @@ void VarManager::FillTrack(T const& track, float* values) } // Quantities based on the barrel PID tables - if constexpr ((fillMap & TrackPID) > 0 || (fillMap & ReducedTrackBarrelPID) > 0) { + if constexpr ((fillMap & TrackPID) > 0 || (fillMap & TrackTPCPID) > 0 || (fillMap & ReducedTrackBarrelPID) > 0) { values[kTPCnSigmaEl] = track.tpcNSigmaEl(); values[kTPCnSigmaPi] = track.tpcNSigmaPi(); values[kTPCnSigmaKa] = track.tpcNSigmaKa(); @@ -2479,10 +2483,13 @@ void VarManager::FillTrack(T const& track, float* values) values[kTPCnSigmaPr_Corr] = track.tpcNSigmaPr(); } } - values[kTOFnSigmaEl] = track.tofNSigmaEl(); - values[kTOFnSigmaPi] = track.tofNSigmaPi(); - values[kTOFnSigmaKa] = track.tofNSigmaKa(); - values[kTOFnSigmaPr] = track.tofNSigmaPr(); + + if constexpr ((fillMap & TrackPID) > 0 || (fillMap & ReducedTrackBarrelPID) > 0) { + values[kTOFnSigmaEl] = track.tofNSigmaEl(); + values[kTOFnSigmaPi] = track.tofNSigmaPi(); + values[kTOFnSigmaKa] = track.tofNSigmaKa(); + values[kTOFnSigmaPr] = track.tofNSigmaPr(); + } if (fgUsedVars[kTPCsignalRandomized] || fgUsedVars[kTPCnSigmaElRandomized] || fgUsedVars[kTPCnSigmaPiRandomized] || fgUsedVars[kTPCnSigmaPrRandomized]) { // NOTE: this is needed temporarily for the study of the impact of TPC pid degradation on the quarkonium triggers in high lumi pp @@ -2910,7 +2917,7 @@ void VarManager::FillPair(T1 const& t1, T2 const& t2, float* values) ROOT::Math::XYZVector yaxis_PP{(v12.Vect()).Unit()}; ROOT::Math::XYZVector xaxis_PP{(yaxis_PP.Cross(zaxis_PP)).Unit()}; if (fgUsedVars[kCosThetaPP]) { - values[kCosThetaPP] = zaxis_PP.Dot(v_CM); + values[kCosThetaPP] = zaxis_PP.Dot(v_CM) / std::sqrt(zaxis_PP.Mag2()); } if (fgUsedVars[kPhiPP]) { values[kPhiPP] = TMath::ATan2(yaxis_PP.Dot(v_CM), xaxis_PP.Dot(v_CM)); @@ -3972,6 +3979,7 @@ void VarManager::FillTripletVertexing(C const& collision, T const& t1, T const& values[VarManager::kVertexingProcCode] = procCode; if (procCode == 0) { // TODO: set the other variables to appropriate values and return + values[kVertexingChi2PCA] = -999.; values[kVertexingLxy] = -999.; values[kVertexingLxyz] = -999.; values[kVertexingLz] = -999.; @@ -4006,6 +4014,11 @@ void VarManager::FillTripletVertexing(C const& collision, T const& t1, T const& o2::dataformats::VertexBase primaryVertex = {std::move(vtxXYZ), std::move(vtxCov)}; auto covMatrixPV = primaryVertex.getCov(); + if (fgUsedVars[kVertexingChi2PCA]) { + auto chi2PCA = fgFitterThreeProngBarrel.getChi2AtPCACandidate(); + values[VarManager::kVertexingChi2PCA] = chi2PCA; + } + double phi = std::atan2(secondaryVertex[1] - collision.posY(), secondaryVertex[0] - collision.posX()); double theta = std::atan2(secondaryVertex[2] - collision.posZ(), std::sqrt((secondaryVertex[0] - collision.posX()) * (secondaryVertex[0] - collision.posX()) + @@ -4272,9 +4285,10 @@ void VarManager::FillDileptonTrackVertexing(C const& collision, T1 const& lepton covMatrixPCA = fgFitterThreeProngFwd.calcPCACovMatrixFlat(); } - auto chi2PCA = fgFitterThreeProngBarrel.getChi2AtPCACandidate(); - if (fgUsedVars[kVertexingChi2PCA]) + if (fgUsedVars[kVertexingChi2PCA]) { + auto chi2PCA = fgFitterThreeProngBarrel.getChi2AtPCACandidate(); values[VarManager::kVertexingChi2PCA] = chi2PCA; + } double phi = std::atan2(secondaryVertex[1] - collision.posY(), secondaryVertex[0] - collision.posX()); double theta = std::atan2(secondaryVertex[2] - collision.posZ(), diff --git a/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx b/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx index a2e053375d9..484ec4873d5 100644 --- a/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx +++ b/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx @@ -989,6 +989,7 @@ struct TableMakerMC { if (sig->CheckSignal(true, mctrack)) { mcflags |= (static_cast(1) << i); if (fDoDetailedQA) { + j = 0; for (auto& cut : fMuonCuts) { if (trackTempFilterMap & (uint8_t(1) << j)) { fHistMan->FillHistClass(Form("Muons_%s_%s", cut->GetName(), sig->GetName()), VarManager::fgValues); // fill the reconstructed truth diff --git a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx index 9630c8275b5..cb44ae1d935 100644 --- a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx +++ b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx @@ -1507,7 +1507,8 @@ struct AnalysisSameEventPairing { // assign hist directories for pairs matched to MC signals for each (muon cut, MCrec signal) combination if (!sigNamesStr.IsNull()) { - for (auto& sig : fRecMCSignals) { + for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { + auto sig = fRecMCSignals.at(isig); names = { Form("PairsMuonSEPM_%s_%s", objArray->At(icut)->GetName(), sig->GetName()), Form("PairsMuonSEPP_%s_%s", objArray->At(icut)->GetName(), sig->GetName()), @@ -1526,9 +1527,9 @@ struct AnalysisSameEventPairing { for (auto& n : names) { histNames += Form("%s;", n.Data()); } + fMuonHistNamesMCmatched.try_emplace(icut * fRecMCSignals.size() + isig, names); } // end loop over MC signals } - fMuonHistNamesMCmatched[icut] = names; } } } // end loop over cuts diff --git a/PWGDQ/Tasks/tableReader_withAssoc.cxx b/PWGDQ/Tasks/tableReader_withAssoc.cxx index a58b23fac02..c17a0b3d24c 100644 --- a/PWGDQ/Tasks/tableReader_withAssoc.cxx +++ b/PWGDQ/Tasks/tableReader_withAssoc.cxx @@ -2903,6 +2903,10 @@ struct AnalysisDileptonTrack { Configurable fConfigGRPmagPath{"cfgGrpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable fConfigMagField{"cfgMagField", 5.0f, "Manually set magnetic field"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; + Configurable fConfigGeoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. int fNCuts; // number of dilepton leg cuts int fNLegCuts; @@ -3152,6 +3156,16 @@ struct AnalysisDileptonTrack { VarManager::SetUseVars(fHistMan->GetUsedVars()); fOutputList.setObject(fHistMan->GetMainHistogramList()); + + fCCDB->setURL(fConfigCcdbUrl.value); + fCCDB->setCaching(true); + fCCDB->setLocalObjectValidityChecking(); + fCCDB->setCreatedNotAfter(fConfigNoLaterThan.value); + if (!o2::base::GeometryManager::isGeometryLoaded()) { + LOG(info) << "Loading geometry from CCDB in dilepton-track task"; + fCCDB->get(fConfigGeoPath); + } + LOG(info) << "Initialization of AnalysisDileptonTrack finished (idstoreh)"; } diff --git a/PWGEM/Dilepton/Core/DielectronCut.h b/PWGEM/Dilepton/Core/DielectronCut.h index 9ad54af870c..eec8c0928b9 100644 --- a/PWGEM/Dilepton/Core/DielectronCut.h +++ b/PWGEM/Dilepton/Core/DielectronCut.h @@ -359,13 +359,13 @@ class DielectronCut : public TNamed { switch (cut) { case DielectronCuts::kTrackPtRange: - return track.pt() >= mMinTrackPt && track.pt() <= mMaxTrackPt; + return track.pt() > mMinTrackPt && track.pt() < mMaxTrackPt; case DielectronCuts::kTrackEtaRange: - return track.eta() >= mMinTrackEta && track.eta() <= mMaxTrackEta; + return track.eta() > mMinTrackEta && track.eta() < mMaxTrackEta; case DielectronCuts::kTrackPhiRange: - return track.phi() >= mMinTrackPhi && track.phi() <= mMaxTrackPhi; + return track.phi() > mMinTrackPhi && track.phi() < mMaxTrackPhi; case DielectronCuts::kTPCNCls: return track.tpcNClsFound() >= mMinNClustersTPC; @@ -374,10 +374,10 @@ class DielectronCut : public TNamed return track.tpcNClsCrossedRows() >= mMinNCrossedRowsTPC; case DielectronCuts::kTPCCrossedRowsOverNCls: - return track.tpcCrossedRowsOverFindableCls() >= mMinNCrossedRowsOverFindableClustersTPC; + return track.tpcCrossedRowsOverFindableCls() > mMinNCrossedRowsOverFindableClustersTPC; case DielectronCuts::kTPCFracSharedClusters: - return track.tpcFractionSharedCls() <= mMaxFracSharedClustersTPC; + return track.tpcFractionSharedCls() < mMaxFracSharedClustersTPC; case DielectronCuts::kRelDiffPin: return mMinRelDiffPin < (track.tpcInnerParam() - track.p()) / track.p() && (track.tpcInnerParam() - track.p()) / track.p() < mMaxRelDiffPin; @@ -386,13 +386,13 @@ class DielectronCut : public TNamed return mMinChi2PerClusterTPC < track.tpcChi2NCl() && track.tpcChi2NCl() < mMaxChi2PerClusterTPC; case DielectronCuts::kDCA3Dsigma: - return mMinDca3D <= dca3DinSigma(track) && dca3DinSigma(track) <= mMaxDca3D; // in sigma for single leg + return mMinDca3D < dca3DinSigma(track) && dca3DinSigma(track) < mMaxDca3D; // in sigma for single leg case DielectronCuts::kDCAxy: - return std::fabs(track.dcaXY()) <= ((mMaxDcaXYPtDep) ? mMaxDcaXYPtDep(track.pt()) : mMaxDcaXY); + return std::fabs(track.dcaXY()) < ((mMaxDcaXYPtDep) ? mMaxDcaXYPtDep(track.pt()) : mMaxDcaXY); case DielectronCuts::kDCAz: - return std::fabs(track.dcaZ()) <= mMaxDcaZ; + return std::fabs(track.dcaZ()) < mMaxDcaZ; case DielectronCuts::kITSNCls: return mMinNClustersITS <= track.itsNCls() && track.itsNCls() <= mMaxNClustersITS; diff --git a/PWGEM/Dilepton/Core/Dilepton.h b/PWGEM/Dilepton/Core/Dilepton.h index ebe9e26ad50..33f0ba99718 100644 --- a/PWGEM/Dilepton/Core/Dilepton.h +++ b/PWGEM/Dilepton/Core/Dilepton.h @@ -281,6 +281,11 @@ struct Dilepton { Configurable cfg_min_rabs{"cfg_min_rabs", 17.6, "min Radius at the absorber end"}; Configurable cfg_max_rabs{"cfg_max_rabs", 89.5, "max Radius at the absorber end"}; Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; + Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_DPhi_wrt_matchedMCHMID{"cfg_max_DPhi_wrt_matchedMCHMID", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; + Configurable requireMFTHitMap{"requireMFTHitMap", false, "flag to apply MFT hit map"}; + Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{0}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; } dimuoncuts; o2::aod::rctsel::RCTFlagsChecker rctChecker; @@ -749,6 +754,8 @@ struct Dilepton { fDimuonCut.SetDCAxy(0.f, dimuoncuts.cfg_max_dcaxy); fDimuonCut.SetRabs(dimuoncuts.cfg_min_rabs, dimuoncuts.cfg_max_rabs); fDimuonCut.SetMaxPDCARabsDep([&](float rabs) { return (rabs < 26.5 ? 594.f : 324.f); }); + fDimuonCut.SetMaxdPtdEtadPhiwrtMCHMID(dimuoncuts.cfg_max_relDPt_wrt_matchedMCHMID, dimuoncuts.cfg_max_DEta_wrt_matchedMCHMID, dimuoncuts.cfg_max_DPhi_wrt_matchedMCHMID); // this is relevant for global muons + fDimuonCut.SetMFTHitMap(dimuoncuts.requireMFTHitMap, dimuoncuts.requiredMFTDisks); } template @@ -903,6 +910,11 @@ struct Dilepton { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hMvsPhiV"), phiv, v12.M(), weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hMvsOpAng"), opAng, v12.M(), weight); + if (cfgDCAType == 1) { + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hDCA1vsDCA2"), dcaXYinSigma(t1), dcaXYinSigma(t2), weight); + } else if (cfgDCAType == 2) { + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hDCA1vsDCA2"), dcaZinSigma(t1), dcaZinSigma(t2), weight); + } } } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, weight); @@ -910,6 +922,11 @@ struct Dilepton { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hMvsPhiV"), phiv, v12.M(), weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hMvsOpAng"), opAng, v12.M(), weight); + if (cfgDCAType == 1) { + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hDCA1vsDCA2"), dcaXYinSigma(t1), dcaXYinSigma(t2), weight); + } else if (cfgDCAType == 2) { + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hDCA1vsDCA2"), dcaZinSigma(t1), dcaZinSigma(t2), weight); + } } } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, weight); @@ -917,6 +934,11 @@ struct Dilepton { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hMvsPhiV"), phiv, v12.M(), weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hMvsOpAng"), opAng, v12.M(), weight); + if (cfgDCAType == 1) { + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hDCA1vsDCA2"), dcaXYinSigma(t1), dcaXYinSigma(t2), weight); + } else if (cfgDCAType == 2) { + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hDCA1vsDCA2"), dcaZinSigma(t1), dcaZinSigma(t2), weight); + } } } } else if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kUPC)) { diff --git a/PWGEM/Dilepton/Core/DileptonMC.h b/PWGEM/Dilepton/Core/DileptonMC.h index 769c6b72ec3..25ebe949553 100644 --- a/PWGEM/Dilepton/Core/DileptonMC.h +++ b/PWGEM/Dilepton/Core/DileptonMC.h @@ -273,6 +273,11 @@ struct DileptonMC { Configurable cfg_min_rabs{"cfg_min_rabs", 17.6, "min Radius at the absorber end"}; Configurable cfg_max_rabs{"cfg_max_rabs", 89.5, "max Radius at the absorber end"}; Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; + Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_DPhi_wrt_matchedMCHMID{"cfg_max_DPhi_wrt_matchedMCHMID", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; + Configurable requireMFTHitMap{"requireMFTHitMap", false, "flag to apply MFT hit map"}; + Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{0}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; } dimuoncuts; o2::aod::rctsel::RCTFlagsChecker rctChecker; @@ -715,6 +720,8 @@ struct DileptonMC { fDimuonCut.SetDCAxy(0.f, dimuoncuts.cfg_max_dcaxy); fDimuonCut.SetRabs(dimuoncuts.cfg_min_rabs, dimuoncuts.cfg_max_rabs); fDimuonCut.SetMaxPDCARabsDep([&](float rabs) { return (rabs < 26.5 ? 594.f : 324.f); }); + fDimuonCut.SetMaxdPtdEtadPhiwrtMCHMID(dimuoncuts.cfg_max_relDPt_wrt_matchedMCHMID, dimuoncuts.cfg_max_DEta_wrt_matchedMCHMID, dimuoncuts.cfg_max_DPhi_wrt_matchedMCHMID); // this is relevant for global muons + fDimuonCut.SetMFTHitMap(dimuoncuts.requireMFTHitMap, dimuoncuts.requiredMFTDisks); } template diff --git a/PWGEM/Dilepton/Core/DimuonCut.cxx b/PWGEM/Dilepton/Core/DimuonCut.cxx index ee18a8e4232..96f00f8b7a5 100644 --- a/PWGEM/Dilepton/Core/DimuonCut.cxx +++ b/PWGEM/Dilepton/Core/DimuonCut.cxx @@ -119,3 +119,22 @@ void DimuonCut::SetMaxPDCARabsDep(std::function RabsDepCut) mMaxPDCARabsDep = RabsDepCut; LOG(info) << "Dimuon Cut, set max pDCA as a function of Rabs: " << mMaxPDCARabsDep(10.0); } +void DimuonCut::SetMFTHitMap(bool flag, std::vector hitMap) +{ + mApplyMFTHitMap = flag; + mRequiredMFTDisks = hitMap; + if (mApplyMFTHitMap) { + for (const auto& iDisk : mRequiredMFTDisks) { + LOG(info) << "Dimuon Cut, require MFT hit on Disk: " << iDisk; + } + } +} +void DimuonCut::SetMaxdPtdEtadPhiwrtMCHMID(float reldPtMax, float dEtaMax, float dPhiMax) +{ + mMaxReldPtwrtMCHMID = reldPtMax; + mMaxdEtawrtMCHMID = dEtaMax; + mMaxdPhiwrtMCHMID = dPhiMax; + LOG(info) << "Dimuon Cut, set max rel. dpt between MFT-MCH-MID and associated MCH-MID: " << mMaxReldPtwrtMCHMID; + LOG(info) << "Dimuon Cut, set max deta between MFT-MCH-MID and associated MCH-MID: " << mMaxdEtawrtMCHMID; + LOG(info) << "Dimuon Cut, set max dphi between MFT-MCH-MID and associated MCH-MID: " << mMaxdPhiwrtMCHMID; +} diff --git a/PWGEM/Dilepton/Core/DimuonCut.h b/PWGEM/Dilepton/Core/DimuonCut.h index 4bb854c6b73..b96afcd7c28 100644 --- a/PWGEM/Dilepton/Core/DimuonCut.h +++ b/PWGEM/Dilepton/Core/DimuonCut.h @@ -59,6 +59,8 @@ class DimuonCut : public TNamed kMatchingChi2MCHMID, kRabs, kPDCA, + kMFTHitMap, + kDPtDEtaDPhiwrtMCHMID, kNCuts }; @@ -154,6 +156,12 @@ class DimuonCut : public TNamed if (!IsSelectedTrack(track, DimuonCuts::kRabs)) { return false; } + if (mApplyMFTHitMap && track.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) && !IsSelectedTrack(track, DimuonCuts::kMFTHitMap)) { + return false; + } + if (track.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) && !IsSelectedTrack(track, DimuonCuts::kDPtDEtaDPhiwrtMCHMID)) { + return false; + } return true; } @@ -198,6 +206,19 @@ class DimuonCut : public TNamed case DimuonCuts::kRabs: return mMinRabs < track.rAtAbsorberEnd() && track.rAtAbsorberEnd() < mMaxRabs; + case DimuonCuts::kMFTHitMap: { + std::vector mftHitMap{checkMFTHitMap<0, 1>(track), checkMFTHitMap<2, 3>(track), checkMFTHitMap<4, 5>(track), checkMFTHitMap<6, 7>(track), checkMFTHitMap<8, 9>(track)}; + for (const auto& iDisk : mRequiredMFTDisks) { + if (!mftHitMap[iDisk]) { + return false; + } + } + return true; + } + + case DimuonCuts::kDPtDEtaDPhiwrtMCHMID: + return std::fabs(track.ptMatchedMCHMID() - track.pt()) / track.pt() < mMaxReldPtwrtMCHMID && std::sqrt(std::pow((track.etaMatchedMCHMID() - track.eta()) / mMaxdEtawrtMCHMID, 2) + std::pow((track.phiMatchedMCHMID() - track.phi()) / mMaxdPhiwrtMCHMID, 2)) < 1.f; + default: return false; } @@ -222,6 +243,8 @@ class DimuonCut : public TNamed void SetDCAxy(float min, float max); // in cm void SetRabs(float min, float max); // in cm void SetMaxPDCARabsDep(std::function RabsDepCut); + void SetMFTHitMap(bool flag, std::vector hitMap); + void SetMaxdPtdEtadPhiwrtMCHMID(float reldPtMax, float dEtaMax, float dPhiMax); // this is relevant for global muons private: // pair cuts @@ -249,6 +272,9 @@ class DimuonCut : public TNamed float mMinRabs{17.6}, mMaxRabs{89.5}; float mMinDcaXY{0.0f}, mMaxDcaXY{1e10f}; + float mMaxReldPtwrtMCHMID{1e10f}, mMaxdEtawrtMCHMID{1e10f}, mMaxdPhiwrtMCHMID{1e10f}; + bool mApplyMFTHitMap{false}; + std::vector mRequiredMFTDisks{}; ClassDef(DimuonCut, 1); }; diff --git a/PWGEM/Dilepton/Core/SingleTrackQC.h b/PWGEM/Dilepton/Core/SingleTrackQC.h index 7ed467c2814..561e8a2adee 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQC.h @@ -201,6 +201,11 @@ struct SingleTrackQC { Configurable cfg_min_rabs{"cfg_min_rabs", 17.6, "min Radius at the absorber end"}; Configurable cfg_max_rabs{"cfg_max_rabs", 89.5, "max Radius at the absorber end"}; Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; + Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_DPhi_wrt_matchedMCHMID{"cfg_max_DPhi_wrt_matchedMCHMID", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; + Configurable requireMFTHitMap{"requireMFTHitMap", false, "flag to apply MFT hit map"}; + Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{0}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; } dimuoncuts; o2::aod::rctsel::RCTFlagsChecker rctChecker; @@ -231,7 +236,7 @@ struct SingleTrackQC { // track info fRegistry.add("Track/positive/hs", "rec. single electron", kTHnSparseD, {axis_pt, axis_eta, axis_phi, axis_dca}, true); - fRegistry.add("Track/positive/hQoverPt", "q/pT;q/p_{T} (GeV/c)^{-1}", kTH1F, {{400, -20, 20}}, false); + fRegistry.add("Track/positive/hQoverPt", "q/pT;q/p_{T} (GeV/c)^{-1}", kTH1F, {{2000, -5, 5}}, false); fRegistry.add("Track/positive/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", kTH2F, {{200, -1.0f, 1.0f}, {700, -3.5f, 3.5f}}, false); fRegistry.add("Track/positive/hDCAxyzSigma", "DCA xy vs. z;DCA_{xy} (#sigma);DCA_{z} (#sigma)", kTH2F, {{400, -20.0f, 20.0f}, {400, -20.0f, 20.0f}}, false); fRegistry.add("Track/positive/hDCAxyRes_Pt", "DCA_{xy} resolution vs. pT;p_{T} (GeV/c);DCA_{xy} resolution (#mum)", kTH2F, {{200, 0, 10}, {500, 0., 500}}, false); @@ -282,6 +287,7 @@ struct SingleTrackQC { // track info fRegistry.add("Track/positive/hs", "rec. single muon", kTHnSparseD, {axis_pt, axis_eta, axis_phi, axis_dca}, true); fRegistry.add("Track/positive/hEtaPhi_MatchMCHMID", "#eta vs. #varphi of matched MCHMID", kTH2F, {{180, 0, 2.f * M_PI}, {100, -6, -1}}, false); + fRegistry.add("Track/positive/hdEtadPhi", "#Delta#eta vs. #Delta#varphi between MFT-MCH-MID and MCH-MID;#varphi_{sa} - #varphi_{gl} (rad.);#eta_{sa} - #eta_{gl}", kTH2F, {{90, -M_PI / 4, M_PI / 4}, {100, -0.5, +0.5}}, false); fRegistry.add("Track/positive/hQoverPt", "q/pT;q/p_{T} (GeV/c)^{-1}", kTH1F, {{400, -20, 20}}, false); fRegistry.add("Track/positive/hTrackType", "track type", kTH1F, {{6, -0.5f, 5.5}}, false); fRegistry.add("Track/positive/hDCAxy", "DCA x vs. y;DCA_{x} (cm);DCA_{y} (cm)", kTH2F, {{200, -0.5f, 0.5f}, {200, -0.5f, 0.5f}}, false); @@ -452,6 +458,8 @@ struct SingleTrackQC { fDimuonCut.SetDCAxy(0.f, dimuoncuts.cfg_max_dcaxy); fDimuonCut.SetRabs(dimuoncuts.cfg_min_rabs, dimuoncuts.cfg_max_rabs); fDimuonCut.SetMaxPDCARabsDep([&](float rabs) { return (rabs < 26.5 ? 594.f : 324.f); }); + fDimuonCut.SetMaxdPtdEtadPhiwrtMCHMID(dimuoncuts.cfg_max_relDPt_wrt_matchedMCHMID, dimuoncuts.cfg_max_DEta_wrt_matchedMCHMID, dimuoncuts.cfg_max_DPhi_wrt_matchedMCHMID); // this is relevant for global muons + fDimuonCut.SetMFTHitMap(dimuoncuts.requireMFTHitMap, dimuoncuts.requiredMFTDisks); } template @@ -560,9 +568,15 @@ struct SingleTrackQC { weight = map_weight[track.globalIndex()]; } float dca_xy = fwdDcaXYinSigma(track); + + float deta = track.etaMatchedMCHMID() - track.eta(); + float dphi = track.phiMatchedMCHMID() - track.phi(); + o2::math_utils::bringToPMPi(dphi); + if (track.sign() > 0) { fRegistry.fill(HIST("Track/positive/hs"), track.pt(), track.eta(), track.phi(), dca_xy, weight); fRegistry.fill(HIST("Track/positive/hEtaPhi_MatchMCHMID"), track.phiMatchedMCHMID(), track.etaMatchedMCHMID(), weight); + fRegistry.fill(HIST("Track/positive/hdEtadPhi"), dphi, deta, weight); fRegistry.fill(HIST("Track/positive/hQoverPt"), track.sign() / track.pt()); fRegistry.fill(HIST("Track/positive/hTrackType"), track.trackType()); fRegistry.fill(HIST("Track/positive/hDCAxy"), track.fwdDcaX(), track.fwdDcaY()); @@ -580,6 +594,7 @@ struct SingleTrackQC { } else { fRegistry.fill(HIST("Track/negative/hs"), track.pt(), track.eta(), track.phi(), dca_xy, weight); fRegistry.fill(HIST("Track/negative/hEtaPhi_MatchMCHMID"), track.phiMatchedMCHMID(), track.etaMatchedMCHMID(), weight); + fRegistry.fill(HIST("Track/negative/hdEtadPhi"), dphi, deta, weight); fRegistry.fill(HIST("Track/negative/hQoverPt"), track.sign() / track.pt()); fRegistry.fill(HIST("Track/negative/hTrackType"), track.trackType()); fRegistry.fill(HIST("Track/negative/hDCAxy"), track.fwdDcaX(), track.fwdDcaY()); diff --git a/PWGEM/Dilepton/Core/SingleTrackQCMC.h b/PWGEM/Dilepton/Core/SingleTrackQCMC.h index f400b617f1f..5fb15b4ec26 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQCMC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQCMC.h @@ -207,6 +207,11 @@ struct SingleTrackQCMC { Configurable cfg_min_rabs{"cfg_min_rabs", 17.6, "min Radius at the absorber end"}; Configurable cfg_max_rabs{"cfg_max_rabs", 89.5, "max Radius at the absorber end"}; Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; + Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_DPhi_wrt_matchedMCHMID{"cfg_max_DPhi_wrt_matchedMCHMID", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; + Configurable requireMFTHitMap{"requireMFTHitMap", false, "flag to apply MFT hit map"}; + Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{0}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; } dimuoncuts; o2::aod::rctsel::RCTFlagsChecker rctChecker; @@ -339,6 +344,7 @@ struct SingleTrackQCMC { fRegistry.add("Track/lf/positive/hs", "rec. single muon", kTHnSparseD, {axis_pt, axis_eta, axis_phi, axis_dca, axis_charge_gen}, true); if (cfgFillQA) { fRegistry.add("Track/lf/positive/hEtaPhi_MatchMCHMID", "#eta vs. #varphi of matched MCHMID", kTH2F, {{180, 0, 2.f * M_PI}, {100, -6, -1}}, false); + fRegistry.add("Track/lf/positive/hdEtadPhi", "#Delta#eta vs. #Delta#varphi between MFT-MCH-MID and MCH-MID;#varphi_{sa} - #varphi_{gl} (rad.);#eta_{sa} - #eta_{gl}", kTH2F, {{90, -M_PI / 4, M_PI / 4}, {100, -0.5, +0.5}}, false); fRegistry.add("Track/lf/positive/hQoverPt", "q/pT;q/p_{T} (GeV/c)^{-1}", kTH1F, {{400, -20, 20}}, false); fRegistry.add("Track/lf/positive/hTrackType", "track type", kTH1F, {{6, -0.5f, 5.5}}, false); fRegistry.add("Track/lf/positive/hDCAxy", "DCA x vs. y;DCA_{x} (cm);DCA_{y} (cm)", kTH2F, {{200, -0.5f, 0.5f}, {200, -0.5f, 0.5f}}, false); @@ -511,6 +517,8 @@ struct SingleTrackQCMC { fDimuonCut.SetDCAxy(0.f, dimuoncuts.cfg_max_dcaxy); fDimuonCut.SetRabs(dimuoncuts.cfg_min_rabs, dimuoncuts.cfg_max_rabs); fDimuonCut.SetMaxPDCARabsDep([&](float rabs) { return (rabs < 26.5 ? 594.f : 324.f); }); + fDimuonCut.SetMaxdPtdEtadPhiwrtMCHMID(dimuoncuts.cfg_max_relDPt_wrt_matchedMCHMID, dimuoncuts.cfg_max_DEta_wrt_matchedMCHMID, dimuoncuts.cfg_max_DPhi_wrt_matchedMCHMID); // this is relevant for global muons + fDimuonCut.SetMFTHitMap(dimuoncuts.requireMFTHitMap, dimuoncuts.requiredMFTDisks); } template @@ -670,6 +678,9 @@ struct SingleTrackQCMC { { auto mctrack = track.template emmcparticle_as(); float dca_xy = fwdDcaXYinSigma(track); + float deta = track.etaMatchedMCHMID() - track.eta(); + float dphi = track.phiMatchedMCHMID() - track.phi(); + o2::math_utils::bringToPMPi(dphi); float weight = 1.f; if (cfgApplyWeightTTCA) { @@ -681,6 +692,7 @@ struct SingleTrackQCMC { fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hs"), track.pt(), track.eta(), track.phi(), dca_xy, -mctrack.pdgCode() / pdg_lepton, weight); if (cfgFillQA) { fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hEtaPhi_MatchMCHMID"), track.phiMatchedMCHMID(), track.etaMatchedMCHMID(), weight); + fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hdEtadPhi"), dphi, deta, weight); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hQoverPt"), track.sign() / track.pt()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hTrackType"), track.trackType()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hDCAxy"), track.fwdDcaX(), track.fwdDcaY()); @@ -703,6 +715,7 @@ struct SingleTrackQCMC { fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hs"), track.pt(), track.eta(), track.phi(), dca_xy, -mctrack.pdgCode() / pdg_lepton, weight); if (cfgFillQA) { fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hEtaPhi_MatchMCHMID"), track.phiMatchedMCHMID(), track.etaMatchedMCHMID(), weight); + fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hdEtadPhi"), dphi, deta, weight); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hQoverPt"), track.sign() / track.pt()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hTrackType"), track.trackType()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hDCAxy"), track.fwdDcaX(), track.fwdDcaY()); diff --git a/PWGEM/Dilepton/DataModel/dileptonTables.h b/PWGEM/Dilepton/DataModel/dileptonTables.h index ac688a57b98..244d5ada6cc 100644 --- a/PWGEM/Dilepton/DataModel/dileptonTables.h +++ b/PWGEM/Dilepton/DataModel/dileptonTables.h @@ -641,6 +641,47 @@ DECLARE_SOA_TABLE(EMGlobalMuonSelfIds, "AOD", "EMGLMUSELFID", emprimarymuon::Glo // iterators using EMGlobalMuonSelfId = EMGlobalMuonSelfIds::iterator; +// Dummy data for MC +namespace emdummydata +{ +DECLARE_SOA_COLUMN(A, a, float); +DECLARE_SOA_COLUMN(B, b, float); +DECLARE_SOA_COLUMN(C, c, float); +DECLARE_SOA_COLUMN(D, d, float); +DECLARE_SOA_COLUMN(E, e, float); +DECLARE_SOA_COLUMN(F, f, float); +DECLARE_SOA_COLUMN(G, g, float); +DECLARE_SOA_COLUMN(H, h, float); +DECLARE_SOA_COLUMN(I, i, float); +DECLARE_SOA_COLUMN(J, j, float); +DECLARE_SOA_COLUMN(K, k, float); +DECLARE_SOA_COLUMN(L, l, float); +DECLARE_SOA_COLUMN(M, m, float); +DECLARE_SOA_COLUMN(N, n, float); +DECLARE_SOA_COLUMN(O, o, float); +DECLARE_SOA_COLUMN(P, p, float); +DECLARE_SOA_COLUMN(Q, q, float); +DECLARE_SOA_COLUMN(R, r, float); +DECLARE_SOA_COLUMN(S, s, float); +DECLARE_SOA_COLUMN(T, t, float); +DECLARE_SOA_COLUMN(U, u, float); +DECLARE_SOA_COLUMN(V, v, float); +DECLARE_SOA_COLUMN(W, w, float); +DECLARE_SOA_COLUMN(X, x, float); +DECLARE_SOA_COLUMN(Y, y, float); +DECLARE_SOA_COLUMN(Z, z, float); +} // namespace emdummydata +DECLARE_SOA_TABLE(EMDummyDatas, "AOD", "EMDUMMYDATA", + o2::soa::Index<>, + emdummydata::A, emdummydata::B, emdummydata::C, emdummydata::D, emdummydata::E, + emdummydata::F, emdummydata::G, emdummydata::H, emdummydata::I, emdummydata::J, + emdummydata::K, emdummydata::L, emdummydata::M, emdummydata::N, emdummydata::O, + emdummydata::P, emdummydata::Q, emdummydata::R, emdummydata::S, emdummydata::T, + emdummydata::U, emdummydata::V, emdummydata::W, emdummydata::X, emdummydata::Y, + emdummydata::Z); + +// iterators +using EMDummyData = EMDummyDatas::iterator; } // namespace o2::aod #endif // PWGEM_DILEPTON_DATAMODEL_DILEPTONTABLES_H_ diff --git a/PWGEM/Dilepton/TableProducer/associateMCinfoDilepton.cxx b/PWGEM/Dilepton/TableProducer/associateMCinfoDilepton.cxx index fcccd1cf9c0..bdca5c93802 100644 --- a/PWGEM/Dilepton/TableProducer/associateMCinfoDilepton.cxx +++ b/PWGEM/Dilepton/TableProducer/associateMCinfoDilepton.cxx @@ -33,10 +33,6 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::soa; -using MyCollisionsMC = soa::Join; -using TracksMC = soa::Join; -using FwdTracksMC = soa::Join; - struct AssociateMCInfoDilepton { enum SubSystem { kElectron = 0x1, @@ -44,6 +40,10 @@ struct AssociateMCInfoDilepton { kPCM = 0x4, }; + using MyCollisionsMC = soa::Join; + using TracksMC = soa::Join; + using FwdTracksMC = soa::Join; + Produces mcevents; Produces mceventlabels; Produces emmcparticles; @@ -51,7 +51,9 @@ struct AssociateMCInfoDilepton { Produces v0legmclabels; Produces emprimaryelectronmclabels; Produces emprimarymuonmclabels; + Produces emdummydata; + Configurable n_dummy_loop{"n_dummy_loop", 0, "for loop runs over n times"}; Configurable down_scaling_omega{"down_scaling_omega", 1.1, "down scaling factor to store omega"}; Configurable down_scaling_phi{"down_scaling_phi", 1.1, "down scaling factor to store phi"}; Configurable min_eta_gen_primary{"min_eta_gen_primary", -1.5, "min rapidity Y to store generated information"}; // smearing is applied at analysis stage. set wider value. @@ -642,6 +644,19 @@ struct AssociateMCInfoDilepton { skimmingMC(collisions, bcs, mccollisions, mcTracks, o2tracks, nullptr, v0photons, v0legs, nullptr, nullptr); } + void processGenDummy(MyCollisionsMC const&) + { + for (int i = 0; i < n_dummy_loop; i++) { + emdummydata( + 0.f, 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, 0.f, + 0.f); + } + } + void processDummy(MyCollisionsMC const&) {} PROCESS_SWITCH(AssociateMCInfoDilepton, processMC_Electron, "create em mc event table for Electron", false); @@ -650,6 +665,7 @@ struct AssociateMCInfoDilepton { PROCESS_SWITCH(AssociateMCInfoDilepton, processMC_Electron_FwdMuon_PCM, "create em mc event table for PCM, Electron, FwdMuon", false); PROCESS_SWITCH(AssociateMCInfoDilepton, processMC_Electron_PCM, "create em mc event table for PCM, Electron", false); PROCESS_SWITCH(AssociateMCInfoDilepton, processMC_PCM, "create em mc event table for PCM", false); + PROCESS_SWITCH(AssociateMCInfoDilepton, processGenDummy, "produce dummy data", false); PROCESS_SWITCH(AssociateMCInfoDilepton, processDummy, "processDummy", true); }; diff --git a/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx b/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx index a24b62374f8..a0c7b6362f7 100644 --- a/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx +++ b/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx @@ -54,7 +54,7 @@ using namespace o2::constants::physics; using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; -using MyTracks = soa::Join; using MyTrack = MyTracks::iterator; @@ -77,19 +77,18 @@ struct TreeCreatorElectronMLDDA { {"V0/hMassK0Short", "V0 mass K0S", {HistType::kTH1F, {{200, 0.4, 0.6}}}}, {"V0/hMassLambda", "V0 mass Lambda", {HistType::kTH1F, {{100, 1.08, 1.18}}}}, {"V0/hMassAntiLambda", "V0 mass AntiLambda", {HistType::kTH1F, {{100, 1.08, 1.18}}}}, - {"hMvsPhiV", "mee vs. phiv", {HistType::kTH2F, {{72, 0, M_PI}, {100, 0, 0.1}}}}, - - {"V0/hTPCdEdx_P_El", "TPC dEdx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, - {"V0/hTPCdEdx_P_Mu", "TPC dEdx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, - {"V0/hTPCdEdx_P_Pi", "TPC dEdx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, - {"V0/hTPCdEdx_P_Ka", "TPC dEdx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, - {"V0/hTPCdEdx_P_Pr", "TPC dEdx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, - - {"V0/hTOFbeta_P_El", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, - {"V0/hTOFbeta_P_Mu", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, - {"V0/hTOFbeta_P_Pi", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, - {"V0/hTOFbeta_P_Ka", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, - {"V0/hTOFbeta_P_Pr", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, + {"hMvsPhiV", "m_{ee} vs. #varphi_{V};#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", {HistType::kTH2F, {{90, 0, M_PI}, {100, 0, 0.1}}}}, + + {"V0/hTPCdEdx_P_El", "TPC dEdx vs. p;p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, + {"V0/hTPCdEdx_P_Mu", "TPC dEdx vs. p;p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, + {"V0/hTPCdEdx_P_Pi", "TPC dEdx vs. p;p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, + {"V0/hTPCdEdx_P_Ka", "TPC dEdx vs. p;p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, + {"V0/hTPCdEdx_P_Pr", "TPC dEdx vs. p;p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0, 5}, {200, 0, 200}}}}, + {"V0/hTOFbeta_P_El", "TOF beta vs. p;p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, + {"V0/hTOFbeta_P_Mu", "TOF beta vs. p;p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, + {"V0/hTOFbeta_P_Pi", "TOF beta vs. p;p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, + {"V0/hTOFbeta_P_Ka", "TOF beta vs. p;p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, + {"V0/hTOFbeta_P_Pr", "TOF beta vs. p;p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0, 5}, {220, 0, 1.1}}}}, {"Cascade/hRxy_Xi", "R_{xy} of cascade vs. mass;m_{#Lambda#pi};R_{xy} (cm)", {HistType::kTH2F, {{200, 1.2, 1.4}, {200, 0, 20.f}}}}, {"Cascade/hRxy_Omega", "R_{xy} of cascade vs. mass;m_{#LambdaK};R_{xy} (cm)", {HistType::kTH2F, {{200, 1.6, 1.8}, {200, 0, 20.f}}}}, @@ -103,9 +102,7 @@ struct TreeCreatorElectronMLDDA { {"Cascade/hMassXi", "cascade mass #Xi", {HistType::kTH1F, {{200, 1.2, 1.4}}}}, {"Cascade/hMassOmega", "cascade mass #Omega", {HistType::kTH1F, {{200, 1.6, 1.8}}}}, {"Cascade/hMassPt_Xi", "cascade mass #Xi^{#pm};m_{#Lambda#pi} (GeV/c^{2});p_{T,#Lambda#pi} (GeV/c)", {HistType::kTH2F, {{200, 1.2, 1.4}, {100, 0, 10}}}}, - {"Cascade/hMassPt_Xi_bachelor", "cascade mass #Xi^{#pm};m_{#Lambda#pi} (GeV/c^{2});p_{T,#pi} (GeV/c)", {HistType::kTH2F, {{200, 1.2, 1.4}, {100, 0, 10}}}}, {"Cascade/hMassPt_Omega", "cascade mass #Omega^{#pm};m_{#LambdaK} (GeV/c^{2});p_{T,#LambdaK} (GeV/c)", {HistType::kTH2F, {{200, 1.6, 1.8}, {100, 0, 10}}}}, - {"Cascade/hMassPt_Omega_bachelor", "cascade mass #Omega^{#pm};m_{#LambdaK} (GeV/c^{2});p_{T,K} (GeV/c)", {HistType::kTH2F, {{200, 1.6, 1.8}, {100, 0, 10}}}}, }, }; @@ -386,15 +383,15 @@ struct TreeCreatorElectronMLDDA { } mDcaInfoCov.set(999, 999, 999, 999, 999); - auto track_par_cov_recalc = getTrackParCov(track); - track_par_cov_recalc.setPID(track.pidForTracking()); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(track.pidForTracking()); mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, track_par_cov_recalc, 2.f, matCorr, &mDcaInfoCov); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); float dcaXY = mDcaInfoCov.getY(); float dcaZ = mDcaInfoCov.getZ(); - if (std::fabs(track_par_cov_recalc.getEta()) > trackcuts.cfg_max_eta || track_par_cov_recalc.getPt() < trackcuts.cfg_min_pt) { + if (std::fabs(trackParCov.getEta()) > trackcuts.cfg_max_eta || trackParCov.getPt() < trackcuts.cfg_min_pt) { return false; } @@ -442,15 +439,15 @@ struct TreeCreatorElectronMLDDA { } mDcaInfoCov.set(999, 999, 999, 999, 999); - auto track_par_cov_recalc = getTrackParCov(track); - track_par_cov_recalc.setPID(track.pidForTracking()); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(track.pidForTracking()); mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, track_par_cov_recalc, 2.f, matCorr, &mDcaInfoCov); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); float dcaXY = mDcaInfoCov.getY(); // float dcaZ = mDcaInfoCov.getZ(); - if (std::fabs(track_par_cov_recalc.getEta()) > v0cuts.cfg_max_eta || track_par_cov_recalc.getPt() < v0cuts.cfg_min_pt) { + if (std::fabs(trackParCov.getEta()) > v0cuts.cfg_max_eta || trackParCov.getPt() < v0cuts.cfg_min_pt) { return false; } @@ -526,17 +523,17 @@ struct TreeCreatorElectronMLDDA { if (std::find(stored_trackIds.begin(), stored_trackIds.end(), track.globalIndex()) == stored_trackIds.end()) { mDcaInfoCov.set(999, 999, 999, 999, 999); - auto track_par_cov_recalc = getTrackParCov(track); - track_par_cov_recalc.setPID(track.pidForTracking()); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(track.pidForTracking()); mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, track_par_cov_recalc, 2.f, matCorr, &mDcaInfoCov); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); float dcaXY = mDcaInfoCov.getY(); float dcaZ = mDcaInfoCov.getZ(); emprimarytracks(collision.globalIndex(), collision.posZ(), collision.numContrib(), collision.trackOccupancyInTimeRange(), collision.ft0cOccupancyInTimeRange(), - track.pt(), track.eta(), track.phi(), track.tgl(), track.signed1Pt(), - dcaXY, dcaZ, track_par_cov_recalc.getSigmaY2(), track_par_cov_recalc.getSigmaZ2(), track_par_cov_recalc.getSigmaZY(), + trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi() > 0.f ? trackParCov.getPhi() : trackParCov.getPhi() + 2 * M_PI, trackParCov.getTgl(), trackParCov.getQ2Pt(), + dcaXY, dcaZ, trackParCov.getSigmaY2(), trackParCov.getSigmaZ2(), trackParCov.getSigmaZY(), track.tpcNClsFindable(), track.tpcNClsFound(), track.tpcNClsCrossedRows(), track.tpcChi2NCl(), track.tpcInnerParam(), track.tpcSignal(), track.tpcNSigmaEl(), track.tpcNSigmaMu(), track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), @@ -582,33 +579,32 @@ struct TreeCreatorElectronMLDDA { for (const auto& v0 : v0s_coll) { auto pos = v0.template posTrack_as(); auto neg = v0.template negTrack_as(); - if (!isSelectedV0Leg(collision, pos) || !isSelectedV0Leg(collision, neg)) { + // LOGF(info, "v0.globalIndex() = %d, v0.collisionId() = %d, v0.posTrackId() = %d, v0.negTrackId() = %d", v0.globalIndex(), v0.collisionId(), v0.posTrackId(), v0.negTrackId()); + + if (v0.dcaV0daughters() > v0cuts.cfg_max_dcadau) { + continue; + } + if (v0.v0cosPA() < v0cuts.cfg_min_cospa) { continue; } if (pos.sign() * neg.sign() > 0) { continue; } - - // LOGF(info, "v0.globalIndex() = %d, v0.collisionId() = %d, v0.posTrackId() = %d, v0.negTrackId() = %d", v0.globalIndex(), v0.collisionId(), v0.posTrackId(), v0.negTrackId()); + if (!isSelectedV0Leg(collision, pos) || !isSelectedV0Leg(collision, neg)) { + continue; + } registry.fill(HIST("V0/hPCA"), v0.dcaV0daughters()); registry.fill(HIST("V0/hCosPA"), v0.v0cosPA()); registry.fill(HIST("V0/hAP"), v0.alpha(), v0.qtarm()); - if (v0.dcaV0daughters() > v0cuts.cfg_max_dcadau) { - continue; - } - if (v0.v0cosPA() < v0cuts.cfg_min_cospa) { - continue; - } - if (isPion(pos) && isPion(neg)) { registry.fill(HIST("V0/hMassK0Short"), v0.mK0Short()); if (v0cuts.cfg_min_mass_k0s < v0.mK0Short() && v0.mK0Short() < v0cuts.cfg_max_mass_k0s) { - registry.fill(HIST("V0/hTPCdEdx_P_Pi"), neg.p(), neg.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_Pi"), neg.p(), neg.beta()); - registry.fill(HIST("V0/hTPCdEdx_P_Pi"), pos.p(), pos.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_Pi"), pos.p(), pos.beta()); + registry.fill(HIST("V0/hTPCdEdx_P_Pi"), neg.tpcInnerParam(), neg.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_Pi"), neg.tpcInnerParam(), neg.beta()); + registry.fill(HIST("V0/hTPCdEdx_P_Pi"), pos.tpcInnerParam(), pos.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_Pi"), pos.tpcInnerParam(), pos.beta()); if (dist01(engine) < downscaling_pion || pos.tpcInnerParam() > max_pin_for_downscaling_pion) { fillTrackTable(collision, pos, static_cast(o2::aod::pwgem::dilepton::PID_Label::kPion), static_cast(o2::aod::pwgem::dilepton::Track_Type::kSecondary), false); } @@ -623,8 +619,8 @@ struct TreeCreatorElectronMLDDA { if (dist01(engine) < downscaling_proton || pos.tpcInnerParam() > max_pin_for_downscaling_proton) { fillTrackTable(collision, pos, static_cast(o2::aod::pwgem::dilepton::PID_Label::kProton), static_cast(o2::aod::pwgem::dilepton::Track_Type::kSecondary), false); } - registry.fill(HIST("V0/hTPCdEdx_P_Pr"), pos.p(), pos.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_Pr"), pos.p(), pos.beta()); + registry.fill(HIST("V0/hTPCdEdx_P_Pr"), pos.tpcInnerParam(), pos.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_Pr"), pos.tpcInnerParam(), pos.beta()); } } if (isPionTight(pos) && isProton(neg)) { @@ -633,14 +629,14 @@ struct TreeCreatorElectronMLDDA { if (dist01(engine) < downscaling_proton || neg.tpcInnerParam() > max_pin_for_downscaling_proton) { fillTrackTable(collision, neg, static_cast(o2::aod::pwgem::dilepton::PID_Label::kProton), static_cast(o2::aod::pwgem::dilepton::Track_Type::kSecondary), false); } - registry.fill(HIST("V0/hTPCdEdx_P_Pr"), neg.p(), neg.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_Pr"), neg.p(), neg.beta()); + registry.fill(HIST("V0/hTPCdEdx_P_Pr"), neg.tpcInnerParam(), neg.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_Pr"), neg.tpcInnerParam(), neg.beta()); } } - registry.fill(HIST("V0/hMassGamma"), v0.mGamma()); - registry.fill(HIST("V0/hXY_Gamma"), v0.x(), v0.y()); - registry.fill(HIST("V0/hMassGamma_Rxy"), v0.v0radius(), v0.mGamma()); if (isElectron(pos) && isElectron(neg)) { + registry.fill(HIST("V0/hMassGamma"), v0.mGamma()); + registry.fill(HIST("V0/hXY_Gamma"), v0.x(), v0.y()); + registry.fill(HIST("V0/hMassGamma_Rxy"), v0.v0radius(), v0.mGamma()); if ((v0cuts.cfg_min_mass_photon < v0.mGamma() && v0.mGamma() < v0cuts.cfg_max_mass_photon)) { if (dist01(engine) < downscaling_electron || pos.tpcInnerParam() > max_pin_for_downscaling_electron) { fillTrackTable(collision, pos, static_cast(o2::aod::pwgem::dilepton::PID_Label::kElectron), static_cast(o2::aod::pwgem::dilepton::Track_Type::kSecondary), false); @@ -648,10 +644,10 @@ struct TreeCreatorElectronMLDDA { if (dist01(engine) < downscaling_electron || neg.tpcInnerParam() > max_pin_for_downscaling_electron) { fillTrackTable(collision, neg, static_cast(o2::aod::pwgem::dilepton::PID_Label::kElectron), static_cast(o2::aod::pwgem::dilepton::Track_Type::kSecondary), false); } - registry.fill(HIST("V0/hTPCdEdx_P_El"), neg.p(), neg.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_El"), neg.p(), neg.beta()); - registry.fill(HIST("V0/hTPCdEdx_P_El"), pos.p(), pos.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_El"), pos.p(), pos.beta()); + registry.fill(HIST("V0/hTPCdEdx_P_El"), neg.tpcInnerParam(), neg.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_El"), neg.tpcInnerParam(), neg.beta()); + registry.fill(HIST("V0/hTPCdEdx_P_El"), pos.tpcInnerParam(), pos.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_El"), pos.tpcInnerParam(), pos.beta()); } } } // end of v0 loop @@ -662,10 +658,6 @@ struct TreeCreatorElectronMLDDA { auto bachelor = cascade.template bachelor_as(); auto pos = cascade.template posTrack_as(); auto neg = cascade.template negTrack_as(); - if (!isSelectedV0Leg(collision, pos) || !isSelectedV0Leg(collision, neg) || !isSelectedV0Leg(collision, bachelor)) { - continue; - } - if (pos.sign() * neg.sign() > 0) { continue; } @@ -680,7 +672,6 @@ struct TreeCreatorElectronMLDDA { } } - registry.fill(HIST("Cascade/hMassLambda"), cascade.mLambda()); if (!(v0cuts.cfg_min_mass_lambda < cascade.mLambda() && cascade.mLambda() < v0cuts.cfg_max_mass_lambda)) { continue; } @@ -689,11 +680,6 @@ struct TreeCreatorElectronMLDDA { continue; } - registry.fill(HIST("Cascade/hV0PCA"), cascade.dcaV0daughters()); - registry.fill(HIST("Cascade/hV0CosPA"), cascade.v0cosPA(collision.posX(), collision.posY(), collision.posZ())); - registry.fill(HIST("Cascade/hPCA"), cascade.dcacascdaughters()); // distance between bachelor and V0. - registry.fill(HIST("Cascade/hCosPA"), cascade.casccosPA(collision.posX(), collision.posY(), collision.posZ())); - if (cascade.dcaV0daughters() > cascadecuts.cfg_max_dcadau_v0) { continue; } @@ -715,6 +701,16 @@ struct TreeCreatorElectronMLDDA { continue; } + if (!isSelectedV0Leg(collision, pos) || !isSelectedV0Leg(collision, neg) || !isSelectedV0Leg(collision, bachelor)) { + continue; + } + + registry.fill(HIST("Cascade/hMassLambda"), cascade.mLambda()); + registry.fill(HIST("Cascade/hV0PCA"), cascade.dcaV0daughters()); + registry.fill(HIST("Cascade/hV0CosPA"), cascade.v0cosPA(collision.posX(), collision.posY(), collision.posZ())); + registry.fill(HIST("Cascade/hPCA"), cascade.dcacascdaughters()); // distance between bachelor and V0. + registry.fill(HIST("Cascade/hCosPA"), cascade.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + float length = std::sqrt(std::pow(cascade.x() - collision.posX(), 2) + std::pow(cascade.y() - collision.posY(), 2) + std::pow(cascade.z() - collision.posZ(), 2)); float mom = cascade.p(); float ctauXi = length / mom * o2::constants::physics::MassXiMinus; // 4.91 cm in PDG @@ -723,19 +719,17 @@ struct TreeCreatorElectronMLDDA { if (isPion(bachelor)) { registry.fill(HIST("Cascade/hMassXi"), cascade.mXi()); registry.fill(HIST("Cascade/hMassPt_Xi"), cascade.mXi(), cascade.pt()); - registry.fill(HIST("Cascade/hMassPt_Xi_bachelor"), cascade.mXi(), bachelor.p()); registry.fill(HIST("Cascade/hRxy_Xi"), cascade.mXi(), cascade.cascradius()); registry.fill(HIST("Cascade/hCTau_Xi"), cascade.mXi(), ctauXi); } if (!(cascadecuts.cfg_min_mass_Xi < cascade.mXi() && cascade.mXi() < cascadecuts.cfg_max_mass_Xi) && isKaon(bachelor)) { // reject Xi candidates registry.fill(HIST("Cascade/hMassOmega"), cascade.mOmega()); registry.fill(HIST("Cascade/hMassPt_Omega"), cascade.mOmega(), cascade.pt()); - registry.fill(HIST("Cascade/hMassPt_Omega_bachelor"), cascade.mOmega(), bachelor.p()); registry.fill(HIST("Cascade/hRxy_Omega"), cascade.mOmega(), cascade.cascradius()); registry.fill(HIST("Cascade/hCTau_Omega"), cascade.mOmega(), ctauOmega); if (cascadecuts.cfg_min_mass_Omega < cascade.mOmega() && cascade.mOmega() < cascadecuts.cfg_max_mass_Omega) { // select Omega candidates - registry.fill(HIST("V0/hTPCdEdx_P_Ka"), bachelor.p(), bachelor.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_Ka"), bachelor.p(), bachelor.beta()); + registry.fill(HIST("V0/hTPCdEdx_P_Ka"), bachelor.tpcInnerParam(), bachelor.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_Ka"), bachelor.tpcInnerParam(), bachelor.beta()); if (dist01(engine) < downscaling_kaon || bachelor.tpcInnerParam() > max_pin_for_downscaling_kaon) { fillTrackTable(collision, bachelor, static_cast(o2::aod::pwgem::dilepton::PID_Label::kKaon), static_cast(o2::aod::pwgem::dilepton::Track_Type::kPrimary), false); } @@ -743,21 +737,38 @@ struct TreeCreatorElectronMLDDA { } } // end of cascade loop + std::array ppos{0, 0, 0}; + std::array pneg{0, 0, 0}; + // for electron sample for validation auto posTracks_per_coll = posTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); auto negTracks_per_coll = negTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); for (const auto& [pos, neg] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { - if (!isSelectedTrack(collision, pos) || !isSelectedTrack(collision, neg)) { + if (!isElectron(pos) || !isElectron(neg)) { continue; } - if (!isElectron(pos) || !isElectron(neg)) { + if (!isSelectedTrack(collision, pos) || !isSelectedTrack(collision, neg)) { continue; } - ROOT::Math::PtEtaPhiMVector v1(neg.pt(), neg.eta(), neg.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(pos.pt(), pos.eta(), pos.phi(), o2::constants::physics::MassElectron); + auto posParCov = getTrackParCov(pos); + posParCov.setPID(pos.pidForTracking()); + mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); + mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, posParCov, 2.f, matCorr, &mDcaInfoCov); + getPxPyPz(posParCov, ppos); + + auto negParCov = getTrackParCov(neg); + negParCov.setPID(pos.pidForTracking()); + mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); + mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, negParCov, 2.f, matCorr, &mDcaInfoCov); + getPxPyPz(negParCov, pneg); + + ROOT::Math::PtEtaPhiMVector v1(negParCov.getPt(), negParCov.getEta(), negParCov.getPhi() > 0.f ? negParCov.getPhi() : negParCov.getPhi() + 2 * M_PI, o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v2(posParCov.getPt(), posParCov.getEta(), posParCov.getPhi() > 0.f ? posParCov.getPhi() : posParCov.getPhi() + 2 * M_PI, o2::constants::physics::MassElectron); ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(pos.px(), pos.py(), pos.pz(), neg.px(), neg.py(), neg.pz(), pos.sign(), neg.sign(), d_bz); + float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(ppos[0], ppos[1], ppos[2], pneg[0], pneg[1], pneg[2], pos.sign(), neg.sign(), d_bz); registry.fill(HIST("hMvsPhiV"), phiv, v12.M()); if ((dalitzcuts.cfg_min_mass_ee < v12.M() && v12.M() < dalitzcuts.cfg_max_mass_ee) && (dalitzcuts.cfg_min_phiv_ee < phiv && phiv < dalitzcuts.cfg_max_phiv_ee)) { // ee from pi0 dalitz decay is found. @@ -793,19 +804,19 @@ struct MLTrackQC { { {"hTPCdEdx_P_All", "TPC dE/dx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0.f, 5.f}, {200, 0, 200}}}}, {"hTOFbeta_P_All", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0.f, 5.f}, {220, 0.0, 1.1}}}}, - {"hITSClusterSize_P_All", "mean ITS cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {64, 0.0, 16}}}}, + {"hITSobClusterSize_P_All", "mean ITSob cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {150, 0.0, 15}}}}, {"hTPCdEdx_P_Electron", "TPC dE/dx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0.f, 5.f}, {200, 0, 200}}}}, {"hTOFbeta_P_Electron", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0.f, 5.f}, {220, 0.0, 1.1}}}}, - {"hITSClusterSize_P_Electron", "mean ITS cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {64, 0.0, 16}}}}, + {"hITSobClusterSize_P_Electron", "mean ITSob cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {150, 0.0, 15}}}}, {"hTPCdEdx_P_Pion", "TPC dE/dx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0.f, 5.f}, {200, 0, 200}}}}, {"hTOFbeta_P_Pion", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0.f, 5.f}, {220, 0.0, 1.1}}}}, - {"hITSClusterSize_P_Pion", "mean ITS cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {64, 0.0, 16}}}}, + {"hITSobClusterSize_P_Pion", "mean ITSob cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {150, 0.0, 15}}}}, {"hTPCdEdx_P_Kaon", "TPC dE/dx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0.f, 5.f}, {200, 0, 200}}}}, {"hTOFbeta_P_Kaon", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0.f, 5.f}, {220, 0.0, 1.1}}}}, - {"hITSClusterSize_P_Kaon", "mean ITS cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {64, 0.0, 16}}}}, + {"hITSobClusterSize_P_Kaon", "mean ITSob cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {150, 0.0, 15}}}}, {"hTPCdEdx_P_Proton", "TPC dE/dx vs. p;p^{ITS-TPC} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0.f, 5.f}, {200, 0, 200}}}}, {"hTOFbeta_P_Proton", "TOF beta vs. p;p^{ITS-TPC} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0.f, 5.f}, {220, 0.0, 1.1}}}}, - {"hITSClusterSize_P_Proton", "mean ITS cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {64, 0.0, 16}}}}, + {"hITSobClusterSize_P_Proton", "mean ITSob cluster size vs. p;p^{ITS-TPC} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {150, 0.0, 15}}}}, {"hTPCNsigmaEl_P", "TPC n#sigma_{e} vs. p;p^{ITS-TPC} (GeV/c);n #sigma_{e}^{TPC}", {HistType::kTH2F, {{500, 0.f, 5.f}, {100, -5, +5}}}}, {"hTPCNsigmaPi_P", "TPC n#sigma_{#pi} vs. p;p^{ITS-TPC} (GeV/c);n #sigma_{#pi}^{TPC}", {HistType::kTH2F, {{500, 0.f, 5.f}, {100, -5, +5}}}}, @@ -823,29 +834,29 @@ struct MLTrackQC { for (const auto& track : tracks) { registry.fill(HIST("hTPCdEdx_P_All"), track.p(), track.tpcSignal()); registry.fill(HIST("hTOFbeta_P_All"), track.p(), track.beta()); - registry.fill(HIST("hITSClusterSize_P_All"), track.p(), track.meanClusterSizeITS() * std::cos(std::atan(track.tgl()))); + registry.fill(HIST("hITSobClusterSize_P_All"), track.p(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); if (track.pidlabel() == static_cast(o2::aod::pwgem::dilepton::PID_Label::kElectron)) { registry.fill(HIST("hTPCdEdx_P_Electron"), track.p(), track.tpcSignal()); registry.fill(HIST("hTOFbeta_P_Electron"), track.p(), track.beta()); - registry.fill(HIST("hITSClusterSize_P_Electron"), track.p(), track.meanClusterSizeITS() * std::cos(std::atan(track.tgl()))); + registry.fill(HIST("hITSobClusterSize_P_Electron"), track.p(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); registry.fill(HIST("hTPCNsigmaEl_P"), track.p(), track.tpcNSigmaEl()); registry.fill(HIST("hTOFNsigmaEl_P"), track.p(), track.tofNSigmaEl()); } else if (track.pidlabel() == static_cast(o2::aod::pwgem::dilepton::PID_Label::kPion)) { registry.fill(HIST("hTPCdEdx_P_Pion"), track.p(), track.tpcSignal()); registry.fill(HIST("hTOFbeta_P_Pion"), track.p(), track.beta()); - registry.fill(HIST("hITSClusterSize_P_Pion"), track.p(), track.meanClusterSizeITS() * std::cos(std::atan(track.tgl()))); + registry.fill(HIST("hITSobClusterSize_P_Pion"), track.p(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); registry.fill(HIST("hTPCNsigmaPi_P"), track.p(), track.tpcNSigmaPi()); registry.fill(HIST("hTOFNsigmaPi_P"), track.p(), track.tofNSigmaPi()); } else if (track.pidlabel() == static_cast(o2::aod::pwgem::dilepton::PID_Label::kKaon)) { registry.fill(HIST("hTPCdEdx_P_Kaon"), track.p(), track.tpcSignal()); registry.fill(HIST("hTOFbeta_P_Kaon"), track.p(), track.beta()); - registry.fill(HIST("hITSClusterSize_P_Kaon"), track.p(), track.meanClusterSizeITS() * std::cos(std::atan(track.tgl()))); + registry.fill(HIST("hITSobClusterSize_P_Kaon"), track.p(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); registry.fill(HIST("hTPCNsigmaKa_P"), track.p(), track.tpcNSigmaKa()); registry.fill(HIST("hTOFNsigmaKa_P"), track.p(), track.tofNSigmaKa()); } else if (track.pidlabel() == static_cast(o2::aod::pwgem::dilepton::PID_Label::kProton)) { registry.fill(HIST("hTPCdEdx_P_Proton"), track.p(), track.tpcSignal()); registry.fill(HIST("hTOFbeta_P_Proton"), track.p(), track.beta()); - registry.fill(HIST("hITSClusterSize_P_Proton"), track.p(), track.meanClusterSizeITS() * std::cos(std::atan(track.tgl()))); + registry.fill(HIST("hITSobClusterSize_P_Proton"), track.p(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); registry.fill(HIST("hTPCNsigmaPr_P"), track.p(), track.tpcNSigmaPr()); registry.fill(HIST("hTOFNsigmaPr_P"), track.p(), track.tofNSigmaPr()); } diff --git a/PWGEM/Dilepton/Tasks/createResolutionMap.cxx b/PWGEM/Dilepton/Tasks/createResolutionMap.cxx index 8070c41ac61..8bbec973fb8 100644 --- a/PWGEM/Dilepton/Tasks/createResolutionMap.cxx +++ b/PWGEM/Dilepton/Tasks/createResolutionMap.cxx @@ -13,38 +13,41 @@ // Analysis task to produce resolution mapfor electrons/muons in dilepton analysis // Please write to: daiki.sekihata@cern.ch -#include -#include -#include -#include -#include -#include +#include "PWGEM/Dilepton/Utils/MCUtilities.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/ASoA.h" -#include "Framework/DataTypes.h" -#include "Framework/HistogramRegistry.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/EventSelection.h" +#include "Common/CCDB/RCTSelectionFlags.h" +#include "Common/Core/fwdtrackUtilities.h" +#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/CollisionAssociationTables.h" -#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" #include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPMagField.h" #include "DataFormatsCalibration/MeanVertexObject.h" -#include "TGeoGlobalMagField.h" -#include "Field/MagneticField.h" - +#include "DataFormatsParameters/GRPMagField.h" #include "DetectorsBase/Propagator.h" +#include "Field/MagneticField.h" +#include "Framework/ASoA.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/DataTypes.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" #include "GlobalTracking/MatchGlobalFwd.h" #include "MCHTracking/TrackExtrap.h" #include "MCHTracking/TrackParam.h" #include "ReconstructionDataFormats/TrackFwd.h" -#include "PWGEM/Dilepton/Utils/MCUtilities.h" + +#include "TGeoGlobalMagField.h" + +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -52,17 +55,9 @@ using namespace o2::framework::expressions; using namespace o2::aod; using namespace o2::soa; using namespace o2::aod::pwgem::dilepton::utils::mcutil; +using namespace o2::aod::fwdtrackutils; struct CreateResolutionMap { - // Index used to set different options for Muon propagation - enum class MuonExtrapolation : int { - kToVertex = 0, // propagtion to vertex by default - kToDCA = 1, - kToRabs = 2, - }; - using SMatrix55 = ROOT::Math::SMatrix>; - using SMatrix5 = ROOT::Math::SVector; - Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; @@ -74,12 +69,12 @@ struct CreateResolutionMap { Configurable cfgEventGeneratorType{"cfgEventGeneratorType", -1, "if positive, select event generator type. i.e. gap or signal"}; Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; - Configurable cfg_require_true_mc_collision_association{"cfg_require_true_mc_collision_association", true, "flag to require true mc collision association"}; + Configurable cfg_require_true_mc_collision_association{"cfg_require_true_mc_collision_association", false, "flag to require true mc collision association"}; Configurable cfg_reject_fake_match_its_tpc{"cfg_reject_fake_match_its_tpc", false, "flag to reject fake match between ITS-TPC"}; // Configurable cfg_reject_fake_match_its_tpc_tof{"cfg_reject_fake_match_its_tpc_tof", false, "flag to reject fake match between ITS-TPC-TOF"}; Configurable cfg_reject_fake_match_mft_mch{"cfg_reject_fake_match_mft_mch", false, "flag to reject fake match between MFT-MCH"}; - ConfigurableAxis ConfPtGenBins{"ConfPtGenBins", {VARIABLE_WIDTH, 0.00, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.10, 2.20, 2.30, 2.40, 2.50, 2.60, 2.70, 2.80, 2.90, 3.00, 3.10, 3.20, 3.30, 3.40, 3.50, 3.60, 3.70, 3.80, 3.90, 4.00, 4.10, 4.20, 4.30, 4.40, 4.50, 4.60, 4.70, 4.80, 4.90, 5.00, 5.50, 6.00, 6.50, 7.00, 7.50, 8.00, 8.50, 9.00, 9.50, 10.00, 11.00, 12.00, 13.00, 14.00, 15.00, 16.00, 17.00, 18.00, 19.00, 20.00}, "gen. pT bins for output histograms"}; + ConfigurableAxis ConfPtGenBins{"ConfPtGenBins", {VARIABLE_WIDTH, 0.00, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.10, 2.20, 2.30, 2.40, 2.50, 2.60, 2.70, 2.80, 2.90, 3.00, 3.10, 3.20, 3.30, 3.40, 3.50, 3.60, 3.70, 3.80, 3.90, 4.00, 4.10, 4.20, 4.30, 4.40, 4.50, 4.60, 4.70, 4.80, 4.90, 5.00, 5.50, 6.00, 6.50, 7.00, 7.50, 8.00, 8.50, 9.00, 9.50, 10.00, 11.00, 12.00, 13.00, 14.00, 15.00, 16.00, 17.00, 18.00, 19.00, 20.00}, "gen. pT bins for output histograms"}; ConfigurableAxis ConfCentBins{"ConfCentBins", {VARIABLE_WIDTH, 0, 10, 30, 50, 110}, "centrality (%) bins for output histograms"}; ConfigurableAxis ConfEtaCBGenBins{"ConfEtaCBGenBins", {30, -1.5, +1.5}, "gen. eta bins at midrapidity for output histograms"}; @@ -87,8 +82,18 @@ struct CreateResolutionMap { ConfigurableAxis ConfPhiGenBins{"ConfPhiGenBins", {72, 0, 2.f * M_PI}, "gen. eta bins at forward rapidity for output histograms"}; ConfigurableAxis ConfRelDeltaPtBins{"ConfRelDeltaPtBins", {200, -1.f, +1.f}, "rel. dpt for output histograms"}; - ConfigurableAxis ConfDeltaEtaBins{"ConfDeltaEtaBins", {100, -0.1f, +0.1f}, "deta bins for output histograms"}; - ConfigurableAxis ConfDeltaPhiBins{"ConfDeltaPhiBins", {100, -0.1f, +0.1f}, "dphi bins for output histograms"}; + ConfigurableAxis ConfDeltaEtaBins{"ConfDeltaEtaBins", {200, -0.2f, +0.2f}, "deta bins for output histograms"}; + ConfigurableAxis ConfDeltaPhiBins{"ConfDeltaPhiBins", {200, -0.2f, +0.2f}, "dphi bins for output histograms"}; + + Configurable cfgFillTHnSparse{"cfgFillTHnSparse", true, "fill THnSparse for output"}; + Configurable cfgFillTH2{"cfgFillTH2", false, "fill TH2 for output"}; + + Configurable cfgRequireGoodRCT{"cfgRequireGoodRCT", false, "require good detector flag in run condtion table"}; + Configurable cfgRCTLabelCB{"cfgRCTLabelCB", "CBT_hadronPID", "select 1 [CBT, CBT_hadron] see O2Physics/Common/CCDB/RCTSelectionFlags.h"}; + Configurable cfgRCTLabelFWDSA{"cfgRCTLabelFWDSA", "CBT_muon", "select 1 [CBT_muon] see O2Physics/Common/CCDB/RCTSelectionFlags.h"}; + Configurable cfgRCTLabelFWDGL{"cfgRCTLabelFWDGL", "CBT_muon_glo", "select 1 [CBT_muon_glo] see O2Physics/Common/CCDB/RCTSelectionFlags.h"}; + Configurable cfgCheckZDC{"cfgCheckZDC", false, "set ZDC flag for PbPb"}; + Configurable cfgTreatLimitedAcceptanceAsBad{"cfgTreatLimitedAcceptanceAsBad", false, "reject all events where the detectors relevant for the specified Runlist are flagged as LimitedAcceptance"}; struct : ConfigurableGroup { std::string prefix = "eventcut_group"; @@ -119,40 +124,55 @@ struct CreateResolutionMap { Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.01, "min pT for single track"}; Configurable cfg_min_eta_track{"cfg_min_eta_track", -1.5, "min eta for single track"}; Configurable cfg_max_eta_track{"cfg_max_eta_track", +1.5, "max eta for single track"}; - Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 90, "min ncluster tpc"}; + Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; Configurable cfg_min_ncluster_its{"cfg_min_ncluster_its", 5, "min ncluster its"}; Configurable cfg_min_ncluster_itsib{"cfg_min_ncluster_itsib", 1, "min ncluster itsib"}; - Configurable cfg_min_ncrossedrows{"cfg_min_ncrossedrows", 0, "min ncrossed rows"}; + Configurable cfg_min_ncrossedrows{"cfg_min_ncrossedrows", 80, "min ncrossed rows"}; Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; Configurable cfg_max_chi2its{"cfg_max_chi2its", 5.0, "max chi2/NclsITS"}; Configurable cfg_min_tpc_cr_findable_ratio{"cfg_min_tpc_cr_findable_ratio", 0.8, "min. TPC Ncr/Nf ratio"}; Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; - Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 0.2, "max dca XY for single track in cm"}; - Configurable cfg_max_dcaz{"cfg_max_dcaz", 0.2, "max dca Z for single track in cm"}; + Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 1.0, "max dca XY for single track in cm"}; + Configurable cfg_max_dcaz{"cfg_max_dcaz", 1.0, "max dca Z for single track in cm"}; Configurable cfg_require_itsib_1st{"cfg_require_itsib_1st", false, "flag to require ITS ib 1st hit"}; } electroncuts; struct : ConfigurableGroup { std::string prefix = "muoncut_group"; - Configurable cfg_track_type{"cfg_track_type", 3, "muon track type [0: MFT-MCH-MID, 3: MCH-MID]"}; Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.01, "min pT for single track"}; - Configurable cfg_min_eta_track{"cfg_min_eta_track", -5.5, "min eta for single track"}; - Configurable cfg_max_eta_track{"cfg_max_eta_track", -1.5, "max eta for single track"}; + Configurable cfg_min_eta_track_sa{"cfg_min_eta_track_sa", -5.5, "min eta for standalone muon track"}; + Configurable cfg_max_eta_track_sa{"cfg_max_eta_track_sa", -1.5, "max eta for standalone muon track"}; + Configurable cfg_min_eta_track_gl{"cfg_min_eta_track_gl", -5.5, "min eta for global muon track"}; + Configurable cfg_max_eta_track_gl{"cfg_max_eta_track_gl", -1.5, "max eta for global muon track"}; Configurable cfg_min_ncluster_mft{"cfg_min_ncluster_mft", 5, "min ncluster MFT"}; Configurable cfg_min_ncluster_mch{"cfg_min_ncluster_mch", 5, "min ncluster MCH"}; - Configurable cfg_max_chi2{"cfg_max_chi2", 1e+10, "max chi2/NclsTPC"}; - Configurable cfg_max_matching_chi2_mftmch{"cfg_max_matching_chi2_mftmch", 1e+10, "max chi2 for MFT-MCH matching"}; + Configurable cfg_max_chi2_sa{"cfg_max_chi2_sa", 1e+10, "max chi2 for standalone muon track"}; + Configurable cfg_max_chi2_gl{"cfg_max_chi2_gl", 40, "max chi2 for standalone muon track"}; + Configurable cfg_max_matching_chi2_mftmch{"cfg_max_matching_chi2_mftmch", 40, "max chi2 for MFT-MCH matching"}; Configurable cfg_max_matching_chi2_mchmid{"cfg_max_matching_chi2_mchmid", 1e+10, "max chi2 for MCH-MID matching"}; - Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 1e+10, "max dca XY for single track in cm"}; - Configurable cfg_min_rabs{"cfg_min_rabs", 17.6, "min Radius at the absorber end"}; - Configurable cfg_max_rabs{"cfg_max_rabs", 89.5, "max Radius at the absorber end"}; + Configurable cfg_max_dcaxy_gl{"cfg_max_dcaxy_gl", 0.1, "max dca XY for single track in cm"}; + Configurable cfg_min_rabs_sa{"cfg_min_rabs_sa", 17.6, "min Radius at the absorber end for standalone muon track"}; + Configurable cfg_max_rabs_sa{"cfg_max_rabs_sa", 89.5, "max Radius at the absorber end for standalone muon track"}; + Configurable cfg_min_rabs_gl{"cfg_min_rabs_gl", 27.6, "min Radius at the absorber end for global muon track"}; + Configurable cfg_max_rabs_gl{"cfg_max_rabs_gl", 89.5, "max Radius at the absorber end for global muon track"}; + Configurable cfg_mid_rabs{"cfg_mid_rabs", 26.5, "middle R at absorber end for pDCA cut"}; + Configurable cfg_max_pdca_forLargeR{"cfg_max_pdca_forLargeR", 324.f, "max. pDCA for large R at absorber end"}; + Configurable cfg_max_pdca_forSmallR{"cfg_max_pdca_forSmallR", 594.f, "max. pDCA for small R at absorber end"}; + Configurable cfg_max_reldpt{"cfg_max_reldpt", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_deta{"cfg_max_deta", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; + Configurable cfg_max_dphi{"cfg_max_dphi", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; + Configurable refitGlobalMuon{"refitGlobalMuon", true, "flag to refit global muon"}; + Configurable requireMFTHitMap{"requireMFTHitMap", false, "flag to require MFT hit map"}; + Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{4}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; } muoncuts; HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; + o2::aod::rctsel::RCTFlagsChecker rctCheckerCB; + o2::aod::rctsel::RCTFlagsChecker rctCheckerFWDSA; + o2::aod::rctsel::RCTFlagsChecker rctCheckerFWDGL; o2::ccdb::CcdbApi ccdbApi; Service ccdb; - o2::globaltracking::MatchGlobalFwd mMatching; int mRunNumber = 0; float d_bz; // o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; @@ -176,6 +196,9 @@ struct CreateResolutionMap { ccdb->setLocalObjectValidityChecking(); ccdb->setFatalWhenNull(false); ccdbApi.init(ccdburl); + rctCheckerCB.init(cfgRCTLabelCB.value, cfgCheckZDC.value, cfgTreatLimitedAcceptanceAsBad.value); + rctCheckerFWDSA.init(cfgRCTLabelFWDSA.value, cfgCheckZDC.value, cfgTreatLimitedAcceptanceAsBad.value); + rctCheckerFWDGL.init(cfgRCTLabelFWDGL.value, cfgCheckZDC.value, cfgTreatLimitedAcceptanceAsBad.value); mRunNumber = 0; d_bz = 0; @@ -190,21 +213,27 @@ struct CreateResolutionMap { const AxisSpec axis_dphi{ConfDeltaPhiBins, "#varphi_{l}^{gen} - #varphi_{l}^{rec} (rad.)"}; const AxisSpec axis_charge_gen{3, -1.5, +1.5, "true sign"}; - registry.add("Event/Electron/hImpPar_Centrality", "true imapact parameter vs. estimated centrality;impact parameter (fm);centrality (%)", kTH2F, {{200, 0, 20}, {110, 0, 110}}, true); - registry.add("Event/Muon/hImpPar_Centrality", "true imapact parameter vs. estimated centrality;impact parameter (fm);centrality (%)", kTH2F, {{200, 0, 20}, {110, 0, 110}}, true); - - registry.add("Electron/hPt", "rec. p_{T,l};p_{T,l} (GeV/c)", kTH1F, {{1000, 0, 10}}, false); - registry.add("Electron/hEtaPhi", "rec. #eta vs. #varphi;#varphi_{l} (rad.);#eta_{l}", kTH2F, {{90, 0, 2 * M_PI}, {80, -2, +2}}, false); - registry.add("Electron/Ptgen_RelDeltaPt", "resolution", kTH2F, {{axis_pt_gen}, {axis_dpt}}, true); - registry.add("Electron/Ptgen_DeltaEta", "resolution", kTH2F, {{axis_pt_gen}, {axis_deta}}, true); - registry.add("Electron/Ptgen_DeltaPhi_Pos", "resolution", kTH2F, {{axis_pt_gen}, {axis_dphi}}, true); - registry.add("Electron/Ptgen_DeltaPhi_Neg", "resolution", kTH2F, {{axis_pt_gen}, {axis_dphi}}, true); - registry.addClone("Electron/", "StandaloneMuon/"); - registry.addClone("Electron/", "GlobalMuon/"); - - registry.add("Electron/hs_reso", "8D resolution positive", kTHnSparseF, {axis_cent, axis_pt_gen, axis_eta_cb_gen, axis_phi_gen, axis_charge_gen, axis_dpt, axis_deta, axis_dphi}, true); - registry.add("StandaloneMuon/hs_reso", "8D resolution positive", kTHnSparseF, {axis_cent, axis_pt_gen, axis_eta_fwd_gen, axis_phi_gen, axis_charge_gen, axis_dpt, axis_deta, axis_dphi}, true); - registry.add("GlobalMuon/hs_reso", "8D resolution positive", kTHnSparseF, {axis_cent, axis_pt_gen, axis_eta_fwd_gen, axis_phi_gen, axis_charge_gen, axis_dpt, axis_deta, axis_dphi}, true); + // registry.add("Event/Electron/hImpPar_Centrality", "true imapact parameter vs. estimated centrality;impact parameter (fm);centrality (%)", kTH2F, {{200, 0, 20}, {110, 0, 110}}, true); + // registry.add("Event/Electron/hImpPar_Centrality", "true imapact parameter vs. estimated centrality;impact parameter (fm);centrality (%)", kTH2F, {{200, 0, 20}, {110, 0, 110}}, true); + if (doprocessGen) { + registry.add("Event/hGenID", "generator ID;generator ID;Number of mc collisions", kTH1F, {{7, -1.5, 5.5}}, true); + } + if (cfgFillTH2) { + registry.add("Electron/hPt", "rec. p_{T,l};p_{T,l} (GeV/c)", kTH1F, {{1000, 0, 10}}, false); + registry.add("Electron/hEtaPhi", "rec. #eta vs. #varphi;#varphi_{l} (rad.);#eta_{l}", kTH2F, {{90, 0, 2 * M_PI}, {100, -5, +5}}, false); + registry.add("Electron/Ptgen_RelDeltaPt", "resolution", kTH2F, {{axis_pt_gen}, {axis_dpt}}, true); + registry.add("Electron/Ptgen_DeltaEta", "resolution", kTH2F, {{axis_pt_gen}, {axis_deta}}, true); + registry.add("Electron/Ptgen_DeltaPhi_Pos", "resolution", kTH2F, {{axis_pt_gen}, {axis_dphi}}, true); + registry.add("Electron/Ptgen_DeltaPhi_Neg", "resolution", kTH2F, {{axis_pt_gen}, {axis_dphi}}, true); + registry.addClone("Electron/", "StandaloneMuon/"); + registry.addClone("Electron/", "GlobalMuon/"); + } + + if (cfgFillTHnSparse) { + registry.add("Electron/hs_reso", "8D resolution", kTHnSparseF, {axis_cent, axis_pt_gen, axis_eta_cb_gen, axis_phi_gen, axis_charge_gen, axis_dpt, axis_deta, axis_dphi}, true); + registry.add("StandaloneMuon/hs_reso", "8D resolution", kTHnSparseF, {axis_cent, axis_pt_gen, axis_eta_fwd_gen, axis_phi_gen, axis_charge_gen, axis_dpt, axis_deta, axis_dphi}, true); + registry.add("GlobalMuon/hs_reso", "8D resolution", kTHnSparseF, {axis_cent, axis_pt_gen, axis_eta_fwd_gen, axis_phi_gen, axis_charge_gen, axis_dpt, axis_deta, axis_dphi}, true); + } } void initCCDB(aod::BCsWithTimestamps::iterator const& bc) @@ -357,8 +386,8 @@ struct CreateResolutionMap { std::pair> itsRequirement_ibany = {1, {0, 1, 2}}; // any hits on 3 ITS ib layers. std::pair> itsRequirement_ib1st = {1, {0}}; // first hit on ITS ib layers. - template - bool isSelectedTrack(TCollision const& collision, TTrack const& track) + template + bool isSelectedTrack(TTrack const& track) { if (!track.hasITS() || !track.hasTPC()) { return false; @@ -406,80 +435,69 @@ struct CreateResolutionMap { return false; } - o2::dataformats::DCA mDcaInfoCov; - mDcaInfoCov.set(999, 999, 999, 999, 999); - auto track_par_cov_recalc = getTrackParCov(track); - track_par_cov_recalc.setPID(o2::track::PID::Electron); - mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); - mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, track_par_cov_recalc, 2.f, matCorr, &mDcaInfoCov); - float dcaXY = mDcaInfoCov.getY(); - float dcaZ = mDcaInfoCov.getZ(); + return true; + } - // LOGF(info, "collision.globalIndex() = %d, track.collisionId() = %d, track.pt() = %.16f, track_par_cov_recalc.getPt() = %.16f", collision.globalIndex(), track.collisionId(), track.pt(), track_par_cov_recalc.getPt()); + template + bool isSelectedTrackKine(TTrack const& track, const float pt, const float eta, const float dcaXY, const float dcaZ) + { + if (!track.hasITS() || !track.hasTPC()) { + return false; + } + + if (track.tpcChi2NCl() > electroncuts.cfg_max_chi2tpc) { + return false; + } + + if (track.itsChi2NCl() > electroncuts.cfg_max_chi2its) { + return false; + } + + if (track.itsNCls() < electroncuts.cfg_min_ncluster_its) { + return false; + } + if (track.itsNClsInnerBarrel() < electroncuts.cfg_min_ncluster_itsib) { + return false; + } + + auto hits = std::count_if(itsRequirement_ibany.second.begin(), itsRequirement_ibany.second.end(), [&](auto&& requiredLayer) { return track.itsClusterMap() & (1 << requiredLayer); }); + if (hits < itsRequirement_ibany.first) { + return false; + } + if (electroncuts.cfg_require_itsib_1st) { + auto hit_ib1st = std::count_if(itsRequirement_ib1st.second.begin(), itsRequirement_ib1st.second.end(), [&](auto&& requiredLayer) { return track.itsClusterMap() & (1 << requiredLayer); }); + if (hit_ib1st < itsRequirement_ib1st.first) { + return false; + } + } + + if (track.tpcNClsFound() < electroncuts.cfg_min_ncluster_tpc) { + return false; + } + + if (track.tpcNClsCrossedRows() < electroncuts.cfg_min_ncrossedrows) { + return false; + } + + if (track.tpcCrossedRowsOverFindableCls() < electroncuts.cfg_min_tpc_cr_findable_ratio) { + return false; + } + + if (track.tpcFractionSharedCls() > electroncuts.cfg_max_frac_shared_clusters_tpc) { + return false; + } if (std::fabs(dcaXY) > electroncuts.cfg_max_dcaxy || std::fabs(dcaZ) > electroncuts.cfg_max_dcaz) { return false; } - if (track_par_cov_recalc.getPt() < electroncuts.cfg_min_pt_track || std::fabs(track_par_cov_recalc.getEta()) > electroncuts.cfg_max_eta_track) { + if (pt < electroncuts.cfg_min_pt_track || std::fabs(eta) > electroncuts.cfg_max_eta_track) { return false; } return true; } - template - o2::dataformats::GlobalFwdTrack PropagateMuon(T const& muon, C const& collision, const CreateResolutionMap::MuonExtrapolation endPoint) - { - double chi2 = muon.chi2(); - SMatrix5 tpars(muon.x(), muon.y(), muon.phi(), muon.tgl(), muon.signed1Pt()); - std::vector v1{muon.cXX(), muon.cXY(), muon.cYY(), muon.cPhiX(), muon.cPhiY(), - muon.cPhiPhi(), muon.cTglX(), muon.cTglY(), muon.cTglPhi(), muon.cTglTgl(), - muon.c1PtX(), muon.c1PtY(), muon.c1PtPhi(), muon.c1PtTgl(), muon.c1Pt21Pt2()}; - SMatrix55 tcovs(v1.begin(), v1.end()); - o2::track::TrackParCovFwd fwdtrack{muon.z(), tpars, tcovs, chi2}; - o2::dataformats::GlobalFwdTrack propmuon; - - if (static_cast(muon.trackType()) > 2) { // MCH-MID or MCH standalone - o2::dataformats::GlobalFwdTrack track; - track.setParameters(tpars); - track.setZ(fwdtrack.getZ()); - track.setCovariances(tcovs); - auto mchTrack = mMatching.FwdtoMCH(track); - - if (endPoint == CreateResolutionMap::MuonExtrapolation::kToVertex) { - o2::mch::TrackExtrap::extrapToVertex(mchTrack, collision.posX(), collision.posY(), collision.posZ(), collision.covXX(), collision.covYY()); - } - if (endPoint == CreateResolutionMap::MuonExtrapolation::kToDCA) { - o2::mch::TrackExtrap::extrapToVertexWithoutBranson(mchTrack, collision.posZ()); - } - if (endPoint == CreateResolutionMap::MuonExtrapolation::kToRabs) { - o2::mch::TrackExtrap::extrapToZ(mchTrack, -505.); - } - - auto proptrack = mMatching.MCHtoFwd(mchTrack); - propmuon.setParameters(proptrack.getParameters()); - propmuon.setZ(proptrack.getZ()); - propmuon.setCovariances(proptrack.getCovariances()); - } else if (static_cast(muon.trackType()) < 2) { // MFT-MCH-MID - double centerMFT[3] = {0, 0, -61.4}; - o2::field::MagneticField* field = static_cast(TGeoGlobalMagField::Instance()->GetField()); - auto Bz = field->getBz(centerMFT); // Get field at centre of MFT - auto geoMan = o2::base::GeometryManager::meanMaterialBudget(muon.x(), muon.y(), muon.z(), collision.posX(), collision.posY(), collision.posZ()); - auto x2x0 = static_cast(geoMan.meanX2X0); - fwdtrack.propagateToVtxhelixWithMCS(collision.posZ(), {collision.posX(), collision.posY()}, {collision.covXX(), collision.covYY()}, Bz, x2x0); - propmuon.setParameters(fwdtrack.getParameters()); - propmuon.setZ(fwdtrack.getZ()); - propmuon.setCovariances(fwdtrack.getCovariances()); - } - - v1.clear(); - v1.shrink_to_fit(); - - return propmuon; - } - template void fillMuon(TCollision const& collision, TMuon const& muon, const float centrality) { @@ -494,78 +512,196 @@ struct CreateResolutionMap { return; } - o2::dataformats::GlobalFwdTrack propmuonAtPV = PropagateMuon(muon, collision, CreateResolutionMap::MuonExtrapolation::kToVertex); + if (muon.chi2MatchMCHMID() < 0.f) { // this should never happen. only for protection. + return; + } + o2::dataformats::GlobalFwdTrack propmuonAtPV = propagateMuon(muon, collision, propagationPoint::kToVertex); + o2::dataformats::GlobalFwdTrack propmuonAtDCA = propagateMuon(muon, collision, propagationPoint::kToDCA); + float pt = propmuonAtPV.getPt(); float eta = propmuonAtPV.getEta(); float phi = propmuonAtPV.getPhi(); + o2::math_utils::bringTo02Pi(phi); - if (pt < muoncuts.cfg_min_pt_track) { - return; - } + float dcaX = propmuonAtDCA.getX() - collision.posX(); + float dcaY = propmuonAtDCA.getY() - collision.posY(); + float dcaXY = std::sqrt(dcaX * dcaX + dcaY * dcaY); + + float rAtAbsorberEnd = muon.rAtAbsorberEnd(); // this works only for GlobalMuonTrack + float pDCA = muon.p() * dcaXY; + int nClustersMFT = 0; + float ptMatchedMCHMID = propmuonAtPV.getPt(); + float etaMatchedMCHMID = propmuonAtPV.getEta(); + float phiMatchedMCHMID = propmuonAtPV.getPhi(); + o2::math_utils::bringTo02Pi(phiMatchedMCHMID); + + if (muon.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) { + // mcparticle for global MFT-MCH-MID is identical to mcparticle of MCH-MID track. If not, mismatch. + const auto& mchtrack = muon.template matchMCHTrack_as(); // MCH-MID + const auto& mfttrack = muon.template matchMFTTrack_as(); // MFTsa + if (!mchtrack.has_mcParticle() || !mfttrack.has_mcParticle()) { + return; + } + auto mcparticle_MCHMID = mchtrack.template mcParticle_as(); + auto mcparticle_MFT = mfttrack.template mcParticle_as(); + if (mcparticle.globalIndex() != mcparticle_MCHMID.globalIndex()) { // this should not happen. this is only for protection. + return; + } + if (cfg_reject_fake_match_mft_mch && mcparticle.globalIndex() != mcparticle_MFT.globalIndex()) { // evaluate mismatch + return; + } - if (eta < muoncuts.cfg_min_eta_track || muoncuts.cfg_max_eta_track < eta) { - return; - } + o2::dataformats::GlobalFwdTrack propmuonAtPV_Matched = propagateMuon(mchtrack, collision, propagationPoint::kToVertex); + ptMatchedMCHMID = propmuonAtPV_Matched.getPt(); + etaMatchedMCHMID = propmuonAtPV_Matched.getEta(); + phiMatchedMCHMID = propmuonAtPV_Matched.getPhi(); + o2::math_utils::bringTo02Pi(phiMatchedMCHMID); + o2::dataformats::GlobalFwdTrack propmuonAtDCA_Matched = propagateMuon(mchtrack, collision, propagationPoint::kToDCA); + float dcaX_Matched = propmuonAtDCA_Matched.getX() - collision.posX(); + float dcaY_Matched = propmuonAtDCA_Matched.getY() - collision.posY(); + float dcaXY_Matched = std::sqrt(dcaX_Matched * dcaX_Matched + dcaY_Matched * dcaY_Matched); + pDCA = mchtrack.p() * dcaXY_Matched; + nClustersMFT = mfttrack.nClusters(); + + if (nClustersMFT < muoncuts.cfg_min_ncluster_mft) { + return; + } + if (muon.chi2MatchMCHMFT() > muoncuts.cfg_max_matching_chi2_mftmch) { + return; + } + if (muoncuts.refitGlobalMuon) { + eta = mfttrack.eta(); + phi = mfttrack.phi(); + o2::math_utils::bringTo02Pi(phi); + pt = propmuonAtPV_Matched.getP() * std::sin(2.f * std::atan(std::exp(-eta))); + } - o2::math_utils::bringTo02Pi(phi); - if (phi < 0.f || 2.f * M_PI < phi) { - return; - } + float dpt = (ptMatchedMCHMID - pt) / pt; + float deta = etaMatchedMCHMID - eta; + float dphi = phiMatchedMCHMID - phi; + o2::math_utils::bringToPMPi(dphi); + if (std::sqrt(std::pow(deta / muoncuts.cfg_max_deta, 2) + std::pow(dphi / muoncuts.cfg_max_dphi, 2)) > 1.f || std::fabs(dpt) > muoncuts.cfg_max_reldpt) { + return; + } - float rAtAbsorberEnd = muon.rAtAbsorberEnd(); - if (muon.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack)) { - o2::dataformats::GlobalFwdTrack propmuonAtRabs = PropagateMuon(muon, collision, CreateResolutionMap::MuonExtrapolation::kToRabs); + if (muoncuts.requireMFTHitMap) { + std::vector hasMFTs{hasMFT<0, 1>(mfttrack), hasMFT<2, 3>(mfttrack), hasMFT<4, 5>(mfttrack), hasMFT<6, 7>(mfttrack), hasMFT<8, 9>(mfttrack)}; + for (int i = 0; i < static_cast(muoncuts.requiredMFTDisks->size()); i++) { + if (!hasMFTs[muoncuts.requiredMFTDisks->at(i)]) { + return; + } + } + } + + } else if (muon.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { + o2::dataformats::GlobalFwdTrack propmuonAtRabs = propagateMuon(muon, collision, propagationPoint::kToRabs); // this is necessary only for MuonStandaloneTrack float xAbs = propmuonAtRabs.getX(); float yAbs = propmuonAtRabs.getY(); rAtAbsorberEnd = std::sqrt(xAbs * xAbs + yAbs * yAbs); // Redo propagation only for muon tracks // propagation of MFT tracks alredy done in reconstruction + } else { + return; } - if (rAtAbsorberEnd < muoncuts.cfg_min_rabs || muoncuts.cfg_max_rabs < rAtAbsorberEnd) { + if (muon.nClusters() < muoncuts.cfg_min_ncluster_mch) { return; } - if (rAtAbsorberEnd < 26.5) { - if (muon.pDca() > 594.f) { + if (!isSelectedMuon(pt, eta, rAtAbsorberEnd, pDCA, muon.chi2(), muon.trackType(), dcaXY)) { + return; + } + + if (muon.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack)) { + if (cfgRequireGoodRCT && !rctCheckerFWDSA.checkTable(collision)) { return; } - } else { - if (muon.pDca() > 324.f) { + if (cfgFillTHnSparse) { + registry.fill(HIST("StandaloneMuon/hs_reso"), centrality, mcparticle.pt(), mcparticle.eta(), mcparticle.phi(), -mcparticle.pdgCode() / 13, (mcparticle.pt() - pt) / mcparticle.pt(), mcparticle.eta() - eta, mcparticle.phi() - phi); + } + + if (cfgFillTH2) { + registry.fill(HIST("StandaloneMuon/hPt"), pt); + registry.fill(HIST("StandaloneMuon/hEtaPhi"), phi, eta); + registry.fill(HIST("StandaloneMuon/Ptgen_RelDeltaPt"), mcparticle.pt(), (mcparticle.pt() - pt) / mcparticle.pt()); + registry.fill(HIST("StandaloneMuon/Ptgen_DeltaEta"), mcparticle.pt(), mcparticle.eta() - eta); + if (mcparticle.pdgCode() == -13) { // positive muon + registry.fill(HIST("StandaloneMuon/Ptgen_DeltaPhi_Pos"), mcparticle.pt(), mcparticle.phi() - phi); + } else if (mcparticle.pdgCode() == 13) { // negative muon + registry.fill(HIST("StandaloneMuon/Ptgen_DeltaPhi_Neg"), mcparticle.pt(), mcparticle.phi() - phi); + } + } + } else if (muon.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack)) { + if (cfgRequireGoodRCT && !rctCheckerFWDGL.checkTable(collision)) { return; } + if (cfgFillTHnSparse) { + registry.fill(HIST("GlobalMuon/hs_reso"), centrality, mcparticle.pt(), mcparticle.eta(), mcparticle.phi(), -mcparticle.pdgCode() / 13, (mcparticle.pt() - pt) / mcparticle.pt(), mcparticle.eta() - eta, mcparticle.phi() - phi); + } + if (cfgFillTH2) { + registry.fill(HIST("GlobalMuon/hPt"), pt); + registry.fill(HIST("GlobalMuon/hEtaPhi"), phi, eta); + registry.fill(HIST("GlobalMuon/Ptgen_RelDeltaPt"), mcparticle.pt(), (mcparticle.pt() - pt) / mcparticle.pt()); + registry.fill(HIST("GlobalMuon/Ptgen_DeltaEta"), mcparticle.pt(), mcparticle.eta() - eta); + if (mcparticle.pdgCode() == -13) { // positive muon + registry.fill(HIST("GlobalMuon/Ptgen_DeltaPhi_Pos"), mcparticle.pt(), mcparticle.phi() - phi); + } else if (mcparticle.pdgCode() == 13) { // negative muon + registry.fill(HIST("GlobalMuon/Ptgen_DeltaPhi_Neg"), mcparticle.pt(), mcparticle.phi() - phi); + } + } } + return; + } - if (muon.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) && muon.chi2MatchMCHMFT() > muoncuts.cfg_max_matching_chi2_mftmch) { - return; + bool isSelectedMuon(const float pt, const float eta, const float rAtAbsorberEnd, const float pDCA, const float chi2, const uint8_t trackType, const float dcaXY) + { + if (pt < muoncuts.cfg_min_pt_track) { + return false; } - - if (cfg_reject_fake_match_mft_mch && muon.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) && o2::aod::pwgem::dilepton::utils::mcutil::hasFakeMatchMFTMCH(muon)) { - return; + if (rAtAbsorberEnd < muoncuts.cfg_min_rabs_sa || muoncuts.cfg_max_rabs_sa < rAtAbsorberEnd) { + return false; + } + if (rAtAbsorberEnd < muoncuts.cfg_mid_rabs ? pDCA > muoncuts.cfg_max_pdca_forSmallR : pDCA > muoncuts.cfg_max_pdca_forLargeR) { + return false; } - if (muon.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack)) { - registry.fill(HIST("StandaloneMuon/hPt"), pt); - registry.fill(HIST("StandaloneMuon/hEtaPhi"), phi, eta); - registry.fill(HIST("StandaloneMuon/hs_reso"), centrality, mcparticle.pt(), mcparticle.eta(), mcparticle.phi(), -mcparticle.pdgCode() / 13, (mcparticle.pt() - pt) / mcparticle.pt(), mcparticle.eta() - eta, mcparticle.phi() - phi); - registry.fill(HIST("StandaloneMuon/Ptgen_RelDeltaPt"), mcparticle.pt(), (mcparticle.pt() - pt) / mcparticle.pt()); - registry.fill(HIST("StandaloneMuon/Ptgen_DeltaEta"), mcparticle.pt(), mcparticle.eta() - eta); - if (mcparticle.pdgCode() == -13) { // positive muon - registry.fill(HIST("StandaloneMuon/Ptgen_DeltaPhi_Pos"), mcparticle.pt(), mcparticle.phi() - phi); - } else if (mcparticle.pdgCode() == 13) { // negative muon - registry.fill(HIST("StandaloneMuon/Ptgen_DeltaPhi_Neg"), mcparticle.pt(), mcparticle.phi() - phi); + if (trackType == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack)) { + if (eta < muoncuts.cfg_min_eta_track_gl || muoncuts.cfg_max_eta_track_gl < eta) { + return false; } - } else if (muon.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack)) { - registry.fill(HIST("GlobalMuon/hPt"), pt); - registry.fill(HIST("GlobalMuon/hEtaPhi"), phi, eta); - registry.fill(HIST("GlobalMuon/hs_reso"), centrality, mcparticle.pt(), mcparticle.eta(), mcparticle.phi(), -mcparticle.pdgCode() / 13, (mcparticle.pt() - pt) / mcparticle.pt(), mcparticle.eta() - eta, mcparticle.phi() - phi); - registry.fill(HIST("GlobalMuon/Ptgen_RelDeltaPt"), mcparticle.pt(), (mcparticle.pt() - pt) / mcparticle.pt()); - registry.fill(HIST("GlobalMuon/Ptgen_DeltaEta"), mcparticle.pt(), mcparticle.eta() - eta); - if (mcparticle.pdgCode() == -13) { // positive muon - registry.fill(HIST("GlobalMuon/Ptgen_DeltaPhi_Pos"), mcparticle.pt(), mcparticle.phi() - phi); - } else if (mcparticle.pdgCode() == 13) { // negative muon - registry.fill(HIST("GlobalMuon/Ptgen_DeltaPhi_Neg"), mcparticle.pt(), mcparticle.phi() - phi); + if (muoncuts.cfg_max_dcaxy_gl < dcaXY) { + return false; + } + if (chi2 < 0.f || muoncuts.cfg_max_chi2_gl < chi2) { + return false; + } + if (rAtAbsorberEnd < muoncuts.cfg_min_rabs_gl || muoncuts.cfg_max_rabs_gl < rAtAbsorberEnd) { + return false; + } + } else if (trackType == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack)) { + if (eta < muoncuts.cfg_min_eta_track_sa || muoncuts.cfg_max_eta_track_sa < eta) { + return false; + } + if (chi2 < 0.f || muoncuts.cfg_max_chi2_sa < chi2) { + return false; } + } else { + return false; } - return; + + return true; + } + + template + bool hasMFT(T const& track) + { + // logical-OR + uint64_t mftClusterSizesAndTrackFlags = track.mftClusterSizesAndTrackFlags(); + uint16_t clmap = 0; + for (unsigned int layer = begin; layer <= end; layer++) { + if ((mftClusterSizesAndTrackFlags >> (layer * 6)) & 0x3f) { + clmap |= (1 << layer); + } + } + return (clmap > 0); } SliceCache cache; @@ -575,15 +711,21 @@ struct CreateResolutionMap { using MyCollisions = Join; using MyCollision = MyCollisions::iterator; - using MyTracks = soa::Join; + using MyTracks = soa::Join; using MyTrack = MyTracks::iterator; using MyFwdTracks = soa::Join; using MyFwdTrack = MyFwdTracks::iterator; + using MyMFTTracks = soa::Join; + using MyMFTTrack = MyMFTTracks::iterator; + template void fillElectron(TCollision const& collision, TTrack const& track, const float centrality) { + if (cfgRequireGoodRCT && !rctCheckerCB.checkTable(collision)) { + return; + } auto mcparticle = track.template mcParticle_as(); if (std::abs(mcparticle.pdgCode()) != 11 || !(mcparticle.isPhysicalPrimary() || mcparticle.producedByGenerator())) { @@ -595,7 +737,8 @@ struct CreateResolutionMap { if (cfg_require_true_mc_collision_association && mcparticle.mcCollisionId() != collision.mcCollisionId()) { return; } - if (!isSelectedTrack(collision, track)) { + + if (!isSelectedTrack(track)) { return; } @@ -606,29 +749,37 @@ struct CreateResolutionMap { mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, track_par_cov_recalc, 2.f, matCorr, &mDcaInfoCov); - // float dcaXY = mDcaInfoCov.getY(); - // float dcaZ = mDcaInfoCov.getZ(); + float dcaXY = mDcaInfoCov.getY(); + float dcaZ = mDcaInfoCov.getZ(); float pt = track_par_cov_recalc.getPt(); float eta = track_par_cov_recalc.getEta(); float phi = track_par_cov_recalc.getPhi(); o2::math_utils::bringTo02Pi(phi); - registry.fill(HIST("Electron/hPt"), pt); - registry.fill(HIST("Electron/hEtaPhi"), phi, eta); - registry.fill(HIST("Electron/hs_reso"), centrality, mcparticle.pt(), mcparticle.eta(), mcparticle.phi(), -mcparticle.pdgCode() / 11, (mcparticle.pt() - pt) / mcparticle.pt(), mcparticle.eta() - eta, mcparticle.phi() - phi); - registry.fill(HIST("Electron/Ptgen_RelDeltaPt"), mcparticle.pt(), (mcparticle.pt() - pt) / mcparticle.pt()); - registry.fill(HIST("Electron/Ptgen_DeltaEta"), mcparticle.pt(), mcparticle.eta() - eta); - if (mcparticle.pdgCode() == -11) { // positron - registry.fill(HIST("Electron/Ptgen_DeltaPhi_Pos"), mcparticle.pt(), mcparticle.phi() - phi); - } else if (mcparticle.pdgCode() == 11) { // electron - registry.fill(HIST("Electron/Ptgen_DeltaPhi_Neg"), mcparticle.pt(), mcparticle.phi() - phi); + if (!isSelectedTrackKine(track, pt, eta, dcaXY, dcaZ)) { + return; + } + + if (cfgFillTHnSparse) { + registry.fill(HIST("Electron/hs_reso"), centrality, mcparticle.pt(), mcparticle.eta(), mcparticle.phi(), -mcparticle.pdgCode() / 11, (mcparticle.pt() - pt) / mcparticle.pt(), mcparticle.eta() - eta, mcparticle.phi() - phi); + } + if (cfgFillTH2) { + registry.fill(HIST("Electron/hPt"), pt); + registry.fill(HIST("Electron/hEtaPhi"), phi, eta); + registry.fill(HIST("Electron/Ptgen_RelDeltaPt"), mcparticle.pt(), (mcparticle.pt() - pt) / mcparticle.pt()); + registry.fill(HIST("Electron/Ptgen_DeltaEta"), mcparticle.pt(), mcparticle.eta() - eta); + if (mcparticle.pdgCode() == -11) { // positron + registry.fill(HIST("Electron/Ptgen_DeltaPhi_Pos"), mcparticle.pt(), mcparticle.phi() - phi); + } else if (mcparticle.pdgCode() == 11) { // electron + registry.fill(HIST("Electron/Ptgen_DeltaPhi_Neg"), mcparticle.pt(), mcparticle.phi() - phi); + } } } void processElectronSA(MyCollisions const& collisions, aod::BCsWithTimestamps const&, MyTracks const& tracks, aod::McCollisions const&, aod::McParticles const&) { - for (auto& collision : collisions) { + for (const auto& collision : collisions) { auto bc = collision.template foundBC_as(); initCCDB(bc); @@ -640,19 +791,22 @@ struct CreateResolutionMap { continue; } - auto mccollision = collision.template mcCollision_as(); - if (cfgEventGeneratorType >= 0 && mccollision.getSubGeneratorId() != cfgEventGeneratorType) { - continue; - } - float centrality = std::array{collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}[cfgCentEstimator]; - registry.fill(HIST("Event/Electron/hImpPar_Centrality"), mccollision.impactParameter(), centrality); + // auto mccollision = collision.template mcCollision_as(); + // registry.fill(HIST("Event/Electron/hImpPar_Centrality"), mccollision.impactParameter(), centrality); auto tracks_per_coll = tracks.sliceBy(perCollision_mid, collision.globalIndex()); - for (auto& track : tracks_per_coll) { + for (const auto& track : tracks_per_coll) { if (!track.has_mcParticle()) { continue; } + + auto mctrack = track.template mcParticle_as(); + auto mccollision_from_mctrack = mctrack.template mcCollision_as(); + if (cfgEventGeneratorType >= 0 && mccollision_from_mctrack.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } + fillElectron(collision, track, centrality); } // end of track loop } // end of collision loop @@ -662,7 +816,7 @@ struct CreateResolutionMap { Preslice trackIndicesPerCollision = aod::track_association::collisionId; void processElectronTTCA(MyCollisions const& collisions, aod::BCsWithTimestamps const&, MyTracks const&, aod::TrackAssoc const& trackIndices, aod::McCollisions const&, aod::McParticles const&) { - for (auto& collision : collisions) { + for (const auto& collision : collisions) { auto bc = collision.template foundBC_as(); initCCDB(bc); @@ -674,20 +828,21 @@ struct CreateResolutionMap { continue; } - auto mccollision = collision.template mcCollision_as(); - if (cfgEventGeneratorType >= 0 && mccollision.getSubGeneratorId() != cfgEventGeneratorType) { - continue; - } - float centrality = std::array{collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}[cfgCentEstimator]; - registry.fill(HIST("Event/Electron/hImpPar_Centrality"), mccollision.impactParameter(), centrality); + // auto mccollision = collision.template mcCollision_as(); + // registry.fill(HIST("Event/Electron/hImpPar_Centrality"), mccollision.impactParameter(), centrality); auto trackIdsThisCollision = trackIndices.sliceBy(trackIndicesPerCollision, collision.globalIndex()); - for (auto& trackId : trackIdsThisCollision) { + for (const auto& trackId : trackIdsThisCollision) { auto track = trackId.template track_as(); if (!track.has_mcParticle()) { continue; } + auto mctrack = track.template mcParticle_as(); + auto mccollision_from_mctrack = mctrack.template mcCollision_as(); + if (cfgEventGeneratorType >= 0 && mccollision_from_mctrack.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } fillElectron(collision, track, centrality); } // end of track loop } // end of collision loop @@ -697,9 +852,9 @@ struct CreateResolutionMap { Partition sa_muons = o2::aod::fwdtrack::trackType == uint8_t(o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack); // MCH-MID Partition global_muons = o2::aod::fwdtrack::trackType == uint8_t(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack); // MFT-MCH-MID - void processMuonSA(MyCollisions const& collisions, aod::BCsWithTimestamps const&, MyFwdTracks const&, aod::McCollisions const&, aod::McParticles const&) + void processMuonSA(MyCollisions const& collisions, aod::BCsWithTimestamps const&, MyFwdTracks const&, MyMFTTracks const&, aod::McCollisions const&, aod::McParticles const&) { - for (auto& collision : collisions) { + for (const auto& collision : collisions) { auto bc = collision.template foundBC_as(); initCCDB(bc); @@ -711,28 +866,35 @@ struct CreateResolutionMap { continue; } - auto mccollision = collision.template mcCollision_as(); - if (cfgEventGeneratorType >= 0 && mccollision.getSubGeneratorId() != cfgEventGeneratorType) { - continue; - } - float centrality = std::array{collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}[cfgCentEstimator]; - registry.fill(HIST("Event/Muon/hImpPar_Centrality"), mccollision.impactParameter(), centrality); + // auto mccollision = collision.template mcCollision_as(); + // registry.fill(HIST("Event/Muon/hImpPar_Centrality"), mccollision.impactParameter(), centrality); auto sa_muons_per_coll = sa_muons->sliceByCached(o2::aod::fwdtrack::collisionId, collision.globalIndex(), cache); auto global_muons_per_coll = global_muons->sliceByCached(o2::aod::fwdtrack::collisionId, collision.globalIndex(), cache); - for (auto& muon : sa_muons_per_coll) { + for (const auto& muon : sa_muons_per_coll) { if (!muon.has_mcParticle()) { continue; } + + auto mctrack = muon.template mcParticle_as(); + auto mccollision_from_mctrack = mctrack.template mcCollision_as(); + if (cfgEventGeneratorType >= 0 && mccollision_from_mctrack.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } fillMuon(collision, muon, centrality); } // end of standalone muon loop - for (auto& muon : global_muons_per_coll) { + for (const auto& muon : global_muons_per_coll) { if (!muon.has_mcParticle()) { continue; } + auto mctrack = muon.template mcParticle_as(); + auto mccollision_from_mctrack = mctrack.template mcCollision_as(); + if (cfgEventGeneratorType >= 0 && mccollision_from_mctrack.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } fillMuon(collision, muon, centrality); } // end of global muon loop @@ -741,9 +903,9 @@ struct CreateResolutionMap { PROCESS_SWITCH(CreateResolutionMap, processMuonSA, "create resolution map for muon at forward rapidity", true); Preslice fwdtrackIndicesPerCollision = aod::track_association::collisionId; - void processMuonTTCA(MyCollisions const& collisions, aod::BCsWithTimestamps const&, MyFwdTracks const&, aod::FwdTrackAssoc const& fwdtrackIndices, aod::McCollisions const&, aod::McParticles const&) + void processMuonTTCA(MyCollisions const& collisions, aod::BCsWithTimestamps const&, MyFwdTracks const&, MyMFTTracks const&, aod::FwdTrackAssoc const& fwdtrackIndices, aod::McCollisions const&, aod::McParticles const&) { - for (auto& collision : collisions) { + for (const auto& collision : collisions) { auto bc = collision.template foundBC_as(); initCCDB(bc); @@ -755,25 +917,34 @@ struct CreateResolutionMap { continue; } - auto mccollision = collision.template mcCollision_as(); - if (cfgEventGeneratorType >= 0 && mccollision.getSubGeneratorId() != cfgEventGeneratorType) { - continue; - } - float centrality = std::array{collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}[cfgCentEstimator]; - registry.fill(HIST("Event/Muon/hImpPar_Centrality"), mccollision.impactParameter(), centrality); + // auto mccollision = collision.template mcCollision_as(); + // registry.fill(HIST("Event/Muon/hImpPar_Centrality"), mccollision.impactParameter(), centrality); auto fwdtrackIdsThisCollision = fwdtrackIndices.sliceBy(fwdtrackIndicesPerCollision, collision.globalIndex()); - for (auto& fwdtrackId : fwdtrackIdsThisCollision) { + for (const auto& fwdtrackId : fwdtrackIdsThisCollision) { auto muon = fwdtrackId.template fwdtrack_as(); if (!muon.has_mcParticle()) { continue; } + auto mctrack = muon.template mcParticle_as(); + auto mccollision_from_mctrack = mctrack.template mcCollision_as(); + if (cfgEventGeneratorType >= 0 && mccollision_from_mctrack.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } fillMuon(collision, muon, centrality); } // end of fwdtrack loop } // end of collision loop } PROCESS_SWITCH(CreateResolutionMap, processMuonTTCA, "create resolution map for muon at forward rapidity", false); + + void processGen(aod::McCollisions const& mcCollisions) + { + for (const auto& mccollision : mcCollisions) { + registry.fill(HIST("Event/hGenID"), mccollision.getSubGeneratorId()); + } + } + PROCESS_SWITCH(CreateResolutionMap, processGen, "process generated info", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { diff --git a/PWGEM/Dilepton/Utils/EMTrackUtilities.h b/PWGEM/Dilepton/Utils/EMTrackUtilities.h index 6ac2275aee1..eb73226cd1e 100644 --- a/PWGEM/Dilepton/Utils/EMTrackUtilities.h +++ b/PWGEM/Dilepton/Utils/EMTrackUtilities.h @@ -65,12 +65,12 @@ float dcaZinSigma(T const& track) template float fwdDcaXYinSigma(T const& track) { - float cXX = track.cXXatDCA(); // in cm^2 - float cYY = track.cYYatDCA(); // in cm^2 - float cXY = track.cXYatDCA(); // in cm^2 - float dcaX = track.fwdDcaX(); // in cm - float dcaY = track.fwdDcaY(); // in cm - float det = cXX * cYY - cXY * cXY; // determinant + float cXX = track.cXXatDCA(); // in cm^2 + float cYY = track.cYYatDCA(); // in cm^2 + float cXY = track.cXYatDCA(); // in cm^2 + float dcaX = track.fwdDcaX(); // in cm + float dcaY = track.fwdDcaY(); // in cm + float det = cXX * cYY - cXY * cXY; // determinant if (det < 0) { return 999.f; @@ -88,6 +88,20 @@ float sigmaFwdDcaXY(T const& track) return dcaXY / fwdDcaXYinSigma(track); } //_______________________________________________________________________ +template +bool checkMFTHitMap(T const& track) +{ + // logical-OR + uint64_t mftClusterSizesAndTrackFlags = track.mftClusterSizesAndTrackFlags(); + uint16_t clmap = 0; + for (unsigned int layer = begin; layer <= end; layer++) { + if ((mftClusterSizesAndTrackFlags >> (layer * 6)) & 0x3f) { + clmap |= (1 << layer); + } + } + return (clmap > 0); +} +//_______________________________________________________________________ template bool isBestMatch(TTrack const& track, TCut const& cut, TTracks const& tracks) { diff --git a/PWGEM/PhotonMeson/TableProducer/createPCM.cxx b/PWGEM/PhotonMeson/TableProducer/createPCM.cxx index f8ba87d2cbc..4ca74633e1b 100644 --- a/PWGEM/PhotonMeson/TableProducer/createPCM.cxx +++ b/PWGEM/PhotonMeson/TableProducer/createPCM.cxx @@ -554,15 +554,8 @@ struct createPCM { PROCESS_SWITCH(createPCM, processTrkCollAsso, "create V0s with track-to-collision associator", false); }; -// Extends the v0data table with expression columns -struct v0Initializer { - Spawns v0cores; - void init(InitContext const&) {} -}; - WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc, TaskName{"v0-finder"}), - adaptAnalysisTask(cfgc, TaskName{"v0-initializer"})}; + adaptAnalysisTask(cfgc, TaskName{"v0-finder"})}; } diff --git a/PWGEM/Tasks/phosElId.cxx b/PWGEM/Tasks/phosElId.cxx index a3e401e2175..23e09da288f 100644 --- a/PWGEM/Tasks/phosElId.cxx +++ b/PWGEM/Tasks/phosElId.cxx @@ -81,6 +81,30 @@ enum CentEstimators { FV0A, FDDM, NTPV }; +bool testLambda(float pt, float l1, float l2, float cutThreshold, bool useNegativeCrossTerm) +{ + float l2Mean = 1.53126f + 9.50835e+06f / (1.f + 1.08728e+07f * pt + 1.73420e+06f * pt * pt); + float l1Mean = 1.12365f + 0.123770f * std::exp(-pt * 0.246551f) + 5.30000e-03f * pt; + float l2Sigma = 6.48260e-02f + 7.60261e+10f / (1.f + 1.53012e+11f * pt + 5.01265e+05f * pt * pt) + 9.00000e-03f * pt; + float l1Sigma = 4.44719e-04f + 6.99839e-01f / (1.f + 1.22497e+00f * pt + 6.78604e-07f * pt * pt) + 9.00000e-03f * pt; + float c = -0.35f - 0.550f * std::exp(-0.390730f * pt); + if (l1Sigma == 0.f || l2Sigma == 0.f) + return false; + + float term1 = 0.5f * (l1 - l1Mean) * (l1 - l1Mean) / (l1Sigma * l1Sigma); + float term2 = 0.5f * (l2 - l2Mean) * (l2 - l2Mean) / (l2Sigma * l2Sigma); + float crossTerm = 0.5f * c * (l1 - l1Mean) * (l2 - l2Mean) / (l1Sigma * l2Sigma); + + float rSquared; + if (useNegativeCrossTerm) { + rSquared = term1 + term2 - crossTerm; + } else { + rSquared = term1 + term2 + crossTerm; + } + + return rSquared < cutThreshold; +} + struct PhosElId { Produces phosMatch; @@ -89,7 +113,10 @@ struct PhosElId { using MyTracks = soa::Join; - Configurable isSel8{"isSel8", 1, "check if event is Single Event Latch-up 8"}; + Configurable isSel8{"isSel8", 1, "check if event is Single Event Latch-up 8"}, + mSwapM20M02ForTestLambda{"mSwapM20M02ForTestLambda", false, "Swap m20 and m02 arguments for testLambda (false for note's correct order, true for swapped/original incorrect order)"}, + mUseNegativeCrossTerm{"mUseNegativeCrossTerm", true, "Use negative sign for the cross-term in testLambda (true for analysis note version, false for old version)"}; + Configurable mColMaxZ{"mColMaxZ", 10.f, "maximum z accepted in analysis"}, mMinCluE{"mMinCluE", 0.3, "Minimum cluster energy for analysis"}, mMinCluTime{"minCluTime", -25.e-9, "Min. cluster time"}, @@ -125,7 +152,8 @@ struct PhosElId { TPCNSigmaKaMax{"TPCNSigmaKaMax", {4.f}, "max TPC nsigma kaon for exclusion"}, TOFNSigmaElMin{"TOFNSigmaElMin", {-3.f}, "min TOF nsigma e for inclusion"}, TOFNSigmaElMax{"TOFNSigmaElMax", {3.f}, "max TOF nsigma e for inclusion"}, - NsigmaTrackMatch{"NsigmaTrackMatch", {2.f}, "PHOS Track Matching Nsigma for inclusion"}; + NsigmaTrackMatch{"NsigmaTrackMatch", {2.f}, "PHOS Track Matching Nsigma for inclusion"}, + mShowerShapeCutValue{"mShowerShapeCutValue", 4.f, "Cut threshold for testLambda shower shape"}; Configurable mEvSelTrig{"mEvSelTrig", kTVXinPHOS, "Select events with this trigger"}, mAmountOfModules{"mAmountOfModules", 4, "amount of modules for PHOS"}, @@ -371,7 +399,11 @@ struct PhosElId { clu.time() > mMaxCluTime || clu.time() < mMinCluTime) continue; - bool isDispOK = testLambda(cluE, clu.m02(), clu.m20()); + bool isDispOK = false; + if (mSwapM20M02ForTestLambda) + isDispOK = testLambda(cluE, clu.m02(), clu.m20(), mShowerShapeCutValue, mUseNegativeCrossTerm); + else + isDispOK = testLambda(cluE, clu.m20(), clu.m02(), mShowerShapeCutValue, mUseNegativeCrossTerm); float posX = clu.x(), posZ = clu.z(), dX = trackX - posX, dZ = trackZ - posZ, Ep = cluE / trackMom; mHistManager.fill(HIST("coordinateMatching/hdZpmod"), dZ, trackPT, module); @@ -446,6 +478,11 @@ struct PhosElId { for (auto const& clu : clusters) { double cluE = clu.e(), cluTime = clu.time(); int mod = clu.mod(); + bool isDispOK = false; + if (mSwapM20M02ForTestLambda) + isDispOK = testLambda(cluE, clu.m02(), clu.m20(), mShowerShapeCutValue, mUseNegativeCrossTerm); + else + isDispOK = testLambda(cluE, clu.m20(), clu.m02(), mShowerShapeCutValue, mUseNegativeCrossTerm); if (cluE > mMinCluE) { mHistManager.fill(HIST("clusterSpectra/hCluE_mod_energy_cut"), cluE, mod); mHistManager.fill(HIST("clusterSpectra/hCluE_v_mod_v_time"), cluE, cluTime * 1e9, mod); @@ -455,7 +492,7 @@ struct PhosElId { mHistManager.fill(HIST("clusterSpectra/hCluE_mod_cell_cut"), cluE, mod); mHistManager.fill(HIST("coordinateMatching/hCluXZ_mod"), clu.x(), clu.z(), mod); mHistManager.fill(HIST("clusterSpectra/hCluE_ncells_mod"), cluE, clu.ncell(), mod); - if (testLambda(cluE, clu.m02(), clu.m20())) + if (isDispOK) mHistManager.fill(HIST("clusterSpectra/hCluE_mod_disp"), cluE, mod); } } @@ -482,7 +519,7 @@ struct PhosElId { mHistManager.fill(HIST("singleLoop/trackdist/clusterSpectra/hCluE_v_pt_Nsigma"), cluE, matchedTrack.pt(), mod); mHistManager.fill(HIST("singleLoop/trackdist/energyMomentumRatio/hEp_v_pt_Nsigma"), cluE / matchedTrack.p(), matchedTrack.pt(), mod); mHistManager.fill(HIST("singleLoop/trackdist/energyMomentumRatio/hEp_v_E_Nsigma"), cluE / matchedTrack.p(), cluE, mod); - if (testLambda(cluE, clu.m02(), clu.m20())) { + if (isDispOK) { mHistManager.fill(HIST("singleLoop/trackdist/clusterSpectra/hCluE_v_pt_Nsigma_disp"), cluE, matchedTrack.pt(), mod); mHistManager.fill(HIST("singleLoop/trackdist/energyMomentumRatio/hEp_v_pt_Nsigma_disp"), cluE / matchedTrack.p(), matchedTrack.pt(), mod); mHistManager.fill(HIST("singleLoop/trackdist/energyMomentumRatio/hEp_v_E_Nsigma_disp"), cluE / matchedTrack.p(), cluE, mod); @@ -505,13 +542,13 @@ struct PhosElId { isElectron = true; } if (isElectron) { - mHistManager.fill(HIST("singleLoop/trackdist/clusterSpectra/hCluE_v_pt_Nsigma_TPC"), cluE, matchedTrack.pt(), mod); - mHistManager.fill(HIST("singleLoop/trackdist/energyMomentumRatio/hEp_v_pt_Nsigma_TPC"), cluE / matchedTrack.p(), matchedTrack.pt(), mod); - mHistManager.fill(HIST("singleLoop/trackdist/energyMomentumRatio/hEp_v_E_Nsigma_TPC"), cluE / matchedTrack.p(), cluE, mod); - if (testLambda(cluE, clu.m02(), clu.m20())) { - mHistManager.fill(HIST("singleLoop/trackdist/clusterSpectra/hCluE_v_pt_Nsigma_disp_TPC"), cluE, matchedTrack.pt(), mod); - mHistManager.fill(HIST("singleLoop/trackdist/energyMomentumRatio/hEp_v_pt_Nsigma_disp_TPC"), cluE / matchedTrack.p(), matchedTrack.pt(), mod); - mHistManager.fill(HIST("singleLoop/trackdist/energyMomentumRatio/hEp_v_E_Nsigma_disp_TPC"), cluE / matchedTrack.p(), cluE, mod); + mHistManager.fill(HIST("singleLoop/trackdist/clusterSpectra/hCluE_v_pt_Nsigma_TPCel"), cluE, matchedTrack.pt(), mod); + mHistManager.fill(HIST("singleLoop/trackdist/energyMomentumRatio/hEp_v_pt_Nsigma_TPCel"), cluE / matchedTrack.p(), matchedTrack.pt(), mod); + mHistManager.fill(HIST("singleLoop/trackdist/energyMomentumRatio/hEp_v_E_Nsigma_TPCel"), cluE / matchedTrack.p(), cluE, mod); + if (isDispOK) { + mHistManager.fill(HIST("singleLoop/trackdist/clusterSpectra/hCluE_v_pt_Nsigma_disp_TPCel"), cluE, matchedTrack.pt(), mod); + mHistManager.fill(HIST("singleLoop/trackdist/energyMomentumRatio/hEp_v_pt_Nsigma_disp_TPCel"), cluE / matchedTrack.p(), matchedTrack.pt(), mod); + mHistManager.fill(HIST("singleLoop/trackdist/energyMomentumRatio/hEp_v_E_Nsigma_disp_TPCel"), cluE / matchedTrack.p(), cluE, mod); } } } // end of cluster loop @@ -593,21 +630,6 @@ struct PhosElId { trackZ = posL[1]; return true; } - //_____________________________________________________________________________ - bool testLambda(float pt, float l1, float l2) - { - // Parameterization for full dispersion - float l2Mean = 1.53126 + 9.50835e+06 / (1. + 1.08728e+07 * pt + 1.73420e+06 * pt * pt); - float l1Mean = 1.12365 + 0.123770 * std::exp(-pt * 0.246551) + 5.30000e-03 * pt; - float l2Sigma = 6.48260e-02 + 7.60261e+10 / (1. + 1.53012e+11 * pt + 5.01265e+05 * pt * pt) + 9.00000e-03 * pt; - float l1Sigma = 4.44719e-04 + 6.99839e-01 / (1. + 1.22497e+00 * pt + 6.78604e-07 * pt * pt) + 9.00000e-03 * pt; - float c = -0.35 - 0.550 * std::exp(-0.390730 * pt); - - return 0.5 * (l1 - l1Mean) * (l1 - l1Mean) / l1Sigma / l1Sigma + - 0.5 * (l2 - l2Mean) * (l2 - l2Mean) / l2Sigma / l2Sigma + - 0.5 * c * (l1 - l1Mean) * (l2 - l2Mean) / l1Sigma / l2Sigma < - 4.; - } }; struct MassSpectra { @@ -863,7 +885,10 @@ struct TpcElIdMassSpectrum { using MyTracks = soa::Join; - Configurable isSel8{"isSel8", 1, "check if event is Single Event Latch-up 8"}; + Configurable isSel8{"isSel8", 1, "check if event is Single Event Latch-up 8"}, + mSwapM20M02ForTestLambda{"mSwapM20M02ForTestLambda", false, "Swap m20 and m02 arguments for testLambda (false for note's correct order, true for swapped/original incorrect order)"}, + mUseNegativeCrossTerm{"mUseNegativeCrossTerm", true, "Use negative sign for the cross-term in testLambda (true for analysis note version, false for old version)"}; + Configurable mColMaxZ{"mColMaxZ", 10.f, "maximum z accepted in analysis"}, mMinCluE{"mMinCluE", 0.1, "Minimum cluster energy for photons in the analysis"}, mCutMIPCluE{"mCutMIPCluE", 0.3, "Min cluster energy to reject MIPs in the analysis"}, @@ -903,7 +928,8 @@ struct TpcElIdMassSpectrum { eeMassMin{"eeMassMin", {2.9f}, "J/psi(e+e-) Mass corridor lower limit (for Chic selection)"}, eeMassMax{"eeMassMax", {3.3f}, "J/psi(e+e-) Mass corridor upper limit (for Chic selection)"}, JpsiMass{"JpsiMass", {3.097f}, "J/psi Mass constant"}, - mMassSpectrumLowerCutoff{"mMassSpectrumLowerCutoff", {0.01f}, "Used to exclude 0+0 masses"}; + mMassSpectrumLowerCutoff{"mMassSpectrumLowerCutoff", {0.01f}, "Used to exclude 0+0 masses"}, + mShowerShapeCutValue{"mShowerShapeCutValue", 4.f, "Cut threshold for testLambda shower shape"}; Configurable mEvSelTrig{"mEvSelTrig", kTVXinPHOS, "Select events with this trigger"}, CentBinning{"CentBinning", 10, "Binning for centrality"}, @@ -1223,7 +1249,11 @@ struct TpcElIdMassSpectrum { continue; bool matchFlag = false; bool isJpsi = (pairMass > eeMassMin && pairMass < eeMassMax); - bool isDispOK = testLambda(cluE, gamma.m02(), gamma.m20()); + bool isDispOK = false; + if (mSwapM20M02ForTestLambda) + isDispOK = testLambda(cluE, gamma.m02(), gamma.m20(), mShowerShapeCutValue, mUseNegativeCrossTerm); + else + isDispOK = testLambda(cluE, gamma.m20(), gamma.m02(), mShowerShapeCutValue, mUseNegativeCrossTerm); for (auto const& match : matches) { if (gamma.index() == match.caloClusterId()) { matchFlag = true; @@ -1333,10 +1363,16 @@ struct TpcElIdMassSpectrum { for (auto const& gamma1 : clusters) { float cluE1 = gamma1.e(); - if (cluE1 < mMinCluE || cluE1 > mMaxCluE || gamma1.ncell() < mMinCluNcell || gamma1.time() > mMaxCluTime || gamma1.time() < mMinCluTime) + if (cluE1 < mMinCluE || gamma1.ncell() < mMinCluNcell || gamma1.time() > mMaxCluTime || gamma1.time() < mMinCluTime) continue; bool matchFlag1 = false; - if (!testLambda(cluE1, gamma1.m02(), gamma1.m20())) + + bool isDispOKClu1 = false; + if (mSwapM20M02ForTestLambda) + isDispOKClu1 = testLambda(cluE1, gamma1.m02(), gamma1.m20(), mShowerShapeCutValue, mUseNegativeCrossTerm); + else + isDispOKClu1 = testLambda(cluE1, gamma1.m20(), gamma1.m02(), mShowerShapeCutValue, mUseNegativeCrossTerm); + if (!isDispOKClu1) continue; for (auto const& match : matches) { if (gamma1.index() == match.caloClusterId()) { @@ -1348,9 +1384,14 @@ struct TpcElIdMassSpectrum { if (gamma1.index() >= gamma2.index()) continue; float cluE2 = gamma2.e(); - if (cluE2 < mMinCluE || cluE2 > mMaxCluE || gamma2.ncell() < mMinCluNcell || gamma2.time() > mMaxCluTime || gamma2.time() < mMinCluTime) + if (cluE2 < mMinCluE || gamma2.ncell() < mMinCluNcell || gamma2.time() > mMaxCluTime || gamma2.time() < mMinCluTime) continue; - if (!testLambda(cluE2, gamma2.m02(), gamma2.m20())) + bool isDispOKClu2 = false; + if (mSwapM20M02ForTestLambda) + isDispOKClu2 = testLambda(cluE2, gamma2.m02(), gamma2.m20(), mShowerShapeCutValue, mUseNegativeCrossTerm); + else + isDispOKClu2 = testLambda(cluE2, gamma2.m20(), gamma2.m02(), mShowerShapeCutValue, mUseNegativeCrossTerm); + if (!isDispOKClu2) continue; bool matchFlag2 = false; for (auto const& match : matches) { @@ -1395,21 +1436,6 @@ struct TpcElIdMassSpectrum { } } } - - bool testLambda(float pt, float l1, float l2) - { - float l2Mean = 1.53126f + 9.50835e+06f / (1.f + 1.08728e+07f * pt + 1.73420e+06f * pt * pt); - float l1Mean = 1.12365f + 0.123770f * std::exp(-pt * 0.246551f) + 5.30000e-03f * pt; - float l2Sigma = 6.48260e-02f + 7.60261e+10f / (1.f + 1.53012e+11f * pt + 5.01265e+05f * pt * pt) + 9.00000e-03f * pt; - float l1Sigma = 4.44719e-04f + 6.99839e-01f / (1.f + 1.22497e+00f * pt + 6.78604e-07f * pt * pt) + 9.00000e-03f * pt; - float c = -0.35f - 0.550f * std::exp(-0.390730f * pt); - if (l1Sigma == 0.f || l2Sigma == 0.f) - return false; - return 0.5f * (l1 - l1Mean) * (l1 - l1Mean) / (l1Sigma * l1Sigma) + - 0.5f * (l2 - l2Mean) * (l2 - l2Mean) / (l2Sigma * l2Sigma) + - 0.5f * c * (l1 - l1Mean) * (l2 - l2Mean) / (l1Sigma * l2Sigma) < - 4.f; - } }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/Core/CentralityEstimation.h b/PWGHF/Core/CentralityEstimation.h index 203cc4680c8..e575e11aa57 100644 --- a/PWGHF/Core/CentralityEstimation.h +++ b/PWGHF/Core/CentralityEstimation.h @@ -16,6 +16,8 @@ #ifndef PWGHF_CORE_CENTRALITYESTIMATION_H_ #define PWGHF_CORE_CENTRALITYESTIMATION_H_ +#include + namespace o2::hf_centrality { // centrality selection estimators @@ -30,32 +32,27 @@ enum CentralityEstimator { }; template -concept hasFT0ACent = requires(T collision) -{ +concept hasFT0ACent = requires(T collision) { collision.centFT0A(); }; template -concept hasFT0CCent = requires(T collision) -{ +concept hasFT0CCent = requires(T collision) { collision.centFT0C(); }; template -concept hasFT0MCent = requires(T collision) -{ +concept hasFT0MCent = requires(T collision) { collision.centFT0M(); }; template -concept hasFV0ACent = requires(T collision) -{ +concept hasFV0ACent = requires(T collision) { collision.centFV0A(); }; template -concept hasNTracksPVCent = requires(T collision) -{ +concept hasNTracksPVCent = requires(T collision) { collision.centNTPV(); }; diff --git a/PWGHF/Core/DecayChannels.h b/PWGHF/Core/DecayChannels.h new file mode 100644 index 00000000000..f56e8ce1005 --- /dev/null +++ b/PWGHF/Core/DecayChannels.h @@ -0,0 +1,180 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file DecayChannels.h +/// \brief Definitions of constants for MC flagging of HF decay channels. +/// \author Vít Kučera , Inha University +/// \note DecayChannelMain enums define unique combinations of the mother and the daughters for main channels. +/// \note DecayChannelResonant enums define unique combinations of the mother and the daughters for resonant channels. +/// \note Value 0 is reserved to indicate no match. +/// \note Daughter ordering convention: (charm|strange|π±|K±|π0), (baryon|meson), (+|−) + +#ifndef PWGHF_CORE_DECAYCHANNELS_H_ +#define PWGHF_CORE_DECAYCHANNELS_H_ + +#include + +namespace o2::hf_decay +{ + +// TODO +// - HF cascades (Λc+ → p K0short) +// - HF cascades to LF cascades (Ωc0/Ξc0 → Ξ+ π−, Ξc+ → Ξ+ π− π+) +// - Σc + +namespace hf_cand_2prong +{ +/// @brief 2-prong candidates: main channels +enum DecayChannelMain : int8_t { + // D0 + D0ToPiK = 1, // π+ K− + D0ToPiKPi0, // π+ K− π0 + D0ToPiPi, // π+ π− + D0ToPiPiPi0, // π+ π− π0 + D0ToKK, // K+ K− + // + LastChannelMain +}; +/// @brief 2-prong candidates: resonant channels +enum DecayChannelResonant : int8_t { + // D0 + D0ToRhoplusPi = 1, // ρ+ π− + D0ToRhoplusK, // ρ+ K− + D0ToKstar0Pi0, // anti-K*0 π0 + D0ToKstarPi, // K*− π+ + // + LastChannelResonant +}; +} // namespace hf_cand_2prong + +namespace hf_cand_3prong +{ +/// @brief 3-prong candidates: main channels +enum DecayChannelMain : int8_t { + // D+ + DplusToPiKPi = 1, // π+ K− π+ + DplusToPiKPiPi0, // π+ K− π+ π0 + DplusToPiPiPi, // π+ π− π+ + DplusToPiKK, // π+ K− K+ + // Ds+ + DsToPiKK, // π+ K− K+ + DsToPiKKPi0, // π+ K− K+ π0 + DsToPiPiK, // π+ π− K+ + DsToPiPiPi, // π+ π− π+ + DsToPiPiPiPi0, // π+ π− π+ π0 + // D*+ + DstarToPiKPi, // π+ K− π+ (from [(D0 → π+ K−) π+]) + // Λc+ + LcToPKPi, // p K− π+ + LcToPKPiPi0, // p K− π+ π0 + LcToPPiPi, // p π− π+ + LcToPKK, // p K− K+ + // Ξc+ + XicToPKPi, // p K− π+ + XicToPKK, // p K− K+ + XicToSPiPi, // Σ+ π− π+ + // + LastChannelMain +}; +/// @brief 3-prong candidates: resonant channels +enum DecayChannelResonant : int8_t { + // D+ + DplusToPhiPi = 1, // φ π+ + DplusToKstar0K, // anti-K*0 K+ + DplusToKstar1430_0K, // anti-K*0(1430) K+ + DplusToRho0Pi, // ρ0 π+ + DplusToF2_1270Pi, // f2(1270) π+ + // Ds+ + DsToPhiPi, // φ π+ + DsToPhiRhoplus, // φ ρ+ + DsToKstar0K, // anti-K*0 K+ + DsToKstar0Pi, // anti-K*0 π+ + DsToRho0Pi, // ρ0 π+ + DsToRho0K, // ρ0 K+ + DsToF2_1270Pi, // f2(1270) π+ + DsToF0_1370K, // f0(1370) K+ + DsToEtaPi, // η π+ + // Λc+ + LcToPKstar0, // p K*0(892) + LcToDeltaplusplusK, // Δ++ K− + LcToL1520Pi, // Λ(1520) π+ + // Ξc+ + XicToPKstar0, // p anti-K*0(892) + XicToPPhi, // p φ + // + LastChannelResonant +}; +} // namespace hf_cand_3prong + +namespace hf_cand_dstar +{ +/// @brief D*+ candidates: main channels +enum DecayChannelMain : int8_t { + // D*+ + DstarToPiKPi = 1, // π+ K− π+ (from [(D0 → π+ K−) π+]) + DstarToPiKPiPi0, // π+ K− π+ π0 (from [(D0 → π+ K− π0) π+] or [(D+ → π+ K− π+) π0]) + // + LastChannelMain +}; +} // namespace hf_cand_dstar + +namespace hf_cand_beauty +{ +/// @brief beauty candidates: main channels +enum DecayChannelMain : int8_t { + // B0 + B0ToDminusPi = 1, // D− π+ + B0ToDminusPiPi0, // D− π+ π0 + B0ToDminusPiGamma, // D− π+ γ0 + B0ToDminusK, // D− K+ + B0ToD0PiPi, // anti-D0 π+ π− + // Bs0 + BsToDsPi, // Ds− π+ + BsToDsPiPi0, // Ds− π+ π0 + BsToDsPiGamma, // Ds− π+ γ0 + BsToDsK, // Ds− K+ + // Λb0 + LbToLcPi, // Λc+ π− + LbToLcPiPi0, // Λc+ π− π0 + LbToLcPiGamma, // Λc+ π− γ0 + LbToLcK, // Λc+ K− + LbToLcKPi0, // Λc+ K− π0 + // B+ + BplusToD0Pi, // anti-D0 π+ + BplusToD0PiPi0, // anti-D0 π+ π0 + BplusToD0PiGamma, // anti-D0 π+ γ0 + BplusToD0K, // anti-D0 K+ + // + LastChannelMain +}; +/// @brief beauty candidates: resonant channels +enum DecayChannelResonant : int8_t { + // B0 + B0ToDminusRhoplus = 1, // D− ρ+ + B0ToDstarminusPi, // D*− π+ + // Bs0 + BsToDsRhoplus, // Ds− ρ+ + BsToDsstarPi, // Ds*− π+ + // Λb0 + LbToLcRhoplus, // Λc+ ρ− + LbToScPi, // Σc+ π− + LbToScK, // Σc+ K− + LbToSc0Pi0, // Σc0 π0 + // B+ + BplusToD0Rhoplus, // anti-D0 ρ+ + BplusToDstar0Pi, // anti-D*0 π+ + // + LastChannelResonant +}; +} // namespace hf_cand_beauty +} // namespace o2::hf_decay + +#endif // PWGHF_CORE_DECAYCHANNELS_H_ diff --git a/PWGHF/Core/HfHelper.h b/PWGHF/Core/HfHelper.h index 929fd2ba256..a2f87263e0f 100644 --- a/PWGHF/Core/HfHelper.h +++ b/PWGHF/Core/HfHelper.h @@ -17,18 +17,20 @@ #ifndef PWGHF_CORE_HFHELPER_H_ #define PWGHF_CORE_HFHELPER_H_ -#include - -#include "Math/GenVector/Boost.h" -#include "Math/Vector4D.h" -#include - -#include "CommonConstants/PhysicsConstants.h" +#include "PWGHF/Utils/utilsAnalysis.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelectorPID.h" -#include "PWGHF/Utils/utilsAnalysis.h" +#include +#include + +#include +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) + +#include +#include +#include class HfHelper { diff --git a/PWGHF/Core/HfMlResponseLcToPKPi.h b/PWGHF/Core/HfMlResponseLcToPKPi.h index 405e16cfc42..956fff55b28 100644 --- a/PWGHF/Core/HfMlResponseLcToPKPi.h +++ b/PWGHF/Core/HfMlResponseLcToPKPi.h @@ -16,9 +16,12 @@ #ifndef PWGHF_CORE_HFMLRESPONSELCTOPKPI_H_ #define PWGHF_CORE_HFMLRESPONSELCTOPKPI_H_ -#include - #include "PWGHF/Core/HfMlResponse.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" + +#include +#include +#include // Fill the map of available input features // the key is the feature's name (std::string) @@ -129,10 +132,22 @@ enum class InputFeaturesLcToPKPi : uint8_t { tofNSigmaPrExpPr0, tofNSigmaPiExpPi2, tpcTofNSigmaPrExpPr0, - tpcTofNSigmaPiExpPi2 + tpcTofNSigmaPiExpPi2, + kfChi2PrimProton, + kfChi2PrimKaon, + kfChi2PrimPion, + kfChi2GeoKaonPion, + kfChi2GeoProtonPion, + kfChi2GeoProtonKaon, + kfDcaKaonPion, + kfDcaProtonPion, + kfDcaProtonKaon, + kfChi2Geo, + kfChi2Topo, + kfDecayLengthNormalised }; -template +template class HfMlResponseLcToPKPi : public HfMlResponse { public: @@ -179,8 +194,6 @@ class HfMlResponseLcToPKPi : public HfMlResponse CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcNSigmaPr2, nSigTpcPr2); CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcNSigmaKa2, nSigTpcKa2); CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcNSigmaPi2, nSigTpcPi2); - // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong0, prong2, tpcNSigmaPrExpPr0, tpcNSigmaPr); - // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong2, prong0, tpcNSigmaPiExpPi2, tpcNSigmaPi); CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tpcNSigmaPrExpPr0, nSigTpcPr0, nSigTpcPr2); CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tpcNSigmaPiExpPi2, nSigTpcPi2, nSigTpcPi0); // TOF PID variables @@ -193,8 +206,6 @@ class HfMlResponseLcToPKPi : public HfMlResponse CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tofNSigmaPr2, nSigTofPr2); CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tofNSigmaKa2, nSigTofKa2); CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tofNSigmaPi2, nSigTofPi2); - // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong0, prong2, tofNSigmaPrExpPr0, tofNSigmaPr); - // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong2, prong0, tofNSigmaPiExpPi2, tofNSigmaPi); CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tofNSigmaPrExpPr0, nSigTofPr0, nSigTofPr2); CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tofNSigmaPiExpPi2, nSigTofPi2, nSigTofPi0); // Combined PID variables @@ -207,13 +218,29 @@ class HfMlResponseLcToPKPi : public HfMlResponse CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcTofNSigmaPr0, tpcTofNSigmaPr0); CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcTofNSigmaPr1, tpcTofNSigmaPr1); CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, tpcTofNSigmaPr2, tpcTofNSigmaPr2); - // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong0, prong2, tpcTofNSigmaPrExpPr0, tpcTofNSigmaPr); - // CHECK_AND_FILL_VEC_LCTOPKPI_OBJECT_SIGNED(prong2, prong0, tpcTofNSigmaPiExpPi2, tpcTofNSigmaPi); CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tpcTofNSigmaPrExpPr0, tpcTofNSigmaPr0, tpcTofNSigmaPr2); CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, tpcTofNSigmaPiExpPi2, tpcTofNSigmaPi2, tpcTofNSigmaPi0); } + if constexpr (reconstructionType == aod::hf_cand::VertexerType::KfParticle) { + switch (idx) { + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, kfChi2PrimProton, kfChi2PrimProng0, kfChi2PrimProng2); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, kfChi2PrimKaon, kfChi2PrimProng1); + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, kfChi2PrimPion, kfChi2PrimProng2, kfChi2PrimProng0); + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, kfChi2GeoKaonPion, kfChi2GeoProng1Prong2, kfChi2GeoProng0Prong1); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, kfChi2GeoProtonPion, kfChi2GeoProng0Prong2); + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, kfChi2GeoProtonKaon, kfChi2GeoProng0Prong1, kfChi2GeoProng1Prong2); + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, kfDcaKaonPion, kfDcaProng1Prong2, kfDcaProng0Prong1); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, kfDcaProtonPion, kfDcaProng0Prong2); + CHECK_AND_FILL_VEC_LCTOPKPI_SIGNED(candidate, kfDcaProtonKaon, kfDcaProng0Prong1, kfDcaProng1Prong2); + CHECK_AND_FILL_VEC_LCTOPKPI(kfChi2Geo); + CHECK_AND_FILL_VEC_LCTOPKPI(kfChi2Topo); + case static_cast(InputFeaturesLcToPKPi::kfDecayLengthNormalised): { + inputFeatures.emplace_back(candidate.kfDecayLength() / candidate.kfDecayLengthError()); + break; + } + } + } } - return inputFeatures; } @@ -273,6 +300,23 @@ class HfMlResponseLcToPKPi : public HfMlResponse FILL_MAP_LCTOPKPI(tpcTofNSigmaPr2), FILL_MAP_LCTOPKPI(tpcTofNSigmaPrExpPr0), FILL_MAP_LCTOPKPI(tpcTofNSigmaPiExpPi2)}; + if constexpr (reconstructionType == aod::hf_cand::VertexerType::KfParticle) { + std::map mapKfFeatures{ + // KFParticle variables + FILL_MAP_LCTOPKPI(kfChi2PrimProton), + FILL_MAP_LCTOPKPI(kfChi2PrimKaon), + FILL_MAP_LCTOPKPI(kfChi2PrimPion), + FILL_MAP_LCTOPKPI(kfChi2GeoKaonPion), + FILL_MAP_LCTOPKPI(kfChi2GeoProtonPion), + FILL_MAP_LCTOPKPI(kfChi2GeoProtonKaon), + FILL_MAP_LCTOPKPI(kfDcaKaonPion), + FILL_MAP_LCTOPKPI(kfDcaProtonPion), + FILL_MAP_LCTOPKPI(kfDcaProtonKaon), + FILL_MAP_LCTOPKPI(kfChi2Geo), + FILL_MAP_LCTOPKPI(kfChi2Topo), + FILL_MAP_LCTOPKPI(kfDecayLengthNormalised)}; + MlResponse::mAvailableInputFeatures.insert(mapKfFeatures.begin(), mapKfFeatures.end()); + } } }; diff --git a/PWGHF/Core/HfMlResponseXic0ToXiPiKf.h b/PWGHF/Core/HfMlResponseXic0ToXiPiKf.h new file mode 100644 index 00000000000..3458b503783 --- /dev/null +++ b/PWGHF/Core/HfMlResponseXic0ToXiPiKf.h @@ -0,0 +1,144 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file HfMlResponseXic0ToXiPiKf.h +/// \brief Class to compute the ML response for Ξc^0 → Ξ∓ π± kf analysis selections +/// \author Tao Fang , Central China Normal University + +#ifndef PWGHF_CORE_HFMLRESPONSEXIC0TOXIPIKF_H_ +#define PWGHF_CORE_HFMLRESPONSEXIC0TOXIPIKF_H_ + +#include "PWGHF/Core/HfMlResponse.h" + +#include + +// Fill the map of available input features +// the key is the feature's name (std::string) +// the value is the corresponding value in EnumInputFeatures +#define FILL_MAP_XIC0TOXIPIKF(FEATURE) \ + { \ + #FEATURE, static_cast(InputFeaturesXic0ToXiPiKf::FEATURE) \ + } + +// Check if the index of mCachedIndices (index associated to a FEATURE) +// matches the entry in EnumInputFeatures associated to this FEATURE +// if so, the inputFeatures vector is filled with the FEATURE's value +// by calling the corresponding GETTER from OBJECT +#define CHECK_AND_FILL_VEC_XIC0TOXIPIKF_FULL(OBJECT, FEATURE, GETTER) \ + case static_cast(InputFeaturesXic0ToXiPiKf::FEATURE): { \ + inputFeatures.emplace_back(OBJECT.GETTER()); \ + break; \ + } + +// where OBJECT is named candidate and FEATURE = GETTER +#define CHECK_AND_FILL_VEC_XIC0TOXIPIKF(GETTER) \ + case static_cast(InputFeaturesXic0ToXiPiKf::GETTER): { \ + inputFeatures.emplace_back(candidate.GETTER()); \ + break; \ + } + +namespace o2::analysis +{ + +enum class InputFeaturesXic0ToXiPiKf : uint8_t { + tpcNSigmaPiFromLambda, + tpcNSigmaPiFromCasc, + tpcNSigmaPiFromCharmBaryon, + dcaCascDau, + dcaCharmBaryonDau, + kfDcaXYPiFromXic, + kfDcaXYCascToPv, + cascChi2OverNdf, + xicChi2OverNdf, + cascldl, + chi2TopoCascToPv, + chi2TopoCascToXic, + cosPaCascToXic, + decayLenXYCasc +}; + +template +class HfMlResponseXic0ToXiPiKf : public HfMlResponse +{ + public: + /// Default constructor + HfMlResponseXic0ToXiPiKf() = default; + /// Default destructor + virtual ~HfMlResponseXic0ToXiPiKf() = default; + + /// Method to get the input features vector needed for ML inference + /// \param candidate is the Xic0 candidate + /// \return inputFeatures vector + template + // std::vector getInputFeatures(T1 const& candidate) + std::vector getInputFeatures(T1 const& candidate, T2 const& lamProngPi, T2 const& cascProngPi, T3 const& charmBaryonProngPi) + { + std::vector inputFeatures; + + for (const auto& idx : MlResponse::mCachedIndices) { + switch (idx) { + // PID variables + CHECK_AND_FILL_VEC_XIC0TOXIPIKF_FULL(lamProngPi, tpcNSigmaPiFromLambda, tpcNSigmaPi); + CHECK_AND_FILL_VEC_XIC0TOXIPIKF_FULL(cascProngPi, tpcNSigmaPiFromCasc, tpcNSigmaPi); + CHECK_AND_FILL_VEC_XIC0TOXIPIKF_FULL(charmBaryonProngPi, tpcNSigmaPiFromCharmBaryon, tpcNSigmaPi); + // DCA + CHECK_AND_FILL_VEC_XIC0TOXIPIKF(dcaCascDau); + CHECK_AND_FILL_VEC_XIC0TOXIPIKF(dcaCharmBaryonDau); + CHECK_AND_FILL_VEC_XIC0TOXIPIKF(kfDcaXYPiFromXic); + CHECK_AND_FILL_VEC_XIC0TOXIPIKF(kfDcaXYCascToPv); + // Chi2Geo + CHECK_AND_FILL_VEC_XIC0TOXIPIKF(cascChi2OverNdf); + CHECK_AND_FILL_VEC_XIC0TOXIPIKF(xicChi2OverNdf); + // ldl + CHECK_AND_FILL_VEC_XIC0TOXIPIKF(cascldl); + // Chi2Topo + CHECK_AND_FILL_VEC_XIC0TOXIPIKF(chi2TopoCascToPv); + CHECK_AND_FILL_VEC_XIC0TOXIPIKF(chi2TopoCascToXic); + // CosPa + CHECK_AND_FILL_VEC_XIC0TOXIPIKF(cosPaCascToXic); + // Decay length + CHECK_AND_FILL_VEC_XIC0TOXIPIKF(decayLenXYCasc); + } + } + + return inputFeatures; + } + + protected: + /// Method to fill the map of available input features + void setAvailableInputFeatures() + { + MlResponse::mAvailableInputFeatures = { + FILL_MAP_XIC0TOXIPIKF(tpcNSigmaPiFromLambda), + FILL_MAP_XIC0TOXIPIKF(tpcNSigmaPiFromCasc), + FILL_MAP_XIC0TOXIPIKF(tpcNSigmaPiFromCharmBaryon), + FILL_MAP_XIC0TOXIPIKF(dcaCascDau), + FILL_MAP_XIC0TOXIPIKF(dcaCharmBaryonDau), + FILL_MAP_XIC0TOXIPIKF(kfDcaXYPiFromXic), + FILL_MAP_XIC0TOXIPIKF(kfDcaXYCascToPv), + FILL_MAP_XIC0TOXIPIKF(cascChi2OverNdf), + FILL_MAP_XIC0TOXIPIKF(xicChi2OverNdf), + FILL_MAP_XIC0TOXIPIKF(cascldl), + FILL_MAP_XIC0TOXIPIKF(chi2TopoCascToPv), + FILL_MAP_XIC0TOXIPIKF(chi2TopoCascToXic), + FILL_MAP_XIC0TOXIPIKF(cosPaCascToXic), + FILL_MAP_XIC0TOXIPIKF(decayLenXYCasc), + }; + } +}; + +} // namespace o2::analysis + +#undef FILL_MAP_XIC0TOXIPIKF +#undef CHECK_AND_FILL_VEC_XIC0TOXIPIKF_FULL +#undef CHECK_AND_FILL_VEC_XIC0TOXIPIKF + +#endif // PWGHF_CORE_HFMLRESPONSEXIC0TOXIPIKF_H_ diff --git a/PWGHF/D2H/DataModel/ReducedDataModel.h b/PWGHF/D2H/DataModel/ReducedDataModel.h index 79f5c804dde..673d6f481ca 100644 --- a/PWGHF/D2H/DataModel/ReducedDataModel.h +++ b/PWGHF/D2H/DataModel/ReducedDataModel.h @@ -23,16 +23,22 @@ #ifndef PWGHF_D2H_DATAMODEL_REDUCEDDATAMODEL_H_ #define PWGHF_D2H_DATAMODEL_REDUCEDDATAMODEL_H_ -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoA.h" -#include "ReconstructionDataFormats/Track.h" -#include "ReconstructionDataFormats/Vertex.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/Utils/utilsPid.h" #include "Common/Core/RecoDecay.h" -#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/Qvectors.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/Utils/utilsPid.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/ASoA.h" +#include "Framework/AnalysisDataModel.h" + +#include +#include namespace o2 { @@ -506,11 +512,11 @@ using HfRedCandBs = soa::Join; namespace hf_cand_lb_reduced { -DECLARE_SOA_INDEX_COLUMN_FULL(Prong0, prong0, int, HfRed3Prongs, "_0"); //! Prong0 index -DECLARE_SOA_INDEX_COLUMN_FULL(Prong1, prong1, int, HfRedTrackBases, "_1"); //! Prong1 index -DECLARE_SOA_COLUMN(Prong0MlScoreBkg, prong0MlScoreBkg, float); //! Bkg ML score of the Lc daughter -DECLARE_SOA_COLUMN(Prong0MlScorePrompt, prong0MlScorePrompt, float); //! Prompt ML score of the Lc daughter -DECLARE_SOA_COLUMN(Prong0MlScoreNonprompt, prong0MlScoreNonprompt, float); //! Nonprompt ML score of the Lc daughter +DECLARE_SOA_INDEX_COLUMN_FULL(Prong0, prong0, int, HfRed3Prongs, "_0"); //! Prong0 index +DECLARE_SOA_INDEX_COLUMN_FULL(Prong1, prong1, int, HfRedTrackBases, "_1"); //! Prong1 index +DECLARE_SOA_COLUMN(Prong0MlScoreBkg, prong0MlScoreBkg, float); //! Bkg ML score of the Lc daughter +DECLARE_SOA_COLUMN(Prong0MlScorePrompt, prong0MlScorePrompt, float); //! Prompt ML score of the Lc daughter +DECLARE_SOA_COLUMN(Prong0MlScoreNonprompt, prong0MlScoreNonprompt, float); //! Nonprompt ML score of the Lc daughter } // namespace hf_cand_lb_reduced DECLARE_SOA_TABLE(HfRedLbProngs, "AOD", "HFREDLBPRONG", //! Table with Lb daughter indices @@ -871,6 +877,21 @@ DECLARE_SOA_DYNAMIC_COLUMN(PVector, pVector, [](float px0, float py0, float pz0, float px1, float py1, float pz1, float px2, float py2, float pz2) -> std::array { return std::array{px0 + px1 + px2, py0 + py1 + py2, pz0 + pz1 + pz2}; }); } // namespace hf_reso_3_prong +namespace hf_reso_2_prong +{ +DECLARE_SOA_COLUMN(SelFlagD0, selFlagD0, uint8_t); //! Integer with D0 selection flag: 1 = selected as D0, 2 = selected as D0bar, 3 = selected as D0 and D0bar +DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! + [](float pxProng0, float pxProng1) -> float { return 1.f * pxProng0 + 1.f * pxProng1; }); +DECLARE_SOA_DYNAMIC_COLUMN(Py, py, //! + [](float pyProng0, float pyProng1) -> float { return 1.f * pyProng0 + 1.f * pyProng1; }); +DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, //! + [](float pzProng0, float pzProng1) -> float { return 1.f * pzProng0 + 1.f * pzProng1; }); +DECLARE_SOA_DYNAMIC_COLUMN(PVector, pVector, + [](float pxProng0, float pyProng0, float pzProng0, float pxProng1, float pyProng1, float pzProng1) -> std::array { return std::array{pxProng0 + pxProng1, pyProng0 + pyProng1, pzProng0 + pzProng1}; }); +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! + [](float pxProng0, float pxProng1, float pyProng0, float pyProng1) -> float { return RecoDecay::pt((1.f * pxProng0 + 1.f * pxProng1), (1.f * pyProng0 + 1.f * pyProng1)); }); +} // namespace hf_reso_2_prong + namespace hf_reso_v0 { DECLARE_SOA_COLUMN(Cpa, cpa, float); //! Cosine of Pointing Angle of V0 candidate @@ -988,6 +1009,31 @@ DECLARE_SOA_TABLE(HfRed3PrNoTrks, "AOD", "HFRED3PRNOTRK", //! Table with 3 prong hf_cand::PVectorProng2, hf_reso_3_prong::PVector); +DECLARE_SOA_TABLE(HfRed2PrNoTrks, "AOD", "HFRED2PRNOTRK", //! Table with 2 prong candidate information for resonances reduced workflow + o2::soa::Index<>, + // Indices + hf_track_index_reduced::Prong0Id, hf_track_index_reduced::Prong1Id, + hf_track_index_reduced::HfRedCollisionId, + // Static + hf_cand::XSecondaryVertex, hf_cand::YSecondaryVertex, hf_cand::ZSecondaryVertex, + hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PzProng0, + hf_cand::PxProng1, hf_cand::PyProng1, hf_cand::PzProng1, + hf_track_vars_reduced::ItsNClsProngMin, hf_track_vars_reduced::TpcNClsCrossedRowsProngMin, hf_track_vars_reduced::TpcChi2NClProngMax, + hf_reso_2_prong::SelFlagD0, + // Dynamic + hf_reso_2_prong::Px, + hf_reso_2_prong::Py, + hf_reso_2_prong::Pz, + hf_track_vars_reduced::PtProng0, + hf_track_vars_reduced::PtProng1, + hf_track_vars_reduced::EtaProng0, + hf_track_vars_reduced::EtaProng1, + hf_reso_2_prong::PVector, + hf_reso_2_prong::Pt, + // InvMasses + hf_cand_dstar::InvMassD0, + hf_cand_dstar::InvMassD0Bar); + namespace hf_reso_cand_reduced { DECLARE_SOA_COLUMN(InvMass, invMass, float); //! Invariant mass in GeV/c2 @@ -1006,7 +1052,7 @@ DECLARE_SOA_COLUMN(FlagMcMatchGen, flagMcMatchGen, int8_t); // fla DECLARE_SOA_COLUMN(DebugMcRec, debugMcRec, int8_t); // debug flag for mis-association at reconstruction level DECLARE_SOA_COLUMN(Origin, origin, int8_t); // Flag for origin of MC particle 1=promt, 2=FD DECLARE_SOA_COLUMN(SignD0, signD0, int8_t); // Sign of the D0 in the channels with D* -> D0 pi, needed in case of non-matched D* - +DECLARE_SOA_COLUMN(InvMassGen, invMassGen, float); //! Invariant mass at generation level in GeV/c2 DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! [](float pxProng0, float pxProng1, float pyProng0, float pyProng1) -> float { return RecoDecay::pt((1.f * pxProng0 + 1.f * pxProng1), (1.f * pyProng0 + 1.f * pyProng1)); }); DECLARE_SOA_DYNAMIC_COLUMN(PtProng0, ptProng0, //! @@ -1067,6 +1113,7 @@ DECLARE_SOA_TABLE(HfMcRecRedDV0s, "AOD", "HFMCRECREDDV0", //! Table with reconst hf_reso_cand_reduced::Origin, hf_reso_cand_reduced::SignD0, hf_b0_mc::PtMother, + hf_reso_cand_reduced::InvMassGen, o2::soa::Marker<1>); DECLARE_SOA_TABLE(HfMcGenRedResos, "AOD", "HFMCGENREDRESO", //! Generation-level MC information on Ds-Resonances candidates for reduced workflow diff --git a/PWGHF/D2H/Macros/HFInvMassFitter.cxx b/PWGHF/D2H/Macros/HFInvMassFitter.cxx index b29661d4b1b..f58f90b9373 100644 --- a/PWGHF/D2H/Macros/HFInvMassFitter.cxx +++ b/PWGHF/D2H/Macros/HFInvMassFitter.cxx @@ -19,22 +19,35 @@ #include "HFInvMassFitter.h" -#include -#include - -#include -#include #include -#include -#include #include #include +#include +#include #include -#include -#include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include using namespace RooFit; diff --git a/PWGHF/D2H/Macros/HFInvMassFitter.h b/PWGHF/D2H/Macros/HFInvMassFitter.h index 61c8b601179..a791ce8ebb1 100644 --- a/PWGHF/D2H/Macros/HFInvMassFitter.h +++ b/PWGHF/D2H/Macros/HFInvMassFitter.h @@ -20,20 +20,18 @@ #ifndef PWGHF_D2H_MACROS_HFINVMASSFITTER_H_ #define PWGHF_D2H_MACROS_HFINVMASSFITTER_H_ -#include - #include #include #include -#include -#include #include -#include #include #include -#include -#include -#include +#include + +#include +#include + +#include class HFInvMassFitter : public TNamed { diff --git a/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx b/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx index 8b83e3bf349..7e93bb339d7 100644 --- a/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx @@ -13,8 +13,12 @@ /// \brief Reconstruction of Resonance candidates /// /// \author Luca Aglietta , Università degli Studi di Torino -#include -#include +#include "PWGHF/D2H/Core/SelectorCutsRedDataFormat.h" +#include "PWGHF/D2H/DataModel/ReducedDataModel.h" +#include "PWGHF/Utils/utilsAnalysis.h" + +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/CollisionAssociationTables.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" @@ -22,13 +26,8 @@ #include "ReconstructionDataFormats/DCA.h" #include "ReconstructionDataFormats/V0.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/CollisionAssociationTables.h" -#include "EventFiltering/PWGHF/HFFilterHelpers.h" - -#include "PWGHF/D2H/DataModel/ReducedDataModel.h" -#include "PWGHF/D2H/Core/SelectorCutsRedDataFormat.h" -#include "PWGHF/Utils/utilsAnalysis.h" +#include +#include using namespace o2; using namespace o2::aod; diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx index 8eac85d1878..401bdd028a9 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx @@ -18,11 +18,20 @@ /// \author Fabio Catalano , CERN /// \author Biao Zhang , Heidelberg University -#include -#include -#include -#include -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/D2H/DataModel/ReducedDataModel.h" +#include "PWGHF/D2H/Utils/utilsRedDataFormat.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsBfieldCCDB.h" +#include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGHF/Utils/utilsTrkCandHf.h" + +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/Qvectors.h" #include "CommonConstants/PhysicsConstants.h" #include "DCAFitter/DCAFitterN.h" @@ -31,19 +40,11 @@ #include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/DCA.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/CollisionAssociationTables.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Qvectors.h" - -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsBfieldCCDB.h" -#include "PWGHF/Utils/utilsEvSelHf.h" -#include "PWGHF/D2H/DataModel/ReducedDataModel.h" -#include "PWGHF/Utils/utilsTrkCandHf.h" -#include "PWGHF/D2H/Utils/utilsRedDataFormat.h" +#include +#include +#include +#include +#include using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx index 3dc7cdcb08c..5238f04c737 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx @@ -15,33 +15,32 @@ /// \author Luca Aglietta , UniTO Turin /// \author Fabrizio Grosa , CERN -#include -#include -#include -#include -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/D2H/DataModel/ReducedDataModel.h" +#include "PWGHF/D2H/Utils/utilsRedDataFormat.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsBfieldCCDB.h" +#include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/TrackSelectionTables.h" -#include "DetectorsBase/Propagator.h" #include "CommonConstants/PhysicsConstants.h" #include "DCAFitter/DCAFitterN.h" +#include "DetectorsBase/Propagator.h" #include "Framework/AnalysisTask.h" #include "Framework/O2DatabasePDGPlugin.h" #include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/DCA.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/CollisionAssociationTables.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include "PWGLF/DataModel/LFStrangenessTables.h" - -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsBfieldCCDB.h" -#include "PWGHF/D2H/DataModel/ReducedDataModel.h" -#include "PWGHF/Utils/utilsEvSelHf.h" -#include "PWGHF/D2H/Utils/utilsRedDataFormat.h" +#include +#include +#include +#include +#include using namespace o2; using namespace o2::analysis; @@ -73,26 +72,38 @@ enum BachelorType : uint8_t { enum DType : uint8_t { Dplus = 1, - Dstar + Dstar, + D0 +}; + +enum PairingType : uint8_t { + V0Only, + TrackOnly, + V0AndTrack +}; + +enum D0Sel : uint8_t { + selectedD0 = 0, + selectedD0Bar }; enum DecayTypeMc : uint8_t { - Ds1ToDStarK0ToD0PiK0s = 1, + Ds1ToDstarK0ToD0PiK0s = 1, Ds2StarToDplusK0sToPiKaPiPiPi, - Ds1ToDStarK0ToDPlusPi0K0s, - Ds1ToDStarK0ToD0PiK0sPart, - Ds1ToDStarK0ToD0NoPiK0sPart, - Ds1ToDStarK0ToD0PiK0sOneMu, + Ds1ToDstarK0ToDplusPi0K0s, + Ds1ToDstarK0ToD0PiK0sPart, + Ds1ToDstarK0ToD0NoPiK0sPart, + Ds1ToDstarK0ToD0PiK0sOneMu, Ds2StarToDplusK0sOneMu }; enum PartialMatchMc : uint8_t { K0Matched = 0, D0Matched, - DStarMatched, - DPlusMatched, + DstarMatched, + DplusMatched, K0MuMatched, - DStarMuMatched + DstarMuMatched }; /// Creation of D-V0 pairs @@ -104,27 +115,22 @@ struct HfDataCreatorCharmResoReduced { // tracks, V0 and D candidates reduced tables Produces hfCandV0; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h Produces hfTrackNoParam; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h - Produces hfCandD; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + Produces hfCandD3Pr; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + Produces hfCandD2Pr; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h // ML optional Tables - Produces hfCandDMl; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + Produces hfCandD3PrMl; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h + Produces hfCandD2PrMl; // Defined in PWGHF/D2H/DataModel/ReducedDataModel.h // MC Tables Produces rowHfDV0McRecReduced; Produces rowHfResoMcGenReduced; - // CCDB configuration - o2::ccdb::CcdbApi ccdbApi; - Service ccdb; - Configurable url{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; - Configurable propagateV0toPV{"propagateV0toPV", false, "Enable or disable V0 propagation to V0"}; - Configurable doMcRecQa{"doMcRecQa", true, "Fill QA histograms for Mc matching"}; - - int runNumber{0}; // needed to detect if the run changed and trigger update of calibrations etc. // selection D struct : ConfigurableGroup { std::string prefix = "dmesons"; Configurable selectionFlagDplus{"selectionFlagDplus", 7, "Selection Flag for D"}; Configurable selectionFlagDstarToD0Pi{"selectionFlagDstarToD0Pi", true, "Selection Flag for D* decay to D0 & Pi"}; + Configurable selectionFlagD0{"selectionFlagD0", 1, "Selection Flag for D0"}; + Configurable selectionFlagD0Bar{"selectionFlagD0Bar", 1, "Selection Flag for D0bar"}; } cfgDmesCuts; // selection V0 @@ -137,6 +143,7 @@ struct HfDataCreatorCharmResoReduced { Configurable trackNclusItsCut{"trackNclusItsCut", 0, "Minimum number of ITS clusters for V0 daughter"}; Configurable trackNCrossedRowsTpc{"trackNCrossedRowsTpc", 50, "Minimum TPC crossed rows"}; Configurable trackNsharedClusTpc{"trackNsharedClusTpc", 1000, "Maximum number of shared TPC clusters for V0 daughter"}; + Configurable trackFracMaxindableTpcCls{"trackFracMaxindableTpcCls", 0.8f, "Maximum fraction of findable TPC clusters for V0 daughter"}; Configurable dcaDau{"dcaDau", 1.f, "DCA V0 daughters"}; Configurable dcaMaxDauToPv{"dcaMaxDauToPv", 0.1f, "Maximum daughter's DCA to PV"}; Configurable dcaPv{"dcaPv", 1.f, "DCA V0 to PV"}; @@ -157,19 +164,43 @@ struct HfDataCreatorCharmResoReduced { Configurable maxNsigmaTpcPr{"maxNsigmaTpcPr", 3., "maximum proton NSigma in TPC for single tracks to be paired with D mesons; set negative to reject"}; } cfgSingleTrackCuts; + // QA histograms + struct : ConfigurableGroup { + Configurable applyCutsForQaHistograms{"applyCutsForQaHistograms", true, "flag to apply cuts to QA histograms"}; + Configurable cutMassDstarMin{"cutMassDstarMin", 0.143, "minimum mass for Dstar candidates"}; + Configurable cutMassDstarMax{"cutMassDstarMax", 0.155, "maximum mass for Dstar candidates"}; + Configurable cutMassDMin{"cutMassDMin", 1.83, "minimum mass for D0 and Dplus candidates"}; + Configurable cutMassDMax{"cutMassDMax", 1.92, "maximum mass for D0 and Dplus candidates"}; + Configurable cutMassK0sMin{"cutMassK0sMin", 0.485, "minimum mass for K0s candidates"}; + Configurable cutMassK0sMax{"cutMassK0sMax", 0.509, "maximum mass for K0s candidates"}; + Configurable cutMassLambdaMin{"cutMassLambdaMin", 1.11, "minimum mass for Lambda candidates"}; + Configurable cutMassLambdaMax{"cutMassLambdaMax", 1.12, "maximum mass for Lambda candidates"}; + } cfgQaPlots; // other configurables + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; + Configurable propagateV0toPV{"propagateV0toPV", false, "Enable or disable V0 propagation to V0"}; + Configurable doMcRecQa{"doMcRecQa", true, "Fill QA histograms for Mc matching"}; Configurable rejectPairsWithCommonDaughter{"rejectPairsWithCommonDaughter", true, "flag to reject already at this stage the pairs that share a daughter track"}; - // material correction for track propagation - o2::base::MatLayerCylSet* lut; - o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; HfHelper hfHelper; o2::hf_evsel::HfEventSelection hfEvSel; - o2::vertexing::DCAFitterN<2> fitter; + + // CCDB service + o2::ccdb::CcdbApi ccdbApi; + Service ccdb; double bz{0.}; + int runNumber{0}; // needed to detect if the run changed and trigger update of calibrations etc. + + // material correction for track propagation + o2::base::MatLayerCylSet* lut; + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + + // O2DatabasePDG service Service pdg; - // bool isHfCandResoConfigFilled = false; + // vertex fitter + o2::vertexing::DCAFitterN<2> fitter; // Helper struct to pass V0 informations struct { @@ -192,25 +223,36 @@ struct HfDataCreatorCharmResoReduced { struct { float invMassD; float ptD; - float invMassDdau; - float invMassKPiPiV0; + float invMassD0; + float invMassD0Bar; + float invMassReso; float ptReso; + int8_t signD; + std::array pVectorProng0; + std::array pVectorProng1; + std::array pVectorProng2; } varUtils; + using CandsDplusFiltered = soa::Filtered>; using CandsDplusFilteredWithMl = soa::Filtered>; - using CandDstarFiltered = soa::Filtered>; - using CandDstarFilteredWithMl = soa::Filtered>; + using CandsDstarFiltered = soa::Filtered>; + using CandsDstarFilteredWithMl = soa::Filtered>; + using CandsD0Filtered = soa::Filtered>; + using CandsD0FilteredWithMl = soa::Filtered>; using TracksWithPID = soa::Join; using TracksIUWithPID = soa::Join; using TracksIUWithPIDAndMC = soa::Join; Filter filterSelectDplus = (aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= cfgDmesCuts.selectionFlagDplus); Filter filterSelectedCandDstar = (aod::hf_sel_candidate_dstar::isSelDstarToD0Pi == cfgDmesCuts.selectionFlagDstarToD0Pi); + Filter filterSelectD0Candidates = (aod::hf_sel_candidate_d0::isSelD0 >= cfgDmesCuts.selectionFlagD0 || aod::hf_sel_candidate_d0::isSelD0bar >= cfgDmesCuts.selectionFlagD0Bar); Preslice candsDplusPerCollision = aod::hf_cand::collisionId; Preslice candsDplusPerCollisionWithMl = aod::hf_cand::collisionId; - Preslice candsDstarPerCollision = aod::hf_cand::collisionId; - Preslice candsDstarPerCollisionWithMl = aod::hf_cand::collisionId; + Preslice candsDstarPerCollision = aod::hf_cand::collisionId; + Preslice candsDstarPerCollisionWithMl = aod::hf_cand::collisionId; + Preslice candsD0PerCollision = aod::hf_cand::collisionId; + Preslice candsD0PerCollisionWithMl = aod::hf_cand::collisionId; Preslice candsV0PerCollision = aod::v0::collisionId; Preslice trackIndicesPerCollision = aod::track_association::collisionId; @@ -225,70 +267,88 @@ struct HfDataCreatorCharmResoReduced { labels[Event::NoDV0Selected] = "without DV0 pairs"; labels[Event::DV0Selected] = "with DV0 pairs"; static const AxisSpec axisEvents = {kNBinsEvents, 0.5, kNBinsEvents + 0.5, ""}; - registry.add("hEvents", "Events;;entries", HistType::kTH1F, {axisEvents}); + registry.add("hEvents", "Events;;entries", HistType::kTH1D, {axisEvents}); for (int iBin = 0; iBin < kNBinsEvents; iBin++) { registry.get(HIST("hEvents"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); } - const AxisSpec axisPt{50, 0.f, 50.f, ""}; - const AxisSpec axisP{100, 0.f, 10.f, ""}; + const AxisSpec axisPt{50, 0.f, 50.f, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec axisP{100, 0.f, 10.f, "#it{p} (GeV/#it{c})"}; const AxisSpec axisDeDx{500, 0.f, 1000.f, ""}; - const AxisSpec axisMassDplus{200, 1.7f, 2.1f, ""}; - const AxisSpec axisMassDstar{200, 0.139f, 0.179f, ""}; - const AxisSpec axisMassLambda{100, 1.05f, 1.35f, ""}; - const AxisSpec axisMassKzero{100, 0.35f, 0.65f, ""}; - const AxisSpec axisMassDsj{400, 0.49f, 0.89f, ""}; - - registry.add("hMassVsPtDplusAll", "Dplus candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDplus}}); - registry.add("hMassVsPtDstarAll", "Dstar candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDstar}}); - registry.add("hMassVsPtDplusPaired", "Dplus candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDplus}}); - registry.add("hMassVsPtDstarPaired", "Dstar candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDstar}}); - - registry.add("hMassVsPtK0s", "K0^{s} candidates;#it{p}_{T} (GeV/#it{c});inv. mass (#pi^{#plus}#pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassKzero}}); - registry.add("hMassVsPtLambda", "Lambda candidates;#it{p}_{T} (GeV/#it{c});inv. mass (p #pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassLambda}}); - registry.add("hdEdxVsP", "Tracks;#it{p} (GeV/#it{c});d#it{E}/d#it{x};entries", {HistType::kTH2F, {axisP, axisDeDx}}); - - registry.add("hMassDs1", "Ds1 candidates;m_{Ds1} - m_{D^{*}} (GeV/#it{c}^{2});entries", {HistType::kTH1F, {axisMassDsj}}); - registry.add("hMassDsStar2", "Ds^{*}2 candidates; Ds^{*}2 - m_{D^{#plus}} (GeV/#it{c}^{2});entries", {HistType::kTH1F, {axisMassDsj}}); - registry.add("hMassXcRes", "XcRes candidates; XcRes - m_{D^{#plus}} (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{300, 1.1, 1.4}}}); - registry.add("hMassDstarProton", "D^{*}-proton candidates;m_{D^{*}p} - m_{D^{*}} (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 0.9, 1.4}}}); - registry.add("hDType", "D selection flag", {HistType::kTH1F, {{5, -2.5, 2.5}}}); - - registry.add("hMCRecCounter", "Number of Reconstructed MC Matched candidates per channel", {HistType::kTH1F, {{17, -8.5, 8.5}}}); - registry.add("hMCRecDebug", "Debug of MC Reco", {HistType::kTH1F, {{16, -0.5, 15.5}}}); - registry.add("hMCRecOrigin", "Origin of Matched particles", {HistType::kTH1F, {{3, -0.5, 2.5}}}); - - registry.add("hMCGenCounter", "Number of Generated particles; Decay Channel Flag; pT [GeV/c]", {HistType::kTH2F, {{17, -8.5, 8.5}, {100, 0, 50}}}); - registry.add("hMCSignCounter", "Sign of Generated particles", {HistType::kTH1F, {{3, -1.5, 1.5}}}); - registry.add("hMCGenOrigin", "Origin of Generated particles", {HistType::kTH1F, {{3, -0.5, 2.5}}}); - registry.add("hMCOriginCounterWrongDecay", "Origin of Generated particles in Wrong decay", {HistType::kTH1F, {{3, -0.5, 2.5}}}); + const AxisSpec axisMassD0{200, 1.7f, 2.1f, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisMassDplus{200, 1.7f, 2.1f, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisMassDstar{200, 0.139f, 0.179f, "delta inv. mass (GeV/#it{c}^{2})"}; // o2-linter: disable=pdg/explicit-mass (false positive) + const AxisSpec axisMassLambda{100, 1.05f, 1.35f, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisMassKzero{100, 0.35f, 0.65f, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisDeltaMassToK{500, 0.49, 1.49, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisDeltaMassToPi{500, 0.13, 1.13, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisDeltaMassToPr{500, 0.93, 1.93, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisDeltaMassToLambda{500, 1.05, 2.05, "inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisMassDsj{400, 0.49f, 0.89f, ""}; // Ds1 and Ds2Star legacy + registry.add("hMassVsPtDplusAll", "Dplus candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDplus}}); + registry.add("hMassVsPtDstarAll", "Dstar candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDstar}}); + registry.add("hMassVsPtD0All", "D0 candidates (all, regardless the pairing with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassD0}}); + registry.add("hMassVsPtDplusPaired", "Dplus candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDplus}}); + registry.add("hMassVsPtDstarPaired", "Dstar candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDstar}}); + registry.add("hMassVsPtD0Paired", "D0 candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassD0}}); + registry.add("hMassVsPtD0BarPaired", "D0 candidates (paired with V0s);#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassD0}}); + registry.add("hMassVsPtK0s", "K0^{s} candidates;#it{p}_{T} (GeV/#it{c});inv. mass (#pi^{#plus}#pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassKzero}}); + registry.add("hMassVsPtLambda", "Lambda candidates;#it{p}_{T} (GeV/#it{c});inv. mass (p #pi^{#minus}) (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassLambda}}); + registry.add("hdEdxVsP", "Tracks;#it{p} (GeV/#it{c});d#it{E}/d#it{x};entries", {HistType::kTH2D, {axisP, axisDeDx}}); + registry.add("hDType", "D selection flag", {HistType::kTH1D, {{5, -2.5, 2.5}}}); + + // QA reso invariant mass histograms + registry.add("hMassD0Pi", "D0Pi candidates; m_{D^{0}#pi^{+}} - m_{D^{0}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPi}}); + registry.add("hMassD0K", "D0Kplus candidates; m_{D^{0}K^{+}} - m_{D^{0} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); + registry.add("hMassD0Proton", "D0Proton candidates; m_{D^{0}p} - m_{D^{0} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPr}}); + registry.add("hMassD0Lambda", "D0Lambda candidates; m_{D^{0}#Lambda} - m_{D^{0} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToLambda}}); + registry.add("hMassDstarPi", "DstarPi candidates; m_{D^{*+}#pi^{-}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPi}}); + registry.add("hMassDstarK", "DstarK candidates; m_{D^{*+}#pi^{-}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); + registry.add("hMassDstarProton", "DstarProton candidates; m_{D^{*}p} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPr}}); + registry.add("hMassDstarK0s", "DstarK0s candidates; m_{D^{*}K^{0}_{S}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); + registry.add("hMassDstarLambda", "DstarLambda candidates; m_{D^{*}#Lambda} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToLambda}}); + registry.add("hMassDplusK0s", "DplusK0s candidates; m_{D^{+}K^{0}_{S}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); + registry.add("hMassDplusPi", "DplusPi candidates; m_{D^{+}#pi^{-}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPi}}); + registry.add("hMassDplusK", "DplusK candidates; m_{D^{+}#pi^{-}} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToK}}); + registry.add("hMassDplusProton", "DplusProton candidates; m_{D^{+}p} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToPr}}); + registry.add("hMassDplusLambda", "DplusLambda candidates; m_{D^{+}#Lambda} (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisDeltaMassToLambda}}); + // MC Rec + registry.add("hMCRecCounter", "Number of Reconstructed MC Matched candidates per channel", {HistType::kTH1D, {{17, -8.5, 8.5}}}); + registry.add("hMCRecDebug", "Debug of MC Reco", {HistType::kTH1D, {{16, -0.5, 15.5}}}); + registry.add("hMCRecOrigin", "Origin of Matched particles", {HistType::kTH1D, {{3, -0.5, 2.5}}}); + registry.add("hMCRecMassGen", "Generated inv. mass of resoncances", {HistType::kTH1D, {{2000, 1.8, 3.8}}}); + // MC Gen + registry.add("hMCGenCounter", "Number of Generated particles; Decay Channel Flag; pT [GeV/c]", {HistType::kTH2D, {{17, -8.5, 8.5}, {100, 0, 50}}}); + registry.add("hMCSignCounter", "Sign of Generated particles", {HistType::kTH1D, {{3, -1.5, 1.5}}}); + registry.add("hMCGenOrigin", "Origin of Generated particles", {HistType::kTH1D, {{3, -0.5, 2.5}}}); + registry.add("hMCOriginCounterWrongDecay", "Origin of Generated particles in Wrong decay", {HistType::kTH1D, {{3, -0.5, 2.5}}}); if (doMcRecQa) { - registry.add("hMassVsPtK0Matched", "K0s candidates Matched ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassKzero}}); - registry.add("hMassVsPtD0Matched", "D0 candidates Matched ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDplus}}); - registry.add("hMassVsPtDstarMatched", "Dstar candidates Matched ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDstar}}); - registry.add("hMassVsPtDplusMatched", "Dplus candidates Matched ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDplus}}); - registry.add("hMassVsPtDs1Matched", "Ds1 candidates Matched ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDsj}}); - registry.add("hMassVsPtDs2StarMatched", "Ds2Star candidates Matched ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDsj}}); - registry.add("hMassVsPtK0MatchedPiToMu", "K0s candidates Matched with PiToMu decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassKzero}}); - registry.add("hMassVsPtD0MatchedPiToMu", "D0 candidates Matched with PiToMu decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDplus}}); - registry.add("hMassVsPtDstarMatchedPiToMu", "Dstar candidates Matched with PiToMu decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDstar}}); - registry.add("hMassVsPtDplusMatchedPiToMu", "Dplus candidates Matched with PiToMu decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDplus}}); - registry.add("hMassVsPtDs1MatchedPiToMu", "Ds1 candidates Matched with PiToMu decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDsj}}); - registry.add("hMassVsPtDs2StarMatchedPiToMu", "Ds2Star candidates Matched with PiToMu decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDsj}}); - registry.add("hMassVsPtD0MatchedKaToPi", "D0 candidates Matched with KaToPi decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDplus}}); - registry.add("hMassVsPtDstarMatchedKaToPi", "Dstar candidates Matched with KaToPi decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDstar}}); - registry.add("hMassVsPtDplusMatchedKaToPi", "Dplus candidates Matched with KaToPi decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDplus}}); - registry.add("hMassVsPtDs1MatchedKaToPi", "Ds1 candidates Matched with KaToPi decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDsj}}); - registry.add("hMassVsPtDs2StarMatchedKaToPi", "Ds2Star candidates Matched with KaToPi decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPt, axisMassDsj}}); + registry.add("hMassVsPtK0Matched", "K0s candidates Matched ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassKzero}}); + registry.add("hMassVsPtD0Matched", "D0 candidates Matched ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDplus}}); + registry.add("hMassVsPtDstarMatched", "Dstar candidates Matched ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDstar}}); + registry.add("hMassVsPtDplusMatched", "Dplus candidates Matched ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDplus}}); + registry.add("hMassVsPtDs1Matched", "Ds1 candidates Matched ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDsj}}); + registry.add("hMassVsPtDs2StarMatched", "Ds2Star candidates Matched ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDsj}}); + registry.add("hMassVsPtK0MatchedPiToMu", "K0s candidates Matched with PiToMu decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassKzero}}); + registry.add("hMassVsPtD0MatchedPiToMu", "D0 candidates Matched with PiToMu decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDplus}}); + registry.add("hMassVsPtDstarMatchedPiToMu", "Dstar candidates Matched with PiToMu decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDstar}}); + registry.add("hMassVsPtDplusMatchedPiToMu", "Dplus candidates Matched with PiToMu decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDplus}}); + registry.add("hMassVsPtDs1MatchedPiToMu", "Ds1 candidates Matched with PiToMu decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDsj}}); + registry.add("hMassVsPtDs2StarMatchedPiToMu", "Ds2Star candidates Matched with PiToMu decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDsj}}); + registry.add("hMassVsPtD0MatchedKaToPi", "D0 candidates Matched with KaToPi decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDplus}}); + registry.add("hMassVsPtDstarMatchedKaToPi", "Dstar candidates Matched with KaToPi decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDstar}}); + registry.add("hMassVsPtDplusMatchedKaToPi", "Dplus candidates Matched with KaToPi decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDplus}}); + registry.add("hMassVsPtDs1MatchedKaToPi", "Ds1 candidates Matched with KaToPi decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDsj}}); + registry.add("hMassVsPtDs2StarMatchedKaToPi", "Ds2Star candidates Matched with KaToPi decay ;#it{p}_{T} (GeV/#it{c});inv. mass (GeV/#it{c}^{2});entries", {HistType::kTH2D, {axisPt, axisMassDsj}}); } // Configure CCDB access - ccdb->setURL(url.value); + ccdb->setURL(ccdbUrl.value); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); - ccdbApi.init(url); + ccdbApi.init(ccdbUrl); runNumber = 0; lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get("GLO/Param/MatLUT")); @@ -325,7 +385,7 @@ struct HfDataCreatorCharmResoReduced { if (track.itsNCls() < cfgV0Cuts.trackNclusItsCut || track.tpcNClsFound() < cfgV0Cuts.trackNCrossedRowsTpc || track.tpcNClsCrossedRows() < cfgV0Cuts.trackNCrossedRowsTpc || - track.tpcNClsCrossedRows() < 0.8 * track.tpcNClsFindable() || + track.tpcNClsCrossedRows() < cfgV0Cuts.trackFracMaxindableTpcCls * track.tpcNClsFindable() || track.tpcNClsShared() > cfgV0Cuts.trackNsharedClusTpc) { return false; } @@ -392,7 +452,7 @@ struct HfDataCreatorCharmResoReduced { auto& trackNegProp = fitter.getTrack(1); trackPosProp.getPxPyPzGlo(candidateV0.momPos); trackNegProp.getPxPyPzGlo(candidateV0.momNeg); - for (int i = 0; i < 3; ++i) { + for (int i = 0; i < 3; ++i) { // o2-linter: disable=magic-number (loop on xyz) candidateV0.mom[i] = candidateV0.momPos[i] + candidateV0.momNeg[i]; } candidateV0.pT = std::hypot(candidateV0.mom[0], candidateV0.mom[1]); @@ -413,7 +473,7 @@ struct HfDataCreatorCharmResoReduced { if (candidateV0.radius < cfgV0Cuts.radiusMin) { return false; } - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 3; i++) { // o2-linter: disable=magic-number (loop on xyz) candidateV0.pos[i] = vtx[i]; } // v0 DCA to primary vertex @@ -533,17 +593,16 @@ struct HfDataCreatorCharmResoReduced { /// \param vecDaughtersReso is the vector with all daughter tracks (bachelor pion in last position) /// \param indexHfCandCharm is the index of the charm-hadron bachelor in the reduced table /// \param indexCandV0 is the index of the v0 bachelor in the reduced table - template + template void fillMcRecoInfo(const PParticles& particlesMc, const std::vector& vecDaughtersReso, int& indexHfCandCharm, int& indexCandV0) { - // we check the MC matching to be stored int8_t sign{0}; - int8_t signDStar{0}; - int8_t signDPlus{0}; + int8_t signDstar{0}; + int8_t signDplus{0}; int8_t signD0{0}; int8_t signV0{0}; int8_t flag{0}; @@ -553,38 +612,39 @@ struct HfDataCreatorCharmResoReduced { int8_t nKaToPiReso{0}, nKaToPiV0, nKaToPiD0{0}, nKaToPiDstar{0}, nKaToPiDplus{0}; std::vector idxBhadMothers{}; float motherPt{-1.f}; + float invMassGen{-1.f}; int indexRecReso{-1}, indexRecDstar{-1}, indexRecDplus{-1}, indexRecD0{-1}, indexRecK0{-1}, indexRecResoPartReco{-1}; - if constexpr (decChannel == DecayChannel::DstarV0) { + if constexpr (dType == DType::Dstar) { // Ds1 → D* K0 → (D0 π+) K0s → ((K-π+) π+)(π+π-) indexRecD0 = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1]}, Pdg::kD0, std::array{+kPiPlus, -kKPlus}, true, &signD0, 1, &nPiToMuD0, &nKaToPiD0); indexRecK0 = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[3], vecDaughtersReso[4]}, kK0, std::array{+kPiPlus, -kPiPlus}, true, &signV0, 2, &nPiToMuV0, &nKaToPiV0); if (indexRecD0 > -1) { - indexRecDstar = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2]}, Pdg::kDStar, std::array{-kKPlus, +kPiPlus, +kPiPlus}, true, &signDStar, 2, &nPiToMuDstar, &nKaToPiDstar); + indexRecDstar = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2]}, Pdg::kDStar, std::array{-kKPlus, +kPiPlus, +kPiPlus}, true, &signDstar, 2, &nPiToMuDstar, &nKaToPiDstar); } if (indexRecD0 > -1 && indexRecDstar > -1 && indexRecK0 > -1) { indexRecReso = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3], vecDaughtersReso[4]}, Pdg::kDS1, std::array{+kPiPlus, -kKPlus, +kPiPlus, +kPiPlus, -kPiPlus}, true, &sign, 3, &nPiToMuReso, &nKaToPiReso); if (indexRecReso > -1 && nPiToMuReso == 0 && nKaToPiReso == 0) { - flag = sign * DecayTypeMc::Ds1ToDStarK0ToD0PiK0s; + flag = sign * DecayTypeMc::Ds1ToDstarK0ToD0PiK0s; } else if (indexRecReso > -1 && nPiToMuReso >= 1 && nKaToPiReso == 0) { - flag = sign * DecayTypeMc::Ds1ToDStarK0ToD0PiK0sOneMu; + flag = sign * DecayTypeMc::Ds1ToDstarK0ToD0PiK0sOneMu; } } // Ds1+ not matched: we check if it is partially reco if (indexRecReso < 0) { indexRecResoPartReco = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3], vecDaughtersReso[4]}, Pdg::kDS1, std::array{+kPiPlus, -kKPlus, +kPiPlus, +kPiPlus, -kPiPlus}, true, &sign, 3); - indexRecDplus = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2]}, Pdg::kDPlus, std::array{+kPiPlus, -kKPlus, +kPiPlus}, true, &signDPlus, 2); + indexRecDplus = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2]}, Pdg::kDPlus, std::array{+kPiPlus, -kKPlus, +kPiPlus}, true, &signDplus, 2); if (indexRecResoPartReco > -1) { // we look for decays of D* or D0 with more daughters if (indexRecDstar < 0 && indexRecK0 > -1) { - auto indexRecDstarPartReco = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2]}, Pdg::kDStar, std::array{-kKPlus, +kPiPlus, +kPiPlus}, true, &signDStar, 3); + auto indexRecDstarPartReco = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2]}, Pdg::kDStar, std::array{-kKPlus, +kPiPlus, +kPiPlus}, true, &signDstar, 3); if (indexRecDstarPartReco > -1) { if (indexRecDplus > -1) { // Ds1 -> D* K0s -> D+ π0 K0s - flag = sign * DecayTypeMc::Ds1ToDStarK0ToDPlusPi0K0s; + flag = sign * DecayTypeMc::Ds1ToDstarK0ToDplusPi0K0s; } else { - auto indexRecDzeroPartReco = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1]}, Pdg::kD0, std::array{+kPiPlus, -kKPlus}, true, &signD0, 2); - if (indexRecDzeroPartReco > -1) { // Ds1 -> D* K0s -> D0 π+ K0s -> K- π+ π0 π+ K0s - flag = sign * DecayTypeMc::Ds1ToDStarK0ToD0PiK0sPart; + auto indexRecD0PartReco = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1]}, Pdg::kD0, std::array{+kPiPlus, -kKPlus}, true, &signD0, 2); + if (indexRecD0PartReco > -1) { // Ds1 -> D* K0s -> D0 π+ K0s -> K- π+ π0 π+ K0s + flag = sign * DecayTypeMc::Ds1ToDstarK0ToD0PiK0sPart; } } } @@ -593,7 +653,7 @@ struct HfDataCreatorCharmResoReduced { if (indexRecD0 > -1 && indexRecK0 > -1 && indexRecDstar < 0) { indexRecResoPartReco = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[3], vecDaughtersReso[4]}, Pdg::kDS1, std::array{+kPiPlus, -kKPlus, +kPiPlus, -kPiPlus}, true, &sign, 3); if (indexRecResoPartReco > -1) { - flag = sign * DecayTypeMc::Ds1ToDStarK0ToD0NoPiK0sPart; + flag = sign * DecayTypeMc::Ds1ToDstarK0ToD0NoPiK0sPart; } } } @@ -608,39 +668,40 @@ struct HfDataCreatorCharmResoReduced { auto particleReso = particlesMc.iteratorAt(indexParticle); origin = RecoDecay::getCharmHadronOrigin(particlesMc, particleReso, false, &idxBhadMothers); motherPt = particleReso.pt(); + invMassGen = RecoDecay::m(particleReso.p(), particleReso.e()); } if (doMcRecQa) { if (indexRecReso > -1) { if (nPiToMuReso == 0 && nKaToPiReso == 0) { - registry.fill(HIST("hMassVsPtDs1Matched"), varUtils.ptD, varUtils.invMassKPiPiV0 - varUtils.invMassD); + registry.fill(HIST("hMassVsPtDs1Matched"), varUtils.ptD, varUtils.invMassReso - varUtils.invMassD); } if (nPiToMuReso >= 1) { - registry.fill(HIST("hMassVsPtDs1MatchedPiToMu"), varUtils.ptD, varUtils.invMassKPiPiV0 - varUtils.invMassD); + registry.fill(HIST("hMassVsPtDs1MatchedPiToMu"), varUtils.ptD, varUtils.invMassReso - varUtils.invMassD); } if (nKaToPiReso >= 1) { - registry.fill(HIST("hMassVsPtDs1MatchedKaToPi"), varUtils.ptD, varUtils.invMassKPiPiV0 - varUtils.invMassD); + registry.fill(HIST("hMassVsPtDs1MatchedKaToPi"), varUtils.ptD, varUtils.invMassReso - varUtils.invMassD); } } if (indexRecD0 > -1) { if (nPiToMuD0 == 0 && nKaToPiD0 == 0) { - registry.fill(HIST("hMassVsPtD0Matched"), varUtils.ptD, varUtils.invMassDdau); + registry.fill(HIST("hMassVsPtD0Matched"), varUtils.ptD, varUtils.invMassD0); } if (nPiToMuD0 >= 1) { - registry.fill(HIST("hMassVsPtD0MatchedPiToMu"), varUtils.ptD, varUtils.invMassDdau); + registry.fill(HIST("hMassVsPtD0MatchedPiToMu"), varUtils.ptD, varUtils.invMassD0); } if (nKaToPiD0 >= 1) { - registry.fill(HIST("hMassVsPtD0MatchedKaToPi"), varUtils.ptD, varUtils.invMassDdau); + registry.fill(HIST("hMassVsPtD0MatchedKaToPi"), varUtils.ptD, varUtils.invMassD0); } } if (indexRecDstar > -1) { if (nPiToMuDstar == 0 && nKaToPiDstar == 0) { - registry.fill(HIST("hMassVsPtDstarMatched"), varUtils.ptD, varUtils.invMassD - varUtils.invMassDdau); + registry.fill(HIST("hMassVsPtDstarMatched"), varUtils.ptD, varUtils.invMassD - varUtils.invMassD0); } if (nPiToMuDstar >= 1) { - registry.fill(HIST("hMassVsPtDstarMatchedPiToMu"), varUtils.ptD, varUtils.invMassD - varUtils.invMassDdau); + registry.fill(HIST("hMassVsPtDstarMatchedPiToMu"), varUtils.ptD, varUtils.invMassD - varUtils.invMassD0); } if (nKaToPiDstar >= 1) { - registry.fill(HIST("hMassVsPtDstarMatchedKaToPi"), varUtils.ptD, varUtils.invMassD - varUtils.invMassDdau); + registry.fill(HIST("hMassVsPtDstarMatchedKaToPi"), varUtils.ptD, varUtils.invMassD - varUtils.invMassD0); } } if (indexRecK0 > -1) { @@ -655,10 +716,10 @@ struct HfDataCreatorCharmResoReduced { } } } - } else if constexpr (decChannel == DecayChannel::DplusV0) { + } else if constexpr (dType == DType::Dplus) { // Ds2Star → D+ K0 → (π+K-π+) K0s → (π+K-π+)(π+π-) indexRecK0 = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[3], vecDaughtersReso[4]}, kK0, std::array{+kPiPlus, -kPiPlus}, true, &signV0, 2, &nPiToMuV0, &nKaToPiV0); - indexRecDplus = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2]}, Pdg::kDPlus, std::array{+kPiPlus, -kKPlus, +kPiPlus}, true, &signDPlus, 2, &nPiToMuDplus, &nKaToPiDplus); + indexRecDplus = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2]}, Pdg::kDPlus, std::array{+kPiPlus, -kKPlus, +kPiPlus}, true, &signDplus, 2, &nPiToMuDplus, &nKaToPiDplus); if (indexRecK0 > -1 && indexRecDplus > -1) { indexRecReso = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3], vecDaughtersReso[4]}, Pdg::kDS2Star, std::array{+kPiPlus, -kKPlus, +kPiPlus, +kPiPlus, -kPiPlus}, true, &sign, 3, &nPiToMuReso, &nKaToPiReso); if (indexRecReso > -1 && nPiToMuReso == 0 && nKaToPiReso == 0) { @@ -667,11 +728,11 @@ struct HfDataCreatorCharmResoReduced { flag = sign * DecayTypeMc::Ds2StarToDplusK0sOneMu; } else if (indexRecReso < 0) { // Verify partly reconstructed decay Ds1 -> D* K0s -> D+ π0 K0s - indexRecDstar = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2]}, Pdg::kDStar, std::array{-kKPlus, +kPiPlus, +kPiPlus}, true, &signDStar, 2); + indexRecDstar = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2]}, Pdg::kDStar, std::array{-kKPlus, +kPiPlus, +kPiPlus}, true, &signDstar, 2); if (indexRecDstar > -1) { indexRecReso = RecoDecay::getMatchedMCRec(particlesMc, std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3], vecDaughtersReso[4]}, Pdg::kDS1, std::array{+kPiPlus, -kKPlus, +kPiPlus, +kPiPlus, -kPiPlus}, true, &sign, 3); if (indexRecReso > -1) { - flag = sign * DecayTypeMc::Ds1ToDStarK0ToDPlusPi0K0s; + flag = sign * DecayTypeMc::Ds1ToDstarK0ToDplusPi0K0s; } } } @@ -680,17 +741,18 @@ struct HfDataCreatorCharmResoReduced { auto particleReso = particlesMc.iteratorAt(indexRecReso); origin = RecoDecay::getCharmHadronOrigin(particlesMc, particleReso, false, &idxBhadMothers); motherPt = particleReso.pt(); + invMassGen = RecoDecay::m(particleReso.p(), particleReso.e()); } if (doMcRecQa) { if (indexRecReso > -1) { if (nPiToMuReso == 0 && nKaToPiReso == 0) { - registry.fill(HIST("hMassVsPtDs2StarMatched"), varUtils.ptD, varUtils.invMassKPiPiV0 - varUtils.invMassD); + registry.fill(HIST("hMassVsPtDs2StarMatched"), varUtils.ptD, varUtils.invMassReso - varUtils.invMassD); } if (nPiToMuReso >= 1) { - registry.fill(HIST("hMassVsPtDs2StarMatchedPiToMu"), varUtils.ptD, varUtils.invMassKPiPiV0 - varUtils.invMassD); + registry.fill(HIST("hMassVsPtDs2StarMatchedPiToMu"), varUtils.ptD, varUtils.invMassReso - varUtils.invMassD); } if (nKaToPiReso >= 1) { - registry.fill(HIST("hMassVsPtDs2StarMatchedKaToPi"), varUtils.ptD, varUtils.invMassKPiPiV0 - varUtils.invMassD); + registry.fill(HIST("hMassVsPtDs2StarMatchedKaToPi"), varUtils.ptD, varUtils.invMassReso - varUtils.invMassD); } } if (indexRecDplus > -1) { @@ -720,6 +782,7 @@ struct HfDataCreatorCharmResoReduced { if (flag != 0) { registry.fill(HIST("hMCRecCounter"), flag); registry.fill(HIST("hMCRecOrigin"), origin); + registry.fill(HIST("hMCRecMassGen"), invMassGen); } else { if (indexRecK0 > -1) { SETBIT(debug, PartialMatchMc::K0Matched); @@ -728,21 +791,23 @@ struct HfDataCreatorCharmResoReduced { SETBIT(debug, PartialMatchMc::D0Matched); } if (indexRecDstar > -1) { - SETBIT(debug, PartialMatchMc::DStarMatched); + SETBIT(debug, PartialMatchMc::DstarMatched); } if (indexRecDplus > -1) { - SETBIT(debug, PartialMatchMc::DPlusMatched); + SETBIT(debug, PartialMatchMc::DplusMatched); } registry.fill(HIST("hMCRecDebug"), debug); } - rowHfDV0McRecReduced(indexHfCandCharm, indexCandV0, flag, debug, origin, signD0, motherPt); + rowHfDV0McRecReduced(indexHfCandCharm, indexCandV0, flag, debug, origin, signD0, motherPt, invMassGen); } - template + template void runDataCreation(Coll const& collision, CCands const& candsD, - BBach const& bachelors, - Tr const&, + BBachV0s const& bachelorV0s, + BBachTracks const& bachelorTrks, + Tr const& tracks, + TrIU const&, PParticles const& particlesMc, aod::BCsWithTimestamps const&) { @@ -753,6 +818,8 @@ struct HfDataCreatorCharmResoReduced { std::map selectedV0s; std::map selectedTracks; bool fillHfReducedCollision = false; + const bool doTracks = pairingType == PairingType::TrackOnly || pairingType == PairingType::V0AndTrack; + const bool doV0s = pairingType == PairingType::V0Only || pairingType == PairingType::V0AndTrack; auto bc = collision.template bc_as(); if (runNumber != bc.runNumber()) { LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; @@ -763,60 +830,80 @@ struct HfDataCreatorCharmResoReduced { fitter.setBz(bz); // loop on D candidates for (const auto& candD : candsD) { - // initialize variables depending on decay channel + // initialize variables depending on D meson type bool fillHfCandD = false; - std::array pVecD; - std::array pVecProng2; std::array secondaryVertexD; std::array prongIdsD; - int8_t dtype; - std::array bdtScores; - std::vector charmHadDauTracks{}; + int8_t dtype{0}; + std::array bdtScores = {-1.f, -1.f, -1.f, -1.f, -1.f, -1.f}; + std::vector charmHadDauTracks{}; varUtils.ptD = candD.pt(); - if constexpr (DecayChannel == DecayChannel::DstarV0 || DecayChannel == DecayChannel::DstarTrack) { - if (candD.signSoftPi() > 0) { + if constexpr (dType == DType::Dstar) { + varUtils.signD = candD.signSoftPi(); + if (varUtils.signD > 0) { varUtils.invMassD = candD.invMassDstar(); - varUtils.invMassDdau = candD.invMassD0(); + varUtils.invMassD0 = candD.invMassD0(); } else { varUtils.invMassD = candD.invMassAntiDstar(); - varUtils.invMassDdau = candD.invMassD0Bar(); + varUtils.invMassD0 = candD.invMassD0Bar(); } - pVecD = candD.pVector(); secondaryVertexD[0] = candD.xSecondaryVertexD0(); secondaryVertexD[1] = candD.ySecondaryVertexD0(); secondaryVertexD[2] = candD.zSecondaryVertexD0(); prongIdsD[0] = candD.prong0Id(); prongIdsD[1] = candD.prong1Id(); prongIdsD[2] = candD.prongPiId(); - pVecProng2 = candD.pVecSoftPi(); - charmHadDauTracks.push_back(candD.template prong0_as
()); - charmHadDauTracks.push_back(candD.template prong1_as
()); - charmHadDauTracks.push_back(candD.template prongPi_as
()); - dtype = candD.signSoftPi() * DType::Dstar; + std::copy(candD.pVectorProng0().begin(), candD.pVectorProng0().end(), varUtils.pVectorProng0.begin()); + std::copy(candD.pVectorProng1().begin(), candD.pVectorProng1().end(), varUtils.pVectorProng1.begin()); + std::copy(candD.pVecSoftPi().begin(), candD.pVecSoftPi().end(), varUtils.pVectorProng2.begin()); + charmHadDauTracks.push_back(candD.template prong0_as()); + charmHadDauTracks.push_back(candD.template prong1_as()); + charmHadDauTracks.push_back(candD.template prongPi_as()); + dtype = varUtils.signD * DType::Dstar; if constexpr (withMl) { std::copy(candD.mlProbDstarToD0Pi().begin(), candD.mlProbDstarToD0Pi().end(), bdtScores.begin()); } - registry.fill(HIST("hMassVsPtDstarAll"), candD.pt(), varUtils.invMassD - varUtils.invMassDdau); - } else if constexpr (DecayChannel == DecayChannel::DplusV0) { - auto prong0 = candD.template prong0_as
(); + registry.fill(HIST("hMassVsPtDstarAll"), varUtils.ptD, varUtils.invMassD - varUtils.invMassD0); + } else if constexpr (dType == DType::Dplus) { + auto prong0 = candD.template prong0_as(); varUtils.invMassD = hfHelper.invMassDplusToPiKPi(candD); - pVecD = candD.pVector(); secondaryVertexD[0] = candD.xSecondaryVertex(); secondaryVertexD[1] = candD.ySecondaryVertex(); secondaryVertexD[2] = candD.zSecondaryVertex(); prongIdsD[0] = candD.prong0Id(); prongIdsD[1] = candD.prong1Id(); prongIdsD[2] = candD.prong2Id(); - pVecProng2 = candD.pVectorProng2(); - dtype = static_cast(prong0.sign() * DType::Dplus); - charmHadDauTracks.push_back(candD.template prong0_as
()); - charmHadDauTracks.push_back(candD.template prong1_as
()); - charmHadDauTracks.push_back(candD.template prong2_as
()); + varUtils.signD = prong0.sign(); + std::copy(candD.pVectorProng0().begin(), candD.pVectorProng0().end(), varUtils.pVectorProng0.begin()); + std::copy(candD.pVectorProng1().begin(), candD.pVectorProng1().end(), varUtils.pVectorProng1.begin()); + std::copy(candD.pVectorProng2().begin(), candD.pVectorProng2().end(), varUtils.pVectorProng2.begin()); + dtype = static_cast(varUtils.signD * DType::Dplus); + charmHadDauTracks.push_back(candD.template prong0_as()); + charmHadDauTracks.push_back(candD.template prong1_as()); + charmHadDauTracks.push_back(candD.template prong2_as()); if constexpr (withMl) { std::copy(candD.mlProbDplusToPiKPi().begin(), candD.mlProbDplusToPiKPi().end(), bdtScores.begin()); } - registry.fill(HIST("hMassVsPtDplusAll"), candD.pt(), varUtils.invMassD); - } // else if + registry.fill(HIST("hMassVsPtDplusAll"), varUtils.ptD, varUtils.invMassD0); + } else if constexpr (dType == DType::D0) { + varUtils.invMassD0 = hfHelper.invMassD0ToPiK(candD); + varUtils.invMassD0Bar = hfHelper.invMassD0barToKPi(candD); + secondaryVertexD[0] = candD.xSecondaryVertex(); + secondaryVertexD[1] = candD.ySecondaryVertex(); + secondaryVertexD[2] = candD.zSecondaryVertex(); + prongIdsD[0] = candD.prong0Id(); + prongIdsD[1] = candD.prong1Id(); + prongIdsD[2] = -1; // D0 does not have a third prong + charmHadDauTracks.push_back(candD.template prong0_as()); + charmHadDauTracks.push_back(candD.template prong1_as()); + std::copy(candD.pVectorProng0().begin(), candD.pVectorProng0().end(), varUtils.pVectorProng0.begin()); + std::copy(candD.pVectorProng1().begin(), candD.pVectorProng1().end(), varUtils.pVectorProng1.begin()); + varUtils.pVectorProng2 = {0.f, 0.f, 0.f}; // D0 does not have a third prong + if constexpr (withMl) { + std::copy(candD.mlProbD0().begin(), candD.mlProbD0().end(), bdtScores.begin()); + std::copy(candD.mlProbD0bar().begin(), candD.mlProbD0bar().end(), bdtScores.begin() + 3); + } + } // end of dType switch // Get single track variables float chi2TpcDauMax = -1.f; @@ -833,11 +920,11 @@ struct HfDataCreatorCharmResoReduced { } } - if constexpr (DecayChannel == DecayChannel::DplusV0 || DecayChannel == DecayChannel::DstarV0) { - // Loop on V0 candidates - for (const auto& v0 : bachelors) { - auto trackPos = v0.template posTrack_as
(); - auto trackNeg = v0.template negTrack_as
(); + // Loop on the bachelor V0s + if constexpr (doV0s) { + for (const auto& v0 : bachelorV0s) { + auto trackPos = v0.template posTrack_as(); + auto trackNeg = v0.template negTrack_as(); // Apply selsection auto v0DauTracks = std::array{trackPos, trackNeg}; if (!buildAndSelectV0(collision, prongIdsD, v0DauTracks)) { @@ -867,44 +954,95 @@ struct HfDataCreatorCharmResoReduced { o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParK0, 2.f, matCorr, &dcaInfo); getPxPyPz(trackParK0, candidateV0.mom); } + // compute resonance invariant mass and filling of QA histograms if (TESTBIT(candidateV0.v0Type, K0s)) { - if constexpr (DecayChannel == DecayChannel::DplusV0) { - varUtils.invMassKPiPiV0 = RecoDecay::m(std::array{candD.pVectorProng0(), candD.pVectorProng1(), candD.pVectorProng2(), candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassK0}); - // varUtils.ptReso = RecoDecay::pt(std::array{candD.pVectorProng0(), candD.pVectorProng1(), candD.pVectorProng2(), candidateV0.mom}); - } else if (DecayChannel == DecayChannel::DstarV0) { - // varUtils.ptReso = RecoDecay::pt(std::array{candD.pVectorProng0(), candD.pVectorProng1(), candD.pVecSoftPi(), candidateV0.mom}); - if (candD.signSoftPi() > 0) { - varUtils.invMassKPiPiV0 = RecoDecay::m(std::array{candD.pVectorProng0(), candD.pVectorProng1(), candD.pVecSoftPi(), candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassK0}); - } else { - varUtils.invMassKPiPiV0 = RecoDecay::m(std::array{candD.pVectorProng1(), candD.pVectorProng0(), candD.pVecSoftPi(), candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassK0}); - } - } registry.fill(HIST("hMassVsPtK0s"), candidateV0.pT, candidateV0.mK0Short); - if constexpr (DecayChannel == DecayChannel::DstarV0) { - registry.fill(HIST("hMassDs1"), varUtils.invMassKPiPiV0 - varUtils.invMassD); - } else if constexpr (DecayChannel == DecayChannel::DplusV0) { - registry.fill(HIST("hMassDsStar2"), varUtils.invMassKPiPiV0 - varUtils.invMassD); - } - } + switch (dType) { + case DType::Dstar: + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candidateV0.mom)); + if (varUtils.signD > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassK0}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassK0}); + } + if (!cfgQaPlots.applyCutsForQaHistograms || + (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin && + varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax && + candidateV0.mK0Short > cfgQaPlots.cutMassK0sMin && + candidateV0.mK0Short < cfgQaPlots.cutMassK0sMax)) { + registry.fill(HIST("hMassDstarK0s"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + break; + case DType::Dplus: + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassK0}); + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candidateV0.mom)); + if (!cfgQaPlots.applyCutsForQaHistograms || + (varUtils.invMassD > cfgQaPlots.cutMassDMin && + varUtils.invMassD < cfgQaPlots.cutMassDMax && + candidateV0.mK0Short > cfgQaPlots.cutMassK0sMin && + candidateV0.mK0Short < cfgQaPlots.cutMassK0sMax)) { + registry.fill(HIST("hMassDplusK0s"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + break; + default: + break; // no other D meson types expected + } // end of dType switch + } // matched with K0s bool isLambda = TESTBIT(candidateV0.v0Type, Lambda); bool isAntiLambda = TESTBIT(candidateV0.v0Type, AntiLambda); if (isLambda || isAntiLambda) { - if constexpr (DecayChannel == DecayChannel::DplusV0) { - varUtils.invMassKPiPiV0 = RecoDecay::m(std::array{candD.pVectorProng0(), candD.pVectorProng1(), candD.pVectorProng2(), candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassLambda0}); - } else if (DecayChannel == DecayChannel::DstarV0) { - if (candD.signSoftPi() > 0) { - varUtils.invMassKPiPiV0 = RecoDecay::m(std::array{candD.pVectorProng0(), candD.pVectorProng1(), candD.pVecSoftPi(), candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassLambda0}); - } else { - varUtils.invMassKPiPiV0 = RecoDecay::m(std::array{candD.pVectorProng1(), candD.pVectorProng0(), candD.pVecSoftPi(), candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassLambda0}); - } - } - if (isLambda || isAntiLambda) { - registry.fill(HIST("hMassVsPtLambda"), candidateV0.pT, candidateV0.mLambda); - } - if constexpr (DecayChannel == DecayChannel::DplusV0) { - registry.fill(HIST("hMassXcRes"), varUtils.invMassKPiPiV0 - varUtils.invMassD); - } - } + registry.fill(HIST("hMassVsPtLambda"), candidateV0.pT, candidateV0.mLambda); + switch (dType) { + case DType::Dstar: + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candidateV0.mom)); + if (varUtils.signD > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassLambda}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassLambda}); + } + if (!cfgQaPlots.applyCutsForQaHistograms || + (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin && + varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax && + candidateV0.mLambda > cfgQaPlots.cutMassLambdaMin && + candidateV0.mLambda < cfgQaPlots.cutMassLambdaMax)) { + registry.fill(HIST("hMassDstarLambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + break; + case DType::Dplus: + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassLambda}); + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, candidateV0.mom)); + if (!cfgQaPlots.applyCutsForQaHistograms || + (varUtils.invMassD > cfgQaPlots.cutMassDMin && + varUtils.invMassD < cfgQaPlots.cutMassDMax && + candidateV0.mLambda > cfgQaPlots.cutMassLambdaMin && + candidateV0.mLambda < cfgQaPlots.cutMassLambdaMax)) { + registry.fill(HIST("hMassDplusLambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + break; + case DType::D0: + if (isLambda) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassLambda}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, candidateV0.mom}, std::array{MassPiPlus, MassKPlus, MassLambda}); + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, candidateV0.mom)); + if (!cfgQaPlots.applyCutsForQaHistograms || + (varUtils.invMassD0 > cfgQaPlots.cutMassDMin && + varUtils.invMassD0 < cfgQaPlots.cutMassDMax && + candidateV0.mLambda > cfgQaPlots.cutMassLambdaMin && + candidateV0.mLambda < cfgQaPlots.cutMassLambdaMax)) { + if (isLambda) { + registry.fill(HIST("hMassD0Lambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); + } else { + registry.fill(HIST("hMassD0Lambda"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); + } + } + break; + default: + break; + } // end of dType switch + } // matched with Lambda or AntiLambda + // fill V0 table // if information on V0 already stored, go to next V0 if (!selectedV0s.count(v0.globalIndex())) { @@ -920,26 +1058,27 @@ struct HfDataCreatorCharmResoReduced { selectedV0s[v0.globalIndex()] = hfCandV0.lastIndex(); } fillHfCandD = true; - // Optional filling of MC Rec table - if constexpr (doMc) { + // Optional filling of MC Rec table, for now only implemented for Ds1->D*K0s and Ds2*->D+K0s + if constexpr (doMc && (dType == DType::Dstar || dType == DType::Dplus)) { std::vector charmResoDauTracks{}; for (const auto& track : charmHadDauTracks) { charmResoDauTracks.push_back(track); } charmResoDauTracks.push_back(trackPos); charmResoDauTracks.push_back(trackNeg); - int indexHfCandCharm = hfCandD.lastIndex() + 1; + int indexHfCandCharm = hfCandD3Pr.lastIndex() + 1; int indexHfCandV0 = hfCandV0.lastIndex(); - fillMcRecoInfo(particlesMc, charmResoDauTracks, indexHfCandCharm, indexHfCandV0); + fillMcRecoInfo(particlesMc, charmResoDauTracks, indexHfCandCharm, indexHfCandV0); } - } // V0 loop - } else if constexpr (DecayChannel == DecayChannel::DstarTrack) { - for (const auto& trackIndex : bachelors) { - auto track = trackIndex.template track_as
(); + } // end of loop on V0 candidates + } // end of do V0s + // Loop on the bachelor tracks + if constexpr (doTracks) { + for (const auto& trackIndex : bachelorTrks) { + auto track = tracks.rawIteratorAt(trackIndex.trackId()); if (!isTrackSelected(track, prongIdsD)) { continue; } - // if the track has been reassociated, re-propagate it to PV (minor difference) auto trackParCovTrack = getTrackParCov(track); std::array dcaTrack{track.dcaXY(), track.dcaZ()}; @@ -948,15 +1087,162 @@ struct HfDataCreatorCharmResoReduced { o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCovTrack, 2.f, matCorr, &dcaTrack); getPxPyPz(trackParCovTrack, pVecTrack); } - registry.fill(HIST("hdEdxVsP"), track.p(), track.tpcSignal()); - float invMassKPiPiP{0.f}; - if (candD.signSoftPi() > 0) { - invMassKPiPiP = RecoDecay::m(std::array{candD.pVectorProng0(), candD.pVectorProng1(), candD.pVecSoftPi(), pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassProton}); - } else { - invMassKPiPiP = RecoDecay::m(std::array{candD.pVectorProng1(), candD.pVectorProng0(), candD.pVecSoftPi(), pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassProton}); - } - registry.fill(HIST("hMassDstarProton"), invMassKPiPiP - varUtils.invMassD); + // compute invariant mass and filling of QA histograms + switch (dType) { + case DType::Dstar: + // D* pi + if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi) { + if (varUtils.signD > 0 && track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassPiPlus}); + } else if (varUtils.signD < 0 && track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassPiPlus}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms || + (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin && + varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax)) { + registry.fill(HIST("hMassDstarPi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } + if (std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa) { + if (varUtils.signD > 0 && track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassKPlus}); + } else if (varUtils.signD < 0 && track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassKPlus}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms || + (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin && + varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax)) { + registry.fill(HIST("hMassDstarK"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } + // D* p + if (std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr) { + if (varUtils.signD > 0 && track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassProton}); + } else if (varUtils.signD < 0 && track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassProton}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms || + (varUtils.invMassD - varUtils.invMassD0 > cfgQaPlots.cutMassDstarMin && + varUtils.invMassD - varUtils.invMassD0 < cfgQaPlots.cutMassDstarMax)) { + registry.fill(HIST("hMassDstarProton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } + break; + case DType::Dplus: + // D+ pi + if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi) { + if (varUtils.signD * track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassPiPlus}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms || + (varUtils.invMassD > cfgQaPlots.cutMassDMin && + varUtils.invMassD < cfgQaPlots.cutMassDMax)) { + registry.fill(HIST("hMassDplusPi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } + // D+ K + if (std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa) { + if (varUtils.signD * track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassKPlus}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms || + (varUtils.invMassD > cfgQaPlots.cutMassDMin && + varUtils.invMassD < cfgQaPlots.cutMassDMax)) { + registry.fill(HIST("hMassDplusK"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } + // D+ pr + if (std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr) { + if (varUtils.signD * track.sign() < 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus, MassProton}); + } else { + varUtils.invMassReso = -1.f; // invalid case + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, varUtils.pVectorProng2, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms || + (varUtils.invMassD > cfgQaPlots.cutMassDMin && + varUtils.invMassD < cfgQaPlots.cutMassDMax)) { + registry.fill(HIST("hMassDplusProton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD); + } + } + break; + case DType::D0: + // D0 pi + if (std::abs(track.tpcNSigmaPi()) < cfgSingleTrackCuts.maxNsigmaTpcPi) { + if (track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassPiPlus}); + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms || + (varUtils.invMassD0 > cfgQaPlots.cutMassDMin && + varUtils.invMassD0 < cfgQaPlots.cutMassDMax)) { + if (track.sign() > 0) { + registry.fill(HIST("hMassD0Pi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); + } else { + registry.fill(HIST("hMassD0Pi"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); + } + } + } + // D0 K + if (std::abs(track.tpcNSigmaKa()) < cfgSingleTrackCuts.maxNsigmaTpcKa) { + if (track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassKPlus}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, pVecTrack}, std::array{MassPiPlus, MassKPlus, MassKPlus}); + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms || + (varUtils.invMassD0 > cfgQaPlots.cutMassDMin && + varUtils.invMassD0 < cfgQaPlots.cutMassDMax)) { + if (track.sign() > 0) { + registry.fill(HIST("hMassD0K"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); + } else { + registry.fill(HIST("hMassD0K"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); + } + } + } + // D0 p + if (std::abs(track.tpcNSigmaPr()) < cfgSingleTrackCuts.maxNsigmaTpcPr) { + if (track.sign() > 0) { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack}, std::array{MassProton, MassKPlus, MassProton}); + } else { + varUtils.invMassReso = RecoDecay::m(std::array{varUtils.pVectorProng1, varUtils.pVectorProng0, pVecTrack}, std::array{MassProton, MassKPlus, MassProton}); + } + varUtils.ptReso = RecoDecay::pt(RecoDecay::sumOfVec(varUtils.pVectorProng0, varUtils.pVectorProng1, pVecTrack)); + if (!cfgQaPlots.applyCutsForQaHistograms || + (varUtils.invMassD0 > cfgQaPlots.cutMassDMin && + varUtils.invMassD0 < cfgQaPlots.cutMassDMax)) { + if (track.sign() > 0) { + registry.fill(HIST("hMassD0Proton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0); + } else { + registry.fill(HIST("hMassD0Proton"), varUtils.ptReso, varUtils.invMassReso - varUtils.invMassD0Bar); + } + } + } + break; + default: + break; // no other D meson types expected + } // end of DType switch + // fill track table if (!selectedTracks.count(track.globalIndex())) { hfTrackNoParam(indexHfReducedCollision, track.px(), track.py(), track.pz(), track.sign(), @@ -966,25 +1252,48 @@ struct HfDataCreatorCharmResoReduced { selectedTracks[track.globalIndex()] = hfTrackNoParam.lastIndex(); } fillHfCandD = true; - } // track loop - } - + } // end of loop on bachelor tracks + } // end of do tracks + // fill D candidate table if (fillHfCandD) { // fill candDplus table only once per D candidate, only if at least one V0 is found - hfCandD(prongIdsD[0], prongIdsD[1], prongIdsD[2], - indexHfReducedCollision, - secondaryVertexD[0], secondaryVertexD[1], secondaryVertexD[2], - candD.pxProng0(), candD.pyProng0(), candD.pzProng0(), - candD.pxProng1(), candD.pyProng1(), candD.pzProng1(), - pVecProng2[0], pVecProng2[1], pVecProng2[2], - nItsClsDauMin, nTpcCrossRowsDauMin, chi2TpcDauMax, dtype); - if constexpr (withMl) { - hfCandDMl(bdtScores[0], bdtScores[1], bdtScores[2], -1., -1., -1.); + if constexpr (dType == DType::Dstar || dType == DType::Dplus) { + hfCandD3Pr(prongIdsD[0], prongIdsD[1], prongIdsD[2], + indexHfReducedCollision, + secondaryVertexD[0], secondaryVertexD[1], secondaryVertexD[2], + candD.pxProng0(), candD.pyProng0(), candD.pzProng0(), + candD.pxProng1(), candD.pyProng1(), candD.pzProng1(), + varUtils.pVectorProng2[0], varUtils.pVectorProng2[1], varUtils.pVectorProng2[2], + nItsClsDauMin, nTpcCrossRowsDauMin, chi2TpcDauMax, dtype); + if constexpr (withMl) { + hfCandD3PrMl(bdtScores[0], bdtScores[1], bdtScores[2], bdtScores[3], bdtScores[4], bdtScores[5]); + } + } else if constexpr (dType == DType::D0) { + uint8_t selFlagD0 = {BIT(D0Sel::selectedD0) | BIT(D0Sel::selectedD0Bar)}; + if (candD.isSelD0() < cfgDmesCuts.selectionFlagD0) { + CLRBIT(selFlagD0, D0Sel::selectedD0); + } + if (candD.isSelD0bar() < cfgDmesCuts.selectionFlagD0Bar) { + CLRBIT(selFlagD0, D0Sel::selectedD0Bar); + } + hfCandD2Pr(prongIdsD[0], prongIdsD[1], + indexHfReducedCollision, + secondaryVertexD[0], secondaryVertexD[1], secondaryVertexD[2], + candD.pxProng0(), candD.pyProng0(), candD.pzProng0(), + candD.pxProng1(), candD.pyProng1(), candD.pzProng1(), + nItsClsDauMin, nTpcCrossRowsDauMin, chi2TpcDauMax, + selFlagD0); + if constexpr (withMl) { + hfCandD2PrMl(bdtScores[0], bdtScores[1], bdtScores[2], bdtScores[3], bdtScores[4], bdtScores[5]); + } } fillHfReducedCollision = true; - if constexpr (DecayChannel == DecayChannel::DstarV0 || DecayChannel == DecayChannel::DstarTrack) { - registry.fill(HIST("hMassVsPtDstarPaired"), candD.pt(), varUtils.invMassD - varUtils.invMassDdau); - } else if constexpr (DecayChannel == DecayChannel::DplusV0) { + if constexpr (dType == DType::Dstar) { + registry.fill(HIST("hMassVsPtDstarPaired"), candD.pt(), varUtils.invMassD - varUtils.invMassD0); + } else if constexpr (dType == DType::Dplus) { registry.fill(HIST("hMassVsPtDplusPaired"), candD.pt(), varUtils.invMassD); + } else if constexpr (dType == DType::D0) { + registry.fill(HIST("hMassVsPtD0Paired"), candD.pt(), varUtils.invMassD0); + registry.fill(HIST("hMassVsPtD0BarPaired"), candD.pt(), varUtils.invMassD0Bar); } registry.fill(HIST("hDType"), dtype); } @@ -999,8 +1308,9 @@ struct HfDataCreatorCharmResoReduced { uint16_t hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); // fill collision table if it contains a DPi pair a minima hfReducedCollision(collision.posX(), collision.posY(), collision.posZ(), collision.numContrib(), hfRejMap, bz); - } // run data creation + } // end of runDataCreation function + // to be modified in the future to allow for different decay channels template void runMcGen(aod::McParticles const& particlesMc) { @@ -1008,8 +1318,8 @@ struct HfDataCreatorCharmResoReduced { for (const auto& particle : particlesMc) { int8_t sign{0}; int8_t flag{0}; - int8_t signDStar{0}; - int8_t signDPlus{0}; + int8_t signDstar{0}; + int8_t signDplus{0}; int8_t signV0{0}; int8_t origin = 0; std::vector idxBhadMothers{}; @@ -1021,25 +1331,25 @@ struct HfDataCreatorCharmResoReduced { origin = RecoDecay::getCharmHadronOrigin(particlesMc, particle, false, &idxBhadMothers); registry.fill(HIST("hMCGenOrigin"), origin); auto candV0MC = particlesMc.rawIteratorAt(particle.daughtersIds().back()); - auto candDStarMC = particlesMc.rawIteratorAt(particle.daughtersIds().front()); + auto candDstarMC = particlesMc.rawIteratorAt(particle.daughtersIds().front()); // K0 -> K0s -> π+π- if (RecoDecay::isMatchedMCGen(particlesMc, candV0MC, kK0, std::array{+kPiPlus, -kPiPlus}, true, &signV0, 2)) { // D* -> D0 π+ -> K-π+π+ - if (RecoDecay::isMatchedMCGen(particlesMc, candDStarMC, Pdg::kDStar, std::array{static_cast(Pdg::kD0), +static_cast(kPiPlus)}, true, &signDStar, 1)) { - auto candD0MC = particlesMc.rawIteratorAt(candDStarMC.daughtersIds().front()); - if (RecoDecay::isMatchedMCGen(particlesMc, candDStarMC, Pdg::kDStar, std::array{-kKPlus, +kPiPlus, +kPiPlus}, true, &signDStar, 2)) { - flag = signDStar * DecayTypeMc::Ds1ToDStarK0ToD0PiK0s; - } else if (RecoDecay::isMatchedMCGen(particlesMc, candD0MC, Pdg::kD0, std::array{-kKPlus, +kPiPlus, +kPiPlus, +kPi0}, true, &signDStar, 2) || - RecoDecay::isMatchedMCGen(particlesMc, candD0MC, Pdg::kD0, std::array{-kKPlus, +kPiPlus, +kPiPlus, -kPi0}, true, &signDStar, 2)) { - flag = signDStar * DecayTypeMc::Ds1ToDStarK0ToD0PiK0sPart; + if (RecoDecay::isMatchedMCGen(particlesMc, candDstarMC, Pdg::kDStar, std::array{static_cast(Pdg::kD0), +static_cast(kPiPlus)}, true, &signDstar, 1)) { + auto candD0MC = particlesMc.rawIteratorAt(candDstarMC.daughtersIds().front()); + if (RecoDecay::isMatchedMCGen(particlesMc, candDstarMC, Pdg::kDStar, std::array{-kKPlus, +kPiPlus, +kPiPlus}, true, &signDstar, 2)) { + flag = signDstar * DecayTypeMc::Ds1ToDstarK0ToD0PiK0s; + } else if (RecoDecay::isMatchedMCGen(particlesMc, candD0MC, Pdg::kD0, std::array{-kKPlus, +kPiPlus, +kPiPlus, +kPi0}, true, &signDstar, 2) || + RecoDecay::isMatchedMCGen(particlesMc, candD0MC, Pdg::kD0, std::array{-kKPlus, +kPiPlus, +kPiPlus, -kPi0}, true, &signDstar, 2)) { + flag = signDstar * DecayTypeMc::Ds1ToDstarK0ToD0PiK0sPart; } - } else if (RecoDecay::isMatchedMCGen(particlesMc, candDStarMC, Pdg::kDStar, std::array{static_cast(Pdg::kDPlus), static_cast(kGamma)}, true, &signDStar, 1) || - RecoDecay::isMatchedMCGen(particlesMc, candDStarMC, Pdg::kDStar, std::array{static_cast(Pdg::kDPlus), -static_cast(kGamma)}, true, &signDStar, 1) || - RecoDecay::isMatchedMCGen(particlesMc, candDStarMC, Pdg::kDStar, std::array{static_cast(Pdg::kDPlus), static_cast(kPi0)}, true, &signDStar, 1) || - RecoDecay::isMatchedMCGen(particlesMc, candDStarMC, Pdg::kDStar, std::array{static_cast(Pdg::kDPlus), -static_cast(kPi0)}, true, &signDStar, 1)) { - auto candDPlusMC = particlesMc.rawIteratorAt(candDStarMC.daughtersIds().front()); - if (RecoDecay::isMatchedMCGen(particlesMc, candDPlusMC, Pdg::kDPlus, std::array{+kPiPlus, -kKPlus, +kPiPlus}, true, &signDPlus, 2)) - flag = sign * DecayTypeMc::Ds1ToDStarK0ToDPlusPi0K0s; + } else if (RecoDecay::isMatchedMCGen(particlesMc, candDstarMC, Pdg::kDStar, std::array{static_cast(Pdg::kDPlus), static_cast(kGamma)}, true, &signDstar, 1) || + RecoDecay::isMatchedMCGen(particlesMc, candDstarMC, Pdg::kDStar, std::array{static_cast(Pdg::kDPlus), -static_cast(kGamma)}, true, &signDstar, 1) || + RecoDecay::isMatchedMCGen(particlesMc, candDstarMC, Pdg::kDStar, std::array{static_cast(Pdg::kDPlus), static_cast(kPi0)}, true, &signDstar, 1) || + RecoDecay::isMatchedMCGen(particlesMc, candDstarMC, Pdg::kDStar, std::array{static_cast(Pdg::kDPlus), -static_cast(kPi0)}, true, &signDstar, 1)) { + auto candDplusMC = particlesMc.rawIteratorAt(candDstarMC.daughtersIds().front()); + if (RecoDecay::isMatchedMCGen(particlesMc, candDplusMC, Pdg::kDPlus, std::array{+kPiPlus, -kKPlus, +kPiPlus}, true, &signDplus, 2)) + flag = sign * DecayTypeMc::Ds1ToDstarK0ToDplusPi0K0s; } } } else { @@ -1077,11 +1387,11 @@ struct HfDataCreatorCharmResoReduced { origin = RecoDecay::getCharmHadronOrigin(particlesMc, particle, false, &idxBhadMothers); registry.fill(HIST("hMCGenOrigin"), origin); auto candV0MC = particlesMc.rawIteratorAt(particle.daughtersIds().back()); - auto candDPlusMC = particlesMc.rawIteratorAt(particle.daughtersIds().front()); + auto candDplusMC = particlesMc.rawIteratorAt(particle.daughtersIds().front()); // K0 -> K0s -> π+π- if (RecoDecay::isMatchedMCGen(particlesMc, candV0MC, kK0, std::array{+kPiPlus, -kPiPlus}, true, &signV0, 2)) { // D* -> D0 π+ -> K-π+π+ - if (RecoDecay::isMatchedMCGen(particlesMc, candDPlusMC, Pdg::kDPlus, std::array{+kPiPlus, -kKPlus, +kPiPlus}, true, &signDPlus, 2)) { + if (RecoDecay::isMatchedMCGen(particlesMc, candDplusMC, Pdg::kDPlus, std::array{+kPiPlus, -kKPlus, +kPiPlus}, true, &signDplus, 2)) { flag = sign * DecayTypeMc::Ds2StarToDplusK0sToPiKaPiPiPi; } } @@ -1089,21 +1399,20 @@ struct HfDataCreatorCharmResoReduced { auto candV0MC = particlesMc.rawIteratorAt(particle.daughtersIds().back()); // K0 -> K0s -> π+π- if (RecoDecay::isMatchedMCGen(particlesMc, candV0MC, kK0, std::array{+kPiPlus, -kPiPlus}, true, &signV0, 2)) { - auto candDStarMC = particlesMc.rawIteratorAt(particle.daughtersIds().front()); + auto candDstarMC = particlesMc.rawIteratorAt(particle.daughtersIds().front()); // D* -> D+ π0/γ ->π+K-π+ π0/γ - if (RecoDecay::isMatchedMCGen(particlesMc, candDStarMC, Pdg::kDStar, std::array{static_cast(Pdg::kDPlus), static_cast(kGamma)}, true, &signDStar, 1) || - RecoDecay::isMatchedMCGen(particlesMc, candDStarMC, Pdg::kDStar, std::array{static_cast(Pdg::kDPlus), -static_cast(kGamma)}, true, &signDStar, 1) || - RecoDecay::isMatchedMCGen(particlesMc, candDStarMC, Pdg::kDStar, std::array{static_cast(Pdg::kDPlus), static_cast(kPi0)}, true, &signDStar, 1) || - RecoDecay::isMatchedMCGen(particlesMc, candDStarMC, Pdg::kDStar, std::array{static_cast(Pdg::kDPlus), -static_cast(kPi0)}, true, &signDStar, 1)) { - auto candDPlusMC = particlesMc.rawIteratorAt(candDStarMC.daughtersIds().front()); - if (RecoDecay::isMatchedMCGen(particlesMc, candDPlusMC, Pdg::kDPlus, std::array{+kPiPlus, -kKPlus, +kPiPlus}, true, &signDPlus, 2)) - flag = sign * DecayTypeMc::Ds1ToDStarK0ToDPlusPi0K0s; + if (RecoDecay::isMatchedMCGen(particlesMc, candDstarMC, Pdg::kDStar, std::array{static_cast(Pdg::kDPlus), static_cast(kGamma)}, true, &signDstar, 1) || + RecoDecay::isMatchedMCGen(particlesMc, candDstarMC, Pdg::kDStar, std::array{static_cast(Pdg::kDPlus), -static_cast(kGamma)}, true, &signDstar, 1) || + RecoDecay::isMatchedMCGen(particlesMc, candDstarMC, Pdg::kDStar, std::array{static_cast(Pdg::kDPlus), static_cast(kPi0)}, true, &signDstar, 1) || + RecoDecay::isMatchedMCGen(particlesMc, candDstarMC, Pdg::kDStar, std::array{static_cast(Pdg::kDPlus), -static_cast(kPi0)}, true, &signDstar, 1)) { + auto candDplusMC = particlesMc.rawIteratorAt(candDstarMC.daughtersIds().front()); + if (RecoDecay::isMatchedMCGen(particlesMc, candDplusMC, Pdg::kDPlus, std::array{+kPiPlus, -kKPlus, +kPiPlus}, true, &signDplus, 2)) + flag = sign * DecayTypeMc::Ds1ToDstarK0ToDplusPi0K0s; } } } else { if (std::abs(particle.pdgCode()) == Pdg::kDS2Star) { origin = RecoDecay::getCharmHadronOrigin(particlesMc, particle, false, &idxBhadMothers); - // LOGF(info, "Found DS2Star that decays into %d, %d", particlesMc.rawIteratorAt(particle.daughtersIds().front()).pdgCode(),particlesMc.rawIteratorAt(particle.daughtersIds().back()).pdgCode()); registry.fill(HIST("hMCOriginCounterWrongDecay"), origin); } } @@ -1134,10 +1443,14 @@ struct HfDataCreatorCharmResoReduced { } // for loop } // gen - void processDplusV0(soa::Join const& collisions, - CandsDplusFiltered const& candsDplus, - aod::V0s const& V0s, - TracksIUWithPID const& tracks, + // Process functions + // No ML + // Data + // D* + void processDstarV0(soa::Join const& collisions, + CandsDstarFiltered const& candsDstar, + aod::V0s const& v0s, + TracksIUWithPID const& tracksIU, aod::BCsWithTimestamps const& bcs) { int zvtxColl{0}; @@ -1148,21 +1461,46 @@ struct HfDataCreatorCharmResoReduced { for (const auto& collision : collisions) { o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); - auto V0sThisColl = V0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, V0sThisColl, tracks, tracks, bcs); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, v0sThisColl, tracksIU, tracksIU, tracksIU, bcs); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0, "Process Dplus candidates paired with V0s without MC info and without ML info", true); + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0, "Process Dstar candidates paired with V0s", true); - void processDplusV0MC(soa::Join const& collisions, - CandsDplusFiltered const& candsDplus, - aod::V0s const& V0s, - TracksIUWithPIDAndMC const& tracks, - aod::McParticles const& particlesMc, - aod::BCsWithTimestamps const& bcs) + void processDstarTrack(soa::Join const& collisions, + CandsDstarFiltered const& candsDstar, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + aod::BCsWithTimestamps const& bcs) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, trackIdsThisColl, trackIdsThisColl, tracks, tracks, tracks, bcs); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarTrack, "Process Dstar candidates paired with Tracks", false); + + void processDstarV0AndTrack(soa::Join const& collisions, + CandsDstarFiltered const& candsDstar, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const& bcs) { int zvtxColl{0}; int sel8Coll{0}; @@ -1172,21 +1510,22 @@ struct HfDataCreatorCharmResoReduced { for (const auto& collision : collisions) { o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); - auto V0sThisColl = V0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, V0sThisColl, tracks, particlesMc, bcs); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, tracks, bcs); } - runMcGen(particlesMc); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0MC, "Process DPlus candidates paired with V0s with MC matching and without ML info", false); + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0AndTrack, "Process Dstar candidates paired with V0s and Tracks", false); - void processDplusV0WithMl(soa::Join const& collisions, - CandsDplusFilteredWithMl const& candsDplus, - aod::V0s const& V0s, - TracksIUWithPID const& tracks, - aod::BCsWithTimestamps const& bcs) + // Dplus + void processDplusV0(soa::Join const& collisions, + CandsDplusFiltered const& candsDplus, + aod::V0s const& v0s, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const& bcs) { int zvtxColl{0}; int sel8Coll{0}; @@ -1196,20 +1535,45 @@ struct HfDataCreatorCharmResoReduced { for (const auto& collision : collisions) { o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); - auto V0sThisColl = V0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, V0sThisColl, tracks, tracks, bcs); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, v0sThisColl, tracksIU, tracksIU, tracksIU, bcs); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0WithMl, "Process Dplus candidates paired with V0s with ML info", false); + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0, "Process Dplus candidates paired with V0s", false); - void processDplusV0MCWithMl(soa::Join const& collisions, - CandsDplusFilteredWithMl const& candsDplus, - aod::V0s const& V0s, - TracksIUWithPIDAndMC const& tracks, - aod::McParticles const& particlesMc, + void processDplusTrack(soa::Join const& collisions, + CandsDplusFiltered const& candsDplus, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + aod::BCsWithTimestamps const& bcs) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, trackIdsThisColl, trackIdsThisColl, tracks, tracks, tracks, bcs); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusTrack, "Process Dplus candidates paired with Tracks", false); + + void processDplusV0AndTrack(soa::Join const& collisions, + CandsDplusFiltered const& candsDplus, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + TracksIUWithPID const& tracksIU, aod::BCsWithTimestamps const& bcs) { int zvtxColl{0}; @@ -1221,19 +1585,43 @@ struct HfDataCreatorCharmResoReduced { o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); - auto V0sThisColl = V0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, V0sThisColl, tracks, particlesMc, bcs); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, tracks, bcs); } - runMcGen(particlesMc); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0MCWithMl, "Process DPlus candidates paired with V0s with MC matching and with ML info", false); + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0AndTrack, "Process Dplus candidates paired with V0s and Tracks", false); + + // D0 + void processD0V0(soa::Join const& collisions, + CandsD0Filtered const& candsD0, + aod::V0s const& v0s, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const& bcs) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, v0sThisColl, tracksIU, tracksIU, tracksIU, bcs); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0V0, "Process D0 candidates paired with V0s", false); - void processDstarV0(soa::Join const& collisions, - CandDstarFiltered const& candsDstar, - aod::V0s const& V0s, - TracksIUWithPID const& tracks, + void processD0Track(soa::Join const& collisions, + CandsD0Filtered const& candsD0, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, aod::BCsWithTimestamps const& bcs) { int zvtxColl{0}; @@ -1243,20 +1631,49 @@ struct HfDataCreatorCharmResoReduced { int allSelColl{0}; for (const auto& collision : collisions) { o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); - auto V0sThisColl = V0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, V0sThisColl, tracks, tracks, bcs); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, trackIdsThisColl, trackIdsThisColl, tracks, tracks, tracks, bcs); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0, "Process DStar candidates paired with V0s without MC info and without ML info", false); + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0Track, "Process D0 candidates paired with Tracks", false); + + void processD0V0AndTrack(soa::Join const& collisions, + CandsD0Filtered const& candsD0, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const& bcs) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, tracks, bcs); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0V0AndTrack, "Process D0 candidates paired with V0s and Tracks", false); + // MC + // D* void processDstarV0MC(soa::Join const& collisions, - CandDstarFiltered const& candsDstar, - aod::V0s const& V0s, - TracksIUWithPIDAndMC const& tracks, + CandsDstarFiltered const& candsDstar, + aod::V0s const& v0s, + TracksIUWithPIDAndMC const& tracksIU, aod::McParticles const& particlesMc, aod::BCsWithTimestamps const& bcs) { @@ -1269,19 +1686,50 @@ struct HfDataCreatorCharmResoReduced { o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); - auto V0sThisColl = V0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, V0sThisColl, tracks, particlesMc, bcs); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, v0sThisColl, tracksIU, tracksIU, particlesMc, bcs); } runMcGen(particlesMc); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0MC, "Process DStar candidates paired with V0s with MC matching and without ML info", false); + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0MC, "Process Dstar candidates paired with V0s with MC matching", false); + + // Dplus + void processDplusV0MC(soa::Join const& collisions, + CandsDplusFiltered const& candsDplus, + aod::V0s const& v0s, + TracksIUWithPIDAndMC const& tracksIU, + aod::McParticles const& particlesMc, + aod::BCsWithTimestamps const& bcs) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, v0sThisColl, tracksIU, tracksIU, particlesMc, bcs); + } + runMcGen(particlesMc); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0MC, "Process Dstar candidates paired with V0s with MC matching", false); + // D0 + // Not implemented yet + // ML + // Data + // D* void processDstarV0WithMl(soa::Join const& collisions, - CandDstarFilteredWithMl const& candsDstar, - aod::V0s const& V0s, - TracksIUWithPID const& tracks, + CandsDstarFilteredWithMl const& candsDstar, + aod::V0s const& v0s, + TracksIUWithPID const& tracksIU, aod::BCsWithTimestamps const& bcs) { int zvtxColl{0}; @@ -1291,23 +1739,21 @@ struct HfDataCreatorCharmResoReduced { int allSelColl{0}; for (const auto& collision : collisions) { o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); - auto thisCollId = collision.globalIndex(); auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); - auto V0sThisColl = V0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, V0sThisColl, tracks, tracks, bcs); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, v0sThisColl, tracksIU, tracksIU, tracksIU, bcs); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0WithMl, "Process DStar candidates paired with V0s with ML info", false); + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0WithMl, "Process Dstar candidates paired with V0s with ML info", false); - void processDstarV0MCWithMl(soa::Join const& collisions, - CandDstarFilteredWithMl const& candsDstar, - aod::V0s const& V0s, - TracksIUWithPIDAndMC const& tracks, - aod::McParticles const& particlesMc, - aod::BCsWithTimestamps const& bcs) + void processDstarTrackWithMl(soa::Join const& collisions, + CandsDstarFilteredWithMl const& candsDstar, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + aod::BCsWithTimestamps const& bcs) { int zvtxColl{0}; int sel8Coll{0}; @@ -1316,22 +1762,24 @@ struct HfDataCreatorCharmResoReduced { int allSelColl{0}; for (const auto& collision : collisions) { o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); - auto V0sThisColl = V0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, V0sThisColl, tracks, particlesMc, bcs); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, trackIdsThisColl, trackIdsThisColl, tracks, tracks, tracks, bcs); } - runMcGen(particlesMc); // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0MCWithMl, "Process MC DStar candidates paired with V0s with ML info", false); - - void processDstarTrack(soa::Join const& collisions, - CandDstarFiltered const& candsDstar, - aod::TrackAssoc const& trackIndices, - TracksWithPID const& tracks, - aod::BCsWithTimestamps const& bcs) + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarTrackWithMl, "Process Dstar candidates paired with Tracks with ML info", false); + + void processDstarV0AndTrackWithMl(soa::Join const& collisions, + CandsDstarFilteredWithMl const& candsDstar, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const& bcs) { int zvtxColl{0}; int sel8Coll{0}; @@ -1341,17 +1789,42 @@ struct HfDataCreatorCharmResoReduced { for (const auto& collision : collisions) { o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, trackIdsThisColl, tracks, tracks, bcs); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, tracks, bcs); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarTrack, "Process DStar candidates paired with tracks without MC info and without ML info", false); + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0AndTrackWithMl, "Process Dstar candidates paired with V0s and Tracks with ML info", false); - void processDstarTrackWithMl(soa::Join const& collisions, - CandDstarFilteredWithMl const& candsDstar, + // Dplus + void processDplusV0WithMl(soa::Join const& collisions, + CandsDplusFilteredWithMl const& candsDplus, + aod::V0s const& v0s, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const& bcs) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, v0sThisColl, tracksIU, tracksIU, tracksIU, bcs); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0WithMl, "Process Dplus candidates paired with V0s with ML info", false); + + void processDplusTrackWithMl(soa::Join const& collisions, + CandsDplusFilteredWithMl const& candsDplus, aod::TrackAssoc const& trackIndices, TracksWithPID const& tracks, aod::BCsWithTimestamps const& bcs) @@ -1365,15 +1838,169 @@ struct HfDataCreatorCharmResoReduced { o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollisionWithMl, thisCollId); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, trackIdsThisColl, trackIdsThisColl, tracks, tracks, tracks, bcs); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusTrackWithMl, "Process Dplus candidates paired with Tracks with ML info", false); + + void processDplusV0AndTrackWithMl(soa::Join const& collisions, + CandsDplusFilteredWithMl const& candsDplus, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const& bcs) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollisionWithMl, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, tracks, bcs); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0AndTrackWithMl, "Process Dplus candidates paired with V0s and Tracks with ML info", false); + + // D0 + void processD0V0WithMl(soa::Join const& collisions, + CandsD0FilteredWithMl const& candsD0, + aod::V0s const& v0s, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const& bcs) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, v0sThisColl, tracksIU, tracksIU, tracksIU, bcs); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0V0WithMl, "Process D0 candidates paired with V0s with ML info", false); + + void processD0TrackWithMl(soa::Join const& collisions, + CandsD0FilteredWithMl const& candsD0, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + aod::BCsWithTimestamps const& bcs) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); + auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, trackIdsThisColl, trackIdsThisColl, tracks, tracks, tracks, bcs); + } + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0TrackWithMl, "Process D0 candidates paired with Tracks with ML info", false); + + void processD0V0AndTrackWithMl(soa::Join const& collisions, + CandsD0FilteredWithMl const& candsD0, + aod::V0s const& v0s, + aod::TrackAssoc const& trackIndices, + TracksWithPID const& tracks, + TracksIUWithPID const& tracksIU, + aod::BCsWithTimestamps const& bcs) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD0.sliceBy(candsD0PerCollisionWithMl, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); auto trackIdsThisColl = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, trackIdsThisColl, tracks, tracks, bcs); + runDataCreation(collision, candsDThisColl, v0sThisColl, trackIdsThisColl, tracks, tracksIU, tracks, bcs); } // handle normalization by the right number of collisions hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); } - PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarTrackWithMl, "Process DStar candidates paired with tracks with ML info", false); + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processD0V0AndTrackWithMl, "Process D0 candidates paired with V0s and Tracks with ML info", false); + // MC + // D* + void processDstarV0MCWithMl(soa::Join const& collisions, + CandsDstarFilteredWithMl const& candsDstar, + aod::V0s const& v0s, + TracksIUWithPIDAndMC const& tracksIU, + aod::McParticles const& particlesMc, + aod::BCsWithTimestamps const& bcs) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDstar.sliceBy(candsDstarPerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, v0sThisColl, tracksIU, tracksIU, particlesMc, bcs); + } + runMcGen(particlesMc); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDstarV0MCWithMl, "Process Dstar candidates paired with V0s with MC matching and with ML info", false); + + // Dplus + void processDplusV0MCWithMl(soa::Join const& collisions, + CandsDplusFilteredWithMl const& candsDplus, + aod::V0s const& v0s, + TracksIUWithPIDAndMC const& tracksIU, + aod::McParticles const& particlesMc, + aod::BCsWithTimestamps const& bcs) + { + int zvtxColl{0}; + int sel8Coll{0}; + int zvtxAndSel8Coll{0}; + int zvtxAndSel8CollAndSoftTrig{0}; + int allSelColl{0}; + for (const auto& collision : collisions) { + o2::hf_evsel::checkEvSel(collision, hfEvSel, zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl, ccdb, registry); + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); + auto v0sThisColl = v0s.sliceBy(candsV0PerCollision, thisCollId); + runDataCreation(collision, candsDThisColl, v0sThisColl, v0sThisColl, tracksIU, tracksIU, particlesMc, bcs); + } + runMcGen(particlesMc); + // handle normalization by the right number of collisions + hfCollisionCounter(collisions.tableSize(), zvtxColl, sel8Coll, zvtxAndSel8Coll, zvtxAndSel8CollAndSoftTrig, allSelColl); + } + PROCESS_SWITCH(HfDataCreatorCharmResoReduced, processDplusV0MCWithMl, "Process Dplus candidates paired with V0s with MC matching and with ML info", false); + // D0 + // Not implemented yet }; // struct WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/D2H/Tasks/taskCharmPolarisation.cxx b/PWGHF/D2H/Tasks/taskCharmPolarisation.cxx index 43b75756959..95cefe1ff0f 100644 --- a/PWGHF/D2H/Tasks/taskCharmPolarisation.cxx +++ b/PWGHF/D2H/Tasks/taskCharmPolarisation.cxx @@ -1086,8 +1086,8 @@ struct TaskPolarisationCharmHadrons { bool partRecoDstar{false}; if constexpr (doMc) { if constexpr (channel == charm_polarisation::DecayChannel::DstarToDzeroPi) { - partRecoDstar = TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_dstar::DecayType::DstarToD0PiPi0) && TESTBIT(std::abs(candidate.flagMcMatchRecD0()), aod::hf_cand_dstar::DecayType::D0ToPiKPi0); - bool signalDstar = TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_dstar::DecayType::DstarToD0Pi) && TESTBIT(std::abs(candidate.flagMcMatchRecD0()), aod::hf_cand_dstar::DecayType::D0ToPiK); + partRecoDstar = std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPiPi0 && std::abs(candidate.flagMcMatchRecD0()) == hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiKPi0; + bool signalDstar = std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi && std::abs(candidate.flagMcMatchRecD0()) == hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK; if (!signalDstar && (!partRecoDstar || !activatePartRecoDstar)) { // this candidate is not signal and not partially reconstructed signal, skip return isCandidateInSignalRegion; } @@ -1099,8 +1099,8 @@ struct TaskPolarisationCharmHadrons { return isCandidateInSignalRegion; } } else if constexpr (channel == charm_polarisation::DecayChannel::LcToPKPi) { - if constexpr (!studyLcPKPiBkgMc) { // skip this if studyLcPKPiBkgMc is true, since we are interested in background - if (!TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_3prong::DecayType::LcToPKPi)) { // this candidate is not signal, skip + if constexpr (!studyLcPKPiBkgMc) { // skip this if studyLcPKPiBkgMc is true, since we are interested in background + if (std::abs(candidate.flagMcMatchRec()) != hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { // this candidate is not signal, skip return isCandidateInSignalRegion; } origin = candidate.originMcRec(); @@ -1501,7 +1501,7 @@ struct TaskPolarisationCharmHadrons { /// check if the pKpi triplet is a Lc->pKpi int8_t isRealLcPKPi = 0; - if (isRealPKPi && TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_3prong::DecayType::LcToPKPi)) { + if (isRealPKPi && (std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi)) { isRealLcPKPi = 1; } @@ -1607,8 +1607,8 @@ struct TaskPolarisationCharmHadrons { int8_t charge = -99; bool partRecoDstar{false}; if constexpr (channel == charm_polarisation::DecayChannel::DstarToDzeroPi) { - partRecoDstar = TESTBIT(std::abs(mcParticle.flagMcMatchGen()), aod::hf_cand_dstar::DecayType::DstarToD0PiPi0) && TESTBIT(std::abs(mcParticle.flagMcMatchGenD0()), aod::hf_cand_dstar::DecayType::D0ToPiKPi0); - bool signalDstar = TESTBIT(std::abs(mcParticle.flagMcMatchGen()), aod::hf_cand_dstar::DecayType::DstarToD0Pi) && TESTBIT(std::abs(mcParticle.flagMcMatchGenD0()), aod::hf_cand_dstar::DecayType::D0ToPiK); + partRecoDstar = TESTBIT(std::abs(mcParticle.flagMcMatchGen()), hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPiPi0) && TESTBIT(std::abs(mcParticle.flagMcMatchGenD0()), hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiKPi0); + bool signalDstar = TESTBIT(std::abs(mcParticle.flagMcMatchGen()), hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi) && TESTBIT(std::abs(mcParticle.flagMcMatchGenD0()), hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK); if (!signalDstar && (!activatePartRecoDstar || !partRecoDstar)) { // this particle is not signal and not partially reconstructed signal, skip return; @@ -1629,7 +1629,7 @@ struct TaskPolarisationCharmHadrons { massDau = massPi; massCharmHad = massDstar; } else if constexpr (channel == charm_polarisation::DecayChannel::LcToPKPi) { - if (!TESTBIT(std::abs(mcParticle.flagMcMatchGen()), aod::hf_cand_3prong::DecayType::LcToPKPi)) { // this particle is not signal, skip + if (std::abs(mcParticle.flagMcMatchGen()) != hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { // this particle is not signal, skip return; } origin = mcParticle.originMcGen(); diff --git a/PWGHF/D2H/Tasks/taskCharmResoReduced.cxx b/PWGHF/D2H/Tasks/taskCharmResoReduced.cxx index 078be76881c..37aef67937a 100644 --- a/PWGHF/D2H/Tasks/taskCharmResoReduced.cxx +++ b/PWGHF/D2H/Tasks/taskCharmResoReduced.cxx @@ -22,6 +22,7 @@ #include "Common/Core/RecoDecay.h" // #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/D2H/DataModel/ReducedDataModel.h" using namespace o2; diff --git a/PWGHF/D2H/Tasks/taskD0.cxx b/PWGHF/D2H/Tasks/taskD0.cxx index 0db5a832135..8e20ac90556 100644 --- a/PWGHF/D2H/Tasks/taskD0.cxx +++ b/PWGHF/D2H/Tasks/taskD0.cxx @@ -15,20 +15,21 @@ /// \author Gian Michele Innocenti , CERN /// \author Vít Kučera , CERN -#include -#include // std::min +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsAnalysis.h" +#include "PWGHF/Utils/utilsEvSelHf.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsEvSelHf.h" -#include "PWGHF/Utils/utilsAnalysis.h" +#include // std::min +#include using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/D2H/Tasks/taskDplus.cxx b/PWGHF/D2H/Tasks/taskDplus.cxx index e67ec0dfa69..59e555710ec 100644 --- a/PWGHF/D2H/Tasks/taskDplus.cxx +++ b/PWGHF/D2H/Tasks/taskDplus.cxx @@ -17,19 +17,20 @@ /// \author Vít Kučera , CERN /// \author Luca Aglietta , University and INFN Torino -#include +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsAnalysis.h" +#include "PWGHF/Utils/utilsEvSelHf.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsEvSelHf.h" -#include "PWGHF/Utils/utilsAnalysis.h" +#include using namespace o2; using namespace o2::analysis; @@ -73,12 +74,12 @@ struct HfTaskDplus { Partition selectedDPlusCandidatesWithMl = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus; // Matched MC - Partition recoDPlusCandidates = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus; - Partition recoDPlusCandidatesWithMl = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus; + Partition recoDPlusCandidates = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus; + Partition recoDPlusCandidatesWithMl = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus; // MC Bkg - Partition recoBkgCandidates = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus; - Partition recoBkgCandidatesWithMl = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus; + Partition recoBkgCandidates = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus; + Partition recoBkgCandidatesWithMl = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus; ConfigurableAxis thnConfigAxisY{"thnConfigAxisY", {40, -1, 1}, "Cand. rapidity bins"}; ConfigurableAxis thnConfigAxisCent{"thnConfigAxisCent", {110, 0., 110.}, ""}; @@ -568,7 +569,7 @@ struct HfTaskDplus { ptGenB = -1; flagGenB = -1; auto yGen = RecoDecay::y(particle.pVector(), o2::constants::physics::MassDPlus); - if ((yCandGenMax >= 0. && std::abs(yGen) > yCandGenMax) || (std::abs(particle.flagMcMatchGen()) != 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi)) { + if ((yCandGenMax >= 0. && std::abs(yGen) > yCandGenMax) || (std::abs(particle.flagMcMatchGen()) != hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi)) { continue; } if (particle.originMcGen() == RecoDecay::OriginType::NonPrompt) { diff --git a/PWGHF/D2H/Tasks/taskDs.cxx b/PWGHF/D2H/Tasks/taskDs.cxx index f8d848e596f..2b94c93f6b8 100644 --- a/PWGHF/D2H/Tasks/taskDs.cxx +++ b/PWGHF/D2H/Tasks/taskDs.cxx @@ -57,6 +57,19 @@ enum DataType { Data = 0, McBkg, kDataTypes }; +enum Mother : int8_t { + Ds, + Dplus +}; + +enum ResonantChannel : int8_t { + PhiPi = 1, + Kstar0K = 2 +}; + +static std::unordered_map> channelsResonant = {{{Mother::Ds, {{ResonantChannel::PhiPi, hf_decay::hf_cand_3prong::DecayChannelResonant::DsToPhiPi}, {ResonantChannel::Kstar0K, hf_decay::hf_cand_3prong::DecayChannelResonant::DsToKstar0K}}}, + {Mother::Dplus, {{ResonantChannel::PhiPi, hf_decay::hf_cand_3prong::DecayChannelResonant::DplusToPhiPi}, {ResonantChannel::Kstar0K, hf_decay::hf_cand_3prong::DecayChannelResonant::DplusToKstar0K}}}}}; + template concept hasDsMlInfo = requires(T candidate) { candidate.mlProbDsToKKPi(); @@ -66,7 +79,7 @@ concept hasDsMlInfo = requires(T candidate) { /// Ds± analysis task struct HfTaskDs { - Configurable decayChannel{"decayChannel", 1, "Switch between decay channels: 1 for Ds/Dplus->PhiPi->KKpi, 2 for Ds/Dplus->K0*K->KKPi"}; + Configurable decayChannel{"decayChannel", 1, "Switch between resonant decay channels: 1 for Ds/Dplus->PhiPi->KKpi, 2 for Ds/Dplus->K0*K->KKPi"}; Configurable fillDplusMc{"fillDplusMc", true, "Switch to fill Dplus MC information"}; Configurable selectionFlagDs{"selectionFlagDs", 7, "Selection Flag for Ds"}; Configurable> classMl{"classMl", {0, 2, 3}, "Indexes of ML scores to be stored. Three indexes max."}; @@ -128,7 +141,6 @@ struct HfTaskDs { ConfigurableAxis axisCentrality{"axisCentrality", {100, 0., 1.}, "axis for centrality/multiplicity"}; ConfigurableAxis axisOccupancy{"axisOccupancy", {14, 0., 14000.}, "axis for occupancy"}; - int offsetDplusDecayChannel = aod::hf_cand_3prong::DecayChannelDToKKPi::DplusToPhiPi - aod::hf_cand_3prong::DecayChannelDToKKPi::DsToPhiPi; // Offset between Dplus and Ds to use the same decay channel. See aod::hf_cand_3prong::DecayChannelDToKKPi int mRunNumber{0}; bool lCalibLoaded; TList* lCalibObjects; @@ -162,6 +174,10 @@ struct HfTaskDs { LOGP(fatal, "No process function enabled"); } + if (decayChannel != ResonantChannel::PhiPi && decayChannel != ResonantChannel::Kstar0K) { + LOGP(fatal, "Invalid value of decayChannel"); + } + AxisSpec ptbins{axisPt, "#it{p}_{T} (GeV/#it{c})"}; AxisSpec ptBHad{axisPtBHad, "#it{p}_{T}(B) (GeV/#it{c})"}; AxisSpec flagBHad{axisFlagBHad, "B Hadron flag"}; @@ -272,37 +288,37 @@ struct HfTaskDs { template bool isDsPrompt(const CandDs& candidate) { - return std::abs(candidate.flagMcMatchRec()) == static_cast(BIT(aod::hf_cand_3prong::DecayType::DsToKKPi)) && candidate.flagMcDecayChanRec() == decayChannel && candidate.originMcRec() == RecoDecay::OriginType::Prompt; + return std::abs(candidate.flagMcMatchRec()) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) && candidate.flagMcDecayChanRec() == channelsResonant[Mother::Ds][decayChannel] && candidate.originMcRec() == RecoDecay::OriginType::Prompt; } template bool isDplusPrompt(const CandDs& candidate) { - return std::abs(candidate.flagMcMatchRec()) == static_cast(BIT(aod::hf_cand_3prong::DecayType::DsToKKPi)) && candidate.flagMcDecayChanRec() == decayChannel + offsetDplusDecayChannel && candidate.originMcRec() == RecoDecay::OriginType::Prompt; + return std::abs(candidate.flagMcMatchRec()) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKK) && candidate.flagMcDecayChanRec() == channelsResonant[Mother::Dplus][decayChannel] && candidate.originMcRec() == RecoDecay::OriginType::Prompt; } template bool isDsNonPrompt(const CandDs& candidate) { - return std::abs(candidate.flagMcMatchRec()) == static_cast(BIT(aod::hf_cand_3prong::DecayType::DsToKKPi)) && candidate.flagMcDecayChanRec() == decayChannel && candidate.originMcRec() == RecoDecay::OriginType::NonPrompt; + return std::abs(candidate.flagMcMatchRec()) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) && candidate.flagMcDecayChanRec() == channelsResonant[Mother::Ds][decayChannel] && candidate.originMcRec() == RecoDecay::OriginType::NonPrompt; } template bool isDplusNonPrompt(const CandDs& candidate) { - return std::abs(candidate.flagMcMatchRec()) == static_cast(BIT(aod::hf_cand_3prong::DecayType::DsToKKPi)) && candidate.flagMcDecayChanRec() == decayChannel + offsetDplusDecayChannel && candidate.originMcRec() == RecoDecay::OriginType::NonPrompt; + return std::abs(candidate.flagMcMatchRec()) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKK) && candidate.flagMcDecayChanRec() == channelsResonant[Mother::Dplus][decayChannel] && candidate.originMcRec() == RecoDecay::OriginType::NonPrompt; } template bool isDplusBkg(const CandDs& candidate) { - return std::abs(candidate.flagMcMatchRec()) == static_cast(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)); + return std::abs(candidate.flagMcMatchRec()) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi); } template bool isLcBkg(const CandDs& candidate) { - return std::abs(candidate.flagMcMatchRec()) == static_cast(BIT(aod::hf_cand_3prong::DecayType::LcToPKPi)); + return std::abs(candidate.flagMcMatchRec()) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi); } /// Checks whether the candidate is in the signal region of either the Ds or D+ decay @@ -673,9 +689,9 @@ struct HfTaskDs { // MC gen. for (const auto& particle : mcParticles) { - if (std::abs(particle.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::DsToKKPi) { + if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK || std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKK) { const auto& recoCollsPerMcColl = recoCollisions.sliceBy(colPerMcCollision, particle.mcCollision().globalIndex()); - if (particle.flagMcDecayChanGen() == decayChannel || (fillDplusMc && particle.flagMcDecayChanGen() == (decayChannel + offsetDplusDecayChannel))) { + if (particle.flagMcDecayChanGen() == channelsResonant[Mother::Ds][decayChannel] || (fillDplusMc && particle.flagMcDecayChanGen() == channelsResonant[Mother::Dplus][decayChannel])) { auto pt = particle.pt(); double y{0.f}; @@ -689,7 +705,7 @@ struct HfTaskDs { occ = o2::hf_occupancy::getOccupancyGenColl(recoCollsPerMcColl, occEstimator); } - if (particle.flagMcDecayChanGen() == decayChannel) { + if (particle.flagMcDecayChanGen() == channelsResonant[Mother::Ds][decayChannel]) { y = RecoDecay::y(particle.pVector(), o2::constants::physics::MassDS); if (yCandGenMax >= 0. && std::abs(y) > yCandGenMax) { continue; diff --git a/PWGHF/D2H/Tasks/taskDstarToD0Pi.cxx b/PWGHF/D2H/Tasks/taskDstarToD0Pi.cxx index eaadbab783c..0682c0584aa 100644 --- a/PWGHF/D2H/Tasks/taskDstarToD0Pi.cxx +++ b/PWGHF/D2H/Tasks/taskDstarToD0Pi.cxx @@ -313,8 +313,8 @@ struct HfTaskDstarToD0Pi { continue; } auto collision = candDstarMcRec.template collision_as(); - auto centrality = collision.centFT0M(); // 0-100% - if (TESTBIT(std::abs(candDstarMcRec.flagMcMatchRec()), aod::hf_cand_dstar::DecayType::DstarToD0Pi)) { // if MC matching is successful at Reconstruction Level + auto centrality = collision.centFT0M(); // 0-100% + if (std::abs(candDstarMcRec.flagMcMatchRec()) == hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi) { // if MC matching is successful at Reconstruction Level // LOGF(info, "MC Rec Dstar loop MC Matched"); // get MC Mother particle auto prong0 = candDstarMcRec.template prong0_as(); @@ -392,7 +392,7 @@ struct HfTaskDstarToD0Pi { { // MC Gen level for (auto const& mcParticle : rowsMcPartilces) { - if (TESTBIT(std::abs(mcParticle.flagMcMatchGen()), aod::hf_cand_dstar::DecayType::DstarToD0Pi)) { // MC Matching is successful at Generator Level + if (std::abs(mcParticle.flagMcMatchGen()) == hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi) { // MC Matching is successful at Generator Level auto ptGen = mcParticle.pt(); auto yGen = RecoDecay::y(mcParticle.pVector(), o2::constants::physics::MassDStar); if (yCandDstarGenMax >= 0. && std::abs(yGen) > yCandDstarGenMax) { diff --git a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx index 862b4910c72..03e475bc7ed 100644 --- a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx +++ b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx @@ -14,6 +14,7 @@ /// /// \author S. Politanò, INFN Torino, Italy /// \author Wu Chuntai, CUG, China +/// \author Ran Tu, Fudan University, China #include #include @@ -48,7 +49,8 @@ enum DecayChannel { DplusToPiKPi = 0, LcToPKPi, LcToPiKP, XicToPKPi, - XicToPiKP + XicToPiKP, + Xic0ToXiPi }; enum QvecEstimator { FV0A = 0, @@ -75,25 +77,11 @@ struct HfTaskFlowCharmHadrons { Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable> classMl{"classMl", {0, 2}, "Indexes of BDT scores to be stored. Two indexes max."}; - ConfigurableAxis thnConfigAxisInvMass{"thnConfigAxisInvMass", {100, 1.78, 2.05}, ""}; - ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {10, 0., 10.}, ""}; - ConfigurableAxis thnConfigAxisCent{"thnConfigAxisCent", {10000, 0., 100.}, ""}; - ConfigurableAxis thnConfigAxisCosNPhi{"thnConfigAxisCosNPhi", {100, -1., 1.}, ""}; - ConfigurableAxis thnConfigAxisPsi{"thnConfigAxisPsi", {6000, 2. * TMath::Pi(), 2. * TMath::Pi()}, ""}; - ConfigurableAxis thnConfigAxisCosDeltaPhi{"thnConfigAxisCosDeltaPhi", {100, -1., 1.}, ""}; - ConfigurableAxis thnConfigAxisScalarProd{"thnConfigAxisScalarProd", {100, 0., 1.}, ""}; - ConfigurableAxis thnConfigAxisMlOne{"thnConfigAxisMlOne", {1000, 0., 1.}, ""}; - ConfigurableAxis thnConfigAxisMlTwo{"thnConfigAxisMlTwo", {1000, 0., 1.}, ""}; - ConfigurableAxis thnConfigAxisOccupancyITS{"thnConfigAxisOccupancyITS", {14, 0, 14000}, ""}; - ConfigurableAxis thnConfigAxisOccupancyFT0C{"thnConfigAxisOccupancyFT0C", {14, 0, 140000}, ""}; - ConfigurableAxis thnConfigAxisNoSameBunchPileup{"thnConfigAxisNoSameBunchPileup", {2, 0, 2}, ""}; - ConfigurableAxis thnConfigAxisOccupancy{"thnConfigAxisOccupancy", {2, 0, 2}, ""}; - ConfigurableAxis thnConfigAxisNoCollInTimeRangeNarrow{"thnConfigAxisNoCollInTimeRangeNarrow", {2, 0, 2}, ""}; - ConfigurableAxis thnConfigAxisNoCollInTimeRangeStandard{"thnConfigAxisNoCollInTimeRangeStandard", {2, 0, 2}, ""}; - ConfigurableAxis thnConfigAxisNoCollInRofStandard{"thnConfigAxisNoCollInRofStandard", {2, 0, 2}, ""}; - ConfigurableAxis thnConfigAxisResoFT0cFV0a{"thnConfigAxisResoFT0cFV0a", {160, -8, 8}, ""}; - ConfigurableAxis thnConfigAxisResoFT0cTPCtot{"thnConfigAxisResoFT0cTPCtot", {160, -8, 8}, ""}; - ConfigurableAxis thnConfigAxisResoFV0aTPCtot{"thnConfigAxisResoFV0aTPCtot", {160, -8, 8}, ""}; + HfHelper hfHelper; + EventPlaneHelper epHelper; + HfEventSelection hfEvSel; // event selection and monitoring + o2::framework::Service ccdb; + SliceCache cache; using CandDsDataWMl = soa::Filtered>; using CandDsData = soa::Filtered>; @@ -103,6 +91,8 @@ struct HfTaskFlowCharmHadrons { using CandLcDataWMl = soa::Filtered>; using CandXicData = soa::Filtered>; using CandXicDataWMl = soa::Filtered>; + using CandXic0Data = soa::Filtered>; + using CandXic0DataWMl = soa::Filtered>; using CandD0DataWMl = soa::Filtered>; using CandD0Data = soa::Filtered>; using CollsWithQvecs = soa::Join; @@ -112,6 +102,7 @@ struct HfTaskFlowCharmHadrons { Filter filterSelectD0Candidates = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag; Filter filterSelectLcCandidates = aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlag || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlag; Filter filterSelectXicCandidates = aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlag || aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlag; + Filter filterSelectXic0Candidates = aod::hf_sel_toxipi::resultSelections >= selectionFlag; Partition selectedDsToKKPi = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag; Partition selectedDsToPiKK = aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; @@ -129,12 +120,28 @@ struct HfTaskFlowCharmHadrons { Partition selectedXicToPiKP = aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlag; Partition selectedXicToPKPiWMl = aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlag; Partition selectedXicToPiKPWMl = aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlag; + Partition selectedXic0 = aod::hf_sel_toxipi::resultSelections >= selectionFlag; + Partition selectedXic0WMl = aod::hf_sel_toxipi::resultSelections >= selectionFlag; - SliceCache cache; - HfHelper hfHelper; - EventPlaneHelper epHelper; - HfEventSelection hfEvSel; // event selection and monitoring - o2::framework::Service ccdb; + ConfigurableAxis thnConfigAxisInvMass{"thnConfigAxisInvMass", {100, 1.78, 2.05}, ""}; + ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {10, 0., 10.}, ""}; + ConfigurableAxis thnConfigAxisCent{"thnConfigAxisCent", {10000, 0., 100.}, ""}; + ConfigurableAxis thnConfigAxisCosNPhi{"thnConfigAxisCosNPhi", {100, -1., 1.}, ""}; + ConfigurableAxis thnConfigAxisPsi{"thnConfigAxisPsi", {6000, 0, constants::math::TwoPI}, ""}; + ConfigurableAxis thnConfigAxisCosDeltaPhi{"thnConfigAxisCosDeltaPhi", {100, -1., 1.}, ""}; + ConfigurableAxis thnConfigAxisScalarProd{"thnConfigAxisScalarProd", {100, 0., 1.}, ""}; + ConfigurableAxis thnConfigAxisMlOne{"thnConfigAxisMlOne", {1000, 0., 1.}, ""}; + ConfigurableAxis thnConfigAxisMlTwo{"thnConfigAxisMlTwo", {1000, 0., 1.}, ""}; + ConfigurableAxis thnConfigAxisOccupancyITS{"thnConfigAxisOccupancyITS", {14, 0, 14000}, ""}; + ConfigurableAxis thnConfigAxisOccupancyFT0C{"thnConfigAxisOccupancyFT0C", {14, 0, 140000}, ""}; + ConfigurableAxis thnConfigAxisNoSameBunchPileup{"thnConfigAxisNoSameBunchPileup", {2, 0, 2}, ""}; + ConfigurableAxis thnConfigAxisOccupancy{"thnConfigAxisOccupancy", {2, 0, 2}, ""}; + ConfigurableAxis thnConfigAxisNoCollInTimeRangeNarrow{"thnConfigAxisNoCollInTimeRangeNarrow", {2, 0, 2}, ""}; + ConfigurableAxis thnConfigAxisNoCollInTimeRangeStandard{"thnConfigAxisNoCollInTimeRangeStandard", {2, 0, 2}, ""}; + ConfigurableAxis thnConfigAxisNoCollInRofStandard{"thnConfigAxisNoCollInRofStandard", {2, 0, 2}, ""}; + ConfigurableAxis thnConfigAxisResoFT0cFV0a{"thnConfigAxisResoFT0cFV0a", {160, -8, 8}, ""}; + ConfigurableAxis thnConfigAxisResoFT0cTPCtot{"thnConfigAxisResoFT0cTPCtot", {160, -8, 8}, ""}; + ConfigurableAxis thnConfigAxisResoFV0aTPCtot{"thnConfigAxisResoFV0aTPCtot", {160, -8, 8}, ""}; HistogramRegistry registry{"registry", {}}; @@ -231,15 +238,15 @@ struct HfTaskFlowCharmHadrons { } if (storeResoOccu) { - std::vector axes_reso = {thnAxisCent, thnAxisResoFT0cFV0a, thnAxisResoFT0cTPCtot, thnAxisResoFV0aTPCtot}; + std::vector axesReso = {thnAxisCent, thnAxisResoFT0cFV0a, thnAxisResoFT0cTPCtot, thnAxisResoFV0aTPCtot}; if (occEstimator == 1) { - axes_reso.insert(axes_reso.end(), {thnAxisOccupancyITS, thnAxisNoSameBunchPileup, thnAxisOccupancy, - thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard}); + axesReso.insert(axesReso.end(), {thnAxisOccupancyITS, thnAxisNoSameBunchPileup, thnAxisOccupancy, + thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard}); } else { - axes_reso.insert(axes_reso.end(), {thnAxisOccupancyFT0C, thnAxisNoSameBunchPileup, thnAxisOccupancy, - thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard}); + axesReso.insert(axesReso.end(), {thnAxisOccupancyFT0C, thnAxisNoSameBunchPileup, thnAxisOccupancy, + thnAxisNoCollInTimeRangeNarrow, thnAxisNoCollInTimeRangeStandard, thnAxisNoCollInRofStandard}); } - registry.add("spReso/hSparseReso", "THn for resolution with occupancy", HistType::kTHnSparseF, axes_reso); + registry.add("spReso/hSparseReso", "THn for resolution with occupancy", HistType::kTHnSparseF, axesReso); } hfEvSel.addHistograms(registry); // collision monitoring @@ -285,6 +292,44 @@ struct HfTaskFlowCharmHadrons { } } + /// Compute the Q vector for the candidate's tracks + /// \param cand is the candidate + /// \param tracksQx is the X component of the Q vector for the tracks + /// \param tracksQy is the Y component of the Q vector for the tracks + /// \param channel is the decay channel + template + void getQvecXic0Tracks(const T1& cand, + std::vector& tracksQx, + std::vector& tracksQy, + float ampl) + { + // add possibility to consider different weights for the tracks, at the moment only pT is considered; + float pXTrack0 = cand.pxPosV0Dau(); + float pYTrack0 = cand.pyPosV0Dau(); + float pTTrack0 = std::hypot(pXTrack0, pYTrack0); + float phiTrack0 = std::atan2(pXTrack0, pYTrack0); + float pXTrack1 = cand.pxNegV0Dau(); + float pYTrack1 = cand.pyNegV0Dau(); + float pTTrack1 = std::hypot(pXTrack1, pYTrack1); + float phiTrack1 = std::atan2(pXTrack1, pYTrack1); + float pYTrack2 = cand.pxBachFromCasc(); + float pXTrack2 = cand.pyBachFromCasc(); + float pTTrack2 = std::hypot(pXTrack2, pYTrack2); + float phiTrack2 = std::atan2(pXTrack2, pYTrack2); + float pXTrack3 = cand.pxBachFromCharmBaryon(); + float pYTrack3 = cand.pyBachFromCharmBaryon(); + float pTTrack3 = std::hypot(pXTrack3, pYTrack3); + float phiTrack3 = std::atan2(pXTrack3, pYTrack3); + + tracksQx.push_back(std::cos(harmonic * phiTrack0) * pTTrack0 / ampl); + tracksQy.push_back(std::sin(harmonic * phiTrack0) * pTTrack0 / ampl); + tracksQx.push_back(std::cos(harmonic * phiTrack1) * pTTrack1 / ampl); + tracksQy.push_back(std::sin(harmonic * phiTrack1) * pTTrack1 / ampl); + tracksQx.push_back(std::cos(harmonic * phiTrack2) * pTTrack2 / ampl); + tracksQy.push_back(std::sin(harmonic * phiTrack2) * pTTrack2 / ampl); + tracksQx.push_back(std::cos(harmonic * phiTrack3) * pTTrack3 / ampl); + tracksQy.push_back(std::sin(harmonic * phiTrack3) * pTTrack3 / ampl); + } /// Compute the delta psi in the range [0, pi/harmonic] /// \param psi1 is the first angle /// \param psi2 is the second angle @@ -292,12 +337,7 @@ struct HfTaskFlowCharmHadrons { float getDeltaPsiInRange(float psi1, float psi2) { float deltaPsi = psi1 - psi2; - if (std::abs(deltaPsi) > constants::math::PI / harmonic) { - if (deltaPsi > 0.) - deltaPsi -= constants::math::TwoPI / harmonic; - else - deltaPsi += constants::math::TwoPI / harmonic; - } + deltaPsi = RecoDecay::constrainAngle(deltaPsi, -o2::constants::math::PI / harmonic, harmonic); return deltaPsi; } @@ -552,18 +592,36 @@ struct HfTaskFlowCharmHadrons { default: break; } + } else if constexpr (std::is_same_v || std::is_same_v) { + massCand = candidate.invMassCharmBaryon(); + if constexpr (std::is_same_v) { + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) + outputMl[iclass] = candidate.mlProbToXiPi()[classMl->at(iclass)]; + } } - float ptCand = candidate.pt(); - float phiCand = candidate.phi(); + float ptCand = 0.; + float phiCand = 0.; + + if constexpr (std::is_same_v || std::is_same_v) { + ptCand = candidate.kfptXic(); + phiCand = std::atan2(candidate.pxCharmBaryon(), candidate.pyCharmBaryon()); + } else { + ptCand = candidate.pt(); + phiCand = candidate.phi(); + } // If TPC is used for the SP estimation, the tracks of the hadron candidate must be removed from the TPC Q vector to avoid double counting if (qvecDetector == QvecEstimator::TPCNeg || qvecDetector == QvecEstimator::TPCPos) { float ampl = amplQVec - static_cast(nProngs); std::vector tracksQx = {}; std::vector tracksQy = {}; - - getQvecDtracks(candidate, tracksQx, tracksQy, ampl); + if constexpr (std::is_same_v || std::is_same_v) { + // std::cout<(candidate, tracksQx, tracksQy, ampl); + } for (auto iTrack{0u}; iTrack < tracksQx.size(); ++iTrack) { xQVec -= tracksQx[iTrack]; yQVec -= tracksQy[iTrack]; @@ -683,6 +741,24 @@ struct HfTaskFlowCharmHadrons { } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXic, "Process Xic candidates", false); + // Xic0 with ML + void processXic0Ml(CollsWithQvecs::iterator const& collision, + CandXic0DataWMl const&) + { + auto candsXic0WMl = selectedXic0WMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + runFlowAnalysis(collision, candsXic0WMl); + } + PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXic0Ml, "Process Xic0 candidates with ML", false); + + // Xic0 + void processXic0(CollsWithQvecs::iterator const& collision, + CandXic0Data const&) + { + auto candsXic0 = selectedXic0->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + runFlowAnalysis(collision, candsXic0); + } + PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXic0, "Process Xic0 candidates", false); + // Resolution void processResolution(CollsWithQvecs::iterator const& collision, aod::BCsWithTimestamps const& bcs) diff --git a/PWGHF/D2H/Tasks/taskLc.cxx b/PWGHF/D2H/Tasks/taskLc.cxx index be75dc055bf..2411f630c87 100644 --- a/PWGHF/D2H/Tasks/taskLc.cxx +++ b/PWGHF/D2H/Tasks/taskLc.cxx @@ -18,18 +18,19 @@ /// \author Annalena Kalteyer , GSI Darmstadt /// \author Biao Zhang , Heidelberg University -#include // std::vector +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsEvSelHf.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsEvSelHf.h" +#include // std::vector using namespace o2; using namespace o2::analysis; @@ -375,7 +376,7 @@ struct HfTaskLc { continue; } - if (std::abs(candidate.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::LcToPKPi) { + if (std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { // Get the corresponding MC particle. auto mcParticleProng0 = candidate.template prong0_as().template mcParticle_as>(); auto pdgCodeProng0 = std::abs(mcParticleProng0.pdgCode()); @@ -588,7 +589,7 @@ struct HfTaskLc { { // MC gen. for (const auto& particle : mcParticles) { - if (std::abs(particle.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::LcToPKPi) { + if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { auto yGen = RecoDecay::y(particle.pVector(), o2::constants::physics::MassLambdaCPlus); if (yCandGenMax >= 0. && std::abs(yGen) > yCandGenMax) { continue; diff --git a/PWGHF/D2H/Tasks/taskLcToK0sP.cxx b/PWGHF/D2H/Tasks/taskLcToK0sP.cxx index 3c373a59f72..157f73fce52 100644 --- a/PWGHF/D2H/Tasks/taskLcToK0sP.cxx +++ b/PWGHF/D2H/Tasks/taskLcToK0sP.cxx @@ -17,15 +17,16 @@ /// /// \note based on taskD0.cxx, taskLc.cxx -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/D2H/Tasks/taskOmegac0ToOmegapi.cxx b/PWGHF/D2H/Tasks/taskOmegac0ToOmegapi.cxx index 7142b2d2e49..ad6ce06b649 100644 --- a/PWGHF/D2H/Tasks/taskOmegac0ToOmegapi.cxx +++ b/PWGHF/D2H/Tasks/taskOmegac0ToOmegapi.cxx @@ -14,18 +14,19 @@ /// \author Yunfan Liu , China University of Geosciences /// \author Fabio Catalano , University of Houston -#include +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsEvSelHf.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsEvSelHf.h" +#include using namespace o2; using namespace o2::analysis; @@ -37,6 +38,7 @@ using namespace o2::framework::expressions; struct HfTaskOmegac0ToOmegapi { // ML inference Configurable applyMl{"applyMl", false, "Flag to apply ML selections"}; + Configurable fillCent{"fillCent", false, "Flag to fill centrality information"}; Configurable selectionFlagOmegac0{"selectionFlagOmegac0", true, "Select Omegac0 candidates"}; Configurable yCandGenMax{"yCandGenMax", 0.5, "max. gen particle rapidity"}; Configurable yCandRecoMax{"yCandRecoMax", 0.8, "max. cand. rapidity"}; @@ -57,20 +59,26 @@ struct HfTaskOmegac0ToOmegapi { using Omegac0Gen = soa::Filtered>; using Collisions = soa::Join; + using CollisionsWithFT0C = soa::Join; + using CollisionsWithFT0M = soa::Join; using CollisionsWithMcLabels = soa::Join; Filter filterOmegaCToOmegaPiFlag = (aod::hf_track_index::hfflag & static_cast(BIT(aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi))) != static_cast(0); Filter filterOmegaCMatchedRec = nabs(aod::hf_cand_xic0_omegac0::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPi)); Filter filterOmegaCMatchedGen = nabs(aod::hf_cand_xic0_omegac0::flagMcMatchGen) == static_cast(BIT(aod::hf_cand_xic0_omegac0::DecayType::OmegaczeroToOmegaPi)); + Preslice candOmegacKFPerCollision = aod::hf_cand_xic0_omegac0::collisionId; + Preslice candOmegacKFMlPerCollision = aod::hf_cand_xic0_omegac0::collisionId; PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; // ThnSparse for ML outputScores and Vars - ConfigurableAxis thnConfigAxisPromptScore{"thnConfigAxisPromptScore", {50, 0, 1}, "Prompt score bins"}; + ConfigurableAxis thnConfigAxisPromptScore{"thnConfigAxisPromptScore", {100, 0, 1}, "Prompt score bins"}; ConfigurableAxis thnConfigAxisMass{"thnConfigAxisMass", {120, 2.4, 3.1}, "Cand. inv-mass bins"}; ConfigurableAxis thnConfigAxisPtB{"thnConfigAxisPtB", {1000, 0, 100}, "Cand. beauty mother pTB bins"}; ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {100, 0, 20}, "Cand. pT bins"}; ConfigurableAxis thnConfigAxisY{"thnConfigAxisY", {20, -1, 1}, "Cand. rapidity bins"}; + ConfigurableAxis thnConfigAxisCent{"thnConfigAxisCent", {100, 0, 100}, "Centrality bins"}; + ConfigurableAxis thnConfigAxisPtPion{"thnConfigAxisPtPion", {100, 0, 10}, "PtPion from Omegac0 bins"}; ConfigurableAxis thnConfigAxisOrigin{"thnConfigAxisOrigin", {3, -0.5, 2.5}, "Cand. origin type"}; ConfigurableAxis thnConfigAxisMatchFlag{"thnConfigAxisMatchFlag", {15, -7.5, 7.5}, "Cand. MC Match Flag type"}; ConfigurableAxis thnConfigAxisGenPtD{"thnConfigAxisGenPtD", {500, 0, 50}, "Gen Pt D"}; @@ -80,7 +88,7 @@ struct HfTaskOmegac0ToOmegapi { void init(InitContext&) { - std::array doprocess{doprocessDataWithKFParticle, doprocessMcWithKFParticle, doprocessDataWithKFParticleMl, doprocessMcWithKFParticleMl}; + std::array doprocess{doprocessDataWithKFParticle, doprocessMcWithKFParticle, doprocessDataWithKFParticleMl, doprocessMcWithKFParticleMl, doprocessDataWithKFParticleFT0C, doprocessDataWithKFParticleMlFT0C, doprocessDataWithKFParticleFT0M, doprocessDataWithKFParticleMlFT0M}; if ((std::accumulate(doprocess.begin(), doprocess.end(), 0)) != 1) { LOGP(fatal, "One and only one process function should be enabled at a time."); } @@ -117,6 +125,26 @@ struct HfTaskOmegac0ToOmegapi { registry.add("hMassVsPtVsPtBVsYVsOriginVsOmegac0Type", "Thn for Omegac0 candidates", HistType::kTHnSparseF, axes); registry.get(HIST("hMassVsPtVsPtBVsYVsOriginVsOmegac0Type"))->Sumw2(); } + if (fillCent) { + const AxisSpec thnAxisPromptScore{thnConfigAxisPromptScore, "BDT score prompt."}; + const AxisSpec thnAxisCent{thnConfigAxisCent, "Centrality."}; + const AxisSpec thnAxisPtPion{thnConfigAxisPtPion, "Pt of Pion from Omegac0."}; + std::vector axesWithBdtCent = {thnAxisPromptScore, thnAxisMass, thnAxisPt, thnAxisY, thnAxisCent, thnAxisPtPion, thnConfigAxisNumPvContr}; + std::vector axesWithCent = {thnAxisMass, thnAxisPt, thnAxisY, thnAxisCent, thnAxisPtPion, thnConfigAxisNumPvContr}; + registry.add("hBdtScoreVsMassVsPtVsYVsCentVsPtPion", "Thn for Omegac0 candidates with BDT&Cent&pTpi", HistType::kTHnSparseD, axesWithBdtCent); + registry.add("hMassVsPtVsYVsCentVsPtPion", "Thn for Omegac0 candidates with Cent&pTpi", HistType::kTHnSparseD, axesWithCent); + registry.get(HIST("hBdtScoreVsMassVsPtVsYVsCentVsPtPion"))->Sumw2(); + registry.get(HIST("hMassVsPtVsYVsCentVsPtPion"))->Sumw2(); + } + } + + /// Evaluate centrality/multiplicity percentile (centrality estimator is automatically selected based on the used table) + /// \param candidate is candidate + /// \return centrality/multiplicity percentile of the collision + template + float evaluateCentralityColl(const Coll& collision) + { + return o2::hf_centrality::getCentralityColl(collision); } template @@ -138,6 +166,47 @@ struct HfTaskOmegac0ToOmegapi { } } + template + void processDataCent(const CandType& candidates, CollType const& collisions) + { + for (const auto& collision : collisions) { + + auto thisCollId = collision.globalIndex(); + auto groupedOmegacCandidates = applyMl + ? candidates.sliceBy(candOmegacKFMlPerCollision, thisCollId) + : candidates.sliceBy(candOmegacKFPerCollision, thisCollId); + auto numPvContributors = collision.numContrib(); + + for (const auto& candidate : groupedOmegacCandidates) { + if (!(candidate.resultSelections() == true || (candidate.resultSelections() == false && !selectionFlagOmegac0))) { + continue; + } + if (yCandRecoMax >= 0. && std::abs(candidate.kfRapOmegac()) > yCandRecoMax) { + continue; + } + float cent = evaluateCentralityColl(collision); + if constexpr (applyMl) { + registry.fill(HIST("hBdtScoreVsMassVsPtVsYVsCentVsPtPion"), + candidate.mlProbOmegac()[0], + candidate.invMassCharmBaryon(), + candidate.ptCharmBaryon(), + candidate.kfRapOmegac(), + cent, + candidate.kfptPiFromOmegac(), + numPvContributors); + } else { + registry.fill(HIST("hMassVsPtVsYVsCentVsPtPion"), + candidate.invMassCharmBaryon(), + candidate.ptCharmBaryon(), + candidate.kfRapOmegac(), + cent, + candidate.kfptPiFromOmegac(), + numPvContributors); + } + } + } + } + template void processMc(const CandType& candidates, Omegac0Gen const& mcParticles, @@ -202,6 +271,34 @@ struct HfTaskOmegac0ToOmegapi { } PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processDataWithKFParticleMl, "process HfTaskOmegac0ToOmegapi with KFParticle and ML selections", false); + void processDataWithKFParticleFT0C(Omegac0CandsKF const& candidates, + CollisionsWithFT0C const& collisions) + { + processDataCent(candidates, collisions); + } + PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processDataWithKFParticleFT0C, "process HfTaskOmegac0ToOmegapi with KFParticle and with FT0C centrality", false); + + void processDataWithKFParticleMlFT0C(Omegac0CandsMlKF const& candidates, + CollisionsWithFT0C const& collisions) + { + processDataCent(candidates, collisions); + } + PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processDataWithKFParticleMlFT0C, "process HfTaskOmegac0ToOmegapi with KFParticle and ML selections and with FT0C centrality", false); + + void processDataWithKFParticleFT0M(Omegac0CandsKF const& candidates, + CollisionsWithFT0M const& collisions) + { + processDataCent(candidates, collisions); + } + PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processDataWithKFParticleFT0M, "process HfTaskOmegac0ToOmegapi with KFParticle and with FT0M centrality", false); + + void processDataWithKFParticleMlFT0M(Omegac0CandsMlKF const& candidates, + CollisionsWithFT0M const& collisions) + { + processDataCent(candidates, collisions); + } + PROCESS_SWITCH(HfTaskOmegac0ToOmegapi, processDataWithKFParticleMlFT0M, "process HfTaskOmegac0ToOmegapi with KFParticle and ML selections and with FT0M centrality", false); + void processMcWithKFParticle(OmegaC0CandsMcKF const& omegaC0CandidatesMcKF, Omegac0Gen const& mcParticles, TracksMc const& tracks, diff --git a/PWGHF/D2H/Tasks/taskSigmac.cxx b/PWGHF/D2H/Tasks/taskSigmac.cxx index 39011a4a44d..dff39af4c28 100644 --- a/PWGHF/D2H/Tasks/taskSigmac.cxx +++ b/PWGHF/D2H/Tasks/taskSigmac.cxx @@ -726,13 +726,13 @@ struct HfTaskSigmac { /// loop over Lc generated particles for (const auto& particle : mcParticlesLc) { - if (std::abs(particle.flagMcMatchGen()) != BIT(aod::hf_cand_3prong::DecayType::LcToPKPi)) { + if (std::abs(particle.flagMcMatchGen()) != hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { continue; } if (yCandGenMax >= 0. && std::abs(RecoDecay::y(particle.pVector(), o2::constants::physics::MassLambdaCPlus)) > yCandGenMax) { continue; } - double ptGenLc(-1.), ptGenLcBMother(-1.); + double ptGenLc(particle.pt()), ptGenLcBMother(-1.); int origin = particle.originMcGen(); int channel = particle.flagMcDecayChanGen(); if (origin == RecoDecay::OriginType::Prompt) { @@ -1149,7 +1149,7 @@ struct HfTaskSigmac { if (enableTHn) { /// loop over Λc+ candidates w/o Σc0,++ mass-window cut for (const auto& candidateLc : candidatesLc) { - if (!TESTBIT(std::abs(candidateLc.flagMcMatchRec()), aod::hf_cand_3prong::DecayType::LcToPKPi)) { + if (std::abs(candidateLc.flagMcMatchRec()) != hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { continue; } double massLc(-1.); diff --git a/PWGHF/D2H/Tasks/taskSigmacToCascade.cxx b/PWGHF/D2H/Tasks/taskSigmacToCascade.cxx index 279c9322b0e..50229ee2959 100644 --- a/PWGHF/D2H/Tasks/taskSigmacToCascade.cxx +++ b/PWGHF/D2H/Tasks/taskSigmacToCascade.cxx @@ -15,19 +15,20 @@ /// \author Rutuparna Rath , INFN BOLOGNA and GSI Darmstadt /// In collaboration with Andrea Alici , INFN BOLOGNA -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" + +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectionDefaults.h" - -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/D2H/Tasks/taskXic.cxx b/PWGHF/D2H/Tasks/taskXic.cxx index 00b513cd1a4..4e4ca72c019 100644 --- a/PWGHF/D2H/Tasks/taskXic.cxx +++ b/PWGHF/D2H/Tasks/taskXic.cxx @@ -19,7 +19,10 @@ /// \author Himanshu Sharma , University and INFN Padova /// \author Cristina Terrevoli , INFN Bari -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" @@ -27,9 +30,7 @@ #include "Framework/O2DatabasePDGPlugin.h" #include "Framework/runDataProcessing.h" -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include using namespace o2; using namespace o2::analysis; @@ -47,8 +48,13 @@ struct HfTaskXic { Configurable dcaZTrackMax{"dcaZTrackMax", 0.0025, "max. DCAz for track"}; Configurable> binsPt{"binsPt", std::vector{hf_cuts_xic_to_p_k_pi::vecBinsPt}, "pT bin limits"}; - // THnSparse for ML outputScores and Vars Configurable enableTHn{"enableTHn", false, "enable THn for Xic"}; + HfHelper hfHelper; + Service pdg; + + Filter filterSelectCandidates = (aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlagXic || aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlagXic); + + // THnSparse for ML outputScores and Vars ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {36, 0, 36}, ""}; ConfigurableAxis thnConfigAxisMass{"thnConfigAxisMass", {300, 1.98, 2.58}, ""}; ConfigurableAxis thnConfigAxisPtProng{"thnConfigAxisPtProng", {100, 0, 20}, ""}; @@ -60,19 +66,10 @@ struct HfTaskXic { ConfigurableAxis thnConfigAxisBdtScoreSignal{"thnConfigAxisBdtScoreSignal", {100, 0., 1.}, ""}; ConfigurableAxis thnConfigAxisYMC{"thnConfigAxisYMC", {100, -2., 2.}, ""}; // - Service pdg; - HfHelper hfHelper; float etaMaxAcceptance = 0.8; float ptMinAcceptance = 0.1; - using TracksWPid = soa::Join; - - Filter filterSelectCandidates = (aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlagXic || aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlagXic); - - Partition> selectedMCXicCandidates = (aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlagXic || aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlagXic); - HistogramRegistry registry{ "registry", // histo not in pt bins { @@ -256,7 +253,7 @@ struct HfTaskXic { template void analysisData(aod::Collision const& collision, Cands const& candidates, - TracksWPid const& tracks) + aod::TracksWDca const& tracks) { int nTracks = 0; @@ -316,9 +313,9 @@ struct HfTaskXic { registry.fill(HIST("Data/hChi2PCA"), candidate.chi2PCA(), ptCandidate); // PID histos - auto trackProng0 = candidate.template prong0_as(); - auto trackProng1 = candidate.template prong1_as(); - auto trackProng2 = candidate.template prong2_as(); + auto trackProng0 = candidate.template prong0_as(); + auto trackProng1 = candidate.template prong1_as(); + auto trackProng2 = candidate.template prong2_as(); auto momentumProng0 = trackProng0.p(); auto momentumProng1 = trackProng1.p(); @@ -354,10 +351,11 @@ struct HfTaskXic { if (enableTHn) { double massXic(-1); double outputBkg(-1), outputPrompt(-1), outputFD(-1); + const int ternaryCl = 3; if (candidate.isSelXicToPKPi() >= selectionFlagXic) { massXic = hfHelper.invMassXicToPKPi(candidate); if constexpr (useMl) { - if (candidate.mlProbXicToPKPi().size() == 3) { + if (candidate.mlProbXicToPKPi().size() == ternaryCl) { outputBkg = candidate.mlProbXicToPKPi()[0]; /// bkg score outputPrompt = candidate.mlProbXicToPKPi()[1]; /// prompt score outputFD = candidate.mlProbXicToPKPi()[2]; /// non-prompt score @@ -371,7 +369,7 @@ struct HfTaskXic { if (candidate.isSelXicToPiKP() >= selectionFlagXic) { massXic = hfHelper.invMassXicToPiKP(candidate); if constexpr (useMl) { - if (candidate.mlProbXicToPiKP().size() == 3) { + if (candidate.mlProbXicToPiKP().size() == ternaryCl) { outputBkg = candidate.mlProbXicToPiKP()[0]; /// bkg score outputPrompt = candidate.mlProbXicToPiKP()[1]; /// prompt score outputFD = candidate.mlProbXicToPiKP()[2]; /// non-prompt score @@ -388,14 +386,14 @@ struct HfTaskXic { void processDataStd(aod::Collision const& collision, soa::Filtered> const& candidates, - TracksWPid const& tracks) + aod::TracksWDca const& tracks) { analysisData(collision, candidates, tracks); } PROCESS_SWITCH(HfTaskXic, processDataStd, "Process Data with the standard method", true); void processDataWithMl(aod::Collision const& collision, - soa::Filtered> const& candidatesMl, TracksWPid const& tracks) + soa::Filtered> const& candidatesMl, aod::TracksWDca const& tracks) { analysisData(collision, candidatesMl, tracks); } @@ -428,7 +426,7 @@ struct HfTaskXic { massXicToPiKP = hfHelper.invMassXicToPiKP(candidate); // mass conjugate } - if (std::abs(candidate.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::XicToPKPi) { + if (std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::XicToPKPi) { // Get the corresponding MC particle. auto mcParticleProng0 = candidate.template prong0_as().template mcParticle_as>(); auto pdgCodeProng0 = std::abs(mcParticleProng0.pdgCode()); @@ -493,6 +491,7 @@ struct HfTaskXic { if (enableTHn) { double massXic(-1); double outputBkg(-1), outputPrompt(-1), outputFD(-1); + const int ternaryCl = 3; bool allProngsInAcceptance = false; if ((candidate.isSelXicToPKPi() >= selectionFlagXic) && pdgCodeProng0 == kProton) { massXic = hfHelper.invMassXicToPKPi(candidate); @@ -504,7 +503,7 @@ struct HfTaskXic { } allProngsInAcceptance = isProngInAcceptance(etaProngs[0], ptProngs[0]) && isProngInAcceptance(etaProngs[1], ptProngs[1]) && isProngInAcceptance(etaProngs[2], ptProngs[2]); if constexpr (useMl) { - if (candidate.mlProbXicToPKPi().size() == 3) { + if (candidate.mlProbXicToPKPi().size() == ternaryCl) { outputBkg = candidate.mlProbXicToPKPi()[0]; /// bkg score outputPrompt = candidate.mlProbXicToPKPi()[1]; /// prompt score outputFD = candidate.mlProbXicToPKPi()[2]; /// non-prompt score @@ -525,7 +524,7 @@ struct HfTaskXic { } allProngsInAcceptance = isProngInAcceptance(etaProngs[0], ptProngs[0]) && isProngInAcceptance(etaProngs[1], ptProngs[1]) && isProngInAcceptance(etaProngs[2], ptProngs[2]); if constexpr (useMl) { - if (candidate.mlProbXicToPiKP().size() == 3) { + if (candidate.mlProbXicToPiKP().size() == ternaryCl) { outputBkg = candidate.mlProbXicToPiKP()[0]; /// bkg score outputPrompt = candidate.mlProbXicToPiKP()[1]; /// prompt score outputFD = candidate.mlProbXicToPiKP()[2]; /// non-prompt score @@ -571,7 +570,7 @@ struct HfTaskXic { // MC gen. for (const auto& particle : mcParticles) { - if (std::abs(particle.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::XicToPKPi) { + if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::XicToPKPi) { auto yGen = RecoDecay::y(particle.pVector(), o2::constants::physics::MassXiCPlus); if (yCandGenMax >= 0. && std::abs(yGen) > yCandGenMax) { continue; diff --git a/PWGHF/D2H/Tasks/taskXicc.cxx b/PWGHF/D2H/Tasks/taskXicc.cxx index 9e9f4999f80..83c662ef6da 100644 --- a/PWGHF/D2H/Tasks/taskXicc.cxx +++ b/PWGHF/D2H/Tasks/taskXicc.cxx @@ -16,15 +16,16 @@ /// \author Gian Michele Innocenti , CERN /// \author Jinjoo Seo , Inha University -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include using namespace o2; using namespace o2::analysis; @@ -275,8 +276,8 @@ struct HfTaskXiccMc { registry.fill(HIST("hPtvsEtavsYGen"), particle.pt(), particle.eta(), RecoDecay::y(particle.pVector(), o2::constants::physics::MassXiCCPlusPlus)); } } // end of loop of MC particles - } // end of process function -}; // end of struct + } // end of process function +}; // end of struct WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { diff --git a/PWGHF/D2H/Utils/utilsRedDataFormat.h b/PWGHF/D2H/Utils/utilsRedDataFormat.h index 9740e55d372..b5cd1e07e27 100644 --- a/PWGHF/D2H/Utils/utilsRedDataFormat.h +++ b/PWGHF/D2H/Utils/utilsRedDataFormat.h @@ -16,12 +16,17 @@ #ifndef PWGHF_D2H_UTILS_UTILSREDDATAFORMAT_H_ #define PWGHF_D2H_UTILS_UTILSREDDATAFORMAT_H_ -#include "Framework/HistogramRegistry.h" - -#include "CCDB/BasicCCDBManager.h" #include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/Utils/utilsEvSelHf.h" +#include "CCDB/BasicCCDBManager.h" +#include "Framework/AnalysisHelpers.h" +#include "Framework/HistogramRegistry.h" + +#include + +#include + namespace o2::hf_evsel { /// Helper function to count collisions at different event selection stages diff --git a/PWGHF/DataModel/CandidateReconstructionTables.h b/PWGHF/DataModel/CandidateReconstructionTables.h index 41b5ccbf905..f8a16a15799 100644 --- a/PWGHF/DataModel/CandidateReconstructionTables.h +++ b/PWGHF/DataModel/CandidateReconstructionTables.h @@ -18,23 +18,23 @@ #ifndef PWGHF_DATAMODEL_CANDIDATERECONSTRUCTIONTABLES_H_ #define PWGHF_DATAMODEL_CANDIDATERECONSTRUCTIONTABLES_H_ -#include - -#include "Math/GenVector/Boost.h" -#include "Math/Vector4D.h" - -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/AnalysisDataModel.h" +#include "PWGHF/Core/DecayChannels.h" // FIXME: temporary until propagated where needed +#include "PWGHF/Utils/utilsPid.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" #include "ALICE3/DataModel/ECAL.h" #include "Common/Core/RecoDecay.h" -#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" +#include +#include +#include -#include "PWGHF/Core/SelectorCuts.h" -#include "PWGHF/Utils/utilsPid.h" +#include +#include +#include namespace o2::aod { diff --git a/PWGHF/DataModel/CandidateSelectionTables.h b/PWGHF/DataModel/CandidateSelectionTables.h index ca58828bc0c..f693605f635 100644 --- a/PWGHF/DataModel/CandidateSelectionTables.h +++ b/PWGHF/DataModel/CandidateSelectionTables.h @@ -17,13 +17,9 @@ #ifndef PWGHF_DATAMODEL_CANDIDATESELECTIONTABLES_H_ #define PWGHF_DATAMODEL_CANDIDATESELECTIONTABLES_H_ -#include - -#include "Common/Core/RecoDecay.h" -#include "Common/Core/TrackSelectorPID.h" +#include -#include "PWGHF/Core/SelectorCuts.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include namespace o2::aod { @@ -354,6 +350,7 @@ DECLARE_SOA_COLUMN(TofNSigmaPiFromLambda, tofNSigmaPiFromLambda, float); DECLARE_SOA_COLUMN(TofNSigmaPrFromLambda, tofNSigmaPrFromLambda, float); DECLARE_SOA_COLUMN(PidTpcInfoStored, pidTpcInfoStored, int); DECLARE_SOA_COLUMN(PidTofInfoStored, pidTofInfoStored, int); +DECLARE_SOA_COLUMN(MlProbToXiPi, mlProbToXiPi, std::vector); } // namespace hf_sel_toxipi DECLARE_SOA_TABLE(HfSelToXiPi, "AOD", "HFSELTOXIPI", @@ -370,6 +367,9 @@ DECLARE_SOA_TABLE(HfSelToXiPiKf, "AOD", "HFSELTOXIPIKF", hf_sel_toxipi::TpcNSigmaPiFromCharmBaryon, hf_sel_toxipi::TpcNSigmaPiFromCasc, hf_sel_toxipi::TpcNSigmaPiFromLambda, hf_sel_toxipi::TpcNSigmaPrFromLambda, hf_sel_toxipi::TofNSigmaPiFromCharmBaryon, hf_sel_toxipi::TofNSigmaPiFromCasc, hf_sel_toxipi::TofNSigmaPiFromLambda, hf_sel_toxipi::TofNSigmaPrFromLambda); +DECLARE_SOA_TABLE(HfMlToXiPiKf, "AOD", "HFMLSELTOXIPIKF", + hf_sel_toxipi::MlProbToXiPi); + namespace hf_sel_toomegapi { DECLARE_SOA_COLUMN(StatusPidLambda, statusPidLambda, bool); @@ -393,13 +393,12 @@ DECLARE_SOA_COLUMN(PidTpcInfoStored, pidTpcInfoStored, int); DECLARE_SOA_COLUMN(PidTofInfoStored, pidTofInfoStored, int); // Machine learning column for omegac0 to omega pi DECLARE_SOA_COLUMN(MlProbOmegac, mlProbOmegac, std::vector); -DECLARE_SOA_COLUMN(MlValueOmegac, mlValueOmegac, float); } // namespace hf_sel_toomegapi DECLARE_SOA_TABLE(HfSelToOmegaPi, "AOD", "HFSELTOOMEPI", hf_sel_toomegapi::StatusPidLambda, hf_sel_toomegapi::StatusPidCascade, hf_sel_toomegapi::StatusPidCharmBaryon, hf_sel_toomegapi::StatusInvMassLambda, hf_sel_toomegapi::StatusInvMassCascade, hf_sel_toomegapi::StatusInvMassCharmBaryon, - hf_sel_toomegapi::ResultSelections, hf_sel_toomegapi::PidTpcInfoStored, hf_sel_toomegapi::PidTofInfoStored, hf_sel_toomegapi::MlValueOmegac, + hf_sel_toomegapi::ResultSelections, hf_sel_toomegapi::PidTpcInfoStored, hf_sel_toomegapi::PidTofInfoStored, hf_sel_toomegapi::TpcNSigmaPiFromCharmBaryon, hf_sel_toomegapi::TpcNSigmaKaFromCasc, hf_sel_toomegapi::TpcNSigmaPiFromLambda, hf_sel_toomegapi::TpcNSigmaPrFromLambda, hf_sel_toomegapi::TofNSigmaPiFromCharmBaryon, hf_sel_toomegapi::TofNSigmaKaFromCasc, hf_sel_toomegapi::TofNSigmaPiFromLambda, hf_sel_toomegapi::TofNSigmaPrFromLambda); diff --git a/PWGHF/DataModel/DerivedTables.h b/PWGHF/DataModel/DerivedTables.h index 77f5f848ce2..61c85b9fd63 100644 --- a/PWGHF/DataModel/DerivedTables.h +++ b/PWGHF/DataModel/DerivedTables.h @@ -16,17 +16,18 @@ #ifndef PWGHF_DATAMODEL_DERIVEDTABLES_H_ #define PWGHF_DATAMODEL_DERIVEDTABLES_H_ -#include - -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoA.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Centrality.h" -#include "PWGLF/DataModel/mcCentrality.h" +#include +#include -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include + +#include +#include namespace o2::aod { diff --git a/PWGHF/HFC/DataModel/CorrelationTables.h b/PWGHF/HFC/DataModel/CorrelationTables.h index 370f3738975..d65ace1f8be 100644 --- a/PWGHF/HFC/DataModel/CorrelationTables.h +++ b/PWGHF/HFC/DataModel/CorrelationTables.h @@ -16,12 +16,15 @@ #ifndef PWGHF_HFC_DATAMODEL_CORRELATIONTABLES_H_ #define PWGHF_HFC_DATAMODEL_CORRELATIONTABLES_H_ -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/AnalysisDataModel.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" // NOLINT #include "Common/Core/RecoDecay.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include +#include +#include // NOLINT + +#include namespace o2::aod { @@ -144,6 +147,7 @@ DECLARE_SOA_COLUMN(DeltaEta, deltaEta, float); //! D DECLARE_SOA_COLUMN(DeltaY, deltaY, float); //! DeltaY between Lc and Hadrons DECLARE_SOA_COLUMN(PtLc, ptLc, float); //! Transverse momentum of Lc DECLARE_SOA_COLUMN(PtHadron, ptHadron, float); //! Transverse momentum of Hadron +DECLARE_SOA_COLUMN(ChargeCand, chargeCand, int); //! store charge of Lc and Sc DECLARE_SOA_COLUMN(MLc, mLc, float); //! Invariant mass of Lc DECLARE_SOA_COLUMN(MlScoreBkg, mlScoreBkg, float); //! ML background score for Lc selection DECLARE_SOA_COLUMN(MlScorePrompt, mlScorePrompt, float); //! ML prompt score for Lc selection @@ -213,8 +217,14 @@ DECLARE_SOA_TABLE(TrkRecInfoLc, "AOD", "TRKRECINFOLC", //! Tracks Reconstructed aod::hf_correlation_lc_hadron::TrackDcaXY, aod::hf_correlation_lc_hadron::TrackDcaZ, aod::hf_correlation_lc_hadron::TrackTPCNClsCrossedRows); -DECLARE_SOA_TABLE(LcHadronPairY, "AOD", "LCHPAIRY", //! Lc candidates Generated Information + +DECLARE_SOA_TABLE(LcHadronPairY, "AOD", "LCHPAIRY", aod::hf_correlation_lc_hadron::DeltaY); +DECLARE_SOA_TABLE(CandChargePair, "AOD", "CANDCHARGEPAIR", + aod::hf_correlation_lc_hadron::ChargeCand); +DECLARE_SOA_TABLE(CandCharge, "AOD", "CANDCHARGE", + aod::hf_correlation_lc_hadron::ChargeCand); + // definition of columns and tables for Ds-Hadron correlation pairs namespace hf_correlation_ds_hadron { diff --git a/PWGHF/HFC/DataModel/DMesonPairsTables.h b/PWGHF/HFC/DataModel/DMesonPairsTables.h index 9ba4d72c78b..35e12760919 100644 --- a/PWGHF/HFC/DataModel/DMesonPairsTables.h +++ b/PWGHF/HFC/DataModel/DMesonPairsTables.h @@ -17,9 +17,10 @@ #ifndef PWGHF_HFC_DATAMODEL_DMESONPAIRSTABLES_H_ #define PWGHF_HFC_DATAMODEL_DMESONPAIRSTABLES_H_ -#include +#include -#include "Framework/AnalysisDataModel.h" +#include +#include namespace o2::aod { diff --git a/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h b/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h index 9e99e6ab011..b9425517913 100644 --- a/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h +++ b/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h @@ -16,7 +16,7 @@ #ifndef PWGHF_HFC_DATAMODEL_DERIVEDDATACORRELATIONTABLES_H_ #define PWGHF_HFC_DATAMODEL_DERIVEDDATACORRELATIONTABLES_H_ -#include "Framework/AnalysisDataModel.h" +#include namespace o2::aod { diff --git a/PWGHF/HFC/Macros/DhCorrelationExtraction.h b/PWGHF/HFC/Macros/DhCorrelationExtraction.h index a659724594b..ddfe205372c 100644 --- a/PWGHF/HFC/Macros/DhCorrelationExtraction.h +++ b/PWGHF/HFC/Macros/DhCorrelationExtraction.h @@ -17,22 +17,17 @@ #ifndef PWGHF_HFC_MACROS_DHCORRELATIONEXTRACTION_H_ #define PWGHF_HFC_MACROS_DHCORRELATIONEXTRACTION_H_ -#include -#include "TObject.h" -#include "TMath.h" -#include "TFile.h" -#include "TDirectoryFile.h" -#include "TList.h" -#include "TCanvas.h" -#include "TPaveText.h" -#include "TLegend.h" -#include "TSystem.h" -#include "TH1D.h" -#include "TH2D.h" -#include "TH3D.h" -#include "TF1.h" -#include "THnSparse.h" -#include "TVector.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include class DhCorrelationExtraction : public TObject { diff --git a/PWGHF/HFC/Macros/DhCorrelationFitter.h b/PWGHF/HFC/Macros/DhCorrelationFitter.h index 3832b67b645..e2354624bf2 100644 --- a/PWGHF/HFC/Macros/DhCorrelationFitter.h +++ b/PWGHF/HFC/Macros/DhCorrelationFitter.h @@ -17,12 +17,12 @@ #ifndef PWGHF_HFC_MACROS_DHCORRELATIONFITTER_H_ #define PWGHF_HFC_MACROS_DHCORRELATIONFITTER_H_ -#include +#include +#include + +#include -#include -#include -#include -#include +#include class DhCorrelationFitter { diff --git a/PWGHF/HFC/TableProducer/CMakeLists.txt b/PWGHF/HFC/TableProducer/CMakeLists.txt index 56b01bcd412..99f2c4fb152 100644 --- a/PWGHF/HFC/TableProducer/CMakeLists.txt +++ b/PWGHF/HFC/TableProducer/CMakeLists.txt @@ -64,6 +64,11 @@ o2physics_add_dpl_workflow(correlator-lc-hadrons PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(correlator-lc-sc-hadrons + SOURCES correlatorLcScHadrons.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(femto-dream-producer SOURCES femtoDreamProducer.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils O2Physics::MLCore diff --git a/PWGHF/HFC/TableProducer/correlatorD0D0bar.cxx b/PWGHF/HFC/TableProducer/correlatorD0D0bar.cxx index 294e34db2c7..8c958dfe34b 100644 --- a/PWGHF/HFC/TableProducer/correlatorD0D0bar.cxx +++ b/PWGHF/HFC/TableProducer/correlatorD0D0bar.cxx @@ -14,20 +14,21 @@ /// /// \author Fabio Colamaria , INFN Bari -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/HFC/DataModel/CorrelationTables.h" + +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/HFC/DataModel/CorrelationTables.h" +#include using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/HFC/TableProducer/correlatorD0D0barBarrelFullPid.cxx b/PWGHF/HFC/TableProducer/correlatorD0D0barBarrelFullPid.cxx index f92f8150abc..dc0340a8805 100644 --- a/PWGHF/HFC/TableProducer/correlatorD0D0barBarrelFullPid.cxx +++ b/PWGHF/HFC/TableProducer/correlatorD0D0barBarrelFullPid.cxx @@ -14,20 +14,21 @@ /// /// \author Fabio Colamaria , INFN Bari -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/HFC/DataModel/CorrelationTables.h" + +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/HFC/DataModel/CorrelationTables.h" +#include using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/HFC/TableProducer/correlatorD0Hadrons.cxx b/PWGHF/HFC/TableProducer/correlatorD0Hadrons.cxx index 7b6517f29dc..c84d52f77e9 100644 --- a/PWGHF/HFC/TableProducer/correlatorD0Hadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorD0Hadrons.cxx @@ -15,12 +15,12 @@ /// \author Samrangy Sadhu , INFN Bari /// \author Swapnesh Santosh Khade , IIT Indore -#include - -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/HFC/DataModel/CorrelationTables.h" +#include "PWGHF/HFC/Utils/utilsCorrelations.h" #include "Common/Core/TrackSelection.h" #include "Common/DataModel/Centrality.h" @@ -28,11 +28,12 @@ #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/HFC/DataModel/CorrelationTables.h" -#include "PWGHF/HFC/Utils/utilsCorrelations.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx b/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx index ef5791fadc8..3f522608f47 100644 --- a/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx @@ -14,23 +14,24 @@ /// /// \author Andrea Tavira García , IJCLab Orsay -#include -#include - -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" - -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" - #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/HfMlResponse.h" #include "PWGHF/Core/HfMlResponseD0ToKPi.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/HFC/DataModel/DMesonPairsTables.h" +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include +#include + using namespace o2; using namespace o2::analysis; using namespace o2::constants::physics; diff --git a/PWGHF/HFC/TableProducer/correlatorDplusDminus.cxx b/PWGHF/HFC/TableProducer/correlatorDplusDminus.cxx index 2871d9f9793..55b45737cf2 100644 --- a/PWGHF/HFC/TableProducer/correlatorDplusDminus.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDplusDminus.cxx @@ -14,20 +14,21 @@ /// /// \author Fabio Colamaria , INFN Bari -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/HFC/DataModel/CorrelationTables.h" + +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/HFC/DataModel/CorrelationTables.h" +#include using namespace o2; using namespace o2::analysis; @@ -297,7 +298,7 @@ struct HfCorrelatorDplusDminus { if (outerSecondTrack.sign() == 1) { outerParticleSign = -1; // Dminus (second daughter track is positive) } - if (std::abs(candidate1.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi) { + if (std::abs(candidate1.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) { // fill invariant mass plots and per-candidate distributions from Dplus/Dminus signal candidates if (outerParticleSign == 1) { // reco and matched as Dplus registry.fill(HIST("hMassDplusMCRecSig"), hfHelper.invMassDplusToPiKPi(candidate1), candidate1.pt(), efficiencyWeight); @@ -325,7 +326,7 @@ struct HfCorrelatorDplusDminus { if (outerParticleSign == -1) { continue; // reject Dminus in outer loop } - flagDplusSignal = std::abs(candidate1.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi; // flagDplusSignal 'true' if candidate1 matched to Dplus + flagDplusSignal = std::abs(candidate1.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi; // flagDplusSignal 'true' if candidate1 matched to Dplus for (const auto& candidate2 : selectedDPlusCandidatesGroupedMC) { if (!(candidate2.hfflag() & 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi)) { // check decay channel flag for candidate2 continue; @@ -334,7 +335,7 @@ struct HfCorrelatorDplusDminus { if (innerSecondTrack.sign() != 1) { // keep only Dminus (with second daughter track positive) continue; } - flagDminusSignal = std::abs(candidate2.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi; // flagDminusSignal 'true' if candidate2 matched to Dminus + flagDminusSignal = std::abs(candidate2.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi; // flagDminusSignal 'true' if candidate2 matched to Dminus if (yCandMax >= 0. && std::abs(hfHelper.yDplus(candidate2)) > yCandMax) { continue; } @@ -427,7 +428,7 @@ struct HfCorrelatorDplusDminus { // fill pairs vs etaCut plot bool rightDecayChannels = false; - if ((std::abs(particle1.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi) && (std::abs(particle2.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi)) { + if ((std::abs(particle1.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) && (std::abs(particle2.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi)) { rightDecayChannels = true; } do { diff --git a/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx index d6c50370ed5..9b4bd141b02 100644 --- a/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx @@ -13,12 +13,11 @@ /// \brief D+-Hadrons correlator task - data-like, MC-reco and MC-Gen analyses /// \author Shyam Kumar -#include - -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/HFC/DataModel/CorrelationTables.h" #include "Common/Core/TrackSelection.h" #include "Common/DataModel/Centrality.h" @@ -26,10 +25,12 @@ #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/HFC/DataModel/CorrelationTables.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include using namespace o2; using namespace o2::analysis; @@ -421,7 +422,7 @@ struct HfCorrelatorDplusHadrons { efficiencyWeightD = 1. / efficiencyD->at(effBinD); } // Dplus flag - isDplusSignal = TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_3prong::DecayType::DplusToPiKPi); + isDplusSignal = std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi; // prompt and non-prompt division isDplusPrompt = candidate.originMcRec() == RecoDecay::OriginType::Prompt; isDplusNonPrompt = candidate.originMcRec() == RecoDecay::OriginType::NonPrompt; @@ -530,7 +531,7 @@ struct HfCorrelatorDplusHadrons { if (std::abs(particle1.pdgCode()) != Pdg::kDPlus) { continue; } - if (!TESTBIT(std::abs(particle1.flagMcMatchGen()), aod::hf_cand_3prong::DecayType::DplusToPiKPi)) { + if (std::abs(particle1.flagMcMatchGen()) != hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) { continue; } double yD = RecoDecay::y(particle1.pVector(), MassDPlus); @@ -636,7 +637,7 @@ struct HfCorrelatorDplusHadrons { continue; } // Dplus flag - bool isDplusSignal = TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_3prong::DecayType::DplusToPiKPi); + bool isDplusSignal = std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi; // prompt and non-prompt division bool isDplusPrompt = candidate.originMcRec() == RecoDecay::OriginType::Prompt; bool isDplusNonPrompt = candidate.originMcRec() == RecoDecay::OriginType::NonPrompt; @@ -674,7 +675,7 @@ struct HfCorrelatorDplusHadrons { std::vector outputMl = {-1., -1., -1.}; bool isPhysicalPrimary = false; int trackOrigin = -1; - bool isDplusSignal = std::abs(candidate.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi; + bool isDplusSignal = std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi; // prompt and non-prompt division bool isDplusPrompt = candidate.originMcRec() == RecoDecay::OriginType::Prompt; if (pAssoc.has_mcParticle()) { diff --git a/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx index 50881aad9d2..2501a089766 100644 --- a/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx @@ -14,12 +14,12 @@ /// \author Grazia Luparello /// \author Samuele Cattaruzzi -#include - -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/HFC/DataModel/CorrelationTables.h" +#include "PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h" #include "Common/Core/TrackSelection.h" #include "Common/DataModel/Centrality.h" @@ -27,11 +27,13 @@ #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/HFC/DataModel/CorrelationTables.h" -#include "PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include +#include using namespace o2; using namespace o2::analysis; @@ -40,6 +42,13 @@ using namespace o2::constants::math; using namespace o2::framework; using namespace o2::framework::expressions; +enum ResonantChannel : int8_t { + PhiPi = 1, + Kstar0K = 2 +}; + +static std::unordered_map channelsResonant = {{{ResonantChannel::PhiPi, hf_decay::hf_cand_3prong::DecayChannelResonant::DsToPhiPi}, {ResonantChannel::Kstar0K, hf_decay::hf_cand_3prong::DecayChannelResonant::DsToKstar0K}}}; + /// Returns deltaPhi value in range [-pi/2., 3.*pi/2], typically used for correlation studies double getDeltaPhi(double phiHadron, double phiD) { @@ -155,7 +164,7 @@ struct HfCorrelatorDsHadrons { Configurable selNoSameBunchPileUpColl{"selNoSameBunchPileUpColl", true, "Flag for rejecting the collisions associated with the same bunch crossing (used only in MC processes)"}; Configurable selectionFlagDs{"selectionFlagDs", 7, "Selection Flag for Ds (avoid the case of flag = 0, no outputMlScore)"}; Configurable numberEventsMixed{"numberEventsMixed", 5, "Number of events mixed in ME process"}; - Configurable decayChannel{"decayChannel", 1, "Decay channels: 1 for Ds->PhiPi->KKpi, 2 for Ds->K0*K->KKPi"}; + Configurable decayChannel{"decayChannel", 1, "Resonant decay channels: 1 for Ds->PhiPi->KKpi, 2 for Ds->K0*K->KKPi"}; Configurable applyEfficiency{"applyEfficiency", true, "Flag for applying D-meson efficiency weights"}; Configurable yCandMax{"yCandMax", 0.8, "max. cand. rapidity"}; Configurable yCandGenMax{"yCandGenMax", 0.5, "max. gen. cand. rapidity"}; @@ -461,8 +470,8 @@ struct HfCorrelatorDsHadrons { // prompt and non-prompt division isDsPrompt = candidate.originMcRec() == RecoDecay::OriginType::Prompt; // Ds Signal - isDsSignal = std::abs(candidate.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::DsToKKPi; - isDecayChan = candidate.flagMcDecayChanRec() == decayChannel; + isDsSignal = std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK; + isDecayChan = candidate.flagMcDecayChanRec() == channelsResonant[decayChannel]; if (std::abs(hfHelper.yDs(candidate)) > yCandMax || candidate.pt() < ptCandMin || candidate.pt() > ptCandMax) { continue; @@ -642,7 +651,7 @@ struct HfCorrelatorDsHadrons { // MC gen level for (const auto& particle : groupedMcParticles) { // check if the particle is Ds - if ((std::abs(particle.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::DsToKKPi) && (particle.flagMcDecayChanGen() == decayChannel)) { + if ((std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) && (particle.flagMcDecayChanGen() == channelsResonant[decayChannel])) { double yD = RecoDecay::y(particle.pVector(), MassDS); if (std::abs(yD) > yCandGenMax || particle.pt() < ptCandMin || particle.pt() > ptCandMax) { continue; @@ -650,7 +659,7 @@ struct HfCorrelatorDsHadrons { fillMcGenHisto(particle); // prompt and non-prompt division isDsPrompt = particle.originMcGen() == RecoDecay::OriginType::Prompt; - isDecayChan = particle.flagMcDecayChanGen() == decayChannel; + isDecayChan = particle.flagMcDecayChanGen() == channelsResonant[decayChannel]; std::vector listDaughters{}; std::array arrDaughDsPDG = {+kKPlus, -kKPlus, kPiPlus}; std::array prongsId; @@ -822,7 +831,7 @@ struct HfCorrelatorDsHadrons { if (std::abs(hfHelper.yDs(candidate)) > yCandMax || candidate.pt() < ptCandMin || candidate.pt() > ptCandMax) { continue; } - if (std::abs(candidate.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::DsToKKPi) { + if (std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) { // DsToKKPi and DsToPiKK division if (candidate.isSelDsToKKPi() >= selectionFlagDs) { fillHistoMcRecSig(candidate, 0.); @@ -859,7 +868,7 @@ struct HfCorrelatorDsHadrons { // prompt and non-prompt division isDsPrompt = candidate.originMcRec() == RecoDecay::OriginType::Prompt; // Ds Signal - isDsSignal = std::abs(candidate.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::DsToKKPi; + isDsSignal = std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK; isDecayChan = candidate.flagMcDecayChanRec() == decayChannel; if (pAssoc.has_mcParticle()) { auto mcParticle = pAssoc.template mcParticle_as(); @@ -910,7 +919,7 @@ struct HfCorrelatorDsHadrons { for (const auto& [c1, tracks1, c2, tracks2] : pairMcGen) { int poolBin = corrBinningMcGen.getBin(std::make_tuple(c1.posZ(), c1.multMCFT0A())); for (const auto& [candidate, particleAssoc] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { - if ((std::abs(candidate.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::DsToKKPi) && (candidate.flagMcDecayChanGen() == decayChannel)) { + if ((std::abs(candidate.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) && (candidate.flagMcDecayChanGen() == decayChannel)) { double yD = RecoDecay::y(candidate.pVector(), MassDS); if (std::abs(yD) > yCandGenMax || candidate.pt() < ptCandMin || candidate.pt() > ptCandMax) { continue; diff --git a/PWGHF/HFC/TableProducer/correlatorDsHadronsReduced.cxx b/PWGHF/HFC/TableProducer/correlatorDsHadronsReduced.cxx index 31fd99530c2..d810282b9b0 100644 --- a/PWGHF/HFC/TableProducer/correlatorDsHadronsReduced.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDsHadronsReduced.cxx @@ -13,15 +13,16 @@ /// \brief Ds-Hadrons correlator task for offline analysis /// \author Samuele Cattaruzzi -#include +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/HFC/DataModel/CorrelationTables.h" +#include "PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "PWGHF/HFC/DataModel/CorrelationTables.h" -#include "PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h" +#include using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/HFC/TableProducer/correlatorLcHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorLcHadrons.cxx index 506f98073ef..2b8a6f7ff51 100644 --- a/PWGHF/HFC/TableProducer/correlatorLcHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorLcHadrons.cxx @@ -16,8 +16,18 @@ /// \author Zhen Zhang /// \author Ravindra Singh -#include -#include "TRandom3.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/HFC/DataModel/CorrelationTables.h" +#include "PWGHF/HFC/Utils/utilsCorrelations.h" + +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" @@ -25,17 +35,9 @@ #include "Framework/O2DatabasePDGPlugin.h" #include "Framework/runDataProcessing.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "TRandom3.h" -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/HFC/DataModel/CorrelationTables.h" -#include "PWGHF/HFC/Utils/utilsCorrelations.h" +#include using namespace o2; using namespace o2::analysis; @@ -530,8 +532,8 @@ struct HfCorrelatorLcHadrons { } auto trackPos1 = candidate.template prong0_as(); // positive daughter (negative for the antiparticles) auto trackPos2 = candidate.template prong2_as(); - int8_t chargeLc = trackPos1.sign(); // charge of 1st prong will be the charge of Lc candidate - isLcSignal = TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_3prong::DecayType::LcToPKPi); + int8_t chargeLc = trackPos1.sign(); // charge of 1st prong will be the charge of Lc candidate + isLcSignal = std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi; isLcPrompt = candidate.originMcRec() == RecoDecay::OriginType::Prompt; isLcNonPrompt = candidate.originMcRec() == RecoDecay::OriginType::NonPrompt; std::vector outputMl = {-1., -1., -1.}; @@ -777,7 +779,7 @@ struct HfCorrelatorLcHadrons { if (std::abs(particle.pdgCode()) != Pdg::kLambdaCPlus) { continue; } - if (!TESTBIT(std::abs(particle.flagMcMatchGen()), aod::hf_cand_3prong::DecayType::LcToPKPi)) { + if (std::abs(particle.flagMcMatchGen()) != hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { continue; } double yL = RecoDecay::y(particle.pVector(), MassLambdaCPlus); @@ -943,7 +945,7 @@ struct HfCorrelatorLcHadrons { continue; } // Lc flag - bool isLcSignal = TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_3prong::DecayType::LcToPKPi); + bool isLcSignal = std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi; // prompt and non-prompt division bool isLcPrompt = candidate.originMcRec() == RecoDecay::OriginType::Prompt; bool isLcNonPrompt = candidate.originMcRec() == RecoDecay::OriginType::NonPrompt; @@ -992,7 +994,7 @@ struct HfCorrelatorLcHadrons { std::vector outputMl = {-1., -1., -1.}; bool isPhysicalPrimary = false; int trackOrigin = -1; - bool isLcSignal = std::abs(candidate.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::LcToPKPi; + bool isLcSignal = std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi; bool isLcPrompt = candidate.originMcRec() == RecoDecay::OriginType::Prompt; if (pidTrkApplied) { if (!passPIDSelection(pAssoc, trkPIDspecies, pidTPCMax, pidTOFMax, tofPIDThreshold, forceTOF)) diff --git a/PWGHF/HFC/TableProducer/correlatorLcScHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorLcScHadrons.cxx new file mode 100644 index 00000000000..464d184c138 --- /dev/null +++ b/PWGHF/HFC/TableProducer/correlatorLcScHadrons.cxx @@ -0,0 +1,1078 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file correlatorLcScHadrons.cxx +/// \brief Lc-Hadrons correlator task - data-like, Mc-Reco and Mc-Gen analyses +/// +/// \author Marianna Mazzilli +/// \author Zhen Zhang +/// \author Ravindra Singh + +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/HFC/DataModel/CorrelationTables.h" +#include "PWGHF/HFC/Utils/utilsCorrelations.h" + +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CommonConstants/MathConstants.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" + +#include "TRandom3.h" + +#include + +using namespace o2; +using namespace o2::analysis; +using namespace o2::constants::physics; +using namespace o2::constants::math; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::analysis::hf_correlations; +/// +/// Returns deltaPhi values in range [-pi/2., 3.*pi/2.], typically used for correlation studies +/// +double getDeltaPhi(double phiLc, double phiHadron) +{ + return RecoDecay::constrainAngle(phiHadron - phiLc, -PIHalf); +} + +// definition of ME variables +using BinningType = ColumnBinningPolicy>; +using BinningTypeMcGen = ColumnBinningPolicy; + +// Code to select collisions with at least one Lambda_c +struct HfCorrelatorLcScHadronsSelection { + Produces lcSel; + + Configurable useSel8{"useSel8", true, "Flag for applying sel8 for collision selection"}; + Configurable selNoSameBunchPileUpColl{"selNoSameBunchPileUpColl", true, "Flag for rejecting the collisions associated with the same bunch crossing"}; + Configurable doSelLcCollision{"doSelLcCollision", true, "Select collisions with at least one Lc"}; + Configurable selectionFlagLc{"selectionFlagLc", 1, "Selection Flag for Lc"}; + Configurable yCandMax{"yCandMax", 0.8, "max. cand. rapidity"}; + Configurable ptCandMin{"ptCandMin", 1., "min. cand. pT"}; + + HfHelper hfHelper; + SliceCache cache; + + using SelCollisions = soa::Join; + using CandsLcDataFiltered = soa::Filtered>; + using CandsLcMcRecFiltered = soa::Filtered>; + using CandidatesLcMcGen = soa::Join; + + // filter on selection of Lc and decay channel Lc->PKPi + Filter lcFilter = ((o2::aod::hf_track_index::hfflag & static_cast(1 << aod::hf_cand_3prong::DecayType::LcToPKPi)) != static_cast(0)) && (aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlagLc || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlagLc); + + /// Code to select collisions with at least one Lc - for real data and data-like analysis + void processLcSelectionData(SelCollisions::iterator const& collision, + CandsLcDataFiltered const& candidates) + { + bool isSelColl = true; + bool isLcFound = true; + bool isSel8 = true; + bool isNosameBunchPileUp = true; + if (doSelLcCollision) { + for (const auto& candidate : candidates) { + if (std::abs(hfHelper.yLc(candidate)) > yCandMax || candidate.pt() < ptCandMin) { + isLcFound = false; + continue; + } + isLcFound = true; + break; + } + } + if (useSel8) { + isSel8 = collision.sel8(); + } + if (selNoSameBunchPileUpColl) { + isNosameBunchPileUp = static_cast(collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)); + } + isSelColl = isLcFound && isSel8 && isNosameBunchPileUp; + lcSel(isSelColl); + } + PROCESS_SWITCH(HfCorrelatorLcScHadronsSelection, processLcSelectionData, "Process Lc Collision Selection Data", true); + + void processLcSelectionMcRec(SelCollisions::iterator const& collision, + CandsLcMcRecFiltered const& candidates) + { + bool isSelColl = true; + bool isLcFound = true; + bool isSel8 = true; + bool isNosameBunchPileUp = true; + if (doSelLcCollision) { + for (const auto& candidate : candidates) { + if (std::abs(hfHelper.yLc(candidate)) > yCandMax || candidate.pt() < ptCandMin) { + isLcFound = false; + continue; + } + isLcFound = true; + break; + } + } + if (useSel8) { + isSel8 = collision.sel8(); + } + if (selNoSameBunchPileUpColl) { + isNosameBunchPileUp = static_cast(collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)); + } + isSelColl = isLcFound && isSel8 && isNosameBunchPileUp; + lcSel(isSelColl); + } + PROCESS_SWITCH(HfCorrelatorLcScHadronsSelection, processLcSelectionMcRec, "Process Lc Selection McRec", false); + + void processLcSelectionMcGen(aod::McCollision const&, + CandidatesLcMcGen const& mcParticles) + { + bool isLcFound = true; + for (const auto& particle : mcParticles) { + if (std::abs(particle.pdgCode()) != Pdg::kLambdaCPlus) { + isLcFound = false; + continue; + } + double yL = RecoDecay::y(particle.pVector(), MassLambdaCPlus); + if (std::abs(yL) > yCandMax || particle.pt() < ptCandMin) { + isLcFound = false; + continue; + } + isLcFound = true; + break; + } + lcSel(isLcFound); + } + PROCESS_SWITCH(HfCorrelatorLcScHadronsSelection, processLcSelectionMcGen, "Process Lc Selection McGen", false); +}; + +// Lc-Hadron correlation pair builder - for real data and data-like analysis (i.e. reco-level w/o matching request via Mc truth) +struct HfCorrelatorLcScHadrons { + Produces entryCandHadronPair; + Produces entryCandHadronPairY; + Produces entryCandHadronPairTrkPID; + Produces entryCandHadronRecoInfo; + Produces entryCandHadronMlInfo; + Produces entryCandCandRecoInfo; + Produces entryCandHadronGenInfo; + Produces entryCandCandGenInfo; + Produces entryTrackRecoInfo; + Produces entryCand; + Produces entryHadron; + Produces entryTrkPID; + Produces entryPairCandCharge; + Produces entryCandCharge; + + Configurable selectionFlagLc{"selectionFlagLc", 1, "Selection Flag for Lc"}; + Configurable numberEventsMixed{"numberEventsMixed", 5, "number of events mixed in ME process"}; + Configurable applyEfficiency{"applyEfficiency", 1, "Flag for applying Lc efficiency weights"}; + Configurable yCandMax{"yCandMax", 0.8, "max. cand. rapidity"}; + Configurable yCandGenMax{"yCandGenMax", 0.5, "max. gen. cand. rapidity"}; + Configurable etaTrackMax{"etaTrackMax", 0.8, "max. eta of tracks"}; + Configurable dcaXYTrackMax{"dcaXYTrackMax", 1., "max. DCAxy of tracks"}; + Configurable dcaZTrackMax{"dcaZTrackMax", 1., "max. DCAz of tracks"}; + Configurable ptCandMin{"ptCandMin", 1., "min. cand. pT"}; + Configurable ptCandMax{"ptCandMax", 50., "max. cand. pT"}; + Configurable ptTrackMin{"ptTrackMin", 0.3, "min. track pT"}; + Configurable ptTrackMax{"ptTrackMax", 50., "max. track pT"}; + Configurable multMin{"multMin", 0., "minimum multiplicity accepted"}; + Configurable multMax{"multMax", 10000., "maximum multiplicity accepted"}; + Configurable> classMl{"classMl", {0, 1, 2}, "Indexes of ML scores to be stored. Three indexes max."}; + Configurable> binsPtLc{"binsPtLc", std::vector{o2::analysis::hf_cuts_lc_to_p_k_pi::vecBinsPt}, "pT bin limits for candidate mass plots"}; + Configurable> binsPtHadron{"binsPtHadron", std::vector{0.3, 2., 4., 8., 12., 50.}, "pT bin limits for assoc particle"}; + Configurable> binsPtEfficiencyLc{"binsPtEfficiencyLc", std::vector{o2::analysis::hf_cuts_lc_to_p_k_pi::vecBinsPt}, "pT bin limits for efficiency"}; + Configurable> efficiencyLc{"efficiencyLc", {1., 1., 1., 1., 1., 1.}, "efficiency values for Lc"}; + Configurable storeAutoCorrelationFlag{"storeAutoCorrelationFlag", false, "Store flag that indicates if the track is paired to its Lc mother instead of skipping it"}; + Configurable correlateLcWithLeadingParticle{"correlateLcWithLeadingParticle", false, "Switch for correlation of Lc baryons with leading particle only"}; + Configurable pidTrkApplied{"pidTrkApplied", false, "Apply PID selection for associated tracks"}; + Configurable> trkPIDspecies{"trkPIDspecies", std::vector{o2::track::PID::Proton, o2::track::PID::Pion, o2::track::PID::Kaon}, "Trk sel: Particles species for PID, proton, pion, kaon"}; + Configurable> pidTPCMax{"pidTPCMax", std::vector{3., 0., 0.}, "maximum nSigma TPC"}; + Configurable> pidTOFMax{"pidTOFMax", std::vector{3., 0., 0.}, "maximum nSigma TOF"}; + Configurable tofPIDThreshold{"tofPIDThreshold", 0.75, "minimum pT after which TOF PID is applicable"}; + Configurable fillTrkPID{"fillTrkPID", false, "fill PID information for associated tracks"}; + Configurable forceTOF{"forceTOF", false, "fill PID information for associated tracks"}; + Configurable calTrkEff{"calTrkEff", false, "fill histograms to calculate efficiency"}; + Configurable isRecTrkPhyPrimary{"isRecTrkPhyPrimary", true, "Calculate the efficiency of reconstructed primary physical tracks"}; + Configurable calEffEventWithCand{"calEffEventWithCand", true, "Calculate the efficiency of Lc candidate"}; + Configurable eventFractionToAnalyze{"eventFractionToAnalyze", -1, "Fraction of events to analyze (use only for ME offline on very large samples)"}; + + HfHelper hfHelper; + SliceCache cache; + Service pdg; + int leadingIndex = 0; + int poolBin = 0; + int poolBinLc = 0; + bool correlationStatus = false; + bool isPrompt = false; + bool isNonPrompt = false; + bool isSignal = false; + + static constexpr size_t NDaughters{3u}; + TRandom3* rnd = new TRandom3(0); + std::vector outputMl = {-1., -1., -1.}; + std::vector outputMlPKPi = {-1., -1., -1.}; + std::vector outputMlPiKP = {-1., -1., -1.}; + + // Event Mixing for the Data Mode + using SelCollisionsWithSc = soa::Join; + using SelCollisionsWithLc = soa::Filtered>; + using SelCollisionsWithLcMc = soa::Filtered>; // collisionFilter applied + + using CandsLcData = soa::Join; + using CandsLcDataFiltered = soa::Filtered; + + // Event Mixing for the MCRec Mode + using CandsLcMcRec = soa::Join; + using CandsLcMcRecFiltered = soa::Filtered; + using CandidatesLcMcGen = soa::Join; // flagLcFilter applied + // Event Mixing for the MCGen Mode + using McCollisionsSel = soa::Filtered>; + using McParticlesSel = soa::Filtered; + // Tracks used in Data and MC + using TracksData = soa::Filtered>; // trackFilter applied + using TracksWithMc = soa::Filtered>; // trackFilter applied + // Filters for ME + Filter collisionFilter = aod::hf_selection_lc_collision::lcSel == true; + Filter lcFilter = ((o2::aod::hf_track_index::hfflag & static_cast(1 << aod::hf_cand_3prong::DecayType::LcToPKPi)) != static_cast(0)) && (aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlagLc || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlagLc); + Filter trackFilter = (nabs(aod::track::eta) < etaTrackMax) && (nabs(aod::track::pt) > ptTrackMin) && (nabs(aod::track::dcaXY) < dcaXYTrackMax) && (nabs(aod::track::dcaZ) < dcaZTrackMax); + + // Preslice perTrueCollision = o2::aod::mcparticle::McCollisionId; + Preslice perTrueCollision = o2::aod::mcparticle::mcCollisionId; + // configurable axis definition + ConfigurableAxis binsMultiplicity{"binsMultiplicity", {VARIABLE_WIDTH, 0.0f, 2000.0f, 6000.0f, 100000.0f}, "Mixing bins - multiplicity"}; + ConfigurableAxis binsZVtx{"binsZVtx", {VARIABLE_WIDTH, -10.0f, -2.5f, 2.5f, 10.0f}, "Mixing bins - z-vertex"}; + ConfigurableAxis binsMultiplicityMc{"binsMultiplicityMc", {VARIABLE_WIDTH, 0.0f, 20.0f, 50.0f, 500.0f}, "Mixing bins - MC multiplicity"}; // In MCGen multiplicity is defined by counting tracks + ConfigurableAxis binsBdtScore{"binsBdtScore", {100, 0., 1.}, "Bdt output scores"}; + ConfigurableAxis binsEta{"binsEta", {50, -2., 2.}, "#it{#eta}"}; + ConfigurableAxis binsPhi{"binsPhi", {64, -PIHalf, 3. * PIHalf}, "#it{#varphi}"}; + ConfigurableAxis binsPoolBin{"binsPoolBin", {9, 0., 9.}, "PoolBin"}; + ConfigurableAxis binsMultFT0M{"binsMultFT0M", {600, 0., 6000.}, "Multiplicity as FT0M signal amplitude"}; + ConfigurableAxis binsCandMass{"binsCandMass", {200, 1.98, 2.58}, "inv. mass (p K #pi) (GeV/#it{c}^{2})"}; + + BinningType corrBinning{{binsZVtx, binsMultiplicity}, true}; + + HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; + void init(InitContext&) + { + AxisSpec axisCandMass = {binsCandMass, "inv. mass (p K #pi) (GeV/#it{c}^{2})"}; + AxisSpec axisEta = {binsEta, "#it{eta}"}; + AxisSpec axisPhi = {binsPhi, "#it{#varphi}"}; + AxisSpec axisPtLc = {static_cast>(binsPtLc), "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec axisPtHadron = {static_cast>(binsPtHadron), "#it{p}_{T} Hadron (GeV/#it{c})"}; + AxisSpec axisPtTrack = {500, 0, 50, "#it{p}_{T} Hadron (GeV/#it{c})"}; + AxisSpec axisMultiplicity = {binsMultiplicity, "Multiplicity"}; + AxisSpec axisMultFT0M = {binsMultFT0M, "MultiplicityFT0M"}; + AxisSpec axisPosZ = {binsZVtx, "PosZ"}; + AxisSpec axisBdtScore = {binsBdtScore, "Bdt score"}; + AxisSpec axisPoolBin = {binsPoolBin, "PoolBin"}; + AxisSpec axisRapidity = {100, -2, 2, "Rapidity"}; + AxisSpec axisSign = {2, -1, 1, "Sign"}; + + registry.add("hPtCand", "Lc,Hadron candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPtLc}}); + registry.add("hPtProng0", "Lc,Hadron candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPtLc}}); + registry.add("hPtProng1", "Lc,Hadron candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPtLc}}); + registry.add("hPtProng2", "Lc,Hadron candidates;prong 2 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPtLc}}); + registry.add("hSelectionStatusLcToPKPi", "Lc,Hadron candidates;selection status;entries", {HistType::kTH1F, {{8, -0.5, 7.5}}}); + registry.add("hSelectionStatusLcToPiKP", "Lc,Hadron candidates;selection status;entries", {HistType::kTH1F, {{8, -0.5, 7.5}}}); + registry.add("hEta", "Lc,Hadron candidates;candidate #it{#eta};entries", {HistType::kTH1F, {axisEta}}); + registry.add("hPhi", "Lc,Hadron candidates;candidate #it{#varphi};entries", {HistType::kTH1F, {axisPhi}}); + registry.add("hcountCandHadronPerEvent", "Lc,Hadron particles - MC gen;Number per event;entries", {HistType::kTH1F, {{21, -0.5, 20.5}}}); + registry.add("hMultiplicityPreSelection", "multiplicity prior to selection;multiplicity;entries", {HistType::kTH1F, {{10000, 0., 10000.}}}); + registry.add("hMultiplicity", "multiplicity;multiplicity;entries", {HistType::kTH1F, {{10000, 0., 10000.}}}); + registry.add("hMultFT0M", "multiplicity;multiplicity;entries", {HistType::kTH1F, {{10000, 0., 10000.}}}); + registry.add("hZvtx", "z vertex;z vertex;entries", {HistType::kTH1F, {{200, -20., 20.}}}); + registry.add("hCandBin", "Lc selected in pool Bin;pool Bin;entries", {HistType::kTH1F, {{9, 0., 9.}}}); + registry.add("hTracksBin", "Tracks selected in pool Bin;pool Bin;entries", {HistType::kTH1F, {{9, 0., 9.}}}); + registry.add("hMassLcVsPt", "Lc candidates;inv. mass (p K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{axisCandMass}, {axisPtLc}}}); + registry.add("hMassLcData", "Lc candidates;inv. mass (p K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{axisCandMass}}}); + registry.add("hLcPoolBin", "Lc candidates pool bin", {HistType::kTH1F, {axisPoolBin}}); + registry.add("hTracksPoolBin", "Particles associated pool bin", {HistType::kTH1F, {axisPoolBin}}); + // Histograms for MC Reco analysis + registry.add("hMcEvtCount", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}); + registry.add("hMassLcMcRecBkg", "Lc background candidates - MC reco;inv. mass (p K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{axisCandMass}, {axisPtLc}}}); + registry.add("hPtCandSig", "Lc,Hadron candidates - MC Reco", {HistType::kTH1F, {axisPtLc}}); + registry.add("hPtCandSigPrompt", "Lc,Hadron candidates Prompt - MC Reco", {HistType::kTH1F, {axisPtLc}}); + registry.add("hPtCandSigNonPrompt", "Lc,Hadron candidates Non Prompt - MC Reco", {HistType::kTH1F, {axisPtLc}}); + registry.add("hPtCandMcRecBkg", "Lc,Hadron candidates - MC Reco", {HistType::kTH1F, {axisPtLc}}); + registry.add("hEtaSig", "Lc,Hadron candidates - MC Reco", {HistType::kTH1F, {axisEta}}); + registry.add("hPhiSig", "Lc,Hadron candidates - MC Reco", {HistType::kTH1F, {axisPhi}}); + registry.add("hY", "Lc,Hadron candidates;candidate #it{#y};entries", {HistType::kTH1F, {axisRapidity}}); + registry.add("hYSig", "Lc,Hadron candidates - MC reco;candidate #it{#y};entries", {HistType::kTH1F, {axisRapidity}}); + registry.add("hPtCandMcRecSigPrompt", "Lc,Hadron candidates Prompt - MC Reco", {HistType::kTH1F, {axisPtLc}}); + registry.add("hPtCandMcRecSigNonPrompt", "Lc,Hadron candidates Non Prompt - MC Reco", {HistType::kTH1F, {axisPtLc}}); + registry.add("hEtaMcRecBkg", "Lc,Hadron candidates - MC Reco", {HistType::kTH1F, {axisEta}}); + registry.add("hPhiMcRecBkg", "Lc,Hadron candidates - MC Reco", {HistType::kTH1F, {axisPhi}}); + registry.add("hYMcRecBkg", "Lc,Hadron candidates - MC reco;candidate #it{#y};entries", {HistType::kTH1F, {axisRapidity}}); + registry.add("hFakeTracksMcRec", "Fake tracks - MC Rec", {HistType::kTH1F, {axisPtHadron}}); + registry.add("hPtParticleAssocVsCandMcRec", "Associated Particle - MC Rec", {HistType::kTH2F, {{axisPtHadron}, {axisPtLc}}}); + registry.add("hPtTracksVsSignRec", "Associated Particle - MC Rec", {HistType::kTH2F, {{axisPtTrack}, {axisSign}}}); + registry.add("hPtTracksVsSignRecTrue", "Associated Particle - MC Rec (True)", {HistType::kTH2F, {{axisPtTrack}, {axisSign}}}); + registry.add("hPtTracksVsSignGen", "Associated Particle - MC Gen", {HistType::kTH2F, {{axisPtTrack}, {axisSign}}}); + registry.add("hPtPrimaryParticleAssocVsCandMcRec", "Associated Particle - MC Rec", {HistType::kTH2F, {{axisPtHadron}, {axisPtLc}}}); + registry.add("hPtVsMultiplicityMcRecPrompt", "Multiplicity FT0M - MC Rec Prompt", {HistType::kTH2F, {{axisPtLc}, {axisMultFT0M}}}); + registry.add("hPtVsMultiplicityMcRecNonPrompt", "Multiplicity FT0M - MC Rec Non Prompt", {HistType::kTH2F, {{axisPtLc}, {axisMultFT0M}}}); + // Histograms for MC Gen analysis + registry.add("hcountCandtriggersMcGen", "Lc trigger particles - MC gen;;N of trigger Lc", {HistType::kTH2F, {{1, -0.5, 0.5}, {axisPtLc}}}); + registry.add("hPtCandMcGen", "Lc,Hadron particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPtLc}}); + registry.add("hYMcGen", "Lc,Hadron candidates - MC gen;candidate #it{#y};entries", {HistType::kTH1F, {axisRapidity}}); + registry.add("hPtCandMcGenPrompt", "Lc,Hadron particles - MC Gen Prompt", {HistType::kTH1F, {axisPtLc}}); + registry.add("hPtCandMcGenNonPrompt", "Lc,Hadron particles - MC Gen Non Prompt", {HistType::kTH1F, {axisPtLc}}); + registry.add("hPtParticleAssocMcGen", "Associated Particle - MC Gen", {HistType::kTH1F, {axisPtHadron}}); + registry.add("hEtaMcGen", "Lc,Hadron particles - MC Gen", {HistType::kTH1F, {axisEta}}); + registry.add("hPhiMcGen", "Lc,Hadron particles - MC Gen", {HistType::kTH1F, {axisPhi}}); + registry.add("hMultFT0AMcGen", "Lc,Hadron multiplicity FT0A - MC Gen", {HistType::kTH1F, {axisMultiplicity}}); + + corrBinning = {{binsZVtx, binsMultiplicity}, true}; + } + + template + void fillMlOutput(MlProbType const& mlProb, std::vector& outputMl) + { + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { + outputMl[iclass] = mlProb[classMl->at(iclass)]; + } + }; + + template + double estimateY(CandType const& candidate) + { + double y = -999.; + const int chargeScZero = 0; + if constexpr (isCandSc) { + int8_t chargeCand = candidate.charge(); + + if (chargeCand == chargeScZero) { + y = hfHelper.ySc0(candidate); + } else { + y = hfHelper.yScPlusPlus(candidate); + } + + } else { + y = hfHelper.yLc(candidate); + } + return y; + } + + template + void calculateTrkEff(T1 const& trackPos1, T2 const& trackPos2, McPart const& mcParticles) + { + // genrated tracks + decltype(trackPos1.template mcParticle_as()) mctrk{}; + if (trackPos1.has_mcParticle()) { // ambiguous tracks should be small + mctrk = trackPos1.template mcParticle_as(); + } else if (trackPos2.has_mcParticle()) { + mctrk = trackPos2.template mcParticle_as(); + } else { + return; + } + auto gentracks = mcParticles.sliceBy(perTrueCollision, mctrk.mcCollisionId()); + for (const auto& track : gentracks) { + if (std::abs(track.eta()) > etaTrackMax || track.pt() < ptTrackMin || track.pt() > ptTrackMax) { + continue; + } + if ((std::abs(track.pdgCode()) != kElectron) && (std::abs(track.pdgCode()) != kMuonMinus) && (std::abs(track.pdgCode()) != kPiPlus) && (std::abs(track.pdgCode()) != kKPlus) && (std::abs(track.pdgCode()) != kProton)) { + continue; + } + + if (pidTrkApplied && (std::abs(track.pdgCode()) != kProton)) + continue; // proton PID + + if (!track.isPhysicalPrimary()) { + continue; + } + + auto motherTrkGen = mcParticles.iteratorAt(track.mothersIds()[0]); + if (std::abs(motherTrkGen.pdgCode()) == kLambdaCPlus) + continue; + + auto chargeTrack = pdg->GetParticle(track.pdgCode())->Charge(); // Retrieve charge + registry.fill(HIST("hPtTracksVsSignGen"), track.pt(), chargeTrack / (2 * std::abs(chargeTrack))); + } + } + template + void fillCorrelationTable(bool trkPidFill, TrackType const& track, CandType const& candidate, + const std::vector& outMl, int binPool, int8_t correlStatus, + double yCand, int signCand, McPart const& mcParticles) + { + bool isPhysicalPrimary = false; + int trackOrigin = -1; + + entryCandHadronPair(getDeltaPhi(track.phi(), candidate.phi()), + track.eta() - candidate.eta(), + candidate.pt(), + track.pt() * track.sign(), + binPool, + correlStatus); + entryCandHadronPairY(track.y() - yCand); + entryCandHadronMlInfo(outMl[0], outMl[1]); + entryTrackRecoInfo(track.dcaXY(), track.dcaZ(), track.tpcNClsCrossedRows()); + entryPairCandCharge(signCand); + if (trkPidFill) { + entryCandHadronPairTrkPID(track.tpcNSigmaPr(), track.tpcNSigmaKa(), track.tpcNSigmaPi(), track.tofNSigmaPr(), track.tofNSigmaKa(), track.tofNSigmaPi()); + } + if constexpr (isMcRec) { + if (track.has_mcParticle()) { + auto mcParticle = track.template mcParticle_as(); + isPhysicalPrimary = mcParticle.isPhysicalPrimary(); + trackOrigin = RecoDecay::getCharmHadronOrigin(mcParticles, mcParticle, true); + entryCandHadronGenInfo(isPrompt, isPhysicalPrimary, trackOrigin); + } else { + entryCandHadronGenInfo(isPrompt, false, 0); + registry.fill(HIST("hFakeTracksMcRec"), track.pt()); + } + registry.fill(HIST("hPtParticleAssocVsCandMcRec"), track.pt(), candidate.pt()); + if (isPhysicalPrimary) { + registry.fill(HIST("hPtPrimaryParticleAssocVsCandMcRec"), track.pt(), candidate.pt()); + } + } + } + + template + void doSameEvent(CollisionType const& collision, + TrackType const& tracks, + CandType const& candidates, + aod::McParticles const* mcParticles = nullptr) + { + + int nTracks = 0; + int64_t timeStamp = 0; + const int chargeScPlusPlus = 2; + const int chargeScZero = 0; + bool skipMixedEventTableFilling = false; + float multiplicityFT0M = collision.multFT0M(); + int gCollisionId = collision.globalIndex(); + if (candidates.size() == 0) { + return; + } + + if (eventFractionToAnalyze > 0) { + if (rnd->Uniform(0, 1) > eventFractionToAnalyze) { + skipMixedEventTableFilling = true; + } + } + + if constexpr (!isMcRec) { + timeStamp = collision.template bc_as().timestamp(); + } + + poolBin = corrBinning.getBin(std::make_tuple(collision.posZ(), multiplicityFT0M)); + if (correlateLcWithLeadingParticle) { + leadingIndex = findLeadingParticle(tracks, etaTrackMax.value); + } + + // Count good tracks + if (collision.numContrib() > 1) { + for (const auto& track : tracks) { + if (std::abs(track.eta()) > etaTrackMax || std::abs(track.dcaXY()) > dcaXYTrackMax || std::abs(track.dcaZ()) > dcaZTrackMax) { + continue; + } + nTracks++; + } + } + + registry.fill(HIST("hMultiplicityPreSelection"), nTracks); + if (nTracks < multMin || nTracks > multMax) { + return; + } + registry.fill(HIST("hMultiplicity"), nTracks); + + int countCand = 1; + + for (const auto& candidate : candidates) { + + int8_t chargeCand = 3; + double efficiencyWeightCand = 1.; + double yCand = -999.0; + double etaCand = -999.0; + double ptCandLc = -999.0; + double ptCand = -999.0; + double phiCand = -999.0; + double massCandPKPi = -999.0; + double massCandPiKP = -999.0; + bool selLcPKPi = false; + bool selLcPiKP = false; + + yCand = estimateY(candidate); + etaCand = candidate.eta(); + ptCand = candidate.pt(); + phiCand = RecoDecay::constrainAngle(candidate.phi(), -PIHalf); + + if ((std::abs(yCand) > yCandMax) || ptCand < ptCandMin || ptCand > ptCandMax) { + continue; + } + + registry.fill(HIST("hY"), yCand); + registry.fill(HIST("hPtCand"), ptCand); + registry.fill(HIST("hEta"), etaCand); + registry.fill(HIST("hPhi"), phiCand); + registry.fill(HIST("hCandBin"), poolBin); + + if (applyEfficiency) { + efficiencyWeightCand = 1. / efficiencyLc->at(o2::analysis::findBin(binsPtEfficiencyLc, ptCand)); + } + + if constexpr (isMcRec) { + isPrompt = candidate.originMcRec() == RecoDecay::OriginType::Prompt; + isNonPrompt = candidate.originMcRec() == RecoDecay::OriginType::NonPrompt; + } + + if constexpr (isCandSc) { + chargeCand = candidate.charge(); + const auto& candidateLc = candidate.template prongLc_as(); + ptCandLc = candidateLc.pt(); + selLcPKPi = (candidateLc.isSelLcToPKPi() >= selectionFlagLc) && (candidate.statusSpreadLcMinvPKPiFromPDG()); + selLcPiKP = (candidateLc.isSelLcToPiKP() >= selectionFlagLc) && (candidate.statusSpreadLcMinvPiKPFromPDG()); + if (selLcPKPi) { + const auto& probs = candidateLc.mlProbLcToPKPi(); + fillMlOutput(probs, outputMlPKPi); + massCandPKPi = hfHelper.invMassScRecoLcToPKPi(candidate, candidateLc); + } + if (selLcPiKP) { + const auto& probs = candidateLc.mlProbLcToPiKP(); + fillMlOutput(probs, outputMlPiKP); + massCandPiKP = hfHelper.invMassScRecoLcToPiKP(candidate, candidateLc); + } + if constexpr (isMcRec) { + // isSignal = + // (TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi) && chargeCand == 0) || + // (TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi) && std::abs(chargeCand) == 2); + isSignal = + (std::abs(candidate.flagMcMatchRec()) == (1 << aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi) && chargeCand == chargeScZero) || + (std::abs(candidate.flagMcMatchRec()) == (1 << aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi) && std::abs(chargeCand) == chargeScPlusPlus); + + auto trackPos1 = candidateLc.template prong0_as(); + auto trackPos2 = candidateLc.template prong2_as(); + if (calTrkEff && countCand == 1 && (isSignal || !calEffEventWithCand)) { + calculateTrkEff(trackPos1, trackPos2, *mcParticles); + } + registry.fill(HIST("hPtProng1"), candidate.template prong1_as().pt()); + } else { + registry.fill(HIST("hPtProng1"), candidate.prong1().pt()); + } + registry.fill(HIST("hPtProng0"), ptCandLc); + } else { + selLcPKPi = candidate.isSelLcToPKPi() >= selectionFlagLc; + selLcPiKP = candidate.isSelLcToPiKP() >= selectionFlagLc; + if (selLcPKPi) { + const auto& probs = candidate.mlProbLcToPKPi(); + fillMlOutput(probs, outputMlPKPi); + massCandPKPi = hfHelper.invMassLcToPKPi(candidate); + } + if (selLcPiKP) { + const auto& probs = candidate.mlProbLcToPiKP(); + fillMlOutput(probs, outputMlPiKP); + massCandPiKP = hfHelper.invMassLcToPiKP(candidate); + } + auto trackPos1 = candidate.template prong0_as(); + auto trackPos2 = candidate.template prong2_as(); + chargeCand = trackPos1.sign(); + if constexpr (isMcRec) { + isSignal = TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_3prong::DecayType::LcToPKPi); + if (calTrkEff && countCand == 1 && (isSignal || !calEffEventWithCand)) { + calculateTrkEff(trackPos1, trackPos2, *mcParticles); + } + } + registry.fill(HIST("hPtProng0"), candidate.ptProng0()); + registry.fill(HIST("hPtProng1"), candidate.ptProng1()); + registry.fill(HIST("hPtProng2"), candidate.ptProng2()); + } + + if (isSignal) { + registry.fill(HIST("hPtCandSig"), ptCand); + registry.fill(HIST("hEtaSig"), ptCand); + registry.fill(HIST("hPhiSig"), phiCand); + registry.fill(HIST("hYSig"), yCand); + } + + if (selLcPKPi) { + registry.fill(HIST("hMassLcVsPt"), massCandPKPi, ptCand, efficiencyWeightCand); + registry.fill(HIST("hMassLcData"), massCandPKPi, efficiencyWeightCand); + registry.fill(HIST("hSelectionStatusLcToPKPi"), selLcPKPi); + if (isPrompt) { + registry.fill(HIST("hPtCandSigPrompt"), ptCand); + registry.fill(HIST("hPtVsMultiplicityMcRecPrompt"), ptCand, multiplicityFT0M); + } else if (isNonPrompt) { + registry.fill(HIST("hPtCandSigNonPrompt"), ptCand); + registry.fill(HIST("hPtVsMultiplicityMcRecNonPrompt"), ptCand, multiplicityFT0M); + } + + entryCandCandRecoInfo(massCandPKPi, ptCand, outputMlPKPi[0], outputMlPKPi[1]); + entryCandCandGenInfo(isPrompt); + if (!skipMixedEventTableFilling) { + entryCand(candidate.phi(), etaCand, ptCand, massCandPKPi, poolBin, gCollisionId, timeStamp); + entryCandCharge(chargeCand); + } + } + + if (selLcPiKP) { + registry.fill(HIST("hMassLcVsPt"), massCandPiKP, ptCand, efficiencyWeightCand); + registry.fill(HIST("hMassLcData"), massCandPiKP, efficiencyWeightCand); + registry.fill(HIST("hSelectionStatusLcToPiKP"), selLcPiKP); + if (isPrompt) { + registry.fill(HIST("hPtCandSigPrompt"), ptCand); + registry.fill(HIST("hPtVsMultiplicityMcRecPrompt"), ptCand, multiplicityFT0M); + } else if (isNonPrompt) { + registry.fill(HIST("hPtCandSigNonPrompt"), ptCand); + registry.fill(HIST("hPtVsMultiplicityMcRecNonPrompt"), ptCand, multiplicityFT0M); + } + entryCandCandRecoInfo(massCandPiKP, ptCand, outputMlPiKP[0], outputMlPiKP[1]); + entryCandCandGenInfo(isPrompt); + if (!skipMixedEventTableFilling) { + entryCand(candidate.phi(), etaCand, ptCand, massCandPiKP, poolBin, gCollisionId, timeStamp); + entryCandCharge(chargeCand); + } + } + + registry.fill(HIST("hCandBin"), poolBin); + // Correlation with hadrons + for (const auto& track : tracks) { + // Remove Lc daughters by checking track indices + if constexpr (!isCandSc) { + if ((candidate.prong0Id() == track.globalIndex()) || (candidate.prong1Id() == track.globalIndex()) || (candidate.prong2Id() == track.globalIndex())) { + if (!storeAutoCorrelationFlag) { + continue; + } + correlationStatus = true; + } + } else { + const auto& candidateLc = candidate.template prongLc_as(); + if ((candidateLc.prong0Id() == track.globalIndex()) || (candidateLc.prong1Id() == track.globalIndex()) || (candidateLc.prong2Id() == track.globalIndex()) || (candidate.prong1Id() == track.globalIndex())) { + if (!storeAutoCorrelationFlag) { + continue; + } + correlationStatus = true; + } + } + if (!track.isGlobalTrackWoDCA()) { + continue; + } + if (pidTrkApplied) { + if (!passPIDSelection(track, trkPIDspecies, pidTPCMax, pidTOFMax, tofPIDThreshold, forceTOF)) + continue; + } + if (correlateLcWithLeadingParticle) { + if (track.globalIndex() != leadingIndex) { + continue; + } + } + if constexpr (isMcRec) { + if (calTrkEff && countCand == 1 && (isSignal || !calEffEventWithCand) && track.has_mcParticle()) { + auto mcParticle = track.template mcParticle_as(); + if (!mcParticle.isPhysicalPrimary() && isRecTrkPhyPrimary) + continue; + + auto motherTrk = mcParticles->iteratorAt(mcParticle.mothersIds()[0]); + if (std::abs(motherTrk.pdgCode()) == kLambdaCPlus) + continue; + + registry.fill(HIST("hPtTracksVsSignRec"), track.pt(), track.sign() / 2.); + if (std::abs(mcParticle.pdgCode()) == kProton) + registry.fill(HIST("hPtTracksVsSignRecTrue"), track.pt(), track.sign() / 2.); + } + } + + if (selLcPKPi) { + fillCorrelationTable(fillTrkPID, track, candidate, outputMlPKPi, poolBin, correlationStatus, yCand, chargeCand, *mcParticles); + entryCandHadronRecoInfo(massCandPKPi, false); + } + if (selLcPiKP) { + fillCorrelationTable(fillTrkPID, track, candidate, outputMlPiKP, poolBin, correlationStatus, yCand, chargeCand, *mcParticles); + entryCandHadronRecoInfo(massCandPiKP, false); + } + + if (countCand == 1) { + if (!skipMixedEventTableFilling) { + entryHadron(track.phi(), track.eta(), track.pt() * track.sign(), poolBin, gCollisionId, timeStamp); + if (fillTrkPID) { + entryTrkPID(track.tpcNSigmaPr(), track.tpcNSigmaKa(), track.tpcNSigmaPi(), track.tofNSigmaPr(), track.tofNSigmaKa(), track.tofNSigmaPi()); + } + registry.fill(HIST("hTracksBin"), poolBin); + } + } + } // end Hadron Tracks loop + countCand++; + } // end outer Lc loop + registry.fill(HIST("hZvtx"), collision.posZ()); + registry.fill(HIST("hMultFT0M"), multiplicityFT0M); + } + + template + void doMixEvent(CollisionType const& collisions, + TrackType const& tracks, + CandType const& candidates, + aod::McParticles const* mcParticles = nullptr) + { + + if (candidates.size() == 0) { + return; + } + + double yCand = -999.; + double ptCand = -999.; + int8_t chargeCand = 3; + double massCandPKPi = -999.0; + double massCandPiKP = -999.0; + bool selLcPKPi = false; + bool selLcPiKP = false; + const int chargeScPlusPlus = 2; + const int chargeScZero = 0; + + auto tracksTuple = std::make_tuple(candidates, tracks); + Pair pairData{corrBinning, numberEventsMixed, -1, collisions, tracksTuple, &cache}; + + for (const auto& [c1, tracks1, c2, tracks2] : pairData) { + poolBin = corrBinning.getBin(std::make_tuple(c2.posZ(), c2.multFT0M())); + poolBinLc = corrBinning.getBin(std::make_tuple(c1.posZ(), c1.multFT0M())); + registry.fill(HIST("hMultFT0M"), c1.multFT0M()); + registry.fill(HIST("hZvtx"), c1.posZ()); + registry.fill(HIST("hTracksPoolBin"), poolBin); + registry.fill(HIST("hLcPoolBin"), poolBinLc); + for (const auto& [candidate, assocParticle] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { + + yCand = estimateY(candidate); + ptCand = candidate.pt(); + if constexpr (isMcRec) { + isPrompt = candidate.originMcRec() == RecoDecay::OriginType::Prompt; + isNonPrompt = candidate.originMcRec() == RecoDecay::OriginType::NonPrompt; + } + + if constexpr (isCandSc) { + const auto& candidateLc = candidate.template prongLc_as(); + chargeCand = candidate.charge(); + selLcPKPi = (candidateLc.isSelLcToPKPi() >= selectionFlagLc) && (candidate.statusSpreadLcMinvPKPiFromPDG()); + selLcPiKP = (candidateLc.isSelLcToPiKP() >= selectionFlagLc) && (candidate.statusSpreadLcMinvPiKPFromPDG()); + if (selLcPKPi) { + const auto& probs = candidateLc.mlProbLcToPKPi(); + fillMlOutput(probs, outputMlPKPi); + massCandPKPi = hfHelper.invMassScRecoLcToPKPi(candidate, candidateLc); + } + if (selLcPiKP) { + const auto& probs = candidateLc.mlProbLcToPiKP(); + fillMlOutput(probs, outputMlPiKP); + massCandPiKP = hfHelper.invMassScRecoLcToPKPi(candidate, candidateLc); + } + if constexpr (isMcRec) { + isSignal = + (TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi) && chargeCand == chargeScZero) || + (TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi) && std::abs(chargeCand) == chargeScPlusPlus); + } + } else { + selLcPKPi = candidate.isSelLcToPKPi() >= selectionFlagLc; + selLcPiKP = candidate.isSelLcToPiKP() >= selectionFlagLc; + if (selLcPKPi) { + const auto& probs = candidate.mlProbLcToPKPi(); + fillMlOutput(probs, outputMlPKPi); + massCandPKPi = hfHelper.invMassLcToPKPi(candidate); + } + if (selLcPiKP) { + const auto& probs = candidate.mlProbLcToPiKP(); + fillMlOutput(probs, outputMlPiKP); + massCandPiKP = hfHelper.invMassLcToPiKP(candidate); + } + auto trackPos1 = candidate.template prong0_as(); + chargeCand = trackPos1.sign(); + if constexpr (isMcRec) { + isSignal = TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_3prong::DecayType::LcToPKPi); + } + } + + if (!assocParticle.isGlobalTrackWoDCA() || std::abs(yCand) > yCandMax) { + continue; + } + + if (pidTrkApplied) { + if (!passPIDSelection(assocParticle, trkPIDspecies, pidTPCMax, pidTOFMax, tofPIDThreshold, forceTOF)) + continue; + } + + if (selLcPKPi) { + fillCorrelationTable(fillTrkPID, assocParticle, candidate, outputMlPKPi, poolBin, correlationStatus, yCand, chargeCand, *mcParticles); + entryCandHadronRecoInfo(massCandPKPi, false); + + if (isPrompt) { + registry.fill(HIST("hPtCandMcRecSigPrompt"), ptCand); + registry.fill(HIST("hPtVsMultiplicityMcRecPrompt"), ptCand, 0); + } else if (isNonPrompt) { + registry.fill(HIST("hPtCandMcRecSigNonPrompt"), ptCand); + registry.fill(HIST("hPtVsMultiplicityMcRecNonPrompt"), ptCand, 0); + } + } + + if (selLcPiKP) { + fillCorrelationTable(fillTrkPID, assocParticle, candidate, outputMlPiKP, poolBin, correlationStatus, yCand, chargeCand, *mcParticles); + entryCandHadronRecoInfo(massCandPiKP, false); + + if (isPrompt) { + registry.fill(HIST("hPtCandMcRecSigPrompt"), ptCand); + registry.fill(HIST("hPtVsMultiplicityMcRecPrompt"), ptCand, 0); + } else if (isNonPrompt) { + registry.fill(HIST("hPtCandMcRecSigNonPrompt"), ptCand); + registry.fill(HIST("hPtVsMultiplicityMcRecNonPrompt"), ptCand, 0); + } + } + } + } + } + + //} + + /// Lc-hadron correlation pair builder - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) + void processDataLc(SelCollisionsWithLc::iterator const& collision, + TracksData const& tracks, + CandsLcDataFiltered const& candidates, + aod::BCsWithTimestamps const&) + { + doSameEvent(collision, tracks, candidates); + } + PROCESS_SWITCH(HfCorrelatorLcScHadrons, processDataLc, "Process data", true); + + void processDataSc(SelCollisionsWithSc::iterator const& collision, + TracksData const& tracks, + aod::Tracks const&, + aod::HfCandSc const& candidates, + CandsLcData const&, + aod::BCsWithTimestamps const&) // MUST be last among index-compatible + { + doSameEvent(collision, tracks, candidates); + } + PROCESS_SWITCH(HfCorrelatorLcScHadrons, processDataSc, "Process data Sc", false); + + /// Lc-Hadron correlation process starts for McRec + void processMcRecLc(SelCollisionsWithLc::iterator const& collision, + TracksWithMc const& tracks, + CandsLcMcRecFiltered const& candidates, + aod::McParticles const& mcParticles) + { + doSameEvent(collision, tracks, candidates, &mcParticles); + } + PROCESS_SWITCH(HfCorrelatorLcScHadrons, processMcRecLc, "Process Mc Reco mode", false); + + /// Lc-Hadron correlation process starts for McRec + void processMcRecSc(SelCollisionsWithSc::iterator const& collision, + TracksWithMc const& tracks, + aod::TracksWMc const&, + soa::Join const& candidates, + CandsLcData const&, + aod::McParticles const& mcParticles) + { + doSameEvent(collision, tracks, candidates, &mcParticles); + } + PROCESS_SWITCH(HfCorrelatorLcScHadrons, processMcRecSc, "Process Mc Reco mode", false); + + void processDataMixedEventSc(SelCollisionsWithSc const& collisions, + TracksData const& tracks, + aod::Tracks const&, + aod::HfCandSc const& candidates, + CandsLcData const&) + { + doMixEvent(collisions, tracks, candidates); + } + PROCESS_SWITCH(HfCorrelatorLcScHadrons, processDataMixedEventSc, "Process Mixed Event Data", false); + + void processDataMixedEventLc(SelCollisionsWithLc const& collisions, + CandsLcDataFiltered const& candidates, + TracksData const& tracks) + { + + doMixEvent(collisions, tracks, candidates); + } + PROCESS_SWITCH(HfCorrelatorLcScHadrons, processDataMixedEventLc, "Process Mixed Event Data", false); + + void processMcRecMixedEventSc(SelCollisionsWithSc const& collisions, + TracksWithMc const& tracks, + aod::TracksWMc const&, + soa::Join const& candidates, + CandsLcData const&, + aod::McParticles const& mcParticles) + { + doMixEvent(collisions, tracks, candidates, &mcParticles); + } + PROCESS_SWITCH(HfCorrelatorLcScHadrons, processMcRecMixedEventSc, "Process Mixed Event McRec", false); + + void processMcRecMixedEventLc(SelCollisionsWithLc const& collisions, + CandsLcMcRecFiltered const& candidates, + TracksWithMc const& tracks, + aod::McParticles const& mcParticles) + { + doMixEvent(collisions, tracks, candidates, &mcParticles); + } + PROCESS_SWITCH(HfCorrelatorLcScHadrons, processMcRecMixedEventLc, "Process Mixed Event McRec", false) + + /// Lc-Hadron correlation pair builder - for Mc Gen-level analysis + void processMcGen(SelCollisionsWithLcMc::iterator const& mcCollision, + CandidatesLcMcGen const& mcParticles) + { + int counterLcHadron = 0; + registry.fill(HIST("hMcEvtCount"), 0); + + BinningTypeMcGen corrBinningMcGen{{binsZVtx, binsMultiplicityMc}, true}; + poolBin = corrBinningMcGen.getBin(std::make_tuple(mcCollision.posZ(), mcCollision.multMCFT0A())); + registry.fill(HIST("hMultFT0AMcGen"), mcCollision.multMCFT0A()); + + // find leading particle + if (correlateLcWithLeadingParticle) { + leadingIndex = findLeadingParticleMcGen(mcParticles, etaTrackMax.value, ptTrackMin.value); + } + + // Mc Gen level + for (const auto& particle : mcParticles) { + if (std::abs(particle.pdgCode()) != Pdg::kLambdaCPlus) { + continue; + } + if (!TESTBIT(std::abs(particle.flagMcMatchGen()), aod::hf_cand_3prong::DecayType::LcToPKPi)) { + continue; + } + double yL = RecoDecay::y(particle.pVector(), MassLambdaCPlus); + if (std::abs(yL) > yCandGenMax || particle.pt() < ptCandMin) { + continue; + } + registry.fill(HIST("hCandBin"), poolBin); + registry.fill(HIST("hPtCandMcGen"), particle.pt()); + registry.fill(HIST("hEtaMcGen"), particle.eta()); + registry.fill(HIST("hPhiMcGen"), RecoDecay::constrainAngle(particle.phi(), -PIHalf)); + registry.fill(HIST("hYMcGen"), yL); + + isPrompt = particle.originMcGen() == RecoDecay::OriginType::Prompt; + isNonPrompt = particle.originMcGen() == RecoDecay::OriginType::NonPrompt; + if (isPrompt) { + registry.fill(HIST("hPtCandMcGenPrompt"), particle.pt()); + } else if (isNonPrompt) { + registry.fill(HIST("hPtCandMcGenNonPrompt"), particle.pt()); + } + + // prompt and non-prompt division + std::vector listDaughters{}; + std::array arrDaughLcPDG = {kProton, -kKPlus, kPiPlus}; + std::array prongsId; + listDaughters.clear(); + RecoDecay::getDaughters(particle, &listDaughters, arrDaughLcPDG, 2); + int counterDaughters = 0; + if (listDaughters.size() == NDaughters) { + for (const auto& dauIdx : listDaughters) { + auto daughI = mcParticles.rawIteratorAt(dauIdx - mcParticles.offset()); + counterDaughters += 1; + prongsId[counterDaughters - 1] = daughI.globalIndex(); + } + } + counterLcHadron++; + // Lc Hadron correlation dedicated section + // if it's a Lc particle, search for Hadron and evalutate correlations + registry.fill(HIST("hcountCandtriggersMcGen"), 0, particle.pt()); // to count trigger Lc for normalisation + for (const auto& particleAssoc : mcParticles) { + if (std::abs(particleAssoc.eta()) > etaTrackMax || particleAssoc.pt() < ptTrackMin || particleAssoc.pt() > ptTrackMax) { + continue; + } + if (particleAssoc.globalIndex() == prongsId[0] || particleAssoc.globalIndex() == prongsId[1] || particleAssoc.globalIndex() == prongsId[2]) { + if (!storeAutoCorrelationFlag) { + continue; + } + correlationStatus = true; + } + + if ((std::abs(particleAssoc.pdgCode()) != kElectron) && (std::abs(particleAssoc.pdgCode()) != kMuonMinus) && (std::abs(particleAssoc.pdgCode()) != kPiPlus) && (std::abs(particle.pdgCode()) != kKPlus) && (std::abs(particleAssoc.pdgCode()) != kProton)) { + continue; + } + + if (pidTrkApplied && (std::abs(particleAssoc.pdgCode()) != kProton)) + continue; // proton PID + + if (!particleAssoc.isPhysicalPrimary()) { + continue; + } + + if (correlateLcWithLeadingParticle) { + if (particleAssoc.globalIndex() != leadingIndex) { + continue; + } + } + + int8_t chargeLc = pdg->GetParticle(particle.pdgCode())->Charge(); // Retrieve charge + int8_t chargeAssoc = pdg->GetParticle(particleAssoc.pdgCode())->Charge(); // Retrieve charge + + int trackOrigin = RecoDecay::getCharmHadronOrigin(mcParticles, particleAssoc, true); + registry.fill(HIST("hPtParticleAssocMcGen"), particleAssoc.pt()); + entryCandHadronPair(getDeltaPhi(particleAssoc.phi(), particle.phi()), + particleAssoc.eta() - particle.eta(), + particle.pt() * chargeLc / std::abs(chargeLc), + particleAssoc.pt() * chargeAssoc / std::abs(chargeAssoc), + poolBin, + correlationStatus); + entryCandHadronPairY(particleAssoc.y() - yL); + entryCandHadronRecoInfo(MassLambdaCPlus, true); + entryCandHadronGenInfo(isPrompt, particleAssoc.isPhysicalPrimary(), trackOrigin); + } // end inner loop + } // end outer loop + registry.fill(HIST("hcountCandHadronPerEvent"), counterLcHadron); + registry.fill(HIST("hZvtx"), mcCollision.posZ()); + } + PROCESS_SWITCH(HfCorrelatorLcScHadrons, processMcGen, "Process Mc Gen mode", false); + + void processMcGenMixedEvent(SelCollisionsWithLcMc const& collisions, + CandidatesLcMcGen const& mcParticles) + { + BinningTypeMcGen corrBinningMcGen{{binsZVtx, binsMultiplicityMc}, true}; + auto tracksTuple = std::make_tuple(mcParticles, mcParticles); + Pair pairMcGen{corrBinningMcGen, numberEventsMixed, -1, collisions, tracksTuple, &cache}; + for (const auto& [c1, tracks1, c2, tracks2] : pairMcGen) { + poolBin = corrBinningMcGen.getBin(std::make_tuple(c1.posZ(), c1.multMCFT0A())); + for (const auto& [candidate, particleAssoc] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { + if (std::abs(candidate.pdgCode()) != Pdg::kLambdaCPlus) { + continue; + } + double yL = RecoDecay::y(candidate.pVector(), MassLambdaCPlus); + if (std::abs(yL) > yCandGenMax || candidate.pt() < ptCandMin || candidate.pt() > ptCandMax) { + continue; + } + if (std::abs(particleAssoc.eta()) > etaTrackMax || particleAssoc.pt() < ptTrackMin || particleAssoc.pt() > ptTrackMax) { + continue; + } + if ((std::abs(particleAssoc.pdgCode()) != kElectron) && (std::abs(particleAssoc.pdgCode()) != kMuonMinus) && (std::abs(particleAssoc.pdgCode()) != kPiPlus) && (std::abs(particleAssoc.pdgCode()) != kKPlus) && (std::abs(particleAssoc.pdgCode()) != kProton)) { + continue; + } + if (!particleAssoc.isPhysicalPrimary()) { + continue; + } + if (pidTrkApplied && (std::abs(particleAssoc.pdgCode()) != kProton)) { + continue; // proton PID + } + int8_t chargeLc = pdg->GetParticle(candidate.pdgCode())->Charge(); // Retrieve charge + int8_t chargeAssoc = pdg->GetParticle(particleAssoc.pdgCode())->Charge(); // Retrieve charge + + int trackOrigin = RecoDecay::getCharmHadronOrigin(mcParticles, particleAssoc, true); + bool isPrompt = candidate.originMcGen() == RecoDecay::OriginType::Prompt; + entryCandHadronPair(getDeltaPhi(particleAssoc.phi(), candidate.phi()), + particleAssoc.eta() - candidate.eta(), + candidate.pt() * chargeLc / std::abs(chargeLc), + particleAssoc.pt() * chargeAssoc / std::abs(chargeAssoc), + poolBin, + correlationStatus); + entryCandHadronPairY(particleAssoc.y() - yL); + entryCandHadronRecoInfo(MassLambdaCPlus, true); + entryCandHadronGenInfo(isPrompt, particleAssoc.isPhysicalPrimary(), trackOrigin); + } + } + } + PROCESS_SWITCH(HfCorrelatorLcScHadrons, processMcGenMixedEvent, "Process Mixed Event McGen", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/HFC/TableProducer/femtoDreamProducer.cxx b/PWGHF/HFC/TableProducer/femtoDreamProducer.cxx index 16a32177afd..ee8ec8aaa26 100644 --- a/PWGHF/HFC/TableProducer/femtoDreamProducer.cxx +++ b/PWGHF/HFC/TableProducer/femtoDreamProducer.cxx @@ -563,7 +563,7 @@ struct HfFemtoDreamProducer { // Filling particle properties rowCandCharmHadGen.reserve(particles.size()); for (const auto& particle : particles) { - if (std::abs(particle.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::LcToPKPi) { + if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { rowCandCharmHadGen( particle.mcCollisionId(), particle.flagMcMatchGen(), diff --git a/PWGHF/HFC/Tasks/taskCorrelationD0Hadrons.cxx b/PWGHF/HFC/Tasks/taskCorrelationD0Hadrons.cxx index 2112aa91566..1ba66ef7177 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationD0Hadrons.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationD0Hadrons.cxx @@ -16,18 +16,19 @@ /// \author Samrangy Sadhu , INFN Bari /// \author Swapnesh Santosh Khade , IIT Indore -#include - -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" - #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsAnalysis.h" #include "PWGHF/HFC/DataModel/CorrelationTables.h" #include "PWGHF/HFC/Utils/utilsCorrelations.h" +#include "PWGHF/Utils/utilsAnalysis.h" + +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include using namespace o2; using namespace o2::constants::physics; diff --git a/PWGHF/HFC/Tasks/taskCorrelationDDbar.cxx b/PWGHF/HFC/Tasks/taskCorrelationDDbar.cxx index b45ce1b4a63..d641e9ea21c 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationDDbar.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationDDbar.cxx @@ -14,16 +14,17 @@ /// /// \author Fabio Colamaria , INFN Bari -#include +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/HFC/DataModel/CorrelationTables.h" +#include "PWGHF/Utils/utilsAnalysis.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsAnalysis.h" -#include "PWGHF/HFC/DataModel/CorrelationTables.h" +#include using namespace o2; using namespace o2::framework; diff --git a/PWGHF/HFC/Tasks/taskCorrelationDplusHadrons.cxx b/PWGHF/HFC/Tasks/taskCorrelationDplusHadrons.cxx index 73d703ffde1..963322d393f 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationDplusHadrons.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationDplusHadrons.cxx @@ -12,19 +12,22 @@ /// \file taskCorrelationDplusHadrons.cxx /// \brief D+-Hadrons azimuthal correlations analysis task - data-like, MC-reco and MC-Gen analyses /// \author Shyam Kumar -#include // std::shared_ptr -#include -#include -#include "CCDB/BasicCCDBManager.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsAnalysis.h" #include "PWGHF/HFC/DataModel/CorrelationTables.h" +#include "PWGHF/Utils/utilsAnalysis.h" + +#include "CCDB/BasicCCDBManager.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include // std::shared_ptr +#include +#include using namespace o2; using namespace o2::constants::math; @@ -77,7 +80,8 @@ struct HfTaskCorrelationDplusHadrons { Configurable selectionFlagDplus{"selectionFlagDplus", 7, "Selection Flag for D+"}; // 7 corresponds to topo+PID cuts Configurable selNoSameBunchPileUpColl{"selNoSameBunchPileUpColl", true, "Flag for rejecting the collisions associated with the same bunch crossing"}; Configurable> classMl{"classMl", {0, 1, 2}, "Indexes of ML scores to be stored. Three indexes max."}; - Configurable> mlScorePromptOrNonPrompt{"mlScorePromptOrNonPrompt", {0.5, 0.5, 0.5, 0.5}, "Machine learning scores for prompt or Feed-down"}; + Configurable> mlScorePromptOrNonPromptMin{"mlScorePromptOrNonPromptMin", {0.5, 0.5, 0.5, 0.5}, "Minimum Machine learning scores for prompt or Feed-down"}; + Configurable> mlScorePromptOrNonPromptMax{"mlScorePromptOrNonPromptMax", {1.0, 1.0, 1.0, 1.0}, "Maximum Machine learning scores for prompt or Feed-down"}; Configurable> mlScoreBkg{"mlScoreBkg", {0.5, 0.5, 0.5, 0.5}, "Machine learning scores for bkg"}; // pT ranges for correlation plots: the default values are those embedded in hf_cuts_dplus_to_pi_k_pi (i.e. the mass pT bins), but can be redefined via json files Configurable> binsPtCorrelations{"binsPtCorrelations", std::vector{ptBinsCorrelationsVec}, "pT bin limits for correlation plots"}; @@ -312,7 +316,7 @@ struct HfTaskCorrelationDplusHadrons { continue; } - if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPrompt->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { + if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPromptMin->at(effBinD) || bdtScorePromptOrNonPrompt > mlScorePromptOrNonPromptMax->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { continue; } double efficiencyWeightD = 1.; @@ -351,7 +355,7 @@ struct HfTaskCorrelationDplusHadrons { continue; } - if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPrompt->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { + if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPromptMin->at(effBinD) || bdtScorePromptOrNonPrompt > mlScorePromptOrNonPromptMax->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { continue; } if (trackDcaXY > dcaXYTrackMax || trackDcaZ > dcaZTrackMax || trackTpcCrossedRows < nTpcCrossedRaws) { @@ -414,7 +418,7 @@ struct HfTaskCorrelationDplusHadrons { if (ptD < binsPtEfficiencyD->front() || ptD > binsPtEfficiencyD->back()) continue; - if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPrompt->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { + if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPromptMin->at(effBinD) || bdtScorePromptOrNonPrompt > mlScorePromptOrNonPromptMax->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { continue; } double efficiencyWeightD = 1.; @@ -468,7 +472,7 @@ struct HfTaskCorrelationDplusHadrons { if (ptD < binsPtEfficiencyD->front() || ptD > binsPtEfficiencyD->back()) continue; - if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPrompt->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { + if (bdtScorePromptOrNonPrompt < mlScorePromptOrNonPromptMin->at(effBinD) || bdtScorePromptOrNonPrompt > mlScorePromptOrNonPromptMax->at(effBinD) || bdtScoreBkg > mlScoreBkg->at(effBinD)) { continue; } if (trackDcaXY > dcaXYTrackMax || trackDcaZ > dcaZTrackMax || trackTpcCrossedRows < nTpcCrossedRaws) { @@ -586,7 +590,7 @@ struct HfTaskCorrelationDplusHadrons { auto mcCollision = mcParticle.template mcCollision_as>(); multiplicity = mcCollision.multMCFT0A() + mcCollision.multMCFT0C(); // multFT0M = multFt0A + multFT0C hCandidates->Fill(kCandidateStepMcGenAll, mcParticle.pt(), multiplicity, mcParticle.originMcGen()); - if (std::abs(mcParticle.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi) { + if (std::abs(mcParticle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) { hCandidates->Fill(kCandidateStepMcGenDplusToPiKPi, mcParticle.pt(), multiplicity, mcParticle.originMcGen()); auto yDplus = RecoDecay::y(mcParticle.pVector(), o2::constants::physics::MassDPlus); if (std::abs(yDplus) <= yCandGenMax) { @@ -625,7 +629,7 @@ struct HfTaskCorrelationDplusHadrons { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl->at(iclass)]; } - if (outputMl[0] > mlScoreBkg->at(o2::analysis::findBin(binsPtEfficiencyD, candidate.pt())) || outputMl[idxBdtScore] < mlScorePromptOrNonPrompt->at(o2::analysis::findBin(binsPtEfficiencyD, candidate.pt()))) { + if (outputMl[0] > mlScoreBkg->at(o2::analysis::findBin(binsPtEfficiencyD, candidate.pt())) || outputMl[idxBdtScore] < mlScorePromptOrNonPromptMin->at(o2::analysis::findBin(binsPtEfficiencyD, candidate.pt())) || outputMl[idxBdtScore] > mlScorePromptOrNonPromptMax->at(o2::analysis::findBin(binsPtEfficiencyD, candidate.pt()))) { continue; } auto collision = candidate.template collision_as>(); @@ -633,7 +637,7 @@ struct HfTaskCorrelationDplusHadrons { continue; } multiplicity = collision.multFT0M(); - if (std::abs(candidate.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi) { + if (std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) { hCandidates->Fill(kCandidateStepMcReco, candidate.pt(), multiplicity, candidate.originMcRec()); if (std::abs(hfHelper.yDplus(candidate)) <= yCandMax) { hCandidates->Fill(kCandidateStepMcRecoInAcceptance, candidate.pt(), multiplicity, candidate.originMcRec()); diff --git a/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx b/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx index fc4c059c61b..8221a1ad33c 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx @@ -14,20 +14,21 @@ /// \author Grazia Luparello /// \author Samuele Cattaruzzi -#include -#include -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/HFC/DataModel/CorrelationTables.h" +#include "PWGHF/Utils/utilsAnalysis.h" #include "CCDB/BasicCCDBManager.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsAnalysis.h" -#include "PWGHF/HFC/DataModel/CorrelationTables.h" +#include +#include +#include using namespace o2; using namespace o2::constants::physics; @@ -692,7 +693,7 @@ struct HfTaskCorrelationDsHadrons { // generated candidate loop for (const auto& mcParticle : groupedMcParticles) { - if ((std::abs(mcParticle.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::DsToKKPi) && (mcParticle.flagMcDecayChanGen() == decayChannel)) { + if ((std::abs(mcParticle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) && (mcParticle.flagMcDecayChanGen() == decayChannel)) { hCandidates->Fill(kCandidateStepMcGenDsToKKPi, mcParticle.pt(), multiplicityGen, mcParticle.originMcGen()); auto yDs = RecoDecay::y(mcParticle.pVector(), o2::constants::physics::MassDS); if (std::abs(yDs) <= yCandGenMax) { @@ -737,7 +738,7 @@ struct HfTaskCorrelationDsHadrons { continue; } - if ((std::abs(candidate.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::DsToKKPi) && (candidate.flagMcDecayChanRec() == decayChannel)) { + if ((std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) && (candidate.flagMcDecayChanRec() == decayChannel)) { auto prong0McPart = candidate.template prong0_as().template mcParticle_as(); // DsToKKPi and DsToPiKK division if (((std::abs(prong0McPart.pdgCode()) == kKPlus) && (candidate.isSelDsToKKPi() >= selectionFlagDs)) || ((std::abs(prong0McPart.pdgCode()) == kPiPlus) && (candidate.isSelDsToPiKK() >= selectionFlagDs))) { @@ -772,7 +773,7 @@ struct HfTaskCorrelationDsHadrons { float multiplicity = -1.; for (const auto& mcParticle : mcParticles) { // generated candidates - if ((std::abs(mcParticle.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::DsToKKPi) && (mcParticle.flagMcDecayChanGen() == decayChannel)) { + if ((std::abs(mcParticle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) && (mcParticle.flagMcDecayChanGen() == decayChannel)) { auto mcCollision = mcParticle.template mcCollision_as>(); multiplicity = mcCollision.multMCFT0A() + mcCollision.multMCFT0C(); // multFT0M = multFt0A + multFT0C hCandidates->Fill(kCandidateStepMcGenDsToKKPi, mcParticle.pt(), multiplicity, mcParticle.originMcGen()); @@ -823,7 +824,7 @@ struct HfTaskCorrelationDsHadrons { continue; } multiplicity = collision.multFT0M(); - if ((std::abs(candidate.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::DsToKKPi) && (candidate.flagMcDecayChanRec() == decayChannel)) { + if ((std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) && (candidate.flagMcDecayChanRec() == decayChannel)) { auto prong0McPart = candidate.template prong0_as().template mcParticle_as(); // DsToKKPi and DsToPiKK division if (((std::abs(prong0McPart.pdgCode()) == kKPlus) && (candidate.isSelDsToKKPi() >= selectionFlagDs)) || ((std::abs(prong0McPart.pdgCode()) == kPiPlus) && (candidate.isSelDsToPiKK() >= selectionFlagDs))) { diff --git a/PWGHF/HFC/Tasks/taskCorrelationLcHadrons.cxx b/PWGHF/HFC/Tasks/taskCorrelationLcHadrons.cxx index 2c7e3dd3e80..6e6393b008a 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationLcHadrons.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationLcHadrons.cxx @@ -14,20 +14,22 @@ /// \author Marianna Mazzilli /// \author Zhen Zhang -#include // std::shared_ptr -#include -#include -#include "CCDB/BasicCCDBManager.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" - #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsAnalysis.h" #include "PWGHF/HFC/DataModel/CorrelationTables.h" #include "PWGHF/HFC/Utils/utilsCorrelations.h" +#include "PWGHF/Utils/utilsAnalysis.h" + +#include "CCDB/BasicCCDBManager.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include // std::shared_ptr +#include +#include using namespace o2; using namespace o2::constants::math; @@ -809,7 +811,7 @@ struct HfTaskCorrelationLcHadrons { auto mcCollision = mcParticle.template mcCollision_as>(); multiplicity = mcCollision.multMCFT0A() + mcCollision.multMCFT0C(); // multFT0M = multFt0A + multFT0C hCandidates->Fill(kCandidateStepMcGenAll, mcParticle.pt(), multiplicity, mcParticle.originMcGen()); - if (std::abs(mcParticle.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::LcToPKPi) { + if (std::abs(mcParticle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { hCandidates->Fill(kCandidateStepMcGenLcToPKPi, mcParticle.pt(), multiplicity, mcParticle.originMcGen()); auto yL = RecoDecay::y(mcParticle.pVector(), o2::constants::physics::MassLambdaCPlus); if (std::abs(yL) <= yCandGenMax) { @@ -860,7 +862,7 @@ struct HfTaskCorrelationLcHadrons { continue; } multiplicity = collision.multFT0M(); - if (std::abs(candidate.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::LcToPKPi) { + if (std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { hCandidates->Fill(kCandidateStepMcReco, candidate.pt(), multiplicity, candidate.originMcRec()); if (std::abs(hfHelper.yLc(candidate)) <= yCandMax) { hCandidates->Fill(kCandidateStepMcRecoInAcceptance, candidate.pt(), multiplicity, candidate.originMcRec()); diff --git a/PWGHF/HFC/Tasks/taskFlow.cxx b/PWGHF/HFC/Tasks/taskFlow.cxx index 840357b0b3e..981ce78e7ca 100644 --- a/PWGHF/HFC/Tasks/taskFlow.cxx +++ b/PWGHF/HFC/Tasks/taskFlow.cxx @@ -809,7 +809,7 @@ struct HfTaskFlow { // } } } else { // For now, that means we do LambdaC - if (std::abs(mcCandidate.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::LcToPKPi) { + if (std::abs(mcCandidate.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { if (etaCandidateMax >= 0. && std::abs(etaCandidate) > etaCandidateMax) { return false; diff --git a/PWGHF/HFC/Utils/utilsCorrelations.h b/PWGHF/HFC/Utils/utilsCorrelations.h index a38e36f7fc1..dbf9b6cae58 100644 --- a/PWGHF/HFC/Utils/utilsCorrelations.h +++ b/PWGHF/HFC/Utils/utilsCorrelations.h @@ -16,10 +16,17 @@ #ifndef PWGHF_HFC_UTILS_UTILSCORRELATIONS_H_ #define PWGHF_HFC_UTILS_UTILSCORRELATIONS_H_ -#include +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" + +#include "CommonConstants/MathConstants.h" + #include -#include "CommonConstants/PhysicsConstants.h" +#include + +#include +#include namespace o2::analysis::hf_correlations { diff --git a/PWGHF/HFL/DataModel/ElectronSelectionTable.h b/PWGHF/HFL/DataModel/ElectronSelectionTable.h index e590ee1d94d..fd3678668d6 100644 --- a/PWGHF/HFL/DataModel/ElectronSelectionTable.h +++ b/PWGHF/HFL/DataModel/ElectronSelectionTable.h @@ -18,7 +18,10 @@ #ifndef PWGHF_HFL_DATAMODEL_ELECTRONSELECTIONTABLE_H_ #define PWGHF_HFL_DATAMODEL_ELECTRONSELECTIONTABLE_H_ -#include "Framework/AnalysisDataModel.h" +#include +#include // NOLINT + +#include namespace o2::aod { diff --git a/PWGHF/HFL/Tasks/CMakeLists.txt b/PWGHF/HFL/Tasks/CMakeLists.txt index 275bd761534..7c87297ca23 100644 --- a/PWGHF/HFL/Tasks/CMakeLists.txt +++ b/PWGHF/HFL/Tasks/CMakeLists.txt @@ -24,6 +24,11 @@ o2physics_add_dpl_workflow(task-single-muon PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(task-single-muon-mult + SOURCES taskSingleMuonMult.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(task-single-muon-reader SOURCES taskSingleMuonReader.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::PWGDQCore diff --git a/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx b/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx index b86e10b98e4..be71ab35a01 100644 --- a/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx +++ b/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx @@ -81,6 +81,10 @@ struct HfTaskElectronWeakBoson { Configurable energyIsolationMax{"energyIsolationMax", 0.1, "isolation cut on energy"}; Configurable trackIsolationMax{"trackIsolationMax", 3, "Maximum number of tracks in isolation cone"}; + // flag for THn + Configurable isTHnElectron{"isTHnElectron", true, "Enables THn for electrons"}; + Configurable ptTHnThresh{"ptTHnThresh", 5.0, "Threshold for THn make"}; + // Skimmed dataset processing configurations Configurable cfgSkimmedProcessing{"cfgSkimmedProcessing", true, "Enables processing of skimmed datasets"}; Configurable cfgTriggerName{"cfgTriggerName", "fGammaHighPtEMCAL", "Trigger of interest (comma separated for multiple)"}; @@ -143,27 +147,29 @@ struct HfTaskElectronWeakBoson { zorroSummary.setObject(zorro.getZorroSummary()); } + // add configurable for CCDB path + zorro.setBaseCCDBPath(cfgCCDBPath.value); + // define axes you want to use - const AxisSpec axisZvtx{400, -20, 20, "Zvtx"}; + const AxisSpec axisZvtx{40, -20, 20, "Zvtx"}; const AxisSpec axisCounter{1, 0, 1, "events"}; - const AxisSpec axisEta{200, -1.0, 1.0, "#eta"}; + const AxisSpec axisEta{20, -1.0, 1.0, "#eta"}; const AxisSpec axisPt{nBinsPt, 0, binPtmax, "p_{T}"}; const AxisSpec axisNsigma{100, -5, 5, "N#sigma"}; const AxisSpec axisE{nBinsE, 0, binEmax, "Energy"}; const AxisSpec axisM02{100, 0, 1, "M02"}; - const AxisSpec axisdPhi{200, -1, 1, "dPhi"}; - const AxisSpec axisdEta{200, -1, 1, "dEta"}; + const AxisSpec axisdPhi{100, -0.5, 0.5, "dPhi"}; + const AxisSpec axisdEta{100, -0.5, 0.5, "dEta"}; const AxisSpec axisPhi{350, 0, 7, "Phi"}; const AxisSpec axisEop{200, 0, 2, "Eop"}; - const AxisSpec axisChi2{500, 0.0, 50.0, "#chi^{2}"}; + const AxisSpec axisChi2{250, 0.0, 25.0, "#chi^{2}"}; const AxisSpec axisCluster{100, 0.0, 200.0, "counts"}; - const AxisSpec axisITSNCls{20, 0.0, 20, "counts"}; - const AxisSpec axisEMCtime{200, -100.0, 100, "EMC time"}; - const AxisSpec axisIsoEnergy{100, 0, 1, "Isolation energy(GeV/C)"}; - const AxisSpec axisIsoTrack{20, -0.5, 19.5, "Isolation Track"}; - const AxisSpec axisInvMassZ{200, 0, 200, "M_{ee} (GeV/c^{2})"}; - const AxisSpec axisInvMassDy{200, 0, 2, "M_{ee} (GeV/c^{2})"}; - const AxisSpec axisTrigger{3, 0, 2, "Trigger status of zorro"}; + const AxisSpec axisITSNCls{10, 0.0, 10, "counts"}; + const AxisSpec axisEMCtime{100, -50.0, 50, "EMC time"}; + const AxisSpec axisIsoEnergy{100, 0, 1.0, "Isolation energy(GeV/C)"}; + const AxisSpec axisIsoTrack{15, -0.5, 14.5, "Isolation Track"}; + const AxisSpec axisInvMassZ{150, 0, 150, "M_{ee} (GeV/c^{2})"}; + const AxisSpec axisTrigger{3, -0.5, 2.5, "Trigger status of zorro"}; // create registrygrams registry.add("hZvtx", "Z vertex", kTH1F, {axisZvtx}); @@ -178,8 +184,6 @@ struct HfTaskElectronWeakBoson { registry.add("hPt", "track pt", kTH1F, {axisPt}); registry.add("hTPCNsigma", "TPC electron Nsigma", kTH2F, {{axisPt}, {axisNsigma}}); registry.add("hEnergy", "EMC cluster energy", kTH1F, {axisE}); - registry.add("hM02", "EMC M02", kTH2F, {{axisNsigma}, {axisM02}}); - registry.add("hM20", "EMC M20", kTH2F, {{axisNsigma}, {axisM02}}); registry.add("hTrMatch", "Track EMC Match", kTH2F, {{axisdPhi}, {axisdEta}}); registry.add("hTrMatch_mim", "Track EMC Match minimu minimumm", kTH2F, {{axisdPhi}, {axisdEta}}); registry.add("hMatchPhi", "Match in Phi", kTH2F, {{axisPhi}, {axisPhi}}); @@ -193,18 +197,19 @@ struct HfTaskElectronWeakBoson { registry.add("hIsolationTrack", "Isolation Track", kTH2F, {{axisE}, {axisIsoTrack}}); registry.add("hInvMassZeeLs", "invariant mass for Z LS pair", kTH2F, {{axisPt}, {axisInvMassZ}}); registry.add("hInvMassZeeUls", "invariant mass for Z ULS pair", kTH2F, {{axisPt}, {axisInvMassZ}}); + registry.add("hTHnElectrons", "electron info", HistType::kTHnSparseF, {axisPt, axisNsigma, axisM02, axisEop, axisIsoEnergy, axisIsoTrack}); // hisotgram for EMCal trigger registry.add("hEMCalTrigger", "EMCal trigger", kTH1F, {axisTrigger}); } - bool isIsolatedCluster(const o2::aod::EMCALCluster& cluster, - const SelectedClusters& clusters) + double getIsolatedCluster(const o2::aod::EMCALCluster& cluster, + const SelectedClusters& clusters) { - float energySum = 0.0; - float isoEnergy = 10.0; - float etaAssCluster = cluster.eta(); - float phiAssCluster = cluster.phi(); + double energySum = 0.0; + double isoEnergy = 10.0; + double etaAssCluster = cluster.eta(); + double phiAssCluster = cluster.phi(); for (const auto& associateCluster : clusters) { // Calculate angular distances @@ -229,9 +234,9 @@ struct HfTaskElectronWeakBoson { registry.fill(HIST("hIsolationEnergy"), cluster.energy(), isoEnergy); - return (isoEnergy < energyIsolationMax); + return (isoEnergy); } - bool isIsolatedTrack(double etaEle, + int getIsolatedTrack(double etaEle, double phiEle, float ptEle, TrackEle const& tracks) @@ -239,9 +244,6 @@ struct HfTaskElectronWeakBoson { int trackCount = 0; for (const auto& track : tracks) { - // skip the reference track - if (std::abs(track.pt() - ptEle) < 1e-4) - continue; double dEta = track.eta() - etaEle; double dPhi = track.phi() - phiEle; @@ -256,7 +258,7 @@ struct HfTaskElectronWeakBoson { registry.fill(HIST("hIsolationTrack"), ptEle, trackCount); - return (trackCount <= trackIsolationMax); + return (trackCount); } void process(soa::Filtered::iterator const& collision, @@ -280,9 +282,6 @@ struct HfTaskElectronWeakBoson { LOGF(info, "Initializing Zorro for run %d", runNumber); uint64_t currentTimestamp = bc.timestamp(); - // add configurable for CCDB path - zorro.setBaseCCDBPath(cfgCCDBPath.value); - // debug for timestamp LOGF(info, "Using CCDB path: %s, timestamp: %llu", cfgCCDBPath.value.c_str(), currentTimestamp); @@ -303,7 +302,6 @@ struct HfTaskElectronWeakBoson { return; } } - // initialze for inclusive-electron selectedElectronsIso.clear(); selectedElectronsAss.clear(); @@ -375,10 +373,7 @@ struct HfTaskElectronWeakBoson { for (const auto& match : tracksofcluster) { if (match.emcalcluster_as().time() < timeEmcMin || match.emcalcluster_as().time() > timeEmcMax) continue; - if (match.emcalcluster_as().m02() < m02Min || match.emcalcluster_as().m02() > m02Max) - continue; - float m20Emc = match.emcalcluster_as().m20(); float m02Emc = match.emcalcluster_as().m02(); float energyEmc = match.emcalcluster_as().energy(); double phiEmc = match.emcalcluster_as().phi(); @@ -413,17 +408,24 @@ struct HfTaskElectronWeakBoson { double eop = energyEmc / match.track_as().p(); + double isoEnergy = getIsolatedCluster(cluster, emcClusters); + + int trackCount = getIsolatedTrack(track.eta(), track.phi(), track.pt(), tracks) - 1; + + if (match.track_as().pt() > ptTHnThresh && isTHnElectron) { + registry.fill(HIST("hTHnElectrons"), match.track_as().pt(), match.track_as().tpcNSigmaEl(), m02Emc, eop, isoEnergy, trackCount); + } // LOG(info) << "E/p" << eop; registry.fill(HIST("hEopNsigTPC"), match.track_as().tpcNSigmaEl(), eop); - registry.fill(HIST("hM02"), match.track_as().tpcNSigmaEl(), m02Emc); - registry.fill(HIST("hM20"), match.track_as().tpcNSigmaEl(), m20Emc); + if (match.emcalcluster_as().m02() < m02Min || match.emcalcluster_as().m02() > m02Max) + continue; + if (match.track_as().tpcNSigmaEl() > nsigTpcMin && match.track_as().tpcNSigmaEl() < nsigTpcMax) { registry.fill(HIST("hEop"), match.track_as().pt(), eop); - - if (eop > eopMin && eop < eopMax) { - isIsolated = isIsolatedCluster(cluster, emcClusters); - isIsolatedTr = isIsolatedTrack(track.phi(), track.eta(), track.pt(), tracks); - } + if (eop > eopMin && eop < eopMax && isoEnergy < energyIsolationMax) + isIsolated = true; + if (eop > eopMin && eop < eopMax && trackCount < trackIsolationMax) + isIsolatedTr = true; if (isIsolated) { registry.fill(HIST("hEopIsolation"), match.track_as().pt(), eop); diff --git a/PWGHF/HFL/Tasks/taskSingleMuonMult.cxx b/PWGHF/HFL/Tasks/taskSingleMuonMult.cxx new file mode 100644 index 00000000000..f3ef620346b --- /dev/null +++ b/PWGHF/HFL/Tasks/taskSingleMuonMult.cxx @@ -0,0 +1,265 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file taskSingleMuonMult.cxx +/// \brief Task used to study the Open heavy flavour decay muon production as a function of multiplicity. +/// \author Md Samsul Islam , IITB + +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CommonConstants/MathConstants.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/TrackFwd.h" + +#include + +using namespace o2; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::aod::fwdtrack; + +struct HfTaskSingleMuonMult { + + // enum for event selection bins + enum EventSelection { + AllEvents = 0, + Sel8, + VtxZAfterSel, + NEventSelection + }; + + // enum for muon track selection bins + enum MuonSelection { + NoCut = 0, + EtaCut, + RAbsorbCut, + PDcaCut, + Chi2Cut, + NMuonSelection + }; + + Configurable zVtxMax{"zVtxMax", 10., "maxium z of primary vertex [cm]"}; + Configurable ptTrackMin{"ptTrackMin", 0.15, "minimum pt of tracks"}; + Configurable etaTrackMax{"etaTrackMax", 0.8, "maximum pseudorapidity of tracks"}; + Configurable etaMin{"etaMin", -3.6, "minimum pseudorapidity"}; + Configurable etaMax{"etaMax", -2.5, "maximum pseudorapidity"}; + Configurable pDcaMin{"pDcaMin", 324., "p*DCA value for small RAbsorb"}; + Configurable pDcaMax{"pDcaMax", 594., "p*DCA value for large RAbsorb"}; + Configurable rAbsorbMin{"rAbsorbMin", 17.6, "R at absorber end minimum value"}; + Configurable rAbsorbMax{"rAbsorbMax", 89.5, "R at absorber end maximum value"}; + Configurable rAbsorbMid{"rAbsorbMid", 26.5, "R at absorber end split point for different p*DCA selections"}; + Configurable reduceOrphMft{"reduceOrphMft", true, "reduce orphan MFT tracks"}; + + using MyCollisions = soa::Join; + using MyMuons = soa::Join; + using MyMcMuons = soa::Join; + using MyTracks = soa::Filtered>; + + // Filter Global Track for Multiplicty + Filter trackFilter = ((nabs(aod::track::eta) < etaTrackMax) && (aod::track::pt > ptTrackMin)); + + // Number the types of muon tracks + static constexpr uint8_t NTrackTypes{ForwardTrackTypeEnum::MCHStandaloneTrack + 1}; + + HistogramRegistry registry{"registry"}; + + void init(InitContext&) + { + AxisSpec axisCent = {101, -0.5, 100.5, "centrality"}; + AxisSpec axisEvent{NEventSelection, 0, NEventSelection, "Event Selection"}; + AxisSpec axisVtxZ{80, -20., 20., "#it{z}_{vtx} (cm)"}; + AxisSpec axisMuon{NMuonSelection, 0, NMuonSelection, "Muon Selection"}; + AxisSpec axisNCh{500, 0.5, 500.5, "#it{N}_{ch}"}; + AxisSpec axisNMu{20, -0.5, 19.5, "#it{N}_{#mu}"}; + AxisSpec axisPt{1000, 0., 500., "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec axisEta{250, -5., 5., "#it{#eta}"}; + AxisSpec axisTheta{500, 170., 180., "#it{#theta}"}; + AxisSpec axisRAbsorb{1000, 0., 100., "#it{R}_{Absorb} (cm)"}; + AxisSpec axisDCA{500, 0., 5., "#it{DCA}_{xy} (cm)"}; + AxisSpec axisChi2MatchMCHMFT{1000, 0., 1000., "MCH-MFT matching #chi^{2}"}; + AxisSpec axisSign{5, -2.5, 2.5, "Charge"}; + AxisSpec axisPDca{100000, 0, 100000, "#it{p} #times DCA (GeV/#it{c} * cm)"}; + AxisSpec axisDCAx{1000, -5., 5., "#it{DCA}_{x or y} (cm)"}; + AxisSpec axisEtaDif{200, -2., 2., "#it{#eta} diff"}; + AxisSpec axisDeltaPt{10000, -50, 50, "#Delta #it{p}_{T} (GeV/#it{c})"}; + AxisSpec axisTrackType{8, -1.5, 6.5, "TrackType"}; + AxisSpec axisPtDif{200, -2., 2., "#it{p}_{T} diff (GeV/#it{c})"}; + + registry.add("hCentrality", "Centrality Percentile", {HistType::kTH1F, {axisCent}}); + registry.add("hEventSel", " Number of Events", {HistType::kTH1F, {axisEvent}}); + registry.add("hNch", "Charged Particle Multiplicity", {HistType::kTH1F, {axisNCh}}); + registry.add("hVtxZBeforeSel", "Z-vertex distribution before zVtx Cut", {HistType::kTH1F, {axisVtxZ}}); + registry.add("hVtxZAfterSel", "Z-vertex distribution after zVtx Cut", {HistType::kTH1F, {axisVtxZ}}); + + registry.add("hMuonSel", "Selection of muon tracks at various kinematic cuts", {HistType::kTH1F, {axisMuon}}); + registry.add("hMuBeforeMatchMFT", "Muon information before any Kinemeatic cuts applied", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); + registry.add("hMuBeforeAccCuts", "Muon information before applying Acceptance cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); + registry.add("h3DCABeforeAccCuts", "DCAx,DCAy,DCAz information before Acceptance cuts", {HistType::kTH3F, {axisDCAx, axisDCAx, axisTrackType}}); + registry.add("hMuDeltaPtBeforeAccCuts", "Muon information with DeltaPt before applying Acceptance cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisDeltaPt}, 10}); + registry.add("hMuAfterEtaCuts", "Muon information after applying Eta cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); + registry.add("hMuAfterRAbsorbCuts", "Muon information after applying RAbsorb cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); + registry.add("hMuAfterPdcaCuts", "Muon information after applying Pdca cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); + registry.add("hMuAfterAccCuts", "Muon information after applying all Kinematic cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); + registry.add("h3DCAAfterAccCuts", "DCAx,DCAy,DCAz information after Acceptance cuts", {HistType::kTH3F, {axisDCAx, axisDCAx, axisTrackType}}); + registry.add("hMuDeltaPtAfterAccCuts", "Muon information with DeltaPt after applying Acceptance cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisDeltaPt}, 10}); + + registry.add("hTHnTrk", "Muon information with multiplicity", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisSign}, 5}); + registry.add("h3MultNchNmu", "Number of muons and multiplicity", {HistType::kTH3F, {axisCent, axisNCh, axisNMu}}); + registry.add("hMultNchNmuTrackType", "Number of muons with different types and multiplicity", {HistType::kTHnSparseF, {axisCent, axisNCh, axisNMu, axisTrackType}, 4}); + + auto hEvstat = registry.get(HIST("hEventSel")); + auto* xEv = hEvstat->GetXaxis(); + xEv->SetBinLabel(AllEvents + 1, "All events"); + xEv->SetBinLabel(Sel8 + 1, "sel8"); + xEv->SetBinLabel(VtxZAfterSel + 1, "VtxZAfterSel"); + + auto hMustat = registry.get(HIST("hMuonSel")); + auto* xMu = hMustat->GetXaxis(); + xMu->SetBinLabel(NoCut + 1, "noCut"); + xMu->SetBinLabel(EtaCut + 1, "etaCut"); + xMu->SetBinLabel(RAbsorbCut + 1, "RAbsorbCut"); + xMu->SetBinLabel(PDcaCut + 1, "pDcaCut"); + xMu->SetBinLabel(Chi2Cut + 1, "chi2Cut"); + } + + void process(MyCollisions::iterator const& collision, + MyTracks const& tracks, + MyMuons const& muons) + { + registry.fill(HIST("hEventSel"), AllEvents); + + if (!collision.sel8()) { + return; + } + registry.fill(HIST("hEventSel"), Sel8); + registry.fill(HIST("hVtxZBeforeSel"), collision.posZ()); + + if (std::abs(collision.posZ()) > zVtxMax) { + return; + } + registry.fill(HIST("hEventSel"), VtxZAfterSel); + registry.fill(HIST("hVtxZAfterSel"), collision.posZ()); + + // T0M centrality + const auto cent = collision.centFT0M(); + registry.fill(HIST("hCentrality"), cent); + + // Charged particles + for (const auto& track : tracks) { + if (!track.isGlobalTrack()) { + continue; + } + } + + auto nCh{tracks.size()}; + if (nCh < 1) { + return; + } + registry.fill(HIST("hNch"), nCh); + + for (const auto& track : tracks) { + registry.fill(HIST("hTHnTrk"), cent, nCh, track.pt(), track.eta(), track.sign()); + } + + // muons per event + int nMu{0}; + int nMuType[NTrackTypes] = {0}; + + for (const auto& muon : muons) { + const auto pt{muon.pt()}, eta{muon.eta()}, theta{90.0f - ((std::atan(muon.tgl())) * constants::math::Rad2Deg)}, pDca{muon.pDca()}, rAbsorb{muon.rAtAbsorberEnd()}, chi2{muon.chi2MatchMCHMFT()}; + const auto dcaXY{RecoDecay::sqrtSumOfSquares(muon.fwdDcaX(), muon.fwdDcaY())}; + const auto muTrackType{muon.trackType()}; + + registry.fill(HIST("hMuBeforeMatchMFT"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, muTrackType); + + // histograms before the acceptance cuts + registry.fill(HIST("hMuonSel"), NoCut); + registry.fill(HIST("hMuBeforeAccCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, muTrackType); + registry.fill(HIST("h3DCABeforeAccCuts"), muon.fwdDcaX(), muon.fwdDcaY(), muTrackType); + + if (muon.has_matchMCHTrack()) { + auto muonType3 = muon.template matchMCHTrack_as(); + auto dpt = muonType3.pt() - pt; + if (muTrackType == ForwardTrackTypeEnum::GlobalMuonTrack) { + registry.fill(HIST("hMuDeltaPtBeforeAccCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, dpt); + } + } + + // Apply various standard muon acceptance cuts + // eta cuts + if ((eta >= etaMax) || (eta < etaMin)) { + continue; + } + registry.fill(HIST("hMuonSel"), EtaCut); + registry.fill(HIST("hMuAfterEtaCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, muTrackType); + + // Rabsorb cuts + if ((rAbsorb < rAbsorbMin) || (rAbsorb >= rAbsorbMax)) { + continue; + } + registry.fill(HIST("hMuonSel"), RAbsorbCut); + registry.fill(HIST("hMuAfterRAbsorbCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, muTrackType); + + if ((rAbsorb < rAbsorbMid) && (pDca >= pDcaMin)) { + continue; + } + if ((rAbsorb >= rAbsorbMid) && (pDca >= pDcaMax)) { + continue; + } + registry.fill(HIST("hMuonSel"), PDcaCut); + registry.fill(HIST("hMuAfterPdcaCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, muTrackType); + + // MCH-MFT matching chi2 + if (muon.chi2() >= 1e6) { + continue; + } + registry.fill(HIST("hMuonSel"), Chi2Cut); + + // histograms after acceptance cuts + registry.fill(HIST("hMuAfterAccCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, muTrackType); + registry.fill(HIST("h3DCAAfterAccCuts"), muon.fwdDcaX(), muon.fwdDcaY(), muTrackType); + nMu++; + nMuType[muTrackType]++; + + if (muon.has_matchMCHTrack()) { + auto muonType3 = muon.template matchMCHTrack_as(); + auto dpt = muonType3.pt() - pt; + + if (muTrackType == ForwardTrackTypeEnum::GlobalMuonTrack) { + registry.fill(HIST("hMuDeltaPtAfterAccCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, dpt); + } + } + } + + registry.fill(HIST("h3MultNchNmu"), cent, nCh, nMu); + + // Fill number of muons of various types with multiplicity + for (auto indexType{0u}; indexType < NTrackTypes; ++indexType) { + if (nMuType[indexType] > 0) { + registry.fill(HIST("hMultNchNmuTrackType"), cent, nCh, nMuType[indexType], indexType); + } + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/TableProducer/CMakeLists.txt b/PWGHF/TableProducer/CMakeLists.txt index c74e876761e..2ec33b5d134 100644 --- a/PWGHF/TableProducer/CMakeLists.txt +++ b/PWGHF/TableProducer/CMakeLists.txt @@ -174,7 +174,7 @@ o2physics_add_dpl_workflow(candidate-selector-omegac0-to-omega-pi o2physics_add_dpl_workflow(candidate-selector-xic0-to-xi-pi-kf SOURCES candidateSelectorXic0ToXiPiKf.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(candidate-selector-to-xi-pi diff --git a/PWGHF/TableProducer/candidateCreator2Prong.cxx b/PWGHF/TableProducer/candidateCreator2Prong.cxx index 66e11d2559d..8344e34e98e 100644 --- a/PWGHF/TableProducer/candidateCreator2Prong.cxx +++ b/PWGHF/TableProducer/candidateCreator2Prong.cxx @@ -20,36 +20,38 @@ #define HomogeneousField // o2-linter: disable=name/macro (required by KFParticle) #endif -#include -#include -#include - -#include -#include -#include -#include -#include +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/Utils/utilsBfieldCCDB.h" +#include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGHF/Utils/utilsMcGen.h" +#include "PWGHF/Utils/utilsPid.h" +#include "PWGHF/Utils/utilsTrkCandHf.h" +#include "PWGLF/DataModel/mcCentrality.h" -#include +#include "Common/Core/trackUtilities.h" +#include "Tools/KFparticle/KFUtilities.h" #include "CommonConstants/PhysicsConstants.h" #include "DCAFitter/DCAFitterN.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" #include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/DCA.h" -#include "Common/Core/trackUtilities.h" -#include "Tools/KFparticle/KFUtilities.h" +#include -#include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/Utils/utilsBfieldCCDB.h" -#include "PWGHF/Utils/utilsEvSelHf.h" -#include "PWGHF/Utils/utilsPid.h" -#include "PWGHF/Utils/utilsTrkCandHf.h" -#include "PWGHF/Utils/utilsMcGen.h" +#include +#include +#include +#include +#include + +#include +#include +#include using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/TableProducer/candidateCreator3Prong.cxx b/PWGHF/TableProducer/candidateCreator3Prong.cxx index 426c42c5771..c6ec90a7c4c 100644 --- a/PWGHF/TableProducer/candidateCreator3Prong.cxx +++ b/PWGHF/TableProducer/candidateCreator3Prong.cxx @@ -19,43 +19,45 @@ #define HomogeneousField // o2-linter: disable=name/macro (required by KFParticle) #endif -#include -#include -#include -#include - -#include -#include -#include -#include -#include +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/DecayChannels.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/Utils/utilsBfieldCCDB.h" +#include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGHF/Utils/utilsMcGen.h" +#include "PWGHF/Utils/utilsPid.h" +#include "PWGHF/Utils/utilsTrkCandHf.h" +#include "PWGLF/DataModel/mcCentrality.h" -#include +#include "Common/Core/trackUtilities.h" +#include "Tools/KFparticle/KFUtilities.h" #include "CommonConstants/PhysicsConstants.h" #include "DCAFitter/DCAFitterN.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" #include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/DCA.h" -#include "Common/Core/trackUtilities.h" -#include "Tools/KFparticle/KFUtilities.h" +#include -#include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/Utils/utilsBfieldCCDB.h" -#include "PWGHF/Utils/utilsEvSelHf.h" -#include "PWGHF/Utils/utilsMcGen.h" -#include "PWGHF/Utils/utilsPid.h" -#include "PWGHF/Utils/utilsTrkCandHf.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include using namespace o2; -using namespace o2::analysis; using namespace o2::hf_evsel; using namespace o2::hf_trkcandsel; using namespace o2::aod::hf_cand_3prong; +using namespace o2::hf_decay::hf_cand_3prong; using namespace o2::hf_centrality; using namespace o2::hf_occupancy; using namespace o2::constants::physics; @@ -950,7 +952,7 @@ struct HfCandidateCreator3ProngExpressions { indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, Pdg::kDPlus, std::array{+kPiPlus, -kKPlus, +kPiPlus}, true, &sign, 2); } if (indexRec > -1) { - flag = sign * (1 << DecayType::DplusToPiKPi); + flag = sign * DecayChannelMain::DplusToPiKPi; } } @@ -979,9 +981,7 @@ struct HfCandidateCreator3ProngExpressions { } } if (indexRec > -1) { - // DecayType::DsToKKPi is used to flag both Ds± → K± K∓ π± and D± → K± K∓ π± - // TODO: move to different and explicit flags - flag = sign * (1 << DecayType::DsToKKPi); + flag = sign * (isDplus ? DecayChannelMain::DplusToPiKK : DecayChannelMain::DsToPiKK); if (arrayDaughters[0].has_mcParticle()) { swapping = int8_t(std::abs(arrayDaughters[0].mcParticle().pdgCode()) == kPiPlus); } @@ -992,9 +992,9 @@ struct HfCandidateCreator3ProngExpressions { arrPDGDaugh[iProng] = std::abs(daughI.pdgCode()); } if ((arrPDGDaugh[0] == arrPDGResonantDPhiPi[0] && arrPDGDaugh[1] == arrPDGResonantDPhiPi[1]) || (arrPDGDaugh[0] == arrPDGResonantDPhiPi[1] && arrPDGDaugh[1] == arrPDGResonantDPhiPi[0])) { - channel = isDplus ? DecayChannelDToKKPi::DplusToPhiPi : DecayChannelDToKKPi::DsToPhiPi; + channel = isDplus ? DecayChannelResonant::DplusToPhiPi : DecayChannelResonant::DsToPhiPi; } else if ((arrPDGDaugh[0] == arrPDGResonantDKstarK[0] && arrPDGDaugh[1] == arrPDGResonantDKstarK[1]) || (arrPDGDaugh[0] == arrPDGResonantDKstarK[1] && arrPDGDaugh[1] == arrPDGResonantDKstarK[0])) { - channel = isDplus ? DecayChannelDToKKPi::DplusToK0starK : DecayChannelDToKKPi::DsToK0starK; + channel = isDplus ? DecayChannelResonant::DplusToKstar0K : DecayChannelResonant::DsToKstar0K; } } } @@ -1008,7 +1008,7 @@ struct HfCandidateCreator3ProngExpressions { indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, Pdg::kDStar, std::array{+kPiPlus, +kPiPlus, -kKPlus}, true, &sign, 2); } if (indexRec > -1) { - flag = sign * (1 << DstarToPiKPiBkg); + flag = sign * DecayChannelMain::DstarToPiKPi; channel = 1; } } @@ -1025,7 +1025,7 @@ struct HfCandidateCreator3ProngExpressions { indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, Pdg::kLambdaCPlus, std::array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2); } if (indexRec > -1) { - flag = sign * (1 << DecayType::LcToPKPi); + flag = sign * DecayChannelMain::LcToPKPi; // Flagging the different Λc± → p± K∓ π± decay channels if (arrayDaughters[0].has_mcParticle()) { @@ -1060,7 +1060,7 @@ struct HfCandidateCreator3ProngExpressions { indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, Pdg::kXiCPlus, std::array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2); } if (indexRec > -1) { - flag = sign * (1 << DecayType::XicToPKPi); + flag = sign * DecayChannelMain::XicToPKPi; if (arrayDaughters[0].has_mcParticle()) { swapping = int8_t(std::abs(arrayDaughters[0].mcParticle().pdgCode()) == kPiPlus); } diff --git a/PWGHF/TableProducer/candidateCreatorB0.cxx b/PWGHF/TableProducer/candidateCreatorB0.cxx index 6caca925a2d..b9a1fb6fae3 100644 --- a/PWGHF/TableProducer/candidateCreatorB0.cxx +++ b/PWGHF/TableProducer/candidateCreatorB0.cxx @@ -15,9 +15,16 @@ /// /// \author Alexandre Bigot , IPHC Strasbourg -#include -#include -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsBfieldCCDB.h" +#include "PWGHF/Utils/utilsMcGen.h" +#include "PWGHF/Utils/utilsTrkCandHf.h" + +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/CollisionAssociationTables.h" #include "CommonConstants/PhysicsConstants.h" #include "DCAFitter/DCAFitterN.h" @@ -26,15 +33,9 @@ #include "ReconstructionDataFormats/DCA.h" #include "ReconstructionDataFormats/V0.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/CollisionAssociationTables.h" - -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsBfieldCCDB.h" -#include "PWGHF/Utils/utilsTrkCandHf.h" -#include "PWGHF/Utils/utilsMcGen.h" +#include +#include +#include using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/TableProducer/candidateCreatorBplus.cxx b/PWGHF/TableProducer/candidateCreatorBplus.cxx index f1d306cad12..7686e4743d5 100644 --- a/PWGHF/TableProducer/candidateCreatorBplus.cxx +++ b/PWGHF/TableProducer/candidateCreatorBplus.cxx @@ -18,9 +18,16 @@ /// \author Deepa Thomas , UT Austin /// \author Antonio Palasciano , Università degli Studi di Bari & INFN, Sezione di Bari -#include -#include -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsBfieldCCDB.h" +#include "PWGHF/Utils/utilsMcGen.h" +#include "PWGHF/Utils/utilsTrkCandHf.h" + +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/CollisionAssociationTables.h" #include "CommonConstants/PhysicsConstants.h" #include "DCAFitter/DCAFitterN.h" @@ -29,15 +36,9 @@ #include "ReconstructionDataFormats/DCA.h" #include "ReconstructionDataFormats/V0.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/CollisionAssociationTables.h" - -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsBfieldCCDB.h" -#include "PWGHF/Utils/utilsTrkCandHf.h" -#include "PWGHF/Utils/utilsMcGen.h" +#include +#include +#include using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/TableProducer/candidateCreatorBs.cxx b/PWGHF/TableProducer/candidateCreatorBs.cxx index 5ce38797762..b6fe1630190 100644 --- a/PWGHF/TableProducer/candidateCreatorBs.cxx +++ b/PWGHF/TableProducer/candidateCreatorBs.cxx @@ -15,9 +15,15 @@ /// /// \author Phil Stahlhut -#include -#include -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsBfieldCCDB.h" +#include "PWGHF/Utils/utilsTrkCandHf.h" + +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/CollisionAssociationTables.h" #include "CommonConstants/PhysicsConstants.h" #include "DCAFitter/DCAFitterN.h" @@ -26,14 +32,9 @@ #include "ReconstructionDataFormats/DCA.h" #include "ReconstructionDataFormats/V0.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/CollisionAssociationTables.h" - -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsBfieldCCDB.h" -#include "PWGHF/Utils/utilsTrkCandHf.h" +#include +#include +#include using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/TableProducer/candidateCreatorCascade.cxx b/PWGHF/TableProducer/candidateCreatorCascade.cxx index 25c7a343849..d098bf3fd76 100644 --- a/PWGHF/TableProducer/candidateCreatorCascade.cxx +++ b/PWGHF/TableProducer/candidateCreatorCascade.cxx @@ -15,29 +15,31 @@ /// \author Chiara Zampolli, , CERN /// Paul Buehler, , Vienna -#include -#include -#include +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/Utils/utilsBfieldCCDB.h" +#include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGHF/Utils/utilsTrkCandHf.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/mcCentrality.h" -#include +#include "Common/Core/trackUtilities.h" #include "CommonConstants/PhysicsConstants.h" #include "DCAFitter/DCAFitterN.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" #include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/DCA.h" #include "ReconstructionDataFormats/V0.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "Common/Core/trackUtilities.h" +#include -#include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/Utils/utilsBfieldCCDB.h" -#include "PWGHF/Utils/utilsEvSelHf.h" -#include "PWGHF/Utils/utilsTrkCandHf.h" +#include +#include +#include using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/TableProducer/candidateCreatorDstar.cxx b/PWGHF/TableProducer/candidateCreatorDstar.cxx index 146c0b94ee7..f25a09dbbb3 100644 --- a/PWGHF/TableProducer/candidateCreatorDstar.cxx +++ b/PWGHF/TableProducer/candidateCreatorDstar.cxx @@ -15,7 +15,8 @@ /// \author Vít Kučera , CERN /// \author Deependra Sharma , IITB /// \author Fabrizio Grosa , CERN -// std + +// C++ #include #include #include @@ -30,8 +31,11 @@ #include "Framework/RunningWorkflowInfo.h" // O2Physics #include "Common/Core/trackUtilities.h" +// PWGLF +#include "PWGLF/DataModel/mcCentrality.h" // PWGHF #include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/Utils/utilsBfieldCCDB.h" #include "PWGHF/Utils/utilsEvSelHf.h" @@ -634,10 +638,10 @@ struct HfCandidateCreatorDstarExpressions { } if (indexRecDstar > -1) { - flagDstar = signDstar * (BIT(aod::hf_cand_dstar::DecayType::DstarToD0Pi)); + flagDstar = signDstar * hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi; } if (indexRecD0 > -1) { - flagD0 = signD0 * (BIT(aod::hf_cand_dstar::DecayType::D0ToPiK)); + flagD0 = signD0 * hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK; } // check partly reconstructed decays, namely D0->Kpipi0 @@ -669,11 +673,11 @@ struct HfCandidateCreatorDstarExpressions { auto motherParticleDstar = mcParticles.rawIteratorAt(indexRecDstar); if (signDstar > 0) { if (RecoDecay::isMatchedMCGen(mcParticles, motherParticleDstar, Pdg::kDStar, std::array{+kPiPlus, +kPiPlus, -kKPlus, +kPi0}, false, &signDstar, 2)) { - flagDstar = signDstar * (BIT(aod::hf_cand_dstar::DecayType::DstarToD0PiPi0)); + flagDstar = signDstar * hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPiPi0; } } else { if (RecoDecay::isMatchedMCGen(mcParticles, motherParticleDstar, -Pdg::kDStar, std::array{-kPiPlus, -kPiPlus, +kKPlus, +kPi0}, false, &signDstar, 2)) { - flagDstar = signDstar * (BIT(aod::hf_cand_dstar::DecayType::DstarToD0PiPi0)); + flagDstar = signDstar * hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPiPi0; } } } @@ -682,11 +686,11 @@ struct HfCandidateCreatorDstarExpressions { auto motherParticleD0 = mcParticles.rawIteratorAt(indexRecD0); if (signD0 > 0) { if (RecoDecay::isMatchedMCGen(mcParticles, motherParticleD0, Pdg::kD0, std::array{+kPiPlus, -kKPlus, +kPi0}, false, &signD0)) { - flagD0 = signD0 * (BIT(aod::hf_cand_dstar::DecayType::D0ToPiKPi0)); + flagD0 = signD0 * hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiKPi0; } } else { if (RecoDecay::isMatchedMCGen(mcParticles, motherParticleD0, -Pdg::kD0, std::array{-kPiPlus, +kKPlus, +kPi0}, false, &signD0)) { - flagD0 = signD0 * (BIT(aod::hf_cand_dstar::DecayType::D0ToPiKPi0)); + flagD0 = signD0 * hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiKPi0; } } } @@ -760,11 +764,11 @@ struct HfCandidateCreatorDstarExpressions { } } if (RecoDecay::isMatchedMCGen(mcParticles, particleD0, Pdg::kD0, std::array{+kPiPlus, -kKPlus}, true, &signD0)) { - flagDstar = signDstar * (BIT(aod::hf_cand_dstar::DecayType::DstarToD0Pi)); - flagD0 = signD0 * (BIT(aod::hf_cand_dstar::DecayType::D0ToPiK)); + flagDstar = signDstar * hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi; + flagD0 = signD0 * hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK; } else if (RecoDecay::isMatchedMCGen(mcParticles, particleD0, Pdg::kD0, std::array{+kPiPlus, -kKPlus, +kPi0}, false, &signD0) || RecoDecay::isMatchedMCGen(mcParticles, particleD0, -Pdg::kD0, std::array{-kPiPlus, +kKPlus, +kPi0}, false, &signD0)) { - flagDstar = signDstar * (BIT(aod::hf_cand_dstar::DecayType::DstarToD0PiPi0)); - flagD0 = signD0 * (BIT(aod::hf_cand_dstar::DecayType::D0ToPiKPi0)); + flagDstar = signDstar * hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPiPi0; + flagD0 = signD0 * hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiKPi0; } } diff --git a/PWGHF/TableProducer/candidateCreatorMcGen.cxx b/PWGHF/TableProducer/candidateCreatorMcGen.cxx index c27a2f8b734..3c5f7a2c3c1 100644 --- a/PWGHF/TableProducer/candidateCreatorMcGen.cxx +++ b/PWGHF/TableProducer/candidateCreatorMcGen.cxx @@ -30,7 +30,6 @@ #include "PWGHF/Utils/utilsMcGen.h" using namespace o2; -using namespace o2::analysis; using namespace o2::framework; /// Reconstruction of heavy-flavour 2-prong decay candidates diff --git a/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx b/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx index b87c879d7e8..9d019f1b919 100644 --- a/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx +++ b/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx @@ -15,9 +15,17 @@ /// /// \author Mattia Faggin , University and INFN PADOVA -#include -#include -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsBfieldCCDB.h" // for dca recalculation +#include "PWGHF/Utils/utilsEvSelHf.h" + +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/CollisionAssociationTables.h" #include "CCDB/BasicCCDBManager.h" // for dca recalculation #include "CommonConstants/PhysicsConstants.h" @@ -27,19 +35,12 @@ #include "DetectorsBase/Propagator.h" // for dca recalculation #include "DetectorsVertexing/PVertexer.h" // for dca recalculation #include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" #include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/CollisionAssociationTables.h" -#include "Common/Core/TrackSelectionDefaults.h" - -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsBfieldCCDB.h" // for dca recalculation -#include "PWGHF/Utils/utilsEvSelHf.h" +#include +#include +#include using namespace o2; using namespace o2::analysis; @@ -471,7 +472,7 @@ struct HfCandidateSigmac0plusplusMc { /// skip immediately the candidate Σc0,++ w/o a Λc+ matched to MC auto candLc = candSigmac.prongLc_as(); - if (!(std::abs(candLc.flagMcMatchRec()) == BIT(aod::hf_cand_3prong::DecayType::LcToPKPi))) { /// (*) + if (std::abs(candLc.flagMcMatchRec()) != hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { /// (*) rowMCMatchScRec(flag, origin, -1.f, 0, -1); continue; } diff --git a/PWGHF/TableProducer/candidateCreatorSigmac0plusplusCascade.cxx b/PWGHF/TableProducer/candidateCreatorSigmac0plusplusCascade.cxx index 857e8b68bf9..b12dc258e73 100644 --- a/PWGHF/TableProducer/candidateCreatorSigmac0plusplusCascade.cxx +++ b/PWGHF/TableProducer/candidateCreatorSigmac0plusplusCascade.cxx @@ -15,19 +15,20 @@ /// \author Rutuparna Rath , INFN BOLOGNA and GSI Darmstadt /// In collaboration with Andrea Alici , INFN BOLOGNA -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" + +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/Core/trackUtilities.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/trackUtilities.h" -#include "Common/Core/TrackSelectionDefaults.h" - -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx b/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx index b8d114a6583..778a7292f19 100644 --- a/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx +++ b/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx @@ -15,6 +15,7 @@ /// \author Ruiqi Yin , Fudan University /// \author Yunfan Liu , China University of Geosciences /// \author Ran Tu , Fudan University +/// \author Tao Fang , Central China Normal University #ifndef HomogeneousField #define HomogeneousField // o2-linter: disable=name/macro (required by KFParticle) @@ -26,41 +27,41 @@ #include /// includes KFParticle -#include "KFParticle.h" -#include "KFParticleBase.h" -#include "KFPTrack.h" -#include "KFPVertex.h" -#include "KFVertex.h" +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsBfieldCCDB.h" +#include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/mcCentrality.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Tools/KFparticle/KFUtilities.h" #include "CCDB/BasicCCDBManager.h" #include "CommonConstants/PhysicsConstants.h" +#include "DCAFitter/DCAFitterN.h" #include "DataFormatsParameters/GRPMagField.h" #include "DataFormatsParameters/GRPObject.h" -#include "DCAFitter/DCAFitterN.h" #include "DetectorsBase/Propagator.h" +#include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/runDataProcessing.h" #include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/DCA.h" #include "ReconstructionDataFormats/Track.h" #include "ReconstructionDataFormats/V0.h" -#include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/CollisionAssociationTables.h" -#include "Common/DataModel/EventSelection.h" -#include "Tools/KFparticle/KFUtilities.h" - -#include "PWGLF/DataModel/LFStrangenessTables.h" - -#include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/Core/SelectorCuts.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsBfieldCCDB.h" -#include "PWGHF/Utils/utilsEvSelHf.h" +#include "KFPTrack.h" +#include "KFPVertex.h" +#include "KFParticle.h" +#include "KFParticleBase.h" +#include "KFVertex.h" using namespace o2; using namespace o2::track; @@ -242,16 +243,16 @@ struct HfCandidateCreatorXic0Omegac0 { void init(InitContext const&) { - std::array allProcesses = {doprocessNoCentToXiPi, doprocessNoCentToXiPiTraCasc, doprocessCentFT0CToXiPi, doprocessCentFT0MToXiPi, doprocessNoCentToOmegaPi, doprocessOmegacToOmegaPiWithKFParticle, doprocessCentFT0CToOmegaPi, doprocessCentFT0MToOmegaPi, doprocessNoCentToOmegaK, doprocessCentFT0CToOmegaK, doprocessCentFT0MToOmegaK, doprocessXicToXiPiWithKFParticle}; + std::array allProcesses = {doprocessNoCentToXiPi, doprocessNoCentToXiPiTraCasc, doprocessCentFT0CToXiPi, doprocessCentFT0MToXiPi, doprocessNoCentToOmegaPi, doprocessNoCentOmegacToOmegaPiWithKFParticle, doprocessCentFT0COmegacToOmegaPiWithKFParticle, doprocessCentFT0MOmegacToOmegaPiWithKFParticle, doprocessCentFT0CToOmegaPi, doprocessCentFT0MToOmegaPi, doprocessNoCentToOmegaK, doprocessCentFT0CToOmegaK, doprocessCentFT0MToOmegaK, doprocessNoCentXicToXiPiWithKFParticle, doprocessCentFT0CXicToXiPiWithKFParticle, doprocessCentFT0MXicToXiPiWithKFParticle}; if (std::accumulate(allProcesses.begin(), allProcesses.end(), 0) == 0) { LOGP(fatal, "No process function enabled, please select one for at least one channel."); } - std::array processesToXiPi = {doprocessNoCentToXiPi, doprocessNoCentToXiPiTraCasc, doprocessCentFT0CToXiPi, doprocessCentFT0MToXiPi, doprocessXicToXiPiWithKFParticle}; + std::array processesToXiPi = {doprocessNoCentToXiPi, doprocessNoCentToXiPiTraCasc, doprocessCentFT0CToXiPi, doprocessCentFT0MToXiPi, doprocessNoCentXicToXiPiWithKFParticle, doprocessCentFT0CXicToXiPiWithKFParticle, doprocessCentFT0MXicToXiPiWithKFParticle}; if (std::accumulate(processesToXiPi.begin(), processesToXiPi.end(), 0) > 1) { LOGP(fatal, "One and only one ToXiPi process function must be enabled at a time."); } - std::array processesToOmegaPi = {doprocessNoCentToOmegaPi, doprocessCentFT0CToOmegaPi, doprocessCentFT0MToOmegaPi, doprocessOmegacToOmegaPiWithKFParticle}; + std::array processesToOmegaPi = {doprocessNoCentToOmegaPi, doprocessCentFT0CToOmegaPi, doprocessCentFT0MToOmegaPi, doprocessNoCentOmegacToOmegaPiWithKFParticle, doprocessCentFT0COmegacToOmegaPiWithKFParticle, doprocessCentFT0MOmegacToOmegaPiWithKFParticle}; if (std::accumulate(processesToOmegaPi.begin(), processesToOmegaPi.end(), 0) > 1) { LOGP(fatal, "One and only one process ToOmegaPi function must be enabled at a time."); } @@ -266,7 +267,7 @@ struct HfCandidateCreatorXic0Omegac0 { LOGP(fatal, "At most one process function for collision monitoring can be enabled at a time."); } if (nProcessesCollisions == 1) { - if ((doprocessNoCentToXiPi && !doprocessCollisions) || (doprocessNoCentToXiPiTraCasc && !doprocessCollisions) || (doprocessNoCentToOmegaPi && !doprocessCollisions) || (doprocessNoCentToOmegaK && !doprocessCollisions) || (doprocessOmegacToOmegaPiWithKFParticle && !doprocessCollisions) || (doprocessXicToXiPiWithKFParticle && !doprocessCollisions)) { + if ((doprocessNoCentToXiPi && !doprocessCollisions) || (doprocessNoCentToXiPiTraCasc && !doprocessCollisions) || (doprocessNoCentToOmegaPi && !doprocessCollisions) || (doprocessNoCentToOmegaK && !doprocessCollisions) || (doprocessNoCentOmegacToOmegaPiWithKFParticle && !doprocessCollisions) || (doprocessNoCentXicToXiPiWithKFParticle && !doprocessCollisions)) { LOGP(fatal, "Process function for collision monitoring not correctly enabled. Did you enable \"processCollisions\"?"); } if ((doprocessCentFT0CToXiPi && !doprocessCollisionsCentFT0C) || (doprocessCentFT0CToOmegaPi && !doprocessCollisionsCentFT0C) || (doprocessCentFT0CToOmegaK && !doprocessCollisionsCentFT0C)) { @@ -724,7 +725,7 @@ struct HfCandidateCreatorXic0Omegac0 { } // loop over LF Cascade-bachelor candidates } // end of run function - template + template void runKfOmegac0CreatorWithKFParticle(Coll const&, aod::BCsWithTimestamps const& /*bcWithTimeStamps*/, MyKfTracks const&, @@ -739,6 +740,12 @@ struct HfCandidateCreatorXic0Omegac0 { hCandidateCounter->Fill(1); auto collision = cand.collision_as(); + float centrality{-1.f}; + const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectionMask != 0) { + /// at least one event selection not satisfied --> reject the candidate + continue; + } // set the magnetic field from CCDB auto bc = collision.template bc_as(); @@ -1195,7 +1202,7 @@ struct HfCandidateCreatorXic0Omegac0 { } // loop over LF Cascade-bachelor candidates } // end of run function //========================================================== - template + template void runKfXic0CreatorWithKFParticle(Coll const&, aod::BCsWithTimestamps const& /*bcWithTimeStamps*/, MyKfTracks const&, @@ -1211,6 +1218,13 @@ struct HfCandidateCreatorXic0Omegac0 { auto collision = cand.collision_as(); + float centrality{-1.f}; + const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + if (rejectionMask != 0) { + /// at least one event selection not satisfied --> reject the candidate + continue; + } + // set the magnetic field from CCDB auto bc = collision.template bc_as(); if (runNumber != bc.runNumber()) { @@ -1677,27 +1691,27 @@ struct HfCandidateCreatorXic0Omegac0 { } PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processNoCentToOmegaPi, "Run candidate creator w/o centrality selections for omega pi decay channel", false); - void processOmegacToOmegaPiWithKFParticle(aod::Collisions const& collisions, + void processNoCentOmegacToOmegaPiWithKFParticle(soa::Join const& collisions, + aod::BCsWithTimestamps const& bcWithTimeStamps, + MyKfTracks const& tracks, + MyKfCascTable const& cascades, + KFCascadesLinked const& cascadeLinks, + aod::HfCascLf2Prongs const& candidates) + { + runKfOmegac0CreatorWithKFParticle(collisions, bcWithTimeStamps, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToOmegaPi, hFitterStatusToOmegaPi, hCandidateCounterToOmegaPi, hCascadesCounterToOmegaPi); + } + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processNoCentOmegacToOmegaPiWithKFParticle, "Run candidate creator w/o centrality selections for Omegac0 To omega pi decay channel using KFParticle", false); + + void processNoCentXicToXiPiWithKFParticle(soa::Join const& collisions, aod::BCsWithTimestamps const& bcWithTimeStamps, MyKfTracks const& tracks, MyKfCascTable const& cascades, KFCascadesLinked const& cascadeLinks, aod::HfCascLf2Prongs const& candidates) { - runKfOmegac0CreatorWithKFParticle(collisions, bcWithTimeStamps, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToOmegaPi, hFitterStatusToOmegaPi, hCandidateCounterToOmegaPi, hCascadesCounterToOmegaPi); + runKfXic0CreatorWithKFParticle(collisions, bcWithTimeStamps, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToXiPi, hFitterStatusToXiPi, hCandidateCounterToXiPi, hCascadesCounterToXiPi); } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processOmegacToOmegaPiWithKFParticle, "Run candidate creator w/o centrality selections for Omegac0 To omega pi decay channel using KFParticle", false); - - void processXicToXiPiWithKFParticle(aod::Collisions const& collisions, - aod::BCsWithTimestamps const& bcWithTimeStamps, - MyKfTracks const& tracks, - MyKfCascTable const& cascades, - KFCascadesLinked const& cascadeLinks, - aod::HfCascLf2Prongs const& candidates) - { - runKfXic0CreatorWithKFParticle(collisions, bcWithTimeStamps, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToXiPi, hFitterStatusToXiPi, hCandidateCounterToXiPi, hCascadesCounterToXiPi); - } - PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processXicToXiPiWithKFParticle, "Run candidate creator w/o centrality selections for Xic0 To Xi pi decay channel using KFParticle", false); + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processNoCentXicToXiPiWithKFParticle, "Run candidate creator w/o centrality selections for Xic0 To Xi pi decay channel using KFParticle", false); void processNoCentToOmegaK(soa::Join const& collisions, aod::BCsWithTimestamps const& bcWithTimeStamps, @@ -1736,6 +1750,28 @@ struct HfCandidateCreatorXic0Omegac0 { } PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0CToOmegaPi, "Run candidate creator w/ centrality selection on FT0C for omega pi channel", false); + void processCentFT0COmegacToOmegaPiWithKFParticle(soa::Join const& collisions, + aod::BCsWithTimestamps const& bcWithTimeStamps, + MyKfTracks const& tracks, + MyKfCascTable const& cascades, + KFCascadesLinked const& cascadeLinks, + aod::HfCascLf2Prongs const& candidates) + { + runKfOmegac0CreatorWithKFParticle(collisions, bcWithTimeStamps, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToOmegaPi, hFitterStatusToOmegaPi, hCandidateCounterToOmegaPi, hCascadesCounterToOmegaPi); + } + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0COmegacToOmegaPiWithKFParticle, "Run candidate creator w/o centrality selections for Omegac0 To omega pi decay channel using KFParticle", false); + + void processCentFT0CXicToXiPiWithKFParticle(soa::Join const& collisions, + aod::BCsWithTimestamps const& bcWithTimeStamps, + MyKfTracks const& tracks, + MyKfCascTable const& cascades, + KFCascadesLinked const& cascadeLinks, + aod::HfCascLf2Prongs const& candidates) + { + runKfXic0CreatorWithKFParticle(collisions, bcWithTimeStamps, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToXiPi, hFitterStatusToXiPi, hCandidateCounterToXiPi, hCascadesCounterToXiPi); + } + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0CXicToXiPiWithKFParticle, "Run candidate creator w FT0C centrality selections for Xic0 To Xi pi decay channel using KFParticle", false); + void processCentFT0CToOmegaK(soa::Join const& collisions, aod::BCsWithTimestamps const& bcWithTimeStamps, TracksWCovDca const& tracks, @@ -1773,6 +1809,28 @@ struct HfCandidateCreatorXic0Omegac0 { } PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0MToOmegaPi, "Run candidate creator w/ centrality selection on FT0M for omega pi channel", false); + void processCentFT0MOmegacToOmegaPiWithKFParticle(soa::Join const& collisions, + aod::BCsWithTimestamps const& bcWithTimeStamps, + MyKfTracks const& tracks, + MyKfCascTable const& cascades, + KFCascadesLinked const& cascadeLinks, + aod::HfCascLf2Prongs const& candidates) + { + runKfOmegac0CreatorWithKFParticle(collisions, bcWithTimeStamps, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToOmegaPi, hFitterStatusToOmegaPi, hCandidateCounterToOmegaPi, hCascadesCounterToOmegaPi); + } + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0MOmegacToOmegaPiWithKFParticle, "Run candidate creator w/o centrality selections for Omegac0 To omega pi decay channel using KFParticle", false); + + void processCentFT0MXicToXiPiWithKFParticle(soa::Join const& collisions, + aod::BCsWithTimestamps const& bcWithTimeStamps, + MyKfTracks const& tracks, + MyKfCascTable const& cascades, + KFCascadesLinked const& cascadeLinks, + aod::HfCascLf2Prongs const& candidates) + { + runKfXic0CreatorWithKFParticle(collisions, bcWithTimeStamps, tracks, cascades, cascadeLinks, candidates, hInvMassCharmBaryonToXiPi, hFitterStatusToXiPi, hCandidateCounterToXiPi, hCascadesCounterToXiPi); + } + PROCESS_SWITCH(HfCandidateCreatorXic0Omegac0, processCentFT0MXicToXiPiWithKFParticle, "Run candidate creator w FT0M centrality selections for Xic0 To Xi pi decay channel using KFParticle", false); + void processCentFT0MToOmegaK(soa::Join const& collisions, aod::BCsWithTimestamps const& bcWithTimeStamps, TracksWCovDca const& tracks, diff --git a/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx b/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx index b5709e5a778..d1ff9253928 100644 --- a/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx +++ b/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx @@ -21,39 +21,38 @@ #define HomogeneousField // o2-linter: disable=name/macro (required by KFParticle) #endif -#include -#include -#include -#include - -#include -#include -#include -#include -#include +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/Utils/utilsBfieldCCDB.h" +#include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/mcCentrality.h" -#include +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Tools/KFparticle/KFUtilities.h" #include "CommonConstants/PhysicsConstants.h" #include "DCAFitter/DCAFitterN.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" #include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/DCA.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/CollisionAssociationTables.h" -#include "Tools/KFparticle/KFUtilities.h" +#include -#include "PWGLF/DataModel/LFStrangenessTables.h" +#include +#include +#include +#include +#include -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/Utils/utilsBfieldCCDB.h" -#include "PWGHF/Utils/utilsEvSelHf.h" +#include +#include +#include +#include using namespace o2; -using namespace o2::analysis; using namespace o2::constants::physics; using namespace o2::framework; using namespace o2::hf_evsel; diff --git a/PWGHF/TableProducer/candidateCreatorXicc.cxx b/PWGHF/TableProducer/candidateCreatorXicc.cxx index 214c2cea891..e4455828b8d 100644 --- a/PWGHF/TableProducer/candidateCreatorXicc.cxx +++ b/PWGHF/TableProducer/candidateCreatorXicc.cxx @@ -105,7 +105,7 @@ struct HfCandidateCreatorXicc { aod::TracksWCov const& tracks) { for (const auto& xicCand : xicCands) { - if (!(xicCand.hfflag() & 1 << o2::aod::hf_cand_3prong::XicToPKPi)) { + if (!(xicCand.hfflag() & 1 << o2::aod::hf_cand_3prong::DecayType::XicToPKPi)) { continue; } if (xicCand.isSelXicToPKPi() >= selectionFlagXic) { @@ -195,9 +195,9 @@ struct HfCandidateCreatorXicc { xicCand.globalIndex(), trackpion.globalIndex(), hfFlag); } // if on selected Xicc - } // loop over candidates - } // end of process -}; // end of struct + } // loop over candidates + } // end of process +}; // end of struct /// Extends the base table with expression columns. struct HfCandidateCreatorXiccExpressions { diff --git a/PWGHF/TableProducer/candidateSelectorD0.cxx b/PWGHF/TableProducer/candidateSelectorD0.cxx index eda8561c6b3..de5818223ed 100644 --- a/PWGHF/TableProducer/candidateSelectorD0.cxx +++ b/PWGHF/TableProducer/candidateSelectorD0.cxx @@ -15,22 +15,23 @@ /// \author Nima Zardoshti , CERN /// \author Vít Kučera , CERN -#include -#include - -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" - -#include "Common/Core/TrackSelectorPID.h" - #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/HfMlResponse.h" #include "PWGHF/Core/HfMlResponseD0ToKPi.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/Utils/utilsAnalysis.h" +#include "Common/Core/TrackSelectorPID.h" + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include +#include + using namespace o2; using namespace o2::analysis; using namespace o2::framework; diff --git a/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx b/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx index 3efd7990991..e9a3bf95377 100644 --- a/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx @@ -15,21 +15,22 @@ /// \author Fabio Catalano , Politecnico and INFN Torino /// \author Vít Kučera , CERN -#include -#include - -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" - -#include "Common/Core/TrackSelectorPID.h" - #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/HfMlResponseDplusToPiKPi.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/Utils/utilsAnalysis.h" +#include "Common/Core/TrackSelectorPID.h" + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include +#include + using namespace o2; using namespace o2::analysis; using namespace o2::framework; diff --git a/PWGHF/TableProducer/candidateSelectorDsToKKPi.cxx b/PWGHF/TableProducer/candidateSelectorDsToKKPi.cxx index b1aad60b510..46f30ca6766 100644 --- a/PWGHF/TableProducer/candidateSelectorDsToKKPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorDsToKKPi.cxx @@ -15,21 +15,22 @@ /// \author Fabio Catalano , Universita and INFN Torino /// \author Stefano Politano , Politecnico and INFN Torino -#include -#include - -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" - -#include "Common/Core/TrackSelectorPID.h" - #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/HfMlResponseDsToKKPi.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/Utils/utilsAnalysis.h" +#include "Common/Core/TrackSelectorPID.h" + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include +#include + using namespace o2; using namespace o2::analysis; using namespace o2::framework; diff --git a/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx b/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx index d8b729dc748..cb058a18f6b 100644 --- a/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx +++ b/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx @@ -30,6 +30,7 @@ // PWGHF #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/HfMlResponseDstarToD0Pi.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/Utils/utilsAnalysis.h" diff --git a/PWGHF/TableProducer/candidateSelectorLc.cxx b/PWGHF/TableProducer/candidateSelectorLc.cxx index 93b84c79522..d48cb5f3daa 100644 --- a/PWGHF/TableProducer/candidateSelectorLc.cxx +++ b/PWGHF/TableProducer/candidateSelectorLc.cxx @@ -93,7 +93,8 @@ struct HfCandidateSelectorLc { Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; HfHelper hfHelper; - o2::analysis::HfMlResponseLcToPKPi hfMlResponse; + o2::analysis::HfMlResponseLcToPKPi hfMlResponseDCA; + o2::analysis::HfMlResponseLcToPKPi hfMlResponseKF; std::vector outputMlLcToPKPi = {}; std::vector outputMlLcToPiKP = {}; o2::ccdb::CcdbApi ccdbApi; @@ -142,15 +143,28 @@ struct HfCandidateSelectorLc { } if (applyMl) { - hfMlResponse.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); - if (loadModelsFromCCDB) { - ccdbApi.init(ccdbUrl); - hfMlResponse.setModelPathsCCDB(onnxFileNames, ccdbApi, modelPathsCCDB, timestampCCDB); - } else { - hfMlResponse.setModelPathsLocal(onnxFileNames); + if (doprocessNoBayesPidWithDCAFitterN || doprocessBayesPidWithDCAFitterN) { + hfMlResponseDCA.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); + if (loadModelsFromCCDB) { + ccdbApi.init(ccdbUrl); + hfMlResponseDCA.setModelPathsCCDB(onnxFileNames, ccdbApi, modelPathsCCDB, timestampCCDB); + } else { + hfMlResponseDCA.setModelPathsLocal(onnxFileNames); + } + hfMlResponseDCA.cacheInputFeaturesIndices(namesInputFeatures); + hfMlResponseDCA.init(); + } + if (doprocessNoBayesPidWithKFParticle || doprocessBayesPidWithKFParticle) { + hfMlResponseKF.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); + if (loadModelsFromCCDB) { + ccdbApi.init(ccdbUrl); + hfMlResponseKF.setModelPathsCCDB(onnxFileNames, ccdbApi, modelPathsCCDB, timestampCCDB); + } else { + hfMlResponseKF.setModelPathsLocal(onnxFileNames); + } + hfMlResponseKF.cacheInputFeaturesIndices(namesInputFeatures); + hfMlResponseKF.init(); } - hfMlResponse.cacheInputFeaturesIndices(namesInputFeatures); - hfMlResponse.init(); } massK0Star892 = o2::constants::physics::MassK0Star892; @@ -273,7 +287,7 @@ struct HfCandidateSelectorLc { return false; } - float massLc, massKPi; + float massLc{0.f}, massKPi{0.f}; if constexpr (reconstructionType == aod::hf_cand::VertexerType::DCAFitter) { if (trackProton.globalIndex() == candidate.prong0Id()) { massLc = hfHelper.invMassLcToPKPi(candidate); @@ -553,13 +567,24 @@ struct HfCandidateSelectorLc { isSelectedMlLcToPKPi = false; isSelectedMlLcToPiKP = false; - if (pidLcToPKPi == 1 && pidBayesLcToPKPi == 1 && topolLcToPKPi) { - std::vector inputFeaturesLcToPKPi = hfMlResponse.getInputFeatures(candidate, true); - isSelectedMlLcToPKPi = hfMlResponse.isSelectedMl(inputFeaturesLcToPKPi, candidate.pt(), outputMlLcToPKPi); - } - if (pidLcToPiKP == 1 && pidBayesLcToPiKP == 1 && topolLcToPiKP) { - std::vector inputFeaturesLcToPiKP = hfMlResponse.getInputFeatures(candidate, false); - isSelectedMlLcToPiKP = hfMlResponse.isSelectedMl(inputFeaturesLcToPiKP, candidate.pt(), outputMlLcToPiKP); + if constexpr (reconstructionType == aod::hf_cand::VertexerType::DCAFitter) { + if (pidLcToPKPi == 1 && pidBayesLcToPKPi == 1 && topolLcToPKPi) { + std::vector inputFeaturesLcToPKPi = hfMlResponseDCA.getInputFeatures(candidate, true); + isSelectedMlLcToPKPi = hfMlResponseDCA.isSelectedMl(inputFeaturesLcToPKPi, candidate.pt(), outputMlLcToPKPi); + } + if (pidLcToPiKP == 1 && pidBayesLcToPiKP == 1 && topolLcToPiKP) { + std::vector inputFeaturesLcToPiKP = hfMlResponseDCA.getInputFeatures(candidate, false); + isSelectedMlLcToPiKP = hfMlResponseDCA.isSelectedMl(inputFeaturesLcToPiKP, candidate.pt(), outputMlLcToPiKP); + } + } else { + if (pidLcToPKPi == 1 && pidBayesLcToPKPi == 1 && topolLcToPKPi) { + std::vector inputFeaturesLcToPKPi = hfMlResponseKF.getInputFeatures(candidate, true); + isSelectedMlLcToPKPi = hfMlResponseKF.isSelectedMl(inputFeaturesLcToPKPi, candidate.pt(), outputMlLcToPKPi); + } + if (pidLcToPiKP == 1 && pidBayesLcToPiKP == 1 && topolLcToPiKP) { + std::vector inputFeaturesLcToPiKP = hfMlResponseKF.getInputFeatures(candidate, false); + isSelectedMlLcToPiKP = hfMlResponseKF.isSelectedMl(inputFeaturesLcToPiKP, candidate.pt(), outputMlLcToPiKP); + } } hfMlLcToPKPiCandidate(outputMlLcToPKPi, outputMlLcToPiKP); diff --git a/PWGHF/TableProducer/candidateSelectorLcToK0sP.cxx b/PWGHF/TableProducer/candidateSelectorLcToK0sP.cxx index 7095fc2b8a1..5ef2dbb9ed1 100644 --- a/PWGHF/TableProducer/candidateSelectorLcToK0sP.cxx +++ b/PWGHF/TableProducer/candidateSelectorLcToK0sP.cxx @@ -17,21 +17,22 @@ /// Daniel Samitz, , Vienna /// Elisa Meninno, , Vienna -#include -#include - -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" - -#include "Common/Core/TrackSelectorPID.h" - #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/HfMlResponse.h" #include "PWGHF/Core/HfMlResponseLcToK0sP.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "Common/Core/TrackSelectorPID.h" + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include +#include + using namespace o2; using namespace o2::analysis; using namespace o2::framework; diff --git a/PWGHF/TableProducer/candidateSelectorOmegac0ToOmegaPi.cxx b/PWGHF/TableProducer/candidateSelectorOmegac0ToOmegaPi.cxx index 14ca3d917d0..c250b13a6ad 100644 --- a/PWGHF/TableProducer/candidateSelectorOmegac0ToOmegaPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorOmegac0ToOmegaPi.cxx @@ -16,23 +16,23 @@ /// \author Yunfan Liu , China University of Geosciences /// \author Fabio Catalano , University of Houston -#include -#include - -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" - -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectorPID.h" - #include "PWGHF/Core/HfMlResponse.h" #include "PWGHF/Core/HfMlResponseOmegacToOmegaPi.h" - +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/Utils/utilsAnalysis.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectorPID.h" + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include +#include + using namespace o2; using namespace o2::aod; using namespace o2::framework; @@ -354,7 +354,7 @@ struct HfCandidateSelectorToOmegaPi { // pt-dependent selection if (!selectionTopol(candidate)) { resultSelections = false; - hfSelToOmegaPi(statusPidLambda, statusPidCascade, statusPidCharmBaryon, statusInvMassLambda, statusInvMassCascade, statusInvMassCharmBaryon, resultSelections, infoTpcStored, infoTofStored, outputMlOmegac[0], + hfSelToOmegaPi(statusPidLambda, statusPidCascade, statusPidCharmBaryon, statusInvMassLambda, statusInvMassCascade, statusInvMassCharmBaryon, resultSelections, infoTpcStored, infoTofStored, trackPiFromCharm.tpcNSigmaPi(), trackKaFromCasc.tpcNSigmaKa(), trackPiFromLam.tpcNSigmaPi(), trackPrFromLam.tpcNSigmaPr(), trackPiFromCharm.tofNSigmaPi(), trackKaFromCasc.tofNSigmaKa(), trackPiFromLam.tofNSigmaPi(), trackPrFromLam.tofNSigmaPr()); if constexpr (ConstructMethod == hf_cand_casc_lf::ConstructMethod::KfParticle) { @@ -746,14 +746,12 @@ struct HfCandidateSelectorToOmegaPi { isSelectedMlOmegac = hfMlResponse.isSelectedMl(inputFeaturesOmegaC, ptCand, outputMlOmegac); if (isSelectedMlOmegac) { registry.fill(HIST("hBDTScoreTest1"), outputMlOmegac[0]); - } else { - resultSelections = false; } hfMlSelToOmegaPi(outputMlOmegac); } } - hfSelToOmegaPi(statusPidLambda, statusPidCascade, statusPidCharmBaryon, statusInvMassLambda, statusInvMassCascade, statusInvMassCharmBaryon, resultSelections, infoTpcStored, infoTofStored, outputMlOmegac[0], + hfSelToOmegaPi(statusPidLambda, statusPidCascade, statusPidCharmBaryon, statusInvMassLambda, statusInvMassCascade, statusInvMassCharmBaryon, resultSelections, infoTpcStored, infoTofStored, trackPiFromCharm.tpcNSigmaPi(), trackKaFromCasc.tpcNSigmaKa(), trackPiFromLam.tpcNSigmaPi(), trackPrFromLam.tpcNSigmaPr(), trackPiFromCharm.tofNSigmaPi(), trackKaFromCasc.tofNSigmaKa(), trackPiFromLam.tofNSigmaPi(), trackPrFromLam.tofNSigmaPr()); diff --git a/PWGHF/TableProducer/candidateSelectorXic0ToXiPiKf.cxx b/PWGHF/TableProducer/candidateSelectorXic0ToXiPiKf.cxx index 904b8c86b5b..367b60f7c31 100644 --- a/PWGHF/TableProducer/candidateSelectorXic0ToXiPiKf.cxx +++ b/PWGHF/TableProducer/candidateSelectorXic0ToXiPiKf.cxx @@ -12,17 +12,23 @@ /// \file candidateSelectorXic0ToXiPiKf.cxx /// \brief Xic0 → Xi Pi selection task /// \author Ran Tu , Fudan University +/// \author Tao Fang , Central China Normal University -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include "PWGHF/Core/HfMlResponseXic0ToXiPiKf.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsAnalysis.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectorPID.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsAnalysis.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include +#include using namespace o2; using namespace o2::aod; @@ -39,6 +45,7 @@ enum PidInfoStored { /// Struct for applying Xic0 -> Xi pi selection cuts struct HfCandidateSelectorXic0ToXiPiKf { Produces hfSelToXiPi; + Produces hfMlToXiPi; // LF analysis selections Configurable radiusCascMin{"radiusCascMin", 0.5, "Min cascade radius"}; @@ -116,6 +123,25 @@ struct HfCandidateSelectorXic0ToXiPiKf { Configurable nClustersItsInnBarrMin{"nClustersItsInnBarrMin", 1, "Minimum number of ITS clusters in inner barrel requirement for pi <- charm baryon"}; Configurable itsChi2PerClusterMax{"itsChi2PerClusterMax", 36, "Maximum value of chi2 fit over ITS clusters for pi <- charm baryon"}; + // ML inference + Configurable applyMl{"applyMl", true, "Flag to apply ML selections"}; + Configurable> binsPtMl{"binsPtMl", std::vector{hf_cuts_ml::vecBinsPt}, "pT bin limits for ML application"}; + Configurable> cutDirMl{"cutDirMl", std::vector{hf_cuts_ml::vecCutDir}, "Whether to reject score values greater or smaller than the threshold"}; + Configurable> cutsMl{"cutsMl", {hf_cuts_ml::Cuts[0], hf_cuts_ml::NBinsPt, hf_cuts_ml::NCutScores, hf_cuts_ml::labelsPt, hf_cuts_ml::labelsCutScore}, "ML selections per pT bin"}; + Configurable nClassesMl{"nClassesMl", static_cast(hf_cuts_ml::NCutScores), "Number of classes in ML model"}; + Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature1", "feature2"}, "Names of ML model input features"}; + + // CCDB configuration + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"EventFiltering/PWGHF/BDTXic0ToXipiKf"}, "Paths of models on CCDB"}; + Configurable> onnxFileNames{"onnxFileNames", std::vector{"ModelHandler_onnx_Xic0ToXipiKf.onnx"}, "ONNX file names for each pT bin (if not from CCDB full path)"}; + Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB"}; + Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; + + o2::analysis::HfMlResponseXic0ToXiPiKf hfMlResponse; + std::vector outputMlXic0ToXiPiKf = {}; + o2::ccdb::CcdbApi ccdbApi; + TrackSelectorPr selectorProton; TrackSelectorPi selectorPion; @@ -176,6 +202,18 @@ struct HfCandidateSelectorXic0ToXiPiKf { registry.add("hSelMassCharmBaryon", "hSelMassCharmBaryon;status;entries", {HistType::kTH1D, {axisSel}}); registry.add("hSelDcaXYToPvV0Daughters", "hSelDcaXYToPvV0Daughters;status;entries", {HistType::kTH1D, {axisSel}}); registry.add("hSelDcaXYToPvPiFromCasc", "hSelDcaXYToPvPiFromCasc;status;entries", {HistType::kTH1D, {axisSel}}); + + if (applyMl) { + hfMlResponse.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); + if (loadModelsFromCCDB) { + ccdbApi.init(ccdbUrl); + hfMlResponse.setModelPathsCCDB(onnxFileNames, ccdbApi, modelPathsCCDB, timestampCCDB); + } else { + hfMlResponse.setModelPathsLocal(onnxFileNames); + } + hfMlResponse.cacheInputFeaturesIndices(namesInputFeatures); + hfMlResponse.init(); + } } void process(aod::HfCandToXiPiKf const& candidates, @@ -186,6 +224,8 @@ struct HfCandidateSelectorXic0ToXiPiKf { // looping over charm baryon candidates for (const auto& candidate : candidates) { + auto ptCand = RecoDecay::pt(candidate.pxCharmBaryon(), candidate.pyCharmBaryon()); + bool resultSelections = true; // True if the candidate passes all the selections, False otherwise auto trackV0PosDauId = candidate.posTrackId(); // positive V0 daughter @@ -503,6 +543,17 @@ struct HfCandidateSelectorXic0ToXiPiKf { registry.fill(HIST("hSelMassCharmBaryon"), 0); } + // ML selections + if (applyMl) { + bool isSelectedMlXic0 = false; + std::vector inputFeaturesXic0 = hfMlResponse.getInputFeatures(candidate, trackPiFromLam, trackPiFromCasc, trackPiFromCharm); + isSelectedMlXic0 = hfMlResponse.isSelectedMl(inputFeaturesXic0, ptCand, outputMlXic0ToXiPiKf); + if (!isSelectedMlXic0) { + continue; + } + hfMlToXiPi(outputMlXic0ToXiPiKf); + } + hfSelToXiPi(statusPidCharmBaryon, statusPidCascade, statusPidLambda, statusInvMassCharmBaryon, statusInvMassCascade, statusInvMassLambda, resultSelections, infoTpcStored, infoTofStored, trackPiFromCharm.tpcNSigmaPi(), trackPiFromCasc.tpcNSigmaPi(), trackPiFromLam.tpcNSigmaPi(), trackPrFromLam.tpcNSigmaPr(), trackPiFromCharm.tofNSigmaPi(), trackPiFromCasc.tofNSigmaPi(), trackPiFromLam.tofNSigmaPi(), trackPrFromLam.tofNSigmaPr()); diff --git a/PWGHF/TableProducer/candidateSelectorXiccToPKPiPi.cxx b/PWGHF/TableProducer/candidateSelectorXiccToPKPiPi.cxx index 28e0035f39c..5bdbd036869 100644 --- a/PWGHF/TableProducer/candidateSelectorXiccToPKPiPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorXiccToPKPiPi.cxx @@ -14,17 +14,18 @@ /// /// \author Gian Michele Innocenti , CERN -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" + +#include "Common/Core/TrackSelectorPID.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" -#include "Common/Core/TrackSelectorPID.h" - -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/TableProducer/derivedDataCreatorDplusToPiKPi.cxx b/PWGHF/TableProducer/derivedDataCreatorDplusToPiKPi.cxx index c5c26270b79..6897b30ec0e 100644 --- a/PWGHF/TableProducer/derivedDataCreatorDplusToPiKPi.cxx +++ b/PWGHF/TableProducer/derivedDataCreatorDplusToPiKPi.cxx @@ -87,7 +87,7 @@ struct HfDerivedDataCreatorDplusToPiKPi { using TypeMcCollisions = soa::Join; Filter filterSelectCandidates = (aod::hf_sel_candidate_dplus::isSelDplusToPiKPi & static_cast(BIT(aod::SelectionStep::RecoMl - 1))) != 0; // select candidates which passed all cuts at least up to RecoMl - 1 - Filter filterMcGenMatching = nabs(aod::hf_cand_3prong::flagMcMatchGen) == static_cast(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)); + Filter filterMcGenMatching = nabs(aod::hf_cand_3prong::flagMcMatchGen) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi); Preslice candidatesPerCollision = aod::hf_cand::collisionId; Preslice candidatesMcPerCollision = aod::hf_cand::collisionId; @@ -101,10 +101,10 @@ struct HfDerivedDataCreatorDplusToPiKPi { Partition candidatesMlAll = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= 0; Partition candidatesMcMlAll = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= 0; // partitions for signal and background - Partition candidatesMcSig = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)); - Partition candidatesMcBkg = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)); - Partition candidatesMcMlSig = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)); - Partition candidatesMcMlBkg = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)); + Partition candidatesMcSig = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi); + Partition candidatesMcBkg = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi); + Partition candidatesMcMlSig = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi); + Partition candidatesMcMlBkg = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi); void init(InitContext const&) { @@ -253,7 +253,7 @@ struct HfDerivedDataCreatorDplusToPiKPi { swapping = candidate.isCandidateSwapped(); flagDecayChanRec = candidate.flagMcDecayChanRec(); if constexpr (onlyBkg) { - if (TESTBIT(std::abs(flagMcRec), aod::hf_cand_3prong::DecayType::DplusToPiKPi)) { + if (std::abs(flagMcRec) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) { continue; } if (downSampleBkgFactor < 1.) { @@ -264,7 +264,7 @@ struct HfDerivedDataCreatorDplusToPiKPi { } } if constexpr (onlySig) { - if (!TESTBIT(std::abs(flagMcRec), aod::hf_cand_3prong::DecayType::DplusToPiKPi)) { + if (std::abs(flagMcRec) != hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) { continue; } } diff --git a/PWGHF/TableProducer/derivedDataCreatorDstarToD0Pi.cxx b/PWGHF/TableProducer/derivedDataCreatorDstarToD0Pi.cxx index 084605c2f3b..7c592e9ccb1 100644 --- a/PWGHF/TableProducer/derivedDataCreatorDstarToD0Pi.cxx +++ b/PWGHF/TableProducer/derivedDataCreatorDstarToD0Pi.cxx @@ -83,7 +83,7 @@ struct HfDerivedDataCreatorDstarToD0Pi { using TypeMcCollisions = soa::Join; Filter filterSelectCandidates = aod::hf_sel_candidate_dstar::isSelDstarToD0Pi == true; - Filter filterMcGenMatching = nabs(aod::hf_cand_dstar::flagMcMatchGen) == static_cast(BIT(aod::hf_cand_dstar::DecayType::DstarToD0Pi)); + Filter filterMcGenMatching = nabs(aod::hf_cand_dstar::flagMcMatchGen) == static_cast(hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi); Preslice candidatesPerCollision = aod::hf_cand::collisionId; Preslice candidatesMcPerCollision = aod::hf_cand::collisionId; @@ -97,10 +97,10 @@ struct HfDerivedDataCreatorDstarToD0Pi { Partition candidatesMlAll = aod::hf_sel_candidate_dstar::isSelDstarToD0Pi == true; Partition candidatesMcMlAll = aod::hf_sel_candidate_dstar::isSelDstarToD0Pi == true; // partitions for signal and background - Partition candidatesMcSig = nabs(aod::hf_cand_dstar::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_dstar::DecayType::DstarToD0Pi)); - Partition candidatesMcBkg = nabs(aod::hf_cand_dstar::flagMcMatchRec) != static_cast(BIT(aod::hf_cand_dstar::DecayType::DstarToD0Pi)); - Partition candidatesMcMlSig = nabs(aod::hf_cand_dstar::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_dstar::DecayType::DstarToD0Pi)); - Partition candidatesMcMlBkg = nabs(aod::hf_cand_dstar::flagMcMatchRec) != static_cast(BIT(aod::hf_cand_dstar::DecayType::DstarToD0Pi)); + Partition candidatesMcSig = nabs(aod::hf_cand_dstar::flagMcMatchRec) == static_cast(hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi); + Partition candidatesMcBkg = nabs(aod::hf_cand_dstar::flagMcMatchRec) != static_cast(hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi); + Partition candidatesMcMlSig = nabs(aod::hf_cand_dstar::flagMcMatchRec) == static_cast(hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi); + Partition candidatesMcMlBkg = nabs(aod::hf_cand_dstar::flagMcMatchRec) != static_cast(hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi); void init(InitContext const&) { @@ -229,7 +229,7 @@ struct HfDerivedDataCreatorDstarToD0Pi { flagMcRec = candidate.flagMcMatchRec(); origin = candidate.originMcRec(); if constexpr (onlyBkg) { - if (TESTBIT(std::abs(flagMcRec), aod::hf_cand_dstar::DecayType::DstarToD0Pi)) { + if (std::abs(flagMcRec) == hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi) { continue; } if (downSampleBkgFactor < 1.) { @@ -240,7 +240,7 @@ struct HfDerivedDataCreatorDstarToD0Pi { } } if constexpr (onlySig) { - if (!TESTBIT(std::abs(flagMcRec), aod::hf_cand_dstar::DecayType::DstarToD0Pi)) { + if (std::abs(flagMcRec) != hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi) { continue; } } diff --git a/PWGHF/TableProducer/derivedDataCreatorLcToPKPi.cxx b/PWGHF/TableProducer/derivedDataCreatorLcToPKPi.cxx index 7078087a222..a956d4ff202 100644 --- a/PWGHF/TableProducer/derivedDataCreatorLcToPKPi.cxx +++ b/PWGHF/TableProducer/derivedDataCreatorLcToPKPi.cxx @@ -87,7 +87,7 @@ struct HfDerivedDataCreatorLcToPKPi { using TypeMcCollisions = soa::Join; Filter filterSelectCandidates = aod::hf_sel_candidate_lc::isSelLcToPKPi >= 1 || aod::hf_sel_candidate_lc::isSelLcToPiKP >= 1; - Filter filterMcGenMatching = nabs(aod::hf_cand_3prong::flagMcMatchGen) == static_cast(BIT(aod::hf_cand_3prong::DecayType::LcToPKPi)); + Filter filterMcGenMatching = nabs(aod::hf_cand_3prong::flagMcMatchGen) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi); Preslice candidatesPerCollision = aod::hf_cand::collisionId; Preslice candidatesMcPerCollision = aod::hf_cand::collisionId; @@ -101,10 +101,10 @@ struct HfDerivedDataCreatorLcToPKPi { Partition candidatesMlAll = aod::hf_sel_candidate_lc::isSelLcToPKPi >= 0; Partition candidatesMcMlAll = aod::hf_sel_candidate_lc::isSelLcToPKPi >= 0; // partitions for signal and background - Partition candidatesMcSig = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_3prong::DecayType::LcToPKPi)); - Partition candidatesMcBkg = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(BIT(aod::hf_cand_3prong::DecayType::LcToPKPi)); - Partition candidatesMcMlSig = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_3prong::DecayType::LcToPKPi)); - Partition candidatesMcMlBkg = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(BIT(aod::hf_cand_3prong::DecayType::LcToPKPi)); + Partition candidatesMcSig = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi); + Partition candidatesMcBkg = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi); + Partition candidatesMcMlSig = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi); + Partition candidatesMcMlBkg = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi); void init(InitContext const&) { @@ -252,7 +252,7 @@ struct HfDerivedDataCreatorLcToPKPi { origin = candidate.originMcRec(); swapping = candidate.isCandidateSwapped(); if constexpr (onlyBkg) { - if (TESTBIT(std::abs(flagMcRec), aod::hf_cand_3prong::DecayType::LcToPKPi)) { + if (std::abs(flagMcRec) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { continue; } if (downSampleBkgFactor < 1.) { @@ -263,7 +263,7 @@ struct HfDerivedDataCreatorLcToPKPi { } } if constexpr (onlySig) { - if (!TESTBIT(std::abs(flagMcRec), aod::hf_cand_3prong::DecayType::LcToPKPi)) { + if (std::abs(flagMcRec) != hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { continue; } } diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index c84a0c11c10..6277a8b915f 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -21,23 +21,13 @@ /// \author Federica Zanone , Heidelberg University /// \author Ruiqi Yin , Fudan University -#include // std::find -#include // std::distance -#include // std::string -#include // std::vector - -#include "CommonConstants/PhysicsConstants.h" -#include "CCDB/BasicCCDBManager.h" // for PV refit -#include "DataFormatsParameters/GRPMagField.h" // for PV refit -#include "DataFormatsParameters/GRPObject.h" // for PV refit -#include "DCAFitter/DCAFitterN.h" -#include "DetectorsBase/Propagator.h" // for PV refit -#include "DetectorsVertexing/PVertexer.h" // for PV refit -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/V0.h" -#include "ReconstructionDataFormats/Vertex.h" // for PV refit +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/Utils/utilsAnalysis.h" +#include "PWGHF/Utils/utilsBfieldCCDB.h" +#include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" #include "Common/Core/TrackSelectorPID.h" #include "Common/Core/trackUtilities.h" @@ -47,13 +37,23 @@ #include "Common/DataModel/TrackSelectionTables.h" #include "Tools/ML/MlResponse.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "CCDB/BasicCCDBManager.h" // for PV refit +#include "CommonConstants/PhysicsConstants.h" +#include "DCAFitter/DCAFitterN.h" +#include "DataFormatsParameters/GRPMagField.h" // for PV refit +#include "DataFormatsParameters/GRPObject.h" // for PV refit +#include "DetectorsBase/Propagator.h" // for PV refit +#include "DetectorsVertexing/PVertexer.h" // for PV refit +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/V0.h" +#include "ReconstructionDataFormats/Vertex.h" // for PV refit -#include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/Utils/utilsAnalysis.h" -#include "PWGHF/Utils/utilsBfieldCCDB.h" -#include "PWGHF/Utils/utilsEvSelHf.h" +#include // std::find +#include // std::distance +#include // std::string +#include // std::vector using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/TableProducer/treeCreatorDplusToPiKPi.cxx b/PWGHF/TableProducer/treeCreatorDplusToPiKPi.cxx index 7e482985c0d..3d23c0b30ca 100644 --- a/PWGHF/TableProducer/treeCreatorDplusToPiKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorDplusToPiKPi.cxx @@ -268,11 +268,11 @@ struct HfTreeCreatorDplusToPiKPi { using CollisionsCent = soa::Join; Filter filterSelectCandidates = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus; - Filter filterMcGenMatching = nabs(o2::aod::hf_cand_3prong::flagMcMatchGen) == static_cast(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)); + Filter filterMcGenMatching = nabs(o2::aod::hf_cand_3prong::flagMcMatchGen) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi); - Partition reconstructedCandSig = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)) || nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_3prong::DecayType::DsToKKPi)); // DecayType::DsToKKPi is used to flag both Ds± → K± K∓ π± and D± → K± K∓ π± - Partition reconstructedCandBkg = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)); - Partition reconstructedCandSigMl = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)) || nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_3prong::DecayType::DsToKKPi)) || nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_3prong::DstarToPiKPiBkg)); // DecayType::DsToKKPi is used to flag both Ds± → K± K∓ π± and D± → K± K∓ π± + Partition reconstructedCandSig = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) || nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) || nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKK); + Partition reconstructedCandBkg = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi); + Partition reconstructedCandSigMl = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) || nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) || nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKK) || nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DstarToPiKPi); void init(InitContext const&) { diff --git a/PWGHF/TableProducer/treeCreatorDsToKKPi.cxx b/PWGHF/TableProducer/treeCreatorDsToKKPi.cxx index cf2f595f44b..a6d19002430 100644 --- a/PWGHF/TableProducer/treeCreatorDsToKKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorDsToKKPi.cxx @@ -17,14 +17,16 @@ /// \author Stefano Politanò , Politecnico & INFN, Torino /// \author Fabio Catalano , CERN +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" + #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include using namespace o2; using namespace o2::framework; @@ -229,6 +231,19 @@ DECLARE_SOA_TABLE(HfCandDsFullPs, "AOD", "HFCANDDSFULLP", hf_cand_3prong::OriginMcGen); } // namespace o2::aod +enum Mother : int8_t { + Ds, + Dplus +}; + +enum ResonantChannel : int8_t { + PhiPi = 1, + Kstar0K = 2 +}; + +static std::unordered_map> channelsResonant = {{{Mother::Ds, {{ResonantChannel::PhiPi, hf_decay::hf_cand_3prong::DecayChannelResonant::DsToPhiPi}, {ResonantChannel::Kstar0K, hf_decay::hf_cand_3prong::DecayChannelResonant::DsToKstar0K}}}, + {Mother::Dplus, {{ResonantChannel::PhiPi, hf_decay::hf_cand_3prong::DecayChannelResonant::DplusToPhiPi}, {ResonantChannel::Kstar0K, hf_decay::hf_cand_3prong::DecayChannelResonant::DplusToKstar0K}}}}}; + /// Writes the full information in an output TTree struct HfTreeCreatorDsToKKPi { Produces rowCandidateFull; @@ -236,7 +251,7 @@ struct HfTreeCreatorDsToKKPi { Produces rowCandidateFullParticles; Produces rowCandidateLite; - Configurable decayChannel{"decayChannel", 1, "Switch between decay channels: 1 for Ds/Dplus->PhiPi->KKpi, 2 for Ds/Dplus->K0*K->KKPi"}; + Configurable decayChannel{"decayChannel", 1, "Switch between resonant decay channels: 1 for Ds/Dplus->PhiPi->KKpi, 2 for Ds/Dplus->K0*K->KKPi"}; Configurable fillDplusMc{"fillDplusMc", false, "Switch to fill Dplus MC information"}; Configurable selectionFlagDs{"selectionFlagDs", 1, "Selection flag for Ds"}; Configurable fillCandidateLiteTable{"fillCandidateLiteTable", false, "Switch to fill lite table with candidate properties"}; @@ -260,16 +275,22 @@ struct HfTreeCreatorDsToKKPi { int offsetDplusDecayChannel = aod::hf_cand_3prong::DecayChannelDToKKPi::DplusToPhiPi - aod::hf_cand_3prong::DecayChannelDToKKPi::DsToPhiPi; // Offset between Dplus and Ds to use the same decay channel. See aod::hf_cand_3prong::DecayChannelDToKKPi Filter filterSelectCandidates = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlagDs || aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlagDs; - Filter filterMcGenMatching = nabs(o2::aod::hf_cand_3prong::flagMcMatchGen) == static_cast(BIT(aod::hf_cand_3prong::DecayType::DsToKKPi)) && (aod::hf_cand_3prong::flagMcDecayChanGen == decayChannel || (fillDplusMc && aod::hf_cand_3prong::flagMcDecayChanGen == (decayChannel + offsetDplusDecayChannel))); // Do not store Dplus MC if fillDplusMc is false + Filter filterMcGenMatching = + nabs(o2::aod::hf_cand_3prong::flagMcMatchGen) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) && + (aod::hf_cand_3prong::flagMcDecayChanGen == channelsResonant[Mother::Ds][decayChannel] || + (fillDplusMc && aod::hf_cand_3prong::flagMcDecayChanGen == channelsResonant[Mother::Dplus][decayChannel])); // Do not store Dplus MC if fillDplusMc is false Partition selectedDsToKKPiCand = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlagDs; Partition selectedDsToPiKKCand = aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlagDs; - Partition reconstructedCandSig = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_3prong::DecayType::DsToKKPi)) && (aod::hf_cand_3prong::flagMcDecayChanRec == decayChannel || (fillDplusMc && aod::hf_cand_3prong::flagMcDecayChanRec == (decayChannel + offsetDplusDecayChannel))); // Do not store Dplus MC if fillDplusMc is false - Partition reconstructedCandBkg = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(BIT(aod::hf_cand_3prong::DecayType::DsToKKPi)); + Partition reconstructedCandSig = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) && (aod::hf_cand_3prong::flagMcDecayChanRec == channelsResonant[Mother::Ds][decayChannel] || (fillDplusMc && aod::hf_cand_3prong::flagMcDecayChanRec == channelsResonant[Mother::Dplus][decayChannel])); // Do not store Dplus MC if fillDplusMc is false + Partition reconstructedCandBkg = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK); void init(InitContext const&) { + if (decayChannel != ResonantChannel::PhiPi && decayChannel != ResonantChannel::Kstar0K) { + LOGP(fatal, "Invalid value of decayChannel"); + } } template @@ -305,7 +326,7 @@ struct HfTreeCreatorDsToKKPi { originMc = candidate.originMcRec(); channelMc = candidate.flagMcDecayChanRec(); isSwapped = candidate.isCandidateSwapped(); - if (fillDplusMc && candidate.flagMcDecayChanRec() == (decayChannel + offsetDplusDecayChannel)) { + if (fillDplusMc && candidate.flagMcDecayChanRec() == channelsResonant[Mother::Dplus][decayChannel]) { yCand = hfHelper.yDplus(candidate); eCand = hfHelper.eDplus(candidate); ctCand = hfHelper.ctDplus(candidate); diff --git a/PWGHF/TableProducer/treeCreatorDstarToD0Pi.cxx b/PWGHF/TableProducer/treeCreatorDstarToD0Pi.cxx index 00d2bea174f..2b838d774b1 100644 --- a/PWGHF/TableProducer/treeCreatorDstarToD0Pi.cxx +++ b/PWGHF/TableProducer/treeCreatorDstarToD0Pi.cxx @@ -261,10 +261,10 @@ struct HfTreeCreatorDstarToD0Pi { using CandDstarMcGen = soa::Filtered>; Filter filterSelectCandidates = aod::hf_sel_candidate_dstar::isSelDstarToD0Pi == selectionFlagDstarToD0Pi; - Filter filterMcGenMatching = nabs(aod::hf_cand_dstar::flagMcMatchGen) == static_cast(BIT(aod::hf_cand_dstar::DecayType::DstarToD0Pi)); + Filter filterMcGenMatching = nabs(aod::hf_cand_dstar::flagMcMatchGen) == static_cast(hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi); - Partition reconstructedCandSig = nabs(aod::hf_cand_dstar::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_dstar::DecayType::DstarToD0Pi)); - Partition reconstructedCandBkg = nabs(aod::hf_cand_dstar::flagMcMatchRec) != static_cast(BIT(aod::hf_cand_dstar::DecayType::DstarToD0Pi)); + Partition reconstructedCandSig = nabs(aod::hf_cand_dstar::flagMcMatchRec) == static_cast(hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi); + Partition reconstructedCandBkg = nabs(aod::hf_cand_dstar::flagMcMatchRec) != static_cast(hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi); void init(InitContext const&) { diff --git a/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx b/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx index 398bf3fc57a..04b85fa626b 100644 --- a/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx @@ -17,18 +17,20 @@ /// \author Nicolo' Jacazio , CERN /// \author Luigi Dello Stritto , CERN -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" + +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Multiplicity.h" - -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -87,6 +89,9 @@ DECLARE_SOA_COLUMN(IsCandidateSwapped, isCandidateSwapped, int8_t); DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, HfCand3ProngWPidPiKaPr, "_0"); DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); DECLARE_SOA_COLUMN(Channel, channel, int8_t); // direct or resonant +DECLARE_SOA_COLUMN(MlScoreFirstClass, mlScoreFirstClass, float); +DECLARE_SOA_COLUMN(MlScoreSecondClass, mlScoreSecondClass, float); +DECLARE_SOA_COLUMN(MlScoreThirdClass, mlScoreThirdClass, float); // Events DECLARE_SOA_INDEX_COLUMN(McCollision, mcCollision); DECLARE_SOA_COLUMN(IsEventReject, isEventReject, int); @@ -238,7 +243,10 @@ DECLARE_SOA_TABLE(HfCandLcLites, "AOD", "HFCANDLCLITE", full::OriginMcRec, full::IsCandidateSwapped, full::Channel, - full::MassKPi); + full::MassKPi, + full::MlScoreFirstClass, + full::MlScoreSecondClass, + full::MlScoreThirdClass); DECLARE_SOA_TABLE(HfCollIdLCLite, "AOD", "HFCOLLIDLCLITE", full::CollisionId); @@ -316,7 +324,10 @@ DECLARE_SOA_TABLE(HfCandLcFulls, "AOD", "HFCANDLCFULL", full::IsCandidateSwapped, full::CandidateId, full::Channel, - full::MassKPi); + full::MassKPi, + full::MlScoreFirstClass, + full::MlScoreSecondClass, + full::MlScoreThirdClass); DECLARE_SOA_TABLE(HfCandLcFullEvs, "AOD", "HFCANDLCFULLEV", full::CollisionId, @@ -374,6 +385,7 @@ struct HfTreeCreatorLcToPKPi { Configurable fillCandidateLiteTable{"fillCandidateLiteTable", false, "Switch to fill lite table with candidate properties"}; Configurable fillCollIdTable{"fillCollIdTable", false, "Fill a single-column table with collision index"}; Configurable fillCandidateMcTable{"fillCandidateMcTable", false, "Switch to fill a table with MC particles matched to candidates"}; + Configurable applyMl{"applyMl", false, "Whether ML was used in candidateSelectorLc"}; Configurable keepOnlySignalMc{"keepOnlySignalMc", false, "Fill MC tree only with signal candidates"}; Configurable keepOnlyBkg{"keepOnlyBkg", false, "Fill MC tree only with background candidates"}; Configurable downSampleBkgFactor{"downSampleBkgFactor", 1., "Fraction of candidates to store in the tree"}; @@ -410,7 +422,7 @@ struct HfTreeCreatorLcToPKPi { SigBgStatus status{Default}; - if (std::abs(flag) == (1 << o2::aod::hf_cand_3prong::DecayType::LcToPKPi)) { + if (std::abs(flag) == o2::hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { if (swapped == 0) { if (candFlag == 0) { if (origin == RecoDecay::OriginType::Prompt) @@ -553,11 +565,40 @@ struct HfTreeCreatorLcToPKPi { return std::make_pair(invMass, invMassKPi); } + /// \brief function to get ML score values for the current candidate and assign them to input parameters + /// \param candidate candidate instance + /// \param candidateMlScore instance of handler of vectors with ML scores associated with the current candidate + /// \param mlScoreFirstClass ML score for belonging to the first class + /// \param mlScoreSecondClass ML score for belonging to the second class + /// \param mlScoreThirdClass ML score for belonging to the third class + /// \param candFlag flag indicating if PKPi (0) or PiKP (1) hypothesis is used + void assignMlScores(aod::HfMlLcToPKPi::iterator const& candidateMlScore, float& mlScoreFirstClass, float& mlScoreSecondClass, float& mlScoreThirdClass, int candFlag) + { + std::vector mlScores; + if (candFlag == 0) { + std::copy(candidateMlScore.mlProbLcToPKPi().begin(), candidateMlScore.mlProbLcToPKPi().end(), std::back_inserter(mlScores)); + } else { + std::copy(candidateMlScore.mlProbLcToPiKP().begin(), candidateMlScore.mlProbLcToPiKP().end(), std::back_inserter(mlScores)); + } + constexpr int IndexFirstClass{0}; + constexpr int IndexSecondClass{1}; + constexpr int IndexThirdClass{2}; + if (mlScores.size() == 0) { + return; // when candidateSelectorLc rejects a candidate by "usual", non-ML cut, the ml score vector remains empty + } + mlScoreFirstClass = mlScores.at(IndexFirstClass); + mlScoreSecondClass = mlScores.at(IndexSecondClass); + if (mlScores.size() > IndexThirdClass) { + mlScoreThirdClass = mlScores.at(IndexThirdClass); + } + } + /// \brief function to fill lite table /// \param candidate candidate instance + /// \param candidateMlScore instance of handler of vectors with ML scores associated with the current candidate /// \param candFlag flag indicating if PKPi (0) or PiKP (1) hypothesis is used template - void fillLiteTable(CandType const& candidate, int candFlag) + void fillLiteTable(CandType const& candidate, aod::HfMlLcToPKPi::iterator const& candidateMlScore, int candFlag) { auto [functionInvMass, functionInvMassKPi] = evaluateInvariantMasses(candidate, candFlag); const float functionCt = hfHelper.ctLc(candidate); @@ -575,6 +616,14 @@ struct HfTreeCreatorLcToPKPi { functionFlagMcDecayChanRec = candidate.flagMcDecayChanRec(); } + float mlScoreFirstClass{UndefValueFloat}; + float mlScoreSecondClass{UndefValueFloat}; + float mlScoreThirdClass{UndefValueFloat}; + + if (applyMl) { + assignMlScores(candidateMlScore, mlScoreFirstClass, mlScoreSecondClass, mlScoreThirdClass, candFlag); + } + rowCandidateLite( candidate.posX(), candidate.posY(), @@ -618,7 +667,10 @@ struct HfTreeCreatorLcToPKPi { functionOriginMcRec, functionIsCandidateSwapped, functionFlagMcDecayChanRec, - functionInvMassKPi); + functionInvMassKPi, + mlScoreFirstClass, + mlScoreSecondClass, + mlScoreThirdClass); if (fillCollIdTable) { /// save also candidate collision indices @@ -628,9 +680,10 @@ struct HfTreeCreatorLcToPKPi { /// \brief function to fill lite table /// \param candidate candidate instance + /// \param candidateMlScore instance of handler of vectors with ML scores associated with the current candidate /// \param candFlag flag indicating if PKPi (0) or PiKP (1) hypothesis is used template - void fillFullTable(CandType const& candidate, int candFlag) + void fillFullTable(CandType const& candidate, aod::HfMlLcToPKPi::iterator const& candidateMlScore, int candFlag) { auto [functionInvMass, functionInvMassKPi] = evaluateInvariantMasses(candidate, candFlag); const float functionCt = hfHelper.ctLc(candidate); @@ -649,6 +702,14 @@ struct HfTreeCreatorLcToPKPi { functionFlagMcDecayChanRec = candidate.flagMcDecayChanRec(); } + float mlScoreFirstClass{UndefValueFloat}; + float mlScoreSecondClass{UndefValueFloat}; + float mlScoreThirdClass{UndefValueFloat}; + + if (applyMl) { + assignMlScores(candidateMlScore, mlScoreFirstClass, mlScoreSecondClass, mlScoreThirdClass, candFlag); + } + rowCandidateFull( candidate.collisionId(), candidate.posX(), @@ -722,7 +783,10 @@ struct HfTreeCreatorLcToPKPi { functionIsCandidateSwapped, candidate.globalIndex(), functionFlagMcDecayChanRec, - functionInvMassKPi); + functionInvMassKPi, + mlScoreFirstClass, + mlScoreSecondClass, + mlScoreThirdClass); } /// \brief function to fill lite table @@ -839,6 +903,7 @@ struct HfTreeCreatorLcToPKPi { void fillTablesMc(Colls const& collisions, aod::McCollisions const&, CandType const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, soa::Join const& particles, soa::Join const&, aod::BCs const&) { @@ -850,7 +915,10 @@ struct HfTreeCreatorLcToPKPi { const size_t candidatesSize = candidates.size(); reserveTables(candidatesSize, IsMc); + int iCand{0}; for (const auto& candidate : candidates) { + auto candidateMlScore = candidateMlScores.rawIteratorAt(iCand); + ++iCand; float ptProng0 = candidate.ptProng0(); auto collision = candidate.template collision_as(); auto fillTable = [&](int candFlag) { @@ -863,9 +931,9 @@ struct HfTreeCreatorLcToPKPi { const bool notSkippedBkg = isMcCandidateSignal || candidate.pt() > downSampleBkgPtMax || pseudoRndm < downSampleBkgFactor; if (passSelection && notSkippedBkg && (keepAll || (keepOnlySignalMc && isMcCandidateSignal) || (keepOnlyBkg && !isMcCandidateSignal))) { if (fillCandidateLiteTable) { - fillLiteTable(candidate, candFlag); + fillLiteTable(candidate, candidateMlScore, candFlag); } else { - fillFullTable(candidate, candFlag); + fillFullTable(candidate, candidateMlScore, candFlag); } if constexpr (reconstructionType == aod::hf_cand::VertexerType::KfParticle) { @@ -917,7 +985,7 @@ struct HfTreeCreatorLcToPKPi { // Filling particle properties rowCandidateFullParticles.reserve(particles.size()); for (const auto& particle : particles) { - if (std::abs(particle.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::LcToPKPi) { + if (std::abs(particle.flagMcMatchGen()) == o2::hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { auto mcDaughter0 = particle.template daughters_as>().begin(); auto mcCollision = particle.template mcCollision_as(); auto p = particle.p(); @@ -955,10 +1023,11 @@ struct HfTreeCreatorLcToPKPi { void processMcNoCentralityWithDCAFitterN(soa::Join const& collisions, aod::McCollisions const& mcCollisions, soa::Join const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, soa::Join const& particles, soa::Join const& tracks, aod::BCs const& bcs) { - fillTablesMc(collisions, mcCollisions, candidates, particles, tracks, bcs); + fillTablesMc(collisions, mcCollisions, candidates, candidateMlScores, particles, tracks, bcs); } PROCESS_SWITCH(HfTreeCreatorLcToPKPi, processMcNoCentralityWithDCAFitterN, "Process MC tree writer w/o centrality with DCAFitterN", false); @@ -971,10 +1040,11 @@ struct HfTreeCreatorLcToPKPi { void processMcWithCentralityWithDCAFitterN(soa::Join const& collisions, aod::McCollisions const& mcCollisions, soa::Join const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, soa::Join const& particles, soa::Join const& tracks, aod::BCs const& bcs) { - fillTablesMc(collisions, mcCollisions, candidates, particles, tracks, bcs); + fillTablesMc(collisions, mcCollisions, candidates, candidateMlScores, particles, tracks, bcs); } PROCESS_SWITCH(HfTreeCreatorLcToPKPi, processMcWithCentralityWithDCAFitterN, "Process MC tree writer with centrality with DCAFitterN", false); @@ -988,10 +1058,11 @@ struct HfTreeCreatorLcToPKPi { void processMcNoCentralityWithKFParticle(soa::Join const& collisions, aod::McCollisions const& mcCollisions, soa::Join const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, soa::Join const& particles, soa::Join const& tracks, aod::BCs const& bcs) { - fillTablesMc(collisions, mcCollisions, candidates, particles, tracks, bcs); + fillTablesMc(collisions, mcCollisions, candidates, candidateMlScores, particles, tracks, bcs); } PROCESS_SWITCH(HfTreeCreatorLcToPKPi, processMcNoCentralityWithKFParticle, "Process MC tree writer w/o centrality with KFParticle", false); @@ -1004,10 +1075,11 @@ struct HfTreeCreatorLcToPKPi { void processMcWithCentralityWithKFParticle(soa::Join const& collisions, aod::McCollisions const& mcCollisions, soa::Join const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, soa::Join const& particles, soa::Join const& tracks, aod::BCs const& bcs) { - fillTablesMc(collisions, mcCollisions, candidates, particles, tracks, bcs); + fillTablesMc(collisions, mcCollisions, candidates, candidateMlScores, particles, tracks, bcs); } PROCESS_SWITCH(HfTreeCreatorLcToPKPi, processMcWithCentralityWithKFParticle, "Process MC tree writer with centrality with KFParticle", false); @@ -1017,6 +1089,7 @@ struct HfTreeCreatorLcToPKPi { template void fillTablesData(Colls const& collisions, CandType const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, TracksWPid const&, aod::BCs const&) { @@ -1029,7 +1102,10 @@ struct HfTreeCreatorLcToPKPi { // Filling candidate properties + int iCand{0}; for (const auto& candidate : candidates) { + auto candidateMlScore = candidateMlScores.rawIteratorAt(iCand); + ++iCand; float ptProng0 = candidate.ptProng0(); auto collision = candidate.template collision_as(); auto fillTable = [&](int candFlag) { @@ -1037,9 +1113,9 @@ struct HfTreeCreatorLcToPKPi { const int functionSelection = candFlag == 0 ? candidate.isSelLcToPKPi() : candidate.isSelLcToPiKP(); if (functionSelection >= selectionFlagLc && (candidate.pt() > downSampleBkgPtMax || (pseudoRndm < downSampleBkgFactor && candidate.pt() < downSampleBkgPtMax))) { if (fillCandidateLiteTable) { - fillLiteTable(candidate, candFlag); + fillLiteTable(candidate, candidateMlScore, candFlag); } else { - fillFullTable(candidate, candFlag); + fillFullTable(candidate, candidateMlScore, candFlag); } if constexpr (reconstructionType == aod::hf_cand::VertexerType::KfParticle) { @@ -1060,9 +1136,10 @@ struct HfTreeCreatorLcToPKPi { /// \param bcs Bunch-crossing table void processDataNoCentralityWithDCAFitterN(soa::Join const& collisions, soa::Join const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, TracksWPid const& tracks, aod::BCs const& bcs) { - fillTablesData(collisions, candidates, tracks, bcs); + fillTablesData(collisions, candidates, candidateMlScores, tracks, bcs); } PROCESS_SWITCH(HfTreeCreatorLcToPKPi, processDataNoCentralityWithDCAFitterN, "Process data tree writer w/o centrality with DCAFitterN", false); @@ -1073,9 +1150,10 @@ struct HfTreeCreatorLcToPKPi { /// \param bcs Bunch-crossing table void processDataWithCentralityWithDCAFitterN(soa::Join const& collisions, soa::Join const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, TracksWPid const& tracks, aod::BCs const& bcs) { - fillTablesData(collisions, candidates, tracks, bcs); + fillTablesData(collisions, candidates, candidateMlScores, tracks, bcs); } PROCESS_SWITCH(HfTreeCreatorLcToPKPi, processDataWithCentralityWithDCAFitterN, "Process data tree writer with centrality with DCAFitterN", true); @@ -1086,9 +1164,10 @@ struct HfTreeCreatorLcToPKPi { /// \param bcs Bunch-crossing table void processDataNoCentralityWithKFParticle(soa::Join const& collisions, soa::Join const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, TracksWPid const& tracks, aod::BCs const& bcs) { - fillTablesData(collisions, candidates, tracks, bcs); + fillTablesData(collisions, candidates, candidateMlScores, tracks, bcs); } PROCESS_SWITCH(HfTreeCreatorLcToPKPi, processDataNoCentralityWithKFParticle, "Process data tree writer w/o centrality with KFParticle", false); @@ -1099,9 +1178,10 @@ struct HfTreeCreatorLcToPKPi { /// \param bcs Bunch-crossing table void processDataWithCentralityWithKFParticle(soa::Join const& collisions, soa::Join const& candidates, + aod::HfMlLcToPKPi const& candidateMlScores, TracksWPid const& tracks, aod::BCs const& bcs) { - fillTablesData(collisions, candidates, tracks, bcs); + fillTablesData(collisions, candidates, candidateMlScores, tracks, bcs); } PROCESS_SWITCH(HfTreeCreatorLcToPKPi, processDataWithCentralityWithKFParticle, "Process data tree writer with centrality with KFParticle", false); }; diff --git a/PWGHF/TableProducer/treeCreatorOmegac0ToOmegaPi.cxx b/PWGHF/TableProducer/treeCreatorOmegac0ToOmegaPi.cxx index 3c5491e0dae..a1b8a2b3706 100644 --- a/PWGHF/TableProducer/treeCreatorOmegac0ToOmegaPi.cxx +++ b/PWGHF/TableProducer/treeCreatorOmegac0ToOmegaPi.cxx @@ -152,7 +152,6 @@ DECLARE_SOA_COLUMN(OmegacChi2OverNdf, omegacChi2OverNdf, float); DECLARE_SOA_COLUMN(MassV0Chi2OverNdf, massV0Chi2OverNdf, float); DECLARE_SOA_COLUMN(MassCascChi2OverNdf, massCascChi2OverNdf, float); DECLARE_SOA_COLUMN(CascRejectInvmass, cascRejectInvmass, float); -DECLARE_SOA_COLUMN(OutputMlOmegac, outputMlOmegac, float); } // namespace full DECLARE_SOA_TABLE(HfToOmegaPiEvs, "AOD", "HFTOOMEPIEV", @@ -200,7 +199,7 @@ DECLARE_SOA_TABLE(HfKfOmegacFulls, "AOD", "HFKFOMEGACFULL", full::V0Ndf, full::CascNdf, full::OmegacNdf, full::MassV0Ndf, full::MassCascNdf, full::V0Chi2OverNdf, full::CascChi2OverNdf, full::OmegacChi2OverNdf, - full::MassV0Chi2OverNdf, full::MassCascChi2OverNdf, full::CascRejectInvmass, full::OutputMlOmegac, + full::MassV0Chi2OverNdf, full::MassCascChi2OverNdf, full::CascRejectInvmass, full::FlagMcMatchRec, full::OriginRec, full::CollisionMatched, hf_track_index::HFflag); DECLARE_SOA_TABLE(HfKfOmegacLites, "AOD", "HFKFOMEGACLITE", @@ -216,9 +215,6 @@ DECLARE_SOA_TABLE(HfKfOmegacLites, "AOD", "HFKFOMEGACLITE", full::V0Chi2OverNdf, full::CascChi2OverNdf, full::OmegacChi2OverNdf, full::CascRejectInvmass, full::FlagMcMatchRec, full::OriginRec, full::CollisionMatched, hf_track_index::HFflag); - -DECLARE_SOA_TABLE(HfKfOmegacMl, "AOD", "HFKFOMEGACML", - full::InvMassCharmBaryon, full::KfptOmegac, full::KfptPiFromOmegac, full::OutputMlOmegac, full::FlagMcMatchRec, full::OriginRec, full::CollisionMatched, hf_track_index::HFflag); } // namespace o2::aod /// Writes the full information in an output TTree @@ -227,7 +223,6 @@ struct HfTreeCreatorOmegac0ToOmegaPi { Produces rowCandidateLite; Produces rowKfCandidateFull; Produces rowKfCandidateLite; - Produces rowKfCandidateMl; Produces rowEv; Configurable zPvCut{"zPvCut", 10., "Cut on absolute value of primary vertex z coordinate"}; @@ -387,7 +382,6 @@ struct HfTreeCreatorOmegac0ToOmegaPi { candidate.massV0Chi2OverNdf(), candidate.massCascChi2OverNdf(), candidate.cascRejectInvmass(), - candidate.mlValueOmegac(), flagMc, originMc, collisionMatched, @@ -438,23 +432,6 @@ struct HfTreeCreatorOmegac0ToOmegaPi { } } // fillKfCandidateLite end - template - void fillKfCandidateMl(const T& candidate, int8_t flagMc, int8_t originMc, bool collisionMatched) - { - if (candidate.resultSelections() && candidate.statusPidCharmBaryon() && candidate.statusInvMassLambda() && candidate.statusInvMassCascade() && candidate.statusInvMassCharmBaryon()) { - - rowKfCandidateMl( - candidate.invMassCharmBaryon(), - candidate.kfptOmegac(), - candidate.kfptPiFromOmegac(), - candidate.mlValueOmegac(), - flagMc, - originMc, - collisionMatched, - candidate.hfflag()); - } - } // fillCandidateMl end - void processDataLite(Colls const& collisions, Tracks const&, soa::Filtered> const& candidates) { @@ -504,22 +481,6 @@ struct HfTreeCreatorOmegac0ToOmegaPi { } PROCESS_SWITCH(HfTreeCreatorOmegac0ToOmegaPi, processKfDataLite, "Process KF data Lite", false); - void processKfCandidateMl(Colls const& collisions, Tracks const&, CandKfSel const& candidates) - { - // Filling event properties - rowEv.reserve(collisions.size()); - for (const auto& collision : collisions) { - fillEvent(collision, zPvCut); - } - - // Filling candidate properties - rowKfCandidateFull.reserve(candidates.size()); - for (const auto& candidate : candidates) { - fillKfCandidateMl(candidate, -7, RecoDecay::OriginType::None, false); - } - } - PROCESS_SWITCH(HfTreeCreatorOmegac0ToOmegaPi, processKfCandidateMl, "Process KF data ML", true); - void processMcLite(Colls const& collisions, Tracks const&, soa::Filtered> const& candidates) { diff --git a/PWGHF/TableProducer/treeCreatorOmegacSt.cxx b/PWGHF/TableProducer/treeCreatorOmegacSt.cxx index 2203536b195..3d5b201abf7 100644 --- a/PWGHF/TableProducer/treeCreatorOmegacSt.cxx +++ b/PWGHF/TableProducer/treeCreatorOmegacSt.cxx @@ -9,42 +9,47 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file taskOmegacSt.cxx -/// \brief Task to reconstruct Ωc from strangeness-tracked Ω and pion +/// \file treeCreatorOmegacSt.cxx +/// \brief Task to reconstruct Ωc from strangeness-tracked Ω and pion/kaon /// /// \author Jochen Klein +/// \author Tiantian Cheng -#include -#include -#include +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/Utils/utilsTrkCandHf.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" -#include +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "EventFiltering/Zorro.h" +#include "EventFiltering/ZorroSummary.h" #include "CCDB/BasicCCDBManager.h" #include "CommonConstants/PhysicsConstants.h" +#include "DCAFitter/DCAFitterN.h" #include "DataFormatsParameters/GRPMagField.h" #include "DataFormatsParameters/GRPObject.h" -#include "DCAFitter/DCAFitterN.h" #include "DetectorsBase/Propagator.h" -#include "EventFiltering/Zorro.h" -#include "EventFiltering/ZorroSummary.h" +#include "Framework/ASoA.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" -#include "Framework/ASoA.h" #include "Framework/HistogramRegistry.h" #include "Framework/O2DatabasePDGPlugin.h" #include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/DCA.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/PIDResponse.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/CollisionAssociationTables.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGHF/Core/SelectorCuts.h" -#include "PWGHF/Utils/utilsTrkCandHf.h" + +#include + +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -67,6 +72,8 @@ DECLARE_SOA_COLUMN(DecayLengthCharmedBaryon, decayLengthCharmedBaryon, float); DECLARE_SOA_COLUMN(DecayLengthXYCharmedBaryon, decayLengthXYCharmedBaryon, float); DECLARE_SOA_COLUMN(DecayLengthCasc, decayLengthCasc, float); DECLARE_SOA_COLUMN(DecayLengthXYCasc, decayLengthXYCasc, float); +DECLARE_SOA_COLUMN(OriginGen, originGen, int); +DECLARE_SOA_COLUMN(DecayChannel, decayChannel, int); } // namespace hf_st_charmed_baryon_gen DECLARE_SOA_TABLE(HfStChBarGens, "AOD", "HFSTCHBARGEN", @@ -81,9 +88,11 @@ DECLARE_SOA_TABLE(HfStChBarGens, "AOD", "HFSTCHBARGEN", hf_st_charmed_baryon_gen::DecayLengthCharmedBaryon, hf_st_charmed_baryon_gen::DecayLengthXYCharmedBaryon, hf_st_charmed_baryon_gen::DecayLengthCasc, - hf_st_charmed_baryon_gen::DecayLengthXYCasc); + hf_st_charmed_baryon_gen::DecayLengthXYCasc, + hf_st_charmed_baryon_gen::OriginGen, + hf_st_charmed_baryon_gen::DecayChannel); -// CharmedBaryon -> Casc + Pion +// CharmedBaryon -> Casc + Pion/Kaon // -> Lambda + BachPi/BachKa // -> Pr + Pi namespace hf_st_charmed_baryon @@ -93,6 +102,8 @@ DECLARE_SOA_COLUMN(MassXi, massXi, float); DECLARE_SOA_COLUMN(MassLambda, massLambda, float); DECLARE_SOA_COLUMN(NSigmaTpcPion, nSigmaTpcPion, float); DECLARE_SOA_COLUMN(NSigmaTofPion, nSigmaTofPion, float); +DECLARE_SOA_COLUMN(NSigmaTpcKaon, nSigmaTpcKaon, float); +DECLARE_SOA_COLUMN(NSigmaTofKaon, nSigmaTofKaon, float); DECLARE_SOA_COLUMN(NSigmaTpcV0Pr, nSigmaTpcV0Pr, float); DECLARE_SOA_COLUMN(NSigmaTofV0Pr, nSigmaTofV0Pr, float); DECLARE_SOA_COLUMN(NSigmaTpcV0Pi, nSigmaTpcV0Pi, float); @@ -105,11 +116,11 @@ DECLARE_SOA_COLUMN(PxCasc, pxCasc, float); DECLARE_SOA_COLUMN(PyCasc, pyCasc, float); DECLARE_SOA_COLUMN(PzCasc, pzCasc, float); DECLARE_SOA_COLUMN(IsPositiveCasc, isPositiveCasc, bool); -DECLARE_SOA_COLUMN(PxPion, pxPion, float); -DECLARE_SOA_COLUMN(PyPion, pyPion, float); -DECLARE_SOA_COLUMN(PzPion, pzPion, float); -DECLARE_SOA_COLUMN(IsPositivePion, isPositivePion, bool); -DECLARE_SOA_COLUMN(ITSClusterMapPion, itsClusterMapPion, uint8_t); +DECLARE_SOA_COLUMN(PxPionOrKaon, pxPionOrKaon, float); +DECLARE_SOA_COLUMN(PyPionOrKaon, pyPionOrKaon, float); +DECLARE_SOA_COLUMN(PzPionOrKaon, pzPionOrKaon, float); +DECLARE_SOA_COLUMN(IsPositivePionOrKaon, isPositivePionOrKaon, bool); +DECLARE_SOA_COLUMN(ItsClusterMapPionOrKaon, itsClusterMapPionOrKaon, uint8_t); DECLARE_SOA_COLUMN(CpaCharmedBaryon, cpaCharmedBaryon, float); DECLARE_SOA_COLUMN(CpaXYCharmedBaryon, cpaXYCharmedBaryon, float); DECLARE_SOA_COLUMN(CpaCasc, cpaCasc, float); @@ -118,10 +129,10 @@ DECLARE_SOA_COLUMN(DcaXYCasc, dcaXYCasc, float); DECLARE_SOA_COLUMN(DcaXYUncCasc, dcaXYUncCasc, float); DECLARE_SOA_COLUMN(DcaZCasc, dcaZCasc, float); DECLARE_SOA_COLUMN(DcaZUncCasc, dcaZUncCasc, float); -DECLARE_SOA_COLUMN(DcaXYPion, dcaXYPion, float); -DECLARE_SOA_COLUMN(DcaXYUncPion, dcaXYUncPion, float); -DECLARE_SOA_COLUMN(DcaZPion, dcaZPion, float); -DECLARE_SOA_COLUMN(DcaZUncPion, dcaZUncPion, float); +DECLARE_SOA_COLUMN(DcaXYPionOrKaon, dcaXYPionOrKaon, float); +DECLARE_SOA_COLUMN(DcaXYUncPionOrKaon, dcaXYUncPionOrKaon, float); +DECLARE_SOA_COLUMN(DcaZPionOrKaon, dcaZPionOrKaon, float); +DECLARE_SOA_COLUMN(DcaZUncPionOrKaon, dcaZUncPionOrKaon, float); DECLARE_SOA_COLUMN(DcaXYPr, dcaXYPr, float); DECLARE_SOA_COLUMN(DcaZPr, dcaZPr, float); DECLARE_SOA_COLUMN(DcaXYKa, dcaXYKa, float); @@ -137,7 +148,8 @@ DECLARE_SOA_COLUMN(DecayLengthXYCharmedBaryonUntracked, decayLengthXYCharmedBary DECLARE_SOA_COLUMN(DecayLengthCasc, decayLengthCasc, float); DECLARE_SOA_COLUMN(DecayLengthXYCasc, decayLengthXYCasc, float); DECLARE_SOA_INDEX_COLUMN_FULL(MotherCasc, motherCasc, int, HfStChBarGens, "_Casc"); -DECLARE_SOA_INDEX_COLUMN_FULL(MotherPion, motherPion, int, HfStChBarGens, "_Pion"); +DECLARE_SOA_INDEX_COLUMN_FULL(MotherPionOrKaon, motherPionOrKaon, int, HfStChBarGens, "_PionOrKaon"); +DECLARE_SOA_COLUMN(OriginRec, originRec, int); } // namespace hf_st_charmed_baryon DECLARE_SOA_TABLE(HfStChBars, "AOD", "HFSTCHBAR", @@ -146,6 +158,8 @@ DECLARE_SOA_TABLE(HfStChBars, "AOD", "HFSTCHBAR", hf_st_charmed_baryon::MassLambda, hf_st_charmed_baryon::NSigmaTpcPion, hf_st_charmed_baryon::NSigmaTofPion, + hf_st_charmed_baryon::NSigmaTpcKaon, + hf_st_charmed_baryon::NSigmaTofKaon, hf_st_charmed_baryon::NSigmaTpcV0Pr, hf_st_charmed_baryon::NSigmaTofV0Pr, hf_st_charmed_baryon::NSigmaTpcV0Pi, @@ -158,11 +172,11 @@ DECLARE_SOA_TABLE(HfStChBars, "AOD", "HFSTCHBAR", hf_st_charmed_baryon::PyCasc, hf_st_charmed_baryon::PzCasc, hf_st_charmed_baryon::IsPositiveCasc, - hf_st_charmed_baryon::PxPion, - hf_st_charmed_baryon::PyPion, - hf_st_charmed_baryon::PzPion, - hf_st_charmed_baryon::IsPositivePion, - hf_st_charmed_baryon::ITSClusterMapPion, + hf_st_charmed_baryon::PxPionOrKaon, + hf_st_charmed_baryon::PyPionOrKaon, + hf_st_charmed_baryon::PzPionOrKaon, + hf_st_charmed_baryon::IsPositivePionOrKaon, + hf_st_charmed_baryon::ItsClusterMapPionOrKaon, hf_st_charmed_baryon::CpaCharmedBaryon, hf_st_charmed_baryon::CpaXYCharmedBaryon, hf_st_charmed_baryon::CpaCasc, @@ -171,10 +185,10 @@ DECLARE_SOA_TABLE(HfStChBars, "AOD", "HFSTCHBAR", hf_st_charmed_baryon::DcaXYUncCasc, hf_st_charmed_baryon::DcaZCasc, hf_st_charmed_baryon::DcaZUncCasc, - hf_st_charmed_baryon::DcaXYPion, - hf_st_charmed_baryon::DcaXYUncPion, - hf_st_charmed_baryon::DcaZPion, - hf_st_charmed_baryon::DcaZUncPion, + hf_st_charmed_baryon::DcaXYPionOrKaon, + hf_st_charmed_baryon::DcaXYUncPionOrKaon, + hf_st_charmed_baryon::DcaZPionOrKaon, + hf_st_charmed_baryon::DcaZUncPionOrKaon, hf_st_charmed_baryon::DcaXYPr, hf_st_charmed_baryon::DcaZPr, hf_st_charmed_baryon::DcaXYKa, @@ -190,16 +204,14 @@ DECLARE_SOA_TABLE(HfStChBars, "AOD", "HFSTCHBAR", hf_st_charmed_baryon::DecayLengthCasc, hf_st_charmed_baryon::DecayLengthXYCasc, hf_st_charmed_baryon::MotherCascId, - hf_st_charmed_baryon::MotherPionId); + hf_st_charmed_baryon::MotherPionOrKaonId, + hf_st_charmed_baryon::OriginRec); } // namespace o2::aod struct HfTreeCreatorOmegacSt { Produces outputTable; Produces outputTableGen; - Zorro zorro; - OutputObj zorroSummary{"zorroSummary"}; - Configurable materialCorrectionType{"materialCorrectionType", static_cast(o2::base::Propagator::MatCorrType::USEMatCorrLUT), "Type of material correction"}; Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable grpMagPath{"grpMagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; @@ -213,8 +225,8 @@ struct HfTreeCreatorOmegacSt { Configurable minParamChange{"minParamChange", 1.e-3, "stop iterations if largest change of any X is smaller than this"}; Configurable minRelChi2Change{"minRelChi2Change", 0.9, "stop iterations if chi2/chi2old > this"}; Configurable minNoClsTrackedCascade{"minNoClsTrackedCascade", 70, "Minimum number of clusters required for daughters of tracked cascades"}; - Configurable minNoClsTrackedPion{"minNoClsTrackedPion", 70, "Minimum number of clusters required for associated pions"}; - Configurable filterCollisions{"filterCollisions", 8, "0: no filtering; 8: sel8"}; + Configurable minNoClsTrackedPionOrKaon{"minNoClsTrackedPionOrKaon", 70, "Minimum number of clusters required for associated pions/kaons"}; + Configurable useSel8Trigger{"useSel8Trigger", true, "filter collisions on sel 8 trigger"}; Configurable massWindowTrackedOmega{"massWindowTrackedOmega", 0.05, "Inv. mass window for tracked Omega"}; Configurable massWindowXiExclTrackedOmega{"massWindowXiExclTrackedOmega", 0.005, "Inv. mass window for exclusion of Xi for tracked Omega-"}; Configurable massWindowTrackedXi{"massWindowTrackedXi", 0., "Inv. mass window for tracked Xi"}; @@ -227,8 +239,14 @@ struct HfTreeCreatorOmegacSt { Configurable maxNSigmaV0Pr{"maxNSigmaV0Pr", 5., "Max Nsigma for proton from V0 from tracked cascade"}; Configurable maxNSigmaV0Pi{"maxNSigmaV0Pi", 5., "Max Nsigma for pion from V0 from tracked cascade"}; Configurable maxNSigmaPion{"maxNSigmaPion", 5., "Max Nsigma for pion to be paired with Omega"}; + Configurable maxNSigmaKaon{"maxNSigmaKaon", 5., "Max Nsigma for kaon to be paired with Omega"}; Configurable bzOnly{"bzOnly", true, "Use B_z instead of full field map"}; + const int itsNClsMin = 4; + const float tpcNclsFindableFraction = 0.8; + const float tpcChi2NclMax = 4.; + const float itsChi2NclMax = 36.; + SliceCache cache; Service ccdb; o2::vertexing::DCAFitterN<2> df2; @@ -241,14 +259,13 @@ struct HfTreeCreatorOmegacSt { using TracksExt = soa::Join; using TracksExtMc = soa::Join; - Filter collisionFilter = (filterCollisions.node() == 0) || - (filterCollisions.node() == 8 && o2::aod::evsel::sel8 == true); + Filter collisionFilter = (useSel8Trigger.node() == false) || (o2::aod::evsel::sel8 == true); // Preslice perCol = aod::track::collisionId; PresliceUnsorted trackIndicesPerCollision = aod::track_association::collisionId; PresliceUnsorted assignedTrackedCascadesPerCollision = aod::track::collisionId; - std::shared_ptr hCandidatesPrPi, hCandidatesV0Pi, hCandidatesCascPi; + std::shared_ptr hCandidatesPrPi, hCandidatesV0Pi, hCandidatesCascPiOrK; HistogramRegistry registry{ "registry", { @@ -267,14 +284,19 @@ struct HfTreeCreatorOmegacSt { {"hDecayLengthScaledId", "Decay length * M/p (true #Omega_{c});L (#mum / #it{c})", {HistType::kTH1D, {{200, 0., 500.}}}}, {"hDecayLengthScaledGen", "Decay length * M/p (MC id);L (#mum / #it{c})", {HistType::kTH1D, {{200, 0., 500.}}}}, {"hDecayLengthScaledMc", "Decay length * M/p (MC);L (#mum / #it{c})", {HistType::kTH1D, {{200, 0., 500.}}}}, - {"hMassOmegac", "inv. mass #Omega + #pi;inv. mass (GeV/#it{c}^{2})", {HistType::kTH1D, {{400, 1.5, 3.}}}}, - {"hMassOmegacVsPt", "inv. mass #Omega + #pi;inv. mass (GeV/#it{c}^{2});p_{T} (GeV/#it{c})", {HistType::kTH2D, {{400, 1.5, 3.}, {10, 0., 10.}}}}, + {"hMassOmegaPi", "inv. mass #Omega + #pi;inv. mass (GeV/#it{c}^{2})", {HistType::kTH1D, {{400, 1.5, 3.}}}}, + {"hMassOmegaPiVsPt", "inv. mass #Omega + #pi;inv. mass (GeV/#it{c}^{2});p_{T} (GeV/#it{c})", {HistType::kTH2D, {{400, 1.5, 3.}, {10, 0., 10.}}}}, + {"hMassOmegaK", "inv. mass #Omega + K;inv. mass (GeV/#it{c}^{2})", {HistType::kTH1D, {{400, 1.5, 3.}}}}, + {"hMassOmegaKVsPt", "inv. mass #Omega + K;inv. mass (GeV/#it{c}^{2});p_{T} (GeV/#it{c})", {HistType::kTH2D, {{400, 1.5, 3.}, {10, 0., 10.}}}}, {"hMassOmegacId", "inv. mass #Omega + #pi (MC ID);inv. mass (GeV/#it{c}^{2})", {HistType::kTH1D, {{400, 1.5, 3.}}}}, {"hMassOmegacGen", "inv. mass #Omega + #pi (from MC);inv. mass (GeV/#it{c}^{2})", {HistType::kTH1D, {{400, 1.5, 3.}}}}, {"hPtVsMassOmega", "#Omega mass;p_{T} (GeV/#it{c});m (GeV/#it{c}^3)", {HistType::kTH2D, {{200, 0., 10.}, {1000, 1., 3.}}}}, {"hDeltaPtVsPt", "Delta pt;p_{T} (GeV/#it{c});#Delta p_{T} / p_{T}", {HistType::kTH2D, {{200, 0., 10.}, {200, -1., 1.}}}}, }}; + Zorro zorro; + OutputObj zorroSummary{"zorroSummary"}; + void init(InitContext const&) { df2.setPropagateToPCA(propToDCA); @@ -297,15 +319,27 @@ struct HfTreeCreatorOmegacSt { /// candidate monitoring hCandidatesPrPi = registry.add("hCandidatesPrPi", "Pr-Pi candidates counter", {HistType::kTH1D, {axisCands}}); hCandidatesV0Pi = registry.add("hCandidatesV0Pi", "V0-Pi candidates counter", {HistType::kTH1D, {axisCands}}); - hCandidatesCascPi = registry.add("hCandidatesCascPi", "Casc-Pi candidates counter", {HistType::kTH1D, {axisCands}}); + hCandidatesCascPiOrK = registry.add("hCandidatesCascPiOrK", "Casc-Pi/K candidates counter", {HistType::kTH1D, {axisCands}}); setLabelHistoCands(hCandidatesPrPi); setLabelHistoCands(hCandidatesV0Pi); - setLabelHistoCands(hCandidatesCascPi); + setLabelHistoCands(hCandidatesCascPiOrK); } // processMC: loop over MC objects // processData: loop over reconstructed objects, no MC information // processGen: loop over reconstructed objects, use MC information (mutually exclusive? combine?) + int indexRec = -1; + int indexRecCharmBaryon = -1; + int8_t sign = -9; + int8_t signCasc = -9; + int8_t signV0 = -9; + int8_t origin = 0; // to be used for prompt/non prompt + int8_t nPiToMuV0{0}, nPiToMuCasc{0}, nPiToMuOmegac0{0}; + int8_t nKaToPiCasc{0}, nKaToPiOmegac0{0}; + std::vector idxBhadMothers{}; + int decayChannel = -1; // flag for different decay channels + bool isMatched = false; + static constexpr std::size_t NDaughters{2u}; void processMc(aod::McCollisions const&, aod::McParticles const& mcParticles) @@ -316,9 +350,10 @@ struct HfTreeCreatorOmegacSt { const bool isXiC = std::abs(mcParticle.pdgCode()) == constants::physics::Pdg::kXiC0; if (isOmegaC || isXiC) { const auto daughters = mcParticle.daughters_as(); - if (daughters.size() == 2) { + if (daughters.size() == NDaughters) { int idxPionDaughter = -1; int idxCascDaughter = -1; + int idxKaonDaughter = -1; const auto daughters = mcParticle.daughters_as(); for (const auto& daughter : daughters) { if (idxCascDaughter < 0 && (std::abs(daughter.pdgCode()) == (isOmegaC ? kOmegaMinus : kXiMinus))) { @@ -327,8 +362,23 @@ struct HfTreeCreatorOmegacSt { if (idxPionDaughter < 0 && (std::abs(daughter.pdgCode()) == kPiPlus)) { idxPionDaughter = daughter.globalIndex(); } + if (idxKaonDaughter < 0 && (std::abs(daughter.pdgCode()) == kKPlus)) { + idxKaonDaughter = daughter.globalIndex(); + } + } + if (idxPionDaughter >= 0 && idxCascDaughter >= 0) { + decayChannel = o2::aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi; // OmegaC -> Omega + Pi + } else if (idxKaonDaughter >= 0 && idxCascDaughter >= 0) { + decayChannel = o2::aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK; // OmegaC -> Omega + K + } else { + decayChannel = -1; + LOG(warning) << "Decay channel not recognized!"; } - if ((idxPionDaughter >= 0) && (idxCascDaughter >= 0)) { + if (decayChannel != -1) { + int idxDaughter = (decayChannel == o2::aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi) ? idxPionDaughter : idxKaonDaughter; + auto particle = mcParticles.rawIteratorAt(idxDaughter); + origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false, &idxBhadMothers); + const auto& cascDaughter = mcParticles.iteratorAt(idxCascDaughter); const auto& mcColl = mcParticle.mcCollision(); std::array primaryVertexPosGen = {mcColl.posX(), mcColl.posY(), mcColl.posZ()}; @@ -356,7 +406,9 @@ struct HfTreeCreatorOmegacSt { decayLengthGen, decayLengthXYGen, decayLengthCascGen, - decayLengthXYCascGen); + decayLengthXYCascGen, + origin, + decayChannel); mapMcPartToGenTable[mcParticle.globalIndex()] = outputTableGen.lastIndex(); } } @@ -368,7 +420,8 @@ struct HfTreeCreatorOmegacSt { template void fillTable(Collisions const& collisions, aod::AssignedTrackedCascades const& trackedCascades, - aod::TrackAssoc const& trackIndices) + aod::TrackAssoc const& trackIndices, + std::optional> mcParticles = std::nullopt) { const auto matCorr = static_cast(materialCorrectionType.value); @@ -454,8 +507,8 @@ struct HfTreeCreatorOmegacSt { } hCandidatesPrPi->Fill(SVFitting::FitOk); - std::array massesV0Daughters{o2::constants::physics::MassProton, o2::constants::physics::MassPiMinus}; - std::array, 2> momentaV0Daughters; + std::array massesV0Daughters{o2::constants::physics::MassProton, o2::constants::physics::MassPiMinus}; + std::array, NDaughters> momentaV0Daughters; o2::track::TrackPar trackParV0Pr = df2.getTrackParamAtPCA(0); trackParV0Pr.getPxPyPzGlo(momentaV0Daughters[0]); o2::track::TrackPar trackParV0Pi = df2.getTrackParamAtPCA(1); @@ -480,7 +533,7 @@ struct HfTreeCreatorOmegacSt { const auto decayLengthCascXY = RecoDecay::distanceXY(secondaryVertex, primaryVertexPos); o2::track::TrackPar trackParV0 = df2.getTrackParamAtPCA(0); o2::track::TrackPar trackParBachelor = df2.getTrackParamAtPCA(1); - std::array, 2> momentaCascDaughters; + std::array, NDaughters> momentaCascDaughters; trackParV0.getPxPyPzGlo(momentaCascDaughters[0]); trackParBachelor.getPxPyPzGlo(momentaCascDaughters[1]); o2::track::TrackParCov trackParCovCascUntracked = df2.createParentTrackParCov(0); @@ -489,9 +542,9 @@ struct HfTreeCreatorOmegacSt { const auto cpaCasc = RecoDecay::cpa(primaryVertexPos, df2.getPCACandidate(), pCasc); const auto cpaXYCasc = RecoDecay::cpaXY(primaryVertexPos, df2.getPCACandidate(), pCasc); - std::array massesXiDaughters = {o2::constants::physics::MassLambda0, o2::constants::physics::MassPiPlus}; + std::array massesXiDaughters = {o2::constants::physics::MassLambda0, o2::constants::physics::MassPiPlus}; const auto massXi = RecoDecay::m(momentaCascDaughters, massesXiDaughters); - std::array massesOmegaDaughters = {o2::constants::physics::MassLambda0, o2::constants::physics::MassKPlus}; + std::array massesOmegaDaughters = {o2::constants::physics::MassLambda0, o2::constants::physics::MassKPlus}; const auto massOmega = RecoDecay::m(momentaCascDaughters, massesOmegaDaughters); registry.fill(HIST("hDca"), std::sqrt(impactParameterCasc.getR2())); @@ -508,9 +561,11 @@ struct HfTreeCreatorOmegacSt { if (((std::abs(bachelor.tpcNSigmaKa()) < maxNSigmaBachelor) || (std::abs(bachelor.tpcNSigmaPi()) < maxNSigmaBachelor)) && (std::abs(v0TrackPr.tpcNSigmaPr()) < maxNSigmaV0Pr) && (std::abs(v0TrackPi.tpcNSigmaPi()) < maxNSigmaV0Pi)) { - std::array massesOmegacDaughters{o2::constants::physics::MassOmegaMinus, o2::constants::physics::MassPiPlus}; - std::array massesXicDaughters{o2::constants::physics::MassXiMinus, o2::constants::physics::MassPiPlus}; - std::array, 2> momenta; + + std::array massesOmegacToOmegaPi{o2::constants::physics::MassOmegaMinus, o2::constants::physics::MassPiPlus}; + std::array massesOmegacToOmegaK{o2::constants::physics::MassOmegaMinus, o2::constants::physics::MassKPlus}; + std::array massesXicDaughters{o2::constants::physics::MassXiMinus, o2::constants::physics::MassPiPlus}; + std::array, NDaughters> momenta; auto trackParCovPr = getTrackParCov(v0TrackPr); auto trackParCovKa = getTrackParCov(v0TrackPi); @@ -528,21 +583,21 @@ struct HfTreeCreatorOmegacSt { o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovPi, 2.f, matCorr, &impactParameterPi); } - for (auto trackId : groupedTrackIds) { + for (const auto& trackId : groupedTrackIds) { const auto track = trackId.template track_as(); if (track.globalIndex() == v0TrackPr.globalIndex() || track.globalIndex() == v0TrackPi.globalIndex() || track.globalIndex() == bachelor.globalIndex()) { continue; } - if ((track.itsNCls() >= 4) && - (track.tpcNClsFound() >= minNoClsTrackedPion) && - (track.tpcNClsCrossedRows() >= minNoClsTrackedPion) && - (track.tpcNClsCrossedRows() >= 0.8 * track.tpcNClsFindable()) && - (track.tpcChi2NCl() <= 4.f) && - (track.itsChi2NCl() <= 36.f) && - (std::abs(track.tpcNSigmaPi()) < maxNSigmaPion)) { - LOGF(debug, " .. combining with pion candidate %d", track.globalIndex()); + if ((track.itsNCls() >= itsNClsMin) && + (track.tpcNClsFound() >= minNoClsTrackedPionOrKaon) && + (track.tpcNClsCrossedRows() >= minNoClsTrackedPionOrKaon) && + (track.tpcNClsCrossedRows() >= tpcNclsFindableFraction * track.tpcNClsFindable()) && + (track.tpcChi2NCl() <= tpcChi2NclMax) && + (track.itsChi2NCl() <= itsChi2NclMax) && + (std::abs(track.tpcNSigmaPi()) < maxNSigmaPion || std::abs(track.tpcNSigmaKa()) < maxNSigmaKaon)) { + LOGF(debug, " .. combining with pion/kaon candidate %d", track.globalIndex()); int trackMotherId = -1; if constexpr (std::is_same::value) { if (track.has_mcParticle() && track.mcParticle().has_mothers()) { @@ -552,24 +607,24 @@ struct HfTreeCreatorOmegacSt { } } auto trackParCovCasc = getTrackParCov(trackCasc); - auto trackParCovPion = getTrackParCov(track); + auto trackParCovPionOrKaon = getTrackParCov(track); o2::dataformats::DCA impactParameterPion; if (bzOnly) { - o2::base::Propagator::Instance()->propagateToDCA(primaryVertex, trackParCovPion, bz, 2.f, matCorr, &impactParameterPion); + o2::base::Propagator::Instance()->propagateToDCA(primaryVertex, trackParCovPionOrKaon, bz, 2.f, matCorr, &impactParameterPion); } else { - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovPion, 2.f, matCorr, &impactParameterPion); + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVertex, trackParCovPionOrKaon, 2.f, matCorr, &impactParameterPion); } - hCandidatesCascPi->Fill(SVFitting::BeforeFit); + hCandidatesCascPiOrK->Fill(SVFitting::BeforeFit); try { auto decayLengthUntracked = -1.; auto decayLengthXYUntracked = -1.; - if (df2.process(trackParCovCascUntracked, trackParCovPion)) { + if (df2.process(trackParCovCascUntracked, trackParCovPionOrKaon)) { const auto& secondaryVertexUntracked = df2.getPCACandidate(); decayLengthUntracked = RecoDecay::distance(secondaryVertexUntracked, primaryVertexPos); decayLengthXYUntracked = RecoDecay::distanceXY(secondaryVertexUntracked, primaryVertexPos); } - if (df2.process(trackParCovCasc, trackParCovPion)) { + if (df2.process(trackParCovCasc, trackParCovPionOrKaon)) { const auto& secondaryVertex = df2.getPCACandidate(); const auto decayLength = RecoDecay::distance(secondaryVertex, primaryVertexPos); const auto decayLengthXY = RecoDecay::distanceXY(secondaryVertex, primaryVertexPos); @@ -581,12 +636,67 @@ struct HfTreeCreatorOmegacSt { df2.getTrackParamAtPCA(0).getPxPyPzGlo(momenta[0]); df2.getTrackParamAtPCA(1).getPxPyPzGlo(momenta[1]); - const auto massOmegaC = RecoDecay::m(momenta, massesOmegacDaughters); + const auto massOmegaPi = RecoDecay::m(momenta, massesOmegacToOmegaPi); + const auto massOmegaK = RecoDecay::m(momenta, massesOmegacToOmegaK); const auto massXiC = RecoDecay::m(momenta, massesXicDaughters); - registry.fill(HIST("hMassOmegac"), massOmegaC); - registry.fill(HIST("hMassOmegacVsPt"), massOmegaC, RecoDecay::pt(momenta[0], momenta[1])); + registry.fill(HIST("hMassOmegaPi"), massOmegaPi); + registry.fill(HIST("hMassOmegaPiVsPt"), massOmegaPi, RecoDecay::pt(momenta[0], momenta[1])); + registry.fill(HIST("hMassOmegaK"), massOmegaK); + registry.fill(HIST("hMassOmegaKVsPt"), massOmegaK, RecoDecay::pt(momenta[0], momenta[1])); + + //--- do the MC Rec match + if (mcParticles) { + auto arrayDaughters = std::array{ + trackId.template track_as(), // bachelor <- charm baryon + casc.bachelor_as(), // bachelor <- cascade + v0.posTrack_as(), // p <- lambda + v0.negTrack_as()}; // pi <- lambda + + auto arrayDaughtersCasc = std::array{ + casc.bachelor_as(), // bachelor <- cascade + v0.posTrack_as(), // p <- lambda + v0.negTrack_as()}; // pi <- lambda + auto arrayDaughtersV0 = std::array{ + v0.posTrack_as(), // p <- lambda + v0.negTrack_as()}; // pi <- lambda + + if (decayChannel == o2::aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi) { + // Match Omegac0 → Omega- + Pi+ + indexRec = RecoDecay::getMatchedMCRec(mcParticles->get(), arrayDaughters, o2::constants::physics::kOmegaC0, + std::array{+kPiPlus, +kKMinus, +kProton, +kPiMinus}, true, &sign, 3, &nPiToMuOmegac0, &nKaToPiOmegac0); + } else if (decayChannel == o2::aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK) { + // Match Omegac0 → Omega- + K+ + indexRec = RecoDecay::getMatchedMCRec(mcParticles->get(), arrayDaughters, o2::constants::physics::kOmegaC0, + std::array{+kKPlus, +kKMinus, +kProton, +kPiMinus}, true, &sign, 3, &nPiToMuOmegac0, &nKaToPiOmegac0); + } + indexRecCharmBaryon = indexRec; + if (indexRec > -1) { + // Omega- → K pi p (Cascade match) + indexRec = RecoDecay::getMatchedMCRec(mcParticles->get(), arrayDaughtersCasc, +kOmegaMinus, std::array{+kKMinus, +kProton, +kPiMinus}, true, &signCasc, 2, &nPiToMuCasc, &nKaToPiCasc); + if (indexRec > -1) { + // Lambda → p pi (Lambda match) + indexRec = RecoDecay::getMatchedMCRec(mcParticles->get(), arrayDaughtersV0, +kLambda0, std::array{+kProton, +kPiMinus}, true, &signV0, 1, &nPiToMuV0); + if (decayChannel == o2::aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi) { + if (nPiToMuOmegac0 >= 1 && nKaToPiOmegac0 == 0) { + isMatched = true; + } else if (nPiToMuOmegac0 == 0 && nKaToPiOmegac0 == 0) { + isMatched = true; + } + } else if (decayChannel == o2::aod::hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK) { + if (nPiToMuOmegac0 == 0 && nKaToPiOmegac0 == 0) { + isMatched = true; + } + } + } + } + if (isMatched) { + auto particle = mcParticles->get().rawIteratorAt(indexRecCharmBaryon); + origin = RecoDecay::getCharmHadronOrigin(mcParticles->get(), particle, false, &idxBhadMothers); + } + } - if ((std::abs(massOmegaC - o2::constants::physics::MassOmegaC0) < massWindowOmegaC) || + if ((std::abs(massOmegaK - o2::constants::physics::MassOmegaC0) < massWindowOmegaC) || + (std::abs(massOmegaPi - o2::constants::physics::MassOmegaC0) < massWindowOmegaC) || (std::abs(massXiC - o2::constants::physics::MassXiC0) < massWindowXiC)) { registry.fill(HIST("hDecayLength"), decayLength * 1e4); registry.fill(HIST("hDecayLengthScaled"), decayLength * o2::constants::physics::MassOmegaC0 / RecoDecay::p(momenta[0], momenta[1]) * 1e4); @@ -595,6 +705,8 @@ struct HfTreeCreatorOmegacSt { massV0, track.tpcNSigmaPi(), track.tofNSigmaPi(), + track.tpcNSigmaKa(), + track.tofNSigmaKa(), v0TrackPr.tpcNSigmaPr(), v0TrackPr.tofNSigmaPr(), v0TrackPi.tpcNSigmaPi(), @@ -607,7 +719,7 @@ struct HfTreeCreatorOmegacSt { momenta[0][1], momenta[0][2], trackCasc.sign() > 0 ? true : false, - momenta[1][0], // pion momentum + momenta[1][0], // pion/kaon momentum momenta[1][1], momenta[1][2], track.sign() > 0 ? true : false, @@ -639,17 +751,18 @@ struct HfTreeCreatorOmegacSt { decayLengthCasc, decayLengthCascXY, trackCascMotherId, - trackMotherId); + trackMotherId, + origin); } } else { continue; } } catch (const std::runtime_error& error) { - LOG(info) << "Run time error found: " << error.what() << ". DCAFitterN for Casc-Pi cannot work, skipping the candidate."; - hCandidatesCascPi->Fill(SVFitting::Fail); + LOG(info) << "Run time error found: " << error.what() << ". DCAFitterN for Casc-Pi/K cannot work, skipping the candidate."; + hCandidatesCascPiOrK->Fill(SVFitting::Fail); continue; } - hCandidatesCascPi->Fill(SVFitting::FitOk); + hCandidatesCascPiOrK->Fill(SVFitting::FitOk); } } } @@ -678,10 +791,10 @@ struct HfTreeCreatorOmegacSt { aod::V0s const&, // TracksExt const& tracks, // TODO: should be TracksExtMc TracksExtMc const&, - aod::McParticles const&, + aod::McParticles const& mcParticles, aod::BCsWithTimestamps const&) { - fillTable(collisions, trackedCascades, trackIndices); + fillTable(collisions, trackedCascades, trackIndices, mcParticles); } PROCESS_SWITCH(HfTreeCreatorOmegacSt, processMcRec, "Process MC reco", true); @@ -747,8 +860,8 @@ struct HfTreeCreatorOmegacSt { LOG(debug) << "cascade with PDG code: " << pdgCode; if (std::abs(pdgCode) == kOmegaMinus) { LOG(debug) << "found Omega, looking for pions"; - std::array masses{o2::constants::physics::MassOmegaMinus, o2::constants::physics::MassPiPlus}; - std::array, 2> momenta; + std::array masses{o2::constants::physics::MassOmegaMinus, o2::constants::physics::MassPiPlus}; + std::array, NDaughters> momenta; std::array primaryVertexPos = {primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ()}; const auto& mcColl = mother.mcCollision(); std::array primaryVertexPosGen = {mcColl.posX(), mcColl.posY(), mcColl.posZ()}; @@ -773,7 +886,7 @@ struct HfTreeCreatorOmegacSt { registry.fill(HIST("hDeltaPtVsPt"), mcpart.pt(), (trackParCovPion.getPt() - mcpart.pt()) / mcpart.pt()); registry.fill(HIST("hMassOmegacId"), RecoDecay::m(momenta, masses)); - hCandidatesCascPi->Fill(SVFitting::BeforeFit); + hCandidatesCascPiOrK->Fill(SVFitting::BeforeFit); try { if (df2.process(trackParCovCasc, trackParCovPion)) { const auto& secondaryVertex = df2.getPCACandidate(); @@ -794,11 +907,11 @@ struct HfTreeCreatorOmegacSt { } } } - hCandidatesCascPi->Fill(SVFitting::FitOk); + hCandidatesCascPiOrK->Fill(SVFitting::FitOk); } } catch (const std::runtime_error& error) { LOG(info) << "Run time error found: " << error.what() << ". DCAFitterN for Casc-Pi cannot work, skipping the candidate."; - hCandidatesCascPi->Fill(SVFitting::Fail); + hCandidatesCascPiOrK->Fill(SVFitting::Fail); continue; } diff --git a/PWGHF/TableProducer/treeCreatorTccToD0D0Pi.cxx b/PWGHF/TableProducer/treeCreatorTccToD0D0Pi.cxx index da825bcee19..84f32851aeb 100644 --- a/PWGHF/TableProducer/treeCreatorTccToD0D0Pi.cxx +++ b/PWGHF/TableProducer/treeCreatorTccToD0D0Pi.cxx @@ -111,6 +111,8 @@ DECLARE_SOA_COLUMN(CentOfCand, centOfCand, float); // Events DECLARE_SOA_COLUMN(IsEventReject, isEventReject, int); DECLARE_SOA_COLUMN(RunNumber, runNumber, int); +DECLARE_SOA_COLUMN(GIndexCol, gIndexCol, int); //! Global index for the collisionAdd commentMore actions +DECLARE_SOA_COLUMN(TimeStamp, timeStamp, int64_t); //! Timestamp for the collision } // namespace full DECLARE_SOA_TABLE(HfCandTccLites, "AOD", "HFCANDTCCLITE", @@ -135,7 +137,6 @@ DECLARE_SOA_TABLE(HfCandTccLites, "AOD", "HFCANDTCCLITE", full::MD2, full::DeltaMD1, full::DeltaMD2, - full::MDD, full::MDPi1, full::MDPi2, full::MDDPi, @@ -165,7 +166,34 @@ DECLARE_SOA_TABLE(HfCandTccLites, "AOD", "HFCANDTCCLITE", full::NITSClsSoftPi, full::NTPCClsCrossedRowsSoftPi, full::NTPCChi2NClSoftPi, - full::CentOfCand); + full::CentOfCand, + full::GIndexCol, + full::TimeStamp); + +DECLARE_SOA_TABLE(HfCandDDPairs, "AOD", "HFCANDDDPAIR", + full::PxProng0D1, + full::PxProng1D1, + full::PyProng0D1, + full::PyProng1D1, + full::PzProng0D1, + full::PzProng1D1, + full::PxProng0D2, + full::PxProng1D2, + full::PyProng0D2, + full::PyProng1D2, + full::PzProng0D2, + full::PzProng1D2, + full::SelFlagD1, + full::SelFlagD2, + full::EtaD1, + full::EtaD2, + full::PhiD1, + full::PhiD2, + full::MlScoreD1, + full::MlScoreD2, + full::CentOfCand, + full::GIndexCol, + full::TimeStamp); DECLARE_SOA_TABLE(HfCandTccFullEvs, "AOD", "HFCANDTCCFULLEV", full::CollisionId, @@ -180,6 +208,7 @@ DECLARE_SOA_TABLE(HfCandTccFullEvs, "AOD", "HFCANDTCCFULLEV", /// Writes the full information in an output TTree struct HfTreeCreatorTccToD0D0Pi { Produces rowCandidateLite; + Produces rowCandidateDDPair; Produces rowCandidateFullEvents; Configurable ptMinSoftPion{"ptMinSoftPion", 0.0, "Min pt for the soft pion"}; @@ -208,6 +237,7 @@ struct HfTreeCreatorTccToD0D0Pi { Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; o2::vertexing::DCAFitterN<3> dfTcc; // Tcc vertex fitter + o2::vertexing::DCAFitterN<2> dfDD; // DD pair vertex fitter o2::vertexing::DCAFitterN<2> dfD1; // 2-prong vertex fitter (to rebuild D01 vertex) o2::vertexing::DCAFitterN<2> dfD2; // 2-prong vertex fitter (to rebuild D02 vertex) @@ -232,7 +262,7 @@ struct HfTreeCreatorTccToD0D0Pi { Preslice candsD0PerCollisionWithMl = aod::track_association::collisionId; Preslice trackIndicesPerCollision = aod::track_association::collisionId; // Partition candidatesMlAll = aod::hf_sel_candidate_d0::isSelD0 >= 0; - std::shared_ptr hCandidatesD1, hCandidatesD2, hCandidatesTcc; + std::shared_ptr hCandidatesD1, hCandidatesD2, hCandidatesTcc, hCandidatesDD; HistogramRegistry registry{"registry"}; OutputObj hCovPVXX{TH1F("hCovPVXX", "Tcc candidates;XX element of cov. matrix of prim. vtx. position (cm^{2});entries", 100, 0., 1.e-4)}; OutputObj hCovSVXX{TH1F("hCovSVXX", "Tcc candidates;XX element of cov. matrix of sec. vtx. position (cm^{2});entries", 100, 0., 0.2)}; @@ -260,6 +290,14 @@ struct HfTreeCreatorTccToD0D0Pi { dfD2.setUseAbsDCA(useAbsDCA); dfD2.setWeightedFinalPCA(useWeightedFinalPCA); + dfDD.setPropagateToPCA(propagateToPCA); + dfDD.setMaxR(maxR); + dfDD.setMaxDZIni(maxDZIni); + dfDD.setMinParamChange(minParamChange); + dfDD.setMinRelChi2Change(minRelChi2Change); + dfDD.setUseAbsDCA(useAbsDCA); + dfDD.setWeightedFinalPCA(useWeightedFinalPCA); + dfTcc.setPropagateToPCA(propagateToPCA); dfTcc.setMaxR(maxR); dfTcc.setMaxDZIni(maxDZIni); @@ -277,9 +315,12 @@ struct HfTreeCreatorTccToD0D0Pi { hCandidatesD1 = registry.add("hCandidatesD1", "D1 candidate counter", {HistType::kTH1D, {axisCands}}); hCandidatesD2 = registry.add("hCandidatesD2", "D2 candidate counter", {HistType::kTH1D, {axisCands}}); hCandidatesTcc = registry.add("hCandidatesTcc", "Tcc candidate counter", {HistType::kTH1D, {axisCands}}); + hCandidatesDD = registry.add("hCandidatesDD", "DD pair candidate counter", {HistType::kTH1D, {axisCands}}); + setLabelHistoCands(hCandidatesD1); setLabelHistoCands(hCandidatesD2); setLabelHistoCands(hCandidatesTcc); + setLabelHistoCands(hCandidatesDD); } } @@ -316,7 +357,7 @@ struct HfTreeCreatorTccToD0D0Pi { auto primaryVertex = getPrimaryVertex(collision); auto bc = collision.template bc_as(); fillEvent(collision, 0, bc.runNumber()); - + int64_t timeStamp = bc.timestamp(); if (buildVertex) { if (runNumber != bc.runNumber()) { LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; @@ -325,9 +366,13 @@ struct HfTreeCreatorTccToD0D0Pi { LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; } dfTcc.setBz(bz); + dfDD.setBz(bz); dfD1.setBz(bz); dfD2.setBz(bz); } + + o2::dataformats::V0 trackD1; + o2::dataformats::V0 trackD2; auto thisCollId = collision.globalIndex(); auto candwD0ThisColl = candidates.sliceBy(candsD0PerCollisionWithMl, thisCollId); if (candwD0ThisColl.size() <= 1) @@ -335,7 +380,165 @@ struct HfTreeCreatorTccToD0D0Pi { auto trackIdsThisCollision = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); for (const auto& candidateD1 : candwD0ThisColl) { + + auto trackD1Prong0 = tracks.rawIteratorAt(candidateD1.prong0Id()); // positive daughter for D1 + auto trackD1Prong1 = tracks.rawIteratorAt(candidateD1.prong1Id()); // negative daughter for D1 + std::array pVecD1Prong0{trackD1Prong0.pVector()}; + std::array pVecD1Prong1{trackD1Prong1.pVector()}; + std::array pVecD1 = RecoDecay::pVec(pVecD1Prong0, pVecD1Prong1); + for (auto candidateD2 = candidateD1 + 1; candidateD2 != candwD0ThisColl.end(); ++candidateD2) { + // avoid shared tracks + if ( + (candidateD1.prong0Id() == candidateD2.prong0Id()) || + (candidateD1.prong0Id() == candidateD2.prong1Id()) || + (candidateD1.prong1Id() == candidateD2.prong0Id()) || + (candidateD1.prong1Id() == candidateD2.prong1Id())) { + continue; + } + + auto trackD2Prong0 = tracks.rawIteratorAt(candidateD2.prong0Id()); // positive daughter for D2 + auto trackD2Prong1 = tracks.rawIteratorAt(candidateD2.prong1Id()); // negative daughter for D2 + std::array pVecD2Prong0{trackD2Prong0.pVector()}; + std::array pVecD2Prong1{trackD2Prong1.pVector()}; + std::array pVecD2 = RecoDecay::pVec(pVecD2Prong0, pVecD2Prong1); + + if (buildVertex) { + auto trackParVarD1Prong0 = getTrackParCov(trackD1Prong0); + auto trackParVarD1Prong1 = getTrackParCov(trackD1Prong1); + auto dca0D1 = o2::dataformats::DCA(trackD1Prong0.dcaXY(), trackD1Prong0.dcaZ(), trackD1Prong0.cYY(), trackD1Prong0.cZY(), trackD1Prong0.cZZ()); + auto dca1D1 = o2::dataformats::DCA(trackD1Prong1.dcaXY(), trackD1Prong1.dcaZ(), trackD1Prong1.cYY(), trackD1Prong1.cZY(), trackD1Prong1.cZZ()); + + // repropagate tracks to this collision if needed + if (trackD1Prong0.collisionId() != thisCollId) { + trackParVarD1Prong0.propagateToDCA(primaryVertex, bz, &dca0D1); + } + + if (trackD1Prong1.collisionId() != thisCollId) { + trackParVarD1Prong1.propagateToDCA(primaryVertex, bz, &dca1D1); + } + // reconstruct the 2-prong secondary vertex + hCandidatesD1->Fill(SVFitting::BeforeFit); + try { + if (dfD1.process(trackParVarD1Prong0, trackParVarD1Prong1) == 0) { + continue; + } + } catch (const std::runtime_error& error) { + LOG(info) << "Run time error found: " << error.what() << ". DCAFitterN for first D0 cannot work, skipping the candidate."; + hCandidatesD1->Fill(SVFitting::Fail); + continue; + } + hCandidatesD1->Fill(SVFitting::FitOk); + const auto& vertexD1 = dfD1.getPCACandidatePos(); + trackParVarD1Prong0.propagateTo(vertexD1[0], bz); + trackParVarD1Prong1.propagateTo(vertexD1[0], bz); + + // build a D1 neutral track + trackD1 = o2::dataformats::V0(vertexD1, pVecD1, dfD1.calcPCACovMatrixFlat(), trackParVarD1Prong0, trackParVarD1Prong1); + + auto trackParVarD2Prong0 = getTrackParCov(trackD2Prong0); + auto trackParVarD2Prong1 = getTrackParCov(trackD2Prong1); + auto dca0D2 = o2::dataformats::DCA(trackD2Prong0.dcaXY(), trackD2Prong0.dcaZ(), trackD2Prong0.cYY(), trackD2Prong0.cZY(), trackD2Prong0.cZZ()); + auto dca1D2 = o2::dataformats::DCA(trackD2Prong1.dcaXY(), trackD2Prong1.dcaZ(), trackD2Prong1.cYY(), trackD2Prong1.cZY(), trackD2Prong1.cZZ()); + + // repropagate tracks to this collision if needed + if (trackD2Prong0.collisionId() != thisCollId) { + trackParVarD2Prong0.propagateToDCA(primaryVertex, bz, &dca0D2); + } + if (trackD2Prong1.collisionId() != thisCollId) { + trackParVarD2Prong1.propagateToDCA(primaryVertex, bz, &dca1D2); + } + + // reconstruct the 2-prong secondary vertex + hCandidatesD2->Fill(SVFitting::BeforeFit); + try { + if (dfD2.process(trackParVarD2Prong0, trackParVarD2Prong1) == 0) { + continue; + } + } catch (const std::runtime_error& error) { + LOG(info) << "Run time error found: " << error.what() << ". DCAFitterN for second D0 cannot work, skipping the candidate."; + hCandidatesD2->Fill(SVFitting::Fail); + continue; + } + + hCandidatesD2->Fill(SVFitting::FitOk); + const auto& vertexD2 = dfD2.getPCACandidatePos(); + trackParVarD2Prong0.propagateTo(vertexD2[0], bz); + trackParVarD2Prong1.propagateTo(vertexD2[0], bz); + // build a D2 neutral track + trackD2 = o2::dataformats::V0(vertexD2, pVecD2, dfD2.calcPCACovMatrixFlat(), trackParVarD2Prong0, trackParVarD2Prong1); + + hCandidatesDD->Fill(SVFitting::BeforeFit); + try { + if (dfDD.process(trackD1, trackD2) == 0) { + continue; + } + } catch (const std::runtime_error& error) { + LOG(info) << "Run time error found: " << error.what() << ". DCAFitterN for DD cannot work, skipping the candidate."; + hCandidatesDD->Fill(SVFitting::Fail); + continue; + } + hCandidatesDD->Fill(SVFitting::FitOk); + } + + int candFlagD1 = -999; + int candFlagD2 = -999; + float cent = evaluateCentralityColl(collision); + float massD01 = -999; + float massD02 = -999; + std::vector mlScoresD1; + std::vector mlScoresD2; + + if (candidateD1.isSelD0()) { + candFlagD1 = (candidateD1.isSelD0bar()) ? 3 : 1; + std::copy(candidateD1.mlProbD0().begin(), candidateD1.mlProbD0().end(), std::back_inserter(mlScoresD1)); + massD01 = hfHelper.invMassD0ToPiK(candidateD1); + } + if (candidateD1.isSelD0bar() && !candidateD1.isSelD0()) { + candFlagD1 = 2; + std::copy(candidateD1.mlProbD0bar().begin(), candidateD1.mlProbD0bar().end(), std::back_inserter(mlScoresD1)); + massD01 = hfHelper.invMassD0barToKPi(candidateD1); + } + + if (candidateD2.isSelD0()) { + candFlagD2 = (candidateD2.isSelD0bar()) ? 3 : 1; + std::copy(candidateD2.mlProbD0().begin(), candidateD2.mlProbD0().end(), std::back_inserter(mlScoresD2)); + massD02 = hfHelper.invMassD0ToPiK(candidateD2); + } + if (candidateD2.isSelD0bar() && !candidateD2.isSelD0()) { + candFlagD2 = 2; + std::copy(candidateD2.mlProbD0bar().begin(), candidateD2.mlProbD0bar().end(), std::back_inserter(mlScoresD2)); + massD02 = hfHelper.invMassD0barToKPi(candidateD2); + } + + // const auto massD0D0Pair = RecoDecay::m(std::array{pVecD1, pVecD2}, std::array{MassD0, MassD0}); + + rowCandidateDDPair( + candidateD1.pxProng0(), + candidateD1.pxProng1(), + candidateD1.pyProng0(), + candidateD1.pyProng1(), + candidateD1.pzProng0(), + candidateD1.pzProng1(), + candidateD2.pxProng0(), + candidateD2.pxProng1(), + candidateD2.pyProng0(), + candidateD2.pyProng1(), + candidateD2.pzProng0(), + candidateD2.pzProng1(), + candFlagD1, + candFlagD2, + candidateD1.eta(), + candidateD2.eta(), + candidateD1.phi(), + candidateD2.phi(), + mlScoresD1[0], + mlScoresD2[0], + cent, + collision.globalIndex(), + timeStamp); + + // start to add the track of softpi to reconstruct Tcc for (const auto& trackId : trackIdsThisCollision) { auto trackPion = trackId.template track_as(); @@ -351,10 +554,6 @@ struct HfTreeCreatorTccToD0D0Pi { } // avoid shared tracks if ( - (candidateD1.prong0Id() == candidateD2.prong0Id()) || - (candidateD1.prong0Id() == candidateD2.prong1Id()) || - (candidateD1.prong1Id() == candidateD2.prong0Id()) || - (candidateD1.prong1Id() == candidateD2.prong1Id()) || (candidateD1.prong0Id() == trackPion.globalIndex()) || (candidateD1.prong1Id() == trackPion.globalIndex()) || (candidateD2.prong0Id() == trackPion.globalIndex()) || @@ -362,91 +561,14 @@ struct HfTreeCreatorTccToD0D0Pi { continue; } - auto trackD1Prong0 = tracks.rawIteratorAt(candidateD1.prong0Id()); // positive daughter for D1 - auto trackD1Prong1 = tracks.rawIteratorAt(candidateD1.prong1Id()); // negative daughter for D1 - auto trackD2Prong0 = tracks.rawIteratorAt(candidateD2.prong0Id()); // positive daughter for D2 - auto trackD2Prong1 = tracks.rawIteratorAt(candidateD2.prong1Id()); // negative daughter for D2 - - std::array pVecD1Prong0{trackD1Prong0.pVector()}; - std::array pVecD1Prong1{trackD1Prong1.pVector()}; - std::array pVecD2Prong0{trackD2Prong0.pVector()}; - std::array pVecD2Prong1{trackD2Prong1.pVector()}; std::array pVecSoftPi = {trackPion.pVector()}; - // Get D momentum - std::array pVecD1 = RecoDecay::pVec(pVecD1Prong0, pVecD1Prong1); - std::array pVecD2 = RecoDecay::pVec(pVecD2Prong0, pVecD2Prong1); float impactParameterYD1 = -999.f; float impactParameterYD2 = -999.f; float impactParameterYSoftPi = -999.f; float chi2PCA = -999.f; if (buildVertex) { - auto trackParVarD1Prong0 = getTrackParCov(trackD1Prong0); - auto trackParVarD1Prong1 = getTrackParCov(trackD1Prong1); - auto dca0D1 = o2::dataformats::DCA(trackD1Prong0.dcaXY(), trackD1Prong0.dcaZ(), trackD1Prong0.cYY(), trackD1Prong0.cZY(), trackD1Prong0.cZZ()); - auto dca1D1 = o2::dataformats::DCA(trackD1Prong1.dcaXY(), trackD1Prong1.dcaZ(), trackD1Prong1.cYY(), trackD1Prong1.cZY(), trackD1Prong1.cZZ()); - - // repropagate tracks to this collision if needed - if (trackD1Prong0.collisionId() != thisCollId) { - trackParVarD1Prong0.propagateToDCA(primaryVertex, bz, &dca0D1); - } - - if (trackD1Prong1.collisionId() != thisCollId) { - trackParVarD1Prong1.propagateToDCA(primaryVertex, bz, &dca1D1); - } - // reconstruct the 2-prong secondary vertex - hCandidatesD1->Fill(SVFitting::BeforeFit); - try { - if (dfD1.process(trackParVarD1Prong0, trackParVarD1Prong1) == 0) { - continue; - } - } catch (const std::runtime_error& error) { - LOG(info) << "Run time error found: " << error.what() << ". DCAFitterN for first D0 cannot work, skipping the candidate."; - hCandidatesD1->Fill(SVFitting::Fail); - continue; - } - hCandidatesD1->Fill(SVFitting::FitOk); - const auto& vertexD1 = dfD1.getPCACandidatePos(); - trackParVarD1Prong0.propagateTo(vertexD1[0], bz); - trackParVarD1Prong1.propagateTo(vertexD1[0], bz); - - // build a D1 neutral track - auto trackD1 = o2::dataformats::V0(vertexD1, pVecD1, dfD1.calcPCACovMatrixFlat(), trackParVarD1Prong0, trackParVarD1Prong1); - - auto trackParVarD2Prong0 = getTrackParCov(trackD2Prong0); - auto trackParVarD2Prong1 = getTrackParCov(trackD2Prong1); - auto dca0D2 = o2::dataformats::DCA(trackD2Prong0.dcaXY(), trackD2Prong0.dcaZ(), trackD2Prong0.cYY(), trackD2Prong0.cZY(), trackD2Prong0.cZZ()); - auto dca1D2 = o2::dataformats::DCA(trackD2Prong1.dcaXY(), trackD2Prong1.dcaZ(), trackD2Prong1.cYY(), trackD2Prong1.cZY(), trackD2Prong1.cZZ()); - - // repropagate tracks to this collision if needed - if (trackD2Prong0.collisionId() != thisCollId) { - trackParVarD2Prong0.propagateToDCA(primaryVertex, bz, &dca0D2); - } - if (trackD2Prong1.collisionId() != thisCollId) { - trackParVarD2Prong1.propagateToDCA(primaryVertex, bz, &dca1D2); - } - - // reconstruct the 2-prong secondary vertex - hCandidatesD2->Fill(SVFitting::BeforeFit); - try { - if (dfD2.process(trackParVarD2Prong0, trackParVarD2Prong1) == 0) { - continue; - } - } catch (const std::runtime_error& error) { - LOG(info) << "Run time error found: " << error.what() << ". DCAFitterN for second D0 cannot work, skipping the candidate."; - hCandidatesD2->Fill(SVFitting::Fail); - continue; - } - - hCandidatesD2->Fill(SVFitting::FitOk); - const auto& vertexD2 = dfD2.getPCACandidatePos(); - trackParVarD2Prong0.propagateTo(vertexD2[0], bz); - trackParVarD2Prong1.propagateTo(vertexD2[0], bz); - // build a D2 neutral track - auto trackD2 = o2::dataformats::V0(vertexD2, pVecD2, dfD2.calcPCACovMatrixFlat(), trackParVarD2Prong0, trackParVarD2Prong1); - auto trackParCovPi = getTrackParCov(trackPion); - // find the DCA between the D01, D02 and the bachelor track, for Tcc hCandidatesTcc->Fill(SVFitting::BeforeFit); try { @@ -488,38 +610,8 @@ struct HfTreeCreatorTccToD0D0Pi { // Retrieve properties of the two D0 candidates float yD1 = hfHelper.yD0(candidateD1); float yD2 = hfHelper.yD0(candidateD2); - float massD01 = -999; - float massD02 = -999; float deltaMassD01 = -999; float deltaMassD02 = -999; - int candFlagD1 = -999; - int candFlagD2 = -999; - float cent = evaluateCentralityColl(collision); - - std::vector mlScoresD1; - std::vector mlScoresD2; - - if (candidateD1.isSelD0()) { - candFlagD1 = (candidateD1.isSelD0bar()) ? 3 : 1; - std::copy(candidateD1.mlProbD0().begin(), candidateD1.mlProbD0().end(), std::back_inserter(mlScoresD1)); - massD01 = hfHelper.invMassD0ToPiK(candidateD1); - } - if (candidateD1.isSelD0bar() && !candidateD1.isSelD0()) { - candFlagD1 = 2; - std::copy(candidateD1.mlProbD0bar().begin(), candidateD1.mlProbD0bar().end(), std::back_inserter(mlScoresD1)); - massD01 = hfHelper.invMassD0barToKPi(candidateD1); - } - - if (candidateD2.isSelD0()) { - candFlagD2 = (candidateD2.isSelD0bar()) ? 3 : 1; - std::copy(candidateD2.mlProbD0().begin(), candidateD2.mlProbD0().end(), std::back_inserter(mlScoresD2)); - massD02 = hfHelper.invMassD0ToPiK(candidateD2); - } - if (candidateD2.isSelD0bar() && !candidateD2.isSelD0()) { - candFlagD2 = 2; - std::copy(candidateD2.mlProbD0bar().begin(), candidateD2.mlProbD0bar().end(), std::back_inserter(mlScoresD2)); - massD02 = hfHelper.invMassD0barToKPi(candidateD2); - } std::array massD1Daus{MassPiPlus, MassKPlus}; std::array massD2Daus{MassPiPlus, MassKPlus}; @@ -539,7 +631,6 @@ struct HfTreeCreatorTccToD0D0Pi { auto arrayMomentaDDpi = std::array{pVecD1, pVecD2, pVecSoftPi}; const auto massD0D0Pi = RecoDecay::m(std::move(arrayMomentaDDpi), std::array{MassD0, MassD0, MassPiPlus}); const auto deltaMassD0D0Pi = massD0D0Pi - (massD01 + massD02); - const auto massD0D0Pair = RecoDecay::m(std::array{pVecD1, pVecD2}, std::array{MassD0, MassD0}); deltaMassD01 = massKpipi1 - massD01; deltaMassD02 = massKpipi2 - massD02; @@ -570,7 +661,6 @@ struct HfTreeCreatorTccToD0D0Pi { massD02, deltaMassD01, deltaMassD02, - massD0D0Pair, massKpipi1, massKpipi2, massD0D0Pi, @@ -600,7 +690,9 @@ struct HfTreeCreatorTccToD0D0Pi { trackPion.itsNCls(), trackPion.tpcNClsCrossedRows(), trackPion.tpcChi2NCl(), - cent); + cent, + collision.globalIndex(), + timeStamp); } // end of loop track } // end of loop second D0 } // end of loop first D0 diff --git a/PWGHF/TableProducer/treeCreatorXic0ToXiPiKf.cxx b/PWGHF/TableProducer/treeCreatorXic0ToXiPiKf.cxx index e763724e501..d038ff9df5b 100644 --- a/PWGHF/TableProducer/treeCreatorXic0ToXiPiKf.cxx +++ b/PWGHF/TableProducer/treeCreatorXic0ToXiPiKf.cxx @@ -14,14 +14,17 @@ /// In this file are defined and filled the output tables /// /// \author Ran Tu , Fudan University +/// \author Tao Fang , Central China Normal University -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" #include "Common/Core/RecoDecay.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" using namespace o2; using namespace o2::framework; @@ -30,6 +33,7 @@ namespace o2::aod { namespace full { +DECLARE_SOA_COLUMN(Centrality, centrality, float); DECLARE_SOA_COLUMN(InvMassLambda, invMassLambda, float); DECLARE_SOA_COLUMN(InvMassCascade, invMassCascade, float); DECLARE_SOA_COLUMN(InvMassCharmBaryon, invMassCharmBaryon, float); @@ -97,6 +101,7 @@ DECLARE_SOA_COLUMN(MassCascChi2OverNdf, massCascChi2OverNdf, float); } // namespace full DECLARE_SOA_TABLE(HfKfXicFulls, "AOD", "HFKFXICFULL", + full::Centrality, full::TpcNSigmaPiFromCharmBaryon, full::TofNSigmaPiFromCharmBaryon, full::TpcNSigmaPiFromCasc, full::TofNSigmaPiFromCasc, full::TpcNSigmaPiFromLambda, full::TofNSigmaPiFromLambda, full::TpcNSigmaPrFromLambda, full::TofNSigmaPrFromLambda, full::KfDcaXYPiFromXic, full::DcaCascDau, full::DcaCharmBaryonDau, full::KfDcaXYCascToPv, @@ -127,18 +132,29 @@ struct HfTreeCreatorXic0ToXiPiKf { Configurable zPvCut{"zPvCut", 10., "Cut on absolute value of primary vertex z coordinate"}; using MyTrackTable = soa::Join; + using MyEventTable = soa::Join; + using MyEventTableWithFT0C = soa::Join; + using MyEventTableWithFT0M = soa::Join; + using MyEventTableWithNTracksPV = soa::Join; void init(InitContext const&) { } - template + template void fillKfCandidate(const T& candidate, int8_t flagMc, int8_t debugMc, int8_t originMc, bool collisionMatched) { if (candidate.resultSelections() && candidate.statusPidCharmBaryon() && candidate.statusInvMassLambda() && candidate.statusInvMassCascade() && candidate.statusInvMassCharmBaryon()) { + float centrality = -999.f; + if constexpr (useCentrality) { + auto const& collision = candidate.template collision_as(); + centrality = o2::hf_centrality::getCentralityColl(collision); + } + rowKfCandidate( + centrality, candidate.tpcNSigmaPiFromCharmBaryon(), candidate.tofNSigmaPiFromCharmBaryon(), candidate.tpcNSigmaPiFromCasc(), @@ -202,26 +218,85 @@ struct HfTreeCreatorXic0ToXiPiKf { } } - void processKfData(MyTrackTable const&, + void processKfData(MyTrackTable const&, MyEventTable const&, soa::Join const& candidates) { rowKfCandidate.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillKfCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); + fillKfCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); } } PROCESS_SWITCH(HfTreeCreatorXic0ToXiPiKf, processKfData, "Process KF data", false); + void processKfDataWithFT0C(MyTrackTable const&, MyEventTableWithFT0C const&, + soa::Join const& candidates) + { + rowKfCandidate.reserve(candidates.size()); + for (const auto& candidate : candidates) { + fillKfCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); + } + } + PROCESS_SWITCH(HfTreeCreatorXic0ToXiPiKf, processKfDataWithFT0C, "Process KF data with FT0C", false); + + void processKfDataWithFT0M(MyTrackTable const&, MyEventTableWithFT0M const&, + soa::Join const& candidates) + { + rowKfCandidate.reserve(candidates.size()); + for (const auto& candidate : candidates) { + fillKfCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); + } + } + PROCESS_SWITCH(HfTreeCreatorXic0ToXiPiKf, processKfDataWithFT0M, "Process KF data with FT0M", false); + + void processDataLiteWithNTracksPV(MyTrackTable const&, + soa::Join const& candidates) + { + rowKfCandidate.reserve(candidates.size()); + for (const auto& candidate : candidates) { + fillKfCandidate(candidate, -7, -7, RecoDecay::OriginType::None, false); + } + } + PROCESS_SWITCH(HfTreeCreatorXic0ToXiPiKf, processDataLiteWithNTracksPV, "Process KF data with Ntracks", false); + void processKfMcXic0(MyTrackTable const&, soa::Join const& candidates) { rowKfCandidate.reserve(candidates.size()); for (const auto& candidate : candidates) { - fillKfCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originRec(), candidate.collisionMatched()); + fillKfCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originRec(), candidate.collisionMatched()); } } PROCESS_SWITCH(HfTreeCreatorXic0ToXiPiKf, processKfMcXic0, "Process MC with information for xic0", false); + void processKfMCWithFT0C(MyTrackTable const&, + soa::Join const& candidates) + { + rowKfCandidate.reserve(candidates.size()); + for (const auto& candidate : candidates) { + fillKfCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originRec(), candidate.collisionMatched()); + } + } + PROCESS_SWITCH(HfTreeCreatorXic0ToXiPiKf, processKfMCWithFT0C, "Process MC with information for xic0 at FT0C", false); + + void processKfMCWithFT0M(MyTrackTable const&, + soa::Join const& candidates) + { + rowKfCandidate.reserve(candidates.size()); + for (const auto& candidate : candidates) { + fillKfCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originRec(), candidate.collisionMatched()); + } + } + PROCESS_SWITCH(HfTreeCreatorXic0ToXiPiKf, processKfMCWithFT0M, "Process MC with information for xic0 at FT0M", false); + + void processMCLiteWithNTracksPV(MyTrackTable const&, + soa::Join const& candidates) + { + rowKfCandidate.reserve(candidates.size()); + for (const auto& candidate : candidates) { + fillKfCandidate(candidate, candidate.flagMcMatchRec(), candidate.debugMcRec(), candidate.originRec(), candidate.collisionMatched()); + } + } + PROCESS_SWITCH(HfTreeCreatorXic0ToXiPiKf, processMCLiteWithNTracksPV, "Process MC with information for xic0 at Ntrack", false); }; // end of struct WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx b/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx index 279dbc797fc..b038f28c80e 100644 --- a/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx @@ -231,13 +231,13 @@ struct HfTreeCreatorXicToPKPi { using CandXicMcGen = soa::Filtered>; Filter filterSelectCandidates = aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlagXic || aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlagXic; - Filter filterMcGenMatching = nabs(o2::aod::hf_cand_3prong::flagMcMatchGen) == static_cast(BIT(aod::hf_cand_3prong::DecayType::XicToPKPi)); + Filter filterMcGenMatching = nabs(o2::aod::hf_cand_3prong::flagMcMatchGen) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::XicToPKPi); Partition selectedXicToPKPiCand = aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlagXic; Partition selectedXicToPiKPCand = aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlagXic; - Partition reconstructedCandSig = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_3prong::DecayType::XicToPKPi)); - Partition reconstructedCandBkg = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(BIT(aod::hf_cand_3prong::DecayType::XicToPKPi)); + Partition reconstructedCandSig = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::XicToPKPi); + Partition reconstructedCandBkg = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::XicToPKPi); void init(InitContext const&) { diff --git a/PWGHF/Tasks/CMakeLists.txt b/PWGHF/Tasks/CMakeLists.txt index 658988d070a..b212b705b23 100644 --- a/PWGHF/Tasks/CMakeLists.txt +++ b/PWGHF/Tasks/CMakeLists.txt @@ -46,7 +46,7 @@ o2physics_add_dpl_workflow(task-multiplicity-estimator-correlation o2physics_add_dpl_workflow(task-pid-studies SOURCES taskPidStudies.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::EventFilteringUtils + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::EventFilteringUtils O2Physics::AnalysisCCDB COMPONENT_NAME Analysis) # o2physics_add_dpl_workflow(task-sel-optimisation diff --git a/PWGHF/Tasks/taskCharmHadImpactPar.cxx b/PWGHF/Tasks/taskCharmHadImpactPar.cxx index 051fdd0b7a2..9671501387f 100644 --- a/PWGHF/Tasks/taskCharmHadImpactPar.cxx +++ b/PWGHF/Tasks/taskCharmHadImpactPar.cxx @@ -162,7 +162,7 @@ struct HfTaskCharmHadImpactPar { if constexpr (channel == Channel::DplusToKPiPi) { // D+ -> Kpipi if constexpr (doMc) { if (fillOnlySignal) { - if (std::abs(candidate.flagMcMatchRec()) != 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi) { + if (std::abs(candidate.flagMcMatchRec()) != o2::hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) { return; } } diff --git a/PWGHF/Tasks/taskLcCentrality.cxx b/PWGHF/Tasks/taskLcCentrality.cxx index 091b70b66ec..2455c147685 100644 --- a/PWGHF/Tasks/taskLcCentrality.cxx +++ b/PWGHF/Tasks/taskLcCentrality.cxx @@ -16,17 +16,18 @@ /// \author Luigi Dello Stritto , University and INFN SALERNO /// \author Vít Kučera , CERN -#include +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" + +#include "Common/DataModel/Centrality.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" -#include "Common/DataModel/Centrality.h" - -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include using namespace o2; using namespace o2::analysis; @@ -162,7 +163,7 @@ struct HfTaskLcCentralityMc { if (yCandMax >= 0. && std::abs(hfHelper.yLc(candidate)) > yCandMax) { continue; } - if (std::abs(candidate.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::LcToPKPi) { + if (std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { // Get the corresponding MC particle. auto indexMother = RecoDecay::getMother(mcParticles, candidate.prong0_as().mcParticle_as>(), o2::constants::physics::Pdg::kLambdaCPlus, true); auto particleMother = mcParticles.rawIteratorAt(indexMother); @@ -184,7 +185,7 @@ struct HfTaskLcCentralityMc { } // MC gen. for (const auto& particle : mcParticles) { - if (std::abs(particle.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::LcToPKPi) { + if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { if (yCandMax >= 0. && std::abs(RecoDecay::y(particle.pVector(), o2::constants::physics::MassLambdaCPlus)) > yCandMax) { continue; } diff --git a/PWGHF/Tasks/taskMcEfficiencyToXiPi.cxx b/PWGHF/Tasks/taskMcEfficiencyToXiPi.cxx index 1d1f6a1af22..72091aa99d9 100644 --- a/PWGHF/Tasks/taskMcEfficiencyToXiPi.cxx +++ b/PWGHF/Tasks/taskMcEfficiencyToXiPi.cxx @@ -14,20 +14,21 @@ /// /// \author Federica Zanone, Heidelberg University -#include +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "TMCProcess.h" // for VMC Particle Production Process +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/TrackSelectionTables.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "Common/Core/RecoDecay.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "TMCProcess.h" // for VMC Particle Production Process -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include using namespace o2; using namespace o2::analysis; @@ -370,7 +371,7 @@ struct HfTaskMcEfficiencyToXiPi { } } // close loop mcParticles - } // close candidateMcLoop + } // close candidateMcLoop // process functions void processXic0(Xic0CandidateInfo const& candidates, diff --git a/PWGHF/Tasks/taskMcValidation.cxx b/PWGHF/Tasks/taskMcValidation.cxx index b1dc03cdbb2..98fd3e6ad1b 100644 --- a/PWGHF/Tasks/taskMcValidation.cxx +++ b/PWGHF/Tasks/taskMcValidation.cxx @@ -18,24 +18,26 @@ /// \author Fabrizio Grosa , CERN /// \author Fabio Catalano , CERN -#include -#include -#include +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGLF/DataModel/mcCentrality.h" + +#include "Common/DataModel/CollisionAssociationTables.h" +#include "CCDB/BasicCCDBManager.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" #include "Framework/RunningWorkflowInfo.h" #include "Framework/StaticFor.h" +#include "Framework/runDataProcessing.h" -#include "CCDB/BasicCCDBManager.h" -#include "Common/DataModel/CollisionAssociationTables.h" - -#include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/Utils/utilsEvSelHf.h" +#include +#include +#include using namespace o2; using namespace o2::analysis; @@ -1103,21 +1105,21 @@ struct HfTaskMcValidationRec { continue; } int whichHad = -1; - if (isDPlusSel && TESTBIT(std::abs(cand3Prong.flagMcMatchRec()), hf_cand_3prong::DecayType::DplusToPiKPi)) { + if (isDPlusSel && std::abs(cand3Prong.flagMcMatchRec()) == o2::hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) { whichHad = DplusToPiKPi; - } else if (isDsSel && TESTBIT(std::abs(cand3Prong.flagMcMatchRec()), hf_cand_3prong::DecayType::DsToKKPi)) { - if (cand3Prong.flagMcDecayChanRec() == hf_cand_3prong::DecayChannelDToKKPi::DsToPhiPi) { + } else if (isDsSel && std::abs(cand3Prong.flagMcMatchRec()) == o2::hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) { + if (cand3Prong.flagMcDecayChanRec() == o2::hf_decay::hf_cand_3prong::DecayChannelResonant::DsToPhiPi) { whichHad = DsToPhiPiToKKPi; } - if (cand3Prong.flagMcDecayChanRec() == hf_cand_3prong::DecayChannelDToKKPi::DsToK0starK) { + if (cand3Prong.flagMcDecayChanRec() == o2::hf_decay::hf_cand_3prong::DecayChannelResonant::DsToKstar0K) { whichHad = DsToK0starKToKKPi; } - if (cand3Prong.flagMcDecayChanRec() == hf_cand_3prong::DecayChannelDToKKPi::DplusToPhiPi) { + if (cand3Prong.flagMcDecayChanRec() == o2::hf_decay::hf_cand_3prong::DecayChannelResonant::DplusToPhiPi) { whichHad = DplusToPhiPiToKKPi; } - } else if (isLcSel && TESTBIT(std::abs(cand3Prong.flagMcMatchRec()), hf_cand_3prong::DecayType::LcToPKPi)) { + } else if (isLcSel && std::abs(cand3Prong.flagMcMatchRec()) == o2::hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { whichHad = LcToPKPi; - } else if (isXicSel && TESTBIT(std::abs(cand3Prong.flagMcMatchRec()), hf_cand_3prong::DecayType::XicToPKPi)) { + } else if (isXicSel && std::abs(cand3Prong.flagMcMatchRec()) == o2::hf_decay::hf_cand_3prong::DecayChannelMain::XicToPKPi) { whichHad = XiCplusToPKPi; } int whichOrigin; diff --git a/PWGHF/Tasks/taskPidStudies.cxx b/PWGHF/Tasks/taskPidStudies.cxx index 6f5056d9a9c..3c467438511 100644 --- a/PWGHF/Tasks/taskPidStudies.cxx +++ b/PWGHF/Tasks/taskPidStudies.cxx @@ -17,25 +17,27 @@ /// \author Marcello Di Costanzo , Politecnico and INFN Torino /// \author Luca Aglietta , Università and INFN Torino -#include -#include +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "TPDGCode.h" +#include "Common/CCDB/ctpRateFetcher.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" #include "CCDB/BasicCCDBManager.h" #include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" #include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" -#include "Common/DataModel/PIDResponse.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/LFStrangenessPIDTables.h" -#include "PWGHF/Utils/utilsEvSelHf.h" -#include "PWGHF/Core/CentralityEstimation.h" +#include "TPDGCode.h" + +#include +#include using namespace o2; using namespace o2::framework; @@ -98,11 +100,12 @@ DECLARE_SOA_COLUMN(NSigmaTpcBachKa, nSigmaTpcBachKa, float); //! nSigmaTPC of ba DECLARE_SOA_COLUMN(NSigmaTofBachKa, nSigmaTofBachKa, float); //! nSigmaTOF of bachelor with kaon hypothesis // Common columns -DECLARE_SOA_COLUMN(OccupancyFt0c, occupancyFt0c, float); //! Occupancy from FT0C -DECLARE_SOA_COLUMN(OccupancyIts, occupancyIts, float); //! Occupancy from ITS -DECLARE_SOA_COLUMN(CentralityFT0C, centralityFT0C, float); //! Centrality from FT0C -DECLARE_SOA_COLUMN(CentralityFT0M, centralityFT0M, float); //! Centrality from FT0M -DECLARE_SOA_COLUMN(CandFlag, candFlag, int); //! Flag for MC matching +DECLARE_SOA_COLUMN(OccupancyFt0c, occupancyFt0c, float); //! Occupancy from FT0C +DECLARE_SOA_COLUMN(OccupancyIts, occupancyIts, float); //! Occupancy from ITS +DECLARE_SOA_COLUMN(CentralityFT0C, centralityFT0C, float); //! Centrality from FT0C +DECLARE_SOA_COLUMN(CentralityFT0M, centralityFT0M, float); //! Centrality from FT0M +DECLARE_SOA_COLUMN(InteractionRate, interactionRate, double); //! Centrality from FT0M +DECLARE_SOA_COLUMN(CandFlag, candFlag, int); //! Flag for MC matching } // namespace pid_studies DECLARE_SOA_TABLE(PidV0s, "AOD", "PIDV0S", //! Table with PID information @@ -132,6 +135,7 @@ DECLARE_SOA_TABLE(PidV0s, "AOD", "PIDV0S", //! Table with PID information pid_studies::OccupancyIts, pid_studies::CentralityFT0C, pid_studies::CentralityFT0M, + pid_studies::InteractionRate, pid_studies::CandFlag); DECLARE_SOA_TABLE(PidCascades, "AOD", "PIDCASCADES", //! Table with PID information @@ -152,6 +156,7 @@ DECLARE_SOA_TABLE(PidCascades, "AOD", "PIDCASCADES", //! Table with PID informat pid_studies::OccupancyIts, pid_studies::CentralityFT0C, pid_studies::CentralityFT0M, + pid_studies::InteractionRate, pid_studies::CandFlag); } // namespace o2::aod @@ -172,6 +177,8 @@ struct HfTaskPidStudies { Configurable massLambdaMax{"massLambdaMax", 1.3, "Maximum mass for lambda"}; Configurable massOmegaMin{"massOmegaMin", 1.5, "Minimum mass for omega"}; Configurable massOmegaMax{"massOmegaMax", 1.8, "Maximum mass for omega"}; + Configurable interactionRateMin{"interactionRateMin", -1, "Minimum interaction rate (kHz)"}; + Configurable interactionRateMax{"interactionRateMax", 1.e20, "Maximum interaction rate (kHz)"}; Configurable radiusMax{"radiusMax", 2.3, "Maximum decay radius (cm)"}; Configurable cosPaMin{"cosPaMin", 0.98, "Minimum cosine of pointing angle"}; Configurable dcaV0DaughtersMax{"dcaV0DaughtersMax", 0.2, "Maximum DCA among the V0 daughters (cm)"}; @@ -181,6 +188,7 @@ struct HfTaskPidStudies { Configurable qtArmenterosMaxForLambda{"qtArmenterosMaxForLambda", 0.12, "Minimum Armenteros' qt for (anti)Lambda"}; Configurable downSampleBkgFactor{"downSampleBkgFactor", 1., "Fraction of candidates to keep"}; Configurable ptMaxForDownSample{"ptMaxForDownSample", 10., "Maximum pt for the application of the downsampling factor"}; + Configurable ctpFetcherSource{"ctpFetcherSource", "T0VTX", "Source for CTP rate fetching, e.g. T0VTX, T0CE, T0SC, ZNC (hadronic)"}; Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; using PidTracks = soa::Join; using CascsMcRec = soa::Join; + ctpRateFetcher rateFetcher; HfEventSelection hfEvSel; HfEventSelectionMc hfEvSelMc; + double interactionRate{-1.}; o2::framework::Service ccdb; HistogramRegistry registry{"registry", {}}; @@ -259,6 +269,7 @@ struct HfTaskPidStudies { coll.trackOccupancyInTimeRange(), coll.centFT0C(), coll.centFT0M(), + interactionRate, flag); } else { const auto& bachTrack = candidate.template bachelor_as(); @@ -280,6 +291,7 @@ struct HfTaskPidStudies { coll.trackOccupancyInTimeRange(), coll.centFT0C(), coll.centFT0M(), + interactionRate, flag); } } @@ -328,6 +340,12 @@ struct HfTaskPidStudies { template bool isCollSelected(const Coll& coll) { + auto bc = coll.template bc_as(); + interactionRate = rateFetcher.fetch(ccdb.service, bc.timestamp(), bc.runNumber(), ctpFetcherSource.value) * 1.e-3; // convert to kHz + if (interactionRate < interactionRateMin || interactionRate > interactionRateMax) { + return false; + } + float cent{-1.f}; const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(coll, cent, ccdb, registry); /// monitor the satisfied event selections diff --git a/PWGHF/Utils/utilsAnalysis.h b/PWGHF/Utils/utilsAnalysis.h index ec59ec55bf0..7a2c2f45d0a 100644 --- a/PWGHF/Utils/utilsAnalysis.h +++ b/PWGHF/Utils/utilsAnalysis.h @@ -17,11 +17,14 @@ #ifndef PWGHF_UTILS_UTILSANALYSIS_H_ #define PWGHF_UTILS_UTILSANALYSIS_H_ -#include // std::upper_bound -#include // std::distance -#include //std::string +#include +#include +#include -#include "CommonConstants/PhysicsConstants.h" +#include // std::upper_bound +#include +#include // std::distance +#include //std::string namespace o2::analysis { diff --git a/PWGHF/Utils/utilsBfieldCCDB.h b/PWGHF/Utils/utilsBfieldCCDB.h index 8e61485ae53..63337e34ba8 100644 --- a/PWGHF/Utils/utilsBfieldCCDB.h +++ b/PWGHF/Utils/utilsBfieldCCDB.h @@ -16,11 +16,16 @@ #ifndef PWGHF_UTILS_UTILSBFIELDCCDB_H_ #define PWGHF_UTILS_UTILSBFIELDCCDB_H_ -#include // std::string +#include +#include +#include +#include +#include +#include + +#include -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" +#include // std::string /// \brief Sets up the grp object for magnetic field (w/o matCorr for propagation) /// \param bc is the bunch crossing @@ -29,7 +34,8 @@ /// \param ccdbPathGrp is the path where the GRP oject is stored /// \param lut is a pointer to the o2::base::MatLayerCylSet object /// \param isRun2 tells whether we are analysing Run2 converted data or not (different GRP object type) -void initCCDB(o2::aod::BCsWithTimestamps::iterator const& bc, int& mRunNumber, +template +void initCCDB(TBc const& bc, int& mRunNumber, o2::framework::Service const& ccdb, std::string const& ccdbPathGrp, o2::base::MatLayerCylSet* lut, bool isRun2) { diff --git a/PWGHF/Utils/utilsDerivedData.h b/PWGHF/Utils/utilsDerivedData.h index c5eb6cc3b89..35adafa3192 100644 --- a/PWGHF/Utils/utilsDerivedData.h +++ b/PWGHF/Utils/utilsDerivedData.h @@ -16,18 +16,17 @@ #ifndef PWGHF_UTILS_UTILSDERIVEDDATA_H_ #define PWGHF_UTILS_UTILSDERIVEDDATA_H_ -#include -#include +#include "Common/Core/RecoDecay.h" -#include "fairlogger/Logger.h" +#include +#include +#include -#include "Framework/AnalysisHelpers.h" -#include "Framework/Configurable.h" -#include "Framework/ASoA.h" +#include -#include "Common/Core/RecoDecay.h" - -#include "PWGHF/DataModel/DerivedTables.h" +#include +#include +#include // Macro to store nSigma for prong _id_ with PID hypothesis _hyp_ in an array #define GET_N_SIGMA_PRONG(_array_, _candidate_, _id_, _hyp_) \ diff --git a/PWGHF/Utils/utilsEvSelHf.h b/PWGHF/Utils/utilsEvSelHf.h index 4103cd517de..77329f656c5 100644 --- a/PWGHF/Utils/utilsEvSelHf.h +++ b/PWGHF/Utils/utilsEvSelHf.h @@ -18,20 +18,30 @@ #ifndef PWGHF_UTILS_UTILSEVSELHF_H_ #define PWGHF_UTILS_UTILSEVSELHF_H_ -#include // std::shared_ptr -#include // std::string - -#include "Framework/Configurable.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/HistogramSpec.h" -#include "Framework/OutputObjHeader.h" +#include "PWGHF/Core/CentralityEstimation.h" #include "Common/CCDB/EventSelectionParams.h" #include "Common/CCDB/RCTSelectionFlags.h" #include "EventFiltering/Zorro.h" #include "EventFiltering/ZorroSummary.h" -#include "PWGLF/DataModel/mcCentrality.h" -#include "PWGHF/Core/CentralityEstimation.h" + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include +#include +#include // std::shared_ptr +#include // std::string namespace o2::hf_occupancy { diff --git a/PWGHF/Utils/utilsMcGen.h b/PWGHF/Utils/utilsMcGen.h index 863d7041102..0e16ae33c0c 100644 --- a/PWGHF/Utils/utilsMcGen.h +++ b/PWGHF/Utils/utilsMcGen.h @@ -17,15 +17,20 @@ #ifndef PWGHF_UTILS_UTILSMCGEN_H_ #define PWGHF_UTILS_UTILSMCGEN_H_ -#include +#include "PWGHF/Core/DecayChannels.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include +#include "Common/Core/RecoDecay.h" -#include "CommonConstants/PhysicsConstants.h" +#include -#include "Common/Core/RecoDecay.h" +#include -#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include + +#include +#include +#include namespace hf_mc_gen { @@ -82,6 +87,7 @@ template void fillMcMatchGen3Prong(T const& mcParticles, U const& mcParticlesPerMcColl, V& rowMcMatchGen, bool rejectBackground) { using namespace o2::constants::physics; + constexpr std::size_t NDaughtersResonant{2u}; // Match generated particles. for (const auto& particle : mcParticlesPerMcColl) { @@ -91,12 +97,12 @@ void fillMcMatchGen3Prong(T const& mcParticles, U const& mcParticlesPerMcColl, V int8_t sign = 0; std::vector arrDaughIndex; std::vector idxBhadMothers{}; - std::array arrPDGDaugh; - std::array arrPDGResonant1 = {kProton, 313}; // Λc± → p± K* - std::array arrPDGResonant2 = {2224, kKPlus}; // Λc± → Δ(1232)±± K∓ - std::array arrPDGResonant3 = {102134, kPiPlus}; // Λc± → Λ(1520) π± - std::array arrPDGResonantDPhiPi = {333, kPiPlus}; // Ds± → Phi π± and D± → Phi π± - std::array arrPDGResonantDKstarK = {313, kKPlus}; // Ds± → K*(892)0bar K± and D± → K*(892)0bar K± + std::array arrPDGDaugh; + std::array arrPDGResonant1 = {kProton, Pdg::kK0Star892}; // Λc± → p± K* + std::array arrPDGResonant2 = {2224, kKPlus}; // Λc± → Δ(1232)±± K∓ + std::array arrPDGResonant3 = {102134, kPiPlus}; // Λc± → Λ(1520) π± + std::array arrPDGResonantDPhiPi = {Pdg::kPhi, kPiPlus}; // Ds± → Phi π± and D± → Phi π± + std::array arrPDGResonantDKstarK = {Pdg::kK0Star892, kKPlus}; // Ds± → K*(892)0bar K± and D± → K*(892)0bar K± // Reject particles from background events if (particle.fromBackgroundEvent() && rejectBackground) { rowMcMatchGen(flag, origin, channel, -1); @@ -106,7 +112,7 @@ void fillMcMatchGen3Prong(T const& mcParticles, U const& mcParticlesPerMcColl, V // D± → π± K∓ π± if (flag == 0) { if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kDPlus, std::array{+kPiPlus, -kKPlus, +kPiPlus}, true, &sign, 2)) { - flag = sign * (1 << o2::aod::hf_cand_3prong::DecayType::DplusToPiKPi); + flag = sign * o2::hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi; } } @@ -116,24 +122,24 @@ void fillMcMatchGen3Prong(T const& mcParticles, U const& mcParticlesPerMcColl, V if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kDS, std::array{+kKPlus, -kKPlus, +kPiPlus}, true, &sign, 2)) { // DecayType::DsToKKPi is used to flag both Ds± → K± K∓ π± and D± → K± K∓ π± // TODO: move to different and explicit flags - flag = sign * (1 << o2::aod::hf_cand_3prong::DecayType::DsToKKPi); + flag = sign * o2::hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK; } else if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kDPlus, std::array{+kKPlus, -kKPlus, +kPiPlus}, true, &sign, 2)) { // DecayType::DsToKKPi is used to flag both Ds± → K± K∓ π± and D± → K± K∓ π± // TODO: move to different and explicit flags - flag = sign * (1 << o2::aod::hf_cand_3prong::DecayType::DsToKKPi); + flag = sign * o2::hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKK; isDplus = true; } if (flag != 0) { RecoDecay::getDaughters(particle, &arrDaughIndex, std::array{0}, 1); - if (arrDaughIndex.size() == 2) { + if (arrDaughIndex.size() == NDaughtersResonant) { for (auto jProng = 0u; jProng < arrDaughIndex.size(); ++jProng) { auto daughJ = mcParticles.rawIteratorAt(arrDaughIndex[jProng]); arrPDGDaugh[jProng] = std::abs(daughJ.pdgCode()); } if ((arrPDGDaugh[0] == arrPDGResonantDPhiPi[0] && arrPDGDaugh[1] == arrPDGResonantDPhiPi[1]) || (arrPDGDaugh[0] == arrPDGResonantDPhiPi[1] && arrPDGDaugh[1] == arrPDGResonantDPhiPi[0])) { - channel = isDplus ? o2::aod::hf_cand_3prong::DecayChannelDToKKPi::DplusToPhiPi : o2::aod::hf_cand_3prong::DecayChannelDToKKPi::DsToPhiPi; + channel = isDplus ? o2::hf_decay::hf_cand_3prong::DecayChannelResonant::DplusToPhiPi : o2::hf_decay::hf_cand_3prong::DecayChannelResonant::DsToPhiPi; } else if ((arrPDGDaugh[0] == arrPDGResonantDKstarK[0] && arrPDGDaugh[1] == arrPDGResonantDKstarK[1]) || (arrPDGDaugh[0] == arrPDGResonantDKstarK[1] && arrPDGDaugh[1] == arrPDGResonantDKstarK[0])) { - channel = isDplus ? o2::aod::hf_cand_3prong::DecayChannelDToKKPi::DplusToK0starK : o2::aod::hf_cand_3prong::DecayChannelDToKKPi::DsToK0starK; + channel = isDplus ? o2::hf_decay::hf_cand_3prong::DecayChannelResonant::DplusToKstar0K : o2::hf_decay::hf_cand_3prong::DecayChannelResonant::DsToKstar0K; } } } @@ -142,18 +148,18 @@ void fillMcMatchGen3Prong(T const& mcParticles, U const& mcParticlesPerMcColl, V // D*± → D0(bar) π± if (flag == 0) { if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kDStar, std::array{+kPiPlus, +kPiPlus, -kKPlus}, true, &sign, 2)) { - flag = sign * (1 << o2::aod::hf_cand_3prong::DstarToPiKPiBkg); + flag = sign * o2::hf_decay::hf_cand_3prong::DecayChannelMain::DstarToPiKPi; } } // Λc± → p± K∓ π± if (flag == 0) { if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kLambdaCPlus, std::array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2)) { - flag = sign * (1 << o2::aod::hf_cand_3prong::DecayType::LcToPKPi); + flag = sign * o2::hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi; // Flagging the different Λc± → p± K∓ π± decay channels RecoDecay::getDaughters(particle, &arrDaughIndex, std::array{0}, 1); - if (arrDaughIndex.size() == 2) { + if (arrDaughIndex.size() == NDaughtersResonant) { for (auto jProng = 0u; jProng < arrDaughIndex.size(); ++jProng) { auto daughJ = mcParticles.rawIteratorAt(arrDaughIndex[jProng]); arrPDGDaugh[jProng] = std::abs(daughJ.pdgCode()); @@ -172,7 +178,7 @@ void fillMcMatchGen3Prong(T const& mcParticles, U const& mcParticlesPerMcColl, V // Ξc± → p± K∓ π± if (flag == 0) { if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kXiCPlus, std::array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2)) { - flag = sign * (1 << o2::aod::hf_cand_3prong::DecayType::XicToPKPi); + flag = sign * o2::hf_decay::hf_cand_3prong::DecayChannelMain::XicToPKPi; } } diff --git a/PWGHF/Utils/utilsPid.h b/PWGHF/Utils/utilsPid.h index 1ea021c096a..173ee2c6986 100644 --- a/PWGHF/Utils/utilsPid.h +++ b/PWGHF/Utils/utilsPid.h @@ -17,6 +17,13 @@ #ifndef PWGHF_UTILS_UTILSPID_H_ #define PWGHF_UTILS_UTILSPID_H_ +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" + +#include + +#include + namespace o2::aod::pid_tpc_tof_utils { /// @brief Species of HF-candidate daughter tracks diff --git a/PWGHF/Utils/utilsTrkCandHf.h b/PWGHF/Utils/utilsTrkCandHf.h index a1d1b41c10f..6f2dd9a7b17 100644 --- a/PWGHF/Utils/utilsTrkCandHf.h +++ b/PWGHF/Utils/utilsTrkCandHf.h @@ -16,7 +16,11 @@ #ifndef PWGHF_UTILS_UTILSTRKCANDHF_H_ #define PWGHF_UTILS_UTILSTRKCANDHF_H_ -#include "Framework/HistogramSpec.h" +#include + +#include + +#include namespace o2::hf_trkcandsel { diff --git a/PWGJE/Core/JetFindingUtilities.h b/PWGJE/Core/JetFindingUtilities.h index d99c84ecbbf..ac81338a99d 100644 --- a/PWGJE/Core/JetFindingUtilities.h +++ b/PWGJE/Core/JetFindingUtilities.h @@ -224,7 +224,7 @@ bool analyseCandidateMC(std::vector& inputParticles, T const * @param v0s V0 candidates */ template -bool analyseV0s(std::vector& inputParticles, T const& v0s, float v0PtMin, float v0PtMax, float v0YMin, float v0YMax, int v0Index) +bool analyseV0s(std::vector& inputParticles, T const& v0s, float v0PtMin, float v0PtMax, float v0YMin, float v0YMax, int v0Index, bool useV0SignalFlags) { float v0Mass = 0; float v0Y = -10.0; @@ -235,6 +235,9 @@ bool analyseV0s(std::vector& inputParticles, T const& v0s, f v0Mass = v0.m(); v0Y = v0.y(); } else { + if (useV0SignalFlags && v0.isRejectedCandidate()) { + continue; + } if (v0Index == 0) { v0Mass = o2::constants::physics::MassKaonNeutral; } diff --git a/PWGJE/Core/JetHFUtilities.h b/PWGJE/Core/JetHFUtilities.h index 97394dd6a70..a5ec07fe157 100644 --- a/PWGJE/Core/JetHFUtilities.h +++ b/PWGJE/Core/JetHFUtilities.h @@ -283,13 +283,13 @@ constexpr bool isMatchedHFCandidate(T const& candidate) return false; } } else if constexpr (isDplusCandidate()) { - if (std::abs(candidate.flagMcMatchRec()) == 1 << o2::aod::hf_cand_3prong::DecayType::DplusToPiKPi) { + if (std::abs(candidate.flagMcMatchRec()) == o2::hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) { return true; } else { return false; } } else if constexpr (isLcCandidate()) { - if (std::abs(candidate.flagMcMatchRec()) == 1 << o2::aod::hf_cand_3prong::DecayType::LcToPKPi) { + if (std::abs(candidate.flagMcMatchRec()) == o2::hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { return true; } else { return false; @@ -307,13 +307,13 @@ constexpr bool isMatchedHFCandidate(T const& candidate) return false; } } else if constexpr (isDplusMcCandidate()) { - if (std::abs(candidate.flagMcMatchGen()) == 1 << o2::aod::hf_cand_3prong::DecayType::DplusToPiKPi) { + if (std::abs(candidate.flagMcMatchGen()) == o2::hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) { return true; } else { return false; } } else if constexpr (isLcMcCandidate()) { - if (std::abs(candidate.flagMcMatchGen()) == 1 << o2::aod::hf_cand_3prong::DecayType::LcToPKPi) { + if (std::abs(candidate.flagMcMatchGen()) == o2::hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { return true; } else { return false; diff --git a/PWGJE/DataModel/Jet.h b/PWGJE/DataModel/Jet.h index 8db401ffc48..6b8fde1f849 100644 --- a/PWGJE/DataModel/Jet.h +++ b/PWGJE/DataModel/Jet.h @@ -23,19 +23,21 @@ #ifndef PWGJE_DATAMODEL_JET_H_ #define PWGJE_DATAMODEL_JET_H_ -#include -#include "Framework/AnalysisDataModel.h" +#include "PWGDQ/DataModel/ReducedInfoTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/DataModel/DerivedTables.h" #include "PWGJE/DataModel/EMCALClusters.h" #include "PWGJE/DataModel/JetReducedData.h" +#include "PWGJE/DataModel/JetReducedDataDQ.h" #include "PWGJE/DataModel/JetReducedDataHF.h" #include "PWGJE/DataModel/JetReducedDataV0.h" -#include "PWGJE/DataModel/JetReducedDataDQ.h" #include "PWGJE/DataModel/JetSubtraction.h" - -#include "PWGHF/DataModel/DerivedTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGDQ/DataModel/ReducedInfoTables.h" +#include "PWGLF/DataModel/V0SelectorTables.h" + +#include "Framework/AnalysisDataModel.h" + +#include namespace o2::aod { @@ -244,8 +246,8 @@ using JetParticlesSubBplus = JMcParticleBplusSubs; using McCollisionsBplus = o2::soa::Join; using CandidatesBplusMCP = o2::soa::Join; -using CandidatesV0Data = o2::soa::Join; -using CandidatesV0MCD = o2::soa::Join; +using CandidatesV0Data = o2::soa::Join; +using CandidatesV0MCD = o2::soa::Join; // using V0Daughters = DauTrackExtras; using McCollisionsV0 = o2::soa::Join; using CandidatesV0MCP = o2::soa::Join; diff --git a/PWGJE/JetFinders/jetFinder.cxx b/PWGJE/JetFinders/jetFinder.cxx index 4482509804b..a1d854ec4bc 100644 --- a/PWGJE/JetFinders/jetFinder.cxx +++ b/PWGJE/JetFinders/jetFinder.cxx @@ -15,14 +15,36 @@ /// \author Jochen Klein /// \author Raymond Ehlers , ORNL -#include +#include "PWGJE/Core/JetFinder.h" -#include "PWGJE/Core/JetFindingUtilities.h" #include "PWGJE/Core/JetDerivedDataUtilities.h" -#include "Framework/runDataProcessing.h" +#include "PWGJE/Core/JetFindingUtilities.h" +#include "PWGJE/DataModel/EMCALClusterDefinition.h" +#include "PWGJE/DataModel/EMCALClusters.h" +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetReducedData.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include // IWYU pragma: keep (needed in tasks) + +#include +#include + +#include +#include + +#include +#include +#include using namespace o2; -using namespace o2::analysis; using namespace o2::framework; using namespace o2::framework::expressions; diff --git a/PWGJE/JetFinders/jetFinderHF.cxx b/PWGJE/JetFinders/jetFinderHF.cxx index 9b435cf93a0..e64608f403e 100644 --- a/PWGJE/JetFinders/jetFinderHF.cxx +++ b/PWGJE/JetFinders/jetFinderHF.cxx @@ -14,22 +14,38 @@ /// \author Nima Zardoshti /// \author Jochen Klein -#include - -#include "CommonConstants/PhysicsConstants.h" - -#include "PWGJE/Core/JetFindingUtilities.h" #include "PWGJE/Core/JetDerivedDataUtilities.h" -#include "Common/Core/RecoDecay.h" +#include "PWGJE/Core/JetFinder.h" +#include "PWGJE/Core/JetFindingUtilities.h" +#include "PWGJE/DataModel/EMCALClusterDefinition.h" +#include "PWGJE/DataModel/EMCALClusters.h" +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetReducedData.h" +#include "PWGJE/DataModel/JetSubtraction.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include // IWYU pragma: keep (needed in tasks) + +#include +#include + +#include +#include + +#include +#include using namespace o2; -using namespace o2::analysis; using namespace o2::framework; using namespace o2::framework::expressions; -// NB: runDataProcessing.h must be included after customize! -#include "Framework/runDataProcessing.h" - template struct JetFinderHFTask { Produces jetsTable; diff --git a/PWGJE/JetFinders/jetFinderV0.cxx b/PWGJE/JetFinders/jetFinderV0.cxx index cdb827783ac..724d0bfe34f 100644 --- a/PWGJE/JetFinders/jetFinderV0.cxx +++ b/PWGJE/JetFinders/jetFinderV0.cxx @@ -13,22 +13,36 @@ // /// \author Nima Zardoshti -#include - -#include "CommonConstants/PhysicsConstants.h" - -#include "PWGJE/Core/JetFindingUtilities.h" #include "PWGJE/Core/JetDerivedDataUtilities.h" -#include "Common/Core/RecoDecay.h" +#include "PWGJE/Core/JetFinder.h" +#include "PWGJE/Core/JetFindingUtilities.h" +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetReducedData.h" +#include "PWGLF/DataModel/V0SelectorTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include // IWYU pragma: keep (needed in tasks) + +#include +#include + +#include +#include + +#include +#include using namespace o2; -using namespace o2::analysis; using namespace o2::framework; using namespace o2::framework::expressions; -// NB: runDataProcessing.h must be included after customize! -#include "Framework/runDataProcessing.h" - template struct JetFinderV0Task { @@ -80,6 +94,7 @@ struct JetFinderV0Task { Configurable jetPtBinWidth{"jetPtBinWidth", 5, "used to define the width of the jetPt bins for the THnSparse"}; Configurable fillTHnSparse{"fillTHnSparse", true, "switch to fill the THnSparse"}; Configurable jetExtraParam{"jetExtraParam", -99.0, "sets the _extra_param in fastjet"}; + Configurable useV0SignalFlags{"useV0SignalFlags", true, "use V0 signal flags table"}; Service pdgDatabase; int trackSelection = -1; @@ -148,7 +163,6 @@ struct JetFinderV0Task { Filter mcCollisionFilter = ((skipMBGapEvents.node() == false) || (aod::jmccollision::subGeneratorId != static_cast(jetderiveddatautilities::JCollisionSubGeneratorId::mbGap))); // should we add a posZ vtx cut here or leave it to analysers? Filter trackCuts = (aod::jtrack::pt >= trackPtMin && aod::jtrack::pt < trackPtMax && aod::jtrack::eta >= trackEtaMin && aod::jtrack::eta <= trackEtaMax && aod::jtrack::phi >= trackPhiMin && aod::jtrack::phi <= trackPhiMax); Filter partCuts = (aod::jmcparticle::pt >= trackPtMin && aod::jmcparticle::pt < trackPtMax && aod::jmcparticle::eta >= trackEtaMin && aod::jmcparticle::eta <= trackEtaMax && aod::jmcparticle::phi >= trackPhiMin && aod::jmcparticle::phi <= trackPhiMax); - // Filter candidateCuts = (aod::hfcand::pt >= candPtMin && aod::hfcand::pt < candPtMax && aod::hfcand::y >= candYMin && aod::hfcand::y < candYMax); // function that generalically processes Data and reco level events template @@ -158,7 +172,7 @@ struct JetFinderV0Task { return; } inputParticles.clear(); - if (!jetfindingutilities::analyseV0s(inputParticles, candidates, candPtMin, candPtMax, candYMin, candYMax, candIndex)) { + if (!jetfindingutilities::analyseV0s(inputParticles, candidates, candPtMin, candPtMax, candYMin, candYMax, candIndex, useV0SignalFlags)) { return; } @@ -179,7 +193,7 @@ struct JetFinderV0Task { { inputParticles.clear(); - if (!jetfindingutilities::analyseV0s(inputParticles, candidates, candPtMin, candPtMax, candYMin, candYMax, candIndex)) { + if (!jetfindingutilities::analyseV0s(inputParticles, candidates, candPtMin, candPtMax, candYMin, candYMax, candIndex, useV0SignalFlags)) { return; } jetfindingutilities::analyseParticles(inputParticles, particleSelection, jetTypeParticleLevel, particles, pdgDatabase, &candidates); diff --git a/PWGJE/TableProducer/emcalCorrectionTask.cxx b/PWGJE/TableProducer/emcalCorrectionTask.cxx index c2389d10b02..47e5bf9f03a 100644 --- a/PWGJE/TableProducer/emcalCorrectionTask.cxx +++ b/PWGJE/TableProducer/emcalCorrectionTask.cxx @@ -18,39 +18,57 @@ /// \author Raymond Ehlers (raymond.ehlers@cern.ch) ORNL, Florian Jonas (florian.jonas@cern.ch) /// -#include -#include -#include -#include -#include -#include -#include -#include - -#include "CCDB/BasicCCDBManager.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoA.h" - -#include "DetectorsBase/GeometryManager.h" +#include "GPUROOTCartesianFwd.h" +#include "PWGJE/Core/JetUtilities.h" +#include "PWGJE/DataModel/EMCALClusterDefinition.h" #include "PWGJE/DataModel/EMCALClusters.h" #include "PWGJE/DataModel/EMCALMatchedCollisions.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/TrackSelectionTables.h" + +#include "CCDB/BasicCCDBManager.h" +#include "DataFormatsEMCAL/AnalysisCluster.h" #include "DataFormatsEMCAL/Cell.h" #include "DataFormatsEMCAL/CellLabel.h" +#include "DataFormatsEMCAL/ClusterLabel.h" #include "DataFormatsEMCAL/Constants.h" -#include "DataFormatsEMCAL/AnalysisCluster.h" -#include "EMCALBase/Geometry.h" +#include "DetectorsBase/GeometryManager.h" #include "EMCALBase/ClusterFactory.h" +#include "EMCALBase/Geometry.h" #include "EMCALBase/NonlinearityHandler.h" #include "EMCALReconstruction/Clusterizer.h" -#include "PWGJE/Core/JetUtilities.h" +#include "Framework/ASoA.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/Configurable.h" +#include "Framework/Expressions.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/HistogramSpec.h" +#include "Framework/InitContext.h" +#include "Framework/WorkflowSpec.h" +#include "Framework/runDataProcessing.h" + +#include "TH1.h" #include "TVector2.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; @@ -97,6 +115,7 @@ struct EmcalCorrectionTask { Configurable isMC{"isMC", false, "States if run over MC"}; Configurable applyCellTimeCorrection{"applyCellTimeCorrection", true, "apply a correction to the cell time for data and MC: Shift both average cell times to 0 and smear MC time distribution to fit data better. For MC requires isMC to be true"}; Configurable trackMinPt{"trackMinPt", 0.3, "Minimum pT for tracks to perform track matching, to reduce computing time. Tracks below a certain pT will be loopers anyway."}; + Configurable fillQA{"fillQA", false, "Switch to turn on QA histograms."}; // Require EMCAL cells (CALO type 1) Filter emccellfilter = aod::calo::caloType == selectedCellType; @@ -206,22 +225,26 @@ struct EmcalCorrectionTask { // Setup QA hists. // NOTE: This is not comprehensive. using O2HistType = o2::framework::HistType; - o2::framework::AxisSpec energyAxis{200, 0., 100., "E (GeV)"}, - timeAxis{300, -100, 200., "t (ns)"}, - etaAxis{160, -0.8, 0.8, "#eta"}, - phiAxis{72, 0, 2 * 3.14159, "phi"}, - nlmAxis{50, -0.5, 49.5, "NLM"}; - mHistManager.add("hCellE", "hCellE", O2HistType::kTH1F, {energyAxis}); + o2::framework::AxisSpec energyAxis{200, 0., 100., "#it{E} (GeV)"}, + timeAxis{300, -100, 200., "#it{t} (ns)"}, + etaAxis{160, -0.8, 0.8, "#it{#eta}"}, + phiAxis{72, 0, 2 * 3.14159, "#it{#varphi} (rad)"}, + nlmAxis{50, -0.5, 49.5, "NLM"}, + fCrossAxis{100, 0., 1., "F_{+}"}, + sigmaLongAxis{100, 0., 1.0, "#sigma^{2}_{long}"}, + sigmaShortAxis{100, 0., 1.0, "#sigma^{2}_{short}"}, + nCellAxis{60, -0.5, 59.5, "#it{n}_{cells}"}; + mHistManager.add("hCellE", "hCellE", O2HistType::kTH1D, {energyAxis}); mHistManager.add("hCellTowerID", "hCellTowerID", O2HistType::kTH1D, {{20000, 0, 20000}}); mHistManager.add("hCellEtaPhi", "hCellEtaPhi", O2HistType::kTH2F, {etaAxis, phiAxis}); mHistManager.add("hHGCellTimeEnergy", "hCellTime", O2HistType::kTH2F, {{300, -30, 30}, cellEnergyBins}); // Cell time vs energy for high gain cells (low energies) mHistManager.add("hLGCellTimeEnergy", "hCellTime", O2HistType::kTH2F, {{300, -30, 30}, cellEnergyBins}); // Cell time vs energy for low gain cells (high energies) // NOTE: Reversed column and row because it's more natural for presentation. mHistManager.add("hCellRowCol", "hCellRowCol;Column;Row", O2HistType::kTH2D, {{96, -0.5, 95.5}, {208, -0.5, 207.5}}); - mHistManager.add("hClusterE", "hClusterE", O2HistType::kTH1F, {energyAxis}); - mHistManager.add("hClusterNLM", "hClusterNLM", O2HistType::kTH1F, {nlmAxis}); + mHistManager.add("hClusterE", "hClusterE", O2HistType::kTH1D, {energyAxis}); + mHistManager.add("hClusterNLM", "hClusterNLM", O2HistType::kTH1D, {nlmAxis}); mHistManager.add("hClusterEtaPhi", "hClusterEtaPhi", O2HistType::kTH2F, {etaAxis, phiAxis}); - mHistManager.add("hClusterTime", "hClusterTime", O2HistType::kTH1F, {timeAxis}); + mHistManager.add("hClusterTime", "hClusterTime", O2HistType::kTH1D, {timeAxis}); mHistManager.add("hGlobalTrackEtaPhi", "hGlobalTrackEtaPhi", O2HistType::kTH2F, {etaAxis, phiAxis}); mHistManager.add("hGlobalTrackMult", "hGlobalTrackMult", O2HistType::kTH1D, {{200, -0.5, 199.5, "N_{trk}"}}); mHistManager.add("hCollisionType", "hCollisionType;;#it{count}", O2HistType::kTH1D, {{3, -0.5, 2.5}}); @@ -251,9 +274,15 @@ struct EmcalCorrectionTask { hBC->GetXaxis()->SetBinLabel(6, "no EMCal cells and with collision"); hBC->GetXaxis()->SetBinLabel(7, "no EMCal cells and mult. collisions"); hBC->GetXaxis()->SetBinLabel(8, "all BC"); - if (isMC) { - mHistManager.add("hContributors", "hContributors;contributor per cell hit;#it{counts}", O2HistType::kTH1I, {{20, 0, 20}}); - mHistManager.add("hMCParticleEnergy", "hMCParticleEnergy;#it{E} (GeV/#it{c});#it{counts}", O2HistType::kTH1F, {energyAxis}); + if (isMC.value) { + mHistManager.add("hContributors", "hContributors;contributor per cell hit;#it{counts}", O2HistType::kTH1D, {{20, 0, 20}}); + mHistManager.add("hMCParticleEnergy", "hMCParticleEnergy;#it{E} (GeV/#it{c});#it{counts}", O2HistType::kTH1D, {energyAxis}); + } + if (fillQA.value) { + mHistManager.add("hClusterNCellE", "hClusterNCellE", O2HistType::kTH2D, {energyAxis, nCellAxis}); + mHistManager.add("hClusterFCrossE", "hClusterFCrossE", O2HistType::kTH2D, {energyAxis, fCrossAxis}); + mHistManager.add("hClusterFCrossSigmaLongE", "hClusterFCrossSigmaLongE", O2HistType::kTH3F, {energyAxis, fCrossAxis, sigmaLongAxis}); + mHistManager.add("hClusterFCrossSigmaShortE", "hClusterFCrossSigmaShortE", O2HistType::kTH3F, {energyAxis, fCrossAxis, sigmaShortAxis}); } // For some runs, LG cells require an extra time shift of 2 * 8.8ns due to problems in the time calibration @@ -721,6 +750,12 @@ struct EmcalCorrectionTask { mHistManager.fill(HIST("hClusterNLM"), cluster.getNExMax()); mHistManager.fill(HIST("hClusterTime"), cluster.getClusterTime()); mHistManager.fill(HIST("hClusterEtaPhi"), pos.Eta(), TVector2::Phi_0_2pi(pos.Phi())); + if (fillQA.value) { + mHistManager.fill(HIST("hClusterNCellE"), cluster.E(), cluster.getNCells()); + mHistManager.fill(HIST("hClusterFCrossE"), cluster.E(), cluster.getFCross()); + mHistManager.fill(HIST("hClusterFCrossSigmaLongE"), cluster.E(), cluster.getFCross(), cluster.getM02()); + mHistManager.fill(HIST("hClusterFCrossSigmaShortE"), cluster.E(), cluster.getFCross(), cluster.getM20()); + } if (indexMapPair && trackGlobalIndex) { for (unsigned int iTrack = 0; iTrack < std::get<0>(*indexMapPair)[iCluster].size(); iTrack++) { if (std::get<0>(*indexMapPair)[iCluster][iTrack] >= 0) { diff --git a/PWGJE/Tasks/CMakeLists.txt b/PWGJE/Tasks/CMakeLists.txt index 1a0854a2fbf..0e39c04445a 100644 --- a/PWGJE/Tasks/CMakeLists.txt +++ b/PWGJE/Tasks/CMakeLists.txt @@ -241,8 +241,8 @@ if(FastJet_FOUND) SOURCES statPromptPhoton.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(full-jet-spectra-pp - SOURCES fullJetSpectraPP.cxx + o2physics_add_dpl_workflow(full-jet-spectra + SOURCES fullJetSpectra.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(bjet-tagging-ml diff --git a/PWGJE/Tasks/dijetFinderQA.cxx b/PWGJE/Tasks/dijetFinderQA.cxx index 0250a405537..d2697e614bf 100644 --- a/PWGJE/Tasks/dijetFinderQA.cxx +++ b/PWGJE/Tasks/dijetFinderQA.cxx @@ -52,6 +52,7 @@ struct DijetFinderQATask { Configurable centralityMax{"centralityMax", 999.0, "maximum centrality"}; Configurable eventSelections{"eventSelections", "sel8", "choose event selection"}; Configurable vertexZCut{"vertexZCut", 10.0f, "Accepted z-vertex range"}; + Configurable checkMcCollisionIsMatched{"checkMcCollisionIsMatched", false, "0: count whole MCcollisions, 1: select MCcollisions which only have their correspond collisions"}; Configurable trackSelections{"trackSelections", "globalTracks", "set track selections"}; Configurable trackPtMin{"trackPtMin", 0.15, "minimum pT acceptance for tracks"}; Configurable trackPtMax{"trackPtMax", 1000.0, "maximum pT acceptance for tracks"}; @@ -73,6 +74,28 @@ struct DijetFinderQATask { std::vector dijetMassBins; + void labelCollisionHistograms(HistogramRegistry& registry) + { + if (doprocessDijetMCP) { + auto hColCounter_MCP = registry.get(HIST("hColCounter_MCP")); + hColCounter_MCP->GetXaxis()->SetBinLabel(1, "AllMcCollisions"); + hColCounter_MCP->GetXaxis()->SetBinLabel(2, "McCollisionsWithVertexZ"); + hColCounter_MCP->GetXaxis()->SetBinLabel(3, "MatchedMcCollisions"); + } + if (doprocessDijetMCD) { + auto hColCounter_MCD = registry.get(HIST("hColCounter_MCD")); + hColCounter_MCD->GetXaxis()->SetBinLabel(1, "AllDetCollisions"); + hColCounter_MCD->GetXaxis()->SetBinLabel(2, "DetCollisionsWithVertexZ"); + hColCounter_MCD->GetXaxis()->SetBinLabel(3, "AcceptedDetCollisions"); + } + if (doprocessDijetData) { + auto hColCounter_Data = registry.get(HIST("hColCounter_Data")); + hColCounter_Data->GetXaxis()->SetBinLabel(1, "AllDataCollisions"); + hColCounter_Data->GetXaxis()->SetBinLabel(2, "DataCollisionsWithVertexZ"); + hColCounter_Data->GetXaxis()->SetBinLabel(3, "AcceptedDataCollisions"); + } + } + void init(o2::framework::InitContext&) { eventSelection = jetderiveddatautilities::initialiseEventSelectionBits(static_cast(eventSelections)); @@ -86,32 +109,33 @@ struct DijetFinderQATask { } AxisSpec dijetMassAxis = {dijetMassBins, "M_{jj} (GeV/#it{c}^2)"}; - AxisSpec eventCountAxis = {{0.5, 1.5}, "events"}; if (doprocessDijetMCP) { registry.add("h_part_dijet_mass", "Dijet invariant mass;;entries", {HistType::kTH1F, {dijetMassAxis}}); - registry.add("hColCounterFinal_MCP", "Event count;;entries", {HistType::kTH1F, {eventCountAxis}}); + registry.add("hColCounter_MCP", "event status; event status;entries", {HistType::kTH1F, {{10, 0., 10.0}}}); } if (doprocessDijetMCD) { registry.add("h_detec_dijet_mass", "Dijet invariant mass;;entries", {HistType::kTH1F, {dijetMassAxis}}); - registry.add("hColCounterFinal_MCD", "Event count;;entries", {HistType::kTH1F, {eventCountAxis}}); + registry.add("hColCounter_MCD", "event status; event status;entries", {HistType::kTH1F, {{10, 0., 10.0}}}); + // registry.add("hColCounter_MCD", "Event count;;entries", {HistType::kTH1F, {eventCountAxis}}); } if (doprocessDijetData) { registry.add("h_data_dijet_mass", "Dijet invariant mass;;entries", {HistType::kTH1F, {dijetMassAxis}}); - registry.add("hColCounterFinal_Data", "Event count;;entries", {HistType::kTH1F, {eventCountAxis}}); + registry.add("hColCounter_Data", "event status; event status;entries", {HistType::kTH1F, {{10, 0., 10.0}}}); + // registry.add("hColCounter_Data", "Event count;;entries", {HistType::kTH1F, {eventCountAxis}}); } - if (doprocessDijetMCMatched) { + if (doprocessDijetMCPMCDMatched) { registry.add("h_matched_dijet_mass", "M_{jj matched};M_{jj part}; M_{jj det}", {HistType::kTH2F, {dijetMassAxis, dijetMassAxis}}); } + + labelCollisionHistograms(registry); } /****************************************************************************************************************************************************************/ Filter trackCuts = (aod::jtrack::pt >= trackPtMin && aod::jtrack::pt < trackPtMax && aod::jtrack::eta > trackEtaMin && aod::jtrack::eta < trackEtaMax); - Filter eventCuts = (nabs(aod::jcollision::posZ) < vertexZCut && aod::jcollision::centrality >= centralityMin && aod::jcollision::centrality < centralityMax); - Filter mcCollisionsFilter = nabs(aod::jmccollision::posZ) < vertexZCut; Filter jetCuts = aod::jet::pt > jetPtMin&& aod::jet::r == nround(jetR.node() * 100.0f); /****************************************************************************************************************************************************************/ @@ -170,7 +194,7 @@ struct DijetFinderQATask { } template - void fillMassHistogramsMCMatched(T const& mass_P, T const& mass_D) + void fillMassHistogramsMCPMCDMatched(T const& mass_P, T const& mass_D) { registry.fill(HIST("h_matched_dijet_mass"), mass_P, mass_D); } @@ -180,25 +204,44 @@ struct DijetFinderQATask { } PROCESS_SWITCH(DijetFinderQATask, processDummy, "dummy", false); - void processDijetMCP(soa::Filtered::iterator const&, soa::Filtered const& jets, soa::SmallGroups const& collisions) + void processDijetMCP(aod::JetMcCollisions::iterator const& mccollision, + soa::Filtered> const& jets, + soa::SmallGroups const& collisions) { - if (collisions.size() == 0) { + registry.fill(HIST("hColCounter_MCP"), 0.5); + if (fabs(mccollision.posZ()) > vertexZCut) { return; } - for (auto& collision : collisions) { - if (fabs(collision.posZ()) > vertexZCut || !jetderiveddatautilities::selectCollision(collision, eventSelection)) + registry.fill(HIST("hColCounter_MCP"), 1.5); + if (checkMcCollisionIsMatched) { + if (collisions.size() == 0) { return; + } + for (auto& collision : collisions) { + if (fabs(collision.posZ()) > vertexZCut || !jetderiveddatautilities::selectCollision(collision, eventSelection)) { + return; + } + } + registry.fill(HIST("hColCounter_MCP"), 2.5); } - registry.fill(HIST("hColCounterFinal_MCP"), 1); - std::vector> jetPtcuts; for (auto& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + if (!isAcceptedJet(jet)) { + continue; + } + if (jet.pt() < setJetPtCut) { + continue; + } jetPtcuts.push_back({jet.pt(), jet.eta(), jet.phi()}); } if (jetPtcuts.size() >= 2) { auto& leading_jet = jetPtcuts[0]; + bool found_pair = false; for (size_t i = 1; i < jetPtcuts.size() && !found_pair; i++) { @@ -219,21 +262,36 @@ struct DijetFinderQATask { } PROCESS_SWITCH(DijetFinderQATask, processDijetMCP, "QA for invariant mass of dijet in particle level MC", false); - void processDijetMCD(soa::Filtered::iterator const& collision, soa::Filtered const& jets) + void processDijetMCD(aod::JetCollisions::iterator const& collision, + soa::Filtered> const& jets) { + registry.fill(HIST("hColCounter_MCD"), 0.5); + if (fabs(collision.posZ()) > vertexZCut) { + return; + } + registry.fill(HIST("hColCounter_MCD"), 1.5); if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } - - registry.fill(HIST("hColCounterFinal_MCD"), 1); + registry.fill(HIST("hColCounter_MCD"), 2.5); std::vector> jetPtcuts; for (auto& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + if (!isAcceptedJet(jet)) { + continue; + } + if (jet.pt() < setJetPtCut) { + continue; + } jetPtcuts.push_back({jet.pt(), jet.eta(), jet.phi()}); } if (jetPtcuts.size() >= 2) { auto& leading_jet = jetPtcuts[0]; + bool found_pair = false; for (size_t i = 1; i < jetPtcuts.size() && !found_pair; i++) { @@ -254,22 +312,36 @@ struct DijetFinderQATask { } PROCESS_SWITCH(DijetFinderQATask, processDijetMCD, "QA for invariant mass of dijet in detector level MC", false); - void processDijetData(soa::Filtered::iterator const& collision, soa::Filtered const& jets) + void processDijetData(aod::JetCollisions::iterator const& collision, + soa::Filtered> const& jets) { + registry.fill(HIST("hColCounter_Data"), 0.5); + if (fabs(collision.posZ()) > vertexZCut) { + return; + } + registry.fill(HIST("hColCounter_Data"), 1.5); if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } - - // Fill event count histogram - registry.fill(HIST("hColCounterFinal_Data"), 1); + registry.fill(HIST("hColCounter_Data"), 2.5); std::vector> jetPtcuts; for (auto& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + if (!isAcceptedJet(jet)) { + continue; + } + if (jet.pt() < setJetPtCut) { + continue; + } jetPtcuts.push_back({jet.pt(), jet.eta(), jet.phi()}); } if (jetPtcuts.size() >= 2) { auto& leading_jet = jetPtcuts[0]; + bool found_pair = false; for (size_t i = 1; i < jetPtcuts.size() && !found_pair; i++) { @@ -290,11 +362,22 @@ struct DijetFinderQATask { } PROCESS_SWITCH(DijetFinderQATask, processDijetData, "QA for invariant mass of dijet in data", false); - using JetMCPTable = soa::Filtered>; - void processDijetMCMatched(soa::Filtered::iterator const& collision, - soa::Filtered> const& mcdjets, - JetMCPTable const&, aod::JetTracks const&, aod::JetParticles const&) + using JetMCPTable = soa::Filtered>; + using JetMCDTable = soa::Filtered>; + + void processDijetMCPMCDMatched(aod::JetCollisionsMCD::iterator const& collision, + JetMCDTable const& mcdjets, + JetMCPTable const&, + aod::JetTracks const&, + aod::JetParticles const&) { + if (fabs(collision.posZ()) > vertexZCut) { + return; + } if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } @@ -302,14 +385,29 @@ struct DijetFinderQATask { std::vector> jetPtcuts_D; std::vector> jetPtcuts_P; - for (auto& jet : mcdjets) { - if (jet.has_matchedJetGeo()) { - for (auto& matchedJet : jet.template matchedJetPt_as()) { - if (matchedJet.pt() > setJetPtCut) { - jetPtcuts_D.push_back({jet.pt(), jet.eta(), jet.phi()}); - jetPtcuts_P.push_back({matchedJet.pt(), matchedJet.eta(), matchedJet.phi()}); - break; + for (auto& mcdjet : mcdjets) { + if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + if (!isAcceptedJet(mcdjet)) { + continue; + } + if (mcdjet.pt() < setJetPtCut) { + continue; + } + if (mcdjet.has_matchedJetGeo()) { + for (auto& matchedjet : mcdjet.template matchedJetPt_as()) { + if (matchedjet.pt() < setJetPtCut) { + continue; + } + if (!jetfindingutilities::isInEtaAcceptance(matchedjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + if (!isAcceptedJet(matchedjet)) { + continue; } + jetPtcuts_D.push_back({mcdjet.pt(), mcdjet.eta(), mcdjet.phi()}); + jetPtcuts_P.push_back({matchedjet.pt(), matchedjet.eta(), matchedjet.phi()}); } } } @@ -317,34 +415,48 @@ struct DijetFinderQATask { if (jetPtcuts_D.size() >= 2 && jetPtcuts_P.size() >= 2) { auto& leading_jet_D = jetPtcuts_D[0]; auto& leading_jet_P = jetPtcuts_P[0]; - bool found_pair = false; - for (size_t i = 1; i < jetPtcuts_D.size() && !found_pair; i++) { - auto& candidate_jet_D = jetPtcuts_D[i]; - auto& candidate_jet_P = jetPtcuts_P[i]; + std::array candidate_jet_D{}; + std::array candidate_jet_P{}; - Double_t dphi_D = fabs(leading_jet_D[2] - candidate_jet_D[2]); - Double_t deta_D = fabs(leading_jet_D[1] - candidate_jet_D[1]); - Double_t dphi_P = fabs(leading_jet_P[2] - candidate_jet_P[2]); - Double_t deta_P = fabs(leading_jet_P[1] - candidate_jet_P[1]); - Double_t condition = fabs(dphi_D - M_PI); + auto dphi_D = 0.; + auto dphi_P = 0.; - if (condition < setPhiCut * M_PI) { - double pt1_D = leading_jet_D[0]; - double pt2_D = candidate_jet_D[0]; - double dijet_mass_D = sqrt(2 * pt1_D * pt2_D * (cosh(deta_D) - cos(dphi_D))); - - double pt1_P = leading_jet_P[0]; - double pt2_P = candidate_jet_P[0]; - double dijet_mass_P = sqrt(2 * pt1_P * pt2_P * (cosh(deta_P) - cos(dphi_P))); + bool found_pair_MCD = false; + bool found_pair_MCP = false; - fillMassHistogramsMCMatched(dijet_mass_P, dijet_mass_D); - found_pair = true; + for (size_t i = 1; i < jetPtcuts_D.size() && !found_pair_MCD; i++) { + candidate_jet_D = jetPtcuts_D[i]; + dphi_D = fabs(leading_jet_D[2] - candidate_jet_D[2]); + Double_t condition = fabs(dphi_D - M_PI); + if (condition > setPhiCut * M_PI) { + continue; + } + found_pair_MCD = true; + } + for (size_t i = 1; i < jetPtcuts_P.size() && !found_pair_MCP; i++) { + candidate_jet_P = jetPtcuts_P[i]; + dphi_P = fabs(leading_jet_P[2] - candidate_jet_P[2]); + Double_t condition = fabs(dphi_P - M_PI); + if (condition > setPhiCut * M_PI) { + continue; } + found_pair_MCP = true; + } + if (found_pair_MCD && found_pair_MCP) { + Double_t deta_D = fabs(leading_jet_D[1] - candidate_jet_D[1]); + Double_t deta_P = fabs(leading_jet_P[1] - candidate_jet_P[1]); + double pt1_D = leading_jet_D[0]; + double pt2_D = candidate_jet_D[0]; + double pt1_P = leading_jet_P[0]; + double pt2_P = candidate_jet_P[0]; + double dijet_mass_D = sqrt(2 * pt1_D * pt2_D * (cosh(deta_D) - cos(dphi_D))); + double dijet_mass_P = sqrt(2 * pt1_P * pt2_P * (cosh(deta_P) - cos(dphi_P))); + fillMassHistogramsMCPMCDMatched(dijet_mass_P, dijet_mass_D); } } } - PROCESS_SWITCH(DijetFinderQATask, processDijetMCMatched, "QA for invariant mass of dijet in mcmactched", false); + PROCESS_SWITCH(DijetFinderQATask, processDijetMCPMCDMatched, "QA for invariant mass of dijet in mcmactched", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGJE/Tasks/emcClusterMonitor.cxx b/PWGJE/Tasks/emcClusterMonitor.cxx index 9db525fe409..37ee979cc67 100644 --- a/PWGJE/Tasks/emcClusterMonitor.cxx +++ b/PWGJE/Tasks/emcClusterMonitor.cxx @@ -100,31 +100,31 @@ struct ClusterMonitor { const AxisSpec thAxisCellTimeMean{1500, -600, 900, "#LT#it{t}_{cell}#GT (ns)"}; // event properties - mHistManager.add("eventsAll", "Number of events", o2HistType::kTH1F, {{1, 0.5, 1.5}}); - mHistManager.add("eventsSelected", "Number of events", o2HistType::kTH1F, {{1, 0.5, 1.5}}); - mHistManager.add("eventBCAll", "Bunch crossing ID of event (all events)", o2HistType::kTH1F, {bcAxis}); - mHistManager.add("eventBCSelected", "Bunch crossing ID of event (selected events)", o2HistType::kTH1F, {bcAxis}); - mHistManager.add("eventVertexZAll", "z-vertex of event (all events)", o2HistType::kTH1F, {{200, -20, 20}}); - mHistManager.add("eventVertexZSelected", "z-vertex of event (selected events)", o2HistType::kTH1F, {{200, -20, 20}}); - mHistManager.add("numberOfClustersEvents", "number of clusters per event (selected events)", o2HistType::kTH1F, {numberClustersAxis}); - mHistManager.add("numberOfClustersBC", "number of clusters per bunch crossing (ambiguous BCs)", o2HistType::kTH1F, {numberClustersAxis}); - mHistManager.add("numberOfClustersEventsRejected", "number of clusters per event (rejected events)", o2HistType::kTH1F, {numberClustersAxis}); + mHistManager.add("eventsAll", "Number of events", o2HistType::kTH1D, {{1, 0.5, 1.5}}); + mHistManager.add("eventsSelected", "Number of events", o2HistType::kTH1D, {{1, 0.5, 1.5}}); + mHistManager.add("eventBCAll", "Bunch crossing ID of event (all events)", o2HistType::kTH1D, {bcAxis}); + mHistManager.add("eventBCSelected", "Bunch crossing ID of event (selected events)", o2HistType::kTH1D, {bcAxis}); + mHistManager.add("eventVertexZAll", "z-vertex of event (all events)", o2HistType::kTH1D, {{200, -20, 20}}); + mHistManager.add("eventVertexZSelected", "z-vertex of event (selected events)", o2HistType::kTH1D, {{200, -20, 20}}); + mHistManager.add("numberOfClustersEvents", "number of clusters per event (selected events)", o2HistType::kTH1D, {numberClustersAxis}); + mHistManager.add("numberOfClustersBC", "number of clusters per bunch crossing (ambiguous BCs)", o2HistType::kTH1D, {numberClustersAxis}); + mHistManager.add("numberOfClustersEventsRejected", "number of clusters per event (rejected events)", o2HistType::kTH1D, {numberClustersAxis}); mHistManager.add("numberOfClustersSMEvents", "number of clusters per supermodule per event (selected events)", o2HistType::kTH2F, {numberClustersAxis, {20, -0.5, 19.5, "SupermoduleID"}}); mHistManager.add("numberOfClustersSMBC", "number of clusters per supermodule per bunch crossing (ambiguous BCs)", o2HistType::kTH2F, {numberClustersAxis, {20, -0.5, 19.5, "SupermoduleID"}}); // cluster properties (matched clusters) - mHistManager.add("clusterE", "Energy of cluster", o2HistType::kTH1F, {energyAxis}); - mHistManager.add("clusterEMatched", "Energy of cluster (with match)", o2HistType::kTH1F, {energyAxis}); + mHistManager.add("clusterE", "Energy of cluster", o2HistType::kTH1D, {energyAxis}); + mHistManager.add("clusterEMatched", "Energy of cluster (with match)", o2HistType::kTH1D, {energyAxis}); mHistManager.add("clusterESupermodule", "Energy of the cluster vs. supermoduleID", o2HistType::kTH2F, {energyAxis, supermoduleAxis}); - mHistManager.add("clusterE_SimpleBinning", "Energy of cluster", o2HistType::kTH1F, {{2000, 0, 200}}); + mHistManager.add("clusterE_SimpleBinning", "Energy of cluster", o2HistType::kTH1D, {{2000, 0, 200}}); mHistManager.add("clusterEtaPhi", "Eta and phi of cluster", o2HistType::kTH2F, {{100, -1, 1}, {100, 0, 2 * TMath::Pi()}}); - mHistManager.add("clusterM02", "M02 of cluster", o2HistType::kTH1F, {{400, 0, 5}}); - mHistManager.add("clusterM20", "M20 of cluster", o2HistType::kTH1F, {{400, 0, 2.5}}); - mHistManager.add("clusterNLM", "Number of local maxima of cluster", o2HistType::kTH1I, {{10, 0, 10}}); - mHistManager.add("clusterNCells", "Number of cells in cluster", o2HistType::kTH1I, {{50, 0, 50}}); - mHistManager.add("clusterDistanceToBadChannel", "Distance to bad channel", o2HistType::kTH1F, {{100, 0, 100}}); + mHistManager.add("clusterM02", "M02 of cluster", o2HistType::kTH1D, {{400, 0, 5}}); + mHistManager.add("clusterM20", "M20 of cluster", o2HistType::kTH1D, {{400, 0, 2.5}}); + mHistManager.add("clusterNLM", "Number of local maxima of cluster", o2HistType::kTH1D, {{10, 0, 10}}); + mHistManager.add("clusterNCells", "Number of cells in cluster", o2HistType::kTH1D, {{50, 0, 50}}); + mHistManager.add("clusterDistanceToBadChannel", "Distance to bad channel", o2HistType::kTH1D, {{100, 0, 100}}); mHistManager.add("clusterTimeVsE", "Cluster time vs energy", o2HistType::kTH2F, {timeAxis, energyAxis}); - mHistManager.add("clusterAmpFractionLeadingCell", "Fraction of energy in leading cell", o2HistType::kTH1F, {{100, 0, 1}}); + mHistManager.add("clusterAmpFractionLeadingCell", "Fraction of energy in leading cell", o2HistType::kTH1D, {{100, 0, 1}}); mHistManager.add("clusterCellTimeDiff", "Cell time difference in clusters", o2HistType::kTH1D, {thAxisCellTimeDiff}); mHistManager.add("clusterCellTimeMean", "Mean cell time per cluster", o2HistType::kTH1D, {thAxisCellTimeMean}); diff --git a/PWGJE/Tasks/fullJetSpectraPP.cxx b/PWGJE/Tasks/fullJetSpectra.cxx similarity index 52% rename from PWGJE/Tasks/fullJetSpectraPP.cxx rename to PWGJE/Tasks/fullJetSpectra.cxx index a8eb7399502..9c34aece80d 100644 --- a/PWGJE/Tasks/fullJetSpectraPP.cxx +++ b/PWGJE/Tasks/fullJetSpectra.cxx @@ -8,41 +8,43 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. - -// FullJet Spectra in pp -// // +/// \file fullJetSpectra.cxx +/// \brief Task for full jet spectra studies in pp collisions. /// \author Archita Rani Dash -#include -#include -#include -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/ASoA.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" -#include "Framework/RunningWorkflowInfo.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGJE/Core/JetDerivedDataUtilities.h" +#include "PWGJE/Core/JetFinder.h" +#include "PWGJE/Core/JetFindingUtilities.h" +#include "PWGJE/Core/JetUtilities.h" +#include "PWGJE/DataModel/EMCALClusters.h" +#include "PWGJE/DataModel/EMCALMatchedCollisions.h" +#include "PWGJE/DataModel/Jet.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "EventFiltering/filterTables.h" -#include "PWGHF/Core/HfHelper.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/ASoA.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/Logger.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" -#include "PWGJE/DataModel/Jet.h" -#include "PWGJE/DataModel/EMCALClusters.h" -#include "PWGJE/DataModel/EMCALMatchedCollisions.h" -#include "PWGJE/Core/JetFinder.h" -#include "PWGJE/Core/JetUtilities.h" -#include "PWGJE/Core/JetDerivedDataUtilities.h" -#include "PWGJE/Core/JetFindingUtilities.h" +#include -#include "EventFiltering/filterTables.h" +#include +#include +#include +#include using namespace std; using namespace o2; @@ -51,12 +53,17 @@ using namespace o2::framework; using namespace o2::framework::expressions; // using namespace jetderiveddatautilities; -struct FullJetSpectrapp { +struct FullJetSpectra { HistogramRegistry registry; + // MC Sample split configurables + /* Configurable mcSplitSeed{"mcSplitSeed", 12345, "Seed for reproducible MC event splitting"}; + Configurable mcClosureSplitFrac{"mcClosureSplitFrac", 0.2f, "Fraction of MC events for closure test (MCD)"}; + Configurable doMcClosure{"doMcClosure", false, "Enable random splitting for MC closure test"}; + */ // Event configurables - Configurable VertexZCut{"VertexZCut", 10.0f, "Accepted z-vertex range"}; + Configurable vertexZCut{"vertexZCut", 10.0f, "Accepted z-vertex range"}; Configurable centralityMin{"centralityMin", -999.0, "minimum centrality"}; Configurable centralityMax{"centralityMax", 999.0, "maximum centrality"}; Configurable doEMCALEventWorkaround{"doEMCALEventWorkaround", false, "apply the workaround to read the EMC trigger bit by requiring a cell content in the EMCAL"}; @@ -88,8 +95,7 @@ struct FullJetSpectrapp { Configurable particleSelections{"particleSelections", "PhysicalPrimary", "set particle selections"}; // Cluster configurables - - Configurable clusterDefinitionS{"clusterDefinition", "kV3Default", "cluster definition to be selected, e.g. V3Default"}; + Configurable clusterDefinitionS{"clusterDefinitionS", "kV3Default", "cluster definition to be selected, e.g. V3Default"}; Configurable clusterEtaMin{"clusterEtaMin", -0.7, "minimum cluster eta"}; Configurable clusterEtaMax{"clusterEtaMax", 0.7, "maximum cluster eta"}; Configurable clusterPhiMin{"clusterPhiMin", 1.396, "minimum cluster phi"}; @@ -105,6 +111,8 @@ struct FullJetSpectrapp { Configurable pTHatAbsoluteMin{"pTHatAbsoluteMin", -99.0, "minimum value of pTHat"}; int trackSelection = -1; + const float kJetAreaFractionMinThreshold = -98.0f; + const float kLeadingConstituentPtMinThreshold = -98.0f; std::vector eventSelectionBits; std::vector filledJetR; std::vector jetRadiiValues; @@ -113,48 +121,109 @@ struct FullJetSpectrapp { Service pdgDatabase; + // Random splitter instance + /* TRandom3 randGen; + // float eventRandomValue = -1.0; // default invalid + // Cache to store random values per MC collision ID + std::unordered_map mcCollisionRandomValues; + */ + /* + MC CLOSURE SPLITTING LOGIC -> still not working across different process functions. Not so trivial in O2Physics Framework! + -------------------------- + • doMcClosure=true activates MC sample splitting. + • Each event gets ONE random value in [0, 1), stored in eventRandomValue. + • Events are split as: + - ≤ mcClosureSplitFrac -> Closure (MCD) + - > mcClosureSplitFrac -> Response (MCP + Matched) + • This ensures mutually exclusive processing — NO double-counting. + • eventRandomValue is reset to -1 after each event -> this is done by the `endOfEvent` defined at the end + */ + // Add Collision Histograms' Bin Labels for clarity void labelCollisionHistograms(HistogramRegistry& registry) { - if (doprocessTracks) { - auto h_collisions_unweighted = registry.get(HIST("h_collisions_unweighted")); - h_collisions_unweighted->GetXaxis()->SetBinLabel(1, "AllUnweightedDetColl"); - h_collisions_unweighted->GetXaxis()->SetBinLabel(2, "UnweightedCollWithVertexZ"); - h_collisions_unweighted->GetXaxis()->SetBinLabel(3, "EMCAcceptedUnweightedColl"); - h_collisions_unweighted->GetXaxis()->SetBinLabel(4, "UnweightedCollAfterTrackSel"); + if (doprocessDataTracks || doprocessMCTracks) { + auto hCollisionsUnweighted = registry.get(HIST("hCollisionsUnweighted")); + hCollisionsUnweighted->GetXaxis()->SetBinLabel(1, "allDetColl"); + hCollisionsUnweighted->GetXaxis()->SetBinLabel(2, "DetCollWithVertexZ"); + hCollisionsUnweighted->GetXaxis()->SetBinLabel(3, "MBRejectedDetEvents"); + hCollisionsUnweighted->GetXaxis()->SetBinLabel(4, "EventsNotSatisfyingEventSelection"); + hCollisionsUnweighted->GetXaxis()->SetBinLabel(5, "EMCreadoutDetEventsWithkTVXinEMC"); + hCollisionsUnweighted->GetXaxis()->SetBinLabel(6, "AllRejectedEventsAfterEMCEventSelection"); + hCollisionsUnweighted->GetXaxis()->SetBinLabel(7, "EMCAcceptedDetColl"); + hCollisionsUnweighted->GetXaxis()->SetBinLabel(8, "EMCAcceptedCollAfterTrackSel"); } if (doprocessTracksWeighted) { - auto h_collisions_weighted = registry.get(HIST("h_collisions_weighted")); - h_collisions_weighted->GetXaxis()->SetBinLabel(1, "AllWeightedDetColl"); - h_collisions_weighted->GetXaxis()->SetBinLabel(2, "WeightedCollWithVertexZ"); - h_collisions_weighted->GetXaxis()->SetBinLabel(3, "EMCAcceptedWeightedColl"); - h_collisions_weighted->GetXaxis()->SetBinLabel(4, "WeightedCollAfterTrackSel"); + auto hCollisionsWeighted = registry.get(HIST("hCollisionsWeighted")); + hCollisionsWeighted->GetXaxis()->SetBinLabel(1, "AllWeightedDetColl"); + hCollisionsWeighted->GetXaxis()->SetBinLabel(2, "WeightedCollWithVertexZ"); + hCollisionsWeighted->GetXaxis()->SetBinLabel(3, "MBRejectedDetEvents"); + hCollisionsWeighted->GetXaxis()->SetBinLabel(4, "EventsNotSatisfyingEventSelection"); + hCollisionsWeighted->GetXaxis()->SetBinLabel(5, "EMCreadoutDetJJEventsWithkTVXinEMC"); + hCollisionsWeighted->GetXaxis()->SetBinLabel(6, "AllRejectedEventsAfterEMCEventSelection"); + hCollisionsWeighted->GetXaxis()->SetBinLabel(7, "EMCAcceptedWeightedDetColl"); + hCollisionsWeighted->GetXaxis()->SetBinLabel(8, "EMCAcceptedWeightedCollAfterTrackSel"); } if (doprocessJetsData || doprocessJetsMCD || doprocessJetsMCDWeighted) { - auto h_Detcollision_counter = registry.get(HIST("h_Detcollision_counter")); - h_Detcollision_counter->GetXaxis()->SetBinLabel(1, "allDetColl"); - h_Detcollision_counter->GetXaxis()->SetBinLabel(2, "DetCollWithVertexZ"); - h_Detcollision_counter->GetXaxis()->SetBinLabel(3, "EMCAcceptedDetColl"); + auto hDetcollisionCounter = registry.get(HIST("hDetcollisionCounter")); + hDetcollisionCounter->GetXaxis()->SetBinLabel(1, "allDetColl"); + hDetcollisionCounter->GetXaxis()->SetBinLabel(2, "DetCollWithVertexZ"); + hDetcollisionCounter->GetXaxis()->SetBinLabel(3, "RejectedDetCollWithOutliers"); + hDetcollisionCounter->GetXaxis()->SetBinLabel(4, "MBRejectedDetEvents"); + hDetcollisionCounter->GetXaxis()->SetBinLabel(5, "EventsNotSatisfyingEventSelection"); + hDetcollisionCounter->GetXaxis()->SetBinLabel(6, "EMCreadoutDetEventsWithkTVXinEMC"); + hDetcollisionCounter->GetXaxis()->SetBinLabel(7, "AllRejectedEventsAfterEMCEventSelection"); + hDetcollisionCounter->GetXaxis()->SetBinLabel(8, "EMCAcceptedDetColl"); } if (doprocessJetsMCP || doprocessJetsMCPWeighted) { - auto h_Partcollision_counter = registry.get(HIST("h_Partcollision_counter")); - h_Partcollision_counter->GetXaxis()->SetBinLabel(1, "allMcColl"); - h_Partcollision_counter->GetXaxis()->SetBinLabel(2, "McCollWithVertexZ"); - h_Partcollision_counter->GetXaxis()->SetBinLabel(3, "DetCollWithSize>1"); - h_Partcollision_counter->GetXaxis()->SetBinLabel(4, "EMCAcceptedDetColl"); + auto hPartcollisionCounter = registry.get(HIST("hPartcollisionCounter")); + hPartcollisionCounter->GetXaxis()->SetBinLabel(1, "allMcColl"); + hPartcollisionCounter->GetXaxis()->SetBinLabel(2, "McCollWithVertexZ"); + hPartcollisionCounter->GetXaxis()->SetBinLabel(3, "PartCollWithSize>1"); + hPartcollisionCounter->GetXaxis()->SetBinLabel(4, "RejectedPartCollForDetCollWithSize0"); + hPartcollisionCounter->GetXaxis()->SetBinLabel(5, "RejectedPartCollWithOutliers"); + hPartcollisionCounter->GetXaxis()->SetBinLabel(6, "MBRejectedPartEvents"); + hPartcollisionCounter->GetXaxis()->SetBinLabel(7, "EMCreadoutDetJJEventsWithkTVXinEMC"); + hPartcollisionCounter->GetXaxis()->SetBinLabel(8, "AllRejectedPartEventsAfterEMCEventSelection"); + hPartcollisionCounter->GetXaxis()->SetBinLabel(9, "EMCAcceptedPartColl"); } if (doprocessJetsMCPMCDMatched || doprocessJetsMCPMCDMatchedWeighted) { - auto h_Matchedcollision_counter = registry.get(HIST("h_Matchedcollision_counter")); - h_Matchedcollision_counter->GetXaxis()->SetBinLabel(1, "allDetColl"); - h_Matchedcollision_counter->GetXaxis()->SetBinLabel(2, "DetCollWithVertexZ"); - h_Matchedcollision_counter->GetXaxis()->SetBinLabel(3, "EMCAcceptedDetColl"); + auto hMatchedcollisionCounter = registry.get(HIST("hMatchedcollisionCounter")); + hMatchedcollisionCounter->GetXaxis()->SetBinLabel(1, "allDetColl"); + hMatchedcollisionCounter->GetXaxis()->SetBinLabel(2, "DetCollWithVertexZ"); + hMatchedcollisionCounter->GetXaxis()->SetBinLabel(3, "RejectedDetCollWithOutliers"); + hMatchedcollisionCounter->GetXaxis()->SetBinLabel(4, "RejectedPartCollWithOutliers"); + hMatchedcollisionCounter->GetXaxis()->SetBinLabel(5, "EMCMBRejectedDetColl"); + hMatchedcollisionCounter->GetXaxis()->SetBinLabel(6, "EventsNotSatisfyingEventSelection"); + hMatchedcollisionCounter->GetXaxis()->SetBinLabel(7, "EMCreadoutDetJJEventsWithkTVXinEMC"); + hMatchedcollisionCounter->GetXaxis()->SetBinLabel(8, "AllRejectedDetEventsAfterEMCEventSelection"); + hMatchedcollisionCounter->GetXaxis()->SetBinLabel(9, "EMCAcceptedDetColl"); + } + + if (doprocessMBCollisionsDATAWithMultiplicity || doprocessMBCollisionsWithMultiplicity || doprocessCollisionsWeightedWithMultiplicity) { + auto hEventmultiplicityCounter = registry.get(HIST("hEventmultiplicityCounter")); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(1, "allDetColl"); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(2, "DetCollWithVertexZ"); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(3, "MBRejectedDetEvents"); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(4, "EventsNotSatisfyingEventSelection"); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(5, "EMCreadoutDetEventsWithkTVXinEMC"); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(6, "AllRejectedEventsAfterEMCEventSelection"); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(7, "EMCAcceptedDetColl"); } } + // Add Bin Labels for the MC Split Event Counter + /* void labelMCSplitHistogram(HistogramRegistry& registry) { + auto hSpliteventSelector = registry.get(HIST("hSpliteventSelector")); + hSpliteventSelector->GetXaxis()->SetBinLabel(1, "MCD"); + hSpliteventSelector->GetXaxis()->SetBinLabel(2, "MCP"); + hSpliteventSelector->GetXaxis()->SetBinLabel(3, "MatchedforRM"); +} +*/ void init(o2::framework::InitContext&) { trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); @@ -162,19 +231,46 @@ struct FullJetSpectrapp { particleSelection = static_cast(particleSelections); jetRadiiValues = (std::vector)jetRadii; + /* if (doMcClosure) { + // randGen.SetSeed(mcSplitSeed); + // randGen.SetSeed(static_cast(std::time(nullptr))); + // int seed = mcSplitSeed >= 0 ? mcSplitSeed : static_cast(std::time(nullptr)); + // randGen.SetSeed(seed); + // LOGF(info, "MC closure seed = %d", seed); + + int seed = mcSplitSeed >= 0 ? mcSplitSeed : static_cast(std::time(nullptr)); + randGen.SetSeed(seed); + LOGF(info, "MC closure splitting enabled with seed = %d, split fraction = %.2f", seed, static_cast(mcClosureSplitFrac)); + + registry.add("hSpliteventSelector", "Random MC Split Selector;Split Type;Entries",{HistType::kTH1F, {{3, 0.0, 3.0}}}); // 0=MCD, 1=MCP, 2=RM + + //individual processes' event counters for sanity checks + registry.add("h_MCD_splitevent_counter", "Events into MCD split", {HistType::kTH1F, {{1, 0.0, 1.0}}}); + registry.add("h_MCP_splitevent_counter", "Events into MCP split", {HistType::kTH1F, {{1, 0.0, 1.0}}}); + registry.add("h_Matched_splitevent_counter", "Events into Matched split", {HistType::kTH1F, {{1, 0.0, 1.0}}}); + registry.add("hRandomValueDebug", "Random values for debugging;Random Value;Entries", {HistType::kTH1F, {{100, 0.0, 1.0}}}); + + // DEBUG: Add counters for total events processed (before splitting) + registry.add("h_MCD_total_events", "Total MCD events processed", {HistType::kTH1F, {{1, 0.0, 1.0}}}); + registry.add("h_MCP_total_events", "Total MCP events processed", {HistType::kTH1F, {{1, 0.0, 1.0}}}); + registry.add("h_Matched_total_events", "Total Matched events processed", {HistType::kTH1F, {{1, 0.0, 1.0}}}); + registry.add("hMCCollisionIdDebug_MCP", "MC Collision Ids being processed", {HistType::kTH1F, {{100000, 0.0, 100000.0}}}); + + } + */ for (std::size_t iJetRadius = 0; iJetRadius < jetRadiiValues.size(); iJetRadius++) { filledJetR.push_back(0.0); } auto jetRadiiBins = (std::vector)jetRadii; if (jetRadiiBins.size() > 1) { - jetRadiiBins.push_back(jetRadiiBins[jetRadiiBins.size() - 1] + (TMath::Abs(jetRadiiBins[jetRadiiBins.size() - 1] - jetRadiiBins[jetRadiiBins.size() - 2]))); + jetRadiiBins.push_back(jetRadiiBins[jetRadiiBins.size() - 1] + (std::abs(jetRadiiBins[jetRadiiBins.size() - 1] - jetRadiiBins[jetRadiiBins.size() - 2]))); } else { jetRadiiBins.push_back(jetRadiiBins[jetRadiiBins.size() - 1] + 0.1); } // Track QA histograms - if (doprocessTracks || doprocessTracksWeighted) { - registry.add("h_collisions_unweighted", "event status; event status;entries", {HistType::kTH1F, {{12, 0., 12.0}}}); + if (doprocessDataTracks || doprocessMCTracks || doprocessTracksWeighted) { + registry.add("hCollisionsUnweighted", "event status; event status;entries", {HistType::kTH1F, {{12, 0., 12.0}}}); registry.add("h_track_pt", "track pT;#it{p}_{T,track} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); registry.add("h_track_eta", "track #eta;#eta_{track};entries", {HistType::kTH1F, {{100, -1., 1.}}}); @@ -191,21 +287,22 @@ struct FullJetSpectrapp { registry.add("h_cluster_energysum", "cluster energy sum;Sum of cluster energy per event;entries", {HistType::kTH1F, {{400, 0., 400.}}}); if (doprocessTracksWeighted) { - registry.add("h_collisions_weighted", "event status;event status;entries", {HistType::kTH1F, {{12, 0.0, 12.0}}}); + registry.add("hCollisionsWeighted", "event status;event status;entries", {HistType::kTH1F, {{12, 0.0, 12.0}}}); } } // Jet QA histograms if (doprocessJetsData || doprocessJetsMCD || doprocessJetsMCDWeighted) { - registry.add("h_Detcollision_counter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.}}}); + + registry.add("hDetcollisionCounter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.}}}); registry.add("h_full_jet_pt", "#it{p}_{T,jet};#it{p}_{T_jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); registry.add("h_full_jet_pt_pTHatcut", "#it{p}_{T,jet};#it{p}_{T_jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); registry.add("h_full_jet_eta", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1., 1.}}}); registry.add("h_full_jet_phi", "jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, 0., 7.}}}); registry.add("h_full_jet_clusterTime", "Time of cluster", HistType::kTH1F, {{500, -250, 250, "#it{t}_{cls} (ns)"}}); - registry.add("h2_full_jet_NEF", "#it{p}_{T,jet} vs NEF at Det Level; #it{p}_{T,jet} (GeV/#it{c});NEF", {HistType::kTH2F, {{350, 0., 350.}, {105, 0., 1.05}}}); - registry.add("h2_full_jet_NEF_rejected", "#it{p}_{T,jet} vs NEF at Det Level for rejected events; #it{p}_{T,jet} (GeV/#it{c});NEF", {HistType::kTH2F, {{350, 0., 350.}, {105, 0., 1.05}}}); + registry.add("h2_full_jet_nef", "#it{p}_{T,jet} vs nef at Det Level; #it{p}_{T,jet} (GeV/#it{c});nef", {HistType::kTH2F, {{350, 0., 350.}, {105, 0., 1.05}}}); + registry.add("h2_full_jet_nef_rejected", "#it{p}_{T,jet} vs nef at Det Level for rejected events; #it{p}_{T,jet} (GeV/#it{c});nef", {HistType::kTH2F, {{350, 0., 350.}, {105, 0., 1.05}}}); registry.add("h_Detjet_ntracks", "#it{p}_{T,track};#it{p}_{T,track} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); registry.add("h2_full_jet_chargedconstituents", "Number of charged constituents at Det Level;#it{p}_{T,jet} (GeV/#it{c});N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}); @@ -228,14 +325,14 @@ struct FullJetSpectrapp { registry.add("h2_jet_etaphi", "jet #eta vs jet #varphi; #eta_{jet};#varphi_{jet}", {HistType::kTH2F, {{100, -1., 1.}, {160, -1., 7.}}}); } if (doprocessJetsMCP || doprocessJetsMCPWeighted) { - registry.add("h_Partcollision_counter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}); + registry.add("hPartcollisionCounter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}); registry.add("h_full_mcpjet_tablesize", "", {HistType::kTH1F, {{4, 0., 5.}}}); registry.add("h_full_mcpjet_ntracks", "", {HistType::kTH1F, {{200, -0.5, 200.}}}); registry.add("h_full_jet_pt_part", "jet pT;#it{p}_{T_jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); registry.add("h_full_jet_eta_part", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1., 1.}}}); registry.add("h_full_jet_phi_part", "jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, 0., 7.}}}); - registry.add("h2_full_jet_NEF_part", "#it{p}_{T,jet} vs NEF at Part Level;#it{p}_{T,jet} (GeV/#it{c});NEF", {HistType::kTH2F, {{350, 0., 350.}, {105, 0., 1.05}}}); + registry.add("h2_full_jet_nef_part", "#it{p}_{T,jet} vs nef at Part Level;#it{p}_{T,jet} (GeV/#it{c});nef", {HistType::kTH2F, {{350, 0., 350.}, {105, 0., 1.05}}}); registry.add("h_Partjet_ntracks", "#it{p}_{T,constituent};#it{p}_{T_constituent} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); registry.add("h2_full_jet_chargedconstituents_part", "Number of charged constituents at Part Level;#it{p}_{T,jet} (GeV/#it{c});N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}); @@ -253,12 +350,18 @@ struct FullJetSpectrapp { registry.add("h2_track_etaphi_part", "jet_track #eta vs jet_track #varphi; #eta_{track};#varphi_{track}", {HistType::kTH2F, {{500, -5., 5.}, {160, -1., 7.}}}); registry.add("h2_jet_etaphi_part", "jet #eta vs jet #varphi; #eta_{jet};#varphi_{jet}", {HistType::kTH2F, {{100, -1., 1.}, {160, -1., 7.}}}); - registry.add("h_NOmcpemcalcollisions", "event status;entries", {HistType::kTH1F, {{100, 0., 100.}}}); - registry.add("h_mcpemcalcollisions", "event status;entries", {HistType::kTH1F, {{100, 0., 100.}}}); + // registry.add("h_NOmcpemcalcollisions", "event status;entries", {HistType::kTH1F, {{100, 0., 100.}}}); + // registry.add("h_mcpemcalcollisions", "event status;entries", {HistType::kTH1F, {{100, 0., 100.}}}); + registry.add("h2_full_mcpjetOutsideFiducial_pt", "MCP jet outside EMC Fiducial Acceptance #it{p}_{T,part};#it{p}_{T,part} (GeV/c); Ncounts", {HistType::kTH2F, {{350, 0., 350.}, {10000, 0., 10000.}}}); + registry.add("h_full_mcpjetOutside_eta_part", "MCP jet #eta outside EMC Fiducial Acceptance;#eta_{jet};entries", {HistType::kTH1F, {{100, -1., 1.}}}); + registry.add("h_full_mcpjetOutside_phi_part", "MCP jet #varphi outside EMC Fiducial Acceptance;#varphi_{jet};entries", {HistType::kTH1F, {{160, 0., 7.}}}); + registry.add("h2_full_mcpjetInsideFiducial_pt", "MCP jet #it{p}_{T,part} inside EMC Fiducial Acceptance;#it{p}_{T,part} (GeV/c); Ncounts", {HistType::kTH2F, {{350, 0., 350.}, {10000, 0., 10000.}}}); + registry.add("h_full_mcpjetInside_eta_part", "MCP jet #eta inside EMC Fiducial Acceptance;#eta_{jet};entries", {HistType::kTH1F, {{100, -1., 1.}}}); + registry.add("h_full_mcpjetInside_phi_part", "MCP jet #varphi inside EMC Fiducial Acceptance;#varphi_{jet};entries", {HistType::kTH1F, {{160, 0., 7.}}}); } if (doprocessJetsMCPMCDMatched || doprocessJetsMCPMCDMatchedWeighted) { - registry.add("h_Matchedcollision_counter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}); + registry.add("hMatchedcollisionCounter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}); registry.add("h_full_matchedmcdjet_tablesize", "", {HistType::kTH1F, {{350, 0., 350.}}}); registry.add("h_full_matchedmcpjet_tablesize", "", {HistType::kTH1F, {{350, 0., 350.}}}); @@ -286,23 +389,49 @@ struct FullJetSpectrapp { registry.add("h2_full_jet_energyscaleChargedVsFullPart", "Jet Energy Scale (charged part, vs. full jet pt); p_{T,part} (GeV/c); (p_{T,det} - p_{T,part})/p_{T,part}", {HistType::kTH2F, {{400, 0., 400.}, {200, -1., 1.}}}); registry.add("h2_full_jet_energyscaleNeutralVsFullPart", "Jet Energy Scale (neutral part, vs. full jet pt); p_{T,part} (GeV/c); (p_{T,det} - p_{T,part})/p_{T,part}", {HistType::kTH2F, {{400, 0., 400.}, {200, -1., 1.}}}); registry.add("h2_full_fakemcdjets", "Fake MCD Jets; p_{T,det} (GeV/c); NCounts", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}); - registry.add("h2_full_fakemcpjets", "Fake MCP Jets; p_{T,part} (GeV/c); NCounts", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}); + registry.add("h2FullfakeMcpJets", "Fake MCP Jets; p_{T,part} (GeV/c); NCounts", {HistType::kTH2F, {{350, 0., 350.}, {100, 0., 100.}}}); + registry.add("h2_full_matchedmcpjet_pt", "Matched MCP jet in EMC Fiducial Acceptance #it{p}_{T,part};#it{p}_{T,part} (GeV/c); Ncounts", {HistType::kTH2F, {{350, 0., 350.}, {10000, 0., 10000.}}}); + // Response Matrix registry.add("h_full_jet_ResponseMatrix", "Full Jets Response Matrix; p_{T,det} (GeV/c); p_{T,part} (GeV/c)", {HistType::kTH2F, {{350, 0., 350.}, {350, 0., 350.}}}); } - if (doprocessCollisionsWeightedWithMultiplicity || doprocessMBCollisionsWithMultiplicity) { + if (doprocessCollisionsWeightedWithMultiplicity || doprocessMBCollisionsWithMultiplicity || doprocessMBCollisionsDATAWithMultiplicity) { + registry.add("hEventmultiplicityCounter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}); registry.add("h_FT0Mults_occupancy", "", {HistType::kTH1F, {{3500, 0., 3500.}}}); registry.add("h2_full_jet_FT0Amplitude", "; FT0C Amplitude; Counts", {HistType::kTH1F, {{3500, 0., 3500.}}}); registry.add("h2_full_jet_jetpTDetVsFT0Mults", "; p_{T,det} (GeV/c); FT0C Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}); - registry.add("h3_full_jet_jetpTDet_FT0Mults_NEF", "; p_{T,det} (GeV/c); FT0C Multiplicity, NEF", {HistType::kTH3F, {{350, 0., 350.}, {3500, 0., 3500.}, {105, 0.0, 1.05}}}); + registry.add("h3_full_jet_jetpTDet_FT0Mults_nef", "; p_{T,det} (GeV/c); FT0C Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {3500, 0., 3500.}, {105, 0.0, 1.05}}}); } // Label the histograms labelCollisionHistograms(registry); + // labelMCSplitHistogram(registry); } // init + // Get or generate random value for a specific MC collision + /* float getMCCollisionRandomValue(int64_t mcCollisionId) { + if (!doMcClosure) return 0.0f; + + // Check if I already have a random value for this MC collision + auto it = mcCollisionRandomValues.find(mcCollisionId); + if (it != mcCollisionRandomValues.end()) { + LOGF(debug, "Using cached random value %.4f for MC collision %lld", it->second, mcCollisionId); + return it->second; + } + + // Generate new random value for this MC collision + float randomVal = randGen.Uniform(0.0, 1.0); + mcCollisionRandomValues[mcCollisionId] = randomVal; + + // Debug histogram + registry.fill(HIST("hRandomValueDebug"), randomVal); + + LOGF(info, "Generated NEW random value %.4f for MC collision %lld", randomVal, mcCollisionId); + return randomVal; + } + */ using EMCCollisionsData = o2::soa::Join; // JetCollisions with EMCAL Collision Labels using EMCCollisionsMCD = o2::soa::Join; // where, JetCollisionsMCD = JetCollisions+JMcCollisionLbs @@ -313,33 +442,33 @@ struct FullJetSpectrapp { using JetTableMCPWeightedJoined = soa::Join; using JetTableMCDMatchedJoined = soa::Join; - using JetTableMCPMatchedJoined = soa::Join; + using jetMcpPerMcCollision = soa::Join; using JetTableMCDMatchedWeightedJoined = soa::Join; using JetTableMCPMatchedWeightedJoined = soa::Join; // Applying some cuts(filters) on collisions, tracks, clusters - Filter eventCuts = (nabs(aod::jcollision::posZ) < VertexZCut && aod::jcollision::centrality >= centralityMin && aod::jcollision::centrality < centralityMax); - // Filter EMCeventCuts = (nabs(aod::collision::posZ) < VertexZCut && aod::collision::centrality >= centralityMin && aod::collision::centrality < centralityMax); + Filter eventCuts = (nabs(aod::jcollision::posZ) < vertexZCut && aod::jcollision::centrality >= centralityMin && aod::jcollision::centrality < centralityMax); + // Filter EMCeventCuts = (nabs(aod::collision::posZ) < vertexZCut && aod::collision::centrality >= centralityMin && aod::collision::centrality < centralityMax); Filter trackCuts = (aod::jtrack::pt >= trackpTMin && aod::jtrack::pt < trackpTMax && aod::jtrack::eta > trackEtaMin && aod::jtrack::eta < trackEtaMax && aod::jtrack::phi >= trackPhiMin && aod::jtrack::phi <= trackPhiMax); aod::EMCALClusterDefinition clusterDefinition = aod::emcalcluster::getClusterDefinitionFromString(clusterDefinitionS.value); Filter clusterFilter = (aod::jcluster::definition == static_cast(clusterDefinition) && aod::jcluster::eta > clusterEtaMin && aod::jcluster::eta < clusterEtaMax && aod::jcluster::phi >= clusterPhiMin && aod::jcluster::phi <= clusterPhiMax && aod::jcluster::energy >= clusterEnergyMin && aod::jcluster::time > clusterTimeMin && aod::jcluster::time < clusterTimeMax && (clusterRejectExotics && aod::jcluster::isExotic != true)); - Preslice JetMCPPerMcCollision = aod::jet::mcCollisionId; + Preslice JetMCPPerMcCollision = aod::jet::mcCollisionId; PresliceUnsorted> CollisionsPerMCPCollision = aod::jmccollisionlb::mcCollisionId; template bool isAcceptedJet(U const& jet) { - if (jetAreaFractionMin > -98.0) { - if (jet.area() < jetAreaFractionMin * M_PI * (jet.r() / 100.0) * (jet.r() / 100.0)) { + if (jetAreaFractionMin > kJetAreaFractionMinThreshold) { + if (jet.area() < jetAreaFractionMin * o2::constants::math::PI * (jet.r() / 100.0) * (jet.r() / 100.0)) { return false; } } - if (leadingConstituentPtMin > -98.0) { + if (leadingConstituentPtMin > kLeadingConstituentPtMinThreshold) { bool isMinleadingConstituent = false; - for (auto& constituent : jet.template tracks_as()) { + for (const auto& constituent : jet.template tracks_as()) { if (constituent.pt() >= leadingConstituentPtMin) { isMinleadingConstituent = true; break; @@ -355,11 +484,6 @@ struct FullJetSpectrapp { template void fillJetHistograms(T const& jet, float weight = 1.0) { - float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); - if (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) { // for MCD jets only to remove outliers; setting pTHatMaxMCD = 1 improves purity - return; - } - float neutralEnergy = 0.0; double sumtrackE = 0.0; if (jet.r() == round(selectedJetsRadius * 100.0f)) { @@ -368,7 +492,7 @@ struct FullJetSpectrapp { registry.fill(HIST("h_full_jet_phi"), jet.phi(), weight); registry.fill(HIST("h2_jet_etaphi"), jet.eta(), jet.phi(), weight); - for (auto& cluster : jet.template clusters_as()) { + for (const auto& cluster : jet.template clusters_as()) { registry.fill(HIST("h2_full_jet_neutralconstituents"), jet.pt(), jet.clustersIds().size(), weight); neutralEnergy += cluster.energy(); @@ -380,10 +504,10 @@ struct FullJetSpectrapp { registry.fill(HIST("h_full_jet_neutralconstituents_energy"), cluster.energy(), weight); registry.fill(HIST("h_full_jet_neutralconstituents_energysum"), neutralEnergy, weight); } - auto NEF = neutralEnergy / jet.energy(); - registry.fill(HIST("h2_full_jet_NEF"), jet.pt(), NEF, weight); + auto nef = neutralEnergy / jet.energy(); + registry.fill(HIST("h2_full_jet_nef"), jet.pt(), nef, weight); - for (auto& jettrack : jet.template tracks_as()) { + for (const auto& jettrack : jet.template tracks_as()) { sumtrackE += jettrack.energy(); registry.fill(HIST("h_Detjet_ntracks"), jettrack.pt(), weight); @@ -402,30 +526,34 @@ struct FullJetSpectrapp { } // jet.r() } - // check for NEF distribution for rejected events + // check for nef distribution for rejected events template void fillRejectedJetHistograms(T const& jet, float weight = 1.0) { float neutralEnergy = 0.0; if (jet.r() == round(selectedJetsRadius * 100.0f)) { - for (auto& cluster : jet.template clusters_as()) { + for (const auto& cluster : jet.template clusters_as()) { neutralEnergy += cluster.energy(); } - auto NEF = neutralEnergy / jet.energy(); - registry.fill(HIST("h2_full_jet_NEF_rejected"), jet.pt(), NEF, weight); + auto nef = neutralEnergy / jet.energy(); + registry.fill(HIST("h2_full_jet_nef_rejected"), jet.pt(), nef, weight); } // jet.r() } template void fillMCPHistograms(T const& jet, float weight = 1.0) { - float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); - if (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) { // MCP outlier rejection - return; - } float neutralEnergy = 0.0; int neutralconsts = 0; int chargedconsts = 0; + int mcpjetOutsideFid = 0; + int mcpjetInsideFid = 0; + + auto isInFiducial = [&](auto const& jet) { + return jet.eta() >= jetEtaMin && jet.eta() <= jetEtaMax && + jet.phi() >= jetPhiMin && jet.phi() <= jetPhiMax; + }; + if (jet.r() == round(selectedJetsRadius * 100.0f)) { registry.fill(HIST("h_full_mcpjet_tablesize"), jet.size(), weight); registry.fill(HIST("h_full_mcpjet_ntracks"), jet.tracksIds().size(), weight); @@ -434,7 +562,21 @@ struct FullJetSpectrapp { registry.fill(HIST("h_full_jet_phi_part"), jet.phi(), weight); registry.fill(HIST("h2_jet_etaphi_part"), jet.eta(), jet.phi(), weight); - for (auto& constituent : jet.template tracks_as()) { + if (!isInFiducial(jet)) { + // jet is outside + mcpjetOutsideFid++; + registry.fill(HIST("h2_full_mcpjetOutsideFiducial_pt"), jet.pt(), mcpjetOutsideFid, weight); + registry.fill(HIST("h_full_mcpjetOutside_eta_part"), jet.eta(), weight); + registry.fill(HIST("h_full_mcpjetOutside_phi_part"), jet.phi(), weight); + } else { + // jet is inside + mcpjetInsideFid++; + registry.fill(HIST("h2_full_mcpjetInsideFiducial_pt"), jet.pt(), mcpjetInsideFid, weight); + registry.fill(HIST("h_full_mcpjetInside_eta_part"), jet.eta(), weight); + registry.fill(HIST("h_full_mcpjetInside_phi_part"), jet.phi(), weight); + } + + for (const auto& constituent : jet.template tracks_as()) { auto pdgParticle = pdgDatabase->GetParticle(constituent.pdgCode()); if (pdgParticle->Charge() == 0) { neutralconsts++; @@ -456,19 +598,16 @@ struct FullJetSpectrapp { registry.fill(HIST("h2_track_etaphi_part"), constituent.eta(), constituent.phi(), weight); } } // constituent loop - auto NEF = neutralEnergy / jet.energy(); - registry.fill(HIST("h2_full_jet_NEF_part"), jet.pt(), NEF, weight); - } + auto nef = neutralEnergy / jet.energy(); + registry.fill(HIST("h2_full_jet_nef_part"), jet.pt(), nef, weight); + } // jet.r() } template void fillTrackHistograms(T const& tracks, U const& clusters, float weight = 1.0) { double sumtrackE = 0.0; - float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); - if (pTHat < pTHatAbsoluteMin) { // Track outlier rejection - return; - } + for (auto const& track : tracks) { if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { continue; @@ -484,7 +623,7 @@ struct FullJetSpectrapp { double clusterpt = cluster.energy() / std::cosh(cluster.eta()); sumclusterE += cluster.energy(); - registry.fill(HIST("h_clusterTime"), cluster.time()); + registry.fill(HIST("h_clusterTime"), cluster.time(), weight); registry.fill(HIST("h_cluster_pt"), clusterpt, weight); registry.fill(HIST("h_cluster_eta"), cluster.eta(), weight); registry.fill(HIST("h_cluster_phi"), cluster.phi(), weight); @@ -496,20 +635,12 @@ struct FullJetSpectrapp { template void fillMatchedHistograms(T const& jetBase, float weight = 1.0) { - float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); - if (jetBase.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) { - return; - } - if (jetBase.has_matchedJetGeo()) { // geometrical jet matching only needed for pp - here,matching Base(Det.level) with Tag (Part. level) jets registry.fill(HIST("h_full_matchedmcdjet_tablesize"), jetBase.size(), weight); registry.fill(HIST("h_full_matchedmcdjet_ntracks"), jetBase.tracksIds().size(), weight); registry.fill(HIST("h2_matchedjet_etaphiDet"), jetBase.eta(), jetBase.phi(), weight); - for (auto& jetTag : jetBase.template matchedJetGeo_as>()) { - if (jetTag.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) { // MCP outlier rejection - continue; - } + for (const auto& jetTag : jetBase.template matchedJetGeo_as>()) { auto deltaEta = jetBase.eta() - jetTag.eta(); auto deltaPhi = jetBase.phi() - jetTag.phi(); auto deltaR = jetutilities::deltaR(jetBase, jetTag); @@ -537,31 +668,51 @@ struct FullJetSpectrapp { void processDummy(aod::JetCollisions const&) { } - PROCESS_SWITCH(FullJetSpectrapp, processDummy, "dummy task", true); + PROCESS_SWITCH(FullJetSpectra, processDummy, "dummy task", true); void processJetsData(soa::Filtered::iterator const& collision, FullJetTableDataJoined const& jets, aod::JetTracks const&, aod::JetClusters const&) { bool eventAccepted = false; - registry.fill(HIST("h_Detcollision_counter"), 0.5); + double weight = 1.0; + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); - if (fabs(collision.posZ()) > VertexZCut) { + registry.fill(HIST("hDetcollisionCounter"), 0.5); // allDetColl + if (std::fabs(collision.posZ()) > vertexZCut) { return; } - registry.fill(HIST("h_Detcollision_counter"), 1.5); + registry.fill(HIST("hDetcollisionCounter"), 1.5); // DetCollWithVertexZ + + // outlier check: for every outlier jet, reject the whole event + for (auto const& jet : jets) { + if (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) { // for MCD jets only to remove outliers; setting pTHatMaxMCD = 1 improves purity + registry.fill(HIST("hDetcollisionCounter"), 2.5); // RejectedDetCollWithOutliers + return; + } + // this cut only to be used for calculating Jet Purity and not for Response Matrix + // this is mainly applied to remove all high weight jets causing big fluctuations + if (jet.pt() > 1 * pTHat) { + registry.fill(HIST("h_full_jet_pt_pTHatcut"), jet.pt(), weight); + } + } + if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + registry.fill(HIST("hDetcollisionCounter"), 3.5); // MBRejectedDetEvents return; } if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + registry.fill(HIST("hDetcollisionCounter"), 4.5); // EventsNotSatisfyingEventSelection return; } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { + registry.fill(HIST("hDetcollisionCounter"), 5.5); // EMCreadoutDetEventsWithkTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { + registry.fill(HIST("hDetcollisionCounter"), 5.5); // EMCreadoutDetEventsWithkTVXinEMC eventAccepted = true; } } @@ -572,9 +723,10 @@ struct FullJetSpectrapp { fillRejectedJetHistograms(jet, 1.0); } } + registry.fill(HIST("hDetcollisionCounter"), 6.5); // AllRejectedDetEventsAfterEMCEventSelection return; } - registry.fill(HIST("h_Detcollision_counter"), 2.5); + registry.fill(HIST("hDetcollisionCounter"), 7.5); // EMCAcceptedDetColl for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { @@ -589,32 +741,75 @@ struct FullJetSpectrapp { fillJetHistograms(jet); } } - PROCESS_SWITCH(FullJetSpectrapp, processJetsData, "Full Jets Data", false); + PROCESS_SWITCH(FullJetSpectra, processJetsData, "Full Jets Data", false); void processJetsMCD(soa::Filtered::iterator const& collision, JetTableMCDJoined const& jets, aod::JetTracks const&, aod::JetClusters const&) { bool eventAccepted = false; + double weight = 1.0; + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); + + /* if (doMcClosure) { + // Count total events processed (before splitting decision) + registry.fill(HIST("h_MCD_total_events"), 0.5); - registry.fill(HIST("h_Detcollision_counter"), 0.5); - if (fabs(collision.posZ()) > VertexZCut) { + // DEBUG: Let's verify what collision IDs we're actually seeing + LOGF(info, "[MCD DEBUG] Processing MC collision ID: %lld", collision.mcCollisionId()); + + // Get random value for this MC collision + float eventRandomValue = getMCCollisionRandomValue(collision.mcCollisionId()); + + // MCD gets events with random value <= split fraction (20%) + if (eventRandomValue > mcClosureSplitFrac) { + LOGF(debug, "[MCD] Event REJECTED: rand = %.4f > split = %.2f (MC collision %d)", + eventRandomValue, static_cast(mcClosureSplitFrac), collision.mcCollisionId()); + return; // This event goes to MCP & Matched processes + } + + LOGF(info, "[MCD] Event ACCEPTED: rand = %.4f <= split = %.2f (MC collision %d)", + eventRandomValue, static_cast(mcClosureSplitFrac), collision.mcCollisionId()); + + registry.fill(HIST("hSpliteventSelector"), 0.5); // 20% Closure input for the measured spectra (reco) + registry.fill(HIST("h_MCD_splitevent_counter"), 0.5); + } + */ + registry.fill(HIST("hDetcollisionCounter"), 0.5); // allDetColl + if (std::fabs(collision.posZ()) > vertexZCut) { return; } - registry.fill(HIST("h_Detcollision_counter"), 1.5); + registry.fill(HIST("hDetcollisionCounter"), 1.5); // DetCollWithVertexZ + + // outlier check: for every outlier jet, reject the whole event + for (auto const& jet : jets) { + if (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) { // for MCD jets only to remove outliers; setting pTHatMaxMCD = 1 improves purity + registry.fill(HIST("hDetcollisionCounter"), 2.5); // RejectedDetCollWithOutliers + return; + } + // this cut only to be used for calculating Jet Purity and not for Response Matrix + // this is mainly applied to remove all high weight jets causing big fluctuations + if (jet.pt() > 1 * pTHat) { + registry.fill(HIST("h_full_jet_pt_pTHatcut"), jet.pt(), weight); + } + } if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + registry.fill(HIST("hDetcollisionCounter"), 3.5); // MBRejectedDetEvents return; } if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + registry.fill(HIST("hDetcollisionCounter"), 4.5); // EventsNotSatisfyingEventSelection return; } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { + registry.fill(HIST("hDetcollisionCounter"), 5.5); // EMCreadoutDetEventsWithkTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; + registry.fill(HIST("hDetcollisionCounter"), 5.5); // EMCreadoutDetEventsWithkTVXinEMC } } @@ -624,9 +819,10 @@ struct FullJetSpectrapp { fillRejectedJetHistograms(jet, 1.0); } } + registry.fill(HIST("hDetcollisionCounter"), 6.5); // AllRejectedDetEventsAfterEMCEventSelection return; } - registry.fill(HIST("h_Detcollision_counter"), 2.5); + registry.fill(HIST("hDetcollisionCounter"), 7.5); // EMCAcceptedDetColl for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { @@ -641,33 +837,73 @@ struct FullJetSpectrapp { fillJetHistograms(jet); } } - PROCESS_SWITCH(FullJetSpectrapp, processJetsMCD, "Full Jets at Detector Level", false); + PROCESS_SWITCH(FullJetSpectra, processJetsMCD, "Full Jets at Detector Level", false); void processJetsMCDWeighted(soa::Filtered::iterator const& collision, JetTableMCDWeightedJoined const& jets, aod::JMcCollisions const&, aod::JetTracks const&, aod::JetClusters const&) { bool eventAccepted = false; + double pTHat = 10. / (std::pow(collision.mcCollision().weight(), 1.0 / pTHatExponent)); + + /* if (doMcClosure) { + // Count total events processed (before splitting decision) + registry.fill(HIST("h_MCD_total_events"), 0.5); + + // DEBUG: Let's verify what collision IDs we're actually seeing + LOGF(info, "[MCD DEBUG] Processing MC collision ID: %lld", collision.mcCollisionId()); + + // Get random value for this MC collision + float eventRandomValue = getMCCollisionRandomValue(collision.mcCollisionId()); + + // MCD gets events with random value <= split fraction (20%) + if (eventRandomValue > mcClosureSplitFrac) { + LOGF(debug, "[MCD] Event REJECTED: rand = %.4f > split = %.2f (MC collision %d)", + eventRandomValue, static_cast(mcClosureSplitFrac), collision.mcCollisionId()); + return; // This event goes to MCP & Matched processes + } - registry.fill(HIST("h_Detcollision_counter"), 0.5); - if (fabs(collision.posZ()) > VertexZCut) { + LOGF(info, "[MCD] Event ACCEPTED: rand = %.4f <= split = %.2f (MC collision %d)", + eventRandomValue, static_cast(mcClosureSplitFrac), collision.mcCollisionId()); + + registry.fill(HIST("hSpliteventSelector"), 0.5); // 20% Closure input for the measured spectra (reco) + registry.fill(HIST("h_MCD_splitevent_counter"), 0.5); + } + */ + registry.fill(HIST("hDetcollisionCounter"), 0.5, collision.mcCollision().weight()); // allDetColl + if (std::fabs(collision.posZ()) > vertexZCut) { return; } - registry.fill(HIST("h_Detcollision_counter"), 1.5); + registry.fill(HIST("hDetcollisionCounter"), 1.5, collision.mcCollision().weight()); // DetCollWithVertexZ + // outlier check: for every outlier jet, reject the whole event + for (auto const& jet : jets) { + if (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) { // for MCD jets only to remove outliers; setting pTHatMaxMCD = 1 improves purity + registry.fill(HIST("hDetcollisionCounter"), 2.5, collision.mcCollision().weight()); // RejectedDetCollWithOutliers + return; + } + // this cut only to be used for calculating Jet Purity and not for Response Matrix + // this is mainly applied to remove all high weight jets causing big fluctuations + if (jet.pt() > 1 * pTHat) { + registry.fill(HIST("h_full_jet_pt_pTHatcut"), jet.pt(), collision.mcCollision().weight()); + } + } if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + registry.fill(HIST("hDetcollisionCounter"), 3.5, collision.mcCollision().weight()); // MBRejectedDetEvents return; } if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + registry.fill(HIST("hDetcollisionCounter"), 4.5, collision.mcCollision().weight()); // EventsNotSatisfyingEventSelection return; } - if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { + registry.fill(HIST("hDetcollisionCounter"), 5.5, collision.mcCollision().weight()); // EMCreadoutDetEventsWithkTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; + registry.fill(HIST("hDetcollisionCounter"), 5.5, collision.mcCollision().weight()); // EMCreadoutDetEventsWithkTVXinEMC } } @@ -677,9 +913,10 @@ struct FullJetSpectrapp { fillRejectedJetHistograms(jet, collision.mcCollision().weight()); } } + registry.fill(HIST("hDetcollisionCounter"), 6.5, collision.mcCollision().weight()); // AllRejectedDetEventsAfterEMCEventSelection return; } - registry.fill(HIST("h_Detcollision_counter"), 2.5); + registry.fill(HIST("hDetcollisionCounter"), 7.5, collision.mcCollision().weight()); // EMCAcceptedDetColl for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { @@ -691,56 +928,96 @@ struct FullJetSpectrapp { if (!isAcceptedJet(jet)) { continue; } - - // this cut only to be used for calculating Jet Purity and not for Response Matrix - // this is mainly applied to remove all high weight jets causing big fluctuations - double pTHat = 10. / (std::pow(collision.mcCollision().weight(), 1.0 / pTHatExponent)); - if (jet.pt() > 1 * pTHat) { - registry.fill(HIST("h_full_jet_pt_pTHatcut"), jet.pt(), collision.mcCollision().weight()); - } - fillJetHistograms(jet, collision.mcCollision().weight()); } } - PROCESS_SWITCH(FullJetSpectrapp, processJetsMCDWeighted, "Full Jets at Detector Level on weighted events", false); + PROCESS_SWITCH(FullJetSpectra, processJetsMCDWeighted, "Full Jets at Detector Level on weighted events", false); void processJetsMCP(aod::JetMcCollision const& mccollision, JetTableMCPJoined const& jets, aod::JetParticles const&, soa::SmallGroups const& collisions) { bool eventAccepted = false; + double weight = 1.0; + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); + + /* if (doMcClosure) { + // Count total events processed (before splitting decision) + registry.fill(HIST("h_MCP_total_events"), 0.5); - registry.fill(HIST("h_Partcollision_counter"), 0.5); - if (fabs(mccollision.posZ()) > VertexZCut) { + // DEBUG: Let's verify what collision IDs we're actually seeing + LOGF(info, "[MCP DEBUG] Processing MC collision ID: %lld", mccollision.globalIndex()); + + // Get random value for this MC collision + float eventRandomValue = getMCCollisionRandomValue(mccollision.globalIndex()); + + // DEBUG: Track which MC collisions we're processing + registry.fill(HIST("hMCCollisionIdDebug_MCP"), static_cast(mccollision.globalIndex() % 100000)); + + // MCP gets events with random value > split fraction (80%) + if (eventRandomValue <= mcClosureSplitFrac) { + LOGF(debug, "[MCP] Event REJECTED: rand = %.4f <= split = %.2f (MC collision %lld)", + eventRandomValue, static_cast(mcClosureSplitFrac), mccollision.globalIndex()); + return; // This event goes to MCD only + } + + LOGF(info, "[MCP] Event ACCEPTED: rand = %.4f > split = %.2f (MC collision %lld)", + eventRandomValue, static_cast(mcClosureSplitFrac), mccollision.globalIndex()); + + registry.fill(HIST("hSpliteventSelector"), 1.5); // remaining 80% input for MCP + registry.fill(HIST("h_MCP_splitevent_counter"), 0.5); + } + */ + registry.fill(HIST("hPartcollisionCounter"), 0.5); // allMcColl + if (std::fabs(mccollision.posZ()) > vertexZCut) { return; } - registry.fill(HIST("h_Partcollision_counter"), 1.5); + registry.fill(HIST("hPartcollisionCounter"), 1.5); // McCollWithVertexZ if (collisions.size() < 1) { return; } - registry.fill(HIST("h_Partcollision_counter"), 2.5); - for (auto const& collision : collisions) { - if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + registry.fill(HIST("hPartcollisionCounter"), 2.5); // PartCollWithSize>1 + + if (collisions.size() == 0) { + registry.fill(HIST("hPartcollisionCounter"), 3.5); // RejectedPartCollForDetCollWithSize0 + return; + } + + // outlier check: for every outlier jet, reject the whole event + for (auto const& jet : jets) { + if (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) { + registry.fill(HIST("hPartcollisionCounter"), 4.5); // RejectedPartCollWithOutliers return; } - if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { - eventAccepted = true; - // return; + } + + if (doMBGapTrigger && mccollision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + // Fill rejected MB events; + registry.fill(HIST("hPartcollisionCounter"), 5.5); // MBRejectedPartEvents + return; + } + + for (auto const& collision : collisions) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + return; } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { + registry.fill(HIST("hPartcollisionCounter"), 6.5); // EMCreadoutDetEventsWithkTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; + registry.fill(HIST("hPartcollisionCounter"), 6.5); // EMCreadoutDetEventsWithkTVXinEMC } } } if (!eventAccepted) { + registry.fill(HIST("hPartcollisionCounter"), 7.5); // AllRejectedPartEventsAfterEMCEventSelection return; } - registry.fill(HIST("h_Partcollision_counter"), 3.5); + registry.fill(HIST("hPartcollisionCounter"), 8.5); // EMCAcceptedWeightedPartColl for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { @@ -760,44 +1037,93 @@ struct FullJetSpectrapp { } } } - PROCESS_SWITCH(FullJetSpectrapp, processJetsMCP, "Full Jets at Particle Level", false); + PROCESS_SWITCH(FullJetSpectra, processJetsMCP, "Full Jets at Particle Level", false); void processJetsMCPWeighted(aod::JetMcCollision const& mccollision, JetTableMCPWeightedJoined const& jets, aod::JetParticles const&, soa::SmallGroups const& collisions) { bool eventAccepted = false; + float pTHat = 10. / (std::pow(mccollision.weight(), 1.0 / pTHatExponent)); + + /* if (doMcClosure) { + // Count total events processed (before splitting decision) + registry.fill(HIST("h_MCP_total_events"), 0.5); + + // DEBUG: Let's verify what collision IDs we're actually seeing + LOGF(info, "[MCP DEBUG] Processing MC collision ID: %lld", mccollision.globalIndex()); + + // Get random value for this MC collision + float eventRandomValue = getMCCollisionRandomValue(mccollision.globalIndex()); + + // DEBUG: Track which MC collisions we're processing + registry.fill(HIST("hMCCollisionIdDebug_MCP"), static_cast(mccollision.globalIndex() % 100000)); - registry.fill(HIST("h_Partcollision_counter"), 0.5); - if (fabs(mccollision.posZ()) > VertexZCut) { + // MCP gets events with random value > split fraction (80%) + if (eventRandomValue <= mcClosureSplitFrac) { + LOGF(debug, "[MCP] Event REJECTED: rand = %.4f <= split = %.2f (MC collision %lld)", + eventRandomValue, static_cast(mcClosureSplitFrac), mccollision.globalIndex()); + return; // This event goes to MCD only + } + + LOGF(info, "[MCP] Event ACCEPTED: rand = %.4f > split = %.2f (MC collision %lld)", + eventRandomValue, static_cast(mcClosureSplitFrac), mccollision.globalIndex()); + + registry.fill(HIST("hSpliteventSelector"), 1.5); // remaining 80% input for MCP + registry.fill(HIST("h_MCP_splitevent_counter"), 0.5); + } + */ + registry.fill(HIST("hPartcollisionCounter"), 0.5, mccollision.weight()); // allMcColl + if (std::fabs(mccollision.posZ()) > vertexZCut) { return; } - registry.fill(HIST("h_Partcollision_counter"), 1.5); + registry.fill(HIST("hPartcollisionCounter"), 1.5, mccollision.weight()); // McCollWithVertexZ if (collisions.size() < 1) { return; } - registry.fill(HIST("h_Partcollision_counter"), 2.5); - for (auto const& collision : collisions) { - if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + registry.fill(HIST("hPartcollisionCounter"), 2.5, mccollision.weight()); // PartCollWithSize>1 + + if (collisions.size() == 0) { + registry.fill(HIST("hPartcollisionCounter"), 3.5, mccollision.weight()); // RejectedPartCollForDetCollWithSize0 + return; + } + + // outlier check: for every outlier jet, reject the whole event + for (auto const& jet : jets) { + if (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) { + registry.fill(HIST("hPartcollisionCounter"), 4.5, mccollision.weight()); // RejectedPartCollWithOutliers return; } - if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { - eventAccepted = true; + } + + if (doMBGapTrigger && mccollision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + // Fill rejected MB events + registry.fill(HIST("hPartcollisionCounter"), 5.5, mccollision.weight()); // MBRejectedPartEvents + return; + } + + for (auto const& collision : collisions) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + return; } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { + registry.fill(HIST("hPartcollisionCounter"), 6.5, mccollision.weight()); // EMCreadoutDetJJEventsWithkTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; + registry.fill(HIST("hPartcollisionCounter"), 6.5, mccollision.weight()); // EMCreadoutDetJJEventsWithkTVXinEMC } } } if (!eventAccepted) { + registry.fill(HIST("hPartcollisionCounter"), 7.5, mccollision.weight()); // AllRejectedPartEventsAfterEMCEventSelection return; } - registry.fill(HIST("h_Partcollision_counter"), 3.5); + // Fill EMCAL JJ Part events + registry.fill(HIST("hPartcollisionCounter"), 8.5, mccollision.weight()); // EMCAcceptedWeightedPartColl for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { @@ -821,43 +1147,91 @@ struct FullJetSpectrapp { } } } - PROCESS_SWITCH(FullJetSpectrapp, processJetsMCPWeighted, "Full Jets at Particle Level on weighted events", false); + PROCESS_SWITCH(FullJetSpectra, processJetsMCPWeighted, "Full Jets at Particle Level on weighted events", false); - void processJetsMCPMCDMatched(soa::Filtered::iterator const& collision, JetTableMCDMatchedJoined const& mcdjets, JetTableMCPMatchedJoined const& mcpjets, aod::JMcCollisions const&, aod::JetTracks const&, aod::JetClusters const&, aod::JetParticles const&) + void processJetsMCPMCDMatched(soa::Filtered::iterator const& collision, JetTableMCDMatchedJoined const& mcdjets, jetMcpPerMcCollision const& mcpjets, aod::JMcCollisions const&, aod::JetTracks const&, aod::JetClusters const&, aod::JetParticles const&) { bool eventAccepted = false; - int fakemcdjet = 0; - int fakemcpjet = 0; + int fakeMcdJet = 0; + int fakeMcpJet = 0; + double weight = 1.0; + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); const auto mcpJetsPerMcCollision = mcpjets.sliceBy(JetMCPPerMcCollision, collision.mcCollisionId()); - registry.fill(HIST("h_Matchedcollision_counter"), 0.5); + /* if (doMcClosure) { + // Count total events processed (before splitting decision) + registry.fill(HIST("h_Matched_total_events"), 0.5); + + // Use consistent MC collision ID - same as MCD + int64_t mcCollisionId = collision.mcCollisionId(); + + // DEBUG: Let's verify what collision IDs we're actually seeing + LOGF(info, "[Matched DEBUG] Processing MC collision ID: %lld", mcCollisionId); + float eventRandomValue = getMCCollisionRandomValue(mcCollisionId); + + // Matched gets events with random value > split fraction (80%) - same as MCP + if (eventRandomValue <= mcClosureSplitFrac) { + LOGF(debug, "[Matched] Event REJECTED: rand = %.4f <= split = %.2f (MC collision %lld)", + eventRandomValue, static_cast(mcClosureSplitFrac), mcCollisionId); + return; // This event goes to MCD only + } + + LOGF(info, "[Matched] Event ACCEPTED: rand = %.4f > split = %.2f (MC collision %lld)", + eventRandomValue, static_cast(mcClosureSplitFrac), mcCollisionId); + + registry.fill(HIST("hSpliteventSelector"), 2.5); // Bin for Response Matrix + registry.fill(HIST("h_Matched_splitevent_counter"), 0.5); + } + */ + registry.fill(HIST("hMatchedcollisionCounter"), 0.5); // allDetColl - if (fabs(collision.posZ()) > VertexZCut) { // making double sure this condition is satisfied + if (std::fabs(collision.posZ()) > vertexZCut) { // making double sure this condition is satisfied return; } - registry.fill(HIST("h_Matchedcollision_counter"), 1.5); + registry.fill(HIST("hMatchedcollisionCounter"), 1.5); // DetCollWithVertexZ + + // outlier check: for every outlier jet, reject the whole event + for (auto const& mcdjet : mcdjets) { + if (mcdjet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) { + registry.fill(HIST("hMatchedcollisionCounter"), 2.5); // RejectedDetCollWithOutliers + return; + } + } + // //outlier check for Part collisions: commenting out this for now otherwise this rejects all Det Colls + // for (auto const& mcpjet : mcpjets) { + // if (mcpjet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) { + // registry.fill(HIST("hMatchedcollisionCounter"),3.5); //RejectedPartCollWithOutliers + // return; + // } + // } if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + registry.fill(HIST("hMatchedcollisionCounter"), 4.5); // EMCMBRejectedDetColl return; } + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + registry.fill(HIST("hMatchedcollisionCounter"), 5.5); // EventsNotSatisfyingEventSelection return; } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { + registry.fill(HIST("hMatchedcollisionCounter"), 6.5); // EMCreadoutDetEventsWithkTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; + registry.fill(HIST("hMatchedcollisionCounter"), 6.5); // EMCreadoutDetEventsWithkTVXinEMC } } if (!eventAccepted) { + registry.fill(HIST("hMatchedcollisionCounter"), 7.5); // AllRejectedDetEventsAfterEMCEventSelection return; } - registry.fill(HIST("h_Matchedcollision_counter"), 2.5); + registry.fill(HIST("hMatchedcollisionCounter"), 8.5); // EMCAcceptedDetColl for (const auto& mcdjet : mcdjets) { if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { @@ -865,50 +1239,94 @@ struct FullJetSpectrapp { } // Check if MCD jet is within the EMCAL fiducial region; if not then flag it as a fake jet if (mcdjet.phi() < jetPhiMin || mcdjet.phi() > jetPhiMax || mcdjet.eta() < jetEtaMin || mcdjet.eta() > jetEtaMax) { - fakemcdjet++; - registry.fill(HIST("h2_full_fakemcdjets"), mcdjet.pt(), fakemcdjet, 1.0); + fakeMcdJet++; + registry.fill(HIST("h2_full_fakemcdjets"), mcdjet.pt(), fakeMcdJet, 1.0); continue; } if (!isAcceptedJet(mcdjet)) { continue; } - for (auto& mcpjet : mcdjet.template matchedJetGeo_as()) { + for (const auto& mcpjet : mcdjet.template matchedJetGeo_as()) { // apply emcal fiducial cuts to the matched particle level jets if (mcpjet.eta() > jetEtaMax || mcpjet.eta() < jetEtaMin || mcpjet.phi() > jetPhiMax || mcpjet.phi() < jetPhiMin) { - fakemcpjet++; - registry.fill(HIST("h2_full_fakemcpjets"), mcpjet.pt(), fakemcpjet, 1.0); + fakeMcpJet++; + registry.fill(HIST("h2_full_fakemcpjets"), mcpjet.pt(), fakeMcpJet, 1.0); continue; } } // mcpjet loop - fillMatchedHistograms(mcdjet); + fillMatchedHistograms(mcdjet); } // mcdjet loop } - PROCESS_SWITCH(FullJetSpectrapp, processJetsMCPMCDMatched, "Full Jet finder MCP matched to MCD", false); + PROCESS_SWITCH(FullJetSpectra, processJetsMCPMCDMatched, "Full Jet finder MCP matched to MCD", false); void processJetsMCPMCDMatchedWeighted(soa::Filtered::iterator const& collision, JetTableMCDMatchedWeightedJoined const& mcdjets, JetTableMCPMatchedWeightedJoined const& mcpjets, aod::JMcCollisions const&, aod::JetTracks const&, aod::JetClusters const&, aod::JetParticles const&) { + bool eventAccepted = false; + int fakeMcdJet = 0; + int fakeMcpJet = 0; + int NPartJetFid = 0; float eventWeight = collision.mcCollision().weight(); + float pTHat = 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)); + const auto mcpJetsPerMcCollision = mcpjets.sliceBy(JetMCPPerMcCollision, collision.mcCollisionId()); + + /* if (doMcClosure) { + // Count total events processed (before splitting decision) + registry.fill(HIST("h_Matched_total_events"), 0.5); - registry.fill(HIST("h_Matchedcollision_counter"), 0.5); - if (fabs(collision.posZ()) > VertexZCut) { // making double sure this condition is satisfied + // Use consistent MC collision ID - same as MCD + int64_t mcCollisionId = collision.mcCollisionId(); + + // DEBUG: Let's verify what collision IDs we're actually seeing + LOGF(info, "[Matched DEBUG] Processing MC collision ID: %lld", mcCollisionId); + float eventRandomValue = getMCCollisionRandomValue(mcCollisionId); + + // Matched gets events with random value > split fraction (80%) - same as MCP + if (eventRandomValue <= mcClosureSplitFrac) { + LOGF(debug, "[Matched] Event REJECTED: rand = %.4f <= split = %.2f (MC collision %lld)", + eventRandomValue, static_cast(mcClosureSplitFrac), mcCollisionId); + return; // This event goes to MCD only + } + + LOGF(info, "[Matched] Event ACCEPTED: rand = %.4f > split = %.2f (MC collision %lld)", + eventRandomValue, static_cast(mcClosureSplitFrac), mcCollisionId); + + registry.fill(HIST("hSpliteventSelector"), 2.5); // Bin for Response Matrix + registry.fill(HIST("h_Matched_splitevent_counter"), 0.5); + } + */ + registry.fill(HIST("hMatchedcollisionCounter"), 0.5, eventWeight); // allDetColl + if (std::fabs(collision.posZ()) > vertexZCut) { // making double sure this condition is satisfied return; } - registry.fill(HIST("h_Matchedcollision_counter"), 1.5); + registry.fill(HIST("hMatchedcollisionCounter"), 1.5, eventWeight); // DetCollWithVertexZ + + // outlier check: for every outlier jet, reject the whole event + for (auto const& mcdjet : mcdjets) { + if (mcdjet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) { + registry.fill(HIST("hMatchedcollisionCounter"), 2.5, eventWeight); // RejectedDetCollWithOutliers + return; + } + } + // outlier check for Part collisions: commenting out this for now otherwise this rejects all Det Colls + // for (auto const& mcpjet : mcpjets) { + // if (mcpjet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) { + // registry.fill(HIST("hMatchedcollisionCounter"),3.5, eventWeight); //RejectedPartCollWithOutliers + // return; + // } + // } if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + registry.fill(HIST("hMatchedcollisionCounter"), 4.5, eventWeight); // EMCMBRejectedDetColl return; } + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + registry.fill(HIST("hMatchedcollisionCounter"), 5.5, eventWeight); // EventsNotSatisfyingEventSelection return; } - bool eventAccepted = false; - int fakemcdjet = 0; - int fakemcpjet = 0; - float pTHat = 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)); - const auto mcpJetsPerMcCollision = mcpjets.sliceBy(JetMCPPerMcCollision, collision.mcCollisionId()); - for (auto mcpjet : mcpJetsPerMcCollision) { - if (mcpjet.pt() > pTHatMaxMCP * pTHat) { // outlier rejection for MCP + for (auto const& mcpjet : mcpJetsPerMcCollision) { + if (mcpjet.pt() > pTHatMaxMCP * pTHat) { // outlier rejection for MCP: Should I remove this cut as I'm already doing MC outlier rejection @L1071? return; } } @@ -916,25 +1334,26 @@ struct FullJetSpectrapp { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { - registry.fill(HIST("h_Matchedcollision_counter"), eventWeight); + registry.fill(HIST("hMatchedcollisionCounter"), 6.5, eventWeight); // EMCreadoutDetJJEventsWithkTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; - registry.fill(HIST("h_Matchedcollision_counter"), eventWeight); + registry.fill(HIST("hMatchedcollisionCounter"), 6.5, eventWeight); // EMCreadoutDetJJEventsWithkTVXinEMC } } if (!eventAccepted) { + registry.fill(HIST("hMatchedcollisionCounter"), 7.5, eventWeight); // AllRejectedDetEventsAfterEMCEventSelection return; } - registry.fill(HIST("h_Matchedcollision_counter"), 2.5); + registry.fill(HIST("hMatchedcollisionCounter"), 8.5, eventWeight); // EMCAcceptedDetColl for (const auto& mcdjet : mcdjets) { // Check if MCD jet is within the EMCAL fiducial region; if not then flag it as a fake jet if (mcdjet.phi() < jetPhiMin || mcdjet.phi() > jetPhiMax || mcdjet.eta() < jetEtaMin || mcdjet.eta() > jetEtaMax) { - fakemcdjet++; - registry.fill(HIST("h2_full_fakemcdjets"), mcdjet.pt(), fakemcdjet, eventWeight); + fakeMcdJet++; + registry.fill(HIST("h2_full_fakemcdjets"), mcdjet.pt(), fakeMcdJet, eventWeight); continue; } if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { @@ -944,35 +1363,73 @@ struct FullJetSpectrapp { continue; } - for (auto& mcpjet : mcdjet.template matchedJetGeo_as()) { - // apply emcal fiducial cuts to the matched particle level jets + for (const auto& mcpjet : mcdjet.template matchedJetGeo_as()) { + // apply emcal fiducial cuts to the matched particle level jets - if the matched mcp jet lies outside of the EMCAL fiducial, flag it as a fake jet if (mcpjet.eta() > jetEtaMax || mcpjet.eta() < jetEtaMin || mcpjet.phi() > jetPhiMax || mcpjet.phi() < jetPhiMin) { - fakemcpjet++; - registry.fill(HIST("h2_full_fakemcpjets"), mcpjet.pt(), fakemcpjet, eventWeight); + fakeMcpJet++; + registry.fill(HIST("h2FullfakeMcpJets"), mcpjet.pt(), fakeMcpJet, eventWeight); continue; + } else { + NPartJetFid++; + // // If both MCD-MCP matched jet pairs are within the EMCAL fiducial region, fill these histos + registry.fill(HIST("h2_full_matchedmcpjet_pt"), mcpjet.pt(), NPartJetFid, eventWeight); + registry.fill(HIST("h_full_matchedmcpjet_eta"), mcpjet.eta(), eventWeight); + registry.fill(HIST("h_full_matchedmcpjet_phi"), mcpjet.phi(), eventWeight); } - // // If both MCD-MCP matched jet pairs are within the EMCAL fiducial region, fill these histos - registry.fill(HIST("h_full_matchedmcpjet_eta"), mcpjet.eta(), eventWeight); - registry.fill(HIST("h_full_matchedmcpjet_phi"), mcpjet.phi(), eventWeight); } // mcpjet fillMatchedHistograms(mcdjet, eventWeight); } // mcdjet } - PROCESS_SWITCH(FullJetSpectrapp, processJetsMCPMCDMatchedWeighted, "Full Jet finder MCP matched to MCD on weighted events", false); + PROCESS_SWITCH(FullJetSpectra, processJetsMCPMCDMatchedWeighted, "Full Jet finder MCP matched to MCD on weighted events", false); + + // Periodic cleanup to prevent unbounded memory growth + /*void processCleanup(aod::Collision const&) { + static int callCount = 0; + callCount++; + + // Clean up cache every 50000 calls to prevent memory issues + if (doMcClosure && callCount % 50000 == 0 && mcCollisionRandomValues.size() > 20000) { + LOGF(info, "Cleaning up MC collision random values cache (size: %zu)", mcCollisionRandomValues.size()); + mcCollisionRandomValues.clear(); + + // IMPROVEMENT: Add logging to verify our split ratios + float mcdCount = registry.get(HIST("h_MCD_splitevent_counter"))->GetBinContent(1); + float mcpCount = registry.get(HIST("h_MCP_splitevent_counter"))->GetBinContent(1); + float matchedCount = registry.get(HIST("h_Matched_splitevent_counter"))->GetBinContent(1); + + float totalEvents = mcdCount + mcpCount; // MCP and Matched should be the same, so don't double count + float actualSplitFrac = totalEvents > 0 ? mcdCount / totalEvents : 0.0f; - void processTracks(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, soa::Filtered const& clusters) + LOGF(info, "Current split statistics: MCD=%.1f, MCP=%.1f, Matched=%.1f", mcdCount, mcpCount, matchedCount); + LOGF(info, "Actual split fraction: %.3f (target: %.3f)", actualSplitFrac, static_cast(mcClosureSplitFrac)); + } + } + PROCESS_SWITCH(FullJetSpectra, processCleanup, "Periodic cleanup", true); + */ + void processDataTracks(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, soa::Filtered const& clusters) { bool eventAccepted = false; + double weight = 1.0; + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); + + registry.fill(HIST("hCollisionsUnweighted"), 0.5); // allDetColl + if (std::fabs(collision.posZ()) > vertexZCut) { + return; + } + registry.fill(HIST("hCollisionsUnweighted"), 1.5); // DetCollWithVertexZ - registry.fill(HIST("h_collisions_unweighted"), 0.5); - if (fabs(collision.posZ()) > VertexZCut) { + // for (auto const& track : tracks) { + if (pTHat < pTHatAbsoluteMin) { // Track outlier rejection: should this be for every track iteration or for every collision? return; } - registry.fill(HIST("h_collisions_unweighted"), 1.5); + // } + if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + registry.fill(HIST("hCollisionsUnweighted"), 2.5); // MBRejectedDetEvents return; } if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + registry.fill(HIST("hCollisionsUnweighted"), 3.5); // EventsNotSatisfyingEventSelection return; } // needed for the workaround to access EMCAL trigger bits. - This is needed for the MC productions in which the EMC trigger bits are missing. (MB MC LHC24f3, for ex.) @@ -986,8 +1443,7 @@ struct FullJetSpectrapp { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { - registry.fill(HIST("h_collisions_unweighted"), 4.0); // Tracks with kTVXinEMC - registry.fill(HIST("h_Detcollision_counter"), 1.0); + registry.fill(HIST("hCollisionsUnweighted"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC } } } else { @@ -995,16 +1451,72 @@ struct FullJetSpectrapp { // This is the default check for the simulations with proper trigger flags not requiring the above workaround. if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; - registry.fill(HIST("h_collisions_unweighted"), 4.0); // Tracks with kTVXinEMC - registry.fill(HIST("h_Detcollision_counter"), 1.0); + registry.fill(HIST("hCollisionsUnweighted"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC + } + } + + if (!eventAccepted) { + registry.fill(HIST("hCollisionsUnweighted"), 5.5); // AllRejectedDetEventsAfterEMCEventSelection + return; + } + registry.fill(HIST("hCollisionsUnweighted"), 6.5); // EMCAcceptedDetColl + + for (auto const& track : tracks) { + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { + continue; + } + // Fill Accepted events histos + fillTrackHistograms(tracks, clusters, 1.0); + } + registry.fill(HIST("hCollisionsUnweighted"), 7.5); // EMCAcceptedCollAfterTrackSel + } + PROCESS_SWITCH(FullJetSpectra, processDataTracks, "Full Jet tracks for Data", false); + + void processMCTracks(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, soa::Filtered const& clusters) + { + bool eventAccepted = false; + double weight = 1.0; + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); + + registry.fill(HIST("hCollisionsUnweighted"), 0.5); // allDetColl + if (std::fabs(collision.posZ()) > vertexZCut) { + return; + } + registry.fill(HIST("hCollisionsUnweighted"), 1.5); // DetCollWithVertexZ + + // for (auto const& track : tracks) { + if (pTHat < pTHatAbsoluteMin) { // Track outlier rejection: should this be for every track iteration or for every collision? + return; + } + // } + if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + registry.fill(HIST("hCollisionsUnweighted"), 2.5); // MBRejectedDetEvents + return; + } + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + registry.fill(HIST("hCollisionsUnweighted"), 3.5); // EventsNotSatisfyingEventSelection + return; + } + + if (doEMCALEventWorkaround) { + if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content + eventAccepted = true; + if (collision.alias_bit(kTVXinEMC)) { + registry.fill(HIST("hCollisionsUnweighted"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC + } + } + } else { + if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; + registry.fill(HIST("hCollisionsUnweighted"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC } } if (!eventAccepted) { - registry.fill(HIST("h_collisions_unweighted"), 8.0); // Tracks w/o kTVXinEMC + registry.fill(HIST("hCollisionsUnweighted"), 5.5); // AllRejectedDetEventsAfterEMCEventSelection return; } - registry.fill(HIST("h_collisions_unweighted"), 2.5); + registry.fill(HIST("hCollisionsUnweighted"), 6.5); // EMCAcceptedDetColl for (auto const& track : tracks) { if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { @@ -1013,9 +1525,9 @@ struct FullJetSpectrapp { // Fill Accepted events histos fillTrackHistograms(tracks, clusters, 1.0); } - registry.fill(HIST("h_collisions_unweighted"), 3.5); + registry.fill(HIST("hCollisionsUnweighted"), 7.5); // EMCAcceptedCollAfterTrackSel } - PROCESS_SWITCH(FullJetSpectrapp, processTracks, "Full Jet tracks", false); + PROCESS_SWITCH(FullJetSpectra, processMCTracks, "Full Jet tracks for MC", false); void processTracksWeighted(soa::Filtered::iterator const& collision, aod::JMcCollisions const&, @@ -1024,54 +1536,63 @@ struct FullJetSpectrapp { { bool eventAccepted = false; float eventWeight = collision.mcCollision().weight(); + float pTHat = 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)); - registry.fill(HIST("h_collisions_weighted"), 0.5); - if (fabs(collision.posZ()) > VertexZCut) { + registry.fill(HIST("hCollisionsWeighted"), 0.5, eventWeight); // AllWeightedDetColl + if (std::fabs(collision.posZ()) > vertexZCut) { return; } - registry.fill(HIST("h_collisions_weighted"), 1.5); + registry.fill(HIST("hCollisionsWeighted"), 1.5, eventWeight); // WeightedCollWithVertexZ + + // for (auto const& track : tracks) { + if (pTHat < pTHatAbsoluteMin) { // Track outlier rejection: should this be for every track iteration or for every collision? + return; + } + // } if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + registry.fill(HIST("hCollisionsWeighted"), 2.5, eventWeight); // MBRejectedDetEvents return; } if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + registry.fill(HIST("hCollisionsWeighted"), 3.5, eventWeight); // EventsNotSatisfyingEventSelection return; } if (doMBGapTrigger && eventWeight == 1) { + registry.fill(HIST("hCollisionsWeighted"), 2.5, eventWeight); // MBRejectedDetEvents return; } - registry.fill(HIST("h_collisions_weighted"), 1.0, eventWeight); // total events if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; fillTrackHistograms(tracks, clusters, eventWeight); if (collision.alias_bit(kTVXinEMC)) { - registry.fill(HIST("h_collisions_weighted"), 4.0, eventWeight); // TracksWeighted with kTVXinEMC + registry.fill(HIST("hCollisionsWeighted"), 4.5, eventWeight); // EMCreadoutDetJJEventsWithkTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; - registry.fill(HIST("h_collisions_weighted"), 4.0, eventWeight); // TracksWeighted with kTVXinEMC + registry.fill(HIST("hCollisionsWeighted"), 4.5, eventWeight); // EMCreadoutDetJJEventsWithkTVXinEMC } } if (!eventAccepted) { - registry.fill(HIST("h_collisions_weighted"), 7.0, eventWeight); // TracksWeighted w/o kTVXinEMC + registry.fill(HIST("hCollisionsWeighted"), 5.5, eventWeight); // AllRejectedDetEventsAfterEMCEventSelection return; } - registry.fill(HIST("h_collisions_weighted"), 2.5); + registry.fill(HIST("hCollisionsWeighted"), 6.5); // EMCAcceptedWeightedDetColl for (auto const& track : tracks) { if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { continue; } // Fill Accepted events histos - fillTrackHistograms(tracks, clusters, 1.0); + fillTrackHistograms(tracks, clusters, eventWeight); } - registry.fill(HIST("h_collisions_weighted"), 3.5); + registry.fill(HIST("hCollisionsWeighted"), 7.5, eventWeight); // EMCAcceptedWeightedCollAfterTrackSel } - PROCESS_SWITCH(FullJetSpectrapp, processTracksWeighted, "Full Jet tracks weighted", false); + PROCESS_SWITCH(FullJetSpectra, processTracksWeighted, "Full Jet tracks weighted", false); void processCollisionsWeightedWithMultiplicity(soa::Filtered>::iterator const& collision, JetTableMCDWeightedJoined const& mcdjets, aod::JMcCollisions const&, soa::Filtered const& tracks, soa::Filtered const& clusters) { @@ -1079,16 +1600,21 @@ struct FullJetSpectrapp { float eventWeight = collision.mcCollision().weight(); float neutralEnergy = 0.0; - if (fabs(collision.posZ()) > VertexZCut) { + registry.fill(HIST("hEventmultiplicityCounter"), 0.5, eventWeight); // allDetColl + if (std::fabs(collision.posZ()) > vertexZCut) { + registry.fill(HIST("hEventmultiplicityCounter"), 1.5, eventWeight); // DetCollWithVertexZ return; } if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + registry.fill(HIST("hEventmultiplicityCounter"), 2.5, eventWeight); // MBRejectedDetEvents return; } if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + registry.fill(HIST("hEventmultiplicityCounter"), 3.5, eventWeight); // EventsNotSatisfyingEventSelection return; } if (doMBGapTrigger && eventWeight == 1) { + registry.fill(HIST("hEventmultiplicityCounter"), 2.5, eventWeight); // MBRejectedDetEvents return; } @@ -1097,23 +1623,29 @@ struct FullJetSpectrapp { eventAccepted = true; fillTrackHistograms(tracks, clusters, eventWeight); if (collision.alias_bit(kTVXinEMC)) { + registry.fill(HIST("hEventmultiplicityCounter"), 4.5, eventWeight); // EMCreadoutDetJJEventsWithkTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; + registry.fill(HIST("hEventmultiplicityCounter"), 4.5, eventWeight); // EMCreadoutDetJJEventsWithkTVXinEMC } } if (!eventAccepted) { + registry.fill(HIST("hEventmultiplicityCounter"), 5.5, eventWeight); // AllRejectedDetEventsAfterEMCEventSelection return; } + registry.fill(HIST("hCollisionsWeighted"), 6.5); // EMCAcceptedWeightedDetColl + for (auto const& track : tracks) { if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { continue; } } - registry.fill(HIST("h_FT0Mults_occupancy"), collision.multiplicity()); + registry.fill(HIST("hEventmultiplicityCounter"), 7.5, eventWeight); // EMCAcceptedWeightedCollAfterTrackSel + registry.fill(HIST("h_FT0Mults_occupancy"), collision.multiplicity(), eventWeight); for (auto const& mcdjet : mcdjets) { float pTHat = 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)); @@ -1134,11 +1666,11 @@ struct FullJetSpectrapp { for (auto const& cluster : clusters) { neutralEnergy += cluster.energy(); } - auto NEF = neutralEnergy / mcdjet.energy(); - registry.fill(HIST("h3_full_jet_jetpTDet_FT0Mults_NEF"), mcdjet.pt(), collision.multiplicity(), NEF, eventWeight); + auto nef = neutralEnergy / mcdjet.energy(); + registry.fill(HIST("h3_full_jet_jetpTDet_FT0Mults_nef"), mcdjet.pt(), collision.multiplicity(), nef, eventWeight); } } - PROCESS_SWITCH(FullJetSpectrapp, processCollisionsWeightedWithMultiplicity, "Weighted Collisions for Full Jets Multiplicity Studies", false); + PROCESS_SWITCH(FullJetSpectra, processCollisionsWeightedWithMultiplicity, "Weighted Collisions for Full Jets Multiplicity Studies", false); void processMBCollisionsWithMultiplicity(soa::Filtered>::iterator const& collision, JetTableMCDJoined const& mcdjets, aod::JMcCollisions const&, soa::Filtered const& tracks, soa::Filtered const& clusters) { @@ -1146,13 +1678,18 @@ struct FullJetSpectrapp { float pTHat = 10. / (std::pow(1.0, 1.0 / pTHatExponent)); float neutralEnergy = 0.0; - if (fabs(collision.posZ()) > VertexZCut) { + registry.fill(HIST("hEventmultiplicityCounter"), 0.5); // allDetColl + if (std::fabs(collision.posZ()) > vertexZCut) { return; } + registry.fill(HIST("hEventmultiplicityCounter"), 1.5); // DetCollWithVertexZ + if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + registry.fill(HIST("hEventmultiplicityCounter"), 2.5); // MBRejectedDetEvents return; } if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + registry.fill(HIST("hEventmultiplicityCounter"), 3.5); // EventsNotSatisfyingEventSelection return; } @@ -1161,22 +1698,28 @@ struct FullJetSpectrapp { eventAccepted = true; fillTrackHistograms(tracks, clusters, 1.0); if (collision.alias_bit(kTVXinEMC)) { + registry.fill(HIST("hEventmultiplicityCounter"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; + registry.fill(HIST("hEventmultiplicityCounter"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC } } if (!eventAccepted) { + registry.fill(HIST("hEventmultiplicityCounter"), 5.5); // AllRejectedDetEventsAfterEMCEventSelection return; } + registry.fill(HIST("hEventmultiplicityCounter"), 6.5); // EMCAcceptedDetColl + for (auto const& track : tracks) { if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { continue; } } + registry.fill(HIST("hEventmultiplicityCounter"), 7.5); // EMCAcceptedCollAfterTrackSel registry.fill(HIST("h_FT0Mults_occupancy"), collision.multiplicity()); for (auto const& mcdjet : mcdjets) { @@ -1197,15 +1740,85 @@ struct FullJetSpectrapp { for (auto const& cluster : clusters) { neutralEnergy += cluster.energy(); } - auto NEF = neutralEnergy / mcdjet.energy(); - registry.fill(HIST("h3_full_jet_jetpTDet_FT0Mults_NEF"), mcdjet.pt(), collision.multiplicity(), NEF, 1.0); + auto nef = neutralEnergy / mcdjet.energy(); + registry.fill(HIST("h3_full_jet_jetpTDet_FT0Mults_nef"), mcdjet.pt(), collision.multiplicity(), nef, 1.0); + } + } + PROCESS_SWITCH(FullJetSpectra, processMBCollisionsWithMultiplicity, "MB MCD Collisions for Full Jets Multiplicity Studies", false); + + void processMBCollisionsDATAWithMultiplicity(soa::Filtered>::iterator const& collision, FullJetTableDataJoined const& jets, soa::Filtered const& tracks, soa::Filtered const& clusters) + { + bool eventAccepted = false; + float neutralEnergy = 0.0; + + registry.fill(HIST("hEventmultiplicityCounter"), 0.5); // allDetColl + if (std::fabs(collision.posZ()) > vertexZCut) { + return; + } + registry.fill(HIST("hEventmultiplicityCounter"), 1.5); // DetCollWithVertexZ + if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + registry.fill(HIST("hEventmultiplicityCounter"), 2.5); // MBRejectedDetEvents + return; + } + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { + registry.fill(HIST("hEventmultiplicityCounter"), 3.5); // EventsNotSatisfyingEventSelection + return; + } + + if (doEMCALEventWorkaround) { + if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content + eventAccepted = true; + fillTrackHistograms(tracks, clusters, 1.0); + if (collision.alias_bit(kTVXinEMC)) { + registry.fill(HIST("hEventmultiplicityCounter"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC + } + } + } else { + if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; + registry.fill(HIST("hEventmultiplicityCounter"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC + } + } + + if (!eventAccepted) { + registry.fill(HIST("hEventmultiplicityCounter"), 5.5); // AllRejectedDetEventsAfterEMCEventSelection + return; + } + registry.fill(HIST("hEventmultiplicityCounter"), 6.5); // EMCAcceptedDetColl + + for (auto const& track : tracks) { + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { + continue; + } + } + registry.fill(HIST("hEventmultiplicityCounter"), 7.5); // EMCAcceptedCollAfterTrackSel + registry.fill(HIST("h_FT0Mults_occupancy"), collision.multiplicity()); + + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + if (jet.phi() < jetPhiMin || jet.phi() > jetPhiMax) { + continue; + } + if (!isAcceptedJet(jet)) { + continue; + } + registry.fill(HIST("h2_full_jet_jetpTDetVsFT0Mults"), jet.pt(), collision.multiplicity(), 1.0); + + for (auto const& cluster : clusters) { + neutralEnergy += cluster.energy(); + } + auto nef = neutralEnergy / jet.energy(); + registry.fill(HIST("h3_full_jet_jetpTDet_FT0Mults_nef"), jet.pt(), collision.multiplicity(), nef, 1.0); } } - PROCESS_SWITCH(FullJetSpectrapp, processMBCollisionsWithMultiplicity, "MB Collisions for Full Jets Multiplicity Studies", false); + PROCESS_SWITCH(FullJetSpectra, processMBCollisionsDATAWithMultiplicity, "MB DATA Collisions for Full Jets Multiplicity Studies", false); + }; // struct WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc, TaskName{"full-jet-spectra-pp"})}; + adaptAnalysisTask(cfgc)}; } diff --git a/PWGJE/Tasks/hadronPhotonCorrelation.cxx b/PWGJE/Tasks/hadronPhotonCorrelation.cxx index 4681a8d586f..70850130b5c 100644 --- a/PWGJE/Tasks/hadronPhotonCorrelation.cxx +++ b/PWGJE/Tasks/hadronPhotonCorrelation.cxx @@ -63,13 +63,21 @@ struct HadronPhotonCorrelation { Configurable eventSelections{"eventSelections", "sel8", "choose event selection"}; Configurable trackSelections{"trackSelections", "globalTracks", "set track selections"}; + Configurable subGeneratorIdSelections{"subGeneratorIdSelections", -1, "set sub generator id"}; - Configurable etaMax{"etaMax", 0.8, "maximum eta cut"}; + Configurable tpcNClsCrossedRows{"tpcNClsCrossedRows", 70, "tpcNClsCrossedRows"}; + Configurable tpcCrossedRowsOverFindableCls{"tpcCrossedRowsOverFindableCls", 0.8, "tpcCrossedRowsOverFindableCls"}; + Configurable tpcNSigmaPi{"tpcNSigmaPi", 2., "tpcNSigmaPi"}; - AxisSpec axisPhi = {72, 0., TwoPI, "#phi"}; // Axis for phi distribution - AxisSpec axisDeltaPhi = {72, -PIHalf, 3 * PIHalf, "#Delta #phi"}; // Axis for Delta phi in correlations - AxisSpec axisEta = {40, -.8, .8, "#eta"}; // Axis for eta distribution - AxisSpec axisDeltaEta = {80, -1.6, 1.6, "#Delta #eta"}; // Axis for Delta eta in correlations + const int pidCodeHadronCut = 100; + + Configurable etaMaxTrig{"etaMaxTrig", 0.8, "maximum eta cut for triggers"}; + Configurable etaMaxAssoc{"etaMaxAssoc", 0.8, "maximum eta cut for associateds"}; + Configurable etaBinsTrig{"etaBinsTrig", 40, "number of eta bins for triggers"}; + Configurable etaBinsAssoc{"etaBinsAssoc", 40, "number of eta bins for associateds"}; + Configurable phiBins{"phiBins", 72, "number of phi bins"}; + + AxisSpec axisEventStats = {3, -.5, 2.5, "Stats"}; ConfigurableAxis axisPtTrig = {"axisPtTrig", {VARIABLE_WIDTH, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 9.0f, 11.0f, 15.0f, 20.0f}, @@ -77,13 +85,12 @@ struct HadronPhotonCorrelation { ConfigurableAxis axisPtAssoc = {"axisPtAssoc", {VARIABLE_WIDTH, 0.2, 0.5, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 9.0f, 11.0f, 15.0f}, - "p_{T, assoc} [GeV]"}; // Axis for associated particle pt distribution - AxisSpec axisDeltaPt = {200, 0., 1.2, "#Delta p_T"}; // Axis for pt ratio between neutral hadrons and decay photons - AxisSpec axisPid = {9, -3.5, 5.5, "pid"}; // Axis for PID of neutral hadrons - AxisSpec axisMult = {100, 0., 99., "N_{ch}"}; // Axis for mutplipicity - AxisSpec axisAlpha = {100, 0., 1., "alpha"}; // Axis for decay photon pt assymetry - - AxisSpec axisDeltaRDecay = {100, 0., 0.8, "#Delta R"}; // Axis for Delta R = sqrt(Delta eta^2 + Delta phi^2) between neutral hadrons and decay photons + "p_{T, assoc} [GeV]"}; // Axis for associated particle pt distribution + ConfigurableAxis axisDeltaPt = {"axisDeltaPt", {200, 0., 1.2}, "#Delta p_T"}; // Axis for pt ratio between neutral hadrons and decay photons + AxisSpec axisPid = {10, -3.5, 6.5, "pid"}; // Axis for PID of neutral hadrons + ConfigurableAxis axisMult = {"axisMult", {100, 0., 99.}, "N_{ch}"}; // Axis for mutplipicity + AxisSpec axisAlpha = {100, 0., 1., "alpha"}; // Axis for decay photon pt assymetry + ConfigurableAxis axisDeltaRDecay = {"axisDeltaRDecay", {400, 0., 3.2}, "#Delta R"}; // Axis for Delta R = sqrt(Delta eta^2 + Delta phi^2) between neutral hadrons and decay photons float ptMinTrig; float ptMaxTrig; @@ -98,7 +105,9 @@ struct HadronPhotonCorrelation { {"eta", 2}, // eta {"eta'", 3}, // eta' {"phi", 4}, // phi - {"omega", 5}}; // omega + {"omega", 5}, // omega + {"Sigma0", 6}, // Sigma + {"Sigma0_bar", 6}}; Service pdg; @@ -112,56 +121,66 @@ struct HadronPhotonCorrelation { ptMinAssoc = axisPtAssoc->at(1); ptMaxAssoc = axisPtAssoc->back(); + AxisSpec axisPhi = {phiBins, 0., TwoPI, "#phi"}; // Axis for phi distribution + AxisSpec axisDeltaPhi = {phiBins, -PIHalf, 3 * PIHalf, "#Delta #phi"}; // Axis for Delta phi in correlations + AxisSpec axisEtaTrig = {etaBinsTrig, -etaMaxTrig, etaMaxTrig, "#eta"}; // Axis for eta distribution + AxisSpec axisEtaAssoc = {etaBinsAssoc, -etaMaxAssoc, etaMaxAssoc, "#eta"}; // Axis for eta distribution + AxisSpec axisDeltaEta = {etaBinsTrig + etaBinsAssoc, -(etaMaxTrig + etaMaxAssoc), etaMaxTrig + etaMaxAssoc, "#Delta #eta"}; // Axis for Delta eta in correlations + eventSelectionBits = jetderiveddatautilities::initialiseEventSelectionBits(static_cast(eventSelections)); trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); // Generated histograms + registry.add("generated/events/hEventStats", "Event statistics", kTH1F, {axisEventStats}); + // Triggers registry.add("generated/triggers/hTrigMultGen", "Generated Trigger Multiplicity", kTH1F, {axisMult}); - registry.add("generated/triggers/hTrigSpectrumGen", "Generated Trigger Spectrum", kTHnSparseF, {axisPtTrig, axisEta, axisPhi}); + registry.add("generated/triggers/hTrigSpectrumGen", "Generated Trigger Spectrum", kTHnSparseF, {axisPtTrig, axisEtaTrig, axisPhi}); // Hadrons registry.add("generated/hadrons/hHadronCorrelGen", "Generated Trigger-Hadron Correlation", kTHnSparseF, {axisPtTrig, axisPtAssoc, axisDeltaEta, axisDeltaPhi}); registry.add("generated/hadrons/hHadronMultGen", "Generated Hadron Multiplicity", kTH1F, {axisMult}); - registry.add("generated/hadrons/hHadronSpectrumGen", "Generated Hadron Spectrum", kTHnSparseF, {axisPtAssoc, axisEta, axisPhi}); + registry.add("generated/hadrons/hHadronSpectrumGen", "Generated Hadron Spectrum", kTHnSparseF, {axisPtAssoc, axisEtaAssoc, axisPhi}); // Photons registry.add("generated/photons/hPhotonCorrelGen", "Generated Trigger-Photon Correlation", kTHnSparseF, {axisPtTrig, axisPtAssoc, axisDeltaEta, axisDeltaPhi, axisPid}); registry.add("generated/photons/hPhotonMultGen", "Generated Photon Multiplicity", kTH1F, {axisMult}); - registry.add("generated/photons/hPhotonSpectrumGen", "Generated Photon Spectrum", kTHnSparseF, {axisPtAssoc, axisEta, axisPhi, axisPid}); + registry.add("generated/photons/hPhotonSpectrumGen", "Generated Photon Spectrum", kTHnSparseF, {axisPtAssoc, axisEtaAssoc, axisPhi, axisPid}); // Charged pions registry.add("generated/charged/hPionCorrelGen", "Generated Trigger-Pion Correlation", kTHnSparseF, {axisPtTrig, axisPtAssoc, axisDeltaEta, axisDeltaPhi}); registry.add("generated/charged/hPionMultGen", "Generated Pion Multiplicity", kTH1F, {axisMult}); - registry.add("generated/charged/hPionSpectrumGen", "Generated Pion Spectrum", kTHnSparseF, {axisPtAssoc, axisEta, axisPhi}); + registry.add("generated/charged/hPionSpectrumGen", "Generated Pion Spectrum", kTHnSparseF, {axisPtAssoc, axisEtaAssoc, axisPhi}); ////Neutral particles registry.add("generated/neutral/hNeutralCorrelGen", "Generated Trigger-Neutral Hadron Correlation", kTHnSparseF, {axisPtTrig, axisPtAssoc, axisDeltaEta, axisDeltaPhi, axisPid}); registry.add("generated/neutral/hNeutralMultGen", "Generated Neutral Hadron Multiplicity", kTH1F, {axisMult}); - registry.add("generated/neutral/hNeutralSpectrumGen", "Generated Neutral Hadron Spectrum", kTHnSparseF, {axisPtAssoc, axisEta, axisPhi, axisPid}); // Particle ID of neutral hadrons + registry.add("generated/neutral/hNeutralSpectrumGen", "Generated Neutral Hadron Spectrum", kTHnSparseF, {axisPtAssoc, axisEtaAssoc, axisPhi, axisPid}); registry.add("generated/neutral/hNeutralDecayGen", "Generated Neutral Hadron-Decay Photon Correlation", kTHnSparseF, {axisPtAssoc, axisDeltaPt, axisDeltaRDecay, axisAlpha, axisPid}); // Correlation with decay photons // Reconstructed histograms + registry.add("reconstructed/events/hEventStats", "Event statistics", kTH1F, {axisEventStats}); + // Triggers registry.add("reconstructed/triggers/hTrigMultReco", "Reconstructed Trigger Multiplicity", kTH1F, {axisMult}); - registry.add("reconstructed/triggers/hTrigSpectrumReco", "Reconstructed Trigger Spectrum", kTHnSparseF, {axisPtTrig, axisEta, axisPhi}); + registry.add("reconstructed/triggers/hTrigSpectrumReco", "Reconstructed Trigger Spectrum", kTHnSparseF, {axisPtTrig, axisEtaTrig, axisPhi}); // Hadrons registry.add("reconstructed/hadrons/hHadronCorrelReco", "Reconstructed Trigger-Hadron Correlation", kTHnSparseF, {axisPtTrig, axisPtAssoc, axisDeltaEta, axisDeltaPhi}); registry.add("reconstructed/hadrons/hHadronMultReco", "Reconstructed Hadron Multiplicity", kTH1F, {axisMult}); - registry.add("reconstructed/hadrons/hHadronSpectrumReco", "Reconstructed Hadron Spectrum", kTHnSparseF, {axisPtAssoc, axisEta, axisPhi}); + registry.add("reconstructed/hadrons/hHadronSpectrumReco", "Reconstructed Hadron Spectrum", kTHnSparseF, {axisPtAssoc, axisEtaAssoc, axisPhi}); registry.add("reconstructed/hadrons/hHadronPtPrimReco", "Reconstructed Primaries Spectrum", kTH1F, {axisPtAssoc}); // Primary hadron spectrum registry.add("reconstructed/hadrons/hHadronPtSecReco", "Reconstructed Secondaries Spectrum", kTH1F, {axisPtAssoc}); // Secondary hadron spectrum // Photons registry.add("reconstructed/photons/hPhotonCorrelReco", "Reconstructed Trigger-Photon Correlation", kTHnSparseF, {axisPtTrig, axisPtAssoc, axisDeltaEta, axisDeltaPhi}); registry.add("reconstructed/photons/hPhotonMultReco", "Reconstructed Photon Multiplicity", kTH1F, {axisMult}); - registry.add("reconstructed/photons/hPhotonSpectrumReco", "Reconstructed Photon Spectrum", kTHnSparseF, {axisPtAssoc, axisEta, axisPhi}); + registry.add("reconstructed/photons/hPhotonSpectrumReco", "Reconstructed Photon Spectrum", kTHnSparseF, {axisPtAssoc, axisEtaAssoc, axisPhi}); // Charged Pions registry.add("reconstructed/charged/hPionCorrelReco", "Reconstructed Trigger-Pion Correlation", kTHnSparseF, {axisPtTrig, axisPtAssoc, axisDeltaEta, axisDeltaPhi}); registry.add("reconstructed/charged/hPionMultReco", "Reconstructed Pion Multiplicity", kTH1F, {axisMult}); - registry.add("reconstructed/charged/hPionSpectrumReco", "Reconstructed Pion Spectrum", kTHnSparseF, {axisPtAssoc, axisEta, axisPhi}); + registry.add("reconstructed/charged/hPionSpectrumReco", "Reconstructed Pion Spectrum", kTHnSparseF, {axisPtAssoc, axisEtaAssoc, axisPhi}); } // To check if object has has_mcParticle() (i.e. is MC Track or data track) @@ -185,7 +204,7 @@ struct HadronPhotonCorrelation { } } - if (std::abs(track.eta()) > etaMax) { + if (std::abs(track.eta()) > etaMaxAssoc) { return false; } @@ -205,7 +224,11 @@ struct HadronPhotonCorrelation { return false; } - if (std::abs(particle.eta()) > etaMax) { + if (particle.getGenStatusCode() == -1) { + return false; + } + + if (std::abs(particle.eta()) > etaMaxAssoc) { return false; } @@ -227,7 +250,7 @@ struct HadronPhotonCorrelation { } } - if (std::abs(track.eta()) > etaMax) { + if (std::abs(track.eta()) > etaMaxTrig) { return false; } @@ -251,7 +274,7 @@ struct HadronPhotonCorrelation { return false; } - if (std::abs(particle.eta()) > etaMax) { + if (std::abs(particle.eta()) > etaMaxTrig) { return false; } @@ -286,17 +309,49 @@ struct HadronPhotonCorrelation { return false; } - if (track.tpcNClsCrossedRows() < 70) { + if (track.tpcNClsCrossedRows() < tpcNClsCrossedRows) { return false; } - if (track.tpcCrossedRowsOverFindableCls() < 0.8) { + if (track.tpcCrossedRowsOverFindableCls() < tpcCrossedRowsOverFindableCls) { return false; } return true; } + /**************************************************************************************************** + ************************************************ EVENTS ******************************************** + ****************************************************************************************************/ + + void processEventsMCGen(JetMcCollision const& collision) + { + if (collision.subGeneratorId() != subGeneratorIdSelections) { + return; + } + + registry.fill(HIST("generated/events/hEventStats"), 0); + registry.fill(HIST("generated/events/hEventStats"), 1, collision.weight()); + registry.fill(HIST("generated/events/hEventStats"), 2, collision.xsectGen()); + } + PROCESS_SWITCH(HadronPhotonCorrelation, processEventsMCGen, "event stats MC gen", true); + + void processEventsMCReco(JetCollisionMCD const& collision, + JetMcCollisions const&) + { + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, false)) { + return; + } + if (collision.subGeneratorId() != subGeneratorIdSelections) { + return; + } + + registry.fill(HIST("reconstructed/events/hEventStats"), 0); + registry.fill(HIST("reconstructed/events/hEventStats"), 1, collision.mcCollision().weight()); + registry.fill(HIST("reconstructed/events/hEventStats"), 2, collision.mcCollision().xsectGen()); + } + PROCESS_SWITCH(HadronPhotonCorrelation, processEventsMCReco, "event stats MC reco", true); + /**************************************************************************************************** ************************************************ TRIGGER ******************************************** ****************************************************************************************************/ @@ -329,11 +384,15 @@ struct HadronPhotonCorrelation { /*********************************************** MC ************************************************/ - void processTrigsMCReco(JetCollision const& collision, + void processTrigsMCReco(JetCollisionMCD const& collision, + JetMcCollisions const&, Join const& tracks, JetParticles const&) { - if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, false)) { + return; + } + if (collision.subGeneratorId() != subGeneratorIdSelections) { return; } @@ -346,26 +405,29 @@ struct HadronPhotonCorrelation { if (!initTrig(track)) { continue; } - registry.fill(HIST("reconstructed/triggers/hTrigSpectrumReco"), track.pt(), track.eta(), track.phi()); + registry.fill(HIST("reconstructed/triggers/hTrigSpectrumReco"), track.pt(), track.eta(), track.phi(), collision.mcCollision().weight()); nTrigs++; } - registry.fill(HIST("reconstructed/triggers/hTrigMultReco"), nTrigs); + registry.fill(HIST("reconstructed/triggers/hTrigMultReco"), nTrigs, collision.mcCollision().weight()); } PROCESS_SWITCH(HadronPhotonCorrelation, processTrigsMCReco, "trigger particle mc properties", true); - void processTrigsMCGen(JetMcCollision const&, + void processTrigsMCGen(JetMcCollision const& collision, JetParticles const& particles) { + if (collision.subGeneratorId() != subGeneratorIdSelections) { + return; + } int nTrigs = 0; for (const auto& particle : particles) { if (!initTrigParticle(particle)) { continue; } - registry.fill(HIST("generated/triggers/hTrigSpectrumGen"), particle.pt(), particle.eta(), particle.phi()); + registry.fill(HIST("generated/triggers/hTrigSpectrumGen"), particle.pt(), particle.eta(), particle.phi(), collision.weight()); nTrigs++; } - registry.fill(HIST("generated/triggers/hTrigMultGen"), nTrigs); + registry.fill(HIST("generated/triggers/hTrigMultGen"), nTrigs, collision.weight()); } PROCESS_SWITCH(HadronPhotonCorrelation, processTrigsMCGen, "trigger particle mc properties", true); @@ -402,8 +464,8 @@ struct HadronPhotonCorrelation { if (!initTrig(track)) { continue; } - float dphi = RecoDecay::constrainAngle(track.phi() - v0.phi(), -PIHalf); - registry.fill(HIST("reconstructed/photons/hPhotonCorrelReco"), track.pt(), v0.pt(), track.eta() - v0.eta(), dphi); + float dphi = RecoDecay::constrainAngle(v0.phi() - track.phi(), -PIHalf); + registry.fill(HIST("reconstructed/photons/hPhotonCorrelReco"), track.pt(), v0.pt(), v0.eta() - track.eta(), dphi); } } registry.fill(HIST("reconstructed/photons/hPhotonMultReco"), nPhotons); @@ -413,14 +475,17 @@ struct HadronPhotonCorrelation { /*********************************************** MC ************************************************/ using MyTracksMC = soa::Join; - void processPhotonCorrelationsMCReco(Join::iterator const& collision_reco, + void processPhotonCorrelationsMCReco(Join::iterator const& collision_reco, JetMcCollisions const&, JetTracks const& tracks_reco, JetParticles const&, MyTracksMC const&, V0Datas const& v0s) { - if (!jetderiveddatautilities::selectCollision(collision_reco, eventSelectionBits)) { + if (!jetderiveddatautilities::selectCollision(collision_reco, eventSelectionBits, false)) { + return; + } + if (collision_reco.mcCollision().subGeneratorId() != subGeneratorIdSelections) { return; } @@ -431,7 +496,7 @@ struct HadronPhotonCorrelation { if (!initV0(v0)) { continue; } - registry.fill(HIST("reconstructed/photons/hPhotonSpectrumReco"), v0.pt(), v0.eta(), v0.phi()); + registry.fill(HIST("reconstructed/photons/hPhotonSpectrumReco"), v0.pt(), v0.eta(), v0.phi(), collision_reco.mcCollision().weight()); nPhotons++; for (const auto& track : tracks_reco) { @@ -442,17 +507,21 @@ struct HadronPhotonCorrelation { if (!initTrig(track)) { continue; } - float dphi = RecoDecay::constrainAngle(track.phi() - v0.phi(), -PIHalf); - registry.fill(HIST("reconstructed/photons/hPhotonCorrelReco"), track.pt(), v0.pt(), track.eta() - v0.eta(), dphi); + float dphi = RecoDecay::constrainAngle(v0.phi() - track.phi(), -PIHalf); + registry.fill(HIST("reconstructed/photons/hPhotonCorrelReco"), track.pt(), v0.pt(), v0.eta() - track.eta(), dphi, collision_reco.mcCollision().weight()); } } - registry.fill(HIST("reconstructed/photons/hPhotonMultReco"), nPhotons); + registry.fill(HIST("reconstructed/photons/hPhotonMultReco"), nPhotons, collision_reco.mcCollision().weight()); } PROCESS_SWITCH(HadronPhotonCorrelation, processPhotonCorrelationsMCReco, "hadron-photon correlation", true); - void processPhotonCorrelationsMCGen(JetMcCollision const&, + void processPhotonCorrelationsMCGen(JetMcCollision const& collision, JetParticles const& tracks_true) { + if (collision.subGeneratorId() != subGeneratorIdSelections) { + return; + } + int nPhotons = 0; for (const auto& track_assoc : tracks_true) { if (!initParticle(track_assoc, false)) { @@ -474,8 +543,9 @@ struct HadronPhotonCorrelation { } auto pdgMother = pdg->GetParticle(mother.pdgCode()); - if (!pdgMother) + if (!pdgMother) { continue; + } int photonGeneration; switch (std::abs(origPhoton.getGenStatusCode())) { case 23: // prompt direct photons @@ -496,7 +566,7 @@ struct HadronPhotonCorrelation { break; } - registry.fill(HIST("generated/photons/hPhotonSpectrumGen"), track_assoc.pt(), track_assoc.eta(), track_assoc.phi(), photonGeneration); + registry.fill(HIST("generated/photons/hPhotonSpectrumGen"), track_assoc.pt(), track_assoc.eta(), track_assoc.phi(), photonGeneration, collision.weight()); nPhotons++; @@ -507,12 +577,12 @@ struct HadronPhotonCorrelation { if (!initParticle(track_assoc)) { continue; } - float dphi = RecoDecay::constrainAngle(track_trig.phi() - track_assoc.phi(), -PIHalf); - registry.fill(HIST("generated/photons/hPhotonCorrelGen"), track_trig.pt(), track_assoc.pt(), track_trig.eta() - track_assoc.eta(), dphi, photonGeneration); + float dphi = RecoDecay::constrainAngle(track_assoc.phi() - track_trig.phi(), -PIHalf); + registry.fill(HIST("generated/photons/hPhotonCorrelGen"), track_trig.pt(), track_assoc.pt(), track_assoc.eta() - track_trig.eta(), dphi, photonGeneration, collision.weight()); } } - registry.fill(HIST("generated/photons/hPhotonMultGen"), nPhotons); + registry.fill(HIST("generated/photons/hPhotonMultGen"), nPhotons, collision.weight()); } PROCESS_SWITCH(HadronPhotonCorrelation, processPhotonCorrelationsMCGen, "mc hadron-photon correlation", true); @@ -550,8 +620,8 @@ struct HadronPhotonCorrelation { if (!initTrig(track_trig)) { continue; } - float dphi = RecoDecay::constrainAngle(track_trig.phi() - track_assoc.phi(), -PIHalf); - registry.fill(HIST("reconstructed/hadrons/hadrons/hHadronCorrelReco"), track_trig.pt(), track_assoc.pt(), track_trig.eta() - track_assoc.eta(), dphi); + float dphi = RecoDecay::constrainAngle(track_assoc.phi() - track_trig.phi(), -PIHalf); + registry.fill(HIST("reconstructed/hadrons/hadrons/hHadronCorrelReco"), track_trig.pt(), track_assoc.pt(), track_assoc.eta() - track_trig.eta(), dphi); } } registry.fill(HIST("reconstructed/hadrons/hHadronMultReco"), nHadrons); @@ -560,9 +630,13 @@ struct HadronPhotonCorrelation { /*********************************************** MC ************************************************/ - void processHadronCorrelationsMCGen(JetMcCollision const&, + void processHadronCorrelationsMCGen(JetMcCollision const& collision, JetParticles const& tracks_true) { + if (collision.subGeneratorId() != subGeneratorIdSelections) { + return; + } + int nHadrons = 0; for (const auto& track_assoc : tracks_true) { if (!initParticle(track_assoc)) { @@ -572,11 +646,11 @@ struct HadronPhotonCorrelation { if (!pdgParticle || pdgParticle->Charge() == 0.) { continue; } - if (std::abs(track_assoc.pdgCode()) < 100) { + if (std::abs(track_assoc.pdgCode()) < pidCodeHadronCut) { continue; } - registry.fill(HIST("generated/hadrons/hHadronSpectrumGen"), track_assoc.pt(), track_assoc.eta(), track_assoc.phi()); + registry.fill(HIST("generated/hadrons/hHadronSpectrumGen"), track_assoc.pt(), track_assoc.eta(), track_assoc.phi(), collision.weight()); nHadrons++; for (const auto& track_trig : tracks_true) { @@ -586,21 +660,24 @@ struct HadronPhotonCorrelation { if (track_trig == track_assoc) { continue; } - float dphi = RecoDecay::constrainAngle(track_trig.phi() - track_assoc.phi(), -PIHalf); + float dphi = RecoDecay::constrainAngle(track_assoc.phi() - track_trig.phi(), -PIHalf); - registry.fill(HIST("generated/hadrons/hHadronCorrelGen"), track_trig.pt(), track_assoc.pt(), track_trig.eta() - track_assoc.eta(), dphi); + registry.fill(HIST("generated/hadrons/hHadronCorrelGen"), track_trig.pt(), track_assoc.pt(), track_assoc.eta() - track_trig.eta(), dphi, collision.weight()); } } - registry.fill(HIST("generated/hadrons/hHadronMultGen"), nHadrons); + registry.fill(HIST("generated/hadrons/hHadronMultGen"), nHadrons, collision.weight()); } PROCESS_SWITCH(HadronPhotonCorrelation, processHadronCorrelationsMCGen, "mc hadron-hadron correlation", true); - void processHadronCorrelationsMCReco(Join::iterator const& collision_reco, + void processHadronCorrelationsMCReco(JetCollisionMCD const& collision_reco, JetMcCollisions const&, - Join const& tracks_reco, + JetTracksMCD const& tracks_reco, JetParticles const&) { - if (!jetderiveddatautilities::selectCollision(collision_reco, eventSelectionBits)) { + if (!jetderiveddatautilities::selectCollision(collision_reco, eventSelectionBits, false)) { + return; + } + if (collision_reco.mcCollision().subGeneratorId() != subGeneratorIdSelections) { return; } @@ -618,16 +695,16 @@ struct HadronPhotonCorrelation { if (!pdgParticle || pdgParticle->Charge() == 0.) { continue; } - if (std::abs(particle.pdgCode()) < 100) { + if (std::abs(particle.pdgCode()) < pidCodeHadronCut) { continue; } - registry.fill(HIST("reconstructed/hadrons/hHadronSpectrumReco"), track_assoc.pt(), track_assoc.eta(), track_assoc.phi()); + registry.fill(HIST("reconstructed/hadrons/hHadronSpectrumReco"), track_assoc.pt(), track_assoc.eta(), track_assoc.phi(), collision_reco.mcCollision().weight()); if (particle.isPhysicalPrimary()) { - registry.fill(HIST("reconstructed/hadrons/hHadronPtPrimReco"), track_assoc.pt()); + registry.fill(HIST("reconstructed/hadrons/hHadronPtPrimReco"), track_assoc.pt(), collision_reco.mcCollision().weight()); } else { - registry.fill(HIST("reconstructed/hadrons/hHadronPtSecReco"), track_assoc.pt()); + registry.fill(HIST("reconstructed/hadrons/hHadronPtSecReco"), track_assoc.pt(), collision_reco.mcCollision().weight()); } nHadrons++; @@ -641,12 +718,12 @@ struct HadronPhotonCorrelation { if (!initTrig(track_trig)) { continue; } - float dphi = RecoDecay::constrainAngle(track_trig.phi() - track_assoc.phi(), -PIHalf); + float dphi = RecoDecay::constrainAngle(track_assoc.phi() - track_trig.phi(), -PIHalf); - registry.fill(HIST("reconstructed/hadrons/hHadronCorrelReco"), track_trig.pt(), track_assoc.pt(), track_trig.eta() - track_assoc.eta(), dphi); + registry.fill(HIST("reconstructed/hadrons/hHadronCorrelReco"), track_trig.pt(), track_assoc.pt(), track_assoc.eta() - track_trig.eta(), dphi, collision_reco.mcCollision().weight()); } } - registry.fill(HIST("reconstructed/hadrons/hHadronMultReco"), nHadrons); + registry.fill(HIST("reconstructed/hadrons/hHadronMultReco"), nHadrons, collision_reco.mcCollision().weight()); } PROCESS_SWITCH(HadronPhotonCorrelation, processHadronCorrelationsMCReco, "mc hadron-hadron correlation", true); @@ -671,7 +748,7 @@ struct HadronPhotonCorrelation { if (!initTrack(track_assoc)) { continue; } - if (std::abs(track_assoc.tpcNSigmaPi()) > 2) { + if (std::abs(track_assoc.tpcNSigmaPi()) > tpcNSigmaPi) { continue; } // remove non-pions registry.fill(HIST("reconstructed/charged/hPionSpectrumReco"), track_assoc.pt(), track_assoc.eta(), track_assoc.phi()); @@ -687,8 +764,8 @@ struct HadronPhotonCorrelation { if (!initTrig(track_trig)) { continue; } - float dphi = RecoDecay::constrainAngle(track_trig.phi() - track_assoc.phi(), -PIHalf); - registry.fill(HIST("reconstructed/charged/hPionCorrelReco"), track_trig.pt(), track_assoc.pt(), track_trig.eta() - track_assoc.eta(), dphi); + float dphi = RecoDecay::constrainAngle(track_assoc.phi() - track_trig.phi(), -PIHalf); + registry.fill(HIST("reconstructed/charged/hPionCorrelReco"), track_trig.pt(), track_assoc.pt(), track_assoc.eta() - track_trig.eta(), dphi); } } registry.fill(HIST("reconstructed/charged/hPionMultReco"), nPions); @@ -697,9 +774,13 @@ struct HadronPhotonCorrelation { /*********************************************** MC ************************************************/ - void processPionCorrelationsMCGen(JetMcCollision const&, + void processPionCorrelationsMCGen(JetMcCollision const& collision, JetParticles const& tracks_true) { + if (collision.subGeneratorId() != subGeneratorIdSelections) { + return; + } + int nPions = 0; for (const auto& track_assoc : tracks_true) { if (!initParticle(track_assoc)) { @@ -709,7 +790,7 @@ struct HadronPhotonCorrelation { continue; } - registry.fill(HIST("generated/charged/hPionSpectrumGen"), track_assoc.pt(), track_assoc.eta(), track_assoc.phi()); + registry.fill(HIST("generated/charged/hPionSpectrumGen"), track_assoc.pt(), track_assoc.eta(), track_assoc.phi(), collision.weight()); nPions++; for (const auto& track_trig : tracks_true) { @@ -719,21 +800,24 @@ struct HadronPhotonCorrelation { if (track_trig == track_assoc) { continue; } - float dphi = RecoDecay::constrainAngle(track_trig.phi() - track_assoc.phi(), -PIHalf); + float dphi = RecoDecay::constrainAngle(track_assoc.phi() - track_trig.phi(), -PIHalf); - registry.fill(HIST("generated/charged/hPionCorrelGen"), track_trig.pt(), track_assoc.pt(), track_trig.eta() - track_assoc.eta(), dphi); + registry.fill(HIST("generated/charged/hPionCorrelGen"), track_trig.pt(), track_assoc.pt(), track_assoc.eta() - track_trig.eta(), dphi, collision.weight()); } } - registry.fill(HIST("generated/charged/hPionMultGen"), nPions); + registry.fill(HIST("generated/charged/hPionMultGen"), nPions, collision.weight()); } PROCESS_SWITCH(HadronPhotonCorrelation, processPionCorrelationsMCGen, "mc hadron-pion correlation", true); - void processPionCorrelationsMCReco(Join::iterator const& collision_reco, + void processPionCorrelationsMCReco(JetCollisionMCD const& collision_reco, JetMcCollisions const&, - Join const& tracks_reco, + JetTracksMCD const& tracks_reco, JetParticles const&) { - if (!jetderiveddatautilities::selectCollision(collision_reco, eventSelectionBits)) { + if (!jetderiveddatautilities::selectCollision(collision_reco, eventSelectionBits, false)) { + return; + } + if (collision_reco.mcCollision().subGeneratorId() != subGeneratorIdSelections) { return; } @@ -750,7 +834,7 @@ struct HadronPhotonCorrelation { continue; } - registry.fill(HIST("reconstructed/charged/hPionSpectrumReco"), track_assoc.pt(), track_assoc.eta(), track_assoc.phi()); + registry.fill(HIST("reconstructed/charged/hPionSpectrumReco"), track_assoc.pt(), track_assoc.eta(), track_assoc.phi(), collision_reco.mcCollision().weight()); nPions++; for (const auto& track_trig : tracks_reco) { @@ -764,11 +848,11 @@ struct HadronPhotonCorrelation { if (!initTrig(track_trig)) { continue; } - float dphi = RecoDecay::constrainAngle(track_trig.phi() - track_assoc.phi(), -PIHalf); - registry.fill(HIST("reconstructed/charged/hPionCorrelReco"), track_trig.pt(), track_assoc.pt(), track_trig.eta() - track_assoc.eta(), dphi); + float dphi = RecoDecay::constrainAngle(track_assoc.phi() - track_trig.phi(), -PIHalf); + registry.fill(HIST("reconstructed/charged/hPionCorrelReco"), track_trig.pt(), track_assoc.pt(), track_assoc.eta() - track_trig.eta(), dphi, collision_reco.mcCollision().weight()); } } - registry.fill(HIST("reconstructed/charged/hPionMultReco"), nPions); + registry.fill(HIST("reconstructed/charged/hPionMultReco"), nPions, collision_reco.mcCollision().weight()); } PROCESS_SWITCH(HadronPhotonCorrelation, processPionCorrelationsMCReco, "mc hadron-pion correlation", true); @@ -778,9 +862,13 @@ struct HadronPhotonCorrelation { /*********************************************** MC ************************************************/ - void processNeutralCorrelationsMCGen(JetMcCollision const&, + void processNeutralCorrelationsMCGen(JetMcCollision const& collision, JetParticles const& tracks_true) { + if (collision.subGeneratorId() != subGeneratorIdSelections) { + return; + } + int nNeutrals = 0; for (const auto& track_assoc : tracks_true) { if (!initParticle(track_assoc, false)) { @@ -793,16 +881,17 @@ struct HadronPhotonCorrelation { if (pdgParticle->Charge() != 0.) { continue; } // remove charged particles - if (track_assoc.pdgCode() < 100 || (PDG_t)track_assoc.pdgCode() == kNeutron) { + if (track_assoc.pdgCode() < pidCodeHadronCut || (PDG_t)track_assoc.pdgCode() == kNeutron) { continue; } // remove non-hadrons and neutrons - registry.fill(HIST("generated/neutral/hNeutralSpectrumGen"), track_assoc.pt(), track_assoc.eta(), track_assoc.phi(), pidCodes[pdgParticle->GetName()]); + registry.fill(HIST("generated/neutral/hNeutralSpectrumGen"), track_assoc.pt(), track_assoc.eta(), track_assoc.phi(), pidCodes[pdgParticle->GetName()], collision.weight()); nNeutrals++; // Get correlations between neutral hadrons and their respective decay photons auto daughters = track_assoc.daughters_as(); double alpha = -1; - if (daughters.size() == 2) { + int nPhotonsPionDecay = 2; + if (daughters.size() == nPhotonsPionDecay) { auto daughter = daughters.begin(); double pt1 = daughter.pt(); ++daughter; @@ -811,18 +900,18 @@ struct HadronPhotonCorrelation { } for (const auto& daughter : daughters) { - if ((PDG_t)std::abs(daughter.pdgCode()) != kGamma) - continue; - if (!initParticle(daughter, false)) + if ((PDG_t)std::abs(daughter.pdgCode()) != kGamma) { continue; - if (!daughter.isPhysicalPrimary() && daughter.getGenStatusCode() == -1) + } + if (!daughter.isPhysicalPrimary() && daughter.getGenStatusCode() == -1) { continue; + } double deltaPt = daughter.pt() / track_assoc.pt(); double deltaEta = daughter.eta() - track_assoc.eta(); double deltaPhi = RecoDecay::constrainAngle(daughter.phi() - track_assoc.phi(), -PIHalf); double deltaR = std::sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi); - registry.fill(HIST("generated/neutral/hNeutralDecayGen"), track_assoc.pt(), deltaPt, deltaR, alpha, pidCodes[pdgParticle->GetName()]); + registry.fill(HIST("generated/neutral/hNeutralDecayGen"), track_assoc.pt(), deltaPt, deltaR, alpha, pidCodes[pdgParticle->GetName()], collision.weight()); } // Get correlations between triggers and neutral hadrons @@ -831,10 +920,10 @@ struct HadronPhotonCorrelation { continue; } float dphi = RecoDecay::constrainAngle(track_assoc.phi() - track_trig.phi(), -PIHalf); - registry.fill(HIST("generated/neutral/hNeutralCorrelGen"), track_trig.pt(), track_assoc.pt(), track_assoc.eta() - track_trig.eta(), dphi, pidCodes[pdgParticle->GetName()]); + registry.fill(HIST("generated/neutral/hNeutralCorrelGen"), track_trig.pt(), track_assoc.pt(), track_assoc.eta() - track_trig.eta(), dphi, pidCodes[pdgParticle->GetName()], collision.weight()); } } - registry.fill(HIST("generated/neutral/hNeutralMultGen"), nNeutrals); + registry.fill(HIST("generated/neutral/hNeutralMultGen"), nNeutrals, collision.weight()); } PROCESS_SWITCH(HadronPhotonCorrelation, processNeutralCorrelationsMCGen, "mc hadron-pion correlation", true); }; diff --git a/PWGJE/Tasks/jetFragmentation.cxx b/PWGJE/Tasks/jetFragmentation.cxx index c181254819f..18d5dea2c56 100644 --- a/PWGJE/Tasks/jetFragmentation.cxx +++ b/PWGJE/Tasks/jetFragmentation.cxx @@ -56,9 +56,9 @@ using MatchedMCPJetsWithConstituents = soa::Join; -using CandidatesV0DataWithFlags = soa::Join; +using CandidatesV0DataWithFlags = aod::CandidatesV0Data; -using CandidatesV0MCDWithLabelsAndFlags = soa::Join; +using CandidatesV0MCDWithLabelsAndFlags = soa::Join; using MCDV0Jets = aod::V0ChargedMCDetectorLevelJets; using MCDV0JetsWithConstituents = soa::Join; using MatchedMCDV0Jets = soa::Join; diff --git a/PWGJE/Tasks/jetHadronRecoil.cxx b/PWGJE/Tasks/jetHadronRecoil.cxx index 3d0e6f1bb59..71946c49aee 100644 --- a/PWGJE/Tasks/jetHadronRecoil.cxx +++ b/PWGJE/Tasks/jetHadronRecoil.cxx @@ -71,6 +71,8 @@ struct JetHadronRecoil { Configurable pTHatExponent{"pTHatExponent", 4.0, "exponent of the event weight for the calculation of pTHat"}; Configurable pTHatMaxMCD{"pTHatMaxMCD", 999.0, "maximum fraction of hard scattering for jet acceptance in detector MC"}; Configurable pTHatMaxMCP{"pTHatMaxMCP", 999.0, "maximum fraction of hard scattering for jet acceptance in particle MC"}; + Configurable pTHatTrackMaxMCD{"pTHatTrackMaxMCD", 999.0, "maximum fraction of hard scattering for track acceptance in detector MC"}; + Configurable pTHatTrackMaxMCP{"pTHatTrackMaxMCP", 999.0, "maximum fraction of hard scattering for track acceptance in particle MC"}; Configurable rhoReferenceShift{"rhoReferenceShift", 0.0, "shift in rho calculated in reference events for consistency with signal events"}; Configurable triggerMasks{"triggerMasks", "", "possible JE Trigger masks: fJetChLowPt,fJetChHighPt,fTrackLowPt,fTrackHighPt,fJetD0ChLowPt,fJetD0ChHighPt,fJetLcChLowPt,fJetLcChHighPt,fEMCALReadout,fJetFullHighPt,fJetFullLowPt,fJetNeutralHighPt,fJetNeutralLowPt,fGammaVeryHighPtEMCAL,fGammaVeryHighPtDCAL,fGammaHighPtEMCAL,fGammaHighPtDCAL,fGammaLowPtEMCAL,fGammaLowPtDCAL,fGammaVeryLowPtEMCAL,fGammaVeryLowPtDCAL"}; Configurable skipMBGapEvents{"skipMBGapEvents", false, "flag to choose to reject min. bias gap events; jet-level rejection applied at the jet finder level, here rejection is applied for collision and track process functions"}; @@ -106,7 +108,6 @@ struct JetHadronRecoil { 0.57, 0.60}; AxisSpec dRAxis = {dRBinning, "#Delta R"}; - AxisSpec ptAxisDet = {ptBinningDet, "#it{p}_{T,det} (GeV/c)"}; AxisSpec ptAxisPart = {ptBinningPart, "#it{p}_{T,part} (GeV/c)"}; AxisSpec phiAxisDet = {100, 0.0, o2::constants::math::TwoPI, "#phi_{det}"}; @@ -116,10 +117,14 @@ struct JetHadronRecoil { HistogramRegistry registry{"registry", {{"hNtrig", "number of triggers;trigger type;entries", {HistType::kTH1F, {{2, 0, 2}}}}, + {"hSignalTriggersPtHard", "Signal triggers vs PtHard", {HistType::kTH1F, {{20, 0, 5}}}}, + {"hReferenceTriggersPtHard", "Reference triggers vs PtHard", {HistType::kTH1F, {{20, 0, 5}}}}, {"hZvtxSelected", "Z vertex position;Z_{vtx};entries", {HistType::kTH1F, {{80, -20, 20}}}}, {"hPtTrack", "Track p_{T};p_{T};entries", {HistType::kTH1F, {{200, 0, 200}}}}, {"hEtaTrack", "Track #eta;#eta;entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}}, {"hPhiTrack", "Track #phi;#phi;entries", {HistType::kTH1F, {{100, 0.0, o2::constants::math::TwoPI}}}}, + {"hTrack3D", "3D tracks histogram;p_{T};#eta;#phi", {HistType::kTH3F, {{200, 0, 200}, {100, -1.0, 1.0}, {100, 0.0, o2::constants::math::TwoPI}}}}, + {"hPtTrackPtHard", "Track p_{T} vs #hat{p};p_{T};#frac{p_{T}}{#hat{p}}", {HistType::kTH2F, {{200, 0, 200}, {20, 0, 5}}}}, {"hConstituents3D", "3D constituents histogram;p_{T};#eta;#phi", {HistType::kTH3F, {{200, 0, 200}, {100, -1.0, 1.0}, {100, 0.0, o2::constants::math::TwoPI}}}}, {"hReferencePtDPhi", "jet p_{T} vs DPhi;#Delta#phi;p_{T,jet}", {HistType::kTH2F, {{100, 0, o2::constants::math::TwoPI}, {500, -100, 400}}}}, {"hReferencePtDPhiShifts", "rho shifts;#Delta#phi;p_{T,jet};shifts", {HistType::kTH3F, {{100, 0, o2::constants::math::TwoPI}, {500, -100, 400}, {20, 0.0, 2.0}}}}, @@ -139,6 +144,8 @@ struct JetHadronRecoil { {"hPtPart", "Particle p_{T};p_{T};entries", {HistType::kTH1F, {{200, 0, 200}}}}, {"hEtaPart", "Particle #eta;#eta;entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}}, {"hPhiPart", "Particle #phi;#phi;entries", {HistType::kTH1F, {{100, 0.0, o2::constants::math::TwoPI}}}}, + {"hPart3D", "3D tracks histogram;p_{T};#eta;#phi", {HistType::kTH3F, {{200, 0, 200}, {100, -1.0, 1.0}, {100, 0.0, o2::constants::math::TwoPI}}}}, + {"hPtPartPtHard", "Track p_{T} vs #hat{p};p_{T};#frac{p_{T}}{#hat{p}}", {HistType::kTH2F, {{200, 0, 200}, {20, 0, 5}}}}, {"hDeltaR", "#DeltaR;#DeltaR;#frac{dN_{jets}}{d#DeltaR}", {HistType::kTH1F, {dRAxis}}}, {"hDeltaRPart", "Particle #DeltaR;#DeltaR;#frac{1}{N_{jets}}#frac{dN_{jets}}{d#DeltaR}", {HistType::kTH1F, {dRAxis}}}, {"hDeltaRpT", "jet p_{T} vs #DeltaR;p_{T,jet};#DeltaR", {HistType::kTH2F, {{500, -100, 400}, dRAxis}}}, @@ -216,6 +223,9 @@ struct JetHadronRecoil { if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { continue; } + if (track.pt() > pTHatTrackMaxMCD * pTHat) { + return; + } if (isSigCol && track.pt() < ptTTsigMax && track.pt() > ptTTsigMin) { phiTTAr.push_back(track.phi()); ptTTAr.push_back(track.pt()); @@ -231,6 +241,8 @@ struct JetHadronRecoil { registry.fill(HIST("hPtTrack"), track.pt(), weight); registry.fill(HIST("hEtaTrack"), track.eta(), weight); registry.fill(HIST("hPhiTrack"), track.phi(), weight); + registry.fill(HIST("hTrack3D"), track.pt(), track.eta(), track.phi(), weight); + registry.fill(HIST("hPtTrackPtHard"), track.pt(), track.pt() / pTHat, weight); } if (nTT > 0) { @@ -241,6 +253,7 @@ struct JetHadronRecoil { registry.fill(HIST("hNtrig"), 1.5, weight); registry.fill(HIST("hSigEventTriggers"), nTT, weight); registry.fill(HIST("hRhoSignal"), rho, weight); + registry.fill(HIST("hSignalTriggersPtHard"), ptTT / pTHat, weight); } if (!isSigCol) { registry.fill(HIST("hNtrig"), 0.5, weight); @@ -249,12 +262,13 @@ struct JetHadronRecoil { for (double shift = 0.0; shift <= 2.0; shift += 0.1) { registry.fill(HIST("hRhoReferenceShift"), rho + shift, shift, weight); } + registry.fill(HIST("hReferenceTriggersPtHard"), ptTT / pTHat, weight); } } for (const auto& jet : jets) { if (jet.pt() > pTHatMaxMCD * pTHat) { - continue; + return; } for (const auto& constituent : jet.template tracks_as
()) { if (constituent.pt() > leadingPT) { @@ -317,7 +331,9 @@ struct JetHadronRecoil { { bool isSigCol; std::vector phiTTAr; + std::vector ptTTAr; double phiTT = 0; + double ptTT = 0; int trigNumber = 0; int nTT = 0; float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); @@ -329,6 +345,9 @@ struct JetHadronRecoil { isSigCol = false; for (const auto& particle : particles) { + if (particle.pt() > pTHatTrackMaxMCD * pTHat) { + return; + } auto pdgParticle = pdg->GetParticle(particle.pdgCode()); if (!pdgParticle) { continue; @@ -338,33 +357,40 @@ struct JetHadronRecoil { } if (isSigCol && particle.pt() < ptTTsigMax && particle.pt() > ptTTsigMin) { phiTTAr.push_back(particle.phi()); + ptTTAr.push_back(particle.pt()); nTT++; } if (!isSigCol && particle.pt() < ptTTrefMax && particle.pt() > ptTTrefMin) { phiTTAr.push_back(particle.phi()); + ptTTAr.push_back(particle.pt()); nTT++; } registry.fill(HIST("hPtPart"), particle.pt(), weight); registry.fill(HIST("hEtaPart"), particle.eta(), weight); registry.fill(HIST("hPhiPart"), particle.phi(), weight); + registry.fill(HIST("hPart3D"), particle.pt(), particle.eta(), particle.phi(), weight); + registry.fill(HIST("hPtPartPtHard"), particle.pt(), particle.pt() / pTHat, weight); } if (nTT > 0) { trigNumber = rand->Integer(nTT); phiTT = phiTTAr[trigNumber]; + ptTT = ptTTAr[trigNumber]; if (isSigCol) { registry.fill(HIST("hNtrig"), 1.5, weight); registry.fill(HIST("hSigEventTriggers"), nTT, weight); + registry.fill(HIST("hSignalTriggersPtHard"), ptTT / pTHat, weight); } if (!isSigCol) { registry.fill(HIST("hNtrig"), 0.5, weight); registry.fill(HIST("hRefEventTriggers"), nTT, weight); + registry.fill(HIST("hReferenceTriggersPtHard"), ptTT / pTHat, weight); } } for (const auto& jet : jets) { if (jet.pt() > pTHatMaxMCP * pTHat) { - continue; + return; } for (const auto& constituent : jet.template tracks_as()) { registry.fill(HIST("hConstituents3D"), constituent.pt(), constituent.eta(), constituent.phi()); @@ -389,6 +415,7 @@ struct JetHadronRecoil { registry.fill(HIST("hSignalPtDPhi"), dphi, jet.pt(), weight); if (std::abs(dphi - o2::constants::math::PI) < 0.6) { registry.fill(HIST("hSignalPt"), jet.pt(), weight); + registry.fill(HIST("hSignalPtHard"), jet.pt(), ptTT / pTHat, weight); } } if (!isSigCol) { @@ -400,6 +427,7 @@ struct JetHadronRecoil { registry.fill(HIST("hReferencePtDPhi"), dphi, jet.pt(), weight); if (std::abs(dphi - o2::constants::math::PI) < 0.6) { registry.fill(HIST("hReferencePt"), jet.pt(), weight); + registry.fill(HIST("hReferencePtHard"), jet.pt(), ptTT / pTHat, weight); } } } @@ -407,46 +435,48 @@ struct JetHadronRecoil { } template - void fillMatchedHistograms(T const& jetBase, V const& mcdjetsWTA, W const& mcpjetsWTA, U const&, X const& tracks, Y const& particles, float weight = 1.0, float rho = 0.0) + void fillMatchedHistograms(T const& jetsBase, V const& mcdjetsWTA, W const& mcpjetsWTA, U const&, X const& tracks, Y const& particles, float weight = 1.0, float rho = 0.0) { - double dR = 0; - double dRp = 0; + for (const auto& jetBase : jetsBase) { + double dR = 0; + double dRp = 0; - float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); - if (jetBase.pt() > pTHatMaxMCD * pTHat) { - return; - } - - for (const auto& mcdjetWTA : mcdjetsWTA) { - double djet = RecoDecay::sqrtSumOfSquares(RecoDecay::constrainAngle(jetBase.phi() - mcdjetWTA.phi(), -o2::constants::math::PI), jetBase.eta() - mcdjetWTA.eta()); - if (mcdjetWTA.pt() > pTHatMaxMCD * pTHat) { - continue; - } - if (djet < 0.6 * jetR) { - dR = djet; - break; + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); + if (jetBase.pt() > pTHatMaxMCD * pTHat) { + return; } - } - - dR = getWTAaxisDifference(jetBase, mcdjetsWTA, tracks, true); - if (jetBase.has_matchedJetGeo()) { - for (const auto& jetTag : jetBase.template matchedJetGeo_as>()) { - if (jetTag.pt() > pTHatMaxMCP * pTHat) { + for (const auto& mcdjetWTA : mcdjetsWTA) { + double djet = RecoDecay::sqrtSumOfSquares(RecoDecay::constrainAngle(jetBase.phi() - mcdjetWTA.phi(), -o2::constants::math::PI), jetBase.eta() - mcdjetWTA.eta()); + if (mcdjetWTA.pt() > pTHatMaxMCD * pTHat) { continue; } + if (djet < 0.6 * jetR) { + dR = djet; + break; + } + } + + dR = getWTAaxisDifference(jetBase, mcdjetsWTA, tracks, true); + + if (jetBase.has_matchedJetGeo()) { + for (const auto& jetTag : jetBase.template matchedJetGeo_as>()) { + if (jetTag.pt() > pTHatMaxMCP * pTHat) { + return; + } - dRp = getWTAaxisDifference(jetTag, mcpjetsWTA, particles, true); - - registry.fill(HIST("hPtMatched"), jetBase.pt() - (rho * jetBase.area()), jetTag.pt(), weight); - registry.fill(HIST("hPhiMatched"), jetBase.phi(), jetTag.phi(), weight); - registry.fill(HIST("hPtResolution"), jetTag.pt(), (jetTag.pt() - (jetBase.pt() - (rho * jetBase.area()))) / jetTag.pt(), weight); - registry.fill(HIST("hPhiResolution"), jetTag.pt(), jetTag.phi() - jetBase.phi(), weight); - registry.fill(HIST("hDeltaRMatched"), dR, dRp, weight); - registry.fill(HIST("hDeltaRResolution"), jetTag.pt(), dRp - dR, weight); - registry.fill(HIST("hFullMatching"), jetBase.pt() - (rho * jetBase.area()), jetTag.pt(), jetBase.phi(), jetTag.phi(), dR, dRp, weight); - registry.fill(HIST("hPtMatched1d"), jetTag.pt(), weight); - registry.fill(HIST("hDeltaRMatched1d"), dRp, weight); + dRp = getWTAaxisDifference(jetTag, mcpjetsWTA, particles, true); + + registry.fill(HIST("hPtMatched"), jetBase.pt() - (rho * jetBase.area()), jetTag.pt(), weight); + registry.fill(HIST("hPhiMatched"), jetBase.phi(), jetTag.phi(), weight); + registry.fill(HIST("hPtResolution"), jetTag.pt(), (jetTag.pt() - (jetBase.pt() - (rho * jetBase.area()))) / jetTag.pt(), weight); + registry.fill(HIST("hPhiResolution"), jetTag.pt(), jetTag.phi() - jetBase.phi(), weight); + registry.fill(HIST("hDeltaRMatched"), dR, dRp, weight); + registry.fill(HIST("hDeltaRResolution"), jetTag.pt(), dRp - dR, weight); + registry.fill(HIST("hFullMatching"), jetBase.pt() - (rho * jetBase.area()), jetTag.pt(), jetBase.phi(), jetTag.phi(), dR, dRp, weight); + registry.fill(HIST("hPtMatched1d"), jetTag.pt(), weight); + registry.fill(HIST("hDeltaRMatched1d"), dRp, weight); + } } } } @@ -610,9 +640,7 @@ struct JetHadronRecoil { } registry.fill(HIST("hZvtxSelected"), collision.posZ()); const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(partJetsPerCollision, collision.mcCollisionId()); - for (const auto& mcdjet : mcdjets) { - fillMatchedHistograms(mcdjet, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles); - } + fillMatchedHistograms(mcdjets, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles); } PROCESS_SWITCH(JetHadronRecoil, processJetsMCPMCDMatched, "process MC matched (inc jets)", false); @@ -633,20 +661,18 @@ struct JetHadronRecoil { } registry.fill(HIST("hZvtxSelected"), collision.posZ()); const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(partJetsPerCollision, collision.mcCollisionId()); - for (const auto& mcdjet : mcdjets) { - fillMatchedHistograms(mcdjet, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles, 1.0, collision.rho()); - } + fillMatchedHistograms(mcdjets, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles); } PROCESS_SWITCH(JetHadronRecoil, processJetsMCPMCDMatchedWithRhoSubtraction, "process MC matched (inc jets) with rho subtraction", false); void processJetsMCPMCDMatchedWeighted(soa::Filtered::iterator const& collision, - soa::Filtered> const& mcdjets, + soa::Filtered> const& mcdjets, soa::Filtered> const& mcdjetsWTA, soa::Filtered> const& mcpjetsWTA, aod::JetTracks const& tracks, aod::JetParticles const& particles, aod::JetMcCollisions const&, - soa::Filtered> const& mcpjets) + soa::Filtered> const& mcpjets) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { return; @@ -656,20 +682,18 @@ struct JetHadronRecoil { } registry.fill(HIST("hZvtxSelected"), collision.posZ()); const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(partJetsPerCollision, collision.mcCollisionId()); - for (const auto& mcdjet : mcdjets) { - fillMatchedHistograms(mcdjet, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles, mcdjet.eventWeight()); - } + fillMatchedHistograms(mcdjets, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles, collision.mcCollision().weight()); } PROCESS_SWITCH(JetHadronRecoil, processJetsMCPMCDMatchedWeighted, "process MC matched with event weights (inc jets)", false); void processJetsMCPMCDMatchedWeightedWithRhoSubtraction(soa::Filtered>::iterator const& collision, - soa::Filtered> const& mcdjets, + soa::Filtered> const& mcdjets, soa::Filtered> const& mcdjetsWTA, soa::Filtered> const& mcpjetsWTA, aod::JetTracks const& tracks, aod::JetParticles const& particles, aod::JetMcCollisions const&, - soa::Filtered> const& mcpjets) + soa::Filtered> const& mcpjets) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { return; @@ -679,9 +703,7 @@ struct JetHadronRecoil { } registry.fill(HIST("hZvtxSelected"), collision.posZ()); const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(partJetsPerCollision, collision.mcCollisionId()); - for (const auto& mcdjet : mcdjets) { - fillMatchedHistograms(mcdjet, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles, mcdjet.eventWeight(), collision.rho()); - } + fillMatchedHistograms(mcdjets, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles, collision.mcCollision().weight(), collision.rho()); } PROCESS_SWITCH(JetHadronRecoil, processJetsMCPMCDMatchedWeightedWithRhoSubtraction, "process MC matched with event weights (inc jets) and rho subtraction", false); @@ -710,21 +732,19 @@ struct JetHadronRecoil { } } if (ishJetEvent) { - for (const auto& mcdjet : mcdjets) { - fillMatchedHistograms(mcdjet, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles); - } + fillMatchedHistograms(mcdjets, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles); } } PROCESS_SWITCH(JetHadronRecoil, processRecoilJetsMCPMCDMatched, "process MC matched (recoil jets)", false); void processRecoilJetsMCPMCDMatchedWeighted(soa::Filtered::iterator const& collision, - soa::Filtered> const& mcdjets, + soa::Filtered> const& mcdjets, soa::Filtered> const& mcdjetsWTA, soa::Filtered> const& mcpjetsWTA, soa::Filtered const& tracks, soa::Filtered const& particles, aod::JetMcCollisions const&, - soa::Filtered> const& mcpjets) + soa::Filtered> const& mcpjets) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { return; @@ -742,9 +762,7 @@ struct JetHadronRecoil { } } if (ishJetEvent) { - for (const auto& mcdjet : mcdjets) { - fillMatchedHistograms(mcdjet, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles, mcdjet.eventWeight()); - } + fillMatchedHistograms(mcdjets, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles, collision.mcCollision().weight()); } } PROCESS_SWITCH(JetHadronRecoil, processRecoilJetsMCPMCDMatchedWeighted, "process MC matched with event weights (recoil jets)", false); diff --git a/PWGJE/Tasks/trackEfficiency.cxx b/PWGJE/Tasks/trackEfficiency.cxx index b9fde50abde..a591c32f958 100644 --- a/PWGJE/Tasks/trackEfficiency.cxx +++ b/PWGJE/Tasks/trackEfficiency.cxx @@ -9,9 +9,9 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -// track efficiency task (global tracks) -// +/// \file trackEfficiency.cxx /// \author Aimeric Landou +/// \brief task that creates the histograms necessary for computation of efficiency and purity functions in offline postprocess macros; also can make mcparticle and track QC histograms #include #include @@ -43,7 +43,7 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -struct TrackEfficiencyJets { +struct TrackEfficiency { Service pdg; using JetParticlesWithOriginal = soa::Join; @@ -76,18 +76,31 @@ struct TrackEfficiencyJets { Configurable> centralityBinning{"centralityBinning", {0., 10., 50., 70.}, "binning of centrality histograms"}; Configurable intRateNBins{"intRateNBins", 50, "number of bins for interaction rate axis"}; Configurable intRateMax{"intRateMax", 50000.0, "maximum value of interaction rate axis"}; + Configurable phiEffNBins{"phiEffNBins", 200, "number of bins for phi axis in efficiency plots"}; + Configurable etaEffNBins{"etaEffNBins", 200, "number of bins for eta axis in efficiency plots"}; + + Configurable ptHatMin{"ptHatMin", 5, "min pT hat of collisions"}; + Configurable ptHatMax{"ptHatMax", 300, "max pT hat of collisions"}; + Configurable pTHatExponent{"pTHatExponent", 6.0, "exponent of the event weight for the calculation of pTHat"}; std::vector eventSelectionBits; int trackSelection = -1; + enum AcceptSplitCollisionsOptions { + NonSplitOnly = 0, + SplitOkCheckAnyAssocColl, // 1 + SplitOkCheckFirstAssocCollOnly // 2 + }; + bool isChargedParticle(int code) { + const float chargeUnit = 3.; auto p = pdg->GetParticle(code); auto charge = 0.; if (p != nullptr) { charge = p->Charge(); } - return std::abs(charge) >= 3.; + return std::abs(charge) >= chargeUnit; } template @@ -123,10 +136,14 @@ struct TrackEfficiencyJets { void init(o2::framework::InitContext&) { + if (!(acceptSplitCollisions == NonSplitOnly || acceptSplitCollisions == SplitOkCheckAnyAssocColl || acceptSplitCollisions == SplitOkCheckFirstAssocCollOnly)) { + LOGF(fatal, "Configurable acceptSplitCollisions has wrong input value; stopping workflow"); + } + eventSelectionBits = jetderiveddatautilities::initialiseEventSelectionBits(static_cast(eventSelections)); trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); - if (doprocessEFficiencyPurity) { + if (doprocessEFficiencyPurity || doprocessEFficiencyPurityWeighted) { registry.add("hMcCollCutsCounts", "McColl cuts count checks", {HistType::kTH1F, {{10, 0., 10.}}}); registry.get(HIST("hMcCollCutsCounts"))->GetXaxis()->SetBinLabel(1, "allMcColl"); @@ -135,6 +152,7 @@ struct TrackEfficiencyJets { registry.get(HIST("hMcCollCutsCounts"))->GetXaxis()->SetBinLabel(4, "splitColl"); registry.get(HIST("hMcCollCutsCounts"))->GetXaxis()->SetBinLabel(5, "recoCollEvtSel"); registry.get(HIST("hMcCollCutsCounts"))->GetXaxis()->SetBinLabel(6, "centralityCut"); + registry.get(HIST("hMcCollCutsCounts"))->GetXaxis()->SetBinLabel(7, "ptHatCut"); registry.add("hMcPartCutsCounts", "McPart cuts count checks", {HistType::kTH1F, {{10, 0., 10.}}}); registry.get(HIST("hMcPartCutsCounts"))->GetXaxis()->SetBinLabel(1, "allPartsInSelMcColl"); @@ -149,46 +167,46 @@ struct TrackEfficiencyJets { registry.get(HIST("hTrackCutsCounts"))->GetXaxis()->SetBinLabel(4, "mcPartIsPrimary"); registry.get(HIST("hTrackCutsCounts"))->GetXaxis()->SetBinLabel(5, "etaAcc"); // not actually applied here but it will give an idea of what will be done in the post processing - AxisSpec ptAxis_eff = {nBinsLowPt, 0., 10., "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec ptAxisHigh_eff = {18, 10., 100., "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec etaAxis_eff = {100, -1.0, 1.0, "#eta"}; - AxisSpec phiAxis_eff = {200, -1.0, 7., "#phi"}; + AxisSpec ptAxisEff = {nBinsLowPt, 0., 10., "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec ptAxisHighEff = {18, 10., 100., "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec etaAxisEff = {etaEffNBins, -1.0, 1.0, "#eta"}; + AxisSpec phiAxisEff = {phiEffNBins, -1.0, 7., "#phi"}; // ptAxisLow - registry.add("h3_particle_pt_particle_eta_particle_phi_mcpartofinterest", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxis_eff, etaAxis_eff, phiAxis_eff}}); - registry.add("h3_particle_pt_particle_eta_particle_phi_mcpart_nonprimary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxis_eff, etaAxis_eff, phiAxis_eff}}); + registry.add("h3_particle_pt_particle_eta_particle_phi_mcpartofinterest", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxisEff, etaAxisEff, phiAxisEff}}); + registry.add("h3_particle_pt_particle_eta_particle_phi_mcpart_nonprimary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxisEff, etaAxisEff, phiAxisEff}}); - registry.add("h3_track_pt_track_eta_track_phi_nonassociatedtrack", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxis_eff, etaAxis_eff, phiAxis_eff}}); - registry.add("h3_track_pt_track_eta_track_phi_associatedtrack_primary", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxis_eff, etaAxis_eff, phiAxis_eff}}); - registry.add("h3_track_pt_track_eta_track_phi_associatedtrack_nonprimary", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxis_eff, etaAxis_eff, phiAxis_eff}}); - registry.add("h3_track_pt_track_eta_track_phi_associatedtrack_split_primary", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxis_eff, etaAxis_eff, phiAxis_eff}}); - registry.add("h3_track_pt_track_eta_track_phi_associatedtrack_split_nonprimary", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxis_eff, etaAxis_eff, phiAxis_eff}}); + registry.add("h3_track_pt_track_eta_track_phi_nonassociatedtrack", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxisEff, etaAxisEff, phiAxisEff}}); + registry.add("h3_track_pt_track_eta_track_phi_associatedtrack_primary", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxisEff, etaAxisEff, phiAxisEff}}); + registry.add("h3_track_pt_track_eta_track_phi_associatedtrack_nonprimary", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxisEff, etaAxisEff, phiAxisEff}}); + registry.add("h3_track_pt_track_eta_track_phi_associatedtrack_split_primary", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxisEff, etaAxisEff, phiAxisEff}}); + registry.add("h3_track_pt_track_eta_track_phi_associatedtrack_split_nonprimary", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxisEff, etaAxisEff, phiAxisEff}}); - registry.add("h3_particle_pt_particle_eta_particle_phi_associatedtrack_primary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxis_eff, etaAxis_eff, phiAxis_eff}}); - registry.add("h3_particle_pt_particle_eta_particle_phi_associatedtrack_nonprimary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxis_eff, etaAxis_eff, phiAxis_eff}}); - registry.add("h3_particle_pt_particle_eta_particle_phi_associatedtrack_split_primary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxis_eff, etaAxis_eff, phiAxis_eff}}); - registry.add("h3_particle_pt_particle_eta_particle_phi_associatedtrack_split_nonprimary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxis_eff, etaAxis_eff, phiAxis_eff}}); + registry.add("h3_particle_pt_particle_eta_particle_phi_associatedtrack_primary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxisEff, etaAxisEff, phiAxisEff}}); + registry.add("h3_particle_pt_particle_eta_particle_phi_associatedtrack_nonprimary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxisEff, etaAxisEff, phiAxisEff}}); + registry.add("h3_particle_pt_particle_eta_particle_phi_associatedtrack_split_primary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxisEff, etaAxisEff, phiAxisEff}}); + registry.add("h3_particle_pt_particle_eta_particle_phi_associatedtrack_split_nonprimary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxisEff, etaAxisEff, phiAxisEff}}); - registry.add("h2_particle_pt_track_pt_residual_associatedtrack_primary", "(#it{p}_{T, mcpart} - #it{p}_{T, track}) / #it{p}_{T, mcpart}; #it{p}_{T, mcpart} (GeV/#it{c})", {HistType::kTH2F, {ptAxis_eff, {200, -1., 1.}}}); + registry.add("h2_particle_pt_track_pt_residual_associatedtrack_primary", "(#it{p}_{T, mcpart} - #it{p}_{T, track}) / #it{p}_{T, mcpart}; #it{p}_{T, mcpart} (GeV/#it{c})", {HistType::kTH2F, {ptAxisEff, {200, -1., 1.}}}); // ptAxisHigh - registry.add("h3_particle_pt_high_particle_eta_particle_phi_mcpartofinterest", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxisHigh_eff, etaAxis_eff, phiAxis_eff}}); + registry.add("h3_particle_pt_high_particle_eta_particle_phi_mcpartofinterest", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxisHighEff, etaAxisEff, phiAxisEff}}); - registry.add("h3_track_pt_high_track_eta_track_phi_nonassociatedtrack", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxisHigh_eff, etaAxis_eff, phiAxis_eff}}); - registry.add("h3_track_pt_high_track_eta_track_phi_associatedtrack_primary", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxisHigh_eff, etaAxis_eff, phiAxis_eff}}); - registry.add("h3_track_pt_high_track_eta_track_phi_associatedtrack_nonprimary", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxisHigh_eff, etaAxis_eff, phiAxis_eff}}); - registry.add("h3_track_pt_high_track_eta_track_phi_associatedtrack_split_primary", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxisHigh_eff, etaAxis_eff, phiAxis_eff}}); - registry.add("h3_track_pt_high_track_eta_track_phi_associatedtrack_split_nonprimary", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxisHigh_eff, etaAxis_eff, phiAxis_eff}}); + registry.add("h3_track_pt_high_track_eta_track_phi_nonassociatedtrack", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxisHighEff, etaAxisEff, phiAxisEff}}); + registry.add("h3_track_pt_high_track_eta_track_phi_associatedtrack_primary", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxisHighEff, etaAxisEff, phiAxisEff}}); + registry.add("h3_track_pt_high_track_eta_track_phi_associatedtrack_nonprimary", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxisHighEff, etaAxisEff, phiAxisEff}}); + registry.add("h3_track_pt_high_track_eta_track_phi_associatedtrack_split_primary", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxisHighEff, etaAxisEff, phiAxisEff}}); + registry.add("h3_track_pt_high_track_eta_track_phi_associatedtrack_split_nonprimary", "#it{p}_{T, track} (GeV/#it{c}); #eta_{track}; #phi_{track}", {HistType::kTH3F, {ptAxisHighEff, etaAxisEff, phiAxisEff}}); - registry.add("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_primary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxisHigh_eff, etaAxis_eff, phiAxis_eff}}); - registry.add("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_nonprimary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxisHigh_eff, etaAxis_eff, phiAxis_eff}}); - registry.add("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_split_primary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxisHigh_eff, etaAxis_eff, phiAxis_eff}}); - registry.add("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_split_nonprimary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxisHigh_eff, etaAxis_eff, phiAxis_eff}}); + registry.add("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_primary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxisHighEff, etaAxisEff, phiAxisEff}}); + registry.add("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_nonprimary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxisHighEff, etaAxisEff, phiAxisEff}}); + registry.add("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_split_primary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxisHighEff, etaAxisEff, phiAxisEff}}); + registry.add("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_split_nonprimary", "#it{p}_{T, mcpart} (GeV/#it{c}); #eta_{mcpart}; #phi_{mcpart}", {HistType::kTH3F, {ptAxisHighEff, etaAxisEff, phiAxisEff}}); - registry.add("h2_particle_pt_high_track_pt_high_residual_associatedtrack_primary", "(#it{p}_{T, mcpart} - #it{p}_{T, track}) / #it{p}_{T, mcpart}; #it{p}_{T, mcpart} (GeV/#it{c})", {HistType::kTH2F, {ptAxisHigh_eff, {200, -1., 1.}}}); + registry.add("h2_particle_pt_high_track_pt_high_residual_associatedtrack_primary", "(#it{p}_{T, mcpart} - #it{p}_{T, track}) / #it{p}_{T, mcpart}; #it{p}_{T, mcpart} (GeV/#it{c})", {HistType::kTH2F, {ptAxisHighEff, {200, -1., 1.}}}); } - if (doprocessTracks || doprocessTracksWeighted) { + if (doprocessTracks || doprocessTracksMc || doprocessTracksMcWeighted) { AxisSpec centAxis = {centralityBinning, "centrality (%)"}; AxisSpec intRateAxis = {intRateNBins, 0., intRateMax, "int. rate (kHz)"}; registry.add("h2_centrality_track_pt", "centrality vs track pT; centrality; #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {centAxis, {200, 0., 200.}}}); @@ -200,6 +218,9 @@ struct TrackEfficiencyJets { registry.add("h2_track_pt_track_sigma1overpt", "#sigma(1/#it{p}_{T}); #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {{100, 0., 10.}, {1000, 0.0, 10.0}}}); registry.add("h2_track_pt_high_track_sigma1overpt", "#sigma(1/#it{p}_{T}); #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {{90, 10., 100.}, {1000, 0.0, 10.0}}}); registry.add("h3_intrate_centrality_track_pt", "interaction rate vs centrality vs track pT; int. rate; centrality; #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH3F, {intRateAxis, centAxis, {200, 0., 200.}}}); + + registry.add("h_collisions", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); + registry.add("h2_centrality_collisions", "centrality vs collisions; centrality; collisions", {HistType::kTH2F, {centAxis, {4, 0.0, 4.0}}}); } if (doprocessParticles || doprocessParticlesWeighted) { @@ -210,20 +231,16 @@ struct TrackEfficiencyJets { registry.add("h2_centrality_particle_phi", "centrality vs particle #varphi; centrality; #varphi_{part}", {HistType::kTH2F, {centAxis, {160, -1.0, 7.}}}); registry.add("h2_centrality_particle_energy", "centrality vs particle energy; centrality; Energy GeV", {HistType::kTH2F, {centAxis, {100, 0.0, 100.0}}}); registry.add("h3_intrate_centrality_particle_pt", "interaction rate vs centrality vs particle pT; int. rate; centrality; #it{p}_{T,part} (GeV/#it{c})", {HistType::kTH3F, {intRateAxis, centAxis, {200, 0., 200.}}}); + + registry.add("h_mccollisions", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); + registry.add("h2_centrality_mccollisions", "centrality vs mccollisions; centrality; collisions", {HistType::kTH2F, {centAxis, {4, 0.0, 4.0}}}); } - if (doprocessTracks || doprocessTracksWeighted) { + if (doprocessTracksMc || doprocessTracksMcWeighted) { AxisSpec centAxis = {centralityBinning, "centrality (%)"}; - registry.add("h_collisions", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); registry.add("h_fakecollisions", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); - registry.add("h2_centrality_collisions", "centrality vs collisions; centrality; collisions", {HistType::kTH2F, {centAxis, {4, 0.0, 4.0}}}); - } - if (doprocessParticles || doprocessParticlesWeighted) { - AxisSpec centAxis = {centralityBinning, "centrality (%)"}; - registry.add("h_mccollisions", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); - registry.add("h2_centrality_mccollisions", "centrality vs mccollisions; centrality; collisions", {HistType::kTH2F, {centAxis, {4, 0.0, 4.0}}}); } - if (doprocessTracksWeighted) { + if (doprocessTracksMcWeighted) { registry.add("h_collisions_weighted", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); } if (doprocessParticlesWeighted) { @@ -251,7 +268,7 @@ struct TrackEfficiencyJets { registry.fill(HIST("hMcCollCutsCounts"), 0.5); // all mcCollisions - if (!(abs(mcCollision.posZ()) < vertexZCut)) { + if (!(std::abs(mcCollision.posZ()) < vertexZCut)) { return; } registry.fill(HIST("hMcCollCutsCounts"), 1.5); // mcCollision.posZ() condition @@ -261,22 +278,22 @@ struct TrackEfficiencyJets { } registry.fill(HIST("hMcCollCutsCounts"), 2.5); // mcCollisions with at least one reconstructed collision - if (acceptSplitCollisions == 0 && collisions.size() > 1) { + if (acceptSplitCollisions == NonSplitOnly && collisions.size() > 1) { return; } registry.fill(HIST("hMcCollCutsCounts"), 3.5); // split mcCollisions condition bool hasSel8Coll = false; bool centralityCheck = false; - if (acceptSplitCollisions == 2) { // check only that the first reconstructed collision passes the check + if (acceptSplitCollisions == SplitOkCheckFirstAssocCollOnly || acceptSplitCollisions == NonSplitOnly) { // check only that the first reconstructed collision passes the check (for the NonSplitOnly case, there's only one associated collision) if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split hasSel8Coll = true; } if (!checkCentrality || ((centralityMin < collisions.begin().centrality()) && (collisions.begin().centrality() < centralityMax))) { // effect unclear if mcColl is split centralityCheck = true; } - } else { // check that at least one of the reconstructed collisions passes the checks - for (auto& collision : collisions) { + } else if (acceptSplitCollisions == SplitOkCheckAnyAssocColl) { // check that at least one of the reconstructed collisions passes the checks + for (auto const& collision : collisions) { if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split hasSel8Coll = true; } @@ -295,7 +312,13 @@ struct TrackEfficiencyJets { } registry.fill(HIST("hMcCollCutsCounts"), 5.5); // at least one of the reconstructed collisions associated with this mcCollision is selected with regard to centrality - for (auto& jMcParticle : jMcParticles) { + float pTHat = 10. / (std::pow(mcCollision.weight(), 1.0 / pTHatExponent)); + if (pTHat < ptHatMin || pTHat > ptHatMax) { // only allows mcCollisions with weight in between min and max + return; + } + registry.fill(HIST("hMcCollCutsCounts"), 6.5); // ptHat condition + + for (auto const& jMcParticle : jMcParticles) { registry.fill(HIST("hMcPartCutsCounts"), 0.5); // allPartsInSelMcColl if (!isChargedParticle(jMcParticle.pdgCode())) { @@ -314,7 +337,7 @@ struct TrackEfficiencyJets { registry.fill(HIST("h3_particle_pt_high_particle_eta_particle_phi_mcpartofinterest"), jMcParticle.pt(), jMcParticle.eta(), jMcParticle.phi()); - if ((abs(jMcParticle.eta()) < trackEtaAcceptanceCountQA)) { // removed from actual cuts for now because all the histograms have an eta axis + if ((std::abs(jMcParticle.eta()) < trackEtaAcceptanceCountQA)) { // removed from actual cuts for now because all the histograms have an eta axis registry.fill(HIST("hMcPartCutsCounts"), 3.5); // etaAccept // not actually applied here but it will give an idea of what will be done in the post processing } } @@ -322,18 +345,18 @@ struct TrackEfficiencyJets { std::vector seenMcParticlesVector; // is reset every mc collision int splitCollCounter = 0; - for (auto& collision : collisions) { + for (auto const& collision : collisions) { splitCollCounter++; - if (acceptSplitCollisions == 2 && splitCollCounter > 1) { + if (acceptSplitCollisions == SplitOkCheckFirstAssocCollOnly && splitCollCounter > 1) { return; } - if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents) || !(abs(collision.posZ()) < vertexZCut)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents) || !(std::abs(collision.posZ()) < vertexZCut)) { continue; } auto collTracks = jetTracks.sliceBy(tracksPerJCollision, collision.globalIndex()); - for (auto& track : collTracks) { + for (auto const& track : collTracks) { registry.fill(HIST("hTrackCutsCounts"), 0.5); if (!(jetderiveddatautilities::selectTrack(track, trackSelection) && jetderiveddatautilities::selectTrackDcaZ(track, trackDcaZmax))) { // if track selection is uniformTrack, dcaZ cuts need to be added as they aren't in the selection so that they can be studied here @@ -390,13 +413,180 @@ struct TrackEfficiencyJets { seenMcParticlesVector.push_back(jMcParticleFromTrack.globalIndex()); } - if (abs(jMcParticleFromTrack.eta()) < trackEtaAcceptanceCountQA) { // not actually applied here but it will give an idea of what will be done in the post processing + if (std::abs(jMcParticleFromTrack.eta()) < trackEtaAcceptanceCountQA) { // not actually applied here but it will give an idea of what will be done in the post processing registry.fill(HIST("hTrackCutsCounts"), 4.5); } } } } - PROCESS_SWITCH(TrackEfficiencyJets, processEFficiencyPurity, "Histograms for efficiency and purity quantities", true); + PROCESS_SWITCH(TrackEfficiency, processEFficiencyPurity, "Histograms for efficiency and purity quantities", true); + + void processEFficiencyPurityWeighted(aod::JetMcCollision const& mcCollision, + soa::SmallGroups const& collisions, // smallgroups gives only the collisions associated to the current mccollision, thanks to the mccollisionlabel pre-integrated in jetcollisionsmcd + soa::Join const& jetTracks, + JetParticlesWithOriginal const& jMcParticles) + { + // missing: + // * constexpr auto hasCentrality = CollisionMCRecTableCentFT0C::template contains(); + // if constexpr (hasCentrality) { + // * dividing in centrality bins + // I should maybe introduce the sel8 cuts on the collisoins (reco, but what about mccoll? maybe not htat way included in efficiency) + + registry.fill(HIST("hMcCollCutsCounts"), 0.5); // all mcCollisions + + if (!(std::abs(mcCollision.posZ()) < vertexZCut)) { + return; + } + registry.fill(HIST("hMcCollCutsCounts"), 1.5); // mcCollision.posZ() condition + + if (collisions.size() < 1) { + return; + } + registry.fill(HIST("hMcCollCutsCounts"), 2.5); // mcCollisions with at least one reconstructed collision + + if (acceptSplitCollisions == NonSplitOnly && collisions.size() > 1) { + return; + } + registry.fill(HIST("hMcCollCutsCounts"), 3.5); // split mcCollisions condition + + bool hasSel8Coll = false; + bool centralityCheck = false; + if (acceptSplitCollisions == SplitOkCheckFirstAssocCollOnly || acceptSplitCollisions == NonSplitOnly) { // check only that the first reconstructed collision passes the check (for the NonSplitOnly case, there's only one associated collision) + if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split + hasSel8Coll = true; + } + if (!checkCentrality || ((centralityMin < collisions.begin().centrality()) && (collisions.begin().centrality() < centralityMax))) { // effect unclear if mcColl is split + centralityCheck = true; + } + } else if (acceptSplitCollisions == SplitOkCheckAnyAssocColl) { // check that at least one of the reconstructed collisions passes the checks + for (auto const& collision : collisions) { + if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split + hasSel8Coll = true; + } + if (!checkCentrality || ((centralityMin < collision.centrality()) && (collision.centrality() < centralityMax))) { // effect unclear if mcColl is split + centralityCheck = true; + } + } + } + if (!hasSel8Coll) { + return; + } + registry.fill(HIST("hMcCollCutsCounts"), 4.5); // at least one of the reconstructed collisions associated with this mcCollision is selected + + if (!centralityCheck) { + return; + } + registry.fill(HIST("hMcCollCutsCounts"), 5.5); // at least one of the reconstructed collisions associated with this mcCollision is selected with regard to centrality + + float eventWeight = mcCollision.weight(); + float pTHat = 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)); + if (pTHat < ptHatMin || pTHat > ptHatMax) { // only allows mcCollisions with weight in between min and max + return; + } + registry.fill(HIST("hMcCollCutsCounts"), 6.5); // ptHat condition + + for (auto const& jMcParticle : jMcParticles) { + registry.fill(HIST("hMcPartCutsCounts"), 0.5); // allPartsInSelMcColl + + if (!isChargedParticle(jMcParticle.pdgCode())) { + continue; + } + registry.fill(HIST("hMcPartCutsCounts"), 1.5); // isCharged + + registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_mcpart_nonprimary"), jMcParticle.pt(), jMcParticle.eta(), jMcParticle.phi(), eventWeight); + + if (checkPrimaryPart && !jMcParticle.isPhysicalPrimary()) { // global tracks should be mostly primaries + continue; + } + registry.fill(HIST("hMcPartCutsCounts"), 2.5); // isPrimary + + registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_mcpartofinterest"), jMcParticle.pt(), jMcParticle.eta(), jMcParticle.phi(), eventWeight); + + registry.fill(HIST("h3_particle_pt_high_particle_eta_particle_phi_mcpartofinterest"), jMcParticle.pt(), jMcParticle.eta(), jMcParticle.phi(), eventWeight); + + if ((std::abs(jMcParticle.eta()) < trackEtaAcceptanceCountQA)) { // removed from actual cuts for now because all the histograms have an eta axis + registry.fill(HIST("hMcPartCutsCounts"), 3.5); // etaAccept // not actually applied here but it will give an idea of what will be done in the post processing + } + } + + std::vector seenMcParticlesVector; // is reset every mc collision + + int splitCollCounter = 0; + for (auto const& collision : collisions) { + splitCollCounter++; + if (acceptSplitCollisions == SplitOkCheckFirstAssocCollOnly && splitCollCounter > 1) { + return; + } + + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents) || !(std::abs(collision.posZ()) < vertexZCut)) { + continue; + } + + auto collTracks = jetTracks.sliceBy(tracksPerJCollision, collision.globalIndex()); + for (auto const& track : collTracks) { + registry.fill(HIST("hTrackCutsCounts"), 0.5); + + if (!(jetderiveddatautilities::selectTrack(track, trackSelection) && jetderiveddatautilities::selectTrackDcaZ(track, trackDcaZmax))) { // if track selection is uniformTrack, dcaZ cuts need to be added as they aren't in the selection so that they can be studied here + continue; + } + registry.fill(HIST("hTrackCutsCounts"), 1.5); + + if (!track.has_mcParticle()) { + registry.fill(HIST("h3_track_pt_track_eta_track_phi_nonassociatedtrack"), track.pt(), track.eta(), track.phi(), eventWeight); + + registry.fill(HIST("h3_track_pt_high_track_eta_track_phi_nonassociatedtrack"), track.pt(), track.eta(), track.phi(), eventWeight); + continue; + } + registry.fill(HIST("hTrackCutsCounts"), 2.5); + + auto jMcParticleFromTrack = track.mcParticle_as(); + if (!jMcParticleFromTrack.isPhysicalPrimary()) { + registry.fill(HIST("h3_track_pt_track_eta_track_phi_associatedtrack_nonprimary"), track.pt(), track.eta(), track.phi(), eventWeight); + registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_associatedtrack_nonprimary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), eventWeight); + + registry.fill(HIST("h3_track_pt_high_track_eta_track_phi_associatedtrack_nonprimary"), track.pt(), track.eta(), track.phi(), eventWeight); + registry.fill(HIST("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_nonprimary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), eventWeight); + + if (std::find(seenMcParticlesVector.begin(), seenMcParticlesVector.end(), jMcParticleFromTrack.globalIndex()) != seenMcParticlesVector.end()) { + registry.fill(HIST("h3_track_pt_track_eta_track_phi_associatedtrack_split_nonprimary"), track.pt(), track.eta(), track.phi(), eventWeight); + registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_associatedtrack_split_nonprimary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), eventWeight); + + registry.fill(HIST("h3_track_pt_high_track_eta_track_phi_associatedtrack_split_nonprimary"), track.pt(), track.eta(), track.phi(), eventWeight); + registry.fill(HIST("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_split_nonprimary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), eventWeight); + } else { + seenMcParticlesVector.push_back(jMcParticleFromTrack.globalIndex()); + } + + continue; + } + + registry.fill(HIST("hTrackCutsCounts"), 3.5); + + registry.fill(HIST("h3_track_pt_track_eta_track_phi_associatedtrack_primary"), track.pt(), track.eta(), track.phi(), eventWeight); + registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_associatedtrack_primary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), eventWeight); + registry.fill(HIST("h2_particle_pt_track_pt_residual_associatedtrack_primary"), jMcParticleFromTrack.pt(), (jMcParticleFromTrack.pt() - track.pt()) / jMcParticleFromTrack.pt(), eventWeight); + + registry.fill(HIST("h3_track_pt_high_track_eta_track_phi_associatedtrack_primary"), track.pt(), track.eta(), track.phi(), eventWeight); + registry.fill(HIST("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_primary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), eventWeight); + registry.fill(HIST("h2_particle_pt_high_track_pt_high_residual_associatedtrack_primary"), jMcParticleFromTrack.pt(), (jMcParticleFromTrack.pt() - track.pt()) / jMcParticleFromTrack.pt(), eventWeight); + + if (std::find(seenMcParticlesVector.begin(), seenMcParticlesVector.end(), jMcParticleFromTrack.globalIndex()) != seenMcParticlesVector.end()) { + registry.fill(HIST("h3_track_pt_track_eta_track_phi_associatedtrack_split_primary"), track.pt(), track.eta(), track.phi(), eventWeight); + registry.fill(HIST("h3_particle_pt_particle_eta_particle_phi_associatedtrack_split_primary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), eventWeight); + + registry.fill(HIST("h3_track_pt_high_track_eta_track_phi_associatedtrack_split_primary"), track.pt(), track.eta(), track.phi(), eventWeight); + registry.fill(HIST("h3_particle_pt_high_particle_eta_particle_phi_associatedtrack_split_primary"), jMcParticleFromTrack.pt(), jMcParticleFromTrack.eta(), jMcParticleFromTrack.phi(), eventWeight); + } else { + seenMcParticlesVector.push_back(jMcParticleFromTrack.globalIndex()); + } + + if (std::abs(jMcParticleFromTrack.eta()) < trackEtaAcceptanceCountQA) { // not actually applied here but it will give an idea of what will be done in the post processing + registry.fill(HIST("hTrackCutsCounts"), 4.5); + } + } + } + } + PROCESS_SWITCH(TrackEfficiency, processEFficiencyPurityWeighted, "Histograms for efficiency and purity quantities for weighted simulations", false); void processTracks(soa::Filtered::iterator const& collision, soa::Filtered> const& tracks) @@ -413,13 +603,46 @@ struct TrackEfficiencyJets { } registry.fill(HIST("h_collisions"), 2.5); registry.fill(HIST("h2_centrality_collisions"), collision.centrality(), 2.5); + + fillTrackHistograms(collision, tracks); + } + PROCESS_SWITCH(TrackEfficiency, processTracks, "QA for charged tracks in data", false); + + void processTracksMc(soa::Join::iterator const& collision, + aod::JetMcCollisions const&, + soa::Filtered> const& tracks) + { + if (!collision.has_mcCollision()) { // the collision is fake and has no associated mc coll; skip as .mccollision() cannot be called + registry.fill(HIST("h_fakecollisions"), 0.5); + return; + } + registry.fill(HIST("h_collisions"), 0.5); + registry.fill(HIST("h2_centrality_collisions"), collision.centrality(), 0.5); + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { + return; + } + registry.fill(HIST("h_collisions"), 1.5); + registry.fill(HIST("h2_centrality_collisions"), collision.centrality(), 1.5); + if (collision.trackOccupancyInTimeRange() < trackOccupancyInTimeRangeMin || trackOccupancyInTimeRangeMax < collision.trackOccupancyInTimeRange()) { + return; + } + registry.fill(HIST("h_collisions"), 2.5); + registry.fill(HIST("h2_centrality_collisions"), collision.centrality(), 2.5); + + float pTHat = 10. / (std::pow(collision.mcCollision().weight(), 1.0 / pTHatExponent)); + if (pTHat < ptHatMin || pTHat > ptHatMax) { // only allows mcCollisions with weight in between min and max + return; + } + registry.fill(HIST("h_collisions"), 3.5); + registry.fill(HIST("h2_centrality_collisions"), collision.centrality(), 3.5); + fillTrackHistograms(collision, tracks); } - PROCESS_SWITCH(TrackEfficiencyJets, processTracks, "QA for charged tracks", false); + PROCESS_SWITCH(TrackEfficiency, processTracksMc, "QA for charged tracks in MC without weights", false); - void processTracksWeighted(soa::Join::iterator const& collision, - aod::JetMcCollisions const&, - soa::Filtered> const& tracks) + void processTracksMcWeighted(soa::Join::iterator const& collision, + aod::JetMcCollisions const&, + soa::Filtered> const& tracks) { if (!collision.has_mcCollision()) { // the collision is fake and has no associated mc coll; skip as .mccollision() cannot be called registry.fill(HIST("h_fakecollisions"), 0.5); @@ -438,9 +661,17 @@ struct TrackEfficiencyJets { } registry.fill(HIST("h_collisions"), 2.5); registry.fill(HIST("h_collisions_weighted"), 2.5, eventWeight); + + float pTHat = 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)); + if (pTHat < ptHatMin || pTHat > ptHatMax) { // only allows mcCollisions with weight in between min and max + return; + } + registry.fill(HIST("h_collisions"), 3.5); + registry.fill(HIST("h2_centrality_collisions"), collision.centrality(), 3.5); + fillTrackHistograms(collision, tracks, eventWeight); } - PROCESS_SWITCH(TrackEfficiencyJets, processTracksWeighted, "QA for charged tracks weighted", false); + PROCESS_SWITCH(TrackEfficiency, processTracksMcWeighted, "QA for charged tracks in weighted MC", false); void processParticles(aod::JetMcCollision const& mcCollision, soa::SmallGroups const& collisions, @@ -449,27 +680,34 @@ struct TrackEfficiencyJets { registry.fill(HIST("h_mccollisions"), 0.5); registry.fill(HIST("h2_centrality_mccollisions"), collisions.begin().centrality(), 0.5); - if (!(abs(mcCollision.posZ()) < vertexZCut)) { + if (!(std::abs(mcCollision.posZ()) < vertexZCut)) { return; } if (collisions.size() < 1) { return; } - if (acceptSplitCollisions == 0 && collisions.size() > 1) { + if (acceptSplitCollisions == NonSplitOnly && collisions.size() > 1) { return; } + float pTHat = 10. / (std::pow(mcCollision.weight(), 1.0 / pTHatExponent)); + if (pTHat < ptHatMin || pTHat > ptHatMax) { // only allows mcCollisions with weight in between min and max + return; + } + registry.fill(HIST("h_mccollisions"), 1.5); + registry.fill(HIST("h2_centrality_mccollisions"), collisions.begin().centrality(), 1.5); + bool hasSel8Coll = false; bool centralityCheck = false; - if (acceptSplitCollisions == 2) { // check only that the first reconstructed collision passes the check + if (acceptSplitCollisions == SplitOkCheckFirstAssocCollOnly || acceptSplitCollisions == NonSplitOnly) { // check only that the first reconstructed collision passes the check (for the NonSplitOnly case, there's only one associated collision) if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split hasSel8Coll = true; } if (!checkCentrality || ((centralityMin < collisions.begin().centrality()) && (collisions.begin().centrality() < centralityMax))) { // effect unclear if mcColl is split centralityCheck = true; } - } else { // check that at least one of the reconstructed collisions passes the checks - for (auto& collision : collisions) { + } else if (acceptSplitCollisions == SplitOkCheckAnyAssocColl) { // check that at least one of the reconstructed collisions passes the checks + for (auto const& collision : collisions) { if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split hasSel8Coll = true; } @@ -484,12 +722,12 @@ struct TrackEfficiencyJets { if (!centralityCheck) { return; } + registry.fill(HIST("h_mccollisions"), 2.5); + registry.fill(HIST("h2_centrality_mccollisions"), collisions.begin().centrality(), 2.5); - registry.fill(HIST("h_mccollisions"), 1.5); - registry.fill(HIST("h2_centrality_mccollisions"), collisions.begin().centrality(), 1.5); fillParticlesHistograms(collisions.begin(), mcparticles); } - PROCESS_SWITCH(TrackEfficiencyJets, processParticles, "QA for charged particles", false); + PROCESS_SWITCH(TrackEfficiency, processParticles, "QA for charged particles", false); void processParticlesWeighted(aod::JetMcCollision const& mcCollision, soa::SmallGroups const& collisions, @@ -503,27 +741,34 @@ struct TrackEfficiencyJets { registry.fill(HIST("h_mccollisions"), 0.5); registry.fill(HIST("h_mccollisions_weighted"), 0.5, eventWeight); - if (!(abs(mcCollision.posZ()) < vertexZCut)) { + if (!(std::abs(mcCollision.posZ()) < vertexZCut)) { return; } if (collisions.size() < 1) { return; } - if (acceptSplitCollisions == 0 && collisions.size() > 1) { + if (acceptSplitCollisions == NonSplitOnly && collisions.size() > 1) { return; } + float pTHat = 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)); + if (pTHat < ptHatMin || pTHat > ptHatMax) { // only allows mcCollisions with weight in between min and max + return; + } + registry.fill(HIST("h_mccollisions"), 1.5); + registry.fill(HIST("h_mccollisions_weighted"), 1.5, eventWeight); + bool hasSel8Coll = false; bool centralityCheck = false; - if (acceptSplitCollisions == 2) { // check only that the first reconstructed collision passes the check + if (acceptSplitCollisions == SplitOkCheckFirstAssocCollOnly || acceptSplitCollisions == NonSplitOnly) { // check only that the first reconstructed collision passes the check (for the NonSplitOnly case, there's only one associated collision) if (jetderiveddatautilities::selectCollision(collisions.begin(), eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split hasSel8Coll = true; } if (!checkCentrality || ((centralityMin < collisions.begin().centrality()) && (collisions.begin().centrality() < centralityMax))) { // effect unclear if mcColl is split centralityCheck = true; } - } else { // check that at least one of the reconstructed collisions passes the checks - for (auto& collision : collisions) { + } else if (acceptSplitCollisions == SplitOkCheckAnyAssocColl) { // check that at least one of the reconstructed collisions passes the checks + for (auto const& collision : collisions) { if (jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents)) { // Skipping MC events that have not a single selected reconstructed collision ; effect unclear if mcColl is split hasSel8Coll = true; } @@ -538,12 +783,15 @@ struct TrackEfficiencyJets { if (!centralityCheck) { return; } + registry.fill(HIST("h_mccollisions"), 2.5); + registry.fill(HIST("h_mccollisions_weighted"), 2.5, eventWeight); - registry.fill(HIST("h_mccollisions"), 1.5); - registry.fill(HIST("h_mccollisions_weighted"), 1.5, eventWeight); fillParticlesHistograms(collisions.begin(), mcparticles, eventWeight); } - PROCESS_SWITCH(TrackEfficiencyJets, processParticlesWeighted, "QA for charged particles weighted", false); + PROCESS_SWITCH(TrackEfficiency, processParticlesWeighted, "QA for charged particles weighted", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"track-efficiency"})}; } +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGJE/Tasks/v0QA.cxx b/PWGJE/Tasks/v0QA.cxx index 6966c3b0101..8d8d0ab2cfc 100644 --- a/PWGJE/Tasks/v0QA.cxx +++ b/PWGJE/Tasks/v0QA.cxx @@ -47,7 +47,7 @@ using MCDV0JetsWithConstituents = soa::Join; using MatchedMCDV0JetsWithConstituents = soa::Join; -using CandidatesV0MCDWithFlags = soa::Join; +using CandidatesV0MCDWithFlags = soa::Join; using MCPV0Jets = aod::V0ChargedMCParticleLevelJets; using MCPV0JetsWithConstituents = soa::Join; @@ -1221,7 +1221,7 @@ struct V0QA { using DaughterJTracks = soa::Join; using DaughterTracks = soa::Join; - void processV0TrackQA(aod::JetCollision const& /*jcoll*/, soa::Join const& v0s, DaughterJTracks const&, DaughterTracks const&) + void processV0TrackQA(aod::JetCollision const& /*jcoll*/, aod::CandidatesV0Data const& v0s, DaughterJTracks const&, DaughterTracks const&) { // if (!jetderiveddatautilities::selectCollision(jcoll, eventSelectionBits)) { // return; diff --git a/PWGLF/DataModel/LFHypernucleiKfTables.h b/PWGLF/DataModel/LFHypernucleiKfTables.h index 98f8076b2f6..0e2424f3bb5 100644 --- a/PWGLF/DataModel/LFHypernucleiKfTables.h +++ b/PWGLF/DataModel/LFHypernucleiKfTables.h @@ -45,6 +45,7 @@ DECLARE_SOA_COLUMN(Svx, svx, float); //! DECLARE_SOA_COLUMN(Svy, svy, float); //! DECLARE_SOA_COLUMN(Svz, svz, float); //! DECLARE_SOA_COLUMN(Occupancy, occupancy, int); //! +DECLARE_SOA_COLUMN(RunNumber, runNumber, int); //! DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, [](float px, float py) { return RecoDecay::pt(std::array{px, py}); }); DECLARE_SOA_DYNAMIC_COLUMN(Y, y, [](float E, float pz) { return 0.5 * std::log((E + pz) / (E - pz)); }); DECLARE_SOA_DYNAMIC_COLUMN(Mass, mass, [](float E, float px, float py, float pz) { return std::sqrt(E * E - px * px - py * py - pz * pz); }); @@ -80,7 +81,8 @@ DECLARE_SOA_TABLE(HypKfColls, "AOD", "HYPKFCOLL", cent::CentFT0A, cent::CentFT0C, cent::CentFT0M, - hykfmc::Occupancy); + hykfmc::Occupancy, + hykfmc::RunNumber); using HypKfColl = HypKfColls::iterator; namespace hykftrk @@ -102,14 +104,14 @@ DECLARE_SOA_DYNAMIC_COLUMN(Y, y, [](float pt, float eta, float mass) { return st DECLARE_SOA_DYNAMIC_COLUMN(Lambda, lambda, [](float eta) { return 1. / std::cosh(eta); }); DECLARE_SOA_DYNAMIC_COLUMN(ItsNcluster, itsNcluster, [](uint32_t itsClusterSizes) { uint8_t n = 0; - for (uint8_t i = 0; i < 7; i++) { + for (uint8_t i = 0; i < 0x08; i++) { if (itsClusterSizes >> (4 * i) & 15) n++; } return n; }); DECLARE_SOA_DYNAMIC_COLUMN(ItsFirstLayer, itsFirstLayer, [](uint32_t itsClusterSizes) { - for (int i = 0; i < 8; i++) { + for (int i = 0; i < 0x08; i++) { if (itsClusterSizes >> (4 * i) & 15) return i; } @@ -117,7 +119,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(ItsFirstLayer, itsFirstLayer, [](uint32_t itsClusterS }); DECLARE_SOA_DYNAMIC_COLUMN(ItsMeanClsSize, itsMeanClsSize, [](uint32_t itsClusterSizes) { int sum = 0, n = 0; - for (int i = 0; i < 8; i++) { + for (int i = 0; i < 0x08; i++) { sum += (itsClusterSizes >> (4 * i) & 15); if (itsClusterSizes >> (4 * i) & 15) n++; @@ -194,9 +196,9 @@ DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, [](float px, float py, float pz) { return R DECLARE_SOA_DYNAMIC_COLUMN(Phi, phi, [](float px, float py) { return RecoDecay::phi(std::array{px, py}); }); DECLARE_SOA_DYNAMIC_COLUMN(P, p, [](float px, float py, float pz) { return RecoDecay::p(px, py, pz); }); // DECLARE_SOA_DYNAMIC_COLUMN(Y, y, [](float px, float py, float pz, float mass) { return RecoDecay::y(std::array{px, py, pz}, mass); }); -DECLARE_SOA_DYNAMIC_COLUMN(McTrue, mcTrue, [](int hypKfMcPartId) { return hypKfMcPartId > 0; }); +DECLARE_SOA_DYNAMIC_COLUMN(McTrue, mcTrue, [](int hypKfMcPartId) { return hypKfMcPartId >= 0; }); DECLARE_SOA_DYNAMIC_COLUMN(IsMatter, isMatter, [](int8_t species) { return species > 0; }); -DECLARE_SOA_DYNAMIC_COLUMN(Cascade, cascade, [](int hypDaughter) { return hypDaughter > 0; }); +DECLARE_SOA_DYNAMIC_COLUMN(Cascade, cascade, [](int hypDaughter) { return hypDaughter >= 0; }); } // namespace hykfhyp DECLARE_SOA_TABLE(HypKfHypNucs, "AOD", "HYPKFHYPNUC", diff --git a/PWGLF/DataModel/LFNonPromptCascadeTables.h b/PWGLF/DataModel/LFNonPromptCascadeTables.h index 687d698a529..177167d5997 100644 --- a/PWGLF/DataModel/LFNonPromptCascadeTables.h +++ b/PWGLF/DataModel/LFNonPromptCascadeTables.h @@ -115,6 +115,10 @@ DECLARE_SOA_COLUMN(MotherDecayDaughters, motherDecayDaughters, int8_t); DECLARE_SOA_COLUMN(Sel8, sel8, bool); DECLARE_SOA_COLUMN(MultFT0C, multFT0C, float); DECLARE_SOA_COLUMN(MultFT0A, multFT0A, float); +DECLARE_SOA_COLUMN(MultFT0M, multFT0M, float); +DECLARE_SOA_COLUMN(CentFT0C, centFT0C, float); +DECLARE_SOA_COLUMN(CentFT0A, centFT0A, float); +DECLARE_SOA_COLUMN(CentFT0M, centFT0M, float); } // namespace NPCascadeTable DECLARE_SOA_TABLE(NPCascTable, "AOD", "NPCASCTABLE", @@ -175,7 +179,11 @@ DECLARE_SOA_TABLE(NPCascTable, "AOD", "NPCASCTABLE", NPCascadeTable::BachPionTOFNSigma, NPCascadeTable::Sel8, NPCascadeTable::MultFT0C, - NPCascadeTable::MultFT0A) + NPCascadeTable::MultFT0A, + NPCascadeTable::MultFT0M, + NPCascadeTable::CentFT0C, + NPCascadeTable::CentFT0A, + NPCascadeTable::CentFT0M) DECLARE_SOA_TABLE(NPCascTableNT, "AOD", "NPCASCTABLENT", NPCascadeTable::MatchingChi2, @@ -235,7 +243,11 @@ DECLARE_SOA_TABLE(NPCascTableNT, "AOD", "NPCASCTABLENT", NPCascadeTable::BachPionTOFNSigma, NPCascadeTable::Sel8, NPCascadeTable::MultFT0C, - NPCascadeTable::MultFT0A) + NPCascadeTable::MultFT0A, + NPCascadeTable::MultFT0M, + NPCascadeTable::CentFT0C, + NPCascadeTable::CentFT0A, + NPCascadeTable::CentFT0M) DECLARE_SOA_TABLE(NPCascTableMC, "AOD", "NPCASCTABLEMC", NPCascadeTable::MatchingChi2, @@ -302,6 +314,10 @@ DECLARE_SOA_TABLE(NPCascTableMC, "AOD", "NPCASCTABLEMC", NPCascadeTable::Sel8, NPCascadeTable::MultFT0C, NPCascadeTable::MultFT0A, + NPCascadeTable::MultFT0M, + NPCascadeTable::CentFT0C, + NPCascadeTable::CentFT0A, + NPCascadeTable::CentFT0M, NPCascadeTable::gPt, NPCascadeTable::gEta, NPCascadeTable::gPhi, @@ -381,6 +397,10 @@ DECLARE_SOA_TABLE(NPCascTableMCNT, "AOD", "NPCASCTABLEMCNT", NPCascadeTable::Sel8, NPCascadeTable::MultFT0C, NPCascadeTable::MultFT0A, + NPCascadeTable::MultFT0M, + NPCascadeTable::CentFT0C, + NPCascadeTable::CentFT0A, + NPCascadeTable::CentFT0M, NPCascadeTable::gPt, NPCascadeTable::gEta, NPCascadeTable::gPhi, diff --git a/PWGLF/DataModel/LFSlimNucleiTables.h b/PWGLF/DataModel/LFSlimNucleiTables.h index 28067a9521b..e562c35ddc6 100644 --- a/PWGLF/DataModel/LFSlimNucleiTables.h +++ b/PWGLF/DataModel/LFSlimNucleiTables.h @@ -44,15 +44,39 @@ DECLARE_SOA_COLUMN(ITSclsMap, itsClsMap, uint8_t); DECLARE_SOA_COLUMN(TPCnCls, tpcNCls, uint8_t); DECLARE_SOA_COLUMN(TPCnClsShared, tpcNClsShared, uint8_t); DECLARE_SOA_COLUMN(ITSclusterSizes, itsClusterSizes, uint32_t); +DECLARE_SOA_COLUMN(SurvivedEventSelection, survivedEventSelection, bool); DECLARE_SOA_COLUMN(gPt, genPt, float); DECLARE_SOA_COLUMN(gEta, genEta, float); DECLARE_SOA_COLUMN(gPhi, genPhi, float); DECLARE_SOA_COLUMN(PDGcode, pdgCode, int); DECLARE_SOA_COLUMN(MotherPDGcode, MotherpdgCode, int); -DECLARE_SOA_COLUMN(SurvivedEventSelection, survivedEventSelection, bool); +DECLARE_SOA_COLUMN(MotherDecRad, motherDecRad, float); DECLARE_SOA_COLUMN(AbsoDecL, absoDecL, float); } // namespace NucleiTableNS + +namespace NucleiPairTableNS +{ +DECLARE_SOA_COLUMN(Pt1, pt1, float); // first particle pt +DECLARE_SOA_COLUMN(Eta1, eta1, float); // first particle eta +DECLARE_SOA_COLUMN(Phi1, phi1, float); // first particle phi +DECLARE_SOA_COLUMN(TPCInnerParam1, tpcInnerParam1, float); // first particle TPC inner param +DECLARE_SOA_COLUMN(TPCsignal1, tpcSignal1, float); // first particle TPC signal +DECLARE_SOA_COLUMN(DCAxy1, dcaxy1, float); // first particle DCA xy +DECLARE_SOA_COLUMN(DCAz1, dcaz1, float); // first particle DCA z +DECLARE_SOA_COLUMN(ClusterSizesITS1, clusterSizesITS1, uint32_t); // first particle ITS cluster sizes +DECLARE_SOA_COLUMN(Flags1, flags1, uint16_t); // first particle flags +DECLARE_SOA_COLUMN(Pt2, pt2, float); // second particle pt +DECLARE_SOA_COLUMN(Eta2, eta2, float); // second particle eta +DECLARE_SOA_COLUMN(Phi2, phi2, float); // second particle phi +DECLARE_SOA_COLUMN(TPCInnerParam2, tpcInnerParam2, float); // second particle TPC inner param +DECLARE_SOA_COLUMN(TPCsignal2, tpcSignal2, float); // second particle TPC signal +DECLARE_SOA_COLUMN(DCAxy2, dcaxy2, float); // second particle DCA xy +DECLARE_SOA_COLUMN(DCAz2, dcaz2, float); // second particle DCA z +DECLARE_SOA_COLUMN(ClusterSizesITS2, clusterSizesITS2, uint32_t); // second particle ITS cluster sizes +DECLARE_SOA_COLUMN(Flags2, flags2, uint16_t); // second particle flags +} // namespace NucleiPairTableNS + namespace NucleiFlowTableNS { DECLARE_SOA_COLUMN(CentFV0A, centFV0A, float); // centrality with FT0A estimator @@ -128,14 +152,35 @@ DECLARE_SOA_TABLE(NucleiTableMC, "AOD", "NUCLEITABLEMC", NucleiTableNS::TPCnCls, NucleiTableNS::TPCnClsShared, NucleiTableNS::ITSclusterSizes, + NucleiTableNS::SurvivedEventSelection, NucleiTableNS::gPt, NucleiTableNS::gEta, NucleiTableNS::gPhi, NucleiTableNS::PDGcode, NucleiTableNS::MotherPDGcode, - NucleiTableNS::SurvivedEventSelection, + NucleiTableNS::MotherDecRad, NucleiTableNS::AbsoDecL); +DECLARE_SOA_TABLE(NucleiPairTable, "AOD", "NUCLEIPAIRTABLE", + NucleiPairTableNS::Pt1, + NucleiPairTableNS::Eta1, + NucleiPairTableNS::Phi1, + NucleiPairTableNS::TPCInnerParam1, + NucleiPairTableNS::TPCsignal1, + NucleiPairTableNS::DCAxy1, + NucleiPairTableNS::DCAz1, + NucleiPairTableNS::ClusterSizesITS1, + NucleiPairTableNS::Flags1, + NucleiPairTableNS::Pt2, + NucleiPairTableNS::Eta2, + NucleiPairTableNS::Phi2, + NucleiPairTableNS::TPCInnerParam2, + NucleiPairTableNS::TPCsignal2, + NucleiPairTableNS::DCAxy2, + NucleiPairTableNS::DCAz2, + NucleiPairTableNS::ClusterSizesITS2, + NucleiPairTableNS::Flags2); + } // namespace o2::aod #endif // PWGLF_DATAMODEL_LFSLIMNUCLEITABLES_H_ diff --git a/PWGLF/DataModel/LFStrangenessTables.h b/PWGLF/DataModel/LFStrangenessTables.h index bfe3a4f055d..ce2e9e65eda 100644 --- a/PWGLF/DataModel/LFStrangenessTables.h +++ b/PWGLF/DataModel/LFStrangenessTables.h @@ -618,42 +618,28 @@ DECLARE_SOA_COLUMN(GeneratedK0Short, generatedK0Short, std::vector); DECLARE_SOA_COLUMN(GeneratedLambda, generatedLambda, std::vector); //! Lambda binned generated data DECLARE_SOA_COLUMN(GeneratedAntiLambda, generatedAntiLambda, std::vector); //! AntiLambda binned generated data -//______________________________________________________ -// EXPRESSION COLUMNS -DECLARE_SOA_EXPRESSION_COLUMN(Px, px, //! V0 px - float, 1.f * aod::v0data::pxpos + 1.f * aod::v0data::pxneg); -DECLARE_SOA_EXPRESSION_COLUMN(Py, py, //! V0 py - float, 1.f * aod::v0data::pypos + 1.f * aod::v0data::pyneg); -DECLARE_SOA_EXPRESSION_COLUMN(Pz, pz, //! V0 pz - float, 1.f * aod::v0data::pzpos + 1.f * aod::v0data::pzneg); -DECLARE_SOA_EXPRESSION_COLUMN(Pt, pt, float, //! Transverse momentum in GeV/c - nsqrt((1.f * aod::v0data::pxpos + 1.f * aod::v0data::pxneg) * - (1.f * aod::v0data::pxpos + 1.f * aod::v0data::pxneg) + - (1.f * aod::v0data::pypos + 1.f * aod::v0data::pyneg) * (1.f * aod::v0data::pypos + 1.f * aod::v0data::pyneg))); -DECLARE_SOA_EXPRESSION_COLUMN(P, p, float, //! Total momentum in GeV/c - nsqrt((1.f * aod::v0data::pxpos + 1.f * aod::v0data::pxneg) * - (1.f * aod::v0data::pxpos + 1.f * aod::v0data::pxneg) + - (1.f * aod::v0data::pypos + 1.f * aod::v0data::pyneg) * (1.f * aod::v0data::pypos + 1.f * aod::v0data::pyneg) + - (1.f * aod::v0data::pzpos + 1.f * aod::v0data::pzneg) * (1.f * aod::v0data::pzpos + 1.f * aod::v0data::pzneg))); -DECLARE_SOA_EXPRESSION_COLUMN(Phi, phi, float, //! Phi in the range [0, 2pi) - o2::constants::math::PI + natan2(-1.0f * (1.f * aod::v0data::pypos + 1.f * aod::v0data::pyneg), -1.0f * (1.f * aod::v0data::pxpos + 1.f * aod::v0data::pxneg))); -DECLARE_SOA_EXPRESSION_COLUMN(Eta, eta, float, //! Pseudorapidity, conditionally defined to avoid FPEs - ifnode((nsqrt((1.f * aod::v0data::pxpos + 1.f * aod::v0data::pxneg) * (1.f * aod::v0data::pxpos + 1.f * aod::v0data::pxneg) + - (1.f * aod::v0data::pypos + 1.f * aod::v0data::pyneg) * (1.f * aod::v0data::pypos + 1.f * aod::v0data::pyneg) + - (1.f * aod::v0data::pzpos + 1.f * aod::v0data::pzneg) * (1.f * aod::v0data::pzpos + 1.f * aod::v0data::pzneg)) - - (1.f * aod::v0data::pzpos + 1.f * aod::v0data::pzneg)) < static_cast(1e-7), - ifnode((1.f * aod::v0data::pzpos + 1.f * aod::v0data::pzneg) < 0.f, -100.f, 100.f), - 0.5f * nlog((nsqrt((1.f * aod::v0data::pxpos + 1.f * aod::v0data::pxneg) * (1.f * aod::v0data::pxpos + 1.f * aod::v0data::pxneg) + - (1.f * aod::v0data::pypos + 1.f * aod::v0data::pyneg) * (1.f * aod::v0data::pypos + 1.f * aod::v0data::pyneg) + - (1.f * aod::v0data::pzpos + 1.f * aod::v0data::pzneg) * (1.f * aod::v0data::pzpos + 1.f * aod::v0data::pzneg)) + - (1.f * aod::v0data::pzpos + 1.f * aod::v0data::pzneg)) / - (nsqrt((1.f * aod::v0data::pxpos + 1.f * aod::v0data::pxneg) * (1.f * aod::v0data::pxpos + 1.f * aod::v0data::pxneg) + - (1.f * aod::v0data::pypos + 1.f * aod::v0data::pyneg) * (1.f * aod::v0data::pypos + 1.f * aod::v0data::pyneg) + - (1.f * aod::v0data::pzpos + 1.f * aod::v0data::pzneg) * (1.f * aod::v0data::pzpos + 1.f * aod::v0data::pzneg)) - - (1.f * aod::v0data::pzpos + 1.f * aod::v0data::pzneg))))); - //______________________________________________________ // DYNAMIC COLUMNS +DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! V0 px + [](float pxPos, float pxNeg) -> float { return pxPos + pxNeg; }); +DECLARE_SOA_DYNAMIC_COLUMN(Py, py, //! V0 py + [](float pyPos, float pyNeg) -> float { return pyPos + pyNeg; }); +DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, //! V0 pz + [](float pzPos, float pzNeg) -> float { return pzPos + pzNeg; }); +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! Transverse momentum in GeV/c + [](float pxPos, float pyPos, float pxNeg, float pyNeg) -> float { + return RecoDecay::sqrtSumOfSquares(pxPos + pxNeg, pyPos + pyNeg); + }); +DECLARE_SOA_DYNAMIC_COLUMN(P, p, //! Total momentum in GeV/c + [](float pxPos, float pyPos, float pzPos, float pxNeg, float pyNeg, float pzNeg) -> float { + return RecoDecay::sqrtSumOfSquares(pxPos + pxNeg, pyPos + pyNeg, pzPos + pzNeg); + }); +DECLARE_SOA_DYNAMIC_COLUMN(Phi, phi, //! Phi in the range [0, 2pi) + [](float pxPos, float pyPos, float pxNeg, float pyNeg) -> float { return RecoDecay::phi(pxPos + pxNeg, pyPos + pyNeg); }); +DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, //! Pseudorapidity, conditionally defined to avoid FPEs + [](float pxPos, float pyPos, float pzPos, float pxNeg, float pyNeg, float pzNeg) -> float { + return RecoDecay::eta(std::array{pxPos + pxNeg, pyPos + pyNeg, pzPos + pzNeg}); + }); // Account for rigidity in case of hypertriton DECLARE_SOA_DYNAMIC_COLUMN(PtHypertriton, ptHypertriton, //! V0 pT [](float pxpos, float pypos, float pxneg, float pyneg) -> float { return RecoDecay::sqrtSumOfSquares(2.0f * pxpos + pxneg, 2.0f * pypos + pyneg); }); @@ -666,8 +652,8 @@ DECLARE_SOA_DYNAMIC_COLUMN(V0Radius, v0radius, //! V0 decay radius (2D, centered // Distance Over To Mom DECLARE_SOA_DYNAMIC_COLUMN(DistOverTotMom, distovertotmom, //! PV to V0decay distance over total momentum - [](float X, float Y, float Z, float Px, float Py, float Pz, float pvX, float pvY, float pvZ) { - float P = RecoDecay::sqrtSumOfSquares(Px, Py, Pz); + [](float X, float Y, float Z, float pxPos, float pyPos, float pzPos, float pxNeg, float pyNeg, float pzNeg, float pvX, float pvY, float pvZ) { + float P = RecoDecay::sqrtSumOfSquares(pxPos + pxNeg, pyPos + pyNeg, pzPos + pzNeg); return std::sqrt(std::pow(X - pvX, 2) + std::pow(Y - pvY, 2) + std::pow(Z - pvZ, 2)) / (P + 1E-10); }); @@ -746,19 +732,23 @@ DECLARE_SOA_DYNAMIC_COLUMN(M, m, //! mass under a certain hypothesis (0:K0, 1:L, }); DECLARE_SOA_DYNAMIC_COLUMN(YK0Short, yK0Short, //! V0 y with K0short hypothesis - [](float Px, float Py, float Pz) -> float { return RecoDecay::y(std::array{Px, Py, Pz}, o2::constants::physics::MassKaonNeutral); }); + [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { + return RecoDecay::y(std::array{pxpos + pxneg, pypos + pyneg, pzpos + pzneg}, o2::constants::physics::MassKaonNeutral); + }); DECLARE_SOA_DYNAMIC_COLUMN(YLambda, yLambda, //! V0 y with lambda or antilambda hypothesis - [](float Px, float Py, float Pz) -> float { return RecoDecay::y(std::array{Px, Py, Pz}, o2::constants::physics::MassLambda); }); + [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { + return RecoDecay::y(std::array{pxpos + pxneg, pypos + pyneg, pzpos + pzneg}, o2::constants::physics::MassLambda); + }); DECLARE_SOA_DYNAMIC_COLUMN(YHypertriton, yHypertriton, //! V0 y with hypertriton hypothesis [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::y(std::array{2.0f * pxpos + pxneg, 2.0f * pypos + pyneg, 2.0f * pzpos + pzneg}, o2::constants::physics::MassHyperTriton); }); DECLARE_SOA_DYNAMIC_COLUMN(YAntiHypertriton, yAntiHypertriton, //! V0 y with antihypertriton hypothesis [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::y(std::array{pxpos + 2.0f * pxneg, pypos + 2.0f * pyneg, pzpos + 2.0f * pzneg}, o2::constants::physics::MassHyperTriton); }); DECLARE_SOA_DYNAMIC_COLUMN(Rapidity, rapidity, //! rapidity (0:K0, 1:L, 2:Lbar) - [](float Px, float Py, float Pz, int value) -> float { + [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg, int value) -> float { if (value == 0) - return RecoDecay::y(std::array{Px, Py, Pz}, o2::constants::physics::MassKaonNeutral); + return RecoDecay::y(std::array{pxpos + pxneg, pypos + pyneg, pzpos + pzneg}, o2::constants::physics::MassKaonNeutral); if (value == 1 || value == 2) - return RecoDecay::y(std::array{Px, Py, Pz}, o2::constants::physics::MassLambda); + return RecoDecay::y(std::array{pxpos + pxneg, pypos + pyneg, pzpos + pzneg}, o2::constants::physics::MassLambda); return 0.0f; }); @@ -820,10 +810,17 @@ DECLARE_SOA_TABLE_STAGED(V0CoresBase, "V0CORE", //! core information about decay v0data::V0CosPA, v0data::DCAV0ToPV, v0data::V0Type, // Dynamic columns + v0data::Px, + v0data::Py, + v0data::Pz, + v0data::Pt, + v0data::P, + v0data::Phi, + v0data::Eta, v0data::PtHypertriton, v0data::PtAntiHypertriton, v0data::V0Radius, - v0data::DistOverTotMom, + v0data::DistOverTotMom, v0data::Alpha, v0data::QtArm, v0data::PsiPair, @@ -840,11 +837,11 @@ DECLARE_SOA_TABLE_STAGED(V0CoresBase, "V0CORE", //! core information about decay v0data::M, // Longitudinal - v0data::YK0Short, - v0data::YLambda, + v0data::YK0Short, + v0data::YLambda, v0data::YHypertriton, v0data::YAntiHypertriton, - v0data::Rapidity, + v0data::Rapidity, v0data::NegativePt, v0data::PositivePt, v0data::NegativeEta, @@ -855,8 +852,8 @@ DECLARE_SOA_TABLE_STAGED(V0CoresBase, "V0CORE", //! core information about decay v0data::IsPhotonTPConly); // extended table with expression columns that can be used as arguments of dynamic columns -DECLARE_SOA_EXTENDED_TABLE_USER(V0Cores, V0CoresBase, "V0COREEXT", //! - v0data::Px, v0data::Py, v0data::Pz, v0data::Pt, v0data::P, v0data::Phi, v0data::Eta); // the table name has here to be the one with EXT which is not nice and under study +// DECLARE_SOA_EXTENDED_TABLE_USER(V0Cores, V0CoresBase, "V0COREEXT", //! +// v0data::Px, v0data::Py, v0data::Pz, v0data::Pt, v0data::P, v0data::Phi, v0data::Eta); // the table name has here to be the one with EXT which is not nice and under study // // extended table with expression columns that can be used as arguments of dynamic columns // DECLARE_SOA_EXTENDED_TABLE_USER(StoredV0Cores, StoredV0CoresBase, "V0COREEXT", //! @@ -894,10 +891,17 @@ DECLARE_SOA_TABLE_FULL(StoredV0fCCores, "V0fCCores", "AOD", "V0FCCORE", //! core v0data::V0CosPA, v0data::DCAV0ToPV, v0data::V0Type, // Dynamic columns + v0data::Px, + v0data::Py, + v0data::Pz, + v0data::Pt, + v0data::P, + v0data::Phi, + v0data::Eta, v0data::PtHypertriton, v0data::PtAntiHypertriton, v0data::V0Radius, - v0data::DistOverTotMom, + v0data::DistOverTotMom, v0data::Alpha, v0data::QtArm, v0data::PsiPair, @@ -914,11 +918,11 @@ DECLARE_SOA_TABLE_FULL(StoredV0fCCores, "V0fCCores", "AOD", "V0FCCORE", //! core v0data::M, // Longitudinal - v0data::YK0Short, - v0data::YLambda, + v0data::YK0Short, + v0data::YLambda, v0data::YHypertriton, v0data::YAntiHypertriton, - v0data::Rapidity, + v0data::Rapidity, v0data::NegativePt, v0data::PositivePt, v0data::NegativeEta, @@ -930,8 +934,8 @@ DECLARE_SOA_TABLE_FULL(StoredV0fCCores, "V0fCCores", "AOD", "V0FCCORE", //! core o2::soa::Marker<2>); // extended table with expression columns that can be used as arguments of dynamic columns -DECLARE_SOA_EXTENDED_TABLE_USER(V0fCCores, StoredV0fCCores, "V0FCCOREEXT", //! - v0data::Px, v0data::Py, v0data::Pz, v0data::Pt, v0data::P, v0data::Phi, v0data::Eta); // the table name has here to be the one with EXT which is not nice and under study +// DECLARE_SOA_EXTENDED_TABLE_USER(V0fCCores, StoredV0fCCores, "V0FCCOREEXT", //! +// v0data::Px, v0data::Py, v0data::Pz, v0data::Pt, v0data::P, v0data::Phi, v0data::Eta); // the table name has here to be the one with EXT which is not nice and under study DECLARE_SOA_TABLE_FULL(V0fCCovs, "V0fCCovs", "AOD", "V0FCCOVS", //! V0 covariance matrices v0data::PositionCovMat, v0data::MomentumCovMat, o2::soa::Marker<2>); @@ -1001,6 +1005,9 @@ DECLARE_SOA_TABLE(GeAntiLambda, "AOD", "GeAntiLambda", v0data::GeneratedAntiLamb DECLARE_SOA_TABLE_STAGED(V0MCMothers, "V0MCMOTHER", //! optional table for MC mothers o2::soa::Index<>, v0data::MotherMCPartId); +using V0fCCores = StoredV0fCCores; +using V0Cores = V0CoresBase; + using V0MCCores = V0MCCores_002; using StoredV0MCCores = StoredV0MCCores_002; @@ -1263,13 +1270,20 @@ DECLARE_SOA_DYNAMIC_COLUMN(CascRadius, cascradius, //! // CosPAs DECLARE_SOA_DYNAMIC_COLUMN(V0CosPA, v0cosPA, //! - [](float Xlambda, float Ylambda, float Zlambda, float PxLambda, float PyLambda, float PzLambda, float pvX, float pvY, float pvZ) -> float { return RecoDecay::cpa(std::array{pvX, pvY, pvZ}, std::array{Xlambda, Ylambda, Zlambda}, std::array{PxLambda, PyLambda, PzLambda}); }); + [](float Xlambda, float Ylambda, float Zlambda, float pxPos, float pyPos, float pzPos, float pxNeg, float pyNeg, float pzNeg, float pvX, float pvY, float pvZ) -> float { + return RecoDecay::cpa(std::array{pvX, pvY, pvZ}, std::array{Xlambda, Ylambda, Zlambda}, std::array{pxPos + pxNeg, pyPos + pyNeg, pzPos + pzNeg}); + }); // DECLARE_SOA_DYNAMIC_COLUMN(CascCosPA, casccosPA, //! // [](float X, float Y, float Z, float Px, float Py, float Pz, float pvX, float pvY, float pvZ) -> float { return RecoDecay::cpa(std::array{pvX, pvY, pvZ}, std::array{X, Y, Z}, std::array{Px, Py, Pz}); }); DECLARE_SOA_DYNAMIC_COLUMN(CascCosPA, casccosPA, //! [](float X, float Y, float Z, float PxBach, float PxPos, float PxNeg, float PyBach, float PyPos, float PyNeg, float PzBach, float PzPos, float PzNeg, float pvX, float pvY, float pvZ) -> float { return RecoDecay::cpa(std::array{pvX, pvY, pvZ}, std::array{X, Y, Z}, std::array{PxBach + PxPos + PxNeg, PyBach + PyPos + PyNeg, PzBach + PzPos + PzNeg}); }); DECLARE_SOA_DYNAMIC_COLUMN(DCAV0ToPV, dcav0topv, //! - [](float X, float Y, float Z, float Px, float Py, float Pz, float pvX, float pvY, float pvZ) -> float { return std::sqrt((std::pow((pvY - Y) * Pz - (pvZ - Z) * Py, 2) + std::pow((pvX - X) * Pz - (pvZ - Z) * Px, 2) + std::pow((pvX - X) * Py - (pvY - Y) * Px, 2)) / (Px * Px + Py * Py + Pz * Pz)); }); + [](float X, float Y, float Z, float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg, float pvX, float pvY, float pvZ) -> float { + float px = pxpos + pxneg; + float py = pypos + pyneg; + float pz = pzpos + pzneg; + return std::sqrt((std::pow((pvY - Y) * pz - (pvZ - Z) * py, 2) + std::pow((pvX - X) * pz - (pvZ - Z) * px, 2) + std::pow((pvX - X) * py - (pvY - Y) * px, 2)) / (px * px + py * py + pz * pz)); + }); // Calculated on the fly with mass assumption + dynamic tables DECLARE_SOA_DYNAMIC_COLUMN(MLambda, mLambda, //! @@ -1332,42 +1346,22 @@ DECLARE_SOA_DYNAMIC_COLUMN(BachelorPtMC, bachelorptMC, //! bachelor daughter pT [](float pxBachMC, float pyBachMC) -> float { return RecoDecay::sqrtSumOfSquares(pxBachMC, pyBachMC); }); DECLARE_SOA_DYNAMIC_COLUMN(PtMC, ptMC, //! cascade pT [](float pxMC, float pyMC) -> float { return RecoDecay::sqrtSumOfSquares(pxMC, pyMC); }); -} // namespace cascdata -//______________________________________________________ -// EXPRESSION COLUMNS FOR TRACASCCORES -namespace cascdataext -{ -DECLARE_SOA_EXPRESSION_COLUMN(PxLambda, pxlambda, //! - float, 1.f * aod::cascdata::pxpos + 1.f * aod::cascdata::pxneg); -DECLARE_SOA_EXPRESSION_COLUMN(PyLambda, pylambda, //! - float, 1.f * aod::cascdata::pypos + 1.f * aod::cascdata::pyneg); -DECLARE_SOA_EXPRESSION_COLUMN(PzLambda, pzlambda, //! - float, 1.f * aod::cascdata::pzpos + 1.f * aod::cascdata::pzneg); -DECLARE_SOA_EXPRESSION_COLUMN(Pt, pt, float, //! Transverse momentum in GeV/c - nsqrt(aod::cascdata::px* aod::cascdata::px + - aod::cascdata::py * aod::cascdata::py)); -DECLARE_SOA_EXPRESSION_COLUMN(P, p, float, //! Total momentum in GeV/c - nsqrt(aod::cascdata::px* aod::cascdata::px + - aod::cascdata::py * aod::cascdata::py + - aod::cascdata::pz * aod::cascdata::pz)); -DECLARE_SOA_EXPRESSION_COLUMN(Phi, phi, float, //! Phi in the range [0, 2pi) - o2::constants::math::PI + natan2(-1.0f * aod::cascdata::py, -1.0f * aod::cascdata::px)); -DECLARE_SOA_EXPRESSION_COLUMN(Eta, eta, float, //! Pseudorapidity, conditionally defined to avoid FPEs - ifnode((nsqrt(aod::cascdata::px * aod::cascdata::px + - aod::cascdata::py * aod::cascdata::py + - aod::cascdata::pz * aod::cascdata::pz) - - aod::cascdata::pz) < static_cast(1e-7), - ifnode(aod::cascdata::pz < 0.f, -100.f, 100.f), - 0.5f * nlog((nsqrt(aod::cascdata::px * aod::cascdata::px + - aod::cascdata::py * aod::cascdata::py + - aod::cascdata::pz * aod::cascdata::pz) + - aod::cascdata::pz) / - (nsqrt(aod::cascdata::px * aod::cascdata::px + - aod::cascdata::py * aod::cascdata::py + - aod::cascdata::pz * aod::cascdata::pz) - - aod::cascdata::pz)))); -} // namespace cascdataext +DECLARE_SOA_DYNAMIC_COLUMN(PxLambda, pxlambda, //! Lambda daughter px + [](float pxPos, float pxNeg) -> float { return pxPos + pxNeg; }); +DECLARE_SOA_DYNAMIC_COLUMN(PyLambda, pylambda, //! Lambda daughter py + [](float pyPos, float pyNeg) -> float { return pyPos + pyNeg; }); +DECLARE_SOA_DYNAMIC_COLUMN(PzLambda, pzlambda, //! Lambda daughter pz + [](float pzPos, float pzNeg) -> float { return pzPos + pzNeg; }); +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! Cascade transverse momentum in GeV/c + [](float px, float py) -> float { return RecoDecay::sqrtSumOfSquares(px, py); }); +DECLARE_SOA_DYNAMIC_COLUMN(P, p, //! Cascade total momentum in GeV/c + [](float px, float py, float pz) -> float { return RecoDecay::sqrtSumOfSquares(px, py, pz); }); +DECLARE_SOA_DYNAMIC_COLUMN(Phi, phi, //! Cascade phi in the range [0, 2pi) + [](float px, float py) -> float { return RecoDecay::phi(px, py); }); +DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, //! Cascade pseudorapidity + [](float px, float py, float pz) -> float { return RecoDecay::eta(std::array{px, py, pz}); }); +} // namespace cascdata //______________________________________________________ // Cascade data model: @@ -1413,11 +1407,18 @@ DECLARE_SOA_TABLE(StoredCascCores, "AOD", "CASCCORE", //! core information about cascdata::DCAPosToPV, cascdata::DCANegToPV, cascdata::DCABachToPV, cascdata::DCAXYCascToPV, cascdata::DCAZCascToPV, // Dynamic columns + cascdata::PxLambda, + cascdata::PyLambda, + cascdata::PzLambda, + cascdata::Pt, + cascdata::P, + cascdata::Phi, + cascdata::Eta, cascdata::V0Radius, cascdata::CascRadius, - cascdata::V0CosPA, + cascdata::V0CosPA, cascdata::CascCosPA, - cascdata::DCAV0ToPV, + cascdata::DCAV0ToPV, // Invariant masses cascdata::MLambda, @@ -1456,11 +1457,18 @@ DECLARE_SOA_TABLE(StoredKFCascCores, "AOD", "KFCASCCORE", //! kfcascdata::MLambda, cascdata::KFV0Chi2, cascdata::KFCascadeChi2, // Dynamic columns + cascdata::PxLambda, + cascdata::PyLambda, + cascdata::PzLambda, + cascdata::Pt, + cascdata::P, + cascdata::Phi, + cascdata::Eta, cascdata::V0Radius, cascdata::CascRadius, - cascdata::V0CosPA, + cascdata::V0CosPA, cascdata::CascCosPA, - cascdata::DCAV0ToPV, + cascdata::DCAV0ToPV, // Invariant masses cascdata::M, @@ -1494,11 +1502,18 @@ DECLARE_SOA_TABLE(StoredTraCascCores, "AOD", "TRACASCCORE", //! cascdata::MatchingChi2, cascdata::TopologyChi2, cascdata::ItsClsSize, // Dynamic columns + cascdata::PxLambda, + cascdata::PyLambda, + cascdata::PzLambda, + cascdata::Pt, + cascdata::P, + cascdata::Phi, + cascdata::Eta, cascdata::V0Radius, cascdata::CascRadius, - cascdata::V0CosPA, + cascdata::V0CosPA, cascdata::CascCosPA, - cascdata::DCAV0ToPV, + cascdata::DCAV0ToPV, // Invariant masses cascdata::MLambda, @@ -1568,19 +1583,9 @@ DECLARE_SOA_TABLE(TraCascCovs, "AOD", "TRACASCCOVS", //! cascdata::MomentumCovMat, o2::soa::Marker<2>); -// extended table with expression columns that can be used as arguments of dynamic columns -DECLARE_SOA_EXTENDED_TABLE_USER(CascCores, StoredCascCores, "CascDATAEXT", //! - cascdataext::PxLambda, cascdataext::PyLambda, cascdataext::PzLambda, cascdataext::Pt, cascdataext::P, cascdataext::Eta, cascdataext::Phi); - -// extended table with expression columns that can be used as arguments of dynamic columns -DECLARE_SOA_EXTENDED_TABLE_USER(KFCascCores, StoredKFCascCores, "KFCascDATAEXT", //! - cascdataext::PxLambda, cascdataext::PyLambda, cascdataext::PzLambda, - cascdataext::Pt, cascdataext::P, cascdataext::Eta, cascdataext::Phi); - -// extended table with expression columns that can be used as arguments of dynamic columns -DECLARE_SOA_EXTENDED_TABLE_USER(TraCascCores, StoredTraCascCores, "TraCascDATAEXT", //! - cascdataext::PxLambda, cascdataext::PyLambda, cascdataext::PzLambda, - cascdataext::Pt, cascdataext::P, cascdataext::Eta, cascdataext::Phi); +using CascCores = StoredCascCores; +using KFCascCores = StoredKFCascCores; +using TraCascCores = StoredTraCascCores; namespace cascdata { diff --git a/PWGLF/TableProducer/Common/kinkBuilder.cxx b/PWGLF/TableProducer/Common/kinkBuilder.cxx index f51e1ba1599..d2b25be26a0 100644 --- a/PWGLF/TableProducer/Common/kinkBuilder.cxx +++ b/PWGLF/TableProducer/Common/kinkBuilder.cxx @@ -122,12 +122,9 @@ struct kinkBuilder { Configurable unlikeSignBkg{"unlikeSignBkg", false, "Use unlike sign background"}; // CCDB options - Configurable inputBz{"inputBz", -999, "bz field, -999 is automatic"}; Configurable ccdbPath{"ccdbPath", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; - Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; // PDG codes @@ -174,7 +171,6 @@ struct kinkBuilder { ccdb->setURL(ccdbPath); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); - ccdb->setFatalWhenNull(false); fitter.setPropagateToPCA(true); fitter.setMaxR(200.); fitter.setMinParamChange(1e-3); @@ -183,10 +179,6 @@ struct kinkBuilder { fitter.setMaxChi2(1e9); fitter.setUseAbsDCA(true); - lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(lutPath)); - int mat{static_cast(cfgMaterialCorrection)}; - fitter.setMatCorrType(static_cast(mat)); - svCreator.setTimeMargin(customVertexerTimeMargin); if (skipAmbiTracks) { svCreator.setSkipAmbiTracks(); @@ -210,6 +202,11 @@ struct kinkBuilder { h2MothMassPt = qaRegistry.add("h2MothMassPt", "; p_{T} (GeV/#it{c}); m (GeV/#it{c}^{2})", HistType::kTH2F, {ptAxis, massAxis}); h2ClsMapPtMoth = qaRegistry.add("h2ClsMapPtMoth", "; p_{T} (GeV/#it{c}); ITS cluster map", HistType::kTH2F, {ptAxis, itsClusterMapAxis}); h2ClsMapPtDaug = qaRegistry.add("h2ClsMapPtDaug", "; p_{T} (GeV/#it{c}); ITS cluster map", HistType::kTH2F, {ptAxis, itsClusterMapAxis}); + + for (int i = 0; i < 5; i++) { + mBBparamsDaug[i] = cfgBetheBlochParams->get("Daughter", Form("p%i", i)); + } + mBBparamsDaug[5] = cfgBetheBlochParams->get("Daughter", "resolution"); } template @@ -247,7 +244,7 @@ struct kinkBuilder { } template - void fillCandidateData(const Tcolls& collisions, const Ttracks& tracks, aod::AmbiguousTracks const& ambiguousTracks, aod::BCsWithTimestamps const& bcs) + void fillCandidateData(const Tcolls& collisions, const Ttracks& tracks, aod::AmbiguousTracks const& ambiguousTracks, aod::BCs const& bcs) { svCreator.clearPools(); svCreator.fillBC2Coll(collisions, bcs); @@ -274,7 +271,7 @@ struct kinkBuilder { auto trackDaug = tracks.rawIteratorAt(svCand.tr1Idx); auto const& collision = trackMoth.template collision_as(); - auto const& bc = collision.template bc_as(); + auto const& bc = collision.template bc_as(); initCCDB(bc); o2::dataformats::VertexBase primaryVertex; @@ -283,9 +280,9 @@ struct kinkBuilder { kinkCand.primVtx = {primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ()}; o2::track::TrackParCov trackParCovMoth = getTrackParCov(trackMoth); + o2::track::TrackParCov trackParCovMothPV{trackParCovMoth}; o2::base::Propagator::Instance()->PropagateToXBxByBz(trackParCovMoth, LayerRadii[trackMoth.itsNCls() - 1]); - o2::track::TrackParCov trackParCovMothPV = getTrackParCov(trackMoth); std::array dcaInfoMoth; o2::base::Propagator::Instance()->propagateToDCABxByBz({primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ()}, trackParCovMothPV, 2.f, static_cast(cfgMaterialCorrection.value), &dcaInfoMoth); @@ -401,51 +398,28 @@ struct kinkBuilder { } } - void initCCDB(aod::BCsWithTimestamps::iterator const& bc) + void initCCDB(aod::BCs::iterator const& bc) { if (mRunNumber == bc.runNumber()) { return; } - auto run3grp_timestamp = bc.timestamp(); - - o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); - o2::parameters::GRPMagField* grpmag = 0x0; - if (grpo) { - o2::base::Propagator::initFieldFromGRP(grpo); - if (inputBz < -990) { - // Fetch magnetic field from ccdb for current collision - mBz = grpo->getNominalL3Field(); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << mBz << " kZG"; - } else { - mBz = inputBz; - } - } else { - grpmag = ccdb->getForTimeStamp(grpmagPath, run3grp_timestamp); - if (!grpmag) { - LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; - } - o2::base::Propagator::initFieldFromGRP(grpmag); - if (inputBz < -990) { - // Fetch magnetic field from ccdb for current collision - mBz = std::lround(5.f * grpmag->getL3Current() / 30000.f); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << mBz << " kZG"; - } else { - mBz = inputBz; - } - } + mRunNumber = bc.runNumber(); + LOG(info) << "Initializing CCDB for run " << mRunNumber; + o2::parameters::GRPMagField* grpmag = ccdb->getForRun(grpmagPath, mRunNumber); + o2::base::Propagator::initFieldFromGRP(grpmag); + mBz = grpmag->getNominalL3Field(); + fitter.setBz(mBz); - for (int i = 0; i < 5; i++) { - mBBparamsDaug[i] = cfgBetheBlochParams->get("Daughter", Form("p%i", i)); + if (!lut) { + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(lutPath)); + int mat{static_cast(cfgMaterialCorrection)}; + fitter.setMatCorrType(static_cast(mat)); } - mBBparamsDaug[5] = cfgBetheBlochParams->get("Daughter", "resolution"); - - fitter.setBz(mBz); - mRunNumber = bc.runNumber(); o2::base::Propagator::Instance()->setMatLUT(lut); LOG(info) << "Task initialized for run " << mRunNumber << " with magnetic field " << mBz << " kZG"; } - void process(aod::Collisions const& collisions, TracksFull const& tracks, aod::AmbiguousTracks const& ambiTracks, aod::BCsWithTimestamps const& bcs) + void process(aod::Collisions const& collisions, TracksFull const& tracks, aod::AmbiguousTracks const& ambiTracks, aod::BCs const& bcs) { kinkCandidates.clear(); diff --git a/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx b/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx index be6be00f699..ae78ecdb735 100644 --- a/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx +++ b/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx @@ -231,7 +231,7 @@ struct EbyeMaker { Configurable> cfgBetheBlochParamsITS{"cfgBetheBlochParamsITS", {betheBlochDefaultITS, 1, 6, particleName, betheBlochParNames}, "ITS Bethe-Bloch parameterisation for deuteron"}; ConfigurableAxis centAxis{"centAxis", {106, 0, 106}, "binning for the centrality"}; - ConfigurableAxis zVtxAxis{"zVtxAxis", {100, -20.f, 20.f}, "Binning for the vertex z in cm"}; + ConfigurableAxis zVtxAxis{"zVtxBins", {100, -20.f, 20.f}, "Binning for the vertex z in cm"}; ConfigurableAxis multAxis{"multAxis", {100, 0, 10000}, "Binning for the multiplicity axis"}; ConfigurableAxis multFt0Axis{"multFt0Axis", {100, 0, 100000}, "Binning for the ft0 multiplicity axis"}; @@ -239,7 +239,7 @@ struct EbyeMaker { ConfigurableAxis massLambdaAxis{"massLambdaAxis", {400, o2::constants::physics::MassLambda0 - 0.03f, o2::constants::physics::MassLambda0 + 0.03f}, "binning for the lambda invariant-mass"}; // binning of PID QA histograms - ConfigurableAxis momAxis{"momAxis", {5.e2, 0.f, 5.f}, "momentum axis binning"}; + ConfigurableAxis momAxis{"momAxisFine", {5.e2, 0.f, 5.f}, "momentum axis binning"}; ConfigurableAxis tpcAxis{"tpcAxis", {4.e2, 0.f, 4.e3f}, "tpc signal axis binning"}; ConfigurableAxis tofMassAxis{"tofMassAxis", {1000, 0., 3.f}, "tof mass axis"}; @@ -249,7 +249,7 @@ struct EbyeMaker { Configurable outerPIDMin{"outerPIDMin", -4.f, "minimum outer PID"}; Configurable storeTracksNum{"storeTracksNum", false, "store the number of tracks instead of tracklets"}; - Configurable genName{"genName", "", "Genearator name: HIJING, PYTHIA8, ... Default: \"\""}; + Configurable genName{"genname", "", "Genearator name: HIJING, PYTHIA8, ... Default: \"\""}; Configurable triggerCut{"triggerCut", 0x0, "trigger cut to select"}; Configurable kINT7Intervals{"kINT7Intervals", false, "toggle kINT7 trigger selection in the 10-30% and 50-90% centrality intervals (2018 Pb-Pb)"}; @@ -268,14 +268,14 @@ struct EbyeMaker { Configurable lambdaPtMax{"lambdaPtMax", 4.f, "maximum (anti)lambda pT (GeV/c)"}; Configurable trackNcrossedRows{"trackNcrossedRows", 70, "Minimum number of crossed TPC rows"}; - Configurable trackNclusItsCut{"trackNclusItsCut", 2, "Minimum number of ITS clusters"}; - Configurable trackNclusTpcCut{"trackNclusTpcCut", 60, "Minimum number of TPC clusters"}; + Configurable trackNclusItsCut{"trackNclusITScut", 2, "Minimum number of ITS clusters"}; + Configurable trackNclusTpcCut{"trackNclusTPCcut", 60, "Minimum number of TPC clusters"}; Configurable trackChi2Cut{"trackChi2Cut", 4.f, "Maximum chi2/ncls in TPC"}; Configurable> cfgDcaSels{"cfgDcaSels", {dcaSels, 1, 3, particleName, dcaSelsNames}, "DCA selections"}; Configurable v0trackNcrossedRows{"v0trackNcrossedRows", 100, "Minimum number of crossed TPC rows for V0 daughter"}; - Configurable v0trackNclusItsCut{"v0trackNclusItsCut", 0, "Minimum number of ITS clusters for V0 daughter"}; - Configurable v0trackNclusTpcCut{"v0trackNclusTpcCut", 100, "Minimum number of TPC clusters for V0 daughter"}; + Configurable v0trackNclusItsCut{"v0trackNclusITScut", 0, "Minimum number of ITS clusters for V0 daughter"}; + Configurable v0trackNclusTpcCut{"v0trackNclusTPCcut", 100, "Minimum number of TPC clusters for V0 daughter"}; Configurable v0trackNsharedClusTpc{"v0trackNsharedClusTpc", 5, "Maximum number of shared TPC clusters for V0 daughter"}; Configurable v0requireITSrefit{"v0requireITSrefit", false, "require ITS refit for V0 daughter"}; Configurable vetoMassK0Short{"vetoMassK0Short", 0.01f, "veto for V0 compatible with K0s mass"}; @@ -283,8 +283,8 @@ struct EbyeMaker { Configurable antidNsigmaTpcCutLow{"antidNsigmaTpcCutLow", -4.f, "TPC PID cut low"}; Configurable antidNsigmaTpcCutUp{"antidNsigmaTpcCutUp", 4.f, "TPC PID cut up"}; - Configurable antidTpcInnerParamMax{"antidTpcInnerParamMax", 0.f, "(temporary) tpc inner param cut"}; - Configurable antidTofMassMax{"antidTofMassMax", 0.3f, "(temporary) tof mass cut"}; + Configurable antidTpcInnerParamMax{"tpcInnerParamMax", 0.f, "(temporary) tpc inner param cut"}; + Configurable antidTofMassMax{"tofMassMax", 0.3f, "(temporary) tof mass cut"}; Configurable antipNsigmaTpcCutLow{"antipNsigmaTpcCutLow", -4.f, "TPC PID cut low"}; Configurable antipNsigmaTpcCutUp{"antipNsigmaTpcCutUp", 4.f, "TPC PID cut up"}; @@ -292,13 +292,13 @@ struct EbyeMaker { Configurable antipTofMassMax{"antipTofMassMax", 0.3f, "(temporary) tof mass cut"}; Configurable tofMassMaxQA{"tofMassMaxQA", 0.6f, "(temporary) tof mass cut (for QA histograms)"}; - Configurable v0settingDcaV0Dau{"v0settingDcaV0Dau", 0.5f, "DCA V0 Daughters"}; - Configurable v0settingDcaV0Pv{"v0settingDcaV0Pv", 1.f, "DCA V0 to Pv"}; - Configurable v0settingDcaDaughToPv{"v0settingDcaDaughToPv", 0.1f, "DCA Pos To PV"}; - Configurable v0settingCosPa{"v0settingCosPa", 0.99f, "V0 CosPA"}; - Configurable v0settingRadius{"v0settingRadius", 5.f, "v0radius"}; - Configurable v0settingLifetime{"v0settingLifetime", 40.f, "v0 lifetime cut"}; - Configurable v0settingNSigmaTpc{"v0settingNSigmaTpc", 4.f, "nsigmatpc"}; + Configurable v0settingDcaV0Dau{"v0setting_dcav0dau", 0.5f, "DCA V0 Daughters"}; + Configurable v0settingDcaV0Pv{"v0setting_dcav0pv", 1.f, "DCA V0 to Pv"}; + Configurable v0settingDcaDaughToPv{"v0setting_dcadaughtopv", 0.1f, "DCA Pos To PV"}; + Configurable v0settingCosPa{"v0setting_cospa", 0.99f, "V0 CosPA"}; + Configurable v0settingRadius{"v0setting_radius", 5.f, "v0radius"}; + Configurable v0settingLifetime{"v0setting_lifetime", 40.f, "v0 lifetime cut"}; + Configurable v0settingNSigmaTpc{"v0setting_nsigmatpc", 4.f, "nsigmatpc"}; Configurable lambdaMassCut{"lambdaMassCut", 0.02f, "maximum deviation from PDG mass (for QA histograms)"}; Configurable constDCASel{"constDCASel", true, "use DCA selections independent of pt"}; diff --git a/PWGLF/TableProducer/Nuspex/hypKfRecoTask.cxx b/PWGLF/TableProducer/Nuspex/hypKfRecoTask.cxx index 68e334f5766..b35e8ced9e5 100644 --- a/PWGLF/TableProducer/Nuspex/hypKfRecoTask.cxx +++ b/PWGLF/TableProducer/Nuspex/hypKfRecoTask.cxx @@ -13,36 +13,46 @@ /// \brief Hypernuclei rconstruction using KFParticle package /// \author Janik Ditzel and Michael Hartung -#include -#include -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" +#include "MetadataHelper.h" + +#include "PWGLF/DataModel/LFHypernucleiKfTables.h" + +#include "Common/Core/PID/TPCPIDResponse.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/trackUtilities.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Centrality.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/TableProducer/PID/pidTPCBase.h" + #include "CCDB/BasicCCDBManager.h" #include "CommonConstants/PhysicsConstants.h" -#include "Common/Core/PID/TPCPIDResponse.h" -#include "DataFormatsTPC/BetheBlochAleph.h" #include "DCAFitter/DCAFitterN.h" -#include "Common/DataModel/PIDResponse.h" -#include "PWGLF/DataModel/LFHypernucleiKfTables.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DataFormatsTPC/BetheBlochAleph.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/PID.h" +#include "ReconstructionDataFormats/Track.h" + #include "TRandom3.h" -#include "Common/DataModel/CollisionAssociationTables.h" + +#include +#include +#include +#include // KFParticle #ifndef HomogeneousField -#define HomogeneousField // o2-linter: disable=[name/macro] +#define HomogeneousField // o2-linter: disable=name/macro (Name is defined in KFParticle package) #endif #include "KFParticle.h" #include "KFPTrack.h" @@ -54,10 +64,11 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -using CollisionsFull = soa::Join; +using CollisionsFull = soa::Join; using CollisionsFullMC = soa::Join; -using TracksFull = soa::Join; +using TracksFull = soa::Join; +MetadataHelper metadataInfo; // Metadata helper //---------------------------------------------------------------------------------------------------------------- namespace @@ -148,7 +159,7 @@ static const std::vector cascadeNames{"4LLH->4LHe+pi", "4XHe->4LHe+ constexpr int cascadeEnabled[nCascades][1]{{0}, {0}, {0}, {0}, {0}, {0}}; constexpr int cascadePdgCodes[nCascades][1]{ {1020010040}, - {1120010040}, + {1120020040}, {0}, {0}, {0}, @@ -167,33 +178,32 @@ constexpr double preSelectionsCascades[nCascades][nSelCas]{ {0.00, 9.90, 0, 100, -1., 100., 10., 10.}, {0.00, 9.90, 0, 100, -1., 100., 10., 10.}, {0.00, 9.90, 0, 100, -1., 100., 10., 10.}}; - //---------------------------------------------------------------------------------------------------------------- struct DaughterParticle { TString name; int pdgCode, charge; double mass, resolution; - std::vector betheParams; + std::array betheParams; bool active; DaughterParticle(std::string name_, int pdgCode_, double mass_, int charge_, LabeledArray bethe) : name(name_), pdgCode(pdgCode_), charge(charge_), mass(mass_), active(false) { resolution = bethe.get(name, "resolution"); - betheParams.clear(); - for (unsigned int i = 0; i < 5; i++) - betheParams.push_back(bethe.get(name, i)); + for (unsigned int i = 0; i < betheParams.size(); i++) + betheParams[i] = bethe.get(name, i); } + int getCentralPIDIndex() { return getPIDIndex(pdgCode); } }; // struct DaughterParticle struct HyperNucleus { TString name; int pdgCode; - bool active; + bool active, savePrimary; std::vector daughters, daughterTrackSigns; - HyperNucleus(std::string name_, int pdgCode_, bool active_, std::vector daughters_, std::vector daughterTrackSigns_) : pdgCode(pdgCode_), active(active_) + HyperNucleus(std::string name_, int pdgCode_, bool active_, std::vector daughters_, std::vector daughterTrackSigns_) : pdgCode(pdgCode_), active(active_), savePrimary(active_) { init(name_, daughters_, daughterTrackSigns_); } - HyperNucleus(std::string name_, int pdgCode_, bool active_, int hypDaughter, std::vector daughters_, std::vector daughterTrackSigns_) : pdgCode(pdgCode_), active(active_) + HyperNucleus(std::string name_, int pdgCode_, bool active_, int hypDaughter, std::vector daughters_, std::vector daughterTrackSigns_) : pdgCode(pdgCode_), active(active_), savePrimary(active_) { daughters.push_back(hypDaughter); init(name_, daughters_, daughterTrackSigns_); @@ -213,16 +223,22 @@ struct HyperNucleus { struct DaughterKf { int64_t daughterTrackId; - int hypNucId; + int species, hypNucId; KFParticle daughterKfp; - float dcaToPv, dcaToPvXY, dcaToPvZ; - DaughterKf(int64_t daughterTrackId_, KFParticle daughterKfp_, std::vector vtx) : daughterTrackId(daughterTrackId_), hypNucId(-1), daughterKfp(daughterKfp_) + float dcaToPv, dcaToPvXY, dcaToPvZ, tpcNsigma, tpcNsigmaNLP, tpcNsigmaNHP; + bool active; + std::vector vtx; + DaughterKf(int species_, int64_t daughterTrackId_, std::vector vtx_, float tpcNsigma_, float tpcNsigmaNLP_, float tpcNsigmaNHP_) : daughterTrackId(daughterTrackId_), species(species_), hypNucId(-1), tpcNsigma(tpcNsigma_), tpcNsigmaNLP(tpcNsigmaNLP_), tpcNsigmaNHP(tpcNsigmaNHP_), vtx(vtx_) {} + DaughterKf(int species_, KFParticle daughterKfp_, int hypNucId_) : daughterTrackId(-999), species(species_), hypNucId(hypNucId_), daughterKfp(daughterKfp_), dcaToPv(-999), dcaToPvXY(-999), dcaToPvZ(-999) {} + void addKfp(KFParticle daughterKfp_) { + daughterKfp = daughterKfp_; dcaToPvXY = daughterKfp.GetDistanceFromVertexXY(&vtx[0]); dcaToPv = daughterKfp.GetDistanceFromVertex(&vtx[0]); dcaToPvZ = std::sqrt(dcaToPv * dcaToPv - dcaToPvXY * dcaToPvXY); } - DaughterKf(KFParticle daughterKfp_, int hypNucId_) : daughterTrackId(-999), hypNucId(hypNucId_), daughterKfp(daughterKfp_), dcaToPv(-999), dcaToPvXY(-999), dcaToPvZ(-999) {} + + bool isTrack() { return daughterTrackId >= 0; } }; // struct DaughterKf struct HyperNucCandidate { @@ -325,7 +341,7 @@ struct HyperNucCandidate { } void calcDcaToVtx(KFPVertex& vtx) { - if (devToPvXY != 999) + if (devToPvXY != 999) // o2-linter: disable=magic-number (To be checked) return; devToPvXY = kfp.GetDeviationFromVertexXY(vtx); dcaToPvXY = kfp.GetDistanceFromVertexXY(vtx); @@ -338,11 +354,23 @@ struct HyperNucCandidate { dcaToVtxZ = getDcaMotherToVtxZ(cand.recoSV); } float getSubDaughterMass(int d1, int d2) + { + return calcSubDaughterMass(daughters.at(d1)->daughterKfp, daughters.at(d2)->daughterKfp); + } + float getSubDaughterMassCascade(int d1, int d2) + { + if (!isCascade()) { + LOGF(warning, "Primary hypernucleus has no hypernucleus daughter!"); + return -999; + } + return calcSubDaughterMass(daughters.at(d1)->daughterKfp, hypNucDaughter->daughters.at(d2)->daughterKfp); + } + float calcSubDaughterMass(KFParticle d1, KFParticle d2) { KFParticle subDaughter; subDaughter.SetConstructMethod(2); - subDaughter.AddDaughter(daughters.at(d1)->daughterKfp); - subDaughter.AddDaughter(daughters.at(d2)->daughterKfp); + subDaughter.AddDaughter(d1); + subDaughter.AddDaughter(d2); subDaughter.TransportToDecayVertex(); return subDaughter.GetMass(); } @@ -363,6 +391,14 @@ struct IndexPairs { } return false; } + bool hasIndex(int64_t a) + { + for (const auto& pair : pairs) { + if (pair.first == a) + return true; + } + return false; + } }; // struct IndexPairs struct McCollInfo { @@ -419,6 +455,12 @@ struct HypKfRecoTask { Configurable> cfgPreSelectionsSecondaries{"cfgPreSelectionsSecondaries", {preSelectionsSecondaries[0], nHyperNuclei, nSelSec, hyperNucNames, preSelectionSecNames}, "selection criteria for secondary hypernuclei"}; Configurable> cfgPreSelectionsCascades{"cfgPreSelectionsCascades", {preSelectionsCascades[0], nCascades, nSelCas, cascadeNames, preSelectionCascadeNames}, "selection criteria for cascade hypernuclei"}; + // TPC PID Response + bool usePidResponse; + o2::pid::tpc::Response* response; + std::map metadata; + std::array betheParams; + // CCDB Service ccdb; Configurable bField{"bField", -999, "bz field, -999 is automatic"}; @@ -427,10 +469,10 @@ struct HypKfRecoTask { Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; - Configurable pidPath{"pidPath", "", "Path to the PID response object"}; + Configurable pidPath{"pidPath", "Analysis/PID/TPC/Response", "Path to the PID response object"}; + std::vector activePdgs; std::vector daughterParticles; - std::vector> foundDaughters; std::vector> foundDaughterKfs, hypNucDaughterKfs; std::vector> singleHyperNucCandidates, cascadeHyperNucCandidates; std::vector singleHyperNuclei, cascadeHyperNuclei; @@ -438,7 +480,7 @@ struct HypKfRecoTask { std::vector mcCollInfos; IndexPairs trackIndices, mcPartIndices; KFPVertex kfPrimVtx; - bool collHasCandidate, collHasMcTrueCandidate, collPassedEvSel, activeCascade; + bool collHasCandidate, collHasMcTrueCandidate, collPassedEvSel, activeCascade, isMC; int64_t mcCollTableIndex; int mRunNumber, occupancy; float dBz; @@ -447,6 +489,7 @@ struct HypKfRecoTask { void init(InitContext const&) { + isMC = false; mRunNumber = 0; dBz = 0; rand.SetSeed(0); @@ -456,18 +499,37 @@ struct HypKfRecoTask { ccdb->setLocalObjectValidityChecking(); ccdb->setFatalWhenNull(false); - for (int i = 0; i < nDaughterParticles; i++) { // create daughterparticles + usePidResponse = false; + for (unsigned int i = 0; i < nDaughterParticles; i++) { // create daughterparticles daughterParticles.push_back(DaughterParticle(particleNames.at(i), particlePdgCodes.at(i), particleMasses.at(i), particleCharge.at(i), cfgBetheBlochParams)); + if (cfgTrackPIDsettings->get(i, "useBBparams") == 2 || cfgTrackPIDsettings->get(i, "useBBparams") == 0) // o2-linter: disable=magic-number (To be checked) + usePidResponse = true; } + for (unsigned int i = 0; i < nHyperNuclei; i++) { // create hypernuclei - singleHyperNuclei.push_back(HyperNucleus(hyperNucNames.at(i), cfgHyperNucPdg->get(i, 0u), cfgHyperNucsActive->get(i, 0u), getDaughterVec(i, cfgHyperNucDaughters), getDaughterSignVec(i, cfgHyperNucSigns))); + auto active = cfgHyperNucsActive->get(i, 0u); + auto pdg = cfgHyperNucPdg->get(i, 0u); + singleHyperNuclei.push_back(HyperNucleus(hyperNucNames.at(i), pdg, active, getDaughterVec(i, cfgHyperNucDaughters), getDaughterSignVec(i, cfgHyperNucSigns))); + if (active) + activePdgs.push_back(pdg); } + activeCascade = false; for (unsigned int i = 0; i < nCascades; i++) { // create cascades - cascadeHyperNuclei.push_back(HyperNucleus(cascadeNames.at(i), cfgCascadesPdg->get(i, 0u), cfgCascadesActive->get(i, 0u), getHypDaughterVec(i, cfgCascadeHypDaughter), getDaughterVec(i, cfgCascadeDaughters), getDaughterSignVec(i, cfgCascadeSigns))); - if (cfgCascadesActive->get(i, 0u)) + auto active = cfgCascadesActive->get(i, 0u); + auto pdg = cfgCascadesPdg->get(i, 0u); + auto hypDaughter = getHypDaughterVec(i, cfgCascadeHypDaughter); + cascadeHyperNuclei.push_back(HyperNucleus(cascadeNames.at(i), pdg, active, hypDaughter, getDaughterVec(i, cfgCascadeDaughters), getDaughterSignVec(i, cfgCascadeSigns))); + if (active) { + activePdgs.push_back(pdg); + if (!singleHyperNuclei.at(hypDaughter).active) { + singleHyperNuclei.at(hypDaughter).active = true; + activePdgs.push_back(singleHyperNuclei.at(hypDaughter).pdgCode); + } activeCascade = true; + } } + // define histogram axes const AxisSpec axisMagField{10, -10., 10., "magnetic field"}; const AxisSpec axisNev{3, 0., 3., "Number of events"}; @@ -506,7 +568,7 @@ struct HypKfRecoTask { } //---------------------------------------------------------------------------------------------------------------- - void findDaughterParticles(aod::TrackAssoc const& tracksByColl, TracksFull const& tracks) + void findDaughterParticles(aod::TrackAssoc const& tracksByColl, TracksFull const& tracks, CollisionsFull::iterator const& coll) { // track loop, store daughter candidates in std::vector for (const auto& trackId : tracksByColl) { @@ -525,63 +587,69 @@ struct HypKfRecoTask { continue; if (track.itsChi2NCl() > cfgTrackPIDsettings->get(i, "maxITSchi2")) continue; - if (std::abs(getTPCnSigma(track, daughterParticles.at(i))) > cfgTrackPIDsettings->get(i, "maxTPCnSigma")) + if (getRigidity(track) < cfgTrackPIDsettings->get(i, "minRigidity") || getRigidity(track) > cfgTrackPIDsettings->get(i, "maxRigidity")) + continue; + float tpcNsigma = getTPCnSigma(track, coll, daughterParticles.at(i)); + if (std::abs(tpcNsigma) > cfgTrackPIDsettings->get(i, "maxTPCnSigma")) continue; filldedx(track, i); if (getMeanItsClsSize(track) < cfgTrackPIDsettings->get(i, "minITSclsSize")) continue; if (getMeanItsClsSize(track) > cfgTrackPIDsettings->get(i, "maxITSclsSize")) continue; - if (getRigidity(track) < cfgTrackPIDsettings->get(i, "minRigidity") || getRigidity(track) > cfgTrackPIDsettings->get(i, "maxRigidity")) - continue; if (cfgTrackPIDsettings->get(i, "TOFrequiredabove") >= 0 && getRigidity(track) > cfgTrackPIDsettings->get(i, "TOFrequiredabove") && (track.mass() < cfgTrackPIDsettings->get(i, "minTOFmass") || track.mass() > cfgTrackPIDsettings->get(i, "maxTOFmass"))) continue; - foundDaughters.at(i).push_back(track.globalIndex()); + float tpcNsigmaNHP = (i == kAlpha ? -999 : getTPCnSigma(track, coll, daughterParticles.at(i + 1))); + float tpcNsigmaNLP = (i == kPion ? 999 : getTPCnSigma(track, coll, daughterParticles.at(i - 1))); + foundDaughterKfs.at(i).push_back(DaughterKf(i, track.globalIndex(), primVtx, tpcNsigma, tpcNsigmaNLP, tpcNsigmaNHP)); } } // track loop } - //---------------------------------------------------------------------------------------------------------------- - void checkMCTrueTracks(aod::McTrackLabels const& trackLabels, aod::McParticles const&) + + void checkMCTrueTracks(aod::McTrackLabels const& trackLabels, aod::McParticles const&, TracksFull const& tracks, CollisionsFull::iterator const& coll) { - std::vector activePdgs; - std::vector*> hypNucVectors = {&singleHyperNuclei, &cascadeHyperNuclei}; - for (int vec = 0; vec < 2; vec++) { - for (size_t hyperNucIter = 0; hyperNucIter < hypNucVectors.at(vec)->size(); hyperNucIter++) { - HyperNucleus* hyperNuc = &(hypNucVectors.at(vec)->at(hyperNucIter)); - if (!hyperNuc->active) - continue; - activePdgs.push_back(std::abs(hyperNuc->pdgCode)); - } - } for (int i = 0; i < nDaughterParticles; i++) { - auto& daughterVec = foundDaughters.at(i); + auto& daughterVec = foundDaughterKfs.at(i); if (!daughterVec.size()) continue; for (auto it = daughterVec.end() - 1; it >= daughterVec.begin(); it--) { - const auto& mcLab = trackLabels.rawIteratorAt(*it); + const auto& mcLab = trackLabels.rawIteratorAt(it->daughterTrackId); if (!mcLab.has_mcParticle()) { daughterVec.erase(it); continue; } const auto& mcPart = mcLab.mcParticle_as(); - if (std::abs(mcPart.pdgCode()) != daughterParticles.at(i).pdgCode) { - daughterVec.erase(it); - continue; - } - if (!mcPart.has_mothers()) { - daughterVec.erase(it); - continue; - } - bool isDaughter = false; - for (const auto& mother : mcPart.mothers_as()) { - if (std::find(activePdgs.begin(), activePdgs.end(), std::abs(mother.pdgCode())) != activePdgs.end()) { - isDaughter = true; + if (cfgSaveOnlyMcTrue) { + if (std::abs(mcPart.pdgCode()) != daughterParticles.at(i).pdgCode) { + daughterVec.erase(it); + continue; + } + if (!mcPart.has_mothers()) { + daughterVec.erase(it); + continue; + } + bool isDaughter = false; + for (const auto& mother : mcPart.mothers_as()) { + if (std::find(activePdgs.begin(), activePdgs.end(), std::abs(mother.pdgCode())) != activePdgs.end()) { + isDaughter = true; + } + } + if (!isDaughter) { + daughterVec.erase(it); + continue; } } - if (!isDaughter) { - daughterVec.erase(it); - continue; + if (cfgTrackPIDsettings->get(i, "useBBparams") == 0) { + const auto& trk = tracks.rawIteratorAt(it->daughterTrackId); + const auto tpcNsigmaMC = getTPCnSigmaMC(trk, coll, daughterParticles.at(i), daughterParticles.at(i)); + if (std::abs(tpcNsigmaMC) <= cfgTrackPIDsettings->get(i, "maxTPCnSigma")) { + it->tpcNsigma = tpcNsigmaMC; + it->tpcNsigmaNHP = (i == kAlpha ? -999 : getTPCnSigmaMC(trk, coll, daughterParticles.at(i), daughterParticles.at(i + 1))); + it->tpcNsigmaNLP = (i == kPion ? 999 : getTPCnSigmaMC(trk, coll, daughterParticles.at(i), daughterParticles.at(i - 1))); + } else { + daughterVec.erase(it); + } } } } @@ -589,33 +657,42 @@ struct HypKfRecoTask { //---------------------------------------------------------------------------------------------------------------- void createKFDaughters(TracksFull const& tracks) { + for (size_t daughterCount = 0; daughterCount < daughterParticles.size(); daughterCount++) { + daughterParticles.at(daughterCount).active = false; + } std::vector*> hypNucVectors = {&singleHyperNuclei, &cascadeHyperNuclei}; - for (size_t vec = 0; vec < 2; vec++) { + bool singleHypNucActive = false; + for (size_t vec = 0; vec < hypNucVectors.size(); vec++) { for (const auto& hyperNuc : *(hypNucVectors.at(vec))) { if (!hyperNuc.active) continue; for (size_t i = vec; i < hyperNuc.daughters.size(); i++) { - if (foundDaughters.at(hyperNuc.daughters.at(i)).size() > 0) + if (foundDaughterKfs.at(hyperNuc.daughters.at(i)).size() > 0) daughterParticles.at(hyperNuc.daughters.at(i)).active = true; else break; + if (i == hyperNuc.daughters.size() - 1) + singleHypNucActive = true; } } + if (!singleHypNucActive) + break; } + for (size_t daughterCount = 0; daughterCount < daughterParticles.size(); daughterCount++) { const auto& daughterParticle = daughterParticles.at(daughterCount); - if (!daughterParticle.active) + if (!daughterParticle.active) { + foundDaughterKfs.at(daughterCount).clear(); continue; + } const auto& daughterMass = daughterParticle.mass; const auto& daughterCharge = daughterParticle.charge; - for (const auto& daughterId : foundDaughters.at(daughterCount)) { - const auto& daughterTrack = tracks.rawIteratorAt(daughterId); - DaughterKf daughter(daughterId, createKFParticle(daughterTrack, daughterMass, daughterCharge), primVtx); - if (std::abs(daughter.dcaToPvXY) < cfgTrackPIDsettings->get(daughterCount, "minDcaToPvXY")) - continue; - if (std::abs(daughter.dcaToPvZ) < cfgTrackPIDsettings->get(daughterCount, "minDcaToPvZ")) - continue; - foundDaughterKfs.at(daughterCount).push_back(daughter); + auto& daughterVec = foundDaughterKfs.at(daughterCount); + for (auto it = daughterVec.end() - 1; it >= daughterVec.begin(); it--) { + const auto& daughterTrack = tracks.rawIteratorAt(it->daughterTrackId); + it->addKfp(createKFParticle(daughterTrack, daughterMass, daughterCharge)); + if (std::abs(it->dcaToPvXY) < cfgTrackPIDsettings->get(daughterCount, "minDcaToPvXY") || std::abs(it->dcaToPvZ) < cfgTrackPIDsettings->get(daughterCount, "minDcaToPvZ")) + daughterVec.erase(it); } } } @@ -685,7 +762,7 @@ struct HypKfRecoTask { candidate.calcDcaToVtx(kfPrimVtx); candidate.isSecondaryCandidate = true; } - if (candidate.isPrimaryCandidate || candidate.isSecondaryCandidate) + if ((candidate.isPrimaryCandidate && hyperNuc->savePrimary) || (candidate.isSecondaryCandidate && activeCascade)) singleHyperNucCandidates.at(hyperNucIter).push_back(candidate); } } @@ -711,7 +788,7 @@ struct HypKfRecoTask { for (int64_t i = 0; i < static_cast(nHypNucDaughters); i++) { if (singleHyperNucCandidates.at(hyperNuc->daughters.at(0)).at(i).isSecondaryCandidate) { auto hypNucDaughter = &(singleHyperNucCandidates.at(hyperNuc->daughters.at(0)).at(i)); - hypNucDaughterKfs.at(hyperNucIter).push_back(DaughterKf(hypNucDaughter->kfp, i)); + hypNucDaughterKfs.at(hyperNucIter).push_back(DaughterKf(hyperNuc->daughters.at(0), hypNucDaughter->kfp, i)); } } int nCombinations = hypNucDaughterKfs.at(hyperNucIter).size(); @@ -796,9 +873,8 @@ struct HypKfRecoTask { HyperNucleus* hyperNuc = &(hypNucVectors.at(vec)->at(hyperNucIter)); if (!hyperNuc->active) continue; - for (auto& hypCand : candidateVector->at(hyperNucIter)) { // o2-linter: disable=[const-ref-in-for-loop] + for (auto& hypCand : candidateVector->at(hyperNucIter)) { // o2-linter: disable=[const-ref-in-for-loop] (Object is non const and modified in loop) std::vector motherIds; - int daughterCount = 0; if (hypCand.isCascade()) { if (!hypCand.hypNucDaughter->mcTrue) continue; @@ -811,16 +887,15 @@ struct HypKfRecoTask { break; } } - daughterCount++; } for (const auto& daughter : hypCand.daughters) { - if (daughter->daughterTrackId < 0) + if (!daughter->isTrack()) continue; const auto& mcLab = trackLabels.rawIteratorAt(daughter->daughterTrackId); if (!mcLab.has_mcParticle()) continue; const auto& mcPart = mcLab.mcParticle_as(); - if (std::abs(mcPart.pdgCode()) != daughterParticles.at(hyperNuc->daughters.at(daughterCount++)).pdgCode) + if (std::abs(mcPart.pdgCode()) != daughterParticles.at(daughter->species).pdgCode) continue; if (!mcPart.has_mothers()) continue; @@ -840,6 +915,8 @@ struct HypKfRecoTask { for (auto iter = motherIds.begin(); iter != motherIds.end() - 1; iter++) if (*iter != *(iter + 1)) hypCand.mcTrue = false; + if (!mcPartIndices.hasIndex(motherIds.front())) + hypCand.mcTrue = false; if (hypCand.mcTrue) { hypCand.mcParticleId = motherIds.front(); collHasMcTrueCandidate = true; @@ -858,49 +935,39 @@ struct HypKfRecoTask { outputCollisionTable( collPassedEvSel, mcCollTableIndex, primVtx.at(0), primVtx.at(1), primVtx.at(2), - cents.at(0), cents.at(1), cents.at(2), occupancy); + cents.at(0), cents.at(1), cents.at(2), occupancy, mRunNumber); std::vector*> hypNucVectors = {&singleHyperNuclei, &cascadeHyperNuclei}; std::vector>*> candidateVectors = {&singleHyperNucCandidates, &cascadeHyperNucCandidates}; - for (int vec = 0; vec < 2; vec++) { + for (unsigned int vec = 0; vec < candidateVectors.size(); vec++) { auto candidateVector = candidateVectors.at(vec); for (size_t hyperNucIter = 0; hyperNucIter < hypNucVectors.at(vec)->size(); hyperNucIter++) { HyperNucleus* hyperNuc = &(hypNucVectors.at(vec)->at(hyperNucIter)); if (!hyperNuc->active) continue; - for (auto& hypCand : candidateVector->at(hyperNucIter)) { // o2-linter: disable=[const-ref-in-for-loop] + for (auto& hypCand : candidateVector->at(hyperNucIter)) { // o2-linter: disable=const-ref-in-for-loop (Object is non const and modified in loop) if (!hypCand.isPrimaryCandidate && !hypCand.isUsedSecondary && !hypCand.isCascade()) continue; if (saveOnlyMcTrue && !hypCand.mcTrue && !hypCand.isCascade()) continue; hInvMass[vec * nHyperNuclei + hyperNucIter]->Fill(hypCand.mass); std::vector vecDaugtherTracks, vecAddons, vecSubDaughters; - int daughterCount = 0; for (const auto& daughter : hypCand.daughters) { - const auto& daughterTrackId = daughter->daughterTrackId; - if (daughterTrackId < 0) + if (!daughter->isTrack()) continue; + const auto& daughterTrackId = daughter->daughterTrackId; int trackTableId; if (!trackIndices.getIndex(daughterTrackId, trackTableId)) { - auto daught = hyperNuc->daughters.at(daughterCount); const auto& track = tracks.rawIteratorAt(daughterTrackId); outputTrackTable( - hyperNuc->daughters.at(daughterCount) * track.sign(), - track.pt(), track.eta(), track.phi(), - daughter->dcaToPvXY, daughter->dcaToPvZ, - track.tpcNClsFound(), track.tpcChi2NCl(), - track.itsClusterSizes(), track.itsChi2NCl(), - getRigidity(track), track.tpcSignal(), getTPCnSigma(track, daughterParticles.at(daught)), - daught == kAlpha ? -999 : getTPCnSigma(track, daughterParticles.at(daught + 1)), - daught == kPion ? 999 : getTPCnSigma(track, daughterParticles.at(daught - 1)), - track.mass(), - track.isPVContributor()); + daughter->species * track.sign(), track.pt(), track.eta(), track.phi(), daughter->dcaToPvXY, daughter->dcaToPvZ, track.tpcNClsFound(), track.tpcChi2NCl(), + track.itsClusterSizes(), track.itsChi2NCl(), getRigidity(track), track.tpcSignal(), daughter->tpcNsigma, daughter->tpcNsigmaNHP, daughter->tpcNsigmaNLP, + track.mass(), track.isPVContributor()); trackTableId = outputTrackTable.lastIndex(); trackIndices.add(daughterTrackId, trackTableId); } vecDaugtherTracks.push_back(trackTableId); - daughterCount++; } for (int i = 0; i < hypCand.getNdaughters(); i++) { std::vector& posMom = hypCand.daughterPosMoms.at(i); @@ -908,7 +975,7 @@ struct HypKfRecoTask { posMom.at(0), posMom.at(1), posMom.at(2), posMom.at(3), posMom.at(4), posMom.at(5)); vecAddons.push_back(outputDaughterAddonTable.lastIndex()); } - if (hypCand.getNdaughters() > 2) { + if (hypCand.getNdaughters() > 2) { // o2-linter: disable=magic-number (To be checked) for (int i = 0; i < hypCand.getNdaughters(); i++) { for (int j = i + 1; j < hypCand.getNdaughters(); j++) { outputSubDaughterTable(hypCand.getSubDaughterMass(i, j)); @@ -916,18 +983,23 @@ struct HypKfRecoTask { } } } + if (hypCand.isCascade()) { + for (int i = 1; i < hypCand.getNdaughters(); i++) { + for (int j = 0; j < hypCand.hypNucDaughter->getNdaughters(); j++) { + outputSubDaughterTable(hypCand.getSubDaughterMassCascade(i, j)); + vecSubDaughters.push_back(outputSubDaughterTable.lastIndex()); + } + } + } hypCand.kfp.TransportToDecayVertex(); int mcPartTableId; outputHypNucTable( mcPartIndices.getIndex(hypCand.mcParticleId, mcPartTableId) ? mcPartTableId : -1, outputCollisionTable.lastIndex(), vecDaugtherTracks, vecAddons, hypCand.getDaughterTableId(), vecSubDaughters, - (vec * nHyperNuclei + hyperNucIter + 1) * hypCand.getSign(), - hypCand.isPrimaryCandidate, hypCand.mass, - hypCand.px, hypCand.py, hypCand.pz, - hypCand.dcaToPvXY, hypCand.dcaToPvZ, hypCand.devToPvXY, - hypCand.dcaToVtxXY, hypCand.dcaToVtxZ, hypCand.chi2, - hypCand.recoSV.at(0), hypCand.recoSV.at(1), hypCand.recoSV.at(2)); + (vec * nHyperNuclei + hyperNucIter + 1) * hypCand.getSign(), hypCand.isPrimaryCandidate, hypCand.mass, + hypCand.px, hypCand.py, hypCand.pz, hypCand.dcaToPvXY, hypCand.dcaToPvZ, hypCand.devToPvXY, + hypCand.dcaToVtxXY, hypCand.dcaToVtxZ, hypCand.chi2, hypCand.recoSV.at(0), hypCand.recoSV.at(1), hypCand.recoSV.at(2)); hypCand.tableId = outputHypNucTable.lastIndex(); } } @@ -935,21 +1007,23 @@ struct HypKfRecoTask { } //---------------------------------------------------------------------------------------------------------------- - void processMC(CollisionsFullMC const& collisions, aod::McCollisions const& mcColls, TracksFull const& tracks, aod::BCsWithTimestamps const&, aod::McParticles const& particlesMC, aod::McTrackLabels const& trackLabelsMC, aod::McCollisionLabels const& collLabels, aod::TrackAssoc const& tracksColl) + void processMC(CollisionsFullMC const& collisions, aod::McCollisions const& mcColls, TracksFull const& tracks, aod::BCsWithTimestamps const&, aod::McParticles const& particlesMC, aod::McTrackLabels const& trackLabelsMC, aod::McCollisionLabels const& collLabels, aod::TrackAssoc const& tracksColl, CollisionsFull const& colls) { - + isMC = true; mcCollInfos.clear(); mcCollInfos.resize(mcColls.size()); mcPartIndices.clear(); for (const auto& collision : collisions) { if (!collision.has_mcCollision()) continue; - if (collision.sel8() && std::abs(collision.posZ()) < 10) + if (collision.sel8() && std::abs(collision.posZ()) < 10) // o2-linter: disable=magic-number (To be checked) mcCollInfos.at(collision.mcCollisionId()).passedEvSel = true; } std::vector*> hypNucVectors = {&singleHyperNuclei, &cascadeHyperNuclei}; for (const auto& mcPart : particlesMC) { - for (int vec = 0; vec < 2; vec++) { + if (!mcCollInfos.at(mcPart.mcCollisionId()).passedEvSel) + continue; + for (unsigned int vec = 0; vec < hypNucVectors.size(); vec++) { for (size_t hyperNucIter = 0; hyperNucIter < hypNucVectors.at(vec)->size(); hyperNucIter++) { HyperNucleus* hyperNuc = &(hypNucVectors.at(vec)->at(hyperNucIter)); if (!hyperNuc->active) @@ -958,11 +1032,7 @@ struct HypKfRecoTask { continue; bool isDecayMode = false; float svx, svy, svz; - int daughterPdg; - if (vec == 0) - daughterPdg = daughterParticles.at(hyperNuc->daughters.at(0)).pdgCode; - else - daughterPdg = singleHyperNuclei.at(hyperNuc->daughters.at(0)).pdgCode; + int daughterPdg = vec ? singleHyperNuclei.at(hyperNuc->daughters.at(0)).pdgCode : daughterParticles.at(hyperNuc->daughters.at(0)).pdgCode; for (const auto& mcDaught : mcPart.daughters_as()) { if (std::abs(mcDaught.pdgCode()) == daughterPdg) { isDecayMode = true; @@ -999,11 +1069,14 @@ struct HypKfRecoTask { auto bc = collision.bc_as(); initCCDB(bc); initCollision(collision); + if (!collision.has_mcCollision() || !mcCollInfos.at(collision.mcCollisionId()).passedEvSel) + continue; + const uint64_t collIdx = collision.globalIndex(); auto tracksByColl = tracksColl.sliceBy(perCollision, collIdx); - findDaughterParticles(tracksByColl, tracks); - if (cfgSaveOnlyMcTrue) - checkMCTrueTracks(trackLabelsMC, particlesMC); + findDaughterParticles(tracksByColl, tracks, colls.rawIteratorAt(collision.globalIndex())); + if (cfgSaveOnlyMcTrue || usePidResponse) + checkMCTrueTracks(trackLabelsMC, particlesMC, tracks, colls.rawIteratorAt(collision.globalIndex())); createKFDaughters(tracks); createKFHypernuclei(tracks); createMCinfo(trackLabelsMC, collLabels, particlesMC, mcColls); @@ -1015,16 +1088,13 @@ struct HypKfRecoTask { if (cfgSaveOnlyMcTrue && !collHasMcTrueCandidate) continue; - mcCollTableIndex = -1; - if (collision.has_mcCollision()) { - mcCollTableIndex = mcCollInfos.at(collision.mcCollisionId()).tableIndex; - if (mcCollTableIndex < 0) { - outputMcCollisionTable( - mcCollInfos.at(collision.mcCollisionId()).passedEvSel, - collision.mcCollision().posX(), collision.mcCollision().posY(), collision.mcCollision().posZ()); - mcCollTableIndex = outputMcCollisionTable.lastIndex(); - mcCollInfos.at(collision.mcCollisionId()).tableIndex = mcCollTableIndex; - } + mcCollTableIndex = mcCollInfos.at(collision.mcCollisionId()).tableIndex; + if (mcCollTableIndex < 0) { + outputMcCollisionTable( + mcCollInfos.at(collision.mcCollisionId()).passedEvSel, + collision.mcCollision().posX(), collision.mcCollision().posY(), collision.mcCollision().posZ()); + mcCollTableIndex = outputMcCollisionTable.lastIndex(); + mcCollInfos.at(collision.mcCollisionId()).tableIndex = mcCollTableIndex; } fillTree(tracks, cfgSaveOnlyMcTrue); } @@ -1042,7 +1112,7 @@ struct HypKfRecoTask { continue; const uint64_t collIdx = collision.globalIndex(); auto tracksByColl = tracksColl.sliceBy(perCollision, collIdx); - findDaughterParticles(tracksByColl, tracks); + findDaughterParticles(tracksByColl, tracks, collision); createKFDaughters(tracks); createKFHypernuclei(tracks); createKFCascades(tracks); @@ -1065,7 +1135,7 @@ struct HypKfRecoTask { o2::parameters::GRPMagField* grpmag = 0x0; if (grpo) { o2::base::Propagator::initFieldFromGRP(grpo); - if (bField < -990) { + if (bField < -990) { // o2-linter: disable=magic-number (To be checked) // Fetch magnetic field from ccdb for current collision dBz = grpo->getNominalL3Field(); LOG(info) << "Retrieved GRP for timestamp " << run3grpTimestamp << " with magnetic field of " << dBz << " kZG"; @@ -1078,7 +1148,7 @@ struct HypKfRecoTask { LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grpTimestamp; } o2::base::Propagator::initFieldFromGRP(grpmag); - if (bField < -990) { + if (bField < -990) { // o2-linter: disable=magic-number (To be checked) // Fetch magnetic field from ccdb for current collision dBz = std::lround(5.f * grpmag->getL3Current() / 30000.f); LOG(info) << "Retrieved GRP for timestamp " << run3grpTimestamp << " with magnetic field of " << dBz << " kZG"; @@ -1088,13 +1158,35 @@ struct HypKfRecoTask { } mRunNumber = bc.runNumber(); KFParticle::SetField(dBz); + + // PID response + if (!usePidResponse) + return; + if (metadataInfo.isFullyDefined()) { + metadata["RecoPassName"] = metadataInfo.get("RecoPassName"); + LOGP(info, "Automatically setting reco pass for TPC Response to {} from AO2D", metadata["RecoPassName"]); + } else { + LOG(info) << "Setting reco pass for TPC response to default name"; + metadata["RecoPassName"] = "apass5"; + } + const std::string path = pidPath.value; + ccdb->setTimestamp(run3grpTimestamp); + response = ccdb->getSpecific(path, run3grpTimestamp, metadata); + if (!response) { + LOGF(warning, "Unable to find TPC parametrisation for specified pass name - falling back to latest object"); + response = ccdb->getForTimeStamp(path, run3grpTimestamp); + if (!response) { + LOGF(fatal, "Unable to find any TPC object corresponding to timestamp {}!", run3grpTimestamp); + } + } + LOG(info) << "Successfully retrieved TPC PID object from CCDB for timestamp " << run3grpTimestamp << ", recoPass " << metadata["RecoPassName"]; + response->PrintAll(); + betheParams = response->GetBetheBlochParams(); } //---------------------------------------------------------------------------------------------------------------- template void initCollision(const T& collision) { - foundDaughters.clear(); - foundDaughters.resize(nDaughterParticles); foundDaughterKfs.clear(); foundDaughterKfs.resize(nDaughterParticles); hypNucDaughterKfs.clear(); @@ -1108,7 +1200,7 @@ struct HypKfRecoTask { collHasMcTrueCandidate = false; histos.fill(HIST("histMagField"), dBz); histos.fill(HIST("histNev"), 0.5); - collPassedEvSel = collision.sel8() && std::abs(collision.posZ()) < 10; + collPassedEvSel = collision.sel8() && std::abs(collision.posZ()) < 10; // o2-linter: disable=magic-number (To be checked) occupancy = collision.trackOccupancyInTimeRange(); if (collPassedEvSel) { histos.fill(HIST("histNev"), 1.5); @@ -1129,45 +1221,63 @@ struct HypKfRecoTask { { const float rigidity = getRigidity(track); hDeDx[2 * species]->Fill(track.sign() * rigidity, track.tpcSignal()); - if (track.tpcNClsFound() < 100 || track.itsNCls() < 2) + if (track.tpcNClsFound() < 100 || track.itsNCls() < 2) // o2-linter: disable=magic-number (To be checked) return; hDeDx[2 * species + 1]->Fill(track.sign() * rigidity, track.tpcSignal()); } //---------------------------------------------------------------------------------------------------------------- - template - float getTPCnSigma(T const& track, DaughterParticle const& particle) + template + float getTPCnSigma(T const& track, C const& coll, DaughterParticle& particle) { const float rigidity = getRigidity(track); if (!track.hasTPC()) return -999; + float mMip = 1, chargeFactor = 1; + float* parBB; - if (particle.name == "pion" && cfgTrackPIDsettings->get("pion", "useBBparams") < 1) - return cfgTrackPIDsettings->get("pion", "useBBparams") == 0 ? track.tpcNSigmaPi() : 0; - if (particle.name == "proton" && cfgTrackPIDsettings->get("proton", "useBBparams") < 1) - return cfgTrackPIDsettings->get("proton", "useBBparams") == 0 ? track.tpcNSigmaPr() : 0; - if (particle.name == "deuteron" && cfgTrackPIDsettings->get("deuteron", "useBBparams") < 1) - return cfgTrackPIDsettings->get("deuteron", "useBBparams") == 0 ? track.tpcNSigmaDe() : 0; - if (particle.name == "triton" && cfgTrackPIDsettings->get("triton", "useBBparams") < 1) - return cfgTrackPIDsettings->get("triton", "useBBparams") == 0 ? track.tpcNSigmaTr() : 0; - if (particle.name == "helion" && cfgTrackPIDsettings->get("helion", "useBBparams") < 1) - return cfgTrackPIDsettings->get("helion", "useBBparams") == 0 ? track.tpcNSigmaHe() : 0; - if (particle.name == "alpha" && cfgTrackPIDsettings->get("alpha", "useBBparams") < 1) - return cfgTrackPIDsettings->get("alpha", "useBBparams") == 0 ? track.tpcNSigmaAl() : 0; - - double expBethe{tpc::BetheBlochAleph(static_cast(particle.charge * rigidity / particle.mass), particle.betheParams[0], particle.betheParams[1], particle.betheParams[2], particle.betheParams[3], particle.betheParams[4])}; + switch (static_cast(cfgTrackPIDsettings->get(particle.name, "useBBparams"))) { + case -1: + return 0; + case 0: + return isMC ? 0 : response->GetNumberOfSigma(coll, track, particle.getCentralPIDIndex()); + case 1: + parBB = &particle.betheParams[0]; + break; + case 2: + mMip = response->GetMIP(); + chargeFactor = std::pow(particle.charge, response->GetChargeFactor()); + parBB = &betheParams[0]; + break; + default: + return -999; + } + double expBethe{mMip * chargeFactor * o2::tpc::BetheBlochAleph(static_cast(particle.charge * rigidity / particle.mass), parBB[0], parBB[1], parBB[2], parBB[3], parBB[4])}; double expSigma{expBethe * particle.resolution}; float sigmaTPC = static_cast((track.tpcSignal() - expBethe) / expSigma); return sigmaTPC; } //---------------------------------------------------------------------------------------------------------------- + + template + float getTPCnSigmaMC(T const& trk, C const& coll, DaughterParticle& particle1, DaughterParticle& particle2) + { + const float pidval1 = particle1.getCentralPIDIndex(); + const float pidval2 = particle2.getCentralPIDIndex(); + const auto expSignal = response->GetExpectedSignal(trk, pidval2); + const auto expSigma = response->GetExpectedSigma(coll, trk, pidval2); + const auto mcTunedTPCSignal = gRandom->Gaus(expSignal, expSigma); + return response->GetNumberOfSigmaMCTuned(coll, trk, pidval1, mcTunedTPCSignal); + } + //---------------------------------------------------------------------------------------------------------------- + template float getMeanItsClsSize(T const& track) { int sum = 0, n = 0; - for (int i = 0; i < 8; i++) { - sum += (track.itsClusterSizes() >> (4 * i) & 15); - if (track.itsClusterSizes() >> (4 * i) & 15) + for (int i = 0; i < 0x08; i++) { + sum += (track.itsClusterSizes() >> (0x04 * i) & 0x0f); + if (track.itsClusterSizes() >> (0x04 * i) & 0x0f) n++; } return n > 0 ? static_cast(sum) / n : 0.f; @@ -1192,7 +1302,7 @@ struct HypKfRecoTask { trackparCov.getXYZGlo(fP); trackparCov.getPxPyPzGlo(fM); float fPM[6]; - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 0x03; i++) { fPM[i] = fP[i]; fPM[i + 3] = fM[i] * std::abs(charge); } @@ -1228,7 +1338,7 @@ struct HypKfRecoTask { std::vector getDaughterVec(unsigned int hypNuc, LabeledArray cfg) { std::vector vec; - for (unsigned int i = 0; i < 4; i++) { + for (unsigned int i = 0; i < 0x04; i++) { std::string daughter = cfg.get(hypNuc, i); if (std::find(particleNames.begin(), particleNames.end(), daughter) == particleNames.end()) break; @@ -1241,7 +1351,7 @@ struct HypKfRecoTask { std::vector getDaughterSignVec(unsigned int hypNuc, LabeledArray cfg) { std::vector vec; - for (unsigned int i = 0; i < 4; i++) { + for (unsigned int i = 0; i < 0x04; i++) { std::string sign = cfg.get(hypNuc, i); if (sign != "+" && sign != "-") break; @@ -1256,6 +1366,7 @@ struct HypKfRecoTask { //---------------------------------------------------------------------------------------------------------------- WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { + metadataInfo.initMetadata(cfgc); // Parse AO2D metadata return WorkflowSpec{ adaptAnalysisTask(cfgc)}; } diff --git a/PWGLF/TableProducer/Nuspex/hypKfTreeCreator.cxx b/PWGLF/TableProducer/Nuspex/hypKfTreeCreator.cxx index da8316e3c8d..246a67f57d6 100644 --- a/PWGLF/TableProducer/Nuspex/hypKfTreeCreator.cxx +++ b/PWGLF/TableProducer/Nuspex/hypKfTreeCreator.cxx @@ -56,15 +56,15 @@ struct TrackProperties { }; struct HyperNucleus { - HyperNucleus() : pdgCode(0), isReconstructed(0), globalIndex(0), species(0), isPrimaryCandidate(0), isMatter(0), passedEvSel(0), isMatterMC(0), passedEvSelMC(0), isPhysicalPrimary(0), collisionMcTrue(0), mass(0), y(0), pt(0), ct(0), yGen(0), ptGen(0), ctGen(0), cpaPvGen(0), cpaPv(0), cpaSv(0), maxDcaTracks(0), maxDcaTracksSv(0), dcaToPvXY(0), dcaToPvZ(0), dcaToVtxXY(0), dcaToVtxZ(0), devToPvXY(0), chi2(0), pvx(0), pvy(0), pvz(0), svx(0), svy(0), svz(0), px(0), py(0), pz(0), pvxGen(0), pvyGen(0), pvzGen(0), svxGen(0), svyGen(0), svzGen(0), pxGen(0), pyGen(0), pzGen(0), nSingleDaughters(0), nCascadeDaughters(0), mcTrue(0), mcTrueVtx(0), mcPhysicalPrimary(0), hypNucDaughter(0) {} + HyperNucleus() : pdgCode(0), isReconstructed(0), globalIndex(0), species(0), speciesMC(0), isPrimaryCandidate(0), isMatter(0), isCascade(0), isCascadeMC(0), passedEvSel(0), isMatterMC(0), passedEvSelMC(0), isPhysicalPrimary(0), collisionMcTrue(0), mass(0), y(0), pt(0), ct(0), yGen(0), ptGen(0), ctGen(0), cpaPvGen(0), cpaPv(0), cpaSv(0), maxDcaTracks(0), maxDcaTracksSv(0), dcaToPvXY(0), dcaToPvZ(0), dcaToVtxXY(0), dcaToVtxZ(0), devToPvXY(0), chi2(0), pvx(0), pvy(0), pvz(0), svx(0), svy(0), svz(0), px(0), py(0), pz(0), pvxGen(0), pvyGen(0), pvzGen(0), svxGen(0), svyGen(0), svzGen(0), pxGen(0), pyGen(0), pzGen(0), nSingleDaughters(0), nCascadeDaughters(0), mcTrue(0), mcTrueVtx(0), mcPhysicalPrimary(0), hypNucDaughter(0) {} int pdgCode, isReconstructed, globalIndex; - uint8_t species; - bool isPrimaryCandidate, isMatter, passedEvSel, isMatterMC, passedEvSelMC, isPhysicalPrimary, collisionMcTrue; + uint8_t species, speciesMC; + bool isPrimaryCandidate, isMatter, isCascade, isCascadeMC, passedEvSel, isMatterMC, passedEvSelMC, isPhysicalPrimary, collisionMcTrue; float mass, y, pt, ct, yGen, ptGen, ctGen, cpaPvGen, cpaPv, cpaSv, maxDcaTracks, maxDcaTracksSv; float dcaToPvXY, dcaToPvZ, dcaToVtxXY, dcaToVtxZ, devToPvXY, chi2; float pvx, pvy, pvz, svx, svy, svz, px, py, pz; float pvxGen, pvyGen, pvzGen, svxGen, svyGen, svzGen, pxGen, pyGen, pzGen; - int nSingleDaughters, nCascadeDaughters, cent, occu; + int nSingleDaughters, nCascadeDaughters, cent, occu, runNumber; bool mcTrue, mcTrueVtx, mcPhysicalPrimary; std::vector daughterTracks; std::vector subDaughterMassVec; @@ -110,10 +110,12 @@ DECLARE_SOA_COLUMN(TvyGen, tvyGen, float); DECLARE_SOA_COLUMN(TvzGen, tvzGen, float); DECLARE_SOA_COLUMN(Centrality, centrality, int); DECLARE_SOA_COLUMN(Occupancy, occupancy, int); +DECLARE_SOA_COLUMN(RunNumber, runNumber, int); DECLARE_SOA_COLUMN(PassedEvSelMC, passedEvSelMC, bool); +DECLARE_SOA_COLUMN(SpeciesMC, speciesMC, int8_t); //! DECLARE_SOA_COLUMN(IsMatter, isMatter, bool); DECLARE_SOA_COLUMN(IsMatterGen, isMatterGen, bool); -DECLARE_SOA_COLUMN(IsReconstructed, isReconstructed, bool); +DECLARE_SOA_COLUMN(IsReconstructed, isReconstructed, int); DECLARE_SOA_COLUMN(CollMcTrue, collMcTrue, bool); DECLARE_SOA_COLUMN(D1X, d1X, float); DECLARE_SOA_COLUMN(D1Y, d1Y, float); @@ -263,15 +265,18 @@ DECLARE_SOA_COLUMN(Sd3IsPvContributor, sd3IsPvContributor, bool); DECLARE_SOA_COLUMN(Sd1sd2Mass, sd1sd2Mass, float); DECLARE_SOA_COLUMN(Sd1sd3Mass, sd1sd3Mass, float); DECLARE_SOA_COLUMN(Sd2sd3Mass, sd2sd3Mass, float); +DECLARE_SOA_COLUMN(D1sd1Mass, d1sd1Mass, float); +DECLARE_SOA_COLUMN(D1sd2Mass, d1sd2Mass, float); +DECLARE_SOA_COLUMN(D1sd3Mass, d1sd3Mass, float); } // namespace hypkftree -#define HYPKFGENBASE mcparticle::PdgCode, hypkftree::IsMatterGen, hypkftree::IsReconstructed, hykfmc::IsPhysicalPrimary, hypkftree::PassedEvSelMC, hypkftree::YGen, hypkftree::PtGen, hypkftree::CtGen +#define HYPKFGENBASE hypkftree::SpeciesMC, mcparticle::PdgCode, hypkftree::IsMatterGen, hypkftree::IsReconstructed, hykfmc::IsPhysicalPrimary, hypkftree::PassedEvSelMC, hypkftree::YGen, hypkftree::PtGen, hypkftree::CtGen #define HYPKFGENEXT hypkftree::CpaPvGen, hypkftree::PxGen, hypkftree::PyGen, hypkftree::PzGen, hypkftree::PvxGen, hypkftree::PvyGen, hypkftree::PvzGen, hypkftree::SvxGen, hypkftree::SvyGen, hypkftree::SvzGen #define HYPKFGENCAS hypkftree::TvxGen, hypkftree::TvyGen, hypkftree::TvzGen -#define HYPKFHYPNUC hykfmc::Species, hypkftree::IsMatter, hypkftree::Centrality, hypkftree::Occupancy, hykfmccoll::PassedEvSel, hykfhyp::Mass, hypkftree::Y, track::Pt, hypkftree::Ct, hypkftree::CosPa, hypkftree::DcaTracks, hypkftree::DcaTrackSv, hykfhyp::DcaToPvXY, hykfhyp::DcaToPvZ, hykfhyp::DevToPvXY, hykfhyp::Chi2, hypkftree::Pvx, hypkftree::Pvy, hypkftree::Pvz, hykfmc::Svx, hykfmc::Svy, hykfmc::Svz, hykfhyp::Px, hykfhyp::Py, hykfhyp::Pz, hypkftree::CollMcTrue +#define HYPKFHYPNUC hykfmc::Species, hypkftree::IsMatter, hypkftree::Centrality, hypkftree::Occupancy, hypkftree::RunNumber, hykfmccoll::PassedEvSel, hykfhyp::Mass, hypkftree::Y, track::Pt, hypkftree::Ct, hypkftree::CosPa, hypkftree::DcaTracks, hypkftree::DcaTrackSv, hykfhyp::DcaToPvXY, hykfhyp::DcaToPvZ, hykfhyp::DevToPvXY, hykfhyp::Chi2, hypkftree::Pvx, hypkftree::Pvy, hypkftree::Pvz, hykfmc::Svx, hykfmc::Svy, hykfmc::Svz, hykfhyp::Px, hykfhyp::Py, hykfhyp::Pz, hypkftree::CollMcTrue #define HYPKFHYPNUCMC hypkftree::McTrue, hykfmc::IsPhysicalPrimary @@ -291,6 +296,7 @@ DECLARE_SOA_COLUMN(Sd2sd3Mass, sd2sd3Mass, float); #define HYPKFSDMASS hypkftree::D1d2Mass, hypkftree::D1d3Mass, hypkftree::D2d3Mass #define HYPKFSSDMASS hypkftree::Sd1sd2Mass, hypkftree::Sd1sd3Mass, hypkftree::Sd2sd3Mass +#define HYPKFCSDMASS hypkftree::D1sd1Mass, hypkftree::D1sd2Mass, hypkftree::D1sd3Mass DECLARE_SOA_TABLE(HypKfGens, "AOD", "HYPKFGEN", HYPKFGENBASE); using HypKfGen = HypKfGens::iterator; @@ -307,10 +313,10 @@ using HypKfSingleThreeBodyCandidate = HypKfSingleThreeBodyCandidates::iterator; DECLARE_SOA_TABLE(HypKfMcSingleThreeBodyCandidates, "AOD", "HYPKFMCCAND3", HYPKFGENBASE, HYPKFGENEXT, HYPKFHYPNUC, HYPKFD1, HYPKFD2, HYPKFD3, HYPKFSDMASS); using HypKfMcSingleThreeBodyCandidate = HypKfMcSingleThreeBodyCandidates::iterator; -DECLARE_SOA_TABLE(HypKfCascadeTwoThreeCandidates, "AOD", "HYPKFCAND23", HYPKFHYPNUC, HYPKFHYPNUCMC, HYPKFD0, HYPKFD1, HYPKFSD1, HYPKFSD2, HYPKFSD3, HYPKFSSDMASS); +DECLARE_SOA_TABLE(HypKfCascadeTwoThreeCandidates, "AOD", "HYPKFCAND23", HYPKFHYPNUC, HYPKFHYPNUCMC, HYPKFD0, HYPKFD1, HYPKFSD1, HYPKFSD2, HYPKFSD3, HYPKFSSDMASS, HYPKFCSDMASS); using HypKfCascadeTwoThreeCandidate = HypKfCascadeTwoThreeCandidates::iterator; -DECLARE_SOA_TABLE(HypKfMcCascadeTwoThreeCandidates, "AOD", "HYPKFMCCAND23", HYPKFGENBASE, HYPKFGENEXT, HYPKFHYPNUC, HYPKFD0, HYPKFD1, HYPKFSD1, HYPKFSD2, HYPKFSD3, HYPKFSSDMASS); +DECLARE_SOA_TABLE(HypKfMcCascadeTwoThreeCandidates, "AOD", "HYPKFMCCAND23", HYPKFGENBASE, HYPKFGENEXT, HYPKFHYPNUC, HYPKFD0, HYPKFD1, HYPKFSD1, HYPKFSD2, HYPKFSD3, HYPKFSSDMASS, HYPKFCSDMASS); using HypKfMcCascadeTwoThreeCandidate = HypKfMcCascadeTwoThreeCandidates::iterator; DECLARE_SOA_TABLE(HypKfCascadeThreeTwoCandidates, "AOD", "HYPKFCAND32", HYPKFHYPNUC, HYPKFHYPNUCMC, HYPKFD0, HYPKFD1, HYPKFD2, HYPKFSDMASS, HYPKFSD1, HYPKFSD2); @@ -376,22 +382,22 @@ struct HypKfTreeCreator { { if (isMC && cfgMCGenerated) outputMcGenTable( - cand.pdgCode, cand.isMatterMC, cand.isReconstructed, cand.isPhysicalPrimary, cand.passedEvSelMC, cand.yGen, cand.ptGen, cand.ctGen); + cand.speciesMC, cand.pdgCode, cand.isMatterMC, cand.isReconstructed, cand.isPhysicalPrimary, cand.passedEvSelMC, cand.yGen, cand.ptGen, cand.ctGen); if (!cand.isReconstructed) { cand.daughterTracks.resize(4); cand.subDaughterMassVec.resize(4); hypDaughter.daughterTracks.resize(4); - hypDaughter.subDaughterMassVec.resize(4); + hypDaughter.subDaughterMassVec.resize(8); } - if (cfgNprimDaughters == 2 && cfgNsecDaughters == 0) { + if (cfgNprimDaughters == 2 && cfgNsecDaughters == 0) { // o2-linter: disable=magic-number (To be checked) const auto& d1 = cand.daughterTracks.at(0); const auto& d2 = cand.daughterTracks.at(1); if (!isMC || (isMC && cfgMCReconstructed && cand.isReconstructed)) outputTableTwo( - cand.species, cand.isMatter, cand.cent, cand.occu, cand.passedEvSel, cand.mass, cand.y, cand.pt, cand.ct, cand.cpaPv, cand.maxDcaTracks, cand.maxDcaTracksSv, cand.dcaToPvXY, - cand.dcaToPvZ, cand.devToPvXY, cand.chi2, cand.pvx, cand.pvy, cand.pvz, cand.svx, cand.svy, cand.svz, cand.px, cand.py, cand.pz, cand.collisionMcTrue, + cand.species, cand.isMatter, cand.cent, cand.occu, cand.runNumber, cand.passedEvSel, cand.mass, cand.y, cand.pt, cand.ct, cand.cpaPv, cand.maxDcaTracks, cand.maxDcaTracksSv, + cand.dcaToPvXY, cand.dcaToPvZ, cand.devToPvXY, cand.chi2, cand.pvx, cand.pvy, cand.pvz, cand.svx, cand.svy, cand.svz, cand.px, cand.py, cand.pz, cand.collisionMcTrue, cand.mcTrue, cand.mcPhysicalPrimary, d1.x, d1.y, d1.z, d1.px, d1.py, d1.pz, d1.tpcNcls, d1.tpcChi2, d1.itsNcls, d1.itsChi2, d1.itsMeanClsSizeL, d1.rigidity, d1.tpcSignal, d1.tpcNsigma, d1.tpcNsigmaNhp, d1.tpcNsigmaNlp, d1.tofMass, d1.dcaXY, d1.dcaZ, d1.isPvContributor, @@ -399,24 +405,24 @@ struct HypKfTreeCreator { d2.rigidity, d2.tpcSignal, d2.tpcNsigma, d2.tpcNsigmaNhp, d2.tpcNsigmaNlp, d2.tofMass, d2.dcaXY, d2.dcaZ, d2.isPvContributor); if (isMC && cfgMCCombined) outputTableMcTwo( - cand.pdgCode, cand.isMatterMC, cand.isReconstructed, cand.isPhysicalPrimary, cand.passedEvSelMC, cand.yGen, cand.ptGen, cand.ctGen, + cand.speciesMC, cand.pdgCode, cand.isMatterMC, cand.isReconstructed, cand.isPhysicalPrimary, cand.passedEvSelMC, cand.yGen, cand.ptGen, cand.ctGen, cand.cpaPvGen, cand.pxGen, cand.pyGen, cand.pzGen, cand.pvxGen, cand.pvyGen, cand.pvzGen, cand.svxGen, cand.svyGen, cand.svzGen, - cand.species, cand.isMatter, cand.cent, cand.occu, cand.passedEvSel, cand.mass, cand.y, cand.pt, cand.ct, cand.cpaPv, cand.maxDcaTracks, cand.maxDcaTracksSv, - cand.dcaToPvXY, cand.dcaToPvZ, cand.devToPvXY, + cand.species, cand.isMatter, cand.cent, cand.occu, cand.runNumber, cand.passedEvSel, cand.mass, cand.y, cand.pt, cand.ct, cand.cpaPv, cand.maxDcaTracks, + cand.maxDcaTracksSv, cand.dcaToPvXY, cand.dcaToPvZ, cand.devToPvXY, cand.chi2, cand.pvx, cand.pvy, cand.pvz, cand.svx, cand.svy, cand.svz, cand.px, cand.py, cand.pz, cand.collisionMcTrue, d1.x, d1.y, d1.z, d1.px, d1.py, d1.pz, d1.tpcNcls, d1.tpcChi2, d1.itsNcls, d1.itsChi2, d1.itsMeanClsSizeL, d1.rigidity, d1.tpcSignal, d1.tpcNsigma, d1.tpcNsigmaNhp, d1.tpcNsigmaNlp, d1.tofMass, d1.dcaXY, d1.dcaZ, d1.isPvContributor, d2.x, d2.y, d2.z, d2.px, d2.py, d2.pz, d2.tpcNcls, d2.tpcChi2, d2.itsNcls, d2.itsChi2, d2.itsMeanClsSizeL, d2.rigidity, d2.tpcSignal, d2.tpcNsigma, d2.tpcNsigmaNhp, d2.tpcNsigmaNlp, d2.tofMass, d2.dcaXY, d2.dcaZ, d2.isPvContributor); } - if (cand.isPrimaryCandidate && ((cfgNprimDaughters == 3 && cfgNsecDaughters == 0) || (cfgNsecDaughters == 3 && cfgSpecies == 0))) { + if (((!isMC && cand.isPrimaryCandidate) || (isMC && cand.isPhysicalPrimary)) && ((cfgNprimDaughters == 3 && cfgNsecDaughters == 0) || (cfgNsecDaughters == 3 && cfgSpecies == 0))) { // o2-linter: disable=magic-number (To be checked) const auto& d1 = cand.daughterTracks.at(0); const auto& d2 = cand.daughterTracks.at(1); const auto& d3 = cand.daughterTracks.at(2); if (!isMC || (isMC && cfgMCReconstructed && cand.isReconstructed)) outputTableThree( - cand.species, cand.isMatter, cand.cent, cand.occu, cand.passedEvSel, cand.mass, cand.y, cand.pt, cand.ct, cand.cpaPv, cand.maxDcaTracks, cand.maxDcaTracksSv, cand.dcaToPvXY, - cand.dcaToPvZ, cand.devToPvXY, cand.chi2, cand.pvx, cand.pvy, cand.pvz, cand.svx, cand.svy, cand.svz, cand.px, cand.py, cand.pz, cand.collisionMcTrue, + cand.species, cand.isMatter, cand.cent, cand.occu, cand.runNumber, cand.passedEvSel, cand.mass, cand.y, cand.pt, cand.ct, cand.cpaPv, cand.maxDcaTracks, cand.maxDcaTracksSv, + cand.dcaToPvXY, cand.dcaToPvZ, cand.devToPvXY, cand.chi2, cand.pvx, cand.pvy, cand.pvz, cand.svx, cand.svy, cand.svz, cand.px, cand.py, cand.pz, cand.collisionMcTrue, cand.mcTrue, cand.mcPhysicalPrimary, d1.x, d1.y, d1.z, d1.px, d1.py, d1.pz, d1.tpcNcls, d1.tpcChi2, d1.itsNcls, d1.itsChi2, d1.itsMeanClsSizeL, d1.rigidity, d1.tpcSignal, d1.tpcNsigma, d1.tpcNsigmaNhp, d1.tpcNsigmaNlp, d1.tofMass, d1.dcaXY, d1.dcaZ, d1.isPvContributor, @@ -427,10 +433,10 @@ struct HypKfTreeCreator { d1.subMass, d2.subMass, d3.subMass); if (isMC && cfgMCCombined) outputTableMcThree( - cand.pdgCode, cand.isMatterMC, cand.isReconstructed, cand.isPhysicalPrimary, cand.passedEvSelMC, cand.yGen, cand.ptGen, cand.ctGen, + cand.speciesMC, cand.pdgCode, cand.isMatterMC, cand.isReconstructed, cand.isPhysicalPrimary, cand.passedEvSelMC, cand.yGen, cand.ptGen, cand.ctGen, cand.cpaPvGen, cand.pxGen, cand.pyGen, cand.pzGen, cand.pvxGen, cand.pvyGen, cand.pvzGen, cand.svxGen, cand.svyGen, cand.svzGen, - cand.species, cand.isMatter, cand.cent, cand.occu, cand.passedEvSel, cand.mass, cand.y, cand.pt, cand.ct, cand.cpaPv, cand.maxDcaTracks, cand.maxDcaTracksSv, - cand.dcaToPvXY, cand.dcaToPvZ, cand.devToPvXY, cand.chi2, cand.pvx, cand.pvy, cand.pvz, cand.svx, cand.svy, cand.svz, cand.px, cand.py, + cand.species, cand.isMatter, cand.cent, cand.occu, cand.runNumber, cand.passedEvSel, cand.mass, cand.y, cand.pt, cand.ct, cand.cpaPv, cand.maxDcaTracks, + cand.maxDcaTracksSv, cand.dcaToPvXY, cand.dcaToPvZ, cand.devToPvXY, cand.chi2, cand.pvx, cand.pvy, cand.pvz, cand.svx, cand.svy, cand.svz, cand.px, cand.py, cand.pz, cand.collisionMcTrue, d1.x, d1.y, d1.z, d1.px, d1.py, d1.pz, d1.tpcNcls, d1.tpcChi2, d1.itsNcls, d1.itsChi2, d1.itsMeanClsSizeL, d1.rigidity, d1.tpcSignal, d1.tpcNsigma, d1.tpcNsigmaNhp, d1.tpcNsigmaNlp, d1.tofMass, d1.dcaXY, d1.dcaZ, d1.isPvContributor, @@ -440,7 +446,9 @@ struct HypKfTreeCreator { d3.rigidity, d3.tpcSignal, d3.tpcNsigma, d3.tpcNsigmaNhp, d3.tpcNsigmaNlp, d3.tofMass, d3.dcaXY, d3.dcaZ, d3.isPvContributor, d1.subMass, d2.subMass, d3.subMass); } - if (cfgNprimDaughters == 2 && cfgNsecDaughters == 3) { + if ((!isMC && !cand.isCascade) || (isMC && !cand.isCascadeMC)) + return; + if (cfgNprimDaughters == 2 && cfgNsecDaughters == 3) { // o2-linter: disable=magic-number (To be checked) const auto& d0 = cand.daughterTracks.at(0); const auto& d1 = cand.daughterTracks.at(1); const auto& sd1 = hypDaughter.daughterTracks.at(0); @@ -448,8 +456,8 @@ struct HypKfTreeCreator { const auto& sd3 = hypDaughter.daughterTracks.at(2); if (!isMC || (isMC && cfgMCReconstructed && cand.isReconstructed)) outputTableTwoThree( - cand.species, cand.isMatter, cand.cent, cand.occu, cand.passedEvSel, cand.mass, cand.y, cand.pt, cand.ct, cand.cpaPv, cand.maxDcaTracks, cand.maxDcaTracksSv, cand.dcaToPvXY, - cand.dcaToPvZ, cand.devToPvXY, cand.chi2, cand.pvx, cand.pvy, cand.pvz, cand.svx, cand.svy, cand.svz, cand.px, cand.py, cand.pz, cand.collisionMcTrue, + cand.species, cand.isMatter, cand.cent, cand.occu, cand.runNumber, cand.passedEvSel, cand.mass, cand.y, cand.pt, cand.ct, cand.cpaPv, cand.maxDcaTracks, cand.maxDcaTracksSv, + cand.dcaToPvXY, cand.dcaToPvZ, cand.devToPvXY, cand.chi2, cand.pvx, cand.pvy, cand.pvz, cand.svx, cand.svy, cand.svz, cand.px, cand.py, cand.pz, cand.collisionMcTrue, cand.mcTrue, cand.mcPhysicalPrimary, hypDaughter.svx, hypDaughter.svy, hypDaughter.svz, d0.x, d0.y, d0.z, d0.px, d0.py, d0.pz, hypDaughter.mass, hypDaughter.ct, hypDaughter.cpaPv, hypDaughter.maxDcaTracks, hypDaughter.dcaToPvXY, hypDaughter.dcaToPvZ, hypDaughter.dcaToVtxXY, hypDaughter.dcaToVtxZ, hypDaughter.chi2, @@ -461,13 +469,13 @@ struct HypKfTreeCreator { sd2.rigidity, sd2.tpcSignal, sd2.tpcNsigma, sd2.tpcNsigmaNhp, sd2.tpcNsigmaNlp, sd2.tofMass, sd2.dcaXY, sd2.dcaZ, sd2.isPvContributor, sd3.x, sd3.y, sd3.z, sd3.px, sd3.py, sd3.pz, sd3.tpcNcls, sd3.tpcChi2, sd3.itsNcls, sd3.itsChi2, sd3.itsMeanClsSizeL, sd3.rigidity, sd3.tpcSignal, sd3.tpcNsigma, sd3.tpcNsigmaNhp, sd3.tpcNsigmaNlp, sd3.tofMass, sd3.dcaXY, sd3.dcaZ, sd3.isPvContributor, - sd1.subMass, sd2.subMass, sd3.subMass); + sd1.subMass, sd2.subMass, sd3.subMass, cand.subDaughterMassVec.at(0), cand.subDaughterMassVec.at(1), cand.subDaughterMassVec.at(2)); if (isMC && cfgMCCombined) outputTableMcTwoThree( - cand.pdgCode, cand.isMatterMC, cand.isReconstructed, cand.isPhysicalPrimary, cand.passedEvSelMC, cand.yGen, cand.ptGen, cand.ctGen, + cand.speciesMC, cand.pdgCode, cand.isMatterMC, cand.isReconstructed, cand.isPhysicalPrimary, cand.passedEvSelMC, cand.yGen, cand.ptGen, cand.ctGen, cand.cpaPvGen, cand.pxGen, cand.pyGen, cand.pzGen, cand.pvxGen, cand.pvyGen, cand.pvzGen, cand.svxGen, cand.svyGen, cand.svzGen, - cand.species, cand.isMatter, cand.cent, cand.occu, cand.passedEvSel, cand.mass, cand.y, cand.pt, cand.ct, cand.cpaPv, cand.maxDcaTracks, cand.maxDcaTracksSv, cand.dcaToPvXY, - cand.dcaToPvZ, cand.devToPvXY, + cand.species, cand.isMatter, cand.cent, cand.occu, cand.runNumber, cand.passedEvSel, cand.mass, cand.y, cand.pt, cand.ct, cand.cpaPv, cand.maxDcaTracks, cand.maxDcaTracksSv, + cand.dcaToPvXY, cand.dcaToPvZ, cand.devToPvXY, cand.chi2, cand.pvx, cand.pvy, cand.pvz, cand.svx, cand.svy, cand.svz, cand.px, cand.py, cand.pz, cand.collisionMcTrue, hypDaughter.svx, hypDaughter.svy, hypDaughter.svz, d0.x, d0.y, d0.z, d0.px, d0.py, d0.pz, hypDaughter.mass, hypDaughter.ct, hypDaughter.cpaPv, hypDaughter.maxDcaTracks, hypDaughter.dcaToPvXY, hypDaughter.dcaToPvZ, hypDaughter.dcaToVtxXY, hypDaughter.dcaToVtxZ, hypDaughter.chi2, @@ -479,9 +487,9 @@ struct HypKfTreeCreator { sd2.rigidity, sd2.tpcSignal, sd2.tpcNsigma, sd2.tpcNsigmaNhp, sd2.tpcNsigmaNlp, sd2.tofMass, sd2.dcaXY, sd2.dcaZ, sd2.isPvContributor, sd3.x, sd3.y, sd3.z, sd3.px, sd3.py, sd3.pz, sd3.tpcNcls, sd3.tpcChi2, sd3.itsNcls, sd3.itsChi2, sd3.itsMeanClsSizeL, sd3.rigidity, sd3.tpcSignal, sd3.tpcNsigma, sd3.tpcNsigmaNhp, sd3.tpcNsigmaNlp, sd3.tofMass, sd3.dcaXY, sd3.dcaZ, sd3.isPvContributor, - sd1.subMass, sd2.subMass, sd3.subMass); + sd1.subMass, sd2.subMass, sd3.subMass, cand.subDaughterMassVec.at(0), cand.subDaughterMassVec.at(1), cand.subDaughterMassVec.at(2)); } - if (cfgNprimDaughters == 3 && cfgNsecDaughters == 1) { + if (cfgNprimDaughters == 3 && cfgNsecDaughters == 1) { // o2-linter: disable=magic-number (To be checked) const auto& d0 = cand.daughterTracks.at(0); const auto& d1 = cand.daughterTracks.at(1); const auto& d2 = cand.daughterTracks.at(2); @@ -489,8 +497,8 @@ struct HypKfTreeCreator { const auto& sd2 = hypDaughter.daughterTracks.at(1); if (!isMC || (isMC && cfgMCReconstructed && cand.isReconstructed)) outputTableThreeTwo( - cand.species, cand.isMatter, cand.cent, cand.occu, cand.passedEvSel, cand.mass, cand.y, cand.pt, cand.ct, cand.cpaPv, cand.maxDcaTracks, cand.maxDcaTracksSv, cand.dcaToPvXY, - cand.dcaToPvZ, cand.devToPvXY, cand.chi2, cand.pvx, cand.pvy, cand.pvz, cand.svx, cand.svy, cand.svz, cand.px, cand.py, cand.pz, cand.collisionMcTrue, + cand.species, cand.isMatter, cand.cent, cand.occu, cand.runNumber, cand.passedEvSel, cand.mass, cand.y, cand.pt, cand.ct, cand.cpaPv, cand.maxDcaTracks, cand.maxDcaTracksSv, + cand.dcaToPvXY, cand.dcaToPvZ, cand.devToPvXY, cand.chi2, cand.pvx, cand.pvy, cand.pvz, cand.svx, cand.svy, cand.svz, cand.px, cand.py, cand.pz, cand.collisionMcTrue, cand.mcTrue, cand.mcPhysicalPrimary, hypDaughter.svx, hypDaughter.svy, hypDaughter.svz, d0.x, d0.y, d0.z, d0.px, d0.py, d0.pz, hypDaughter.mass, hypDaughter.ct, hypDaughter.cpaPv, hypDaughter.maxDcaTracks, hypDaughter.dcaToPvXY, hypDaughter.dcaToPvZ, hypDaughter.dcaToVtxXY, hypDaughter.dcaToVtxZ, hypDaughter.chi2, d1.x, d1.y, d1.z, d1.px, d1.py, d1.pz, d1.tpcNcls, d1.tpcChi2, d1.itsNcls, d1.itsChi2, d1.itsMeanClsSizeL, @@ -504,10 +512,10 @@ struct HypKfTreeCreator { sd2.rigidity, sd2.tpcSignal, sd2.tpcNsigma, sd2.tpcNsigmaNhp, sd2.tpcNsigmaNlp, sd2.tofMass, sd2.dcaXY, sd2.dcaZ, sd2.isPvContributor); if (isMC && cfgMCCombined) outputTableMcThreeTwo( - cand.pdgCode, cand.isMatterMC, cand.isReconstructed, cand.isPhysicalPrimary, cand.passedEvSelMC, cand.yGen, cand.ptGen, cand.ctGen, + cand.speciesMC, cand.pdgCode, cand.isMatterMC, cand.isReconstructed, cand.isPhysicalPrimary, cand.passedEvSelMC, cand.yGen, cand.ptGen, cand.ctGen, cand.cpaPvGen, cand.pxGen, cand.pyGen, cand.pzGen, cand.pvxGen, cand.pvyGen, cand.pvzGen, cand.svxGen, cand.svyGen, cand.svzGen, - cand.species, cand.isMatter, cand.cent, cand.occu, cand.passedEvSel, cand.mass, cand.y, cand.pt, cand.ct, cand.cpaPv, cand.maxDcaTracks, cand.maxDcaTracksSv, cand.dcaToPvXY, - cand.dcaToPvZ, cand.devToPvXY, cand.chi2, cand.pvx, cand.pvy, cand.pvz, cand.svx, cand.svy, cand.svz, cand.px, cand.py, cand.pz, cand.collisionMcTrue, + cand.species, cand.isMatter, cand.cent, cand.occu, cand.runNumber, cand.passedEvSel, cand.mass, cand.y, cand.pt, cand.ct, cand.cpaPv, cand.maxDcaTracks, cand.maxDcaTracksSv, + cand.dcaToPvXY, cand.dcaToPvZ, cand.devToPvXY, cand.chi2, cand.pvx, cand.pvy, cand.pvz, cand.svx, cand.svy, cand.svz, cand.px, cand.py, cand.pz, cand.collisionMcTrue, hypDaughter.svx, hypDaughter.svy, hypDaughter.svz, d0.x, d0.y, d0.z, d0.px, d0.py, d0.pz, hypDaughter.mass, hypDaughter.ct, hypDaughter.cpaPv, hypDaughter.maxDcaTracks, hypDaughter.dcaToPvXY, hypDaughter.dcaToPvZ, hypDaughter.dcaToVtxXY, hypDaughter.dcaToVtxZ, hypDaughter.chi2, d1.x, d1.y, d1.z, d1.px, d1.py, d1.pz, d1.tpcNcls, d1.tpcChi2, d1.itsNcls, d1.itsChi2, d1.itsMeanClsSizeL, @@ -547,8 +555,11 @@ struct HypKfTreeCreator { cand.species = std::abs(hypNuc.species()); cand.isPrimaryCandidate = hypNuc.primary(); cand.isMatter = hypNuc.isMatter(); + cand.mcTrue = hypNuc.mcTrue(); + cand.isCascade = cand.species > 10; // o2-linter: disable=magic-number (To be checked) cand.cent = coll.centFT0C(); cand.occu = coll.occupancy(); + cand.runNumber = coll.runNumber(); cand.passedEvSel = coll.passedEvSel(); cand.mass = hypNuc.mass(); cand.y = hypNuc.y(); @@ -601,11 +612,19 @@ struct HypKfTreeCreator { cand.daughterTracks.at(trackCount).z = addOn.z(); cand.daughterTracks.at(trackCount).px = addOn.px(); cand.daughterTracks.at(trackCount).py = addOn.py(); - cand.daughterTracks.at(trackCount).pz = addOn.py(); + cand.daughterTracks.at(trackCount).pz = addOn.pz(); trackCount++; } + + if (cand.isCascade) { + auto subDaughters = hypNuc.hypKfSubD_as(); + for (const auto& subDaughter : subDaughters) { + cand.subDaughterMassVec.push_back(subDaughter.subMass()); + } + } + cand.nSingleDaughters = trackCount; - if (cand.nSingleDaughters < 3) + if (cand.nSingleDaughters < 3) // o2-linter: disable=magic-number (To be checked) return; trackCount = 0; @@ -626,9 +645,12 @@ struct HypKfTreeCreator { const auto mcParticleIdx = mcHypNuc.globalIndex(); auto hypNucsByMc = hypNucs.sliceBy(perMcParticle, mcParticleIdx); HyperNucleus candidate, hypNucDaughter; + candidate.speciesMC = mcHypNuc.species(); + candidate.isCascadeMC = candidate.speciesMC > 10; // o2-linter: disable=magic-number (To be checked) candidate.pdgCode = mcHypNuc.pdgCode(); candidate.isMatterMC = mcHypNuc.isMatter(); candidate.isPhysicalPrimary = mcHypNuc.isPhysicalPrimary(); + candidate.mcPhysicalPrimary = mcHypNuc.isPhysicalPrimary(); candidate.passedEvSelMC = mcColl.passedEvSel(); candidate.yGen = mcHypNuc.y(); candidate.ptGen = mcHypNuc.pt(); diff --git a/PWGLF/TableProducer/Nuspex/hyperhelium4sigmaRecoTask.cxx b/PWGLF/TableProducer/Nuspex/hyperhelium4sigmaRecoTask.cxx index 567211b67b6..30801a93e2e 100644 --- a/PWGLF/TableProducer/Nuspex/hyperhelium4sigmaRecoTask.cxx +++ b/PWGLF/TableProducer/Nuspex/hyperhelium4sigmaRecoTask.cxx @@ -13,20 +13,30 @@ /// \brief QA and analysis task for hyper-helium4sigma (He4S) /// \author Yuanzhe Wang -#include -#include +#include "PWGLF/DataModel/LFHyperhelium4sigmaTables.h" +#include "PWGLF/DataModel/LFKinkDecayTables.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" #include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponse.h" + +#include "CCDB/BasicCCDBManager.h" #include "CommonConstants/PhysicsConstants.h" -#include "PWGLF/DataModel/LFKinkDecayTables.h" -#include "PWGLF/DataModel/LFHyperhelium4sigmaTables.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -39,10 +49,13 @@ using MCLabeledTracksIU = soa::Join; namespace { +constexpr float BzLowerLimit = -990.f; +constexpr std::array LayerRadii{2.33959f, 3.14076f, 3.91924f, 19.6213f, 24.5597f, 34.388f, 39.3329f}; constexpr int kITSLayers = 7; constexpr int kITSInnerBarrelLayers = 3; // constexpr int kITSOuterBarrelLayers = 4; std::shared_ptr hMotherCounter; +std::shared_ptr hMother2BCounter; std::shared_ptr hDauAlphaCounter; std::shared_ptr hDauTritonCounter; std::shared_ptr hDauProtonCounter; @@ -130,6 +143,19 @@ Channel getDecayChannelHe4S(TMCParticle const& particle, std::vector& list) return kNDecayChannel; } +//-------------------------------------------------------------- +// Extract track parameters from a mcparticle, use global coordinates as the local one +template +o2::track::TrackParametrization getTrackParFromMC(const T& mcparticle) +{ + int sign = mcparticle.pdgCode() > 0 ? 1 : -1; // ok for hyperhelium4sigma + TrackPrecision snp = mcparticle.py() / (mcparticle.pt() + 1.e-10f); + TrackPrecision tgl = mcparticle.pz() / (mcparticle.pt() + 1.e-10f); + std::array arraypar = {mcparticle.vy(), mcparticle.vz(), snp, + tgl, 2 * sign / (mcparticle.pt() + 1.e-10f)}; + return o2::track::TrackParametrization(mcparticle.vx(), 0, std::move(arraypar)); +} + //-------------------------------------------------------------- // construct index array from mcParticle to track template @@ -195,6 +221,9 @@ struct Hyperhelium4sigmaRecoTask { Produces outputDataTable; Produces outputMCTable; + Service ccdb; + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; + std::vector mcHe4sIndices; // Histograms are defined with HistogramRegistry @@ -205,6 +234,18 @@ struct Hyperhelium4sigmaRecoTask { Configurable maxZVertex{"maxZVertex", 10.0f, "Accepted z-vertex range (cm)"}; Configurable cutNSigmaAl{"cutNSigmaAl", 5, "NSigmaTPCAlpha"}; + // CCDB options + Configurable inputBz{"inputBz", -999, "bz field, -999 is automatic"}; + Configurable ccdbPath{"ccdbPath", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; + Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + + int mRunNumber; + float mBz; + o2::base::MatLayerCylSet* lut = nullptr; + void init(InitContext const&) { // Axes @@ -212,24 +253,77 @@ struct Hyperhelium4sigmaRecoTask { const AxisSpec ptAxis{50, -10, 10, "#it{p}_{T} (GeV/#it{c})"}; const AxisSpec nSigmaAxis{120, -6.f, 6.f, "n#sigma_{#alpha}"}; const AxisSpec massAxis{100, 3.85, 4.25, "m (GeV/#it{c}^{2})"}; + const AxisSpec diffPtAxis{200, -10.f, 10.f, "#Delta p_{T} (GeV/#it{c})"}; + const AxisSpec diffPzAxis{200, -10.f, 10.f, "#Delta p_{z} (GeV/#it{c})"}; + const AxisSpec radiusAxis{40, 0.f, 40.f, "R (cm)"}; registry.add("hEventCounter", "hEventCounter", HistType::kTH1F, {{2, 0, 2}}); registry.add("hVertexZCollision", "hVertexZCollision", HistType::kTH1F, {vertexZAxis}); registry.add("hCandidateCounter", "hCandidateCounter", HistType::kTH1F, {{3, 0, 3}}); - registry.add("h2MassHyperhelium4sigmaPt", "h2MassHyperhelium4sigmaPt", HistType::kTH2F, {{ptAxis, massAxis}}); - registry.add("h2NSigmaAlPt", "h2NSigmaAlPt", HistType::kTH2F, {{ptAxis, nSigmaAxis}}); - if (doprocessMC == true) { - registry.add("hDiffSVx", ";;#Delta x (cm)", HistType::kTH1F, {{200, -10, 10}}); - registry.add("hDiffSVy", ";;#Delta y (cm)", HistType::kTH1F, {{200, -10, 10}}); - registry.add("hDiffSVz", ";;#Delta z (cm)", HistType::kTH1F, {{200, -10, 10}}); + registry.add("hTrueCandidateCounter", "hTrueCandidateCounter", HistType::kTH1F, {{3, 0, 3}}); + registry.add("hDiffSVx", ";#Delta x (cm);", HistType::kTH1F, {{200, -10, 10}}); + registry.add("hDiffSVy", ";#Delta y (cm);", HistType::kTH1F, {{200, -10, 10}}); + registry.add("hDiffSVz", ";#Delta z (cm);", HistType::kTH1F, {{200, -10, 10}}); + registry.add("h2TrueMotherDiffPtVsRecSVR", ";Reconstruced SV R (cm);#Delta p_{T} (GeV/#it{c});", HistType::kTH2F, {radiusAxis, diffPtAxis}); + registry.add("h2TrueMotherDiffPzVsRecSVR", ";Reconstruced SV R (cm);#Delta p_{z} (GeV/#it{c});", HistType::kTH2F, {radiusAxis, diffPzAxis}); registry.add("hDiffDauPx", ";#Delta p_{x} (GeV/#it{c}); ", HistType::kTH1D, {{200, -10, 10}}); registry.add("hDiffDauPy", ";#Delta p_{y} (GeV/#it{c}); ", HistType::kTH1D, {{200, -10, 10}}); registry.add("hDiffDauPz", ";#Delta p_{z} (GeV/#it{c}); ", HistType::kTH1D, {{200, -10, 10}}); registry.add("h2TrueSignalMassPt", "h2TrueSignalMassPt", HistType::kTH2F, {{ptAxis, massAxis}}); registry.add("h2TrueSignalNSigmaAlPt", "h2TrueSignalNSigmaAlPt", HistType::kTH2F, {{ptAxis, nSigmaAxis}}); + + registry.add("hDCAXYMothToRecSV", "hDCAXYMothToRecSV", HistType::kTH1F, {{200, -10, 10}}); + registry.add("hDCAZMothToRecSV", "hDCAZMothToRecSV", HistType::kTH1F, {{200, -10, 10}}); } + + registry.add("h2MassHyperhelium4sigmaPt", "h2MassHyperhelium4sigmaPt", HistType::kTH2F, {{ptAxis, massAxis}}); + registry.add("h2NSigmaAlPt", "h2NSigmaAlPt", HistType::kTH2F, {{ptAxis, nSigmaAxis}}); + + ccdb->setURL(ccdbPath); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(false); + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(lutPath)); + } + + void initCCDB(aod::BCsWithTimestamps::iterator const& bc) + { + if (mRunNumber == bc.runNumber()) { + return; + } + auto timestamp = bc.timestamp(); + + o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp(grpPath, timestamp); + o2::parameters::GRPMagField* grpmag = 0x0; + if (grpo) { + o2::base::Propagator::initFieldFromGRP(grpo); + if (inputBz < BzLowerLimit) { + // Fetch magnetic field from ccdb for current collision + mBz = grpo->getNominalL3Field(); + LOG(info) << "Retrieved GRP for timestamp " << timestamp << " with magnetic field of " << mBz << " kZG"; + } else { + mBz = inputBz; + } + } else { + grpmag = ccdb->getForTimeStamp(grpmagPath, timestamp); + if (!grpmag) { + LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << timestamp; + } + o2::base::Propagator::initFieldFromGRP(grpmag); + if (inputBz < BzLowerLimit) { + // Fetch magnetic field from ccdb for current collision + mBz = std::lround(5.f * grpmag->getL3Current() / 30000.f); + LOG(info) << "Retrieved GRP for timestamp " << timestamp << " with magnetic field of " << mBz << " kZG"; + } else { + mBz = inputBz; + } + } + + mRunNumber = bc.runNumber(); + o2::base::Propagator::Instance()->setMatLUT(lut); + LOG(info) << "Task initialized for run " << mRunNumber << " with magnetic field " << mBz << " kZG"; } template @@ -328,7 +422,7 @@ struct Hyperhelium4sigmaRecoTask { } PROCESS_SWITCH(Hyperhelium4sigmaRecoTask, processData, "process data", true); - void processMC(MCLabeledCollisionsFull const& collisions, aod::KinkCands const& KinkCands, MCLabeledTracksIU const& tracks, aod::McParticles const& particlesMC, aod::McCollisions const& mcCollisions) + void processMC(MCLabeledCollisionsFull const& collisions, aod::KinkCands const& KinkCands, MCLabeledTracksIU const& tracks, aod::McParticles const& particlesMC, aod::McCollisions const& mcCollisions, aod::BCsWithTimestamps const&) { mcHe4sIndices.clear(); std::vector mcPartIndices; @@ -351,48 +445,76 @@ struct Hyperhelium4sigmaRecoTask { } for (const auto& kinkCand : KinkCands) { + auto motherTrack = kinkCand.trackMoth_as(); + auto dauTrack = kinkCand.trackDaug_as(); + + bool isTrueSignal = false; + if (motherTrack.has_mcParticle() && dauTrack.has_mcParticle()) { + auto mcMotherTrack = motherTrack.mcParticle_as(); + auto mcDauTrack = dauTrack.mcParticle_as(); + auto dChannel = getDecayChannelHe4S(mcMotherTrack, dauIDList); + if (dChannel == k2body && dauIDList[0] == mcDauTrack.globalIndex()) { + isTrueSignal = true; + } + } + registry.fill(HIST("hCandidateCounter"), 0); + if (isTrueSignal) { + registry.fill(HIST("hTrueCandidateCounter"), 0); + } auto collision = kinkCand.collision_as(); if (!isGoodCollisions[collision.globalIndex()]) { continue; } registry.fill(HIST("hCandidateCounter"), 1); + if (isTrueSignal) { + registry.fill(HIST("hTrueCandidateCounter"), 1); + } - auto dauTrack = kinkCand.trackDaug_as(); if (std::abs(dauTrack.tpcNSigmaAl()) > cutNSigmaAl) { continue; } float invMass = RecoDecay::m(std::array{std::array{kinkCand.pxDaug(), kinkCand.pyDaug(), kinkCand.pzDaug()}, std::array{kinkCand.pxDaugNeut(), kinkCand.pyDaugNeut(), kinkCand.pzDaugNeut()}}, std::array{o2::constants::physics::MassAlpha, o2::constants::physics::MassPi0}); registry.fill(HIST("hCandidateCounter"), 2); + if (isTrueSignal) { + registry.fill(HIST("hTrueCandidateCounter"), 2); + } registry.fill(HIST("h2MassHyperhelium4sigmaPt"), kinkCand.mothSign() * kinkCand.ptMoth(), invMass); registry.fill(HIST("h2NSigmaAlPt"), kinkCand.mothSign() * kinkCand.ptDaug(), dauTrack.tpcNSigmaAl()); - auto motherTrack = kinkCand.trackMoth_as(); Hyphe4sCandidate hyphe4sCand; fillCandidate(hyphe4sCand, collision, kinkCand, motherTrack, dauTrack); // qa for true signal - if (motherTrack.has_mcParticle() && dauTrack.has_mcParticle()) { + if (isTrueSignal) { auto mcMotherTrack = motherTrack.mcParticle_as(); auto mcDauTrack = dauTrack.mcParticle_as(); - auto dChannel = getDecayChannelHe4S(mcMotherTrack, dauIDList); - if (dChannel == k2body && dauIDList[0] == mcDauTrack.globalIndex()) { - registry.fill(HIST("hDiffSVx"), kinkCand.xDecVtx() - mcDauTrack.vx()); - registry.fill(HIST("hDiffSVy"), kinkCand.yDecVtx() - mcDauTrack.vy()); - registry.fill(HIST("hDiffSVz"), kinkCand.zDecVtx() - mcDauTrack.vz()); - registry.fill(HIST("hDiffDauPx"), kinkCand.pxDaug() - mcDauTrack.px()); - registry.fill(HIST("hDiffDauPy"), kinkCand.pyDaug() - mcDauTrack.py()); - registry.fill(HIST("hDiffDauPz"), kinkCand.pzDaug() - mcDauTrack.pz()); - registry.fill(HIST("h2TrueSignalMassPt"), kinkCand.mothSign() * kinkCand.ptMoth(), invMass); - registry.fill(HIST("h2TrueSignalNSigmaAlPt"), kinkCand.mothSign() * kinkCand.ptDaug(), dauTrack.tpcNSigmaAl()); - - hyphe4sCand.isSignal = true; - hyphe4sCand.isSignalReco = true; - hyphe4sCand.isCollReco = true; - hyphe4sCand.isSurvEvSelection = true; - fillCandidateMCInfo(hyphe4sCand, mcMotherTrack, mcDauTrack); - mcHe4sIndices.push_back(mcMotherTrack.globalIndex()); - } + float recSVR = std::sqrt(kinkCand.xDecVtx() * kinkCand.xDecVtx() + kinkCand.yDecVtx() * kinkCand.yDecVtx()); + registry.fill(HIST("hDiffSVx"), kinkCand.xDecVtx() - mcDauTrack.vx()); + registry.fill(HIST("hDiffSVy"), kinkCand.yDecVtx() - mcDauTrack.vy()); + registry.fill(HIST("hDiffSVz"), kinkCand.zDecVtx() - mcDauTrack.vz()); + registry.fill(HIST("h2TrueMotherDiffPtVsRecSVR"), recSVR, mcMotherTrack.pt() - kinkCand.ptMoth()); + registry.fill(HIST("h2TrueMotherDiffPzVsRecSVR"), recSVR, mcMotherTrack.pz() - kinkCand.pzMoth()); + registry.fill(HIST("hDiffDauPx"), kinkCand.pxDaug() - mcDauTrack.px()); + registry.fill(HIST("hDiffDauPy"), kinkCand.pyDaug() - mcDauTrack.py()); + registry.fill(HIST("hDiffDauPz"), kinkCand.pzDaug() - mcDauTrack.pz()); + registry.fill(HIST("h2TrueSignalMassPt"), kinkCand.mothSign() * kinkCand.ptMoth(), invMass); + registry.fill(HIST("h2TrueSignalNSigmaAlPt"), kinkCand.mothSign() * kinkCand.ptDaug(), dauTrack.tpcNSigmaAl()); + + hyphe4sCand.isSignal = true; + hyphe4sCand.isSignalReco = true; + hyphe4sCand.isCollReco = true; + hyphe4sCand.isSurvEvSelection = true; + fillCandidateMCInfo(hyphe4sCand, mcMotherTrack, mcDauTrack); + mcHe4sIndices.push_back(mcMotherTrack.globalIndex()); + + auto bc = collision.bc_as(); + initCCDB(bc); + std::array dcaInfo; + auto mcMotherTrackPar = getTrackParFromMC(mcMotherTrack); + o2::base::Propagator::Instance()->propagateToDCABxByBz({kinkCand.xDecVtx(), kinkCand.yDecVtx(), kinkCand.zDecVtx()}, mcMotherTrackPar, 2.f, matCorr, &dcaInfo); + registry.fill(HIST("hDCAXYMothToRecSV"), dcaInfo[0]); + registry.fill(HIST("hDCAZMothToRecSV"), dcaInfo[1]); } outputMCTable( @@ -471,7 +593,8 @@ struct Hyperhelium4sigmaQa { const AxisSpec invMassAxis{invMassBins, "Inv Mass (GeV/#it{c}^{2})"}; const AxisSpec diffPtAxis{200, -10.f, 10.f, "#Delta p_{T} (GeV/#it{c})"}; const AxisSpec diffPzAxis{200, -10.f, 10.f, "#Delta p_{z} (GeV/#it{c})"}; - const AxisSpec radiusAxis{radiusBins, "R (cm)"}; + const AxisSpec itsRadiusAxis{radiusBins, "ITS R (cm)"}; + const AxisSpec svRadiuAxis{radiusBins, "Decay Vertex R (cm)"}; auto hCollCounter = genQAHist.add("hCollCounter", "hCollCounter", HistType::kTH1F, {{2, 0.0f, 2.0f}}); hCollCounter->GetXaxis()->SetBinLabel(1, "Reconstructed Collisions"); @@ -504,24 +627,44 @@ struct Hyperhelium4sigmaQa { // efficiency/criteria studies for tracks which are true candidates hMotherCounter = recoQAHist.add("hMotherCounter", "", HistType::kTH1F, {{9, 0.f, 9.f}}); - hMotherCounter->GetXaxis()->SetBinLabel(1, "Generated"); - hMotherCounter->GetXaxis()->SetBinLabel(2, "Reconstructed"); - hMotherCounter->GetXaxis()->SetBinLabel(3, "eta"); - hMotherCounter->GetXaxis()->SetBinLabel(4, "has collision"); - hMotherCounter->GetXaxis()->SetBinLabel(5, "ITSonly"); - hMotherCounter->GetXaxis()->SetBinLabel(6, "ITS hits"); - hMotherCounter->GetXaxis()->SetBinLabel(7, "ITS IR"); - hMotherCounter->GetXaxis()->SetBinLabel(8, "ITS chi2"); - hMotherCounter->GetXaxis()->SetBinLabel(9, "pt"); - recoQAHist.add("hTrueMotherRVsDiffPt", ";#Delta p_{T} (GeV/#it{c});R (cm);", HistType::kTH2F, {diffPtAxis, radiusAxis}); - recoQAHist.add("hTrueMotherRVsDiffPz", ";#Delta p_{z} (GeV/#it{c});R (cm);", HistType::kTH2F, {diffPzAxis, radiusAxis}); - recoQAHist.add("hGoodMotherRVsDiffPt", ";#Delta p_{T} (GeV/#it{c});R (cm);", HistType::kTH2F, {diffPtAxis, radiusAxis}); - recoQAHist.add("hGoodMotherRVsDiffPz", ";#Delta p_{z} (GeV/#it{c});R (cm);", HistType::kTH2F, {diffPzAxis, radiusAxis}); + hMother2BCounter = recoQAHist.add("hMother2BCounter", "", HistType::kTH1F, {{9, 0.f, 9.f}}); + for (const auto& hist : {hMotherCounter, hMother2BCounter}) { + hist->GetXaxis()->SetBinLabel(1, "Generated"); + hist->GetXaxis()->SetBinLabel(2, "Reconstructed"); + hist->GetXaxis()->SetBinLabel(3, "eta"); + hist->GetXaxis()->SetBinLabel(4, "has collision"); + hist->GetXaxis()->SetBinLabel(5, "ITSonly"); + hist->GetXaxis()->SetBinLabel(6, "ITS hits"); + hist->GetXaxis()->SetBinLabel(7, "ITS IR"); + hist->GetXaxis()->SetBinLabel(8, "ITS chi2"); + hist->GetXaxis()->SetBinLabel(9, "pt"); + } + recoQAHist.add("h2TrueMotherSVRVsRLastITS", ";ITS R (cm); Decay Vertex R (cm);", HistType::kTH2F, {itsRadiusAxis, svRadiuAxis}); + recoQAHist.add("h2GoodMotherSVRVsRLastITS", ";ITS R (cm); Decay Vertex R (cm);", HistType::kTH2F, {itsRadiusAxis, svRadiuAxis}); + recoQAHist.add("h2TrueMotherDiffPtVsDiffR", ";#Delta R (cm);#Delta p_{T} (GeV/#it{c});", HistType::kTH2F, {{80, -40.f, 40.f}, diffPtAxis}); + recoQAHist.add("h2GoodMotherDiffPtVsDiffR", ";#Delta R (cm);#Delta p_{T} (GeV/#it{c});", HistType::kTH2F, {{80, -40.f, 40.f}, diffPtAxis}); + recoQAHist.add("h2TrueMotherDiffPtVsTrueSVR", ";Decay Vertex R (cm);#Delta p_{T} (GeV/#it{c});", HistType::kTH2F, {svRadiuAxis, diffPtAxis}); + recoQAHist.add("h2TrueMotherDiffPzVsTrueSVR", ";Decay Vertex R (cm);#Delta p_{z} (GeV/#it{c});", HistType::kTH2F, {svRadiuAxis, diffPzAxis}); + recoQAHist.add("h2GoodMotherDiffPtVsTrueSVR", ";Decay Vertex R (cm);#Delta p_{T} (GeV/#it{c});", HistType::kTH2F, {svRadiuAxis, diffPtAxis}); + recoQAHist.add("h2GoodMotherDiffPzVsTrueSVR", ";Decay Vertex R (cm);#Delta p_{z} (GeV/#it{c});", HistType::kTH2F, {svRadiuAxis, diffPzAxis}); + recoQAHist.add("h2TrueMotherDiffPtVsRLastITS", ";ITS R (cm);#Delta p_{T} (GeV/#it{c});", HistType::kTH2F, {itsRadiusAxis, diffPtAxis}); + recoQAHist.add("h2TrueMotherDiffPzVsRLastITS", ";ITS R (cm);#Delta p_{z} (GeV/#it{c});", HistType::kTH2F, {itsRadiusAxis, diffPzAxis}); + recoQAHist.add("h2GoodMotherDiffPtVsRLastITS", ";ITS R (cm);#Delta p_{T} (GeV/#it{c});", HistType::kTH2F, {itsRadiusAxis, diffPtAxis}); + recoQAHist.add("h2GoodMotherDiffPzVsRLastITS", ";ITS R (cm);#Delta p_{z} (GeV/#it{c});", HistType::kTH2F, {itsRadiusAxis, diffPzAxis}); hDauAlphaCounter = recoQAHist.add("hDauAlphaCounter", "", HistType::kTH1F, {{7, 0.f, 7.f}}); hDauTritonCounter = recoQAHist.add("hDauTritonCounter", "", HistType::kTH1F, {{7, 0.f, 7.f}}); hDauProtonCounter = recoQAHist.add("hDauProtonCounter", "", HistType::kTH1F, {{7, 0.f, 7.f}}); hDauPionCounter = recoQAHist.add("hDauPionCounter", "", HistType::kTH1F, {{7, 0.f, 7.f}}); + for (const auto& hist : {hDauAlphaCounter, hDauTritonCounter, hDauProtonCounter, hDauPionCounter}) { + hist->GetXaxis()->SetBinLabel(1, "Generated"); + hist->GetXaxis()->SetBinLabel(2, "Reconstructed"); + hist->GetXaxis()->SetBinLabel(3, "eta"); + hist->GetXaxis()->SetBinLabel(4, "has ITS && TPC"); + hist->GetXaxis()->SetBinLabel(5, "ITS quality"); + hist->GetXaxis()->SetBinLabel(6, "TPC n#sigma"); + hist->GetXaxis()->SetBinLabel(7, "has TOF"); + } recoQAHist.add("hDauAlphaTPCNSigma", "", HistType::kTH2F, {rigidityAxis, nsigmaAxis}); recoQAHist.add("hDauTritonTPCNSigma", "", HistType::kTH2F, {rigidityAxis, nsigmaAxis}); @@ -533,9 +676,10 @@ struct Hyperhelium4sigmaQa { Configurable skipRejectedEvents{"skipRejectedEvents", false, "Flag to skip events that fail event selection cuts"}; Configurable doEventCut{"doEventCut", true, "Apply event selection"}; Configurable maxZVertex{"maxZVertex", 10.0f, "Accepted z-vertex range (cm)"}; + Configurable only2BodyDecay{"only2BodyDecay", true, "Only consider 2-body decays for hyperhelium4sigma"}; Configurable etaMax{"etaMax", 1., "eta cut for tracks"}; - Configurable minPtMoth{"minPtMoth", 0.25, "Minimum pT/z of the hyperhelium4sigma candidate"}; + Configurable minPtMoth{"minPtMoth", 0.5, "Minimum pT/z of the hyperhelium4sigma candidate"}; Configurable tpcPidNsigmaCut{"tpcPidNsigmaCut", 5, "tpcPidNsigmaCut"}; Configurable nTPCClusMinDaug{"nTPCClusMinDaug", 80, "daug NTPC clusters cut"}; Configurable itsMaxChi2{"itsMaxChi2", 36, "max chi2 for ITS"}; @@ -656,21 +800,13 @@ struct Hyperhelium4sigmaQa { bool isMatter; if (mcparticle.pdgCode() == o2::constants::physics::Pdg::kHyperHelium4Sigma) { - genQAHist.fill(HIST("hGenHyperHelium4SigmaCounter"), 1.5); isMatter = true; } else if (mcparticle.pdgCode() == -o2::constants::physics::Pdg::kHyperHelium4Sigma) { - genQAHist.fill(HIST("hGenHyperHelium4SigmaCounter"), 2.5); isMatter = false; } else { continue; } - genQAHist.fill(HIST("hGenHyperHelium4SigmaCounter"), 0.5); - genQAHist.fill(HIST("hEvtSelectedHyperHelium4SigmaCounter"), 0.5); - if (isSelectedMCCollisions[mcCollision.globalIndex()]) { - genQAHist.fill(HIST("hEvtSelectedHyperHelium4SigmaCounter"), 1.5); - } - auto dChannel = getDecayChannelHe4S(mcparticle, dauIDList); if (dChannel == kNDecayChannel) { genQAHist.fill(HIST("hGenHyperHelium4SigmaCounter"), 10.5); @@ -678,8 +814,22 @@ struct Hyperhelium4sigmaQa { } // qa for mother tracks + if (dChannel == k2body) { + recoQAHist.fill(HIST("hMother2BCounter"), 0); + } else { + if (only2BodyDecay) { + continue; // skip 3-body decays + } + } recoQAHist.fill(HIST("hMotherCounter"), 0); + genQAHist.fill(HIST("hGenHyperHelium4SigmaCounter"), 0.5); + genQAHist.fill(HIST("hGenHyperHelium4SigmaCounter"), isMatter ? 1.5 : 2.5); + genQAHist.fill(HIST("hEvtSelectedHyperHelium4SigmaCounter"), 0.5); + if (isSelectedMCCollisions[mcCollision.globalIndex()]) { + genQAHist.fill(HIST("hEvtSelectedHyperHelium4SigmaCounter"), 1.5); + } + float svPos[3] = {-999, -999, -999}; float dauAlphaMom[3] = {-999, -999, -999}; float dauTritonMom[3] = {-999, -999, -999}; @@ -701,9 +851,9 @@ struct Hyperhelium4sigmaQa { recoQAHist.fill(HIST("hDauAlphaCounter"), 0); if (mcPartIndices[mcparticleDaughter.globalIndex()] != -1) { auto track = tracks.rawIteratorAt(mcPartIndices[mcparticleDaughter.globalIndex()]); + daughterTrackCheck(track, hDauAlphaCounter, track.tpcNSigmaAl()); if (track.hasTPC()) { recoQAHist.fill(HIST("hDauAlphaTPCNSigma"), track.p() * track.sign(), track.tpcNSigmaAl()); - daughterTrackCheck(track, hDauAlphaCounter, track.tpcNSigmaAl()); } } } else if (std::abs(mcparticleDaughter.pdgCode()) == o2::constants::physics::Pdg::kTriton) { @@ -719,9 +869,9 @@ struct Hyperhelium4sigmaQa { recoQAHist.fill(HIST("hDauTritonCounter"), 0); if (mcPartIndices[mcparticleDaughter.globalIndex()] != -1) { auto track = tracks.rawIteratorAt(mcPartIndices[mcparticleDaughter.globalIndex()]); + daughterTrackCheck(track, hDauTritonCounter, track.tpcNSigmaTr()); if (track.hasTPC()) { recoQAHist.fill(HIST("hDauTritonTPCNSigma"), track.p() * track.sign(), track.tpcNSigmaTr()); - daughterTrackCheck(track, hDauTritonCounter, track.tpcNSigmaTr()); } } } else if (std::abs(mcparticleDaughter.pdgCode()) == PDG_t::kProton) { @@ -732,9 +882,9 @@ struct Hyperhelium4sigmaQa { recoQAHist.fill(HIST("hDauProtonCounter"), 0); if (mcPartIndices[mcparticleDaughter.globalIndex()] != -1) { auto track = tracks.rawIteratorAt(mcPartIndices[mcparticleDaughter.globalIndex()]); + daughterTrackCheck(track, hDauProtonCounter, track.tpcNSigmaPr()); if (track.hasTPC()) { recoQAHist.fill(HIST("hDauProtonTPCNSigma"), track.p() * track.sign(), track.tpcNSigmaPr()); - daughterTrackCheck(track, hDauProtonCounter, track.tpcNSigmaPr()); } } } else if (std::abs(mcparticleDaughter.pdgCode()) == PDG_t::kNeutron) { @@ -768,12 +918,34 @@ struct Hyperhelium4sigmaQa { if (mcPartIndices[mcparticle.globalIndex()] != -1) { auto motherTrack = tracks.rawIteratorAt(mcPartIndices[mcparticle.globalIndex()]); bool isGoodMother = motherTrackCheck(motherTrack, hMotherCounter); + if (dChannel == k2body) { + motherTrackCheck(motherTrack, hMother2BCounter); + } float svR = RecoDecay::sqrtSumOfSquares(svPos[0], svPos[1]); - recoQAHist.fill(HIST("hTrueMotherRVsDiffPt"), mcparticle.pt() - 2 * motherTrack.pt(), svR); - recoQAHist.fill(HIST("hTrueMotherRVsDiffPz"), mcparticle.pz() - 2 * motherTrack.pz(), svR); + float diffpt = mcparticle.pt() - 2 * motherTrack.pt(); + float diffpz = mcparticle.pz() - 2 * motherTrack.pz(); + + int lastITSLayerMoth = 0; + for (int i = 6; i >= 0; i--) { + if ((motherTrack.itsClusterSizes() >> (i * 4)) & 0xf) { + lastITSLayerMoth = i; + break; + } + } + float motherR = LayerRadii[lastITSLayerMoth]; + recoQAHist.fill(HIST("h2TrueMotherSVRVsRLastITS"), motherR, svR); + recoQAHist.fill(HIST("h2TrueMotherDiffPtVsDiffR"), svR - motherR, diffpt); + recoQAHist.fill(HIST("h2TrueMotherDiffPtVsTrueSVR"), svR, diffpt); + recoQAHist.fill(HIST("h2TrueMotherDiffPzVsTrueSVR"), svR, diffpz); + recoQAHist.fill(HIST("h2TrueMotherDiffPtVsRLastITS"), motherR, diffpt); + recoQAHist.fill(HIST("h2TrueMotherDiffPzVsRLastITS"), motherR, diffpz); if (isGoodMother) { - recoQAHist.fill(HIST("hGoodMotherRVsDiffPt"), mcparticle.pt() - 2 * motherTrack.pt(), svR); - recoQAHist.fill(HIST("hGoodMotherRVsDiffPz"), mcparticle.pz() - 2 * motherTrack.pz(), svR); + recoQAHist.fill(HIST("h2GoodMotherSVRVsRLastITS"), motherR, svR); + recoQAHist.fill(HIST("h2GoodMotherDiffPtVsDiffR"), svR - motherR, diffpt); + recoQAHist.fill(HIST("h2GoodMotherDiffPtVsTrueSVR"), svR, diffpt); + recoQAHist.fill(HIST("h2GoodMotherDiffPzVsTrueSVR"), svR, diffpz); + recoQAHist.fill(HIST("h2GoodMotherDiffPtVsRLastITS"), motherR, diffpt); + recoQAHist.fill(HIST("h2GoodMotherDiffPzVsRLastITS"), motherR, diffpz); } // fill qahist if charged daughters are also reconstructed bool isDauReconstructed = mcPartIndices[dauIDList[0]] != -1 && (dChannel == k2body ? true : mcPartIndices[dauIDList[1]] != -1); diff --git a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx index 57796ba11af..fd79be1ced8 100644 --- a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx +++ b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx @@ -19,53 +19,47 @@ // o2-analysis-pid-tof-base, o2-analysis-multiplicity-table, o2-analysis-event-selection // (to add flow: o2-analysis-qvector-table, o2-analysis-centrality-table) -#include -#include -#include -#include -#include - -#include "Math/Vector4D.h" - -#include "CCDB/BasicCCDBManager.h" +#include "PWGLF/DataModel/EPCalibrationTables.h" +#include "PWGLF/DataModel/LFSlimNucleiTables.h" +#include "Common/Core/EventPlaneHelper.h" +#include "Common/Core/PID/PIDTOF.h" +#include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/PIDResponseITS.h" +#include "Common/DataModel/Qvectors.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Common/Core/PID/PIDTOF.h" #include "Common/TableProducer/PID/pidTOFBase.h" -#include "Common/Core/EventPlaneHelper.h" -#include "Common/DataModel/Qvectors.h" -#include "Common/Tools/TrackTuner.h" -#include "Common/Core/RecoDecay.h" +#include "EventFiltering/Zorro.h" +#include "EventFiltering/ZorroSummary.h" +#include "CCDB/BasicCCDBManager.h" #include "DataFormatsParameters/GRPMagField.h" #include "DataFormatsParameters/GRPObject.h" #include "DataFormatsTPC/BetheBlochAleph.h" #include "DetectorsBase/GeometryManager.h" #include "DetectorsBase/Propagator.h" - -#include "EventFiltering/Zorro.h" -#include "EventFiltering/ZorroSummary.h" - +#include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" - #include "ReconstructionDataFormats/Track.h" -#include "PWGLF/DataModel/EPCalibrationTables.h" -#include "PWGLF/DataModel/LFSlimNucleiTables.h" - +#include "Math/Vector4D.h" #include "TRandom3.h" +#include +#include +#include +#include +#include + using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; @@ -267,12 +261,12 @@ struct nucleiSpectra { }; Produces nucleiTable; + Produces nucleiPairTable; Produces nucleiTableMC; Produces nucleiTableFlow; Service ccdb; Zorro zorro; OutputObj zorroSummary{"zorroSummary"}; - TrackTuner trackTunerObj; Configurable cfgCompensatePIDinTracking{"cfgCompensatePIDinTracking", false, "If true, divide tpcInnerParam by the electric charge"}; @@ -281,8 +275,8 @@ struct nucleiSpectra { Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; Configurable cfgCutTpcMom{"cfgCutTpcMom", 0.2f, "Minimum TPC momentum for tracks"}; - Configurable cfgCutRapidityMin{"cfgCutRapidityMin", -0.5, "Minimum rapidity for tracks"}; - Configurable cfgCutRapidityMax{"cfgCutRapidityMax", 0.5, "Maximum rapidity for tracks"}; + Configurable cfgCutRapidityMin{"cfgCutRapidityMin", -1., "Minimum rapidity for tracks"}; + Configurable cfgCutRapidityMax{"cfgCutRapidityMax", 1., "Maximum rapidity for tracks"}; Configurable cfgCutOnReconstructedRapidity{"cfgCutOnReconstructedRapidity", false, "Cut on reconstructed rapidity"}; Configurable cfgCutNclusITS{"cfgCutNclusITS", 5, "Minimum number of ITS clusters"}; Configurable cfgCutNclusTPC{"cfgCutNclusTPC", 70, "Minimum number of TPC clusters"}; @@ -297,6 +291,7 @@ struct nucleiSpectra { Configurable> cfgDCAcut{"cfgDCAcut", {nuclei::DCAcutDefault[0], 5, 2, nuclei::names, nuclei::nDCAConfigName}, "Max DCAxy and DCAz for light nuclei"}; Configurable> cfgDownscaling{"cfgDownscaling", {nuclei::DownscalingDefault[0], 5, 1, nuclei::names, nuclei::DownscalingConfigName}, "Fraction of kept candidates for light nuclei"}; Configurable> cfgTreeConfig{"cfgTreeConfig", {nuclei::TreeConfigDefault[0], 5, 2, nuclei::names, nuclei::treeConfigNames}, "Filtered trees configuration"}; + Configurable cfgFillPairTree{"cfgFillPairTree", true, "Fill trees for pairs of light nuclei"}; Configurable> cfgDCAHists{"cfgDCAHists", {nuclei::DCAHistDefault[0], 5, 2, nuclei::names, nuclei::DCAConfigNames}, "DCA hist configuration"}; Configurable> cfgFlowHist{"cfgFlowHist", {nuclei::FlowHistDefault[0], 5, 1, nuclei::names, nuclei::flowConfigNames}, "Flow hist configuration"}; @@ -325,9 +320,6 @@ struct nucleiSpectra { Configurable cfgSkimmedProcessing{"cfgSkimmedProcessing", false, "Skimmed dataset processing"}; - // configurables for track tuner - Configurable cfgUseTrackTuner{"cfgUseTrackTuner", false, "Apply track tuner corrections to MC tracks"}; - Configurable cfgTrackTunerParams{"cfgTrackTunerParams", "debugInfo=0|updateTrackDCAs=1|updateTrackCovMat=1|updateCurvature=0|updateCurvatureIU=0|updatePulls=1|isInputFileFromCCDB=1|pathInputFile=Users/m/mfaggin/test/inputsTrackTuner/pp2023/smoothHighPtMC|nameInputFile=trackTuner_DataLHC23fPass1_McLHC23k4b_run535085.root|pathFileQoverPt=Users/h/hsharma/qOverPtGraphs|nameFileQoverPt=D0sigma_Data_removal_itstps_MC_LHC22b1b.root|usePvRefitCorrections=0|qOverPtMC=-1.|qOverPtData=-1.", "TrackTuner parameter initialization (format: =|=)"}; // running variables for track tuner o2::dataformats::DCA mDcaInfoCov; o2::track::TrackParametrizationWithError mTrackParCov; @@ -514,6 +506,7 @@ struct nucleiSpectra { spectra.add("hTpcSignalData", "Specific energy loss", HistType::kTH2F, {{600, -6., 6., "#it{p} (GeV/#it{c})"}, {1400, 0, 1400, "d#it{E} / d#it{X} (a. u.)"}}); spectra.add("hTpcSignalDataSelected", "Specific energy loss for selected particles", HistType::kTH2F, {{600, -6., 6., "#it{p} (GeV/#it{c})"}, {1400, 0, 1400, "d#it{E} / d#it{X} (a. u.)"}}); spectra.add("hTofSignalData", "TOF beta", HistType::kTH2F, {{500, 0., 5., "#it{p} (GeV/#it{c})"}, {750, 0, 1.5, "TOF #beta"}}); + for (int iC{0}; iC < 2; ++iC) { nuclei::hGloTOFtracks[iC] = spectra.add(fmt::format("hTPCTOFtracks{}", nuclei::matter[iC]).data(), fmt::format("Global vs TOF matched {} tracks in a collision", nuclei::chargeLabelNames[iC]).data(), HistType::kTH2D, {{300, -0.5, 300.5, "Number of global tracks"}, {300, -0.5, 300.5, "Number of TOF matched tracks"}}); @@ -559,12 +552,6 @@ struct nucleiSpectra { } nuclei::lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get("GLO/Param/MatLUT")); - // TrackTuner initialization - if (cfgUseTrackTuner) { - std::string outputStringParams = trackTunerObj.configParams(cfgTrackTunerParams); - spectra.add("hTrackTunedTracks", outputStringParams.c_str(), HistType::kTH1F, {{1, 0.5, 1.5, ""}}); - trackTunerObj.getDcaGraphs(); - } } template @@ -662,20 +649,6 @@ struct nucleiSpectra { mDcaInfoCov.set(999, 999, 999, 999, 999); setTrackParCov(track, mTrackParCov); mTrackParCov.setPID(track.pidForTracking()); - if constexpr ( - requires { - track.has_mcParticle(); - }) { - if (cfgUseTrackTuner) { - bool hasMcParticle = track.has_mcParticle(); - if (hasMcParticle) { - spectra.get(HIST("hTrackTunedTracks"))->Fill(1); // all tracks - auto mcParticle = track.mcParticle(); - trackTunerObj.tuneTrackParams(mcParticle, mTrackParCov, matCorr, &mDcaInfoCov, spectra.get(HIST("hTrackTunedTracks"))); - } - } - } - std::array dcaInfo; o2::base::Propagator::Instance()->propagateToDCA(collVtx, mTrackParCov, mBz, 2.f, static_cast(cfgMaterialCorrection.value), &dcaInfo); @@ -833,14 +806,24 @@ struct nucleiSpectra { } fillDataInfo(collision, tracks); - for (auto& c : nuclei::candidates) { - if (c.fillTree) { - nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.TOFchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.TPCnClsShared, c.clusterSizesITS); + for (size_t i1{0}; i1 < nuclei::candidates.size(); ++i1) { + auto& c1 = nuclei::candidates[i1]; + if (c1.fillTree) { + nucleiTable(c1.pt, c1.eta, c1.phi, c1.tpcInnerParam, c1.beta, c1.zVertex, c1.DCAxy, c1.DCAz, c1.TPCsignal, c1.ITSchi2, c1.TPCchi2, c1.TOFchi2, c1.flags, c1.TPCfindableCls, c1.TPCcrossedRows, c1.ITSclsMap, c1.TPCnCls, c1.TPCnClsShared, c1.clusterSizesITS); + if (cfgFillPairTree) { + for (size_t i2{i1 + 1}; i2 < nuclei::candidates.size(); ++i2) { + auto& c2 = nuclei::candidates[i2]; + if (!c2.fillTree || ((c1.flags & c2.flags) & 0x1F) == 0) { + continue; + } + nucleiPairTable(c1.pt, c1.eta, c1.phi, c1.tpcInnerParam, c1.TPCsignal, c1.DCAxy, c1.DCAz, c1.clusterSizesITS, c1.flags, c2.pt, c2.eta, c2.phi, c2.tpcInnerParam, c2.TPCsignal, c2.DCAxy, c2.DCAz, c2.clusterSizesITS, c2.flags); + } + } } - if (c.fillDCAHist) { + if (c1.fillDCAHist) { for (int iS{0}; iS < nuclei::species; ++iS) { - if (c.flags & BIT(iS)) { - nuclei::hDCAHists[c.pt < 0][iS]->Fill(std::abs(c.pt), c.DCAxy, c.DCAz, c.nSigmaTPC[iS], c.tofMasses[iS], c.ITSnCls, c.TPCnCls); + if (c1.flags & BIT(iS)) { + nuclei::hDCAHists[c1.pt < 0][iS]->Fill(std::abs(c1.pt), c1.DCAxy, c1.DCAz, c1.nSigmaTPC[iS], c1.tofMasses[iS], c1.ITSnCls, c1.TPCnCls); } } } @@ -944,24 +927,6 @@ struct nucleiSpectra { if (!c.correctPV) { c.flags |= kIsAmbiguous; } - if (!particle.isPhysicalPrimary()) { - c.isSecondary = true; - if (particle.getProcess() == 4) { - c.fromWeakDecay = true; - } - } else { - // if the particle has a hf mother it is flagged as secondary - if (particle.has_mothers()) { - for (auto& motherparticle : particle.mothers_as()) { - if (std::find(nuclei::hfMothCodes.begin(), nuclei::hfMothCodes.end(), std::abs(motherparticle.pdgCode())) != nuclei::hfMothCodes.end()) { - c.isSecondary = true; - c.fromWeakDecay = true; - break; - } - } - } - } - if (c.fillDCAHist && cfgDCAHists->get(iS, c.pt < 0)) { nuclei::hDCAHists[c.pt < 0][iS]->Fill(std::abs(c.pt), c.DCAxy, c.DCAz, c.nSigmaTPC[iS], c.tofMasses[iS], c.ITSnCls, c.TPCnCls, c.correctPV, c.isSecondary, c.fromWeakDecay); } @@ -970,7 +935,12 @@ struct nucleiSpectra { if (!storeIt) { continue; } - int MotherpdgCode = 0; + if (particle.y() < cfgCutRapidityMin || particle.y() > cfgCutRapidityMax) { + continue; + } + + int motherPdgCode = 0; + float motherDecRadius = -1; isReconstructed[particle.globalIndex()] = true; if (particle.isPhysicalPrimary()) { c.flags |= kIsPhysicalPrimary; @@ -978,7 +948,8 @@ struct nucleiSpectra { for (auto& motherparticle : particle.mothers_as()) { if (std::find(nuclei::hfMothCodes.begin(), nuclei::hfMothCodes.end(), std::abs(motherparticle.pdgCode())) != nuclei::hfMothCodes.end()) { c.flags |= kIsSecondaryFromWeakDecay; - MotherpdgCode = motherparticle.pdgCode(); + motherPdgCode = motherparticle.pdgCode(); + motherDecRadius = std::hypot(particle.vx() - motherparticle.vx(), particle.vy() - motherparticle.vy()); break; } } @@ -986,13 +957,16 @@ struct nucleiSpectra { } else if (particle.has_mothers()) { c.flags |= kIsSecondaryFromWeakDecay; for (auto& motherparticle : particle.mothers_as()) { - MotherpdgCode = motherparticle.pdgCode(); + motherPdgCode = motherparticle.pdgCode(); + motherDecRadius = std::hypot(particle.vx() - motherparticle.vx(), particle.vy() - motherparticle.vy()); } } else { c.flags |= kIsSecondaryFromMaterial; } + + isReconstructed[particle.globalIndex()] = true; float absoDecL = computeAbsoDecL(particle); - nucleiTableMC(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.TOFchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.TPCnClsShared, c.clusterSizesITS, particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), MotherpdgCode, goodCollisions[particle.mcCollisionId()], absoDecL); + nucleiTableMC(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.TOFchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.TPCnClsShared, c.clusterSizesITS, goodCollisions[particle.mcCollisionId()], particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), motherPdgCode, motherDecRadius, absoDecL); } int index{0}; @@ -1002,18 +976,40 @@ struct nucleiSpectra { if (pdg != nuclei::codes[iS]) { continue; } - uint16_t flags{kIsPhysicalPrimary}; + if (particle.y() < cfgCutRapidityMin || particle.y() > cfgCutRapidityMax) { + continue; + } + + uint16_t flags = 0; + int motherPdgCode = 0; + float motherDecRadius = -1; if (particle.isPhysicalPrimary()) { - if (particle.y() > cfgCutRapidityMin && particle.y() < cfgCutRapidityMax) { - nuclei::hGenNuclei[iS][particle.pdgCode() < 0]->Fill(1., particle.pt()); + flags |= kIsPhysicalPrimary; + nuclei::hGenNuclei[iS][particle.pdgCode() < 0]->Fill(1., particle.pt()); + if (particle.has_mothers()) { + for (auto& motherparticle : particle.mothers_as()) { + if (std::find(nuclei::hfMothCodes.begin(), nuclei::hfMothCodes.end(), std::abs(motherparticle.pdgCode())) != nuclei::hfMothCodes.end()) { + flags |= kIsSecondaryFromWeakDecay; + motherPdgCode = motherparticle.pdgCode(); + motherDecRadius = std::hypot(particle.vx() - motherparticle.vx(), particle.vy() - motherparticle.vy()); + break; + } + } + } + } else if (particle.has_mothers()) { + flags |= kIsSecondaryFromWeakDecay; + for (auto& motherparticle : particle.mothers_as()) { + motherPdgCode = motherparticle.pdgCode(); + motherDecRadius = std::hypot(particle.vx() - motherparticle.vx(), particle.vy() - motherparticle.vy()); } } else { - continue; /// for not-reconstructed particles we store only the primaries + flags |= kIsSecondaryFromMaterial; } if (!isReconstructed[index] && (cfgTreeConfig->get(iS, 0u) || cfgTreeConfig->get(iS, 1u))) { float absDecL = computeAbsoDecL(particle); - nucleiTableMC(999., 999., 999., 0., 0., 999., 999., 999., -1, -1, -1, -1, flags, 0, 0, 0, 0, 0, 0, particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), 0, goodCollisions[particle.mcCollisionId()], absDecL); + + nucleiTableMC(999., 999., 999., 0., 0., 999., 999., 999., -1, -1, -1, -1, flags, 0, 0, 0, 0, 0, 0, goodCollisions[particle.mcCollisionId()], particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), motherPdgCode, motherDecRadius, absDecL); } break; } diff --git a/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx b/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx index e3c2dd88225..dbd999bbaa0 100644 --- a/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx +++ b/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx @@ -16,8 +16,10 @@ /// /// \author Matthias Herzer , Goethe University Frankfurt /// -#include -#include +#include "PWGLF/DataModel/LFNucleiTables.h" +#include "PWGLF/DataModel/LFParticleIdentification.h" +#include "PWGLF/DataModel/pidTOFGeneric.h" + #include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/PID/TPCPIDResponse.h" #include "Common/Core/trackUtilities.h" @@ -26,17 +28,20 @@ #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" + #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "PWGLF/DataModel/LFNucleiTables.h" -#include "PWGLF/DataModel/LFParticleIdentification.h" #include "ReconstructionDataFormats/PID.h" #include "ReconstructionDataFormats/Track.h" + #include +#include +#include + namespace o2::aod { namespace h3_data @@ -110,13 +115,14 @@ static const std::vector particlePdgCodes{ static const std::vector particleMasses{ o2::constants::physics::MassTriton, o2::constants::physics::MassHelium3}; static const std::vector particleCharge{1, 2}; +static const std::vector particleChargeFactor{2.3, 2.55}; static const std::vector betheBlochParNames{ "p0", "p1", "p2", "p3", "p4", "resolution"}; -constexpr float betheBlochDefault[nParticles][nBetheParams]{ - {0.313129, 181.664226, 2779397163087.684082, 2.130773, 29.609643, - 0.09}, // triton - {70.584685, 3.196364, 0.133878, 2.731736, 1.675617, 0.09}}; // Helion - +constexpr float BetheBlochDefault[nParticles][nBetheParams]{ + {0.248753, 3.58634, 0.0167065, 2.29194, 0.774344, + 0.07}, // triton + {0.0274556, 18.3054, 3.99987e-05, 3.17219, 11.1775, + 0.07}}; // Helion } // namespace using namespace o2; using namespace o2::framework; @@ -125,7 +131,8 @@ using TracksFull = soa::Join; + aod::TOFSignal, aod::TrackSelectionExtension, + o2::aod::EvTimeTOFFT0ForTrack>; class Particle { @@ -135,16 +142,18 @@ class Particle float mass; int charge; float resolution; + float chargeFactor; std::vector betheParams; static constexpr int NNumBetheParams = 5; Particle(const std::string name_, int pdgCode_, float mass_, int charge_, - LabeledArray bethe) + LabeledArray bethe, float chargeFactor_) { name = TString(name_); pdgCode = pdgCode_; mass = mass_; charge = charge_; + chargeFactor = chargeFactor_; resolution = bethe.get(name, "resolution"); // Access the "resolution" parameter @@ -183,7 +192,7 @@ struct TrHeAnalysis { } evselOptions; Configurable cfgTPCPidMethod{"cfgTPCPidMethod", false, "Using own or built in bethe parametrization"}; // false for built in - + Configurable cfgMassMethod{"cfgMassMethod", 0, "0: Using built in 1: mass calculated with beta 2: mass calculated with the event time"}; // Set the multiplity event limits Configurable cfgLowMultCut{"cfgLowMultCut", 0.0f, "Accepted multiplicity percentage lower limit"}; Configurable cfgHighMultCut{"cfgHighMultCut", 100.0f, "Accepted multiplicity percentage higher limit"}; @@ -213,7 +222,7 @@ struct TrHeAnalysis { Configurable cfgCutMaxTofMassH3{"cfgCutMaxTofMassH3", 3.32f, "Maximum TOF mass H3"}; // Set the kinematic and PID cuts for tracks struct : ConfigurableGroup { - Configurable pCut{"pCut", 0.3f, "Value of the p selection for spectra (default 0.3)"}; + Configurable pCut{"pCut", 0.6f, "Value of the p selection for spectra (default 0.3)"}; Configurable etaCut{"etaCut", 0.8f, "Value of the eta selection for spectra (default 0.8)"}; Configurable yLowCut{"yLowCut", -1.0f, "Value of the low rapidity selection for spectra (default -1.0)"}; Configurable yHighCut{"yHighCut", 1.0f, "Value of the high rapidity selection for spectra (default 1.0)"}; @@ -223,7 +232,7 @@ struct TrHeAnalysis { Configurable nsigmaTPCTr{"nsigmaTPCTr", 5.f, "Value of the Nsigma TPC cut for tritons"}; Configurable nsigmaTPCHe{"nsigmaTPCHe", 5.f, "Value of the Nsigma TPC cut for helium-3"}; } nsigmaTPCvar; - Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {betheBlochDefault[0], nParticles, nBetheParams, particleNames, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for light nuclei"}; + Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {BetheBlochDefault[0], nParticles, nBetheParams, particleNames, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for light nuclei"}; void init(o2::framework::InitContext&) { @@ -294,7 +303,7 @@ struct TrHeAnalysis { for (int i = 0; i < nParticles; i++) { particles.push_back(Particle(particleNames.at(i), particlePdgCodes.at(i), particleMasses.at(i), particleCharge.at(i), - cfgBetheBlochParams)); + cfgBetheBlochParams, particleChargeFactor.at(i))); } } void process(soa::Join::iterator const& event, @@ -387,7 +396,7 @@ struct TrHeAnalysis { histos.fill(HIST("histogram/cuts"), 12); continue; } - if (track.mass() < cfgCutMinTofMassH3 || track.mass() > cfgCutMaxTofMassH3) { + if (getMass(track) < cfgCutMinTofMassH3 || getMass(track) > cfgCutMaxTofMassH3) { histos.fill(HIST("histogram/cuts"), 13); continue; } @@ -402,8 +411,8 @@ struct TrHeAnalysis { float tPhi = track.phi(); int8_t tCharge = track.sign(); float tH3DeDx = track.tpcSignal(); - float tnSigmaTpc = track.tpcNSigmaTr(); - float tTofSignalH3 = track.mass(); + float tnSigmaTpc = getTPCnSigma(track, particles.at(0)); + float tTofSignalH3 = getMass(track); float tDcaXY = track.dcaXY(); float tDcaZ = track.dcaZ(); float tSigmaYX = track.sigmaY(); @@ -449,8 +458,8 @@ struct TrHeAnalysis { float tPhi = track.phi(); int8_t tCharge = 2.f * track.sign(); float tHeDeDx = track.tpcSignal(); - float tnSigmaTpc = track.tpcNSigmaHe(); - float tTofSignalHe = track.mass(); + float tnSigmaTpc = getTPCnSigma(track, particles.at(1)); + float tTofSignalHe = getMass(track); float tDcaXY = track.dcaXY(); float tDcaZ = track.dcaZ(); float tSigmaYX = track.sigmaY(); @@ -542,7 +551,7 @@ struct TrHeAnalysis { histos.fill(HIST("histogram/cuts"), 12); continue; } - if (track.mass() < cfgCutMinTofMassH3 || track.mass() > cfgCutMaxTofMassH3) { + if (getMass(track) < cfgCutMinTofMassH3 || getMass(track) > cfgCutMaxTofMassH3) { histos.fill(HIST("histogram/cuts"), 13); continue; } @@ -558,7 +567,7 @@ struct TrHeAnalysis { int8_t tCharge = track.sign(); float tH3DeDx = track.tpcSignal(); float tnSigmaTpc = track.tpcNSigmaTr(); - float tTofSignalH3 = track.mass(); + float tTofSignalH3 = getMass(track); float tDcaXY = track.dcaXY(); float tDcaZ = track.dcaZ(); float tSigmaYX = track.sigmaY(); @@ -604,7 +613,7 @@ struct TrHeAnalysis { int8_t tCharge = 2.f * track.sign(); float tHeDeDx = track.tpcSignal(); float tnSigmaTpc = track.tpcNSigmaHe(); - float tTofSignalHe = track.mass(); + float tTofSignalHe = getMass(track); float tDcaXY = track.dcaXY(); float tDcaZ = track.dcaZ(); float tSigmaYX = track.sigmaY(); @@ -634,29 +643,40 @@ struct TrHeAnalysis { if (!track.hasTPC()) return -999; - float expBethe{tpc::BetheBlochAleph( - static_cast(particle.charge * rigidity / particle.mass), - particle.betheParams[0], particle.betheParams[1], - particle.betheParams[2], particle.betheParams[3], - particle.betheParams[4])}; + float expBethe{betheBlochAleph(particle, rigidity)}; float expSigma{expBethe * particle.resolution}; float sigmaTPC = static_cast((track.tpcSignal() - expBethe) / expSigma); return sigmaTPC; } + template + float betheBlochAleph(Particle const& particle, T const& rigidity) + { + double bg = particle.charge * rigidity / particle.mass; + double beta = bg / std::sqrt(1. + bg * bg); + double aa = std::pow(beta, particle.betheParams[3]); + double bb = std::pow(1. / bg, particle.betheParams[4]); + if ((particle.betheParams[2] + bb) <= 0) + return 0; + bb = std::log(particle.betheParams[2] + bb); + return std::pow(particle.charge, particle.chargeFactor) * 50 * (particle.betheParams[1] - aa - bb) * particle.betheParams[0] / aa; + } + template float getMeanItsClsSize(T const& track) { constexpr int NNumLayers = 8; constexpr int NBitsPerLayer = 4; constexpr int NBitMask = (1 << NBitsPerLayer) - 1; + int sum = 0, n = 0; for (int i = 0; i < NNumLayers; i++) { int clsSize = (track.itsClusterSizes() >> (NBitsPerLayer * i)) & NBitMask; sum += clsSize; - if (clsSize) + if (clsSize) { n++; + } } return n > 0 ? static_cast(sum) / n : 0.f; } @@ -668,6 +688,36 @@ struct TrHeAnalysis { bool hePID = track.pidForTracking() == o2::track::PID::Helium3 || track.pidForTracking() == o2::track::PID::Alpha; return hePID ? track.tpcInnerParam() / 2 : track.tpcInnerParam(); } + template + float getMass(const T& track) + { + if (cfgMassMethod == 0) { + return track.mass(); + } + if (cfgMassMethod == 1) { + const float beta = track.beta(); + const float rigidity = getRigidity(track); + float gamma = 1 / std::sqrt(1 - beta * beta); + float mass = (rigidity / std::sqrt(gamma * gamma - 1.f)); + return mass; + } + if (cfgMassMethod == 2) { + const float rigidity = getRigidity(track); + float tofStartTime = track.evTimeForTrack(); + float tofTime = track.tofSignal(); + constexpr float CInCmPs = 2.99792458e-2f; + float length = track.length(); + float time = tofTime - tofStartTime; + if (time > 0.f && length > 0.f) { + float beta = length / (CInCmPs * time); + float gamma = 1 / std::sqrt(1 - beta * beta); + float mass = rigidity / std::sqrt(gamma * gamma - 1.f); + return mass; + } + return -1.f; + } + return -1.f; + } }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt b/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt index 131672fd384..842137dafe1 100644 --- a/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt +++ b/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt @@ -41,22 +41,22 @@ o2physics_add_dpl_workflow(straevselsconverter o2physics_add_dpl_workflow(straevselsconverter2 SOURCES straevselsconverter2.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::ITStracking + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::ReconstructionDataFormats COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(straevselsconverter3 SOURCES straevselsconverter3.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::ITStracking + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::ReconstructionDataFormats COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(straevselsconverter4 SOURCES straevselsconverter4.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::ITStracking + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(straevselsconverter5 SOURCES straevselsconverter5.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::ITStracking O2Physics::AnalysisCCDB + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::AnalysisCCDB COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(straevselsconverter2rawcents @@ -117,4 +117,4 @@ o2physics_add_dpl_workflow(stramccollisionconverter2 o2physics_add_dpl_workflow(zdcneutronsconverter SOURCES zdcneutronsconverter.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) \ No newline at end of file + COMPONENT_NAME Analysis) diff --git a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter2.cxx b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter2.cxx index 401b04bbc83..fd3ccad4ee4 100644 --- a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter2.cxx +++ b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter2.cxx @@ -8,12 +8,13 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "ITStracking/Vertexer.h" #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Vertex.h" + using namespace o2; using namespace o2::framework; @@ -52,7 +53,7 @@ struct straevselsconverter2 { values.totalFDDAmplitudeC(), values.energyCommonZNA(), values.energyCommonZNC(), - o2::its::Vertex::FlagsMask /*dummy flag value*/); + o2::dataformats::Vertex::FlagsMask /*dummy flag value*/); } } }; diff --git a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter3.cxx b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter3.cxx index ecbd738f5fa..ac209c26fe7 100644 --- a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter3.cxx +++ b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter3.cxx @@ -8,12 +8,13 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "ITStracking/Vertexer.h" #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Vertex.h" + using namespace o2; using namespace o2::framework; @@ -53,7 +54,7 @@ struct straevselsconverter3 { values.totalFDDAmplitudeC(), values.energyCommonZNA(), values.energyCommonZNC(), - o2::its::Vertex::FlagsMask /*dummy flag value*/); + o2::dataformats::Vertex::FlagsMask /*dummy flag value*/); } } }; diff --git a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter4.cxx b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter4.cxx index ad988fd93aa..2dc55f365c9 100644 --- a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter4.cxx +++ b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter4.cxx @@ -8,12 +8,12 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "ITStracking/Vertexer.h" #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + using namespace o2; using namespace o2::framework; diff --git a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter5.cxx b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter5.cxx index f9617c42a0b..0ba066f99b3 100644 --- a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter5.cxx +++ b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter5.cxx @@ -8,13 +8,13 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + #include "CCDB/BasicCCDBManager.h" #include "DataFormatsParameters/AggregatedRunInfo.h" -#include "ITStracking/Vertexer.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" using namespace o2; using namespace o2::framework; diff --git a/PWGLF/TableProducer/Strangeness/LFStrangeTreeCreator.cxx b/PWGLF/TableProducer/Strangeness/LFStrangeTreeCreator.cxx index 955b4ebc142..4ab2f0cc745 100644 --- a/PWGLF/TableProducer/Strangeness/LFStrangeTreeCreator.cxx +++ b/PWGLF/TableProducer/Strangeness/LFStrangeTreeCreator.cxx @@ -157,8 +157,8 @@ struct LFStrangeTreeCreator { int mRunNumber; float d_bz; - // o2::base::MatLayerCylSet* lut = nullptr; - Configurable cfgMaterialCorrection{"cfgMaterialCorrection", static_cast(o2::base::Propagator::MatCorrType::USEMatCorrNONE), "Type of material correction"}; + o2::base::MatLayerCylSet* lut = nullptr; + Configurable cfgMaterialCorrection{"cfgMaterialCorrection", static_cast(o2::base::Propagator::MatCorrType::USEMatCorrLUT), "Type of material correction"}; ConfigurableAxis centAxis{"centAxis", {106, 0, 106}, "binning for the centrality"}; ConfigurableAxis zVtxAxis{"zVtxBins", {100, -20.f, 20.f}, "Binning for the vertex z in cm"}; @@ -248,7 +248,11 @@ struct LFStrangeTreeCreator { mRunNumber = bc.runNumber(); fitter.setBz(d_bz); - // o2::base::Propagator::Instance()->setMatLUT(lut); + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get("GLO/Param/MatLUT")); + o2::base::Propagator::Instance()->setMatLUT(lut); + + int mat{static_cast(cfgMaterialCorrection)}; + fitter.setMatCorrType(static_cast(mat)); } void init(o2::framework::InitContext&) @@ -261,7 +265,6 @@ struct LFStrangeTreeCreator { ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); ccdb->setFatalWhenNull(false); - // lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get("GLO/Param/MatLUT")); fitter.setPropagateToPCA(true); fitter.setMaxR(200.); @@ -272,8 +275,6 @@ struct LFStrangeTreeCreator { fitter.setMaxChi2(1e9); fitter.setUseAbsDCA(true); fitter.setWeightedFinalPCA(false); - int mat{static_cast(cfgMaterialCorrection)}; - fitter.setMatCorrType(static_cast(mat)); // event QA histos.add("QA/zVtx", ";#it{z}_{vtx} (cm);Entries", HistType::kTH1F, {zVtxAxis}); diff --git a/PWGLF/TableProducer/Strangeness/cascadebuilder.cxx b/PWGLF/TableProducer/Strangeness/cascadebuilder.cxx index 453072b6b30..b4a19e6660b 100644 --- a/PWGLF/TableProducer/Strangeness/cascadebuilder.cxx +++ b/PWGLF/TableProducer/Strangeness/cascadebuilder.cxx @@ -2388,14 +2388,6 @@ struct cascadePreselector { //*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<*>-~-<* }; -/// Extends the cascdata table with expression columns -struct cascadeInitializer { - Spawns cascdataext; - Spawns kfcascdataext; - Spawns tracascdataext; - void init(InitContext const&) {} -}; - struct cascadeLinkBuilder { Produces cascdataLink; @@ -2482,7 +2474,6 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) return WorkflowSpec{ adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc)}; diff --git a/PWGLF/TableProducer/Strangeness/cascadefinder.cxx b/PWGLF/TableProducer/Strangeness/cascadefinder.cxx index fcb0479fca2..3901d3f14c3 100644 --- a/PWGLF/TableProducer/Strangeness/cascadefinder.cxx +++ b/PWGLF/TableProducer/Strangeness/cascadefinder.cxx @@ -430,17 +430,10 @@ struct cascadefinderQA { } }; -/// Extends the cascdata table with expression columns -struct cascadeinitializer { - Spawns cascdataext; - void init(InitContext const&) {} -}; - WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ adaptAnalysisTask(cfgc, TaskName{"lf-cascadeprefilter"}), adaptAnalysisTask(cfgc, TaskName{"lf-cascadefinder"}), - adaptAnalysisTask(cfgc, TaskName{"lf-cascadefinderQA"}), - adaptAnalysisTask(cfgc, TaskName{"lf-cascadeinitializer"})}; + adaptAnalysisTask(cfgc, TaskName{"lf-cascadefinderQA"})}; } diff --git a/PWGLF/TableProducer/Strangeness/cascadespawner.cxx b/PWGLF/TableProducer/Strangeness/cascadespawner.cxx index dc004b91e78..ab3f4cb7c3d 100644 --- a/PWGLF/TableProducer/Strangeness/cascadespawner.cxx +++ b/PWGLF/TableProducer/Strangeness/cascadespawner.cxx @@ -35,7 +35,7 @@ using namespace o2::framework::expressions; /// Extends the cascdata table with expression columns struct cascadespawner { - Spawns cascdataext; + // Spawns cascdataext; void init(InitContext const&) {} }; diff --git a/PWGLF/TableProducer/Strangeness/hStrangeCorrelationFilter.cxx b/PWGLF/TableProducer/Strangeness/hStrangeCorrelationFilter.cxx index 6fdccd95a51..6bb0ac92517 100644 --- a/PWGLF/TableProducer/Strangeness/hStrangeCorrelationFilter.cxx +++ b/PWGLF/TableProducer/Strangeness/hStrangeCorrelationFilter.cxx @@ -18,23 +18,26 @@ /// \author David Dobrigkeit Chinellato (david.dobrigkeit.chinellato@cern.ch) /// \author Zhongbao Yin (Zhong-Bao.Yin@cern.ch) -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" #include "PWGLF/DataModel/LFHStrangeCorrelationTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/PIDResponse.h" -#include "Framework/ASoAHelpers.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "EventFiltering/Zorro.h" +#include "EventFiltering/ZorroSummary.h" + #include "CCDB/BasicCCDBManager.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + #include "TF1.h" -#include "string" #include -#include "EventFiltering/Zorro.h" -#include "EventFiltering/ZorroSummary.h" +#include using namespace o2; using namespace o2::constants::math; diff --git a/PWGLF/TableProducer/Strangeness/lambdakzerobuilder.cxx b/PWGLF/TableProducer/Strangeness/lambdakzerobuilder.cxx index bcf2c1268e2..7b898bfa98e 100644 --- a/PWGLF/TableProducer/Strangeness/lambdakzerobuilder.cxx +++ b/PWGLF/TableProducer/Strangeness/lambdakzerobuilder.cxx @@ -1808,18 +1808,10 @@ struct lambdakzeroV0DataLinkBuilder { PROCESS_SWITCH(lambdakzeroV0DataLinkBuilder, processFindable, "process findable V0s", false); }; -// Extends the v0data table with expression columns -struct lambdakzeroInitializer { - Spawns v0cores; - Spawns v0fccores; - void init(InitContext const&) {} -}; - WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc)}; } diff --git a/PWGLF/TableProducer/Strangeness/lambdakzerofinder.cxx b/PWGLF/TableProducer/Strangeness/lambdakzerofinder.cxx index 60d331ea61d..e75c72c77f4 100644 --- a/PWGLF/TableProducer/Strangeness/lambdakzerofinder.cxx +++ b/PWGLF/TableProducer/Strangeness/lambdakzerofinder.cxx @@ -429,17 +429,10 @@ struct lambdakzerofinderQa { PROCESS_SWITCH(lambdakzerofinderQa, processRun2, "Process Run 2 data", false); }; -/// Extends the v0data table with expression columns -struct lambdakzeroinitializer { - Spawns v0cores; - void init(InitContext const&) {} -}; - WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ adaptAnalysisTask(cfgc, TaskName{"lf-lambdakzeroprefilter"}), adaptAnalysisTask(cfgc, TaskName{"lf-lambdakzerofinder"}), - adaptAnalysisTask(cfgc, TaskName{"lf-lambdakzerofinderQA"}), - adaptAnalysisTask(cfgc, TaskName{"lf-lambdakzeroinitializer"})}; + adaptAnalysisTask(cfgc, TaskName{"lf-lambdakzerofinderQA"})}; } diff --git a/PWGLF/TableProducer/Strangeness/lambdakzerospawner.cxx b/PWGLF/TableProducer/Strangeness/lambdakzerospawner.cxx index 7ec0b4cc010..19c174aef7f 100644 --- a/PWGLF/TableProducer/Strangeness/lambdakzerospawner.cxx +++ b/PWGLF/TableProducer/Strangeness/lambdakzerospawner.cxx @@ -35,7 +35,7 @@ using namespace o2::framework::expressions; // Extends the v0data table with expression columns struct lambdakzerospawner { - Spawns v0cores; + // Spawns v0cores; void init(InitContext const&) {} }; diff --git a/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx b/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx index ecc0136a438..c38c792f5e1 100644 --- a/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx +++ b/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx @@ -196,12 +196,12 @@ struct StrangenessBuilder { kCascFoundTags, nTables }; - enum V0PreSelection : uint8_t { selGamma = 0, + enum V0PreSelection : uint8_t { selGamma = static_cast(1) << static_cast(0), selK0Short, selLambda, selAntiLambda }; - enum CascPreSelection : uint8_t { selXiMinus = 0, + enum CascPreSelection : uint8_t { selXiMinus = static_cast(1) << static_cast(0), selXiPlus, selOmegaMinus, selOmegaPlus }; @@ -301,6 +301,9 @@ struct StrangenessBuilder { Configurable mc_findableMode{"mc_findableMode", 0, "0: disabled; 1: add findable-but-not-found to existing V0s from AO2D; 2: reset V0s and generate only findable-but-not-found"}; + // Autoconfigure process functions + Configurable autoConfigureProcess{"autoConfigureProcess", false, "if true, will configure process function switches based on metadata"}; + // V0 building options struct : ConfigurableGroup { std::string prefix = "v0BuilderOpts"; @@ -2644,18 +2647,77 @@ struct StrangenessBuilder { PROCESS_SWITCH(StrangenessBuilder, processMonteCarloRun2WithPID, "process monte carlo (Run 2)", false); }; -// Extends the v0data table with expression columns -struct strangenessbuilderInitializer { - Spawns v0cores; - Spawns cascdataext; - Spawns kfcascdataext; - Spawns tracascdataext; - void init(InitContext const&) {} -}; - WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { + auto strangenessBuilderTask = adaptAnalysisTask(cfgc); + bool isRun3 = true, hasRunInfo = false; + bool isMC = false, hasDataTypeInfo = false; + if (cfgc.options().hasOption("aod-metadata-Run") == true) { + hasRunInfo = true; + if (cfgc.options().get("aod-metadata-Run") == "2") { + isRun3 = false; + } + } + if (cfgc.options().hasOption("aod-metadata-DataType") == true) { + hasDataTypeInfo = true; + if (cfgc.options().get("aod-metadata-DataType") == "MC") { + isMC = true; + } + } + + int idxSwitches[8]; // 8 switches (real / real r2 / MC / MC r2 + PID) + bool autoConfigureProcessConfig = true; + bool withPID = false; + + for (size_t ipar = 0; ipar < strangenessBuilderTask.options.size(); ipar++) { + auto option = strangenessBuilderTask.options[ipar]; + if (option.name == "processRealData") { + idxSwitches[0] = ipar; + } + if (option.name == "processRealDataRun2") { + idxSwitches[1] = ipar; + } + if (option.name == "processMonteCarlo") { + idxSwitches[2] = ipar; + } + if (option.name == "processMonteCarloRun2") { + idxSwitches[3] = ipar; + } + if (option.name == "processRealDataWithPID") { + idxSwitches[4] = ipar; + } + if (option.name == "processRealDataRun2WithPID") { + idxSwitches[5] = ipar; + } + if (option.name == "processMonteCarloWithPID") { + idxSwitches[6] = ipar; + } + if (option.name == "processMonteCarloRun2WithPID") { + idxSwitches[7] = ipar; + } + if (option.name == "autoConfigureProcess") { + autoConfigureProcessConfig = option.defaultValue.get(); // check if autoconfig requested + } + // use withPID in case preselection is requested + if (option.name == "preSelectOpts.preselectOnlyDesiredV0s" || option.name == "preSelectOpts.preselectOnlyDesiredCascades") { + withPID = withPID || option.defaultValue.get(); + } + } + if ((!hasRunInfo || !hasDataTypeInfo) && autoConfigureProcessConfig) { + throw std::runtime_error("Autoconfigure requested but no metadata information found! Please check if --aod-file was used in the last workflow added in the execution and if the AO2D in question has metadata saved in it."); + } + + // positions of switches are known. Next: flip if asked for + if (autoConfigureProcessConfig) { + int relevantProcess = static_cast(!isRun3) + 2 * static_cast(isMC) + 4 * static_cast(withPID); + LOGF(info, "Automatic configuration of process switches requested! Autodetected settings: isRun3? %i, isMC? %i, withPID? %i (switch #%i)", hasRunInfo, hasDataTypeInfo, isRun3, isMC, withPID, relevantProcess); + for (size_t idx = 0; idx < 8; idx++) { + auto option = strangenessBuilderTask.options[idxSwitches[idx]]; + option.defaultValue = false; // switch all off + } + strangenessBuilderTask.options[idxSwitches[relevantProcess]].defaultValue = true; + } + return WorkflowSpec{ - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc)}; + strangenessBuilderTask}; } diff --git a/PWGLF/Tasks/GlobalEventProperties/uccZdc.cxx b/PWGLF/Tasks/GlobalEventProperties/uccZdc.cxx index 0aa0e4ff5a5..7da02f51416 100644 --- a/PWGLF/Tasks/GlobalEventProperties/uccZdc.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/uccZdc.cxx @@ -65,8 +65,8 @@ using SimTracks = soa::Join isNoCollInTimeRangeStrict{"isNoCollInTimeRangeStrict", true, "use isNoCollInTimeRangeStrict?"}; @@ -96,18 +96,25 @@ struct UccZdc { // Track-kinematics selection Configurable minPt{"minPt", 0.1, "minimum pt of the tracks"}; - Configurable maxPt{"maxPt", 50., "maximum pt of the tracks"}; + Configurable maxPt{"maxPt", 3., "maximum pt of the tracks"}; + Configurable maxPtSpectra{"maxPtSpectra", 50., "maximum pt of the tracks"}; Configurable minEta{"minEta", -0.8, "minimum eta"}; Configurable maxEta{"maxEta", +0.8, "maximum eta"}; // Configurables, binning + Configurable nBinsITSTrack{"nBinsITSTrack", 2000, "N bins ITS tracks"}; + Configurable minITSTrack{"minITSTrack", 0., "Min ITS tracks"}; + Configurable maxITSTrack{"maxITSTrack", 6000., "Min ITS tracks"}; Configurable maxAmpFV0{"maxAmpFV0", 2000, "Max FV0 amp"}; Configurable nBinsAmpFT0{"nBinsAmpFT0", 100, "N bins FT0 amp"}; + Configurable nBinsAmpFT0Fine{"nBinsAmpFT0Fine", 1000, "N bins FT0 amp"}; Configurable maxAmpFT0{"maxAmpFT0", 2500, "Max FT0 amp"}; Configurable nBinsNch{"nBinsNch", 2501, "N bins Nch (|eta|<0.8)"}; + Configurable nBinsNchFine{"nBinsNchFine", 3000, "N bins Nch (|eta|<0.8)"}; Configurable minNch{"minNch", 0, "Min Nch (|eta|<0.8)"}; - Configurable maxNch{"maxNch", 2500, "Max Nch (|eta|<0.8)"}; - Configurable nBinsZDC{"nBinsZDC", 400, "N bins ZDC"}; + Configurable maxNch{"maxNch", 3000, "Max Nch (|eta|<0.8)"}; + Configurable nBinsZN{"nBinsZN", 400, "N bins ZN"}; + Configurable nBinsZP{"nBinsZP", 160, "N bins ZP"}; Configurable minZN{"minZN", 0, "Min ZN signal"}; Configurable maxZN{"maxZN", 150, "Max ZN signal"}; Configurable maxZP{"maxZP", 60, "Max ZP signal"}; @@ -144,8 +151,7 @@ struct UccZdc { Zem }; - // Filter trackFilter = ((aod::track::eta > minEta) && (aod::track::eta < maxEta) && (aod::track::pt > minPt) && (aod::track::pt < maxPt) && requireGlobalTrackInFilter()); - Filter trackFilter = ((aod::track::eta > minEta) && (aod::track::eta < maxEta) && (aod::track::pt > minPt) && (aod::track::pt < maxPt)); + Filter trackFilter = ((aod::track::eta > minEta) && (aod::track::eta < maxEta)); // Apply Filters using TheFilteredTracks = soa::Filtered; @@ -171,7 +177,7 @@ struct UccZdc { registry.add("T0Ccent", ";;Entries", kTH1F, {axisCent}); registry.add("NchUncorrected", ";#it{N}_{ch} (|#eta| < 0.8);Entries;", kTH1F, {{300, 0., 3000.}}); registry.add("hEventCounter", ";;Events", kTH1F, {axisEvent}); - registry.add("ZNamp", ";ZNA+ZNC;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZN}}); + registry.add("ZNamp", ";ZNA+ZNC;Entries;", kTH1F, {{nBinsZN, -0.5, maxZN}}); registry.add("ExcludedEvtVsFT0M", ";T0A+T0C (#times 1/100, -3.3 < #eta < -2.1 and 3.5 < #eta < 4.9);Entries;", kTH1F, {{nBinsAmpFT0, 0., maxAmpFT0}}); registry.add("ExcludedEvtVsNch", ";#it{N}_{ch} (|#eta|<0.8);Entries;", kTH1F, {{300, 0, 3000}}); registry.add("Nch", ";#it{N}_{ch} (|#eta| < 0.8, Corrected);", kTH1F, {{nBinsNch, minNch, maxNch}}); @@ -202,11 +208,17 @@ struct UccZdc { x->SetBinLabel(17, "Within ZEM cut?"); if (doprocessZdcCollAss) { - registry.add("NchVsPt", ";#it{N}_{ch} (|#eta| < 0.8, Corrected);;", kTH2F, {{{nBinsNch, minNch, maxNch}, {axisPt}}}); - registry.add("NchVsOneParCorrVsZN", ";#it{N}_{ch} (|#eta| < 0.8, Corrected); ZNA+ZNC; #LT[#it{p}_{T}^{(1)}]#GT", kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, -0.5, maxZN}}}); - registry.add("NchVsTwoParCorrVsZN", ";#it{N}_{ch} (|#eta| < 0.8, Corrected);ZNA+ZNC;#LT[#it{p}_{T}^{(2)}]#GT", kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, -0.5, maxZN}}}); - registry.add("NchVsThreeParCorrVsZN", ";#it{N}_{ch} (|#eta| < 0.8, Corrected);ZNA+ZNC;#LT[#it{p}_{T}^{(3)}]#GT", kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, -0.5, maxZN}}}); - registry.add("NchVsFourParCorrVsZN", ";#it{N}_{ch} (|#eta| < 0.8, Corrected);ZNA+ZNC;#LT[#it{p}_{T}^{(4)}]#GT", kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, -0.5, maxZN}}}); + registry.add("NchVsZN", ";#it{N}_{ch} (|#eta| < 0.8); ZNA+ZNC;", kTH2F, {{{nBinsNchFine, minNch, maxNch}, {nBinsZN, -0.5, maxZN}}}); + registry.add("NchVsZP", ";#it{N}_{ch} (|#eta| < 0.8); ZPA+ZPC;", kTH2F, {{{nBinsNchFine, minNch, maxNch}, {nBinsZP, -0.5, maxZP}}}); + registry.add("NITSTacksVsZN", ";ITS tracks; ZNA+ZNC;", kTH2F, {{{nBinsITSTrack, minITSTrack, maxITSTrack}, {nBinsZN, -0.5, maxZN}}}); + registry.add("NITSTacksVsZP", ";ITS tracks; ZPA+ZPC;", kTH2F, {{{nBinsITSTrack, minITSTrack, maxITSTrack}, {nBinsZP, -0.5, maxZP}}}); + registry.add("T0MVsZN", ";T0A+T0C amp (#times 1/100); ZNA+ZNC;", kTH2F, {{{nBinsAmpFT0Fine, 0., maxAmpFT0}, {nBinsZN, -0.5, maxZN}}}); + registry.add("T0MVsZP", ";T0A+T0C amp (#times 1/100); ZPA+ZPC;", kTH2F, {{{nBinsAmpFT0Fine, 0., maxAmpFT0}, {nBinsZP, -0.5, maxZP}}}); + registry.add("NchVsZNVsPt", ";#it{N}_{ch} (|#eta| < 0.8); ZNA+ZNC;#it{p}_{T} (GeV/#it{c})", kTH3F, {{{nBinsNch, minNch, maxNch}, {nBinsZN, -0.5, maxZN}, {axisPt}}}); + registry.add("NchVsOneParCorrVsZN", ";#it{N}_{ch} (|#eta| < 0.8, Corrected); ZNA+ZNC; #LT[#it{p}_{T}^{(1)}]#G (GeV/#it{c})T", kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZN, -0.5, maxZN}}}); + registry.add("NchVsTwoParCorrVsZN", ";#it{N}_{ch} (|#eta| < 0.8, Corrected);ZNA+ZNC;#LT[#it{p}_{T}^{(2)}]#GT", kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZN, -0.5, maxZN}}}); + registry.add("NchVsThreeParCorrVsZN", ";#it{N}_{ch} (|#eta| < 0.8, Corrected);ZNA+ZNC;#LT[#it{p}_{T}^{(3)}]#GT", kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZN, -0.5, maxZN}}}); + registry.add("NchVsFourParCorrVsZN", ";#it{N}_{ch} (|#eta| < 0.8, Corrected);ZNA+ZNC;#LT[#it{p}_{T}^{(4)}]#GT", kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZN, -0.5, maxZN}}}); } if (doprocessMCclosure) { @@ -260,21 +272,21 @@ struct UccZdc { registry.add("NchVsEt", ";#it{E}_{T} (|#eta|<0.8);#LTITS+TPC tracks#GT (|#eta|<0.8);", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsNch, minNch, maxNch}}}); registry.add("NchVsNPV", ";#it{N}_{PV} (|#eta|<1);ITS+TPC tracks (|#eta|<0.8);", kTH2F, {{{300, -0.5, 5999.5}, {nBinsNch, minNch, maxNch}}}); registry.add("NchVsITStracks", ";ITS tracks nCls >= 5;TITS+TPC tracks (|#eta|<0.8);", kTH2F, {{{300, -0.5, 5999.5}, {nBinsNch, minNch, maxNch}}}); - registry.add("ZNVsFT0A", ";T0A (#times 1/100);ZNA+ZNC;", kTH2F, {{{80, 0., 1800.}, {nBinsZDC, -0.5, maxZN}}}); - registry.add("ZNVsFT0C", ";T0C (#times 1/100);ZNA+ZNC;", kTH2F, {{{80, 0., 600.}, {nBinsZDC, -0.5, maxZN}}}); - registry.add("ZNVsFT0M", ";T0A+T0C (#times 1/100);ZNA+ZNC;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZN}}}); - registry.add("ZNAamp", ";ZNA;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZN}}); - registry.add("ZPAamp", ";ZPA;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZP}}); - registry.add("ZNCamp", ";ZNC;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZN}}); - registry.add("ZPCamp", ";ZPC;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZP}}); + registry.add("ZNVsFT0A", ";T0A (#times 1/100);ZNA+ZNC;", kTH2F, {{{80, 0., 1800.}, {nBinsZN, -0.5, maxZN}}}); + registry.add("ZNVsFT0C", ";T0C (#times 1/100);ZNA+ZNC;", kTH2F, {{{80, 0., 600.}, {nBinsZN, -0.5, maxZN}}}); + registry.add("ZNVsFT0M", ";T0A+T0C (#times 1/100);ZNA+ZNC;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZN, -0.5, maxZN}}}); + registry.add("ZNAamp", ";ZNA;Entries;", kTH1F, {{nBinsZN, -0.5, maxZN}}); + registry.add("ZPAamp", ";ZPA;Entries;", kTH1F, {{nBinsZP, -0.5, maxZP}}); + registry.add("ZNCamp", ";ZNC;Entries;", kTH1F, {{nBinsZN, -0.5, maxZN}}); + registry.add("ZPCamp", ";ZPC;Entries;", kTH1F, {{nBinsZP, -0.5, maxZP}}); registry.add("ZNAVsZNC", ";ZNC;ZNA", kTH2F, {{{30, -0.5, maxZN}, {30, -0.5, maxZN}}}); registry.add("ZPAVsZPC", ";ZPC;ZPA;", kTH2F, {{{100, -0.5, maxZP}, {100, -0.5, maxZP}}}); registry.add("ZNAVsZPA", ";ZPA;ZNA;", kTH2F, {{{20, -0.5, maxZP}, {30, -0.5, maxZN}}}); registry.add("ZNCVsZPC", ";ZPC;ZNC;", kTH2F, {{{20, -0.5, maxZP}, {30, -0.5, maxZN}}}); registry.add("ZNVsZEM", ";ZEM;ZNA+ZNC;", kTH2F, {{{60, -0.5, maxZEM}, {60, -0.5, maxZN}}}); - registry.add("ZNCVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNC;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minZN, maxZN}}}); - registry.add("ZNAVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minZN, maxZN}}}); - registry.add("ZNVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA+ZNC;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minZN, maxZN}}}); + registry.add("ZNCVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNC;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZN, minZN, maxZN}}}); + registry.add("ZNAVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZN, minZN, maxZN}}}); + registry.add("ZNVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA+ZNC;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZN, minZN, maxZN}}}); registry.add("ZNDifVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA-ZNC;", kTH2F, {{{nBinsNch, minNch, maxNch}, {100, -50., 50.}}}); } @@ -284,6 +296,9 @@ struct UccZdc { LOG(info) << "\tuseMidRapNchSel=" << useMidRapNchSel.value; LOG(info) << "\tpaTHmeanNch=" << paTHmeanNch.value; LOG(info) << "\tpaTHsigmaNch=" << paTHsigmaNch.value; + LOG(info) << "\tminPt=" << minPt.value; + LOG(info) << "\tmaxPt=" << maxPt.value; + LOG(info) << "\tmaxPtSpectra=" << maxPtSpectra.value; ccdb->setURL("http://alice-ccdb.cern.ch"); // Enabling object caching, otherwise each call goes to the CCDB server @@ -429,10 +444,10 @@ struct UccZdc { float tZPC{zdc.timeZPC()}; float tZDCdif{tZNC + tZPC - tZNA - tZPA}; float tZDCsum{tZNC + tZPC + tZNA + tZPA}; - znA /= collEnergy; - znC /= collEnergy; - zpA /= collEnergy; - zpC /= collEnergy; + znA /= kCollEnergy; + znC /= kCollEnergy; + zpA /= kCollEnergy; + zpC /= kCollEnergy; float sumZNs{znA + znC}; float sumZEMs{aZEM1 + aZEM2}; @@ -461,6 +476,9 @@ struct UccZdc { if (!track.isGlobalTrack()) { continue; } + if ((track.pt() < minPt) || (track.pt() > maxPt)) { + continue; + } glbTracks++; } @@ -501,6 +519,9 @@ struct UccZdc { if (!track.isGlobalTrack()) { continue; } + if ((track.pt() < minPt) || (track.pt() > maxPtSpectra)) { + continue; + } registry.fill(HIST("ZposVsEta"), collision.posZ(), track.eta()); registry.fill(HIST("EtaVsPhi"), track.eta(), track.phi()); @@ -576,6 +597,8 @@ struct UccZdc { const double normT0M{(aT0A + aT0C) / 100.}; float znA{foundBC.zdc().amplitudeZNA()}; float znC{foundBC.zdc().amplitudeZNC()}; + float zpA{foundBC.zdc().amplitudeZPA()}; + float zpC{foundBC.zdc().amplitudeZPC()}; float aZEM1{foundBC.zdc().amplitudeZEM1()}; float aZEM2{foundBC.zdc().amplitudeZEM2()}; float tZNA{foundBC.zdc().timeZNA()}; @@ -584,9 +607,12 @@ struct UccZdc { float tZPC{foundBC.zdc().timeZPC()}; float tZDCdif{tZNC + tZPC - tZNA - tZPA}; float tZDCsum{tZNC + tZPC + tZNA + tZPA}; - znA /= collEnergy; - znC /= collEnergy; + znA /= kCollEnergy; + znC /= kCollEnergy; + zpA /= kCollEnergy; + zpC /= kCollEnergy; float sumZNs{znA + znC}; + float sumZPs{zpA + zpC}; float sumZEMs{aZEM1 + aZEM2}; // TDC cut @@ -609,12 +635,18 @@ struct UccZdc { registry.fill(HIST("T0Ccent"), collision.centFT0C()); // Nch-based selection - int glbTracks{0}; + int itsTracks = 0, glbTracks = 0; for (const auto& track : tracks) { // Track Selection + if (track.hasITS()) { + itsTracks++; + } if (!track.isGlobalTrack()) { continue; } + if ((track.pt() < minPt) || (track.pt() > maxPt)) { + continue; + } registry.fill(HIST("ZposVsEta"), collision.posZ(), track.eta()); registry.fill(HIST("EtaVsPhi"), track.eta(), track.phi()); registry.fill(HIST("sigma1Pt"), track.pt(), track.sigma1Pt()); @@ -667,6 +699,9 @@ struct UccZdc { if (!track.isGlobalTrack()) { continue; } + if ((track.pt() < minPt) || (track.pt() > maxPtSpectra)) { + continue; + } float pt{track.pt()}; double weight{1.}; @@ -693,7 +728,10 @@ struct UccZdc { if (!track.isGlobalTrack()) { continue; } - registry.fill(HIST("NchVsPt"), w1, track.pt()); + if ((track.pt() < minPt) || (track.pt() > maxPtSpectra)) { + continue; + } + registry.fill(HIST("NchVsZNVsPt"), w1, sumZNs, track.pt()); } // EbE one-particle pT correlation @@ -716,6 +754,12 @@ struct UccZdc { registry.fill(HIST("Nch"), w1); registry.fill(HIST("ZNamp"), sumZNs); + registry.fill(HIST("NchVsZN"), w1, sumZNs); + registry.fill(HIST("NchVsZP"), w1, sumZPs); + registry.fill(HIST("NITSTacksVsZN"), itsTracks, sumZNs); + registry.fill(HIST("NITSTacksVsZP"), itsTracks, sumZPs); + registry.fill(HIST("T0MVsZN"), normT0M, sumZNs); + registry.fill(HIST("T0MVsZP"), normT0M, sumZPs); registry.fill(HIST("NchUncorrected"), glbTracks); registry.fill(HIST("NchVsOneParCorr"), w1, oneParCorr, w1); registry.fill(HIST("NchVsOneParCorrVsZN"), w1, sumZNs, oneParCorr, w1); @@ -760,7 +804,7 @@ struct UccZdc { registry.fill(HIST("T0Ccent"), cent); // Half of the statistics for MC closure - if (rndNum >= zEro && rndNum < evtFracMCcl) { + if (rndNum >= kZero && rndNum < evtFracMCcl) { registry.fill(HIST("EvtsDivided"), 0); // To use run-by-run efficiency diff --git a/PWGLF/Tasks/Nuspex/CMakeLists.txt b/PWGLF/Tasks/Nuspex/CMakeLists.txt index 3493f5fbd6f..b2af549c871 100644 --- a/PWGLF/Tasks/Nuspex/CMakeLists.txt +++ b/PWGLF/Tasks/Nuspex/CMakeLists.txt @@ -49,11 +49,6 @@ o2physics_add_dpl_workflow(hyhefour-analysis PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(antid-lambda-ebye - SOURCES antidLambdaEbye.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(mc-spectra-efficiency SOURCES mcspectraefficiency.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -139,11 +134,6 @@ o2physics_add_dpl_workflow(nuclei-toward-transv PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(ebye-mult - SOURCES ebyeMult.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(nuclei-from-hypertriton-map SOURCES nucleiFromHypertritonMap.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGLF/Tasks/Nuspex/angularCorrelationsInJets.cxx b/PWGLF/Tasks/Nuspex/angularCorrelationsInJets.cxx index 98ee6bfa968..a6fc4bf6032 100644 --- a/PWGLF/Tasks/Nuspex/angularCorrelationsInJets.cxx +++ b/PWGLF/Tasks/Nuspex/angularCorrelationsInJets.cxx @@ -14,32 +14,36 @@ /// \author Lars Jörgensen (lars.christian.joergensen@cern.ch) /// \brief task for analysis of angular correlations in jets using Fastjet -#include -#include -#include -#include -#include +#include "PWGJE/Core/JetBkgSubUtils.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" -#include "CCDB/BasicCCDBManager.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/Core/PID/PIDTOF.h" +#include "Common/Core/RecoDecay.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponse.h" -#include "Common/Core/PID/PIDTOF.h" +#include "Common/DataModel/TrackSelectionTables.h" #include "Common/TableProducer/PID/pidTOFBase.h" -#include "Common/Core/RecoDecay.h" -#include "fastjet/PseudoJet.hh" +#include "CCDB/BasicCCDBManager.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include "TPDGCode.h" +#include "TVector3.h" + #include "fastjet/AreaDefinition.hh" #include "fastjet/ClusterSequenceArea.hh" #include "fastjet/GhostedAreaSpec.hh" -#include "PWGJE/Core/JetBkgSubUtils.h" -#include "TVector3.h" -#include "TPDGCode.h" +#include "fastjet/PseudoJet.hh" + +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -66,7 +70,9 @@ struct AngularCorrelationsInJets { Configurable dopipiCorrelations{"dopipiCorrelations", false, "measure correlations for pi+-p+, pi--pi-"}; Configurable doJetCorrelations{"doJetCorrelations", false, "measure correlations for all particles inside jets"}; Configurable doFullCorrelations{"doFullCorrelations", false, "measure correlations for all particles in an event"}; + Configurable doUECorrelations{"doUECorrelations", false, "measure correlations for p-p, pbar-pbar in cone perp. to jet"}; Configurable measureKaons{"measureKaons", false, "measure correlations for K-K"}; + Configurable useBkgEstimateForUE{"useBkgEstimateForUE", false, "use bkg density for anti-kt-style clustering in UE"}; Configurable rejectEvents{"rejectEvents", false, "reject some events"}; Configurable rejectionPercentage{"rejectionPercentage", 3, "percentage of events to reject"}; @@ -120,7 +126,6 @@ struct AngularCorrelationsInJets { // QC Configurables Configurable zVtx{"zVtx", 10.0, "max zVertex"}; - Configurable rMax{"rMax", 0.3, "Maximum radius for jet and UE regions"}; Service ccdb; int mRunNumber; @@ -136,7 +141,7 @@ struct AngularCorrelationsInJets { using BCsWithRun2Info = soa::Join; using McCollisions = soa::Join; - Filter prelimTrackCuts = (aod::track::itsChi2NCl < maxChi2ITS && + Filter prelimTrackCuts = (aod::track::itsChi2NCl < maxChi2ITS && // some of the track cuts already as filter aod::track::tpcChi2NCl < maxChi2TPC && nabs(aod::track::dcaXY) < maxDCAxy && nabs(aod::track::dcaZ) < maxDCAz && @@ -147,7 +152,7 @@ struct AngularCorrelationsInJets { Preslice perCollisionMcTracksRun2 = o2::aod::track::collisionId; Preslice perCollisionMcTracksRun3 = o2::aod::track::collisionId; - AxisSpecs axisSpecs; + AxisSpecs axisSpecs; // struct for axis specs because at one point there were too many variables for the compiler HistogramRegistry registryData{"data", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; HistogramRegistry registryMC{"MC", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; @@ -158,7 +163,7 @@ struct AngularCorrelationsInJets { void init(o2::framework::InitContext&) { - mRunNumber = 0; + mRunNumber = 0; // this block is a remnant from the run2 code adapted here ccdb->setURL("http://alice-ccdb.cern.ch"); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); @@ -220,6 +225,21 @@ struct AngularCorrelationsInJets { registryData.add("deltaPhiEtaMEProtonAntiproton", "#Delta#varphi vs #Delta#eta of proton-antiproton in mixed events", HistType::kTH2D, {axisSpecs.angDistPhiAxis, axisSpecs.angDistEtaAxis}); } + if (doUECorrelations) { + registryData.add("deltaPhiSEProtonUE", "#Delta#varphi of UE protons in same event", HistType::kTH1D, {axisSpecs.angDistPhiAxis}); + registryData.add("deltaPhiMEProtonUE", "#Delta#varphi of UE protons in mixed events", HistType::kTH1D, {axisSpecs.angDistPhiAxis}); + registryData.add("deltaPhiEtaSEProtonUE", "#Delta#varphi vs #Delta#eta of UE protons in same event", HistType::kTH2D, {axisSpecs.angDistPhiAxis, axisSpecs.angDistEtaAxis}); + registryData.add("deltaPhiEtaMEProtonUE", "#Delta#varphi vs #Delta#eta of UE protons in mixed events", HistType::kTH2D, {axisSpecs.angDistPhiAxis, axisSpecs.angDistEtaAxis}); + registryData.add("deltaPhiSEAntiprotonUE", "#Delta#varphi of UE antiprotons in same event", HistType::kTH1D, {axisSpecs.angDistPhiAxis}); + registryData.add("deltaPhiMEAntiprotonUE", "#Delta#varphi of UE antiprotons in mixed events", HistType::kTH1D, {axisSpecs.angDistPhiAxis}); + registryData.add("deltaPhiEtaSEAntiprotonUE", "#Delta#varphi vs #Delta#eta of UE antiprotons in same event", HistType::kTH2D, {axisSpecs.angDistPhiAxis, axisSpecs.angDistEtaAxis}); + registryData.add("deltaPhiEtaMEAntiprotonUE", "#Delta#varphi vs #Delta#eta of UE antiprotons in mixed events", HistType::kTH2D, {axisSpecs.angDistPhiAxis, axisSpecs.angDistEtaAxis}); + registryData.add("deltaPhiSEPionUE", "#Delta#varphi of UE pions in same event", HistType::kTH1D, {axisSpecs.angDistPhiAxis}); + registryData.add("deltaPhiMEPionUE", "#Delta#varphi of UE pions in mixed events", HistType::kTH1D, {axisSpecs.angDistPhiAxis}); + registryData.add("deltaPhiEtaSEPionUE", "#Delta#varphi vs #Delta#eta of UE pions in same event", HistType::kTH2D, {axisSpecs.angDistPhiAxis, axisSpecs.angDistEtaAxis}); + registryData.add("deltaPhiEtaMEPionUE", "#Delta#varphi vs #Delta#eta of UE pions in mixed events", HistType::kTH2D, {axisSpecs.angDistPhiAxis, axisSpecs.angDistEtaAxis}); + } + if (doprocessMCRun2 || doprocessMCRun3 || doppCorrelations || doapapCorrelations || dopapCorrelations) { registryData.add("ptJetProton", "p_{T} of protons", HistType::kTH1D, {axisSpecs.ptAxisPos}); registryData.add("dcaZJetProton", "DCA_{z} of high purity protons", HistType::kTH2F, {axisSpecs.ptAxisPos, axisSpecs.dcazAxis}); @@ -297,18 +317,25 @@ struct AngularCorrelationsInJets { registryQC.add("deltaJetPt", "deltaJetPt", HistType::kTH1F, {{200, -2, 2, "#Delta#it{p}_{T} (GeV/#it{c})"}}); registryQC.add("nParticlesClusteredInJet", "nParticlesClusteredInJet", HistType::kTH1F, {{50, 0, 50, "#it{N}_{ch}"}}); registryQC.add("ptParticlesClusteredInJet", "ptParticlesClusteredInJet", HistType::kTH1F, {{200, 0, 10, "#it{p}_{T} (GeV/#it{c})"}}); + + registryQC.add("whichUECone", "whichUECone", HistType::kTH1D, {{2, 0, 2, "UE cone"}}); } } + // create track buffers outside processes so the tracks can be stored independently of events for mixed-event distributions std::vector> fBufferProton; std::vector> fBufferAntiproton; std::vector> fBufferPiPlus; std::vector> fBufferPiMinus; std::vector> fBufferJet; std::vector> fBufferFull; + std::vector> fBufferProtonsUE; + std::vector> fBufferAntiprotonsUE; + std::vector> fBufferPiPlusUE; + std::vector> fBufferPiMinusUE; template - void initCCDB(Bc const& bc) + void initCCDB(Bc const& bc) // remnant from run2 code { if (mRunNumber == bc.runNumber()) { return; @@ -397,8 +424,9 @@ struct AngularCorrelationsInJets { return true; } + // reject any track that has TPC nsigma < 3 for more than 1 species to avoid ambiguity (not really suitable for the low statistics in jets, thus optional) template - bool singleSpeciesTPCNSigma(T const& track) // reject any track that has TPC nsigma < 3 for more than 1 species + bool singleSpeciesTPCNSigma(T const& track) { if (useRejectionCut && (track.tpcNSigmaStoreEl() < nsigmaRejection || track.tpcNSigmaStoreMu() < nsigmaRejection || track.tpcNSigmaPi() < nsigmaRejection || track.tpcNSigmaKa() < nsigmaRejection || track.tpcNSigmaStoreTr() < nsigmaRejection || track.tpcNSigmaStoreAl() < nsigmaRejection || track.tpcNSigmaDe() < nsigmaRejection || track.tpcNSigmaHe() < nsigmaRejection)) return false; @@ -426,6 +454,7 @@ struct AngularCorrelationsInJets { double midPt = 1.5; double highPt = 3.0; + // set max nsigma depending on pt range double maxTPCnsigma = protonTPCnsigma; double maxTOFnsigma = protonTOFnsigma; if (pt > midPt) { @@ -437,6 +466,7 @@ struct AngularCorrelationsInJets { maxTOFnsigma = protonTOFnsigma - 2; } + // only TPC below 0.7 GeV registryData.fill(HIST("tpcNSigmaProton"), track.pt(), track.tpcNSigmaPr()); if (pt < protonTPCTOFpT && (std::abs(track.tpcNSigmaPr()) > maxTPCnsigma)) return false; @@ -447,10 +477,11 @@ struct AngularCorrelationsInJets { tofNSigma = track.tofNSigmaPr(); } + // require TOF as well above 0.7 GeV if (pt > protonTPCTOFpT && ((std::abs(tofNSigma) > maxTOFnsigma) || std::abs(track.tpcNSigmaPr()) > maxTPCnsigma)) return false; - if (useRejectionCut && !singleSpeciesTPCNSigma(track)) + if (useRejectionCut && !singleSpeciesTPCNSigma(track)) // useRejectionCut false by default return false; return true; @@ -477,6 +508,7 @@ struct AngularCorrelationsInJets { double midPt = 1.5; double highPt = 3.0; + // set max nsigma depending on pt range double maxTPCnsigma = antiprotonTPCnsigma; double maxTOFnsigma = antiprotonTOFnsigma; if (pt > midPt) { @@ -488,6 +520,7 @@ struct AngularCorrelationsInJets { maxTOFnsigma = antiprotonTOFnsigma - 2; } + // only TPC below 0.7 GeV registryData.fill(HIST("tpcNSigmaAntiproton"), track.pt(), track.tpcNSigmaPr()); if (pt < antiprotonTPCTOFpT && (std::abs(track.tpcNSigmaPr()) > maxTPCnsigma)) return false; @@ -498,6 +531,7 @@ struct AngularCorrelationsInJets { tofNSigma = track.tofNSigmaPr(); } + // require TOF as well above 0.7 GeV if (pt > antiprotonTPCTOFpT && ((std::abs(tofNSigma) > maxTOFnsigma) || std::abs(track.tpcNSigmaPr()) > maxTPCnsigma)) return false; @@ -510,6 +544,7 @@ struct AngularCorrelationsInJets { template bool isPion(const T& track) { + // looser cuts because it's pions and also because the results aren't used in ToMCCA // DCA if (std::abs(track.dcaXY()) > pionDCAxy) return false; @@ -537,6 +572,7 @@ struct AngularCorrelationsInJets { template bool isKaon(const T& track) { + // looser cuts because this was just for the particle-jet pt correlations // DCA if (std::abs(track.dcaXY()) > kaonDCAxy) return false; @@ -563,11 +599,11 @@ struct AngularCorrelationsInJets { void setTrackBuffer(const auto& tempBuffer, auto& buffer) // refresh track buffer { - for (const auto& pair : tempBuffer) { + for (const auto& pair : tempBuffer) { // loop over angles we collected during same-event correlations if (static_cast(buffer.size()) == trackBufferSize) { - buffer.insert(buffer.begin(), pair); - buffer.resize(trackBufferSize); - } else if (static_cast(buffer.size()) < trackBufferSize) { + buffer.insert(buffer.begin(), pair); // insert angles at the beginning + buffer.resize(trackBufferSize); // trim at the end, down to buffer size + } else if (static_cast(buffer.size()) < trackBufferSize) { // buffer not full yet buffer.emplace_back(pair); } } @@ -587,6 +623,8 @@ struct AngularCorrelationsInJets { continue; } + // deltaPhi = (difference track 1 to jet axis 1) - (difference track 2 to jet axis 2) + // overlay jet axes from different events to pretend tracks are from same jet double phiToAxis = RecoDecay::constrainAngle(track.phi() - jetAxis.Phi(), 0); double etaToAxis = track.eta() - jetAxis.Eta(); double deltaPhi = RecoDecay::constrainAngle(phiToAxis - buffer.at(i).first, -constants::math::PIHalf); @@ -617,6 +655,18 @@ struct AngularCorrelationsInJets { registryData.fill(HIST("deltaPhiMEProtonAntiproton"), deltaPhi); registryData.fill(HIST("deltaPhiEtaMEProtonAntiproton"), deltaPhi, deltaEta); break; + case 5: + registryData.fill(HIST("deltaPhiMEProtonUE"), deltaPhi); + registryData.fill(HIST("deltaPhiEtaMEProtonUE"), deltaPhi, deltaEta); + break; + case 6: + registryData.fill(HIST("deltaPhiMEAntiprotonUE"), deltaPhi); + registryData.fill(HIST("deltaPhiEtaMEAntiprotonUE"), deltaPhi, deltaEta); + break; + case 7: + registryData.fill(HIST("deltaPhiMEPionUE"), deltaPhi); + registryData.fill(HIST("deltaPhiEtaMEPionUE"), deltaPhi, deltaEta); + break; } } // for (int i = 0; i < static_cast(buffer.size()); i++) } @@ -625,16 +675,16 @@ struct AngularCorrelationsInJets { { if (std::isnan(jetAxis.Phi())) return; - for (int i = 0; i < static_cast(particleVector.size()); i++) { + for (int i = 0; i < static_cast(particleVector.size()); i++) { // loop over SE tracks if (std::isnan(particleVector.at(i).phi())) continue; - double phiToAxis = RecoDecay::constrainAngle(particleVector.at(i).phi() - jetAxis.Phi(), 0); + double phiToAxis = RecoDecay::constrainAngle(particleVector.at(i).phi() - jetAxis.Phi(), 0); // for use in ME function double etaToAxis = particleVector.at(i).eta() - jetAxis.Eta(); if (std::abs(particleVector.at(i).phi()) > constants::math::TwoPI) { registryData.fill(HIST("trackProtocol"), 11); // # tracks failed with phi > 2 pi continue; } - for (int j = i + 1; j < static_cast(particleVector.size()); j++) { + for (int j = i + 1; j < static_cast(particleVector.size()); j++) { // loop over remaining SE tracks if ((j == static_cast(particleVector.size())) || std::isnan(particleVector.at(j).phi())) continue; if (std::abs(particleVector.at(j).phi()) > constants::math::TwoPI) { @@ -642,7 +692,7 @@ struct AngularCorrelationsInJets { continue; } - double deltaPhi = RecoDecay::constrainAngle(particleVector.at(i).phi() - particleVector.at(j).phi(), -constants::math::PIHalf); + double deltaPhi = RecoDecay::constrainAngle(particleVector.at(i).phi() - particleVector.at(j).phi(), -constants::math::PIHalf); // dPhi in [-pi/2, 3pi/2] double deltaEta = particleVector.at(i).eta() - particleVector.at(j).eta(); switch (particleType) { case -1: @@ -665,14 +715,26 @@ struct AngularCorrelationsInJets { registryData.fill(HIST("deltaPhiSEPion"), deltaPhi); registryData.fill(HIST("deltaPhiEtaSEPion"), deltaPhi, deltaEta); break; + case 5: + registryData.fill(HIST("deltaPhiSEProtonUE"), deltaPhi); + registryData.fill(HIST("deltaPhiEtaSEProtonUE"), deltaPhi, deltaEta); + break; + case 6: + registryData.fill(HIST("deltaPhiSEAntiprotonUE"), deltaPhi); + registryData.fill(HIST("deltaPhiEtaSEAntiprotonUE"), deltaPhi, deltaEta); + break; + case 7: + registryData.fill(HIST("deltaPhiSEPionUE"), deltaPhi); + registryData.fill(HIST("deltaPhiEtaSEPionUE"), deltaPhi, deltaEta); + break; } - } - fillMixedEventDeltas(particleVector.at(i), buffer, particleType, jetAxis); - tempBuffer.emplace_back(std::make_pair(phiToAxis, etaToAxis)); - } + } // for (int j = i + 1; j < static_cast(particleVector.size()); j++) + fillMixedEventDeltas(particleVector.at(i), buffer, particleType, jetAxis); // do ME distribution of current track vs all tracks in buffer + tempBuffer.emplace_back(std::make_pair(phiToAxis, etaToAxis)); // use pair to maintain phi-eta correlation + } // for (int i = 0; i < static_cast(particleVector.size()); i++) } - void doCorrelationsAnti(const auto& particleVector, const auto& particleVectorAnti, const auto& bufferAnti, auto& tempBuffer, const TVector3 jetAxis) // correlations between particle/antiparticle + void doCorrelationsAnti(const auto& particleVector, const auto& particleVectorAnti, const auto& bufferAnti, auto& tempBuffer, const TVector3 jetAxis) // correlations between proton/antiproton - same story as doCorrelations but different track vectors are correlated { if (std::isnan(jetAxis.Phi())) return; @@ -704,24 +766,6 @@ struct AngularCorrelationsInJets { } } - double getDeltaPhi(double a1, double a2) - { - double failedPhi = -999; - if (std::isnan(a1) || std::isnan(a2) || a1 == failedPhi || a2 == failedPhi) - return -999; - double deltaPhi(0); - double phi1 = RecoDecay::constrainAngle(a1, 0); - double phi2 = RecoDecay::constrainAngle(a2, 0); - double diff = std::abs(phi1 - phi2); - - if (diff <= constants::math::PI) - deltaPhi = diff; - if (diff > constants::math::PI) - deltaPhi = constants::math::TwoPI - diff; - - return deltaPhi; - } - void getPerpendicularAxis(TVector3 p, TVector3& u, double sign) { // Initialization @@ -776,9 +820,9 @@ struct AngularCorrelationsInJets { fastjet::PseudoJet subtractedJetPerp(0., 0., 0., 0.); subtractedJetPerp = bkgSub.doRhoAreaSub(jet, rhoPerp, rhoMPerp); - if (subtractedJetPerp.pt() < minJetPt) // cut on jet w/o bkg + if (subtractedJetPerp.pt() < minJetPt) // cut on jet without bkg return jetCounter; - if ((std::fabs(jet.eta()) + jetR) > (maxEta - deltaEtaEdge)) + if ((std::fabs(jet.eta()) + jetR) > (maxEta - deltaEtaEdge)) // keep jet away from acceptance edge return jetCounter; registryData.fill(HIST("ptTotalSubJetPerp"), subtractedJetPerp.pt()); registryQC.fill(HIST("rhoEstimatePerp"), jet.pt(), rhoPerp); @@ -800,13 +844,13 @@ struct AngularCorrelationsInJets { registryData.fill(HIST("numPartInJet"), jet.constituents().size()); TVector3 pJet(0., 0., 0.); - pJet.SetXYZ(jet.px(), jet.py(), jet.pz()); + pJet.SetXYZ(jet.px(), jet.py(), jet.pz()); // create jet axis - if (outputQC) { + if (outputQC) { // for comparison with antinucleiInJets registryQC.fill(HIST("jetBkgDeltaPt"), jetBkgDeltaPt); registryQC.fill(HIST("jetPtVsNumPart"), jet.pt(), jet.constituents().size()); - double maxRadius = 0; + double maxRadius = 0; // get max distance of a jet track to jet axis for (const auto& constituent : constituents) { registryData.fill(HIST("ptJetParticle"), constituent.pt()); registryQC.fill(HIST("phiJet"), constituent.phi()); @@ -840,28 +884,28 @@ struct AngularCorrelationsInJets { for (const auto& [index, track] : particles) { TVector3 particleDir(track.px(), track.py(), track.pz()); double deltaEtaJet = particleDir.Eta() - pJet.Eta(); - double deltaPhiJet = getDeltaPhi(particleDir.Phi(), pJet.Phi()); + double deltaPhiJet = RecoDecay::constrainAngle(particleDir.Phi() - pJet.Phi(), -constants::math::PI); double deltaRJet = std::abs(deltaEtaJet * deltaEtaJet + deltaPhiJet * deltaPhiJet); double deltaEtaUE1 = particleDir.Eta() - ueAxis1.Eta(); - double deltaPhiUE1 = getDeltaPhi(particleDir.Phi(), ueAxis1.Phi()); + double deltaPhiUE1 = RecoDecay::constrainAngle(particleDir.Phi() - ueAxis1.Phi(), -constants::math::PI); double deltaRUE1 = std::abs(deltaEtaUE1 * deltaEtaUE1 + deltaPhiUE1 * deltaPhiUE1); double deltaEtaUE2 = particleDir.Eta() - ueAxis2.Eta(); - double deltaPhiUE2 = getDeltaPhi(particleDir.Phi(), ueAxis2.Phi()); + double deltaPhiUE2 = RecoDecay::constrainAngle(particleDir.Phi() - ueAxis2.Phi(), -constants::math::PI); double deltaRUE2 = std::abs(deltaEtaUE2 * deltaEtaUE2 + deltaPhiUE2 * deltaPhiUE2); double failedPhi = -999; - if (deltaRJet < rMax) { + if (deltaRJet < jetR) { if (deltaPhiJet != failedPhi) registryQC.fill(HIST("deltaEtadeltaPhiJet"), deltaEtaJet, deltaPhiJet); nchJetPlusUE++; ptJetPlusUE = ptJetPlusUE + track.pt(); } - if (deltaRUE1 < rMax) { + if (deltaRUE1 < jetR) { if (deltaPhiUE1 != failedPhi) registryQC.fill(HIST("deltaEtadeltaPhiUE"), deltaEtaUE1, deltaPhiUE1); nchUE++; ptUE = ptUE + track.pt(); } - if (deltaRUE2 < rMax) { + if (deltaRUE2 < jetR) { if (deltaPhiUE2 != failedPhi) registryQC.fill(HIST("deltaEtadeltaPhiUE"), deltaEtaUE2, deltaPhiUE2); nchUE++; @@ -903,10 +947,10 @@ struct AngularCorrelationsInJets { fTempBufferAntiproton.clear(); fTempBufferJet.clear(); - for (const auto& pseudoParticle : constituents) { // analyse jet constituents - this is where the magic happens + for (const auto& pseudoParticle : constituents) { // analyse jet constituents registryData.fill(HIST("trackProtocol"), 2); int id = pseudoParticle.user_index(); - const auto& jetParticle = particles.at(id); + const auto& jetParticle = particles.at(id); // get track for corresponding PseudoJet index if (!selectTrack(jetParticle)) continue; jetAll.emplace_back(jetParticle); @@ -916,10 +960,11 @@ struct AngularCorrelationsInJets { registryData.fill(HIST("tofSignal"), jetParticle.pt() * jetParticle.sign(), jetParticle.beta()); } if (outputQC) { - double ptDiff = pseudoParticle.pt() - jetParticle.pt(); + double ptDiff = pseudoParticle.pt() - jetParticle.pt(); // track recovery from PseudoJet index working properly if this is close to 0 registryQC.fill(HIST("ptDiff"), ptDiff); } + // gather proton/antiproton/pion/kaon in respective vectors if ((doppCorrelations || dopapCorrelations) && isProton(jetParticle)) { registryData.fill(HIST("trackProtocol"), 3); // # high purity protons registryData.fill(HIST("ptJetProton"), jetParticle.pt()); @@ -949,16 +994,17 @@ struct AngularCorrelationsInJets { } } // for (const auto& pseudoParticle : constituents) - if (doJetCorrelations && jetAll.size() > 1) { // general correlation function + if (doJetCorrelations && jetAll.size() > 1) { // correlation of all jet particles doCorrelations(jetAll, fBufferJet, fTempBufferJet, 0, pJet); setTrackBuffer(fTempBufferJet, fBufferJet); } if (dopapCorrelations && (jetProtons.size() > 0) && (jetAntiprotons.size() > 0)) { doCorrelationsAnti(jetProtons, jetAntiprotons, fBufferAntiproton, fTempBufferProton, pJet); - doCorrelationsAnti(jetAntiprotons, jetProtons, fBufferProton, fTempBufferAntiproton, pJet); // divide SE distributions by 2 in post + doCorrelationsAnti(jetAntiprotons, jetProtons, fBufferProton, fTempBufferAntiproton, pJet); // don't worry about dividing result by 2, the factor will drop out in correlation function } int minNumPartForCorrelations = 2; + // need at least 2 tracks in any one list if ((static_cast(jetProtons.size()) < minNumPartForCorrelations) && (static_cast(jetAntiprotons.size()) < minNumPartForCorrelations) && (static_cast(jetPiPlus.size()) < minNumPartForCorrelations) && (static_cast(jetPiMinus.size()) < minNumPartForCorrelations)) return jetCounter; registryData.fill(HIST("eventProtocol"), 6); @@ -990,11 +1036,19 @@ struct AngularCorrelationsInJets { std::vector jetPiPlus; std::vector jetPiMinus; std::vector jetAll; + std::vector protonsUE; + std::vector antiprotonsUE; + std::vector piPlusUE; + std::vector piMinusUE; jetProtons.clear(); jetAntiprotons.clear(); jetPiPlus.clear(); jetPiMinus.clear(); jetAll.clear(); + protonsUE.clear(); + antiprotonsUE.clear(); + piPlusUE.clear(); + piMinusUE.clear(); std::vector> fTempBufferFull; fTempBufferFull.clear(); std::vector jetInput; // input for jet finder @@ -1002,8 +1056,8 @@ struct AngularCorrelationsInJets { std::vector particlesForCF; // particles for full event angular correlations jetInput.clear(); particles.clear(); - int index = 0; - int jetCounter = 0; + int index = 0; // index attached to input PseudoJets + int jetCounter = 0; // how many actual jets in the event for (const auto& track : tracks) { registryData.fill(HIST("trackProtocol"), 0); // # all tracks @@ -1058,15 +1112,134 @@ struct AngularCorrelationsInJets { auto [rhoPerp, rhoMPerp] = bkgSub.estimateRhoPerpCone(jetInput, jets); for (const auto& jet : jets) { + // this is where the magic happens jetCounter = analyseJet(jetCounter, jet, particles, jetProtons, jetAntiprotons, jetPiPlus, jetPiMinus, jetAll, rhoPerp, rhoMPerp); } registryData.fill(HIST("numJetsInEvent"), jetCounter); - TVector3 hardestJetAxis(jets.at(0).px(), jets.at(0).py(), jets.at(0).pz()); // for full event, use hardest jet as orientation + TVector3 hardestJetAxis(jets.at(0).px(), jets.at(0).py(), jets.at(0).pz()); // for full event and UE, use hardest jet as orientation doCorrelations(particlesForCF, fBufferFull, fTempBufferFull, -1, hardestJetAxis); setTrackBuffer(fTempBufferFull, fBufferFull); + + if (!doUECorrelations) + return; + + // UE correlations + TVector3 ueAxis1(0.0, 0.0, 0.0); + TVector3 ueAxis2(0.0, 0.0, 0.0); + getPerpendicularAxis(hardestJetAxis, ueAxis1, +1.0); + getPerpendicularAxis(hardestJetAxis, ueAxis2, -1.0); + + // untested so far, and the method may need to be rethought, this is the best I could think of + // useBkgEstimateForUE == true tries to somewhat imitate a seeded anti-kt algorithm centred around the perp cone axis + // useBkgEstimateForUE == false simply collects all tracks geometrically, with a hard cut at R + for (const auto& track : tracks) { // try for first cone + double uePt = rhoPerp * constants::math::PI * jetR * jetR; // pt = rho_bkg * area + double trackPt = track.pt(); + if (isProton(track)) { + double geometricDelta = (std::pow(track.phi() - ueAxis1.Phi(), 2) + std::pow(track.eta() - ueAxis1.Eta(), 2)) / (jetR * jetR); + double dij = useBkgEstimateForUE ? std::min(1 / (trackPt * trackPt), 1 / (uePt * uePt)) * geometricDelta : geometricDelta; + double diB = useBkgEstimateForUE ? 1 / (uePt * uePt) : 1; + if (dij < diB) { + protonsUE.emplace_back(track); + if (outputQC) + registryQC.fill(HIST("whichUECone"), 1); // see if track ends up in cone 1 or 2 + } + } else if (isAntiproton(track)) { + double geometricDelta = (std::pow(track.phi() - ueAxis1.Phi(), 2) + std::pow(track.eta() - ueAxis1.Eta(), 2)) / (jetR * jetR); + double dij = useBkgEstimateForUE ? std::min(1 / (trackPt * trackPt), 1 / (uePt * uePt)) * geometricDelta : geometricDelta; + double diB = useBkgEstimateForUE ? 1 / (uePt * uePt) : 1; + if (dij < diB) { + antiprotonsUE.emplace_back(track); + if (outputQC) + registryQC.fill(HIST("whichUECone"), 1); + } + } else if (isPion(track)) { + double geometricDelta = (std::pow(track.phi() - ueAxis1.Phi(), 2) + std::pow(track.eta() - ueAxis1.Eta(), 2)) / (jetR * jetR); + double dij = useBkgEstimateForUE ? std::min(1 / (trackPt * trackPt), 1 / (uePt * uePt)) * geometricDelta : geometricDelta; + double diB = useBkgEstimateForUE ? 1 / (uePt * uePt) : 1; + if (dij < diB) { + track.sign() > 0 ? piPlusUE.emplace_back(track) : piMinusUE.emplace_back(track); + if (outputQC) + registryQC.fill(HIST("whichUECone"), 1); + } + } + } // for (const auto& track : tracks) + + std::vector> fTempBufferProtonUE; + std::vector> fTempBufferAntiprotonUE; + std::vector> fTempBufferPiPlusUE; + std::vector> fTempBufferPiMinusUE; + + doCorrelations(protonsUE, fBufferProtonsUE, fTempBufferProtonUE, 5, ueAxis1); + setTrackBuffer(fTempBufferProtonUE, fBufferProtonsUE); + + doCorrelations(antiprotonsUE, fBufferAntiprotonsUE, fTempBufferAntiprotonUE, 6, ueAxis1); + setTrackBuffer(fTempBufferProtonUE, fBufferAntiprotonsUE); + + doCorrelations(piPlusUE, fBufferPiPlusUE, fTempBufferPiPlusUE, 7, ueAxis1); + setTrackBuffer(fTempBufferProtonUE, fBufferPiPlusUE); + + doCorrelations(piMinusUE, fBufferPiMinusUE, fTempBufferPiMinusUE, 7, ueAxis1); + setTrackBuffer(fTempBufferProtonUE, fBufferPiMinusUE); + + fTempBufferProtonUE.clear(); + fTempBufferAntiprotonUE.clear(); + fTempBufferPiPlusUE.clear(); + fTempBufferPiMinusUE.clear(); + fBufferProtonsUE.clear(); + fBufferAntiprotonsUE.clear(); + fBufferPiPlusUE.clear(); + fBufferPiMinusUE.clear(); + + for (const auto& track : tracks) { // try for second cone + double uePt = rhoPerp * constants::math::PI * jetR * jetR; // pt = rho_bkg * area + double trackPt = track.pt(); + if (isProton(track)) { + double geometricDelta = (std::pow(track.phi() - ueAxis2.Phi(), 2) + std::pow(track.eta() - ueAxis2.Eta(), 2)) / (jetR * jetR); + double dij = useBkgEstimateForUE ? std::min(1 / (trackPt * trackPt), 1 / (uePt * uePt)) * geometricDelta : geometricDelta; + double diB = useBkgEstimateForUE ? 1 / (uePt * uePt) : 1; + if (dij < diB) { + protonsUE.emplace_back(track); + if (outputQC) + registryQC.fill(HIST("whichUECone"), 2); // see if track ends up in cone 1 or 2 + } + } else if (isAntiproton(track)) { + double geometricDelta = (std::pow(track.phi() - ueAxis2.Phi(), 2) + std::pow(track.eta() - ueAxis2.Eta(), 2)) / (jetR * jetR); + double dij = useBkgEstimateForUE ? std::min(1 / (trackPt * trackPt), 1 / (uePt * uePt)) * geometricDelta : geometricDelta; + double diB = useBkgEstimateForUE ? 1 / (uePt * uePt) : 1; + if (dij < diB) { + antiprotonsUE.emplace_back(track); + if (outputQC) + registryQC.fill(HIST("whichUECone"), 2); + } + } else if (isPion(track)) { + double geometricDelta = (std::pow(track.phi() - ueAxis2.Phi(), 2) + std::pow(track.eta() - ueAxis2.Eta(), 2)) / (jetR * jetR); + double dij = useBkgEstimateForUE ? std::min(1 / (trackPt * trackPt), 1 / (uePt * uePt)) * geometricDelta : geometricDelta; + double diB = useBkgEstimateForUE ? 1 / (uePt * uePt) : 1; + if (dij < diB) { + track.sign() > 0 ? piPlusUE.emplace_back(track) : piMinusUE.emplace_back(track); + if (outputQC) + registryQC.fill(HIST("whichUECone"), 2); + } + } + } // for (const auto& track : tracks) + + doCorrelations(protonsUE, fBufferProtonsUE, fTempBufferProtonUE, 5, ueAxis2); + setTrackBuffer(fTempBufferProtonUE, fBufferProtonsUE); + + doCorrelations(antiprotonsUE, fBufferAntiprotonsUE, fTempBufferAntiprotonUE, 6, ueAxis2); + setTrackBuffer(fTempBufferProtonUE, fBufferAntiprotonsUE); + + doCorrelations(piPlusUE, fBufferPiPlusUE, fTempBufferPiPlusUE, 7, ueAxis2); + setTrackBuffer(fTempBufferProtonUE, fBufferPiPlusUE); + + doCorrelations(piMinusUE, fBufferPiMinusUE, fTempBufferPiMinusUE, 7, ueAxis2); + setTrackBuffer(fTempBufferProtonUE, fBufferPiMinusUE); } + // this may need to be reworked, it hasn't really been tested yet + // so far it does almost the same as fillHistograms without correlations but including MCgen tracks template void fillHistogramsMC(U const& tracks) { @@ -1176,27 +1349,27 @@ struct AngularCorrelationsInJets { for (const auto& [index, track] : particles) { TVector3 particleDir(track.px(), track.py(), track.pz()); double deltaEtaJet = particleDir.Eta() - pJet.Eta(); - double deltaPhiJet = getDeltaPhi(particleDir.Phi(), pJet.Phi()); + double deltaPhiJet = RecoDecay::constrainAngle(particleDir.Phi() - pJet.Phi(), -constants::math::PI); double deltaRJet = std::abs(deltaEtaJet * deltaEtaJet + deltaPhiJet * deltaPhiJet); double deltaEtaUE1 = particleDir.Eta() - ueAxis1.Eta(); - double deltaPhiUE1 = getDeltaPhi(particleDir.Phi(), ueAxis1.Phi()); + double deltaPhiUE1 = RecoDecay::constrainAngle(particleDir.Phi() - ueAxis1.Phi(), -constants::math::PI); double deltaRUE1 = std::abs(deltaEtaUE1 * deltaEtaUE1 + deltaPhiUE1 * deltaPhiUE1); double deltaEtaUE2 = particleDir.Eta() - ueAxis2.Eta(); - double deltaPhiUE2 = getDeltaPhi(particleDir.Phi(), ueAxis2.Phi()); + double deltaPhiUE2 = RecoDecay::constrainAngle(particleDir.Phi() - ueAxis2.Phi(), -constants::math::PI); double deltaRUE2 = std::abs(deltaEtaUE2 * deltaEtaUE2 + deltaPhiUE2 * deltaPhiUE2); double failedPhi = -999; - if (deltaRJet < rMax) { + if (deltaRJet < jetR) { if (deltaPhiJet != failedPhi) registryQC.fill(HIST("deltaEtadeltaPhiJet"), deltaEtaJet, deltaPhiJet); nchJetPlusUE++; } - if (deltaRUE1 < rMax) { + if (deltaRUE1 < jetR) { if (deltaPhiUE1 != failedPhi) registryQC.fill(HIST("deltaEtadeltaPhiUE"), deltaEtaUE1, deltaPhiUE1); nchUE++; } - if (deltaRUE2 < rMax) { + if (deltaRUE2 < jetR) { if (deltaPhiUE2 != failedPhi) registryQC.fill(HIST("deltaEtadeltaPhiUE"), deltaEtaUE2, deltaPhiUE2); nchUE++; diff --git a/PWGLF/Tasks/Nuspex/antidLambdaEbye.cxx b/PWGLF/Tasks/Nuspex/antidLambdaEbye.cxx deleted file mode 100644 index baa91ce1b27..00000000000 --- a/PWGLF/Tasks/Nuspex/antidLambdaEbye.cxx +++ /dev/null @@ -1,1241 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include -#include -#include - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/EventSelection.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsTPC/BetheBlochAleph.h" -#include "Common/Core/PID/PIDTOF.h" -#include "Common/TableProducer/PID/pidTOFBase.h" - -#include "Common/Core/PID/TPCPIDResponse.h" -#include "Common/DataModel/PIDResponse.h" -#include "DCAFitter/DCAFitterN.h" - -#include "TDatabasePDG.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; - -using TracksFull = soa::Join; -using TracksFullIU = soa::Join; -using BCsWithRun2Info = soa::Join; - -namespace -{ -constexpr int kNpart = 2; -constexpr double betheBlochDefault[kNpart][6]{{-1.e32, -1.e32, -1.e32, -1.e32, -1.e32, -1.e32}, {-1.e32, -1.e32, -1.e32, -1.e32, -1.e32, -1.e32}}; -constexpr double estimatorsCorrelationCoef[2]{-0.669108, 1.04489}; -constexpr double estimatorsSigmaPars[4]{0.933321, 0.0416976, -0.000936344, 8.92179e-06}; -constexpr double deltaEstimatorNsigma[2]{5.5, 5.}; -constexpr double partMass[kNpart]{o2::constants::physics::MassProton, o2::constants::physics::MassDeuteron}; -constexpr double partPdg[kNpart]{2212, o2::constants::physics::kDeuteron}; -static const std::vector betheBlochParNames{"p0", "p1", "p2", "p3", "p4", "resolution"}; -static const std::vector particleNamesBB{"p", "d"}; -std::array, kNpart> tempTracks; -std::shared_ptr tempAntiLambda; -std::shared_ptr tempLambda; -std::shared_ptr nAntid; -std::shared_ptr nAntip; -std::shared_ptr nAntiL; -std::shared_ptr nL; -std::shared_ptr nSqAntid; -std::shared_ptr nSqAntip; -std::shared_ptr nSqAntiL; -std::shared_ptr nSqL; -std::shared_ptr nAntipAntid; -std::shared_ptr nLantiL; -std::shared_ptr nLantid; -std::shared_ptr nAntiLantid; -std::shared_ptr nGenAntid; -std::shared_ptr nGenAntip; -std::shared_ptr nGenAntiL; -std::shared_ptr nGenL; -std::shared_ptr nGenSqAntid; -std::shared_ptr nGenSqAntip; -std::shared_ptr nGenSqAntiL; -std::shared_ptr nGenSqL; -std::shared_ptr nGenAntipAntid; -std::shared_ptr nGenLantiL; -std::shared_ptr nGenLantid; -std::shared_ptr nGenAntiLantid; -std::array, kNpart> recTracks; -std::array, kNpart> recAntiTracks; -std::array, kNpart> genTracks; -std::array, kNpart> genAntiTracks; -std::array, kNpart> tpcNsigma; -std::array, kNpart> tpcNsigmaGlo; -std::array, kNpart> tofMass; -std::array, kNpart> tofSignal; -std::array, kNpart> tofSignal_glo; -void momTotXYZ(std::array& momA, std::array const& momB, std::array const& momC) -{ - for (int i = 0; i < 3; ++i) { - momA[i] = momB[i] + momC[i]; - } -} -float invMass2Body(std::array const& momA, std::array const& momB, std::array const& momC, float const& massB, float const& massC) -{ - float p2B = momB[0] * momB[0] + momB[1] * momB[1] + momB[2] * momB[2]; - float p2C = momC[0] * momC[0] + momC[1] * momC[1] + momC[2] * momC[2]; - float eB = std::sqrt(p2B + massB * massB); - float eC = std::sqrt(p2C + massC * massC); - float eA = eB + eC; - float massA = std::sqrt(eA * eA - momA[0] * momA[0] - momA[1] * momA[1] - momA[2] * momA[2]); - return massA; -} -float alphaAP(std::array const& momA, std::array const& momB, std::array const& momC) -{ - float momTot = std::sqrt(std::pow(momA[0], 2.) + std::pow(momA[1], 2.) + std::pow(momA[2], 2.)); - float lQlPos = (momB[0] * momA[0] + momB[1] * momA[1] + momB[2] * momA[2]) / momTot; - float lQlNeg = (momC[0] * momA[0] + momC[1] * momA[1] + momC[2] * momA[2]) / momTot; - return (lQlPos - lQlNeg) / (lQlPos + lQlNeg); -} -float etaFromMom(std::array const& momA, std::array const& momB) -{ - if (std::sqrt((1.f * momA[0] + 1.f * momB[0]) * (1.f * momA[0] + 1.f * momB[0]) + - (1.f * momA[1] + 1.f * momB[1]) * (1.f * momA[1] + 1.f * momB[1]) + - (1.f * momA[2] + 1.f * momB[2]) * (1.f * momA[2] + 1.f * momB[2])) - - (1.f * momA[2] + 1.f * momB[2]) < - static_cast(1e-7)) { - if ((1.f * momA[2] + 1.f * momB[2]) < 0.f) - return -100.f; - return 100.f; - } - return 0.5f * std::log((std::sqrt((1.f * momA[0] + 1.f * momB[0]) * (1.f * momA[0] + 1.f * momB[0]) + - (1.f * momA[1] + 1.f * momB[1]) * (1.f * momA[1] + 1.f * momB[1]) + - (1.f * momA[2] + 1.f * momB[2]) * (1.f * momA[2] + 1.f * momB[2])) + - (1.f * momA[2] + 1.f * momB[2])) / - (std::sqrt((1.f * momA[0] + 1.f * momB[0]) * (1.f * momA[0] + 1.f * momB[0]) + - (1.f * momA[1] + 1.f * momB[1]) * (1.f * momA[1] + 1.f * momB[1]) + - (1.f * momA[2] + 1.f * momB[2]) * (1.f * momA[2] + 1.f * momB[2])) - - (1.f * momA[2] + 1.f * momB[2]))); -} -float CalculateDCAStraightToPV(float X, float Y, float Z, float Px, float Py, float Pz, float pvX, float pvY, float pvZ) -{ - return std::sqrt((std::pow((pvY - Y) * Pz - (pvZ - Z) * Py, 2) + std::pow((pvX - X) * Pz - (pvZ - Z) * Px, 2) + std::pow((pvX - X) * Py - (pvY - Y) * Px, 2)) / (Px * Px + Py * Py + Pz * Pz)); -} -} // namespace - -struct CandidateV0 { - float pt; - float eta; - float mass; - float cpa; - float dcav0daugh; - float dcav0pv; - int64_t globalIndexPos = -999; - int64_t globalIndexNeg = -999; -}; - -struct CandidateTrack { - float pt; - float eta; - int64_t globalIndex = -999; -}; - -struct antidLambdaEbye { - std::mt19937 gen32; - std::vector candidateV0s; - std::array, 2> candidateTracks; - Service ccdb; - o2::vertexing::DCAFitterN<2> fitter; - - int nSubsamples; - int mRunNumber; - float d_bz; - // o2::base::MatLayerCylSet* lut = nullptr; - - ConfigurableAxis centAxis{"centAxis", {106, 0, 106}, "binning for the centrality"}; - ConfigurableAxis subsampleAxis{"subsampleAxis", {30, 0, 30}, "binning of the subsample axis"}; - ConfigurableAxis deltaEtaAxis{"deltaEtaAxis", {4, 0, 0.8}, "binning of the delta eta axis"}; - ConfigurableAxis ptAntidAxis{"ptAntidAxis", {VARIABLE_WIDTH, 0.7f, 0.8f, 0.9f, 1.0f, 1.2f, 1.4f, 1.6f, 1.8f}, "binning of the antideuteron pT axis (GeV/c)"}; - ConfigurableAxis ptAntipAxis{"ptAntipAxis", {VARIABLE_WIDTH, 0.4f, 0.6f, 0.7f, 0.8f, 0.9f}, "binning of the antiproton pT axis (GeV/c)"}; - ConfigurableAxis ptLambdaAxis{"ptLambdaAxis", {VARIABLE_WIDTH, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f}, "binning of the (anti)lambda pT axis (GeV/c)"}; - - ConfigurableAxis zVtxAxis{"zVtxBins", {100, -20.f, 20.f}, "Binning for the vertex z in cm"}; - ConfigurableAxis multAxis{"multAxis", {100, 0, 10000}, "Binning for the multiplicity axis"}; - ConfigurableAxis multFt0Axis{"multFt0Axis", {100, 0, 100000}, "Binning for the ft0 multiplicity axis"}; - ConfigurableAxis nGenRecAxis{"nGenRecAxis", {20, 0, 20}, "binning for the number of reconstructed or generated candidates per event"}; - - // binning of (anti)lambda QA histograms - ConfigurableAxis massLambdaAxis{"massLambdaAxis", {400, o2::constants::physics::MassLambda0 - 0.03f, o2::constants::physics::MassLambda0 + 0.03f}, "binning for the lambda invariant-mass"}; - ConfigurableAxis cosPaAxis{"cosPaAxis", {1e3, 0.95f, 1.00f}, "binning for the cosPa axis"}; - ConfigurableAxis radiusAxis{"radiusAxis", {1e3, 0.f, 100.f}, "binning for the radius axis"}; - ConfigurableAxis dcaV0daughAxis{"dcaV0daughAxis", {2e2, 0.f, 2.f}, "binning for the dca of V0 daughters"}; - ConfigurableAxis dcaDaughPvAxis{"dcaDaughPvAxis", {1e3, -10.f, 10.f}, "binning for the dca of positive daughter to PV"}; - - // binning of deuteron QA histograms - ConfigurableAxis tpcNsigmaAxis{"tpcNsigmaAxis", {100, -5.f, 5.f}, "tpc nsigma axis"}; - ConfigurableAxis tofMassAxis{"tofMassAxis", {1000, 0., 3.f}, "tof mass axis"}; - ConfigurableAxis momAxis{"momAxis", {60., 0.f, 3.f}, "momentum axis binning"}; - ConfigurableAxis momAxisFine{"momAxisFine", {5.e2, 0.f, 5.f}, "momentum axis binning"}; - ConfigurableAxis momResAxis{"momResAxis", {1.e2, -1.f, 1.f}, "momentum resolution binning"}; - ConfigurableAxis tpcAxis{"tpcAxis", {4.e2, 0.f, 4.e3f}, "tpc signal axis binning"}; - ConfigurableAxis tofAxis{"tofAxis", {1.e3, 0.f, 1.f}, "tof signal axis binning"}; - ConfigurableAxis tpcClsAxis{"tpcClsAxis", {160, 0.f, 160.f}, "tpc n clusters binning"}; - - struct : ConfigurableGroup { - Configurable cfgMaterialCorrection{"cfgMaterialCorrection", static_cast(o2::base::Propagator::MatCorrType::USEMatCorrNONE), "Type of material correction"}; - Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {betheBlochDefault[0], 2, 6, particleNamesBB, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for deuteron"}; - Configurable zVtxMax{"zVtxMax", 10.0f, "maximum z position of the primary vertex"}; - Configurable etaMax{"etaMax", 0.8f, "maximum eta"}; - Configurable etaMaxV0dau{"etaMaxV0dau", 0.8f, "maximum eta V0 daughters"}; - - Configurable fillOnlySignal{"fillOnlySignal", false, "fill histograms only for true signal candidates (MC)"}; - - Configurable kINT7Intervals{"kINT7Intervals", false, "toggle kINT7 trigger selection in the 10-30% and 50-90% centrality intervals (2018 Pb-Pb)"}; - Configurable kUseTPCPileUpCut{"kUseTPCPileUpCut", false, "toggle strong correlation cuts (Run 2)"}; - Configurable kUseEstimatorsCorrelationCut{"kUseEstimatorsCorrelationCut", false, "toggle cut on the correlation between centrality estimators (2018 Pb-Pb)"}; - - Configurable antidPtMin{"antidPtMin", 0.8f, "minimum antideuteron pT (GeV/c)"}; - Configurable antidPtTof{"antidPtTof", 1.0f, "antideuteron pT to switch to TOF pid (GeV/c) "}; - Configurable antidPtMax{"antidPtMax", 1.8f, "maximum antideuteron pT (GeV/c)"}; - - Configurable antipPtMin{"antipPtMin", 0.4f, "minimum antiproton pT (GeV/c)"}; - Configurable antipPtTof{"antipPtTof", 0.6f, "antiproton pT to switch to TOF pid (GeV/c) "}; - Configurable antipPtMax{"antipPtMax", 0.9f, "maximum antiproton pT (GeV/c)"}; - - Configurable lambdaPtMin{"lambdaPtMin", 0.5f, "minimum (anti)lambda pT (GeV/c)"}; - Configurable lambdaPtMax{"lambdaPtMax", 3.0f, "maximum (anti)lambda pT (GeV/c)"}; - - Configurable trackNcrossedRows{"trackNcrossedRows", 70, "Minimum number of crossed TPC rows"}; - Configurable trackNclusItsCut{"trackNclusITScut", 5, "Minimum number of ITS clusters"}; - Configurable trackNclusTpcCut{"trackNclusTPCcut", 70, "Minimum number of TPC clusters"}; - Configurable trackDcaCut{"trackDcaCut", 0.1f, "DCA antid to PV"}; - - Configurable v0trackNcrossedRows{"v0trackNcrossedRows", 70, "Minimum number of crossed TPC rows for V0 daughter"}; - Configurable v0trackNclusItsCut{"v0trackNclusITScut", 1, "Minimum number of ITS clusters for V0 daughter"}; - Configurable v0trackNclusTpcCut{"v0trackNclusTPCcut", 70, "Minimum number of TPC clusters for V0 daughter"}; - Configurable v0trackNsharedClusTpc{"v0trackNsharedClusTpc", 10, "Maximum number of shared TPC clusters for V0 daughter"}; - Configurable v0requireITSrefit{"v0requireITSrefit", false, "require ITS refit for V0 daughter"}; - Configurable vetoMassK0Short{"vetoMassK0Short", -999.f, "veto for V0 compatible with K0s mass"}; - Configurable v0radiusMax{"v0radiusMax", 100.f, "maximum V0 radius eccepted"}; - - Configurable antidNsigmaTpcCutLow{"antidNsigmaTpcCutLow", 4.f, "TPC PID cut low"}; - Configurable antidNsigmaTpcCutUp{"antidNsigmaTpcCutUp", 4.f, "TPC PID cut up"}; - Configurable antidNsigmaTofCut{"antidNsigmaTofCut", 4.f, "TOF PID cut"}; - Configurable antidTpcInnerParamMax{"tpcInnerParamMax", 0.6f, "(temporary) tpc inner param cut"}; - Configurable antidTofMassMax{"tofMassMax", 0.3f, "(temporary) tof mass cut"}; - - Configurable antipNsigmaTpcCutLow{"antipNsigmaTpcCutLow", 4.f, "TPC PID cut low"}; - Configurable antipNsigmaTpcCutUp{"antipNsigmaTpcCutUp", 4.f, "TPC PID cut up"}; - Configurable antipNsigmaTofCut{"antipNsigmaTofCut", 4.f, "TOF PID cut"}; - Configurable antipTpcInnerParamMax{"antipTpcInnerParamMax", 0.6f, "(temporary) tpc inner param cut"}; - Configurable antipTofMassMax{"antipTofMassMax", 0.3f, "(temporary) tof mass cut"}; - Configurable tofMassMaxQA{"tofMassMaxQA", 0.6f, "(temporary) tof mass cut (for QA histograms)"}; - - Configurable v0setting_dcav0dau{"v0setting_dcav0dau", 1, "DCA V0 Daughters"}; - Configurable v0setting_dcav0pv{"v0setting_dcav0pv", 1, "DCA V0 to Pv"}; - Configurable v0setting_dcadaughtopv{"v0setting_dcadaughtopv", 0.1f, "DCA Pos To PV"}; - Configurable v0setting_cospa{"v0setting_cospa", 0.98, "V0 CosPA"}; - Configurable v0setting_radius{"v0setting_radius", 0.5f, "v0radius"}; - Configurable v0setting_lifetime{"v0setting_lifetime", 40.f, "v0 lifetime cut"}; - Configurable v0setting_nsigmatpc{"v0setting_nsigmatpc", 4.f, "nsigmatpc"}; - Configurable lambdaMassCut{"lambdaMassCut", 0.005f, "maximum deviation from PDG mass"}; - Configurable lambdaMassCutQA{"lambdaMassCutQA", 0.02f, "maximum deviation from PDG mass (for QA histograms)"}; - - Configurable antidItsClsSizeCut{"antidItsClsSizeCut", 2.f, "cluster size cut for antideuterons"}; - Configurable antidPtItsClsSizeCut{"antidPtItsClsSizeCut", 1.f, "pt for cluster size cut for antideuterons"}; - } config; - - std::array ptMin; - std::array ptTof; - std::array ptMax; - std::array nSigmaTpcCutLow; - std::array nSigmaTpcCutUp; - std::array nSigmaTofCut; - std::array tpcInnerParamMax; - std::array tofMassMax; - - HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry tempHistos{"tempHistos", {}, OutputObjHandlingPolicy::TransientObject}; - - Preslice perCollisionTracksFull = o2::aod::track::collisionId; - Preslice perCollisionTracksFullIU = o2::aod::track::collisionId; - Preslice perCollisionV0 = o2::aod::v0::collisionId; - Preslice perCollisionMcParts = o2::aod::mcparticle::mcCollisionId; - - template - bool selectV0Daughter(T const& track) - { - if (std::abs(track.eta()) > config.etaMaxV0dau) { - return false; - } - if (track.itsNCls() < config.v0trackNclusItsCut || - track.tpcNClsFound() < config.v0trackNclusTpcCut || - track.tpcNClsCrossedRows() < config.v0trackNclusTpcCut || - track.tpcNClsCrossedRows() < 0.8 * track.tpcNClsFindable() || - track.tpcNClsShared() > config.v0trackNsharedClusTpc) { - return false; - } - if (doprocessRun2 || doprocessMcRun2) { - if (!(track.trackType() & o2::aod::track::Run2Track) || - !(track.flags() & o2::aod::track::TPCrefit)) { - return false; - } - if (config.v0requireITSrefit && !(track.flags() & o2::aod::track::ITSrefit)) { - return false; - } - } - return true; - } - - template - bool selectTrack(T const& track) - { - if (std::abs(track.eta()) > config.etaMax) { - return false; - } - if (!(track.itsClusterMap() & 0x01) && !(track.itsClusterMap() & 0x02)) { - return false; - } - if (track.itsNCls() < config.trackNclusItsCut || - track.tpcNClsFound() < config.trackNclusTpcCut || - track.tpcNClsCrossedRows() < config.trackNcrossedRows || - track.tpcNClsCrossedRows() < 0.8 * track.tpcNClsFindable() || - track.tpcChi2NCl() > 4.f || - track.itsChi2NCl() > 36.f) { - return false; - } - if (doprocessRun2 || doprocessMcRun2) { - if (!(track.trackType() & o2::aod::track::Run2Track) || - !(track.flags() & o2::aod::track::TPCrefit) || - !(track.flags() & o2::aod::track::ITSrefit)) { - return false; - } - } - return true; - } - - template - float getITSClSize(T const& track) - { - float sum{0.f}; - for (int iL{0}; iL < 6; ++iL) { - sum += (track.itsClusterSizes() >> (iL * 4)) & 0xf; - } - return sum / track.itsNCls(); - } - - void fillHistoN(std::shared_ptr hFull, std::shared_ptr const& hTmp, int const subsample, int const centrality) - { - for (int iEta{1}; iEta < hTmp->GetNbinsX() + 1; ++iEta) { - for (int iPt{1}; iPt < hTmp->GetNbinsY() + 1; ++iPt) { - auto eta = hTmp->GetXaxis()->GetBinCenter(iEta); - auto pt = hTmp->GetYaxis()->GetBinCenter(iPt); - auto num = hTmp->Integral(1, iEta, iPt, iPt); - - hFull->Fill(subsample, centrality, eta, pt, num); - } - } - } - - void fillHistoN(std::shared_ptr hFull, std::shared_ptr const& hTmpA, std::shared_ptr const& hTmpB, int const subsample, int const centrality) - { - for (int iEta{1}; iEta < hTmpA->GetNbinsX() + 1; ++iEta) { - auto eta = hTmpA->GetXaxis()->GetBinCenter(iEta); - for (int iPtA{1}; iPtA < hTmpA->GetNbinsY() + 1; ++iPtA) { - for (int iPtB{1}; iPtB < hTmpB->GetNbinsY() + 1; ++iPtB) { - auto ptA = hTmpA->GetYaxis()->GetBinCenter(iPtA); - auto ptB = hTmpB->GetYaxis()->GetBinCenter(iPtB); - auto numA = hTmpA->Integral(1, iEta, iPtA, iPtA); - auto numB = hTmpB->Integral(1, iEta, iPtB, iPtB); - - hFull->Fill(subsample, centrality, eta, ptA, ptB, numA * numB); - } - } - } - } - - template - void initCCDB(Bc const& bc) - { - if (mRunNumber == bc.runNumber()) { - return; - } - - auto timestamp = bc.timestamp(); - o2::parameters::GRPObject* grpo = 0x0; - o2::parameters::GRPMagField* grpmag = 0x0; - if (doprocessRun2 || doprocessMcRun2) { - auto grpPath{"GLO/GRP/GRP"}; - grpo = ccdb->getForTimeStamp("GLO/GRP/GRP", timestamp); - if (!grpo) { - LOG(fatal) << "Got nullptr from CCDB for path " << grpPath << " of object GRPObject for timestamp " << timestamp; - } - o2::base::Propagator::initFieldFromGRP(grpo); - } else { - auto grpmagPath{"GLO/Config/GRPMagField"}; - grpmag = ccdb->getForTimeStamp("GLO/Config/GRPMagField", timestamp); - if (!grpmag) { - LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField for timestamp " << timestamp; - } - o2::base::Propagator::initFieldFromGRP(grpmag); - } - // Fetch magnetic field from ccdb for current collision - d_bz = o2::base::Propagator::Instance()->getNominalBz(); - LOG(info) << "Retrieved GRP for timestamp " << timestamp << " with magnetic field of " << d_bz << " kG"; - mRunNumber = bc.runNumber(); - fitter.setBz(d_bz); - - // o2::base::Propagator::Instance()->setMatLUT(lut); - } - - void init(o2::framework::InitContext&) - { - - mRunNumber = 0; - d_bz = 0; - - ccdb->setURL("http://alice-ccdb.cern.ch"); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setFatalWhenNull(false); - // lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get("GLO/Param/MatLUT")); - - fitter.setPropagateToPCA(true); - fitter.setMaxR(200.); - fitter.setMinParamChange(1e-3); - fitter.setMinRelChi2Change(0.9); - fitter.setMaxDZIni(4); - fitter.setMaxDXYIni(1); - fitter.setMaxChi2(1e9); - fitter.setUseAbsDCA(true); - fitter.setWeightedFinalPCA(false); - int mat{static_cast(config.cfgMaterialCorrection)}; - fitter.setMatCorrType(static_cast(mat)); - - uint32_t randomSeed = static_cast(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); - gen32.seed(randomSeed); - - histos.add("QA/zVtx", ";#it{z}_{vtx} (cm);Entries", HistType::kTH1F, {zVtxAxis}); - - auto hNev = histos.add("nEv", ";Subsample;Centrality (%);", HistType::kTHnSparseD, {subsampleAxis, centAxis}); - nSubsamples = hNev->GetAxis(0)->GetNbins(); - - histos.add("QA/nRecPerEvAntid", ";Centrality (%);#it{N}_{#bar{d}};#it{N}_{ev}", HistType::kTH2D, {centAxis, nGenRecAxis}); - histos.add("QA/nRecPerEvAntip", ";Centrality (%);#it{N}_{#bar{p}};#it{N}_{ev}", HistType::kTH2D, {centAxis, nGenRecAxis}); - histos.add("QA/nRecPerEvAntiL", ";Centrality (%);#it{N}_{#bar{#Lambda}};#it{N}_{ev}", HistType::kTH2D, {centAxis, nGenRecAxis}); - histos.add("QA/nRecPerEvL", ";Centrality (%);#it{N}_{#Lambda};#it{N}_{ev}", HistType::kTH2D, {centAxis, nGenRecAxis}); - histos.add("QA/nTrklCorrelation", ";Tracklets |#eta| > 0.6; Tracklets |#eta| < 0.6", HistType::kTH2D, {{201, -0.5, 200.5}, {201, -0.5, 200.5}}); - histos.add("QA/TrklEta", ";Tracklets #eta; Entries", HistType::kTH1D, {{100, -3., 3.}}); - - nAntid = histos.add("nAntid", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#bar{d}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptAntidAxis}); - nAntip = histos.add("nAntip", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#bar{p}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptAntipAxis}); - nAntiL = histos.add("nAntiL", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#bar{#Lambda}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptLambdaAxis}); - nL = histos.add("nL", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#Lambda) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptLambdaAxis}); - - nSqAntid = histos.add("nSqAntid", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#bar{d}) (GeV/#it{c});#it{p}_{T}(#bar{d}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptAntidAxis, ptAntidAxis}); - nSqAntip = histos.add("nSqAntip", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#bar{p}) (GeV/#it{c});#it{p}_{T}(#bar{p}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptAntipAxis, ptAntipAxis}); - nSqAntiL = histos.add("nSqAntiL", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#bar{#Lambda}) (GeV/#it{c});#it{p}_{T}(#bar{#Lambda}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptLambdaAxis, ptLambdaAxis}); - nSqL = histos.add("nSqL", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#Lambda) (GeV/#it{c});#it{p}_{T}(#Lambda) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptLambdaAxis, ptLambdaAxis}); - - nAntipAntid = histos.add("nAntipAntid", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#bar{p}) (GeV/#it{c});#it{p}_{T}(#bar{d}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptAntipAxis, ptAntidAxis}); - nLantiL = histos.add("nLantiL", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#Lambda) (GeV/#it{c});#it{p}_{T}(#bar{#Lambda}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptLambdaAxis, ptLambdaAxis}); - nLantid = histos.add("nLantid", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#Lambda) (GeV/#it{c});#it{p}_{T}(#bar{d}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptLambdaAxis, ptAntidAxis}); - nAntiLantid = histos.add("nAntiLantid", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#bar{#Lambda}) (GeV/#it{c});#it{p}_{T}(#bar{d}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptLambdaAxis, ptAntidAxis}); - - // mc generated - nGenAntid = histos.add("nGenAntid", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#bar{d}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptAntidAxis}); - nGenAntip = histos.add("nGenAntip", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#bar{p}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptAntipAxis}); - nGenAntiL = histos.add("nGenAntiL", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#bar{#Lambda}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptLambdaAxis}); - nGenL = histos.add("nGenL", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#Lambda) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptLambdaAxis}); - - nGenSqAntid = histos.add("nGenSqAntid", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#bar{d}) (GeV/#it{c});#it{p}_{T}(#bar{d}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptAntidAxis, ptAntidAxis}); - nGenSqAntip = histos.add("nGenSqAntip", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#bar{p}) (GeV/#it{c});#it{p}_{T}(#bar{p}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptAntipAxis, ptAntipAxis}); - nGenSqAntiL = histos.add("nGenSqAntiL", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#bar{#Lambda}) (GeV/#it{c});#it{p}_{T}(#bar{#Lambda}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptLambdaAxis, ptLambdaAxis}); - nGenSqL = histos.add("nGenSqL", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#Lambda) (GeV/#it{c});#it{p}_{T}(#Lambda) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptLambdaAxis, ptLambdaAxis}); - - nGenAntipAntid = histos.add("nGenAntipAntid", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#bar{p}) (GeV/#it{c});#it{p}_{T}(#bar{d}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptAntipAxis, ptAntidAxis}); - nGenLantiL = histos.add("nGenLantiL", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#Lambda) (GeV/#it{c});#it{p}_{T}(#bar{#Lambda}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptLambdaAxis, ptLambdaAxis}); - nGenLantid = histos.add("nGenLantid", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#Lambda) (GeV/#it{c});#it{p}_{T}(#bar{d}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptLambdaAxis, ptAntidAxis}); - nGenAntiLantid = histos.add("nGenAntiLantid", ";Subsample;Centrality (%);#Delta#eta;#it{p}_{T}(#bar{#Lambda}) (GeV/#it{c});#it{p}_{T}(#bar{d}) (GeV/#it{c});", HistType::kTHnSparseD, {subsampleAxis, centAxis, deltaEtaAxis, ptLambdaAxis, ptAntidAxis}); - - // event QA - if (doprocessRun3) { - histos.add("QA/PvMultVsCent", ";Centrality T0C (%);#it{N}_{PV contributors};", HistType::kTH2F, {centAxis, multAxis}); - histos.add("QA/MultVsCent", ";Centrality T0C (%);Multiplicity T0C;", HistType::kTH2F, {centAxis, multFt0Axis}); - } else if (doprocessRun2) { - histos.add("QA/V0MvsCL0", ";Centrality CL0 (%);Centrality V0M (%)", HistType::kTH2F, {centAxis, centAxis}); - histos.add("QA/trackletsVsV0M", ";Centrality CL0 (%);Centrality V0M (%)", HistType::kTH2F, {centAxis, multAxis}); - } - - // v0 QA - histos.add("QA/massLambda", ";Centrality (%);#it{p}_{T} (GeV/#it{c});#it{M}(p + #pi^{-}) (GeV/#it{c}^{2});Entries", HistType::kTH3F, {centAxis, momAxis, massLambdaAxis}); - histos.add("QA/cosPa", ";cosPa;Entries", HistType::kTH1F, {cosPaAxis}); - histos.add("QA/cosPaSig", ";cosPa;Entries", HistType::kTH1F, {cosPaAxis}); - histos.add("QA/cosPaBkg", ";cosPa;Entries", HistType::kTH1F, {cosPaAxis}); - histos.add("QA/dcaV0daughSig", ";dcaV0daugh;Entries", HistType::kTH1F, {dcaV0daughAxis}); - histos.add("QA/dcaV0daughBkg", ";dcaV0daugh;Entries", HistType::kTH1F, {dcaV0daughAxis}); - histos.add("QA/dcaV0PvSig", ";dcaV0Pv;Entries", HistType::kTH1F, {dcaV0daughAxis}); - histos.add("QA/dcaV0PvBkg", ";dcaV0Pv;Entries", HistType::kTH1F, {dcaV0daughAxis}); - histos.add("QA/cosPaDcaV0daughSig", ";cosPa;dcaV0daugh", HistType::kTH2F, {cosPaAxis, dcaV0daughAxis}); - histos.add("QA/cosPaDcaV0daughBkg", ";cosPa;dcaV0daugh", HistType::kTH2F, {cosPaAxis, dcaV0daughAxis}); - histos.add("QA/massLambdaEvRej", ";Centrality (%);#it{p}_{T} (GeV/#it{c});#it{M}(p + #pi^{-}) (GeV/#it{c}^{2});Entries", HistType::kTH3F, {centAxis, momAxis, massLambdaAxis}); - histos.add("QA/massLambdaEvRejSig", ";Centrality (%);#it{p}_{T} (GeV/#it{c});#it{M}(p + #pi^{-}) (GeV/#it{c}^{2});Entries", HistType::kTH3F, {centAxis, momAxis, massLambdaAxis}); - histos.add("QA/massLambdaEvRejBkg", ";Centrality (%);#it{p}_{T} (GeV/#it{c});#it{M}(p + #pi^{-}) (GeV/#it{c}^{2});Entries", HistType::kTH3F, {centAxis, momAxis, massLambdaAxis}); - histos.add("QA/radius", ";radius;Entries", HistType::kTH1F, {radiusAxis}); - histos.add("QA/dcaV0daugh", ";dcaV0daugh;Entries", HistType::kTH1F, {dcaV0daughAxis}); - histos.add("QA/dcaV0Pv", ";dcaV0Pv;Entries", HistType::kTH1F, {dcaV0daughAxis}); - histos.add("QA/dcaPosPv", ";dcaPosPv;Entries", HistType::kTH1F, {dcaDaughPvAxis}); - histos.add("QA/dcaNegPv", ";dcaNegPv;Entries", HistType::kTH1F, {dcaDaughPvAxis}); - histos.add("QA/cosPaBeforeCut", ";cosPa;Entries", HistType::kTH1F, {cosPaAxis}); - histos.add("QA/radiusBeforeCut", ";radius;Entries", HistType::kTH1F, {radiusAxis}); - histos.add("QA/dcaV0daughBeforeCut", ";dcaV0daugh;Entries", HistType::kTH1F, {dcaV0daughAxis}); - histos.add("QA/dcaV0PvBeforeCut", ";dcaV0Pv;Entries", HistType::kTH1F, {dcaV0daughAxis}); - - // d QA - histos.add("QA/dcaPv", ";#it{p}_{T} (GeV/#it{c});dcaPv;Entries", HistType::kTH2F, {momAxis, dcaDaughPvAxis}); - histos.add("QA/nClsTPC", ";tpcCls;Entries", HistType::kTH1F, {tpcClsAxis}); - histos.add("QA/nCrossedRowsTPC", ";nCrossedRowsTPC;Entries", HistType::kTH1F, {tpcClsAxis}); - histos.add("QA/dcaPvBefore", ";#it{p}_{T} (GeV/#it{c});dcaPv;Entries", HistType::kTH2F, {momAxis, dcaDaughPvAxis}); - histos.add("QA/nClsTPCBeforeCut", ";tpcCls;Entries", HistType::kTH1F, {tpcClsAxis}); - histos.add("QA/nCrossedRowsTPCBeforeCut", ";nCrossedRowsTPC;Entries", HistType::kTH1F, {tpcClsAxis}); - - // antid and antip QA - histos.add("QA/tpcSignal", ";#it{p}_{TPC} (GeV/#it{c});d#it{E}/d#it{x}_{TPC} (a.u.)", HistType::kTH2F, {momAxisFine, tpcAxis}); - histos.add("QA/tpcSignal_glo", ";#it{p}_{glo} (GeV/#it{c});d#it{E}/d#it{x}_{TPC} (a.u.);", HistType::kTH2F, {momAxisFine, tpcAxis}); - - tpcNsigma[0] = histos.add("QA/tpcNsigma_p", ";#it{p}_{TPC} (GeV/#it{c});n#sigma_{TPC} (a.u.)", HistType::kTH2F, {momAxis, tpcNsigmaAxis}); - tpcNsigmaGlo[0] = histos.add("QA/tpcNsigmaGlo_p", ";Centrality (%);#it{p}_{T} (GeV/#it{c});n#sigma_{TPC} (a.u.)", HistType::kTH3F, {centAxis, momAxis, tpcNsigmaAxis}); - tofMass[0] = histos.add("QA/tofMass_p", ";Centrality (%);#it{p}_{T} (GeV/#it{c});Mass (GeV/#it{c}^{2});Entries", HistType::kTH3F, {centAxis, momAxis, tofMassAxis}); - tofSignal[0] = histos.add("QA/tofSignal_p", ";#it{p}_{TPC} (GeV/#it{c});#beta_{TOF}", HistType::kTH2F, {momAxisFine, tofAxis}); - tofSignal_glo[0] = histos.add("QA/tofSignal_glo_p", ";#it{p}_{T} (GeV/#it{c});#beta_{TOF}", HistType::kTH2F, {momAxisFine, tofAxis}); - - tpcNsigma[1] = histos.add("QA/tpcNsigma_d", ";#it{p}_{TPC} (GeV/#it{c});n#sigma_{TPC} (a.u.)", HistType::kTH2F, {momAxis, tpcNsigmaAxis}); - tpcNsigmaGlo[1] = histos.add("QA/tpcNsigmaGlo_d", ";Centrality (%);#it{p}_{T} (GeV/#it{c});n#sigma_{TPC} (a.u.)", HistType::kTH3F, {centAxis, momAxis, tpcNsigmaAxis}); - tofMass[1] = histos.add("QA/tofMass_d", ";Centrality (%);#it{p}_{T} (GeV/#it{c});Mass (GeV/#it{c}^{2});Entries", HistType::kTH3F, {centAxis, momAxis, tofMassAxis}); - tofSignal[1] = histos.add("QA/tofSignal_d", ";#it{p}_{TPC} (GeV/#it{c});#beta_{TOF}", HistType::kTH2F, {momAxisFine, tofAxis}); - tofSignal_glo[1] = histos.add("QA/tofSignal_glo_d", ";#it{p}_{T} (GeV/#it{c});#beta_{TOF}", HistType::kTH2F, {momAxisFine, tofAxis}); - - // mc histograms - if (doprocessMcRun3 || doprocessMcRun2) { - histos.add("recL", ";Centrality (%); #it{p}_{T} (GeV/#it{c});#Delta#eta", HistType::kTH3D, {centAxis, ptLambdaAxis, deltaEtaAxis}); - histos.add("recAntiL", ";Centrality (%); #it{p}_{T} (GeV/#it{c});#Delta#eta", HistType::kTH3D, {centAxis, ptLambdaAxis, deltaEtaAxis}); - recTracks[0] = histos.add("recP", ";Centrality (%); #it{p}_{T} (GeV/#it{c});#Delta#eta", HistType::kTH3D, {centAxis, ptAntipAxis, deltaEtaAxis}); - recTracks[1] = histos.add("recD", ";Centrality (%); #it{p}_{T} (GeV/#it{c});#Delta#eta", HistType::kTH3D, {centAxis, ptAntidAxis, deltaEtaAxis}); - recAntiTracks[0] = histos.add("recAntip", ";Centrality (%); #it{p}_{T} (GeV/#it{c});#Delta#eta", HistType::kTH3D, {centAxis, ptAntipAxis, deltaEtaAxis}); - recAntiTracks[1] = histos.add("recAntid", ";Centrality (%); #it{p}_{T} (GeV/#it{c});#Delta#eta", HistType::kTH3D, {centAxis, ptAntidAxis, deltaEtaAxis}); - histos.add("genL", ";Centrality (%); #it{p}_{T} (GeV/#it{c});#Delta#eta", HistType::kTH3D, {centAxis, ptLambdaAxis, deltaEtaAxis}); - histos.add("genAntiL", ";Centrality (%); #it{p}_{T} (GeV/#it{c});#Delta#eta", HistType::kTH3D, {centAxis, ptLambdaAxis, deltaEtaAxis}); - genTracks[0] = histos.add("genP", ";Centrality (%); #it{p}_{T} (GeV/#it{c});#Delta#eta", HistType::kTH3D, {centAxis, ptAntipAxis, deltaEtaAxis}); - genTracks[1] = histos.add("genD", ";Centrality (%); #it{p}_{T} (GeV/#it{c});#Delta#eta", HistType::kTH3D, {centAxis, ptAntidAxis, deltaEtaAxis}); - genAntiTracks[0] = histos.add("genAntip", ";Centrality (%); #it{p}_{T} (GeV/#it{c});#Delta#eta", HistType::kTH3D, {centAxis, ptAntipAxis, deltaEtaAxis}); - genAntiTracks[1] = histos.add("genAntid", ";Centrality (%); #it{p}_{T} (GeV/#it{c});#Delta#eta", HistType::kTH3D, {centAxis, ptAntidAxis, deltaEtaAxis}); - } - - // temporary histograms - tempTracks[0] = tempHistos.add("tempAntip", ";#Delta#eta;#it{p}_{T} (GeV/#it{c})", HistType::kTH2D, {deltaEtaAxis, ptAntipAxis}); - tempTracks[1] = tempHistos.add("tempAntid", ";#Delta#eta;#it{p}_{T} (GeV/#it{c})", HistType::kTH2D, {deltaEtaAxis, ptAntidAxis}); - tempLambda = tempHistos.add("tempLambda", ";#Delta#eta;#it{p}_{T} (GeV/#it{c})", HistType::kTH2D, {deltaEtaAxis, ptLambdaAxis}); - tempAntiLambda = tempHistos.add("tempAntiLambda", ";#Delta#eta;#it{p}_{T} (GeV/#it{c})", HistType::kTH2D, {deltaEtaAxis, ptLambdaAxis}); - - ptMin = std::array{config.antipPtMin, config.antidPtMin}; - ptMax = std::array{config.antipPtMax, config.antidPtMax}; - ptTof = std::array{config.antipPtTof, config.antidPtTof}; - - nSigmaTpcCutLow = std::array{config.antipNsigmaTpcCutLow, config.antidNsigmaTpcCutLow}; - nSigmaTpcCutUp = std::array{config.antipNsigmaTpcCutUp, config.antidNsigmaTpcCutUp}; - nSigmaTofCut = std::array{config.antipNsigmaTofCut, config.antidNsigmaTofCut}; - tpcInnerParamMax = std::array{config.antipTpcInnerParamMax, config.antidTpcInnerParamMax}; - tofMassMax = std::array{config.antipTofMassMax, config.antidTofMassMax}; - } - - template - int fillRecoEvent(C const& collision, T const& tracksAll, aod::V0s const& V0s, float const& centrality) - { - auto tracks = (doprocessRun3 || doprocessMcRun3) ? tracksAll.sliceBy(perCollisionTracksFullIU, collision.globalIndex()) : tracksAll.sliceBy(perCollisionTracksFull, collision.globalIndex()); - candidateTracks[0].clear(); - candidateTracks[1].clear(); - candidateV0s.clear(); - - tempTracks[0]->Reset(); - tempTracks[1]->Reset(); - tempLambda->Reset(); - tempAntiLambda->Reset(); - auto rnd = static_cast(gen32()) / static_cast(gen32.max()); - auto subsample = static_cast(rnd * nSubsamples); - - std::array dcaInfo; - int nTracklets[2]{0, 0}; - for (const auto& track : tracks) { - - histos.fill(HIST("QA/nClsTPCBeforeCut"), track.tpcNClsFound()); - histos.fill(HIST("QA/nCrossedRowsTPCBeforeCut"), track.tpcNClsCrossedRows()); - - if (track.trackType() == 255 && std::abs(track.eta()) < 1.2) { // tracklet - nTracklets[std::abs(track.eta()) < 0.6]++; - histos.fill(HIST("QA/TrklEta"), track.eta()); - } - - if (!selectTrack(track)) { - continue; - } - - if (track.sign() > 0.) { - continue; - } - - auto trackParCov = getTrackParCov(track); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCov, 2.f, fitter.getMatCorrType(), &dcaInfo); - auto dca = std::hypot(dcaInfo[0], dcaInfo[1]); - auto trackPt = trackParCov.getPt(); - auto trackEta = trackParCov.getEta(); - histos.fill(HIST("QA/dcaPvBefore"), trackPt, dca); - if (dca > config.trackDcaCut) { - continue; - } - histos.fill(HIST("QA/dcaPv"), trackPt, dca); - - histos.fill(HIST("QA/nClsTPC"), track.tpcNClsFound()); - histos.fill(HIST("QA/nCrossedRowsTPC"), track.tpcNClsCrossedRows()); - histos.fill(HIST("QA/tpcSignal"), track.tpcInnerParam(), track.tpcSignal()); - histos.fill(HIST("QA/tpcSignal_glo"), track.p(), track.tpcSignal()); - - for (int iP{0}; iP < kNpart; ++iP) { - if (trackPt < ptMin[iP] || trackPt > ptMax[iP]) { - continue; - } - - if (doprocessRun3 || doprocessMcRun3) { - float cosL = 1 / std::sqrt(1.f + track.tgl() * track.tgl()); - if (iP && getITSClSize(track) * cosL < config.antidItsClsSizeCut && trackPt < config.antidPtItsClsSizeCut) { - continue; - } - } - - double expBethe{tpc::BetheBlochAleph(static_cast(track.tpcInnerParam() / partMass[iP]), config.cfgBetheBlochParams->get(iP, "p0"), config.cfgBetheBlochParams->get(iP, "p1"), config.cfgBetheBlochParams->get(iP, "p2"), config.cfgBetheBlochParams->get(iP, "p3"), config.cfgBetheBlochParams->get(iP, "p4"))}; - double expSigma{expBethe * config.cfgBetheBlochParams->get(iP, "resolution")}; - auto nSigmaTPC = static_cast((track.tpcSignal() - expBethe) / expSigma); - - float beta{track.hasTOF() ? track.length() / (track.tofSignal() - track.tofEvTime()) * o2::constants::physics::invLightSpeedCm2PS : -999.f}; - beta = std::min(1.f - 1.e-6f, std::max(1.e-4f, beta)); - float mass{track.tpcInnerParam() * std::sqrt(1.f / (beta * beta) - 1.f)}; - bool hasTof = track.hasTOF() && track.tofChi2() < 3; - - if (trackPt <= ptTof[iP] || (trackPt > ptTof[iP] && hasTof && std::abs(mass - partMass[iP]) < config.tofMassMaxQA)) { // for QA histograms - tpcNsigmaGlo[iP]->Fill(centrality, trackPt, nSigmaTPC); - if (nSigmaTPC > nSigmaTpcCutLow[iP] && nSigmaTPC < nSigmaTpcCutUp[iP]) { - tofMass[iP]->Fill(centrality, trackPt, mass); - } - } - - if (nSigmaTPC < nSigmaTpcCutLow[iP] || nSigmaTPC > nSigmaTpcCutUp[iP]) { - continue; - } - - tpcNsigma[iP]->Fill(track.tpcInnerParam(), nSigmaTPC); - if (trackPt > ptTof[iP] && hasTof) { - tofSignal_glo[iP]->Fill(track.p(), beta); - tofSignal[iP]->Fill(track.tpcInnerParam(), beta); - } - - // temporary cut to reject fake matches (run 3) - if (track.tpcInnerParam() < tpcInnerParamMax[iP]) { - continue; - } - if (trackPt > ptTof[iP] && !hasTof) { - continue; - } - - if (trackPt <= ptTof[iP] || (trackPt > ptTof[iP] && hasTof && std::abs(mass - partMass[iP]) < tofMassMax[iP])) { - tempTracks[iP]->Fill(std::abs(trackEta), trackPt); - CandidateTrack candTrack; - candTrack.pt = trackPt; - candTrack.eta = trackEta; - candTrack.globalIndex = track.globalIndex(); - candidateTracks[iP].push_back(candTrack); - } - } - } - histos.fill(HIST("QA/nTrklCorrelation"), nTracklets[0], nTracklets[1]); - - std::vector trkId; - for (const auto& v0 : V0s) { - auto posTrack = v0.posTrack_as(); - auto negTrack = v0.negTrack_as(); - - bool posSelect = selectV0Daughter(posTrack); - bool negSelect = selectV0Daughter(negTrack); - if (!posSelect || !negSelect) - continue; - - if (doprocessRun2 || doprocessMcRun2) { - bool checkPosPileUp = posTrack.hasTOF() || (posTrack.flags() & o2::aod::track::ITSrefit); - bool checkNegPileUp = negTrack.hasTOF() || (negTrack.flags() & o2::aod::track::ITSrefit); - if (!checkPosPileUp && !checkNegPileUp) { - continue; - } - } - - auto posTrackCov = getTrackParCov(posTrack); - auto negTrackCov = getTrackParCov(negTrack); - - int nCand = 0; - try { - nCand = fitter.process(posTrackCov, negTrackCov); - } catch (...) { - LOG(error) << "Exception caught in DCA fitter process call!"; - continue; - } - if (nCand == 0) { - continue; - } - - auto& posPropTrack = fitter.getTrack(0); - auto& negPropTrack = fitter.getTrack(1); - - std::array momPos; - std::array momNeg; - std::array momV0; - posPropTrack.getPxPyPzGlo(momPos); - negPropTrack.getPxPyPzGlo(momNeg); - momTotXYZ(momV0, momPos, momNeg); - - auto ptV0 = std::hypot(momV0[0], momV0[1]); - if (ptV0 < config.lambdaPtMin || ptV0 > config.lambdaPtMax) { - continue; - } - - auto etaV0 = etaFromMom(momPos, momNeg); - if (std::abs(etaV0) > config.etaMax) { - continue; - } - - auto alpha = alphaAP(momV0, momPos, momNeg); - bool matter = alpha > 0; - auto massPos = matter ? o2::constants::physics::MassProton : o2::constants::physics::MassPionCharged; - auto massNeg = matter ? o2::constants::physics::MassPionCharged : o2::constants::physics::MassProton; - auto mLambda = invMass2Body(momV0, momPos, momNeg, massPos, massNeg); - auto mK0Short = invMass2Body(momV0, momPos, momNeg, o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged); - - // pid selections - double expBethePos{tpc::BetheBlochAleph(static_cast(posTrack.tpcInnerParam() / massPos), config.cfgBetheBlochParams->get("p0"), config.cfgBetheBlochParams->get("p1"), config.cfgBetheBlochParams->get("p2"), config.cfgBetheBlochParams->get("p3"), config.cfgBetheBlochParams->get("p4"))}; - double expSigmaPos{expBethePos * config.cfgBetheBlochParams->get("resolution")}; - auto nSigmaTPCPos = static_cast((posTrack.tpcSignal() - expBethePos) / expSigmaPos); - double expBetheNeg{tpc::BetheBlochAleph(static_cast(negTrack.tpcInnerParam() / massNeg), config.cfgBetheBlochParams->get("p0"), config.cfgBetheBlochParams->get("p1"), config.cfgBetheBlochParams->get("p2"), config.cfgBetheBlochParams->get("p3"), config.cfgBetheBlochParams->get("p4"))}; - double expSigmaNeg{expBetheNeg * config.cfgBetheBlochParams->get("resolution")}; - auto nSigmaTPCNeg = static_cast((negTrack.tpcSignal() - expBetheNeg) / expSigmaNeg); - - if (std::abs(nSigmaTPCPos) > config.v0setting_nsigmatpc || std::abs(nSigmaTPCNeg) > config.v0setting_nsigmatpc) { - continue; - } - - // veto on K0s mass - if (std::abs(mK0Short - o2::constants::physics::MassK0Short) < config.vetoMassK0Short) { - continue; - } - - float dcaV0dau = std::sqrt(fitter.getChi2AtPCACandidate()); - histos.fill(HIST("QA/dcaV0daughBeforeCut"), dcaV0dau); - if (dcaV0dau > config.v0setting_dcav0dau) { - continue; - } - - std::array primVtx = {collision.posX(), collision.posY(), collision.posZ()}; - const auto& vtx = fitter.getPCACandidate(); - - float radiusV0 = std::hypot(vtx[0], vtx[1]); - histos.fill(HIST("QA/radiusBeforeCut"), radiusV0); - if (radiusV0 < config.v0setting_radius || radiusV0 > config.v0radiusMax) { - continue; - } - - float dcaV0Pv = CalculateDCAStraightToPV( - vtx[0], vtx[1], vtx[2], - momPos[0] + momNeg[0], - momPos[1] + momNeg[1], - momPos[2] + momNeg[2], - collision.posX(), collision.posY(), collision.posZ()); - histos.fill(HIST("QA/dcaV0PvBeforeCut"), dcaV0Pv); - if (std::abs(dcaV0Pv) > config.v0setting_dcav0pv) { - continue; - } - - double cosPA = RecoDecay::cpa(primVtx, vtx, momV0); - histos.fill(HIST("QA/cosPaBeforeCut"), cosPA); - if (cosPA < config.v0setting_cospa) { - continue; - } - - auto ptotal = RecoDecay::sqrtSumOfSquares(momV0[0], momV0[1], momV0[2]); - auto lengthTraveled = RecoDecay::sqrtSumOfSquares(vtx[0] - primVtx[0], vtx[1] - primVtx[1], vtx[2] - primVtx[2]); - float ML2P_Lambda = o2::constants::physics::MassLambda * lengthTraveled / ptotal; - if (ML2P_Lambda > config.v0setting_lifetime) { - continue; - } - - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, posTrackCov, 2.f, fitter.getMatCorrType(), &dcaInfo); - auto posDcaToPv = std::hypot(dcaInfo[0], dcaInfo[1]); - if (posDcaToPv < config.v0setting_dcadaughtopv && std::abs(dcaInfo[0]) < config.v0setting_dcadaughtopv) { - continue; - } - - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, negTrackCov, 2.f, fitter.getMatCorrType(), &dcaInfo); - auto negDcaToPv = std::hypot(dcaInfo[0], dcaInfo[1]); - if (negDcaToPv < config.v0setting_dcadaughtopv && std::abs(dcaInfo[0]) < config.v0setting_dcadaughtopv) { - continue; - } - - if (std::abs(mLambda - o2::constants::physics::MassLambda0) > config.lambdaMassCutQA) { // for QA histograms - continue; - } - histos.fill(HIST("QA/massLambda"), centrality, ptV0, mLambda); - - if (std::abs(mLambda - o2::constants::physics::MassLambda0) > config.lambdaMassCut) { - continue; - } - histos.fill(HIST("QA/cosPa"), cosPA); - histos.fill(HIST("QA/radius"), radiusV0); - histos.fill(HIST("QA/dcaV0daugh"), dcaV0dau); - histos.fill(HIST("QA/dcaPosPv"), posDcaToPv); - histos.fill(HIST("QA/dcaNegPv"), negDcaToPv); - histos.fill(HIST("QA/dcaV0Pv"), dcaV0Pv); - - if (matter) { - tempHistos.fill(HIST("tempLambda"), std::abs(etaV0), ptV0); - } else { - tempHistos.fill(HIST("tempAntiLambda"), std::abs(etaV0), ptV0); - } - - trkId.emplace_back(posTrack.globalIndex()); - trkId.emplace_back(negTrack.globalIndex()); - - CandidateV0 candV0; - candV0.pt = ptV0; - candV0.eta = etaV0; - candV0.mass = mLambda; - candV0.cpa = cosPA; - candV0.dcav0daugh = dcaV0dau; - candV0.dcav0pv = dcaV0Pv; - candV0.globalIndexPos = posTrack.globalIndex(); - candV0.globalIndexNeg = negTrack.globalIndex(); - candidateV0s.push_back(candV0); - } - - // reject events having multiple v0s from same tracks (TODO: also across collisions?) - std::sort(trkId.begin(), trkId.end()); - if ((std::adjacent_find(trkId.begin(), trkId.end()) != trkId.end()) && config.fillOnlySignal) { - candidateV0s.clear(); - - CandidateV0 candV0; - candV0.pt = -999.f; - candV0.eta = -999.f; - candV0.globalIndexPos = -999; - candV0.globalIndexNeg = -999; - candidateV0s.push_back(candV0); - return -1; - } - for (auto& candidateV0 : candidateV0s) { - histos.fill(HIST("QA/massLambdaEvRej"), centrality, candidateV0.pt, candidateV0.mass); - } - - histos.fill(HIST("nEv"), subsample, centrality); - - if ((doprocessMcRun3 || doprocessMcRun2) && config.fillOnlySignal) - return subsample; - - fillHistoN(nAntip, tempTracks[0], subsample, centrality); - fillHistoN(nAntid, tempTracks[1], subsample, centrality); - fillHistoN(nAntiL, tempAntiLambda, subsample, centrality); - fillHistoN(nL, tempLambda, subsample, centrality); - - fillHistoN(nSqAntip, tempTracks[0], tempTracks[0], subsample, centrality); - fillHistoN(nSqAntid, tempTracks[1], tempTracks[1], subsample, centrality); - fillHistoN(nSqAntiL, tempAntiLambda, tempAntiLambda, subsample, centrality); - fillHistoN(nSqL, tempLambda, tempLambda, subsample, centrality); - - fillHistoN(nAntipAntid, tempTracks[0], tempTracks[1], subsample, centrality); - fillHistoN(nLantid, tempLambda, tempTracks[1], subsample, centrality); - fillHistoN(nLantiL, tempLambda, tempAntiLambda, subsample, centrality); - fillHistoN(nAntiLantid, tempAntiLambda, tempTracks[1], subsample, centrality); - - histos.fill(HIST("QA/nRecPerEvAntip"), centrality, tempTracks[0]->GetEntries()); - histos.fill(HIST("QA/nRecPerEvAntid"), centrality, tempTracks[1]->GetEntries()); - histos.fill(HIST("QA/nRecPerEvAntiL"), centrality, tempAntiLambda->GetEntries()); - histos.fill(HIST("QA/nRecPerEvL"), centrality, tempLambda->GetEntries()); - - return 0; - } - - template - void fillMcEvent(C const& collision, T const& tracks, aod::V0s const& V0s, float const& centrality, aod::McParticles const&, aod::McTrackLabels const& mcLabels) - { - int subsample = fillRecoEvent(collision, tracks, V0s, centrality); - if (candidateV0s.size() == 1 && candidateV0s[0].pt < -998.f && candidateV0s[0].eta < -998.f && candidateV0s[0].globalIndexPos == -999 && candidateV0s[0].globalIndexPos == -999) { - return; - } - - if (config.fillOnlySignal) { - tempTracks[0]->Reset(); - tempTracks[1]->Reset(); - tempLambda->Reset(); - tempAntiLambda->Reset(); - } - - for (int iP{0}; iP < kNpart; ++iP) { - for (auto& candidateTrack : candidateTracks[iP]) { - auto mcLab = mcLabels.rawIteratorAt(candidateTrack.globalIndex); - if (mcLab.has_mcParticle()) { - auto mcTrack = mcLab.template mcParticle_as(); - if (std::abs(mcTrack.pdgCode()) != partPdg[iP]) - continue; - if (((mcTrack.flags() & 0x8) && doprocessMcRun2) || (mcTrack.flags() & 0x2) || (mcTrack.flags() & 0x1)) - continue; - if (!mcTrack.isPhysicalPrimary()) - continue; - if (mcTrack.pdgCode() > 0) { - recTracks[iP]->Fill(centrality, candidateTrack.pt, std::abs(candidateTrack.eta)); - } else { - recAntiTracks[iP]->Fill(centrality, candidateTrack.pt, std::abs(candidateTrack.eta)); - if (config.fillOnlySignal) - tempTracks[iP]->Fill(std::abs(candidateTrack.eta), candidateTrack.pt); - } - } - } - } - for (auto& candidateV0 : candidateV0s) { - auto mcLabPos = mcLabels.rawIteratorAt(candidateV0.globalIndexPos); - auto mcLabNeg = mcLabels.rawIteratorAt(candidateV0.globalIndexNeg); - - if (mcLabPos.has_mcParticle() && mcLabNeg.has_mcParticle()) { - auto mcTrackPos = mcLabPos.template mcParticle_as(); - auto mcTrackNeg = mcLabNeg.template mcParticle_as(); - if (mcTrackPos.has_mothers() && mcTrackNeg.has_mothers()) { - for (auto& negMother : mcTrackNeg.template mothers_as()) { - for (auto& posMother : mcTrackPos.template mothers_as()) { - if (posMother.globalIndex() != negMother.globalIndex()) - continue; - if (!((mcTrackPos.pdgCode() == 2212 && mcTrackNeg.pdgCode() == -211) || (mcTrackPos.pdgCode() == 211 && mcTrackNeg.pdgCode() == -2212))) - continue; - if (std::abs(posMother.pdgCode()) != 3122) { - histos.fill(HIST("QA/cosPaBkg"), candidateV0.cpa); - histos.fill(HIST("QA/dcaV0daughBkg"), candidateV0.dcav0daugh); - histos.fill(HIST("QA/dcaV0PvBkg"), candidateV0.dcav0pv); - histos.fill(HIST("QA/cosPaDcaV0daughBkg"), candidateV0.cpa, candidateV0.dcav0daugh); - histos.fill(HIST("QA/massLambdaEvRejBkg"), centrality, candidateV0.pt, candidateV0.mass); - continue; - } - if (!posMother.isPhysicalPrimary() && !posMother.has_mothers()) - continue; - if (((posMother.flags() & 0x8) && doprocessMcRun2) || (posMother.flags() & 0x2) || (posMother.flags() & 0x1)) - continue; - histos.fill(HIST("QA/cosPaSig"), candidateV0.cpa); - histos.fill(HIST("QA/dcaV0daughSig"), candidateV0.dcav0daugh); - histos.fill(HIST("QA/dcaV0PvSig"), candidateV0.dcav0pv); - histos.fill(HIST("QA/cosPaDcaV0daughSig"), candidateV0.cpa, candidateV0.dcav0daugh); - histos.fill(HIST("QA/massLambdaEvRejSig"), centrality, candidateV0.pt, candidateV0.mass); - if (posMother.pdgCode() > 0) { - histos.fill(HIST("recL"), centrality, candidateV0.pt, std::abs(candidateV0.eta)); - if (config.fillOnlySignal) - tempLambda->Fill(std::abs(candidateV0.eta), candidateV0.pt); - } else { - histos.fill(HIST("recAntiL"), centrality, candidateV0.pt, std::abs(candidateV0.eta)); - if (config.fillOnlySignal) - tempAntiLambda->Fill(std::abs(candidateV0.eta), candidateV0.pt); - } - } - } - } - } - } - - if (config.fillOnlySignal) { - fillHistoN(nAntip, tempTracks[0], subsample, centrality); - fillHistoN(nAntid, tempTracks[1], subsample, centrality); - fillHistoN(nAntiL, tempAntiLambda, subsample, centrality); - fillHistoN(nL, tempLambda, subsample, centrality); - - fillHistoN(nSqAntip, tempTracks[0], tempTracks[0], subsample, centrality); - fillHistoN(nSqAntid, tempTracks[1], tempTracks[1], subsample, centrality); - fillHistoN(nSqAntiL, tempAntiLambda, tempAntiLambda, subsample, centrality); - fillHistoN(nSqL, tempLambda, tempLambda, subsample, centrality); - - fillHistoN(nAntipAntid, tempTracks[0], tempTracks[1], subsample, centrality); - fillHistoN(nLantid, tempLambda, tempTracks[1], subsample, centrality); - fillHistoN(nLantiL, tempLambda, tempAntiLambda, subsample, centrality); - fillHistoN(nAntiLantid, tempAntiLambda, tempTracks[1], subsample, centrality); - - histos.fill(HIST("QA/nRecPerEvAntip"), centrality, tempTracks[0]->GetEntries()); - histos.fill(HIST("QA/nRecPerEvAntid"), centrality, tempTracks[1]->GetEntries()); - histos.fill(HIST("QA/nRecPerEvAntiL"), centrality, tempAntiLambda->GetEntries()); - histos.fill(HIST("QA/nRecPerEvL"), centrality, tempLambda->GetEntries()); - } - } - - void fillMcGen(aod::McParticles const& mcParticles, aod::McTrackLabels const& /*mcLab*/, std::vector> const& goodCollisions) - { - for (uint64_t iC{0}; iC < goodCollisions.size(); ++iC) { - if (goodCollisions[iC].first == false) { - continue; - } - - tempTracks[0]->Reset(); - tempTracks[1]->Reset(); - tempLambda->Reset(); - tempAntiLambda->Reset(); - - auto centrality = goodCollisions[iC].second; - auto rnd = static_cast(gen32()) / static_cast(gen32.max()); - auto subsample = static_cast(rnd * nSubsamples); - auto mcParticles_thisCollision = mcParticles.sliceBy(perCollisionMcParts, iC); - for (auto& mcPart : mcParticles_thisCollision) { - auto genEta = mcPart.eta(); - if (std::abs(genEta) > config.etaMax) { - continue; - } - if (((mcPart.flags() & 0x8) && doprocessMcRun2) || (mcPart.flags() & 0x2) || (mcPart.flags() & 0x1)) - continue; - auto pdgCode = mcPart.pdgCode(); - if (std::abs(pdgCode) == 3122) { - if (!mcPart.isPhysicalPrimary() && !mcPart.has_mothers()) - continue; - bool foundPr = false; - for (auto& mcDaught : mcPart.daughters_as()) { - if (std::abs(mcDaught.pdgCode()) == 2212) { - foundPr = true; - break; - } - } - if (!foundPr) { - continue; - } - auto genPt = std::hypot(mcPart.px(), mcPart.py()); - - if (pdgCode > 0) { - histos.fill(HIST("genL"), centrality, genPt, std::abs(genEta)); - tempHistos.fill(HIST("tempLambda"), std::abs(genEta), genPt); - } else { - histos.fill(HIST("genAntiL"), centrality, genPt, std::abs(genEta)); - tempHistos.fill(HIST("tempAntiLambda"), std::abs(genEta), genPt); - } - } else if (std::abs(pdgCode) == partPdg[0] || std::abs(pdgCode) == partPdg[1]) { - int iP = 1; - if (std::abs(pdgCode) == partPdg[0]) { - iP = 0; - } - if (!mcPart.isPhysicalPrimary() && !mcPart.has_mothers()) - continue; - auto genPt = std::hypot(mcPart.px(), mcPart.py()); - if (pdgCode > 0) { - genTracks[iP]->Fill(centrality, genPt, std::abs(genEta)); - } else { - genAntiTracks[iP]->Fill(centrality, genPt, std::abs(genEta)); - tempTracks[iP]->Fill(std::abs(genEta), genPt); - } - } - } - - fillHistoN(nGenAntip, tempTracks[0], subsample, centrality); - fillHistoN(nGenAntid, tempTracks[1], subsample, centrality); - fillHistoN(nGenAntiL, tempAntiLambda, subsample, centrality); - fillHistoN(nGenL, tempLambda, subsample, centrality); - - fillHistoN(nGenSqAntip, tempTracks[0], tempTracks[0], subsample, centrality); - fillHistoN(nGenSqAntid, tempTracks[1], tempTracks[1], subsample, centrality); - fillHistoN(nGenSqAntiL, tempAntiLambda, tempAntiLambda, subsample, centrality); - fillHistoN(nGenSqL, tempLambda, tempLambda, subsample, centrality); - - fillHistoN(nGenAntipAntid, tempTracks[0], tempTracks[1], subsample, centrality); - fillHistoN(nGenLantid, tempLambda, tempTracks[1], subsample, centrality); - fillHistoN(nGenLantiL, tempLambda, tempAntiLambda, subsample, centrality); - fillHistoN(nGenAntiLantid, tempAntiLambda, tempTracks[1], subsample, centrality); - } - } - - void processRun3(soa::Join const& collisions, TracksFullIU const& tracks, aod::V0s const& V0s, aod::BCsWithTimestamps const&) - { - for (const auto& collision : collisions) { - auto bc = collision.bc_as(); - initCCDB(bc); - - if (!collision.sel8()) - continue; - - if (std::abs(collision.posZ()) > config.zVtxMax) - continue; - - if (!collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) - continue; - - if (!collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) - continue; - - if (!collision.selection_bit(aod::evsel::kNoSameBunchPileup)) - continue; - - if (!collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) - continue; - - histos.fill(HIST("QA/zVtx"), collision.posZ()); - - const uint64_t collIdx = collision.globalIndex(); - auto V0Table_thisCollision = V0s.sliceBy(perCollisionV0, collIdx); - V0Table_thisCollision.bindExternalIndices(&tracks); - - auto multiplicity = collision.multFT0C(); - auto centrality = collision.centFT0C(); - fillRecoEvent(collision, tracks, V0Table_thisCollision, centrality); - - histos.fill(HIST("QA/PvMultVsCent"), centrality, collision.numContrib()); - histos.fill(HIST("QA/MultVsCent"), centrality, multiplicity); - } - } - PROCESS_SWITCH(antidLambdaEbye, processRun3, "process (Run 3)", false); - - void processRun2(soa::Join const& collisions, TracksFull const& tracks, aod::V0s const& V0s, BCsWithRun2Info const&) - { - for (const auto& collision : collisions) { - auto bc = collision.bc_as(); - initCCDB(bc); - - if (std::abs(collision.posZ()) > config.zVtxMax) - continue; - - if (!(bc.eventCuts() & BIT(aod::Run2EventCuts::kAliEventCutsAccepted))) - continue; - - if (config.kUseTPCPileUpCut && !(bc.eventCuts() & BIT(aod::Run2EventCuts::kTPCPileUp))) - continue; - - auto centrality = collision.centRun2V0M(); - if (!(collision.sel7() && collision.alias_bit(kINT7)) && (!config.kINT7Intervals || (config.kINT7Intervals && ((centrality >= 10 && centrality < 30) || centrality > 50)))) - continue; - - auto centralityCl0 = collision.centRun2CL0(); - if (config.kUseEstimatorsCorrelationCut) { - const auto& x = centralityCl0; - const double center = estimatorsCorrelationCoef[0] + estimatorsCorrelationCoef[1] * x; - const double sigma = estimatorsSigmaPars[0] + estimatorsSigmaPars[1] * x + estimatorsSigmaPars[2] * std::pow(x, 2) + estimatorsSigmaPars[3] * std::pow(x, 3); - if (centrality < center - deltaEstimatorNsigma[0] * sigma || centrality > center + deltaEstimatorNsigma[1] * sigma) { - continue; - } - } - - histos.fill(HIST("QA/zVtx"), collision.posZ()); - - const uint64_t collIdx = collision.globalIndex(); - auto V0Table_thisCollision = V0s.sliceBy(perCollisionV0, collIdx); - V0Table_thisCollision.bindExternalIndices(&tracks); - - auto multTracklets = collision.multTracklets(); - fillRecoEvent(collision, tracks, V0Table_thisCollision, centrality); - - histos.fill(HIST("QA/V0MvsCL0"), centralityCl0, centrality); - histos.fill(HIST("QA/trackletsVsV0M"), centrality, multTracklets); - } - } - PROCESS_SWITCH(antidLambdaEbye, processRun2, "process (Run 2)", false); - - void processMcRun3(soa::Join const& collisions, aod::McCollisions const& mcCollisions, TracksFullIU const& tracks, aod::V0s const& V0s, aod::McParticles const& mcParticles, aod::McTrackLabels const& mcLab, aod::BCsWithTimestamps const&) - { - std::vector> goodCollisions(mcCollisions.size(), std::make_pair(false, -999.)); - for (auto& collision : collisions) { - auto bc = collision.bc_as(); - initCCDB(bc); - - if (!collision.sel8()) - continue; - - if (!collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) - continue; - - if (!collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) - continue; - - if (!collision.selection_bit(aod::evsel::kNoSameBunchPileup)) - continue; - - if (!collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) - continue; - - if (std::abs(collision.posZ()) > config.zVtxMax) - continue; - - auto centrality = collision.centFT0C(); - goodCollisions[collision.mcCollisionId()].first = true; - goodCollisions[collision.mcCollisionId()].second = centrality; - - histos.fill(HIST("QA/zVtx"), collision.posZ()); - - const uint64_t collIdx = collision.globalIndex(); - auto V0Table_thisCollision = V0s.sliceBy(perCollisionV0, collIdx); - V0Table_thisCollision.bindExternalIndices(&tracks); - - fillMcEvent(collision, tracks, V0Table_thisCollision, centrality, mcParticles, mcLab); - if (candidateV0s.size() == 1 && candidateV0s[0].pt < -998.f && candidateV0s[0].eta < -998.f && candidateV0s[0].globalIndexPos == -999 && candidateV0s[0].globalIndexPos == -999) { - goodCollisions[collision.mcCollisionId()].first = false; - } - } - - fillMcGen(mcParticles, mcLab, goodCollisions); - } - PROCESS_SWITCH(antidLambdaEbye, processMcRun3, "process MC (Run 3)", false); - - void processMcRun2(soa::Join const& collisions, aod::McCollisions const& mcCollisions, TracksFull const& tracks, aod::V0s const& V0s, aod::McParticles const& mcParticles, aod::McTrackLabels const& mcLab, BCsWithRun2Info const&) - { - std::vector> goodCollisions(mcCollisions.size(), std::make_pair(false, -999.)); - for (auto& collision : collisions) { - auto bc = collision.bc_as(); - initCCDB(bc); - - if (std::abs(collision.posZ()) > config.zVtxMax) - continue; - - if (!(bc.eventCuts() & BIT(aod::Run2EventCuts::kAliEventCutsAccepted))) - continue; - - auto centrality = collision.centRun2V0M(); - goodCollisions[collision.mcCollisionId()].first = true; - goodCollisions[collision.mcCollisionId()].second = centrality; - - histos.fill(HIST("QA/zVtx"), collision.posZ()); - - const uint64_t collIdx = collision.globalIndex(); - auto V0Table_thisCollision = V0s.sliceBy(perCollisionV0, collIdx); - V0Table_thisCollision.bindExternalIndices(&tracks); - - fillMcEvent(collision, tracks, V0Table_thisCollision, centrality, mcParticles, mcLab); - if (candidateV0s.size() == 1 && candidateV0s[0].pt < -998.f && candidateV0s[0].eta < -998.f && candidateV0s[0].globalIndexPos == -999 && candidateV0s[0].globalIndexPos == -999) { - goodCollisions[collision.mcCollisionId()].first = false; - } - } - - fillMcGen(mcParticles, mcLab, goodCollisions); - } - PROCESS_SWITCH(antidLambdaEbye, processMcRun2, "process MC (Run 2)", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; -} diff --git a/PWGLF/Tasks/Nuspex/ebyeMult.cxx b/PWGLF/Tasks/Nuspex/ebyeMult.cxx deleted file mode 100644 index 63002a0ec31..00000000000 --- a/PWGLF/Tasks/Nuspex/ebyeMult.cxx +++ /dev/null @@ -1,584 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file ebyeMult.cxx -/// \brief task to carry out multiplicity measurements for lf ebye analyses -/// \author Mario Ciacco - -#include -#include -#include - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/Centrality.h" -// #include "Common/DataModel/Multiplicity.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/EventSelection.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "CCDB/BasicCCDBManager.h" - -#include "TFormula.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; - -using TracksFull = soa::Join; -using BCsWithRun2Info = soa::Join; - -namespace -{ -constexpr float dcaSels[3]{10., 10., 10.}; -static const std::vector dcaSelsNames{"dcaxy", "dcaz", "dca"}; -static const std::vector particleName{"tracks"}; -} // namespace - -struct CandidateTrack { - float pt = -999.f; - float eta = -999.f; - float dcapv = 0; - float dcaxypv = 0; - float dcazpv = 0; - float genpt = -999.f; - float geneta = -999.f; - int pdgcode = -999; - bool isreco = 0; - int64_t mcIndex = -999; - int64_t globalIndex = -999; -}; - -struct CandidateEvent { - int nTrkRec = -1; - int nTklRec = -1; -}; - -struct TagRun2V0MCalibration { - bool mCalibrationStored = false; - TH1* mhVtxAmpCorrV0A = nullptr; - TH1* mhVtxAmpCorrV0C = nullptr; - TH1* mhMultSelCalib = nullptr; - float mMCScalePars[6] = {0.0}; - TFormula* mMCScale = nullptr; -} Run2V0MInfo; - -enum PartTypes { - kPi = 0, - kKa = 1, - kPr = 2, - kEl = 3, - kMu = 4, - kSig = 5, - kXi = 6, - kOm = 7, - kOther = 8 -}; - -struct EbyeMult { - std::vector candidateTracks; - Service ccdb; - CandidateEvent candidateEvent; - - int mRunNumber; - float dBz; - uint8_t nTrackletsColl; - - ConfigurableAxis centAxis{"centAxis", {106, 0, 106}, "binning for the centrality"}; - ConfigurableAxis zVtxAxis{"zVtxAxis", {100, -20.f, 20.f}, "Binning for the vertex z in cm"}; - ConfigurableAxis multAxis{"multAxis", {100, 0.f, 100.f}, "Binning for the multiplicity axis"}; - ConfigurableAxis multFt0Axis{"multFt0Axis", {100, 0.f, 100.f}, "Binning for the ft0 multiplicity axis"}; - Configurable genName{"genName", "", "Genearator name: HIJING, PYTHIA8, ... Default: \"\""}; - - Configurable zVtxMax{"zVtxMax", 10.0f, "maximum z position of the primary vertex"}; - Configurable etaMax{"etaMax", 0.8f, "maximum eta"}; - - Configurable ptMin{"ptMin", 0.05f, "minimum pT (GeV/c)"}; - Configurable ptMax{"ptMax", 10.f, "maximum pT (GeV/c)"}; - - Configurable trackNcrossedRows{"trackNcrossedRows", 70, "Minimum number of crossed TPC rows"}; - Configurable trackNclusITScut{"trackNclusITScut", 2, "Minimum number of ITS clusters"}; - Configurable trackNclusTPCcut{"trackNclusTPCcut", 60, "Minimum number of TPC clusters"}; - Configurable trackChi2Cut{"trackChi2Cut", 4.f, "Maximum chi2/ncls in TPC"}; - Configurable> cfgDcaSels{"cfgDcaSels", {dcaSels, 1, 3, particleName, dcaSelsNames}, "DCA selections"}; - - HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - - Preslice perCollisionTracksFull = o2::aod::track::collisionId; - Preslice perCollisionMcParts = o2::aod::mcparticle::mcCollisionId; - - // TODO: add function to extract the particle type based on the pdg code - int getPartType(int const pdgCode) - { - switch (std::abs(pdgCode)) { - case 211: - return PartTypes::kPi; - case 321: - return PartTypes::kKa; - case 2212: - return PartTypes::kPr; - case 11: - return PartTypes::kEl; - case 13: - return PartTypes::kMu; - case 3222: - return PartTypes::kSig; - case 3112: - return PartTypes::kSig; - case 3312: - return PartTypes::kXi; - case 3334: - return PartTypes::kOm; - default: - return PartTypes::kOther; - } - } - - template - bool selectTrack(T const& track) - { - if (std::abs(track.eta()) > etaMax) { - return false; - } - if (!(track.itsClusterMap() & 0x01) && !(track.itsClusterMap() & 0x02)) { - return false; - } - if (track.itsNCls() < trackNclusITScut || - track.tpcNClsFound() < trackNclusTPCcut || - track.tpcNClsCrossedRows() < trackNcrossedRows || - track.tpcNClsCrossedRows() < 0.8 * track.tpcNClsFindable() || - track.tpcChi2NCl() > trackChi2Cut || - track.itsChi2NCl() > 36.f) { - return false; - } - if (doprocessRun2 || doprocessMcRun2) { - if (!(track.trackType() & o2::aod::track::Run2Track) || - !(track.flags() & o2::aod::track::TPCrefit) || - !(track.flags() & o2::aod::track::ITSrefit)) { - return false; - } - } - return true; - } - - template - void initCCDB(Bc const& bc) - { - if (mRunNumber == bc.runNumber()) { - return; - } - - auto timestamp = bc.timestamp(); - o2::parameters::GRPObject* grpo = 0x0; - o2::parameters::GRPMagField* grpmag = 0x0; - if (doprocessRun2 || doprocessMcRun2) { - auto grpPath{"GLO/GRP/GRP"}; - grpo = ccdb->getForTimeStamp("GLO/GRP/GRP", timestamp); - if (!grpo) { - LOG(fatal) << "Got nullptr from CCDB for path " << grpPath << " of object GRPObject for timestamp " << timestamp; - } - o2::base::Propagator::initFieldFromGRP(grpo); - TList* callst = ccdb->getForTimeStamp("Centrality/Estimators", bc.timestamp()); - auto getccdb = [callst](const char* ccdbhname) { - TH1* h = reinterpret_cast(callst->FindObject(ccdbhname)); - return h; - }; - auto getformulaccdb = [callst](const char* ccdbhname) { - TFormula* f = reinterpret_cast(callst->FindObject(ccdbhname)); - return f; - }; - Run2V0MInfo.mhVtxAmpCorrV0A = getccdb("hVtx_fAmplitude_V0A_Normalized"); - Run2V0MInfo.mhVtxAmpCorrV0C = getccdb("hVtx_fAmplitude_V0C_Normalized"); - Run2V0MInfo.mhMultSelCalib = getccdb("hMultSelCalib_V0M"); - Run2V0MInfo.mMCScale = getformulaccdb(TString::Format("%s-V0M", genName->c_str()).Data()); - if ((Run2V0MInfo.mhVtxAmpCorrV0A != nullptr) && (Run2V0MInfo.mhVtxAmpCorrV0C != nullptr) && (Run2V0MInfo.mhMultSelCalib != nullptr)) { - if (genName->length() != 0) { - if (Run2V0MInfo.mMCScale != nullptr) { - for (int ixpar = 0; ixpar < 6; ++ixpar) { - Run2V0MInfo.mMCScalePars[ixpar] = Run2V0MInfo.mMCScale->GetParameter(ixpar); - } - } else { - LOGF(fatal, "MC Scale information from V0M for run %d not available", bc.runNumber()); - } - } - Run2V0MInfo.mCalibrationStored = true; - } else { - LOGF(fatal, "Calibration information from V0M for run %d corrupted", bc.runNumber()); - } - } else { - auto grpmagPath{"GLO/Config/GRPMagField"}; - grpmag = ccdb->getForTimeStamp("GLO/Config/GRPMagField", timestamp); - if (!grpmag) { - LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField for timestamp " << timestamp; - } - o2::base::Propagator::initFieldFromGRP(grpmag); - } - // Fetch magnetic field from ccdb for current collision - dBz = o2::base::Propagator::Instance()->getNominalBz(); - LOG(info) << "Retrieved GRP for timestamp " << timestamp << " with magnetic field of " << dBz << " kG"; - mRunNumber = bc.runNumber(); - } - - float getV0M(int64_t const id, float const zvtx, aod::FV0As const& fv0as, aod::FV0Cs const& fv0cs) - { - auto fv0a = fv0as.rawIteratorAt(id); - auto fv0c = fv0cs.rawIteratorAt(id); - float multFV0A = 0; - float multFV0C = 0; - for (float const& amplitude : fv0a.amplitude()) { - multFV0A += amplitude; - } - - for (float const& amplitude : fv0c.amplitude()) { - multFV0C += amplitude; - } - - float v0m = -1; - auto scaleMC = [](float x, float pars[6]) { - return std::pow(((pars[0] + pars[1] * std::pow(x, pars[2])) - pars[3]) / pars[4], 1.0f / pars[5]); - }; - - if (Run2V0MInfo.mMCScale != nullptr) { - float multFV0M = multFV0A + multFV0C; - v0m = scaleMC(multFV0M, Run2V0MInfo.mMCScalePars); - LOGF(debug, "Unscaled v0m: %f, scaled v0m: %f", multFV0M, v0m); - } else { - v0m = multFV0A * Run2V0MInfo.mhVtxAmpCorrV0A->GetBinContent(Run2V0MInfo.mhVtxAmpCorrV0A->FindFixBin(zvtx)) + - multFV0C * Run2V0MInfo.mhVtxAmpCorrV0C->GetBinContent(Run2V0MInfo.mhVtxAmpCorrV0C->FindFixBin(zvtx)); - } - return v0m; - } - - void init(o2::framework::InitContext&) - { - - mRunNumber = 0; - dBz = 0; - - ccdb->setURL("http://alice-ccdb.cern.ch"); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setFatalWhenNull(false); - - // event QA - histos.add("QA/zVtx", ";#it{z}_{vtx} (cm);Entries", HistType::kTH1F, {zVtxAxis}); - histos.add("QA/V0MvsCL0", ";Centrality CL0 (%);Centrality V0M (%)", HistType::kTH2F, {centAxis, centAxis}); - histos.add("QA/trackletsVsV0M", ";Centrality CL0 (%);Centrality V0M (%)", HistType::kTH2F, {centAxis, multAxis}); - histos.add("QA/nTrklCorrelation", ";Tracklets |#eta| > 0.7; Tracklets |#eta| < 0.6", HistType::kTH2D, {{201, -0.5, 200.5}, {201, -0.5, 200.5}}); - histos.add("QA/nV0MCorrelation", ";V0M Multiplicity (%); Tracklets |#eta| < 0.6", HistType::kTH2D, {multAxis, {201, -0.5, 200.5}}); - histos.add("QA/TrklEta", ";Tracklets #eta; Entries", HistType::kTH1D, {{100, -3., 3.}}); - - // rec tracks - histos.add("RecTracks", ";Tracklets |#eta| > 0.7;#it{p}_{T} (GeV/#it{c});DCA_{#it{xy}} (cm)", HistType::kTH3D, {{201, -0.5, 200.5}, {100, -5., 5.}, {200, -1., 1.}}); - histos.add("RecTracksV0M", ";V0M Multiplicity (%);#it{p}_{T} (GeV/#it{c});DCA_{#it{xy}} (cm)", HistType::kTH3D, {multAxis, {100, -5., 5.}, {200, -1., 1.}}); - - // rec tracks and tracklets distribution - histos.add("TracksDistr", ";Tracklets |#eta| > 0.7;#it{N}_{trk}", HistType::kTH2D, {{201, -0.5, 200.5}, {201, -0.5, 200.5}}); - histos.add("TrackletsDistr", ";Tracklets |#eta| > 0.7;#it{N}_{tkl}", HistType::kTH2D, {{201, -0.5, 200.5}, {201, -0.5, 200.5}}); - - histos.add("TracksDistrV0M", ";V0M Multiplicity (%);#it{N}_{trk}", HistType::kTH2D, {multAxis, {201, -0.5, 200.5}}); - histos.add("TrackletsDistrV0M", ";V0M Multiplicity (%);#it{N}_{tkl}", HistType::kTH2D, {multAxis, {201, -0.5, 200.5}}); - - if (doprocessMcRun2) { - // rec & gen particles (per species) - histos.add("RecPart", ";Tracklets |#eta| > 0.7;#it{p}_{T} (GeV/#it{c});Species", HistType::kTH3D, {{201, -0.5, 200.5}, {100, -5., 5.}, {10, 0, 10}}); - histos.add("GenPart", ";Tracklets |#eta| > 0.7;#it{p}_{T} (GeV/#it{c});Species", HistType::kTH3D, {{201, -0.5, 200.5}, {100, -5., 5.}, {10, 0, 10}}); - - histos.add("RecPartV0M", ";V0M Multiplicity (%);#it{p}_{T} (GeV/#it{c});Species", HistType::kTH3D, {multAxis, {100, -5., 5.}, {10, 0, 10}}); - histos.add("GenPartV0M", ";V0M Multiplicity (%);#it{p}_{T} (GeV/#it{c});Species", HistType::kTH3D, {multAxis, {100, -5., 5.}, {10, 0, 10}}); - - // dca_xy templates - histos.add("PrimTracks", ";Tracklets |#eta| > 0.7;#it{p}_{T} (GeV/#it{c});DCA_{#it{xy}} (cm)", HistType::kTH3D, {{201, -0.5, 200.5}, {100, -5., 5.}, {200, -1., 1.}}); - histos.add("SecWDTracks", ";Tracklets |#eta| > 0.7;#it{p}_{T} (GeV/#it{c});DCA_{#it{xy}} (cm)", HistType::kTH3D, {{201, -0.5, 200.5}, {100, -5., 5.}, {200, -1., 1.}}); - histos.add("SecTracks", ";Tracklets |#eta| > 0.7;#it{p}_{T} (GeV/#it{c});DCA_{#it{xy}} (cm)", HistType::kTH3D, {{201, -0.5, 200.5}, {100, -5., 5.}, {200, -1., 1.}}); - - histos.add("PrimTracksV0M", ";V0M Multiplicity (%);#it{p}_{T} (GeV/#it{c});DCA_{#it{xy}} (cm)", HistType::kTH3D, {multAxis, {100, -5., 5.}, {200, -1., 1.}}); - histos.add("SecWDTracksV0M", ";V0M Multiplicity (%);#it{p}_{T} (GeV/#it{c});DCA_{#it{xy}} (cm)", HistType::kTH3D, {multAxis, {100, -5., 5.}, {200, -1., 1.}}); - histos.add("SecTracksV0M", ";V0M Multiplicity (%);#it{p}_{T} (GeV/#it{c});DCA_{#it{xy}} (cm)", HistType::kTH3D, {multAxis, {100, -5., 5.}, {200, -1., 1.}}); - - // response - histos.add("GenRecTracks", ";Tracklets |#eta| > 0.7;#it{N}_{trk};#it{N}_{gen}", HistType::kTH3D, {{201, -0.5, 200.5}, {201, -0.5, 200.5}, {201, -0.5, 200.5}}); - histos.add("GenRecTracklets", ";Tracklets |#eta| > 0.7;#it{N}_{tkl};#it{N}_{gen}", HistType::kTH3D, {{201, -0.5, 200.5}, {201, -0.5, 200.5}, {201, -0.5, 200.5}}); - - histos.add("GenRecTracksV0M", ";V0M Multiplicity (%);#it{N}_{trk};#it{N}_{gen}", HistType::kTH3D, {multAxis, {201, -0.5, 200.5}, {201, -0.5, 200.5}}); - histos.add("GenRecTrackletsV0M", ";V0M Multiplicity (%);#it{N}_{tkl};#it{N}_{gen}", HistType::kTH3D, {multAxis, {201, -0.5, 200.5}, {201, -0.5, 200.5}}); - } - - // histograms for the evaluation of trigger efficiency - histos.add("GenINELgtZERO", ";#it{N}_{gen}", HistType::kTH1D, {multAxis}); - histos.add("RecINELgtZERO", ";#it{N}_{gen}", HistType::kTH1D, {multAxis}); - } - - template - void fillRecoEvent(C const& collision, T const& tracksAll, float const& centrality) - { - auto tracks = tracksAll.sliceBy(perCollisionTracksFull, collision.globalIndex()); - candidateTracks.clear(); - - std::array dcaInfo; - int nTracklets[2]{0, 0}; - int nTracks{0}; - for (const auto& track : tracks) { - - if (track.trackType() == 255 && std::abs(track.eta()) < 1.2) { // tracklet - if (std::abs(track.eta()) < 0.6) - nTracklets[0]++; - else if (std::abs(track.eta()) > 0.7) - nTracklets[1]++; - } - - if (!selectTrack(track)) { - continue; - } - - auto trackParCov = getTrackParCov(track); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParCov, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrNONE, &dcaInfo); - auto dca = std::hypot(dcaInfo[0], dcaInfo[1]); - auto trackPt = trackParCov.getPt(); - auto trackEta = trackParCov.getEta(); - if (dca > cfgDcaSels->get("dca")) { // dca - continue; - } - if (std::abs(dcaInfo[1]) > cfgDcaSels->get("dcaz")) { // dcaz - continue; - } - - CandidateTrack candTrack; - candTrack.pt = track.sign() > 0. ? trackPt : -trackPt; - if (trackPt < ptMin || trackPt > ptMax) - continue; - candTrack.eta = trackEta; - candTrack.dcapv = dca; - candTrack.dcaxypv = dcaInfo[0]; - candTrack.dcazpv = dcaInfo[1]; - candTrack.globalIndex = track.globalIndex(); - candidateTracks.push_back(candTrack); - - if (std::abs(dcaInfo[0]) < cfgDcaSels->get("dcaxy")) { // dcaxy TODO: add pt dependent dcaxy cut - ++nTracks; - } - } - - histos.fill(HIST("QA/nTrklCorrelation"), nTracklets[1], nTracklets[0]); - histos.fill(HIST("QA/nV0MCorrelation"), centrality, nTracklets[0]); - nTrackletsColl = nTracklets[1]; - - candidateEvent.nTklRec = nTracklets[0]; - histos.fill(HIST("TracksDistr"), nTracklets[1], nTracks); - histos.fill(HIST("TrackletsDistr"), nTracklets[1], nTracklets[0]); - histos.fill(HIST("TracksDistrV0M"), centrality, nTracks); - histos.fill(HIST("TrackletsDistrV0M"), centrality, nTracklets[0]); - } - - template - void fillMcEvent(C const& collision, T const& tracks, float const& centrality, aod::McParticles const&, aod::McTrackLabels const& mcLabels) - { - fillRecoEvent(collision, tracks, centrality); - - int nTracks{0}; - for (int iT{0}; iT < static_cast(candidateTracks.size()); ++iT) { - candidateTracks[iT].isreco = true; - - auto mcLab = mcLabels.rawIteratorAt(candidateTracks[iT].globalIndex); - if (mcLab.has_mcParticle()) { - auto mcTrack = mcLab.template mcParticle_as(); - if (((mcTrack.flags() & 0x8) && (doprocessMcRun2)) || (mcTrack.flags() & 0x2) || (mcTrack.flags() & 0x1)) - continue; - if (!mcTrack.isPhysicalPrimary()) { - if (mcTrack.has_mothers()) { // sec WD - histos.fill(HIST("SecWDTracks"), nTrackletsColl, candidateTracks[iT].pt, candidateTracks[iT].dcaxypv); - histos.fill(HIST("SecWDTracksV0M"), centrality, candidateTracks[iT].pt, candidateTracks[iT].dcaxypv); - } else { // from material - histos.fill(HIST("SecTracks"), nTrackletsColl, candidateTracks[iT].pt, candidateTracks[iT].dcaxypv); - histos.fill(HIST("SecTracksV0M"), centrality, candidateTracks[iT].pt, candidateTracks[iT].dcaxypv); - } - } - if (std::abs(candidateTracks[iT].dcaxypv) > cfgDcaSels->get("dcaxy")) { // TODO: add pt dependent cut - ++nTracks; - } - - if (mcTrack.isPhysicalPrimary()) { // primary - histos.fill(HIST("PrimTracks"), nTrackletsColl, candidateTracks[iT].pt, candidateTracks[iT].dcaxypv); - histos.fill(HIST("PrimTracksV0M"), centrality, candidateTracks[iT].pt, candidateTracks[iT].dcaxypv); - } - - if (std::abs(candidateTracks[iT].dcaxypv) > cfgDcaSels->get("dcaxy")) - continue; - int partType = getPartType(mcTrack.pdgCode()); - if (mcTrack.isPhysicalPrimary()) { // primary - histos.fill(HIST("RecPart"), nTrackletsColl, candidateTracks[iT].pt, partType); - histos.fill(HIST("RecPartV0M"), centrality, candidateTracks[iT].pt, partType); - } - auto genPt = std::hypot(mcTrack.px(), mcTrack.py()); - candidateTracks[iT].pdgcode = mcTrack.pdgCode(); - candidateTracks[iT].genpt = genPt; - candidateTracks[iT].geneta = mcTrack.eta(); - candidateTracks[iT].mcIndex = mcTrack.globalIndex(); - } - } - candidateEvent.nTrkRec = nTracks; - } - - void fillMcGen(aod::McParticles const& mcParticles, aod::McTrackLabels const& /*mcLab*/, uint64_t const& collisionId, float const& centrality) - { - int nParticles = 0; - auto mcParticlesThisCollision = mcParticles.sliceBy(perCollisionMcParts, collisionId); - for (auto const& mcPart : mcParticlesThisCollision) { - auto genEta = mcPart.eta(); - if (std::abs(genEta) > etaMax) { - continue; - } - if (((mcPart.flags() & 0x8) && (doprocessMcRun2)) || (mcPart.flags() & 0x2) || (mcPart.flags() & 0x1)) - continue; - if (!mcPart.isPhysicalPrimary() /* && !mcPart.has_mothers() */) - continue; - auto genPt = std::hypot(mcPart.px(), mcPart.py()); - if (genPt < ptMin || genPt > ptMax) - continue; - CandidateTrack candTrack; - candTrack.genpt = genPt; - candTrack.geneta = mcPart.eta(); - candTrack.pdgcode = mcPart.pdgCode(); - - int partType = getPartType(mcPart.pdgCode()); - if (partType < PartTypes::kOther) { - ++nParticles; - } - histos.fill(HIST("GenPart"), nTrackletsColl, mcPart.pdgCode() > 0 ? genPt : -genPt, partType); - histos.fill(HIST("GenPartV0M"), centrality, mcPart.pdgCode() > 0 ? genPt : -genPt, partType); - - auto it = find_if(candidateTracks.begin(), candidateTracks.end(), [&](CandidateTrack trk) { return trk.mcIndex == mcPart.globalIndex(); }); - if (it != candidateTracks.end()) { - continue; - } else { - candidateTracks.emplace_back(candTrack); - } - } - histos.fill(HIST("RecINELgtZERO"), nParticles); - histos.fill(HIST("GenRecTracks"), nTrackletsColl, candidateEvent.nTrkRec, nParticles); - histos.fill(HIST("GenRecTracklets"), nTrackletsColl, candidateEvent.nTklRec, nParticles); - histos.fill(HIST("GenRecTracksV0M"), centrality, candidateEvent.nTrkRec, nParticles); - histos.fill(HIST("GenRecTrackletsV0M"), centrality, candidateEvent.nTklRec, nParticles); - } - - template - int genMultINELgtZERO(C const& collision, P const& particles) - { - if (std::abs(collision.posZ()) > zVtxMax) - return -1; - - int nParticles = 0; - int partInAcc = 0; - auto particlesThisCollision = particles.sliceBy(perCollisionMcParts, collision.globalIndex()); - for (auto const& particle : particlesThisCollision) { - if (((particle.flags() & 0x8) && (doprocessMcRun2)) || (particle.flags() & 0x2) || (particle.flags() & 0x1)) - continue; - if (!particle.isPhysicalPrimary() /* && !particle.has_mothers() */) - continue; - auto pt = std::hypot(particle.px(), particle.py()); - if (pt < ptMin || pt > ptMax) - continue; - - int partType = getPartType(particle.pdgCode()); - if (partType < PartTypes::kOther) { - if (std::abs(particle.eta()) < etaMax) - ++nParticles; - if (std::abs(particle.eta()) < 1.f) { - ++partInAcc; - } - } - } - if (partInAcc >= 0) - return nParticles; - return -1; - } - - void processRun2(soa::Join const& collisions, TracksFull const& tracks, aod::FV0As const& fv0as, aod::FV0Cs const& fv0cs, BCsWithRun2Info const&) - { - - for (const auto& collision : collisions) { - auto bc = collision.bc_as(); - initCCDB(bc); - - if (std::abs(collision.posZ()) > zVtxMax) - continue; - - if (!collision.alias_bit(kINT7)) - continue; - - if (!(bc.eventCuts() & BIT(aod::Run2EventCuts::kAliEventCutsAccepted))) - continue; - - if (!(bc.eventCuts() & BIT(aod::Run2EventCuts::kINELgtZERO))) - continue; - - float v0m = getV0M(bc.globalIndex(), collision.posZ(), fv0as, fv0cs); - float cV0M = Run2V0MInfo.mhMultSelCalib->GetBinContent(Run2V0MInfo.mhMultSelCalib->FindFixBin(v0m)); - - histos.fill(HIST("QA/zVtx"), collision.posZ()); - - fillRecoEvent(collision, tracks, cV0M); - - for (auto const& t : candidateTracks) { - histos.fill(HIST("RecTracks"), nTrackletsColl, t.pt, t.dcaxypv); - histos.fill(HIST("RecTracksV0M"), cV0M, t.pt, t.dcaxypv); - } - } - } - PROCESS_SWITCH(EbyeMult, processRun2, "process (Run 2)", false); - - void processMcRun2(soa::Join const& collisions, aod::McCollisions const& mcCollisions, TracksFull const& tracks, aod::FV0As const& fv0as, aod::FV0Cs const& fv0cs, aod::McParticles const& mcParticles, aod::McTrackLabels const& mcLab, BCsWithRun2Info const&) - { - - for (const auto& collision : collisions) { // TODO: fill numerator for trigger efficiency - auto bc = collision.bc_as(); - initCCDB(bc); - - if (std::abs(collision.posZ()) > zVtxMax) - continue; - - if (!(bc.eventCuts() & BIT(aod::Run2EventCuts::kAliEventCutsAccepted))) - continue; - - if (!(bc.eventCuts() & BIT(aod::Run2EventCuts::kINELgtZERO))) - continue; - - float v0m = getV0M(bc.globalIndex(), collision.posZ(), fv0as, fv0cs); - float cV0M = Run2V0MInfo.mhMultSelCalib->GetBinContent(Run2V0MInfo.mhMultSelCalib->FindFixBin(v0m)); - - histos.fill(HIST("QA/zVtx"), collision.posZ()); - - fillMcEvent(collision, tracks, cV0M, mcParticles, mcLab); - fillMcGen(mcParticles, mcLab, collision.mcCollisionId(), cV0M); - } - - // search generated INEL > 0 (one charged particle in |eta| < 1) - for (const auto& mcCollision : mcCollisions) { - int mult = genMultINELgtZERO(mcCollision, mcParticles); - if (mult >= 0) { - histos.fill(HIST("GenINELgtZERO"), mult); - } - } - } - PROCESS_SWITCH(EbyeMult, processMcRun2, "process mc (Run 2)", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; -} diff --git a/PWGLF/Tasks/Resonances/CMakeLists.txt b/PWGLF/Tasks/Resonances/CMakeLists.txt index aec43e97f65..4ba33fce401 100644 --- a/PWGLF/Tasks/Resonances/CMakeLists.txt +++ b/PWGLF/Tasks/Resonances/CMakeLists.txt @@ -44,6 +44,11 @@ o2physics_add_dpl_workflow(lambda1520analysis PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(lstaranalysis + SOURCES lstaranalysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(k1analysis SOURCES k1analysis.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGLF/Tasks/Resonances/kstarpbpb.cxx b/PWGLF/Tasks/Resonances/kstarpbpb.cxx index cd2ddf8d0c0..a8ad0497647 100644 --- a/PWGLF/Tasks/Resonances/kstarpbpb.cxx +++ b/PWGLF/Tasks/Resonances/kstarpbpb.cxx @@ -59,6 +59,7 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using std::array; +using namespace o2::aod::rctsel; struct kstarpbpb { struct : ConfigurableGroup { @@ -70,6 +71,16 @@ struct kstarpbpb { Service ccdb; o2::ccdb::CcdbApi ccdbApi; // Service pdg; + struct RCTCut : ConfigurableGroup { + Configurable requireRCTFlagChecker{"requireRCTFlagChecker", true, "Check event quality in run condition table"}; + Configurable cfgEvtRCTFlagCheckerLabel{"cfgEvtRCTFlagCheckerLabel", "CBT_hadronPID", "Evt sel: RCT flag checker label"}; + Configurable cfgEvtRCTFlagCheckerZDCCheck{"cfgEvtRCTFlagCheckerZDCCheck", false, "Evt sel: RCT flag checker ZDC check"}; + Configurable cfgEvtRCTFlagCheckerLimitAcceptAsBad{"cfgEvtRCTFlagCheckerLimitAcceptAsBad", true, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"}; + + RCTFlagsChecker rctChecker; + }; + + RCTCut rctCut; // CCDB options // Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; @@ -162,12 +173,18 @@ struct kstarpbpb { void init(o2::framework::InitContext&) { + rctCut.rctChecker.init( + rctCut.cfgEvtRCTFlagCheckerLabel, + rctCut.cfgEvtRCTFlagCheckerZDCCheck, + rctCut.cfgEvtRCTFlagCheckerLimitAcceptAsBad); + std::vector occupancyBinning = {0.0, 500.0, 1000.0, 1500.0, 2000.0, 3000.0, 4000.0, 5000.0, 50000.0}; AxisSpec phiAxis = {500, -6.28, 6.28, "phi"}; AxisSpec resAxis = {6000, -30, 30, "Res"}; AxisSpec centAxis = {8, 0, 80, "V0M (%)"}; AxisSpec occupancyAxis = {occupancyBinning, "Occupancy"}; if (!fillSA) { + histos.add("hEvtSelInfo", "hEvtSelInfo", kTH1F, {{10, 0, 10.0}}); if (same) { histos.add("hSparseV2SASameEvent_V2", "hSparseV2SASameEvent_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); } @@ -230,10 +247,11 @@ struct kstarpbpb { } if (additionalQAplots) { // DCA QA - histos.add("QAbefore/trkDCAxyka", "DCAxy distribution of kaon track candidates", HistType::kTH1F, {{150, 0.0f, 1.0f}}); - histos.add("QAbefore/trkDCAzka", "DCAz distribution of kaon track candidates", HistType::kTH1F, {{150, 0.0f, 1.0f}}); - histos.add("QAafter/trkDCAxyka", "DCAxy distribution of kaon track candidates", HistType::kTH1F, {{150, 0.0f, 1.0f}}); - histos.add("QAafter/trkDCAzka", "DCAz distribution of kaon track candidates", HistType::kTH1F, {{150, 0.0f, 1.0f}}); + histos.add("QAbefore/trkDCAxyka", "DCAxy distribution of kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAbefore/trkDCAzka", "DCAz distribution of kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAafter/trkDCAxyka", "DCAxy distribution of kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAafter/trkDCAzka", "DCAz distribution of kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + // PID QA before cuts histos.add("QAbefore/TOF_TPC_Mapka_allka", "TOF + TPC Combined PID for Kaon;#sigma_{TOF}^{Kaon};#sigma_{TPC}^{Kaon}", {HistType::kTH2D, {{100, -6, 6}, {100, -6, 6}}}); histos.add("QAbefore/TOF_Nsigma_allka", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Kaon};", {HistType::kTH3D, {{200, 0.0, 20.0}, {100, -6, 6}, {100, 0.0, 100.0}}}); @@ -244,10 +262,10 @@ struct kstarpbpb { histos.add("QAafter/TPC_Nsigma_allka", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Kaon};", {HistType::kTH3D, {{200, 0.0, 20.0}, {100, -6, 6}, {100, 0.0, 100.0}}}); // DCA QA - histos.add("QAbefore/trkDCAxypi", "DCAxy distribution of pion track candidates", HistType::kTH1F, {{150, 0.0f, 1.0f}}); - histos.add("QAbefore/trkDCAzpi", "DCAz distribution of pion track candidates", HistType::kTH1F, {{150, 0.0f, 1.0f}}); - histos.add("QAafter/trkDCAxypi", "DCAxy distribution of pion track candidates", HistType::kTH1F, {{150, 0.0f, 1.0f}}); - histos.add("QAafter/trkDCAzpi", "DCAz distribution of pion track candidates", HistType::kTH1F, {{150, 0.0f, 1.0f}}); + histos.add("QAbefore/trkDCAxypi", "DCAxy distribution of pion track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAbefore/trkDCAzpi", "DCAz distribution of pion track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAafter/trkDCAxypi", "DCAxy distribution of pion track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAafter/trkDCAzpi", "DCAz distribution of pion track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); // PID QA before cuts histos.add("QAbefore/TOF_TPC_Mapka_allpi", "TOF + TPC Combined PID for pion;#sigma_{TOF}^{pion};#sigma_{TPC}^{pion}", {HistType::kTH2D, {{100, -6, 6}, {100, -6, 6}}}); histos.add("QAbefore/TOF_Nsigma_allpi", "TOF NSigma for pion;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{pion};", {HistType::kTH3D, {{200, 0.0, 20.0}, {100, -6, 6}, {100, 0.0, 100.0}}}); @@ -492,9 +510,15 @@ struct kstarpbpb { TH2D* hweight; void processSE(EventCandidates::iterator const& collision, TrackCandidates const& tracks, aod::BCsWithTimestamps const&) { + histos.fill(HIST("hEvtSelInfo"), 0.5); + if (rctCut.requireRCTFlagChecker && !rctCut.rctChecker(collision)) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 1.5); if (!collision.sel8() || !collision.triggereventep() || !collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision.selection_bit(aod::evsel::kNoITSROFrameBorder) || !collision.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { return; } + histos.fill(HIST("hEvtSelInfo"), 2.5); auto centrality = collision.centFT0C(); auto multTPC = collision.multNTracksPV(); int occupancy = collision.trackOccupancyInTimeRange(); @@ -504,15 +528,18 @@ struct kstarpbpb { auto QFT0C = collision.qFT0C(); auto QFT0A = collision.qFT0A(); auto QTPC = collision.qTPC(); - if (fillOccupancy && occupancy >= cfgOccupancyCut) { + if (fillOccupancy && occupancy > cfgOccupancyCut) { return; } + histos.fill(HIST("hEvtSelInfo"), 3.5); if (additionalEvsel && !eventSelected(collision, centrality)) { return; } + histos.fill(HIST("hEvtSelInfo"), 4.5); if (additionalEvselITS && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { return; } + histos.fill(HIST("hEvtSelInfo"), 5.5); if (additionalQAplots1) { histos.fill(HIST("hFTOCvsTPCSelected"), centrality, multTPC); histos.fill(HIST("hPsiFT0C"), centrality, psiFT0C); @@ -1088,6 +1115,12 @@ struct kstarpbpb { BinningTypeVertexContributor binningOnPositions{{axisVertex, axisMultiplicityClass, axisOccup}, true}; SameKindPair pair{binningOnPositions, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; for (auto& [collision1, tracks1, collision2, tracks2] : pair) { + if (rctCut.requireRCTFlagChecker && !rctCut.rctChecker(collision1)) { + continue; + } + if (rctCut.requireRCTFlagChecker && !rctCut.rctChecker(collision2)) { + continue; + } if (!collision1.sel8() || !collision1.triggereventep() || !collision1.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision1.selection_bit(aod::evsel::kNoITSROFrameBorder) || !collision1.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !collision1.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { continue; } diff --git a/PWGLF/Tasks/Resonances/lstaranalysis.cxx b/PWGLF/Tasks/Resonances/lstaranalysis.cxx new file mode 100644 index 00000000000..aa0224d73cc --- /dev/null +++ b/PWGLF/Tasks/Resonances/lstaranalysis.cxx @@ -0,0 +1,1085 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file lstaranalysis.cxx +/// \brief This standalone task reconstructs track-track decay of lambda(1520) resonance candidate +/// \author Hirak Kumar Koley + +// 1. Own header (doesn't exist) + +// 2. C system headers (none) + +// 3. C++ system headers +#include + +// 4. Other includes: O2 framework, ROOT, etc. +#include "PWGLF/Utils/collisionCuts.h" + +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" +#include + +#include "Math/Vector4D.h" +#include "TPDGCode.h" +#include "TRandom.h" +#include "TVector3.h" + +using namespace o2; +using namespace o2::soa; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::constants::physics; + +using LorentzVectorPtEtaPhiMass = ROOT::Math::PtEtaPhiMVector; + +struct Lstaranalysis { + // Define slice per Resocollision + SliceCache cache; + Preslice perCollision = o2::aod::track::collisionId; + + using EventCandidates = soa::Join; + using TrackCandidates = soa::Join; + + using MCEventCandidates = soa::Join; + using MCTrackCandidates = soa::Join; + + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + Service ccdb; + Service pdg; + ccdb::CcdbApi ccdbApi; + + Configurable cfgURL{"cfgURL", "http://alice-ccdb.cern.ch", "Address of the CCDB to browse"}; + Configurable noLaterThan{"noLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "Latest acceptable timestamp of creation for the object"}; + + /// Event cuts + o2::analysis::CollisonCuts colCuts; + Configurable cfgEvtZvtx{"cfgEvtZvtx", 10.f, "Evt sel: Max. z-Vertex (cm)"}; + Configurable cfgEvtOccupancyInTimeRangeMax{"cfgEvtOccupancyInTimeRangeMax", -1, "Evt sel: maximum track occupancy"}; + Configurable cfgEvtOccupancyInTimeRangeMin{"cfgEvtOccupancyInTimeRangeMin", -1, "Evt sel: minimum track occupancy"}; + Configurable cfgEvtTriggerCheck{"cfgEvtTriggerCheck", false, "Evt sel: check for trigger"}; + Configurable cfgEvtOfflineCheck{"cfgEvtOfflineCheck", true, "Evt sel: check for offline selection"}; + Configurable cfgEvtTriggerTVXSel{"cfgEvtTriggerTVXSel", false, "Evt sel: triggerTVX selection (MB)"}; + Configurable cfgEvtTFBorderCut{"cfgEvtTFBorderCut", false, "Evt sel: apply TF border cut"}; + Configurable cfgEvtUseITSTPCvertex{"cfgEvtUseITSTPCvertex", false, "Evt sel: use at lease on ITS-TPC track for vertexing"}; + Configurable cfgEvtZvertexTimedifference{"cfgEvtZvertexTimedifference", false, "Evt sel: apply Z-vertex time difference"}; + Configurable cfgEvtPileupRejection{"cfgEvtPileupRejection", false, "Evt sel: apply pileup rejection"}; + Configurable cfgEvtNoITSROBorderCut{"cfgEvtNoITSROBorderCut", false, "Evt sel: apply NoITSRO border cut"}; + Configurable cfgEvtCollInTimeRangeStandard{"cfgEvtCollInTimeRangeStandard", false, "Evt sel: apply NoCollInTimeRangeStandard"}; + + Configurable cfgEventCentralityMin{"cfgEventCentralityMin", 0.0f, "Event sel: minimum centrality"}; + Configurable cfgEventCentralityMax{"cfgEventCentralityMax", 100.0f, "Event sel: maximum centrality"}; + + // Configurables + // Pre-selection Track cuts + Configurable cMinPtcut{"cMinPtcut", 0.15f, "Minimal pT for tracks"}; + Configurable cMinTPCNClsFound{"cMinTPCNClsFound", 120, "minimum TPCNClsFound value for good track"}; + + // DCA Selections + // DCAr to PV + Configurable cMaxDCArToPVcut{"cMaxDCArToPVcut", 0.1f, "Track DCAr cut to PV Maximum"}; + // DCAz to PV + Configurable cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 0.1f, "Track DCAz cut to PV Maximum"}; + + // Track selections + Configurable cfgPrimaryTrack{"cfgPrimaryTrack", true, "Primary track selection"}; // kGoldenChi2 | kDCAxy | kDCAz + Configurable cfgGlobalWoDCATrack{"cfgGlobalWoDCATrack", true, "Global track selection without DCA"}; // kQualityTracks (kTrackType | kTPCNCls | kTPCCrossedRows | kTPCCrossedRowsOverNCls | kTPCChi2NDF | kTPCRefit | kITSNCls | kITSChi2NDF | kITSRefit | kITSHits) | kInAcceptanceTracks (kPtRange | kEtaRange) + Configurable cfgGlobalTrack{"cfgGlobalTrack", false, "Global track selection"}; // kGoldenChi2 | kDCAxy | kDCAz + Configurable cfgPVContributor{"cfgPVContributor", false, "PV contributor track selection"}; // PV Contriuibutor + Configurable cfgHasTOF{"cfgHasTOF", false, "Require TOF"}; + Configurable cfgUseTPCRefit{"cfgUseTPCRefit", false, "Require TPC Refit"}; + Configurable cfgUseITSRefit{"cfgUseITSRefit", false, "Require ITS Refit"}; + Configurable cTPCNClsFound{"cTPCNClsFound", false, "Switch to turn on/off TPCNClsFound cut"}; + Configurable cDCAr7SigCut{"cDCAr7SigCut", false, "Track DCAr 7 Sigma cut to PV Maximum"}; + + /// PID Selections + Configurable cByPassTOF{"cByPassTOF", false, "By pass TOF PID selection"}; // By pass TOF PID selection + Configurable cPIDcutType{"cPIDcutType", 2, "cPIDcutType = 1 for square cut, 2 for circular cut"}; // By pass TOF PID selection + + // Kaon + Configurable> kaonTPCPIDpTintv{"kaonTPCPIDpTintv", {0.5}, "pT intervals for Kaon TPC PID cuts"}; + Configurable> kaonTPCPIDcuts{"kaonTPCPIDcuts", {2}, "nSigma list for Kaon TPC PID cuts"}; + Configurable> kaonTOFPIDpTintv{"kaonTOFPIDpTintv", {999.}, "pT intervals for Kaon TOF PID cuts"}; + Configurable> kaonTOFPIDcuts{"kaonTOFPIDcuts", {2}, "nSigma list for Kaon TOF PID cuts"}; + Configurable> kaonTPCTOFCombinedpTintv{"kaonTPCTOFCombinedpTintv", {999.}, "pT intervals for Kaon TPC-TOF PID cuts"}; + Configurable> kaonTPCTOFCombinedPIDcuts{"kaonTPCTOFCombinedPIDcuts", {2}, "nSigma list for Kaon TPC-TOF PID cuts"}; + Configurable cMaxTPCnSigmaKaonVETO{"cMaxTPCnSigmaKaonVETO", 3.0, "TPC nSigma VETO cut for Kaon"}; // TPC + + // Proton + Configurable> protonTPCPIDpTintv{"protonTPCPIDpTintv", {0.9}, "pT intervals for Kaon TPC PID cuts"}; + Configurable> protonTPCPIDcuts{"protonTPCPIDcuts", {2}, "nSigma list for Kaon TPC PID cuts"}; + Configurable> protonTOFPIDpTintv{"protonTOFPIDpTintv", {999.}, "pT intervals for Kaon TOF PID cuts"}; + Configurable> protonTOFPIDcuts{"protonTOFPIDcuts", {2}, "nSigma list for Kaon TOF PID cuts"}; + Configurable> protonTPCTOFCombinedpTintv{"protonTPCTOFCombinedpTintv", {999.}, "pT intervals for Proton TPC-TOF PID cuts"}; + Configurable> protonTPCTOFCombinedPIDcuts{"protonTPCTOFCombinedPIDcuts", {2}, "nSigma list for Proton TPC-TOF PID cuts"}; + Configurable cMaxTPCnSigmaProtonVETO{"cMaxTPCnSigmaProtonVETO", 3.0, "TPC nSigma VETO cut for Proton"}; // TPC + + // Additional purity check + Configurable crejectPion{"crejectPion", false, "Switch to turn on/off pion contamination"}; + Configurable cApplyOpeningAngle{"cApplyOpeningAngle", false, "Kinematic Cuts for p-K pair opening angle"}; + Configurable cMinOpeningAngle{"cMinOpeningAngle", 1.4, "Maximum deltaEta between daughters"}; + Configurable cMaxOpeningAngle{"cMaxOpeningAngle", 2.4, "Maximum deltaPhi between daughters"}; + + /// Event Mixing + Configurable nEvtMixing{"nEvtMixing", 10, "Number of events to mix"}; + ConfigurableAxis cfgVtxBins{"cfgVtxBins", {VARIABLE_WIDTH, -10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "Mixing bins - z-vertex"}; + ConfigurableAxis cfgMultBins{"cfgMultBins", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 110.0f}, "Mixing bins - multiplicity"}; + + // Rotational background + Configurable isCalcRotBkg{"isCalcRotBkg", true, "Calculate rotational background"}; + Configurable rotationalcut{"rotationalcut", 10, "Cut value (Rotation angle pi - pi/cut and pi + pi/cut)"}; + Configurable cNofRotations{"cNofRotations", 3, "Number of random rotations in the rotational background"}; + + // MC selection cut + Configurable cZvertCutMC{"cZvertCutMC", 10.0, "MC Z-vertex cut"}; + Configurable cEtacutMC{"cEtacutMC", 0.5, "MC eta cut"}; + + // cuts on mother + Configurable cfgCutsOnMother{"cfgCutsOnMother", false, "Enable additional cuts on mother"}; + Configurable cMaxPtMotherCut{"cMaxPtMotherCut", 10.0, "Maximum pt of mother cut"}; + Configurable cMaxMinvMotherCut{"cMaxMinvMotherCut", 3.0, "Maximum Minv of mother cut"}; + Configurable cMaxDeltaEtaCut{"cMaxDeltaEtaCut", 0.7, "Maximum deltaEta between daughters"}; + Configurable cMaxDeltaPhiCut{"cMaxDeltaPhiCut", 1.5, "Maximum deltaPhi between daughters"}; + + // switches + Configurable cFillMultQA{"cFillMultQA", false, "Turn on/off additional QA plots"}; + Configurable cFilladditionalQAeventPlots{"cFilladditionalQAeventPlots", false, "Additional QA event plots"}; + Configurable cFilladditionalMEPlots{"cFilladditionalMEPlots", false, "Additional Mixed event plots"}; + Configurable cFilldeltaEtaPhiPlots{"cFilldeltaEtaPhiPlots", false, "Enamble additional cuts on daughters"}; + Configurable cFillinvmass1DPlots{"cFillinvmass1DPlots", false, "Invariant mass 1D"}; + + Configurable cfgCentEst{"cfgCentEst", 2, "Centrality estimator, 1: FT0C, 2: FT0M"}; + + TRandom* rn = new TRandom(); + + /// Figures + ConfigurableAxis binsPt{"binsPt", {VARIABLE_WIDTH, 0.0, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.25, 1.3, 1.4, 1.5, 1.6, 1.7, 1.75, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.1, 3.2, 3.3, 3.4, 3.6, 3.7, 3.8, 3.9, 4.0, 4.1, 4.2, 4.5, 4.6, 4.8, 4.9, 5.0, 5.5, 5.6, 6.0, 6.4, 6.5, 7.0, 7.2, 8.0, 9.0, 9.5, 9.6, 10.0, 11.0, 11.5, 12.0, 13.0, 14.0, 14.4, 15.0, 16.0, 18.0, 19.2, 20.}, "Binning of the pT axis"}; + ConfigurableAxis binsPtQA{"binsPtQA", {VARIABLE_WIDTH, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2, 6.4, 6.6, 6.8, 7.0, 7.2, 7.4, 7.6, 7.8, 8.0, 8.2, 8.4, 8.6, 8.8, 9.0, 9.2, 9.4, 9.6, 9.8, 10.0, 10.2, 10.4, 10.6, 10.8, 11, 11.2, 11.4, 11.6, 11.8, 12, 12.2, 12.4, 12.6, 12.8, 13, 13.2, 13.4, 13.6, 13.8, 14, 14.2, 14.4, 14.6, 14.8, 15, 15.2, 15.4, 15.6, 15.8, 16, 16.2, 16.4, 16.6, 16.8, 17, 17.2, 17.4, 17.6, 17.8, 18, 18.2, 18.4, 18.6, 18.8, 19, 19.2, 19.4, 19.6, 19.8, 20}, "Binning of the pT axis"}; + ConfigurableAxis binsEta{"binsEta", {150, -1.5, 1.5}, ""}; + ConfigurableAxis binsMass{"binsMass", {70, 1.3, 2.0}, "Invariant Mass (GeV/#it{c}^2)"}; + ConfigurableAxis binsMult{"binsMult", {110, 0.0, 110.0}, "mult_{FT0M}"}; + ConfigurableAxis binsDCAz{"binsDCAz", {40, -0.2, 0.2}, ""}; + ConfigurableAxis binsDCAxy{"binsDCAxy", {40, -0.2, 0.2}, ""}; + ConfigurableAxis binsTPCXrows{"binsTPCXrows", {100, 60, 160}, ""}; + ConfigurableAxis binsnSigma{"binsnSigma", {130, -6.5, 6.5}, ""}; + ConfigurableAxis binsnTPCSignal{"binsnTPCSignal", {1000, 0, 1000}, ""}; + ConfigurableAxis binsEtaPhi{"binsEtaPhi", {350, -3.5, 3.5}, ""}; + + float centrality; + + void init(framework::InitContext&) + { + centrality = -999; + + colCuts.setCuts(cfgEvtZvtx, cfgEvtTriggerCheck, cfgEvtOfflineCheck, /*checkRun3*/ true, /*triggerTVXsel*/ false, cfgEvtOccupancyInTimeRangeMax, cfgEvtOccupancyInTimeRangeMin); + colCuts.init(&histos); + colCuts.setTriggerTVX(cfgEvtTriggerTVXSel); + colCuts.setApplyTFBorderCut(cfgEvtTFBorderCut); + colCuts.setApplyITSTPCvertex(cfgEvtUseITSTPCvertex); + colCuts.setApplyZvertexTimedifference(cfgEvtZvertexTimedifference); + colCuts.setApplyPileupRejection(cfgEvtPileupRejection); + colCuts.setApplyNoITSROBorderCut(cfgEvtNoITSROBorderCut); + colCuts.setApplyCollInTimeRangeStandard(cfgEvtCollInTimeRangeStandard); + + // axes + AxisSpec axisPt{binsPt, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec axisPtQA{binsPtQA, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec axisEta{binsEta, "#eta"}; + AxisSpec axisMassLambda1520{binsMass, "Invariant Mass (GeV/#it{c}^2)"}; + AxisSpec axisMult{binsMult, "mult_{V0M}"}; + AxisSpec axisDCAz{binsDCAz, "DCA_{z}"}; + AxisSpec axisDCAxy{binsDCAxy, "DCA_{XY}"}; + AxisSpec axisTPCXrow{binsTPCXrows, "#Xrows_{TPC}"}; + AxisSpec axisPIDQA{binsnSigma, "#sigma"}; + AxisSpec axisTPCSignal{binsnTPCSignal, ""}; + AxisSpec axisMClabel{5, -0.5, 5.5, "MC Label"}; + AxisSpec axisEtaPhi{binsEtaPhi, ""}; + AxisSpec axisPhi{350, -3.5, 3.5, "#Phi"}; + AxisSpec axisMultMix{cfgMultBins, "Multiplicity"}; + AxisSpec axisVtxMix{cfgVtxBins, "Vertex Z (cm)"}; + + if (cFilladditionalQAeventPlots) { + // event histograms + if (doprocessData) { + histos.add("TestME/hPairsCounterSameE", "tot n pairs sameE", HistType::kTH1F, {{1, 0.5f, 1.5f}}); + histos.add("QAevent/hEvtCounterSameE", "Number of analyzed Same Events", HistType::kTH1F, {{1, 0.5, 1.5}}); + histos.add("QAevent/hVertexZSameE", "Collision Vertex Z position", HistType::kTH1F, {{100, -15., 15.}}); + histos.add("QAevent/hMultiplicityPercentSameE", "Multiplicity percentile of collision", HistType::kTH1F, {{120, 0.0f, 120.0f}}); + histos.add("TestME/hCollisionIndexSameE", "coll index sameE", HistType::kTH1F, {{500, 0.0f, 500.0f}}); + histos.add("TestME/hnTrksSameE", "n tracks per event SameE", HistType::kTH1F, {{1000, 0.0f, 1000.0f}}); + } + // Test on Mixed event + if (doprocessME) { + + // Histograms for Mixed Event Pool characteristics + histos.add("QAevent/hMixPool_VtxZ", "Mixed Event Pool: Vertex Z;Vtx Z (cm);Counts", HistType::kTH1F, {axisVtxMix}); + histos.add("QAevent/hMixPool_Multiplicity", "Mixed Event Pool: Multiplicity;Multiplicity;Counts", HistType::kTH1F, {axisMultMix}); + histos.add("QAevent/hMixPool_VtxZ_vs_Multiplicity", "Mixed Event Pool: Vertex Z vs Multiplicity;Counts", HistType::kTH2F, {axisVtxMix, axisMultMix}); + + histos.add("TestME/hPairsCounterMixedE", "tot n pairs mixedE", HistType::kTH1F, {{1, 0.5f, 1.5f}}); + histos.add("QAevent/hEvtCounterMixedE", "Number of analyzed Mixed Events", HistType::kTH1F, {{1, 0.5, 1.5}}); + histos.add("QAevent/hVertexZMixedE", "Collision Vertex Z position", HistType::kTH1F, {{100, -15., 15.}}); + histos.add("QAevent/hMultiplicityPercentMixedE", "Multiplicity percentile of collision", HistType::kTH1F, {{120, 0.0f, 120.0f}}); + histos.add("TestME/hCollisionIndexMixedE", "coll index mixedE", HistType::kTH1F, {{500, 0.0f, 500.0f}}); + histos.add("TestME/hnTrksMixedE", "n tracks per event MixedE", HistType::kTH1F, {{1000, 0.0f, 1000.0f}}); + } + } + + if (doprocessData) { + // Track QA before cuts + // --- Track + histos.add("QA/QAbefore/Track/TOF_TPC_Map_ka_all", "TOF + TPC Combined PID for Kaon;#sigma_{TOF}^{Kaon};#sigma_{TPC}^{Kaon}", {HistType::kTHnSparseF, {axisPIDQA, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TOF_Nsigma_ka_all", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Kaon};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TPC_Nsigma_ka_all", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Kaon};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TPConly_Nsigma_ka", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Kaon};", {HistType::kTHnSparseF, {axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TOF_TPC_Map_pr_all", "TOF + TPC Combined PID for Proton;#sigma_{TOF}^{Proton};#sigma_{TPC}^{Proton}", {HistType::kTHnSparseF, {axisPIDQA, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TOF_Nsigma_pr_all", "TOF NSigma for Proton;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Proton};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TPC_Nsigma_pr_all", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Proton};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/TPConly_Nsigma_pr", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Proton};", {HistType::kTHnSparseF, {axisPt, axisPIDQA}}); + histos.add("QA/QAbefore/Track/dcaZ", "DCA_{Z} distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); DCA_{Z} (cm); ", HistType::kTHnSparseF, {axisPt, axisDCAz}); + histos.add("QA/QAbefore/Track/dcaXY", "DCA_{XY} momentum distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); DCA_{XY} (cm);", HistType::kTHnSparseF, {axisPt, axisDCAxy}); + histos.add("QA/QAbefore/Track/TPC_CR", "# TPC Xrows distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); TPC X rows", HistType::kTHnSparseF, {axisPt, axisTPCXrow}); + histos.add("QA/QAbefore/Track/pT", "pT distribution of Kaons; #it{p}_{T} (GeV/#it{c}); Counts;", {HistType::kTH1F, {axisPt}}); + histos.add("QA/QAbefore/Track/eta", "#eta distribution of Kaons; #eta; Counts;", {HistType::kTH1F, {axisEta}}); + + if (cFillMultQA) { + // Multiplicity correlation calibrations + histos.add("MultCalib/centGloPVpr", "Centrality vs Global-Tracks", kTHnSparseF, {{110, 0, 110, "Centrality"}, {500, 0, 5000, "Global Tracks"}, {500, 0, 5000, "PV tracks"}}); + histos.add("MultCalib/centGloPVka", "Centrality vs Global-Tracks", kTHnSparseF, {{110, 0, 110, "Centrality"}, {500, 0, 5000, "Global Tracks"}, {500, 0, 5000, "PV tracks"}}); + } + + // PID QA after cuts + // --- Kaon + histos.add("QA/QAafter/Kaon/TOF_TPC_Map_ka_all", "TOF + TPC Combined PID for Kaon;#sigma_{TOF}^{Kaon};#sigma_{TPC}^{Kaon}", {HistType::kTHnSparseF, {axisPIDQA, axisPIDQA}}); + histos.add("QA/QAafter/Kaon/TOF_Nsigma_ka_all", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Kaon};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAafter/Kaon/TPC_Nsigma_ka_all", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Kaon};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAafter/Kaon/TPC_Nsigma_ka_TPConly", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Kaon};", {HistType::kTHnSparseF, {axisPt, axisPIDQA}}); + histos.add("QA/QAafter/Kaon/dcaZ", "DCA_{Z} distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); DCA_{Z} (cm); ", HistType::kTHnSparseF, {axisPt, axisDCAz}); + histos.add("QA/QAafter/Kaon/dcaXY", "DCA_{XY} momentum distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); DCA_{XY} (cm);", HistType::kTHnSparseF, {axisPt, axisDCAxy}); + histos.add("QA/QAafter/Kaon/TPC_CR", "# TPC Xrows distribution of selected Kaons; #it{p}_{T} (GeV/#it{c}); TPC X rows", HistType::kTHnSparseF, {axisPt, axisTPCXrow}); + histos.add("QA/QAafter/Kaon/pT", "pT distribution of Kaons; #it{p}_{T} (GeV/#it{c}); Counts;", {HistType::kTH1F, {axisPt}}); + histos.add("QA/QAafter/Kaon/eta", "#eta distribution of Kaons; #eta; Counts;", {HistType::kTH1F, {axisEta}}); + histos.add("QA/QAafter/Kaon/TPC_Signal_ka_all", "TPC Signal for Kaon;#it{p}_{T} (GeV/#it{c});TPC Signal (A.U.)", {HistType::kTHnSparseF, {axisPt, axisTPCSignal}}); + histos.add("QA/QAafter/Kaon/TPCnclusterPhika", "TPC ncluster vs phi", kTHnSparseF, {{160, 0, 160, "TPC nCluster"}, {63, 0, 6.28, "#phi"}}); + + // --- Proton + histos.add("QA/QAafter/Proton/TOF_TPC_Map_pr_all", "TOF + TPC Combined PID for Proton;#sigma_{TOF}^{Proton};#sigma_{TPC}^{Proton}", {HistType::kTHnSparseF, {axisPIDQA, axisPIDQA}}); + histos.add("QA/QAafter/Proton/TOF_Nsigma_pr_all", "TOF NSigma for Proton;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Proton};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAafter/Proton/TPC_Nsigma_pr_all", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Proton};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/QAafter/Proton/TPC_Nsigma_pr_TPConly", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Proton};", {HistType::kTHnSparseF, {axisPt, axisPIDQA}}); + histos.add("QA/QAafter/Proton/dcaZ", "DCA_{Z} distribution of selected Protons; #it{p}_{T} (GeV/#it{c}); DCA_{Z} (cm);", HistType::kTHnSparseF, {axisPt, axisDCAz}); + histos.add("QA/QAafter/Proton/dcaXY", "DCA_{XY} momentum distribution of selected Protons; #it{p}_{T} (GeV/#it{c}); DCA_{XY} (cm);", HistType::kTHnSparseF, {axisPt, axisDCAxy}); + histos.add("QA/QAafter/Proton/TPC_CR", "# TPC Xrows distribution of selected Protons; #it{p}_{T} (GeV/#it{c}); TPC X rows", HistType::kTHnSparseF, {axisPt, axisTPCXrow}); + histos.add("QA/QAafter/Proton/pT", "pT distribution of Protons; #it{p}_{T} (GeV/#it{c}); Counts;", {HistType::kTH1F, {axisPt}}); + histos.add("QA/QAafter/Proton/eta", "#eta distribution of Protons; #eta; Counts;", {HistType::kTH1F, {axisEta}}); + histos.add("QA/QAafter/Proton/TPC_Signal_pr_all", "TPC Signal for Proton;#it{p}_{T} (GeV/#it{c});TPC Signal (A.U.)", {HistType::kTHnSparseF, {axisPt, axisTPCSignal}}); + histos.add("QA/QAafter/Proton/TPCnclusterPhipr", "TPC ncluster vs phi", kTHnSparseF, {{160, 0, 160, "TPC nCluster"}, {63, 0, 6.28, "#phi"}}); + + // Mass QA 1D for quick check + if (cFillinvmass1DPlots) { + histos.add("Result/Data/lambda1520invmass", "Invariant mass of #Lambda(1520) K^{#pm}p^{#mp}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); + histos.add("Result/Data/antilambda1520invmass", "Invariant mass of #Lambda(1520) K^{#mp}p^{#pm}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); + histos.add("Result/Data/lambda1520invmassLSPP", "Invariant mass of #Lambda(1520) Like Sign Method K^{#plus}p^{#plus}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); // K+ + Pr + histos.add("Result/Data/lambda1520invmassLSMM", "Invariant mass of #Lambda(1520) Like Sign Method K^{#minus}p^{#minus}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); // K- + anti-Pr + } + // eta phi QA + if (cFilldeltaEtaPhiPlots) { + histos.add("QAbefore/deltaEta", "deltaEta of kaon and proton candidates", HistType::kTH1F, {axisEtaPhi}); + histos.add("QAbefore/deltaPhi", "deltaPhi of kaon and proton candidates", HistType::kTH1F, {axisEtaPhi}); + + histos.add("QAafter/deltaEta", "deltaEta of kaon and proton candidates", HistType::kTH1F, {axisEtaPhi}); + histos.add("QAafter/deltaPhi", "deltaPhi of kaon and proton candidates", HistType::kTH1F, {axisEtaPhi}); + + histos.add("QAafter/deltaEtaafter", "deltaEta of kaon and proton candidates", HistType::kTH1F, {axisEtaPhi}); + histos.add("QAafter/deltaPhiafter", "deltaPhi of kaon and proton candidates", HistType::kTH1F, {axisEtaPhi}); + histos.add("QAafter/EtaPrafter", "Eta of proton candidates", HistType::kTH1F, {axisEta}); + histos.add("QAafter/PhiPrafter", "Phi of proton candidates", HistType::kTH1F, {axisPhi}); + histos.add("QAafter/EtaKaafter", "Eta of kaon candidates", HistType::kTH1F, {axisEta}); + histos.add("QAafter/PhiKaafter", "Phi of kaon candidates", HistType::kTH1F, {axisPhi}); + } + + if (isCalcRotBkg) { + histos.add("Result/Data/h3lambda1520InvMassRotation", "Invariant mass of #Lambda(1520) rotation", kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); + } + + // 3d histogram + histos.add("Result/Data/h3lambda1520invmass", "Invariant mass of #Lambda(1520) K^{#pm}p^{#mp}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); + histos.add("Result/Data/h3antilambda1520invmass", "Invariant mass of #Lambda(1520) K^{#mp}p^{#pm}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); + histos.add("Result/Data/h3lambda1520invmassLSPP", "Invariant mass of #Lambda(1520) Like Sign Method K^{#plus}p^{#plus}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); // K+ + Pr + histos.add("Result/Data/h3lambda1520invmassLSMM", "Invariant mass of #Lambda(1520) Like Sign Method K^{#minus}p^{#minus}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); // K- + anti-Pr + } + if (doprocessME) { + if (cFillinvmass1DPlots) { + histos.add("Result/Data/lambda1520invmassME", "Invariant mass of #Lambda(1520) mixed event K^{#pm}p^{#mp}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); + } + histos.add("Result/Data/h3lambda1520invmassME", "Invariant mass of #Lambda(1520) mixed event K^{#pm}p^{#mp}", HistType::kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); + + if (cFilladditionalMEPlots) { + histos.add("Result/Data/h3lambda1520invmassME_DS", "Invariant mass of #Lambda(1520) mixed event DS", kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); + histos.add("Result/Data/h3lambda1520invmassME_DSAnti", "Invariant mass of #Lambda(1520) mixed event DSAnti", kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); + } + } + + // MC QA + if (doprocessMCTrue) { + histos.add("QA/MC/h2GenEtaPt_beforeanycut", " #eta-#it{p}_{T} distribution of Generated #Lambda(1520); #eta; #it{p}_{T}; Counts;", HistType::kTHnSparseF, {axisEta, axisPtQA}); + histos.add("QA/MC/h2GenPhiRapidity_beforeanycut", " #phi-y distribution of Generated #Lambda(1520); #phi; y; Counts;", HistType::kTHnSparseF, {axisPhi, axisEta}); + histos.add("QA/MC/h2GenEtaPt_beforeEtacut", " #eta-#it{p}_{T} distribution of Generated #Lambda(1520); #eta; #it{p}_{T}; Counts;", HistType::kTHnSparseF, {axisEta, axisPtQA}); + histos.add("QA/MC/h2GenPhiRapidity_beforeEtacut", " #phi-y distribution of Generated #Lambda(1520); #phi; y; Counts;", HistType::kTHnSparseF, {axisPhi, axisEta}); + histos.add("QA/MC/h2GenEtaPt_afterEtacut", " #phi-#it{p}_{T} distribution of Generated #Lambda(1520); #eta; #it{p}_{T}; Counts;", HistType::kTHnSparseF, {axisEta, axisPtQA}); + histos.add("QA/MC/h2GenPhiRapidity_afterEtacut", " #phi-y distribution of Generated #Lambda(1520); #phi; y; Counts;", HistType::kTHnSparseF, {axisPhi, axisEta}); + + histos.add("Result/MC/Genlambda1520pt", "pT distribution of True MC #Lambda(1520)0", kTHnSparseF, {axisMClabel, axisPt, axisMult}); + histos.add("Result/MC/Genantilambda1520pt", "pT distribution of True MC Anti-#Lambda(1520)0", kTHnSparseF, {axisMClabel, axisPt, axisMult}); + } + if (doprocessMC) { + histos.add("QA/MC/h2RecoEtaPt_after", " #eta-#it{p}_{T} distribution of Reconstructed #Lambda(1520); #eta; #it{p}_{T}; Counts;", HistType::kTHnSparseF, {axisEta, axisPt}); + histos.add("QA/MC/h2RecoPhiRapidity_after", " #phi-y distribution of Reconstructed #Lambda(1520); #phi; y; Counts;", HistType::kTHnSparseF, {axisPhi, axisEta}); + + histos.add("QA/MC/trkDCAxy_pr", "DCAxy distribution of proton track candidates", HistType::kTHnSparseF, {axisPt, axisDCAxy}); + histos.add("QA/MC/trkDCAxy_ka", "DCAxy distribution of kaon track candidates", HistType::kTHnSparseF, {axisPt, axisDCAxy}); + histos.add("QA/MC/trkDCAz_pr", "DCAz distribution of proton track candidates", HistType::kTHnSparseF, {axisPt, axisDCAz}); + histos.add("QA/MC/trkDCAz_ka", "DCAz distribution of kaon track candidates", HistType::kTHnSparseF, {axisPt, axisDCAz}); + histos.add("QA/MC/TOF_Nsigma_pr_all", "TOF NSigma for Proton;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Proton};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/MC/TPC_Nsigma_pr_all", "TPC NSigma for Proton;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Proton};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/MC/TOF_Nsigma_ka_all", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Kaon};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + histos.add("QA/MC/TPC_Nsigma_ka_all", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Kaon};", {HistType::kTHnSparseF, {axisMult, axisPt, axisPIDQA}}); + + histos.add("Result/MC/h3lambda1520Recoinvmass", "Invariant mass of Reconstructed MC #Lambda(1520)0", kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); + histos.add("Result/MC/h3antilambda1520Recoinvmass", "Invariant mass of Reconstructed MC Anti-#Lambda(1520)0", kTHnSparseF, {axisMult, axisPt, axisMassLambda1520}); + + ccdb->setURL(cfgURL); + ccdbApi.init("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + } + + // Print output histograms statistics + LOG(info) << "Size of the histograms in spectraTOF"; + histos.print(); + } + + float massKa = MassKaonCharged; + float massPr = MassProton; + + int kLambda1520PDG = static_cast(102134); // PDG code for Lambda(1520) + + template + float getCentrality(CollisionType const& collision) + { + if (cfgCentEst == static_cast(1)) { + return collision.multFT0C(); + } else if (cfgCentEst == static_cast(2)) { + return collision.multFT0M(); + } else { + return -999; + } + } + + template + int getDetId(DetNameType const& name) + { + LOGF(info, "getDetId running"); + if (name.value == "FT0C") { + return 0; + } else if (name.value == "FT0A") { + return 1; + } else if (name.value == "FT0M") { + return 2; + } else if (name.value == "FV0A") { + return 3; + } else if (name.value == "TPCpos") { + return 4; + } else if (name.value == "TPCneg") { + return 5; + } else { + return false; + } + } + + template + bool trackCut(const TrackType track) + { + // basic track cuts + if (std::abs(track.pt()) < cMinPtcut) + return false; + if (cDCAr7SigCut) { + if (std::abs(track.dcaXY()) > (0.004f + 0.0130f / (track.pt()))) // 7 - Sigma cut + return false; + } else { + if (std::abs(track.dcaXY()) > cMaxDCArToPVcut) + return false; + } + if (std::abs(track.dcaZ()) > cMaxDCAzToPVcut) + return false; + if (cTPCNClsFound && (track.tpcNClsFound() < cMinTPCNClsFound)) + return false; + if (cfgHasTOF && !track.hasTOF()) + return false; + if (cfgPrimaryTrack && !track.isPrimaryTrack()) + return false; + if (cfgGlobalWoDCATrack && !track.isGlobalTrackWoDCA()) + return false; + if (cfgPVContributor && !track.isPVContributor()) + return false; + if (cfgGlobalTrack && !track.isGlobalTrack()) + return false; + if (cfgUseITSRefit && !track.passedITSRefit()) + return false; + if (cfgUseTPCRefit && !track.passedTPCRefit()) + return false; + + return true; + } + + // PID selection old PID method + template + bool pTdependentPIDProton(const T& candidate) + { + auto vProtonTPCPIDpTintv = static_cast>(protonTPCPIDpTintv); + vProtonTPCPIDpTintv.insert(vProtonTPCPIDpTintv.begin(), cMinPtcut); + auto vProtonTPCPIDcuts = static_cast>(protonTPCPIDcuts); + auto vProtonTOFPIDpTintv = static_cast>(protonTOFPIDpTintv); + auto vProtonTPCTOFCombinedpTintv = static_cast>(protonTPCTOFCombinedpTintv); + auto vProtonTPCTOFCombinedPIDcuts = static_cast>(protonTPCTOFCombinedPIDcuts); + auto vProtonTOFPIDcuts = static_cast>(protonTOFPIDcuts); + auto lengthOfprotonTPCPIDpTintv = static_cast(vProtonTPCPIDpTintv.size()); + auto lengthOfprotonTOFPIDpTintv = static_cast(vProtonTOFPIDpTintv.size()); + auto lengthOfprotonTPCTOFCombinedPIDpTintv = static_cast(vProtonTPCTOFCombinedpTintv.size()); + + bool tpcPIDPassed{false}, tofPIDPassed{false}; + + // For Proton candidate: + // TPC PID + if (lengthOfprotonTPCPIDpTintv > 0) { + if (candidate.pt() > vProtonTPCPIDpTintv[lengthOfprotonTPCPIDpTintv - 1]) { + tpcPIDPassed = false; + } else { + for (int i = 0; i < lengthOfprotonTPCPIDpTintv; i++) { + if (candidate.pt() > vProtonTPCPIDpTintv[i] && candidate.pt() < vProtonTPCPIDpTintv[i + 1]) { + if (std::abs(candidate.tpcNSigmaPr()) < vProtonTPCPIDcuts[i]) + tpcPIDPassed = true; + } + } + } + } + + // bypass TOF + if (cByPassTOF && tpcPIDPassed) { + return true; + } + + // TOF PID + if (candidate.hasTOF()) { + if (cPIDcutType == 1) { + if (lengthOfprotonTOFPIDpTintv > 0) { + if (candidate.pt() > vProtonTOFPIDpTintv[lengthOfprotonTOFPIDpTintv - 1]) { + tofPIDPassed = false; + } else { + for (int i = 0; i < lengthOfprotonTOFPIDpTintv; i++) { + if (candidate.pt() < vProtonTOFPIDpTintv[i]) { + + if (std::abs(candidate.tofNSigmaPr()) < vProtonTOFPIDcuts[i] && std::abs(candidate.tpcNSigmaPr()) < cMaxTPCnSigmaProtonVETO) + tofPIDPassed = true; + } + } + } + } + } else if (cPIDcutType == static_cast(2)) { + if (lengthOfprotonTPCTOFCombinedPIDpTintv > 0) { + if (candidate.pt() > vProtonTPCTOFCombinedpTintv[lengthOfprotonTPCTOFCombinedPIDpTintv - 1]) { + tofPIDPassed = false; + } else { + for (int i = 0; i < lengthOfprotonTPCTOFCombinedPIDpTintv; i++) { + if (candidate.pt() < vProtonTPCTOFCombinedpTintv[i]) { + if ((candidate.tpcNSigmaPr() * candidate.tpcNSigmaPr() + candidate.tofNSigmaPr() * candidate.tofNSigmaPr()) < (vProtonTPCTOFCombinedPIDcuts[i] * vProtonTPCTOFCombinedPIDcuts[i])) + tofPIDPassed = true; + } + } + } + } + } + } else { + tofPIDPassed = true; + } + + // TPC-TOF Combined PID + if (tpcPIDPassed && tofPIDPassed) { + return true; + } + + return false; + } + + template + bool pTdependentPIDKaon(const T& candidate) + { + auto vKaonTPCPIDpTintv = static_cast>(kaonTPCPIDpTintv); + vKaonTPCPIDpTintv.insert(vKaonTPCPIDpTintv.begin(), cMinPtcut); + auto vKaonTPCPIDcuts = static_cast>(kaonTPCPIDcuts); + auto vKaonTOFPIDpTintv = static_cast>(kaonTOFPIDpTintv); + auto vKaonTPCTOFCombinedpTintv = static_cast>(kaonTPCTOFCombinedpTintv); + auto vKaonTPCTOFCombinedPIDcuts = static_cast>(kaonTPCTOFCombinedPIDcuts); + auto vKaonTOFPIDcuts = static_cast>(kaonTOFPIDcuts); + auto lengthOfkaonTPCPIDpTintv = static_cast(vKaonTPCPIDpTintv.size()); + auto lengthOfkaonTOFPIDpTintv = static_cast(vKaonTOFPIDpTintv.size()); + auto lengthOfkaonTPCTOFCombinedPIDpTintv = static_cast(vKaonTPCTOFCombinedpTintv.size()); + + bool tpcPIDPassed{false}, tofPIDPassed{false}; + + // For Kaon candidate: + // TPC PID + if (lengthOfkaonTPCPIDpTintv > 0) { + if (candidate.pt() > vKaonTPCPIDpTintv[lengthOfkaonTPCPIDpTintv - 1]) { + tpcPIDPassed = false; + } else { + for (int i = 0; i < lengthOfkaonTPCPIDpTintv; i++) { + if (candidate.pt() > vKaonTPCPIDpTintv[i] && candidate.pt() < vKaonTPCPIDpTintv[i + 1]) { + if (std::abs(candidate.tpcNSigmaKa()) < vKaonTPCPIDcuts[i]) + tpcPIDPassed = true; + } + } + } + } + + // bypass TOF + if (cByPassTOF && tpcPIDPassed) { + return true; + } + + // TOF PID + if (candidate.hasTOF()) { + if (cPIDcutType == 1) { + if (lengthOfkaonTOFPIDpTintv > 0) { + if (candidate.pt() > vKaonTOFPIDpTintv[lengthOfkaonTOFPIDpTintv - 1]) { + tofPIDPassed = false; + } else { + for (int i = 0; i < lengthOfkaonTOFPIDpTintv; i++) { + if (candidate.pt() < vKaonTOFPIDpTintv[i]) { + + if (std::abs(candidate.tofNSigmaKa()) < vKaonTOFPIDcuts[i] && std::abs(candidate.tpcNSigmaKa()) < cMaxTPCnSigmaKaonVETO) + tofPIDPassed = true; + } + } + } + } + } else if (cPIDcutType == static_cast(2)) { + if (lengthOfkaonTPCTOFCombinedPIDpTintv > 0) { + if (candidate.pt() > vKaonTPCTOFCombinedpTintv[lengthOfkaonTPCTOFCombinedPIDpTintv - 1]) { + tofPIDPassed = false; + } else { + for (int i = 0; i < lengthOfkaonTPCTOFCombinedPIDpTintv; i++) { + if (candidate.pt() < vKaonTPCTOFCombinedpTintv[i]) { + if ((candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa() + candidate.tofNSigmaKa() * candidate.tofNSigmaKa()) < (vKaonTPCTOFCombinedPIDcuts[i] * vKaonTPCTOFCombinedPIDcuts[i])) + tofPIDPassed = true; + } + } + } + } + } + } else { + tofPIDPassed = true; + } + + // TPC-TOF Combined PID + if (tpcPIDPassed && tofPIDPassed) { + return true; + } + + return false; + } + + template + bool rejectPion(const T& candidate) + { + if (candidate.pt() > static_cast(1.0) && candidate.pt() < static_cast(2.0) && !candidate.hasTOF() && candidate.tpcNSigmaPi() < static_cast(2)) { + return false; + } + return true; + } + + template + void fillHistograms(const CollisionType& collision, const TracksType& dTracks1, const TracksType& dTracks2) + { + auto multiplicity = collision.centFT0M(); + + // Multiplicity correlation calibration plots + if (cFillMultQA) { + if constexpr (IsData) { + histos.fill(HIST("MultCalib/centGloPVpr"), multiplicity, dTracks1.size(), collision.multNTracksPV()); + histos.fill(HIST("MultCalib/centGloPVka"), multiplicity, dTracks2.size(), collision.multNTracksPV()); + } + } + + if (cFilladditionalQAeventPlots) { + if constexpr (!IsMix) { + histos.fill(HIST("QAevent/hVertexZSameE"), collision.posZ()); + histos.fill(HIST("QAevent/hMultiplicityPercentSameE"), multiplicity); + histos.fill(HIST("TestME/hCollisionIndexSameE"), collision.globalIndex()); + histos.fill(HIST("TestME/hnTrksSameE"), dTracks1.size()); + } else { + histos.fill(HIST("QAevent/hVertexZMixedE"), collision.posZ()); + histos.fill(HIST("QAevent/hMultiplicityPercentMixedE"), multiplicity); + histos.fill(HIST("TestME/hCollisionIndexMixedE"), collision.globalIndex()); + histos.fill(HIST("TestME/hnTrksMixedE"), dTracks1.size()); + } + } + // LOG(info) << "After pass, Collision index:" << collision.index() << "multiplicity: " << collision.centFT0M() << endl; + + LorentzVectorPtEtaPhiMass lDecayDaughter1, lDecayDaughter2, lResonance, ldaughterRot, lresonanceRot; + + for (const auto& [trk1, trk2] : combinations(CombinationsFullIndexPolicy(dTracks1, dTracks2))) { + // Full index policy is needed to consider all possible combinations + if (trk1.index() == trk2.index()) + continue; // We need to run (0,1), (1,0) pairs as well. but same id pairs are not needed. + + if (cFilladditionalQAeventPlots) { + if constexpr (IsData) { + histos.fill(HIST("TestME/hPairsCounterSameE"), 1.0); + } else if (IsMix) { + histos.fill(HIST("TestME/hPairsCounterMixedE"), 1.0); + } + } + + // apply the track cut + if (!trackCut(trk1) || !trackCut(trk2)) + continue; + + //// Initialize variables + // Trk1: Proton, Trk2: Kaon + auto isTrk1hasTOF = trk1.hasTOF(); + auto isTrk2hasTOF = trk2.hasTOF(); + + auto trk1ptPr = trk1.pt(); + auto trk1NSigmaPrTPC = trk1.tpcNSigmaPr(); + auto trk1NSigmaPrTOF = (isTrk1hasTOF) ? trk1.tofNSigmaPr() : -999.; + auto trk2ptKa = trk2.pt(); + auto trk2NSigmaKaTPC = trk2.tpcNSigmaKa(); + auto trk2NSigmaKaTOF = (isTrk2hasTOF) ? trk2.tofNSigmaKa() : -999.; + + auto deltaEta = std::abs(trk1.eta() - trk2.eta()); + auto deltaPhi = std::abs(trk1.phi() - trk2.phi()); + deltaPhi = (deltaPhi > constants::math::PI) ? (constants::math::TwoPI - deltaPhi) : deltaPhi; + + //// QA plots before the selection + // --- Track QA all + if constexpr (IsData) { + histos.fill(HIST("QA/QAbefore/Track/TPC_Nsigma_pr_all"), multiplicity, trk1ptPr, trk1NSigmaPrTPC); + if (isTrk1hasTOF) { + histos.fill(HIST("QA/QAbefore/Track/TOF_Nsigma_pr_all"), multiplicity, trk1ptPr, trk1NSigmaPrTOF); + histos.fill(HIST("QA/QAbefore/Track/TOF_TPC_Map_pr_all"), trk1NSigmaPrTOF, trk1NSigmaPrTPC); + } + if (!isTrk1hasTOF) { + histos.fill(HIST("QA/QAbefore/Track/TPConly_Nsigma_pr"), trk1ptPr, trk1NSigmaPrTPC); + } + histos.fill(HIST("QA/QAbefore/Track/TPC_Nsigma_ka_all"), multiplicity, trk2ptKa, trk2NSigmaKaTPC); + if (isTrk2hasTOF) { + histos.fill(HIST("QA/QAbefore/Track/TOF_Nsigma_ka_all"), multiplicity, trk2ptKa, trk2NSigmaKaTOF); + histos.fill(HIST("QA/QAbefore/Track/TOF_TPC_Map_ka_all"), trk2NSigmaKaTOF, trk2NSigmaKaTPC); + } + if (!isTrk2hasTOF) { + histos.fill(HIST("QA/QAbefore/Track/TPConly_Nsigma_ka"), trk2ptKa, trk2NSigmaKaTPC); + } + + histos.fill(HIST("QA/QAbefore/Track/dcaZ"), trk1ptPr, trk1.dcaZ()); + histos.fill(HIST("QA/QAbefore/Track/dcaXY"), trk1ptPr, trk1.dcaXY()); + histos.fill(HIST("QA/QAbefore/Track/TPC_CR"), trk1ptPr, trk1.tpcNClsCrossedRows()); + histos.fill(HIST("QA/QAbefore/Track/pT"), trk1ptPr); + histos.fill(HIST("QA/QAbefore/Track/eta"), trk1.eta()); + if (cFilldeltaEtaPhiPlots) { + histos.fill(HIST("QAbefore/deltaEta"), deltaEta); + histos.fill(HIST("QAbefore/deltaPhi"), deltaPhi); + } + } + + //// Apply the pid selection + if (crejectPion && rejectPion(trk2)) + continue; + + if (!pTdependentPIDProton(trk1) || !pTdependentPIDKaon(trk2)) + continue; + + //// QA plots after the selection + if constexpr (IsData) { // --- PID QA Proton + histos.fill(HIST("QA/QAafter/Proton/TPC_Nsigma_pr_all"), multiplicity, trk1ptPr, trk1NSigmaPrTPC); + histos.fill(HIST("QA/QAafter/Proton/TPC_Signal_pr_all"), trk1ptPr, trk1.tpcSignal()); + if (isTrk1hasTOF) { + histos.fill(HIST("QA/QAafter/Proton/TOF_Nsigma_pr_all"), multiplicity, trk1ptPr, trk1NSigmaPrTOF); + histos.fill(HIST("QA/QAafter/Proton/TOF_TPC_Map_pr_all"), trk1NSigmaPrTOF, trk1NSigmaPrTPC); + } + if (!isTrk1hasTOF) { + histos.fill(HIST("QA/QAafter/Proton/TPC_Nsigma_pr_TPConly"), trk1ptPr, trk1NSigmaPrTPC); + } + histos.fill(HIST("QA/QAafter/Proton/dcaZ"), trk1ptPr, trk1.dcaZ()); + histos.fill(HIST("QA/QAafter/Proton/dcaXY"), trk1ptPr, trk1.dcaXY()); + histos.fill(HIST("QA/QAafter/Proton/TPC_CR"), trk1ptPr, trk1.tpcNClsCrossedRows()); + histos.fill(HIST("QA/QAafter/Proton/pT"), trk1ptPr); + histos.fill(HIST("QA/QAafter/Proton/eta"), trk1.eta()); + histos.fill(HIST("QA/QAafter/Proton/TPCnclusterPhipr"), trk1.tpcNClsFound(), trk1.phi()); + + // --- PID QA Kaon + histos.fill(HIST("QA/QAafter/Kaon/TPC_Nsigma_ka_all"), multiplicity, trk2ptKa, trk2NSigmaKaTPC); + histos.fill(HIST("QA/QAafter/Kaon/TPC_Signal_ka_all"), trk2ptKa, trk2.tpcSignal()); + if (isTrk2hasTOF) { + histos.fill(HIST("QA/QAafter/Kaon/TOF_Nsigma_ka_all"), multiplicity, trk2ptKa, trk2NSigmaKaTOF); + histos.fill(HIST("QA/QAafter/Kaon/TOF_TPC_Map_ka_all"), trk2NSigmaKaTOF, trk2NSigmaKaTPC); + } + if (!isTrk2hasTOF) { + histos.fill(HIST("QA/QAafter/Kaon/TPC_Nsigma_ka_TPConly"), trk2ptKa, trk2NSigmaKaTPC); + } + histos.fill(HIST("QA/QAafter/Kaon/dcaZ"), trk2ptKa, trk2.dcaZ()); + histos.fill(HIST("QA/QAafter/Kaon/dcaXY"), trk2ptKa, trk2.dcaXY()); + histos.fill(HIST("QA/QAafter/Kaon/TPC_CR"), trk2ptKa, trk2.tpcNClsCrossedRows()); + histos.fill(HIST("QA/QAafter/Kaon/pT"), trk2ptKa); + histos.fill(HIST("QA/QAafter/Kaon/eta"), trk2.eta()); + histos.fill(HIST("QA/QAafter/Kaon/TPCnclusterPhika"), trk2.tpcNClsFound(), trk2.phi()); + + if (cFilldeltaEtaPhiPlots) { + histos.fill(HIST("QAafter/deltaEta"), deltaEta); + histos.fill(HIST("QAafter/deltaPhi"), deltaPhi); + } + } + + // Apply kinematic opening angle cut + if (cApplyOpeningAngle) { + TVector3 v1(trk1.px(), trk1.py(), trk1.pz()); + TVector3 v2(trk2.px(), trk2.py(), trk2.pz()); + float alpha = v1.Angle(v2); + if (alpha > cMinOpeningAngle && alpha < cMaxOpeningAngle) + continue; + } + + //// Resonance reconstruction + lDecayDaughter1 = LorentzVectorPtEtaPhiMass(trk1.pt(), trk1.eta(), trk1.phi(), massPr); + lDecayDaughter2 = LorentzVectorPtEtaPhiMass(trk2.pt(), trk2.eta(), trk2.phi(), massKa); + lResonance = lDecayDaughter1 + lDecayDaughter2; + // Rapidity cut + if (std::abs(lResonance.Rapidity()) > static_cast(0.5)) + continue; + + if (cfgCutsOnMother) { + if (lResonance.Pt() >= cMaxPtMotherCut) // excluding candidates in overflow + continue; + if (lResonance.M() >= cMaxMinvMotherCut) // excluding candidates in overflow + continue; + } + + if (cFilldeltaEtaPhiPlots) { + if (deltaEta >= cMaxDeltaEtaCut) + continue; + if (deltaPhi >= cMaxDeltaPhiCut) + continue; + + if constexpr (!IsMix) { + histos.fill(HIST("QAafter/EtaPrafter"), trk1.eta()); + histos.fill(HIST("QAafter/PhiPrafter"), trk1.phi()); + histos.fill(HIST("QAafter/EtaKaafter"), trk2.eta()); + histos.fill(HIST("QAafter/PhiKaafter"), trk2.phi()); + histos.fill(HIST("QAafter/deltaEtaafter"), deltaEta); + histos.fill(HIST("QAafter/deltaPhiafter"), deltaPhi); + } + } + + //// Un-like sign pair only + if (trk1.sign() * trk2.sign() < 0) { + if constexpr (IsData) { + if (isCalcRotBkg) { + for (int i = 0; i < cNofRotations; i++) { + float theta2 = rn->Uniform(constants::math::PI - constants::math::PI / rotationalcut, constants::math::PI + constants::math::PI / rotationalcut); + ldaughterRot = LorentzVectorPtEtaPhiMass(trk2.pt(), trk2.eta(), trk2.phi() + theta2, massKa); // for rotated background + lresonanceRot = lDecayDaughter1 + ldaughterRot; + histos.fill(HIST("Result/Data/h3lambda1520InvMassRotation"), multiplicity, lresonanceRot.Pt(), lresonanceRot.M()); + } + } + + if (trk1.sign() < 0) { + if (cFillinvmass1DPlots) { + histos.fill(HIST("Result/Data/lambda1520invmass"), lResonance.M()); + } + histos.fill(HIST("Result/Data/h3lambda1520invmass"), multiplicity, lResonance.Pt(), lResonance.M()); + } else if (trk1.sign() > 0) { + if (cFillinvmass1DPlots) { + histos.fill(HIST("Result/Data/antilambda1520invmass"), lResonance.M()); + } + histos.fill(HIST("Result/Data/h3antilambda1520invmass"), multiplicity, lResonance.Pt(), lResonance.M()); + } + } else if (IsMix) { + if (cFillinvmass1DPlots) { + histos.fill(HIST("Result/Data/lambda1520invmassME"), lResonance.M()); + } + histos.fill(HIST("Result/Data/h3lambda1520invmassME"), multiplicity, lResonance.Pt(), lResonance.M()); + if (cFilladditionalMEPlots) { + if (trk1.sign() < 0) { + histos.fill(HIST("Result/Data/h3lambda1520invmassME_DS"), multiplicity, lResonance.Pt(), lResonance.M()); + } else if (trk1.sign() > 0) { + histos.fill(HIST("Result/Data/h3lambda1520invmassME_DSAnti"), multiplicity, lResonance.Pt(), lResonance.M()); + } + } + } + + // MC + if constexpr (IsMC) { + // LOG(info) << "trk1 pdgcode: " << trk1.pdgCode() << "trk2 pdgcode: " << trk2.pdgCode() << endl; + + const auto mctrack1 = trk1.mcParticle(); + const auto mctrack2 = trk2.mcParticle(); + + if (std::abs(mctrack1.pdgCode()) != PDG_t::kProton || std::abs(mctrack2.pdgCode()) != PDG_t::kKPlus) + continue; + bool isMotherOk = false; + int pdgCodeMother = -999; + + if (!trk1.has_mcParticle() || !trk2.has_mcParticle()) + continue; + + for (const auto& mothertrack1 : mctrack1.template mothers_as()) { + for (const auto& mothertrack2 : mctrack2.template mothers_as()) { + if (mothertrack1.pdgCode() != mothertrack2.pdgCode()) + continue; + if (mothertrack1.globalIndex() != mothertrack2.globalIndex()) + continue; + + if (std::abs(mothertrack1.pdgCode()) == kLambda1520PDG) // Pb PDG code + continue; + + pdgCodeMother = mothertrack1.pdgCode(); + + isMotherOk = true; + } + } + + // if (motherdTracks1.id() != motherdTracks2.id()) // Same mother + // continue; + // if (std::abs(motherdTracks1.pdgCode()) != kLambda1520PDG) + // continue; + + if (std::abs(lResonance.Eta()) > cEtacutMC) // eta cut + continue; + + if (!isMotherOk) + continue; + + histos.fill(HIST("QA/MC/h2RecoEtaPt_after"), lResonance.Eta(), lResonance.Pt()); + histos.fill(HIST("QA/MC/h2RecoPhiRapidity_after"), lResonance.Phi(), lResonance.Rapidity()); + + // Track selection check. + histos.fill(HIST("QA/MC/trkDCAxy_pr"), trk1ptPr, trk1.dcaXY()); + histos.fill(HIST("QA/MC/trkDCAxy_ka"), trk2ptKa, trk2.dcaXY()); + histos.fill(HIST("QA/MC/trkDCAz_pr"), trk1ptPr, trk1.dcaZ()); + histos.fill(HIST("QA/MC/trkDCAz_ka"), trk2ptKa, trk2.dcaZ()); + + histos.fill(HIST("QA/MC/TPC_Nsigma_pr_all"), multiplicity, trk1ptPr, trk1NSigmaPrTPC); + if (isTrk1hasTOF) { + histos.fill(HIST("QA/MC/TOF_Nsigma_pr_all"), multiplicity, trk1ptPr, trk1NSigmaPrTOF); + } + histos.fill(HIST("QA/MC/TPC_Nsigma_ka_all"), multiplicity, trk2ptKa, trk2NSigmaKaTPC); + if (isTrk2hasTOF) { + histos.fill(HIST("QA/MC/TOF_Nsigma_ka_all"), multiplicity, trk2ptKa, trk2NSigmaKaTOF); + } + + // MC histograms + if (pdgCodeMother > 0) { + histos.fill(HIST("Result/MC/h3lambda1520Recoinvmass"), multiplicity, lResonance.Pt(), lResonance.M()); + } else { + histos.fill(HIST("Result/MC/h3antilambda1520Recoinvmass"), multiplicity, lResonance.Pt(), lResonance.M()); + } + } + } else { + if constexpr (IsData) { + // Like sign pair ++ + if (trk1.sign() > 0) { + if (cFillinvmass1DPlots) { + histos.fill(HIST("Result/Data/lambda1520invmassLSPP"), lResonance.M()); + } + histos.fill(HIST("Result/Data/h3lambda1520invmassLSPP"), multiplicity, lResonance.Pt(), lResonance.M()); + } else { // Like sign pair -- + if (cFillinvmass1DPlots) { + histos.fill(HIST("Result/Data/lambda1520invmassLSMM"), lResonance.M()); + } + histos.fill(HIST("Result/Data/h3lambda1520invmassLSMM"), multiplicity, lResonance.Pt(), lResonance.M()); + } + } + } + } + } + + void processData(EventCandidates::iterator const& collision, + TrackCandidates const& tracks, + BCsWithTimestamps const&) + { + if (!colCuts.isSelected(collision)) // Default event selection + return; + + centrality = getCentrality(collision); + // if (centrality < cfgEventCentralityMin || centrality > cfgEventCentralityMax) + // return; + + colCuts.fillQA(collision); + + if (cFilladditionalQAeventPlots) + histos.fill(HIST("QAevent/hEvtCounterSameE"), 1.0); + fillHistograms(collision, tracks, tracks); + } + PROCESS_SWITCH(Lstaranalysis, processData, "Process Event for data without partition", false); + + void processMC(MCEventCandidates::iterator const& collision, + MCTrackCandidates const& tracks, + BCsWithTimestamps const&) + { + if (!colCuts.isSelected(collision) || (std::abs(collision.posZ()) > cZvertCutMC)) // MC event selection, all cuts missing vtx cut + return; + fillHistograms(collision, tracks, tracks); + } + PROCESS_SWITCH(Lstaranalysis, processMC, "Process Event for MC Light without partition", false); + + void processMCTrue(EventCandidates::iterator const& collision, McParticles const& mcParticles) + { + auto multiplicity = collision.centFT0M(); + + LorentzVectorPtEtaPhiMass lDecayDaughter1, lDecayDaughter2, vresoParent; + + // Not related to the real collisions + for (const auto& part : mcParticles) { // loop over all MC particles + if (std::abs(part.pdgCode()) != kLambda1520PDG) // Lambda1520(0) + continue; + + auto kDaughters = part.daughters_as(); + if (kDaughters.size() != static_cast(2)) { + continue; + } + + // bool pass1 = std::abs(part.daughterPDG1()) == 321 || std::abs(part.daughterPDG2()) == 321; // At least one decay to Kaon + // bool pass2 = std::abs(part.daughterPDG1()) == 2212 || std::abs(part.daughterPDG2()) == 2212; // At least one decay to Proton + + auto daughtp = false; + auto daughtk = false; + for (const auto& kCurrentDaughter : kDaughters) { + if (!kCurrentDaughter.isPhysicalPrimary()) + break; + + if (std::abs(kCurrentDaughter.pdgCode()) == PDG_t::kProton) { // Proton + daughtp = true; + lDecayDaughter1 = LorentzVectorPtEtaPhiMass(kCurrentDaughter.pt(), kCurrentDaughter.eta(), kCurrentDaughter.phi(), massPr); + } else if (std::abs(kCurrentDaughter.pdgCode()) == PDG_t::kKPlus) { + daughtk = true; + lDecayDaughter2 = LorentzVectorPtEtaPhiMass(kCurrentDaughter.pt(), kCurrentDaughter.eta(), kCurrentDaughter.phi(), massKa); + } + } + + // Checking if we have both decay products + if (!daughtp || !daughtk) + continue; + + vresoParent = lDecayDaughter1 + lDecayDaughter2; + + histos.fill(HIST("QA/MC/h2GenEtaPt_beforeanycut"), vresoParent.Eta(), part.pt()); + histos.fill(HIST("QA/MC/h2GenPhiRapidity_beforeanycut"), vresoParent.Phi(), part.y()); + + if (std::abs(part.y()) > static_cast(0.5)) // rapidity cut + continue; + + histos.fill(HIST("QA/MC/h2GenEtaPt_beforeEtacut"), vresoParent.Eta(), part.pt()); + histos.fill(HIST("QA/MC/h2GenPhiRapidity_beforeEtacut"), vresoParent.Phi(), part.y()); + + if (std::abs(vresoParent.Eta()) > cEtacutMC) // eta cut + continue; + + histos.fill(HIST("QA/MC/h2GenEtaPt_afterEtacut"), vresoParent.Eta(), part.pt()); + histos.fill(HIST("QA/MC/h2GenPhiRapidity_afterEtacut"), vresoParent.Phi(), part.y()); + + // without any event selection + if (part.pdgCode() > 0) + histos.fill(HIST("Result/MC/Genlambda1520pt"), 0, part.pt(), multiplicity); + else + histos.fill(HIST("Result/MC/Genantilambda1520pt"), 0, part.pt(), multiplicity); + + if (collision.posZ() > static_cast(10.)) // INEL10 + { + if (part.pdgCode() > 0) + histos.fill(HIST("Result/MC/Genlambda1520pt"), 1, part.pt(), multiplicity); + else + histos.fill(HIST("Result/MC/Genantilambda1520pt"), 1, part.pt(), multiplicity); + } + if (collision.posZ() > static_cast(10.) && collision.sel8()) // INEL>10, vtx10 + { + if (part.pdgCode() > 0) + histos.fill(HIST("Result/MC/Genlambda1520pt"), 2, part.pt(), multiplicity); + else + histos.fill(HIST("Result/MC/Genantilambda1520pt"), 2, part.pt(), multiplicity); + } + if (collision.posZ() > static_cast(10.) && collision.selection_bit(aod::evsel::kIsTriggerTVX)) // vtx10, TriggerTVX + { + if (part.pdgCode() > 0) + histos.fill(HIST("Result/MC/Genlambda1520pt"), 3, part.pt(), multiplicity); + else + histos.fill(HIST("Result/MC/Genantilambda1520pt"), 3, part.pt(), multiplicity); + } + if (colCuts.isSelected(collision)) // after all event selection + { + if (part.pdgCode() > 0) + histos.fill(HIST("Result/MC/Genlambda1520pt"), 4, part.pt(), multiplicity); + else + histos.fill(HIST("Result/MC/Genantilambda1520pt"), 4, part.pt(), multiplicity); + } + } + } + PROCESS_SWITCH(Lstaranalysis, processMCTrue, "Process Event for MC only", false); + + // Processing Event Mixing + using BinningTypeVtxZT0M = ColumnBinningPolicy; + BinningTypeVtxZT0M colBinning{{cfgVtxBins, cfgMultBins}, true}; + + void processME(EventCandidates const& collision, + TrackCandidates const& tracks, + BCsWithTimestamps const&) + { + auto tracksTuple = std::make_tuple(tracks); + SameKindPair pairs{colBinning, nEvtMixing, -1, collision, tracksTuple, &cache}; // -1 is the number of the bin to skip + + for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { + // LOGF(info, "Mixed event collisions: (%d, %d)", collision1.globalIndex(), collision2.globalIndex()); + + // for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { + // LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d)", t1.index(), t2.index(), collision1.index(), collision2.index()); + // } + + if (cFilladditionalQAeventPlots) { + // Fill histograms for the characteristics of the *mixed* events (collision1 and collision2) + // This will show the distribution of events that are actually being mixed. + histos.fill(HIST("QAevent/hMixPool_VtxZ"), collision1.posZ()); + histos.fill(HIST("QAevent/hMixPool_Multiplicity"), collision1.centFT0M()); // Assuming getCentrality() gives multiplicity + histos.fill(HIST("QAevent/hMixPool_VtxZ_vs_Multiplicity"), collision1.posZ(), collision1.centFT0M()); + + // You might also want to fill for collision2 if you want to see both partners' distributions + // histos.fill(HIST("QAevent/hMixPool_VtxZ"), collision2.posZ()); + // histos.fill(HIST("QAevent/hMixPool_Multiplicity"), collision2.getCentrality()); + // histos.fill(HIST("QAevent/hMixPool_VtxZ_vs_Multiplicity"), collision2.posZ(), collision2.getCentrality()); + + histos.fill(HIST("QAevent/hEvtCounterMixedE"), 1.f); + } + fillHistograms(collision1, tracks1, tracks2); + } + } + PROCESS_SWITCH(Lstaranalysis, processME, "Process EventMixing light without partition", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/Tasks/Resonances/phianalysisrun3_PbPb.cxx b/PWGLF/Tasks/Resonances/phianalysisrun3_PbPb.cxx index 425bb69d512..8c24850e7a6 100644 --- a/PWGLF/Tasks/Resonances/phianalysisrun3_PbPb.cxx +++ b/PWGLF/Tasks/Resonances/phianalysisrun3_PbPb.cxx @@ -16,55 +16,65 @@ // (5) particle = 2 --> lambdastar // (6) 4 process function (a) Data same event (b) Data mixed event (c) MC generated (d) MC reconstructed -#include +#include "PWGLF/DataModel/EPCalibrationTables.h" + +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CommonConstants/PhysicsConstants.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include "Math/GenVector/Boost.h" +#include "Math/Vector3D.h" +#include "Math/Vector4D.h" +#include "TF1.h" +#include "TRandom3.h" +#include #include +#include +#include +#include #include #include #include #include -#include -#include -#include #include -#include -#include + #include +#include #include +#include #include -#include "TRandom3.h" -#include "Math/Vector3D.h" -#include "Math/Vector4D.h" -#include "Math/GenVector/Boost.h" -#include "TF1.h" - -#include "PWGLF/DataModel/EPCalibrationTables.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/StepTHn.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Common/DataModel/PIDResponse.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/Core/trackUtilities.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Common/Core/TrackSelection.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "CCDB/BasicCCDBManager.h" - using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using std::array; -struct phianalysisrun3_PbPb { +using namespace o2::aod::rctsel; +struct phianalysisrun3_PbPb { + struct : ConfigurableGroup { + Configurable requireRCTFlagChecker{"requireRCTFlagChecker", true, "Check event quality in run condition table"}; + Configurable cfgEvtRCTFlagCheckerLabel{"cfgEvtRCTFlagCheckerLabel", "CBT_hadronPID", "Evt sel: RCT flag checker label"}; + Configurable cfgEvtRCTFlagCheckerZDCCheck{"cfgEvtRCTFlagCheckerZDCCheck", false, "Evt sel: RCT flag checker ZDC check"}; + Configurable cfgEvtRCTFlagCheckerLimitAcceptAsBad{"cfgEvtRCTFlagCheckerLimitAcceptAsBad", true, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"}; + } rctCut; + RCTFlagsChecker rctChecker; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; // events Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; @@ -110,12 +120,14 @@ struct phianalysisrun3_PbPb { Configurable avoidsplitrackMC{"avoidsplitrackMC", false, "avoid split track in MC"}; void init(o2::framework::InitContext&) { + rctChecker.init(rctCut.cfgEvtRCTFlagCheckerLabel, rctCut.cfgEvtRCTFlagCheckerZDCCheck, rctCut.cfgEvtRCTFlagCheckerLimitAcceptAsBad); AxisSpec impactParAxis = {binsImpactPar, "Impact Parameter"}; AxisSpec ptAxis = {binsPt, "#it{p}_{T} (GeV/#it{c})"}; AxisSpec centAxis = {binsCent, "V0M (%)"}; histos.add("hCentrality", "Centrality distribution", kTH1F, {{200, 0.0, 200.0}}); histos.add("hVtxZ", "Vertex distribution in Z;Z (cm)", kTH1F, {{400, -20.0, 20.0}}); histos.add("hOccupancy", "Occupancy distribution", kTH1F, {{500, 0, 50000}}); + histos.add("hEvtSelInfo", "hEvtSelInfo", kTH1F, {{10, 0, 10.0}}); if (!isMC) { histos.add("h3PhiInvMassUnlikeSign", "Invariant mass of Phi meson Unlike Sign", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); histos.add("h3PhiInvMassMixed", "Invariant mass of Phi meson Mixed", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); @@ -168,18 +180,35 @@ struct phianalysisrun3_PbPb { } // DCA QA - histos.add("QAbefore/trkDCAxy", "DCAxy distribution of kaon track candidates", HistType::kTH1F, {{150, 0.0f, 1.0f}}); - histos.add("QAbefore/trkDCAz", "DCAz distribution of kaon track candidates", HistType::kTH1F, {{150, 0.0f, 1.0f}}); - histos.add("QAafter/trkDCAxy", "DCAxy distribution of kaon track candidates", HistType::kTH1F, {{150, 0.0f, 1.0f}}); - histos.add("QAafter/trkDCAz", "DCAz distribution of kaon track candidates", HistType::kTH1F, {{150, 0.0f, 1.0f}}); + // DCA histograms: separate for positive and negative kaons, range [-1.0, 1.0] + histos.add("QAbefore/trkDCAxy_pos", "DCAxy distribution of positive kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAbefore/trkDCAxy_neg", "DCAxy distribution of negative kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAbefore/trkDCAz_pos", "DCAz distribution of positive kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAbefore/trkDCAz_neg", "DCAz distribution of negative kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + + histos.add("QAafter/trkDCAxy_pos", "DCAxy distribution of positive kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAafter/trkDCAxy_neg", "DCAxy distribution of negative kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAafter/trkDCAz_pos", "DCAz distribution of positive kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("QAafter/trkDCAz_neg", "DCAz distribution of negative kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); // PID QA before cuts - histos.add("QAbefore/TOF_TPC_Mapka_all", "TOF + TPC Combined PID for Kaon;#sigma_{TOF}^{Kaon};#sigma_{TPC}^{Kaon}", {HistType::kTH2D, {{100, -6, 6}, {100, -6, 6}}}); - histos.add("QAbefore/TOF_Nsigma_all", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); - histos.add("QAbefore/TPC_Nsigma_all", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); + histos.add("QAbefore/TOF_TPC_Mapka_all_pos", "TOF + TPC Combined PID for positive Kaon;#sigma_{TOF}^{K^{+}};#sigma_{TPC}^{K^{+}}", {HistType::kTH2D, {{100, -6, 6}, {100, -6, 6}}}); + histos.add("QAbefore/TOF_TPC_Mapka_all_neg", "TOF + TPC Combined PID for negative Kaon;#sigma_{TOF}^{K^{-}};#sigma_{TPC}^{K^{-}}", {HistType::kTH2D, {{100, -6, 6}, {100, -6, 6}}}); + + histos.add("QAbefore/TOF_Nsigma_all_pos", "TOF NSigma for positive Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{K^{+}}", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); + histos.add("QAbefore/TOF_Nsigma_all_neg", "TOF NSigma for negative Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{K^{-}}", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); + + histos.add("QAbefore/TPC_Nsigma_all_pos", "TPC NSigma for positive Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{K^{+}}", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); + histos.add("QAbefore/TPC_Nsigma_all_neg", "TPC NSigma for negative Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{K^{-}}", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); + // PID QA after cuts - histos.add("QAafter/TOF_TPC_Mapka_all", "TOF + TPC Combined PID for Kaon;#sigma_{TOF}^{Kaon};#sigma_{TPC}^{Kaon}", {HistType::kTH2D, {{100, -6, 6}, {100, -6, 6}}}); - histos.add("QAafter/TOF_Nsigma_all", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); - histos.add("QAafter/TPC_Nsigma_all", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); + histos.add("QAafter/TOF_TPC_Mapka_all_pos", "TOF + TPC Combined PID for positive Kaon;#sigma_{TOF}^{K^{+}};#sigma_{TPC}^{K^{+}}", {HistType::kTH2D, {{100, -6, 6}, {100, -6, 6}}}); + histos.add("QAafter/TOF_TPC_Mapka_all_neg", "TOF + TPC Combined PID for negative Kaon;#sigma_{TOF}^{K^{-}};#sigma_{TPC}^{K^{-}}", {HistType::kTH2D, {{100, -6, 6}, {100, -6, 6}}}); + + histos.add("QAafter/TOF_Nsigma_all_pos", "TOF NSigma for positive Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{K^{+}}", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); + histos.add("QAafter/TOF_Nsigma_all_neg", "TOF NSigma for negative Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{K^{-}}", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); + + histos.add("QAafter/TPC_Nsigma_all_pos", "TPC NSigma for positive Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{K^{+}}", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); + histos.add("QAafter/TPC_Nsigma_all_neg", "TPC NSigma for negative Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{K^{-}}", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); } double massKa = o2::constants::physics::MassKPlus; @@ -314,19 +343,28 @@ struct phianalysisrun3_PbPb { ROOT::Math::PxPyPzMVector PhiMesonMother, KaonPlus, KaonMinus; void processSameEvent(EventCandidates::iterator const& collision, TrackCandidates const& tracks, aod::BCs const&) { + histos.fill(HIST("hEvtSelInfo"), 0.5); + if (rctCut.requireRCTFlagChecker && !rctChecker(collision)) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 1.5); if (!collision.sel8()) { return; } + histos.fill(HIST("hEvtSelInfo"), 2.5); if (additionalEvSel2 && (!collision.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { return; } + histos.fill(HIST("hEvtSelInfo"), 3.5); if (additionalEvSel3 && (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard))) { return; } + histos.fill(HIST("hEvtSelInfo"), 4.5); int occupancy = collision.trackOccupancyInTimeRange(); if (fillOccupancy && (occupancy > cfgCutOccupancy)) { return; } + histos.fill(HIST("hEvtSelInfo"), 5.5); float multiplicity{-1}; if (cfgMultFT0) multiplicity = collision.centFT0C(); @@ -337,11 +375,21 @@ struct phianalysisrun3_PbPb { if (!selectionTrack(track1)) { continue; } - histos.fill(HIST("QAbefore/TPC_Nsigma_all"), track1.tpcNSigmaKa(), multiplicity, track1.pt()); - histos.fill(HIST("QAbefore/TOF_Nsigma_all"), track1.tofNSigmaKa(), multiplicity, track1.pt()); - histos.fill(HIST("QAbefore/trkDCAxy"), track1.dcaXY()); - histos.fill(HIST("QAbefore/trkDCAz"), track1.dcaZ()); - histos.fill(HIST("QAbefore/TOF_TPC_Mapka_all"), track1.tofNSigmaKa(), track1.tpcNSigmaKa()); + int track1Sign = track1.sign(); // or track1.charge(), assuming it returns ±1 + + if (track1Sign > 0) { // Positive kaon + histos.fill(HIST("QAbefore/TPC_Nsigma_all_pos"), track1.tpcNSigmaKa(), multiplicity, track1.pt()); + histos.fill(HIST("QAbefore/TOF_Nsigma_all_pos"), track1.tofNSigmaKa(), multiplicity, track1.pt()); + histos.fill(HIST("QAbefore/trkDCAxy_pos"), track1.dcaXY()); + histos.fill(HIST("QAbefore/trkDCAz_pos"), track1.dcaZ()); + histos.fill(HIST("QAbefore/TOF_TPC_Mapka_all_pos"), track1.tofNSigmaKa(), track1.tpcNSigmaKa()); + } else if (track1Sign < 0) { // Negative kaon + histos.fill(HIST("QAbefore/TPC_Nsigma_all_neg"), track1.tpcNSigmaKa(), multiplicity, track1.pt()); + histos.fill(HIST("QAbefore/TOF_Nsigma_all_neg"), track1.tofNSigmaKa(), multiplicity, track1.pt()); + histos.fill(HIST("QAbefore/trkDCAxy_neg"), track1.dcaXY()); + histos.fill(HIST("QAbefore/trkDCAz_neg"), track1.dcaZ()); + histos.fill(HIST("QAbefore/TOF_TPC_Mapka_all_neg"), track1.tofNSigmaKa(), track1.tpcNSigmaKa()); + } auto track1ID = track1.globalIndex(); for (auto track2 : tracks) { @@ -358,19 +406,42 @@ struct phianalysisrun3_PbPb { bool unlike = true; bool mix = false; if (!ispTdepPID && selectionPID(track1) && selectionPID(track2)) { - histos.fill(HIST("QAafter/TPC_Nsigma_all"), track1.tpcNSigmaKa(), multiplicity, track1.pt()); - histos.fill(HIST("QAafter/TOF_Nsigma_all"), track1.tofNSigmaKa(), multiplicity, track1.pt()); - histos.fill(HIST("QAafter/trkDCAxy"), track1.dcaXY()); - histos.fill(HIST("QAafter/trkDCAz"), track1.dcaZ()); - histos.fill(HIST("QAafter/TOF_TPC_Mapka_all"), track1.tofNSigmaKa(), track1.tpcNSigmaKa()); + int track1Sign = track1.sign(); // Assuming `charge()` gives +1 or -1 + + if (track1Sign > 0) { // Positive kaon + histos.fill(HIST("QAafter/TPC_Nsigma_all_pos"), track1.tpcNSigmaKa(), multiplicity, track1.pt()); + histos.fill(HIST("QAafter/TOF_Nsigma_all_pos"), track1.tofNSigmaKa(), multiplicity, track1.pt()); + histos.fill(HIST("QAafter/trkDCAxy_pos"), track1.dcaXY()); + histos.fill(HIST("QAafter/trkDCAz_pos"), track1.dcaZ()); + histos.fill(HIST("QAafter/TOF_TPC_Mapka_all_pos"), track1.tofNSigmaKa(), track1.tpcNSigmaKa()); + } else if (track1Sign < 0) { // Negative kaon + histos.fill(HIST("QAafter/TPC_Nsigma_all_neg"), track1.tpcNSigmaKa(), multiplicity, track1.pt()); + histos.fill(HIST("QAafter/TOF_Nsigma_all_neg"), track1.tofNSigmaKa(), multiplicity, track1.pt()); + histos.fill(HIST("QAafter/trkDCAxy_neg"), track1.dcaXY()); + histos.fill(HIST("QAafter/trkDCAz_neg"), track1.dcaZ()); + histos.fill(HIST("QAafter/TOF_TPC_Mapka_all_neg"), track1.tofNSigmaKa(), track1.tpcNSigmaKa()); + } + FillinvMass(track1, track2, multiplicity, unlike, mix, massKa, massKa); } + if (ispTdepPID && selectionPIDpTdependent(track1) && selectionPIDpTdependent(track2)) { - histos.fill(HIST("QAafter/TPC_Nsigma_all"), track1.tpcNSigmaKa(), multiplicity, track1.pt()); - histos.fill(HIST("QAafter/TOF_Nsigma_all"), track1.tofNSigmaKa(), multiplicity, track1.pt()); - histos.fill(HIST("QAafter/trkDCAxy"), track1.dcaXY()); - histos.fill(HIST("QAafter/trkDCAz"), track1.dcaZ()); - histos.fill(HIST("QAafter/TOF_TPC_Mapka_all"), track1.tofNSigmaKa(), track1.tpcNSigmaKa()); + int track1Sign = track1.sign(); // Same assumption as above + + if (track1Sign > 0) { // Positive kaon + histos.fill(HIST("QAafter/TPC_Nsigma_all_pos"), track1.tpcNSigmaKa(), multiplicity, track1.pt()); + histos.fill(HIST("QAafter/TOF_Nsigma_all_pos"), track1.tofNSigmaKa(), multiplicity, track1.pt()); + histos.fill(HIST("QAafter/trkDCAxy_pos"), track1.dcaXY()); + histos.fill(HIST("QAafter/trkDCAz_pos"), track1.dcaZ()); + histos.fill(HIST("QAafter/TOF_TPC_Mapka_all_pos"), track1.tofNSigmaKa(), track1.tpcNSigmaKa()); + } else if (track1Sign < 0) { // Negative kaon + histos.fill(HIST("QAafter/TPC_Nsigma_all_neg"), track1.tpcNSigmaKa(), multiplicity, track1.pt()); + histos.fill(HIST("QAafter/TOF_Nsigma_all_neg"), track1.tofNSigmaKa(), multiplicity, track1.pt()); + histos.fill(HIST("QAafter/trkDCAxy_neg"), track1.dcaXY()); + histos.fill(HIST("QAafter/trkDCAz_neg"), track1.dcaZ()); + histos.fill(HIST("QAafter/TOF_TPC_Mapka_all_neg"), track1.tofNSigmaKa(), track1.tpcNSigmaKa()); + } + FillinvMass(track1, track2, multiplicity, unlike, mix, massKa, massKa); } } @@ -385,6 +456,12 @@ struct phianalysisrun3_PbPb { BinningTypeVertexContributor binningOnPositions{{axisVertex, axisMultiplicity}, true}; SameKindPair pair{binningOnPositions, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; for (auto& [c1, tracks1, c2, tracks2] : pair) { + if (rctCut.requireRCTFlagChecker && !rctChecker(c1)) { + continue; + } + if (rctCut.requireRCTFlagChecker && !rctChecker(c2)) { + continue; + } if (!c1.sel8()) { continue; } diff --git a/PWGLF/Tasks/Strangeness/cascadeanalysisMC.cxx b/PWGLF/Tasks/Strangeness/cascadeanalysisMC.cxx index b9f32b8600c..a1947c8b6b5 100644 --- a/PWGLF/Tasks/Strangeness/cascadeanalysisMC.cxx +++ b/PWGLF/Tasks/Strangeness/cascadeanalysisMC.cxx @@ -80,6 +80,7 @@ struct cascadeGenerated { Configurable nPtBins{"nPtBins", 200, "number of pT bins"}; Configurable rapidityCut{"rapidityCut", 0.5, "max (absolute) rapidity of generated cascade"}; Configurable nRapidityBins{"nRapidityBins", 200, "number of pT bins"}; + Configurable requirePhysicalPrimary{"requirePhysicalPrimary", false, "require the generated cascade to be a physical primary"}; void init(InitContext const&) { @@ -108,6 +109,8 @@ struct cascadeGenerated { for (auto& particle : mcparts) { if (TMath::Abs(particle.y()) > rapidityCut) continue; + if (requirePhysicalPrimary && !particle.isPhysicalPrimary()) + continue; if (particle.pdgCode() == 3312) { registry.fill(HIST("hPtXiMinus"), particle.pt()); registry.fill(HIST("h2DXiMinus"), particle.pt(), particle.y()); diff --git a/PWGLF/Tasks/Strangeness/cascadecorrelations.cxx b/PWGLF/Tasks/Strangeness/cascadecorrelations.cxx index 8461e713543..632d80dd4d1 100644 --- a/PWGLF/Tasks/Strangeness/cascadecorrelations.cxx +++ b/PWGLF/Tasks/Strangeness/cascadecorrelations.cxx @@ -96,6 +96,7 @@ struct CascadeSelector { Configurable doNoSameBunchPileUp{"doNoSameBunchPileUp", true, "Switch to apply NoSameBunchPileUp event selection"}; Configurable INEL{"INEL", 0, "Number of charged tracks within |eta| < 1 has to be greater than value"}; Configurable maxVertexZ{"maxVertexZ", 10., "Maximum value of z coordinate of PV"}; + Configurable etaCascades{"etaCascades", 0.8, "min/max of eta for cascades"}; // Tracklevel Configurable tpcNsigmaBachelor{"tpcNsigmaBachelor", 3, "TPC NSigma bachelor"}; @@ -104,7 +105,6 @@ struct CascadeSelector { Configurable minTPCCrossedRows{"minTPCCrossedRows", 80, "min N TPC crossed rows"}; // TODO: finetune! 80 > 159/2, so no split tracks? Configurable minITSClusters{"minITSClusters", 4, "minimum number of ITS clusters"}; Configurable etaTracks{"etaTracks", 1.0, "min/max of eta for tracks"}; - Configurable etaCascades{"etaCascades", 0.8, "min/max of eta for cascades"}; // Selection criteria - compatible with core wagon autodetect - copied from cascadeanalysis.cxx //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* @@ -122,28 +122,32 @@ struct CascadeSelector { //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* // TODO: variables as function of Omega mass, only do Xi for now - AxisSpec vertexAxis = {100, -10.0f, 10.0f, "cm"}; - AxisSpec dcaAxis = {50, 0.0f, 5.0f, "cm"}; - // AxisSpec invMassAxis = {1000, 1.0f, 2.0f, "Inv. Mass (GeV/c^{2})"}; - AxisSpec invXiMassAxis = {100, 1.28f, 1.38f, "Inv. Mass (GeV/c^{2})"}; - AxisSpec invOmegaMassAxis = {100, 1.62f, 1.72f, "Inv. Mass (GeV/c^{2})"}; - AxisSpec ptAxis = {150, 0, 15, "#it{p}_{T}"}; - AxisSpec rapidityAxis{100, -1.f, 1.f, "y"}; + ConfigurableAxis radiusAxis = {"radiusAxis", {100, 0.0f, 50.0f}, "cm"}; + ConfigurableAxis cpaAxis = {"cpaAxis", {100, 0.95f, 1.0f}, "CPA"}; + ConfigurableAxis vertexAxis = {"vertexAxis", {100, -10.0f, 10.0f}, "cm"}; + ConfigurableAxis dcaAxis = {"dcaAxis", {100, 0.0f, 2.0f}, "cm"}; + ConfigurableAxis invXiMassAxis = {"invXiMassAxis", {100, 1.28f, 1.38f}, "Inv. Mass (GeV/c^{2})"}; + ConfigurableAxis invOmegaMassAxis = {"invOmegaMassAxis", {100, 1.62f, 1.72f}, "Inv. Mass (GeV/c^{2})"}; + ConfigurableAxis ptAxis = {"ptAxis", {150, 0, 15}, "#it{p}_{T}"}; + ConfigurableAxis rapidityAxis{"rapidityAxis", {100, -1.f, 1.f}, "y"}; + ConfigurableAxis invLambdaMassAxis{"invLambdaMassAxis", {100, 1.07f, 1.17f}, "Inv. Mass (GeV/c^{2})"}; + AxisSpec itsClustersAxis{8, -0.5, 7.5, "number of ITS clusters"}; + AxisSpec tpcRowsAxis{160, -0.5, 159.5, "TPC crossed rows"}; HistogramRegistry registry{ "registry", { // basic selection variables - {"hV0Radius", "hV0Radius", {HistType::kTH3F, {{100, 0.0f, 100.0f, "cm"}, invXiMassAxis, ptAxis}}}, - {"hCascRadius", "hCascRadius", {HistType::kTH3F, {{100, 0.0f, 100.0f, "cm"}, invXiMassAxis, ptAxis}}}, - {"hV0CosPA", "hV0CosPA", {HistType::kTH3F, {{100, 0.95f, 1.0f}, invXiMassAxis, ptAxis}}}, - {"hCascCosPA", "hCascCosPA", {HistType::kTH3F, {{100, 0.95f, 1.0f}, invXiMassAxis, ptAxis}}}, + {"hV0Radius", "hV0Radius", {HistType::kTH3F, {radiusAxis, invXiMassAxis, ptAxis}}}, + {"hCascRadius", "hCascRadius", {HistType::kTH3F, {radiusAxis, invXiMassAxis, ptAxis}}}, + {"hV0CosPA", "hV0CosPA", {HistType::kTH3F, {cpaAxis, invXiMassAxis, ptAxis}}}, + {"hCascCosPA", "hCascCosPA", {HistType::kTH3F, {cpaAxis, invXiMassAxis, ptAxis}}}, {"hDCAPosToPV", "hDCAPosToPV", {HistType::kTH3F, {vertexAxis, invXiMassAxis, ptAxis}}}, {"hDCANegToPV", "hDCANegToPV", {HistType::kTH3F, {vertexAxis, invXiMassAxis, ptAxis}}}, {"hDCABachToPV", "hDCABachToPV", {HistType::kTH3F, {vertexAxis, invXiMassAxis, ptAxis}}}, {"hDCAV0ToPV", "hDCAV0ToPV", {HistType::kTH3F, {vertexAxis, invXiMassAxis, ptAxis}}}, {"hDCAV0Dau", "hDCAV0Dau", {HistType::kTH3F, {dcaAxis, invXiMassAxis, ptAxis}}}, {"hDCACascDau", "hDCACascDau", {HistType::kTH3F, {dcaAxis, invXiMassAxis, ptAxis}}}, - {"hLambdaMass", "hLambdaMass", {HistType::kTH3F, {{100, 1.0f, 1.2f, "Inv. Mass (GeV/c^{2})"}, invXiMassAxis, ptAxis}}}, + {"hLambdaMass", "hLambdaMass", {HistType::kTH3F, {invLambdaMassAxis, invXiMassAxis, ptAxis}}}, {"hMassXiMinus", "hMassXiMinus", {HistType::kTH3F, {invXiMassAxis, ptAxis, rapidityAxis}}}, {"hMassXiPlus", "hMassXiPlus", {HistType::kTH3F, {invXiMassAxis, ptAxis, rapidityAxis}}}, @@ -159,12 +163,12 @@ struct CascadeSelector { // {"hMassXi5", "Xi inv mass after bachelor PID cut", {HistType::kTH2F, {invMassAxis, ptAxis}}}, // ITS & TPC clusters, with Xi inv mass - {"hTPCnCrossedRowsPos", "hTPCnCrossedRowsPos", {HistType::kTH3F, {{160, -0.5, 159.5, "TPC crossed rows"}, invXiMassAxis, ptAxis}}}, - {"hTPCnCrossedRowsNeg", "hTPCnCrossedRowsNeg", {HistType::kTH3F, {{160, -0.5, 159.5, "TPC crossed rows"}, invXiMassAxis, ptAxis}}}, - {"hTPCnCrossedRowsBach", "hTPCnCrossedRowsBach", {HistType::kTH3F, {{160, -0.5, 159.5, "TPC crossed rows"}, invXiMassAxis, ptAxis}}}, - {"hITSnClustersPos", "hITSnClustersPos", {HistType::kTH3F, {{8, -0.5, 7.5, "number of ITS clusters"}, invXiMassAxis, ptAxis}}}, - {"hITSnClustersNeg", "hITSnClustersNeg", {HistType::kTH3F, {{8, -0.5, 7.5, "number of ITS clusters"}, invXiMassAxis, ptAxis}}}, - {"hITSnClustersBach", "hITSnClustersBach", {HistType::kTH3F, {{8, -0.5, 7.5, "number of ITS clusters"}, invXiMassAxis, ptAxis}}}, + {"hTPCnCrossedRowsPos", "hTPCnCrossedRowsPos", {HistType::kTH3F, {tpcRowsAxis, invXiMassAxis, ptAxis}}}, + {"hTPCnCrossedRowsNeg", "hTPCnCrossedRowsNeg", {HistType::kTH3F, {tpcRowsAxis, invXiMassAxis, ptAxis}}}, + {"hTPCnCrossedRowsBach", "hTPCnCrossedRowsBach", {HistType::kTH3F, {tpcRowsAxis, invXiMassAxis, ptAxis}}}, + {"hITSnClustersPos", "hITSnClustersPos", {HistType::kTH3F, {itsClustersAxis, invXiMassAxis, ptAxis}}}, + {"hITSnClustersNeg", "hITSnClustersNeg", {HistType::kTH3F, {itsClustersAxis, invXiMassAxis, ptAxis}}}, + {"hITSnClustersBach", "hITSnClustersBach", {HistType::kTH3F, {itsClustersAxis, invXiMassAxis, ptAxis}}}, {"hTriggerQA", "hTriggerQA", {HistType::kTH1F, {{2, -0.5, 1.5, "Trigger y/n"}}}}, }, @@ -193,11 +197,43 @@ struct CascadeSelector { hEventSel->GetXaxis()->SetBinLabel(4, "V_z"); hEventSel->GetXaxis()->SetBinLabel(5, "NoSameBunchPileUp"); hEventSel->GetXaxis()->SetBinLabel(6, "Selected events"); + + if (doprocessRecMC) { + // only create the rec matched to gen histograms if relevant + registry.add("truerec/hV0Radius", "hV0Radius", HistType::kTH1F, {radiusAxis}); + registry.add("truerec/hCascRadius", "hCascRadius", HistType::kTH1F, {radiusAxis}); + registry.add("truerec/hV0CosPA", "hV0CosPA", HistType::kTH1F, {cpaAxis}); + registry.add("truerec/hCascCosPA", "hCascCosPA", HistType::kTH1F, {cpaAxis}); + registry.add("truerec/hDCAPosToPV", "hDCAPosToPV", HistType::kTH1F, {vertexAxis}); + registry.add("truerec/hDCANegToPV", "hDCANegToPV", HistType::kTH1F, {vertexAxis}); + registry.add("truerec/hDCABachToPV", "hDCABachToPV", HistType::kTH1F, {vertexAxis}); + registry.add("truerec/hDCAV0ToPV", "hDCAV0ToPV", HistType::kTH1F, {vertexAxis}); + registry.add("truerec/hDCAV0Dau", "hDCAV0Dau", HistType::kTH1F, {dcaAxis}); + registry.add("truerec/hDCACascDau", "hDCACascDau", HistType::kTH1F, {dcaAxis}); + registry.add("truerec/hLambdaMass", "hLambdaMass", HistType::kTH1F, {invLambdaMassAxis}); + registry.add("truerec/hTPCnCrossedRowsPos", "hTPCnCrossedRowsPos", HistType::kTH1F, {tpcRowsAxis}); + registry.add("truerec/hTPCnCrossedRowsNeg", "hTPCnCrossedRowsNeg", HistType::kTH1F, {tpcRowsAxis}); + registry.add("truerec/hTPCnCrossedRowsBach", "hTPCnCrossedRowsBach", HistType::kTH1F, {tpcRowsAxis}); + registry.add("truerec/hITSnClustersPos", "hITSnClustersPos", HistType::kTH1F, {itsClustersAxis}); + registry.add("truerec/hITSnClustersNeg", "hITSnClustersNeg", HistType::kTH1F, {itsClustersAxis}); + registry.add("truerec/hITSnClustersBach", "hITSnClustersBach", HistType::kTH1F, {itsClustersAxis}); + registry.add("truerec/hXiMinus", "hXiMinus", HistType::kTH2F, {ptAxis, rapidityAxis}); + registry.add("truerec/hXiPlus", "hXiPlus", HistType::kTH2F, {ptAxis, rapidityAxis}); + registry.add("truerec/hOmegaMinus", "hOmegaMinus", HistType::kTH2F, {ptAxis, rapidityAxis}); + registry.add("truerec/hOmegaPlus", "hOmegaPlus", HistType::kTH2F, {ptAxis, rapidityAxis}); + } + + if (doprocessGenMC) { + // only create the MC gen histograms if relevant + registry.add("gen/hXiMinus", "hXiMinus", HistType::kTH2F, {ptAxis, rapidityAxis}); + registry.add("gen/hXiPlus", "hXiPlus", HistType::kTH2F, {ptAxis, rapidityAxis}); + registry.add("gen/hOmegaMinus", "hOmegaMinus", HistType::kTH2F, {ptAxis, rapidityAxis}); + registry.add("gen/hOmegaPlus", "hOmegaPlus", HistType::kTH2F, {ptAxis, rapidityAxis}); + } } - void process(MyCollisions::iterator const& collision, aod::CascDataExt const& Cascades, FullTracksExtIUWithPID const&, aod::BCsWithTimestamps const&) + bool eventSelection(MyCollisions::iterator const& collision) { - bool evSel = true; if (useTrigger) { auto bc = collision.bc_as(); zorro.initCCDB(ccdb.service, bc.runNumber(), bc.timestamp(), triggerList); @@ -206,177 +242,273 @@ struct CascadeSelector { registry.fill(HIST("hTriggerQA"), 1); } else { registry.fill(HIST("hTriggerQA"), 0); - evSel = false; + return false; } } - // fill event selection based on which selection criteria are applied and passed - // do not skip the collision - this will lead to the cascadeFlag table having less entries than the Cascade table, and therefor not joinable. registry.fill(HIST("hEventSel"), 0); if (doSel8 && !collision.sel8()) { - evSel = false; registry.fill(HIST("hEventSel"), 1); + return false; } else if (collision.multNTracksPVeta1() <= INEL) { - evSel = false; registry.fill(HIST("hEventSel"), 2); + return false; } else if (std::abs(collision.posZ()) > maxVertexZ) { - evSel = false; registry.fill(HIST("hEventSel"), 3); + return false; } else if (doNoSameBunchPileUp && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { - evSel = false; registry.fill(HIST("hEventSel"), 4); + return false; } - if (evSel) // passes all selections - registry.fill(HIST("hEventSel"), 5); + // passes all selections + registry.fill(HIST("hEventSel"), 5); + return true; + } - for (auto const& casc : Cascades) { - if (!evSel) { - cascflags(0); - continue; + void fillMatchedHistos(LabeledCascades::iterator rec, int flag, MyCollisions::iterator collision) + { + if (flag == 0) + return; + if (!rec.has_mcParticle()) + return; + auto gen = rec.mcParticle(); + if (!gen.isPhysicalPrimary()) + return; + int genpdg = gen.pdgCode(); + if ((flag < 3 && TMath::Abs(genpdg) == 3312) || (flag > 1 && TMath::Abs(genpdg) == 3334)) { + // if casc is consistent with Xi and has matched gen Xi OR cand is consistent with Omega and has matched gen omega + // have to do this in case we reco true Xi with only Omega hypothesis (or vice versa) (very unlikely) + registry.fill(HIST("truerec/hV0Radius"), rec.v0radius()); + registry.fill(HIST("truerec/hCascRadius"), rec.cascradius()); + registry.fill(HIST("truerec/hV0CosPA"), rec.v0cosPA(collision.posX(), collision.posY(), collision.posZ())); + registry.fill(HIST("truerec/hCascCosPA"), rec.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + registry.fill(HIST("truerec/hDCAPosToPV"), rec.dcapostopv()); + registry.fill(HIST("truerec/hDCANegToPV"), rec.dcanegtopv()); + registry.fill(HIST("truerec/hDCABachToPV"), rec.dcabachtopv()); + registry.fill(HIST("truerec/hDCAV0ToPV"), rec.dcav0topv(collision.posX(), collision.posY(), collision.posZ())); + registry.fill(HIST("truerec/hDCAV0Dau"), rec.dcaV0daughters()); + registry.fill(HIST("truerec/hDCACascDau"), rec.dcacascdaughters()); + registry.fill(HIST("truerec/hLambdaMass"), rec.mLambda()); + registry.fill(HIST("truerec/hITSnClustersPos"), rec.posTrack_as().itsNCls()); + registry.fill(HIST("truerec/hITSnClustersNeg"), rec.negTrack_as().itsNCls()); + registry.fill(HIST("truerec/hITSnClustersBach"), rec.bachelor_as().itsNCls()); + registry.fill(HIST("truerec/hTPCnCrossedRowsPos"), rec.posTrack_as().tpcNClsCrossedRows()); + registry.fill(HIST("truerec/hTPCnCrossedRowsNeg"), rec.negTrack_as().tpcNClsCrossedRows()); + registry.fill(HIST("truerec/hTPCnCrossedRowsBach"), rec.bachelor_as().tpcNClsCrossedRows()); + switch (genpdg) { // is matched so we can use genpdg + case 3312: + registry.fill(HIST("truerec/hXiMinus"), rec.pt(), rec.yXi()); + break; + case -3312: + registry.fill(HIST("truerec/hXiPlus"), rec.pt(), rec.yXi()); + break; + case 3334: + registry.fill(HIST("truerec/hOmegaMinus"), rec.pt(), rec.yOmega()); + break; + case -3334: + registry.fill(HIST("truerec/hOmegaPlus"), rec.pt(), rec.yOmega()); + break; } + } + } - // these are the tracks: - auto bachTrack = casc.bachelor_as(); - auto posTrack = casc.posTrack_as(); - auto negTrack = casc.negTrack_as(); - - // topo variables before cuts: - registry.fill(HIST("hV0Radius"), casc.v0radius(), casc.mXi(), casc.pt()); - registry.fill(HIST("hCascRadius"), casc.cascradius(), casc.mXi(), casc.pt()); - registry.fill(HIST("hV0CosPA"), casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()), casc.mXi(), casc.pt()); - registry.fill(HIST("hCascCosPA"), casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()), casc.mXi(), casc.pt()); - registry.fill(HIST("hDCAPosToPV"), casc.dcapostopv(), casc.mXi(), casc.pt()); - registry.fill(HIST("hDCANegToPV"), casc.dcanegtopv(), casc.mXi(), casc.pt()); - registry.fill(HIST("hDCABachToPV"), casc.dcabachtopv(), casc.mXi(), casc.pt()); - registry.fill(HIST("hDCAV0ToPV"), casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ()), casc.mXi(), casc.pt()); - registry.fill(HIST("hDCAV0Dau"), casc.dcaV0daughters(), casc.mXi(), casc.pt()); - registry.fill(HIST("hDCACascDau"), casc.dcacascdaughters(), casc.mXi(), casc.pt()); - registry.fill(HIST("hLambdaMass"), casc.mLambda(), casc.mXi(), casc.pt()); - - registry.fill(HIST("hITSnClustersPos"), posTrack.itsNCls(), casc.mXi(), casc.pt()); - registry.fill(HIST("hITSnClustersNeg"), negTrack.itsNCls(), casc.mXi(), casc.pt()); - registry.fill(HIST("hITSnClustersBach"), bachTrack.itsNCls(), casc.mXi(), casc.pt()); - registry.fill(HIST("hTPCnCrossedRowsPos"), posTrack.tpcNClsCrossedRows(), casc.mXi(), casc.pt()); - registry.fill(HIST("hTPCnCrossedRowsNeg"), negTrack.tpcNClsCrossedRows(), casc.mXi(), casc.pt()); - registry.fill(HIST("hTPCnCrossedRowsBach"), bachTrack.tpcNClsCrossedRows(), casc.mXi(), casc.pt()); - - registry.fill(HIST("hSelectionStatus"), 0); // all the cascade before selections - // registry.fill(HIST("hMassXi0"), casc.mXi(), casc.pt()); - - // TPC N crossed rows todo: check if minTPCCrossedRows > 50 - if (posTrack.tpcNClsCrossedRows() < minTPCCrossedRows || negTrack.tpcNClsCrossedRows() < minTPCCrossedRows || bachTrack.tpcNClsCrossedRows() < minTPCCrossedRows) { - cascflags(0); - continue; - } - registry.fill(HIST("hSelectionStatus"), 1); // passes nTPC crossed rows - // registry.fill(HIST("hMassXi1"), casc.mXi(), casc.pt()); + template + int processCandidate(TCascade const& casc, MyCollisions::iterator const& collision) + { + // these are the tracks: + auto bachTrack = casc.template bachelor_as(); + auto posTrack = casc.template posTrack_as(); + auto negTrack = casc.template negTrack_as(); + + // topo variables before cuts: + registry.fill(HIST("hV0Radius"), casc.v0radius(), casc.mXi(), casc.pt()); + registry.fill(HIST("hCascRadius"), casc.cascradius(), casc.mXi(), casc.pt()); + registry.fill(HIST("hV0CosPA"), casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()), casc.mXi(), casc.pt()); + registry.fill(HIST("hCascCosPA"), casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()), casc.mXi(), casc.pt()); + registry.fill(HIST("hDCAPosToPV"), casc.dcapostopv(), casc.mXi(), casc.pt()); + registry.fill(HIST("hDCANegToPV"), casc.dcanegtopv(), casc.mXi(), casc.pt()); + registry.fill(HIST("hDCABachToPV"), casc.dcabachtopv(), casc.mXi(), casc.pt()); + registry.fill(HIST("hDCAV0ToPV"), casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ()), casc.mXi(), casc.pt()); + registry.fill(HIST("hDCAV0Dau"), casc.dcaV0daughters(), casc.mXi(), casc.pt()); + registry.fill(HIST("hDCACascDau"), casc.dcacascdaughters(), casc.mXi(), casc.pt()); + registry.fill(HIST("hLambdaMass"), casc.mLambda(), casc.mXi(), casc.pt()); + + registry.fill(HIST("hITSnClustersPos"), posTrack.itsNCls(), casc.mXi(), casc.pt()); + registry.fill(HIST("hITSnClustersNeg"), negTrack.itsNCls(), casc.mXi(), casc.pt()); + registry.fill(HIST("hITSnClustersBach"), bachTrack.itsNCls(), casc.mXi(), casc.pt()); + registry.fill(HIST("hTPCnCrossedRowsPos"), posTrack.tpcNClsCrossedRows(), casc.mXi(), casc.pt()); + registry.fill(HIST("hTPCnCrossedRowsNeg"), negTrack.tpcNClsCrossedRows(), casc.mXi(), casc.pt()); + registry.fill(HIST("hTPCnCrossedRowsBach"), bachTrack.tpcNClsCrossedRows(), casc.mXi(), casc.pt()); + + registry.fill(HIST("hSelectionStatus"), 0); // all the cascade before selections + // registry.fill(HIST("hMassXi0"), casc.mXi(), casc.pt()); + + // TPC N crossed rows todo: check if minTPCCrossedRows > 50 + if (posTrack.tpcNClsCrossedRows() < minTPCCrossedRows || negTrack.tpcNClsCrossedRows() < minTPCCrossedRows || bachTrack.tpcNClsCrossedRows() < minTPCCrossedRows) + return 0; - // ITS N clusters todo: check if minITSClusters > 0 - if (posTrack.itsNCls() < minITSClusters || negTrack.itsNCls() < minITSClusters || bachTrack.itsNCls() < minITSClusters) { - cascflags(0); - continue; - } - registry.fill(HIST("hSelectionStatus"), 2); // passes nITS clusters - // registry.fill(HIST("hMassXi2"), casc.mXi(), casc.pt()); - - //// TOPO CUTS //// TODO: improve! - double pvx = collision.posX(); - double pvy = collision.posY(); - double pvz = collision.posZ(); - if (casc.v0radius() < v0setting_radius || - casc.cascradius() < cascadesetting_cascradius || - casc.v0cosPA(pvx, pvy, pvz) < v0setting_cospa || - casc.casccosPA(pvx, pvy, pvz) < cascadesetting_cospa || - casc.dcav0topv(pvx, pvy, pvz) < cascadesetting_mindcav0topv || - TMath::Abs(casc.mLambda() - 1.115683) > cascadesetting_v0masswindow) { - // It failed at least one topo selection - cascflags(0); - continue; - } - registry.fill(HIST("hSelectionStatus"), 3); // passes topo - // registry.fill(HIST("hMassXi3"), casc.mXi(), casc.pt()); + registry.fill(HIST("hSelectionStatus"), 1); // passes nTPC crossed rows + // registry.fill(HIST("hMassXi1"), casc.mXi(), casc.pt()); - if (TMath::Abs(posTrack.eta()) > etaTracks || TMath::Abs(negTrack.eta()) > etaTracks || TMath::Abs(bachTrack.eta()) > etaTracks) { - cascflags(0); - continue; - } - registry.fill(HIST("hSelectionStatus"), 4); // passes track eta + // ITS N clusters todo: check if minITSClusters > 0 + if (posTrack.itsNCls() < minITSClusters || negTrack.itsNCls() < minITSClusters || bachTrack.itsNCls() < minITSClusters) + return 0; - if (TMath::Abs(casc.eta()) > etaCascades) { - cascflags(0); - continue; - } - registry.fill(HIST("hSelectionStatus"), 5); // passes candidate eta + registry.fill(HIST("hSelectionStatus"), 2); // passes nITS clusters + // registry.fill(HIST("hMassXi2"), casc.mXi(), casc.pt()); + + //// TOPO CUTS //// TODO: improve! + double pvx = collision.posX(); + double pvy = collision.posY(); + double pvz = collision.posZ(); + if (casc.v0radius() < v0setting_radius || + casc.cascradius() < cascadesetting_cascradius || + casc.v0cosPA(pvx, pvy, pvz) < v0setting_cospa || + casc.casccosPA(pvx, pvy, pvz) < cascadesetting_cospa || + casc.dcav0topv(pvx, pvy, pvz) < cascadesetting_mindcav0topv || + TMath::Abs(casc.mLambda() - 1.115683) > cascadesetting_v0masswindow) + return 0; // It failed at least one topo selection + + registry.fill(HIST("hSelectionStatus"), 3); // passes topo + // registry.fill(HIST("hMassXi3"), casc.mXi(), casc.pt()); + + if (TMath::Abs(posTrack.eta()) > etaTracks || TMath::Abs(negTrack.eta()) > etaTracks || TMath::Abs(bachTrack.eta()) > etaTracks) + return 0; - // TODO: TOF (for pT > 2 GeV per track?) + registry.fill(HIST("hSelectionStatus"), 4); // passes track eta - //// TPC PID //// - // Lambda check - if (casc.sign() < 0) { - // Proton check: - if (TMath::Abs(posTrack.tpcNSigmaPr()) > tpcNsigmaProton) { - cascflags(0); - continue; - } - // Pion check: - if (TMath::Abs(negTrack.tpcNSigmaPi()) > tpcNsigmaPion) { - cascflags(0); - continue; - } - } else { - // Proton check: - if (TMath::Abs(negTrack.tpcNSigmaPr()) > tpcNsigmaProton) { - cascflags(0); - continue; - } - // Pion check: - if (TMath::Abs(posTrack.tpcNSigmaPi()) > tpcNsigmaPion) { - cascflags(0); - continue; - } - } - registry.fill(HIST("hSelectionStatus"), 6); // passes V0 daughters PID - // registry.fill(HIST("hMassXi4"), casc.mXi(), casc.pt()); - - // Bachelor check - if (TMath::Abs(bachTrack.tpcNSigmaPi()) < tpcNsigmaBachelor) { - if (TMath::Abs(bachTrack.tpcNSigmaKa()) < tpcNsigmaBachelor) { - // consistent with both! - cascflags(2); - registry.fill(HIST("hSelectionStatus"), 7); // passes bach PID - // registry.fill(HIST("hMassXi5"), casc.mXi(), casc.pt()); - if (casc.sign() < 0) { - registry.fill(HIST("hMassXiMinus"), casc.mXi(), casc.pt(), casc.yXi()); - registry.fill(HIST("hMassOmegaMinus"), casc.mOmega(), casc.pt(), casc.yOmega()); - } else { - registry.fill(HIST("hMassXiPlus"), casc.mXi(), casc.pt(), casc.yXi()); - registry.fill(HIST("hMassOmegaPlus"), casc.mOmega(), casc.pt(), casc.yOmega()); - } - continue; - } - cascflags(1); + if (TMath::Abs(casc.eta()) > etaCascades) + return 0; + + registry.fill(HIST("hSelectionStatus"), 5); // passes candidate eta + + // TODO: TOF (for pT > 2 GeV per track?) + + //// TPC PID //// + // Lambda check + if (casc.sign() < 0) { + // Proton check: + if (TMath::Abs(posTrack.tpcNSigmaPr()) > tpcNsigmaProton) + return 0; + // Pion check: + if (TMath::Abs(negTrack.tpcNSigmaPi()) > tpcNsigmaPion) + return 0; + } else { + // Proton check: + if (TMath::Abs(negTrack.tpcNSigmaPr()) > tpcNsigmaProton) + return 0; + // Pion check: + if (TMath::Abs(posTrack.tpcNSigmaPi()) > tpcNsigmaPion) + return 0; + } + registry.fill(HIST("hSelectionStatus"), 6); // passes V0 daughters PID + // registry.fill(HIST("hMassXi4"), casc.mXi(), casc.pt()); + + // Bachelor check + if (TMath::Abs(bachTrack.tpcNSigmaPi()) < tpcNsigmaBachelor) { + if (TMath::Abs(bachTrack.tpcNSigmaKa()) < tpcNsigmaBachelor) { + // consistent with both! registry.fill(HIST("hSelectionStatus"), 7); // passes bach PID // registry.fill(HIST("hMassXi5"), casc.mXi(), casc.pt()); if (casc.sign() < 0) { registry.fill(HIST("hMassXiMinus"), casc.mXi(), casc.pt(), casc.yXi()); - } else { - registry.fill(HIST("hMassXiPlus"), casc.mXi(), casc.pt(), casc.yXi()); - } - continue; - } else if (TMath::Abs(bachTrack.tpcNSigmaKa()) < tpcNsigmaBachelor) { - cascflags(3); - registry.fill(HIST("hSelectionStatus"), 7); // passes bach PID - if (casc.sign() < 0) { registry.fill(HIST("hMassOmegaMinus"), casc.mOmega(), casc.pt(), casc.yOmega()); } else { + registry.fill(HIST("hMassXiPlus"), casc.mXi(), casc.pt(), casc.yXi()); registry.fill(HIST("hMassOmegaPlus"), casc.mOmega(), casc.pt(), casc.yOmega()); } + return 2; + } + registry.fill(HIST("hSelectionStatus"), 7); // passes bach PID + // registry.fill(HIST("hMassXi5"), casc.mXi(), casc.pt()); + if (casc.sign() < 0) { + registry.fill(HIST("hMassXiMinus"), casc.mXi(), casc.pt(), casc.yXi()); + } else { + registry.fill(HIST("hMassXiPlus"), casc.mXi(), casc.pt(), casc.yXi()); + } + return 1; + } else if (TMath::Abs(bachTrack.tpcNSigmaKa()) < tpcNsigmaBachelor) { + registry.fill(HIST("hSelectionStatus"), 7); // passes bach PID + if (casc.sign() < 0) { + registry.fill(HIST("hMassOmegaMinus"), casc.mOmega(), casc.pt(), casc.yOmega()); + } else { + registry.fill(HIST("hMassOmegaPlus"), casc.mOmega(), casc.pt(), casc.yOmega()); + } + return 3; + } + // if we reach here, the bachelor was neither pion nor kaon + return 0; + } // processCandidate + + void processGenMC(aod::McCollision const&, soa::SmallGroups> const&, aod::McParticles const& mcParticles) + { + for (auto const& mcPart : mcParticles) { + if (!mcPart.isPhysicalPrimary()) + continue; + if (TMath::Abs(mcPart.eta()) > etaCascades) + continue; + + switch (mcPart.pdgCode()) { + case 3312: + registry.fill(HIST("gen/hXiMinus"), mcPart.pt(), mcPart.y()); + break; + case -3312: + registry.fill(HIST("gen/hXiPlus"), mcPart.pt(), mcPart.y()); + break; + case 3334: + registry.fill(HIST("gen/hOmegaMinus"), mcPart.pt(), mcPart.y()); + break; + case -3334: + registry.fill(HIST("gen/hOmegaPlus"), mcPart.pt(), mcPart.y()); + break; + } + } + + // if (matchedCollisions.size() < 1) { + // return; + // } else if (matchedCollisions.size() == 1) { + // for (auto const& collision : matchedCollisions) { // not really a loop, as there is only one collision + // } + // } else if (matchedCollisions.size() > 1) { + // registry.fill(HIST("MC/hSplitEvents"), matchedCollisions.size()); + // return; + // } + } // processGen + + // wrappers for data/MC processes on reco level + void processRecData(MyCollisions::iterator const& collision, aod::CascDataExt const& Cascades, FullTracksExtIUWithPID const&, aod::BCsWithTimestamps const&) + { + bool evSel = eventSelection(collision); + // do not skip the collision if event selection fails - this will lead to the cascadeFlag table having less entries than the Cascade table, and therefor not joinable. + for (auto const& casc : Cascades) { + if (!evSel) { + cascflags(0); continue; } - // if we reach here, the bachelor was neither pion nor kaon - cascflags(0); - } // cascade loop - } // process + int flag = processCandidate(casc, collision); + cascflags(flag); + } + } + + void processRecMC(MyCollisions::iterator const& collision, LabeledCascades const& Cascades, FullTracksExtIUWithPID const&, aod::BCsWithTimestamps const&, aod::McParticles const&) + { + bool evSel = eventSelection(collision); + // do not skip the collision if event selection fails - this will lead to the cascadeFlag table having less entries than the Cascade table, and therefor not joinable. + for (auto const& casc : Cascades) { + if (!evSel) { + cascflags(0); + continue; + } + int flag = processCandidate(casc, collision); + cascflags(flag); + // do mc matching here + fillMatchedHistos(casc, flag, collision); // if sign < 0 then pdg > 0 + } + } + + PROCESS_SWITCH(CascadeSelector, processRecData, "Process rec data", true); + PROCESS_SWITCH(CascadeSelector, processRecMC, "Process rec MC", false); + PROCESS_SWITCH(CascadeSelector, processGenMC, "Process gen MC", false); }; // struct struct CascadeCorrelations { @@ -395,14 +527,20 @@ struct CascadeCorrelations { Configurable doTFBorderCut{"doTFBorderCut", true, "Switch to apply TimeframeBorderCut event selection"}; Configurable doSel8{"doSel8", true, "Switch to apply sel8 event selection"}; - AxisSpec invMassAxis = {1000, 1.0f, 2.0f, "Inv. Mass (GeV/c^{2})"}; - AxisSpec deltaPhiAxis = {180, -PIHalf, 3 * PIHalf, "#Delta#varphi"}; // 180 is divisible by 18 (tpc sectors) and 20 (run 2 binning) - AxisSpec deltaYAxis = {40, -2 * maxRapidity, 2 * maxRapidity, "#Delta y"}; // TODO: narrower range? - AxisSpec ptAxis = {150, 0, 15, "#it{p}_{T}"}; - AxisSpec selectionFlagAxis = {4, -0.5f, 3.5f, "Selection flag of casc candidate"}; - AxisSpec vertexAxis = {200, -10.0f, 10.0f, "cm"}; - AxisSpec multiplicityAxis{100, 0, 100, "Multiplicity (MultFT0M?)"}; + ConfigurableAxis radiusAxis = {"radiusAxis", {100, 0.0f, 50.0f}, "cm"}; + ConfigurableAxis cpaAxis = {"cpaAxis", {100, 0.95f, 1.0f}, "CPA"}; + ConfigurableAxis invMassAxis = {"invMassAxis", {1000, 1.0f, 2.0f}, "Inv. Mass (GeV/c^{2})"}; + ConfigurableAxis deltaPhiAxis = {"deltaPhiAxis", {180, -PIHalf, 3 * PIHalf}, "#Delta#varphi"}; // 180 is divisible by 18 (tpc sectors) and 20 (run 2 binning) + ConfigurableAxis ptAxis = {"ptAxis", {150, 0, 15}, "#it{p}_{T}"}; + ConfigurableAxis vertexAxis = {"vertexAxis", {200, -10.0f, 10.0f}, "cm"}; + ConfigurableAxis dcaAxis = {"dcaAxis", {100, 0.0f, 2.0f}, "cm"}; + ConfigurableAxis multiplicityAxis{"multiplicityAxis", {100, 0, 100}, "Multiplicity (MultFT0M?)"}; + ConfigurableAxis invLambdaMassAxis{"invLambdaMassAxis", {100, 1.07f, 1.17f}, "Inv. Mass (GeV/c^{2})"}; + AxisSpec deltaYAxis{40, -2 * maxRapidity, 2 * maxRapidity, "#Delta y"}; AxisSpec rapidityAxis{100, -maxRapidity, maxRapidity, "y"}; + AxisSpec selectionFlagAxis{4, -0.5f, 3.5f, "Selection flag of casc candidate"}; + AxisSpec itsClustersAxis{8, -0.5, 7.5, "number of ITS clusters"}; + AxisSpec tpcRowsAxis{160, -0.5, 159.5, "TPC crossed rows"}; // initialize efficiency maps TH1D* hEffXiMin; @@ -460,18 +598,24 @@ struct CascadeCorrelations { // trigger QA {"hTriggerQA", "hTriggerQA", {HistType::kTH1F, {{2, -0.5, 1.5, "Trigger y/n"}}}}, - // basic selection variables - {"hV0Radius", "hV0Radius", {HistType::kTH1F, {{1000, 0.0f, 100.0f, "cm"}}}}, - {"hCascRadius", "hCascRadius", {HistType::kTH1F, {{1000, 0.0f, 100.0f, "cm"}}}}, - {"hV0CosPA", "hV0CosPA", {HistType::kTH1F, {{100, 0.95f, 1.0f}}}}, - {"hCascCosPA", "hCascCosPA", {HistType::kTH1F, {{100, 0.95f, 1.0f}}}}, + // basic selection variables (after cuts) + {"hV0Radius", "hV0Radius", {HistType::kTH1F, {radiusAxis}}}, + {"hCascRadius", "hCascRadius", {HistType::kTH1F, {radiusAxis}}}, + {"hV0CosPA", "hV0CosPA", {HistType::kTH1F, {cpaAxis}}}, + {"hCascCosPA", "hCascCosPA", {HistType::kTH1F, {cpaAxis}}}, {"hDCAPosToPV", "hDCAPosToPV", {HistType::kTH1F, {vertexAxis}}}, {"hDCANegToPV", "hDCANegToPV", {HistType::kTH1F, {vertexAxis}}}, {"hDCABachToPV", "hDCABachToPV", {HistType::kTH1F, {vertexAxis}}}, {"hDCAV0ToPV", "hDCAV0ToPV", {HistType::kTH1F, {vertexAxis}}}, - {"hDCAV0Dau", "hDCAV0Dau", {HistType::kTH1F, {{100, 0.0f, 10.0f, "cm^{2}"}}}}, - {"hDCACascDau", "hDCACascDau", {HistType::kTH1F, {{100, 0.0f, 10.0f, "cm^{2}"}}}}, - {"hLambdaMass", "hLambdaMass", {HistType::kTH1F, {{500, 1.0f, 1.5f, "Inv. Mass (GeV/c^{2})"}}}}, + {"hDCAV0Dau", "hDCAV0Dau", {HistType::kTH1F, {dcaAxis}}}, + {"hDCACascDau", "hDCACascDau", {HistType::kTH1F, {dcaAxis}}}, + {"hLambdaMass", "hLambdaMass", {HistType::kTH1F, {invLambdaMassAxis}}}, + {"hTPCnCrossedRowsPos", "hTPCnCrossedRowsPos", {HistType::kTH1F, {tpcRowsAxis}}}, + {"hTPCnCrossedRowsNeg", "hTPCnCrossedRowsNeg", {HistType::kTH1F, {tpcRowsAxis}}}, + {"hTPCnCrossedRowsBach", "hTPCnCrossedRowsBach", {HistType::kTH1F, {tpcRowsAxis}}}, + {"hITSnClustersPos", "hITSnClustersPos", {HistType::kTH1F, {itsClustersAxis}}}, + {"hITSnClustersNeg", "hITSnClustersNeg", {HistType::kTH1F, {itsClustersAxis}}}, + {"hITSnClustersBach", "hITSnClustersBach", {HistType::kTH1F, {itsClustersAxis}}}, {"hSelectionFlag", "hSelectionFlag", {HistType::kTH1I, {selectionFlagAxis}}}, {"hAutoCorrelation", "hAutoCorrelation", {HistType::kTH1I, {{4, -0.5f, 3.5f, "Types of SS autocorrelation"}}}}, @@ -592,6 +736,12 @@ struct CascadeCorrelations { registry.fill(HIST("hDCAV0Dau"), casc.dcaV0daughters()); registry.fill(HIST("hDCACascDau"), casc.dcacascdaughters()); registry.fill(HIST("hLambdaMass"), casc.mLambda()); + registry.fill(HIST("hITSnClustersPos"), casc.posTrack_as().itsNCls()); + registry.fill(HIST("hITSnClustersNeg"), casc.negTrack_as().itsNCls()); + registry.fill(HIST("hITSnClustersBach"), casc.bachelor_as().itsNCls()); + registry.fill(HIST("hTPCnCrossedRowsPos"), casc.posTrack_as().tpcNClsCrossedRows()); + registry.fill(HIST("hTPCnCrossedRowsNeg"), casc.negTrack_as().tpcNClsCrossedRows()); + registry.fill(HIST("hTPCnCrossedRowsBach"), casc.bachelor_as().tpcNClsCrossedRows()); registry.fill(HIST("hSelectionFlag"), casc.isSelected()); registry.fill(HIST("hPhi"), casc.phi()); diff --git a/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx b/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx index ab7c0d543bd..f9952efca40 100644 --- a/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx +++ b/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx @@ -581,6 +581,13 @@ struct HStrangeCorrelation { hEfficiencyV0[0] = hEfficiencyK0Short; hEfficiencyV0[1] = hEfficiencyLambda; hEfficiencyV0[2] = hEfficiencyAntiLambda; + + float etaWeight = 1; + if (systCuts.doOnTheFlyFlattening) { + float preWeight = 1 - std::abs(deltaeta) / 1.6; + etaWeight = preWeight != 0 ? 1.0f / preWeight : 0.0f; + } + static_for<0, 2>([&](auto i) { constexpr int Index = i.value; float efficiency = 1.0f; @@ -595,6 +602,7 @@ struct HStrangeCorrelation { } float weight = (applyEfficiencyCorrection || applyEfficiencyForTrigger) ? 1. / efficiency : 1.0f; + weight = weight * etaWeight; if (TESTBIT(doCorrelation, Index) && (!applyEfficiencyCorrection || efficiency != 0) && (doPPAnalysis || (TESTBIT(selMap, Index) && TESTBIT(selMap, Index + 3)))) { if (assocCandidate.compatible(Index, systCuts.dEdxCompatibility) && (!doMCassociation || assocCandidate.mcTrue(Index)) && (!doAssocPhysicalPrimary || assocCandidate.mcPhysicalPrimary()) && !mixing && -massWindowConfigurations.maxBgNSigma < assocCandidate.invMassNSigma(Index) && assocCandidate.invMassNSigma(Index) < -massWindowConfigurations.minBgNSigma) histos.fill(HIST("sameEvent/LeftBg/") + HIST(kV0names[Index]), deltaphi, deltaeta, ptassoc, pttrigger, pvz, mult, weight); @@ -703,6 +711,12 @@ struct HStrangeCorrelation { hEfficiencyCascade[2] = hEfficiencyOmegaMinus; hEfficiencyCascade[3] = hEfficiencyOmegaPlus; + float etaWeight = 1; + if (systCuts.doOnTheFlyFlattening) { + float preWeight = 1 - std::abs(deltaeta) / 1.6; + etaWeight = preWeight != 0 ? 1.0f / preWeight : 0.0f; + } + static_for<0, 3>([&](auto i) { constexpr int Index = i.value; float efficiency = 1.0f; @@ -716,6 +730,7 @@ struct HStrangeCorrelation { efficiency = 1; } float weight = (applyEfficiencyCorrection || applyEfficiencyForTrigger) ? 1. / efficiency : 1.0f; + weight = weight * etaWeight; if (TESTBIT(doCorrelation, Index + 3) && (!applyEfficiencyCorrection || efficiency != 0) && (doPPAnalysis || (TESTBIT(CascselMap, Index) && TESTBIT(CascselMap, Index + 4) && TESTBIT(CascselMap, Index + 8) && TESTBIT(CascselMap, Index + 12)))) { if (assocCandidate.compatible(Index, systCuts.dEdxCompatibility) && (!doMCassociation || assocCandidate.mcTrue(Index)) && (!doAssocPhysicalPrimary || assocCandidate.mcPhysicalPrimary()) && !mixing && -massWindowConfigurations.maxBgNSigma < assocCandidate.invMassNSigma(Index) && assocCandidate.invMassNSigma(Index) < -massWindowConfigurations.minBgNSigma) histos.fill(HIST("sameEvent/LeftBg/") + HIST(kCascadenames[Index]), deltaphi, deltaeta, ptassoc, pttrigger, pvz, mult, weight); @@ -1094,8 +1109,8 @@ struct HStrangeCorrelation { if (TESTBIT(doCorrelation, 8)) { histos.add("hAsssocTrackEtaVsPtVsPhi", "", kTH3F, {axisPtQA, axisEta, axisPhi}); - histos.add("hAssocPrimaryEtaVsPt", "", kTH3F, {axisPtQA, axisEta, axisMultNDim}); - histos.add("hAssocHadronsAllSelectedEtaVsPt", "", kTH3F, {axisPtQA, axisEta, axisMultNDim}); + histos.add("hAssocPrimaryEtaVsPt", "", kTH3F, {axisPtQA, axisEta, axisMult}); + histos.add("hAssocHadronsAllSelectedEtaVsPt", "", kTH3F, {axisPtQA, axisEta, axisMult}); histos.add("hAssocPtResolution", ";p_{T}^{reconstructed} (GeV/c); p_{T}^{generated} (GeV/c)", kTH2F, {axisPtQA, axisPtQA}); } diff --git a/PWGLF/Tasks/Strangeness/lambdaJetpolarization.cxx b/PWGLF/Tasks/Strangeness/lambdaJetpolarization.cxx index 93c0b4381dc..62420403d65 100644 --- a/PWGLF/Tasks/Strangeness/lambdaJetpolarization.cxx +++ b/PWGLF/Tasks/Strangeness/lambdaJetpolarization.cxx @@ -11,37 +11,46 @@ /// /// \author Youpeng Su (yousu@cern.ch) -#include -#include -#include -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Common/DataModel/EventSelection.h" +#include "PWGLF/DataModel/lambdaJetpolarization.h" + +#include "PWGJE/Core/JetBkgSubUtils.h" +#include "PWGJE/Core/JetDerivedDataUtilities.h" +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetReducedData.h" #include "PWGLF/DataModel/LFStrangenessTables.h" + +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponse.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include + #include "Framework/ASoA.h" #include "Framework/AnalysisDataModel.h" -#include +#include "Framework/AnalysisTask.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" + +#include "Math/GenVector/Boost.h" +#include "Math/Vector3D.h" +#include "Math/Vector4D.h" +#include "TProfile2D.h" #include +#include #include -#include "PWGLF/DataModel/lambdaJetpolarization.h" +#include +#include #include #include +#include +#include +#include #include #include -#include -#include -#include -#include -#include "PWGJE/Core/JetBkgSubUtils.h" -#include "PWGJE/Core/JetDerivedDataUtilities.h" -#include "PWGJE/DataModel/JetReducedData.h" -#include "PWGJE/DataModel/Jet.h" -#include "Common/Core/trackUtilities.h" + +#include +#include +#include +#include using std::cout; using std::endl; @@ -53,13 +62,13 @@ struct LfMyV0s { HistogramRegistry registry{"registry"}; HistogramRegistry registryData{"registryData", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; HistogramRegistry registryV0Data{"registryV0Data", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry registryLongitudinalPolarization{"registryLongitudinalPolarization", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; Configurable zVtx{"zVtx", 10.0, "Maximum zVertex"}; Configurable rJet{"rJet", 0.4, "Jet resolution parameter R"}; Configurable etaMin{"etaMin", -0.9f, "eta min"}; Configurable etaMax{"etaMax", +0.9f, "eta max"}; Configurable deltaEtaEdge{"deltaEtaEdge", 0.00, "eta gap from the edge"}; - Configurable minJetPt{"minJetPt", 10.0, "Minimum pt of the jet"}; // track parameters Configurable minITSnCls{"minITSnCls", 4.0f, "min number of ITS clusters"}; Configurable minTPCnClsFound{"minTPCnClsFound", 80.0f, "min number of found TPC clusters"}; @@ -94,13 +103,13 @@ struct LfMyV0s { Configurable ispassdTrackSelectionForJetReconstruction{"ispassdTrackSelectionForJetReconstruction", 1, "do track selection"}; // v0Event selection - Configurable sel8{"sel8", 0, "Apply sel8 event selection"}; + Configurable sel8{"sel8", 1, "Apply sel8 event selection"}; Configurable isTriggerTVX{"isTriggerTVX", 1, "TVX trigger"}; Configurable iscutzvertex{"iscutzvertex", 1, "Accepted z-vertex range (cm)"}; Configurable isNoTimeFrameBorder{"isNoTimeFrameBorder", 1, "TF border cut"}; Configurable isNoITSROFrameBorder{"isNoITSROFrameBorder", 1, "ITS ROF border cut"}; Configurable isVertexTOFmatched{"isVertexTOFmatched", 1, "Is Vertex TOF matched"}; - Configurable isGoodZvtxFT0vsPV{"isGoodZvtxFT0vsPV", 0, "isGoodZvtxFT0vsPV"}; + Configurable isGoodZvtxFT0vsPV{"isGoodZvtxFT0vsPV", 1, "isGoodZvtxFT0vsPV"}; Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; Configurable CtauLambda{"ctauLambda", 30, "C tau Lambda (cm)"}; Configurable requirepassedSingleTrackSelection{"requirepassedSingleTrackSelection", false, "requirepassedSingleTrackSelection"}; @@ -111,8 +120,11 @@ struct LfMyV0s { Configurable yMax{"V0yMax", +0.5f, "maximum y"}; Configurable v0rejLambda{"v0rejLambda", 0.01, "V0 rej Lambda"}; Configurable v0accLambda{"v0accLambda", 0.075, "V0 acc Lambda"}; - Configurable ifinitpasslambda{"ifinitpasslambda", 1, "ifinitpasslambda"}; - Configurable ifpasslambda{"passedLambdaSelection", 0, "passedLambdaSelection"}; + Configurable ifinitpasslambda{"ifinitpasslambda", 0, "ifinitpasslambda"}; + Configurable ifpasslambda{"passedLambdaSelection", 1, "passedLambdaSelection"}; + Configurable paramArmenterosCut{"paramArmenterosCut", 0.2, "parameter Armenteros Cut"}; + Configurable doArmenterosCut{"doArmenterosCut", 0, "do Armenteros Cut"}; + Configurable noSameBunchPileUp{"noSameBunchPileUp", true, "reject SameBunchPileUp"}; // Jet background subtraction JetBkgSubUtils backgroundSub; @@ -131,6 +143,9 @@ struct LfMyV0s { const AxisSpec ptAxis{100, 0.0f, 10.0f, "#it{p}_{T} (GeV/#it{c})"}; const AxisSpec invMassLambdaAxis{200, 1.09, 1.14, "m_{p#pi} (GeV/#it{c}^{2})"}; + ConfigurableAxis TProfile2DaxisPt{"#it{p}_{T} (GeV/#it{c})", {VARIABLE_WIDTH, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.2, 3.7, 4.2, 5, 6, 8, 10, 12}, "pt axis for histograms"}; + ConfigurableAxis TProfile2DaxisMass{"Mass p#pi (GeV/#it{c^{2}})", {VARIABLE_WIDTH, 1.10068, 1.10668, 1.11068, 1.11268, 1.11368, 1.11468, 1.11568, 1.11668, 1.11768, 1.11868, 1.12068, 1.12468, 1.13068}, "Mass axis for histograms"}; + registry.add("hMassLambda", "hMassLambda", {HistType::kTH1F, {{200, 0.9f, 1.2f}}}); registry.add("V0pTInLab", "V0pTInLab", kTH1F, {axisPT}); registry.add("hMassVsPtLambda", "hMassVsPtLambda", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {200, 1.016f, 1.216f}}}); @@ -212,6 +227,7 @@ struct LfMyV0s { registryData.add("AntiLambdaPtMass", "AntiLambdaPtMass", HistType::kTH2F, {ptAxis, invMassLambdaAxis}); registryData.add("hMassLambda", "hMassLambda", {HistType::kTH1F, {{200, 0.9f, 1.2f}}}); + registryData.add("hMassAntiLambda", "hMassAntiLambda", {HistType::kTH1F, {{200, 0.9f, 1.2f}}}); registryData.add("V0pTInLab", "V0pTInLab", kTH1F, {axisPT}); registryData.add("V0pxInLab", "V0pxInLab", kTH1F, {axisPx}); @@ -245,6 +261,17 @@ struct LfMyV0s { registryData.add("hLambdaPhiandSinPhi", "hLambdaPhiandSinPhi", kTH2F, {{200, -TMath::Pi() / 2, TMath::Pi() / 2}, {200, -1, 1}}); registryData.add("V0LambdaprotonPhi", "V0LambdaprotonPhi", {HistType::kTH1F, {{200, -TMath::Pi() / 2, TMath::Pi() / 2}}}); + registryData.add("profileAntiLambda", "Invariant Mass vs sin(phi)", {HistType::kTProfile, {{200, 0.9, 1.2}}}); + registryData.add("hAntiLambdamassandSinPhi", "hAntiLambdaPhiandSinPhi", kTH2F, {{200, -TMath::Pi() / 2, TMath::Pi() / 2}, {200, -1, 1}}); + + registryData.add("TProfile2DLambdaPtMassSinPhi", "", kTProfile2D, {TProfile2DaxisMass, TProfile2DaxisPt}); + registryData.add("TProfile2DAntiLambdaPtMassSinPhi", "", kTProfile2D, {TProfile2DaxisMass, TProfile2DaxisPt}); + registryData.add("TProfile2DLambdaPtMassSintheta", "", kTProfile2D, {TProfile2DaxisMass, TProfile2DaxisPt}); + registryData.add("TProfile2DAntiLambdaPtMassSintheta", "", kTProfile2D, {TProfile2DaxisMass, TProfile2DaxisPt}); + + registryData.add("TProfile2DLambdaPtMassCosSquareTheta", "", kTProfile2D, {TProfile2DaxisMass, TProfile2DaxisPt}); + registryData.add("TProfile2DAntiLambdaPtMassCosSquareTheta", "", kTProfile2D, {TProfile2DaxisMass, TProfile2DaxisPt}); + registryData.add("hNEvents", "hNEvents", {HistType::kTH1I, {{10, 0.f, 10.f}}}); registryData.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(1, "all"); registryData.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(2, "sel8"); @@ -295,9 +322,45 @@ struct LfMyV0s { registryV0Data.add("AverageSinthetainJetV0", "AverageSinthetainJetV0", {HistType::kTProfile, {{200, 0.9, 1.2}}}); registryV0Data.add("AverageCosSquarethetainJetV0", "AverageCosSquarethetainJetV0", {HistType::kTProfile, {{200, 0.9, 1.2}}}); + + // LongitudinalPolarization event selection + registryLongitudinalPolarization.add("hNEvents", "hNEvents", {HistType::kTH1I, {{5, 0.f, 5.f}}}); + registryLongitudinalPolarization.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(1, "all"); + registryLongitudinalPolarization.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(2, "sel8"); + registryLongitudinalPolarization.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(3, "zvertex"); + registryLongitudinalPolarization.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(4, "isGoodZvtxFT0vsPV"); + registryLongitudinalPolarization.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(5, "isNoSameBunchPileup"); + registryLongitudinalPolarization.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(6, "Applied selected"); + + registryLongitudinalPolarization.add("hMassVsPtLambda", "hMassVsPtLambda", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {200, 1.016f, 1.216f}}}); + registryLongitudinalPolarization.add("hMassVsPtAntiLambda", "hMassVsPtAntiLambda", {HistType::kTH2F, {{100, 0.0f, 10.0f}, {200, 1.016f, 1.216f}}}); + + registryLongitudinalPolarization.add("V0pxInRest_frame", "V0pxInRest_frame", kTH1F, {axisPx}); + registryLongitudinalPolarization.add("V0pyInRest_frame", "V0pyInRest_frame", kTH1F, {axisPy}); + registryLongitudinalPolarization.add("V0pzInRest_frame", "V0pzInRest_frame", kTH1F, {axisPz}); + + registryLongitudinalPolarization.add("nV0sPerEvent", "nV0sPerEvent", kTH1F, {{10, 0.0, 10.0}}); + registryLongitudinalPolarization.add("nV0sPerEventsel", "nV0sPerEventsel", kTH1F, {{10, 0.0, 10.0}}); + + registryLongitudinalPolarization.add("hprotoncosthetainV0", "hprotoncosthetainV0", kTH1F, {{200, -1.f, 1.f}}); + registryLongitudinalPolarization.add("hprotoncosSquarethetainV0", "hprotoncosSquarethetainV0", kTH1F, {{200, -1.f, 1.f}}); + registryLongitudinalPolarization.add("hLambdamassandCosthetaInV0", "hLambdamassandCosthetaInV0", kTH2F, {{200, 0.9, 1.2}, {200, -1, 1}}); + registryLongitudinalPolarization.add("TProfile2DLambdaPtMassCostheta", "", kTProfile2D, {TProfile2DaxisMass, TProfile2DaxisPt}); + registryLongitudinalPolarization.add("TProfile2DLambdaPtMassCosSquareTheta", "", kTProfile2D, {TProfile2DaxisMass, TProfile2DaxisPt}); + + registryLongitudinalPolarization.add("hantiprotoncosthetainV0", "hantiprotoncosthetainV0", kTH1F, {{200, -1.f, 1.f}}); + registryLongitudinalPolarization.add("hantiprotoncosSquarethetainV0", "hantiprotoncosSquarethetainV0", kTH1F, {{200, -1.f, 1.f}}); + registryLongitudinalPolarization.add("hAntiLambdamassandCosthetaInV0", "hAntiLambdamassandCosthetaInV0", kTH2F, {{200, 0.9, 1.2}, {200, -1, 1}}); + registryLongitudinalPolarization.add("TProfile2DAntiLambdaPtMassCostheta", "TProfile2DAntiLambdaPtMassCostheta", kTProfile2D, {TProfile2DaxisMass, TProfile2DaxisPt}); + registryLongitudinalPolarization.add("TProfile2DAntiLambdaPtMassCosSquareTheta", "TProfile2DAntiLambdaPtMassCosSquareTheta", kTProfile2D, {TProfile2DaxisMass, TProfile2DaxisPt}); + + registryLongitudinalPolarization.add("TProfile1DLambdaPtMassCostheta", "Invariant Mass vs cos(#theta)", {HistType::kTProfile, {{200, 0.9, 1.2}}}); + registryLongitudinalPolarization.add("TProfile1DAntiLambdaPtMassCostheta", "Invariant Mass vs cos(#theta)", {HistType::kTProfile, {{200, 0.9, 1.2}}}); } double massPr = o2::constants::physics::MassProton; double massLambda = o2::constants::physics::MassLambda; + double massPi = o2::constants::physics::MassPionCharged; + ROOT::Math::PxPyPzMVector ProtonVec, PionVec, LambdaVec, ProtonBoostedVec, LambdaBoostedVec; TMatrixD LorentzTransInV0frame(double ELambda, double Lambdapx, double Lambdapy, double Lambdapz) { @@ -655,6 +718,9 @@ struct LfMyV0s { if (TMath::Abs(v0.mLambda() - o2::constants::physics::MassLambda0) > v0accLambda) { return false; } + if (doArmenterosCut && v0.qtarm() > (paramArmenterosCut * std::abs(v0.alpha()))) + return false; + return true; } @@ -723,6 +789,8 @@ struct LfMyV0s { if (TMath::Abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0) > v0accLambda) { return false; } + if (doArmenterosCut && v0.qtarm() > (paramArmenterosCut * std::abs(v0.alpha()))) + return false; return true; } @@ -792,6 +860,32 @@ struct LfMyV0s { return true; } + template + bool AcceptEventForLongitudinalPolarization(TCollision const& collision) + { + if (sel8 && !collision.sel8()) { + return false; + } + registryLongitudinalPolarization.fill(HIST("hNEvents"), 1.5); + + if (iscutzvertex && TMath::Abs(collision.posZ()) > cutzvertex) { + return false; + } + registryLongitudinalPolarization.fill(HIST("hNEvents"), 2.5); + + if (noSameBunchPileUp && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { + return false; + } + registryLongitudinalPolarization.fill(HIST("hNEvents"), 3.5); + // check vertex matching to FT0 + if (isGoodZvtxFT0vsPV && !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { + return false; + } + registryLongitudinalPolarization.fill(HIST("hNEvents"), 4.5); + + return true; + } + using SelCollisions = soa::Join; using StrHadronDaughterTracks = soa::Join; void processData(SelCollisions::iterator const& collision, aod::V0Datas const& fullV0s, StrHadronDaughterTracks const& tracks) @@ -890,6 +984,7 @@ struct LfMyV0s { registryData.fill(HIST("number_of_events_vsmultiplicity"), multiplicity); // v0 loop int V0Numbers = 0; + int AntiV0Numbers = 0; for (const auto& v0 : fullV0s) { const auto& pos = v0.posTrack_as(); const auto& neg = v0.negTrack_as(); @@ -899,6 +994,7 @@ struct LfMyV0s { registryData.fill(HIST("LambdaPtMass"), v0.pt(), v0.mLambda()); } if (passedAntiLambdaSelection(v0, pos, neg)) { + AntiV0Numbers = AntiV0Numbers + 1; registryData.fill(HIST("AntiLambdaPtMass"), v0.pt(), v0.mAntiLambda()); } } @@ -913,6 +1009,7 @@ struct LfMyV0s { return; } double protonsinPhiInJetV0frame = 0; + double AntiprotonsinPhiInJetV0frame = 0; cout << maxJetpx << endl; for (const auto& candidate : fullV0s) { const auto& pos = candidate.posTrack_as(); @@ -982,7 +1079,7 @@ struct LfMyV0s { double protonPinJetV0 = sqrt(protonInJetV0(1, 0) * protonInJetV0(1, 0) + protonInJetV0(2, 0) * protonInJetV0(2, 0) + protonInJetV0(3, 0) * protonInJetV0(3, 0)); double protonPtinJetV0 = sqrt(protonInJetV0(1, 0) * protonInJetV0(1, 0) + protonInJetV0(2, 0) * protonInJetV0(2, 0)); - double protonCosThetainJetV0 = protonInV0(3, 0) / protonPinJetV0; + double protonCosThetainJetV0 = protonInJetV0(3, 0) / protonPinJetV0; double protonSinThetainJetV0 = protonPtinJetV0 / protonPinJetV0; double protonthetainJetV0 = TMath::ASin(protonSinThetainJetV0); registryV0Data.fill(HIST("hprotoncosthetainJetV0"), protonCosThetainJetV0); @@ -997,6 +1094,42 @@ struct LfMyV0s { registryV0Data.fill(HIST("AverageSinthetainJetV0"), candidate.mLambda(), protonSinThetainJetV0); registryV0Data.fill(HIST("AverageCosSquarethetainJetV0"), candidate.mLambda(), protonCosThetainJetV0 * protonCosThetainJetV0); protonsinPhiInJetV0frame = protonsinPhiInJetV0frame + protonInJetV0(2, 0) / sqrt(protonInJetV0(1, 0) * protonInJetV0(1, 0) + protonInJetV0(2, 0) * protonInJetV0(2, 0)); + + registryData.fill(HIST("TProfile2DLambdaPtMassSinPhi"), candidate.mLambda(), candidate.pt(), protonInJetV0(2, 0) / sqrt(protonInJetV0(1, 0) * protonInJetV0(1, 0) + protonInJetV0(2, 0) * protonInJetV0(2, 0))); + registryData.fill(HIST("TProfile2DLambdaPtMassSintheta"), candidate.mLambda(), candidate.pt(), (4.0 / TMath::Pi()) * protonSinThetainJetV0); + registryData.fill(HIST("TProfile2DLambdaPtMassCosSquareTheta"), candidate.mLambda(), candidate.pt(), 3.0 * protonCosThetainJetV0 * protonCosThetainJetV0); + } + if (passedAntiLambdaSelection(candidate, pos, neg)) { + registryData.fill(HIST("hMassAntiLambda"), candidate.mAntiLambda()); + double PAntiLambda = sqrt(candidate.px() * candidate.px() + candidate.py() * candidate.py() + candidate.pz() * candidate.pz()); + double EAntiLambda = sqrt(candidate.mAntiLambda() * candidate.mAntiLambda() + PAntiLambda * PAntiLambda); + double AntiprotonE = sqrt(massPr * massPr + neg.px() * neg.px() + neg.py() * neg.py() + neg.pz() * neg.pz()); + TMatrixD pLabAntiV0(4, 1); + pLabAntiV0(0, 0) = EAntiLambda; + pLabAntiV0(1, 0) = candidate.px(); + pLabAntiV0(2, 0) = candidate.py(); + pLabAntiV0(3, 0) = candidate.pz(); + + TMatrixD AntilambdaInJet(4, 1); + AntilambdaInJet = MyTMatrixTranslationToJet(maxJetpx, maxJetpy, maxJetpz, candidate.px(), candidate.py(), candidate.pz()) * pLabAntiV0; + + TMatrixD pLabAntiproton(4, 1); + pLabAntiproton(0, 0) = AntiprotonE; + pLabAntiproton(1, 0) = neg.px(); + pLabAntiproton(2, 0) = neg.py(); + pLabAntiproton(3, 0) = neg.pz(); + TMatrixD AntiprotonInJetV0(4, 1); + AntiprotonInJetV0 = LorentzTransInV0frame(EAntiLambda, AntilambdaInJet(1, 0), AntilambdaInJet(2, 0), AntilambdaInJet(3, 0)) * MyTMatrixTranslationToJet(maxJetpx, maxJetpy, maxJetpz, candidate.px(), candidate.py(), candidate.pz()) * pLabAntiproton; + AntiprotonsinPhiInJetV0frame = AntiprotonsinPhiInJetV0frame + AntiprotonInJetV0(2, 0) / sqrt(AntiprotonInJetV0(1, 0) * AntiprotonInJetV0(1, 0) + AntiprotonInJetV0(2, 0) * AntiprotonInJetV0(2, 0)); + TMatrixD AntiprotonInV0(4, 1); + AntiprotonInV0 = LorentzTransInV0frame(EAntiLambda, candidate.px(), candidate.py(), candidate.pz()) * pLabAntiproton; + double AntiprotonPinJetV0 = sqrt(AntiprotonInJetV0(1, 0) * AntiprotonInJetV0(1, 0) + AntiprotonInJetV0(2, 0) * AntiprotonInJetV0(2, 0) + AntiprotonInJetV0(3, 0) * AntiprotonInJetV0(3, 0)); + double AntiprotonPtinJetV0 = sqrt(AntiprotonInJetV0(1, 0) * AntiprotonInJetV0(1, 0) + AntiprotonInJetV0(2, 0) * AntiprotonInJetV0(2, 0)); + double AntiprotonCosThetainJetV0 = AntiprotonInJetV0(3, 0) / AntiprotonPinJetV0; + double AntiprotonSinThetainJetV0 = AntiprotonPtinJetV0 / AntiprotonPinJetV0; + registryData.fill(HIST("TProfile2DAntiLambdaPtMassSinPhi"), candidate.mAntiLambda(), candidate.pt(), AntiprotonInJetV0(2, 0) / sqrt(AntiprotonInJetV0(1, 0) * AntiprotonInJetV0(1, 0) + AntiprotonInJetV0(2, 0) * AntiprotonInJetV0(2, 0))); + registryData.fill(HIST("TProfile2DAntiLambdaPtMassSintheta"), candidate.mAntiLambda(), candidate.pt(), (4.0 / TMath::Pi()) * AntiprotonSinThetainJetV0); + registryData.fill(HIST("TProfile2DAntiLambdaPtMassCosSquareTheta"), candidate.mAntiLambda(), candidate.pt(), 3.0 * AntiprotonCosThetainJetV0 * AntiprotonCosThetainJetV0); } } @@ -1009,6 +1142,10 @@ struct LfMyV0s { registryData.fill(HIST("V0LambdaprotonPhi"), TMath::ASin(protonsinPhiInJetV0frame / V0Numbers)); registryData.fill(HIST("profileLambda"), candidate.mLambda(), protonsinPhiInJetV0frame / V0Numbers); } + if (passedAntiLambdaSelection(candidate, pos, neg)) { + registryData.fill(HIST("hAntiLambdamassandSinPhi"), candidate.mAntiLambda(), AntiprotonsinPhiInJetV0frame / AntiV0Numbers); + registryData.fill(HIST("profileAntiLambda"), candidate.mAntiLambda(), AntiprotonsinPhiInJetV0frame / AntiV0Numbers); + } } } PROCESS_SWITCH(LfMyV0s, processData, "processData", true); @@ -1019,7 +1156,6 @@ struct LfMyV0s { if (!AcceptEvent(collision)) { return; } - registryData.fill(HIST("hNEvents"), 8.5); int V0NumbersPerEvent = 0; int V0NumbersPerEventsel = 0; @@ -1087,6 +1223,76 @@ struct LfMyV0s { registryV0Data.fill(HIST("nV0sPerEventsel"), V0NumbersPerEventsel); } PROCESS_SWITCH(LfMyV0s, processDataV0, "processDataV0", true); + + void processLongitudinalPolarization(SelCollisions::iterator const& collision, aod::V0Datas const& fullV0s, StrHadronDaughterTracks const&) + { + registryLongitudinalPolarization.fill(HIST("hNEvents"), 0.5); + if (!AcceptEventForLongitudinalPolarization(collision)) { + return; + } + registryLongitudinalPolarization.fill(HIST("hNEvents"), 5.5); + int V0NumbersPerEvent = 0; + int V0NumbersPerEventsel = 0; + for (const auto& v0 : fullV0s) { + V0NumbersPerEvent++; + float ctauLambda = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0; + float ctauAntiLambda = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0Bar; + const auto& pos = v0.posTrack_as(); + const auto& neg = v0.negTrack_as(); + + if (passedLambdaSelection(v0, pos, neg) && ctauLambda < CtauLambda && ifpasslambda) { + V0NumbersPerEventsel++; + registryLongitudinalPolarization.fill(HIST("hMassVsPtLambda"), v0.pt(), v0.mLambda()); + + ProtonVec = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), massPr); + PionVec = ROOT::Math::PxPyPzMVector(v0.pxneg(), v0.pyneg(), v0.pzneg(), massPi); + LambdaVec = ProtonVec + PionVec; + LambdaVec.SetM(massLambda); + ROOT::Math::Boost boost{LambdaVec.BoostToCM()}; + ProtonBoostedVec = boost(ProtonVec); + LambdaBoostedVec = boost(LambdaVec); + + registryLongitudinalPolarization.fill(HIST("V0pxInRest_frame"), LambdaBoostedVec.Px()); + registryLongitudinalPolarization.fill(HIST("V0pyInRest_frame"), LambdaBoostedVec.Py()); + registryLongitudinalPolarization.fill(HIST("V0pzInRest_frame"), LambdaBoostedVec.Pz()); + + double protonCosThetainV0 = ProtonBoostedVec.Pz() / ProtonBoostedVec.P(); + + registryLongitudinalPolarization.fill(HIST("hprotoncosthetainV0"), protonCosThetainV0); + registryLongitudinalPolarization.fill(HIST("hprotoncosSquarethetainV0"), protonCosThetainV0 * protonCosThetainV0); + registryLongitudinalPolarization.fill(HIST("hLambdamassandCosthetaInV0"), v0.mLambda(), protonCosThetainV0); + + registryLongitudinalPolarization.fill(HIST("TProfile2DLambdaPtMassCostheta"), v0.mLambda(), v0.pt(), protonCosThetainV0); + registryLongitudinalPolarization.fill(HIST("TProfile2DLambdaPtMassCosSquareTheta"), v0.mLambda(), v0.pt(), protonCosThetainV0 * protonCosThetainV0); + + registryLongitudinalPolarization.fill(HIST("TProfile1DLambdaPtMassCostheta"), v0.mLambda(), protonCosThetainV0); + } + if (passedAntiLambdaSelection(v0, pos, neg) && ctauAntiLambda < CtauLambda && ifpasslambda) { + registryLongitudinalPolarization.fill(HIST("hMassVsPtAntiLambda"), v0.pt(), v0.mAntiLambda()); + + ProtonVec = ROOT::Math::PxPyPzMVector(v0.pxneg(), v0.pyneg(), v0.pzneg(), massPr); + PionVec = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), massPi); + LambdaVec = ProtonVec + PionVec; + LambdaVec.SetM(massLambda); + ROOT::Math::Boost boost{LambdaVec.BoostToCM()}; + ProtonBoostedVec = boost(ProtonVec); + LambdaBoostedVec = boost(LambdaVec); + + double protonCosThetainV0 = ProtonBoostedVec.Pz() / ProtonBoostedVec.P(); + + registryLongitudinalPolarization.fill(HIST("hantiprotoncosthetainV0"), protonCosThetainV0); + registryLongitudinalPolarization.fill(HIST("hantiprotoncosSquarethetainV0"), protonCosThetainV0 * protonCosThetainV0); + registryLongitudinalPolarization.fill(HIST("hAntiLambdamassandCosthetaInV0"), v0.mAntiLambda(), protonCosThetainV0); + + registryLongitudinalPolarization.fill(HIST("TProfile2DAntiLambdaPtMassCostheta"), v0.mAntiLambda(), v0.pt(), protonCosThetainV0); + registryLongitudinalPolarization.fill(HIST("TProfile2DAntiLambdaPtMassCosSquareTheta"), v0.mAntiLambda(), v0.pt(), protonCosThetainV0 * protonCosThetainV0); + registryLongitudinalPolarization.fill(HIST("TProfile1DAntiLambdaPtMassCostheta"), v0.mAntiLambda(), protonCosThetainV0); + } + } + registryLongitudinalPolarization.fill(HIST("nV0sPerEvent"), V0NumbersPerEvent); + registryLongitudinalPolarization.fill(HIST("nV0sPerEventsel"), V0NumbersPerEventsel); + } + PROCESS_SWITCH(LfMyV0s, processLongitudinalPolarization, "processLongitudinalPolarization", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx index 51f6ba34bb2..c5388c034a2 100644 --- a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx +++ b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx @@ -121,8 +121,11 @@ struct NPCascCandidate { bool sel8; float multFT0C; float multFT0A; + float multFT0M; + float centFT0C; + float centFT0A; + float centFT0M; }; - std::array isFromHF(auto& particle) { bool fromBeauty = false; @@ -170,8 +173,8 @@ struct NonPromptCascadeTask { using TracksExtData = soa::Join; using TracksExtMC = soa::Join; - using CollisionCandidatesRun3 = soa::Join; - using CollisionCandidatesRun3MC = soa::Join; + using CollisionCandidatesRun3 = soa::Join; + using CollisionCandidatesRun3MC = soa::Join; Preslice perCollision = aod::track::collisionId; Preslice perCollisionMC = aod::track::collisionId; @@ -192,6 +195,7 @@ struct NonPromptCascadeTask { Configurable cfgMinCosPA{"cfgMinCosPA", -1.f, "Minimum cosine of pointing angle"}; Configurable> cfgCutsPID{"particlesCutsPID", {cutsPID[0], nParticles, nCutsPID, particlesNames, cutsNames}, "Nuclei PID selections"}; Configurable cfgSkimmedProcessing{"cfgSkimmedProcessing", true, "Skimmed dataset processing"}; + Configurable cfgTriggersOfInterest{"cfgTriggersOfInterest", "fTrackedOmega,fOmegaHighMult", "Triggers of interest, comma separated for Zorro"}; Zorro mZorro; OutputObj mZorroSummary{"ZorroSummary"}; @@ -290,7 +294,7 @@ struct NonPromptCascadeTask { for (const auto& coll : collisions) { auto bc = coll.template bc_as(); if (runNumber != bc.runNumber()) { - mZorro.initCCDB(mCCDB.service, bc.runNumber(), bc.timestamp(), "fTrackedOmega"); + mZorro.initCCDB(mCCDB.service, bc.runNumber(), bc.timestamp(), cfgTriggersOfInterest.value); mZorro.populateHistRegistry(mRegistry, bc.runNumber()); runNumber = bc.runNumber(); } @@ -298,7 +302,6 @@ struct NonPromptCascadeTask { } } } - template void fillCandidatesVector(CollisionType const&, TrackType const& tracks, auto const& cascades, auto& candidates) { @@ -514,7 +517,7 @@ struct NonPromptCascadeTask { cascITSclusters, protonTrack.itsNCls(), pionTrack.itsNCls(), bachelor.itsNCls(), protonTrack.tpcNClsFound(), pionTrack.tpcNClsFound(), bachelor.tpcNClsFound(), protonTrack.tpcNSigmaPr(), pionTrack.tpcNSigmaPi(), bachelor.tpcNSigmaKa(), bachelor.tpcNSigmaPi(), protonTrack.hasTOF(), pionTrack.hasTOF(), bachelor.hasTOF(), - protonTrack.tofNSigmaPr(), pionTrack.tofNSigmaPi(), bachelor.tofNSigmaKa(), bachelor.tofNSigmaPi(), collision.sel8(), collision.multFT0C(), collision.multFT0A()}); + protonTrack.tofNSigmaPr(), pionTrack.tofNSigmaPi(), bachelor.tofNSigmaKa(), bachelor.tofNSigmaPi(), collision.sel8(), collision.multFT0C(), collision.multFT0A(), collision.multFT0M(), collision.centFT0C(), collision.centFT0A(), collision.centFT0M()}); } } @@ -534,7 +537,7 @@ struct NonPromptCascadeTask { c.protonTPCNSigma, c.pionTPCNSigma, c.bachKaonTPCNSigma, c.bachPionTPCNSigma, c.protonHasTOF, c.pionHasTOF, c.bachHasTOF, c.protonTOFNSigma, c.pionTOFNSigma, c.bachKaonTOFNSigma, c.bachPionTOFNSigma, - c.sel8, c.multFT0C, c.multFT0A); + c.sel8, c.multFT0C, c.multFT0A, c.multFT0M, c.centFT0C, c.centFT0A, c.centFT0M); } } @@ -570,7 +573,7 @@ struct NonPromptCascadeTask { c.cascNClusITS, c.protonNClusITS, c.pionNClusITS, c.bachNClusITS, c.protonNClusTPC, c.pionNClusTPC, c.bachNClusTPC, c.protonTPCNSigma, c.pionTPCNSigma, c.bachKaonTPCNSigma, c.bachPionTPCNSigma, c.protonHasTOF, c.pionHasTOF, c.bachHasTOF, c.protonTOFNSigma, c.pionTOFNSigma, c.bachKaonTOFNSigma, c.bachPionTOFNSigma, - c.sel8, c.multFT0C, c.multFT0A, + c.sel8, c.multFT0C, c.multFT0A, c.multFT0M, c.centFT0C, c.centFT0A, c.centFT0M, particle.pt(), particle.eta(), particle.phi(), mcCollision.posX(), mcCollision.posY(), mcCollision.posZ(), particle.pdgCode(), mcCollision.posX() - particle.vx(), mcCollision.posY() - particle.vy(), mcCollision.posZ() - particle.vz(), mcCollision.globalIndex() == recCollision.mcCollisionId(), c.hasFakeReassociation, motherDecayDaughters); diff --git a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx index cbc97acf8b8..c09b05ba107 100644 --- a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx @@ -311,11 +311,13 @@ struct Phik0shortanalysis { mcEventHist.add("hGenMCVertexZ", "hGenMCVertexZ", kTH1F, {vertexZAxis}); mcEventHist.add("hGenMCMultiplicityPercent", "GenMC Multiplicity Percentile", kTH1F, {binnedmultAxis}); + mcEventHist.add("hGenMCAssocRecoMultiplicityPercent", "GenMC AssocReco Multiplicity Percentile", kTH1F, {binnedmultAxis}); // Eta distribution for dN/deta values estimation in MC mcEventHist.add("h2RecMCEtaDistribution", "Eta vs multiplicity in MCReco", kTH2F, {binnedmultAxis, etaAxis}); mcEventHist.add("h2GenMCEtaDistribution", "Eta vs multiplicity in MCGen", kTH2F, {binnedmultAxis, etaAxis}); mcEventHist.add("h2GenMCEtaDistributionAssocReco", "Eta vs multiplicity in MCGen Assoc Reco", kTH2F, {binnedmultAxis, etaAxis}); + mcEventHist.add("h2GenMCEtaDistributionAssocReco2", "Eta vs multiplicity in MCGen Assoc Reco", kTH2F, {binnedmultAxis, etaAxis}); // Phi topological/PID cuts dataPhiHist.add("h2DauTracksPhiDCAxyPreCutData", "Dcaxy distribution vs pt before DCAxy cut", kTH2F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}, {2000, -0.05, 0.05, "DCA_{xy} (cm)"}}); @@ -2322,6 +2324,19 @@ struct Phik0shortanalysis { mcEventHist.fill(HIST("h2RecMCEtaDistribution"), genmultiplicity, mcTrack.eta()); } + + for (const auto& mcParticle : mcParticlesThisColl) { + if (!mcParticle.isPhysicalPrimary() || std::abs(mcParticle.eta()) > trackConfigs.etaMax) + continue; + + auto pdgTrack = pdgDB->GetParticle(mcParticle.pdgCode()); + if (pdgTrack == nullptr) + continue; + if (pdgTrack->Charge() == trackConfigs.cfgCutCharge) + continue; + + mcEventHist.fill(HIST("h2GenMCEtaDistributionAssocReco"), genmultiplicity, mcParticle.eta()); + } } PROCESS_SWITCH(Phik0shortanalysis, processdNdetaWPhiMCReco, "Process function for dN/deta values in MCReco", false); @@ -2345,6 +2360,8 @@ struct Phik0shortanalysis { float genmultiplicity = mcCollision.centFT0M(); mcEventHist.fill(HIST("hGenMCMultiplicityPercent"), genmultiplicity); + if (isAssocColl) + mcEventHist.fill(HIST("hGenMCAssocRecoMultiplicityPercent"), genmultiplicity); for (const auto& mcParticle : mcParticles) { if (!mcParticle.isPhysicalPrimary() || std::abs(mcParticle.eta()) > trackConfigs.etaMax) @@ -2358,7 +2375,7 @@ struct Phik0shortanalysis { mcEventHist.fill(HIST("h2GenMCEtaDistribution"), genmultiplicity, mcParticle.eta()); if (isAssocColl) - mcEventHist.fill(HIST("h2GenMCEtaDistributionAssocReco"), genmultiplicity, mcParticle.eta()); + mcEventHist.fill(HIST("h2GenMCEtaDistributionAssocReco2"), genmultiplicity, mcParticle.eta()); } } diff --git a/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx b/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx index 2b900fe82d6..b06a6e0d10a 100644 --- a/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx +++ b/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx @@ -14,33 +14,39 @@ /// /// \author prottay.das@cern.ch -#include -#include -#include -#include "Math/Vector3D.h" -#include "Math/Vector4D.h" -#include "Math/GenVector/Boost.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGMM/Mult/DataModel/Index.h" // for Particles2Tracks table -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/StepTHn.h" -#include "Common/DataModel/PIDResponse.h" -#include "Common/DataModel/Multiplicity.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" -#include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/EventSelection.h" -#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/FT0Corrected.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CCDB/BasicCCDBManager.h" #include "CommonConstants/PhysicsConstants.h" -#include "Common/Core/TrackSelection.h" #include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/Track.h" -#include "CCDB/BasicCCDBManager.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/LFStrangenessPIDTables.h" -#include "Common/DataModel/FT0Corrected.h" -#include "PWGMM/Mult/DataModel/Index.h" // for Particles2Tracks table + +#include "Math/GenVector/Boost.h" +#include "Math/Vector2D.h" +#include "Math/Vector3D.h" +#include "Math/Vector4D.h" + +#include + +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -48,6 +54,9 @@ using namespace o2::framework::expressions; using std::array; using namespace o2::aod::rctsel; +using dauTracks = soa::Join; +using v0Candidates = soa::Join; + struct LfTaskLambdaSpinCorr { Service ccdb; @@ -59,6 +68,9 @@ struct LfTaskLambdaSpinCorr { Configurable cfgEvtRCTFlagCheckerLimitAcceptAsBad{"cfgEvtRCTFlagCheckerLimitAcceptAsBad", true, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"}; } rctCut; // mixing + Configurable cosCalculation{"cosCalculation", 0, "cos calculation"}; + Configurable mixingCombination{"mixingCombination", 0, "mixing Combination"}; + Configurable mixingEvSel{"mixingEvSel", false, "mixingEvSel"}; Configurable cfgCutOccupancy{"cfgCutOccupancy", 2000, "Occupancy cut"}; ConfigurableAxis axisVertex{"axisVertex", {5, -10, 10}, "vertex axis for bin"}; ConfigurableAxis axisMultiplicityClass{"axisMultiplicityClass", {8, 0, 80}, "multiplicity percentile for bin"}; @@ -122,6 +134,10 @@ struct LfTaskLambdaSpinCorr { AxisSpec thnAxisInvMass{iMNbins, lbinIM, hbinIM, "#it{M} (GeV/#it{c}^{2})"}; AxisSpec thnAxisInvMasspair{iMNbinspair, lbinIMpair, hbinIMpair, "#it{M} (GeV/#it{c}^{2})"}; histos.add("hEvtSelInfo", "hEvtSelInfo", kTH1F, {{10, 0, 10.0}}); + histos.add("hPtDiff", "hPtDiff", kTH1F, {{1000, 0, 100.0}}); + histos.add("hPhiDiff", "hPhiDiff", kTH1F, {{800, -8.0, 8.0}}); + histos.add("hRDiff", "hRDiff", kTH1F, {{640, -16.0, 16.0}}); + histos.add("hv0Mult", "hv0Mult", kTH1F, {{10001, -0.5, 10000.5}}); histos.add("hCentrality", "Centrality distribution", kTH1F, {{configcentAxis}}); histos.add("hSparseLambdaLambda", "hSparseLambdaLambda", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, thnAxisInvMasspair}, true); histos.add("hSparseLambdaAntiLambda", "hSparseLambdaAntiLambda", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, thnAxisInvMasspair}, true); @@ -236,8 +252,8 @@ struct LfTaskLambdaSpinCorr { const ROOT::Math::PxPyPzMVector& Lambdadummy, const ROOT::Math::PxPyPzMVector& AntiLambdadummy) { - const double minMass = 1.0; - const double maxMass = 2.0; + const double minMass = 1.09; + const double maxMass = 1.14; return (lambdaTag && aLambdaTag && (Lambdadummy.M() > minMass && Lambdadummy.M() < maxMass) && (AntiLambdadummy.M() > minMass && AntiLambdadummy.M() < maxMass)); @@ -274,8 +290,19 @@ struct LfTaskLambdaSpinCorr { auto proton1LambdaRF = boostLambda1ToCM(proton1pairCM); auto proton2LambdaRF = boostLambda2ToCM(proton2pairCM); - double cosThetaDiff = proton1LambdaRF.Vect().Unit().Dot(proton2LambdaRF.Vect().Unit()); - double deltaR = TMath::Sqrt(TMath::Power(particle1.Eta() - particle2.Eta(), 2.0) + TMath::Power(particle1.Phi() - particle2.Phi(), 2.0)); + auto cosThetaDiff = -999.0; + if (cosCalculation == 0) { + cosThetaDiff = proton1LambdaRF.Vect().Unit().Dot(proton2LambdaRF.Vect().Unit()); + } + + if (cosCalculation == 1) { + ROOT::Math::XYZVector quantizationAxis = lambda1CM.Vect().Unit(); + double cosTheta1 = proton1LambdaRF.Vect().Unit().Dot(quantizationAxis); + double cosTheta2 = proton2LambdaRF.Vect().Unit().Dot(quantizationAxis); + cosThetaDiff = cosTheta1 * cosTheta2; + } + double deltaPhi = RecoDecay::constrainAngle(particle1.Phi() - particle2.Phi(), 0.0); + double deltaR = TMath::Sqrt(TMath::Power(particle1.Eta() - particle2.Eta(), 2.0) + TMath::Power(deltaPhi, 2.0)); if (datatype == 0) { if (tag1 && tag3) { histos.fill(HIST("hSparseLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR); @@ -355,6 +382,32 @@ struct LfTaskLambdaSpinCorr { return {lambdaTag, aLambdaTag, true}; // Valid candidate } + std::tuple getLambdaTagsDD(const auto& v0, const auto& collision) + { + auto postrack = v0.template posTrackExtra_as(); + auto negtrack = v0.template negTrackExtra_as(); + + int lambdaTag = 0; + int aLambdaTag = 0; + + if (isSelectedV0Daughter(v0, postrack, 0) && isSelectedV0Daughter(v0, negtrack, 1)) { + lambdaTag = 1; + } + if (isSelectedV0Daughter(v0, negtrack, 0) && isSelectedV0Daughter(v0, postrack, 1)) { + aLambdaTag = 1; + } + + if (!lambdaTag && !aLambdaTag) { + return {0, 0, false}; // No valid tags + } + + if (!selectionV0(collision, v0)) { + return {0, 0, false}; // Fails selection + } + + return {lambdaTag, aLambdaTag, true}; // Valid candidate + } + std::tuple getLambdaTagsMC(const auto& v0, const auto& collision) { auto postrack = v0.template posTrack_as(); @@ -392,7 +445,7 @@ struct LfTaskLambdaSpinCorr { return {lambdaTag, aLambdaTag, true}; // Valid candidate } - + ROOT::Math::PxPyPzMVector lambda0, antiLambda0, proton0, pion0, antiProton0, antiPion0; ROOT::Math::PxPyPzMVector lambda, antiLambda, proton, pion, antiProton, antiPion; ROOT::Math::PxPyPzMVector lambda2, antiLambda2, proton2, pion2, antiProton2, antiPion2; ROOT::Math::PxPyPzMVector lambdamc, antiLambdamc, protonmc, pionmc, antiProtonmc, antiPionmc; @@ -459,7 +512,12 @@ struct LfTaskLambdaSpinCorr { pion = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), o2::constants::physics::MassPionCharged); antiLambda = antiProton + pion; } - + if (lambdaTag && (lambda.M() < lbinIM || lambda.M() > hbinIM)) { + continue; + } + if (aLambdaTag && (antiLambda.M() < lbinIM || antiLambda.M() > hbinIM)) { + continue; + } auto postrack1 = v0.template posTrack_as(); auto negtrack1 = v0.template negTrack_as(); @@ -485,6 +543,12 @@ struct LfTaskLambdaSpinCorr { pion2 = ROOT::Math::PxPyPzMVector(v02.pxpos(), v02.pypos(), v02.pzpos(), o2::constants::physics::MassPionCharged); antiLambda2 = antiProton2 + pion2; } + if (lambdaTag2 && (lambda2.M() < lbinIM || lambda2.M() > hbinIM)) { + continue; + } + if (aLambdaTag2 && (antiLambda2.M() < lbinIM || antiLambda2.M() > hbinIM)) { + continue; + } auto postrack2 = v02.template posTrack_as(); auto negtrack2 = v02.template negTrack_as(); if (postrack1.globalIndex() == postrack2.globalIndex() || negtrack1.globalIndex() == negtrack2.globalIndex()) { @@ -550,7 +614,7 @@ struct LfTaskLambdaSpinCorr { if (additionalEvSel4 && !collision1.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { continue; } - if (additionalEvSel5 && !collision1.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + if (mixingEvSel && additionalEvSel5 && !collision1.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { continue; } @@ -560,7 +624,7 @@ struct LfTaskLambdaSpinCorr { if (additionalEvSel4 && !collision2.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { continue; } - if (additionalEvSel5 && !collision2.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + if (mixingEvSel && additionalEvSel5 && !collision2.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { continue; } @@ -570,11 +634,17 @@ struct LfTaskLambdaSpinCorr { auto groupV03 = V0s.sliceBy(tracksPerCollisionV0, collision2.globalIndex()); // for (auto& [t1, t2, t3] : soa::combinations(o2::soa::CombinationsFullIndexPolicy(groupV01, groupV02, groupV03))) { // LOGF(info, "Mixed event collisions: (%d, %d, %d)", t1.collisionId(),t2.collisionId(),t3.collisionId()); - auto maxV0Size = 1100; - if (groupV01.size() > maxV0Size || groupV02.size() > maxV0Size || groupV03.size() > maxV0Size) { - continue; - } - bool pairStatus[1150][1150] = {{false}}; + + // auto maxV0Size = 1400; + // if (groupV01.size() > maxV0Size || groupV02.size() > maxV0Size || groupV03.size() > maxV0Size) { + // continue; + // } + // bool pairStatus[1500][1500] = {{false}}; + + size_t rows = groupV03.size() + 20; + size_t cols = groupV01.size() + 20; + std::vector> pairStatus(rows, std::vector(cols, false)); + histos.fill(HIST("hv0Mult"), groupV01.size()); for (auto& [t1, t2] : soa::combinations(o2::soa::CombinationsFullIndexPolicy(groupV01, groupV02))) { bool pairfound = false; if (t2.index() <= t1.index()) { @@ -605,9 +675,48 @@ struct LfTaskLambdaSpinCorr { if (postrack1.globalIndex() == postrack2.globalIndex() || negtrack1.globalIndex() == negtrack2.globalIndex()) { continue; } + // auto samePairSumPt = t1.pt() + t2.pt(); + double deltaPhiSame = RecoDecay::constrainAngle(t1.phi() - t2.phi(), 0.0); + auto samePairR = TMath::Sqrt(TMath::Power(deltaPhiSame, 2.0) + TMath::Power(t1.eta() - t2.eta(), 2.0)); + + if (lambdaTag1) { + proton0 = ROOT::Math::PxPyPzMVector(t1.pxpos(), t1.pypos(), t1.pzpos(), o2::constants::physics::MassProton); + antiPion0 = ROOT::Math::PxPyPzMVector(t1.pxneg(), t1.pyneg(), t1.pzneg(), o2::constants::physics::MassPionCharged); + lambda0 = proton0 + antiPion0; + } + if (aLambdaTag1) { + antiProton0 = ROOT::Math::PxPyPzMVector(t1.pxneg(), t1.pyneg(), t1.pzneg(), o2::constants::physics::MassProton); + pion0 = ROOT::Math::PxPyPzMVector(t1.pxpos(), t1.pypos(), t1.pzpos(), o2::constants::physics::MassPionCharged); + antiLambda0 = antiProton0 + pion0; + } + if (lambdaTag1 && (lambda0.M() < lbinIM || lambda0.M() > hbinIM)) { + continue; + } + if (aLambdaTag1 && (antiLambda0.M() < lbinIM || antiLambda0.M() > hbinIM)) { + continue; + } + if (lambdaTag2) { + proton = ROOT::Math::PxPyPzMVector(t2.pxpos(), t2.pypos(), t2.pzpos(), o2::constants::physics::MassProton); + antiPion = ROOT::Math::PxPyPzMVector(t2.pxneg(), t2.pyneg(), t2.pzneg(), o2::constants::physics::MassPionCharged); + lambda = proton + antiPion; + } + if (aLambdaTag2) { + antiProton = ROOT::Math::PxPyPzMVector(t2.pxneg(), t2.pyneg(), t2.pzneg(), o2::constants::physics::MassProton); + pion = ROOT::Math::PxPyPzMVector(t2.pxpos(), t2.pypos(), t2.pzpos(), o2::constants::physics::MassPionCharged); + antiLambda = antiProton + pion; + } + if (lambdaTag2 && (lambda.M() < lbinIM || lambda.M() > hbinIM)) { + continue; + } + if (aLambdaTag2 && (antiLambda.M() < lbinIM || antiLambda.M() > hbinIM)) { + continue; + } for (const auto& t3 : groupV03) { + // if (pairStatus[t3.index()][t2.index()]) { + // LOGF(info, "repeat match found v0 id: (%d, %d)", t3.index(), t2.index()); + // continue; + // } if (pairStatus[t3.index()][t2.index()]) { - // LOGF(info, "repeat match found v0 id: (%d, %d)", t3.index(), t2.index()); continue; } if (t1.collisionId() == t3.collisionId()) { @@ -623,25 +732,341 @@ struct LfTaskLambdaSpinCorr { if (lambdaTag1 != lambdaTag3 || aLambdaTag1 != aLambdaTag3) { continue; } - if (std::abs(t1.pt() - t3.pt()) > ptMix) { + + if (lambdaTag3) { + proton2 = ROOT::Math::PxPyPzMVector(t3.pxpos(), t3.pypos(), t3.pzpos(), o2::constants::physics::MassProton); + antiPion2 = ROOT::Math::PxPyPzMVector(t3.pxneg(), t3.pyneg(), t3.pzneg(), o2::constants::physics::MassPionCharged); + lambda2 = proton2 + antiPion2; + } + if (aLambdaTag3) { + antiProton2 = ROOT::Math::PxPyPzMVector(t3.pxneg(), t3.pyneg(), t3.pzneg(), o2::constants::physics::MassProton); + pion2 = ROOT::Math::PxPyPzMVector(t3.pxpos(), t3.pypos(), t3.pzpos(), o2::constants::physics::MassPionCharged); + antiLambda2 = antiProton2 + pion2; + } + if (lambdaTag3 && (lambda2.M() < lbinIM || lambda2.M() > hbinIM)) { continue; } - if (std::abs(t1.eta() - t3.eta()) > etaMix) { + if (aLambdaTag3 && (antiLambda2.M() < lbinIM || antiLambda2.M() > hbinIM)) { continue; } - if (std::abs(t1.phi() - t3.phi()) > phiMix) { + double deltaPhiMix = RecoDecay::constrainAngle(t3.phi() - t2.phi(), 0.0); + auto mixPairR = TMath::Sqrt(TMath::Power(deltaPhiMix, 2.0) + TMath::Power(t3.eta() - t2.eta(), 2.0)); + auto etaDiff = t1.eta() - t3.eta(); + auto phiDiff = RecoDecay::constrainAngle(t1.phi() - t3.phi(), 0.0); + + histos.fill(HIST("hPtDiff"), t1.pt() - t3.pt()); + histos.fill(HIST("hPhiDiff"), phiDiff); + histos.fill(HIST("hRDiff"), etaDiff); + + if (mixingCombination == 0 && std::abs(t1.pt() - t3.pt()) > ptMix) { continue; } - if (lambdaTag2) { - proton = ROOT::Math::PxPyPzMVector(t2.pxpos(), t2.pypos(), t2.pzpos(), o2::constants::physics::MassProton); - antiPion = ROOT::Math::PxPyPzMVector(t2.pxneg(), t2.pyneg(), t2.pzneg(), o2::constants::physics::MassPionCharged); - lambda = proton + antiPion; + if (mixingCombination == 0 && t1.eta() * t3.eta() > 0 && std::abs(etaDiff) > etaMix) { + continue; } - if (aLambdaTag2) { - antiProton = ROOT::Math::PxPyPzMVector(t2.pxneg(), t2.pyneg(), t2.pzneg(), o2::constants::physics::MassProton); - pion = ROOT::Math::PxPyPzMVector(t2.pxpos(), t2.pypos(), t2.pzpos(), o2::constants::physics::MassPionCharged); - antiLambda = antiProton + pion; + if (mixingCombination == 0 && phiDiff > phiMix) { + continue; + } + + if (mixingCombination == 1 && std::abs(t1.pt() - t3.pt()) > ptMix) { + continue; + } + if (mixingCombination == 1 && std::abs(mixPairR - samePairR) > etaMix) { + continue; + } + + if (lambdaTag2 && lambdaTag3) { + fillHistograms(1, 0, 1, 0, lambda, lambda2, proton, proton2, centrality, 2); + } else if (aLambdaTag2 && aLambdaTag3) { + fillHistograms(0, 1, 0, 1, antiLambda, antiLambda2, antiProton, antiProton2, centrality, 2); + } else if (lambdaTag2 && aLambdaTag3) { + fillHistograms(1, 0, 0, 1, lambda, antiLambda2, proton, antiProton2, centrality, 2); + } else if (aLambdaTag2 && lambdaTag3) { + fillHistograms(0, 1, 1, 0, antiLambda, lambda2, antiProton, proton2, centrality, 2); + } else { + continue; + } + pairfound = true; + pairStatus[t3.index()][t2.index()] = true; + // LOGF(info, "v0 id: (%d, %d)", t3.index(), t2.index()); + if (pairfound) { + // LOGF(info, "Pair found"); + break; + } + } + } + } + } + PROCESS_SWITCH(LfTaskLambdaSpinCorr, processME, "Process data ME", true); + + void processDerivedData(soa::Join::iterator const& collision, v0Candidates const& V0s, dauTracks const&) + { + histos.fill(HIST("hEvtSelInfo"), 0.5); + if (rctCut.requireRCTFlagChecker && !rctChecker(collision)) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 1.5); + if (!collision.sel8()) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 2.5); + auto centrality = collision.centFT0C(); + int occupancy = collision.trackOccupancyInTimeRange(); + if (additionalEvSel && (!collision.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 3.5); + if (additionalEvSel3 && (!collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision.selection_bit(aod::evsel::kNoITSROFrameBorder))) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 4.5); + if (additionalEvSel4 && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 5.5); + if (additionalEvSel5 && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 6.5); + if (occupancy > cfgCutOccupancy) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 7.5); + histos.fill(HIST("hCentrality"), centrality); + + for (const auto& v0 : V0s) { + auto [lambdaTag, aLambdaTag, isValid] = getLambdaTagsDD(v0, collision); + if (!isValid) { + continue; + } + + if (lambdaTag && aLambdaTag) { + continue; + } + + if (lambdaTag) { + proton = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), o2::constants::physics::MassProton); + antiPion = ROOT::Math::PxPyPzMVector(v0.pxneg(), v0.pyneg(), v0.pzneg(), o2::constants::physics::MassPionCharged); + lambda = proton + antiPion; + } + if (aLambdaTag) { + antiProton = ROOT::Math::PxPyPzMVector(v0.pxneg(), v0.pyneg(), v0.pzneg(), o2::constants::physics::MassProton); + pion = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), o2::constants::physics::MassPionCharged); + antiLambda = antiProton + pion; + } + + if (lambdaTag && (lambda.M() < lbinIM || lambda.M() > hbinIM)) { + continue; + } + if (aLambdaTag && (antiLambda.M() < lbinIM || antiLambda.M() > hbinIM)) { + continue; + } + + // auto postrack1 = v0.template posTrackExtra_as(); + // auto negtrack1 = v0.template negTrackExtra_as(); + + // 2nd loop for combination of lambda lambda + for (const auto& v02 : V0s) { + if (v02.index() <= v0.index()) { + continue; + } + auto [lambdaTag2, aLambdaTag2, isValid2] = getLambdaTagsDD(v02, collision); + if (!isValid2) { + continue; + } + if (lambdaTag2 && aLambdaTag2) { + continue; + } + if (lambdaTag2) { + proton2 = ROOT::Math::PxPyPzMVector(v02.pxpos(), v02.pypos(), v02.pzpos(), o2::constants::physics::MassProton); + antiPion2 = ROOT::Math::PxPyPzMVector(v02.pxneg(), v02.pyneg(), v02.pzneg(), o2::constants::physics::MassPionCharged); + lambda2 = proton2 + antiPion2; + } + if (aLambdaTag2) { + antiProton2 = ROOT::Math::PxPyPzMVector(v02.pxneg(), v02.pyneg(), v02.pzneg(), o2::constants::physics::MassProton); + pion2 = ROOT::Math::PxPyPzMVector(v02.pxpos(), v02.pypos(), v02.pzpos(), o2::constants::physics::MassPionCharged); + antiLambda2 = antiProton2 + pion2; + } + + if (lambdaTag2 && (lambda2.M() < lbinIM || lambda2.M() > hbinIM)) { + continue; + } + if (aLambdaTag2 && (antiLambda2.M() < lbinIM || antiLambda2.M() > hbinIM)) { + continue; + } + + // auto postrack2 = v02.template posTrackExtra_as(); + // auto negtrack2 = v02.template negTrackExtra_as(); + if (v0.posTrackExtraId() == v02.posTrackExtraId() || v0.negTrackExtraId() == v02.negTrackExtraId()) { + continue; + } + + if (lambdaTag && lambdaTag2) { + fillHistograms(1, 0, 1, 0, lambda, lambda2, proton, proton2, centrality, 0); + } + if (aLambdaTag && aLambdaTag2) { + fillHistograms(0, 1, 0, 1, antiLambda, antiLambda2, antiProton, antiProton2, centrality, 0); + } + if (lambdaTag && aLambdaTag2) { + fillHistograms(1, 0, 0, 1, lambda, antiLambda2, proton, antiProton2, centrality, 0); + } + if (aLambdaTag && lambdaTag2) { + fillHistograms(0, 1, 1, 0, antiLambda, lambda2, antiProton, proton2, centrality, 0); + } + } + } + } + PROCESS_SWITCH(LfTaskLambdaSpinCorr, processDerivedData, "Process derived data", true); + + Preslice tracksPerCollisionV0Mixed = o2::aod::v0data::straCollisionId; // for derived data only + void processDerivedDataMixed(soa::Join const& collisions, v0Candidates const& V0s, dauTracks const&) + + { + + for (auto& [collision1, collision2] : selfCombinations(colBinning, nMix, -1, collisions, collisions)) { + // LOGF(info, "Mixed event collisions: (%d, %d)", collision1.index(), collision2.index()); + if (rctCut.requireRCTFlagChecker && !rctChecker(collision1)) { + continue; + } + if (rctCut.requireRCTFlagChecker && !rctChecker(collision2)) { + continue; + } + int occupancy1 = collision1.trackOccupancyInTimeRange(); + int occupancy2 = collision2.trackOccupancyInTimeRange(); + + if (collision1.index() == collision2.index()) { + continue; + } + if (!collision1.sel8() || !collision2.sel8()) { + continue; + } + if (additionalEvSel && (!collision1.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { + continue; + } + if (occupancy1 > cfgCutOccupancy) { + continue; + } + if (additionalEvSel && (!collision2.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision2.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { + continue; + } + if (occupancy2 > cfgCutOccupancy) { + continue; + } + if (additionalEvSel3 && (!collision1.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision1.selection_bit(aod::evsel::kNoITSROFrameBorder))) { + continue; + } + if (additionalEvSel4 && !collision1.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + continue; + } + if (mixingEvSel && additionalEvSel5 && !collision1.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + continue; + } + + if (additionalEvSel3 && (!collision2.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision2.selection_bit(aod::evsel::kNoITSROFrameBorder))) { + continue; + } + if (additionalEvSel4 && !collision2.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + continue; + } + if (mixingEvSel && additionalEvSel5 && !collision2.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + continue; + } + auto centrality = collision1.centFT0C(); + auto groupV01 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision1.globalIndex()); + auto groupV02 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision1.globalIndex()); + auto groupV03 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision2.globalIndex()); + + size_t rows = groupV03.size() + 20; + size_t cols = groupV01.size() + 20; + std::vector> pairStatus(rows, std::vector(cols, false)); + histos.fill(HIST("hv0Mult"), groupV01.size()); + for (auto& [t1, t2] : soa::combinations(o2::soa::CombinationsFullIndexPolicy(groupV01, groupV02))) { + bool pairfound = false; + if (t2.index() <= t1.index()) { + continue; + } + if (t1.straCollisionId() != t2.straCollisionId()) { + continue; + } + + auto [lambdaTag1, aLambdaTag1, isValid1] = getLambdaTagsDD(t1, collision1); + auto [lambdaTag2, aLambdaTag2, isValid2] = getLambdaTagsDD(t2, collision1); + if (!isValid1) { + continue; + } + if (!isValid2) { + continue; + } + if (lambdaTag1 && aLambdaTag1) { + continue; + } + if (lambdaTag2 && aLambdaTag2) { + continue; + } + // auto postrack1 = t1.template posTrackExtra_as(); + // auto negtrack1 = t1.template negTrackExtra_as(); + // auto postrack2 = t2.template posTrackExtra_as(); + // auto negtrack2 = t2.template negTrackExtra_as(); + if (t1.posTrackExtraId() == t2.posTrackExtraId() || t1.negTrackExtraId() == t2.negTrackExtraId()) { + continue; + } + // auto samePairSumPt = t1.pt() + t2.pt(); + // auto samePairR = TMath::Sqrt(TMath::Power(t1.phi() - t2.phi(), 2.0) + TMath::Power(t1.eta() - t2.eta(), 2.0)); + + double deltaPhiSame = RecoDecay::constrainAngle(t1.phi() - t2.phi(), 0.0); + auto samePairR = TMath::Sqrt(TMath::Power(deltaPhiSame, 2.0) + TMath::Power(t1.eta() - t2.eta(), 2.0)); + + if (lambdaTag1) { + proton0 = ROOT::Math::PxPyPzMVector(t1.pxpos(), t1.pypos(), t1.pzpos(), o2::constants::physics::MassProton); + antiPion0 = ROOT::Math::PxPyPzMVector(t1.pxneg(), t1.pyneg(), t1.pzneg(), o2::constants::physics::MassPionCharged); + lambda0 = proton0 + antiPion0; + } + if (aLambdaTag1) { + antiProton0 = ROOT::Math::PxPyPzMVector(t1.pxneg(), t1.pyneg(), t1.pzneg(), o2::constants::physics::MassProton); + pion0 = ROOT::Math::PxPyPzMVector(t1.pxpos(), t1.pypos(), t1.pzpos(), o2::constants::physics::MassPionCharged); + antiLambda0 = antiProton0 + pion0; + } + if (lambdaTag1 && (lambda0.M() < lbinIM || lambda0.M() > hbinIM)) { + continue; + } + if (aLambdaTag1 && (antiLambda0.M() < lbinIM || antiLambda0.M() > hbinIM)) { + continue; + } + if (lambdaTag2) { + proton = ROOT::Math::PxPyPzMVector(t2.pxpos(), t2.pypos(), t2.pzpos(), o2::constants::physics::MassProton); + antiPion = ROOT::Math::PxPyPzMVector(t2.pxneg(), t2.pyneg(), t2.pzneg(), o2::constants::physics::MassPionCharged); + lambda = proton + antiPion; + } + if (aLambdaTag2) { + antiProton = ROOT::Math::PxPyPzMVector(t2.pxneg(), t2.pyneg(), t2.pzneg(), o2::constants::physics::MassProton); + pion = ROOT::Math::PxPyPzMVector(t2.pxpos(), t2.pypos(), t2.pzpos(), o2::constants::physics::MassPionCharged); + antiLambda = antiProton + pion; + } + if (lambdaTag2 && (lambda.M() < lbinIM || lambda.M() > hbinIM)) { + continue; + } + if (aLambdaTag2 && (antiLambda.M() < lbinIM || antiLambda.M() > hbinIM)) { + continue; + } + + for (const auto& t3 : groupV03) { + if (pairStatus[t3.index()][t2.index()]) { + continue; } + if (t1.straCollisionId() == t3.straCollisionId()) { + continue; + } + auto [lambdaTag3, aLambdaTag3, isValid3] = getLambdaTagsDD(t3, collision2); + if (!isValid3) { + continue; + } + if (lambdaTag3 && aLambdaTag3) { + continue; + } + if (lambdaTag1 != lambdaTag3 || aLambdaTag1 != aLambdaTag3) { + continue; + } + if (lambdaTag3) { proton2 = ROOT::Math::PxPyPzMVector(t3.pxpos(), t3.pypos(), t3.pzpos(), o2::constants::physics::MassProton); antiPion2 = ROOT::Math::PxPyPzMVector(t3.pxneg(), t3.pyneg(), t3.pzneg(), o2::constants::physics::MassPionCharged); @@ -652,30 +1077,61 @@ struct LfTaskLambdaSpinCorr { pion2 = ROOT::Math::PxPyPzMVector(t3.pxpos(), t3.pypos(), t3.pzpos(), o2::constants::physics::MassPionCharged); antiLambda2 = antiProton2 + pion2; } + if (lambdaTag3 && (lambda2.M() < lbinIM || lambda2.M() > hbinIM)) { + continue; + } + + if (aLambdaTag3 && (antiLambda2.M() < lbinIM || antiLambda2.M() > hbinIM)) { + continue; + } + + double deltaPhiMix = RecoDecay::constrainAngle(t3.phi() - t2.phi(), 0.0); + auto mixPairR = TMath::Sqrt(TMath::Power(deltaPhiMix, 2.0) + TMath::Power(t3.eta() - t2.eta(), 2.0)); + + auto etaDiff = t1.eta() - t3.eta(); + auto phiDiff = RecoDecay::constrainAngle(t1.phi() - t3.phi(), 0.0); + + histos.fill(HIST("hPtDiff"), t1.pt() - t3.pt()); + histos.fill(HIST("hPhiDiff"), phiDiff); + histos.fill(HIST("hRDiff"), etaDiff); + + if (mixingCombination == 0 && std::abs(t1.pt() - t3.pt()) > ptMix) { + continue; + } + if (mixingCombination == 0 && t1.eta() * t3.eta() > 0 && std::abs(etaDiff) > etaMix) { + continue; + } + if (mixingCombination == 0 && phiDiff > phiMix) { + continue; + } + if (mixingCombination == 1 && std::abs(t1.pt() - t3.pt()) > ptMix) { + continue; + } + if (mixingCombination == 1 && std::abs(mixPairR - samePairR) > etaMix) { + continue; + } if (lambdaTag2 && lambdaTag3) { fillHistograms(1, 0, 1, 0, lambda, lambda2, proton, proton2, centrality, 2); - } - if (aLambdaTag2 && aLambdaTag3) { + } else if (aLambdaTag2 && aLambdaTag3) { fillHistograms(0, 1, 0, 1, antiLambda, antiLambda2, antiProton, antiProton2, centrality, 2); - } - if (lambdaTag2 && aLambdaTag3) { + } else if (lambdaTag2 && aLambdaTag3) { fillHistograms(1, 0, 0, 1, lambda, antiLambda2, proton, antiProton2, centrality, 2); - } - if (aLambdaTag2 && lambdaTag3) { + } else if (aLambdaTag2 && lambdaTag3) { fillHistograms(0, 1, 1, 0, antiLambda, lambda2, antiProton, proton2, centrality, 2); + } else { + continue; } pairfound = true; pairStatus[t3.index()][t2.index()] = true; - // LOGF(info, "v0 id: (%d, %d)", t3.index(), t2.index()); if (pairfound) { - // LOGF(info, "Pair found"); break; } } } } } - PROCESS_SWITCH(LfTaskLambdaSpinCorr, processME, "Process data ME", true); + + PROCESS_SWITCH(LfTaskLambdaSpinCorr, processDerivedDataMixed, "Process mixed derived data", true); using CollisionMCRecTableCentFT0C = soa::Join; using TrackMCRecTable = soa::Join; diff --git a/PWGLF/Utils/svPoolCreator.h b/PWGLF/Utils/svPoolCreator.h index 2414eb7e19b..25da298fe34 100644 --- a/PWGLF/Utils/svPoolCreator.h +++ b/PWGLF/Utils/svPoolCreator.h @@ -73,20 +73,20 @@ class svPoolCreator o2::vertexing::DCAFitterN<2>* getFitter() { return &fitter; } std::array, 4> getTrackCandPool() { return trackCandPool; } - template - void fillBC2Coll(const C& collisions, aod::BCsWithTimestamps const&) + template + void fillBC2Coll(const C& collisions, BC const&) { for (unsigned i = 0; i < collisions.size(); i++) { auto collision = collisions.rawIteratorAt(i); if (!collision.has_bc()) { continue; } - bc2Coll[collision.template bc_as().globalBC()] = i; + bc2Coll[collision.template bc_as().globalBC()] = i; } } - template - void appendTrackCand(const T& trackCand, const C& collisions, int pdgHypo, o2::aod::AmbiguousTracks const& ambiTracks, aod::BCsWithTimestamps const&) + template + void appendTrackCand(const T& trackCand, const C& collisions, int pdgHypo, o2::aod::AmbiguousTracks const& ambiTracks, BC const&) { if (pdgHypo != track0Pdg && pdgHypo != track1Pdg) { LOG(debug) << "Wrong pdg hypothesis"; @@ -97,18 +97,18 @@ class svPoolCreator uint64_t globalBC = BcInvalid; if (trackCand.has_collision()) { if (trackCand.template collision_as().has_bc()) { - globalBC = trackCand.template collision_as().template bc_as().globalBC(); + globalBC = trackCand.template collision_as().template bc_as().globalBC(); } } else if (!skipAmbiTracks) { for (const auto& ambTrack : ambiTracks) { if (ambTrack.trackId() != trackCand.globalIndex()) { continue; } - if (!ambTrack.has_bc() || ambTrack.bc_as().size() == 0) { + if (!ambTrack.has_bc() || ambTrack.bc_as().size() == 0) { globalBC = BcInvalid; break; } - globalBC = ambTrack.bc_as().begin().globalBC(); + globalBC = ambTrack.bc_as().begin().globalBC(); break; } } else { @@ -134,7 +134,7 @@ class svPoolCreator const auto& collision = collisions.rawIteratorAt(i); float collTime = collision.collisionTime(); float collTimeRes2 = collision.collisionTimeRes() * collision.collisionTimeRes(); - uint64_t collBC = collision.template bc_as().globalBC(); + uint64_t collBC = collision.template bc_as().globalBC(); int collIdx = collision.globalIndex(); int64_t bcOffset = globalBC - static_cast(collBC); if (static_cast(std::abs(bcOffset)) > bOffsetMax) { diff --git a/PWGMM/UE/Tasks/dedxAnalysis.cxx b/PWGMM/UE/Tasks/dedxAnalysis.cxx index fb4200bbaaa..cf5baa3f417 100644 --- a/PWGMM/UE/Tasks/dedxAnalysis.cxx +++ b/PWGMM/UE/Tasks/dedxAnalysis.cxx @@ -14,21 +14,24 @@ /// \file dedxAnalysis.cxx /// \brief Analysis to do PID +#include "PWGLF/DataModel/LFStrangenessTables.h" + #include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" #include "Common/Core/trackUtilities.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Multiplicity.h" + #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" #include "ReconstructionDataFormats/Track.h" -#include "Common/Core/TrackSelectionDefaults.h" + +#include "TF1.h" using namespace o2; using namespace o2::framework; @@ -38,7 +41,7 @@ using PIDTracks = soa::Join< aod::Tracks, aod::TracksExtra, aod::TrackSelectionExtension, aod::TracksDCA, aod::TrackSelection, aod::pidTOFFullPi, aod::pidTOFFullPr, aod::pidTOFFullEl, aod::pidTOFbeta>; -using SelectedCollisions = soa::Join; +using SelectedCollisions = soa::Join; struct DedxAnalysis { @@ -53,14 +56,14 @@ struct DedxAnalysis { static constexpr int kEtaIntervals = 8; static constexpr int kParticlesType = 4; float tpcCut = 0.6; - float centMin = 0.0; - float centMax = 100.0; float pionMin = 0.35; float pionMax = 0.45; float elTofCut = 0.1; float pionTofCut = 1.0; float invMassCut = 0.01; float invMassCutGamma = 0.0015; + float magField = 1.0; + float pTcut = 2.0; // Configurable Parameters // Tracks cuts @@ -71,6 +74,8 @@ struct DedxAnalysis { "max chi2 per cluster TPC"}; Configurable maxChi2ITS{"maxChi2ITS", 36.0f, "max chi2 per cluster ITS"}; + Configurable maxZDistanceToIP{"maxZDistanceToIP", 10.0f, + "max z distance to IP"}; Configurable etaMin{"etaMin", -0.8f, "etaMin"}; Configurable etaMax{"etaMax", +0.8f, "etaMax"}; Configurable minNCrossedRowsOverFindableClustersTPC{"minNCrossedRowsOverFindableClustersTPC", 0.8f, "Additional cut on the minimum value of the ratio between crossed rows and findable clusters in the TPC"}; @@ -95,6 +100,7 @@ struct DedxAnalysis { Configurable maxMassGamma{"maxMassGamma", 0.002022f, "Maximum Mass Gamma"}; Configurable calibrationMode{"calibrationMode", false, "calibration mode"}; + Configurable additionalCuts{"additionalCuts", false, "additional cuts"}; // Histograms names static constexpr std::string_view kDedxvsMomentumPos[kParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; static constexpr std::string_view kDedxvsMomentumNeg[kParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; @@ -103,6 +109,10 @@ struct DedxAnalysis { Configurable> calibrationFactorPos{"calibrationFactorPos", {50.5157, 50.6359, 50.3198, 49.3345, 48.9197, 49.4931, 50.0188, 50.1406}, "positive calibration factors"}; ConfigurableAxis binP{"binP", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, ""}; + // phi cut fits + TF1* fphiCutHigh = nullptr; + TF1* fphiCutLow = nullptr; + TrackSelection myTrackSelection() { TrackSelection selectedTracks; @@ -117,6 +127,7 @@ struct DedxAnalysis { selectedTracks.SetMaxChi2PerClusterITS(maxChi2ITS); selectedTracks.SetMaxDcaXYPtDep([](float pt) { return 0.0105f + 0.0350f / std::pow(pt, 1.1f); }); selectedTracks.SetMaxDcaZ(maxDCAz); + selectedTracks.SetRequireGoldenChi2(true); return selectedTracks; } @@ -129,6 +140,8 @@ struct DedxAnalysis { AxisSpec ptAxis = {binP, "pT (GeV/c)"}; AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; AxisSpec pAxis = {binP, "#it{p}/Z (GeV/c)"}; + fphiCutLow = new TF1("StandardPhiCutLow", "0.1/x/x+pi/18.0-0.025", 0, 50); + fphiCutHigh = new TF1("StandardPhiCutHigh", "0.12/x+pi/18.0+0.035", 0, 50); if (calibrationMode) { // MIP for pions registryDeDx.add( @@ -201,6 +214,11 @@ struct DedxAnalysis { "hdEdx_vs_phi", "dE/dx", HistType::kTH2F, {{100, 0.0, 6.4, "#phi"}, {dedxAxis}}); + // phi cut + registryDeDx.add( + "hpt_vs_phi", "phi cut", HistType::kTH2F, + {{ptAxis}, {100, 0.0, 6.4, "#phi"}}); + registryDeDx.add( "hbeta_vs_p_Neg", "beta", HistType::kTH2F, {{pAxis}, {100, 0.0, 1.1, "#beta"}}); @@ -374,6 +392,33 @@ struct DedxAnalysis { return true; } + // Phi cut + template + bool passedPhiCut(const T& trk, float magField, const TF1& fphiCutLow, const TF1& fphiCutHigh) + { + float pt = trk.pt(); + float phi = trk.phi(); + int charge = trk.sign(); + + if (pt < pTcut) + return true; + + if (magField < 0.) // for negatve polarity field + phi = o2::constants::math::TwoPI - phi; + if (charge < 0) // for negatve charge + phi = o2::constants::math::TwoPI - phi; + + // to center gap in the middle + phi += o2::constants::math::PI / 18.0f; + phi = std::fmod(phi, o2::constants::math::PI / 9.0f); + + if (phi < fphiCutHigh.Eval(pt) && phi > fphiCutLow.Eval(pt)) + return false; // reject track + + registryDeDx.fill(HIST("hpt_vs_phi"), pt, phi); + return true; + } + // Process Data void process(SelectedCollisions::iterator const& collision, aod::V0Datas const& fullV0s, PIDTracks const& tracks) @@ -382,14 +427,23 @@ struct DedxAnalysis { if (!collision.sel8()) return; + if (additionalCuts) { + if (!collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + return; + + if (!collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + return; + + if (std::abs(collision.posZ()) >= maxZDistanceToIP) + return; + + if (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) + return; + } + // Event Counter registryDeDx.fill(HIST("histRecVtxZData"), collision.posZ()); - // Centrality - float centrality = collision.centFT0C(); - if (centrality < centMin || centrality > centMax) - centrality = 1.0; - // Kaons for (const auto& trk : tracks) { @@ -400,6 +454,10 @@ struct DedxAnalysis { if (!mySelectionPrim.IsSelected(trk)) continue; + // phi cut + if (!passedPhiCut(trk, magField, *fphiCutLow, *fphiCutHigh)) + continue; + float signedP = trk.sign() * trk.tpcInnerParam(); // MIP calibration for pions diff --git a/PWGUD/AQC/udQC.cxx b/PWGUD/AQC/udQC.cxx index b3bc5198a0f..58ae8f9793e 100644 --- a/PWGUD/AQC/udQC.cxx +++ b/PWGUD/AQC/udQC.cxx @@ -14,17 +14,22 @@ /// \author Paul Buehler, paul.buehler@oeaw.ac.at /// \since 04.05.2023 -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "ReconstructionDataFormats/BCRange.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Common/DataModel/FT0Corrected.h" #include "PWGUD/Core/UDHelpers.h" + +#include "Common/DataModel/FT0Corrected.h" + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" #include "Framework/StaticFor.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/BCRange.h" + #include "TLorentzVector.h" #include "TMath.h" +#include + using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; @@ -191,8 +196,13 @@ struct UDQC { aod::Zdcs& zdcs, aod::Calos& calos, aod::V0s const& v0s, aod::Cascades const& cascades) { - LOGF(debug, " Start %i", abcrs.size()); + // LOGF(debug, " Start %i", abcrs.size()); + + if (!tracks.size()) + return; + if (collision.numContrib() < 1) + return; bool isDGcandidate = true; registry.get(HIST("collisions/Stat"))->Fill(0., isDGcandidate * 1.); @@ -248,7 +258,7 @@ struct UDQC { if (track.tpcSignal() > maxdEdxTPC) { maxdEdxTPC = track.tpcSignal(); - LOGF(debug, " New maxdEdx TPC %f", maxdEdxTPC); + // LOGF(debug, " New maxdEdx TPC %f", maxdEdxTPC); } // TOF hit? @@ -256,7 +266,7 @@ struct UDQC { registry.get(HIST("tracks/dEdxTOF"))->Fill(track.p() / track.sign(), track.beta()); if (track.tofSignal() > maxdEdxTOF) { maxdEdxTOF = track.tofSignal(); - LOGF(debug, " New maxdEdx TOF %f", maxdEdxTOF); + // LOGF(debug, " New maxdEdx TOF %f", maxdEdxTOF); } // No vertex track with TOF hit? @@ -281,7 +291,7 @@ struct UDQC { if (collision.numContrib() > 0) { rgtrwTOF /= collision.numContrib(); } - LOGF(debug, " PV tracks with TOF: %f [1]", rgtrwTOF); + // LOGF(debug, " PV tracks with TOF: %f [1]", rgtrwTOF); registry.get(HIST("collisions/tResvsrTOFTracks"))->Fill(collision.collisionTimeRes(), rgtrwTOF); registry.get(HIST("collisions/tResvsTOFTrkNoPV"))->Fill(collision.collisionTimeRes(), norgtrwTOF); @@ -429,7 +439,7 @@ struct UDQC { } // define Lorentz vector to create invariant mass lvtmp.SetPtEtaPhiM(track.pt(), track.eta(), track.phi(), mass2Use); - LOGF(debug, "mass %f track pt %f/%f eta %f/%f", mass2Use, track.pt(), lvtmp.Perp(), track.eta(), lvtmp.Eta()); + // LOGF(debug, "mass %f track pt %f/%f eta %f/%f", mass2Use, track.pt(), lvtmp.Perp(), track.eta(), lvtmp.Eta()); if (track.pt() <= diffCuts.minPt() || track.pt() >= diffCuts.maxPt()) { goodpts = false; } @@ -521,7 +531,7 @@ struct UDQC { registry.get(HIST("DG/etaminus"))->Fill(track.eta(), track.phi()); } - LOGF(debug, "dEdx TPC %f TOF %i %f", track.tpcSignal(), track.hasTOF(), track.hasTOF() ? track.tofSignal() : 0.); + // LOGF(debug, "dEdx TPC %f TOF %i %f", track.tpcSignal(), track.hasTOF(), track.hasTOF() ? track.tofSignal() : 0.); if (collision.numContrib() == 2) { registry.get(HIST("DG/dEdxTPC"))->Fill(track.tpcInnerParam() / track.sign(), track.tpcSignal()); registry.get(HIST("DG/trkDCAxy"))->Fill(track.dcaXY()); @@ -562,7 +572,7 @@ struct UDQC { void processCleanFIT1(CC const& collision, BCs const& bct0s, aod::FT0s const& /*ft0s*/, aod::FV0As const& /*fv0as*/, aod::FDDs const& /*fdds*/) { - LOGF(debug, "(); @@ -677,7 +687,7 @@ struct UDQC { // ............................................................................................................... void processFV0(aod::FV0As const& fv0s, BCs const&) { - LOGF(info, " %d", fv0s.size()); + // LOGF(info, " %d", fv0s.size()); if (fv0s.size() <= 0) { return; } @@ -695,7 +705,7 @@ struct UDQC { // ............................................................................................................... void processFT0(aod::FT0s const& ft0s, aod::FT0sCorrected const& ft0scorr, BCs const&) { - LOGF(debug, " %d", ft0s.size()); + // LOGF(debug, " %d", ft0s.size()); for (auto const& collision : ft0scorr) { if (collision.t0ACorrectedValid()) { @@ -729,7 +739,7 @@ struct UDQC { // ............................................................................................................... void processFDD(aod::FDDs const& fdds, BCs const&) { - LOGF(debug, " %d", fdds.size()); + // LOGF(debug, " %d", fdds.size()); for (auto fdd : fdds) { @@ -751,7 +761,7 @@ struct UDQC { // ............................................................................................................... void processZDC(aod::Zdc const& zdc) { - LOGF(debug, " %d", zdc.size()); + // LOGF(debug, " %d", zdc.size()); // Zdc energies registry.get(HIST("ZdcEnergies"))->Fill(0., zdc.energyZEM1()); diff --git a/PWGUD/Core/SGTrackSelector.h b/PWGUD/Core/SGTrackSelector.h index 1b68ab0ddba..11517771eac 100644 --- a/PWGUD/Core/SGTrackSelector.h +++ b/PWGUD/Core/SGTrackSelector.h @@ -16,16 +16,19 @@ #ifndef PWGUD_CORE_SGTRACKSELECTOR_H_ #define PWGUD_CORE_SGTRACKSELECTOR_H_ -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" +#include "PWGUD/Core/SGSelector.h" +#include "PWGUD/DataModel/UDTables.h" + #include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" #include "Framework/O2DatabasePDGPlugin.h" -#include "iostream" -#include "PWGUD/DataModel/UDTables.h" -#include "PWGUD/Core/SGSelector.h" -#include +#include "Framework/runDataProcessing.h" + #include "TVector3.h" +#include + +#include +#include using namespace std; using namespace o2; using namespace o2::aod; diff --git a/PWGUD/Core/UPCJpsiCentralBarrelCorrHelper.h b/PWGUD/Core/UPCJpsiCentralBarrelCorrHelper.h index 0857d6bab1d..77d3781cbc0 100644 --- a/PWGUD/Core/UPCJpsiCentralBarrelCorrHelper.h +++ b/PWGUD/Core/UPCJpsiCentralBarrelCorrHelper.h @@ -16,10 +16,11 @@ #ifndef PWGUD_CORE_UPCJPSICENTRALBARRELCORRHELPER_H_ #define PWGUD_CORE_UPCJPSICENTRALBARRELCORRHELPER_H_ -#include -#include #include "CommonConstants/MathConstants.h" -#include "random" + +#include +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGUD/Core/UPCPairCuts.h b/PWGUD/Core/UPCPairCuts.h new file mode 100644 index 00000000000..f0cdf532561 --- /dev/null +++ b/PWGUD/Core/UPCPairCuts.h @@ -0,0 +1,346 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \brief Functions which cut on particle pairs (decays, conversions, two-track cuts) adapted for data from UD tables +/// Based on the code "PWGCF/Core/PairCuts.h" made by Jan Fiete Grosse-Oetringhaus +/// Author: + +#ifndef PWGUD_CORE_UPCPAIRCUTS_H_ +#define PWGUD_CORE_UPCPAIRCUTS_H_ + +#include "PWGUD/Core/UPCTauCentralBarrelHelperRL.h" + +#include "CommonConstants/MathConstants.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/Logger.h" + +#include + +using namespace o2; +using namespace o2::framework; +using namespace constants::math; + +class UPCPairCuts +{ + public: + enum Particle { Photon = 0, + K0, + Lambda, + Phi, + Rho, + ParticlesLastEntry }; + + void setHistogramRegistry(HistogramRegistry* registry) { histogramRegistry = registry; } + + void setPairCut(Particle particle, float cut) + { + LOGF(info, "Enabled pair cut for %d with value %f", static_cast(particle), cut); + mCuts[particle] = cut; + if (histogramRegistry != nullptr && histogramRegistry->contains(HIST("ControlConvResonances")) == false) { + histogramRegistry->add("ControlConvResonances", "", {HistType::kTH2F, {{6, -0.5, 5.5, "id"}, {500, -0.5, 0.5, "delta mass"}}}); + } + } + + void setTwoTrackCuts(float distance = 0.02f, float radius = 0.8f) + { + LOGF(info, "Enabled two-track cut with distance %f and radius %f", distance, radius); + mTwoTrackDistance = distance; + mTwoTrackRadius = radius; + + if (histogramRegistry != nullptr && histogramRegistry->contains(HIST("TwoTrackDistancePt_0")) == false) { + histogramRegistry->add("TwoTrackDistancePt_0", "", {HistType::kTH3F, {{100, -0.15, 0.15, "#Delta#eta"}, {100, -0.05, 0.05, "#Delta#varphi^{*}_{min}"}, {20, 0, 10, "#Delta p_{T}"}}}); + histogramRegistry->addClone("TwoTrackDistancePt_0", "TwoTrackDistancePt_1"); + } + } + + template + bool conversionCuts(T const& track1, T const& track2); + + template + bool twoTrackCut(T const& track1, T const& track2); + + protected: + float mCuts[ParticlesLastEntry] = {-1}; + float mTwoTrackDistance = -1; // distance below which the pair is flagged as to be removed + float mTwoTrackRadius = 0.8f; // radius at which the two track cuts are applied + int magField = 5; // magField: B field in kG + + HistogramRegistry* histogramRegistry = nullptr; // if set, control histograms are stored here + + template + bool conversionCut(T const& track1, T const& track2, Particle conv, double cut); + + template + double getInvMassSquared(T const& track1, double m0_1, T const& track2, double m0_2); + + template + double getInvMassSquaredFast(T const& track1, double m0_1, T const& track2, double m0_2); + + template + float getDPhiStar(T const& track1, T const& track2, float radius, int magField); +}; + +template +bool UPCPairCuts::conversionCuts(T const& track1, T const& track2) +{ + // skip if like sign + if (track1.sign() * track2.sign() > 0) { + return false; + } + + for (int i = 0; i < static_cast(ParticlesLastEntry); i++) { + Particle particle = static_cast(i); + if (mCuts[i] > 0) { + if (conversionCut(track1, track2, particle, mCuts[i])) { + return true; + } + if (particle == Lambda) { + if (conversionCut(track2, track1, particle, mCuts[i])) { + return true; + } + } + } + } + + return false; +} + +template +bool UPCPairCuts::twoTrackCut(T const& track1, T const& track2) +{ + // the variables & cut have been developed in Run 1 by the CF - HBT group + // + // Parameters: + // magField: B field in kG + + auto deta = eta(track1.px(), track1.py(), track1.pz()) - eta(track2.px(), track2.py(), track2.pz()); + + // optimization + if (std::fabs(deta) < mTwoTrackDistance * 2.5 * 3) { + // check first boundaries to see if is worth to loop and find the minimum + float dphistar1 = getDPhiStar(track1, track2, mTwoTrackRadius, magField); + float dphistar2 = getDPhiStar(track1, track2, 2.5, magField); + + const float kLimit = mTwoTrackDistance * 3; + + if (std::fabs(dphistar1) < kLimit || std::fabs(dphistar2) < kLimit || dphistar1 * dphistar2 < 0) { + float dphistarminabs = 1e5; + float dphistarmin = 1e5; + for (Double_t rad = mTwoTrackRadius; rad < 2.51; rad += 0.01) { + float dphistar = getDPhiStar(track1, track2, rad, magField); + + float dphistarabs = std::fabs(dphistar); + + if (dphistarabs < dphistarminabs) { + dphistarmin = dphistar; + dphistarminabs = dphistarabs; + } + } + + if (histogramRegistry != nullptr) { + histogramRegistry->fill(HIST("TwoTrackDistancePt_0"), deta, dphistarmin, std::fabs(track1.pt() - track2.pt())); + } + + if (dphistarminabs < mTwoTrackDistance && std::fabs(deta) < mTwoTrackDistance) { + // LOGF(debug, "Removed track pair %ld %ld with %f %f %f %f %d %f %f %d %d", track1.index(), track2.index(), deta, dphistarminabs, track1.phi2(), track1.pt(), track1.sign(), track2.phi2(), track2.pt(), track2.sign(), magField); + return true; + } + + if (histogramRegistry != nullptr) { + histogramRegistry->fill(HIST("TwoTrackDistancePt_1"), deta, dphistarmin, std::fabs(track1.pt() - track2.pt())); + } + } + } + + return false; +} + +template +bool UPCPairCuts::conversionCut(T const& track1, T const& track2, Particle conv, double cut) +{ + // LOGF(info, "pt is %f %f", track1.pt(), track2.pt()); + + if (cut < 0) { + return false; + } + + double massD1, massD2, massM; + + switch (conv) { + case Photon: + massD1 = o2::constants::physics::MassElectron; + massD2 = o2::constants::physics::MassElectron; + massM = 0; + break; + case K0: + massD1 = o2::constants::physics::MassPiPlus; + massD2 = o2::constants::physics::MassPiPlus; + massM = o2::constants::physics::MassK0; + break; + case Lambda: + massD1 = o2::constants::physics::MassProton; + massD2 = o2::constants::physics::MassPiPlus; + massM = o2::constants::physics::MassLambda0; + break; + case Phi: + massD1 = o2::constants::physics::MassKPlus; + massD2 = o2::constants::physics::MassKPlus; + massM = o2::constants::physics::MassPhi; + break; + case Rho: + massD1 = o2::constants::physics::MassPiPlus; + massD2 = o2::constants::physics::MassPiPlus; + massM = 0.770; + break; + default: + LOGF(fatal, "Particle now known"); + return false; + break; + } + + auto massC = getInvMassSquaredFast(track1, massD1, track2, massD2); + + if (std::fabs(massC - massM * massM) > cut * 5) { + return false; + } + + massC = getInvMassSquared(track1, massD1, track2, massD2); + + if (histogramRegistry != nullptr) { + histogramRegistry->fill(HIST("ControlConvResonances"), static_cast(conv), massC - massM * massM); + } + + if (massC > (massM - cut) * (massM - cut) && massC < (massM + cut) * (massM + cut)) { + return true; + } + + return false; +} + +template +double UPCPairCuts::getInvMassSquared(T const& track1, double m0_1, T const& track2, double m0_2) +{ + // calculate inv mass squared + // same can be achieved, but with more computing time with + /*TLorentzVector photon, p1, p2; + p1.SetPtEtaPhiM(triggerParticle->Pt(), triggerEta, triggerParticle->Phi(), 0.510e-3); + p2.SetPtEtaPhiM(particle->Pt(), eta[j], particle->Phi(), 0.510e-3); + photon = p1+p2; + photon.M()*/ + + float tantheta1 = 1e10; + + if (eta(track1.px(), track1.py(), track1.pz()) < -1e-10 || eta(track1.px(), track1.py(), track1.pz()) > 1e-10) { + float expTmp = std::exp(-eta(track1.px(), track1.py(), track1.pz())); + tantheta1 = 2.0 * expTmp / (1.0 - expTmp * expTmp); + } + + float tantheta2 = 1e10; + if (eta(track2.px(), track2.py(), track2.pz()) < -1e-10 || eta(track2.px(), track2.py(), track2.pz()) > 1e-10) { + float expTmp = std::exp(-eta(track2.px(), track2.py(), track2.pz())); + tantheta2 = 2.0 * expTmp / (1.0 - expTmp * expTmp); + } + + float e1squ = m0_1 * m0_1 + track1.pt() * track1.pt() * (1.0 + 1.0 / tantheta1 / tantheta1); + float e2squ = m0_2 * m0_2 + track2.pt() * track2.pt() * (1.0 + 1.0 / tantheta2 / tantheta2); + + float mass2 = m0_1 * m0_1 + m0_2 * m0_2 + 2 * (std::sqrt(e1squ * e2squ) - (track1.pt() * track2.pt() * (std::cos(phi(track1.px(), track1.py()) - phi(track2.px(), track2.py())) + 1.0 / tantheta1 / tantheta2))); + + // LOGF(debug, "%f %f %f %f %f %f %f %f %f", pt1, eta1, phi1, pt2, eta2, phi2, m0_1, m0_2, mass2); + + return mass2; +} + +template +double UPCPairCuts::getInvMassSquaredFast(T const& track1, double m0_1, T const& track2, double m0_2) +{ + // calculate inv mass squared approximately + + const float eta1 = eta(track1.px(), track1.py(), track1.pz()); + const float eta2 = eta(track2.px(), track2.py(), track2.pz()); + const float phi1 = phi(track1.px(), track1.py()); + const float phi2 = phi(track2.px(), track2.py()); + const float pt1 = track1.pt(); + const float pt2 = track2.pt(); + + float tantheta1 = 1e10f; + + if (eta1 < -1e-10f || eta1 > 1e-10f) { + float expTmp = 1.0f - eta1 + eta1 * eta1 / 2.0f - eta1 * eta1 * eta1 / 6.0f + eta1 * eta1 * eta1 * eta1 / 24.0f; + tantheta1 = 2.0f * expTmp / (1.0f - expTmp * expTmp); + } + + float tantheta2 = 1e10f; + if (eta2 < -1e-10f || eta2 > 1e-10f) { + float expTmp = 1.0f - eta2 + eta2 * eta2 / 2.0f - eta2 * eta2 * eta2 / 6.0f + eta2 * eta2 * eta2 * eta2 / 24.0f; + tantheta2 = 2.0f * expTmp / (1.0f - expTmp * expTmp); + } + + float e1squ = m0_1 * m0_1 + pt1 * pt1 * (1.0f + 1.0f / tantheta1 / tantheta1); + float e2squ = m0_2 * m0_2 + pt2 * pt2 * (1.0f + 1.0f / tantheta2 / tantheta2); + + // fold onto 0...pi + float deltaPhi = std::fabs(phi1 - phi2); + while (deltaPhi > TwoPI) { + deltaPhi -= TwoPI; + } + if (deltaPhi > PI) { + deltaPhi = TwoPI - deltaPhi; + } + + float cosDeltaPhi = 0; + if (deltaPhi < PI / 3.0f) { + cosDeltaPhi = 1.0 - deltaPhi * deltaPhi / 2 + deltaPhi * deltaPhi * deltaPhi * deltaPhi / 24; + } else if (deltaPhi < 2.0f * PI / 3.0f) { + cosDeltaPhi = -(deltaPhi - PI / 2) + 1.0 / 6 * std::pow((deltaPhi - PI / 2), 3); + } else { + cosDeltaPhi = -1.0f + 1.0f / 2.0f * (deltaPhi - PI) * (deltaPhi - PI) - 1.0f / 24.0f * std::pow(deltaPhi - PI, 4.0f); + } + + double mass2 = m0_1 * m0_1 + m0_2 * m0_2 + 2.0f * (std::sqrt(e1squ * e2squ) - (pt1 * pt2 * (cosDeltaPhi + 1.0f / tantheta1 / tantheta2))); + + // LOGF(debug, "%f %f %f %f %f %f %f %f %f", pt1, eta1, phi1, pt2, eta2, phi2, m0_1, m0_2, mass2); + + return mass2; +} + +template +float UPCPairCuts::getDPhiStar(T const& track1, T const& track2, float radius, int magField) +{ + // + // calculates dphistar + // + + auto phi1 = phi(track1.px(), track1.py()); + auto pt1 = track1.pt(); + auto charge1 = track1.sign(); + + auto phi2 = phi(track2.px(), track2.py()); + auto pt2 = track2.pt(); + auto charge2 = track2.sign(); + + float dphistar = phi1 - phi2 - charge1 * std::asin(0.015 * magField * radius / pt1) + charge2 * std::asin(0.015 * magField * radius / pt2); + + if (dphistar > PI) { + dphistar = TwoPI - dphistar; + } + if (dphistar < -PI) { + dphistar = -TwoPI - dphistar; + } + if (dphistar > PI) { // might look funny but is needed + dphistar = TwoPI - dphistar; + } + + return dphistar; +} + +#endif // PWGUD_CORE_UPCPAIRCUTS_H_ diff --git a/PWGUD/Tasks/CMakeLists.txt b/PWGUD/Tasks/CMakeLists.txt index 2f78f0629b4..a193e46587e 100644 --- a/PWGUD/Tasks/CMakeLists.txt +++ b/PWGUD/Tasks/CMakeLists.txt @@ -146,7 +146,7 @@ o2physics_add_dpl_workflow(exclusive-phi o2physics_add_dpl_workflow(upc-photonuclear-jmg SOURCES upcPhotonuclearAnalysisJMG.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::ReconstructionDataFormats O2::DetectorsBase O2::DetectorsCommonDataFormats + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore O2::ReconstructionDataFormats O2::DetectorsBase O2::DetectorsCommonDataFormats COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(exclusive-two-protons diff --git a/PWGUD/Tasks/eventByevent.cxx b/PWGUD/Tasks/eventByevent.cxx index 3df594af546..ba7a512a26e 100644 --- a/PWGUD/Tasks/eventByevent.cxx +++ b/PWGUD/Tasks/eventByevent.cxx @@ -10,16 +10,19 @@ // or submit itself to any jurisdiction. // -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "iostream" +#include "PWGUD/Core/SGSelector.h" +#include "PWGUD/Core/SGTrackSelector.h" #include "PWGUD/DataModel/UDTables.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "TLorentzVector.h" #include #include -#include "TLorentzVector.h" -#include "PWGUD/Core/SGSelector.h" -#include "PWGUD/Core/SGTrackSelector.h" + +#include using namespace std; using namespace o2; diff --git a/PWGUD/Tasks/exclusivePentaquark.cxx b/PWGUD/Tasks/exclusivePentaquark.cxx index 95da9600f67..24c7cd2b674 100644 --- a/PWGUD/Tasks/exclusivePentaquark.cxx +++ b/PWGUD/Tasks/exclusivePentaquark.cxx @@ -8,15 +8,19 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "iostream" +#include "PWGUD/Core/SGSelector.h" #include "PWGUD/DataModel/UDTables.h" -#include -#include "TLorentzVector.h" + #include "Common/DataModel/PIDResponse.h" -#include "PWGUD/Core/SGSelector.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "TLorentzVector.h" +#include + +#include using std::array; using namespace std; using namespace o2; diff --git a/PWGUD/Tasks/exclusivePhi.cxx b/PWGUD/Tasks/exclusivePhi.cxx index 8f764f2bfff..d3383fb6d1e 100644 --- a/PWGUD/Tasks/exclusivePhi.cxx +++ b/PWGUD/Tasks/exclusivePhi.cxx @@ -9,16 +9,20 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. // -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "iostream" #include "PWGUD/DataModel/UDTables.h" -#include -#include "TLorentzVector.h" + #include "Common/DataModel/PIDResponse.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "TLorentzVector.h" +#include + +#include +#include + using std::array; using namespace std; using namespace o2; diff --git a/PWGUD/Tasks/exclusivePhiLeptons.cxx b/PWGUD/Tasks/exclusivePhiLeptons.cxx index ea7e92f61dd..45cdeb2d450 100644 --- a/PWGUD/Tasks/exclusivePhiLeptons.cxx +++ b/PWGUD/Tasks/exclusivePhiLeptons.cxx @@ -8,16 +8,20 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "iostream" +#include "PWGUD/Core/SGSelector.h" #include "PWGUD/DataModel/UDTables.h" -#include -#include "TLorentzVector.h" + #include "Common/DataModel/PIDResponse.h" -#include "PWGUD/Core/SGSelector.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "TLorentzVector.h" +#include + +#include +#include using std::array; using namespace std; using namespace o2; diff --git a/PWGUD/Tasks/exclusivePhiLeptonsTrees.cxx b/PWGUD/Tasks/exclusivePhiLeptonsTrees.cxx index e1ef9b8f3b4..48f00ab2524 100644 --- a/PWGUD/Tasks/exclusivePhiLeptonsTrees.cxx +++ b/PWGUD/Tasks/exclusivePhiLeptonsTrees.cxx @@ -8,16 +8,20 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "iostream" +#include "PWGUD/Core/SGSelector.h" #include "PWGUD/DataModel/UDTables.h" -#include -#include "TLorentzVector.h" + #include "Common/DataModel/PIDResponse.h" -#include "PWGUD/Core/SGSelector.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "TLorentzVector.h" +#include + +#include +#include using std::array; using namespace std; using namespace o2; diff --git a/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx b/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx index 238ecac1245..ac0a9459569 100644 --- a/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx +++ b/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx @@ -44,7 +44,6 @@ namespace o2::aod { namespace branch { - // vertex Position DECLARE_SOA_COLUMN(PosX, posX, double); DECLARE_SOA_COLUMN(PosY, posY, double); @@ -68,6 +67,9 @@ DECLARE_SOA_COLUMN(TimeFddc, timeFddc, double); DECLARE_SOA_COLUMN(TimeZna, timeZna, double); DECLARE_SOA_COLUMN(TimeZnc, timeZnc, double); +// Occupancy +DECLARE_SOA_COLUMN(Occupancy, occupancy, double); + // DCA DECLARE_SOA_COLUMN(Dcaxy1, dcaxy1, double); DECLARE_SOA_COLUMN(Dcaxy2, dcaxy2, double); @@ -182,6 +184,8 @@ DECLARE_SOA_TABLE(SignalData, "AOD", "signalData", branch::TimeZna, branch::TimeZnc, + branch::Occupancy, + branch::Dcaxy1, branch::Dcaxy2, branch::Dcaxy3, @@ -282,6 +286,8 @@ DECLARE_SOA_TABLE(BkgroundData, "AOD", "bkgroundData", branch::TimeZna, branch::TimeZnc, + branch::Occupancy, + branch::Dcaxy1, branch::Dcaxy2, branch::Dcaxy3, @@ -408,6 +414,8 @@ DECLARE_SOA_TABLE(SignalMCreco, "AOD", "SignalMCreco", branch::TimeZna, branch::TimeZnc, + branch::Occupancy, + branch::Dcaxy1, branch::Dcaxy2, branch::Dcaxy3, @@ -511,8 +519,11 @@ struct ExclusiveRhoTo4Pi { Configurable fv0Cut{"fv0Cut", 50., "FV0A threshold"}; Configurable ft0aCut{"ft0aCut", 150., "FT0A threshold"}; Configurable ft0cCut{"ft0cCut", 50., "FT0C threshold"}; - Configurable zdcCut{"zdcCut", 1., "ZDC threshold"}; - Configurable occupancyCut{"occupancyCut", 1000, "Occupancy Cut"}; + Configurable zdcCut{"zdcCut", 0., "ZDC threshold"}; + Configurable sbpCut{"sbpCut", 1, "Sbp"}; + Configurable itsROFbCut{"itsROFbCut", 1, "itsROFbCut"}; + Configurable vtxITSTPCcut{"vtxITSTPCcut", 1, "vtxITSTPCcut"}; + Configurable tfbCut{"tfbCut", 1, "tfbCut"}; Configurable pvCut{"pvCut", 1.0, "Use Only PV tracks"}; Configurable numPVContrib{"numPVContrib", 4, "Number of PV Contributors"}; @@ -555,66 +566,66 @@ struct ExclusiveRhoTo4Pi { histosData.add("tpcNClsFindable", "TPC N Cls Findable; N Cls Findable; Counts", kTH1F, {{200, 0, 200}}); // TPC nSigma - histosData.add("tpcNSigmaPi_WTS", "TPC nSigma Pion with track selection; Events", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosData.add("tpcNSigmaPi_WTS_PID_Pi", "TPC nSigma Pion with track selection and PID Selection of Pi; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tpcNSigmaPi_all", "TPC nSigma Pion with track selection; Events", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tpcNSigmaPi_pions", "TPC nSigma Pion with track selection and PID Selection of Pi; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); // TPC nSigma of other particles with selected pion tracks - histosData.add("tpcNSigmaKa_WTS_PID_Pi", "TPC nSigma Kaon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosData.add("tpcNSigmaPr_WTS_PID_Pi", "TPC nSigma Proton with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosData.add("tpcNSigmaEl_WTS_PID_Pi", "TPC nSigma Electron with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosData.add("tpcNSigmaMu_WTS_PID_Pi", "TPC nSigma Muon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tpcNSigmaKa_pions", "TPC nSigma Kaon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tpcNSigmaPr_pions", "TPC nSigma Proton with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tpcNSigmaEl_pions", "TPC nSigma Electron with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tpcNSigmaMu_pions", "TPC nSigma Muon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); // TOF nSigma - histosData.add("tofNSigmaPi_WTS", "TOF nSigma Pion with track selection; Events", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosData.add("tofNSigmaPi_WTS_PID_Pi", "TOF nSigma Pion with track selection and PID Selection of Pi; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tofNSigmaPi_all", "TOF nSigma Pion with track selection; Events", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tofNSigmaPi_pions", "TOF nSigma Pion with track selection and PID Selection of Pi; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); // TOF nSigma of other particles with selected pion tracks - histosData.add("tofNSigmaKa_WTS_PID_Pi", "TOF nSigma Kaon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosData.add("tofNSigmaPr_WTS_PID_Pi", "TOF nSigma Proton with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosData.add("tofNSigmaEl_WTS_PID_Pi", "TOF nSigma Electron with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosData.add("tofNSigmaMu_WTS_PID_Pi", "TOF nSigma Muon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tofNSigmaKa_pions", "TOF nSigma Kaon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tofNSigmaPr_pions", "TOF nSigma Proton with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tofNSigmaEl_pions", "TOF nSigma Electron with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosData.add("tofNSigmaMu_pions", "TOF nSigma Muon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); // Track Transverse Momentum - histosData.add("pT_track_WTS", "pT with track selection; pT [GeV/c]; Counts", kTH1F, {{nBinsPt, 0, 2}}); - histosData.add("pT_track_WTS_PID_Pi", "pT with track selection and PID selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); - histosData.add("pT_track_WTS_PID_Pi_contributed", "pT with track selection and PID selection of Pi which are contributed to selected event; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); + histosData.add("pT_track_all", "pT with track selection; pT [GeV/c]; Counts", kTH1F, {{nBinsPt, 0, 2}}); + histosData.add("pT_track_pions", "pT with track selection and PID selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); + histosData.add("pT_track_pions_contributed", "pT with track selection and PID selection of Pi which are contributed to selected event; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); // Track Rapidity - histosData.add("rapidity_track_WTS", "Rapidity with track selection; y; Counts", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); - histosData.add("rapidity_track_WTS_PID_Pi", "Rapidity with track selection and PID selection of Pi; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); - histosData.add("rapidity_track_WTS_PID_Pi_contributed", "Rapidity with track selection and PID selection of Pi which are contributed to selected event; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosData.add("rapidity_track_all", "Rapidity with track selection; y; Counts", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosData.add("rapidity_track_pions", "Rapidity with track selection and PID selection of Pi; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosData.add("rapidity_track_pions_contributed", "Rapidity with track selection and PID selection of Pi which are contributed to selected event; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); // Zero charge Event Transverse Momentum - histosData.add("pT_event_0charge_WTS_PID_Pi", "Event pT in 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); + histosData.add("fourpion_pT_0_charge", "Event pT in 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); // Non Zero charge Event Transverse Momentum - histosData.add("pT_event_non0charge_WTS_PID_Pi", "Event pT in Non 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); + histosData.add("fourpion_pT_non_0_charge", "Event pT in Non 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); // Rapidity of 0 charge Events - histosData.add("rapidity_event_0charge_WTS_PID_Pi_domainA", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} < 0.15 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); - histosData.add("rapidity_event_0charge_WTS_PID_Pi_domainB", "Rapidity of Events With Track Selection and PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); - histosData.add("rapidity_event_0charge_WTS_PID_Pi_domainC", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} > 0.80 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); + histosData.add("fourpion_rap_0_charge_domA", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} < 0.15 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); + histosData.add("fourpion_rap_0_charge_domB", "Rapidity of Events With Track Selection and PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); + histosData.add("fourpion_rap_0_charge_domC", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} > 0.80 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); // Rapidity of non 0 charge Events - histosData.add("rapidity_event_non0charge_WTS_PID_Pi_domainA", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} < 0.15 GeV/c; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); - histosData.add("rapidity_event_non0charge_WTS_PID_Pi_domainB", "Rapidity of Events With Track Selection and PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c$; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); - histosData.add("rapidity_event_non0charge_WTS_PID_Pi_domainC", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} > 0.80 GeV/c; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosData.add("fourpion_rap_non_0_charge_domA", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} < 0.15 GeV/c; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosData.add("fourpion_rap_non_0_charge_domB", "Rapidity of Events With Track Selection and PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c$; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosData.add("fourpion_rap_non_0_charge_domC", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} > 0.80 GeV/c; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); // Pair Invariant Mass - histosData.add("invMass_pair_1", "Invariant Mass Distribution of 2 pions 1 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); - histosData.add("invMass_pair_2", "Invariant Mass Distribution of 2 pions 2 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); - histosData.add("invMass_pair_3", "Invariant Mass Distribution of 2 pions 3 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); - histosData.add("invMass_pair_4", "Invariant Mass Distribution of 2 pions 4 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); + histosData.add("twopion_mass_1", "Invariant Mass Distribution of 2 pions 1 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); + histosData.add("twopion_mass_2", "Invariant Mass Distribution of 2 pions 2 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); + histosData.add("twopion_mass_3", "Invariant Mass Distribution of 2 pions 3 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); + histosData.add("twopion_mass_4", "Invariant Mass Distribution of 2 pions 4 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); // Invariant Mass of 0 charge events - histosData.add("invMass_event_0charge_WTS_PID_Pi_domainA", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for p_{T} < 0.15 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // pT < 0.15GeV - histosData.add("invMass_event_0charge_WTS_PID_Pi_domainB", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.15GeV < pT < 0.8GeV - histosData.add("invMass_event_0charge_WTS_PID_Pi_domainC", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for p_{T} > 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.8GeV < pT + histosData.add("fourpion_mass_0_charge_domA", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for p_{T} < 0.15 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // pT < 0.15GeV + histosData.add("fourpion_mass_0_charge_domB", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.15GeV < pT < 0.8GeV + histosData.add("fourpion_mass_0_charge_domC", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for p_{T} > 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.8GeV < pT // Invariant mass of non 0 charge events - histosData.add("invMass_event_non0charge_WTS_PID_Pi_domainA", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} < 0.15 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // pT < 0.15GeV - histosData.add("invMass_event_non0charge_WTS_PID_Pi_domainB", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.15GeV < pT < 0.8GeV - histosData.add("invMass_event_non0charge_WTS_PID_Pi_domainC", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} > 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.8GeV < pT + histosData.add("fourpion_mass_non_0_charge_domA", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} < 0.15 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // pT < 0.15GeV + histosData.add("fourpion_mass_non_0_charge_domB", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.15GeV < pT < 0.8GeV + histosData.add("fourpion_mass_non_0_charge_domC", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} > 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.8GeV < pT // tpc signal histosData.add("tpcSignal", "TPC dEdx vs p; p [GeV/c]; dEdx [a.u.]", kTH2F, {{500, 0, 10}, {5000, 0.0, 5000.0}}); @@ -632,12 +643,12 @@ struct ExclusiveRhoTo4Pi { histosData.add("V0A", "V0A amplitude", kTH1F, {{1000, 0.0, 100}}); // Collin Soper Theta and Phi - histosData.add("CS_phi_pair_1", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); - histosData.add("CS_phi_pair_2", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); - histosData.add("CS_costheta_pair_1", "#theta Distribution;cos(#theta); Counts", kTH1F, {{nBinsCosTheta, -1, 1}}); - histosData.add("CS_costheta_pair_2", "#theta Distribution;cos(#theta); Counts", kTH1F, {{nBinsCosTheta, -1, 1}}); - histosData.add("phi_cosTheta_pair_1", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); - histosData.add("phi_cosTheta_pair_2", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); + histosData.add("collin_soper_phi_1", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); + histosData.add("collin_soper_phi_2", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); + histosData.add("collin_soper_costheta_1", "#theta Distribution;cos(#theta); Counts", kTH1F, {{nBinsCosTheta, -1, 1}}); + histosData.add("collin_soper_costheta_2", "#theta Distribution;cos(#theta); Counts", kTH1F, {{nBinsCosTheta, -1, 1}}); + histosData.add("phi_vs_costheta_1", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); + histosData.add("phi_vs_costheta_2", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); // MC Gen Stuff @@ -671,8 +682,8 @@ struct ExclusiveRhoTo4Pi { histosMCgen.add("fourPion_phi_pair_2", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); histosMCgen.add("fourPion_costheta_pair_1", "#theta Distribution;cos(#theta); Events", kTH1F, {{nBinsCosTheta, -1, 1}}); histosMCgen.add("fourPion_costheta_pair_2", "#theta Distribution;cos(#theta); Events", kTH1F, {{nBinsCosTheta, -1, 1}}); - histosMCgen.add("phi_cosTheta_pair_1", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); - histosMCgen.add("phi_cosTheta_pair_2", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); + histosMCgen.add("phi_vs_costheta_1", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); + histosMCgen.add("phi_vs_costheta_2", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); // MC Reco Stuff @@ -689,66 +700,66 @@ struct ExclusiveRhoTo4Pi { histosMCreco.add("EventCounts", "Total Events; Events", kTH1F, {{10, 0, 10}}); // TPC nSigma - histosMCreco.add("tpcNSigmaPi_WTS", "TPC nSigma Pion with track selection; Events", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosMCreco.add("tpcNSigmaPi_WTS_PID_Pi", "TPC nSigma Pion with track selection and PID Selection of Pi; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tpcNSigmaPi_all", "TPC nSigma Pion with track selection; Events", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tpcNSigmaPi_pions", "TPC nSigma Pion with track selection and PID Selection of Pi; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); // TPC nSigma of other particles with selected pion tracks - histosMCreco.add("tpcNSigmaKa_WTS_PID_Pi", "TPC nSigma Kaon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosMCreco.add("tpcNSigmaPr_WTS_PID_Pi", "TPC nSigma Proton with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosMCreco.add("tpcNSigmaEl_WTS_PID_Pi", "TPC nSigma Electron with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosMCreco.add("tpcNSigmaMu_WTS_PID_Pi", "TPC nSigma Muon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tpcNSigmaKa_pions", "TPC nSigma Kaon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tpcNSigmaPr_pions", "TPC nSigma Proton with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tpcNSigmaEl_pions", "TPC nSigma Electron with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tpcNSigmaMu_pions", "TPC nSigma Muon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); // TOF nSigma - histosMCreco.add("tofNSigmaPi_WTS", "TOF nSigma Pion with track selection; Events", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosMCreco.add("tofNSigmaPi_WTS_PID_Pi", "TOF nSigma Pion with track selection and PID Selection of Pi; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tofNSigmaPi_all", "TOF nSigma Pion with track selection; Events", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tofNSigmaPi_pions", "TOF nSigma Pion with track selection and PID Selection of Pi; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); // TOF nSigma of other particles with selected pion tracks - histosMCreco.add("tofNSigmaKa_WTS_PID_Pi", "TOF nSigma Kaon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosMCreco.add("tofNSigmaPr_WTS_PID_Pi", "TOF nSigma Proton with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosMCreco.add("tofNSigmaEl_WTS_PID_Pi", "TOF nSigma Electron with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); - histosMCreco.add("tofNSigmaMu_WTS_PID_Pi", "TOF nSigma Muon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tofNSigmaKa_pions", "TOF nSigma Kaon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tofNSigmaPr_pions", "TOF nSigma Proton with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tofNSigmaEl_pions", "TOF nSigma Electron with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); + histosMCreco.add("tofNSigmaMu_pions", "TOF nSigma Muon with track selection and PID Selection of Pion; Entries", kTH2F, {{1000, -15, 15}, {nBinsPt, 0, 10}}); // Track Transverse Momentum - histosMCreco.add("pT_track_WTS", "pT with track selection; pT [GeV/c]; Counts", kTH1F, {{nBinsPt, 0, 2}}); - histosMCreco.add("pT_track_WTS_PID_Pi", "pT with track selection and PID selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); - histosMCreco.add("pT_track_WTS_PID_Pi_contributed", "pT with track selection and PID selection of Pi which are contributed to selected event; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); + histosMCreco.add("pT_track_all", "pT with track selection; pT [GeV/c]; Counts", kTH1F, {{nBinsPt, 0, 2}}); + histosMCreco.add("pT_track_pions", "pT with track selection and PID selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); + histosMCreco.add("pT_track_pions_contributed", "pT with track selection and PID selection of Pi which are contributed to selected event; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); // Track Rapidity - histosMCreco.add("rapidity_track_WTS", "Rapidity with track selection; y; Counts", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); - histosMCreco.add("rapidity_track_WTS_PID_Pi", "Rapidity with track selection and PID selection of Pi; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); - histosMCreco.add("rapidity_track_WTS_PID_Pi_contributed", "Rapidity with track selection and PID selection of Pi which are contributed to selected event; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosMCreco.add("rapidity_track_all", "Rapidity with track selection; y; Counts", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosMCreco.add("rapidity_track_pions", "Rapidity with track selection and PID selection of Pi; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosMCreco.add("rapidity_track_pions_contributed", "Rapidity with track selection and PID selection of Pi which are contributed to selected event; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); // Zero charge Event Transverse Momentum - histosMCreco.add("pT_event_0charge_WTS_PID_Pi", "Event pT in 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); + histosMCreco.add("fourpion_pT_0_charge", "Event pT in 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); // Non Zero charge Event Transverse Momentum - histosMCreco.add("pT_event_non0charge_WTS_PID_Pi", "Event pT in Non 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); + histosMCreco.add("fourpion_pT_non_0_charge", "Event pT in Non 0 Charge Events With Track Selection and PID Selection of Pi; pT [GeV/c]; Events", kTH1F, {{nBinsPt, 0, 2}}); // Rapidity of 0 charge Events - histosMCreco.add("rapidity_event_0charge_WTS_PID_Pi_domainA", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} < 0.15 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); - histosMCreco.add("rapidity_event_0charge_WTS_PID_Pi_domainB", "Rapidity of Events With Track Selection and PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); - histosMCreco.add("rapidity_event_0charge_WTS_PID_Pi_domainC", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} > 0.80 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); + histosMCreco.add("fourpion_rap_0_charge_domA", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} < 0.15 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); + histosMCreco.add("fourpion_rap_0_charge_domB", "Rapidity of Events With Track Selection and PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); + histosMCreco.add("fourpion_rap_0_charge_domC", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} > 0.80 GeV/c; y; Events", kTH1F, {{1000, -2.5, 2.5}}); // Rapidity of non 0 charge Events - histosMCreco.add("rapidity_event_non0charge_WTS_PID_Pi_domainA", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} < 0.15 GeV/c; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); - histosMCreco.add("rapidity_event_non0charge_WTS_PID_Pi_domainB", "Rapidity of Events With Track Selection and PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c$; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); - histosMCreco.add("rapidity_event_non0charge_WTS_PID_Pi_domainC", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} > 0.80 GeV/c; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosMCreco.add("fourpion_rap_non_0_charge_domA", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} < 0.15 GeV/c; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosMCreco.add("fourpion_rap_non_0_charge_domB", "Rapidity of Events With Track Selection and PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c$; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); + histosMCreco.add("fourpion_rap_non_0_charge_domC", "Rapidity of Events With Track Selection and PID Selection of Pi for p_{T} > 0.80 GeV/c; y; Events", kTH1F, {{nBinsRapidity, -2.5, 2.5}}); // Pair Invariant Mass - histosMCreco.add("invMass_pair_1", "Invariant Mass Distribution of 2 pions 1 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); - histosMCreco.add("invMass_pair_2", "Invariant Mass Distribution of 2 pions 2 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); - histosMCreco.add("invMass_pair_3", "Invariant Mass Distribution of 2 pions 3 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); - histosMCreco.add("invMass_pair_4", "Invariant Mass Distribution of 2 pions 4 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); + histosMCreco.add("twopion_mass_1", "Invariant Mass Distribution of 2 pions 1 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); + histosMCreco.add("twopion_mass_2", "Invariant Mass Distribution of 2 pions 2 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); + histosMCreco.add("twopion_mass_3", "Invariant Mass Distribution of 2 pions 3 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); + histosMCreco.add("twopion_mass_4", "Invariant Mass Distribution of 2 pions 4 ; m(#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{5000, 0, 5}}); // Invariant Mass of 0 charge events - histosMCreco.add("invMass_event_0charge_WTS_PID_Pi_domainA", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for p_{T} < 0.15 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // pT < 0.15GeV - histosMCreco.add("invMass_event_0charge_WTS_PID_Pi_domainB", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.15GeV < pT < 0.8GeV - histosMCreco.add("invMass_event_0charge_WTS_PID_Pi_domainC", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for p_{T} > 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.8GeV < pT + histosMCreco.add("fourpion_mass_0_charge_domA", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for p_{T} < 0.15 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // pT < 0.15GeV + histosMCreco.add("fourpion_mass_0_charge_domB", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.15GeV < pT < 0.8GeV + histosMCreco.add("fourpion_mass_0_charge_domC", "Invariant Mass Distribution of 0 charge Events with PID Selection of Pi for p_{T} > 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.8GeV < pT // Invariant mass of non 0 charge events - histosMCreco.add("invMass_event_non0charge_WTS_PID_Pi_domainA", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} < 0.15 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // pT < 0.15GeV - histosMCreco.add("invMass_event_non0charge_WTS_PID_Pi_domainB", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.15GeV < pT < 0.8GeV - histosMCreco.add("invMass_event_non0charge_WTS_PID_Pi_domainC", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} > 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.8GeV < pT + histosMCreco.add("fourpion_mass_non_0_charge_domA", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} < 0.15 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // pT < 0.15GeV + histosMCreco.add("fourpion_mass_non_0_charge_domB", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.15GeV < pT < 0.8GeV + histosMCreco.add("fourpion_mass_non_0_charge_domC", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} > 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {{nBinsInvariantMass, invariantMassMin, invariantMassMax}}); // 0.8GeV < pT // tpc signal histosMCreco.add("tpcSignal", "TPC dEdx vs p; p [GeV/c]; dEdx [a.u.]", kTH2F, {{500, 0, 10}, {5000, 0.0, 5000.0}}); @@ -766,12 +777,12 @@ struct ExclusiveRhoTo4Pi { histosMCreco.add("V0A", "V0A amplitude", kTH1F, {{1000, 0.0, 100}}); // Collin Soper Theta and Phi - histosMCreco.add("CS_phi_pair_1", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); - histosMCreco.add("CS_phi_pair_2", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); - histosMCreco.add("CS_costheta_pair_1", "#theta Distribution;cos(#theta); Counts", kTH1F, {{nBinsCosTheta, -1, 1}}); - histosMCreco.add("CS_costheta_pair_2", "#theta Distribution;cos(#theta); Counts", kTH1F, {{nBinsCosTheta, -1, 1}}); - histosMCreco.add("phi_cosTheta_pair_1", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); - histosMCreco.add("phi_cosTheta_pair_2", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); + histosMCreco.add("collin_soper_phi_1", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); + histosMCreco.add("collin_soper_phi_2", "#phi Distribution; #phi; Events", kTH1F, {{nBinsPhi, -3.2, 3.2}}); + histosMCreco.add("collin_soper_costheta_1", "#theta Distribution;cos(#theta); Counts", kTH1F, {{nBinsCosTheta, -1, 1}}); + histosMCreco.add("collin_soper_costheta_2", "#theta Distribution;cos(#theta); Counts", kTH1F, {{nBinsCosTheta, -1, 1}}); + histosMCreco.add("phi_vs_costheta_1", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); + histosMCreco.add("phi_vs_costheta_2", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {{nBinsPhi, -3.2, 3.2}, {nBinsCosTheta, -1, 1}}); } // End of init function //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -837,8 +848,9 @@ struct ExclusiveRhoTo4Pi { Filter vertexCut = (nabs(o2::aod::collision::posZ) <= vZCut) && (o2::aod::collision::numContrib == numPVContrib); Filter fitcuts = o2::aod::udcollision::totalFV0AmplitudeA < fv0Cut && o2::aod::udcollision::totalFT0AmplitudeA < ft0aCut && o2::aod::udcollision::totalFT0AmplitudeC < ft0cCut; Filter zdcCuts = (o2::aod::udzdc::energyCommonZNA < zdcCut) && (o2::aod::udzdc::energyCommonZNC < zdcCut); - Filter occupCut = nabs(o2::aod::udcollision::occupancyInTime) < occupancyCut; - using UDtracks = soa::Join; + Filter bcSelectionCut = (o2::aod::udcollision::sbp == sbpCut) && (o2::aod::udcollision::itsROFb == itsROFbCut) && (o2::aod::udcollision::vtxITSTPC == vtxITSTPCcut) && (o2::aod::udcollision::tfb == tfbCut); + Filter onlyPVtracks = o2::aod::udtrack::isPVContributor == true; + using UDtracks = soa::Filtered>; using UDCollisions = soa::Filtered>; // using UDCollision = UDCollisions::iterator; //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -890,10 +902,10 @@ struct ExclusiveRhoTo4Pi { ROOT::Math::PxPyPzMVector selectedTrackVector(selectedTracks[i].px(), selectedTracks[i].py(), selectedTracks[i].pz(), o2::constants::physics::MassPionCharged); histosData.fill(HIST("tpcSignal"), selectedTrackVector.P(), selectedTracks[i].tpcSignal()); histosData.fill(HIST("tofBeta"), selectedTrackVector.P(), selectedTracks[i].beta()); - histosData.fill(HIST("tpcNSigmaPi_WTS"), selectedTracks[i].tpcNSigmaPi(), selectedTrackVector.Pt()); - histosData.fill(HIST("tofNSigmaPi_WTS"), selectedTracks[i].tofNSigmaPi(), selectedTrackVector.Pt()); - histosData.fill(HIST("pT_track_WTS"), selectedTrackVector.Pt()); - histosData.fill(HIST("rapidity_track_WTS"), selectedTrackVector.Rapidity()); + histosData.fill(HIST("tpcNSigmaPi_all"), selectedTracks[i].tpcNSigmaPi(), selectedTrackVector.Pt()); + histosData.fill(HIST("tofNSigmaPi_all"), selectedTracks[i].tofNSigmaPi(), selectedTrackVector.Pt()); + histosData.fill(HIST("pT_track_all"), selectedTrackVector.Pt()); + histosData.fill(HIST("rapidity_track_all"), selectedTrackVector.Rapidity()); histosData.fill(HIST("itsChi2NCl"), selectedTracks[i].itsChi2NCl()); histosData.fill(HIST("tpcChi2NCl"), selectedTracks[i].tpcChi2NCl()); histosData.fill(HIST("tpcNClsFindable"), selectedTracks[i].tpcNClsFindable()); @@ -905,27 +917,44 @@ struct ExclusiveRhoTo4Pi { ROOT::Math::PxPyPzMVector selectedPionTrackVector(selectedPionTracks[i].px(), selectedPionTracks[i].py(), selectedPionTracks[i].pz(), o2::constants::physics::MassPionCharged); histosData.fill(HIST("tpcSignal_Pi"), selectedPionTrackVector.P(), selectedPionTracks[i].tpcSignal()); histosData.fill(HIST("tofBeta_Pi"), selectedPionTrackVector.P(), selectedPionTracks[i].beta()); - histosData.fill(HIST("tpcNSigmaPi_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaPi(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tpcNSigmaKa_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaKa(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tpcNSigmaPr_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaPr(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tpcNSigmaEl_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaEl(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tpcNSigmaMu_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaMu(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tofNSigmaPi_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaPi(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tofNSigmaKa_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaKa(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tofNSigmaPr_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaPr(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tofNSigmaEl_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaEl(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("tofNSigmaMu_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaMu(), selectedPionTrackVector.Pt()); - histosData.fill(HIST("pT_track_WTS_PID_Pi"), selectedPionTrackVector.Pt()); - histosData.fill(HIST("rapidity_track_WTS_PID_Pi"), selectedPionTrackVector.Rapidity()); + histosData.fill(HIST("tpcNSigmaPi_pions"), selectedPionTracks[i].tpcNSigmaPi(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tpcNSigmaKa_pions"), selectedPionTracks[i].tpcNSigmaKa(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tpcNSigmaPr_pions"), selectedPionTracks[i].tpcNSigmaPr(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tpcNSigmaEl_pions"), selectedPionTracks[i].tpcNSigmaEl(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tpcNSigmaMu_pions"), selectedPionTracks[i].tpcNSigmaMu(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tofNSigmaPi_pions"), selectedPionTracks[i].tofNSigmaPi(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tofNSigmaKa_pions"), selectedPionTracks[i].tofNSigmaKa(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tofNSigmaPr_pions"), selectedPionTracks[i].tofNSigmaPr(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tofNSigmaEl_pions"), selectedPionTracks[i].tofNSigmaEl(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("tofNSigmaMu_pions"), selectedPionTracks[i].tofNSigmaMu(), selectedPionTrackVector.Pt()); + histosData.fill(HIST("pT_track_pions"), selectedPionTrackVector.Pt()); + histosData.fill(HIST("rapidity_track_pions"), selectedPionTrackVector.Rapidity()); } // End of loop over tracks with selection and PID selection of Pions if (numSelectedPionTracks != numFourPionTracks) { return; } + histosData.fill(HIST("EventCounts"), 2); + + // Check if there is at least one track with TOF in the selected events, otherwise return + bool hasAtleastOneTOF = false; + for (int i = 0; i < numPiPlusTracks; i++) { + if (selectedPionPlusTracks[i].hasTOF() == true) { + hasAtleastOneTOF = true; + break; + } + } + if (!hasAtleastOneTOF) { + return; + } + histosData.fill(HIST("EventCounts"), 3); + // Selecting Events with net charge = 0 if (numPionMinusTracks == numPiMinus && numPiPlusTracks == numPiPlus) { + histosData.fill(HIST("EventCounts"), 4); + ROOT::Math::PtEtaPhiMVector k1, k2, k3, k4, k1234, k13, k14, k23, k24; ROOT::Math::PxPyPzMVector p1(selectedPionPlusTracks[0].px(), selectedPionPlusTracks[0].py(), selectedPionPlusTracks[0].pz(), o2::constants::physics::MassPionCharged); @@ -933,15 +962,15 @@ struct ExclusiveRhoTo4Pi { ROOT::Math::PxPyPzMVector p3(selectedPionMinusTracks[0].px(), selectedPionMinusTracks[0].py(), selectedPionMinusTracks[0].pz(), o2::constants::physics::MassPionCharged); ROOT::Math::PxPyPzMVector p4(selectedPionMinusTracks[1].px(), selectedPionMinusTracks[1].py(), selectedPionMinusTracks[1].pz(), o2::constants::physics::MassPionCharged); - histosData.fill(HIST("pT_track_WTS_PID_Pi_contributed"), p1.Pt()); - histosData.fill(HIST("pT_track_WTS_PID_Pi_contributed"), p2.Pt()); - histosData.fill(HIST("pT_track_WTS_PID_Pi_contributed"), p3.Pt()); - histosData.fill(HIST("pT_track_WTS_PID_Pi_contributed"), p4.Pt()); + histosData.fill(HIST("pT_track_pions_contributed"), p1.Pt()); + histosData.fill(HIST("pT_track_pions_contributed"), p2.Pt()); + histosData.fill(HIST("pT_track_pions_contributed"), p3.Pt()); + histosData.fill(HIST("pT_track_pions_contributed"), p4.Pt()); - histosData.fill(HIST("rapidity_track_WTS_PID_Pi_contributed"), p1.Rapidity()); - histosData.fill(HIST("rapidity_track_WTS_PID_Pi_contributed"), p2.Rapidity()); - histosData.fill(HIST("rapidity_track_WTS_PID_Pi_contributed"), p3.Rapidity()); - histosData.fill(HIST("rapidity_track_WTS_PID_Pi_contributed"), p4.Rapidity()); + histosData.fill(HIST("rapidity_track_pions_contributed"), p1.Rapidity()); + histosData.fill(HIST("rapidity_track_pions_contributed"), p2.Rapidity()); + histosData.fill(HIST("rapidity_track_pions_contributed"), p3.Rapidity()); + histosData.fill(HIST("rapidity_track_pions_contributed"), p4.Rapidity()); k1.SetCoordinates(p1.Pt(), p1.Eta(), p1.Phi(), o2::constants::physics::MassPionCharged); k2.SetCoordinates(p2.Pt(), p2.Eta(), p2.Phi(), o2::constants::physics::MassPionCharged); @@ -964,7 +993,7 @@ struct ExclusiveRhoTo4Pi { sigFromData( collision.posX(), collision.posY(), collision.posZ(), collision.totalFV0AmplitudeA(), collision.totalFT0AmplitudeA(), collision.totalFT0AmplitudeC(), collision.totalFDDAmplitudeA(), collision.totalFDDAmplitudeC(), - collision.timeFV0A(), collision.timeFT0A(), collision.timeFT0C(), collision.timeFDDA(), collision.timeFDDC(), collision.timeZNA(), collision.timeZNC(), + collision.timeFV0A(), collision.timeFT0A(), collision.timeFT0C(), collision.timeFDDA(), collision.timeFDDC(), collision.timeZNA(), collision.timeZNC(), collision.occupancyInTime(), selectedPionPlusTracks[0].dcaXY(), selectedPionPlusTracks[1].dcaXY(), selectedPionMinusTracks[0].dcaXY(), selectedPionMinusTracks[1].dcaXY(), selectedPionPlusTracks[0].dcaZ(), selectedPionPlusTracks[1].dcaZ(), selectedPionMinusTracks[0].dcaZ(), selectedPionMinusTracks[1].dcaZ(), @@ -993,31 +1022,34 @@ struct ExclusiveRhoTo4Pi { fourPiPhiPair1, fourPiPhiPair2, fourPiCosThetaPair1, fourPiCosThetaPair2); if (std::fabs(p1234.Rapidity()) < rhoRapCut) { - histosData.fill(HIST("pT_event_0charge_WTS_PID_Pi"), p1234.Pt()); + histosData.fill(HIST("fourpion_pT_0_charge"), p1234.Pt()); if (p1234.Pt() < rhoPtCut) { - histosData.fill(HIST("rapidity_event_0charge_WTS_PID_Pi_domainA"), p1234.Rapidity()); - histosData.fill(HIST("invMass_event_0charge_WTS_PID_Pi_domainA"), p1234.M()); - histosData.fill(HIST("invMass_pair_1"), (p1 + p3).M()); - histosData.fill(HIST("invMass_pair_2"), (p1 + p4).M()); - histosData.fill(HIST("invMass_pair_3"), (p2 + p3).M()); - histosData.fill(HIST("invMass_pair_4"), (p2 + p4).M()); + histosData.fill(HIST("EventCounts"), 5); - histosData.fill(HIST("CS_phi_pair_1"), fourPiPhiPair1); - histosData.fill(HIST("CS_phi_pair_2"), fourPiPhiPair2); - histosData.fill(HIST("CS_costheta_pair_1"), fourPiCosThetaPair1); - histosData.fill(HIST("CS_costheta_pair_2"), fourPiCosThetaPair2); + histosData.fill(HIST("fourpion_rap_0_charge_domA"), p1234.Rapidity()); + histosData.fill(HIST("fourpion_mass_0_charge_domA"), p1234.M()); - histosData.fill(HIST("phi_cosTheta_pair_1"), fourPiPhiPair1, fourPiCosThetaPair1); - histosData.fill(HIST("phi_cosTheta_pair_2"), fourPiPhiPair2, fourPiCosThetaPair2); + histosData.fill(HIST("twopion_mass_1"), (p1 + p3).M()); + histosData.fill(HIST("twopion_mass_2"), (p1 + p4).M()); + histosData.fill(HIST("twopion_mass_3"), (p2 + p3).M()); + histosData.fill(HIST("twopion_mass_4"), (p2 + p4).M()); + + histosData.fill(HIST("collin_soper_phi_1"), fourPiPhiPair1); + histosData.fill(HIST("collin_soper_phi_2"), fourPiPhiPair2); + histosData.fill(HIST("collin_soper_costheta_1"), fourPiCosThetaPair1); + histosData.fill(HIST("collin_soper_costheta_2"), fourPiCosThetaPair2); + + histosData.fill(HIST("phi_vs_costheta_1"), fourPiPhiPair1, fourPiCosThetaPair1); + histosData.fill(HIST("phi_vs_costheta_2"), fourPiPhiPair2, fourPiCosThetaPair2); } if (p1234.Pt() > rhoPtCut && p1234.Pt() < zeroPointEight) { - histosData.fill(HIST("rapidity_event_0charge_WTS_PID_Pi_domainB"), p1234.Rapidity()); - histosData.fill(HIST("invMass_event_0charge_WTS_PID_Pi_domainB"), p1234.M()); + histosData.fill(HIST("fourpion_rap_0_charge_domB"), p1234.Rapidity()); + histosData.fill(HIST("fourpion_mass_0_charge_domB"), p1234.M()); } if (p1234.Pt() > zeroPointEight) { - histosData.fill(HIST("rapidity_event_0charge_WTS_PID_Pi_domainC"), p1234.Rapidity()); - histosData.fill(HIST("invMass_event_0charge_WTS_PID_Pi_domainC"), p1234.M()); + histosData.fill(HIST("fourpion_rap_0_charge_domC"), p1234.Rapidity()); + histosData.fill(HIST("fourpion_mass_0_charge_domC"), p1234.M()); } } // End of Rapidity range selection @@ -1026,6 +1058,8 @@ struct ExclusiveRhoTo4Pi { // Selecting Events with net charge != 0 for estimation of background if (numPionMinusTracks != numPiMinus && numPiPlusTracks != numPiPlus) { + histosData.fill(HIST("EventCounts"), 6); + ROOT::Math::PxPyPzMVector p1(selectedPionTracks[0].px(), selectedPionTracks[0].py(), selectedPionTracks[0].pz(), o2::constants::physics::MassPionCharged); ROOT::Math::PxPyPzMVector p2(selectedPionTracks[1].px(), selectedPionTracks[1].py(), selectedPionTracks[1].pz(), o2::constants::physics::MassPionCharged); ROOT::Math::PxPyPzMVector p3(selectedPionTracks[2].px(), selectedPionTracks[2].py(), selectedPionTracks[2].pz(), o2::constants::physics::MassPionCharged); @@ -1037,7 +1071,7 @@ struct ExclusiveRhoTo4Pi { collision.posX(), collision.posY(), collision.posZ(), collision.totalFV0AmplitudeA(), collision.totalFT0AmplitudeA(), collision.totalFT0AmplitudeC(), collision.totalFDDAmplitudeA(), collision.totalFDDAmplitudeC(), collision.timeFV0A(), collision.timeFT0A(), collision.timeFT0C(), collision.timeFDDA(), collision.timeFDDC(), - collision.timeZNA(), collision.timeZNC(), + collision.timeZNA(), collision.timeZNC(), collision.occupancyInTime(), selectedPionTracks[0].dcaXY(), selectedPionTracks[1].dcaXY(), selectedPionTracks[0].dcaXY(), selectedPionTracks[1].dcaXY(), selectedPionTracks[0].dcaZ(), selectedPionTracks[1].dcaZ(), selectedPionTracks[0].dcaZ(), selectedPionTracks[1].dcaZ(), selectedPionTracks[0].tpcNSigmaPi(), selectedPionTracks[1].tpcNSigmaPi(), selectedPionTracks[0].tpcNSigmaPi(), selectedPionTracks[1].tpcNSigmaPi(), @@ -1055,19 +1089,20 @@ struct ExclusiveRhoTo4Pi { p1234.Pt(), p1234.Eta(), p1234.Phi(), p1234.Rapidity(), p1234.M()); if (std::fabs(p1234.Rapidity()) < rhoRapCut) { - histosData.fill(HIST("pT_event_non0charge_WTS_PID_Pi"), p1234.Pt()); + histosData.fill(HIST("fourpion_pT_non_0_charge"), p1234.Pt()); if (p1234.Pt() < rhoPtCut) { - histosData.fill(HIST("rapidity_event_non0charge_WTS_PID_Pi_domainA"), p1234.Rapidity()); - histosData.fill(HIST("invMass_event_non0charge_WTS_PID_Pi_domainA"), p1234.M()); + histosData.fill(HIST("EventCounts"), 7); + histosData.fill(HIST("fourpion_rap_non_0_charge_domA"), p1234.Rapidity()); + histosData.fill(HIST("fourpion_mass_non_0_charge_domA"), p1234.M()); } if (p1234.Pt() > rhoPtCut && p1234.Pt() < zeroPointEight) { - histosData.fill(HIST("rapidity_event_non0charge_WTS_PID_Pi_domainB"), p1234.Rapidity()); - histosData.fill(HIST("invMass_event_non0charge_WTS_PID_Pi_domainB"), p1234.M()); + histosData.fill(HIST("fourpion_rap_non_0_charge_domB"), p1234.Rapidity()); + histosData.fill(HIST("fourpion_mass_non_0_charge_domB"), p1234.M()); } if (p1234.Pt() > zeroPointEight) { - histosData.fill(HIST("rapidity_event_non0charge_WTS_PID_Pi_domainC"), p1234.Rapidity()); - histosData.fill(HIST("invMass_event_non0charge_WTS_PID_Pi_domainC"), p1234.M()); + histosData.fill(HIST("fourpion_rap_non_0_charge_domC"), p1234.Rapidity()); + histosData.fill(HIST("fourpion_mass_non_0_charge_domC"), p1234.M()); } } // End of Rapidity range selection } // End of Analysis for non 0 charge events @@ -1167,14 +1202,14 @@ struct ExclusiveRhoTo4Pi { histosMCgen.fill(HIST("fourPion_phi_pair_2"), phiPair2); histosMCgen.fill(HIST("fourPion_costheta_pair_1"), cosThetaPair1); histosMCgen.fill(HIST("fourPion_costheta_pair_2"), cosThetaPair2); - histosMCgen.fill(HIST("phi_cosTheta_pair_1"), phiPair1, cosThetaPair1); - histosMCgen.fill(HIST("phi_cosTheta_pair_2"), phiPair2, cosThetaPair2); + histosMCgen.fill(HIST("phi_vs_costheta_1"), phiPair1, cosThetaPair1); + histosMCgen.fill(HIST("phi_vs_costheta_2"), phiPair2, cosThetaPair2); } // End of 4 Pion MC Generation Process function PROCESS_SWITCH(ExclusiveRhoTo4Pi, processMCgen, "The Process for 4 Pion Analysis from MC Generation", false); // Begin of MC Reconstruction function----------------------------------------------------------------------------------------------------------------------------------------------- - using CollisionStuff = soa::Filtered>; + using CollisionStuff = soa::Filtered>; using CollisionTotal = CollisionStuff::iterator; using TrackStuff = soa::Join; @@ -1228,10 +1263,10 @@ struct ExclusiveRhoTo4Pi { ROOT::Math::PxPyPzMVector selectedTrackVector(selectedTracks[i].px(), selectedTracks[i].py(), selectedTracks[i].pz(), o2::constants::physics::MassPionCharged); histosMCreco.fill(HIST("tpcSignal"), selectedTrackVector.P(), selectedTracks[i].tpcSignal()); histosMCreco.fill(HIST("tofBeta"), selectedTrackVector.P(), selectedTracks[i].beta()); - histosMCreco.fill(HIST("tpcNSigmaPi_WTS"), selectedTracks[i].tpcNSigmaPi(), selectedTrackVector.Pt()); - histosMCreco.fill(HIST("tofNSigmaPi_WTS"), selectedTracks[i].tofNSigmaPi(), selectedTrackVector.Pt()); - histosMCreco.fill(HIST("pT_track_WTS"), selectedTrackVector.Pt()); - histosMCreco.fill(HIST("rapidity_track_WTS"), selectedTrackVector.Rapidity()); + histosMCreco.fill(HIST("tpcNSigmaPi_all"), selectedTracks[i].tpcNSigmaPi(), selectedTrackVector.Pt()); + histosMCreco.fill(HIST("tofNSigmaPi_all"), selectedTracks[i].tofNSigmaPi(), selectedTrackVector.Pt()); + histosMCreco.fill(HIST("pT_track_all"), selectedTrackVector.Pt()); + histosMCreco.fill(HIST("rapidity_track_all"), selectedTrackVector.Rapidity()); histosMCreco.fill(HIST("itsChi2NCl"), selectedTracks[i].itsChi2NCl()); histosMCreco.fill(HIST("tpcChi2NCl"), selectedTracks[i].tpcChi2NCl()); histosMCreco.fill(HIST("tpcNClsFindable"), selectedTracks[i].tpcNClsFindable()); @@ -1243,18 +1278,18 @@ struct ExclusiveRhoTo4Pi { ROOT::Math::PxPyPzMVector selectedPionTrackVector(selectedPionTracks[i].px(), selectedPionTracks[i].py(), selectedPionTracks[i].pz(), o2::constants::physics::MassPionCharged); histosMCreco.fill(HIST("tpcSignal_Pi"), selectedPionTrackVector.P(), selectedPionTracks[i].tpcSignal()); histosMCreco.fill(HIST("tofBeta_Pi"), selectedPionTrackVector.P(), selectedPionTracks[i].beta()); - histosMCreco.fill(HIST("tpcNSigmaPi_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaPi(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tpcNSigmaKa_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaKa(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tpcNSigmaPr_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaPr(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tpcNSigmaEl_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaEl(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tpcNSigmaMu_WTS_PID_Pi"), selectedPionTracks[i].tpcNSigmaMu(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tofNSigmaPi_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaPi(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tofNSigmaKa_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaKa(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tofNSigmaPr_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaPr(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tofNSigmaEl_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaEl(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("tofNSigmaMu_WTS_PID_Pi"), selectedPionTracks[i].tofNSigmaMu(), selectedPionTrackVector.Pt()); - histosMCreco.fill(HIST("pT_track_WTS_PID_Pi"), std::sqrt(selectedPionTracks[i].px() * selectedPionTracks[i].px() + selectedPionTracks[i].py() * selectedPionTracks[i].py())); - histosMCreco.fill(HIST("rapidity_track_WTS_PID_Pi"), selectedPionTrackVector.Rapidity()); + histosMCreco.fill(HIST("tpcNSigmaPi_pions"), selectedPionTracks[i].tpcNSigmaPi(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tpcNSigmaKa_pions"), selectedPionTracks[i].tpcNSigmaKa(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tpcNSigmaPr_pions"), selectedPionTracks[i].tpcNSigmaPr(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tpcNSigmaEl_pions"), selectedPionTracks[i].tpcNSigmaEl(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tpcNSigmaMu_pions"), selectedPionTracks[i].tpcNSigmaMu(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tofNSigmaPi_pions"), selectedPionTracks[i].tofNSigmaPi(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tofNSigmaKa_pions"), selectedPionTracks[i].tofNSigmaKa(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tofNSigmaPr_pions"), selectedPionTracks[i].tofNSigmaPr(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tofNSigmaEl_pions"), selectedPionTracks[i].tofNSigmaEl(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("tofNSigmaMu_pions"), selectedPionTracks[i].tofNSigmaMu(), selectedPionTrackVector.Pt()); + histosMCreco.fill(HIST("pT_track_pions"), std::sqrt(selectedPionTracks[i].px() * selectedPionTracks[i].px() + selectedPionTracks[i].py() * selectedPionTracks[i].py())); + histosMCreco.fill(HIST("rapidity_track_pions"), selectedPionTrackVector.Rapidity()); } // End of loop over tracks with selection and PID selection of Pions if (numSelectedPionTracks != numFourPionTracks) { @@ -1271,15 +1306,15 @@ struct ExclusiveRhoTo4Pi { ROOT::Math::PxPyPzMVector p3(selectedPionMinusTracks[0].px(), selectedPionMinusTracks[0].py(), selectedPionMinusTracks[0].pz(), o2::constants::physics::MassPionCharged); ROOT::Math::PxPyPzMVector p4(selectedPionMinusTracks[1].px(), selectedPionMinusTracks[1].py(), selectedPionMinusTracks[1].pz(), o2::constants::physics::MassPionCharged); - histosMCreco.fill(HIST("pT_track_WTS_PID_Pi_contributed"), p1.Pt()); - histosMCreco.fill(HIST("pT_track_WTS_PID_Pi_contributed"), p2.Pt()); - histosMCreco.fill(HIST("pT_track_WTS_PID_Pi_contributed"), p3.Pt()); - histosMCreco.fill(HIST("pT_track_WTS_PID_Pi_contributed"), p4.Pt()); + histosMCreco.fill(HIST("pT_track_pions_contributed"), p1.Pt()); + histosMCreco.fill(HIST("pT_track_pions_contributed"), p2.Pt()); + histosMCreco.fill(HIST("pT_track_pions_contributed"), p3.Pt()); + histosMCreco.fill(HIST("pT_track_pions_contributed"), p4.Pt()); - histosMCreco.fill(HIST("rapidity_track_WTS_PID_Pi_contributed"), p1.Rapidity()); - histosMCreco.fill(HIST("rapidity_track_WTS_PID_Pi_contributed"), p2.Rapidity()); - histosMCreco.fill(HIST("rapidity_track_WTS_PID_Pi_contributed"), p3.Rapidity()); - histosMCreco.fill(HIST("rapidity_track_WTS_PID_Pi_contributed"), p4.Rapidity()); + histosMCreco.fill(HIST("rapidity_track_pions_contributed"), p1.Rapidity()); + histosMCreco.fill(HIST("rapidity_track_pions_contributed"), p2.Rapidity()); + histosMCreco.fill(HIST("rapidity_track_pions_contributed"), p3.Rapidity()); + histosMCreco.fill(HIST("rapidity_track_pions_contributed"), p4.Rapidity()); k1.SetCoordinates(p1.Pt(), p1.Eta(), p1.Phi(), o2::constants::physics::MassPionCharged); k2.SetCoordinates(p2.Pt(), p2.Eta(), p2.Phi(), o2::constants::physics::MassPionCharged); @@ -1303,7 +1338,7 @@ struct ExclusiveRhoTo4Pi { collision.posX(), collision.posY(), collision.posZ(), collision.totalFV0AmplitudeA(), collision.totalFT0AmplitudeA(), collision.totalFT0AmplitudeC(), collision.totalFDDAmplitudeA(), collision.totalFDDAmplitudeC(), collision.timeFV0A(), collision.timeFT0A(), collision.timeFT0C(), collision.timeFDDA(), collision.timeFDDC(), - collision.timeZNA(), collision.timeZNC(), + collision.timeZNA(), collision.timeZNC(), collision.occupancyInTime(), selectedPionPlusTracks[0].dcaXY(), selectedPionPlusTracks[1].dcaXY(), selectedPionMinusTracks[0].dcaXY(), selectedPionMinusTracks[1].dcaXY(), selectedPionPlusTracks[0].dcaZ(), selectedPionPlusTracks[1].dcaZ(), selectedPionMinusTracks[0].dcaZ(), selectedPionMinusTracks[1].dcaZ(), selectedPionPlusTracks[0].tpcNSigmaPi(), selectedPionPlusTracks[1].tpcNSigmaPi(), selectedPionMinusTracks[0].tpcNSigmaPi(), selectedPionMinusTracks[1].tpcNSigmaPi(), @@ -1322,30 +1357,30 @@ struct ExclusiveRhoTo4Pi { phiPair1, phiPair2, cosThetaPair1, cosThetaPair2); if (std::fabs(p1234.Rapidity()) < rhoRapCut) { - histosMCreco.fill(HIST("pT_event_0charge_WTS_PID_Pi"), p1234.Pt()); + histosMCreco.fill(HIST("fourpion_pT_0_charge"), p1234.Pt()); if (p1234.Pt() < rhoPtCut) { - histosMCreco.fill(HIST("rapidity_event_0charge_WTS_PID_Pi_domainA"), p1234.Rapidity()); - histosMCreco.fill(HIST("invMass_event_0charge_WTS_PID_Pi_domainA"), p1234.M()); - - histosMCreco.fill(HIST("invMass_pair_1"), (p1 + p3).M()); - histosMCreco.fill(HIST("invMass_pair_2"), (p1 + p4).M()); - histosMCreco.fill(HIST("invMass_pair_3"), (p2 + p3).M()); - histosMCreco.fill(HIST("invMass_pair_4"), (p2 + p4).M()); - - histosMCreco.fill(HIST("CS_phi_pair_1"), phiPair1); - histosMCreco.fill(HIST("CS_phi_pair_2"), phiPair2); - histosMCreco.fill(HIST("CS_costheta_pair_1"), cosThetaPair1); - histosMCreco.fill(HIST("CS_costheta_pair_2"), cosThetaPair2); - histosMCreco.fill(HIST("phi_cosTheta_pair_1"), phiPair1, cosThetaPair1); - histosMCreco.fill(HIST("phi_cosTheta_pair_2"), phiPair2, cosThetaPair2); + histosMCreco.fill(HIST("fourpion_rap_0_charge_domA"), p1234.Rapidity()); + histosMCreco.fill(HIST("fourpion_mass_0_charge_domA"), p1234.M()); + + histosMCreco.fill(HIST("twopion_mass_1"), (p1 + p3).M()); + histosMCreco.fill(HIST("twopion_mass_2"), (p1 + p4).M()); + histosMCreco.fill(HIST("twopion_mass_3"), (p2 + p3).M()); + histosMCreco.fill(HIST("twopion_mass_4"), (p2 + p4).M()); + + histosMCreco.fill(HIST("collin_soper_phi_1"), phiPair1); + histosMCreco.fill(HIST("collin_soper_phi_2"), phiPair2); + histosMCreco.fill(HIST("collin_soper_costheta_1"), cosThetaPair1); + histosMCreco.fill(HIST("collin_soper_costheta_2"), cosThetaPair2); + histosMCreco.fill(HIST("phi_vs_costheta_1"), phiPair1, cosThetaPair1); + histosMCreco.fill(HIST("phi_vs_costheta_2"), phiPair2, cosThetaPair2); } if (p1234.Pt() > rhoPtCut && p1234.Pt() < zeroPointEight) { - histosMCreco.fill(HIST("rapidity_event_0charge_WTS_PID_Pi_domainB"), p1234.Rapidity()); - histosMCreco.fill(HIST("invMass_event_0charge_WTS_PID_Pi_domainB"), p1234.M()); + histosMCreco.fill(HIST("fourpion_rap_0_charge_domB"), p1234.Rapidity()); + histosMCreco.fill(HIST("fourpion_mass_0_charge_domB"), p1234.M()); } if (p1234.Pt() > zeroPointEight) { - histosMCreco.fill(HIST("rapidity_event_0charge_WTS_PID_Pi_domainC"), p1234.Rapidity()); - histosMCreco.fill(HIST("invMass_event_0charge_WTS_PID_Pi_domainC"), p1234.M()); + histosMCreco.fill(HIST("fourpion_rap_0_charge_domC"), p1234.Rapidity()); + histosMCreco.fill(HIST("fourpion_mass_0_charge_domC"), p1234.M()); } } // End of Rapidity range selection @@ -1361,19 +1396,19 @@ struct ExclusiveRhoTo4Pi { ROOT::Math::PxPyPzMVector p1234 = p1 + p2 + p3 + p4; if (std::fabs(p1234.Rapidity()) < rhoRapCut) { - histosMCreco.fill(HIST("pT_event_non0charge_WTS_PID_Pi"), p1234.Pt()); + histosMCreco.fill(HIST("fourpion_pT_non_0_charge"), p1234.Pt()); if (p1234.Pt() < rhoPtCut) { - histosMCreco.fill(HIST("rapidity_event_non0charge_WTS_PID_Pi_domainA"), p1234.Rapidity()); - histosMCreco.fill(HIST("invMass_event_non0charge_WTS_PID_Pi_domainA"), p1234.M()); + histosMCreco.fill(HIST("fourpion_rap_non_0_charge_domA"), p1234.Rapidity()); + histosMCreco.fill(HIST("fourpion_mass_non_0_charge_domA"), p1234.M()); } if (p1234.Pt() > rhoPtCut && p1234.Pt() < zeroPointEight) { - histosMCreco.fill(HIST("rapidity_event_non0charge_WTS_PID_Pi_domainB"), p1234.Rapidity()); - histosMCreco.fill(HIST("invMass_event_non0charge_WTS_PID_Pi_domainB"), p1234.M()); + histosMCreco.fill(HIST("fourpion_rap_non_0_charge_domB"), p1234.Rapidity()); + histosMCreco.fill(HIST("fourpion_mass_non_0_charge_domB"), p1234.M()); } if (p1234.Pt() > zeroPointEight) { - histosMCreco.fill(HIST("rapidity_event_non0charge_WTS_PID_Pi_domainC"), p1234.Rapidity()); - histosMCreco.fill(HIST("invMass_event_non0charge_WTS_PID_Pi_domainC"), p1234.M()); + histosMCreco.fill(HIST("fourpion_rap_non_0_charge_domC"), p1234.Rapidity()); + histosMCreco.fill(HIST("fourpion_mass_non_0_charge_domC"), p1234.M()); } } // End of Rapidity range selection diff --git a/PWGUD/Tasks/exclusiveTwoProtons.cxx b/PWGUD/Tasks/exclusiveTwoProtons.cxx index 72032b06906..966bd2c923a 100644 --- a/PWGUD/Tasks/exclusiveTwoProtons.cxx +++ b/PWGUD/Tasks/exclusiveTwoProtons.cxx @@ -8,15 +8,19 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "iostream" +#include "PWGUD/Core/SGSelector.h" #include "PWGUD/DataModel/UDTables.h" -#include -#include "TLorentzVector.h" + #include "Common/DataModel/PIDResponse.h" -#include "PWGUD/Core/SGSelector.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "TLorentzVector.h" +#include + +#include using std::array; using namespace std; using namespace o2; diff --git a/PWGUD/Tasks/exclusiveTwoProtonsSG.cxx b/PWGUD/Tasks/exclusiveTwoProtonsSG.cxx index 0e0aa7c83dd..539ed887676 100644 --- a/PWGUD/Tasks/exclusiveTwoProtonsSG.cxx +++ b/PWGUD/Tasks/exclusiveTwoProtonsSG.cxx @@ -8,15 +8,19 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "iostream" +#include "PWGUD/Core/SGSelector.h" #include "PWGUD/DataModel/UDTables.h" -#include -#include "TLorentzVector.h" + #include "Common/DataModel/PIDResponse.h" -#include "PWGUD/Core/SGSelector.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "TLorentzVector.h" +#include + +#include using std::array; using namespace std; using namespace o2; diff --git a/PWGUD/Tasks/polarisationRho.cxx b/PWGUD/Tasks/polarisationRho.cxx index 994c921a6df..3693acbfe2a 100644 --- a/PWGUD/Tasks/polarisationRho.cxx +++ b/PWGUD/Tasks/polarisationRho.cxx @@ -8,13 +8,16 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "iostream" #include "PWGUD/DataModel/UDTables.h" -#include + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + #include "TLorentzVector.h" +#include + +#include using namespace std; using namespace o2; using namespace o2::aod; diff --git a/PWGUD/Tasks/sgD0Analyzer.cxx b/PWGUD/Tasks/sgD0Analyzer.cxx index b5c35b9deec..229b6f09a4a 100644 --- a/PWGUD/Tasks/sgD0Analyzer.cxx +++ b/PWGUD/Tasks/sgD0Analyzer.cxx @@ -13,17 +13,21 @@ // \author Sasha Bylinkin, alexander.bylinkin@gmail.com // \since April 2023 -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "iostream" -#include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/SGSelector.h" -#include "Common/DataModel/PIDResponse.h" #include "PWGUD/Core/SGTrackSelector.h" -#include +#include "PWGUD/DataModel/UDTables.h" + +#include "Common/DataModel/PIDResponse.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" + #include "TLorentzVector.h" +#include + +#include using namespace std; using namespace o2; using namespace o2::aod; diff --git a/PWGUD/Tasks/sgExclOmega.cxx b/PWGUD/Tasks/sgExclOmega.cxx index 3e24048e621..4a3cf48490f 100644 --- a/PWGUD/Tasks/sgExclOmega.cxx +++ b/PWGUD/Tasks/sgExclOmega.cxx @@ -13,17 +13,21 @@ // \author Sasha Bylinkin, alexander.bylinkin@gmail.com // \since April 2023 -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "iostream" -#include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/SGSelector.h" -#include "Common/DataModel/PIDResponse.h" #include "PWGUD/Core/SGTrackSelector.h" -#include +#include "PWGUD/DataModel/UDTables.h" + +#include "Common/DataModel/PIDResponse.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" + #include "TLorentzVector.h" +#include + +#include using namespace std; using namespace o2; using namespace o2::aod; diff --git a/PWGUD/Tasks/sgExclusivePhi.cxx b/PWGUD/Tasks/sgExclusivePhi.cxx index 679d1677593..460ae7c6446 100644 --- a/PWGUD/Tasks/sgExclusivePhi.cxx +++ b/PWGUD/Tasks/sgExclusivePhi.cxx @@ -9,16 +9,20 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. // -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "iostream" +#include "PWGUD/Core/SGSelector.h" #include "PWGUD/DataModel/UDTables.h" -#include -#include "TLorentzVector.h" + #include "Common/DataModel/PIDResponse.h" -#include "PWGUD/Core/SGSelector.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "TLorentzVector.h" +#include + +#include +#include using std::array; using namespace std; diff --git a/PWGUD/Tasks/sgExclusivePhiITSselections.cxx b/PWGUD/Tasks/sgExclusivePhiITSselections.cxx index 76c56e609f5..a4bb3daa1bc 100644 --- a/PWGUD/Tasks/sgExclusivePhiITSselections.cxx +++ b/PWGUD/Tasks/sgExclusivePhiITSselections.cxx @@ -9,16 +9,20 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. // -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "iostream" +#include "PWGUD/Core/SGSelector.h" #include "PWGUD/DataModel/UDTables.h" -#include -#include "TLorentzVector.h" + #include "Common/DataModel/PIDResponse.h" -#include "PWGUD/Core/SGSelector.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "TLorentzVector.h" +#include + +#include +#include using std::array; using namespace std; diff --git a/PWGUD/Tasks/sgFourPiAnalyzer.cxx b/PWGUD/Tasks/sgFourPiAnalyzer.cxx index fb437863ed8..49f9fd42c38 100644 --- a/PWGUD/Tasks/sgFourPiAnalyzer.cxx +++ b/PWGUD/Tasks/sgFourPiAnalyzer.cxx @@ -13,21 +13,25 @@ // \author Sasha Bylinkin, alexander.bylinkin@gmail.com // \since April 2023 -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "iostream" -#include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/SGSelector.h" #include "PWGUD/Core/SGTrackSelector.h" +#include "PWGUD/DataModel/UDTables.h" + #include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + #include "Framework/ASoA.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" #include "Framework/DataTypes.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" #include "MathUtils/Utils.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include + #include "TLorentzVector.h" +#include + +#include using namespace std; using namespace o2; using namespace o2::aod; diff --git a/PWGUD/Tasks/sgInclJpsi.cxx b/PWGUD/Tasks/sgInclJpsi.cxx index 7e0557ef5f0..9a2d60c3500 100644 --- a/PWGUD/Tasks/sgInclJpsi.cxx +++ b/PWGUD/Tasks/sgInclJpsi.cxx @@ -13,17 +13,21 @@ // \author Sasha Bylinkin, alexander.bylinkin@gmail.com // \since April 2023 -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "iostream" -#include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/SGSelector.h" -#include "Common/DataModel/PIDResponse.h" #include "PWGUD/Core/SGTrackSelector.h" -#include +#include "PWGUD/DataModel/UDTables.h" + +#include "Common/DataModel/PIDResponse.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" + #include "TLorentzVector.h" +#include + +#include using namespace std; using namespace o2; using namespace o2::aod; diff --git a/PWGUD/Tasks/sgSixPiAnalyzer.cxx b/PWGUD/Tasks/sgSixPiAnalyzer.cxx index 215c5d236a1..888b4325a61 100644 --- a/PWGUD/Tasks/sgSixPiAnalyzer.cxx +++ b/PWGUD/Tasks/sgSixPiAnalyzer.cxx @@ -13,22 +13,25 @@ // \author Sasha Bylinkin, alexander.bylinkin@gmail.com // \since April 2023 -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "iostream" -#include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/SGSelector.h" #include "PWGUD/Core/SGTrackSelector.h" +#include "PWGUD/DataModel/UDTables.h" + #include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + #include "Framework/ASoA.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" #include "Framework/DataTypes.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" #include "MathUtils/Utils.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include #include "TLorentzVector.h" +#include + +#include using namespace std; using namespace o2; using namespace o2::aod; diff --git a/PWGUD/Tasks/sgSpectraAnalyzer.cxx b/PWGUD/Tasks/sgSpectraAnalyzer.cxx index cffb6014300..02793c2c7ad 100644 --- a/PWGUD/Tasks/sgSpectraAnalyzer.cxx +++ b/PWGUD/Tasks/sgSpectraAnalyzer.cxx @@ -13,14 +13,16 @@ // \author Sasha Bylinkin, alexander.bylinkin@gmail.com // \since April 2023 -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "iostream" -#include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/SGSelector.h" #include "PWGUD/Core/SGTrackSelector.h" +#include "PWGUD/DataModel/UDTables.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" + +#include //#include "Common/DataModel/PIDResponse.h" //#include "PWGUD/Core/RLhelper.h" #include diff --git a/PWGUD/Tasks/sgTwoPiAnalyzer.cxx b/PWGUD/Tasks/sgTwoPiAnalyzer.cxx index b7015745448..a7763f614cc 100644 --- a/PWGUD/Tasks/sgTwoPiAnalyzer.cxx +++ b/PWGUD/Tasks/sgTwoPiAnalyzer.cxx @@ -13,22 +13,25 @@ // \author Sasha Bylinkin, alexander.bylinkin@gmail.com // \since April 2023 -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "iostream" -#include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/SGSelector.h" #include "PWGUD/Core/SGTrackSelector.h" +#include "PWGUD/DataModel/UDTables.h" + #include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + #include "Framework/ASoA.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" #include "Framework/DataTypes.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" #include "MathUtils/Utils.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include #include "TLorentzVector.h" +#include + +#include using namespace std; using namespace o2; using namespace o2::aod; diff --git a/PWGUD/Tasks/sginclusivePhiKstarSD.cxx b/PWGUD/Tasks/sginclusivePhiKstarSD.cxx index 20d4f08d1d6..628818bd553 100644 --- a/PWGUD/Tasks/sginclusivePhiKstarSD.cxx +++ b/PWGUD/Tasks/sginclusivePhiKstarSD.cxx @@ -59,6 +59,15 @@ struct SginclusivePhiKstarSD { Configurable zdcCut{"zdcCut", 0., "ZDC threshold"}; Configurable vzCut{"vzCut", 10., "Vz position"}; Configurable occCut{"occCut", 1000., "Occupancy cut"}; + Configurable hadronicRate{"hadronicRate", 1000., "hadronicRate cut"}; + Configurable useTrs{"useTrs", -1, "kNoCollInTimeRangeStandard cut"}; + Configurable useTrofs{"useTrofs", -1, "kNoCollInRofStandard cut"}; + Configurable useHmpr{"useHmpr", -1, "kNoHighMultCollInPrevRof cut"}; + Configurable useTfb{"useTfb", -1, "kNoTimeFrameBorder cut"}; + Configurable useItsrofb{"useItsrofb", -1, "kNoITSROFrameBorder cut"}; + Configurable useSbp{"useSbp", -1, "kNoSameBunchPileup cut"}; + Configurable useZvtxftovpv{"useZvtxftovpv", -1, "kIsGoodZvtxFT0vsPV cut"}; + Configurable useVtxItsTpc{"useVtxItsTpc", -1, "kIsVertexITSTPC cut"}; // Track Selections Configurable pvCut{"pvCut", 1.0, "Use Only PV tracks"}; @@ -395,9 +404,9 @@ struct SginclusivePhiKstarSD { } //_____________________________________________________________________________ - double cosThetaCollinsSoperFrame(TLorentzVector pair1, - TLorentzVector pair2, - TLorentzVector fourpion) + double cosThetaCollinsSoperFrame(ROOT::Math::PxPyPzMVector pair1, + ROOT::Math::PxPyPzMVector pair2, + ROOT::Math::PxPyPzMVector fourpion) { double halfSqrtSnn = 2680.; double massOfLead208 = 193.6823; @@ -483,7 +492,7 @@ struct SginclusivePhiKstarSD { } //------------------------------------------------------------------------------------------------------ - double phiCollinsSoperFrame(TLorentzVector pair1, TLorentzVector pair2, TLorentzVector fourpion) + double phiCollinsSoperFrame(ROOT::Math::PxPyPzMVector pair1, ROOT::Math::PxPyPzMVector pair2, ROOT::Math::PxPyPzMVector fourpion) { // Half of the energy per pair of the colliding nucleons. double halfSqrtSnn = 2680.; @@ -518,24 +527,24 @@ struct SginclusivePhiKstarSD { void process(UDCollisionFull const& collision, UDtracksfull const& tracks) { - TLorentzVector v0; - TLorentzVector v1; - TLorentzVector v01; + ROOT::Math::PxPyPzMVector v0; + ROOT::Math::PxPyPzMVector v1; + ROOT::Math::PxPyPzMVector v01; int gapSide = collision.gapSide(); float fitCut[5] = {fv0Cut, ft0aCut, ft0cCut, fddaCut, fddcCut}; std::vector parameters = {pvCut, dcazCut, dcaxyCut, tpcChi2Cut, tpcNClsFindableCut, itsChi2Cut, etaCut, ptCut}; int truegapSide = sgSelector.trueGap(collision, fitCut[0], fitCut[1], fitCut[2], zdcCut); - TLorentzVector phiv; - TLorentzVector phiv1; + ROOT::Math::PxPyPzMVector phiv; + ROOT::Math::PxPyPzMVector phiv1; - std::vector onlyPionTracksp; + std::vector onlyPionTracksp; std::vector rawPionTracksp; - std::vector onlyPionTrackspm; + std::vector onlyPionTrackspm; std::vector rawPionTrackspm; - std::vector onlyPionTracksn; + std::vector onlyPionTracksn; std::vector rawPionTracksn; registry.fill(HIST("GapSide"), gapSide); @@ -547,6 +556,25 @@ struct SginclusivePhiKstarSD { return; if (std::abs(collision.occupancyInTime()) > occCut) return; + if (std::abs(collision.hadronicRate()) > hadronicRate) + return; + + if (useTrs != -1 && collision.trs() != useTrs) + return; + if (useTrofs != -1 && collision.trofs() != useTrofs) + return; + if (useHmpr != -1 && collision.hmpr() != useHmpr) + return; + if (useTfb != -1 && collision.tfb() != useTfb) + return; + if (useItsrofb != -1 && collision.itsROFb() != useItsrofb) + return; + if (useSbp != -1 && collision.sbp() != useSbp) + return; + if (useZvtxftovpv != -1 && collision.zVtxFT0vPV() != useZvtxftovpv) + return; + if (useVtxItsTpc != -1 && collision.vtxITSTPC() != useVtxItsTpc) + return; int mult = collision.numContrib(); if (gapSide == 0) { @@ -569,18 +597,19 @@ struct SginclusivePhiKstarSD { int trackextra = 0; int trackextraDG = 0; - Partition pvContributors1 = aod::udtrack::isPVContributor == true; - pvContributors1.bindTable(tracks); - if (gapSide == 0) { - registry.get(HIST("nPVContributors_data"))->Fill(pvContributors1.size(), 1.); - } - if (gapSide == 1) { - registry.get(HIST("nPVContributors_data_1"))->Fill(pvContributors1.size(), 1.); - } + /* Partition pvContributors1 = aod::udtrack::isPVContributor == true; + pvContributors1.bindTable(tracks); + if (gapSide == 0) { + registry.get(HIST("nPVContributors_data"))->Fill(pvContributors1.size(), 1.); + } + if (gapSide == 1) { + registry.get(HIST("nPVContributors_data_1"))->Fill(pvContributors1.size(), 1.); + } + */ for (const auto& track1 : tracks) { if (!trackselector(track1, parameters)) continue; - v0.SetXYZM(track1.px(), track1.py(), track1.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(track1.px(), track1.py(), track1.pz(), o2::constants::physics::MassPionCharged); if (selectionPIDPion1(track1)) { onlyPionTrackspm.push_back(v0); rawPionTrackspm.push_back(track1); @@ -719,8 +748,8 @@ struct SginclusivePhiKstarSD { continue; if (phi && selectionPIDKaon1(t0) && selectionPIDKaon1(t1)) { // Apply kaon hypothesis and create pairs - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -754,8 +783,8 @@ struct SginclusivePhiKstarSD { continue; if (kstar && selectionPIDKaon1(t0) && selectionPIDPion1(t1)) { // Apply kaon hypothesis and create pairs - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -790,8 +819,8 @@ struct SginclusivePhiKstarSD { continue; if (phi && selectionPIDKaon1(t0) && selectionPIDKaon1(t1)) { // Apply kaon hypothesis and create pairs - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -825,8 +854,8 @@ struct SginclusivePhiKstarSD { continue; if (kstar && selectionPIDKaon1(t0) && selectionPIDPion1(t1)) { // Apply kaon hypothesis and create pairs - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -860,8 +889,8 @@ struct SginclusivePhiKstarSD { continue; if (phi && selectionPIDKaon1(t0) && selectionPIDKaon1(t1)) { // Apply kaon hypothesis and create pairs - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -895,8 +924,8 @@ struct SginclusivePhiKstarSD { continue; if (kstar && selectionPIDKaon1(t0) && selectionPIDPion1(t1)) { // Apply kaon hypothesis and create pairs - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -932,8 +961,8 @@ struct SginclusivePhiKstarSD { if (phi && selectionPIDKaon1(t0) && selectionPIDKaon1(t1)) { // Apply kaon hypothesis and create pairs - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -971,8 +1000,8 @@ struct SginclusivePhiKstarSD { auto rotkaonPx = t0.px() * std::cos(rotangle) - t0.py() * std::sin(rotangle); auto rotkaonPy = t0.px() * std::sin(rotangle) + t0.py() * std::cos(rotangle); - v0.SetXYZM(rotkaonPx, rotkaonPy, t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); + v0.SetCoordinates(rotkaonPx, rotkaonPy, t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); v01 = v0 + v1; if (t0.sign() != t1.sign()) { if (gapSide == 0) { @@ -995,8 +1024,8 @@ struct SginclusivePhiKstarSD { if (t0.globalIndex() == t1.globalIndex()) continue; if (rho && selectionPIDProton(t0, useTof, nsigmaTpcCut, nsigmaTofCut) && selectionPIDPion1(t1)) { - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassProton); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassProton); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -1025,8 +1054,8 @@ struct SginclusivePhiKstarSD { if (kstar && selectionPIDKaon1(t0) && selectionPIDPion1(t1)) { if (kaoncut && t0.tpcNSigmaPi() < pionNsigmaCut) continue; - v0.SetXYZM(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -1062,8 +1091,8 @@ struct SginclusivePhiKstarSD { auto rotkaonPx = t0.px() * std::cos(rotangle) - t0.py() * std::sin(rotangle); auto rotkaonPy = t0.px() * std::sin(rotangle) + t0.py() * std::cos(rotangle); - v0.SetXYZM(rotkaonPx, rotkaonPy, t0.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(rotkaonPx, rotkaonPy, t0.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); v01 = v0 + v1; if (t0.sign() != t1.sign()) { if (gapSide == 0) { @@ -1082,12 +1111,12 @@ struct SginclusivePhiKstarSD { } if (fourpion) { if (gapSide == 2 && mult2 == 4) { - TLorentzVector pair1, pair2, pair3, pair4; + ROOT::Math::PxPyPzMVector pair1, pair2, pair3, pair4; if (onlyPionTracksp.size() == 2 && onlyPionTracksn.size() == 2) { - TLorentzVector k1 = onlyPionTracksp.at(0); - TLorentzVector k2 = onlyPionTracksp.at(1); - TLorentzVector k3 = onlyPionTracksn.at(0); - TLorentzVector k4 = onlyPionTracksn.at(1); + ROOT::Math::PxPyPzMVector k1 = onlyPionTracksp.at(0); + ROOT::Math::PxPyPzMVector k2 = onlyPionTracksp.at(1); + ROOT::Math::PxPyPzMVector k3 = onlyPionTracksn.at(0); + ROOT::Math::PxPyPzMVector k4 = onlyPionTracksn.at(1); phiv = k1 + k2 + k3 + k4; pair1 = k1 + k3; pair2 = k2 + k4; @@ -1112,10 +1141,10 @@ struct SginclusivePhiKstarSD { if (onlyPionTracksp.size() != 2 && onlyPionTracksn.size() != 2) { if (onlyPionTracksp.size() + onlyPionTracksn.size() != 4) return; - TLorentzVector l1 = onlyPionTrackspm.at(0); - TLorentzVector l2 = onlyPionTrackspm.at(1); - TLorentzVector l3 = onlyPionTrackspm.at(2); - TLorentzVector l4 = onlyPionTrackspm.at(3); + ROOT::Math::PxPyPzMVector l1 = onlyPionTrackspm.at(0); + ROOT::Math::PxPyPzMVector l2 = onlyPionTrackspm.at(1); + ROOT::Math::PxPyPzMVector l3 = onlyPionTrackspm.at(2); + ROOT::Math::PxPyPzMVector l4 = onlyPionTrackspm.at(3); phiv1 = l1 + l2 + l3 + l4; registry.fill(HIST("os_pppp_pT_2_ls"), phiv1.M(), phiv1.Pt(), phiv1.Rapidity()); } @@ -1134,9 +1163,9 @@ struct SginclusivePhiKstarSD { using BinningTypeVertexContributor = ColumnBinningPolicy; void mixprocess(UDCollisionsFull1 const& collisions, UDtracksfull const& /*track*/) { - TLorentzVector v0; - TLorentzVector v1; - TLorentzVector v01; + ROOT::Math::PxPyPzMVector v0; + ROOT::Math::PxPyPzMVector v1; + ROOT::Math::PxPyPzMVector v01; float fitCut[5] = {fv0Cut, ft0aCut, ft0cCut, fddaCut, fddcCut}; std::vector parameters = {pvCut, dcazCut, dcaxyCut, tpcChi2Cut, tpcNClsFindableCut, itsChi2Cut, etaCut, ptCut}; BinningTypeVertexContributor binningOnPositions{{axisVertex, axisMultiplicityClass}, true}; @@ -1158,8 +1187,8 @@ struct SginclusivePhiKstarSD { if (!trackselector(track1, parameters) || !trackselector(track2, parameters)) continue; if (phi && selectionPIDKaon1(track1) && selectionPIDKaon1(track2)) { - v0.SetXYZM(track1.px(), track1.py(), track1.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(track2.px(), track2.py(), track2.pz(), o2::constants::physics::MassKaonCharged); + v0.SetCoordinates(track1.px(), track1.py(), track1.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(track2.px(), track2.py(), track2.pz(), o2::constants::physics::MassKaonCharged); v01 = v0 + v1; // Opposite sign pairs if (track1.sign() != track2.sign()) { @@ -1181,8 +1210,8 @@ struct SginclusivePhiKstarSD { if (track1.globalIndex() == track2.globalIndex()) continue; if (kstar && selectionPIDKaon1(track1) && selectionPIDPion1(track2)) { - v0.SetXYZM(track1.px(), track1.py(), track1.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(track2.px(), track2.py(), track2.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(track1.px(), track1.py(), track1.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(track2.px(), track2.py(), track2.pz(), o2::constants::physics::MassPionCharged); v01 = v0 + v1; // Opposite sign pairs if (track1.sign() != track2.sign()) { @@ -1216,11 +1245,11 @@ struct SginclusivePhiKstarSD { void processMCTruth(aod::UDMcCollisions const& mccollisions, CCs const& collisions, aod::UDMcParticles const& McParts, TCs const& tracks) { // number of McCollisions in DF - TLorentzVector v0; - TLorentzVector v1; - TLorentzVector v01; - TLorentzVector vkstar; - TLorentzVector vphi; + ROOT::Math::PxPyPzMVector v0; + ROOT::Math::PxPyPzMVector v1; + ROOT::Math::PxPyPzMVector v01; + ROOT::Math::PxPyPzMVector vkstar; + ROOT::Math::PxPyPzMVector vphi; for (const auto& mccollision : mccollisions) { if (mccollision.generatorsID() != generatedId) continue; @@ -1236,11 +1265,11 @@ struct SginclusivePhiKstarSD { for (const auto& [tr1, tr2] : combinations(partSlice, partSlice)) { if ((tr1.pdgCode() == kKPlus && tr2.pdgCode() == kPiMinus) || (tr1.pdgCode() == kKMinus && tr2.pdgCode() == kPiPlus) || (tr1.pdgCode() == kPiPlus && tr2.pdgCode() == kKMinus) || (tr1.pdgCode() == kPiMinus && tr2.pdgCode() == kKPlus)) { if (std::abs(tr1.pdgCode()) == kKPlus) { - v0.SetXYZM(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassPionCharged); } else { - v0.SetXYZM(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassPionCharged); - v1.SetXYZM(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassKaonCharged); + v0.SetCoordinates(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassPionCharged); + v1.SetCoordinates(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassKaonCharged); } if (!tr1.isPhysicalPrimary() || !tr2.isPhysicalPrimary()) continue; @@ -1255,7 +1284,7 @@ struct SginclusivePhiKstarSD { if (tr1.has_mothers() && tr2.has_mothers()) { for (const auto& mother : tr1.mothers_as()) { if (std::abs(mother.pdgCode()) == o2::constants::physics::Pdg::kK0Star892) { - vkstar.SetXYZM(mother.px(), mother.py(), mother.pz(), o2::constants::physics::MassK0Star892); + vkstar.SetCoordinates(mother.px(), mother.py(), mother.pz(), o2::constants::physics::MassK0Star892); registry.get(HIST("MC/accMPtRap_kstar_G"))->Fill(vkstar.M(), vkstar.Pt(), vkstar.Rapidity(), 1.); flag = true; } @@ -1279,8 +1308,8 @@ struct SginclusivePhiKstarSD { if (std::abs(tr1.pdgCode()) != kKPlus || std::abs(tr2.pdgCode()) != kKPlus) continue; - v0.SetXYZM(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassKaonCharged); - v1.SetXYZM(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassKaonCharged); + v0.SetCoordinates(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassKaonCharged); + v1.SetCoordinates(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassKaonCharged); if (tr1.pdgCode() == tr2.pdgCode()) continue; v01 = v0 + v1; @@ -1296,7 +1325,7 @@ struct SginclusivePhiKstarSD { if (tr1.has_mothers() && tr2.has_mothers()) { for (const auto& mother : tr1.mothers_as()) { if (std::abs(mother.pdgCode()) == o2::constants::physics::Pdg::kPhi) { - vphi.SetXYZM(mother.px(), mother.py(), mother.pz(), o2::constants::physics::MassPhi); + vphi.SetCoordinates(mother.px(), mother.py(), mother.pz(), o2::constants::physics::MassPhi); registry.get(HIST("MC/accMPtRap_phi_G"))->Fill(vphi.M(), vphi.Pt(), vphi.Rapidity(), 1.); flag = true; } @@ -1349,8 +1378,8 @@ struct SginclusivePhiKstarSD { std::vector parameters = {pvCut, dcazCut, dcaxyCut, tpcChi2Cut, tpcNClsFindableCut, itsChi2Cut, etaCut, ptCut}; int truegapSide = sgSelector.trueGap(collision, fitCut[0], fitCut[1], fitCut[2], zdcCut); registry.get(HIST("Reco/Stat"))->Fill(4.0, 1.); - Partition pvContributors = aod::udtrack::isPVContributor == true; - pvContributors.bindTable(tracks); + // Partition pvContributors = aod::udtrack::isPVContributor == true; + // pvContributors.bindTable(tracks); if (std::abs(collision.posZ()) > vzCut) return; if (std::abs(collision.occupancyInTime()) > occCut) @@ -1358,16 +1387,16 @@ struct SginclusivePhiKstarSD { registry.get(HIST("Reco/Stat"))->Fill(truegapSide, 1.); if (truegapSide != gapsideMC) return; - registry.get(HIST("Reco/nPVContributors"))->Fill(pvContributors.size(), 1.); - TLorentzVector vphi; - TLorentzVector vkstar; - TLorentzVector v0; - TLorentzVector vr0; - TLorentzVector vr1; - TLorentzVector vr01; - TLorentzVector vr0g; - TLorentzVector vr1g; - TLorentzVector vr01g; + // registry.get(HIST("Reco/nPVContributors"))->Fill(pvContributors.size(), 1.); + ROOT::Math::PxPyPzMVector vphi; + ROOT::Math::PxPyPzMVector vkstar; + ROOT::Math::PxPyPzMVector v0; + ROOT::Math::PxPyPzMVector vr0; + ROOT::Math::PxPyPzMVector vr1; + ROOT::Math::PxPyPzMVector vr01; + ROOT::Math::PxPyPzMVector vr0g; + ROOT::Math::PxPyPzMVector vr1g; + ROOT::Math::PxPyPzMVector vr01g; int t1 = 0; if (truegapSide == 0) { registry.fill(HIST("V0A_0_mc"), collision.totalFV0AmplitudeA()); @@ -1401,7 +1430,7 @@ struct SginclusivePhiKstarSD { registry.get(HIST("Reco/tr_chi2ncl_2"))->Fill(tr1.tpcChi2NCl(), 1.); registry.get(HIST("Reco/tr_tpcnclfind_2"))->Fill(tr1.tpcNClsFindable(), 1.); registry.get(HIST("Reco/tr_itsChi2NCl_2"))->Fill(tr1.itsChi2NCl(), 1.); - v0.SetXYZM(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassPionCharged); + v0.SetCoordinates(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassPionCharged); registry.fill(HIST("tpc_dedx_mc"), v0.P(), tr1.tpcSignal()); registry.fill(HIST("tof_beta_mc"), v0.P(), tr1.beta()); @@ -1421,7 +1450,7 @@ struct SginclusivePhiKstarSD { } t1++; - vr0.SetXYZM(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassKaonCharged); + vr0.SetCoordinates(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassKaonCharged); registry.get(HIST("Reco/trpt"))->Fill(vr0.Pt(), 1.); registry.get(HIST("Reco/treta_k"))->Fill(vr0.Eta(), 1.); if (!selectionPIDKaon1(tr1)) @@ -1437,7 +1466,7 @@ struct SginclusivePhiKstarSD { if (t2 > t1) { if (!selectionPIDKaon1(tr2)) continue; - vr1.SetXYZM(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassKaonCharged); + vr1.SetCoordinates(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassKaonCharged); auto mcPart2 = tr2.udMcParticle(); if (std::abs(mcPart2.globalIndex() - mcPart1.globalIndex()) != 1) continue; @@ -1452,7 +1481,7 @@ struct SginclusivePhiKstarSD { if (mcPart1.has_mothers() && mcPart2.has_mothers()) { for (const auto& mother : mcPart1.mothers_as()) { if (std::abs(mother.pdgCode()) == o2::constants::physics::Pdg::kPhi) { - vphi.SetXYZM(mother.px(), mother.py(), mother.pz(), o2::constants::physics::MassPhi); + vphi.SetCoordinates(mother.px(), mother.py(), mother.pz(), o2::constants::physics::MassPhi); registry.get(HIST("MC/accMPtRap_phi_T"))->Fill(vphi.M(), vphi.Pt(), vphi.Rapidity(), 1.); flag = true; } @@ -1463,8 +1492,8 @@ struct SginclusivePhiKstarSD { } } } - vr0g.SetXYZM(mcPart1.px(), mcPart1.py(), mcPart1.pz(), o2::constants::physics::MassKaonCharged); - vr1g.SetXYZM(mcPart2.px(), mcPart2.py(), mcPart2.pz(), o2::constants::physics::MassKaonCharged); + vr0g.SetCoordinates(mcPart1.px(), mcPart1.py(), mcPart1.pz(), o2::constants::physics::MassKaonCharged); + vr1g.SetCoordinates(mcPart2.px(), mcPart2.py(), mcPart2.pz(), o2::constants::physics::MassKaonCharged); vr01g = vr0g + vr1g; vr01 = vr0 + vr1; @@ -1499,10 +1528,10 @@ struct SginclusivePhiKstarSD { if (tr1.sign() * tr2.sign() > 0) continue; - vr0.SetXYZM(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassPionCharged); - vr1.SetXYZM(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassKaonCharged); - vr0g.SetXYZM(mcPart1.px(), mcPart1.py(), mcPart1.pz(), o2::constants::physics::MassPionCharged); - vr1g.SetXYZM(mcPart2.px(), mcPart2.py(), mcPart2.pz(), o2::constants::physics::MassKaonCharged); + vr0.SetCoordinates(tr1.px(), tr1.py(), tr1.pz(), o2::constants::physics::MassPionCharged); + vr1.SetCoordinates(tr2.px(), tr2.py(), tr2.pz(), o2::constants::physics::MassKaonCharged); + vr0g.SetCoordinates(mcPart1.px(), mcPart1.py(), mcPart1.pz(), o2::constants::physics::MassPionCharged); + vr1g.SetCoordinates(mcPart2.px(), mcPart2.py(), mcPart2.pz(), o2::constants::physics::MassKaonCharged); vr01g = vr0g + vr1g; vr01 = vr0 + vr1; if (!trackselector(tr1, parameters) || !trackselector(tr2, parameters)) { @@ -1514,7 +1543,7 @@ struct SginclusivePhiKstarSD { if (mcPart1.has_mothers() && mcPart2.has_mothers()) { for (const auto& mother : mcPart1.mothers_as()) { if (std::abs(mother.pdgCode()) == o2::constants::physics::Pdg::kK0Star892) { - vkstar.SetXYZM(mother.px(), mother.py(), mother.pz(), o2::constants::physics::MassK0Star892); + vkstar.SetCoordinates(mother.px(), mother.py(), mother.pz(), o2::constants::physics::MassK0Star892); registry.get(HIST("MC/accMPtRap_kstar_T"))->Fill(vkstar.M(), vkstar.Pt(), vkstar.Rapidity(), 1.); flag = true; } diff --git a/PWGUD/Tasks/upcForward.cxx b/PWGUD/Tasks/upcForward.cxx index 3a3c6ec722d..16571bc28ac 100644 --- a/PWGUD/Tasks/upcForward.cxx +++ b/PWGUD/Tasks/upcForward.cxx @@ -14,16 +14,19 @@ o2-analysis-timestamp| o2-analysis-upc-forward | o2-analysis-event-selection -- for now AO2D.root I am using is alien:///alice/data/2015/LHC15o/000246392/pass5_lowIR/PWGZZ/Run3_Conversion/148_20210304-0829_child_1/AOD/001/AO2D.root */ -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/DataModel/EventSelection.h" -#include "iostream" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "TLorentzVector.h" #include #include #include -#include "TLorentzVector.h" -#include "Common/CCDB/TriggerAliases.h" + +#include using namespace std; using namespace o2; diff --git a/PWGUD/Tasks/upcPhotonuclearAnalysisJMG.cxx b/PWGUD/Tasks/upcPhotonuclearAnalysisJMG.cxx index 81834492eca..7d474f26513 100644 --- a/PWGUD/Tasks/upcPhotonuclearAnalysisJMG.cxx +++ b/PWGUD/Tasks/upcPhotonuclearAnalysisJMG.cxx @@ -11,10 +11,12 @@ /// /// \brief /// \author Josué Martínez García, josuem@cern.ch +/// \file upcPhotonuclearAnalysisJMG.cxx -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include "PWGCF/Core/CorrelationContainer.h" +#include "PWGUD/Core/UPCPairCuts.h" +#include "PWGUD/Core/UPCTauCentralBarrelHelperRL.h" +#include "PWGUD/DataModel/UDTables.h" #include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/TrackSelection.h" @@ -23,37 +25,97 @@ #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "PWGUD/DataModel/UDTables.h" -#include "PWGUD/Core/UPCTauCentralBarrelHelperRL.h" +#include "CCDB/BasicCCDBManager.h" +#include "CommonConstants/MathConstants.h" +#include "DataFormatsParameters/GRPObject.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" + +#include + +#include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace constants::math; +namespace o2::aod +{ +namespace tree +{ +DECLARE_SOA_COLUMN(PtSideA, ptSideA, std::vector); +DECLARE_SOA_COLUMN(RapSideA, rapSideA, std::vector); +DECLARE_SOA_COLUMN(PhiSideA, phiSideA, std::vector); +DECLARE_SOA_COLUMN(TPCSignalSideA, tpcSignalSideA, std::vector); +DECLARE_SOA_COLUMN(TOFSignalSideA, tofSignalSideA, std::vector); +DECLARE_SOA_COLUMN(TPCNSigmaPiSideA, tpcNSigmaPiSideA, std::vector); +DECLARE_SOA_COLUMN(TOFNSigmaPiSideA, tofNSigmaPiSideA, std::vector); +DECLARE_SOA_COLUMN(TPCNSigmaKaSideA, tpcNSigmaKaSideA, std::vector); +DECLARE_SOA_COLUMN(TOFNSigmaKaSideA, tofNSigmaKaSideA, std::vector); +DECLARE_SOA_COLUMN(PtSideC, ptSideC, std::vector); +DECLARE_SOA_COLUMN(RapSideC, rapSideC, std::vector); +DECLARE_SOA_COLUMN(PhiSideC, phiSideC, std::vector); +DECLARE_SOA_COLUMN(TPCSignalSideC, tpcSignalSideC, std::vector); +DECLARE_SOA_COLUMN(TOFSignalSideC, tofSignalSideC, std::vector); +DECLARE_SOA_COLUMN(TPCNSigmaPiSideC, tpcNSigmaPiSideC, std::vector); +DECLARE_SOA_COLUMN(TOFNSigmaPiSideC, tofNSigmaPiSideC, std::vector); +DECLARE_SOA_COLUMN(TPCNSigmaKaSideC, tpcNSigmaKaSideC, std::vector); +DECLARE_SOA_COLUMN(TOFNSigmaKaSideC, tofNSigmaKaSideC, std::vector); +DECLARE_SOA_COLUMN(NchSideA, nchSideA, int); +DECLARE_SOA_COLUMN(MultiplicitySideA, multiplicitySideA, int); +DECLARE_SOA_COLUMN(NchSideC, nchSideC, int); +DECLARE_SOA_COLUMN(MultiplicitySideC, multiplicitySideC, int); +} // namespace tree +DECLARE_SOA_TABLE(TREE, "AOD", "Tree", + tree::PtSideA, + tree::RapSideA, + tree::PhiSideA, + tree::TPCSignalSideA, + tree::TOFSignalSideA, + tree::TPCNSigmaPiSideA, + tree::TOFNSigmaPiSideA, + tree::TPCNSigmaKaSideA, + tree::TOFNSigmaKaSideA, + tree::PtSideC, + tree::RapSideC, + tree::PhiSideC, + tree::TPCSignalSideC, + tree::TOFSignalSideC, + tree::TPCNSigmaPiSideC, + tree::TOFNSigmaPiSideC, + tree::TPCNSigmaKaSideC, + tree::TOFNSigmaKaSideC, + tree::NchSideA, + tree::MultiplicitySideA, + tree::NchSideC, + tree::MultiplicitySideC); +} // namespace o2::aod + +static constexpr float CFGPairCutDefaults[1][5] = {{-1, -1, -1, -1, -1}}; struct upcPhotonuclearAnalysisJMG { + Produces tree; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; // Declare configurables on events/collisions - Configurable cutMyPosZMin{"cutMyPosZMin", -10., {"My collision cut"}}; - Configurable cutMyPosZMax{"cutMyPosZMax", 10., {"My collision cut"}}; - Configurable cutMyTimeZNA{"cutMyTimeZNA", 2., {"My collision cut"}}; - Configurable cutMyTimeZNC{"cutMyTimeZNC", 2., {"My collision cut"}}; + Configurable nEventsMixed{"nEventsMixed", 3, {"Events to be Mixed"}}; + Configurable factorEventsMixed{"factorEventsMixed", 100, {"factorEventsMixed to events mixed"}}; + Configurable myZVtxCut{"myZVtxCut", 10., {"My collision cut"}}; + Configurable myTimeZNACut{"myTimeZNACut", 2., {"My collision cut"}}; + Configurable myTimeZNCCut{"myTimeZNCCut", 2., {"My collision cut"}}; // Declare configurables on side A gap Configurable cutAGapMyEnergyZNAMax{"cutAGapMyEnergyZNAMax", 0., {"My collision cut. A Gap"}}; - Configurable cutAGapMyAmplitudeFT0AMax{"cutAGapMyAmplitudeFT0AMax", 200., {"My collision cut. A Gap"}}; + // Configurable cutAGapMyAmplitudeFT0AMax{"cutAGapMyAmplitudeFT0AMax", 200., {"My collision cut. A Gap"}}; Configurable cutAGapMyEnergyZNCMin{"cutAGapMyEnergyZNCMin", 1., {"My collision cut. A Gap"}}; - Configurable cutAGapMyAmplitudeFT0CMin{"cutAGapMyAmplitudeFT0CMin", 0., {"My collision cut. A Gap"}}; + // Configurable cutAGapMyAmplitudeFT0CMin{"cutAGapMyAmplitudeFT0CMin", 0., {"My collision cut. A Gap"}}; // Declare configurables on side C gap Configurable cutCGapMyEnergyZNAMin{"cutCGapMyEnergyZNAMin", 1., {"My collision cut. C Gap"}}; - Configurable cutCGapMyAmplitudeFT0AMin{"cutCGapMyAmplitudeFT0AMin", 0., {"My collision cut. A Gap"}}; + // Configurable cutCGapMyAmplitudeFT0AMin{"cutCGapMyAmplitudeFT0AMin", 0., {"My collision cut. A Gap"}}; Configurable cutCGapMyEnergyZNCMax{"cutCGapMyEnergyZNCMax", 0., {"My collision cut. C Gap"}}; - Configurable cutCGapMyAmplitudeFT0CMax{"cutCGapMyAmplitudeFT0CMax", 200., {"My collision cut. A Gap"}}; - // Declare configurables on both side gap - Configurable cutBothGapMyEnergyZNAMax{"cutBothGapMyEnergyZNAMax", 0., {"My collision cut. Both Gap"}}; - Configurable cutBothGapMyAmplitudeFT0AMax{"cutBothGapMyAmplitudeFT0AMax", 200., {"My collision cut. A Gap"}}; - Configurable cutBothGapMyEnergyZNCMax{"cutBothGapMyEnergyZNCMax", 0., {"My collision cut. Both Gap"}}; - Configurable cutBothGapMyAmplitudeFT0CMax{"cutBothGapMyAmplitudeFT0CMax", 200., {"My collision cut. A Gap"}}; + // Configurable cutCGapMyAmplitudeFT0CMax{"cutCGapMyAmplitudeFT0CMax", 200., {"My collision cut. A Gap"}}; // Declare configurables on tracks Configurable cutMyptMin{"cutMyptMin", 0.15, {"My Track cut"}}; Configurable cutMyptMax{"cutMyptMax", 10., {"My Track cut"}}; @@ -72,9 +134,36 @@ struct upcPhotonuclearAnalysisJMG { Configurable cutMyTPCNClsCrossedRowsOverNClsFindableMin{"cutMyTPCNClsCrossedRowsOverNClsFindableMin", 0.8f, {"My Track cut"}}; Configurable cutMyTPCNClsOverFindableNClsMin{"cutMyTPCNClsOverFindableNClsMin", 0.5f, {"My Track cut"}}; Configurable cutMyTPCChi2NclMax{"cutMyTPCChi2NclMax", 4.f, {"My Track cut"}}; + Configurable> cfgPairCut{"cfgPairCut", + {CFGPairCutDefaults[0], + 5, + {"Photon", "K0", "Lambda", "Phi", "Rho"}}, + "Pair cuts on various particles"}; + Configurable cfgTwoTrackCut{"cfgTwoTrackCut", -1, {"Two track cut"}}; + ConfigurableAxis axisVertex{"axisVertex", {10, -10, 10}, "vertex axis for histograms"}; + ConfigurableAxis axisDeltaPhi{"axisDeltaPhi", {72, -constants::math::PIHalf, constants::math::PIHalf * 3}, "delta phi axis for histograms"}; + ConfigurableAxis axisDeltaEta{"axisDeltaEta", {40, -2, 2}, "delta eta axis for histograms"}; + ConfigurableAxis axisPtTrigger{"axisPtTrigger", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "pt trigger axis for histograms"}; + ConfigurableAxis axisPtAssoc{"axisPtAssoc", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0}, "pt associated axis for histograms"}; + ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110.1}, "multiplicity / multiplicity axis for histograms"}; + ConfigurableAxis axisVertexEfficiency{"axisVertexEfficiency", {10, -10, 10}, "vertex axis for efficiency histograms"}; + ConfigurableAxis axisEtaEfficiency{"axisEtaEfficiency", {20, -1.0, 1.0}, "eta axis for efficiency histograms"}; + ConfigurableAxis axisPtEfficiency{"axisPtEfficiency", {VARIABLE_WIDTH, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0}, "pt axis for efficiency histograms"}; + + Filter collisionZVtxFilter = nabs(aod::collision::posZ) < myZVtxCut; + Filter collisionZNTimeFilter = nabs(aod::udzdc::timeZNA) < myTimeZNACut && nabs(aod::udzdc::timeZNC) < myTimeZNCCut; + + using FullSGUDCollision = soa::Filtered>; + using FullUDTracks = soa::Join; + + // Output definitions + OutputObj sameGapSideA{"sameEventGapSideA"}; + OutputObj mixedGapSideA{"mixedEventGapSideA"}; + OutputObj sameGapSideC{"sameEventGapSideC"}; + OutputObj mixedGapSideC{"mixedEventGapSideC"}; - using FullSGUDCollision = soa::Join::iterator; - using FullUDTracks = soa::Join; + UPCPairCuts mPairCuts; + bool doPairCuts = false; void init(InitContext const&) { @@ -83,9 +172,9 @@ struct upcPhotonuclearAnalysisJMG { const AxisSpec axisPt{402, -0.05, 20.05}; const AxisSpec axisP{402, -10.05, 10.05}; const AxisSpec axisTPCSignal{802, -0.05, 400.05}; - const AxisSpec axisPhi{64, -2 * o2::constants::math::PI, 2 * o2::constants::math::PI}; + const AxisSpec axisPhi{64, -2 * PI, 2 * PI}; const AxisSpec axisEta{50, -1.2, 1.2}; - const AxisSpec axisNch{101, -0.5, 100.5}; + const AxisSpec axisNch{201, -0.5, 200.5}; const AxisSpec axisZNEnergy{1002, -0.5, 500.5}; const AxisSpec axisZNTime{21, -10.5, 10.5}; const AxisSpec axisFT0Amplitud{201, -0.5, 200.5}; @@ -93,6 +182,21 @@ struct upcPhotonuclearAnalysisJMG { const AxisSpec axisChi2NCls{100, 0, 50}; const AxisSpec axisTPCNClsCrossedRowsMin{100, -0.05, 2.05}; + histos.add("yields", "multiplicity vs pT vs eta", {HistType::kTH3F, {{100, 0, 100, "multiplicity"}, {40, 0, 20, "p_{T}"}, {100, -2, 2, "#eta"}}}); + histos.add("etaphi", "multiplicity vs eta vs phi", {HistType::kTH3F, {{100, 0, 100, "multiplicity"}, {100, -2, 2, "#eta"}, {200, 0, 2 * PI, "#varphi"}}}); + + const int maxMixBin = axisMultiplicity->size() * axisVertex->size(); + histos.add("eventcount", "bin", {HistType::kTH1F, {{maxMixBin + 2, -2.5, -0.5 + maxMixBin, "bin"}}}); + mPairCuts.setHistogramRegistry(&histos); + if (cfgPairCut->get("Photon") > 0 || cfgPairCut->get("K0") > 0 || cfgPairCut->get("Lambda") > 0 || + cfgPairCut->get("Phi") > 0 || cfgPairCut->get("Rho") > 0) { + mPairCuts.setPairCut(UPCPairCuts::Photon, cfgPairCut->get("Photon")); + mPairCuts.setPairCut(UPCPairCuts::K0, cfgPairCut->get("K0")); + mPairCuts.setPairCut(UPCPairCuts::Lambda, cfgPairCut->get("Lambda")); + mPairCuts.setPairCut(UPCPairCuts::Phi, cfgPairCut->get("Phi")); + mPairCuts.setPairCut(UPCPairCuts::Rho, cfgPairCut->get("Rho")); + doPairCuts = true; + } histos.add("Events/hCountCollisions", "0 total - 1 side A - 2 side C - 3 both side; Number of analysed collision; counts", kTH1F, {axisCollision}); // histos to selection gap in side A @@ -100,6 +204,7 @@ struct upcPhotonuclearAnalysisJMG { histos.add("Tracks/SGsideA/hTrackPhi", "#it{#phi} distribution; #it{#phi}; counts", kTH1F, {axisPhi}); histos.add("Tracks/SGsideA/hTrackEta", "#it{#eta} distribution; #it{#eta}; counts", kTH1F, {axisEta}); histos.add("Tracks/SGsideA/hTrackTPCSignnalP", "#it{TPC dE/dx vs p}; #it{p*charge}; #it{TPC dE/dx}", kTH2F, {axisP, axisTPCSignal}); + histos.add("Tracks/SGsideA/hTrackTOFSignnalP", "#it{TOF signal vs p}; #it{p*charge}; #it{TOF signal}", kTH2F, {axisP, axisTPCSignal}); histos.add("Tracks/SGsideA/hTrackITSNCls", "#it{N Clusters ITS} distribution; #it{N Clusters ITS}; counts", kTH1F, {axisNCls}); histos.add("Tracks/SGsideA/hTrackITSChi2NCls", "#it{N Clusters Chi2 ITS} distribution; #it{N Clusters Chi2 ITS}; counts", kTH1F, {axisChi2NCls}); histos.add("Tracks/SGsideA/hTrackNClsCrossedRowsOverNClsFindable", "#it{NClsCrossedRows/FindableNCls} distribution in TPC; #it{NClsCrossedRows/FindableNCls}; counts", kTH1F, {axisTPCNClsCrossedRowsMin}); @@ -112,8 +217,9 @@ struct upcPhotonuclearAnalysisJMG { histos.add("Tracks/SGsideA/hTrackTPCChi2NCls", "#it{N Clusters Chi2 TPC} distribution; #it{N Clusters Chi2 TPC}; counts", kTH1F, {axisChi2NCls}); histos.add("Tracks/SGsideA/hTrackITSNClsTPCCls", "#it{ITS Clusters vs TPC Clusters}; #it{TPC Clusters}; #it{ITS Clusters}", kTH2F, {axisNCls, axisNCls}); - histos.add("Events/SGsideA/hTrackZVtx", "vertex in z; z (cm); counts", kTH1F, {axisZvtx}); + histos.add("Events/SGsideA/hZVtx", "vertex in z; z (cm); counts", kTH1F, {axisZvtx}); histos.add("Events/SGsideA/hNch", "#it{Charged Tracks Multiplicity} distribution; #it{Charged Tracks Multiplicity}; counts", kTH1F, {axisNch}); + histos.add("Events/SGsideA/hMultiplicity", "#it{Multiplicity} distribution; #it{Multiplicity}; counts", kTH1F, {axisNch}); histos.add("Events/SGsideA/hPtVSNch", "#it{ #LT p_{T} #GT } vs #it{Charged Tracks Multiplicity}; #it{Charged Tracks Multiplicity}; #it{ #LT p_{T} #GT }", kTH2F, {axisNch, axisPt}); histos.add("Events/SGsideA/hEnergyZNA", "Energy in side A distribution; Energy in side A; counts", kTH1F, {axisZNEnergy}); histos.add("Events/SGsideA/hEnergyZNC", "Energy in side C distribution; Energy in side C; counts", kTH1F, {axisZNEnergy}); @@ -129,6 +235,7 @@ struct upcPhotonuclearAnalysisJMG { histos.add("Tracks/SGsideC/hTrackPhi", "#it{#phi} distribution; #it{#phi}; counts", kTH1F, {axisPhi}); histos.add("Tracks/SGsideC/hTrackEta", "#it{#eta} distribution; #it{#eta}; counts", kTH1F, {axisEta}); histos.add("Tracks/SGsideC/hTrackTPCSignnalP", "#it{TPC dE/dx vs p}; #it{p*charge}; #it{TPC dE/dx}", kTH2F, {axisP, axisTPCSignal}); + histos.add("Tracks/SGsideC/hTrackTOFSignnalP", "#it{TOF signal vs p}; #it{p*charge}; #it{TOF signal}", kTH2F, {axisP, axisTPCSignal}); histos.add("Tracks/SGsideC/hTrackITSNCls", "#it{N Clusters ITS} distribution; #it{N Clusters ITS}; counts", kTH1F, {axisNCls}); histos.add("Tracks/SGsideC/hTrackITSChi2NCls", "#it{N Clusters Chi2 ITS} distribution; #it{N Clusters Chi2 ITS}; counts", kTH1F, {axisChi2NCls}); histos.add("Tracks/SGsideC/hTrackNClsCrossedRowsOverNClsFindable", "#it{NClsCrossedRows/FindableNCls} distribution in TPC; #it{NClsCrossedRows/FindableNCls}; counts", kTH1F, {axisTPCNClsCrossedRowsMin}); @@ -141,8 +248,9 @@ struct upcPhotonuclearAnalysisJMG { histos.add("Tracks/SGsideC/hTrackTPCChi2NCls", "#it{N Clusters Chi2 TPC} distribution; #it{N Clusters Chi2 TPC}; counts", kTH1F, {axisChi2NCls}); histos.add("Tracks/SGsideC/hTrackITSNClsTPCCls", "#it{ITS Clusters vs TPC Clusters}; #it{TPC Clusters}; #it{ITS Clusters}", kTH2F, {axisNCls, axisNCls}); - histos.add("Events/SGsideC/hTrackZVtx", "vertex in z; z (cm); counts", kTH1F, {axisZvtx}); + histos.add("Events/SGsideC/hZVtx", "vertex in z; z (cm); counts", kTH1F, {axisZvtx}); histos.add("Events/SGsideC/hNch", "#it{Charged Tracks Multiplicity} distribution; #it{Charged Tracks Multiplicity}; counts", kTH1F, {axisNch}); + histos.add("Events/SGsideC/hMultiplicity", "#it{Multiplicity} distribution; #it{Multiplicity}; counts", kTH1F, {axisNch}); histos.add("Events/SGsideC/hPtVSNch", "#it{ #LT p_{T} #GT } vs #it{Charged Tracks Multiplicity}; #it{Charged Tracks Multiplicity}; #it{ #LT p_{T} #GT }", kTH2F, {axisNch, axisPt}); histos.add("Events/SGsideC/hEnergyZNA", "Energy in side A distribution; Energy in side A; counts", kTH1F, {axisZNEnergy}); histos.add("Events/SGsideC/hEnergyZNC", "Energy in side C distribution; Energy in side C; counts", kTH1F, {axisZNEnergy}); @@ -153,43 +261,34 @@ struct upcPhotonuclearAnalysisJMG { histos.add("Events/SGsideC/hAmplitudFT0A", "Amplitud in side A distribution; Amplitud in side A; counts", kTH1F, {axisFT0Amplitud}); histos.add("Events/SGsideC/hAmplitudFT0C", "Amplitud in side C distribution; Amplitud in side C; counts", kTH1F, {axisFT0Amplitud}); - // histos to selection gap in both sides - histos.add("Tracks/SGsideBoth/hTrackPt", "#it{p_{T}} distribution; #it{p_{T}}; counts", kTH1F, {axisPt}); - histos.add("Tracks/SGsideBoth/hTrackPhi", "#it{#phi} distribution; #it{#phi}; counts", kTH1F, {axisPhi}); - histos.add("Tracks/SGsideBoth/hTrackEta", "#it{#eta} distribution; #it{#eta}; counts", kTH1F, {axisEta}); - histos.add("Tracks/SGsideBoth/hTrackTPCSignnalP", "#it{TPC dE/dx vs p}; #it{p*charge}; #it{TPC dE/dx}", kTH2F, {axisP, axisTPCSignal}); - histos.add("Tracks/SGsideBoth/hTrackITSNCls", "#it{N Clusters ITS} distribution; #it{N Clusters ITS}; counts", kTH1F, {axisNCls}); - histos.add("Tracks/SGsideBoth/hTrackITSChi2NCls", "#it{N Clusters Chi2 ITS} distribution; #it{N Clusters Chi2 ITS}; counts", kTH1F, {axisChi2NCls}); - histos.add("Tracks/SGsideBoth/hTrackNClsCrossedRowsOverNCls", "#it{NClsCrossedRows/FindableNCls} distribution in TPC; #it{NClsCrossedRows/FindableNCls}; counts", kTH1F, {axisTPCNClsCrossedRowsMin}); - histos.add("Tracks/SGsideBoth/hTrackTPCNClsCrossedRows", "#it{Number of crossed TPC Rows} distribution; #it{Number of crossed TPC Rows}; counts", kTH1F, {axisNCls}); - histos.add("Tracks/SGsideBoth/hTrackTPCNClsFindable", "#it{Findable TPC clusters for this track} distribution; #it{Findable TPC clusters for this track}; counts", kTH1F, {axisNCls}); - histos.add("Tracks/SGsideBoth/hTrackTPCChi2NCls", "#it{N Clusters Chi2 TPC} distribution; #it{N Clusters Chi2 TPC}; counts", kTH1F, {axisChi2NCls}); - histos.add("Tracks/SGsideBoth/hTrackITSNClsTPCCls", "#it{ITS Clusters vs TPC Clusters}; #it{TPC Clusters}; #it{ITS Clusters}", kTH2F, {axisNCls, axisNCls}); - - histos.add("Events/SGsideBoth/hTrackZVtx", "vertex in z; z (cm); counts", kTH1F, {axisZvtx}); - histos.add("Events/SGsideBoth/hNch", "#it{Charged Tracks Multiplicity} distribution; #it{Charged Tracks Multiplicity}; counts", kTH1F, {axisNch}); - histos.add("Events/SGsideBoth/hPtVSNch", "#it{ #LT p_{T} #GT } vs #it{Charged Tracks Multiplicity}; #it{Charged Tracks Multiplicity}; #it{ #LT p_{T} #GT }", kTH2F, {axisNch, axisPt}); - histos.add("Events/SGsideBoth/hEnergyZNA", "Energy in side A distribution; Energy in side A; counts", kTH1F, {axisZNEnergy}); - histos.add("Events/SGsideBoth/hEnergyZNC", "Energy in side C distribution; Energy in side C; counts", kTH1F, {axisZNEnergy}); - histos.add("Events/SGsideBoth/hEnergyRelationSides", "Energy in side A vs energy in side C; Energy in side A; Energy in side C", kTH2F, {axisZNEnergy, axisZNEnergy}); - histos.add("Events/SGsideBoth/hTimeZNA", "Time in side A distribution; Time in side A; counts", kTH1F, {axisZNTime}); - histos.add("Events/SGsideBoth/hTimeZNC", "Time in side C distribution; Time in side C; counts", kTH1F, {axisZNTime}); - histos.add("Events/SGsideBoth/hTimeRelationSides", "Time in side A vs time in side C; Time in side A; Time in side C", kTH2F, {axisZNTime, axisZNTime}); - histos.add("Events/SGsideBoth/hAmplitudFT0A", "Amplitud in side A distribution; Amplitud in side A; counts", kTH1F, {axisFT0Amplitud}); - histos.add("Events/SGsideBoth/hAmplitudFT0C", "Amplitud in side C distribution; Amplitud in side C; counts", kTH1F, {axisFT0Amplitud}); + std::vector corrAxis = {{axisDeltaEta, "#Delta#eta"}, + {axisPtAssoc, "p_{T} (GeV/c)"}, + {axisPtTrigger, "p_{T} (GeV/c)"}, + {axisMultiplicity, "multiplicity / multiplicity"}, + {axisDeltaPhi, "#Delta#varphi (rad)"}, + {axisVertex, "z-vtx (cm)"}}; + std::vector effAxis = {{axisEtaEfficiency, "#eta"}, + {axisEtaEfficiency, "#eta"}, + {axisPtEfficiency, "p_{T} (GeV/c)"}, + {axisVertexEfficiency, "z-vtx (cm)"}}; + sameGapSideA.setObject(new CorrelationContainer("sameEventGapSideA", "sameEventGapSideA", corrAxis, effAxis, {})); + mixedGapSideA.setObject(new CorrelationContainer("mixedEventGapSideA", "mixedEventGapSideA", corrAxis, effAxis, {})); + sameGapSideC.setObject(new CorrelationContainer("sameEventGapSideC", "sameEventGapSideC", corrAxis, effAxis, {})); + mixedGapSideC.setObject(new CorrelationContainer("mixedEventGapSideC", "mixedEventGapSideC", corrAxis, effAxis, {})); } - template - bool isGlobalCollisionCut(C const& collision) - { - if (collision.posZ() < cutMyPosZMin || cutMyPosZMax < collision.posZ()) { - return false; - } - if ((std::abs(collision.timeZNA()) < cutMyTimeZNA && std::abs(collision.timeZNC()) < cutMyTimeZNC) == false) { - return false; - } - return true; - } + std::vector vtxBinsEdges{VARIABLE_WIDTH, -10.0f, -7.0f, -5.0f, -2.5f, 0.0f, 2.5f, 5.0f, 7.0f, 10.0f}; + std::vector gapSideBinsEdges{VARIABLE_WIDTH, -0.5, 0.5, 1.5}; + + SliceCache cache; + int countGapA = 0; + int countGapC = 0; + + // Binning only on PosZ without multiplicity + // using BinningType = ColumnBinningPolicy; + using BinningType = ColumnBinningPolicy; + BinningType bindingOnVtx{{vtxBinsEdges, gapSideBinsEdges}, true}; + SameKindPair pairs{bindingOnVtx, nEventsMixed, -1, &cache}; template bool isCollisionCutSG(CSG const& collision, int SideGap) @@ -199,25 +298,17 @@ struct upcPhotonuclearAnalysisJMG { if ((collision.energyCommonZNA() < cutAGapMyEnergyZNAMax && collision.energyCommonZNC() >= cutAGapMyEnergyZNCMin) == false) { // 0n - A side && Xn - C Side return false; } - if ((collision.totalFT0AmplitudeA() < cutAGapMyAmplitudeFT0AMax && collision.totalFT0AmplitudeC() >= cutAGapMyAmplitudeFT0CMin) == false) { - return false; - } + // if ((collision.totalFT0AmplitudeA() < cutAGapMyAmplitudeFT0AMax && collision.totalFT0AmplitudeC() >= cutAGapMyAmplitudeFT0CMin) == false) { + // return false; + // } break; case 1: // Gap in C side if ((collision.energyCommonZNA() >= cutCGapMyEnergyZNAMin && collision.energyCommonZNC() < cutCGapMyEnergyZNCMax) == false) { // Xn - A side && 0n - C Side return false; } - if ((collision.totalFT0AmplitudeA() >= cutCGapMyAmplitudeFT0AMin && collision.totalFT0AmplitudeC() < cutCGapMyAmplitudeFT0CMax) == false) { - return false; - } - break; - case 2: // Gap in Both Sides - if ((collision.energyCommonZNA() < cutBothGapMyEnergyZNAMax && collision.energyCommonZNC() < cutBothGapMyEnergyZNCMax) == false) { // 0n - A side && 0n - C Side - return false; - } - if ((collision.totalFT0AmplitudeA() < cutBothGapMyAmplitudeFT0AMax && collision.totalFT0AmplitudeC() < cutBothGapMyAmplitudeFT0CMax) == false) { - return false; - } + // if ((collision.totalFT0AmplitudeA() >= cutCGapMyAmplitudeFT0AMin && collision.totalFT0AmplitudeC() < cutCGapMyAmplitudeFT0CMax) == false) { + // return false; + // } break; } return true; @@ -281,19 +372,68 @@ struct upcPhotonuclearAnalysisJMG { return true; } - void processSG(FullSGUDCollision const& reconstructedCollision, FullUDTracks const& reconstructedTracks) + template + void fillQAUD(const TTracks tracks) + { + for (const auto& track : tracks) { + histos.fill(HIST("yields"), tracks.size(), track.pt(), eta(track.px(), track.py(), track.pz())); + histos.fill(HIST("etaphi"), tracks.size(), eta(track.px(), track.py(), track.pz()), phi(track.px(), track.py())); + } + } + + template + bool fillCollisionUD(TTarget target, float multiplicity) + { + target->fillEvent(multiplicity, CorrelationContainer::kCFStepAll); + target->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); + return true; + } + + template + void fillCorrelationsUD(TTarget target, const TTracks tracks1, const TTracks tracks2, float multiplicity, float posZ) + { + multiplicity = tracks1.size(); + for (const auto& track1 : tracks1) { + if (isTrackCut(track1) == false) { + continue; + } + target->getTriggerHist()->Fill(CorrelationContainer::kCFStepReconstructed, track1.pt(), multiplicity, posZ, 1.0); + for (const auto& track2 : tracks2) { + if (track1 == track2) { + continue; + } + if (isTrackCut(track2) == false) { + continue; + } + if (doPairCuts && mPairCuts.conversionCuts(track1, track2)) { + continue; + } + float deltaPhi = phi(track1.px(), track1.py()) - phi(track2.px(), track2.py()); + if (deltaPhi > 1.5f * PI) { + deltaPhi -= TwoPI; + } + if (deltaPhi < -PIHalf) { + deltaPhi += TwoPI; + } + target->getPairHist()->Fill(CorrelationContainer::kCFStepReconstructed, eta(track1.px(), track1.py(), track1.pz()) - eta(track2.px(), track2.py(), track2.pz()), track2.pt(), track1.pt(), multiplicity, deltaPhi, posZ, 1.0); + } + } + } + + void processSG(FullSGUDCollision::iterator const& reconstructedCollision, FullUDTracks const& reconstructedTracks) { histos.fill(HIST("Events/hCountCollisions"), 0); - int SGside = reconstructedCollision.gapSide(); + int sgSide = reconstructedCollision.gapSide(); int nTracksCharged = 0; float sumPt = 0; + std::vector vTrackPtSideA, vTrackEtaSideA, vTrackPhiSideA, vTrackTPCSignalSideA, vTrackTOFSignalSideA, vTrackTPCNSigmaPiSideA, vTrackTOFNSigmaPiSideA, vTrackTPCNSigmaKaSideA, vTrackTOFNSigmaKaSideA; + std::vector vTrackPtSideC, vTrackEtaSideC, vTrackPhiSideC, vTrackTPCSignalSideC, vTrackTOFSignalSideC, vTrackTPCNSigmaPiSideC, vTrackTOFNSigmaPiSideC, vTrackTPCNSigmaKaSideC, vTrackTOFNSigmaKaSideC; - if (isGlobalCollisionCut(reconstructedCollision) == false) { - return; - } + int nTracksChargedSideA(-222), nTracksChargedSideC(-222); + int multiplicitySideA(-222), multiplicitySideC(-222); - switch (SGside) { - case 0: // for side A + switch (sgSide) { + case 0: // gap for side A if (isCollisionCutSG(reconstructedCollision, 0) == false) { return; } @@ -304,10 +444,10 @@ struct upcPhotonuclearAnalysisJMG { histos.fill(HIST("Events/SGsideA/hTimeZNA"), reconstructedCollision.timeZNA()); histos.fill(HIST("Events/SGsideA/hTimeZNC"), reconstructedCollision.timeZNC()); histos.fill(HIST("Events/SGsideA/hTimeRelationSides"), reconstructedCollision.timeZNA(), reconstructedCollision.timeZNC()); - histos.fill(HIST("Events/SGsideA/hTrackZVtx"), reconstructedCollision.posZ()); + histos.fill(HIST("Events/SGsideA/hZVtx"), reconstructedCollision.posZ()); histos.fill(HIST("Events/SGsideA/hAmplitudFT0A"), reconstructedCollision.totalFT0AmplitudeA()); histos.fill(HIST("Events/SGsideA/hAmplitudFT0C"), reconstructedCollision.totalFT0AmplitudeC()); - for (auto& track : reconstructedTracks) { + for (const auto& track : reconstructedTracks) { if (track.sign() == 1 || track.sign() == -1) { if (isTrackCut(track) == false) { continue; @@ -318,6 +458,16 @@ struct upcPhotonuclearAnalysisJMG { histos.fill(HIST("Tracks/SGsideA/hTrackPhi"), phi(track.px(), track.py())); histos.fill(HIST("Tracks/SGsideA/hTrackEta"), eta(track.px(), track.py(), track.pz())); histos.fill(HIST("Tracks/SGsideA/hTrackTPCSignnalP"), momentum(track.px(), track.py(), track.pz()) * track.sign(), track.tpcSignal()); + histos.fill(HIST("Tracks/SGsideA/hTrackTOFSignnalP"), momentum(track.px(), track.py(), track.pz()) * track.sign(), track.tofSignal()); + vTrackPtSideA.push_back(track.pt()); + vTrackEtaSideA.push_back(eta(track.px(), track.py(), track.pz())); + vTrackPhiSideA.push_back(phi(track.px(), track.py())); + vTrackTPCSignalSideA.push_back(track.tpcSignal()); + vTrackTOFSignalSideA.push_back(track.tofSignal()); + vTrackTPCNSigmaPiSideA.push_back(track.tpcNSigmaPi()); + vTrackTOFNSigmaPiSideA.push_back(track.tofNSigmaPi()); + vTrackTPCNSigmaKaSideA.push_back(track.tpcNSigmaKa()); + vTrackTOFNSigmaKaSideA.push_back(track.tofNSigmaKa()); histos.fill(HIST("Tracks/SGsideA/hTrackITSNCls"), track.itsNCls()); histos.fill(HIST("Tracks/SGsideA/hTrackITSChi2NCls"), track.itsChi2NCl()); @@ -333,10 +483,13 @@ struct upcPhotonuclearAnalysisJMG { } } histos.fill(HIST("Events/SGsideA/hNch"), nTracksCharged); + histos.fill(HIST("Events/SGsideA/hMultiplicity"), reconstructedTracks.size()); histos.fill(HIST("Events/SGsideA/hPtVSNch"), nTracksCharged, (sumPt / nTracksCharged)); + nTracksChargedSideA = nTracksCharged; + multiplicitySideA = reconstructedTracks.size(); nTracksCharged = sumPt = 0; break; - case 1: // for side C + case 1: // gap for side C if (isCollisionCutSG(reconstructedCollision, 1) == false) { return; } @@ -347,10 +500,10 @@ struct upcPhotonuclearAnalysisJMG { histos.fill(HIST("Events/SGsideC/hTimeZNA"), reconstructedCollision.timeZNA()); histos.fill(HIST("Events/SGsideC/hTimeZNC"), reconstructedCollision.timeZNC()); histos.fill(HIST("Events/SGsideC/hTimeRelationSides"), reconstructedCollision.timeZNA(), reconstructedCollision.timeZNC()); - histos.fill(HIST("Events/SGsideC/hTrackZVtx"), reconstructedCollision.posZ()); + histos.fill(HIST("Events/SGsideC/hZVtx"), reconstructedCollision.posZ()); histos.fill(HIST("Events/SGsideC/hAmplitudFT0A"), reconstructedCollision.totalFT0AmplitudeA()); histos.fill(HIST("Events/SGsideC/hAmplitudFT0C"), reconstructedCollision.totalFT0AmplitudeC()); - for (auto& track : reconstructedTracks) { + for (const auto& track : reconstructedTracks) { if (track.sign() == 1 || track.sign() == -1) { if (isTrackCut(track) == false) { continue; @@ -361,6 +514,16 @@ struct upcPhotonuclearAnalysisJMG { histos.fill(HIST("Tracks/SGsideC/hTrackPhi"), phi(track.px(), track.py())); histos.fill(HIST("Tracks/SGsideC/hTrackEta"), eta(track.px(), track.py(), track.pz())); histos.fill(HIST("Tracks/SGsideC/hTrackTPCSignnalP"), momentum(track.px(), track.py(), track.pz()) * track.sign(), track.tpcSignal()); + histos.fill(HIST("Tracks/SGsideC/hTrackTOFSignnalP"), momentum(track.px(), track.py(), track.pz()) * track.sign(), track.tofSignal()); + vTrackPtSideC.push_back(track.pt()); + vTrackEtaSideC.push_back(eta(track.px(), track.py(), track.pz())); + vTrackPhiSideC.push_back(phi(track.px(), track.py())); + vTrackTPCSignalSideC.push_back(track.tpcSignal()); + vTrackTOFSignalSideC.push_back(track.tofSignal()); + vTrackTPCNSigmaPiSideC.push_back(track.tpcNSigmaPi()); + vTrackTOFNSigmaPiSideC.push_back(track.tofNSigmaPi()); + vTrackTPCNSigmaKaSideC.push_back(track.tpcNSigmaKa()); + vTrackTOFNSigmaKaSideC.push_back(track.tofNSigmaKa()); histos.fill(HIST("Tracks/SGsideC/hTrackITSNCls"), track.itsNCls()); histos.fill(HIST("Tracks/SGsideC/hTrackITSChi2NCls"), track.itsChi2NCl()); @@ -376,54 +539,124 @@ struct upcPhotonuclearAnalysisJMG { } } histos.fill(HIST("Events/SGsideC/hNch"), nTracksCharged); + histos.fill(HIST("Events/SGsideC/hMultiplicity"), reconstructedTracks.size()); histos.fill(HIST("Events/SGsideC/hPtVSNch"), nTracksCharged, (sumPt / nTracksCharged)); + nTracksChargedSideC = nTracksCharged; + multiplicitySideC = reconstructedTracks.size(); nTracksCharged = sumPt = 0; break; - case 2: // for both sides - if (isCollisionCutSG(reconstructedCollision, 2) == false) { + default: + return; + break; + } + tree(vTrackPtSideA, vTrackEtaSideA, vTrackPhiSideA, vTrackTPCSignalSideA, vTrackTOFSignalSideA, vTrackTPCNSigmaPiSideA, vTrackTOFNSigmaPiSideA, vTrackTPCNSigmaKaSideA, vTrackTOFNSigmaKaSideA, vTrackPtSideC, vTrackEtaSideC, vTrackPhiSideC, vTrackTPCSignalSideA, vTrackTOFSignalSideA, vTrackTPCNSigmaPiSideA, vTrackTOFNSigmaPiSideA, vTrackTPCNSigmaKaSideA, vTrackTOFNSigmaKaSideA, nTracksChargedSideA, multiplicitySideA, nTracksChargedSideC, multiplicitySideC); + // nTracksChargedSideA = nTracksChargedSideC = multiplicitySideA = multiplicitySideC = 0; + } + PROCESS_SWITCH(upcPhotonuclearAnalysisJMG, processSG, "Process in UD tables", true); + + void processSame(FullSGUDCollision::iterator const& reconstructedCollision, FullUDTracks const& reconstructedTracks) + { + int sgSide = reconstructedCollision.gapSide(); + float multiplicity = 0; + + switch (sgSide) { + case 0: // gap for side A + if (isCollisionCutSG(reconstructedCollision, 0) == false) { return; } - histos.fill(HIST("Events/hCountCollisions"), 3); - histos.fill(HIST("Events/SGsideBoth/hEnergyZNA"), reconstructedCollision.energyCommonZNA()); - histos.fill(HIST("Events/SGsideBoth/hEnergyZNC"), reconstructedCollision.energyCommonZNC()); - histos.fill(HIST("Events/SGsideBoth/hEnergyRelationSides"), reconstructedCollision.energyCommonZNA(), reconstructedCollision.energyCommonZNC()); - histos.fill(HIST("Events/SGsideBoth/hTimeZNA"), reconstructedCollision.timeZNA()); - histos.fill(HIST("Events/SGsideBoth/hTimeZNC"), reconstructedCollision.timeZNC()); - histos.fill(HIST("Events/SGsideBoth/hTimeRelationSides"), reconstructedCollision.timeZNA(), reconstructedCollision.timeZNC()); - histos.fill(HIST("Events/SGsideBoth/hTrackZVtx"), reconstructedCollision.posZ()); - histos.fill(HIST("Events/SGsideBoth/hAmplitudFT0A"), reconstructedCollision.totalFT0AmplitudeA()); - histos.fill(HIST("Events/SGsideBoth/hAmplitudFT0C"), reconstructedCollision.totalFT0AmplitudeC()); - for (auto& track : reconstructedTracks) { - if (track.sign() == 1 || track.sign() == -1) { - if (isTrackCut(track) == false) { - continue; - } - nTracksCharged++; - sumPt += track.pt(); - histos.fill(HIST("Tracks/SGsideBoth/hTrackPt"), track.pt()); - histos.fill(HIST("Tracks/SGsideBoth/hTrackPhi"), phi(track.px(), track.py())); - histos.fill(HIST("Tracks/SGsideBoth/hTrackEta"), eta(track.px(), track.py(), track.pz())); - histos.fill(HIST("Tracks/SGsideBoth/hTrackTPCSignnalP"), momentum(track.px(), track.py(), track.pz()) * track.sign(), track.tpcSignal()); - - histos.fill(HIST("Tracks/SGsideBoth/hTrackITSNCls"), track.itsNCls()); - histos.fill(HIST("Tracks/SGsideBoth/hTrackITSChi2NCls"), track.itsChi2NCl()); - histos.fill(HIST("Tracks/SGsideBoth/hTrackNClsCrossedRowsOverNCls"), (static_cast(track.tpcNClsCrossedRows()) / static_cast(track.tpcNClsFindable()))); - histos.fill(HIST("Tracks/SGsideBoth/hTrackTPCNClsCrossedRows"), track.tpcNClsCrossedRows()); - histos.fill(HIST("Tracks/SGsideBoth/hTrackTPCNClsFindable"), track.tpcNClsFindable()); - histos.fill(HIST("Tracks/SGsideBoth/hTrackTPCChi2NCls"), track.tpcChi2NCl()); - histos.fill(HIST("Tracks/SGsideBoth/hTrackITSNClsTPCCls"), track.tpcNClsFindable() - track.tpcNClsFindableMinusFound(), track.itsNCls()); - } + multiplicity = reconstructedTracks.size(); + if (fillCollisionUD(sameGapSideA, multiplicity) == false) { + return; } - histos.fill(HIST("Events/SGsideBoth/hNch"), nTracksCharged); - histos.fill(HIST("Events/SGsideBoth/hPtVSNch"), nTracksCharged, (sumPt / nTracksCharged)); - nTracksCharged = sumPt = 0; + // LOGF(debug, "Filling sameGapSideA events"); + histos.fill(HIST("eventcount"), -2); + fillQAUD(reconstructedTracks); + fillCorrelationsUD(sameGapSideA, reconstructedTracks, reconstructedTracks, multiplicity, reconstructedCollision.posZ()); + break; + case 1: // gap for side C + if (isCollisionCutSG(reconstructedCollision, 1) == false) { + return; + } + multiplicity = reconstructedTracks.size(); + if (fillCollisionUD(sameGapSideC, multiplicity) == false) { + return; + } + histos.fill(HIST("eventcount"), -1); + // LOGF(info, "Filling sameGapSideC events"); + fillCorrelationsUD(sameGapSideC, reconstructedTracks, reconstructedTracks, multiplicity, reconstructedCollision.posZ()); break; default: return; break; } } - PROCESS_SWITCH(upcPhotonuclearAnalysisJMG, processSG, "Process in UD tables", true); + + PROCESS_SWITCH(upcPhotonuclearAnalysisJMG, processSame, "Process same event", true); + + void processMixed(FullSGUDCollision::iterator const& reconstructedCollision) + { + (void)reconstructedCollision; + // int sgSide = reconstructedCollision.gapSide(); + // int sgSide = 0; + + int maxCountGapA = 0; + int maxCountGapC = 0; + + if (auto histEventCount = histos.get(HIST("eventcount"))) { + int binA = histEventCount->GetXaxis()->FindBin(-2); // Gap A + int binC = histEventCount->GetXaxis()->FindBin(-1); // Gap C + + maxCountGapA = histEventCount->GetBinContent(binA) * factorEventsMixed; + maxCountGapC = histEventCount->GetBinContent(binC) * factorEventsMixed; + } + + for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { + if (collision1.size() == 0 || collision2.size() == 0) { + // LOGF(info, "One or both collisions are empty."); + continue; + } + + if (countGapA >= maxCountGapA && countGapC >= maxCountGapC) { + break; + } + float multiplicity = 0; + if (collision1.gapSide() == 0 && collision2.gapSide() == 0) { // gap on side A + if (isCollisionCutSG(collision1, 0) == false && isCollisionCutSG(collision2, 0) == false) { + continue; + } + // std::cout << "Counts for Gap A: " << countGapA << " Maximum Count for Gap A " << maxCountGapA << std::endl; + ++countGapA; + // LOGF(info, "In the pairs loop, gap side A"); + multiplicity = tracks1.size(); + if (fillCollisionUD(mixedGapSideA, multiplicity) == false) { + return; + } + // histos.fill(HIST("eventcount"), bindingOnVtx.getBin({collision1.posZ()})); + histos.fill(HIST("eventcount"), bindingOnVtx.getBin({collision1.posZ(), collision1.gapSide()})); + fillCorrelationsUD(mixedGapSideA, tracks1, tracks2, multiplicity, collision1.posZ()); + // LOGF(info, "Filling mixedGapSideA events, Gap for side A"); + } + + if (collision1.gapSide() == 1 && collision2.gapSide() == 1) { // gap on side C + if (isCollisionCutSG(collision1, 1) == false && isCollisionCutSG(collision2, 1) == false) { + continue; + } + // std::cout << "Counts for Gap C: " << countGapC << " Maximum Count for Gap C" << maxCountGapC << std::endl; + ++countGapC; + // LOGF(info, "In the pairs loop, gap side C"); + multiplicity = tracks1.size(); + if (fillCollisionUD(mixedGapSideC, multiplicity) == false) { + return; + } + fillCorrelationsUD(mixedGapSideC, tracks1, tracks2, multiplicity, collision1.posZ()); + // LOGF(info, "Filling mixedGapSideC events, Gap for side C"); + } else { + continue; + } + } + } + + PROCESS_SWITCH(upcPhotonuclearAnalysisJMG, processMixed, "Process mixed events", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGUD/Tasks/upcPionAnalysis.cxx b/PWGUD/Tasks/upcPionAnalysis.cxx index 2d5d35cd564..4d581d5548c 100644 --- a/PWGUD/Tasks/upcPionAnalysis.cxx +++ b/PWGUD/Tasks/upcPionAnalysis.cxx @@ -9,18 +9,22 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. // -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "iostream" -#include "PWGUD/DataModel/UDTables.h" -#include -#include -#include "TLorentzVector.h" #include "PWGUD/Core/SGSelector.h" #include "PWGUD/Core/SGTrackSelector.h" +#include "PWGUD/DataModel/UDTables.h" + #include "Common/Core/RecoDecay.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "TLorentzVector.h" +#include +#include + +#include +#include using namespace std; using namespace o2; using namespace o2::aod; diff --git a/PWGUD/Tasks/upcRhoAnalysis.cxx b/PWGUD/Tasks/upcRhoAnalysis.cxx index 1395d66c04b..da0973501f9 100644 --- a/PWGUD/Tasks/upcRhoAnalysis.cxx +++ b/PWGUD/Tasks/upcRhoAnalysis.cxx @@ -15,21 +15,21 @@ /// \author Jakub Juracka, jakub.juracka@cern.ch /// \file upcRhoAnalysis.cxx -#include -#include -#include +#include "PWGUD/Core/UPCTauCentralBarrelHelperRL.h" +#include "PWGUD/DataModel/UDTables.h" + +#include "Common/DataModel/PIDResponse.h" -#include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" -#include "random" #include "TLorentzVector.h" -#include "Common/DataModel/PIDResponse.h" - -#include "PWGUD/DataModel/UDTables.h" -#include "PWGUD/Core/UPCTauCentralBarrelHelperRL.h" +#include +#include +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGUD/Tasks/upcRhoPrimeAnalysis.cxx b/PWGUD/Tasks/upcRhoPrimeAnalysis.cxx index 64559cc10dd..6cb00abe79a 100644 --- a/PWGUD/Tasks/upcRhoPrimeAnalysis.cxx +++ b/PWGUD/Tasks/upcRhoPrimeAnalysis.cxx @@ -12,20 +12,20 @@ /// \brief Task for analysis of rho' in UPCs using UD tables (from SG producer). /// \author Cesar Ramirez, cesar.ramirez@cern.ch -#include // Para std::string -#include // Para std::vector +#include "PWGUD/Core/UPCTauCentralBarrelHelperRL.h" +#include "PWGUD/DataModel/UDTables.h" + +#include "Common/DataModel/PIDResponse.h" -#include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" #include "Math/Vector4D.h" // similiar to TLorentzVector (which is now legacy apparently) -#include "random" - -#include "Common/DataModel/PIDResponse.h" -#include "PWGUD/DataModel/UDTables.h" -#include "PWGUD/Core/UPCTauCentralBarrelHelperRL.h" +#include +#include // Para std::string +#include // Para std::vector using namespace o2; using namespace o2::framework; diff --git a/Scripts/o2_linter.py b/Scripts/o2_linter.py index f5e8ce8c3e2..af7de5f101b 100644 --- a/Scripts/o2_linter.py +++ b/Scripts/o2_linter.py @@ -47,33 +47,39 @@ class Severity(Enum): class Reference(Enum): - O2 = 1 - ISO_CPP = 2 - LLVM = 3 - GOOGLE = 4 - LINTER = 5 - PWG_HF = 6 - PY_ZEN = 7 - PY_PEP8 = 8 + ISO_CPP = 1 + LLVM = 2 + GOOGLE = 3 + PY_ZEN = 4 + PY_PEP8 = 5 + O2 = 6 + PWG_HF = 7 + LINTER_1 = 8 + LINTER_2 = 9 references_list: "list[tuple[Reference, str, str]]" = [ - (Reference.O2, "ALICE O2 Coding Guidelines", "https://github.com/AliceO2Group/CodingGuidelines"), (Reference.ISO_CPP, "C++ Core Guidelines", "https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines"), (Reference.LLVM, "LLVM Coding Standards", "https://llvm.org/docs/CodingStandards.html"), (Reference.GOOGLE, "Google C++ Style Guide", "https://google.github.io/styleguide/cppguide.html"), + (Reference.PY_ZEN, "The Zen of Python", "https://peps.python.org/pep-0020/"), + (Reference.PY_PEP8, "Style Guide for Python Code", "https://peps.python.org/pep-0008/"), + (Reference.O2, "ALICE O2 Coding Guidelines", "https://github.com/AliceO2Group/CodingGuidelines"), + ( + Reference.PWG_HF, + "PWG-HF guidelines", + "https://aliceo2group.github.io/analysis-framework/docs/advanced-specifics/pwghf.html#contribute", + ), ( - Reference.LINTER, + Reference.LINTER_1, "Proposal of the O2 linter", "https://indico.cern.ch/event/1482467/#29-development-of-the-o2-linte", ), ( - Reference.PWG_HF, - "PWG-HF guidelines", - "https://aliceo2group.github.io/analysis-framework/docs/advanced-specifics/pwghf.html#contribute", + Reference.LINTER_2, + "Update of the O2 linter", + "https://indico.cern.ch/event/1513748/#29-o2-linter-development", ), - (Reference.PY_ZEN, "The Zen of Python", "https://peps.python.org/pep-0020/"), - (Reference.PY_PEP8, "Style Guide for Python Code", "https://peps.python.org/pep-0008/"), ] references: "dict[Reference, dict]" = {name: {"title": title, "url": url} for name, title, url in references_list} @@ -312,7 +318,7 @@ class TestIoStream(TestSpec): name = "include-iostream" message = "Do not include iostream. Use O2 logging instead." rationale = "Performance. Avoid injection of static constructors. Consistent logging." - references = [Reference.LLVM, Reference.LINTER] + references = [Reference.LLVM, Reference.LINTER_1] suffixes = [".h", ".cxx"] def test_line(self, line: str) -> bool: @@ -327,7 +333,7 @@ class TestUsingStd(TestSpec): name = "import-std-name" message = "Do not import names from the std namespace in headers." rationale = "Code safety. Avoid namespace pollution with common names." - references = [Reference.LINTER] + references = [Reference.LINTER_1] suffixes = [".h"] def test_line(self, line: str) -> bool: @@ -342,7 +348,7 @@ class TestUsingDirective(TestSpec): name = "using-directive" message = "Do not put using directives at global scope in headers." rationale = "Code safety. Avoid namespace pollution." - references = [Reference.O2, Reference.ISO_CPP, Reference.LLVM, Reference.GOOGLE, Reference.LINTER] + references = [Reference.O2, Reference.ISO_CPP, Reference.LLVM, Reference.GOOGLE, Reference.LINTER_1] suffixes = [".h"] def test_line(self, line: str) -> bool: @@ -357,7 +363,7 @@ class TestStdPrefix(TestSpec): name = "std-prefix" message = "Use std:: prefix for names from the std namespace." rationale = "Code clarity, safety and portability. Avoid ambiguity (e.g. abs)." - references = [Reference.LLVM, Reference.LINTER] + references = [Reference.LLVM, Reference.LINTER_1] suffixes = [".h", ".cxx", ".C"] prefix_bad = r"[^\w:\.\"]" patterns = [ @@ -401,7 +407,7 @@ class TestRootEntity(TestSpec): name = "root/entity" message = "Replace ROOT entities with equivalents from standard C++ or from O2." rationale = "Code simplicity and maintainability. O2 is not a ROOT code." - references = [Reference.ISO_CPP, Reference.LINTER, Reference.PY_ZEN] + references = [Reference.ISO_CPP, Reference.LINTER_1, Reference.PY_ZEN] suffixes = [".h", ".cxx"] def file_matches(self, path: str) -> bool: @@ -427,7 +433,7 @@ class TestRootLorentzVector(TestSpec): "Use std::array with RecoDecay methods or the ROOT::Math::LorentzVector template instead." ) rationale = "Performance. Use up-to-date tools." - references = [] + references = [Reference.LINTER_2] suffixes = [".h", ".cxx"] def test_line(self, line: str) -> bool: @@ -443,7 +449,7 @@ class TestPi(TestSpec): name = "external-pi" message = "Use the PI constant (and its multiples and fractions) defined in o2::constants::math." rationale = "Code maintainability." - references = [Reference.LINTER, Reference.PY_ZEN] + references = [Reference.LINTER_1, Reference.PY_ZEN] suffixes = [".h", ".cxx"] def file_matches(self, path: str) -> bool: @@ -463,7 +469,7 @@ class TestTwoPiAddSubtract(TestSpec): name = "two-pi-add-subtract" message = "Use RecoDecay::constrainAngle to restrict angle to a given range." rationale = "Code maintainability and safety. Use existing tools." - references = [Reference.ISO_CPP, Reference.LINTER, Reference.PY_ZEN] + references = [Reference.ISO_CPP, Reference.LINTER_1, Reference.PY_ZEN] suffixes = [".h", ".cxx"] def test_line(self, line: str) -> bool: @@ -484,7 +490,7 @@ class TestPiMultipleFraction(TestSpec): name = "pi-multiple-fraction" message = "Use multiples/fractions of PI defined in o2::constants::math." rationale = "Code maintainability." - references = [Reference.LINTER, Reference.PY_ZEN] + references = [Reference.LINTER_1, Reference.PY_ZEN] suffixes = [".h", ".cxx"] def test_line(self, line: str) -> bool: @@ -507,7 +513,7 @@ class TestPdgDatabase(TestSpec): "Use o2::constants::physics::Mass... or Service instead." ) rationale = "Performance." - references = [Reference.LINTER] + references = [Reference.LINTER_1] suffixes = [".h", ".cxx"] def file_matches(self, path: str) -> bool: @@ -526,7 +532,7 @@ class TestPdgExplicitCode(TestSpec): name = "pdg/explicit-code" message = "Avoid hard-coded PDG codes. Use named values from PDG_t or o2::constants::physics::Pdg instead." rationale = "Code comprehensibility, readability, maintainability and safety." - references = [Reference.O2, Reference.ISO_CPP, Reference.LINTER] + references = [Reference.O2, Reference.ISO_CPP, Reference.LINTER_1] suffixes = [".h", ".cxx", ".C"] def test_line(self, line: str) -> bool: @@ -549,7 +555,7 @@ class TestPdgExplicitMass(TestSpec): name = "pdg/explicit-mass" message = "Avoid hard-coded particle masses. Use o2::constants::physics::Mass... instead." rationale = "Code comprehensibility, readability, maintainability and safety." - references = [Reference.O2, Reference.ISO_CPP, Reference.LINTER] + references = [Reference.O2, Reference.ISO_CPP, Reference.LINTER_2] suffixes = [".h", ".cxx"] masses: "list[str]" = [] # list of mass values to detect @@ -593,7 +599,7 @@ class TestPdgKnownMass(TestSpec): name = "pdg/known-mass" message = "Use o2::constants::physics::Mass... instead of calling a database method for a known PDG code." rationale = "Performance." - references = [Reference.LINTER] + references = [Reference.LINTER_1] suffixes = [".h", ".cxx", ".C"] def test_line(self, line: str) -> bool: @@ -612,7 +618,7 @@ class TestLogging(TestSpec): name = "logging" message = "Use O2 logging (LOG, LOGF, LOGP)." rationale = "Logs easy to read and process." - references = [Reference.LINTER] + references = [Reference.LINTER_1] suffixes = [".h", ".cxx"] def file_matches(self, path: str) -> bool: @@ -653,7 +659,7 @@ class TestConstRefInSubscription(TestSpec): name = "const-ref-in-process" message = "Use constant references for table subscriptions in process functions." rationale = "Performance, code comprehensibility and safety." - references = [Reference.O2, Reference.ISO_CPP, Reference.LINTER] + references = [Reference.O2, Reference.ISO_CPP, Reference.LINTER_1] suffixes = [".cxx"] per_line = False @@ -731,7 +737,7 @@ class TestWorkflowOptions(TestSpec): "Use process function switches or metadata instead." ) rationale = "Not supported on AliHyperloop." - references = [Reference.LINTER] + references = [Reference.LINTER_1] suffixes = [".cxx"] per_line = False @@ -767,10 +773,10 @@ class TestMagicNumber(TestSpec): name = "magic-number" message = "Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant." rationale = "Code comprehensibility, maintainability and safety." - references = [Reference.O2, Reference.ISO_CPP] + references = [Reference.O2, Reference.ISO_CPP, Reference.LINTER_2] suffixes = [".h", ".cxx", ".C"] pattern_compare = r"([<>]=?|[!=]=)" - pattern_number = r"[\+-]?([\d\.]+)f?" + pattern_number = r"[\+-]?([\d\.]+(e[\+-]?\d+)?)f?" def test_line(self, line: str) -> bool: if is_comment_cpp(line): @@ -779,7 +785,7 @@ def test_line(self, line: str) -> bool: iterators = re.finditer( rf" {self.pattern_compare} {self.pattern_number}|\W{self.pattern_number} {self.pattern_compare} ", line ) - matches = [(it.start(), it.group(2), it.group(3)) for it in iterators] + matches = [(it.start(), it.group(2), it.group(4)) for it in iterators] if not matches: return True # Ignore matches inside strings. @@ -805,7 +811,7 @@ class TestDocumentationFile(TestSpec): name = "doc/file" message = "Provide mandatory file documentation." rationale = "Code comprehensibility. Collaboration." - references = [Reference.O2, Reference.LINTER] + references = [Reference.O2, Reference.LINTER_1] suffixes = [".h", ".cxx", ".C"] per_line = False @@ -849,7 +855,7 @@ def test_file(self, path: str, content) -> bool: # Reference: https://rawgit.com/AliceO2Group/CodingGuidelines/master/naming_formatting.html rationale_names = "Code readability, comprehensibility and searchability." -references_names = [Reference.O2, Reference.LINTER] +references_names = [Reference.O2, Reference.LINTER_1] class TestNameFunctionVariable(TestSpec): @@ -989,29 +995,23 @@ class TestNameConstant(TestSpec): references = references_names suffixes = [".h", ".cxx", ".C"] + def __init__(self) -> None: + super().__init__() + keyword = r"(.+ )" # e.g. "static " + type_val = r"([\w:<>+\-*\/, ]+ )" # value type e.g. "std::array " + prefix = r"(\w+::)" # prefix with namespace or class, e.g. "MyClass::" + name_val = r"(\w+)" # name of the constant + array = r"(\[.*\])" # array declaration: "[...]" + assignment = r"( =|\(\d|{)" # value assignment, e.g. " = 2", " = expression", "(2)", "{2}", "{{...}}" + self.pattern = re.compile(rf"{keyword}?constexpr {type_val}?{prefix}*{name_val}{array}?{assignment}") + def test_line(self, line: str) -> bool: if is_comment_cpp(line): return True line = remove_comment_cpp(line) - words = line.split() - if "constexpr" not in words or "=" not in words: + if not (match := self.pattern.match(line)): return True - # Extract constant name. - words = words[: words.index("=")] # keep only words before "=" - constant_name = words[-1] # last word before "=" - if ( - constant_name.endswith("]") and "[" not in constant_name - ): # it's an array and we do not have the name before "[" here - opens_brackets = ["[" in w for w in words] - if not any(opens_brackets): # The opening "[" is not on this line. We have to give up. - return True - constant_name = words[opens_brackets.index(True)] # the name is in the first element with "[" - if "[" in constant_name: # Remove brackets for arrays. - constant_name = constant_name[: constant_name.index("[")] - if "::" in constant_name: # Remove the class prefix for methods. - constant_name = constant_name.split("::")[-1] - if "#" in constant_name: # Remove "#" for strings in macros. - constant_name = constant_name[: constant_name.index("#")] + constant_name = match.group(4) # The actual test comes here. if constant_name.startswith("k") and len(constant_name) > 1: # exception for special constants constant_name = constant_name[1:] # test the name without "k" @@ -1149,15 +1149,10 @@ class TestNameUpperCamelCase(TestSpec): def test_line(self, line: str) -> bool: if is_comment_cpp(line): return True - if not line.startswith(f"{self.keyword} "): + if not (match := re.match(rf"{self.keyword}( (class|struct))? (\w+)", line)): return True # Extract object name. - words = line.split() - if not words[1].isalnum(): # "struct : ...", "enum { ..." - return True - object_name = words[1] - if object_name in ("class", "struct") and len(words) > 2: # enum class ... or enum struct - object_name = words[2] + object_name = match.group(3) # The actual test comes here. return is_upper_camel_case(object_name) @@ -1216,7 +1211,7 @@ class TestNameFilePython(TestSpec): name = "name/file-python" message = "Use snake_case for names of Python files." rationale = rationale_names - references = [Reference.LINTER, Reference.PY_PEP8] + references = [Reference.LINTER_1, Reference.PY_PEP8] suffixes = [".py", ".ipynb"] per_line = False @@ -1278,7 +1273,7 @@ class TestNameTask(TestSpec): name = "name/o2-task" message = "Specify task name only when it cannot be derived from the struct name. Only append to the default name." rationale = f"{rationale_names} Correspondence struct ↔ device." - references = [Reference.LINTER] + references = [Reference.LINTER_1] suffixes = [".cxx"] per_line = False @@ -1423,7 +1418,7 @@ class TestNameFileWorkflow(TestSpec): '(Class implementation files should be in "Core" directories.)' ) rationale = f"{rationale_names} Correspondence file ↔ struct." - references = [Reference.LINTER] + references = [Reference.LINTER_1] suffixes = [".cxx"] per_line = False @@ -1466,7 +1461,7 @@ class TestNameConfigurable(TestSpec): "for the struct member as for the JSON string. (Declare the type and names on the same line.)" ) rationale = f"{rationale_names} Correspondence C++ code ↔ JSON." - references = [Reference.O2, Reference.LINTER] + references = [Reference.O2, Reference.LINTER_1] suffixes = [".h", ".cxx"] def file_matches(self, path: str) -> bool: @@ -1475,33 +1470,21 @@ def file_matches(self, path: str) -> bool: def test_line(self, line: str) -> bool: if is_comment_cpp(line): return True - if not line.startswith("Configurable"): - return True + if not (match := re.match(r"((o2::)?framework::)?Configurable(\w+|<.+>) (\w+)( = )?{([^,{]+),", line)): + return not re.match(r"((o2::)?framework::)?Configurable", line) # Extract Configurable name. - words = line.split() - if len(words) < 2: - return False - if len(words) > 2 and words[2] == "=": # expecting Configurable... nameCpp = {"nameJson", - name_cpp = words[1] # nameCpp - name_json = words[3][1:] # expecting "nameJson", - else: - names = words[1].split("{") # expecting Configurable... nameCpp{"nameJson", - if len(names) < 2: - return False - name_cpp = names[0] # nameCpp - name_json = names[1] # expecting "nameJson", - if not name_json: - return False + name_cpp = match.group(4) # nameCpp + name_json = match.group(6) # expecting "nameJson" if name_json[0] != '"': # JSON name is not a literal string. return True - name_json = name_json.strip('",') # expecting nameJson + name_json = name_json[1:-1] # Strip away quotation marks. # The actual test comes here. return is_lower_camel_case(name_cpp) and name_cpp == name_json # PWG-HF -references_hf = [Reference.LINTER, Reference.PWG_HF] +references_hf = [Reference.LINTER_1, Reference.PWG_HF] class TestHfNameStructClass(TestSpec): @@ -1747,7 +1730,7 @@ def main(): ref_names = [] for test in tests: if any(n > 0 for n in (test.n_issues, test.n_disabled, test.n_tolerated, n_files_bad[test.name])): - ref_ids = [ref.value for ref in test.references] + ref_ids = sorted(ref.value for ref in test.references) ref_names += test.references print( f"{test.name}{' ' * (len_max - len(test.name))}\t{test.n_issues}\t{test.n_tolerated}" @@ -1802,7 +1785,7 @@ def main(): print("Skipping writing in GITHUB_OUTPUT.") # Print tips. - print("\nTip: You can run the O2 linter locally with: python3 Scripts/o2_linter.py ") + print("\nTip: You can run the O2 linter locally from the O2Physics directory with: python3 Scripts/o2_linter.py ") if not passed: sys.exit(1) diff --git a/Tutorials/PWGUD/UDTutorial_05.cxx b/Tutorials/PWGUD/UDTutorial_05.cxx index 3a9bfb79605..9ca8ddf62d5 100644 --- a/Tutorials/PWGUD/UDTutorial_05.cxx +++ b/Tutorials/PWGUD/UDTutorial_05.cxx @@ -10,16 +10,18 @@ // or submit itself to any jurisdiction. // -#include "iostream" -#include "TLorentzVector.h" -#include "TDatabasePDG.h" - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/SGSelector.h" #include "PWGUD/Core/SGTrackSelector.h" +#include "PWGUD/DataModel/UDTables.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "TDatabasePDG.h" +#include "TLorentzVector.h" + +#include // using namespace std; using namespace o2; diff --git a/Tutorials/PWGUD/UDTutorial_07.cxx b/Tutorials/PWGUD/UDTutorial_07.cxx index f2a5616f00d..cfa5dc6d27c 100644 --- a/Tutorials/PWGUD/UDTutorial_07.cxx +++ b/Tutorials/PWGUD/UDTutorial_07.cxx @@ -9,16 +9,19 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. // -#include "iostream" -#include -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "PWGUD/DataModel/UDTables.h" -#include "TLorentzVector.h" #include "PWGUD/Core/SGSelector.h" #include "PWGUD/Core/SGTrackSelector.h" +#include "PWGUD/DataModel/UDTables.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "TLorentzVector.h" +#include +#include + +#include using namespace std; using namespace o2;