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/CMakeLists.txt b/ALICE3/Core/CMakeLists.txt index 97718534a77..285c1624853 100644 --- a/ALICE3/Core/CMakeLists.txt +++ b/ALICE3/Core/CMakeLists.txt @@ -24,10 +24,13 @@ o2physics_target_root_dictionary(ALICE3Core o2physics_add_library(FastTracker SOURCES FastTracker.cxx DetLayer.cxx + DelphesO2LutWriter.cxx PUBLIC_LINK_LIBRARIES O2::Framework - O2Physics::AnalysisCore) + O2Physics::AnalysisCore + O2Physics::ALICE3Core) o2physics_target_root_dictionary(FastTracker HEADERS FastTracker.h DetLayer.h + DelphesO2LutWriter.h LINKDEF FastTrackerLinkDef.h) diff --git a/ALICE3/Core/DelphesO2LutWriter.cxx b/ALICE3/Core/DelphesO2LutWriter.cxx new file mode 100644 index 00000000000..f3cba264b11 --- /dev/null +++ b/ALICE3/Core/DelphesO2LutWriter.cxx @@ -0,0 +1,502 @@ +// 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 DelphesO2LutWriter.cxx +/// @brief Porting to O2Physics of DelphesO2 code. +/// Minimal changes have been made to the original code for adaptation purposes, formatting and commented parts have been considered. +/// Relevant sources: +/// DelphesO2/src/lutWrite.cc https://github.com/AliceO2Group/DelphesO2/blob/master/src/lutWrite.cc +/// @author: Roberto Preghenella +/// @email: preghenella@bo.infn.it +/// + +#include + +#include "ALICE3/Core/DelphesO2TrackSmearer.h" +#include "ALICE3/Core/DelphesO2LutWriter.h" +#include +#include "TMatrixD.h" +#include "TVectorD.h" +#include "TAxis.h" +#include "TMatrixDSymEigen.h" +#include "TDatabasePDG.h" +#include "TLorentzVector.h" +#include "ALICE3/Core/FastTracker.h" +#include "ALICE3/Core/TrackUtilities.h" + +// #define USE_FWD_PARAM +#ifdef USE_FWD_PARAM +#include "fwdRes.C" +#endif + +namespace o2::fastsim +{ + +void DelphesO2LutWriter::printLutWriterConfiguration() +{ + std::cout << " --- Printing configuration of LUT writer --- " << std::endl; + std::cout << " -> etaMaxBarrel = " << etaMaxBarrel << std::endl; + std::cout << " -> usePara = " << usePara << std::endl; + std::cout << " -> useDipole = " << useDipole << std::endl; + std::cout << " -> useFlatDipole = " << useFlatDipole << std::endl; +} + +bool DelphesO2LutWriter::fatSolve(lutEntry_t& lutEntry, + float pt, + float eta, + const float mass, + int itof, + int otof, + int q, + const float nch) +{ + lutEntry.valid = false; + + static TLorentzVector tlv; + tlv.SetPtEtaPhiM(pt, eta, 0., mass); + o2::track::TrackParCov trkIn; + o2::upgrade::convertTLorentzVectorToO2Track(q, tlv, {0., 0., 0.}, trkIn); + o2::track::TrackParCov trkOut; + const int status = fat.FastTrack(trkIn, trkOut, nch); + if (status <= 0) { + Printf(" --- fatSolve: FastTrack failed --- \n"); + tlv.Print(); + return false; + } + lutEntry.valid = true; + lutEntry.itof = fat.GetGoodHitProb(itof); + lutEntry.otof = fat.GetGoodHitProb(otof); + for (int i = 0; i < 15; ++i) + lutEntry.covm[i] = trkOut.getCov()[i]; + + // define the efficiency + auto totfake = 0.; + lutEntry.eff = 1.; + for (int i = 1; i < 20; ++i) { + auto igoodhit = fat.GetGoodHitProb(i); + if (igoodhit <= 0. || i == itof || i == otof) + continue; + lutEntry.eff *= igoodhit; + auto pairfake = 0.; + for (int j = i + 1; j < 20; ++j) { + auto jgoodhit = fat.GetGoodHitProb(j); + if (jgoodhit <= 0. || j == itof || j == otof) + continue; + pairfake = (1. - igoodhit) * (1. - jgoodhit); + break; + } + totfake += pairfake; + } + lutEntry.eff2 = (1. - totfake); + + return true; +} + +#ifdef USE_FWD_PARAM +bool DelphesO2LutWriter::fwdSolve(float* covm, float pt, float eta, float mass) +{ + if (fwdRes(covm, pt, eta, mass) < 0) + return false; + return true; +} +#else +bool DelphesO2LutWriter::fwdSolve(float*, float, float, float) +{ + return false; +} +#endif + +bool DelphesO2LutWriter::fwdPara(lutEntry_t& lutEntry, float pt, float eta, float mass, float Bfield) +{ + lutEntry.valid = false; + + // parametrised forward response; interpolates between FAT at eta = 1.75 and a fixed parametrisation at eta = 4; only diagonal elements + if (std::fabs(eta) < etaMaxBarrel || std::fabs(eta) > 4) + return false; + + if (!fatSolve(lutEntry, pt, etaMaxBarrel, mass)) + return false; + float covmbarrel[15] = {0}; + for (int i = 0; i < 15; ++i) { + covmbarrel[i] = lutEntry.covm[i]; + } + + // parametrisation at eta = 4 + const double beta = 1. / std::sqrt(1 + mass * mass / pt / pt / std::cosh(eta) / std::cosh(eta)); + const float dca_pos = 2.5e-4 / std::sqrt(3); // 2.5 micron/sqrt(3) + const float r0 = 0.5; // layer 0 radius [cm] + const float r1 = 1.3; + const float r2 = 2.5; + const float x0layer = 0.001; // material budget (rad length) per layer + const double sigma_alpha = 0.0136 / beta / pt * std::sqrt(x0layer * std::cosh(eta)) * (1 + 0.038 * std::log(x0layer * std::cosh(eta))); + const double dcaxy_ms = sigma_alpha * r0 * std::sqrt(1 + r1 * r1 / (r2 - r0) / (r2 - r0)); + const double dcaxy2 = dca_pos * dca_pos + dcaxy_ms * dcaxy_ms; + + const double dcaz_ms = sigma_alpha * r0 * std::cosh(eta); + const double dcaz2 = dca_pos * dca_pos + dcaz_ms * dcaz_ms; + + const float Leta = 2.8 / sinh(eta) - 0.01 * r0; // m + const double relmomres_pos = 10e-6 * pt / 0.3 / Bfield / Leta / Leta * std::sqrt(720. / 15.); + + const float relmomres_barrel = std::sqrt(covmbarrel[14]) * pt; + const float Router = 1; // m + const float relmomres_pos_barrel = 10e-6 * pt / 0.3 / Bfield / Router / Router / std::sqrt(720. / 15.); + const float relmomres_MS_barrel = std::sqrt(relmomres_barrel * relmomres_barrel - relmomres_pos_barrel * relmomres_pos_barrel); + + // interpolate MS contrib (rel resolution 0.4 at eta = 4) + const float relmomres_MS_eta4 = 0.4 / beta * 0.5 / Bfield; + const float relmomres_MS = relmomres_MS_eta4 * pow(relmomres_MS_eta4 / relmomres_MS_barrel, (std::fabs(eta) - 4.) / (4. - etaMaxBarrel)); + const float momres_tot = pt * std::sqrt(relmomres_pos * relmomres_pos + relmomres_MS * relmomres_MS); // total absolute mom reso + + // Fill cov matrix diag + for (int i = 0; i < 15; ++i) + lutEntry.covm[i] = 0; + + lutEntry.covm[0] = covmbarrel[0]; + if (dcaxy2 > lutEntry.covm[0]) + lutEntry.covm[0] = dcaxy2; + lutEntry.covm[2] = covmbarrel[2]; + if (dcaz2 > lutEntry.covm[2]) + lutEntry.covm[2] = dcaz2; + lutEntry.covm[5] = covmbarrel[5]; // sigma^2 sin(phi) + lutEntry.covm[9] = covmbarrel[9]; // sigma^2 tanl + lutEntry.covm[14] = momres_tot * momres_tot / pt / pt / pt / pt; // sigma^2 1/pt + // Check that all numbers are numbers + for (int i = 0; i < 15; ++i) { + if (std::isnan(lutEntry.covm[i])) { + Printf(" --- lutEntry.covm[%d] is NaN", i); + return false; + } + } + return true; +} + +void DelphesO2LutWriter::lutWrite(const char* filename, int pdg, float field, int itof, int otof) +{ + + if (useFlatDipole && useDipole) { + Printf("Both dipole and dipole flat flags are on, please use only one of them"); + return; + } + + // output file + std::ofstream lutFile(filename, std::ofstream::binary); + if (!lutFile.is_open()) { + Printf("Did not manage to open output file!!"); + return; + } + + // write header + lutHeader_t lutHeader; + // pid + lutHeader.pdg = pdg; + lutHeader.mass = TDatabasePDG::Instance()->GetParticle(pdg)->Mass(); + const int q = std::abs(TDatabasePDG::Instance()->GetParticle(pdg)->Charge()) / 3; + if (q <= 0) { + Printf("Negative or null charge (%f) for pdg code %i. Fix the charge!", TDatabasePDG::Instance()->GetParticle(pdg)->Charge(), pdg); + return; + } + lutHeader.field = field; + // nch + lutHeader.nchmap.log = true; + lutHeader.nchmap.nbins = 20; + lutHeader.nchmap.min = 0.5; + lutHeader.nchmap.max = 3.5; + // radius + lutHeader.radmap.log = false; + lutHeader.radmap.nbins = 1; + lutHeader.radmap.min = 0.; + lutHeader.radmap.max = 100.; + // eta + lutHeader.etamap.log = false; + lutHeader.etamap.nbins = 80; + lutHeader.etamap.min = -4.; + lutHeader.etamap.max = 4.; + // pt + lutHeader.ptmap.log = true; + lutHeader.ptmap.nbins = 200; + lutHeader.ptmap.min = -2; + lutHeader.ptmap.max = 2.; + lutFile.write(reinterpret_cast(&lutHeader), sizeof(lutHeader)); + + // entries + const int nnch = lutHeader.nchmap.nbins; + const int nrad = lutHeader.radmap.nbins; + const int neta = lutHeader.etamap.nbins; + const int npt = lutHeader.ptmap.nbins; + 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); + lutEntry.nch = nch; + fat.SetdNdEtaCent(nch); + 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); + for (int ipt = 0; ipt < npt; ++ipt) { + Printf(" --- writing ipt = %d/%d", ipt, npt); + lutEntry.pt = lutHeader.ptmap.eval(ipt); + lutEntry.valid = true; + 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; + lutEntry.eff = 0.; + lutEntry.eff2 = 0.; + for (int i = 0; i < 15; ++i) { + lutEntry.covm[i] = 0.; + } + successfullCalls--; + failedCalls++; + } + } else { + Printf("Solving outside the barrel"); + // printf(" --- fwdSolve: pt = %f, eta = %f, mass = %f, field=%f \n", lutEntry.pt, lutEntry.eta, lutHeader.mass, lutHeader.field); + 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) { + retval = fwdPara(lutEntry, lutEntry.pt, lutEntry.eta, lutHeader.mass, field); + } else { + retval = fwdSolve(lutEntry.covm, lutEntry.pt, lutEntry.eta, lutHeader.mass); + } + if (useDipole) { // Using the parametrization at the border of the barrel only for efficiency and momentum resolution + lutEntry_t lutEntryBarrel; + retval = fatSolve(lutEntryBarrel, lutEntry.pt, etaMaxBarrel, lutHeader.mass, itof, otof, q); + lutEntry.valid = lutEntryBarrel.valid; + lutEntry.covm[14] = lutEntryBarrel.covm[14]; + lutEntry.eff = lutEntryBarrel.eff; + lutEntry.eff2 = lutEntryBarrel.eff2; + } + if (!retval) { + printf(" --- fwdSolve: error \n"); + lutEntry.valid = false; + for (int i = 0; i < 15; ++i) { + lutEntry.covm[i] = 0.; + } + successfullCalls--; + failedCalls++; + } + } + Printf("Diagonalizing"); + diagonalise(lutEntry); + Printf("Writing"); + lutFile.write(reinterpret_cast(&lutEntry), sizeof(lutEntry_t)); + } + } + } + } + Printf(" --- finished writing LUT file %s", filename); + Printf(" --- successfull calls: %d/%d, failed calls: %d/%d", successfullCalls, nCalls, failedCalls, nCalls); + lutFile.close(); +} + +void DelphesO2LutWriter::diagonalise(lutEntry_t& lutEntry) +{ + TMatrixDSym m(5); + for (int i = 0, k = 0; i < 5; ++i) { + for (int j = 0; j < i + 1; ++j, ++k) { + m(i, j) = lutEntry.covm[k]; + m(j, i) = lutEntry.covm[k]; + } + } + + m.Print(); + TMatrixDSymEigen eigen(m); + // eigenvalues vector + TVectorD eigenVal = eigen.GetEigenValues(); + for (int i = 0; i < 5; ++i) + lutEntry.eigval[i] = eigenVal[i]; + // eigenvectors matrix + TMatrixD eigenVec = eigen.GetEigenVectors(); + for (int i = 0; i < 5; ++i) + for (int j = 0; j < 5; ++j) + lutEntry.eigvec[i][j] = eigenVec[i][j]; + // inverse eigenvectors matrix + eigenVec.Invert(); + for (int i = 0; i < 5; ++i) + for (int j = 0; j < 5; ++j) + lutEntry.eiginv[i][j] = eigenVec[i][j]; +} + +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; + static const int kEfficiencyOuterTOF = 3; + static const int kPtResolution = 4; + static const int kRPhiResolution = 5; + static const int kZResolution = 6; + + o2::delphes::DelphesO2TrackSmearer smearer; + smearer.loadTable(pdg, filename); + auto lutHeader = smearer.getLUTHeader(pdg); + map_t lutMap; + switch (vs) { + case kNch: + lutMap = lutHeader->nchmap; + break; + case kEta: + lutMap = lutHeader->etamap; + break; + case kPt: + lutMap = lutHeader->ptmap; + break; + } + 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) { + switch (vs) { + case kNch: + nch = lutMap.eval(i); + break; + case kEta: + eta = lutMap.eval(i); + break; + case kPt: + pt = lutMap.eval(i); + break; + } + float eff = 0.; + auto lutEntry = smearer.getLUTEntry(pdg, nch, radius, eta, pt, eff); + if (!lutEntry->valid || lutEntry->eff == 0.) { + if (!canBeInvalid) { + Printf(" --- warning: it cannot be invalid"); + } + continue; + } + canBeInvalid = false; + + double cen = 0.; + switch (vs) { + case kNch: + cen = lutEntry->nch; + break; + case kEta: + cen = lutEntry->eta; + break; + case kPt: + cen = lutEntry->pt; + break; + } + double val = 0.; + switch (what) { + case kEfficiency: + val = lutEntry->eff * 100.; // efficiency (%) + break; + case kEfficiency2: + val = lutEntry->eff2 * 100.; // efficiency (%) + break; + case kEfficiencyInnerTOF: + val = lutEntry->itof * 100.; // efficiency (%) + break; + case kEfficiencyOuterTOF: + val = lutEntry->otof * 100.; // efficiency (%) + break; + case kPtResolution: + val = sqrt(lutEntry->covm[14]) * lutEntry->pt * 100.; // pt resolution (%) + break; + case kRPhiResolution: + val = sqrt(lutEntry->covm[0]) * 1.e4; // rphi resolution (um) + break; + case kZResolution: + val = sqrt(lutEntry->covm[1]) * 1.e4; // z resolution (um) + break; + default: + Printf(" --- error: unknown what %d", what); + break; + } + g->AddPoint(cen, val); + } + + return g; +} +} // namespace o2::fastsim + +ClassImp(o2::fastsim::DelphesO2LutWriter); diff --git a/ALICE3/Core/DelphesO2LutWriter.h b/ALICE3/Core/DelphesO2LutWriter.h new file mode 100644 index 00000000000..25faf7f382c --- /dev/null +++ b/ALICE3/Core/DelphesO2LutWriter.h @@ -0,0 +1,69 @@ +// 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 DelphesO2LutWriter.h +/// @brief Porting to O2Physics of DelphesO2 code. +/// Minimal changes have been made to the original code for adaptation purposes, formatting and commented parts have been considered. +/// Relevant sources: +/// DelphesO2/src/lutWrite.cc https://github.com/AliceO2Group/DelphesO2/blob/master/src/lutWrite.cc +/// @author: Roberto Preghenella +/// @email: preghenella@bo.infn.it +/// + +#ifndef ALICE3_CORE_DELPHESO2LUTWRITER_H_ +#define ALICE3_CORE_DELPHESO2LUTWRITER_H_ + +#include "ALICE3/Core/DelphesO2TrackSmearer.h" +#include "ALICE3/Core/FastTracker.h" +#include "TGraph.h" + +namespace o2::fastsim +{ +class DelphesO2LutWriter +{ + public: + DelphesO2LutWriter() = default; + virtual ~DelphesO2LutWriter() = default; + + o2::fastsim::FastTracker fat; + void diagonalise(lutEntry_t& lutEntry); + float etaMaxBarrel = 1.75f; + bool usePara = true; // use fwd parameterisation + bool useDipole = false; // use dipole i.e. flat parametrization for efficiency and momentum resolution + bool useFlatDipole = false; // use dipole i.e. flat parametrization outside of the barrel + + int mAtLeastHits = 4; + int mAtLeastCorr = 4; + int mAtLeastFake = 0; + void SetAtLeastHits(int n) { mAtLeastHits = n; } + void SetAtLeastCorr(int n) { mAtLeastCorr = n; } + void SetAtLeastFake(int n) { mAtLeastFake = n; } + + void printLutWriterConfiguration(); + bool fatSolve(lutEntry_t& lutEntry, + float pt = 0.1, + float eta = 0.0, + const float mass = 0.13957000, + int itof = 0, + int otof = 0, + 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); + TGraph* lutRead(const char* filename, int pdg, int what, int vs, float nch = 0., float radius = 0., float eta = 0., float pt = 0.); + + ClassDef(DelphesO2LutWriter, 1); +}; +} // namespace o2::fastsim + +#endif // ALICE3_CORE_DELPHESO2LUTWRITER_H_ diff --git a/ALICE3/Core/DetLayer.cxx b/ALICE3/Core/DetLayer.cxx index 392356b1e5a..25e61e6e6d5 100644 --- a/ALICE3/Core/DetLayer.cxx +++ b/ALICE3/Core/DetLayer.cxx @@ -16,4 +16,76 @@ /// \brief Basic struct to hold information regarding a detector layer to be used in fast simulation /// +#include +#include + #include "DetLayer.h" + +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..2577c73e42d 100644 --- a/ALICE3/Core/DetLayer.h +++ b/ALICE3/Core/DetLayer.h @@ -19,12 +19,59 @@ #ifndef ALICE3_CORE_DETLAYER_H_ #define ALICE3_CORE_DETLAYER_H_ +#include + #include "TString.h" 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/Core/FastTrackerLinkDef.h b/ALICE3/Core/FastTrackerLinkDef.h index a69755b7e92..a5441d81cde 100644 --- a/ALICE3/Core/FastTrackerLinkDef.h +++ b/ALICE3/Core/FastTrackerLinkDef.h @@ -17,5 +17,6 @@ #pragma link off all functions; #pragma link C++ class o2::fastsim::FastTracker + ; +#pragma link C++ class o2::fastsim::DelphesO2LutWriter + ; #endif // ALICE3_CORE_FASTTRACKERLINKDEF_H_ diff --git a/ALICE3/Core/TrackUtilities.h b/ALICE3/Core/TrackUtilities.h index e4a1e159804..3650d500aaf 100644 --- a/ALICE3/Core/TrackUtilities.h +++ b/ALICE3/Core/TrackUtilities.h @@ -85,7 +85,6 @@ void convertMCParticleToO2Track(McParticleType& particle, { static TLorentzVector tlv; tlv.SetPxPyPzE(particle.px(), particle.py(), particle.pz(), particle.e()); - tlv.SetXYZT(particle.vx(), particle.vy(), particle.vz(), particle.vt()); convertTLorentzVectorToO2Track(particle.pdgCode(), tlv, {particle.vx(), particle.vy(), particle.vz()}, o2track, pdg); } 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..ff804b8485a 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyTracker.cxx @@ -811,11 +811,11 @@ struct OnTheFlyTracker { float phi{std::atan2(-posClusterCandidate[1], -posClusterCandidate[0]) + o2::its::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 +833,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-correlatorDDbar.cxx b/ALICE3/TableProducer/alice3-correlatorDDbar.cxx index ad224442717..6c270dc1cd5 100644 --- a/ALICE3/TableProducer/alice3-correlatorDDbar.cxx +++ b/ALICE3/TableProducer/alice3-correlatorDDbar.cxx @@ -27,6 +27,7 @@ #include "ALICE3/DataModel/A3DecayFinderTables.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/HFC/DataModel/CorrelationTables.h" // #include "PWGHF/DataModel/CandidateReconstructionTables.h" // #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/ALICE3/TableProducer/alice3-decayfinder.cxx b/ALICE3/TableProducer/alice3-decayfinder.cxx index b0aeba5272d..83f1998bf38 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); @@ -343,24 +363,83 @@ struct alice3decayFinder { if (doprocessFindDmesons) { histos.add("h2dGenD", "h2dGenD", 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("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 +469,14 @@ 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) + 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()); + histos.fill(HIST("hDGenForEfficiency"), mcParticle.pt(), mcParticle.y()); // in common for D and Dbar + } } if (doprocessFindLcBaryons) { for (auto const& mcParticle : trueLc) @@ -437,37 +520,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 > 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 <= lowPtDLimit && 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 < minPtPi) // track1 (positive) is the pion continue; - else if (dmeson.pt > 16 && std::fabs(dmeson.cosThetaStar) > DCosThetaStarVHighPt) + if (dmeson.ptdaugNeg < minPtK) // track2 (negative) is the kaon continue; - if (dmeson.normalizedDecayLength > DDauDecayLength) + 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(), @@ -497,37 +665,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 > 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 <= highPtDLimit && std::fabs(dmeson.cosThetaStar) > DCosThetaStarLowPt) continue; - else if (dmeson.pt <= 16 && std::fabs(dmeson.cosThetaStar) > DCosThetaStarHighPt) + else if (dmeson.pt <= highPtDLimit && std::fabs(dmeson.cosThetaStar) > DCosThetaStarHighPt) continue; - else if (dmeson.pt > 16 && std::fabs(dmeson.cosThetaStar) > DCosThetaStarVHighPt) + else if (dmeson.pt > highPtDLimit && std::fabs(dmeson.cosThetaStar) > DCosThetaStarVHighPt) continue; - if (dmeson.normalizedDecayLength > DDauDecayLength) + if (dmeson.normalizedDecayLength < DMinNormDecayLength || dmeson.normalizedDecayLength > DMaxNormDecayLength) continue; - histos.fill(HIST("hDCADbarDaughters"), dmeson.dcaDau * 1e+4); + if (dmeson.ptdaugPos < minPtK) // track1 is the kaon + continue; + if (dmeson.ptdaugNeg < minPtPi) // track2 is the pion + continue; + + if (impParXY_daugPos > maxImpParK) + continue; + if (impParXY_daugNeg > maxImpParPi) + continue; + if (impParXY_daugPos * impParXY_daugNeg > maxImpParProduct) + continue; + + 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..16b16c666d8 100644 --- a/ALICE3/TableProducer/alice3-multicharm.cxx +++ b/ALICE3/TableProducer/alice3-multicharmTable.cxx @@ -71,7 +71,7 @@ using tofTracks = soa::Join; using richTracks = soa::Join; using alice3tracks = soa::Join; -struct alice3multicharm { +struct alice3multicharmTable { SliceCache cache; Produces multiCharmIdx; @@ -131,8 +131,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 +412,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 +516,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 +539,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 +560,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 +587,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 +615,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 +630,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 +651,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 +713,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 +761,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..34276a800b3 --- /dev/null +++ b/ALICE3/Tasks/alice3-multicharm.cxx @@ -0,0 +1,235 @@ +// 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 +#include +#include +#include +#include +#include + +#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 "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/DataModel/TrackSelectionTables.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsBase/GeometryManager.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "CCDB/BasicCCDBManager.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 "DetectorsVertexing/PVertexer.h" +#include "DetectorsVertexing/PVertexerHelpers.h" +#include "CommonConstants/PhysicsConstants.h" + +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/alice3-taskcorrelationDDbar.cxx b/ALICE3/Tasks/alice3-taskcorrelationDDbar.cxx index 66f641302ee..b6c8058f747 100644 --- a/ALICE3/Tasks/alice3-taskcorrelationDDbar.cxx +++ b/ALICE3/Tasks/alice3-taskcorrelationDDbar.cxx @@ -20,6 +20,7 @@ #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/Utils/utilsAnalysis.h" #include "PWGHF/HFC/DataModel/CorrelationTables.h" // #include "PWGHF/DataModel/CandidateReconstructionTables.h" diff --git a/ALICE3/Tasks/alice3Efficiency.cxx b/ALICE3/Tasks/alice3Efficiency.cxx new file mode 100644 index 00000000000..7741ea24696 --- /dev/null +++ b/ALICE3/Tasks/alice3Efficiency.cxx @@ -0,0 +1,103 @@ +// 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 +#include + +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/ConfigParamRegistry.h" +#include "TEfficiency.h" +#include "THashList.h" + +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..ae5b52d0692 --- /dev/null +++ b/ALICE3/Tasks/alice3SeparationPower.cxx @@ -0,0 +1,106 @@ +// 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 +#include +#include +#include + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/HistogramRegistry.h" +#include "TProfile2D.h" +#include "THashList.h" +#include "ALICE3/DataModel/OTFTOF.h" +#include "ALICE3/DataModel/OTFRICH.h" + +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 1c6a87f8878..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 @@ -51,10 +51,10 @@ /PWGLF/TableProducer/Strangeness @alibuild @sustripathy @skundu692 @ercolessi @romainschotter # PWG-MM -/PWGMM @alibuild @sustripathy @skundu692 @aalkin -/PWGMM/Mult @alibuild @sustripathy @skundu692 @aalkin @aortizve @ddobrigk @gbencedi -/PWGMM/Lumi @alibuild @aalkin -/PWGMM/UE @alibuild @aalkin @aortizve +/PWGMM @alibuild @sustripathy @skundu692 @aalkin @jgcn +/PWGMM/Mult @alibuild @sustripathy @skundu692 @aalkin @aortizve @ddobrigk @gbencedi @jgcn +/PWGMM/Lumi @alibuild @aalkin @jgcn +/PWGMM/UE @alibuild @aalkin @aortizve @jgcn /PWGUD @alibuild @pbuehler @abylinkin @rolavick /PWGJE @alibuild @lhavener @maoyx @nzardosh @fjonasALICE @mfasDa @mhemmer-cern diff --git a/Common/CCDB/macros/upload_event_selection_params.C b/Common/CCDB/macros/upload_event_selection_params.C index 5d63cf49be8..cafc863ab03 100644 --- a/Common/CCDB/macros/upload_event_selection_params.C +++ b/Common/CCDB/macros/upload_event_selection_params.C @@ -12,8 +12,8 @@ #include "CCDB/CcdbApi.h" #include "CCDB/BasicCCDBManager.h" #include "TString.h" -#include "map" -#include "string" +#include +#include #include "EventSelectionParams.h" 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..f81491949c6 100644 --- a/Common/CCDB/macros/upload_event_selection_params_run3.C +++ b/Common/CCDB/macros/upload_event_selection_params_run3.C @@ -11,8 +11,8 @@ #include "CCDB/CcdbApi.h" #include "TString.h" -#include "map" -#include "string" +#include +#include #include "EventSelectionParams.h" using std::map; using std::string; diff --git a/Common/DataModel/Centrality.h b/Common/DataModel/Centrality.h index c3074a63c67..fa7e2ec51bc 100644 --- a/Common/DataModel/Centrality.h +++ b/Common/DataModel/Centrality.h @@ -60,6 +60,11 @@ DECLARE_SOA_TABLE(CentMFTs, "AOD", "CENTMFT", cent::CentMFT); //! Ru // Run 3 variant tables DECLARE_SOA_TABLE(CentFT0CVariant1s, "AOD", "CENTFT0Cvar1", cent::CentFT0CVariant1); //! Run 3 FT0C variant 1 +// Run 3 centrality per BC (joinable with BC) +DECLARE_SOA_TABLE(BCCentFT0Ms, "AOD", "BCCENTFT0M", cent::CentFT0M, o2::soa::Marker<1>); //! Run 3 FT0M BC centrality table +DECLARE_SOA_TABLE(BCCentFT0As, "AOD", "BCCENTFT0A", cent::CentFT0A, o2::soa::Marker<1>); //! Run 3 FT0A BC centrality table +DECLARE_SOA_TABLE(BCCentFT0Cs, "AOD", "BCCENTFT0C", cent::CentFT0C, o2::soa::Marker<1>); //! Run 3 FT0C BC centrality table + using CentRun2V0M = CentRun2V0Ms::iterator; using CentRun2V0A = CentRun2V0As::iterator; using CentRun2SPDTrk = CentRun2SPDTrks::iterator; @@ -77,6 +82,10 @@ using CentNTPV = CentNTPVs::iterator; using CentNGlobal = CentNGlobals::iterator; using CentMFT = CentMFTs::iterator; +using BCCentFT0M = BCCentFT0Ms::iterator; +using BCCentFT0A = BCCentFT0As::iterator; +using BCCentFT0C = BCCentFT0Cs::iterator; + template concept HasRun2Centrality = requires(T&& t) { { t.centRun2V0M() }; diff --git a/Common/DataModel/OccupancyTables.h b/Common/DataModel/OccupancyTables.h index e8f33b90990..4828183a269 100644 --- a/Common/DataModel/OccupancyTables.h +++ b/Common/DataModel/OccupancyTables.h @@ -97,16 +97,31 @@ DECLARE_SOA_COLUMN(MeanOccRobustMultExtraTableUnfm80, meanOccRobustMultExtraTabl } // namespace occp DECLARE_SOA_TABLE(OccsBCsList, "AOD", "OCCSBCSLIST", o2::soa::Index<>, o2::aod::occp::TfId, o2::aod::occp::BcsInTFList); -DECLARE_SOA_TABLE(OccsDet, "AOD", "OCCSDET", o2::soa::Index<>, - o2::aod::occp::OccPrimUnfm80, +// 1 +DECLARE_SOA_TABLE(OccsPrim, "AOD", "OCCSPRIM", o2::soa::Index<>, + o2::aod::occp::OccPrimUnfm80); +DECLARE_SOA_TABLE(OccsMeanPrim, "AOD", "OCCSMEANPRIM", o2::soa::Index<>, + o2::aod::occp::MeanOccPrimUnfm80); +// 2 +DECLARE_SOA_TABLE(OccsT0V0, "AOD", "OCCST0V0", o2::soa::Index<>, o2::aod::occp::OccFV0AUnfm80, o2::aod::occp::OccFV0CUnfm80, o2::aod::occp::OccFT0AUnfm80, - o2::aod::occp::OccFT0CUnfm80, + o2::aod::occp::OccFT0CUnfm80); +DECLARE_SOA_TABLE(OccsMeanT0V0, "AOD", "OCCSMEANT0V0", o2::soa::Index<>, + o2::aod::occp::MeanOccFV0AUnfm80, + o2::aod::occp::MeanOccFV0CUnfm80, + o2::aod::occp::MeanOccFT0AUnfm80, + o2::aod::occp::MeanOccFT0CUnfm80); +// 3 +DECLARE_SOA_TABLE(OccsFDD, "AOD", "OCCSFDD", o2::soa::Index<>, o2::aod::occp::OccFDDAUnfm80, o2::aod::occp::OccFDDCUnfm80); - -DECLARE_SOA_TABLE(OccsTrackMult, "AOD", "OCCSTRACKMULT", o2::soa::Index<>, +DECLARE_SOA_TABLE(OccsMeanFDD, "AOD", "OCCSMEANFDD", o2::soa::Index<>, + o2::aod::occp::MeanOccFDDAUnfm80, + o2::aod::occp::MeanOccFDDCUnfm80); +// 4 +DECLARE_SOA_TABLE(OccsNTrackDet, "AOD", "OCCSNTRACKDET", o2::soa::Index<>, o2::aod::occp::OccNTrackITSUnfm80, o2::aod::occp::OccNTrackTPCUnfm80, o2::aod::occp::OccNTrackTRDUnfm80, @@ -117,33 +132,7 @@ DECLARE_SOA_TABLE(OccsTrackMult, "AOD", "OCCSTRACKMULT", o2::soa::Index<>, o2::aod::occp::OccNTrackITSTPCUnfm80, o2::aod::occp::OccNTrackITSTPCAUnfm80, o2::aod::occp::OccNTrackITSTPCCUnfm80); - -DECLARE_SOA_TABLE(OccsMultExtra, "AOD", "OCCSMULTEXTRA", o2::soa::Index<>, - o2::aod::occp::OccMultNTracksHasITSUnfm80, - o2::aod::occp::OccMultNTracksHasTPCUnfm80, - o2::aod::occp::OccMultNTracksHasTOFUnfm80, - o2::aod::occp::OccMultNTracksHasTRDUnfm80, - o2::aod::occp::OccMultNTracksITSOnlyUnfm80, - o2::aod::occp::OccMultNTracksTPCOnlyUnfm80, - o2::aod::occp::OccMultNTracksITSTPCUnfm80, - o2::aod::occp::OccMultAllTracksTPCOnlyUnfm80); - -DECLARE_SOA_TABLE(OccsRobust, "AOD", "OCCSROBUST", o2::soa::Index<>, - o2::aod::occp::OccRobustT0V0PrimUnfm80, - o2::aod::occp::OccRobustFDDT0V0PrimUnfm80, - o2::aod::occp::OccRobustNtrackDetUnfm80, - o2::aod::occp::OccRobustMultExtraTableUnfm80); - -DECLARE_SOA_TABLE(OccsMeanDet, "AOD", "OCCSMEANDET", o2::soa::Index<>, - o2::aod::occp::MeanOccPrimUnfm80, - o2::aod::occp::MeanOccFV0AUnfm80, - o2::aod::occp::MeanOccFV0CUnfm80, - o2::aod::occp::MeanOccFT0AUnfm80, - o2::aod::occp::MeanOccFT0CUnfm80, - o2::aod::occp::MeanOccFDDAUnfm80, - o2::aod::occp::MeanOccFDDCUnfm80); - -DECLARE_SOA_TABLE(OccsMeanTrkMult, "AOD", "OCCSMEANTRKMULT", o2::soa::Index<>, +DECLARE_SOA_TABLE(OccsMeanNTrkDet, "AOD", "OCCSMEANNTRKDET", o2::soa::Index<>, o2::aod::occp::MeanOccNTrackITSUnfm80, o2::aod::occp::MeanOccNTrackTPCUnfm80, o2::aod::occp::MeanOccNTrackTRDUnfm80, @@ -154,7 +143,16 @@ DECLARE_SOA_TABLE(OccsMeanTrkMult, "AOD", "OCCSMEANTRKMULT", o2::soa::Index<>, o2::aod::occp::MeanOccNTrackITSTPCUnfm80, o2::aod::occp::MeanOccNTrackITSTPCAUnfm80, o2::aod::occp::MeanOccNTrackITSTPCCUnfm80); - +// 5 +DECLARE_SOA_TABLE(OccsMultExtra, "AOD", "OCCSMULTEXTRA", o2::soa::Index<>, + o2::aod::occp::OccMultNTracksHasITSUnfm80, + o2::aod::occp::OccMultNTracksHasTPCUnfm80, + o2::aod::occp::OccMultNTracksHasTOFUnfm80, + o2::aod::occp::OccMultNTracksHasTRDUnfm80, + o2::aod::occp::OccMultNTracksITSOnlyUnfm80, + o2::aod::occp::OccMultNTracksTPCOnlyUnfm80, + o2::aod::occp::OccMultNTracksITSTPCUnfm80, + o2::aod::occp::OccMultAllTracksTPCOnlyUnfm80); DECLARE_SOA_TABLE(OccsMnMultExtra, "AOD", "OCCSMNMULTEXTRA", o2::soa::Index<>, o2::aod::occp::MeanOccMultNTracksHasITSUnfm80, o2::aod::occp::MeanOccMultNTracksHasTPCUnfm80, @@ -165,10 +163,26 @@ DECLARE_SOA_TABLE(OccsMnMultExtra, "AOD", "OCCSMNMULTEXTRA", o2::soa::Index<>, o2::aod::occp::MeanOccMultNTracksITSTPCUnfm80, o2::aod::occp::MeanOccMultAllTracksTPCOnlyUnfm80); -DECLARE_SOA_TABLE(OccsMeanRobust, "AOD", "OCCSMEANROBUST", o2::soa::Index<>, - o2::aod::occp::MeanOccRobustT0V0PrimUnfm80, - o2::aod::occp::MeanOccRobustFDDT0V0PrimUnfm80, - o2::aod::occp::MeanOccRobustNtrackDetUnfm80, +// Robust Occupancies +// 1 +DECLARE_SOA_TABLE(ORT0V0Prim, "AOD", "ORT0V0Prim", o2::soa::Index<>, + o2::aod::occp::OccRobustT0V0PrimUnfm80); +DECLARE_SOA_TABLE(OMRT0V0Prim, "AOD", "OMRT0V0PRIM", o2::soa::Index<>, + o2::aod::occp::MeanOccRobustT0V0PrimUnfm80); +// 2 +DECLARE_SOA_TABLE(ORFDDT0V0Prim, "AOD", "ORFDDT0V0PRIM", o2::soa::Index<>, + o2::aod::occp::OccRobustFDDT0V0PrimUnfm80); +DECLARE_SOA_TABLE(OMRFDDT0V0Prim, "AOD", "OMRFDDT0V0PRIM", o2::soa::Index<>, + o2::aod::occp::MeanOccRobustFDDT0V0PrimUnfm80); +// 3 +DECLARE_SOA_TABLE(ORNtrackDet, "AOD", "ORNTRACKDET", o2::soa::Index<>, + o2::aod::occp::OccRobustNtrackDetUnfm80); +DECLARE_SOA_TABLE(OMRNtrackDet, "AOD", "OMRNTRACKDET", o2::soa::Index<>, + o2::aod::occp::MeanOccRobustNtrackDetUnfm80); +// 4 +DECLARE_SOA_TABLE(ORMultExtra, "AOD", "ORMULTEXTRA", o2::soa::Index<>, + o2::aod::occp::OccRobustMultExtraTableUnfm80); +DECLARE_SOA_TABLE(OMRMultExtra, "AOD", "OMRMULTEXTRA", o2::soa::Index<>, o2::aod::occp::MeanOccRobustMultExtraTableUnfm80); using Occs = aod::OccsBCsList; @@ -176,7 +190,7 @@ using Occ = Occs::iterator; namespace occidx { -DECLARE_SOA_INDEX_COLUMN(BC, bc); // Iterator is passed here in index column +DECLARE_SOA_INDEX_COLUMN(BC, bc); // o2-linter: disable=name/o2-column (BC is an acronym already defined in data model) // Iterator is passed here in index column DECLARE_SOA_INDEX_COLUMN(Occ, occ); DECLARE_SOA_COLUMN(TfId, tfId, int); DECLARE_SOA_COLUMN(BcInTF, bcInTF, int); @@ -195,151 +209,173 @@ namespace trackmeanocc { DECLARE_SOA_INDEX_COLUMN(Track, track); -DECLARE_SOA_COLUMN(MeanOccPrimUnfm80, meanOccPrimUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccFV0AUnfm80, meanOccFV0AUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccFV0CUnfm80, meanOccFV0CUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccFT0AUnfm80, meanOccFT0AUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccFT0CUnfm80, meanOccFT0CUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccFDDAUnfm80, meanOccFDDAUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccFDDCUnfm80, meanOccFDDCUnfm80, float); - -DECLARE_SOA_COLUMN(MeanOccNTrackITSUnfm80, meanOccNTrackITSUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccNTrackTPCUnfm80, meanOccNTrackTPCUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccNTrackTRDUnfm80, meanOccNTrackTRDUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccNTrackTOFUnfm80, meanOccNTrackTOFUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccNTrackSizeUnfm80, meanOccNTrackSizeUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccNTrackTPCAUnfm80, meanOccNTrackTPCAUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccNTrackTPCCUnfm80, meanOccNTrackTPCCUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccNTrackITSTPCUnfm80, meanOccNTrackITSTPCUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccNTrackITSTPCAUnfm80, meanOccNTrackITSTPCAUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccNTrackITSTPCCUnfm80, meanOccNTrackITSTPCCUnfm80, float); - -DECLARE_SOA_COLUMN(MeanOccMultNTracksHasITSUnfm80, meanOccMultNTracksHasITSUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccMultNTracksHasTPCUnfm80, meanOccMultNTracksHasTPCUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccMultNTracksHasTOFUnfm80, meanOccMultNTracksHasTOFUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccMultNTracksHasTRDUnfm80, meanOccMultNTracksHasTRDUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccMultNTracksITSOnlyUnfm80, meanOccMultNTracksITSOnlyUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccMultNTracksTPCOnlyUnfm80, meanOccMultNTracksTPCOnlyUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccMultNTracksITSTPCUnfm80, meanOccMultNTracksITSTPCUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccMultAllTracksTPCOnlyUnfm80, meanOccMultAllTracksTPCOnlyUnfm80, float); - -DECLARE_SOA_COLUMN(MeanOccRobustT0V0PrimUnfm80, meanOccRobustT0V0PrimUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccRobustFDDT0V0PrimUnfm80, meanOccRobustFDDT0V0PrimUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccRobustNtrackDetUnfm80, meanOccRobustNtrackDetUnfm80, float); -DECLARE_SOA_COLUMN(MeanOccRobustMultExtraTableUnfm80, meanOccRobustMultExtraTableUnfm80, float); - -DECLARE_SOA_COLUMN(WeightMeanOccPrimUnfm80, weightMeanOccPrimUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccFV0AUnfm80, weightMeanOccFV0AUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccFV0CUnfm80, weightMeanOccFV0CUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccFT0AUnfm80, weightMeanOccFT0AUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccFT0CUnfm80, weightMeanOccFT0CUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccFDDAUnfm80, weightMeanOccFDDAUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccFDDCUnfm80, weightMeanOccFDDCUnfm80, float); - -DECLARE_SOA_COLUMN(WeightMeanOccNTrackITSUnfm80, weightMeanOccNTrackITSUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccNTrackTPCUnfm80, weightMeanOccNTrackTPCUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccNTrackTRDUnfm80, weightMeanOccNTrackTRDUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccNTrackTOFUnfm80, weightMeanOccNTrackTOFUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccNTrackSizeUnfm80, weightMeanOccNTrackSizeUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccNTrackTPCAUnfm80, weightMeanOccNTrackTPCAUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccNTrackTPCCUnfm80, weightMeanOccNTrackTPCCUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccNTrackITSTPCUnfm80, weightMeanOccNTrackITSTPCUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccNTrackITSTPCAUnfm80, weightMeanOccNTrackITSTPCAUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccNTrackITSTPCCUnfm80, weightMeanOccNTrackITSTPCCUnfm80, float); - -DECLARE_SOA_COLUMN(WeightMeanOccMultNTracksHasITSUnfm80, weightMeanOccMultNTracksHasITSUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccMultNTracksHasTPCUnfm80, weightMeanOccMultNTracksHasTPCUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccMultNTracksHasTOFUnfm80, weightMeanOccMultNTracksHasTOFUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccMultNTracksHasTRDUnfm80, weightMeanOccMultNTracksHasTRDUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccMultNTracksITSOnlyUnfm80, weightMeanOccMultNTracksITSOnlyUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccMultNTracksTPCOnlyUnfm80, weightMeanOccMultNTracksTPCOnlyUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccMultNTracksITSTPCUnfm80, weightMeanOccMultNTracksITSTPCUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccMultAllTracksTPCOnlyUnfm80, weightMeanOccMultAllTracksTPCOnlyUnfm80, float); - -DECLARE_SOA_COLUMN(WeightMeanOccRobustT0V0PrimUnfm80, weightMeanOccRobustT0V0PrimUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccRobustFDDT0V0PrimUnfm80, weightMeanOccRobustFDDT0V0PrimUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccRobustNtrackDetUnfm80, weightMeanOccRobustNtrackDetUnfm80, float); -DECLARE_SOA_COLUMN(WeightMeanOccRobustMultExtraTableUnfm80, weightMeanOccRobustMultExtraTableUnfm80, float); +DECLARE_SOA_COLUMN(TmoPrimUnfm80, tmoPrimUnfm80, float); +DECLARE_SOA_COLUMN(TmoFV0AUnfm80, tmoFV0AUnfm80, float); +DECLARE_SOA_COLUMN(TmoFV0CUnfm80, tmoFV0CUnfm80, float); +DECLARE_SOA_COLUMN(TmoFT0AUnfm80, tmoFT0AUnfm80, float); +DECLARE_SOA_COLUMN(TmoFT0CUnfm80, tmoFT0CUnfm80, float); +DECLARE_SOA_COLUMN(TmoFDDAUnfm80, tmoFDDAUnfm80, float); +DECLARE_SOA_COLUMN(TmoFDDCUnfm80, tmoFDDCUnfm80, float); + +DECLARE_SOA_COLUMN(TmoNTrackITSUnfm80, tmoNTrackITSUnfm80, float); +DECLARE_SOA_COLUMN(TmoNTrackTPCUnfm80, tmoNTrackTPCUnfm80, float); +DECLARE_SOA_COLUMN(TmoNTrackTRDUnfm80, tmoNTrackTRDUnfm80, float); +DECLARE_SOA_COLUMN(TmoNTrackTOFUnfm80, tmoNTrackTOFUnfm80, float); +DECLARE_SOA_COLUMN(TmoNTrackSizeUnfm80, tmoNTrackSizeUnfm80, float); +DECLARE_SOA_COLUMN(TmoNTrackTPCAUnfm80, tmoNTrackTPCAUnfm80, float); +DECLARE_SOA_COLUMN(TmoNTrackTPCCUnfm80, tmoNTrackTPCCUnfm80, float); +DECLARE_SOA_COLUMN(TmoNTrackITSTPCUnfm80, tmoNTrackITSTPCUnfm80, float); +DECLARE_SOA_COLUMN(TmoNTrackITSTPCAUnfm80, tmoNTrackITSTPCAUnfm80, float); +DECLARE_SOA_COLUMN(TmoNTrackITSTPCCUnfm80, tmoNTrackITSTPCCUnfm80, float); + +DECLARE_SOA_COLUMN(TmoMultNTracksHasITSUnfm80, tmoMultNTracksHasITSUnfm80, float); +DECLARE_SOA_COLUMN(TmoMultNTracksHasTPCUnfm80, tmoMultNTracksHasTPCUnfm80, float); +DECLARE_SOA_COLUMN(TmoMultNTracksHasTOFUnfm80, tmoMultNTracksHasTOFUnfm80, float); +DECLARE_SOA_COLUMN(TmoMultNTracksHasTRDUnfm80, tmoMultNTracksHasTRDUnfm80, float); +DECLARE_SOA_COLUMN(TmoMultNTracksITSOnlyUnfm80, tmoMultNTracksITSOnlyUnfm80, float); +DECLARE_SOA_COLUMN(TmoMultNTracksTPCOnlyUnfm80, tmoMultNTracksTPCOnlyUnfm80, float); +DECLARE_SOA_COLUMN(TmoMultNTracksITSTPCUnfm80, tmoMultNTracksITSTPCUnfm80, float); +DECLARE_SOA_COLUMN(TmoMultAllTracksTPCOnlyUnfm80, tmoMultAllTracksTPCOnlyUnfm80, float); + +DECLARE_SOA_COLUMN(TmoRobustT0V0PrimUnfm80, tmoRobustT0V0PrimUnfm80, float); +DECLARE_SOA_COLUMN(TmoRobustFDDT0V0PrimUnfm80, tmoRobustFDDT0V0PrimUnfm80, float); +DECLARE_SOA_COLUMN(TmoRobustNtrackDetUnfm80, tmoRobustNtrackDetUnfm80, float); +DECLARE_SOA_COLUMN(TmoRobustMultExtraTableUnfm80, tmoRobustMultExtraTableUnfm80, float); + +DECLARE_SOA_COLUMN(TwmoPrimUnfm80, twmoPrimUnfm80, float); +DECLARE_SOA_COLUMN(TwmoFV0AUnfm80, twmoFV0AUnfm80, float); +DECLARE_SOA_COLUMN(TwmoFV0CUnfm80, twmoFV0CUnfm80, float); +DECLARE_SOA_COLUMN(TwmoFT0AUnfm80, twmoFT0AUnfm80, float); +DECLARE_SOA_COLUMN(TwmoFT0CUnfm80, twmoFT0CUnfm80, float); +DECLARE_SOA_COLUMN(TwmoFDDAUnfm80, twmoFDDAUnfm80, float); +DECLARE_SOA_COLUMN(TwmoFDDCUnfm80, twmoFDDCUnfm80, float); + +DECLARE_SOA_COLUMN(TwmoNTrackITSUnfm80, twmoNTrackITSUnfm80, float); +DECLARE_SOA_COLUMN(TwmoNTrackTPCUnfm80, twmoNTrackTPCUnfm80, float); +DECLARE_SOA_COLUMN(TwmoNTrackTRDUnfm80, twmoNTrackTRDUnfm80, float); +DECLARE_SOA_COLUMN(TwmoNTrackTOFUnfm80, twmoNTrackTOFUnfm80, float); +DECLARE_SOA_COLUMN(TwmoNTrackSizeUnfm80, twmoNTrackSizeUnfm80, float); +DECLARE_SOA_COLUMN(TwmoNTrackTPCAUnfm80, twmoNTrackTPCAUnfm80, float); +DECLARE_SOA_COLUMN(TwmoNTrackTPCCUnfm80, twmoNTrackTPCCUnfm80, float); +DECLARE_SOA_COLUMN(TwmoNTrackITSTPCUnfm80, twmoNTrackITSTPCUnfm80, float); +DECLARE_SOA_COLUMN(TwmoNTrackITSTPCAUnfm80, twmoNTrackITSTPCAUnfm80, float); +DECLARE_SOA_COLUMN(TwmoNTrackITSTPCCUnfm80, twmoNTrackITSTPCCUnfm80, float); + +DECLARE_SOA_COLUMN(TwmoMultNTracksHasITSUnfm80, twmoMultNTracksHasITSUnfm80, float); +DECLARE_SOA_COLUMN(TwmoMultNTracksHasTPCUnfm80, twmoMultNTracksHasTPCUnfm80, float); +DECLARE_SOA_COLUMN(TwmoMultNTracksHasTOFUnfm80, twmoMultNTracksHasTOFUnfm80, float); +DECLARE_SOA_COLUMN(TwmoMultNTracksHasTRDUnfm80, twmoMultNTracksHasTRDUnfm80, float); +DECLARE_SOA_COLUMN(TwmoMultNTracksITSOnlyUnfm80, twmoMultNTracksITSOnlyUnfm80, float); +DECLARE_SOA_COLUMN(TwmoMultNTracksTPCOnlyUnfm80, twmoMultNTracksTPCOnlyUnfm80, float); +DECLARE_SOA_COLUMN(TwmoMultNTracksITSTPCUnfm80, twmoMultNTracksITSTPCUnfm80, float); +DECLARE_SOA_COLUMN(TwmoMultAllTracksTPCOnlyUnfm80, twmoMultAllTracksTPCOnlyUnfm80, float); + +DECLARE_SOA_COLUMN(TwmoRobustT0V0PrimUnfm80, twmoRobustT0V0PrimUnfm80, float); +DECLARE_SOA_COLUMN(TwmoRobustFDDT0V0PrimUnfm80, twmoRobustFDDT0V0PrimUnfm80, float); +DECLARE_SOA_COLUMN(TwmoRobustNtrackDetUnfm80, twmoRobustNtrackDetUnfm80, float); +DECLARE_SOA_COLUMN(TwmoRobustMultExtraTableUnfm80, twmoRobustMultExtraTableUnfm80, float); } // namespace trackmeanocc // Tracks // using Tracks = aod::Tracks; // DECLARE_SOA_INDEX_TABLE_USER(TrackMeanOccs0, Tracks, "TRACKMEANOCCS0", o2::aod::trackmeanocc::TrackId); -DECLARE_SOA_TABLE(TrackMeanOccs0, "AOD", "TRACKMEANOCCS0", o2::aod::trackmeanocc::TrackId); - -DECLARE_SOA_TABLE(TrackMeanOccs1, "AOD", "TRACKMEANOCCS1", o2::soa::Index<>, // TrackMeanOccDet - o2::aod::trackmeanocc::MeanOccPrimUnfm80, - o2::aod::trackmeanocc::MeanOccFV0AUnfm80, - o2::aod::trackmeanocc::MeanOccFV0CUnfm80, - o2::aod::trackmeanocc::MeanOccFT0AUnfm80, - o2::aod::trackmeanocc::MeanOccFT0CUnfm80, - o2::aod::trackmeanocc::MeanOccFDDAUnfm80, - o2::aod::trackmeanocc::MeanOccFDDCUnfm80); - -DECLARE_SOA_TABLE(TrackMeanOccs2, "AOD", "TRACKMEANOCCS2", o2::soa::Index<>, // TrackMeanOccTrackMult - o2::aod::trackmeanocc::MeanOccNTrackITSUnfm80, - o2::aod::trackmeanocc::MeanOccNTrackTPCUnfm80, - o2::aod::trackmeanocc::MeanOccNTrackTRDUnfm80, - o2::aod::trackmeanocc::MeanOccNTrackTOFUnfm80, - o2::aod::trackmeanocc::MeanOccNTrackSizeUnfm80, - o2::aod::trackmeanocc::MeanOccNTrackTPCAUnfm80, - o2::aod::trackmeanocc::MeanOccNTrackTPCCUnfm80, - o2::aod::trackmeanocc::MeanOccNTrackITSTPCUnfm80, - o2::aod::trackmeanocc::MeanOccNTrackITSTPCAUnfm80, - o2::aod::trackmeanocc::MeanOccNTrackITSTPCCUnfm80); - -DECLARE_SOA_TABLE(TrackMeanOccs3, "AOD", "TRACKMEANOCCS3", o2::soa::Index<>, // TrackMeanOccMultExtra - o2::aod::trackmeanocc::MeanOccMultNTracksHasITSUnfm80, - o2::aod::trackmeanocc::MeanOccMultNTracksHasTPCUnfm80, - o2::aod::trackmeanocc::MeanOccMultNTracksHasTOFUnfm80, - o2::aod::trackmeanocc::MeanOccMultNTracksHasTRDUnfm80, - o2::aod::trackmeanocc::MeanOccMultNTracksITSOnlyUnfm80, - o2::aod::trackmeanocc::MeanOccMultNTracksTPCOnlyUnfm80, - o2::aod::trackmeanocc::MeanOccMultNTracksITSTPCUnfm80, - o2::aod::trackmeanocc::MeanOccMultAllTracksTPCOnlyUnfm80); - -DECLARE_SOA_TABLE(TrackMeanOccs4, "AOD", "TRACKMEANOCCS4", o2::soa::Index<>, // TrackMeanOccRobus - o2::aod::trackmeanocc::MeanOccRobustT0V0PrimUnfm80, - o2::aod::trackmeanocc::MeanOccRobustFDDT0V0PrimUnfm80, - o2::aod::trackmeanocc::MeanOccRobustNtrackDetUnfm80, - o2::aod::trackmeanocc::MeanOccRobustMultExtraTableUnfm80); - -DECLARE_SOA_TABLE(TrackMeanOccs5, "AOD", "TRACKMEANOCCS5", o2::soa::Index<>, // TrackWieghtMeanOccDet - o2::aod::trackmeanocc::WeightMeanOccPrimUnfm80, - o2::aod::trackmeanocc::WeightMeanOccFV0AUnfm80, - o2::aod::trackmeanocc::WeightMeanOccFV0CUnfm80, - o2::aod::trackmeanocc::WeightMeanOccFT0AUnfm80, - o2::aod::trackmeanocc::WeightMeanOccFT0CUnfm80, - o2::aod::trackmeanocc::WeightMeanOccFDDAUnfm80, - o2::aod::trackmeanocc::WeightMeanOccFDDCUnfm80); - -DECLARE_SOA_TABLE(TrackMeanOccs6, "AOD", "TRACKMEANOCCS6", o2::soa::Index<>, // TrackWieghtMeanOccMult - o2::aod::trackmeanocc::WeightMeanOccNTrackITSUnfm80, - o2::aod::trackmeanocc::WeightMeanOccNTrackTPCUnfm80, - o2::aod::trackmeanocc::WeightMeanOccNTrackTRDUnfm80, - o2::aod::trackmeanocc::WeightMeanOccNTrackTOFUnfm80, - o2::aod::trackmeanocc::WeightMeanOccNTrackSizeUnfm80, - o2::aod::trackmeanocc::WeightMeanOccNTrackTPCAUnfm80, - o2::aod::trackmeanocc::WeightMeanOccNTrackTPCCUnfm80, - o2::aod::trackmeanocc::WeightMeanOccNTrackITSTPCUnfm80, - o2::aod::trackmeanocc::WeightMeanOccNTrackITSTPCAUnfm80, - o2::aod::trackmeanocc::WeightMeanOccNTrackITSTPCCUnfm80) - -DECLARE_SOA_TABLE(TrackMeanOccs7, "AOD", "TRACKMEANOCCS7", o2::soa::Index<>, // TrackWeightMeanOccMultExtra - o2::aod::trackmeanocc::WeightMeanOccMultNTracksHasITSUnfm80, - o2::aod::trackmeanocc::WeightMeanOccMultNTracksHasTPCUnfm80, - o2::aod::trackmeanocc::WeightMeanOccMultNTracksHasTOFUnfm80, - o2::aod::trackmeanocc::WeightMeanOccMultNTracksHasTRDUnfm80, - o2::aod::trackmeanocc::WeightMeanOccMultNTracksITSOnlyUnfm80, - o2::aod::trackmeanocc::WeightMeanOccMultNTracksTPCOnlyUnfm80, - o2::aod::trackmeanocc::WeightMeanOccMultNTracksITSTPCUnfm80, - o2::aod::trackmeanocc::WeightMeanOccMultAllTracksTPCOnlyUnfm80); - -DECLARE_SOA_TABLE(TrackMeanOccs8, "AOD", "TRACKMEANOCCS8", o2::soa::Index<>, // TrackWieghtMeanOccRboust - o2::aod::trackmeanocc::WeightMeanOccRobustT0V0PrimUnfm80, - o2::aod::trackmeanocc::WeightMeanOccRobustFDDT0V0PrimUnfm80, - o2::aod::trackmeanocc::WeightMeanOccRobustNtrackDetUnfm80, - o2::aod::trackmeanocc::WeightMeanOccRobustMultExtraTableUnfm80); + +DECLARE_SOA_TABLE(TmoTrackId, "AOD", "TMOTRACKID", o2::aod::trackmeanocc::TrackId); + +DECLARE_SOA_TABLE(TmoPrim, "AOD", "TMOPRIM", o2::soa::Index<>, // TrackMeanOccDet + o2::aod::trackmeanocc::TmoPrimUnfm80); + +DECLARE_SOA_TABLE(TmoT0V0, "AOD", "TMOT0V0", o2::soa::Index<>, // TrackMeanOccDet + o2::aod::trackmeanocc::TmoFV0AUnfm80, + o2::aod::trackmeanocc::TmoFV0CUnfm80, + o2::aod::trackmeanocc::TmoFT0AUnfm80, + o2::aod::trackmeanocc::TmoFT0CUnfm80); + +DECLARE_SOA_TABLE(TmoFDD, "AOD", "TMOFDD", o2::soa::Index<>, // TrackMeanOccDet + o2::aod::trackmeanocc::TmoFDDAUnfm80, + o2::aod::trackmeanocc::TmoFDDCUnfm80); + +DECLARE_SOA_TABLE(TmoNTrackDet, "AOD", "TMONTRACKDET", o2::soa::Index<>, // TrackMeanOccNtrackDet + o2::aod::trackmeanocc::TmoNTrackITSUnfm80, + o2::aod::trackmeanocc::TmoNTrackTPCUnfm80, + o2::aod::trackmeanocc::TmoNTrackTRDUnfm80, + o2::aod::trackmeanocc::TmoNTrackTOFUnfm80, + o2::aod::trackmeanocc::TmoNTrackSizeUnfm80, + o2::aod::trackmeanocc::TmoNTrackTPCAUnfm80, + o2::aod::trackmeanocc::TmoNTrackTPCCUnfm80, + o2::aod::trackmeanocc::TmoNTrackITSTPCUnfm80, + o2::aod::trackmeanocc::TmoNTrackITSTPCAUnfm80, + o2::aod::trackmeanocc::TmoNTrackITSTPCCUnfm80); + +DECLARE_SOA_TABLE(TmoMultExtra, "AOD", "TMOMULTEXTRA", o2::soa::Index<>, // TrackMeanOccMultExtra + o2::aod::trackmeanocc::TmoMultNTracksHasITSUnfm80, + o2::aod::trackmeanocc::TmoMultNTracksHasTPCUnfm80, + o2::aod::trackmeanocc::TmoMultNTracksHasTOFUnfm80, + o2::aod::trackmeanocc::TmoMultNTracksHasTRDUnfm80, + o2::aod::trackmeanocc::TmoMultNTracksITSOnlyUnfm80, + o2::aod::trackmeanocc::TmoMultNTracksTPCOnlyUnfm80, + o2::aod::trackmeanocc::TmoMultNTracksITSTPCUnfm80, + o2::aod::trackmeanocc::TmoMultAllTracksTPCOnlyUnfm80); + +DECLARE_SOA_TABLE(TmoRT0V0Prim, "AOD", "TMORT0V0PRIM", o2::soa::Index<>, + o2::aod::trackmeanocc::TmoRobustT0V0PrimUnfm80); + +DECLARE_SOA_TABLE(TmoRFDDT0V0Prim, "AOD", "TMORFDDT0V0PRIM", o2::soa::Index<>, + o2::aod::trackmeanocc::TmoRobustFDDT0V0PrimUnfm80); + +DECLARE_SOA_TABLE(TmoRNtrackDet, "AOD", "TMORNTRACKDET", o2::soa::Index<>, + o2::aod::trackmeanocc::TmoRobustNtrackDetUnfm80); + +DECLARE_SOA_TABLE(TmoRMultExtra, "AOD", "TMORMULTEXTRA", o2::soa::Index<>, + o2::aod::trackmeanocc::TmoRobustMultExtraTableUnfm80); + +DECLARE_SOA_TABLE(TwmoPrim, "AOD", "TWMOPRIM", o2::soa::Index<>, // WeightTrackMeanOcc + o2::aod::trackmeanocc::TwmoPrimUnfm80); + +DECLARE_SOA_TABLE(TwmoT0V0, "AOD", "TWMOT0V0", o2::soa::Index<>, // WeightTrackMeanOccDet + o2::aod::trackmeanocc::TwmoFV0AUnfm80, + o2::aod::trackmeanocc::TwmoFV0CUnfm80, + o2::aod::trackmeanocc::TwmoFT0AUnfm80, + o2::aod::trackmeanocc::TwmoFT0CUnfm80); + +DECLARE_SOA_TABLE(TwmoFDD, "AOD", "TWMOFDD", o2::soa::Index<>, // WeightTrackMeanOccDet + o2::aod::trackmeanocc::TwmoFDDAUnfm80, + o2::aod::trackmeanocc::TwmoFDDCUnfm80); + +DECLARE_SOA_TABLE(TwmoNTrackDet, "AOD", "TWMONTRACKDET", o2::soa::Index<>, // WeightTrackMeanOccTrackMult + o2::aod::trackmeanocc::TwmoNTrackITSUnfm80, + o2::aod::trackmeanocc::TwmoNTrackTPCUnfm80, + o2::aod::trackmeanocc::TwmoNTrackTRDUnfm80, + o2::aod::trackmeanocc::TwmoNTrackTOFUnfm80, + o2::aod::trackmeanocc::TwmoNTrackSizeUnfm80, + o2::aod::trackmeanocc::TwmoNTrackTPCAUnfm80, + o2::aod::trackmeanocc::TwmoNTrackTPCCUnfm80, + o2::aod::trackmeanocc::TwmoNTrackITSTPCUnfm80, + o2::aod::trackmeanocc::TwmoNTrackITSTPCAUnfm80, + o2::aod::trackmeanocc::TwmoNTrackITSTPCCUnfm80); + +DECLARE_SOA_TABLE(TwmoMultExtra, "AOD", "TWMOMULTEXTRA", o2::soa::Index<>, // WeightTrackMeanOccMultExtra + o2::aod::trackmeanocc::TwmoMultNTracksHasITSUnfm80, + o2::aod::trackmeanocc::TwmoMultNTracksHasTPCUnfm80, + o2::aod::trackmeanocc::TwmoMultNTracksHasTOFUnfm80, + o2::aod::trackmeanocc::TwmoMultNTracksHasTRDUnfm80, + o2::aod::trackmeanocc::TwmoMultNTracksITSOnlyUnfm80, + o2::aod::trackmeanocc::TwmoMultNTracksTPCOnlyUnfm80, + o2::aod::trackmeanocc::TwmoMultNTracksITSTPCUnfm80, + o2::aod::trackmeanocc::TwmoMultAllTracksTPCOnlyUnfm80); + +DECLARE_SOA_TABLE(TwmoRT0V0Prim, "AOD", "TWMORT0V0PRIM", o2::soa::Index<>, + o2::aod::trackmeanocc::TwmoRobustT0V0PrimUnfm80); + +DECLARE_SOA_TABLE(TwmoRFDDT0V0Pri, "AOD", "TWMORFDDT0V0PRI", o2::soa::Index<>, + o2::aod::trackmeanocc::TwmoRobustFDDT0V0PrimUnfm80); + +DECLARE_SOA_TABLE(TwmoRNtrackDet, "AOD", "TWMORNTRACKDET", o2::soa::Index<>, + o2::aod::trackmeanocc::TwmoRobustNtrackDetUnfm80); + +DECLARE_SOA_TABLE(TwmoRMultExtra, "AOD", "TWMORMULTEXTRA", o2::soa::Index<>, + o2::aod::trackmeanocc::TwmoRobustMultExtraTableUnfm80); + } // namespace o2::aod #endif // COMMON_DATAMODEL_OCCUPANCYTABLES_H_ diff --git a/Common/TableProducer/CMakeLists.txt b/Common/TableProducer/CMakeLists.txt index 042bd643d3e..3e34a7f3283 100644 --- a/Common/TableProducer/CMakeLists.txt +++ b/Common/TableProducer/CMakeLists.txt @@ -32,6 +32,11 @@ o2physics_add_dpl_workflow(multiplicity-table PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(multcenttable + SOURCES multCentTable.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(multiplicity-extra-table SOURCES multiplicityExtraTable.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/Common/TableProducer/eventSelection.cxx b/Common/TableProducer/eventSelection.cxx index 1418e42604f..b06e98b84c5 100644 --- a/Common/TableProducer/eventSelection.cxx +++ b/Common/TableProducer/eventSelection.cxx @@ -17,6 +17,7 @@ #include #include #include +#include #include "Framework/ConfigParamSpec.h" #include "Framework/runDataProcessing.h" @@ -37,6 +38,8 @@ #include "DataFormatsITSMFT/NoiseMap.h" // missing include in TimeDeadMap.h #include "DataFormatsITSMFT/TimeDeadMap.h" #include "ITSMFTReconstruction/ChipMappingITS.h" +#include "DataFormatsCTP/Configuration.h" +#include "DataFormatsCTP/Scalers.h" #include "TH1D.h" @@ -66,6 +69,7 @@ struct BcSelectionTask { Configurable confTimeFrameEndBorderMargin{"TimeFrameEndBorderMargin", -1, "Number of bcs to cut at the end of the Time Frame. Take from CCDB if -1"}; // o2-linter: disable=name/configurable (temporary fix) Configurable confCheckRunDurationLimits{"checkRunDurationLimits", false, "Check if the BCs are within the run duration limits"}; // o2-linter: disable=name/configurable (temporary fix) Configurable> maxInactiveChipsPerLayer{"maxInactiveChipsPerLayer", {8, 8, 8, 111, 111, 195, 195}, "Maximum allowed number of inactive ITS chips per layer"}; + Configurable confNumberOfOrbitsPerTF{"NumberOfOrbitsPerTF", -1, "Number of orbits per Time Frame. Take from CCDB if -1"}; // o2-linter: disable=name/configurable (temporary fix) int lastRun = -1; int64_t lastTF = -1; @@ -80,7 +84,6 @@ struct BcSelectionTask { int mITSROFrameEndBorderMargin = 20; // default value int mTimeFrameStartBorderMargin = 300; // default value int mTimeFrameEndBorderMargin = 4000; // default value - bool isPP = 1; // default value TriggerAliases* aliases = nullptr; EventSelectionParams* par = nullptr; std::map* mapRCT = nullptr; @@ -92,37 +95,11 @@ 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 = false; - } - } - // ccdb->setURL("http://ccdb-test.cern.ch:8080"); ccdb->setURL("http://alice-ccdb.cern.ch"); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); - - histos.add("hCounterTVX", "", kTH1D, {{1, 0., 1.}}); - histos.add("hCounterTCE", "", kTH1D, {{1, 0., 1.}}); - histos.add("hCounterZEM", "", kTH1D, {{1, 0., 1.}}); - histos.add("hCounterZNC", "", kTH1D, {{1, 0., 1.}}); - histos.add("hCounterTVXafterBCcuts", "", kTH1D, {{1, 0., 1.}}); - histos.add("hCounterTCEafterBCcuts", "", kTH1D, {{1, 0., 1.}}); - histos.add("hCounterZEMafterBCcuts", "", kTH1D, {{1, 0., 1.}}); - histos.add("hCounterZNCafterBCcuts", "", kTH1D, {{1, 0., 1.}}); histos.add("hCounterInvalidBCTimestamp", "", kTH1D, {{1, 0., 1.}}); - histos.add("hLumiTVX", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); - histos.add("hLumiTCE", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); - histos.add("hLumiZEM", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); - histos.add("hLumiZNC", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); - histos.add("hLumiTVXafterBCcuts", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); - histos.add("hLumiTCEafterBCcuts", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); - histos.add("hLumiZEMafterBCcuts", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); - histos.add("hLumiZNCafterBCcuts", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); } void processRun2( @@ -286,7 +263,7 @@ struct BcSelectionTask { // first bc of the first orbit bcSOR = runInfo.orbitSOR * nBCsPerOrbit; // duration of TF in bcs - nBCsPerTF = runInfo.orbitsPerTF * nBCsPerOrbit; + nBCsPerTF = confNumberOfOrbitsPerTF < 0 ? runInfo.orbitsPerTF * nBCsPerOrbit : confNumberOfOrbitsPerTF * nBCsPerOrbit; } // timestamp of the middle of the run used to access run-wise CCDB entries @@ -303,11 +280,7 @@ struct BcSelectionTask { rofLength = alppar->roFrameLengthInBC; // Trigger aliases aliases = ccdb->getForTimeStamp("EventSelection/TriggerAliases", ts); - // Collision system info - auto grplhcif = ccdb->getForTimeStamp("GLO/Config/GRPLHCIF", ts); - int beamZ1 = grplhcif->getBeamZ(o2::constants::lhc::BeamA); - int beamZ2 = grplhcif->getBeamZ(o2::constants::lhc::BeamC); - isPP = beamZ1 == 1 && beamZ2 == 1; + // prepare map of inactive chips auto itsDeadMap = ccdb->getForTimeStamp("ITS/Calib/TimeDeadMap", ts); auto itsDeadMapOrbits = itsDeadMap->getEvolvingMapKeys(); // roughly every second, ~350 TFs = 350x32 orbits @@ -335,12 +308,13 @@ struct BcSelectionTask { std::map metadata; metadata["run"] = Form("%d", run); ccdb->setFatalWhenNull(0); - mapRCT = ccdb->getSpecific>("Users/j/jian/RCT", ts, metadata); + mapRCT = ccdb->getSpecific>("RCT/Flags/RunFlags", ts, metadata); ccdb->setFatalWhenNull(1); if (mapRCT == nullptr) { LOGP(info, "rct object missing... inserting dummy rct flags"); mapRCT = new std::map; - mapRCT->insert(std::pair(sorTimestamp, 0)); + uint32_t dummyValue = 1 << 31; // setting bit 31 to indicate that rct object is missing + mapRCT->insert(std::pair(sorTimestamp, dummyValue)); } } @@ -490,58 +464,7 @@ struct BcSelectionTask { int32_t foundZDC = bc.has_zdc() ? bc.zdc().globalIndex() : -1; LOGP(debug, "foundFT0={}", foundFT0); - // Temporary workaround to get visible cross section. TODO: store run-by-run visible cross sections in CCDB const char* srun = Form("%d", run); - - bool injectionEnergy = (run >= 500000 && run <= 520099) || (run >= 534133 && run <= 534468); // o2-linter: disable=magic-number (TODO extract from ccdb) - // Cross sections in ub. Using dummy -1 if lumi estimator is not reliable - float csTVX = isPP ? (injectionEnergy ? 0.0355e6 : 0.0594e6) : -1.; - float csTCE = isPP ? -1. : 10.36e6; - float csZEM = isPP ? -1. : 415.2e6; // see AN: https://alice-notes.web.cern.ch/node/1515 - float csZNC = isPP ? -1. : 214.5e6; // see AN: https://alice-notes.web.cern.ch/node/1515 - if (run > 543437 && run < 543514) { // o2-linter: disable=magic-number (TODO store and extract cross sections from ccdb) - csTCE = 8.3e6; - } - if (run >= 543514) { // o2-linter: disable=magic-number (TODO store and extract cross sections from ccdb) - csTCE = 4.10e6; // see AN: https://alice-notes.web.cern.ch/node/1515 - } - - // Fill TVX (T0 vertex) counters - if (TESTBIT(selection, kIsTriggerTVX)) { - histos.get(HIST("hCounterTVX"))->Fill(srun, 1); - histos.get(HIST("hLumiTVX"))->Fill(srun, 1. / csTVX); - if (TESTBIT(selection, kNoITSROFrameBorder) && TESTBIT(selection, kNoTimeFrameBorder)) { - histos.get(HIST("hCounterTVXafterBCcuts"))->Fill(srun, 1); - histos.get(HIST("hLumiTVXafterBCcuts"))->Fill(srun, 1. / csTVX); - } - } - // Fill counters and lumi histograms for Pb-Pb lumi monitoring - // TODO: introduce pileup correction - if (bc.has_ft0() ? (TESTBIT(selection, kIsTriggerTVX) && TESTBIT(bc.ft0().triggerMask(), o2::ft0::Triggers::bitCen)) : 0) { - histos.get(HIST("hCounterTCE"))->Fill(srun, 1); - histos.get(HIST("hLumiTCE"))->Fill(srun, 1. / csTCE); - if (TESTBIT(selection, kNoITSROFrameBorder) && TESTBIT(selection, kNoTimeFrameBorder)) { - histos.get(HIST("hCounterTCEafterBCcuts"))->Fill(srun, 1); - histos.get(HIST("hLumiTCEafterBCcuts"))->Fill(srun, 1. / csTCE); - } - } - if (TESTBIT(selection, kIsBBZNA) || TESTBIT(selection, kIsBBZNC)) { - histos.get(HIST("hCounterZEM"))->Fill(srun, 1); - histos.get(HIST("hLumiZEM"))->Fill(srun, 1. / csZEM); - if (TESTBIT(selection, kNoITSROFrameBorder) && TESTBIT(selection, kNoTimeFrameBorder)) { - histos.get(HIST("hCounterZEMafterBCcuts"))->Fill(srun, 1); - histos.get(HIST("hLumiZEMafterBCcuts"))->Fill(srun, 1. / csZEM); - } - } - if (TESTBIT(selection, kIsBBZNC)) { - histos.get(HIST("hCounterZNC"))->Fill(srun, 1); - histos.get(HIST("hLumiZNC"))->Fill(srun, 1. / csZNC); - if (TESTBIT(selection, kNoITSROFrameBorder) && TESTBIT(selection, kNoTimeFrameBorder)) { - histos.get(HIST("hCounterZNCafterBCcuts"))->Fill(srun, 1); - histos.get(HIST("hLumiZNCafterBCcuts"))->Fill(srun, 1. / csZNC); - } - } - if (bc.timestamp() < sorTimestamp || bc.timestamp() > eorTimestamp) { histos.get(HIST("hCounterInvalidBCTimestamp"))->Fill(srun, 1); if (confCheckRunDurationLimits.value) { @@ -575,6 +498,7 @@ struct EventSelectionTask { Configurable confFT0CamplCutVetoOnCollInROF{"FT0CamplPerCollCutVetoOnCollInROF", 5000, "Max allowed FT0C amplitude for each nearby collision inside this ITS ROF"}; // o2-linter: disable=name/configurable (temporary fix) Configurable confEpsilonVzDiffVetoInROF{"EpsilonVzDiffVetoInROF", 0.3, "Minumum distance to nearby collisions along z inside this ITS ROF, cm"}; // o2-linter: disable=name/configurable (temporary fix) Configurable confUseWeightsForOccupancyVariable{"UseWeightsForOccupancyEstimator", 1, "Use or not the delta-time weights for the occupancy estimator"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable confNumberOfOrbitsPerTF{"NumberOfOrbitsPerTF", -1, "Number of orbits per Time Frame. Take from CCDB if -1"}; // o2-linter: disable=name/configurable (temporary fix) Partition tracklets = (aod::track::trackType == static_cast(o2::aod::track::TrackTypeEnum::Run2Tracklet)); @@ -647,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 = false; - } - } if (isMC == -1) { LOG(info) << "Autosetting the MC mode based on metadata"; if (metadataInfo.isMC()) { @@ -766,7 +682,7 @@ struct EventSelectionTask { // first bc of the first orbit bcSOR = runInfo.orbitSOR * nBCsPerOrbit; // duration of TF in bcs - nBCsPerTF = runInfo.orbitsPerTF * nBCsPerOrbit; + nBCsPerTF = confNumberOfOrbitsPerTF < 0 ? runInfo.orbitsPerTF * nBCsPerOrbit : confNumberOfOrbitsPerTF * nBCsPerOrbit; // colliding bc pattern int64_t ts = bcs.iteratorAt(0).timestamp(); auto grplhcif = ccdb->getForTimeStamp("GLO/Config/GRPLHCIF", ts); @@ -1229,6 +1145,315 @@ struct EventSelectionTask { PROCESS_SWITCH(EventSelectionTask, processRun3, "Process Run3 event selection", false); }; +struct LumiTask { + Service ccdb; + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + int lastRun = -1; // last run number (needed to access ccdb only if run!=lastRun) + float csTVX = -1; // dummy -1 for the visible TVX cross section (in ub) used in lumi accounting + float csTCE = -1; // dummy -1 for the visible TCE cross section (in ub) used in lumi accounting + float csZEM = -1; // dummy -1 for the visible ZEM cross section (in ub) used in lumi accounting + float csZNC = -1; // dummy -1 for the visible ZNC cross section (in ub) used in lumi accounting + + std::vector mOrbits; + std::vector mPileupCorrectionTVX; + std::vector mPileupCorrectionTCE; + std::vector mPileupCorrectionZEM; + std::vector mPileupCorrectionZNC; + + int64_t minOrbitInRange = std::numeric_limits::max(); + int64_t maxOrbitInRange = 0; + uint32_t currentOrbitIndex = 0; + std::bitset bcPatternB; // bc pattern of colliding bunches + std::vector mRCTFlagsCheckers; + + void init(InitContext&) + { + histos.add("hCounterTVX", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterTCE", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterZEM", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterZNC", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterTVXafterBCcuts", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterTCEafterBCcuts", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterZEMafterBCcuts", "", kTH1D, {{1, 0., 1.}}); + histos.add("hCounterZNCafterBCcuts", "", kTH1D, {{1, 0., 1.}}); + histos.add("hLumiTVX", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); + histos.add("hLumiTCE", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); + histos.add("hLumiZEM", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); + histos.add("hLumiZNC", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); + histos.add("hLumiTVXafterBCcuts", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); + histos.add("hLumiTCEafterBCcuts", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); + histos.add("hLumiZEMafterBCcuts", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); + histos.add("hLumiZNCafterBCcuts", ";;Luminosity, 1/#mub", kTH1D, {{1, 0., 1.}}); + + const int nLists = 6; + TString rctListNames[] = {"CBT", "CBT_hadronPID", "CBT_electronPID", "CBT_calo", "CBT_muon", "CBT_muon_glo"}; + histos.add("hLumiTVXafterBCcutsRCT", ";;Luminosity, 1/#mub", kTH2D, {{1, 0., 1.}, {4 * nLists, -0.5, 4. * nLists - 0.5}}); + histos.add("hLumiTCEafterBCcutsRCT", ";;Luminosity, 1/#mub", kTH2D, {{1, 0., 1.}, {4 * nLists, -0.5, 4. * nLists - 0.5}}); + histos.add("hLumiZEMafterBCcutsRCT", ";;Luminosity, 1/#mub", kTH2D, {{1, 0., 1.}, {4 * nLists, -0.5, 4. * nLists - 0.5}}); + histos.add("hLumiZNCafterBCcutsRCT", ";;Luminosity, 1/#mub", kTH2D, {{1, 0., 1.}, {4 * nLists, -0.5, 4. * nLists - 0.5}}); + + for (int i = 0; i < nLists; i++) { + const auto& rctListName = rctListNames[i]; + mRCTFlagsCheckers.emplace_back(rctListName.Data(), false, false); // disable zdc check, disable lim. acc. check + mRCTFlagsCheckers.emplace_back(rctListName.Data(), false, true); // disable zdc check, enable lim. acc. check + mRCTFlagsCheckers.emplace_back(rctListName.Data(), true, false); // enable zdc check, disable lim. acc. check + mRCTFlagsCheckers.emplace_back(rctListName.Data(), true, true); // enable zdc check, enable lim. acc. check + histos.get(HIST("hLumiTVXafterBCcutsRCT"))->GetYaxis()->SetBinLabel(4 * i + 1, rctListName.Data()); + histos.get(HIST("hLumiTCEafterBCcutsRCT"))->GetYaxis()->SetBinLabel(4 * i + 1, rctListName.Data()); + histos.get(HIST("hLumiZEMafterBCcutsRCT"))->GetYaxis()->SetBinLabel(4 * i + 1, rctListName.Data()); + histos.get(HIST("hLumiZNCafterBCcutsRCT"))->GetYaxis()->SetBinLabel(4 * i + 1, rctListName.Data()); + histos.get(HIST("hLumiTVXafterBCcutsRCT"))->GetYaxis()->SetBinLabel(4 * i + 2, (rctListName + "_fullacc").Data()); + histos.get(HIST("hLumiTCEafterBCcutsRCT"))->GetYaxis()->SetBinLabel(4 * i + 2, (rctListName + "_fullacc").Data()); + histos.get(HIST("hLumiZEMafterBCcutsRCT"))->GetYaxis()->SetBinLabel(4 * i + 2, (rctListName + "_fullacc").Data()); + histos.get(HIST("hLumiZNCafterBCcutsRCT"))->GetYaxis()->SetBinLabel(4 * i + 2, (rctListName + "_fullacc").Data()); + histos.get(HIST("hLumiTVXafterBCcutsRCT"))->GetYaxis()->SetBinLabel(4 * i + 3, (rctListName + "_zdc").Data()); + histos.get(HIST("hLumiTCEafterBCcutsRCT"))->GetYaxis()->SetBinLabel(4 * i + 3, (rctListName + "_zdc").Data()); + histos.get(HIST("hLumiZEMafterBCcutsRCT"))->GetYaxis()->SetBinLabel(4 * i + 3, (rctListName + "_zdc").Data()); + histos.get(HIST("hLumiZNCafterBCcutsRCT"))->GetYaxis()->SetBinLabel(4 * i + 3, (rctListName + "_zdc").Data()); + histos.get(HIST("hLumiTVXafterBCcutsRCT"))->GetYaxis()->SetBinLabel(4 * i + 4, (rctListName + "_zdc" + "_fullacc").Data()); + histos.get(HIST("hLumiTCEafterBCcutsRCT"))->GetYaxis()->SetBinLabel(4 * i + 4, (rctListName + "_zdc" + "_fullacc").Data()); + histos.get(HIST("hLumiZEMafterBCcutsRCT"))->GetYaxis()->SetBinLabel(4 * i + 4, (rctListName + "_zdc" + "_fullacc").Data()); + histos.get(HIST("hLumiZNCafterBCcutsRCT"))->GetYaxis()->SetBinLabel(4 * i + 4, (rctListName + "_zdc" + "_fullacc").Data()); + } + } + + void processRun2(aod::BCs const&) + { + LOGP(debug, "Dummy process function for Run 2"); + } + + PROCESS_SWITCH(LumiTask, processRun2, "Process Run2 lumi task", false); + + void processRun3(BCsWithBcSelsRun3 const& bcs, aod::FT0s const&) + { + if (bcs.size() == 0) + return; + int run = bcs.iteratorAt(0).runNumber(); + if (run < 500000) // o2-linter: disable=magic-number (skip for unanchored MCs) + return; + if (run != lastRun && run >= 520259) { // o2-linter: disable=magic-number (scalers available for runs above 520120) + lastRun = run; + int64_t ts = bcs.iteratorAt(0).timestamp(); + + // getting GRP LHCIF object to extract colliding system, energy and colliding bc pattern + auto grplhcif = ccdb->getForTimeStamp("GLO/Config/GRPLHCIF", ts); + int beamZ1 = grplhcif->getBeamZ(constants::lhc::BeamA); + int beamZ2 = grplhcif->getBeamZ(constants::lhc::BeamC); + float sqrts = grplhcif->getSqrtS(); + int nCollidingBCs = grplhcif->getBunchFilling().getNBunches(); + bcPatternB = grplhcif->getBunchFilling().getBCPattern(); + + // visible cross sections in ub. Using dummy -1 if lumi estimator is not reliable for this colliding system + csTVX = -1; + csTCE = -1; + csZEM = -1; + 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.) < 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); + } + } else if (beamZ1 == 82 && beamZ2 == 82) { // o2-linter: disable=magic-number (PbPb colliding system) + // see AN: https://alice-notes.web.cern.ch/node/1515 + if (std::fabs(sqrts - 5360) < 20) { // o2-linter: disable=magic-number (TODO store and extract cross sections from ccdb) + csZNC = 214.5e6; // ub + csZEM = 415.2e6; // ub + csTCE = 10.36e6; // ub + if (run > 543437 && run < 543514) { // o2-linter: disable=magic-number (TODO store and extract cross sections from ccdb) + csTCE = 8.3e6; // ub + } else if (run >= 543514 && run < 545367) { // o2-linter: disable=magic-number (TODO store and extract cross sections from ccdb) + csTCE = 4.10e6; // ub + } else if (run >= 559544) { // o2-linter: disable=magic-number (TODO store and extract cross sections from ccdb) + csTCE = 3.86e6; // ub + } + } else { + LOGP(warn, "Cross section for PbPb @ {} GeV is not defined", sqrts); + } + } else { + LOGP(warn, "Cross section for z={} + z={} @ {} GeV is not defined", beamZ1, beamZ2, sqrts); + } + // getting CTP config to extract lumi class indices (used for rate fetching and pileup correction) + std::map metadata; + metadata["runNumber"] = std::to_string(run); + auto config = ccdb->getSpecific("CTP/Config/Config", ts, metadata); + auto classes = config->getCTPClasses(); + TString lumiClassNameZNC = "C1ZNC-B-NOPF-CRU"; + TString lumiClassNameTCE = "CMTVXTCE-B-NOPF-CRU"; + TString lumiClassNameTVX1 = "MINBIAS_TVX"; // run >= 534467 + TString lumiClassNameTVX2 = "MINBIAS_TVX_NOMASK"; // run >= 534468 + TString lumiClassNameTVX3 = "CMTVX-NONE-NOPF-CRU"; // run >= 534996 + TString lumiClassNameTVX4 = "CMTVX-B-NOPF-CRU"; // run >= 543437 + + // find class indices + int classIdZNC = -1; + int classIdTCE = -1; + int classIdTVX = -1; + for (unsigned int i = 0; i < classes.size(); i++) { + TString clname = classes[i].name; + clname.ToUpper(); + // using position (i) in the vector of classes instead of classes[i].getIndex() + // due to bug or inconsistencies in scaler record and class indices + if (clname == lumiClassNameZNC) + classIdZNC = i; + if (clname == lumiClassNameTCE) + classIdTCE = i; + if (clname == lumiClassNameTVX4 || clname == lumiClassNameTVX3 || clname == lumiClassNameTVX2 || clname == lumiClassNameTVX1) + classIdTVX = i; + } + + // extract trigger counts from CTP scalers + auto scalers = ccdb->getSpecific("CTP/Calib/Scalers", ts, metadata); + scalers->convertRawToO2(); + std::vector mCounterTVX; + std::vector mCounterTCE; + std::vector mCounterZNC; + std::vector mCounterZEM; + mOrbits.clear(); + for (const auto& record : scalers->getScalerRecordO2()) { + 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 && 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 + 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 + mPileupCorrectionTVX.clear(); + mPileupCorrectionTCE.clear(); + mPileupCorrectionZEM.clear(); + mPileupCorrectionZNC.clear(); + for (uint32_t i = 0; i < mOrbits.size() - 1; i++) { + int64_t nOrbits = mOrbits[i + 1] - mOrbits[i]; + if (nOrbits <= 0 || nCollidingBCs == 0) + continue; + double perBcRateTVX = static_cast(mCounterTVX[i + 1] - mCounterTVX[i]) / nOrbits / nCollidingBCs; + double perBcRateTCE = static_cast(mCounterTCE[i + 1] - mCounterTCE[i]) / nOrbits / nCollidingBCs; + double perBcRateZNC = static_cast(mCounterZNC[i + 1] - mCounterZNC[i]) / nOrbits / nCollidingBCs; + double perBcRateZEM = static_cast(mCounterZEM[i + 1] - mCounterZEM[i]) / nOrbits / nCollidingBCs; + double muTVX = (perBcRateTVX < 1 && perBcRateTVX > 1e-10) ? -std::log(1 - perBcRateTVX) : 0; + double muTCE = (perBcRateTCE < 1 && perBcRateTCE > 1e-10) ? -std::log(1 - perBcRateTCE) : 0; + double muZNC = (perBcRateZNC < 1 && perBcRateZNC > 1e-10) ? -std::log(1 - perBcRateZNC) : 0; + double muZEM = (perBcRateZEM < 1 && perBcRateZEM > 1e-10) ? -std::log(1 - perBcRateZEM) : 0; + LOGP(debug, "orbit={} muTVX={} muTCE={} muZNC={} muZEM={}", mOrbits[i], muTVX, muTCE, muZNC, muZEM); + mPileupCorrectionTVX.push_back(muTVX > 1e-10 ? muTVX / (1 - std::exp(-muTVX)) : 1); + mPileupCorrectionTCE.push_back(muTCE > 1e-10 ? muTCE / (1 - std::exp(-muTCE)) : 1); + mPileupCorrectionZNC.push_back(muZNC > 1e-10 ? muZNC / (1 - std::exp(-muZNC)) : 1); + mPileupCorrectionZEM.push_back(muZEM > 1e-10 ? muZEM / (1 - std::exp(-muZEM)) : 1); + } + // filling last orbit range using previous orbit range + mPileupCorrectionTVX.push_back(mPileupCorrectionTVX.back()); + mPileupCorrectionTCE.push_back(mPileupCorrectionTCE.back()); + mPileupCorrectionZNC.push_back(mPileupCorrectionZNC.back()); + mPileupCorrectionZEM.push_back(mPileupCorrectionZEM.back()); + } // access ccdb once per run + + const char* srun = Form("%d", run); + + for (const auto& bc : bcs) { + auto& selection = bc.selection_raw(); + if (bcPatternB[bc.globalBC() % nBCsPerOrbit] == 0) // skip non-colliding bcs + continue; + + bool noBorder = TESTBIT(selection, kNoTimeFrameBorder) && TESTBIT(selection, kNoITSROFrameBorder); + bool isTriggerTVX = TESTBIT(selection, kIsTriggerTVX); + bool isTriggerTCE = bc.has_ft0() ? (TESTBIT(selection, kIsTriggerTVX) && TESTBIT(bc.ft0().triggerMask(), o2::ft0::Triggers::bitCen)) : 0; + bool isTriggerZNA = TESTBIT(selection, kIsBBZNA); + bool isTriggerZNC = TESTBIT(selection, kIsBBZNC); + bool isTriggerZEM = isTriggerZNA || isTriggerZNC; + + // determine pileup correction + int64_t orbit = bc.globalBC() / nBCsPerOrbit; + if ((orbit < minOrbitInRange || orbit > maxOrbitInRange) && mOrbits.size() > 1) { + auto it = std::lower_bound(mOrbits.begin(), mOrbits.end(), orbit); + uint32_t nextOrbitIndex = std::distance(mOrbits.begin(), it); + if (nextOrbitIndex == 0) // if orbit is below stored scaler orbits + nextOrbitIndex = 1; + else if (nextOrbitIndex == mOrbits.size()) // if orbit is above stored scaler orbits + nextOrbitIndex = mOrbits.size() - 1; + currentOrbitIndex = nextOrbitIndex - 1; + minOrbitInRange = mOrbits[currentOrbitIndex]; + maxOrbitInRange = mOrbits[nextOrbitIndex]; + } + double pileupCorrectionTVX = currentOrbitIndex < mPileupCorrectionTVX.size() ? mPileupCorrectionTVX[currentOrbitIndex] : 1.; + double pileupCorrectionTCE = currentOrbitIndex < mPileupCorrectionTCE.size() ? mPileupCorrectionTCE[currentOrbitIndex] : 1.; + double pileupCorrectionZNC = currentOrbitIndex < mPileupCorrectionZNC.size() ? mPileupCorrectionZNC[currentOrbitIndex] : 1.; + double pileupCorrectionZEM = currentOrbitIndex < mPileupCorrectionZEM.size() ? mPileupCorrectionZEM[currentOrbitIndex] : 1.; + + double lumiTVX = 1. / csTVX * pileupCorrectionTVX; + double lumiTCE = 1. / csTCE * pileupCorrectionTCE; + double lumiZNC = 1. / csZNC * pileupCorrectionZNC; + double lumiZEM = 1. / csZEM * pileupCorrectionZEM; + + if (isTriggerTVX) { + histos.get(HIST("hCounterTVX"))->Fill(srun, 1); + histos.get(HIST("hLumiTVX"))->Fill(srun, lumiTVX); + if (noBorder) { + histos.get(HIST("hCounterTVXafterBCcuts"))->Fill(srun, 1); + histos.get(HIST("hLumiTVXafterBCcuts"))->Fill(srun, lumiTVX); + for (size_t i = 0; i < mRCTFlagsCheckers.size(); i++) { + if (mRCTFlagsCheckers[i](bc)) + histos.get(HIST("hLumiTVXafterBCcutsRCT"))->Fill(srun, i, lumiTVX); + } + } + } + + if (isTriggerTCE) { + histos.get(HIST("hCounterTCE"))->Fill(srun, 1); + histos.get(HIST("hLumiTCE"))->Fill(srun, lumiTCE); + if (noBorder) { + histos.get(HIST("hCounterTCEafterBCcuts"))->Fill(srun, 1); + histos.get(HIST("hLumiTCEafterBCcuts"))->Fill(srun, lumiTCE); + for (size_t i = 0; i < mRCTFlagsCheckers.size(); i++) { + if (mRCTFlagsCheckers[i](bc)) + histos.get(HIST("hLumiTCEafterBCcutsRCT"))->Fill(srun, i, lumiTCE); + } + } + } + + if (isTriggerZEM) { + histos.get(HIST("hCounterZEM"))->Fill(srun, 1); + histos.get(HIST("hLumiZEM"))->Fill(srun, lumiZEM); + if (noBorder) { + histos.get(HIST("hCounterZEMafterBCcuts"))->Fill(srun, 1); + histos.get(HIST("hLumiZEMafterBCcuts"))->Fill(srun, lumiZEM); + for (size_t i = 0; i < mRCTFlagsCheckers.size(); i++) { + if (mRCTFlagsCheckers[i](bc)) + histos.get(HIST("hLumiZEMafterBCcutsRCT"))->Fill(srun, i, lumiZEM); + } + } + } + + if (isTriggerZNC) { + histos.get(HIST("hCounterZNC"))->Fill(srun, 1); + histos.get(HIST("hLumiZNC"))->Fill(srun, lumiZNC); + if (noBorder) { + histos.get(HIST("hCounterZNCafterBCcuts"))->Fill(srun, 1); + histos.get(HIST("hLumiZNCafterBCcuts"))->Fill(srun, lumiZNC); + for (size_t i = 0; i < mRCTFlagsCheckers.size(); i++) { + if (mRCTFlagsCheckers[i](bc)) + histos.get(HIST("hLumiZNCafterBCcutsRCT"))->Fill(srun, i, lumiZNC); + } + } + } + + } // bcs + } // process + PROCESS_SWITCH(LumiTask, processRun3, "Process Run3 lumi task", false); +}; + WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { // Parse the metadata @@ -1236,5 +1461,6 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) return WorkflowSpec{ adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; } diff --git a/Common/TableProducer/multCentTable.cxx b/Common/TableProducer/multCentTable.cxx new file mode 100644 index 00000000000..c0052088e6c --- /dev/null +++ b/Common/TableProducer/multCentTable.cxx @@ -0,0 +1,204 @@ +// 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 multCentTable.cxx +/// \brief unified, self-configuring mult/cent provider +/// \author ALICE + +//=============================================================== +// +// Unified, self-configuring multiplicity+centrality task +// still work in progress: use at your own discretion +// +//=============================================================== + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/Core/trackUtilities.h" +#include "ReconstructionDataFormats/DCA.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsBase/GeometryManager.h" +#include "CommonUtils/NameConf.h" +#include "CCDB/CcdbApi.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "CCDB/BasicCCDBManager.h" +#include "Framework/HistogramRegistry.h" +#include "DataFormatsCalibration/MeanVertexObject.h" +#include "CommonConstants/GeomConstants.h" +#include "Common/Tools/TrackPropagationModule.h" +#include "Common/Tools/StandardCCDBLoader.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "MetadataHelper.h" +#include "Common/Tools/MultModule.h" + +using namespace o2; +using namespace o2::framework; +// using namespace o2::framework::expressions; + +MetadataHelper metadataInfo; // Metadata helper + +struct MultCentTable { + o2::common::multiplicity::standardConfigurables opts; + o2::common::multiplicity::products products; + o2::common::multiplicity::MultModule module; + + // CCDB boilerplate declarations + o2::framework::Configurable ccdburl{"ccdburl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Service ccdb; + Service pdg; + + // hold multiplicity values for layover to centrality calculation + std::vector mults; + + // slicers + Preslice> slicerTracksIU = o2::aod::track::collisionId; + Preslice> slicerTracksIUwithSelections = o2::aod::track::collisionId; + Preslice> slicerTrackRun2 = o2::aod::track::collisionId; + + void init(o2::framework::InitContext& initContext) + { + // CCDB boilerplate init + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setURL(ccdburl.value); + + // task-specific + module.init(opts, initContext); + } + + void processRun2(soa::Join const& collisions, + soa::Join const& tracks, + soa::Join const& bcs, + aod::Zdcs const&, + aod::FV0As const&, + aod::FV0Cs const&, + aod::FT0s const&) + { + mults.clear(); + for (auto const& collision : collisions) { + o2::common::multiplicity::multEntry mult; + const auto& bc = bcs.rawIteratorAt(collision.getId()); + const uint64_t collIdx = collision.globalIndex(); + auto tracksThisCollision = tracks.sliceBy(slicerTrackRun2, collIdx); + mult = module.collisionProcessRun2(collision, tracksThisCollision, bc, products); + mults.push_back(mult); + } + } + + void processRun3(soa::Join const& collisions, + soa::Join const& tracks, + soa::Join const& bcs, + aod::Zdcs const& zdcs, + aod::FV0As const& fv0as, + aod::FT0s const& ft0s, + aod::FDDs const& fdds) + { + mults.clear(); + for (auto const& collision : collisions) { + o2::common::multiplicity::multEntry mult; + const auto& bc = collision.bc_as>(); + const uint64_t collIdx = collision.globalIndex(); + auto tracksThisCollision = tracks.sliceBy(slicerTracksIU, collIdx); + mult = module.collisionProcessRun3(ccdb, metadataInfo, collision, tracksThisCollision, bc, products); + mults.push_back(mult); + } + } + + void processRun3WithGlobalCounters(soa::Join const& collisions, + soa::Join const& tracks, + soa::Join const& bcs, + aod::Zdcs const& zdcs, + aod::FV0As const& fv0as, + aod::FT0s const& ft0s, + aod::FDDs const& fdds) + { + mults.clear(); + for (auto const& collision : collisions) { + o2::common::multiplicity::multEntry mult; + const auto& bc = collision.bc_as>(); + const uint64_t collIdx = collision.globalIndex(); + auto tracksThisCollision = tracks.sliceBy(slicerTracksIUwithSelections, collIdx); + mult = module.collisionProcessRun3(ccdb, metadataInfo, collision, tracksThisCollision, bc, products); + mults.push_back(mult); + } + } + void processMFT(soa::Join::iterator const& collision, + o2::aod::MFTTracks const& mfttracks, + soa::SmallGroups const& retracks) + { + if (opts.mEnabledTables[o2::common::multiplicity::kMFTMults]) { + // populates MFT information in the mults buffer (in addition to filling table) + module.collisionProcessMFT(collision, mfttracks, retracks, mults, products); + } + } + void processMonteCarlo(aod::McCollision const& mcCollision, aod::McParticles const& mcParticles) + { + if (opts.mEnabledTables[o2::common::multiplicity::kMultMCExtras]) { + module.collisionProcessMonteCarlo(mcCollision, mcParticles, pdg, products); + } + } + void processMonteCarlo2Mults(soa::Join::iterator const& collision) + { + if (opts.mEnabledTables[o2::common::multiplicity::kMult2MCExtras]) { + // establish simple interlink for posterior analysis (derived data) + products.tableExtraMult2MCExtras(collision.mcCollisionId()); + } + } + void processCentralityRun2(aod::Collisions const& collisions, soa::Join const& bcs) + { + // it is important that this function is at the end of the other process functions. + // it requires `mults` to be properly set, which will only happen after the other process + // functions have been called. + + // internally, the function below will do nothing if no centrality is requested. + // it is thus safer to always keep the actual process function for centrality + // generation to true, since the requisites for being in this context are + // always fulfilled + if (collisions.size() != mults.size()) { + LOGF(fatal, "Size of collisions doesn't match size of multiplicity buffer!"); + } + module.generateCentralitiesRun2(ccdb, metadataInfo, bcs, mults, products); + } + void processCentralityRun3(aod::Collisions const& collisions, soa::Join const& bcs, aod::FT0s const&) + { + // it is important that this function is at the end of the other process functions. + // it requires `mults` to be properly set, which will only happen after the other process + // functions have been called. + + // internally, the function below will do nothing if no centrality is requested. + // it is thus safer to always keep the actual process function for centrality + // generation to true, since the requisites for being in this context are + // always fulfilled + if (collisions.size() != mults.size()) { + LOGF(fatal, "Size of collisions doesn't match size of multiplicity buffer!"); + } + module.generateCentralitiesRun3(ccdb, metadataInfo, bcs, mults, products); + } + + PROCESS_SWITCH(MultCentTable, processRun2, "Process Run 2", false); + PROCESS_SWITCH(MultCentTable, processRun3, "Process Run 3", true); + PROCESS_SWITCH(MultCentTable, processRun3WithGlobalCounters, "Process Run 3 + global tracking counters", false); + PROCESS_SWITCH(MultCentTable, processMFT, "Process MFT info", false); + PROCESS_SWITCH(MultCentTable, processMonteCarlo, "Process Monte Carlo information", false); + PROCESS_SWITCH(MultCentTable, processMonteCarlo2Mults, "Process Monte Carlo information", false); + PROCESS_SWITCH(MultCentTable, processCentralityRun2, "Generate Run 2 centralities", false); + PROCESS_SWITCH(MultCentTable, processCentralityRun3, "Generate Run 3 centralities", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + metadataInfo.initMetadata(cfgc); + WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + return workflow; +} diff --git a/Common/TableProducer/occupancyTableProducer.cxx b/Common/TableProducer/occupancyTableProducer.cxx index ce56bfda149..2e4a01ddbb1 100644 --- a/Common/TableProducer/occupancyTableProducer.cxx +++ b/Common/TableProducer/occupancyTableProducer.cxx @@ -19,6 +19,7 @@ #include #include #include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -48,80 +49,100 @@ int32_t nBCsPerOrbit = o2::constants::lhc::LHCMaxBunches; // const int nBCinTFgrp80 = 1425; // nOrbitsPerTF = run < 534133 ? 128 : 32; // for 128 => nBCsPerTF = 456192 , for 32 => nBCsPerTF = 114048 -const int nBCinTF = 114048; /// CCDB value // to be obtained from CCDB in future +// const int nBCinTF = 114048; /// CCDB value // to be obtained from CCDB in future const int nBCinDrift = 114048 / 32; /// to get from ccdb in future -const int arraySize = 10; // Max no timeframes that can be present in a dataframe struct OccupancyTableProducer { Service ccdb; // declare production of tables - Produces genOccIndexTable; Produces genBCTFinfoTable; + // 0 + Produces genOccIndexTable; Produces genOccsBCsList; - - Produces genOccsDet; - Produces genOccsTrackMult; + // 1 + Produces genOccsPrim; + Produces genOccsMeanPrim; + // 2 + Produces genOccsT0V0; + Produces genOccsMeanT0V0; + ; + Produces genORT0V0Prim; + Produces genOccsMeanRobustT0V0Prim; + // 3 + Produces genOccsFDD; + Produces genOccsMeanFDD; + Produces genORFDDT0V0Prim; + Produces genOccsMeanRobustFDDT0V0Prim; + // 4 + Produces genOccsNTrackDet; + Produces genOccsMeanNTrkDet; + Produces genORNtrackDet; + Produces genOccsMeanRobustNtrackDet; + // 5 Produces genOccsMultExtra; - Produces genOccsRobust; - - Produces genOccsMeanDet; - Produces genOccsMeanTrkMult; Produces genOccsMnMultExtra; - Produces genOccsMeanRobust; + Produces genORMultExtra; + Produces genOccsMeanRobustMultExtraTable; Configurable customOrbitOffset{"customOrbitOffset", 0, "customOrbitOffset for MC"}; - Configurable grouping{"grouping", 80, "grouping of BCs"}; + Configurable bcGrouping{"bcGrouping", 80, "bcGrouping of BCs"}; + Configurable nBCinTF{"nBCinTF", 114048, "nBCinTF"}; + Configurable occVecArraySize{"occVecArraySize", 10, "occVecArraySize"}; - Configurable buildOccIndexTable{"buildOccIndexTable", true, "builder of table OccIndexTable"}; - Configurable buildBCTFinfoTable{"buildBCTFinfoTable", true, "builder of table BCTFinfoTable"}; - Configurable buildOccsBCsList{"buildOccsBCsList", true, "builder of table OccsBCsList"}; + Configurable cfgNOrbitsPerTF0RunValue{"cfgNOrbitsPerTF0RunValue", 534133, "cfgNOrbitsPerTF0RunValue"}; + Configurable cfgNOrbitsPerTF1TrueValue{"cfgNOrbitsPerTF1TrueValue", 128, "cfgNOrbitsPerTF1TrueValue"}; + Configurable cfgNOrbitsPerTF2FalseValue{"cfgNOrbitsPerTF2FalseValue", 32, "ccfgNOrbitsPerTF2FalseValue"}; - Configurable buildOccsDet{"buildOccsDet", true, "builder of table OccsDet"}; - Configurable buildOccsTrackMult{"buildOccsTrackMult", true, "builder of table OccsTrackMult"}; - Configurable buildOccsMultExtra{"buildOccsMultExtra", true, "builder of table OccsMultExtra"}; - Configurable buildOccsRobust{"buildOccsRobust", true, "builder of table OccsRobust"}; - - Configurable buildOccsMeanDet{"buildOccsMeanDet", true, "builder of table OccsMeanDet"}; - Configurable buildOccsMeanTrkMult{"buildOccsMeanTrkMult", true, "builder of table OccsMeanTrkMult"}; - Configurable buildOccsMnMultExtra{"buildOccsMnMultExtra", true, "builder of table OccsMnMultExtra"}; - Configurable buildOccsMeanRobust{"buildOccsMeanRobust", true, "builder of table OccsMeanRobust"}; + // declare production of tables + Configurable buildOnlyOccsPrim{"buildOnlyOccsPrim", true, "builder of table OccsPrim"}; + Configurable buildOnlyOccsT0V0Prim{"buildOnlyOccsT0V0Prim", true, "builder of table OccsT0V0Prim"}; + Configurable buildOnlyOccsFDDT0V0Prim{"buildOnlyOccsFDDT0V0Prim", true, "builder of table OccsFDDT0V0Prim"}; + Configurable buildOnlyOccsNtrackDet{"buildOnlyOccsNtrackDet", true, "builder of table OccsNtrackDet"}; + Configurable buildOnlyOccsMultExtra{"buildOnlyOccsMultExtra", true, "builder of table OccsMultExtra"}; + Configurable buildFullOccTableProducer{"buildFullOccTableProducer", true, "builder of all Occupancy Tables"}; + + Configurable buildFlag00OccTable{"buildFlag00OccTable", true, "switch of table Occ Table"}; + Configurable buildFlag01OccMeanTable{"buildFlag01OccMeanTable", true, "switch of table Occ MeanTable"}; + Configurable buildFlag02OccRobustTable{"buildFlag02OccRobustTable", true, "switch of table Occ RobustTable"}; + Configurable buildFlag03OccMeanRobustTable{"buildFlag03OccMeanRobustTable", true, "switch of table Occ MeanRobustTable"}; // Histogram registry; HistogramRegistry recoEvent{"recoEvent", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; HistogramRegistry occupancyQA{"occupancyQA", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - // Data Structures for Occupancy estimation - std::array tfList; - std::array, arraySize> bcTFMap; - std::array, arraySize> occPrimUnfm80; - std::array, arraySize> occFV0AUnfm80; - std::array, arraySize> occFV0CUnfm80; - std::array, arraySize> occFT0AUnfm80; - std::array, arraySize> occFT0CUnfm80; - std::array, arraySize> occFDDAUnfm80; - std::array, arraySize> occFDDCUnfm80; - - std::array, arraySize> occNTrackITSUnfm80; - std::array, arraySize> occNTrackTPCUnfm80; - std::array, arraySize> occNTrackTRDUnfm80; - std::array, arraySize> occNTrackTOFUnfm80; - std::array, arraySize> occNTrackSizeUnfm80; - std::array, arraySize> occNTrackTPCAUnfm80; - std::array, arraySize> occNTrackTPCCUnfm80; - std::array, arraySize> occNTrackITSTPCUnfm80; - std::array, arraySize> occNTrackITSTPCAUnfm80; - std::array, arraySize> occNTrackITSTPCCUnfm80; - - std::array, arraySize> occMultNTracksHasITSUnfm80; - std::array, arraySize> occMultNTracksHasTPCUnfm80; - std::array, arraySize> occMultNTracksHasTOFUnfm80; - std::array, arraySize> occMultNTracksHasTRDUnfm80; - std::array, arraySize> occMultNTracksITSOnlyUnfm80; - std::array, arraySize> occMultNTracksTPCOnlyUnfm80; - std::array, arraySize> occMultNTracksITSTPCUnfm80; - std::array, arraySize> occMultAllTracksTPCOnlyUnfm80; + std::vector tfList; + std::vector> bcTFMap; + + std::vector> occPrimUnfm80; + std::vector> occFV0AUnfm80; + std::vector> occFV0CUnfm80; + std::vector> occFT0AUnfm80; + std::vector> occFT0CUnfm80; + + std::vector> occFDDAUnfm80; + std::vector> occFDDCUnfm80; + + std::vector> occNTrackITSUnfm80; + std::vector> occNTrackTPCUnfm80; + std::vector> occNTrackTRDUnfm80; + std::vector> occNTrackTOFUnfm80; + std::vector> occNTrackSizeUnfm80; + std::vector> occNTrackTPCAUnfm80; + std::vector> occNTrackTPCCUnfm80; + std::vector> occNTrackITSTPCUnfm80; + std::vector> occNTrackITSTPCAUnfm80; + std::vector> occNTrackITSTPCCUnfm80; + + std::vector> occMultNTracksHasITSUnfm80; + std::vector> occMultNTracksHasTPCUnfm80; + std::vector> occMultNTracksHasTOFUnfm80; + std::vector> occMultNTracksHasTRDUnfm80; + std::vector> occMultNTracksITSOnlyUnfm80; + std::vector> occMultNTracksTPCOnlyUnfm80; + std::vector> occMultNTracksITSTPCUnfm80; + std::vector> occMultAllTracksTPCOnlyUnfm80; std::vector vecRobustOccT0V0PrimUnfm80; std::vector vecRobustOccFDDT0V0PrimUnfm80; @@ -132,49 +153,114 @@ struct OccupancyTableProducer { std::vector> vecRobustOccNtrackDetUnfm80medianPosVec; std::vector> vecRobustOccmultTableUnfm80medianPosVec; + std::vector processStatus; + Configurable processStatusSize{"processStatusSize", 10, "processStatusSize"}; void init(InitContext const&) { - // Set size of the vectors - for (int i = 0; i < arraySize; i++) { - bcTFMap[i].resize(nBCinTF / 80); - occPrimUnfm80[i].resize(nBCinTF / 80); - occFV0AUnfm80[i].resize(nBCinTF / 80); - occFV0CUnfm80[i].resize(nBCinTF / 80); - occFT0AUnfm80[i].resize(nBCinTF / 80); - occFT0CUnfm80[i].resize(nBCinTF / 80); - occFDDAUnfm80[i].resize(nBCinTF / 80); - occFDDCUnfm80[i].resize(nBCinTF / 80); - - occNTrackITSUnfm80[i].resize(nBCinTF / 80); - occNTrackTPCUnfm80[i].resize(nBCinTF / 80); - occNTrackTRDUnfm80[i].resize(nBCinTF / 80); - occNTrackTOFUnfm80[i].resize(nBCinTF / 80); - occNTrackSizeUnfm80[i].resize(nBCinTF / 80); - occNTrackTPCAUnfm80[i].resize(nBCinTF / 80); - occNTrackTPCCUnfm80[i].resize(nBCinTF / 80); - occNTrackITSTPCUnfm80[i].resize(nBCinTF / 80); - occNTrackITSTPCAUnfm80[i].resize(nBCinTF / 80); - occNTrackITSTPCCUnfm80[i].resize(nBCinTF / 80); - - occMultNTracksHasITSUnfm80[i].resize(nBCinTF / 80); - occMultNTracksHasTPCUnfm80[i].resize(nBCinTF / 80); - occMultNTracksHasTOFUnfm80[i].resize(nBCinTF / 80); - occMultNTracksHasTRDUnfm80[i].resize(nBCinTF / 80); - occMultNTracksITSOnlyUnfm80[i].resize(nBCinTF / 80); - occMultNTracksTPCOnlyUnfm80[i].resize(nBCinTF / 80); - occMultNTracksITSTPCUnfm80[i].resize(nBCinTF / 80); - occMultAllTracksTPCOnlyUnfm80[i].resize(nBCinTF / 80); - } - - vecRobustOccT0V0PrimUnfm80.resize(nBCinTF / 80); - vecRobustOccFDDT0V0PrimUnfm80.resize(nBCinTF / 80); - vecRobustOccNtrackDetUnfm80.resize(nBCinTF / 80); - vecRobustOccmultTableUnfm80.resize(nBCinTF / 80); - - vecRobustOccT0V0PrimUnfm80medianPosVec.resize(nBCinTF / 80); // Median => one for odd and two for even entries - vecRobustOccFDDT0V0PrimUnfm80medianPosVec.resize(nBCinTF / 80); - vecRobustOccNtrackDetUnfm80medianPosVec.resize(nBCinTF / 80); - vecRobustOccmultTableUnfm80medianPosVec.resize(nBCinTF / 80); + processStatus.resize(processStatusSize); + for (uint i = 0; i < processStatusSize; i++) { + processStatus[i] = false; + } + + // outer vector resized at runtime + tfList.resize(occVecArraySize); + bcTFMap.resize(occVecArraySize); + + if (buildFullOccTableProducer || buildOnlyOccsPrim || buildOnlyOccsT0V0Prim || buildOnlyOccsFDDT0V0Prim || buildOnlyOccsNtrackDet || buildOnlyOccsMultExtra) { + occPrimUnfm80.resize(occVecArraySize); + } + if (buildFullOccTableProducer || buildOnlyOccsT0V0Prim || buildOnlyOccsFDDT0V0Prim) { + occFV0AUnfm80.resize(occVecArraySize); + occFV0CUnfm80.resize(occVecArraySize); + occFT0AUnfm80.resize(occVecArraySize); + occFT0CUnfm80.resize(occVecArraySize); + } + if (buildFullOccTableProducer || buildOnlyOccsFDDT0V0Prim) { + occFDDAUnfm80.resize(occVecArraySize); + occFDDCUnfm80.resize(occVecArraySize); + } + if (buildFullOccTableProducer || buildOnlyOccsNtrackDet) { + occNTrackITSUnfm80.resize(occVecArraySize); + occNTrackTPCUnfm80.resize(occVecArraySize); + occNTrackTRDUnfm80.resize(occVecArraySize); + occNTrackTOFUnfm80.resize(occVecArraySize); + occNTrackSizeUnfm80.resize(occVecArraySize); + occNTrackTPCAUnfm80.resize(occVecArraySize); + occNTrackTPCCUnfm80.resize(occVecArraySize); + occNTrackITSTPCAUnfm80.resize(occVecArraySize); + occNTrackITSTPCCUnfm80.resize(occVecArraySize); + } + if (buildFullOccTableProducer || buildOnlyOccsNtrackDet || buildOnlyOccsMultExtra) { + occNTrackITSTPCUnfm80.resize(occVecArraySize); + } + if (buildFullOccTableProducer || buildOnlyOccsMultExtra) { + occMultNTracksHasITSUnfm80.resize(occVecArraySize); + occMultNTracksHasTPCUnfm80.resize(occVecArraySize); + occMultNTracksHasTOFUnfm80.resize(occVecArraySize); + occMultNTracksHasTRDUnfm80.resize(occVecArraySize); + occMultNTracksITSOnlyUnfm80.resize(occVecArraySize); + occMultNTracksTPCOnlyUnfm80.resize(occVecArraySize); + occMultNTracksITSTPCUnfm80.resize(occVecArraySize); + occMultAllTracksTPCOnlyUnfm80.resize(occVecArraySize); + } + + for (int i = 0; i < occVecArraySize; i++) { + bcTFMap[i].resize(nBCinTF / bcGrouping); + if (buildFullOccTableProducer || buildOnlyOccsPrim || buildOnlyOccsT0V0Prim || buildOnlyOccsFDDT0V0Prim || buildOnlyOccsNtrackDet || buildOnlyOccsMultExtra) { + occPrimUnfm80[i].resize(nBCinTF / bcGrouping); + } + if (buildFullOccTableProducer || buildOnlyOccsT0V0Prim || buildOnlyOccsFDDT0V0Prim) { + occFV0AUnfm80[i].resize(nBCinTF / bcGrouping); + occFV0CUnfm80[i].resize(nBCinTF / bcGrouping); + occFT0AUnfm80[i].resize(nBCinTF / bcGrouping); + occFT0CUnfm80[i].resize(nBCinTF / bcGrouping); + } + if (buildFullOccTableProducer || buildOnlyOccsFDDT0V0Prim) { + occFDDAUnfm80[i].resize(nBCinTF / bcGrouping); + occFDDCUnfm80[i].resize(nBCinTF / bcGrouping); + } + if (buildFullOccTableProducer || buildOnlyOccsNtrackDet) { + occNTrackITSUnfm80[i].resize(nBCinTF / bcGrouping); + occNTrackTPCUnfm80[i].resize(nBCinTF / bcGrouping); + occNTrackTRDUnfm80[i].resize(nBCinTF / bcGrouping); + occNTrackTOFUnfm80[i].resize(nBCinTF / bcGrouping); + occNTrackSizeUnfm80[i].resize(nBCinTF / bcGrouping); + occNTrackTPCAUnfm80[i].resize(nBCinTF / bcGrouping); + occNTrackTPCCUnfm80[i].resize(nBCinTF / bcGrouping); + occNTrackITSTPCAUnfm80[i].resize(nBCinTF / bcGrouping); + occNTrackITSTPCCUnfm80[i].resize(nBCinTF / bcGrouping); + } + if (buildFullOccTableProducer || buildOnlyOccsNtrackDet || buildOnlyOccsMultExtra) { + occNTrackITSTPCUnfm80[i].resize(nBCinTF / bcGrouping); + } + if (buildFullOccTableProducer || buildOnlyOccsMultExtra) { + occMultNTracksHasITSUnfm80[i].resize(nBCinTF / bcGrouping); + occMultNTracksHasTPCUnfm80[i].resize(nBCinTF / bcGrouping); + occMultNTracksHasTOFUnfm80[i].resize(nBCinTF / bcGrouping); + occMultNTracksHasTRDUnfm80[i].resize(nBCinTF / bcGrouping); + occMultNTracksITSOnlyUnfm80[i].resize(nBCinTF / bcGrouping); + occMultNTracksTPCOnlyUnfm80[i].resize(nBCinTF / bcGrouping); + occMultNTracksITSTPCUnfm80[i].resize(nBCinTF / bcGrouping); + occMultAllTracksTPCOnlyUnfm80[i].resize(nBCinTF / bcGrouping); + } + } + + if (buildFullOccTableProducer || buildOnlyOccsT0V0Prim || buildFlag02OccRobustTable || buildFlag03OccMeanRobustTable) { + vecRobustOccT0V0PrimUnfm80.resize(nBCinTF / bcGrouping); + vecRobustOccT0V0PrimUnfm80medianPosVec.resize(nBCinTF / bcGrouping); // Median => one for odd and two for even entries + } + if (buildFullOccTableProducer || buildOnlyOccsFDDT0V0Prim || buildFlag02OccRobustTable || buildFlag03OccMeanRobustTable) { + vecRobustOccFDDT0V0PrimUnfm80.resize(nBCinTF / bcGrouping); + vecRobustOccFDDT0V0PrimUnfm80medianPosVec.resize(nBCinTF / bcGrouping); + } + if (buildFullOccTableProducer || buildOnlyOccsNtrackDet || buildFlag02OccRobustTable || buildFlag03OccMeanRobustTable) { + vecRobustOccNtrackDetUnfm80.resize(nBCinTF / bcGrouping); + vecRobustOccNtrackDetUnfm80medianPosVec.resize(nBCinTF / bcGrouping); + } + if (buildFullOccTableProducer || buildOnlyOccsMultExtra || buildFlag02OccRobustTable || buildFlag03OccMeanRobustTable) { + vecRobustOccmultTableUnfm80.resize(nBCinTF / bcGrouping); + vecRobustOccmultTableUnfm80medianPosVec.resize(nBCinTF / bcGrouping); + } // Getting Info from CCDB, to be implemented Later recoEvent.add("h_nBCinTF", "h_nBCinTF(to check nBCinTF)", {HistType::kTH1F, {{100, 114040, 114060}}}); // 114048 @@ -183,8 +269,13 @@ struct OccupancyTableProducer { recoEvent.add("h_RO_FDDT0V0PrimUnfm80", "h_RO_FDDT0V0PrimUnfm80:median contributors", {HistType::kTH1F, {{12 * 2, -1, 11}}}); recoEvent.add("h_RO_NtrackDetUnfm80", "h_RO_NtrackDetITS/TPC/TRD/TOF_80:median contributors", {HistType::kTH1F, {{12 * 2, -1, 11}}}); recoEvent.add("h_RO_multTableUnfm80", "h_RO_multTableExtra_80:median contributors", {HistType::kTH1F, {{12 * 2, -1, 11}}}); + occupancyQA.add("h_TF_in_DataFrame", "h_TF_in_DataFrame", kTH1F, {{50, -1, 49}}); + occupancyQA.add("h_DFcount_Lvl0", "h_DFcount_Lvl0", kTH1F, {{1, 0, 1}}); + occupancyQA.add("h_DFcount_Lvl1", "h_DFcount_Lvl1", kTH1F, {{1, 0, 1}}); + occupancyQA.add("h_DFcount_Lvl2", "h_DFcount_Lvl2", kTH1F, {{1, 0, 1}}); recoEvent.print(); + occupancyQA.print(); } void normalizeVector(std::vector& OriginalVec, const float& scaleFactor) @@ -218,8 +309,9 @@ struct OccupancyTableProducer { }); double median; + int two = 2; // Find the median - if (n % 2 == 0) { + if (n % two == 0) { median = (data[(n - 1) / 2][0] + data[(n - 1) / 2 + 1][0]) / 2; medianPosVec[i][0] = static_cast(data[(n - 1) / 2][1] + 0.001); medianPosVec[i][1] = static_cast(data[(n - 1) / 2 + 1][1] + 0.001); @@ -238,7 +330,7 @@ struct OccupancyTableProducer { int64_t tsSOR = runDuration.first; auto ctpx = ccdb->getForTimeStamp>("CTP/Calib/OrbitReset", tsSOR); int64_t tsOrbitReset = (*ctpx)[0]; - uint32_t nOrbitsPerTF = run < 534133 ? 128 : 32; + uint32_t nOrbitsPerTF = run < cfgNOrbitsPerTF0RunValue ? cfgNOrbitsPerTF1TrueValue : cfgNOrbitsPerTF2FalseValue; int64_t orbitSOR = (tsSOR * 1000 - tsOrbitReset) / o2::constants::lhc::LHCOrbitMUS; orbitSOR = orbitSOR / nOrbitsPerTF * nOrbitsPerTF; bcSOR = orbitSOR * nBCsPerOrbit + customOrbitOffset * nBCsPerOrbit; // customOrbitOffset is a configurable @@ -259,8 +351,7 @@ struct OccupancyTableProducer { bcInTF = (bc.globalBC() - bcSOR) % nBCsPerTF; } - using MyCollisions = soa::Join; - using MyTracks = soa::Join; + using MyTracks = aod::Tracks; Preslice tracksPerCollisionPreslice = o2::aod::track::collisionId; @@ -273,72 +364,149 @@ struct OccupancyTableProducer { uint tfCounted = 0; int tfIDX = 0; int lastRun = -999; + //_________________________Full Exection Function_______________________________________________________________________________________ + + enum ProcessTags { + kProcessOnlyBCTFinfoTable = 0, + kProcessOnlyOccPrim, + kProcessOnlyOccT0V0Prim, + kProcessOnlyOccFDDT0V0Prim, + kProcessOnlyOccNtrackDet, + kProcessOnlyOccMultExtra, + kProcessFullOccTableProducer + }; - // Process the Data - void process(o2::aod::BCsWithTimestamps const& BCs, MyCollisions const& collisions, MyTracks const& tracks) // aod::TracksQA const& tracksQA, o2::aod::Origins const& Origins //tables only used during debugging - { - // dfCount++;LOG(info) << "DEBUG 1 :: df_" << dfCount ;//<< " :: DF_" << Origins.begin().dataframeID() << " :: collisions.size() = " << collisions.size() << " :: tracks.size() = " << tracks.size() << " :: tracksQA.size() = " << tracksQA.size() << " :: BCs.size() = " << BCs.size(); + static constexpr std::string_view ProcessNames[]{ + "processOnlyBCTFinfoTable", + "processOnlyOccPrimUnfm", + "processOnlyOccT0V0PrimUnfm", + "processOnlyOccFDDT0V0PrimUnfm", + "processOnlyOccNtrackDet", + "processOnlyOccMultExtra", + "processFullOccTableProduer"}; + + enum FillMode { + checkTableMode = 0, + doNotFill, + fillOccTable, + fillMeanOccTable, + fillOccRobustTable, + fillOccMeanRobustTable + }; + template + void executeCollisionCheckAndBCprocessing(B const& BCs, C const& collisions, bool& collisionsSizeIsZero) + { if (collisions.size() == 0) { for (const auto& BC : BCs) { // For BCs and OccIndexTable to have same size for joining getTimingInfo(BC, lastRun, nBCsPerTF, bcSOR, time, tfIdThis, bcInTF); - genOccIndexTable(BC.globalIndex(), -999); // BCId, OccId genBCTFinfoTable(tfIdThis, bcInTF); + genOccIndexTable(BC.globalIndex(), -999); // BCId, OccId + } + collisionsSizeIsZero = true; + } + } + + int processTimeCounter = 0; + template + void executeOccProducerProcessing(B const& BCs, C const& collisions, T const& tracks) + { + if (tableMode == checkTableMode) { + if (buildFlag00OccTable) { + executeOccProducerProcessing(BCs, collisions, tracks); + } else { + executeOccProducerProcessing(BCs, collisions, tracks); } + } + if constexpr (tableMode == checkTableMode) { + return; + } + + if (meanTableMode == checkTableMode) { + if (buildFlag01OccMeanTable) { + executeOccProducerProcessing(BCs, collisions, tracks); + } else { + executeOccProducerProcessing(BCs, collisions, tracks); + } + } + if constexpr (meanTableMode == checkTableMode) { return; } - // Initialisze the vectors components to zero - tfIDX = 0; - tfCounted = 0; - for (int i = 0; i < arraySize; i++) { - tfList[i] = -1; - bcTFMap[i].clear(); // list of BCs used in one time frame; - std::fill(occPrimUnfm80[i].begin(), occPrimUnfm80[i].end(), 0.); - std::fill(occFV0AUnfm80[i].begin(), occFV0AUnfm80[i].end(), 0.); - std::fill(occFV0CUnfm80[i].begin(), occFV0CUnfm80[i].end(), 0.); - std::fill(occFT0AUnfm80[i].begin(), occFT0AUnfm80[i].end(), 0.); - std::fill(occFT0CUnfm80[i].begin(), occFT0CUnfm80[i].end(), 0.); - std::fill(occFDDAUnfm80[i].begin(), occFDDAUnfm80[i].end(), 0.); - std::fill(occFDDCUnfm80[i].begin(), occFDDCUnfm80[i].end(), 0.); - - std::fill(occNTrackITSUnfm80[i].begin(), occNTrackITSUnfm80[i].end(), 0.); - std::fill(occNTrackTPCUnfm80[i].begin(), occNTrackTPCUnfm80[i].end(), 0.); - std::fill(occNTrackTRDUnfm80[i].begin(), occNTrackTRDUnfm80[i].end(), 0.); - std::fill(occNTrackTOFUnfm80[i].begin(), occNTrackTOFUnfm80[i].end(), 0.); - std::fill(occNTrackSizeUnfm80[i].begin(), occNTrackSizeUnfm80[i].end(), 0.); - std::fill(occNTrackTPCAUnfm80[i].begin(), occNTrackTPCAUnfm80[i].end(), 0.); - std::fill(occNTrackTPCCUnfm80[i].begin(), occNTrackTPCCUnfm80[i].end(), 0.); - std::fill(occNTrackITSTPCUnfm80[i].begin(), occNTrackITSTPCUnfm80[i].end(), 0.); - std::fill(occNTrackITSTPCAUnfm80[i].begin(), occNTrackITSTPCAUnfm80[i].end(), 0.); - std::fill(occNTrackITSTPCCUnfm80[i].begin(), occNTrackITSTPCCUnfm80[i].end(), 0.); - - std::fill(occMultNTracksHasITSUnfm80[i].begin(), occMultNTracksHasITSUnfm80[i].end(), 0.); - std::fill(occMultNTracksHasTPCUnfm80[i].begin(), occMultNTracksHasTPCUnfm80[i].end(), 0.); - std::fill(occMultNTracksHasTOFUnfm80[i].begin(), occMultNTracksHasTOFUnfm80[i].end(), 0.); - std::fill(occMultNTracksHasTRDUnfm80[i].begin(), occMultNTracksHasTRDUnfm80[i].end(), 0.); - std::fill(occMultNTracksITSOnlyUnfm80[i].begin(), occMultNTracksITSOnlyUnfm80[i].end(), 0.); - std::fill(occMultNTracksTPCOnlyUnfm80[i].begin(), occMultNTracksTPCOnlyUnfm80[i].end(), 0.); - std::fill(occMultNTracksITSTPCUnfm80[i].begin(), occMultNTracksITSTPCUnfm80[i].end(), 0.); - std::fill(occMultAllTracksTPCOnlyUnfm80[i].begin(), occMultAllTracksTPCOnlyUnfm80[i].end(), 0.); - } - - std::vector tfIDList; - for (const auto& collision : collisions) { - const auto& bc = collision.bc_as(); - getTimingInfo(bc, lastRun, nBCsPerTF, bcSOR, time, tfIdThis, bcInTF); - - recoEvent.fill(HIST("h_nBCinTF"), nBCsPerTF); - recoEvent.fill(HIST("h_bcInTF"), bcInTF); - - if (nBCsPerTF > nBCinTF) { - LOG(error) << "DEBUG :: FATAL ERROR :: nBCsPerTF > nBCinTF i.e " << nBCsPerTF << " > " << nBCinTF << " will cause crash in further process"; - return; + if (robustTableMode == checkTableMode) { + if (buildFlag02OccRobustTable) { + executeOccProducerProcessing(BCs, collisions, tracks); + } else { + executeOccProducerProcessing(BCs, collisions, tracks); + } + } + if constexpr (robustTableMode == checkTableMode) { + return; + } + + if (meanRobustTableMode == checkTableMode) { + if (buildFlag03OccMeanRobustTable) { + executeOccProducerProcessing(BCs, collisions, tracks); + } else { + executeOccProducerProcessing(BCs, collisions, tracks); } + } + if constexpr (meanRobustTableMode == checkTableMode) { + return; + } + + if constexpr (tableMode == checkTableMode || meanTableMode == checkTableMode || robustTableMode == checkTableMode || meanRobustTableMode == checkTableMode) { + return; + } else { + + occupancyQA.fill(HIST("h_DFcount_Lvl2"), 0.5); - const uint64_t collIdx = collision.globalIndex(); - const auto tracksTablePerColl = tracks.sliceBy(tracksPerCollisionPreslice, collIdx); + // Initialisze the vectors components to zero + tfIDX = 0; + tfCounted = 0; + for (int i = 0; i < occVecArraySize; i++) { + tfList[i] = -1; + bcTFMap[i].clear(); // list of BCs used in one time frame; + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccPrim || processMode == kProcessOnlyOccT0V0Prim || processMode == kProcessOnlyOccFDDT0V0Prim || processMode == kProcessOnlyOccNtrackDet || processMode == kProcessOnlyOccMultExtra) { + std::fill(occPrimUnfm80[i].begin(), occPrimUnfm80[i].end(), 0.); + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccT0V0Prim || processMode == kProcessOnlyOccFDDT0V0Prim) { + std::fill(occFV0AUnfm80[i].begin(), occFV0AUnfm80[i].end(), 0.); + std::fill(occFV0CUnfm80[i].begin(), occFV0CUnfm80[i].end(), 0.); + std::fill(occFT0AUnfm80[i].begin(), occFT0AUnfm80[i].end(), 0.); + std::fill(occFT0CUnfm80[i].begin(), occFT0CUnfm80[i].end(), 0.); + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccFDDT0V0Prim) { + std::fill(occFDDAUnfm80[i].begin(), occFDDAUnfm80[i].end(), 0.); + std::fill(occFDDCUnfm80[i].begin(), occFDDCUnfm80[i].end(), 0.); + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccNtrackDet) { + std::fill(occNTrackITSUnfm80[i].begin(), occNTrackITSUnfm80[i].end(), 0.); + std::fill(occNTrackTPCUnfm80[i].begin(), occNTrackTPCUnfm80[i].end(), 0.); + std::fill(occNTrackTRDUnfm80[i].begin(), occNTrackTRDUnfm80[i].end(), 0.); + std::fill(occNTrackTOFUnfm80[i].begin(), occNTrackTOFUnfm80[i].end(), 0.); + std::fill(occNTrackSizeUnfm80[i].begin(), occNTrackSizeUnfm80[i].end(), 0.); + std::fill(occNTrackTPCAUnfm80[i].begin(), occNTrackTPCAUnfm80[i].end(), 0.); + std::fill(occNTrackTPCCUnfm80[i].begin(), occNTrackTPCCUnfm80[i].end(), 0.); + std::fill(occNTrackITSTPCAUnfm80[i].begin(), occNTrackITSTPCAUnfm80[i].end(), 0.); + std::fill(occNTrackITSTPCCUnfm80[i].begin(), occNTrackITSTPCCUnfm80[i].end(), 0.); + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccNtrackDet || processMode == kProcessOnlyOccMultExtra) { + std::fill(occNTrackITSTPCUnfm80[i].begin(), occNTrackITSTPCUnfm80[i].end(), 0.); + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccMultExtra) { + std::fill(occMultNTracksHasITSUnfm80[i].begin(), occMultNTracksHasITSUnfm80[i].end(), 0.); + std::fill(occMultNTracksHasTPCUnfm80[i].begin(), occMultNTracksHasTPCUnfm80[i].end(), 0.); + std::fill(occMultNTracksHasTOFUnfm80[i].begin(), occMultNTracksHasTOFUnfm80[i].end(), 0.); + std::fill(occMultNTracksHasTRDUnfm80[i].begin(), occMultNTracksHasTRDUnfm80[i].end(), 0.); + std::fill(occMultNTracksITSOnlyUnfm80[i].begin(), occMultNTracksITSOnlyUnfm80[i].end(), 0.); + std::fill(occMultNTracksTPCOnlyUnfm80[i].begin(), occMultNTracksTPCOnlyUnfm80[i].end(), 0.); + std::fill(occMultNTracksITSTPCUnfm80[i].begin(), occMultNTracksITSTPCUnfm80[i].end(), 0.); + std::fill(occMultAllTracksTPCOnlyUnfm80[i].begin(), occMultAllTracksTPCOnlyUnfm80[i].end(), 0.); + } + } + std::vector tfIDList; int nTrackITS = 0; int nTrackTPC = 0; int nTrackTRD = 0; @@ -348,380 +516,719 @@ struct OccupancyTableProducer { int nTrackITSTPCA = 0; int nTrackITSTPCC = 0; - for (const auto& track : tracksTablePerColl) { - if (track.hasITS()) { - nTrackITS++; - } // Flag to check if track has a ITS match - if (track.hasTPC()) { - nTrackTPC++; - if (track.eta() <= 0.0) { - nTrackTPCA++; // includes tracks at eta zero as well. - } else { - nTrackTPCC++; + ushort fNumContrib = 0; + + float fMultFV0A = -99999, fMultFV0C = -99999; + float fMultFT0A = -99999, fMultFT0C = -99999; + float fMultFDDA = -99999, fMultFDDC = -99999; + + int fNTrackITS = -9999; + int fNTrackTPC = -9999; + int fNTrackTRD = -9999; + int fNTrackTOF = -9999; + int fNTrackTPCA = -9999; + int fNTrackTPCC = -9999; + int fNTrackSize = -9999; + int fNTrackITSTPC = -9999; + int fNTrackITSTPCA = -9999; + int fNTrackITSTPCC = -9999; + + decltype(&occPrimUnfm80[0]) tfOccPrimUnfm80 = nullptr; + decltype(&occFV0AUnfm80[0]) tfOccFV0AUnfm80 = nullptr; + decltype(&occFV0CUnfm80[0]) tfOccFV0CUnfm80 = nullptr; + decltype(&occFT0AUnfm80[0]) tfOccFT0AUnfm80 = nullptr; + decltype(&occFT0CUnfm80[0]) tfOccFT0CUnfm80 = nullptr; + + decltype(&occFDDAUnfm80[0]) tfOccFDDAUnfm80 = nullptr; + decltype(&occFDDCUnfm80[0]) tfOccFDDCUnfm80 = nullptr; + + decltype(&occNTrackITSTPCUnfm80[0]) tfOccNTrackITSTPCUnfm80 = nullptr; + + decltype(&occNTrackITSUnfm80[0]) tfOccNTrackITSUnfm80 = nullptr; + decltype(&occNTrackTPCUnfm80[0]) tfOccNTrackTPCUnfm80 = nullptr; + decltype(&occNTrackTRDUnfm80[0]) tfOccNTrackTRDUnfm80 = nullptr; + decltype(&occNTrackTOFUnfm80[0]) tfOccNTrackTOFUnfm80 = nullptr; + decltype(&occNTrackSizeUnfm80[0]) tfOccNTrackSizeUnfm80 = nullptr; + decltype(&occNTrackTPCAUnfm80[0]) tfOccNTrackTPCAUnfm80 = nullptr; + decltype(&occNTrackTPCCUnfm80[0]) tfOccNTrackTPCCUnfm80 = nullptr; + decltype(&occNTrackITSTPCAUnfm80[0]) tfOccNTrackITSTPCAUnfm80 = nullptr; + decltype(&occNTrackITSTPCCUnfm80[0]) tfOccNTrackITSTPCCUnfm80 = nullptr; + + decltype(&occMultNTracksHasITSUnfm80[0]) tfOccMultNTracksHasITSUnfm80 = nullptr; + decltype(&occMultNTracksHasTPCUnfm80[0]) tfOccMultNTracksHasTPCUnfm80 = nullptr; + decltype(&occMultNTracksHasTOFUnfm80[0]) tfOccMultNTracksHasTOFUnfm80 = nullptr; + decltype(&occMultNTracksHasTRDUnfm80[0]) tfOccMultNTracksHasTRDUnfm80 = nullptr; + decltype(&occMultNTracksITSOnlyUnfm80[0]) tfOccMultNTracksITSOnlyUnfm80 = nullptr; + decltype(&occMultNTracksTPCOnlyUnfm80[0]) tfOccMultNTracksTPCOnlyUnfm80 = nullptr; + decltype(&occMultNTracksITSTPCUnfm80[0]) tfOccMultNTracksITSTPCUnfm80 = nullptr; + decltype(&occMultAllTracksTPCOnlyUnfm80[0]) tfOccMultAllTracksTPCOnlyUnfm80 = nullptr; + + for (const auto& collision : collisions) { + const auto& bc = collision.template bc_as(); + getTimingInfo(bc, lastRun, nBCsPerTF, bcSOR, time, tfIdThis, bcInTF); + + recoEvent.fill(HIST("h_nBCinTF"), nBCsPerTF); + recoEvent.fill(HIST("h_bcInTF"), bcInTF); + + if (nBCsPerTF > nBCinTF) { + LOG(error) << "DEBUG :: FATAL ERROR :: nBCsPerTF > nBCinTF i.e " << nBCsPerTF << " > " << nBCinTF << " will cause crash in further process"; + } + + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccNtrackDet) { + const uint64_t collIdx = collision.globalIndex(); + const auto tracksTablePerColl = tracks.sliceBy(tracksPerCollisionPreslice, collIdx); + + fNTrackSize = tracksTablePerColl.size(); + + nTrackITS = 0; + nTrackTPC = 0; + nTrackTRD = 0; + nTrackTOF = 0; + nTrackTPCA = 0; + nTrackTPCC = 0; + nTrackITSTPCA = 0; + nTrackITSTPCC = 0; + for (const auto& track : tracksTablePerColl) { + if (track.hasITS()) { + nTrackITS++; + } // Flag to check if track has a ITS match + if (track.hasTPC()) { + nTrackTPC++; + if (track.eta() <= 0.0) { + nTrackTPCA++; // includes tracks at eta zero as well. + } else { + nTrackTPCC++; + } + } // Flag to check if track has a TPC match + if (track.hasTRD()) { + nTrackTRD++; + } // Flag to check if track has a TRD match + if (track.hasTOF()) { + nTrackTOF++; + } // Flag to check if track has a TOF measurement + if (track.hasITS() && track.hasTPC()) { + if (track.eta() <= 0.0) { + nTrackITSTPCA++; // includes tracks at eta zero as well. + } else { + nTrackITSTPCC++; + } + } + } // track loop + } + // if (collision.multNTracksTPCOnly() != 0) { + // LOG(error) << "DEBUG :: ERROR = multNTracksTPCOnly != 0" << collision.multNTracksTPCOnly(); + // return; + // } + // if (collision.multAllTracksITSTPC() != nTrackITSTPC) { + // LOG(error) << "DEBUG :: ERROR :: 10 multAllTracksITSTPC :: " << collision.multAllTracksITSTPC() << " != " << nTrackITSTPC; + // return; + // } + + tfIDList.push_back(tfIdThis); + + if (tfList[tfIDX] != tfIdThis) { + if (tfCounted != 0) { + tfIDX++; + } // + tfList[tfIDX] = tfIdThis; + tfCounted++; + } + + bcTFMap[tfIDX].push_back(bc.globalIndex()); + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccPrim || processMode == kProcessOnlyOccT0V0Prim || processMode == kProcessOnlyOccFDDT0V0Prim || processMode == kProcessOnlyOccNtrackDet || processMode == kProcessOnlyOccMultExtra) { + tfOccPrimUnfm80 = &occPrimUnfm80[tfIDX]; + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccT0V0Prim || processMode == kProcessOnlyOccFDDT0V0Prim) { + tfOccFV0AUnfm80 = &occFV0AUnfm80[tfIDX]; + tfOccFV0CUnfm80 = &occFV0CUnfm80[tfIDX]; + tfOccFT0AUnfm80 = &occFT0AUnfm80[tfIDX]; + tfOccFT0CUnfm80 = &occFT0CUnfm80[tfIDX]; + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccFDDT0V0Prim) { + tfOccFDDAUnfm80 = &occFDDAUnfm80[tfIDX]; + tfOccFDDCUnfm80 = &occFDDCUnfm80[tfIDX]; + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccNtrackDet) { + tfOccNTrackITSUnfm80 = &occNTrackITSUnfm80[tfIDX]; + tfOccNTrackTPCUnfm80 = &occNTrackTPCUnfm80[tfIDX]; + tfOccNTrackTRDUnfm80 = &occNTrackTRDUnfm80[tfIDX]; + tfOccNTrackTOFUnfm80 = &occNTrackTOFUnfm80[tfIDX]; + tfOccNTrackSizeUnfm80 = &occNTrackSizeUnfm80[tfIDX]; + tfOccNTrackTPCAUnfm80 = &occNTrackTPCAUnfm80[tfIDX]; + tfOccNTrackTPCCUnfm80 = &occNTrackTPCCUnfm80[tfIDX]; + tfOccNTrackITSTPCAUnfm80 = &occNTrackITSTPCAUnfm80[tfIDX]; + tfOccNTrackITSTPCCUnfm80 = &occNTrackITSTPCCUnfm80[tfIDX]; + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccNtrackDet || processMode == kProcessOnlyOccMultExtra) { + tfOccNTrackITSTPCUnfm80 = &occNTrackITSTPCUnfm80[tfIDX]; + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccMultExtra) { + tfOccMultNTracksHasITSUnfm80 = &occMultNTracksHasITSUnfm80[tfIDX]; + tfOccMultNTracksHasTPCUnfm80 = &occMultNTracksHasTPCUnfm80[tfIDX]; + tfOccMultNTracksHasTOFUnfm80 = &occMultNTracksHasTOFUnfm80[tfIDX]; + tfOccMultNTracksHasTRDUnfm80 = &occMultNTracksHasTRDUnfm80[tfIDX]; + tfOccMultNTracksITSOnlyUnfm80 = &occMultNTracksITSOnlyUnfm80[tfIDX]; + tfOccMultNTracksTPCOnlyUnfm80 = &occMultNTracksTPCOnlyUnfm80[tfIDX]; + tfOccMultNTracksITSTPCUnfm80 = &occMultNTracksITSTPCUnfm80[tfIDX]; + tfOccMultAllTracksTPCOnlyUnfm80 = &occMultAllTracksTPCOnlyUnfm80[tfIDX]; + } + + // current collision bin in 80/160 bcGrouping. + int bin80Zero = bcInTF / bcGrouping; + // int bin160_0=bcInTF/160; + + // float fbin80Zero =float(bcInTF)/80; + // float fbin160_0=float(bcInTF)/160; + + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccPrim || processMode == kProcessOnlyOccT0V0Prim || processMode == kProcessOnlyOccFDDT0V0Prim || processMode == kProcessOnlyOccNtrackDet || processMode == kProcessOnlyOccMultExtra) { + fNumContrib = collision.numContrib(); // only aod::Collisions will be needed + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccT0V0Prim || processMode == kProcessOnlyOccFDDT0V0Prim) { + fMultFV0A = collision.multFV0A(); + fMultFV0C = collision.multFV0C(); // o2::aod::Mults will be needed + fMultFT0A = collision.multFT0A(); + fMultFT0C = collision.multFT0C(); + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccFDDT0V0Prim) { + fMultFDDA = collision.multFDDA(); + fMultFDDC = collision.multFDDC(); + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccNtrackDet) { + fNTrackITS = nTrackITS; + fNTrackTPC = nTrackTPC; + fNTrackTRD = nTrackTRD; + fNTrackTOF = nTrackTOF; + fNTrackTPCA = nTrackTPCA; + fNTrackTPCC = nTrackTPCC; + fNTrackITSTPC = collision.multAllTracksITSTPC(); + fNTrackITSTPCA = nTrackITSTPCA; + fNTrackITSTPCC = nTrackITSTPCC; + } + // Processing for bcGrouping of 80 BCs + for (int deltaBin = 0; deltaBin < nBCinDrift / bcGrouping; deltaBin++) { + + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccPrim || processMode == kProcessOnlyOccT0V0Prim || processMode == kProcessOnlyOccFDDT0V0Prim || processMode == kProcessOnlyOccNtrackDet || processMode == kProcessOnlyOccMultExtra) { + (*tfOccPrimUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += fNumContrib * 1; + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccT0V0Prim || processMode == kProcessOnlyOccFDDT0V0Prim) { + (*tfOccFV0AUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += fMultFV0A * 1; + (*tfOccFV0CUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += fMultFV0C * 1; + (*tfOccFT0AUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += fMultFT0A * 1; + (*tfOccFT0CUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += fMultFT0C * 1; + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccFDDT0V0Prim) { + (*tfOccFDDAUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += fMultFDDA * 1; + (*tfOccFDDCUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += fMultFDDC * 1; + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccNtrackDet) { + (*tfOccNTrackITSUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += fNTrackITS * 1; + (*tfOccNTrackTPCUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += fNTrackTPC * 1; + (*tfOccNTrackTRDUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += fNTrackTRD * 1; + (*tfOccNTrackTOFUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += fNTrackTOF * 1; + (*tfOccNTrackSizeUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += fNTrackSize * 1; + (*tfOccNTrackTPCAUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += fNTrackTPCA * 1; + (*tfOccNTrackTPCCUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += fNTrackTPCC * 1; + (*tfOccNTrackITSTPCAUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += fNTrackITSTPCA * 1; + (*tfOccNTrackITSTPCCUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += fNTrackITSTPCC * 1; } - } // Flag to check if track has a TPC match - if (track.hasTRD()) { - nTrackTRD++; - } // Flag to check if track has a TRD match - if (track.hasTOF()) { - nTrackTOF++; - } // Flag to check if track has a TOF measurement - if (track.hasITS() && track.hasTPC()) { - if (track.eta() <= 0.0) { - nTrackITSTPCA++; // includes tracks at eta zero as well. - } else { - nTrackITSTPCC++; + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccNtrackDet || processMode == kProcessOnlyOccMultExtra) { + (*tfOccNTrackITSTPCUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += fNTrackITSTPC * 1; + } + + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccMultExtra) { + (*tfOccMultNTracksHasITSUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += collision.multNTracksHasITS() * 1; + (*tfOccMultNTracksHasTPCUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += collision.multNTracksHasTPC() * 1; + (*tfOccMultNTracksHasTOFUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += collision.multNTracksHasTOF() * 1; + (*tfOccMultNTracksHasTRDUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += collision.multNTracksHasTRD() * 1; + (*tfOccMultNTracksITSOnlyUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += collision.multNTracksITSOnly() * 1; + (*tfOccMultNTracksTPCOnlyUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += collision.multNTracksTPCOnly() * 1; + (*tfOccMultNTracksITSTPCUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += collision.multNTracksITSTPC() * 1; + (*tfOccMultAllTracksTPCOnlyUnfm80)[(bin80Zero + deltaBin) % (nBCinTF / bcGrouping)] += collision.multAllTracksTPCOnly() * 1; } } - } // track loop - - // if (collision.multNTracksTPCOnly() != 0) { - // LOG(error) << "DEBUG :: ERROR = multNTracksTPCOnly != 0" << collision.multNTracksTPCOnly(); - // return; - // } - // if (collision.multAllTracksITSTPC() != nTrackITSTPC) { - // LOG(error) << "DEBUG :: ERROR :: 10 multAllTracksITSTPC :: " << collision.multAllTracksITSTPC() << " != " << nTrackITSTPC; - // return; - // } - - tfIDList.push_back(tfIdThis); - - if (tfList[tfIDX] != tfIdThis) { - if (tfCounted != 0) { - tfIDX++; - } // - tfList[tfIDX] = tfIdThis; - tfCounted++; } + // collision Loop is over - bcTFMap[tfIDX].push_back(bc.globalIndex()); - auto& tfOccPrimUnfm80 = occPrimUnfm80[tfIDX]; - auto& tfOccFV0AUnfm80 = occFV0AUnfm80[tfIDX]; - auto& tfOccFV0CUnfm80 = occFV0CUnfm80[tfIDX]; - auto& tfOccFT0AUnfm80 = occFT0AUnfm80[tfIDX]; - auto& tfOccFT0CUnfm80 = occFT0CUnfm80[tfIDX]; - auto& tfOccFDDAUnfm80 = occFDDAUnfm80[tfIDX]; - auto& tfOccFDDCUnfm80 = occFDDCUnfm80[tfIDX]; - - auto& tfOccNTrackITSUnfm80 = occNTrackITSUnfm80[tfIDX]; - auto& tfOccNTrackTPCUnfm80 = occNTrackTPCUnfm80[tfIDX]; - auto& tfOccNTrackTRDUnfm80 = occNTrackTRDUnfm80[tfIDX]; - auto& tfOccNTrackTOFUnfm80 = occNTrackTOFUnfm80[tfIDX]; - auto& tfOccNTrackSizeUnfm80 = occNTrackSizeUnfm80[tfIDX]; - auto& tfOccNTrackTPCAUnfm80 = occNTrackTPCAUnfm80[tfIDX]; - auto& tfOccNTrackTPCCUnfm80 = occNTrackTPCCUnfm80[tfIDX]; - auto& tfOccNTrackITSTPCUnfm80 = occNTrackITSTPCUnfm80[tfIDX]; - auto& tfOccNTrackITSTPCAUnfm80 = occNTrackITSTPCAUnfm80[tfIDX]; - auto& tfOccNTrackITSTPCCUnfm80 = occNTrackITSTPCCUnfm80[tfIDX]; - - auto& tfOccMultNTracksHasITSUnfm80 = occMultNTracksHasITSUnfm80[tfIDX]; - auto& tfOccMultNTracksHasTPCUnfm80 = occMultNTracksHasTPCUnfm80[tfIDX]; - auto& tfOccMultNTracksHasTOFUnfm80 = occMultNTracksHasTOFUnfm80[tfIDX]; - auto& tfOccMultNTracksHasTRDUnfm80 = occMultNTracksHasTRDUnfm80[tfIDX]; - auto& tfOccMultNTracksITSOnlyUnfm80 = occMultNTracksITSOnlyUnfm80[tfIDX]; - auto& tfOccMultNTracksTPCOnlyUnfm80 = occMultNTracksTPCOnlyUnfm80[tfIDX]; - auto& tfOccMultNTracksITSTPCUnfm80 = occMultNTracksITSTPCUnfm80[tfIDX]; - auto& tfOccMultAllTracksTPCOnlyUnfm80 = occMultAllTracksTPCOnlyUnfm80[tfIDX]; - - // current collision bin in 80/160 grouping. - int bin80Zero = bcInTF / 80; - // int bin160_0=bcInTF/160; - - // float fbin80Zero =float(bcInTF)/80; - // float fbin160_0=float(bcInTF)/160; - - ushort fNumContrib = collision.numContrib(); - float fMultFV0A = collision.multFV0A(), fMultFV0C = collision.multFV0C(); - float fMultFT0A = collision.multFT0A(), fMultFT0C = collision.multFT0C(); - float fMultFDDA = collision.multFDDA(), fMultFDDC = collision.multFDDC(); - int fNTrackITS = nTrackITS; - int fNTrackTPC = nTrackTPC, fNTrackTRD = nTrackTRD; - int fNTrackTOF = nTrackTOF; - int fNTrackTPCA = nTrackTPCA, fNTrackTPCC = nTrackTPCC; - int fNTrackITSTPC = collision.multAllTracksITSTPC(), fNTrackSize = tracksTablePerColl.size(); - int fNTrackITSTPCA = nTrackITSTPCA, fNTrackITSTPCC = nTrackITSTPCC; - - // Processing for grouping of 80 BCs - for (int deltaBin = 0; deltaBin < nBCinDrift / 80; deltaBin++) { - tfOccPrimUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += fNumContrib * 1; - tfOccFV0AUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += fMultFV0A * 1; - tfOccFV0CUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += fMultFV0C * 1; - tfOccFT0AUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += fMultFT0A * 1; - tfOccFT0CUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += fMultFT0C * 1; - tfOccFDDAUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += fMultFDDA * 1; - tfOccFDDCUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += fMultFDDC * 1; - - tfOccNTrackITSUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += fNTrackITS * 1; - tfOccNTrackTPCUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += fNTrackTPC * 1; - tfOccNTrackTRDUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += fNTrackTRD * 1; - tfOccNTrackTOFUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += fNTrackTOF * 1; - tfOccNTrackSizeUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += fNTrackSize * 1; - tfOccNTrackTPCAUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += fNTrackTPCA * 1; - tfOccNTrackTPCCUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += fNTrackTPCC * 1; - tfOccNTrackITSTPCUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += fNTrackITSTPC * 1; - tfOccNTrackITSTPCAUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += fNTrackITSTPCA * 1; - tfOccNTrackITSTPCCUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += fNTrackITSTPCC * 1; - - tfOccMultNTracksHasITSUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += collision.multNTracksHasITS() * 1; - tfOccMultNTracksHasTPCUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += collision.multNTracksHasTPC() * 1; - tfOccMultNTracksHasTOFUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += collision.multNTracksHasTOF() * 1; - tfOccMultNTracksHasTRDUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += collision.multNTracksHasTRD() * 1; - tfOccMultNTracksITSOnlyUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += collision.multNTracksITSOnly() * 1; - tfOccMultNTracksTPCOnlyUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += collision.multNTracksTPCOnly() * 1; - tfOccMultNTracksITSTPCUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += collision.multNTracksITSTPC() * 1; - tfOccMultAllTracksTPCOnlyUnfm80[(bin80Zero + deltaBin) % (nBCinTF / 80)] += collision.multAllTracksTPCOnly() * 1; - } - } - // collision Loop is over + occupancyQA.fill(HIST("h_TF_in_DataFrame"), tfCounted); - std::vector sortedTfIDList = tfIDList; - std::sort(sortedTfIDList.begin(), sortedTfIDList.end()); - auto last = std::unique(sortedTfIDList.begin(), sortedTfIDList.end()); - sortedTfIDList.erase(last, sortedTfIDList.end()); + std::vector sortedTfIDList = tfIDList; + std::sort(sortedTfIDList.begin(), sortedTfIDList.end()); + auto last = std::unique(sortedTfIDList.begin(), sortedTfIDList.end()); + sortedTfIDList.erase(last, sortedTfIDList.end()); - if (tfCounted != sortedTfIDList.size()) { - LOG(error) << "DEBUG :: Number mismatch for tf counted and filled :: " << tfCounted << " != " << sortedTfIDList.size(); - } + if (tfCounted != sortedTfIDList.size()) { + LOG(error) << "DEBUG :: Number mismatch for tf counted and filled :: " << tfCounted << " != " << sortedTfIDList.size(); + } - int totalBCcountSize = 0; - for (int i = 0; i < arraySize; i++) { - totalBCcountSize += bcTFMap[i].size(); - // check if the BCs are already sorted or not - if (!std::is_sorted(bcTFMap[i].begin(), bcTFMap[i].end())) { - LOG(debug) << "DEBUG :: ERROR :: BCs are not sorted"; + int totalBCcountSize = 0; + for (int i = 0; i < occVecArraySize; i++) { + totalBCcountSize += bcTFMap[i].size(); + // check if the BCs are already sorted or not + if (!std::is_sorted(bcTFMap[i].begin(), bcTFMap[i].end())) { + LOG(debug) << "DEBUG :: ERROR :: BCs are not sorted"; + } } - } - // - if (totalBCcountSize != collisions.size()) { - LOG(debug) << "DEBUG :: ERROR :: filled TF list and collision size mismatch :: filledTF_Size = " << totalBCcountSize << " != " << collisions.size() << " = collisions.size()"; - } - - // Fill the Producers - for (uint i = 0; i < tfCounted; i++) { - - auto& vecOccPrimUnfm80 = occPrimUnfm80[i]; - auto& vecOccFV0AUnfm80 = occFV0AUnfm80[i]; - auto& vecOccFV0CUnfm80 = occFV0CUnfm80[i]; - auto& vecOccFT0AUnfm80 = occFT0AUnfm80[i]; - auto& vecOccFT0CUnfm80 = occFT0CUnfm80[i]; - auto& vecOccFDDAUnfm80 = occFDDAUnfm80[i]; - auto& vecOccFDDCUnfm80 = occFDDCUnfm80[i]; - - auto& vecOccNTrackITSUnfm80 = occNTrackITSUnfm80[i]; - auto& vecOccNTrackTPCUnfm80 = occNTrackTPCUnfm80[i]; - auto& vecOccNTrackTRDUnfm80 = occNTrackTRDUnfm80[i]; - auto& vecOccNTrackTOFUnfm80 = occNTrackTOFUnfm80[i]; - auto& vecOccNTrackSizeUnfm80 = occNTrackSizeUnfm80[i]; - auto& vecOccNTrackTPCAUnfm80 = occNTrackTPCAUnfm80[i]; - auto& vecOccNTrackTPCCUnfm80 = occNTrackTPCCUnfm80[i]; - auto& vecOccNTrackITSTPCUnfm80 = occNTrackITSTPCUnfm80[i]; - auto& vecOccNTrackITSTPCAUnfm80 = occNTrackITSTPCAUnfm80[i]; - auto& vecOccNTrackITSTPCCUnfm80 = occNTrackITSTPCCUnfm80[i]; - - auto& vecOccMultNTracksHasITSUnfm80 = occMultNTracksHasITSUnfm80[i]; - auto& vecOccMultNTracksHasTPCUnfm80 = occMultNTracksHasTPCUnfm80[i]; - auto& vecOccMultNTracksHasTOFUnfm80 = occMultNTracksHasTOFUnfm80[i]; - auto& vecOccMultNTracksHasTRDUnfm80 = occMultNTracksHasTRDUnfm80[i]; - auto& vecOccMultNTracksITSOnlyUnfm80 = occMultNTracksITSOnlyUnfm80[i]; - auto& vecOccMultNTracksTPCOnlyUnfm80 = occMultNTracksTPCOnlyUnfm80[i]; - auto& vecOccMultNTracksITSTPCUnfm80 = occMultNTracksITSTPCUnfm80[i]; - auto& vecOccMultAllTracksTPCOnlyUnfm80 = occMultAllTracksTPCOnlyUnfm80[i]; - - float meanOccPrimUnfm80 = TMath::Mean(vecOccPrimUnfm80.size(), vecOccPrimUnfm80.data()); - float meanOccFV0AUnfm80 = TMath::Mean(vecOccFV0AUnfm80.size(), vecOccFV0AUnfm80.data()); - float meanOccFV0CUnfm80 = TMath::Mean(vecOccFV0CUnfm80.size(), vecOccFV0CUnfm80.data()); - float meanOccFT0AUnfm80 = TMath::Mean(vecOccFT0AUnfm80.size(), vecOccFT0AUnfm80.data()); - float meanOccFT0CUnfm80 = TMath::Mean(vecOccFT0CUnfm80.size(), vecOccFT0CUnfm80.data()); - float meanOccFDDAUnfm80 = TMath::Mean(vecOccFDDAUnfm80.size(), vecOccFDDAUnfm80.data()); - float meanOccFDDCUnfm80 = TMath::Mean(vecOccFDDCUnfm80.size(), vecOccFDDCUnfm80.data()); - - float meanOccNTrackITSUnfm80 = TMath::Mean(vecOccNTrackITSUnfm80.size(), vecOccNTrackITSUnfm80.data()); - float meanOccNTrackTPCUnfm80 = TMath::Mean(vecOccNTrackTPCUnfm80.size(), vecOccNTrackTPCUnfm80.data()); - float meanOccNTrackTRDUnfm80 = TMath::Mean(vecOccNTrackTRDUnfm80.size(), vecOccNTrackTRDUnfm80.data()); - float meanOccNTrackTOFUnfm80 = TMath::Mean(vecOccNTrackTOFUnfm80.size(), vecOccNTrackTOFUnfm80.data()); - float meanOccNTrackSizeUnfm80 = TMath::Mean(vecOccNTrackSizeUnfm80.size(), vecOccNTrackSizeUnfm80.data()); - float meanOccNTrackTPCAUnfm80 = TMath::Mean(vecOccNTrackTPCAUnfm80.size(), vecOccNTrackTPCAUnfm80.data()); - float meanOccNTrackTPCCUnfm80 = TMath::Mean(vecOccNTrackTPCCUnfm80.size(), vecOccNTrackTPCCUnfm80.data()); - float meanOccNTrackITSTPCUnfm80 = TMath::Mean(vecOccNTrackITSTPCUnfm80.size(), vecOccNTrackITSTPCUnfm80.data()); - float meanOccNTrackITSTPCAUnfm80 = TMath::Mean(vecOccNTrackITSTPCAUnfm80.size(), vecOccNTrackITSTPCAUnfm80.data()); - float meanOccNTrackITSTPCCUnfm80 = TMath::Mean(vecOccNTrackITSTPCCUnfm80.size(), vecOccNTrackITSTPCCUnfm80.data()); - - float meanOccMultNTracksHasITSUnfm80 = TMath::Mean(vecOccMultNTracksHasITSUnfm80.size(), vecOccMultNTracksHasITSUnfm80.data()); - float meanOccMultNTracksHasTPCUnfm80 = TMath::Mean(vecOccMultNTracksHasTPCUnfm80.size(), vecOccMultNTracksHasTPCUnfm80.data()); - float meanOccMultNTracksHasTOFUnfm80 = TMath::Mean(vecOccMultNTracksHasTOFUnfm80.size(), vecOccMultNTracksHasTOFUnfm80.data()); - float meanOccMultNTracksHasTRDUnfm80 = TMath::Mean(vecOccMultNTracksHasTRDUnfm80.size(), vecOccMultNTracksHasTRDUnfm80.data()); - float meanOccMultNTracksITSOnlyUnfm80 = TMath::Mean(vecOccMultNTracksITSOnlyUnfm80.size(), vecOccMultNTracksITSOnlyUnfm80.data()); - float meanOccMultNTracksTPCOnlyUnfm80 = TMath::Mean(vecOccMultNTracksTPCOnlyUnfm80.size(), vecOccMultNTracksTPCOnlyUnfm80.data()); - float meanOccMultNTracksITSTPCUnfm80 = TMath::Mean(vecOccMultNTracksITSTPCUnfm80.size(), vecOccMultNTracksITSTPCUnfm80.data()); - float meanOccMultAllTracksTPCOnlyUnfm80 = TMath::Mean(vecOccMultAllTracksTPCOnlyUnfm80.size(), vecOccMultAllTracksTPCOnlyUnfm80.data()); - - // Normalise the original vectors - normalizeVector(vecOccPrimUnfm80, meanOccPrimUnfm80 / meanOccPrimUnfm80); - normalizeVector(vecOccFV0AUnfm80, meanOccPrimUnfm80 / meanOccFV0AUnfm80); - normalizeVector(vecOccFV0CUnfm80, meanOccPrimUnfm80 / meanOccFV0CUnfm80); - normalizeVector(vecOccFT0AUnfm80, meanOccPrimUnfm80 / meanOccFT0AUnfm80); - normalizeVector(vecOccFT0CUnfm80, meanOccPrimUnfm80 / meanOccFT0CUnfm80); - normalizeVector(vecOccFDDAUnfm80, meanOccPrimUnfm80 / meanOccFDDAUnfm80); - normalizeVector(vecOccFDDCUnfm80, meanOccPrimUnfm80 / meanOccFDDCUnfm80); - - normalizeVector(vecOccNTrackITSUnfm80, meanOccPrimUnfm80 / meanOccNTrackITSUnfm80); - normalizeVector(vecOccNTrackTPCUnfm80, meanOccPrimUnfm80 / meanOccNTrackTPCUnfm80); - normalizeVector(vecOccNTrackTRDUnfm80, meanOccPrimUnfm80 / meanOccNTrackTRDUnfm80); - normalizeVector(vecOccNTrackTOFUnfm80, meanOccPrimUnfm80 / meanOccNTrackTOFUnfm80); - normalizeVector(vecOccNTrackSizeUnfm80, meanOccPrimUnfm80 / meanOccNTrackSizeUnfm80); - normalizeVector(vecOccNTrackTPCAUnfm80, meanOccPrimUnfm80 / meanOccNTrackTPCAUnfm80); - normalizeVector(vecOccNTrackTPCCUnfm80, meanOccPrimUnfm80 / meanOccNTrackTPCCUnfm80); - normalizeVector(vecOccNTrackITSTPCUnfm80, meanOccPrimUnfm80 / meanOccNTrackITSTPCUnfm80); - normalizeVector(vecOccNTrackITSTPCAUnfm80, meanOccPrimUnfm80 / meanOccNTrackITSTPCAUnfm80); - normalizeVector(vecOccNTrackITSTPCCUnfm80, meanOccPrimUnfm80 / meanOccNTrackITSTPCCUnfm80); - - normalizeVector(vecOccMultNTracksHasITSUnfm80, meanOccPrimUnfm80 / meanOccMultNTracksHasITSUnfm80); - normalizeVector(vecOccMultNTracksHasTPCUnfm80, meanOccPrimUnfm80 / meanOccMultNTracksHasTPCUnfm80); - normalizeVector(vecOccMultNTracksHasTOFUnfm80, meanOccPrimUnfm80 / meanOccMultNTracksHasTOFUnfm80); - normalizeVector(vecOccMultNTracksHasTRDUnfm80, meanOccPrimUnfm80 / meanOccMultNTracksHasTRDUnfm80); - normalizeVector(vecOccMultNTracksITSOnlyUnfm80, meanOccPrimUnfm80 / meanOccMultNTracksITSOnlyUnfm80); - normalizeVector(vecOccMultNTracksTPCOnlyUnfm80, meanOccPrimUnfm80 / meanOccMultNTracksTPCOnlyUnfm80); - normalizeVector(vecOccMultNTracksITSTPCUnfm80, meanOccPrimUnfm80 / meanOccMultNTracksITSTPCUnfm80); - normalizeVector(vecOccMultAllTracksTPCOnlyUnfm80, meanOccPrimUnfm80 / meanOccMultAllTracksTPCOnlyUnfm80); - - // Find Robust estimators - // T0A, T0C, V0A, Prim - getMedianOccVect(vecRobustOccT0V0PrimUnfm80, vecRobustOccT0V0PrimUnfm80medianPosVec, - vecOccPrimUnfm80, vecOccFV0AUnfm80, vecOccFT0AUnfm80, vecOccFT0CUnfm80); - - // T0A, T0C, V0A, FDD, Prim - getMedianOccVect(vecRobustOccFDDT0V0PrimUnfm80, vecRobustOccFDDT0V0PrimUnfm80medianPosVec, - vecOccPrimUnfm80, vecOccFV0AUnfm80, vecOccFT0AUnfm80, vecOccFT0CUnfm80, vecOccFDDAUnfm80, vecOccFDDCUnfm80); - - // NTrackDet - getMedianOccVect(vecRobustOccNtrackDetUnfm80, vecRobustOccNtrackDetUnfm80medianPosVec, - vecOccNTrackITSUnfm80, vecOccNTrackTPCUnfm80, vecOccNTrackTRDUnfm80, vecOccNTrackTOFUnfm80); - - // multExtraTable - getMedianOccVect(vecRobustOccmultTableUnfm80, vecRobustOccmultTableUnfm80medianPosVec, - vecOccPrimUnfm80, vecOccMultNTracksHasITSUnfm80, vecOccMultNTracksHasTPCUnfm80, - vecOccMultNTracksHasTOFUnfm80, vecOccMultNTracksHasTRDUnfm80, vecOccMultNTracksITSOnlyUnfm80, - vecOccMultNTracksTPCOnlyUnfm80, vecOccMultNTracksITSTPCUnfm80, vecOccMultAllTracksTPCOnlyUnfm80, - vecOccNTrackITSTPCUnfm80); - - for (const auto& vec : vecRobustOccT0V0PrimUnfm80medianPosVec) { - recoEvent.fill(HIST("h_RO_T0V0PrimUnfm80"), vec[0]); - recoEvent.fill(HIST("h_RO_T0V0PrimUnfm80"), vec[1]); + // + if (totalBCcountSize != collisions.size()) { + LOG(debug) << "DEBUG :: ERROR :: filled TF list and collision size mismatch :: filledTF_Size = " << totalBCcountSize << " != " << collisions.size() << " = collisions.size()"; } - for (const auto& vec : vecRobustOccFDDT0V0PrimUnfm80medianPosVec) { - recoEvent.fill(HIST("h_RO_FDDT0V0PrimUnfm80"), vec[0]); - recoEvent.fill(HIST("h_RO_FDDT0V0PrimUnfm80"), vec[1]); - } + // Fill the Producers + for (uint i = 0; i < tfCounted; i++) { - for (const auto& vec : vecRobustOccNtrackDetUnfm80medianPosVec) { - recoEvent.fill(HIST("h_RO_NtrackDetUnfm80"), vec[0]); - recoEvent.fill(HIST("h_RO_NtrackDetUnfm80"), vec[1]); - } + genOccsBCsList(tfList[i], bcTFMap[i]); - for (const auto& vec : vecRobustOccmultTableUnfm80medianPosVec) { - recoEvent.fill(HIST("h_RO_multTableUnfm80"), vec[0]); - recoEvent.fill(HIST("h_RO_multTableUnfm80"), vec[1]); - } + auto& vecOccPrimUnfm80 = occPrimUnfm80[i]; + float meanOccPrimUnfm80 = TMath::Mean(vecOccPrimUnfm80.size(), vecOccPrimUnfm80.data()); + normalizeVector(vecOccPrimUnfm80, meanOccPrimUnfm80 / meanOccPrimUnfm80); - genOccsBCsList(tfList[i], bcTFMap[i]); + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccPrim || processMode == kProcessOnlyOccT0V0Prim || processMode == kProcessOnlyOccFDDT0V0Prim || processMode == kProcessOnlyOccNtrackDet || processMode == kProcessOnlyOccMultExtra) { + if constexpr (tableMode == fillOccTable) { + genOccsPrim(vecOccPrimUnfm80); + } + if constexpr (meanTableMode == fillMeanOccTable) { + genOccsMeanPrim(meanOccPrimUnfm80); + } + } - if (buildOccsDet) { - genOccsDet(vecOccPrimUnfm80, - vecOccFV0AUnfm80, vecOccFV0CUnfm80, - vecOccFT0AUnfm80, vecOccFT0CUnfm80, - vecOccFDDAUnfm80, vecOccFDDCUnfm80); - } - if (buildOccsTrackMult) { - genOccsTrackMult(vecOccNTrackITSUnfm80, vecOccNTrackTPCUnfm80, - vecOccNTrackTRDUnfm80, vecOccNTrackTOFUnfm80, - vecOccNTrackSizeUnfm80, vecOccNTrackTPCAUnfm80, - vecOccNTrackTPCCUnfm80, vecOccNTrackITSTPCUnfm80, - vecOccNTrackITSTPCAUnfm80, vecOccNTrackITSTPCCUnfm80); - } - if (buildOccsMultExtra) { - genOccsMultExtra(vecOccMultNTracksHasITSUnfm80, vecOccMultNTracksHasTPCUnfm80, - vecOccMultNTracksHasTOFUnfm80, vecOccMultNTracksHasTRDUnfm80, - vecOccMultNTracksITSOnlyUnfm80, vecOccMultNTracksTPCOnlyUnfm80, - vecOccMultNTracksITSTPCUnfm80, vecOccMultAllTracksTPCOnlyUnfm80); - } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccT0V0Prim || processMode == kProcessOnlyOccFDDT0V0Prim) { + auto& vecOccFV0AUnfm80 = occFV0AUnfm80[i]; + auto& vecOccFV0CUnfm80 = occFV0CUnfm80[i]; + auto& vecOccFT0AUnfm80 = occFT0AUnfm80[i]; + auto& vecOccFT0CUnfm80 = occFT0CUnfm80[i]; + + float meanOccFV0AUnfm80 = TMath::Mean(vecOccFV0AUnfm80.size(), vecOccFV0AUnfm80.data()); + float meanOccFV0CUnfm80 = TMath::Mean(vecOccFV0CUnfm80.size(), vecOccFV0CUnfm80.data()); + float meanOccFT0AUnfm80 = TMath::Mean(vecOccFT0AUnfm80.size(), vecOccFT0AUnfm80.data()); + float meanOccFT0CUnfm80 = TMath::Mean(vecOccFT0CUnfm80.size(), vecOccFT0CUnfm80.data()); + + // Normalise the original vectors + normalizeVector(vecOccFV0AUnfm80, meanOccPrimUnfm80 / meanOccFV0AUnfm80); + normalizeVector(vecOccFV0CUnfm80, meanOccPrimUnfm80 / meanOccFV0CUnfm80); + normalizeVector(vecOccFT0AUnfm80, meanOccPrimUnfm80 / meanOccFT0AUnfm80); + normalizeVector(vecOccFT0CUnfm80, meanOccPrimUnfm80 / meanOccFT0CUnfm80); + + // Find Robust estimators + // T0A, T0C, V0A, Prim + if constexpr (robustTableMode == fillOccRobustTable || meanRobustTableMode == fillOccMeanRobustTable) { + getMedianOccVect(vecRobustOccT0V0PrimUnfm80, vecRobustOccT0V0PrimUnfm80medianPosVec, + vecOccPrimUnfm80, vecOccFV0AUnfm80, vecOccFT0AUnfm80, vecOccFT0CUnfm80); + for (const auto& vec : vecRobustOccT0V0PrimUnfm80medianPosVec) { + recoEvent.fill(HIST("h_RO_T0V0PrimUnfm80"), vec[0]); + recoEvent.fill(HIST("h_RO_T0V0PrimUnfm80"), vec[1]); + } + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccT0V0Prim || processMode == kProcessOnlyOccFDDT0V0Prim) { + if constexpr (tableMode == fillOccTable) { + genOccsT0V0(vecOccFV0AUnfm80, vecOccFV0CUnfm80, vecOccFT0AUnfm80, vecOccFT0CUnfm80); + } + if constexpr (meanTableMode == fillMeanOccTable) { + genOccsMeanT0V0(meanOccFV0AUnfm80, meanOccFV0CUnfm80, meanOccFT0AUnfm80, meanOccFT0CUnfm80); + } + if constexpr (robustTableMode == fillOccRobustTable) { + genORT0V0Prim(vecRobustOccT0V0PrimUnfm80); + } + if constexpr (meanRobustTableMode == fillOccMeanRobustTable) { + genOccsMeanRobustT0V0Prim(TMath::Mean(vecRobustOccT0V0PrimUnfm80.size(), vecRobustOccT0V0PrimUnfm80.data())); + } + + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccFDDT0V0Prim) { + auto& vecOccFDDAUnfm80 = occFDDAUnfm80[i]; + auto& vecOccFDDCUnfm80 = occFDDCUnfm80[i]; + float meanOccFDDAUnfm80 = TMath::Mean(vecOccFDDAUnfm80.size(), vecOccFDDAUnfm80.data()); + float meanOccFDDCUnfm80 = TMath::Mean(vecOccFDDCUnfm80.size(), vecOccFDDCUnfm80.data()); + normalizeVector(vecOccFDDAUnfm80, meanOccPrimUnfm80 / meanOccFDDAUnfm80); + normalizeVector(vecOccFDDCUnfm80, meanOccPrimUnfm80 / meanOccFDDCUnfm80); + + // T0A, T0C, V0A, FDD, Prim + if constexpr (robustTableMode == fillOccRobustTable || meanRobustTableMode == fillOccMeanRobustTable) { + getMedianOccVect(vecRobustOccFDDT0V0PrimUnfm80, vecRobustOccFDDT0V0PrimUnfm80medianPosVec, + vecOccPrimUnfm80, vecOccFV0AUnfm80, vecOccFT0AUnfm80, vecOccFT0CUnfm80, vecOccFDDAUnfm80, vecOccFDDCUnfm80); + for (const auto& vec : vecRobustOccFDDT0V0PrimUnfm80medianPosVec) { + recoEvent.fill(HIST("h_RO_FDDT0V0PrimUnfm80"), vec[0]); + recoEvent.fill(HIST("h_RO_FDDT0V0PrimUnfm80"), vec[1]); + } + + if constexpr (tableMode == fillOccTable) { + genOccsFDD(vecOccFDDAUnfm80, vecOccFDDCUnfm80); + } + if constexpr (meanTableMode == fillMeanOccTable) { + genOccsMeanFDD(meanOccFDDAUnfm80, meanOccFDDCUnfm80); + } + if constexpr (robustTableMode == fillOccRobustTable) { + genORFDDT0V0Prim(vecRobustOccFDDT0V0PrimUnfm80); + } + if constexpr (meanRobustTableMode == fillOccMeanRobustTable) { + genOccsMeanRobustFDDT0V0Prim(TMath::Mean(vecRobustOccFDDT0V0PrimUnfm80.size(), vecRobustOccFDDT0V0PrimUnfm80.data())); + } + } + } // Block for FDDT0V0Prim + } // For T0V0Prim only and FDDT0V0Prim + } // Detector Occupancy block + + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccNtrackDet) { + // NTrackDet + auto& vecOccNTrackITSUnfm80 = occNTrackITSUnfm80[i]; + auto& vecOccNTrackTPCUnfm80 = occNTrackTPCUnfm80[i]; + auto& vecOccNTrackTRDUnfm80 = occNTrackTRDUnfm80[i]; + auto& vecOccNTrackTOFUnfm80 = occNTrackTOFUnfm80[i]; + auto& vecOccNTrackSizeUnfm80 = occNTrackSizeUnfm80[i]; + auto& vecOccNTrackTPCAUnfm80 = occNTrackTPCAUnfm80[i]; + auto& vecOccNTrackTPCCUnfm80 = occNTrackTPCCUnfm80[i]; + auto& vecOccNTrackITSTPCUnfm80 = occNTrackITSTPCUnfm80[i]; + auto& vecOccNTrackITSTPCAUnfm80 = occNTrackITSTPCAUnfm80[i]; + auto& vecOccNTrackITSTPCCUnfm80 = occNTrackITSTPCCUnfm80[i]; + float meanOccNTrackITSUnfm80 = TMath::Mean(vecOccNTrackITSUnfm80.size(), vecOccNTrackITSUnfm80.data()); + float meanOccNTrackTPCUnfm80 = TMath::Mean(vecOccNTrackTPCUnfm80.size(), vecOccNTrackTPCUnfm80.data()); + float meanOccNTrackTRDUnfm80 = TMath::Mean(vecOccNTrackTRDUnfm80.size(), vecOccNTrackTRDUnfm80.data()); + float meanOccNTrackTOFUnfm80 = TMath::Mean(vecOccNTrackTOFUnfm80.size(), vecOccNTrackTOFUnfm80.data()); + float meanOccNTrackSizeUnfm80 = TMath::Mean(vecOccNTrackSizeUnfm80.size(), vecOccNTrackSizeUnfm80.data()); + float meanOccNTrackTPCAUnfm80 = TMath::Mean(vecOccNTrackTPCAUnfm80.size(), vecOccNTrackTPCAUnfm80.data()); + float meanOccNTrackTPCCUnfm80 = TMath::Mean(vecOccNTrackTPCCUnfm80.size(), vecOccNTrackTPCCUnfm80.data()); + float meanOccNTrackITSTPCUnfm80 = TMath::Mean(vecOccNTrackITSTPCUnfm80.size(), vecOccNTrackITSTPCUnfm80.data()); + float meanOccNTrackITSTPCAUnfm80 = TMath::Mean(vecOccNTrackITSTPCAUnfm80.size(), vecOccNTrackITSTPCAUnfm80.data()); + float meanOccNTrackITSTPCCUnfm80 = TMath::Mean(vecOccNTrackITSTPCCUnfm80.size(), vecOccNTrackITSTPCCUnfm80.data()); + + normalizeVector(vecOccNTrackITSUnfm80, meanOccPrimUnfm80 / meanOccNTrackITSUnfm80); + normalizeVector(vecOccNTrackTPCUnfm80, meanOccPrimUnfm80 / meanOccNTrackTPCUnfm80); + normalizeVector(vecOccNTrackTRDUnfm80, meanOccPrimUnfm80 / meanOccNTrackTRDUnfm80); + normalizeVector(vecOccNTrackTOFUnfm80, meanOccPrimUnfm80 / meanOccNTrackTOFUnfm80); + normalizeVector(vecOccNTrackSizeUnfm80, meanOccPrimUnfm80 / meanOccNTrackSizeUnfm80); + normalizeVector(vecOccNTrackTPCAUnfm80, meanOccPrimUnfm80 / meanOccNTrackTPCAUnfm80); + normalizeVector(vecOccNTrackTPCCUnfm80, meanOccPrimUnfm80 / meanOccNTrackTPCCUnfm80); + normalizeVector(vecOccNTrackITSTPCUnfm80, meanOccPrimUnfm80 / meanOccNTrackITSTPCUnfm80); + normalizeVector(vecOccNTrackITSTPCAUnfm80, meanOccPrimUnfm80 / meanOccNTrackITSTPCAUnfm80); + normalizeVector(vecOccNTrackITSTPCCUnfm80, meanOccPrimUnfm80 / meanOccNTrackITSTPCCUnfm80); + + if constexpr (robustTableMode == fillOccRobustTable || meanRobustTableMode == fillOccMeanRobustTable) { + getMedianOccVect(vecRobustOccNtrackDetUnfm80, vecRobustOccNtrackDetUnfm80medianPosVec, + vecOccNTrackITSUnfm80, vecOccNTrackTPCUnfm80, vecOccNTrackTRDUnfm80, vecOccNTrackTOFUnfm80); + for (const auto& vec : vecRobustOccNtrackDetUnfm80medianPosVec) { + recoEvent.fill(HIST("h_RO_NtrackDetUnfm80"), vec[0]); + recoEvent.fill(HIST("h_RO_NtrackDetUnfm80"), vec[1]); + } + } - if (buildOccsRobust) { - genOccsRobust(vecRobustOccT0V0PrimUnfm80, vecRobustOccFDDT0V0PrimUnfm80, vecRobustOccNtrackDetUnfm80, vecRobustOccmultTableUnfm80); - } - if (buildOccsMeanDet) { - genOccsMeanDet(meanOccPrimUnfm80, - meanOccFV0AUnfm80, meanOccFV0CUnfm80, - meanOccFT0AUnfm80, meanOccFT0CUnfm80, - meanOccFDDAUnfm80, meanOccFDDCUnfm80); - } + if constexpr (tableMode == fillOccTable) { + genOccsNTrackDet(vecOccNTrackITSUnfm80, vecOccNTrackTPCUnfm80, + vecOccNTrackTRDUnfm80, vecOccNTrackTOFUnfm80, + vecOccNTrackSizeUnfm80, vecOccNTrackTPCAUnfm80, + vecOccNTrackTPCCUnfm80, vecOccNTrackITSTPCUnfm80, + vecOccNTrackITSTPCAUnfm80, vecOccNTrackITSTPCCUnfm80); + } + if constexpr (meanTableMode == fillMeanOccTable) { + genOccsMeanNTrkDet(meanOccNTrackITSUnfm80, meanOccNTrackTPCUnfm80, + meanOccNTrackTRDUnfm80, meanOccNTrackTOFUnfm80, + meanOccNTrackSizeUnfm80, meanOccNTrackTPCAUnfm80, + meanOccNTrackTPCCUnfm80, meanOccNTrackITSTPCUnfm80, + meanOccNTrackITSTPCAUnfm80, meanOccNTrackITSTPCCUnfm80); + } + if constexpr (robustTableMode == fillOccRobustTable) { + genORNtrackDet(vecRobustOccNtrackDetUnfm80); + } + if constexpr (meanRobustTableMode == fillOccMeanRobustTable) { + genOccsMeanRobustNtrackDet(TMath::Mean(vecRobustOccNtrackDetUnfm80.size(), vecRobustOccNtrackDetUnfm80.data())); + } + } + + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccMultExtra) { + auto& vecOccNTrackITSTPCUnfm80 = occNTrackITSTPCUnfm80[i]; + float meanOccNTrackITSTPCUnfm80 = TMath::Mean(vecOccNTrackITSTPCUnfm80.size(), vecOccNTrackITSTPCUnfm80.data()); + normalizeVector(vecOccNTrackITSTPCUnfm80, meanOccPrimUnfm80 / meanOccNTrackITSTPCUnfm80); + + auto& vecOccMultNTracksHasITSUnfm80 = occMultNTracksHasITSUnfm80[i]; + auto& vecOccMultNTracksHasTPCUnfm80 = occMultNTracksHasTPCUnfm80[i]; + auto& vecOccMultNTracksHasTOFUnfm80 = occMultNTracksHasTOFUnfm80[i]; + auto& vecOccMultNTracksHasTRDUnfm80 = occMultNTracksHasTRDUnfm80[i]; + auto& vecOccMultNTracksITSOnlyUnfm80 = occMultNTracksITSOnlyUnfm80[i]; + auto& vecOccMultNTracksTPCOnlyUnfm80 = occMultNTracksTPCOnlyUnfm80[i]; + auto& vecOccMultNTracksITSTPCUnfm80 = occMultNTracksITSTPCUnfm80[i]; + auto& vecOccMultAllTracksTPCOnlyUnfm80 = occMultAllTracksTPCOnlyUnfm80[i]; + float meanOccMultNTracksHasITSUnfm80 = TMath::Mean(vecOccMultNTracksHasITSUnfm80.size(), vecOccMultNTracksHasITSUnfm80.data()); + float meanOccMultNTracksHasTPCUnfm80 = TMath::Mean(vecOccMultNTracksHasTPCUnfm80.size(), vecOccMultNTracksHasTPCUnfm80.data()); + float meanOccMultNTracksHasTOFUnfm80 = TMath::Mean(vecOccMultNTracksHasTOFUnfm80.size(), vecOccMultNTracksHasTOFUnfm80.data()); + float meanOccMultNTracksHasTRDUnfm80 = TMath::Mean(vecOccMultNTracksHasTRDUnfm80.size(), vecOccMultNTracksHasTRDUnfm80.data()); + float meanOccMultNTracksITSOnlyUnfm80 = TMath::Mean(vecOccMultNTracksITSOnlyUnfm80.size(), vecOccMultNTracksITSOnlyUnfm80.data()); + float meanOccMultNTracksTPCOnlyUnfm80 = TMath::Mean(vecOccMultNTracksTPCOnlyUnfm80.size(), vecOccMultNTracksTPCOnlyUnfm80.data()); + float meanOccMultNTracksITSTPCUnfm80 = TMath::Mean(vecOccMultNTracksITSTPCUnfm80.size(), vecOccMultNTracksITSTPCUnfm80.data()); + float meanOccMultAllTracksTPCOnlyUnfm80 = TMath::Mean(vecOccMultAllTracksTPCOnlyUnfm80.size(), vecOccMultAllTracksTPCOnlyUnfm80.data()); + // multExtraTable + normalizeVector(vecOccMultNTracksHasITSUnfm80, meanOccPrimUnfm80 / meanOccMultNTracksHasITSUnfm80); + normalizeVector(vecOccMultNTracksHasTPCUnfm80, meanOccPrimUnfm80 / meanOccMultNTracksHasTPCUnfm80); + normalizeVector(vecOccMultNTracksHasTOFUnfm80, meanOccPrimUnfm80 / meanOccMultNTracksHasTOFUnfm80); + normalizeVector(vecOccMultNTracksHasTRDUnfm80, meanOccPrimUnfm80 / meanOccMultNTracksHasTRDUnfm80); + normalizeVector(vecOccMultNTracksITSOnlyUnfm80, meanOccPrimUnfm80 / meanOccMultNTracksITSOnlyUnfm80); + normalizeVector(vecOccMultNTracksTPCOnlyUnfm80, meanOccPrimUnfm80 / meanOccMultNTracksTPCOnlyUnfm80); + normalizeVector(vecOccMultNTracksITSTPCUnfm80, meanOccPrimUnfm80 / meanOccMultNTracksITSTPCUnfm80); + normalizeVector(vecOccMultAllTracksTPCOnlyUnfm80, meanOccPrimUnfm80 / meanOccMultAllTracksTPCOnlyUnfm80); + + if constexpr (robustTableMode == fillOccRobustTable || meanRobustTableMode == fillOccMeanRobustTable) { + getMedianOccVect(vecRobustOccmultTableUnfm80, vecRobustOccmultTableUnfm80medianPosVec, + vecOccPrimUnfm80, vecOccMultNTracksHasITSUnfm80, vecOccMultNTracksHasTPCUnfm80, + vecOccMultNTracksHasTOFUnfm80, vecOccMultNTracksHasTRDUnfm80, vecOccMultNTracksITSOnlyUnfm80, + vecOccMultNTracksTPCOnlyUnfm80, vecOccMultNTracksITSTPCUnfm80, vecOccMultAllTracksTPCOnlyUnfm80, + vecOccNTrackITSTPCUnfm80); + for (const auto& vec : vecRobustOccmultTableUnfm80medianPosVec) { + recoEvent.fill(HIST("h_RO_multTableUnfm80"), vec[0]); + recoEvent.fill(HIST("h_RO_multTableUnfm80"), vec[1]); + } + } - if (buildOccsMeanTrkMult) { - genOccsMeanTrkMult(meanOccNTrackITSUnfm80, - meanOccNTrackTPCUnfm80, - meanOccNTrackTRDUnfm80, - meanOccNTrackTOFUnfm80, - meanOccNTrackSizeUnfm80, - meanOccNTrackTPCAUnfm80, - meanOccNTrackTPCCUnfm80, - meanOccNTrackITSTPCUnfm80, - meanOccNTrackITSTPCAUnfm80, - meanOccNTrackITSTPCCUnfm80); + if constexpr (tableMode == fillOccTable) { + genOccsMultExtra(vecOccMultNTracksHasITSUnfm80, vecOccMultNTracksHasTPCUnfm80, + vecOccMultNTracksHasTOFUnfm80, vecOccMultNTracksHasTRDUnfm80, + vecOccMultNTracksITSOnlyUnfm80, vecOccMultNTracksTPCOnlyUnfm80, + vecOccMultNTracksITSTPCUnfm80, vecOccMultAllTracksTPCOnlyUnfm80); + } + if constexpr (meanTableMode == fillMeanOccTable) { + genOccsMnMultExtra(meanOccMultNTracksHasITSUnfm80, meanOccMultNTracksHasTPCUnfm80, + meanOccMultNTracksHasTOFUnfm80, meanOccMultNTracksHasTRDUnfm80, + meanOccMultNTracksITSOnlyUnfm80, meanOccMultNTracksTPCOnlyUnfm80, + meanOccMultNTracksITSTPCUnfm80, meanOccMultAllTracksTPCOnlyUnfm80); + } + if constexpr (robustTableMode == fillOccRobustTable) { + genORMultExtra(vecRobustOccmultTableUnfm80); + } + if constexpr (meanRobustTableMode == fillOccMeanRobustTable) { + genOccsMeanRobustMultExtraTable(TMath::Mean(vecRobustOccmultTableUnfm80.size(), vecRobustOccmultTableUnfm80.data())); + } + } } - if (buildOccsMnMultExtra) { - genOccsMnMultExtra(meanOccMultNTracksHasITSUnfm80, meanOccMultNTracksHasTPCUnfm80, - meanOccMultNTracksHasTOFUnfm80, meanOccMultNTracksHasTRDUnfm80, - meanOccMultNTracksITSOnlyUnfm80, meanOccMultNTracksTPCOnlyUnfm80, - meanOccMultNTracksITSTPCUnfm80, meanOccMultAllTracksTPCOnlyUnfm80); + // Create a BC index table. + int64_t occIDX = -1; + int idx = -1; + for (auto const& bc : BCs) { + idx = -1; + getTimingInfo(bc, lastRun, nBCsPerTF, bcSOR, time, tfIdThis, bcInTF); + + auto idxIt = std::find(tfList.begin(), tfList.end(), tfIdThis); + if (idxIt != tfList.end()) { + idx = std::distance(tfList.begin(), idxIt); + } else { + LOG(error) << "DEBUG :: SEVERE :: BC Timeframe not in the list"; + } + + auto it = std::find(bcTFMap[idx].begin(), bcTFMap[idx].end(), bc.globalIndex()); // will find the iterator where object is placed. + if (it != bcTFMap[idx].end()) { + occIDX = idx; // Element is in the vector + } else { + occIDX = -1; // Element is not in the vector + } + + genBCTFinfoTable(tfIdThis, bcInTF); + genOccIndexTable(bc.globalIndex(), occIDX); // BCId, OccId } + } // else block for constexpr + } - if (buildOccsMeanRobust) { - genOccsMeanRobust( - TMath::Mean(vecRobustOccT0V0PrimUnfm80.size(), vecRobustOccT0V0PrimUnfm80.data()), - TMath::Mean(vecRobustOccFDDT0V0PrimUnfm80.size(), vecRobustOccFDDT0V0PrimUnfm80.data()), - TMath::Mean(vecRobustOccNtrackDetUnfm80.size(), vecRobustOccNtrackDetUnfm80.data()), - TMath::Mean(vecRobustOccmultTableUnfm80.size(), vecRobustOccmultTableUnfm80.data())); + void checkAllProcessFunctionStatus(std::vector const& processStatusVector, bool& singleProcessOn) + { + int nProcessOn = 0; + const uint size = processStatusVector.size(); + for (uint i = 0; i < size; i++) { + if (processStatusVector[i]) { + nProcessOn++; } } - // Create a BC index table. - int64_t occIDX = -1; - int idx = -1; - for (auto const& bc : BCs) { - idx = -1; - getTimingInfo(bc, lastRun, nBCsPerTF, bcSOR, time, tfIdThis, bcInTF); - - auto idxIt = std::find(tfList.begin(), tfList.end(), tfIdThis); - if (idxIt != tfList.end()) { - idx = std::distance(tfList.begin(), idxIt); - } else { - LOG(error) << "DEBUG :: SEVERE :: BC Timeframe not in the list"; + if (nProcessOn > 1) { + singleProcessOn = false; + std::ostringstream warningLine; + warningLine << "DEBUG :: More than one track-mean-occ-table-producer process function is on :: "; + for (uint i = 0; i < size; i++) { + if (processStatusVector[i]) { + warningLine << std::string(ProcessNames[processStatusVector[i]]) << " == true :: "; + } } + LOG(error) << warningLine.str(); + } // check nProcess + } - auto it = std::find(bcTFMap[idx].begin(), bcTFMap[idx].end(), bc.globalIndex()); // will find the iterator where object is placed. - if (it != bcTFMap[idx].end()) { - occIDX = idx; // Element is in the vector - } else { - occIDX = -1; // Element is not in the vector - } + //________________________________________End of Exection Function_________________________________________________________________________ + + void processOnlyBCTFinfoTable(o2::aod::BCsWithTimestamps const& BCs) + { + occupancyQA.fill(HIST("h_DFcount_Lvl0"), 0.5); + processStatus[kProcessOnlyBCTFinfoTable] = true; + bool singleProcessOn = true; + checkAllProcessFunctionStatus(processStatus, singleProcessOn); + if (!singleProcessOn) { + return; + } - genOccIndexTable(bc.globalIndex(), occIDX); // BCId, OccId + for (const auto& BC : BCs) { + getTimingInfo(BC, lastRun, nBCsPerTF, bcSOR, time, tfIdThis, bcInTF); genBCTFinfoTable(tfIdThis, bcInTF); } + occupancyQA.fill(HIST("h_DFcount_Lvl1"), 0.5); + } + PROCESS_SWITCH(OccupancyTableProducer, processOnlyBCTFinfoTable, "processOnlyBCTFinfoTable", true); + + // // Process the Data + void processOnlyOccPrimUnfm(o2::aod::BCsWithTimestamps const& BCs, aod::Collisions const& collisions) + { + occupancyQA.fill(HIST("h_DFcount_Lvl0"), 0.5); + if (!buildOnlyOccsPrim) { + LOG(error) << " DEBUG :: ERROR ERROR ERROR :: buildOnlyOccsPrim == false"; + } + processStatus[kProcessOnlyOccPrim] = true; + bool singleProcessOn = true; + checkAllProcessFunctionStatus(processStatus, singleProcessOn); + if (!singleProcessOn) { + return; + } + + bool collisionsSizeIsZero = false; + executeCollisionCheckAndBCprocessing(BCs, collisions, collisionsSizeIsZero); + if (collisionsSizeIsZero) { + return; + } + executeOccProducerProcessing(BCs, collisions, nullptr); + occupancyQA.fill(HIST("h_DFcount_Lvl1"), 0.5); + } + PROCESS_SWITCH(OccupancyTableProducer, processOnlyOccPrimUnfm, "processOnlyOccPrimUnfm", false); + + void processOnlyOccT0V0PrimUnfm(o2::aod::BCsWithTimestamps const& BCs, soa::Join const& collisions) + { + occupancyQA.fill(HIST("h_DFcount_Lvl0"), 0.5); + if (!buildOnlyOccsT0V0Prim) { + LOG(error) << " DEBUG :: ERROR ERROR ERROR :: buildOnlyOccsT0V0Prim == false"; + } + processStatus[kProcessOnlyOccT0V0Prim] = true; + bool singleProcessOn = true; + checkAllProcessFunctionStatus(processStatus, singleProcessOn); + if (!singleProcessOn) { + return; + } + + bool collisionsSizeIsZero = false; + executeCollisionCheckAndBCprocessing(BCs, collisions, collisionsSizeIsZero); + if (collisionsSizeIsZero) { + return; + } + executeOccProducerProcessing(BCs, collisions, nullptr); + occupancyQA.fill(HIST("h_DFcount_Lvl1"), 0.5); + } + PROCESS_SWITCH(OccupancyTableProducer, processOnlyOccT0V0PrimUnfm, "processOnlyOccT0V0PrimUnfm", false); + + void processOnlyOccFDDT0V0PrimUnfm(o2::aod::BCsWithTimestamps const& BCs, soa::Join const& collisions) + { + occupancyQA.fill(HIST("h_DFcount_Lvl0"), 0.5); + if (!buildOnlyOccsFDDT0V0Prim) { + LOG(error) << " DEBUG :: ERROR ERROR ERROR :: buildOnlyOccsFDDT0V0Prim == false"; + } + processStatus[kProcessOnlyOccFDDT0V0Prim] = true; + bool singleProcessOn = true; + checkAllProcessFunctionStatus(processStatus, singleProcessOn); + if (!singleProcessOn) { + return; + } + + bool collisionsSizeIsZero = false; + executeCollisionCheckAndBCprocessing(BCs, collisions, collisionsSizeIsZero); + if (collisionsSizeIsZero) { + return; + } + executeOccProducerProcessing(BCs, collisions, nullptr); + occupancyQA.fill(HIST("h_DFcount_Lvl1"), 0.5); + } + PROCESS_SWITCH(OccupancyTableProducer, processOnlyOccFDDT0V0PrimUnfm, "processOnlyOccFDDT0V0PrimUnfm", false); + + void processOnlyOccNtrackDet(o2::aod::BCsWithTimestamps const& BCs, soa::Join const& collisions, soa::Join const& tracks) + { + occupancyQA.fill(HIST("h_DFcount_Lvl0"), 0.5); + if (!buildOnlyOccsNtrackDet) { + LOG(error) << " DEBUG :: ERROR ERROR ERROR :: buildOnlyOccsNtrackDet == false"; + } + processStatus[kProcessOnlyOccNtrackDet] = true; + bool singleProcessOn = true; + checkAllProcessFunctionStatus(processStatus, singleProcessOn); + if (!singleProcessOn) { + return; + } + + bool collisionsSizeIsZero = false; + executeCollisionCheckAndBCprocessing(BCs, collisions, collisionsSizeIsZero); + if (collisionsSizeIsZero) { + return; + } + executeOccProducerProcessing(BCs, collisions, tracks); + occupancyQA.fill(HIST("h_DFcount_Lvl1"), 0.5); + } + PROCESS_SWITCH(OccupancyTableProducer, processOnlyOccNtrackDet, "processOnlyOccNtrackDet", false); + + void processOnlyOccMultExtra(o2::aod::BCsWithTimestamps const& BCs, soa::Join const& collisions) + { + occupancyQA.fill(HIST("h_DFcount_Lvl0"), 0.5); + if (!buildOnlyOccsMultExtra) { + LOG(error) << " DEBUG :: ERROR ERROR ERROR :: buildOnlyOccsMultExtra == false"; + } + processStatus[kProcessOnlyOccMultExtra] = true; + bool singleProcessOn = true; + checkAllProcessFunctionStatus(processStatus, singleProcessOn); + if (!singleProcessOn) { + return; + } + + bool collisionsSizeIsZero = false; + executeCollisionCheckAndBCprocessing(BCs, collisions, collisionsSizeIsZero); + if (collisionsSizeIsZero) { + return; + } + executeOccProducerProcessing(BCs, collisions, nullptr); + occupancyQA.fill(HIST("h_DFcount_Lvl1"), 0.5); + } + PROCESS_SWITCH(OccupancyTableProducer, processOnlyOccMultExtra, "processOnlyOccMultExtra", false); + + void processFullOccTableProduer(o2::aod::BCsWithTimestamps const& BCs, soa::Join const& collisions, soa::Join const& tracks) + { + occupancyQA.fill(HIST("h_DFcount_Lvl0"), 0.5); + if (!buildFullOccTableProducer) { + LOG(error) << " DEBUG :: ERROR ERROR ERROR :: buildFullOccTableProducer == false"; + } + processStatus[kProcessFullOccTableProducer] = true; + bool singleProcessOn = true; + checkAllProcessFunctionStatus(processStatus, singleProcessOn); + if (!singleProcessOn) { + return; + } + + bool collisionsSizeIsZero = false; + executeCollisionCheckAndBCprocessing(BCs, collisions, collisionsSizeIsZero); + if (collisionsSizeIsZero) { + return; + } + executeOccProducerProcessing(BCs, collisions, tracks); + occupancyQA.fill(HIST("h_DFcount_Lvl1"), 0.5); } // Process function ends + PROCESS_SWITCH(OccupancyTableProducer, processFullOccTableProduer, "processFullOccTableProduer", false); }; struct TrackMeanOccTableProducer { - Produces genTrackMeanOccs0; - Produces genTrackMeanOccs1; - Produces genTrackMeanOccs2; - Produces genTrackMeanOccs3; - Produces genTrackMeanOccs4; - Produces genTrackMeanOccs5; - Produces genTrackMeanOccs6; - Produces genTrackMeanOccs7; - Produces genTrackMeanOccs8; + + // //declare production of tables + Produces genTmoTrackId; + + Produces genTmoPrim; + Produces genTmoT0V0; + Produces genTmoFDD; + Produces genTmoNTrackDet; + Produces genTmoMultExtra; + Produces genTmoRT0V0Prim; + Produces genTmoRFDDT0V0Prim; + Produces genTmoRNtrackDet; + Produces genTmoRMultExtra; + + Produces genTwmoPrim; + Produces genTwmoT0V0; + Produces genTwmoFDD; + Produces genTwmoNTrackDet; + Produces genTwmoMultExtra; + Produces genTwmoRT0V0Prim; + Produces genTwmoRFDDT0V0Pri; + Produces genTwmoRNtrackDet; + Produces genTwmoRMultExtra; Service ccdb; @@ -729,25 +1236,40 @@ struct TrackMeanOccTableProducer { // Configurables Configurable customOrbitOffset{"customOrbitOffset", 0, "customOrbitOffset for MC"}; + Configurable bcGrouping{"bcGrouping", 80, "bcGrouping of BCs"}; + Configurable nBCinTF{"nBCinTF", 114048, "nBCinTF"}; + + Configurable cfgNOrbitsPerTF0RunValue{"cfgNOrbitsPerTF0RunValue", 534133, "cfgNOrbitsPerTF0RunValue"}; + Configurable cfgNOrbitsPerTF1TrueValue{"cfgNOrbitsPerTF1TrueValue", 128, "cfgNOrbitsPerTF1TrueValue"}; + Configurable cfgNOrbitsPerTF2FalseValue{"cfgNOrbitsPerTF2FalseValue", 32, "ccfgNOrbitsPerTF2FalseValue"}; - Configurable buildTrackMeanOccs1{"buildTrackMeanOccs1", true, "builder TrackMeanOccs1"}; - Configurable buildTrackMeanOccs2{"buildTrackMeanOccs2", true, "builder TrackMeanOccs2"}; - Configurable buildTrackMeanOccs3{"buildTrackMeanOccs3", true, "builder TrackMeanOccs3"}; - Configurable buildTrackMeanOccs4{"buildTrackMeanOccs4", true, "builder TrackMeanOccs4"}; - Configurable buildTrackMeanOccs5{"buildTrackMeanOccs5", true, "builder TrackMeanOccs5"}; - Configurable buildTrackMeanOccs6{"buildTrackMeanOccs6", true, "builder TrackMeanOccs6"}; - Configurable buildTrackMeanOccs7{"buildTrackMeanOccs7", true, "builder TrackMeanOccs7"}; - Configurable buildTrackMeanOccs8{"buildTrackMeanOccs8", true, "builder TrackMeanOccs8"}; + Configurable buildOnlyOccsPrim{"buildOnlyOccsPrim", true, "builder of table OccsPrim"}; + Configurable buildOnlyOccsT0V0{"buildOnlyOccsT0V0", true, "builder of table OccsT0V0Prim"}; + Configurable buildOnlyOccsFDD{"buildOnlyOccsFDD", true, "builder of table OccsFDDT0V0Prim"}; + Configurable buildOnlyOccsNtrackDet{"buildOnlyOccsNtrackDet", true, "builder of table OccsNtrackDet"}; + Configurable buildOnlyOccsMultExtra{"buildOnlyOccsMultExtra", true, "builder of table OccsMultExtra"}; - Configurable fillQA1{"fillQA1", false, "fill QA LOG Ratios"}; - Configurable fillQA2{"fillQA2", false, "fill QA condition dependent QAs"}; + Configurable buildOnlyOccsRobustT0V0Prim{"buildOnlyOccsRobustT0V0Prim", true, "build buildOnlyOccsRobustT0V0Prim"}; + Configurable buildOnlyOccsRobustFDDT0V0Prim{"buildOnlyOccsRobustFDDT0V0Prim", true, "build buildOnlyOccsRobustFDDT0V0Prim"}; + Configurable buildOnlyOccsRobustNtrackDet{"buildOnlyOccsRobustNtrackDet", true, "build buildOnlyOccsRobustNtrackDet"}; + Configurable buildOnlyOccsRobustMultExtra{"buildOnlyOccsRobustMultExtra", true, "build buildOnlyOccsRobustMultExtra"}; + + Configurable buildFullOccTableProducer{"buildFullOccTableProducer", true, "builder of all Occupancy Tables"}; + + Configurable buildFlag00MeanTable{"buildFlag00MeanTable", true, "build Flag00MeanTable"}; + Configurable buildFlag01WeightMeanTable{"buildFlag01WeightMeanTable", true, "build Flag01WeightMeanTable"}; + + Configurable fillQA1{"fillQA1", true, "fill QA LOG Ratios"}; + Configurable fillQA2{"fillQA2", true, "fill QA condition dependent QAs"}; // vectors to be used for occupancy estimation std::vector occPrimUnfm80; + std::vector occFV0AUnfm80; std::vector occFV0CUnfm80; std::vector occFT0AUnfm80; std::vector occFT0CUnfm80; + std::vector occFDDAUnfm80; std::vector occFDDCUnfm80; @@ -776,41 +1298,68 @@ struct TrackMeanOccTableProducer { std::vector occRobustNtrackDetUnfm80; std::vector occRobustMultTableUnfm80; + std::vector processStatus; + std::vector processInThisBlock; void init(InitContext const&) { // CCDB related part to be added later - occPrimUnfm80.resize(nBCinTF / 80); - occFV0AUnfm80.resize(nBCinTF / 80); - occFV0CUnfm80.resize(nBCinTF / 80); - occFT0AUnfm80.resize(nBCinTF / 80); - occFT0CUnfm80.resize(nBCinTF / 80); - occFDDAUnfm80.resize(nBCinTF / 80); - occFDDCUnfm80.resize(nBCinTF / 80); - - occNTrackITSUnfm80.resize(nBCinTF / 80); - occNTrackTPCUnfm80.resize(nBCinTF / 80); - occNTrackTRDUnfm80.resize(nBCinTF / 80); - occNTrackTOFUnfm80.resize(nBCinTF / 80); - occNTrackSizeUnfm80.resize(nBCinTF / 80); - occNTrackTPCAUnfm80.resize(nBCinTF / 80); - occNTrackTPCCUnfm80.resize(nBCinTF / 80); - occNTrackITSTPCUnfm80.resize(nBCinTF / 80); - occNTrackITSTPCAUnfm80.resize(nBCinTF / 80); - occNTrackITSTPCCUnfm80.resize(nBCinTF / 80); - - occMultNTracksHasITSUnfm80.resize(nBCinTF / 80); - occMultNTracksHasTPCUnfm80.resize(nBCinTF / 80); - occMultNTracksHasTOFUnfm80.resize(nBCinTF / 80); - occMultNTracksHasTRDUnfm80.resize(nBCinTF / 80); - occMultNTracksITSOnlyUnfm80.resize(nBCinTF / 80); - occMultNTracksTPCOnlyUnfm80.resize(nBCinTF / 80); - occMultNTracksITSTPCUnfm80.resize(nBCinTF / 80); - occMultAllTracksTPCOnlyUnfm80.resize(nBCinTF / 80); - - occRobustT0V0PrimUnfm80.resize(nBCinTF / 80); - occRobustFDDT0V0PrimUnfm80.resize(nBCinTF / 80); - occRobustNtrackDetUnfm80.resize(nBCinTF / 80); - occRobustMultTableUnfm80.resize(nBCinTF / 80); + processStatus.resize(11); + processInThisBlock.resize(11); + + for (uint i = 0; i < processStatus.size(); i++) { + processStatus[i] = false; + processInThisBlock[i] = false; + } + + if (buildFullOccTableProducer || buildOnlyOccsPrim) { + occPrimUnfm80.resize(nBCinTF / bcGrouping); + } + if (buildFullOccTableProducer || buildOnlyOccsT0V0) { + occFV0AUnfm80.resize(nBCinTF / bcGrouping); + occFV0CUnfm80.resize(nBCinTF / bcGrouping); + occFT0AUnfm80.resize(nBCinTF / bcGrouping); + occFT0CUnfm80.resize(nBCinTF / bcGrouping); + } + if (buildFullOccTableProducer || buildOnlyOccsFDD) { + occFDDAUnfm80.resize(nBCinTF / bcGrouping); + occFDDCUnfm80.resize(nBCinTF / bcGrouping); + } + if (buildFullOccTableProducer || buildOnlyOccsNtrackDet) { + occNTrackITSUnfm80.resize(nBCinTF / bcGrouping); + occNTrackTPCUnfm80.resize(nBCinTF / bcGrouping); + occNTrackTRDUnfm80.resize(nBCinTF / bcGrouping); + occNTrackTOFUnfm80.resize(nBCinTF / bcGrouping); + occNTrackSizeUnfm80.resize(nBCinTF / bcGrouping); + occNTrackTPCAUnfm80.resize(nBCinTF / bcGrouping); + occNTrackTPCCUnfm80.resize(nBCinTF / bcGrouping); + occNTrackITSTPCUnfm80.resize(nBCinTF / bcGrouping); + occNTrackITSTPCAUnfm80.resize(nBCinTF / bcGrouping); + occNTrackITSTPCCUnfm80.resize(nBCinTF / bcGrouping); + } + + if (buildFullOccTableProducer || buildOnlyOccsMultExtra) { + occMultNTracksHasITSUnfm80.resize(nBCinTF / bcGrouping); + occMultNTracksHasTPCUnfm80.resize(nBCinTF / bcGrouping); + occMultNTracksHasTOFUnfm80.resize(nBCinTF / bcGrouping); + occMultNTracksHasTRDUnfm80.resize(nBCinTF / bcGrouping); + occMultNTracksITSOnlyUnfm80.resize(nBCinTF / bcGrouping); + occMultNTracksTPCOnlyUnfm80.resize(nBCinTF / bcGrouping); + occMultNTracksITSTPCUnfm80.resize(nBCinTF / bcGrouping); + occMultAllTracksTPCOnlyUnfm80.resize(nBCinTF / bcGrouping); + } + + if (buildFullOccTableProducer || buildOnlyOccsRobustT0V0Prim || fillQA1 || fillQA2) { + occRobustT0V0PrimUnfm80.resize(nBCinTF / bcGrouping); + } + if (buildFullOccTableProducer || buildOnlyOccsRobustFDDT0V0Prim) { + occRobustFDDT0V0PrimUnfm80.resize(nBCinTF / bcGrouping); + } + if (buildFullOccTableProducer || buildOnlyOccsRobustNtrackDet) { + occRobustNtrackDetUnfm80.resize(nBCinTF / bcGrouping); + } + if (buildFullOccTableProducer || buildOnlyOccsRobustMultExtra) { + occRobustMultTableUnfm80.resize(nBCinTF / bcGrouping); + } const AxisSpec axisQA1 = {500, 0, 50000}; const AxisSpec axisQA2 = {200, -2, 2}; @@ -930,6 +1479,11 @@ struct TrackMeanOccTableProducer { occupancyQA.addClone("occTrackQA/Condition1/", "occTrackQA/Condition3/"); occupancyQA.addClone("occTrackQA/Condition1/", "occTrackQA/Condition4/"); } + + occupancyQA.add("h_DFcount_Lvl0", "h_DFcount_Lvl0", kTH1F, {{13, -1, 12}}); + occupancyQA.add("h_DFcount_Lvl1", "h_DFcount_Lvl1", kTH1F, {{13, -1, 12}}); + occupancyQA.add("h_DFcount_Lvl2", "h_DFcount_Lvl2", kTH1F, {{13, -1, 12}}); + occupancyQA.print(); } @@ -1031,7 +1585,7 @@ struct TrackMeanOccTableProducer { int64_t tsSOR = runDuration.first; auto ctpx = ccdb->getForTimeStamp>("CTP/Calib/OrbitReset", tsSOR); int64_t tsOrbitReset = (*ctpx)[0]; - uint32_t nOrbitsPerTF = run < 534133 ? 128 : 32; + uint32_t nOrbitsPerTF = run < cfgNOrbitsPerTF0RunValue ? cfgNOrbitsPerTF1TrueValue : cfgNOrbitsPerTF2FalseValue; int64_t orbitSOR = (tsSOR * 1000 - tsOrbitReset) / o2::constants::lhc::LHCOrbitMUS; orbitSOR = orbitSOR / nOrbitsPerTF * nOrbitsPerTF; bcSOR = orbitSOR * nBCsPerOrbit + customOrbitOffset * nBCsPerOrbit; // customOrbitOffset is a configurable @@ -1120,16 +1674,17 @@ struct TrackMeanOccTableProducer { if (fillQA1) { occupancyQA.fill(HIST("occTrackQA/LogRatio/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), std::log(std::abs(occValue / occRobustValue))); if (fillQA2) { - if (std::abs(std::log(occValue / occRobustValue)) < 2) { // conditional filling start + int two = 2, twenty = 20, fifty = 50, twoHundred = 200; + if (std::abs(std::log(occValue / occRobustValue)) < two) { // conditional filling start occupancyQA.fill(HIST("occTrackQA/Condition1/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), (std::log(occValue / occRobustValue)) * std::sqrt(occValue + occRobustValue)); - if (std::abs(occRobustValue + occValue) > 200) { + if (std::abs(occRobustValue + occValue) > twoHundred) { occupancyQA.fill(HIST("occTrackQA/Condition4/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), (std::log(occValue / occRobustValue)) * std::sqrt(occValue + occRobustValue)); occupancyQA.fill(HIST("occTrackQA/Condition3/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), (std::log(occValue / occRobustValue)) * std::sqrt(occValue + occRobustValue)); occupancyQA.fill(HIST("occTrackQA/Condition2/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), (std::log(occValue / occRobustValue)) * std::sqrt(occValue + occRobustValue)); - } else if (std::abs(occRobustValue + occValue) > 50) { + } else if (std::abs(occRobustValue + occValue) > fifty) { occupancyQA.fill(HIST("occTrackQA/Condition3/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), (std::log(occValue / occRobustValue)) * std::sqrt(occValue + occRobustValue)); occupancyQA.fill(HIST("occTrackQA/Condition2/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), (std::log(occValue / occRobustValue)) * std::sqrt(occValue + occRobustValue)); - } else if (std::abs(occRobustValue + occValue) > 20) { + } else if (std::abs(occRobustValue + occValue) > twenty) { occupancyQA.fill(HIST("occTrackQA/Condition2/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), (std::log(occValue / occRobustValue)) * std::sqrt(occValue + occRobustValue)); } } // conditional filling end @@ -1137,15 +1692,7 @@ struct TrackMeanOccTableProducer { } } - using MyCollisions = soa::Join; - using MyTracks = soa::Join; using MyTracksQA = aod::TracksQA_002; - using MyBCTable = soa::Join; - - using MyOccsDet = soa::Join; - using MyOccsTrackMult = soa::Join; - using MyOccsMultExtra = soa::Join; - using MyOccsRobust = soa::Join; // Process the Data int dfCount = 0; @@ -1157,520 +1704,902 @@ struct TrackMeanOccTableProducer { int64_t tfIdThis = -1; int bcInTF = -1; - void process(MyBCTable const& BCs, MyCollisions const& collisions, MyTracks const& tracks, MyTracksQA const& tracksQA, - // o2::aod::AmbiguousTracks const& ambgTracks, o2::aod::Origins const& Origins, aod::OccsBCsList const& occsBCsList, //tables only used during debugging - MyOccsDet const& occsDet, MyOccsTrackMult const& occsTrackMult, - MyOccsMultExtra const& occsMultExtra, MyOccsRobust const& occsRobust) + enum ProcessTags { + kProcessNothing = 0, + kProcessOnlyOccPrim, + kProcessOnlyOccT0V0, + kProcessOnlyOccFDD, + kProcessOnlyOccNtrackDet, + kProcessOnlyOccMultExtra, + kProcessOnlyRobustT0V0Prim, + kProcessOnlyRobustFDDT0V0Prim, + kProcessOnlyRobustNtrackDet, + kProcessOnlyRobustMultExtra, + kProcessFullOccTableProducer + }; + + enum FillMode { + checkTableMode = 0, + checkQAMode, + doNotFill, + fillOccRobustT0V0dependentQA, + fillMeanOccTable, + fillWeightMeanOccTable + }; + + template + void executeTrackOccProducerProcessing(B const& BCs, C const& collisions, T const& tracks, U const& tracksQA, O const& occsRobustT0V0Prim, V const& occs, bool const& executeInThisBlock) { - // dfCount++;LOG(info) << "DEBUG 2 :: df_" << dfCount ;//<< " :: DF_" << Origins.begin().dataframeID() << " :: collisions.size() = " << collisions.size() << " :: tracks.size() = " << tracks.size() << " :: tracksQA.size() = " << tracksQA.size() - // << " :: MyBCTable.size() = " << BCs.size() - // << " :: occsBCsList.size() = " <(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, executeInThisBlock); + } else { + executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, executeInThisBlock); } + } + if constexpr (meanTableMode == checkTableMode) { + return; + } - // Checking out of the range errors - if (trackQA.trackId() < 0 || tracks.size() <= trackQA.trackId()) { - LOG(error) << "DEBUG :: ERROR :: trackQA has index out of scope :: trackQA.trackId() = " << trackQA.trackId() << " :: track.collisionId() = " << track.collisionId() << " :: track.signed1Pt() = " << track.signed1Pt(); - } - if (!hasCollision && !isAmbgTrack) { - LOG(error) << "DEBUG :: ERROR :: A track with no collsiion and is not Ambiguous"; - } - if (hasCollision && isAmbgTrack) { - LOG(error) << "DEBUG :: ERROR :: A track has collision and is also ambiguous"; + if (weightMeanTableMode == checkTableMode) { + if (buildFlag01WeightMeanTable) { + executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, executeInThisBlock); + } else { + executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, executeInThisBlock); } + } + if constexpr (weightMeanTableMode == checkTableMode) { + return; + } - if (hasCollision) { - lastTrackHadCollision = true; + if (qaMode == checkQAMode) { + if (fillQA1 || fillQA2) { + if (occsRobustT0V0Prim.size() == 0) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: OccsRobustT0V0Prim.size() == 0 :: Check \"occupancy-table-producer\" for \"buildOnlyOccsT0V0Prim == true\" & \"processOnlyOccT0V0PrimUnfm == true\""; + return; + } + executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, executeInThisBlock); + } else { + executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, executeInThisBlock); } - doCollisionUpdate = false; // default is false; - doAmbgUpdate = false; - if (hasCollision) { - if (lastTrackHadCollision) { - if (collision.globalIndex() == oldCollisionIndex) { // if collisions are same - doCollisionUpdate = false; - } else { // if collisions are different + } + if constexpr (qaMode == checkQAMode) { + return; + } + + // BCs.bindExternalIndices(&occsDet); + // BCs.bindExternalIndices(&occsNTrackDet); + // BCs.bindExternalIndices(&occsRobust); + + if constexpr (meanTableMode == checkTableMode || weightMeanTableMode == checkTableMode || qaMode == checkQAMode) { + return; + } else { + occupancyQA.fill(HIST("h_DFcount_Lvl2"), processMode); + + auto bc = BCs.begin(); + + int64_t oldTFid = -1; + + int64_t oldCollisionIndex = -100; + bool hasCollision = false; + bool isAmbgTrack = false; + bool lastTrackHadCollision = false; + bool doCollisionUpdate = false; + bool doAmbgUpdate = false; + + double rBegin = 90., rEnd = 245.; + double zBegin; // collision.posZ() + track.tgl()*rBegin; + double zEnd; // collision.posZ() + track.tgl()*rEnd; + double vdrift = 2.64; + + double dTbegin; // ((250.- TMath::Abs(zBegin))/vdrift)/0.025;//bin + double dTend; // ((250.- TMath::Abs(zEnd))/vdrift)/0.025; //bin + + double bcBegin; // tGlobalBC + dTbegin; + double bcEnd; // tGlobalBC + dTend ; + + int binBCbegin; + int binBCend; + + float meanOccPrimUnfm80 = 0; + float meanOccFV0AUnfm80 = 0; + float meanOccFV0CUnfm80 = 0; + float meanOccFT0AUnfm80 = 0; + float meanOccFT0CUnfm80 = 0; + float meanOccFDDAUnfm80 = 0; + float meanOccFDDCUnfm80 = 0; + + float meanOccNTrackITSUnfm80 = 0; + float meanOccNTrackTPCUnfm80 = 0; + float meanOccNTrackTRDUnfm80 = 0; + float meanOccNTrackTOFUnfm80 = 0; + float meanOccNTrackSizeUnfm80 = 0; + float meanOccNTrackTPCAUnfm80 = 0; + float meanOccNTrackTPCCUnfm80 = 0; + float meanOccNTrackITSTPCUnfm80 = 0; + float meanOccNTrackITSTPCAUnfm80 = 0; + float meanOccNTrackITSTPCCUnfm80 = 0; + + float meanOccMultNTracksHasITSUnfm80 = 0; + float meanOccMultNTracksHasTPCUnfm80 = 0; + float meanOccMultNTracksHasTOFUnfm80 = 0; + float meanOccMultNTracksHasTRDUnfm80 = 0; + float meanOccMultNTracksITSOnlyUnfm80 = 0; + float meanOccMultNTracksTPCOnlyUnfm80 = 0; + float meanOccMultNTracksITSTPCUnfm80 = 0; + float meanOccMultAllTracksTPCOnlyUnfm80 = 0; + + float meanOccRobustT0V0PrimUnfm80 = 0; + float meanOccRobustFDDT0V0PrimUnfm80 = 0; + float meanOccRobustNtrackDetUnfm80 = 0; + float meanOccRobustMultTableUnfm80 = 0; + + float weightMeanOccPrimUnfm80 = 0; + float weightMeanOccFV0AUnfm80 = 0; + float weightMeanOccFV0CUnfm80 = 0; + float weightMeanOccFT0AUnfm80 = 0; + float weightMeanOccFT0CUnfm80 = 0; + float weightMeanOccFDDAUnfm80 = 0; + float weightMeanOccFDDCUnfm80 = 0; + + float weightMeanOccNTrackITSUnfm80 = 0; + float weightMeanOccNTrackTPCUnfm80 = 0; + float weightMeanOccNTrackTRDUnfm80 = 0; + float weightMeanOccNTrackTOFUnfm80 = 0; + float weightMeanOccNTrackSizeUnfm80 = 0; + float weightMeanOccNTrackTPCAUnfm80 = 0; + float weightMeanOccNTrackTPCCUnfm80 = 0; + float weightMeanOccNTrackITSTPCUnfm80 = 0; + float weightMeanOccNTrackITSTPCAUnfm80 = 0; + float weightMeanOccNTrackITSTPCCUnfm80 = 0; + + float weightMeanOccMultNTracksHasITSUnfm80 = 0; + float weightMeanOccMultNTracksHasTPCUnfm80 = 0; + float weightMeanOccMultNTracksHasTOFUnfm80 = 0; + float weightMeanOccMultNTracksHasTRDUnfm80 = 0; + float weightMeanOccMultNTracksITSOnlyUnfm80 = 0; + float weightMeanOccMultNTracksTPCOnlyUnfm80 = 0; + float weightMeanOccMultNTracksITSTPCUnfm80 = 0; + float weightMeanOccMultAllTracksTPCOnlyUnfm80 = 0; + + float weightMeanOccRobustT0V0PrimUnfm80 = 0; + float weightMeanOccRobustFDDT0V0PrimUnfm80 = 0; + float weightMeanOccRobustNtrackDetUnfm80 = 0; + float weightMeanOccRobustMultTableUnfm80 = 0; + + for (const auto& trackQA : tracksQA) { + auto const& track = trackQA.template track_as(); + auto collision = collisions.begin(); + + hasCollision = false; + isAmbgTrack = false; + + if (track.collisionId() >= 0) { // track has collision + collision = track.template collision_as(); // It will build but crash while running for tracks with track.collisionId()= -1;//ambg tracks/orphan tracks + if (track.collisionId() != collision.globalIndex()) { + LOG(error) << "DEBUG :: ERROR :: track collId and collID Mismatch"; + } + hasCollision = true; + } else { // track is ambiguous/orphan + isAmbgTrack = true; + } + + // Checking out of the range errors + if (trackQA.trackId() < 0 || tracks.size() <= trackQA.trackId()) { + LOG(error) << "DEBUG :: ERROR :: trackQA has index out of scope :: trackQA.trackId() = " << trackQA.trackId() << " :: track.collisionId() = " << track.collisionId() << " :: track.signed1Pt() = " << track.signed1Pt(); + } + if (!hasCollision && !isAmbgTrack) { + LOG(error) << "DEBUG :: ERROR :: A track with no collsiion and is not Ambiguous"; + } + if (hasCollision && isAmbgTrack) { + LOG(error) << "DEBUG :: ERROR :: A track has collision and is also ambiguous"; + } + + if (hasCollision) { + lastTrackHadCollision = true; + } + doCollisionUpdate = false; // default is false; + doAmbgUpdate = false; + if (hasCollision) { + if (lastTrackHadCollision) { + if (collision.globalIndex() == oldCollisionIndex) { // if collisions are same + doCollisionUpdate = false; + } else { // if collisions are different + doCollisionUpdate = true; + } + } else { // LastTrackWasAmbiguous doCollisionUpdate = true; } - } else { // LastTrackWasAmbiguous - doCollisionUpdate = true; + } else if (isAmbgTrack) { + doAmbgUpdate = true; + // To be updated later + // if(LastTrackIsAmbg){ + // if( haveSameInfo ) { doAmbgUpdate = false;} + // else { doAmbgUpdate = true; } + // } + // else { doAmbgUpdate = true;} //Last track had Collisions } - } else if (isAmbgTrack) { - doAmbgUpdate = true; - // To be updated later - // if(LastTrackIsAmbg){ - // if( haveSameInfo ) { doAmbgUpdate = false;} - // else { doAmbgUpdate = true; } - // } - // else { doAmbgUpdate = true;} //Last track had Collisions - } - if (doAmbgUpdate) { // sKipping ambiguous tracks for now, will be updated in future - continue; - } - if (doCollisionUpdate || doAmbgUpdate) { // collision.globalIndex() != oldCollisionIndex){ //don't update if info is same as old collision - if (doCollisionUpdate) { - oldCollisionIndex = collision.globalIndex(); - bc = collision.bc_as(); + if (doAmbgUpdate) { // sKipping ambiguous tracks for now, will be updated in future + continue; } - if (doAmbgUpdate) { - // to be updated later - // bc = collisions.iteratorAt(2).bc_as(); - // bc = ambgTracks.iteratorAt(0).bc_as(); + if (doCollisionUpdate || doAmbgUpdate) { // collision.globalIndex() != oldCollisionIndex){ //don't update if info is same as old collision + if (doCollisionUpdate) { + oldCollisionIndex = collision.globalIndex(); + bc = collision.template bc_as(); + } + if (doAmbgUpdate) { + // to be updated later + // bc = collisions.iteratorAt(2).bc_as(); + // bc = ambgTracks.iteratorAt(0).bc_as(); + } + // LOG(info)<<" What happens in the case when the collision id is = -1 and it tries to obtain bc" + getTimingInfo(bc, lastRun, nBCsPerTF, bcSOR, time, tfIdThis, bcInTF); + } + + if (tfIdThis != oldTFid) { + oldTFid = tfIdThis; + auto occsList = occs.iteratorAt(bc.occId()); + + if constexpr (qaMode == fillOccRobustT0V0dependentQA) { + std::copy(occsRobustT0V0Prim.iteratorAt(bc.occId()).occRobustT0V0PrimUnfm80().begin(), occsRobustT0V0Prim.iteratorAt(bc.occId()).occRobustT0V0PrimUnfm80().end(), occRobustT0V0PrimUnfm80.begin()); + } + + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccPrim) { + std::copy(occsList.occPrimUnfm80().begin(), occsList.occPrimUnfm80().end(), occPrimUnfm80.begin()); + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccT0V0) { + std::copy(occsList.occFV0AUnfm80().begin(), occsList.occFV0AUnfm80().end(), occFV0AUnfm80.begin()); + std::copy(occsList.occFV0CUnfm80().begin(), occsList.occFV0CUnfm80().end(), occFV0CUnfm80.begin()); + std::copy(occsList.occFT0AUnfm80().begin(), occsList.occFT0AUnfm80().end(), occFT0AUnfm80.begin()); + std::copy(occsList.occFT0CUnfm80().begin(), occsList.occFT0CUnfm80().end(), occFT0CUnfm80.begin()); + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccFDD) { + std::copy(occsList.occFDDAUnfm80().begin(), occsList.occFDDAUnfm80().end(), occFDDAUnfm80.begin()); + std::copy(occsList.occFDDCUnfm80().begin(), occsList.occFDDCUnfm80().end(), occFDDCUnfm80.begin()); + } + + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccNtrackDet) { + std::copy(occsList.occNTrackITSUnfm80().begin(), occsList.occNTrackITSUnfm80().end(), occNTrackITSUnfm80.begin()); + std::copy(occsList.occNTrackTPCUnfm80().begin(), occsList.occNTrackTPCUnfm80().end(), occNTrackTPCUnfm80.begin()); + std::copy(occsList.occNTrackTRDUnfm80().begin(), occsList.occNTrackTRDUnfm80().end(), occNTrackTRDUnfm80.begin()); + std::copy(occsList.occNTrackTOFUnfm80().begin(), occsList.occNTrackTOFUnfm80().end(), occNTrackTOFUnfm80.begin()); + std::copy(occsList.occNTrackSizeUnfm80().begin(), occsList.occNTrackSizeUnfm80().end(), occNTrackSizeUnfm80.begin()); + std::copy(occsList.occNTrackTPCAUnfm80().begin(), occsList.occNTrackTPCAUnfm80().end(), occNTrackTPCAUnfm80.begin()); + std::copy(occsList.occNTrackTPCCUnfm80().begin(), occsList.occNTrackTPCCUnfm80().end(), occNTrackTPCCUnfm80.begin()); + std::copy(occsList.occNTrackITSTPCUnfm80().begin(), occsList.occNTrackITSTPCUnfm80().end(), occNTrackITSTPCUnfm80.begin()); + std::copy(occsList.occNTrackITSTPCAUnfm80().begin(), occsList.occNTrackITSTPCAUnfm80().end(), occNTrackITSTPCAUnfm80.begin()); + std::copy(occsList.occNTrackITSTPCCUnfm80().begin(), occsList.occNTrackITSTPCCUnfm80().end(), occNTrackITSTPCCUnfm80.begin()); + } + + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccMultExtra) { + std::copy(occsList.occMultNTracksHasITSUnfm80().begin(), occsList.occMultNTracksHasITSUnfm80().end(), occMultNTracksHasITSUnfm80.begin()); + std::copy(occsList.occMultNTracksHasTPCUnfm80().begin(), occsList.occMultNTracksHasTPCUnfm80().end(), occMultNTracksHasTPCUnfm80.begin()); + std::copy(occsList.occMultNTracksHasTOFUnfm80().begin(), occsList.occMultNTracksHasTOFUnfm80().end(), occMultNTracksHasTOFUnfm80.begin()); + std::copy(occsList.occMultNTracksHasTRDUnfm80().begin(), occsList.occMultNTracksHasTRDUnfm80().end(), occMultNTracksHasTRDUnfm80.begin()); + std::copy(occsList.occMultNTracksITSOnlyUnfm80().begin(), occsList.occMultNTracksITSOnlyUnfm80().end(), occMultNTracksITSOnlyUnfm80.begin()); + std::copy(occsList.occMultNTracksTPCOnlyUnfm80().begin(), occsList.occMultNTracksTPCOnlyUnfm80().end(), occMultNTracksTPCOnlyUnfm80.begin()); + std::copy(occsList.occMultNTracksITSTPCUnfm80().begin(), occsList.occMultNTracksITSTPCUnfm80().end(), occMultNTracksITSTPCUnfm80.begin()); + std::copy(occsList.occMultAllTracksTPCOnlyUnfm80().begin(), occsList.occMultAllTracksTPCOnlyUnfm80().end(), occMultAllTracksTPCOnlyUnfm80.begin()); + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyRobustT0V0Prim) { + std::copy(occsList.occRobustT0V0PrimUnfm80().begin(), occsList.occRobustT0V0PrimUnfm80().end(), occRobustT0V0PrimUnfm80.begin()); + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyRobustFDDT0V0Prim) { + std::copy(occsList.occRobustFDDT0V0PrimUnfm80().begin(), occsList.occRobustFDDT0V0PrimUnfm80().end(), occRobustFDDT0V0PrimUnfm80.begin()); + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyRobustNtrackDet) { + std::copy(occsList.occRobustNtrackDetUnfm80().begin(), occsList.occRobustNtrackDetUnfm80().end(), occRobustNtrackDetUnfm80.begin()); + } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyRobustMultExtra) { + std::copy(occsList.occRobustMultExtraTableUnfm80().begin(), occsList.occRobustMultExtraTableUnfm80().end(), occRobustMultTableUnfm80.begin()); + } } - // LOG(info)<<" What happens in the case when the collision id is = -1 and it tries to obtain bc" - getTimingInfo(bc, lastRun, nBCsPerTF, bcSOR, time, tfIdThis, bcInTF); - } - if (tfIdThis != oldTFid) { - oldTFid = tfIdThis; - // auto OccList = Occs.iteratorAt(bc.occId()); - if (buildTrackMeanOccs1 || buildTrackMeanOccs5) { - auto listOccsDet = occsDet.iteratorAt(bc.occId()); - std::copy(listOccsDet.occPrimUnfm80().begin(), listOccsDet.occPrimUnfm80().end(), occPrimUnfm80.begin()); - std::copy(listOccsDet.occFV0AUnfm80().begin(), listOccsDet.occFV0AUnfm80().end(), occFV0AUnfm80.begin()); - std::copy(listOccsDet.occFV0CUnfm80().begin(), listOccsDet.occFV0CUnfm80().end(), occFV0CUnfm80.begin()); - std::copy(listOccsDet.occFT0AUnfm80().begin(), listOccsDet.occFT0AUnfm80().end(), occFT0AUnfm80.begin()); - std::copy(listOccsDet.occFT0CUnfm80().begin(), listOccsDet.occFT0CUnfm80().end(), occFT0CUnfm80.begin()); - std::copy(listOccsDet.occFDDAUnfm80().begin(), listOccsDet.occFDDAUnfm80().end(), occFDDAUnfm80.begin()); - std::copy(listOccsDet.occFDDCUnfm80().begin(), listOccsDet.occFDDCUnfm80().end(), occFDDCUnfm80.begin()); + // Timebc = TGlobalBC+ΔTdrift + // ΔTdrift=((250(cm)-abs(z))/vdrift) + // vdrift=2.64 cm/μs + // z=zv+tgl*Radius + + rBegin = 90., rEnd = 245.; // in cm + zBegin = collision.posZ() + track.tgl() * rBegin; // in cm + zEnd = collision.posZ() + track.tgl() * rEnd; // in cm + vdrift = 2.64; // cm/μs + float length = 250.0; + // clip the result at 250 + if (zBegin > length) { + zBegin = 250; + } else if (zBegin < -length) { + zBegin = -250; } - if (buildTrackMeanOccs2 || buildTrackMeanOccs6) { - auto listOccsTrackMult = occsTrackMult.iteratorAt(bc.occId()); - ; - std::copy(listOccsTrackMult.occNTrackITSUnfm80().begin(), listOccsTrackMult.occNTrackITSUnfm80().end(), occNTrackITSUnfm80.begin()); - std::copy(listOccsTrackMult.occNTrackTPCUnfm80().begin(), listOccsTrackMult.occNTrackTPCUnfm80().end(), occNTrackTPCUnfm80.begin()); - std::copy(listOccsTrackMult.occNTrackTRDUnfm80().begin(), listOccsTrackMult.occNTrackTRDUnfm80().end(), occNTrackTRDUnfm80.begin()); - std::copy(listOccsTrackMult.occNTrackTOFUnfm80().begin(), listOccsTrackMult.occNTrackTOFUnfm80().end(), occNTrackTOFUnfm80.begin()); - std::copy(listOccsTrackMult.occNTrackSizeUnfm80().begin(), listOccsTrackMult.occNTrackSizeUnfm80().end(), occNTrackSizeUnfm80.begin()); - std::copy(listOccsTrackMult.occNTrackTPCAUnfm80().begin(), listOccsTrackMult.occNTrackTPCAUnfm80().end(), occNTrackTPCAUnfm80.begin()); - std::copy(listOccsTrackMult.occNTrackTPCCUnfm80().begin(), listOccsTrackMult.occNTrackTPCCUnfm80().end(), occNTrackTPCCUnfm80.begin()); - std::copy(listOccsTrackMult.occNTrackITSTPCUnfm80().begin(), listOccsTrackMult.occNTrackITSTPCUnfm80().end(), occNTrackITSTPCUnfm80.begin()); - std::copy(listOccsTrackMult.occNTrackITSTPCAUnfm80().begin(), listOccsTrackMult.occNTrackITSTPCAUnfm80().end(), occNTrackITSTPCAUnfm80.begin()); - std::copy(listOccsTrackMult.occNTrackITSTPCCUnfm80().begin(), listOccsTrackMult.occNTrackITSTPCCUnfm80().end(), occNTrackITSTPCCUnfm80.begin()); + if (zEnd > length) { + zEnd = 250; + } else if (zEnd < -length) { + zEnd = -250; } - if (buildTrackMeanOccs3 || buildTrackMeanOccs7) { - auto listOccsMultExtra = occsMultExtra.iteratorAt(bc.occId()); - ; - std::copy(listOccsMultExtra.occMultNTracksHasITSUnfm80().begin(), listOccsMultExtra.occMultNTracksHasITSUnfm80().end(), occMultNTracksHasITSUnfm80.begin()); - std::copy(listOccsMultExtra.occMultNTracksHasTPCUnfm80().begin(), listOccsMultExtra.occMultNTracksHasTPCUnfm80().end(), occMultNTracksHasTPCUnfm80.begin()); - std::copy(listOccsMultExtra.occMultNTracksHasTOFUnfm80().begin(), listOccsMultExtra.occMultNTracksHasTOFUnfm80().end(), occMultNTracksHasTOFUnfm80.begin()); - std::copy(listOccsMultExtra.occMultNTracksHasTRDUnfm80().begin(), listOccsMultExtra.occMultNTracksHasTRDUnfm80().end(), occMultNTracksHasTRDUnfm80.begin()); - std::copy(listOccsMultExtra.occMultNTracksITSOnlyUnfm80().begin(), listOccsMultExtra.occMultNTracksITSOnlyUnfm80().end(), occMultNTracksITSOnlyUnfm80.begin()); - std::copy(listOccsMultExtra.occMultNTracksTPCOnlyUnfm80().begin(), listOccsMultExtra.occMultNTracksTPCOnlyUnfm80().end(), occMultNTracksTPCOnlyUnfm80.begin()); - std::copy(listOccsMultExtra.occMultNTracksITSTPCUnfm80().begin(), listOccsMultExtra.occMultNTracksITSTPCUnfm80().end(), occMultNTracksITSTPCUnfm80.begin()); - std::copy(listOccsMultExtra.occMultAllTracksTPCOnlyUnfm80().begin(), listOccsMultExtra.occMultAllTracksTPCOnlyUnfm80().end(), occMultAllTracksTPCOnlyUnfm80.begin()); + dTbegin = ((length - std::abs(zBegin)) / vdrift) / 0.025; + dTend = ((length - std::abs(zEnd)) / vdrift) / 0.025; + + bcBegin = bcInTF + dTbegin; + bcEnd = bcInTF + dTend; + + binBCbegin = bcBegin / 80; + binBCend = bcEnd / 80; + + // If multiple process are on, fill this table only once + if (executeInThisBlock) { + genTmoTrackId(track.globalIndex()); } - auto listOccsRobust = occsRobust.iteratorAt(bc.occId()); - std::copy(listOccsRobust.occRobustT0V0PrimUnfm80().begin(), listOccsRobust.occRobustT0V0PrimUnfm80().end(), occRobustT0V0PrimUnfm80.begin()); - if (buildTrackMeanOccs4 || buildTrackMeanOccs8) { - std::copy(listOccsRobust.occRobustFDDT0V0PrimUnfm80().begin(), listOccsRobust.occRobustFDDT0V0PrimUnfm80().end(), occRobustFDDT0V0PrimUnfm80.begin()); - std::copy(listOccsRobust.occRobustNtrackDetUnfm80().begin(), listOccsRobust.occRobustNtrackDetUnfm80().end(), occRobustNtrackDetUnfm80.begin()); - std::copy(listOccsRobust.occRobustMultExtraTableUnfm80().begin(), listOccsRobust.occRobustMultExtraTableUnfm80().end(), occRobustMultTableUnfm80.begin()); + if constexpr (qaMode == fillOccRobustT0V0dependentQA) { + if constexpr (meanTableMode == fillMeanOccTable) { + meanOccRobustT0V0PrimUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occRobustT0V0PrimUnfm80); + } + if constexpr (weightMeanTableMode == fillWeightMeanOccTable) { + weightMeanOccRobustT0V0PrimUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occRobustT0V0PrimUnfm80); + } } - } - // Timebc = TGlobalBC+ΔTdrift - // ΔTdrift=((250(cm)-abs(z))/vdrift) - // vdrift=2.64 cm/μs - // z=zv+tgl*Radius - - rBegin = 90., rEnd = 245.; // in cm - zBegin = collision.posZ() + track.tgl() * rBegin; // in cm - zEnd = collision.posZ() + track.tgl() * rEnd; // in cm - vdrift = 2.64; // cm/μs - - // clip the result at 250 - if (zBegin > 250) { - zBegin = 250; - } else if (zBegin < -250) { - zBegin = -250; - } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccPrim) { + if constexpr (meanTableMode == fillMeanOccTable) { + meanOccPrimUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occPrimUnfm80); + genTmoPrim(meanOccPrimUnfm80); + fillQAInfo(meanOccPrimUnfm80, meanOccRobustT0V0PrimUnfm80); + } + if constexpr (weightMeanTableMode == fillWeightMeanOccTable) { + weightMeanOccPrimUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occPrimUnfm80); + genTwmoPrim(weightMeanOccPrimUnfm80); + fillQAInfo(weightMeanOccPrimUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccPrimUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + } + } - if (zEnd > 250) { - zEnd = 250; - } else if (zEnd < -250) { - zEnd = -250; - } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccT0V0) { + if constexpr (meanTableMode == fillMeanOccTable) { + meanOccFV0AUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occFV0AUnfm80); + meanOccFV0CUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occFV0CUnfm80); + meanOccFT0AUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occFT0AUnfm80); + meanOccFT0CUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occFT0CUnfm80); + genTmoT0V0(meanOccFV0AUnfm80, + meanOccFV0CUnfm80, + meanOccFT0AUnfm80, + meanOccFT0CUnfm80); + fillQAInfo(meanOccFV0AUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccFV0CUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccFT0AUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccFT0CUnfm80, meanOccRobustT0V0PrimUnfm80); + } + if constexpr (weightMeanTableMode == fillWeightMeanOccTable) { + weightMeanOccFV0AUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occFV0AUnfm80); + weightMeanOccFV0CUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occFV0CUnfm80); + weightMeanOccFT0AUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occFT0AUnfm80); + weightMeanOccFT0CUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occFT0CUnfm80); + genTwmoT0V0(weightMeanOccFV0AUnfm80, + weightMeanOccFV0CUnfm80, + weightMeanOccFT0AUnfm80, + weightMeanOccFT0CUnfm80); + fillQAInfo(weightMeanOccFV0AUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccFV0CUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccFT0AUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccFT0CUnfm80, meanOccRobustT0V0PrimUnfm80); + + fillQAInfo(weightMeanOccFV0AUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccFV0CUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccFT0AUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccFT0CUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + } + } - dTbegin = ((250. - std::abs(zBegin)) / vdrift) / 0.025; - dTend = ((250. - std::abs(zEnd)) / vdrift) / 0.025; - - bcBegin = bcInTF + dTbegin; - bcEnd = bcInTF + dTend; - - binBCbegin = bcBegin / 80; - binBCend = bcEnd / 80; - - genTrackMeanOccs0(track.globalIndex()); - - meanOccRobustT0V0PrimUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occRobustT0V0PrimUnfm80); - weightMeanOccRobustT0V0PrimUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occRobustT0V0PrimUnfm80); - - if (buildTrackMeanOccs1) { - meanOccPrimUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occPrimUnfm80); - meanOccFV0AUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occFV0AUnfm80); - meanOccFV0CUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occFV0CUnfm80); - meanOccFT0AUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occFT0AUnfm80); - meanOccFT0CUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occFT0CUnfm80); - meanOccFDDAUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occFDDAUnfm80); - meanOccFDDCUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occFDDCUnfm80); - - genTrackMeanOccs1(meanOccPrimUnfm80, - meanOccFV0AUnfm80, - meanOccFV0CUnfm80, - meanOccFT0AUnfm80, - meanOccFT0CUnfm80, - meanOccFDDAUnfm80, - meanOccFDDCUnfm80); - - fillQAInfo(meanOccPrimUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccFV0AUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccFV0CUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccFT0AUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccFT0CUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccFDDAUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccFDDCUnfm80, meanOccRobustT0V0PrimUnfm80); - } - if (buildTrackMeanOccs2) { - meanOccNTrackITSUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackITSUnfm80); - meanOccNTrackTPCUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackTPCUnfm80); - meanOccNTrackTRDUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackTRDUnfm80); - meanOccNTrackTOFUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackTOFUnfm80); - meanOccNTrackSizeUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackSizeUnfm80); - meanOccNTrackTPCAUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackTPCAUnfm80); - meanOccNTrackTPCCUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackTPCCUnfm80); - meanOccNTrackITSTPCUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackITSTPCUnfm80); - meanOccNTrackITSTPCAUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackITSTPCAUnfm80); - meanOccNTrackITSTPCCUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackITSTPCCUnfm80); - - genTrackMeanOccs2(meanOccNTrackITSUnfm80, - meanOccNTrackTPCUnfm80, - meanOccNTrackTRDUnfm80, - meanOccNTrackTOFUnfm80, - meanOccNTrackSizeUnfm80, - meanOccNTrackTPCAUnfm80, - meanOccNTrackTPCCUnfm80, - meanOccNTrackITSTPCUnfm80, - meanOccNTrackITSTPCAUnfm80, - meanOccNTrackITSTPCCUnfm80); - - fillQAInfo(meanOccNTrackITSUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccNTrackTPCUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccNTrackTRDUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccNTrackTOFUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccNTrackSizeUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccNTrackTPCAUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccNTrackTPCCUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccNTrackITSTPCUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccNTrackITSTPCAUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccNTrackITSTPCCUnfm80, meanOccRobustT0V0PrimUnfm80); - } - if (buildTrackMeanOccs3) { - meanOccMultNTracksHasITSUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occMultNTracksHasITSUnfm80); - meanOccMultNTracksHasTPCUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occMultNTracksHasTPCUnfm80); - meanOccMultNTracksHasTOFUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occMultNTracksHasTOFUnfm80); - meanOccMultNTracksHasTRDUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occMultNTracksHasTRDUnfm80); - meanOccMultNTracksITSOnlyUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occMultNTracksITSOnlyUnfm80); - meanOccMultNTracksTPCOnlyUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occMultNTracksTPCOnlyUnfm80); - meanOccMultNTracksITSTPCUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occMultNTracksITSTPCUnfm80); - meanOccMultAllTracksTPCOnlyUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occMultAllTracksTPCOnlyUnfm80); - - genTrackMeanOccs3(meanOccMultNTracksHasITSUnfm80, - meanOccMultNTracksHasTPCUnfm80, - meanOccMultNTracksHasTOFUnfm80, - meanOccMultNTracksHasTRDUnfm80, - meanOccMultNTracksITSOnlyUnfm80, - meanOccMultNTracksTPCOnlyUnfm80, - meanOccMultNTracksITSTPCUnfm80, - meanOccMultAllTracksTPCOnlyUnfm80); - - fillQAInfo(meanOccMultNTracksHasITSUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccMultNTracksHasTPCUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccMultNTracksHasTOFUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccMultNTracksHasTRDUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccMultNTracksITSOnlyUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccMultNTracksTPCOnlyUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccMultNTracksITSTPCUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccMultAllTracksTPCOnlyUnfm80, meanOccRobustT0V0PrimUnfm80); - } - if (buildTrackMeanOccs4) { - meanOccRobustFDDT0V0PrimUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occRobustFDDT0V0PrimUnfm80); - meanOccRobustNtrackDetUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occRobustNtrackDetUnfm80); - meanOccRobustMultTableUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occRobustMultTableUnfm80); - - genTrackMeanOccs4(meanOccRobustT0V0PrimUnfm80, - meanOccRobustFDDT0V0PrimUnfm80, - meanOccRobustNtrackDetUnfm80, - meanOccRobustMultTableUnfm80); - - fillQAInfo(meanOccRobustT0V0PrimUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccRobustFDDT0V0PrimUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccRobustNtrackDetUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(meanOccRobustMultTableUnfm80, meanOccRobustT0V0PrimUnfm80); - } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccFDD) { + if constexpr (meanTableMode == fillMeanOccTable) { + meanOccFDDAUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occFDDAUnfm80); + meanOccFDDCUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occFDDCUnfm80); + genTmoFDD(meanOccFDDAUnfm80, + meanOccFDDCUnfm80); + fillQAInfo(meanOccFDDAUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccFDDCUnfm80, meanOccRobustT0V0PrimUnfm80); + } + if constexpr (weightMeanTableMode == fillWeightMeanOccTable) { + weightMeanOccFDDAUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occFDDAUnfm80); + weightMeanOccFDDCUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occFDDCUnfm80); + genTwmoFDD(weightMeanOccFDDAUnfm80, + weightMeanOccFDDCUnfm80); + fillQAInfo(weightMeanOccFDDAUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccFDDCUnfm80, meanOccRobustT0V0PrimUnfm80); + + fillQAInfo(weightMeanOccFDDAUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccFDDCUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + } + } - if (buildTrackMeanOccs5) { - weightMeanOccPrimUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occPrimUnfm80); - weightMeanOccFV0AUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occFV0AUnfm80); - weightMeanOccFV0CUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occFV0CUnfm80); - weightMeanOccFT0AUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occFT0AUnfm80); - weightMeanOccFT0CUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occFT0CUnfm80); - weightMeanOccFDDAUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occFDDAUnfm80); - weightMeanOccFDDCUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occFDDCUnfm80); - - genTrackMeanOccs5(weightMeanOccPrimUnfm80, - weightMeanOccFV0AUnfm80, - weightMeanOccFV0CUnfm80, - weightMeanOccFT0AUnfm80, - weightMeanOccFT0CUnfm80, - weightMeanOccFDDAUnfm80, - weightMeanOccFDDCUnfm80); - - fillQAInfo(weightMeanOccPrimUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccFV0AUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccFV0CUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccFT0AUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccFT0CUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccFDDAUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccFDDCUnfm80, meanOccRobustT0V0PrimUnfm80); - - fillQAInfo(weightMeanOccPrimUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccFV0AUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccFV0CUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccFT0AUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccFT0CUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccFDDAUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccFDDCUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccNtrackDet) { + if constexpr (meanTableMode == fillMeanOccTable) { + meanOccNTrackITSUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackITSUnfm80); + meanOccNTrackTPCUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackTPCUnfm80); + meanOccNTrackTRDUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackTRDUnfm80); + meanOccNTrackTOFUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackTOFUnfm80); + meanOccNTrackSizeUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackSizeUnfm80); + meanOccNTrackTPCAUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackTPCAUnfm80); + meanOccNTrackTPCCUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackTPCCUnfm80); + meanOccNTrackITSTPCUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackITSTPCUnfm80); + meanOccNTrackITSTPCAUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackITSTPCAUnfm80); + meanOccNTrackITSTPCCUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occNTrackITSTPCCUnfm80); + genTmoNTrackDet(meanOccNTrackITSUnfm80, + meanOccNTrackTPCUnfm80, + meanOccNTrackTRDUnfm80, + meanOccNTrackTOFUnfm80, + meanOccNTrackSizeUnfm80, + meanOccNTrackTPCAUnfm80, + meanOccNTrackTPCCUnfm80, + meanOccNTrackITSTPCUnfm80, + meanOccNTrackITSTPCAUnfm80, + meanOccNTrackITSTPCCUnfm80); + fillQAInfo(meanOccNTrackITSUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccNTrackTPCUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccNTrackTRDUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccNTrackTOFUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccNTrackSizeUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccNTrackTPCAUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccNTrackTPCCUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccNTrackITSTPCUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccNTrackITSTPCAUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccNTrackITSTPCCUnfm80, meanOccRobustT0V0PrimUnfm80); + } + if constexpr (weightMeanTableMode == fillWeightMeanOccTable) { + weightMeanOccNTrackITSUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackITSUnfm80); + weightMeanOccNTrackTPCUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackTPCUnfm80); + weightMeanOccNTrackTRDUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackTRDUnfm80); + weightMeanOccNTrackTOFUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackTOFUnfm80); + weightMeanOccNTrackSizeUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackSizeUnfm80); + weightMeanOccNTrackTPCAUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackTPCAUnfm80); + weightMeanOccNTrackTPCCUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackTPCCUnfm80); + weightMeanOccNTrackITSTPCUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackITSTPCUnfm80); + weightMeanOccNTrackITSTPCAUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackITSTPCAUnfm80); + weightMeanOccNTrackITSTPCCUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackITSTPCCUnfm80); + + genTwmoNTrackDet(weightMeanOccNTrackITSUnfm80, + weightMeanOccNTrackTPCUnfm80, + weightMeanOccNTrackTRDUnfm80, + weightMeanOccNTrackTOFUnfm80, + weightMeanOccNTrackSizeUnfm80, + weightMeanOccNTrackTPCAUnfm80, + weightMeanOccNTrackTPCCUnfm80, + weightMeanOccNTrackITSTPCUnfm80, + weightMeanOccNTrackITSTPCAUnfm80, + weightMeanOccNTrackITSTPCCUnfm80); + + fillQAInfo(weightMeanOccNTrackITSUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackTPCUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackTRDUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackTOFUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackSizeUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackTPCAUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackTPCCUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackITSTPCUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackITSTPCAUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackITSTPCCUnfm80, meanOccRobustT0V0PrimUnfm80); + + fillQAInfo(weightMeanOccNTrackITSUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackTPCUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackTRDUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackTOFUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackSizeUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackTPCAUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackTPCCUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackITSTPCUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackITSTPCAUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccNTrackITSTPCCUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + } + } - if (buildTrackMeanOccs6) { - weightMeanOccNTrackITSUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackITSUnfm80); - weightMeanOccNTrackTPCUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackTPCUnfm80); - weightMeanOccNTrackTRDUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackTRDUnfm80); - weightMeanOccNTrackTOFUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackTOFUnfm80); - weightMeanOccNTrackSizeUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackSizeUnfm80); - weightMeanOccNTrackTPCAUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackTPCAUnfm80); - weightMeanOccNTrackTPCCUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackTPCCUnfm80); - weightMeanOccNTrackITSTPCUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackITSTPCUnfm80); - weightMeanOccNTrackITSTPCAUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackITSTPCAUnfm80); - weightMeanOccNTrackITSTPCCUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occNTrackITSTPCCUnfm80); - - genTrackMeanOccs6(weightMeanOccNTrackITSUnfm80, - weightMeanOccNTrackTPCUnfm80, - weightMeanOccNTrackTRDUnfm80, - weightMeanOccNTrackTOFUnfm80, - weightMeanOccNTrackSizeUnfm80, - weightMeanOccNTrackTPCAUnfm80, - weightMeanOccNTrackTPCCUnfm80, - weightMeanOccNTrackITSTPCUnfm80, - weightMeanOccNTrackITSTPCAUnfm80, - weightMeanOccNTrackITSTPCCUnfm80); - - fillQAInfo(weightMeanOccNTrackITSUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackTPCUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackTRDUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackTOFUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackSizeUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackTPCAUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackTPCCUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackITSTPCUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackITSTPCAUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackITSTPCCUnfm80, meanOccRobustT0V0PrimUnfm80); - - fillQAInfo(weightMeanOccNTrackITSUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackTPCUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackTRDUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackTOFUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackSizeUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackTPCAUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackTPCCUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackITSTPCUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackITSTPCAUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccNTrackITSTPCCUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccMultExtra) { + if constexpr (meanTableMode == fillMeanOccTable) { + meanOccMultNTracksHasITSUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occMultNTracksHasITSUnfm80); + meanOccMultNTracksHasTPCUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occMultNTracksHasTPCUnfm80); + meanOccMultNTracksHasTOFUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occMultNTracksHasTOFUnfm80); + meanOccMultNTracksHasTRDUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occMultNTracksHasTRDUnfm80); + meanOccMultNTracksITSOnlyUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occMultNTracksITSOnlyUnfm80); + meanOccMultNTracksTPCOnlyUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occMultNTracksTPCOnlyUnfm80); + meanOccMultNTracksITSTPCUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occMultNTracksITSTPCUnfm80); + meanOccMultAllTracksTPCOnlyUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occMultAllTracksTPCOnlyUnfm80); + genTmoMultExtra(meanOccMultNTracksHasITSUnfm80, + meanOccMultNTracksHasTPCUnfm80, + meanOccMultNTracksHasTOFUnfm80, + meanOccMultNTracksHasTRDUnfm80, + meanOccMultNTracksITSOnlyUnfm80, + meanOccMultNTracksTPCOnlyUnfm80, + meanOccMultNTracksITSTPCUnfm80, + meanOccMultAllTracksTPCOnlyUnfm80); + fillQAInfo(meanOccMultNTracksHasITSUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccMultNTracksHasTPCUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccMultNTracksHasTOFUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccMultNTracksHasTRDUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccMultNTracksITSOnlyUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccMultNTracksTPCOnlyUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccMultNTracksITSTPCUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccMultAllTracksTPCOnlyUnfm80, meanOccRobustT0V0PrimUnfm80); + } + if constexpr (weightMeanTableMode == fillWeightMeanOccTable) { + weightMeanOccMultNTracksHasITSUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occMultNTracksHasITSUnfm80); + weightMeanOccMultNTracksHasTPCUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occMultNTracksHasTPCUnfm80); + weightMeanOccMultNTracksHasTOFUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occMultNTracksHasTOFUnfm80); + weightMeanOccMultNTracksHasTRDUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occMultNTracksHasTRDUnfm80); + weightMeanOccMultNTracksITSOnlyUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occMultNTracksITSOnlyUnfm80); + weightMeanOccMultNTracksTPCOnlyUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occMultNTracksTPCOnlyUnfm80); + weightMeanOccMultNTracksITSTPCUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occMultNTracksITSTPCUnfm80); + weightMeanOccMultAllTracksTPCOnlyUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occMultAllTracksTPCOnlyUnfm80); + + genTwmoMultExtra(weightMeanOccMultNTracksHasITSUnfm80, + weightMeanOccMultNTracksHasTPCUnfm80, + weightMeanOccMultNTracksHasTOFUnfm80, + weightMeanOccMultNTracksHasTRDUnfm80, + weightMeanOccMultNTracksITSOnlyUnfm80, + weightMeanOccMultNTracksTPCOnlyUnfm80, + weightMeanOccMultNTracksITSTPCUnfm80, + weightMeanOccMultAllTracksTPCOnlyUnfm80); + + fillQAInfo(weightMeanOccMultNTracksHasITSUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccMultNTracksHasTPCUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccMultNTracksHasTOFUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccMultNTracksHasTRDUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccMultNTracksITSOnlyUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccMultNTracksTPCOnlyUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccMultNTracksITSTPCUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccMultAllTracksTPCOnlyUnfm80, meanOccRobustT0V0PrimUnfm80); + + fillQAInfo(weightMeanOccMultNTracksHasITSUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccMultNTracksHasTPCUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccMultNTracksHasTOFUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccMultNTracksHasTRDUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccMultNTracksITSOnlyUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccMultNTracksTPCOnlyUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccMultNTracksITSTPCUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccMultAllTracksTPCOnlyUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + } + } - if (buildTrackMeanOccs7) { - weightMeanOccMultNTracksHasITSUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occMultNTracksHasITSUnfm80); - weightMeanOccMultNTracksHasTPCUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occMultNTracksHasTPCUnfm80); - weightMeanOccMultNTracksHasTOFUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occMultNTracksHasTOFUnfm80); - weightMeanOccMultNTracksHasTRDUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occMultNTracksHasTRDUnfm80); - weightMeanOccMultNTracksITSOnlyUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occMultNTracksITSOnlyUnfm80); - weightMeanOccMultNTracksTPCOnlyUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occMultNTracksTPCOnlyUnfm80); - weightMeanOccMultNTracksITSTPCUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occMultNTracksITSTPCUnfm80); - weightMeanOccMultAllTracksTPCOnlyUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occMultAllTracksTPCOnlyUnfm80); - - genTrackMeanOccs7(weightMeanOccMultNTracksHasITSUnfm80, - weightMeanOccMultNTracksHasTPCUnfm80, - weightMeanOccMultNTracksHasTOFUnfm80, - weightMeanOccMultNTracksHasTRDUnfm80, - weightMeanOccMultNTracksITSOnlyUnfm80, - weightMeanOccMultNTracksTPCOnlyUnfm80, - weightMeanOccMultNTracksITSTPCUnfm80, - weightMeanOccMultAllTracksTPCOnlyUnfm80); - - fillQAInfo(weightMeanOccMultNTracksHasITSUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccMultNTracksHasTPCUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccMultNTracksHasTOFUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccMultNTracksHasTRDUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccMultNTracksITSOnlyUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccMultNTracksTPCOnlyUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccMultNTracksITSTPCUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccMultAllTracksTPCOnlyUnfm80, meanOccRobustT0V0PrimUnfm80); - - fillQAInfo(weightMeanOccMultNTracksHasITSUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccMultNTracksHasTPCUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccMultNTracksHasTOFUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccMultNTracksHasTRDUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccMultNTracksITSOnlyUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccMultNTracksTPCOnlyUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccMultNTracksITSTPCUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccMultAllTracksTPCOnlyUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - } + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyRobustT0V0Prim) { + if constexpr (meanTableMode == fillMeanOccTable) { + meanOccRobustT0V0PrimUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occRobustT0V0PrimUnfm80); + genTmoRT0V0Prim(meanOccRobustT0V0PrimUnfm80); + fillQAInfo(meanOccRobustT0V0PrimUnfm80, meanOccRobustT0V0PrimUnfm80); + } + if constexpr (weightMeanTableMode == fillWeightMeanOccTable) { + weightMeanOccRobustT0V0PrimUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occRobustT0V0PrimUnfm80); + genTwmoRT0V0Prim(weightMeanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccRobustT0V0PrimUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccRobustT0V0PrimUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + } + } + + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyRobustFDDT0V0Prim) { + if constexpr (meanTableMode == fillMeanOccTable) { + meanOccRobustFDDT0V0PrimUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occRobustFDDT0V0PrimUnfm80); + genTmoRFDDT0V0Prim(meanOccRobustFDDT0V0PrimUnfm80); + fillQAInfo(meanOccRobustFDDT0V0PrimUnfm80, meanOccRobustT0V0PrimUnfm80); + } + if constexpr (weightMeanTableMode == fillWeightMeanOccTable) { + weightMeanOccRobustFDDT0V0PrimUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occRobustFDDT0V0PrimUnfm80); + genTwmoRFDDT0V0Pri(weightMeanOccRobustFDDT0V0PrimUnfm80); + fillQAInfo(weightMeanOccRobustFDDT0V0PrimUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccRobustFDDT0V0PrimUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + } + } + + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyRobustNtrackDet) { + if constexpr (meanTableMode == fillMeanOccTable) { + meanOccRobustNtrackDetUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occRobustNtrackDetUnfm80); + genTmoRNtrackDet(meanOccRobustNtrackDetUnfm80); + fillQAInfo(meanOccRobustNtrackDetUnfm80, meanOccRobustT0V0PrimUnfm80); + } + if constexpr (weightMeanTableMode == fillWeightMeanOccTable) { + weightMeanOccRobustNtrackDetUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occRobustNtrackDetUnfm80); + genTwmoRNtrackDet(weightMeanOccRobustNtrackDetUnfm80); + fillQAInfo(weightMeanOccRobustNtrackDetUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccRobustNtrackDetUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + } + } + + if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyRobustMultExtra) { + if constexpr (meanTableMode == fillMeanOccTable) { + meanOccRobustMultTableUnfm80 = getMeanOccupancy(binBCbegin, binBCend, occRobustMultTableUnfm80); + genTmoRMultExtra(meanOccRobustMultTableUnfm80); + fillQAInfo(meanOccRobustMultTableUnfm80, meanOccRobustT0V0PrimUnfm80); + } + if constexpr (weightMeanTableMode == fillWeightMeanOccTable) { + weightMeanOccRobustMultTableUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occRobustMultTableUnfm80); + genTwmoRMultExtra(weightMeanOccRobustMultTableUnfm80); + fillQAInfo(weightMeanOccRobustMultTableUnfm80, meanOccRobustT0V0PrimUnfm80); + fillQAInfo(weightMeanOccRobustMultTableUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + } + } + } // end of trackQA loop + } // end of else block of constexpr + } - if (buildTrackMeanOccs8) { - weightMeanOccRobustFDDT0V0PrimUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occRobustFDDT0V0PrimUnfm80); - weightMeanOccRobustNtrackDetUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occRobustNtrackDetUnfm80); - weightMeanOccRobustMultTableUnfm80 = getWeightedMeanOccupancy(binBCbegin, binBCend, occRobustMultTableUnfm80); - - genTrackMeanOccs8(weightMeanOccRobustT0V0PrimUnfm80, - weightMeanOccRobustFDDT0V0PrimUnfm80, - weightMeanOccRobustNtrackDetUnfm80, - weightMeanOccRobustMultTableUnfm80); - - fillQAInfo(weightMeanOccRobustT0V0PrimUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccRobustFDDT0V0PrimUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccRobustNtrackDetUnfm80, meanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccRobustMultTableUnfm80, meanOccRobustT0V0PrimUnfm80); - - fillQAInfo(weightMeanOccRobustT0V0PrimUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccRobustFDDT0V0PrimUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccRobustNtrackDetUnfm80, weightMeanOccRobustT0V0PrimUnfm80); - fillQAInfo(weightMeanOccRobustMultTableUnfm80, weightMeanOccRobustT0V0PrimUnfm80); + void checkAllProcessFunctionStatus(std::vector const& processStatusVector, bool& singleProcessOn) + { + int nProcessOn = 0; + const uint size = processStatusVector.size(); + for (uint i = 0; i < size; i++) { + if (processStatusVector[i]) { + nProcessOn++; } - } // end of trackQA loop + } + if (nProcessOn > 1) { + singleProcessOn = false; + } // check nProcess + } + + //_________________________________Process Functions start from here______________________________________________________________________________________ + void processNothing(aod::Collisions const&) + { + occupancyQA.fill(HIST("h_DFcount_Lvl0"), kProcessNothing); + return; + occupancyQA.fill(HIST("h_DFcount_Lvl1"), kProcessNothing); + } + PROCESS_SWITCH(TrackMeanOccTableProducer, processNothing, "process Nothing From Track Mean Occ Table Producer", true); + + void processOnlyOccPrim(soa::Join const& BCs, aod::Collisions const& collisions, aod::Tracks const& tracks, MyTracksQA const& tracksQA, aod::ORT0V0Prim const& occsRobustT0V0Prim, aod::OccsPrim const& occs) + { + processStatus[kProcessOnlyOccPrim] = true; + bool singleProcessOn = true; + checkAllProcessFunctionStatus(processStatus, singleProcessOn); + if (singleProcessOn) { + processInThisBlock[kProcessOnlyOccPrim] = true; + } + occupancyQA.fill(HIST("h_DFcount_Lvl0"), kProcessOnlyOccPrim); + if (collisions.size() == 0) { + return; + } + if (!buildOnlyOccsPrim && !buildFullOccTableProducer) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: buildOnlyOccsPrim == false"; + return; + } + if (occs.size() == 0) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: OccsPrim.size() == 0 :: Check \"occupancy-table-producer\" for \"buildOnlyOccsPrim == true\" & \"processOnlyOccPrimUnfm == true\""; + return; + } + executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, processInThisBlock[kProcessOnlyOccPrim]); + occupancyQA.fill(HIST("h_DFcount_Lvl1"), kProcessOnlyOccPrim); + } + PROCESS_SWITCH(TrackMeanOccTableProducer, processOnlyOccPrim, "processOnlyOccPrim", false); + + void processOnlyOccT0V0(soa::Join const& BCs, aod::Collisions const& collisions, aod::Tracks const& tracks, MyTracksQA const& tracksQA, aod::ORT0V0Prim const& occsRobustT0V0Prim, aod::OccsT0V0 const& occs) + { + processStatus[kProcessOnlyOccT0V0] = true; + bool singleProcessOn = true; + checkAllProcessFunctionStatus(processStatus, singleProcessOn); + if (singleProcessOn) { + processInThisBlock[kProcessOnlyOccT0V0] = true; + } + occupancyQA.fill(HIST("h_DFcount_Lvl0"), kProcessOnlyOccT0V0); + if (collisions.size() == 0) { + return; + } + if (!buildOnlyOccsT0V0 && !buildFullOccTableProducer) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: buildOnlyOccsT0V0 == false"; + return; + } + if (occs.size() == 0) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: OccsT0V0.size() == 0 :: Check \"occupancy-table-producer\" for \"buildOnlyOccsT0V0Prim == true\" & \"processOnlyOccT0V0PrimUnfm == true\""; + return; + } + executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, processInThisBlock[kProcessOnlyOccT0V0]); + occupancyQA.fill(HIST("h_DFcount_Lvl1"), kProcessOnlyOccT0V0); + } + PROCESS_SWITCH(TrackMeanOccTableProducer, processOnlyOccT0V0, "processOnlyOccT0V0", false); + + void processOnlyOccFDD(soa::Join const& BCs, aod::Collisions const& collisions, aod::Tracks const& tracks, MyTracksQA const& tracksQA, aod::ORT0V0Prim const& occsRobustT0V0Prim, aod::OccsFDD const& occs) + { + processStatus[kProcessOnlyOccFDD] = true; + bool singleProcessOn = true; + checkAllProcessFunctionStatus(processStatus, singleProcessOn); + if (singleProcessOn) { + processInThisBlock[kProcessOnlyOccFDD] = true; + } + occupancyQA.fill(HIST("h_DFcount_Lvl0"), kProcessOnlyOccFDD); + if (collisions.size() == 0) { + return; + } + if (!buildOnlyOccsFDD && !buildFullOccTableProducer) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: buildOnlyOccsFDD == false"; + return; + } + if (occs.size() == 0) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: OccsFDD.size() == 0 :: Check \"occupancy-table-producer\" for \"buildOnlyOccsFDDT0V0Prim == true\" & \"processOnlyOccFDDT0V0PrimUnfm == true\""; + return; + } + executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, processInThisBlock[kProcessOnlyOccFDD]); + occupancyQA.fill(HIST("h_DFcount_Lvl1"), kProcessOnlyOccFDD); + } + PROCESS_SWITCH(TrackMeanOccTableProducer, processOnlyOccFDD, "processOnlyOccFDD", false); + + void processOnlyOccNtrackDet(soa::Join const& BCs, aod::Collisions const& collisions, aod::Tracks const& tracks, MyTracksQA const& tracksQA, aod::ORT0V0Prim const& occsRobustT0V0Prim, aod::OccsNTrackDet const& occs) + { + processStatus[kProcessOnlyOccNtrackDet] = true; + bool singleProcessOn = true; + checkAllProcessFunctionStatus(processStatus, singleProcessOn); + if (singleProcessOn) { + processInThisBlock[kProcessOnlyOccNtrackDet] = true; + } + occupancyQA.fill(HIST("h_DFcount_Lvl0"), kProcessOnlyOccNtrackDet); + if (collisions.size() == 0) { + return; + } + if (!buildOnlyOccsNtrackDet && !buildFullOccTableProducer) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: buildOnlyOccsNtrackDet == false"; + return; + } + if (occs.size() == 0) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: OccsNtrackDet.size() == 0 :: Check \"occupancy-table-producer\" for \"buildOnlyOccsNtrackDet == true\" & \"processOnlyOccNtrackDet == true\""; + return; + } + executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, processInThisBlock[kProcessOnlyOccNtrackDet]); + occupancyQA.fill(HIST("h_DFcount_Lvl1"), kProcessOnlyOccNtrackDet); + } + PROCESS_SWITCH(TrackMeanOccTableProducer, processOnlyOccNtrackDet, "processOnlyOccNtrackDet", false); + + void processOnlyOccMultExtra(soa::Join const& BCs, aod::Collisions const& collisions, aod::Tracks const& tracks, MyTracksQA const& tracksQA, aod::ORT0V0Prim const& occsRobustT0V0Prim, aod::OccsMultExtra const& occs) + { + processStatus[kProcessOnlyOccMultExtra] = true; + bool singleProcessOn = true; + checkAllProcessFunctionStatus(processStatus, singleProcessOn); + if (singleProcessOn) { + processInThisBlock[kProcessOnlyOccMultExtra] = true; + } + occupancyQA.fill(HIST("h_DFcount_Lvl0"), kProcessOnlyOccMultExtra); + if (collisions.size() == 0) { + return; + } + if (!buildOnlyOccsMultExtra && !buildFullOccTableProducer) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: buildOnlyOccsMultExtra == false"; + return; + } + if (occs.size() == 0) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: OccsMultExtra.size() == 0 :: Check \"occupancy-table-producer\" for \"buildOnlyOccsMultExtra == true\" & \"processOnlyOccMultExtra == true\""; + return; + } + executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, processInThisBlock[kProcessOnlyOccMultExtra]); + occupancyQA.fill(HIST("h_DFcount_Lvl1"), kProcessOnlyOccMultExtra); + } + PROCESS_SWITCH(TrackMeanOccTableProducer, processOnlyOccMultExtra, "processOnlyOccMultExtra", false); + + void processOnlyRobustT0V0Prim(soa::Join const& BCs, aod::Collisions const& collisions, aod::Tracks const& tracks, MyTracksQA const& tracksQA, aod::ORT0V0Prim const& occsRobustT0V0Prim) + { + processStatus[kProcessOnlyRobustT0V0Prim] = true; + bool singleProcessOn = true; + checkAllProcessFunctionStatus(processStatus, singleProcessOn); + if (singleProcessOn) { + processInThisBlock[kProcessOnlyRobustT0V0Prim] = true; + } + occupancyQA.fill(HIST("h_DFcount_Lvl0"), kProcessOnlyRobustT0V0Prim); + if (collisions.size() == 0) { + return; + } + if (!buildOnlyOccsRobustT0V0Prim && !buildFullOccTableProducer) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: buildOnlyOccsRobustT0V0Prim == false"; + return; + } + if (occsRobustT0V0Prim.size() == 0) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: OccsRobustT0V0Prim.size() == 0 :: Check \"occupancy-table-producer\" for \"buildOnlyOccsT0V0Prim == true\" & \"processOnlyOccT0V0PrimUnfm == true\""; + return; + } + executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occsRobustT0V0Prim, processInThisBlock[kProcessOnlyRobustT0V0Prim]); + occupancyQA.fill(HIST("h_DFcount_Lvl1"), kProcessOnlyRobustT0V0Prim); + } + PROCESS_SWITCH(TrackMeanOccTableProducer, processOnlyRobustT0V0Prim, "processOnlyRobustT0V0Prim", false); + + void processOnlyRobustFDDT0V0Prim(soa::Join const& BCs, aod::Collisions const& collisions, aod::Tracks const& tracks, MyTracksQA const& tracksQA, aod::ORT0V0Prim const& occsRobustT0V0Prim, aod::ORFDDT0V0Prim const& occs) + { + processStatus[kProcessOnlyRobustFDDT0V0Prim] = true; + bool singleProcessOn = true; + checkAllProcessFunctionStatus(processStatus, singleProcessOn); + if (singleProcessOn) { + processInThisBlock[kProcessOnlyRobustFDDT0V0Prim] = true; + } + occupancyQA.fill(HIST("h_DFcount_Lvl0"), kProcessOnlyRobustFDDT0V0Prim); + if (collisions.size() == 0) { + return; + } + if (!buildOnlyOccsRobustFDDT0V0Prim && !buildFullOccTableProducer) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: buildOnlyOccsRobustFDDT0V0Prim == false"; + return; + } + if (occs.size() == 0) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: OccsRobustFDDT0V0Prim.size() == 0 :: Check \"occupancy-table-producer\" for \"buildOnlyOccsFDDT0V0Prim == true\" & \"processOnlyOccFDDT0V0PrimUnfm == true\""; + return; + } + executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, processInThisBlock[kProcessOnlyRobustFDDT0V0Prim]); + occupancyQA.fill(HIST("h_DFcount_Lvl1"), kProcessOnlyRobustFDDT0V0Prim); + } + PROCESS_SWITCH(TrackMeanOccTableProducer, processOnlyRobustFDDT0V0Prim, "processOnlyRobustFDDT0V0Prim", false); + + void processOnlyRobustNtrackDet(soa::Join const& BCs, aod::Collisions const& collisions, aod::Tracks const& tracks, MyTracksQA const& tracksQA, aod::ORT0V0Prim const& occsRobustT0V0Prim, aod::ORNtrackDet const& occs) + { + processStatus[kProcessOnlyRobustNtrackDet] = true; + bool singleProcessOn = true; + checkAllProcessFunctionStatus(processStatus, singleProcessOn); + if (singleProcessOn) { + processInThisBlock[kProcessOnlyRobustNtrackDet] = true; + } + occupancyQA.fill(HIST("h_DFcount_Lvl0"), kProcessOnlyRobustNtrackDet); + if (collisions.size() == 0) { + return; + } + if (!buildOnlyOccsRobustNtrackDet && !buildFullOccTableProducer) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: buildOnlyOccsRobustNtrackDet == false"; + return; + } + if (occs.size() == 0) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: OccsRobustNtrackDet.size() == 0 :: Check \"occupancy-table-producer\" for \"buildOnlyOccsNtrackDet == true\" & \"processOnlyOccNtrackDet == true\""; + return; + } + executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, processInThisBlock[kProcessOnlyRobustNtrackDet]); + occupancyQA.fill(HIST("h_DFcount_Lvl1"), kProcessOnlyRobustNtrackDet); + } + PROCESS_SWITCH(TrackMeanOccTableProducer, processOnlyRobustNtrackDet, "processOnlyRobustNtrackDet", false); + + void processOnlyRobustMultExtra(soa::Join const& BCs, aod::Collisions const& collisions, aod::Tracks const& tracks, MyTracksQA const& tracksQA, aod::ORT0V0Prim const& occsRobustT0V0Prim, aod::ORMultExtra const& occs) + { + processStatus[kProcessOnlyRobustMultExtra] = true; + bool singleProcessOn = true; + checkAllProcessFunctionStatus(processStatus, singleProcessOn); + if (singleProcessOn) { + processInThisBlock[kProcessOnlyRobustMultExtra] = true; + } + occupancyQA.fill(HIST("h_DFcount_Lvl0"), kProcessOnlyRobustMultExtra); + if (collisions.size() == 0) { + return; + } + if (!buildOnlyOccsRobustMultExtra && !buildFullOccTableProducer) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: buildOnlyOccsRobustMultExtra == false"; + return; + } + if (occs.size() == 0) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: OccsRobustMultExtra.size() == 0 :: Check \"occupancy-table-producer\" for \"buildOnlyOccsMultExtra == true\" & \"processOnlyOccMultExtra == true\""; + return; + } + executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, processInThisBlock[kProcessOnlyRobustMultExtra]); + occupancyQA.fill(HIST("h_DFcount_Lvl1"), kProcessOnlyRobustMultExtra); + } + PROCESS_SWITCH(TrackMeanOccTableProducer, processOnlyRobustMultExtra, "processOnlyRobustMultExtra", false); + + using JoinedOccTables = soa::Join; + void processFullOccTableProduer(soa::Join const& BCs, aod::Collisions const& collisions, aod::Tracks const& tracks, MyTracksQA const& tracksQA, aod::ORT0V0Prim const& occsRobustT0V0Prim, JoinedOccTables const& occs) + { + processStatus[kProcessFullOccTableProducer] = true; + bool singleProcessOn = true; + checkAllProcessFunctionStatus(processStatus, singleProcessOn); + if (singleProcessOn) { + processInThisBlock[kProcessFullOccTableProducer] = true; + } + if (!singleProcessOn) { + LOG(error) << "More than one process functions are on in track-mean-occ-table-producer"; + return; + } + occupancyQA.fill(HIST("h_DFcount_Lvl0"), kProcessFullOccTableProducer); + if (collisions.size() == 0) { + return; + } + if (!buildFullOccTableProducer) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: buildFullOccTableProducer == false"; + return; + } + if (occs.size() == 0) { + LOG(error) << "DEBUG :: ERROR ERROR ERROR :: Full Occ Table Join size is 0 :: Check \"occupancy-table-producer\" for \"buildFullOccTableProducer == true\" & \"processFullOccTableProduer == true\""; + return; + } + executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, processInThisBlock[kProcessFullOccTableProducer]); + occupancyQA.fill(HIST("h_DFcount_Lvl1"), kProcessFullOccTableProducer); } // Process function ends + PROCESS_SWITCH(TrackMeanOccTableProducer, processFullOccTableProduer, "processFullOccTableProduer", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/Common/TableProducer/trackPropagationTester.cxx b/Common/TableProducer/trackPropagationTester.cxx index 3787c19ee19..694ff77d3c0 100644 --- a/Common/TableProducer/trackPropagationTester.cxx +++ b/Common/TableProducer/trackPropagationTester.cxx @@ -9,12 +9,19 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +/// \file trackPropagationTester.cxx +/// \brief testing ground for track propagation +/// \author ALICE + +//=============================================================== +// +// Experimental version of the track propagation task +// this utilizes an analysis task module that can be employed elsewhere +// and allows for the re-utilization of a material LUT // -// Task to add a table of track parameters propagated to the primary vertex +// candidate approach for core service approach // -// FIXME: THIS IS AN EXPERIMENTAL TASK, MEANT ONLY FOR EXPLORATORY PURPOSES. -// FIXME: PLEASE ONLY USE IT WITH EXTREME CARE. IF IN DOUBT, STICK WITH THE DEFAULT -// FIXME: TRACKPROPAGATION +//=============================================================== #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" @@ -30,10 +37,10 @@ #include "DataFormatsParameters/GRPMagField.h" #include "CCDB/BasicCCDBManager.h" #include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" #include "DataFormatsCalibration/MeanVertexObject.h" #include "CommonConstants/GeomConstants.h" -#include "trackSelectionRequest.h" +#include "Common/Tools/TrackPropagationModule.h" +#include "Common/Tools/StandardCCDBLoader.h" // The Run 3 AO2D stores the tracks at the point of innermost update. For a track with ITS this is the innermost (or second innermost) // ITS layer. For a track without ITS, this is the TPC inner wall or for loopers in the TPC even a radius beyond that. @@ -48,294 +55,45 @@ using namespace o2::framework; // using namespace o2::framework::expressions; struct TrackPropagationTester { - Produces tracksParPropagated; - Produces tracksParExtensionPropagated; - - Produces tracksParCovPropagated; - Produces tracksParCovExtensionPropagated; - - Produces tracksDCA; + o2::common::StandardCCDBLoaderConfigurables standardCCDBLoaderConfigurables; + o2::common::TrackPropagationProducts trackPropagationProducts; + o2::common::TrackPropagationConfigurables trackPropagationConfigurables; + // CCDB boilerplate declarations + o2::framework::Configurable ccdburl{"ccdburl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Service ccdb; - HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - - bool fillTracksDCA = false; - int runNumber = -1; - - o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; - - const o2::dataformats::MeanVertexObject* mVtx = nullptr; - o2::parameters::GRPMagField* grpmag = nullptr; - o2::base::MatLayerCylSet* lut = nullptr; + o2::common::StandardCCDBLoader ccdbLoader; + o2::common::TrackPropagationModule trackPropagation; - // Track selection object in this scope: not necessarily a configurable - trackSelectionRequest trackSels; - // Configurable based on a struct - // Configurable trackSels{"trackSels", {}, "track selections"}; - - Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; - Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; - Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable mVtxPath{"mVtxPath", "GLO/Calib/MeanVertex", "Path of the mean vertex file"}; - Configurable minPropagationRadius{"minPropagationDistance", o2::constants::geom::XTPCInnerRef + 0.1, "Only tracks which are at a smaller radius will be propagated, defaults to TPC inner wall"}; - - // Configurables regarding what to propagate - // FIXME: This is dangerous and error prone for general purpose use. It is meant ONLY for testing. - Configurable propagateUnassociated{"propagateUnassociated", false, "propagate tracks with no collision assoc"}; - Configurable propagateTPConly{"propagateTPConly", false, "propagate tracks with only TPC (no ITS, TRD, TOF)"}; - Configurable minTPCClusters{"minTPCClusters", 70, "min number of TPC clusters to propagate"}; - Configurable maxPropagStep{"maxPropagStep", 2.0, "max propag step"}; // to be checked systematically - // use auto-detect configuration - Configurable d_UseAutodetectMode{"d_UseAutodetectMode", false, "Autodetect requested track criteria"}; - - bool hasEnding(std::string const& fullString, std::string const& ending) - { - if (fullString.length() >= ending.length()) { - return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending)); - } else { - return false; - } - } + HistogramRegistry registry{"registry"}; void init(o2::framework::InitContext& initContext) { - const AxisSpec axisX{(int)4, 0.0f, +4.0f, "Track counter"}; - histos.add("hTrackCounter", "hTrackCounter", kTH1F, {axisX}); - - if (doprocessCovariance == true && doprocessStandard == true) { - LOGF(fatal, "Cannot enable processStandard and processCovariance at the same time. Please choose one."); - } - - // Checking if the tables are requested in the workflow and enabling them - auto& workflows = initContext.services().get(); - for (DeviceSpec const& device : workflows.devices) { - for (auto const& input : device.inputs) { - if (input.matcher.binding == "TracksDCA") { - fillTracksDCA = true; - } - } - } - - ccdb->setURL(ccdburl); + // CCDB boilerplate init ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); + ccdb->setURL(ccdburl.value); - lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(lutPath)); - - if (d_UseAutodetectMode) { - LOGF(info, "*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*"); - LOGF(info, " Track propagator self-configuration"); - LOGF(info, "*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*"); - trackSels.SetTightSelections(); // Only loosen from this point forward - for (DeviceSpec const& device : workflows.devices) { - // Loop over options to find track selection - for (auto const& option : device.options) { - if (hasEnding(option.name, ".requireTPC")) { - bool lVal = option.defaultValue.get(); - LOGF(info, "Device %s, request TPC: %i", device.name, lVal); - if (trackSels.getRequireTPC() == false) - trackSels.setRequireTPC(lVal); - } - if (hasEnding(option.name, ".minTPCclusters")) { - int lVal = option.defaultValue.get(); - LOGF(info, "Device %s, min TPC clusters: %i", device.name, lVal); - if (trackSels.getMinTPCClusters() > lVal) - trackSels.setMinTPCClusters(lVal); - } - if (hasEnding(option.name, ".minTPCcrossedrows")) { - int lVal = option.defaultValue.get(); - LOGF(info, "Device %s, min TPC crossed rows: %i", device.name, lVal); - if (trackSels.getMinTPCCrossedRows() > lVal) - trackSels.setMinTPCCrossedRows(lVal); - } - if (hasEnding(option.name, ".minTPCcrossedrowsoverfindable")) { - float lVal = option.defaultValue.get(); - LOGF(info, "Device %s, min TPC crossed rows over findable: %.3f", device.name, lVal); - if (trackSels.getMinTPCCrossedRowsOverFindable() > lVal) - trackSels.setMinTPCCrossedRowsOverFindable(lVal); - } - if (hasEnding(option.name, ".requireITS")) { - bool lVal = option.defaultValue.get(); - LOGF(info, "Device %s, request ITS: %i", device.name, lVal); - if (trackSels.getRequireITS() == false) - trackSels.setRequireITS(lVal); - } - if (hasEnding(option.name, ".minITSclusters")) { - int lVal = option.defaultValue.get(); - LOGF(info, "Device %s, minimum ITS clusters: %i", device.name, lVal); - if (trackSels.getMinITSClusters() > lVal) - trackSels.setMinITSClusters(lVal); - } - if (hasEnding(option.name, ".maxITSChi2percluster")) { - float lVal = option.defaultValue.get(); - LOGF(info, "Device %s, max ITS chi2/clu: %.3f", device.name, lVal); - if (trackSels.getMaxITSChi2PerCluster() < lVal) - trackSels.setMaxITSChi2PerCluster(lVal); - } - } - } - LOGF(info, "-+*> Automatic self-config ended. Final settings:"); - trackSels.PrintSelections(); - } - } - - void initCCDB(aod::BCsWithTimestamps::iterator const& bc) - { - if (runNumber == bc.runNumber()) { - return; - } - grpmag = ccdb->getForTimeStamp(grpmagPath, bc.timestamp()); - LOG(info) << "Setting magnetic field to current " << grpmag->getL3Current() << " A for run " << bc.runNumber() << " from its GRPMagField CCDB object"; - o2::base::Propagator::initFieldFromGRP(grpmag); - o2::base::Propagator::Instance()->setMatLUT(lut); - if (propagateUnassociated) - mVtx = ccdb->getForTimeStamp(mVtxPath, bc.timestamp()); - runNumber = bc.runNumber(); + // task-specific + trackPropagation.init(trackPropagationConfigurables, registry, initContext); } - template - void FillTracksPar(TTrack& track, aod::track::TrackTypeEnum trackType, TTrackPar& trackPar) + void processReal(aod::Collisions const& collisions, soa::Join const& tracks, aod::Collisions const&, aod::BCs const& bcs) { - tracksParPropagated(track.collisionId(), trackType, trackPar.getX(), trackPar.getAlpha(), trackPar.getY(), trackPar.getZ(), trackPar.getSnp(), trackPar.getTgl(), trackPar.getQ2Pt()); - tracksParExtensionPropagated(trackPar.getPt(), trackPar.getP(), trackPar.getEta(), trackPar.getPhi()); + // task-specific + ccdbLoader.initCCDBfromBCs(standardCCDBLoaderConfigurables, ccdb, bcs); + trackPropagation.fillTrackTables(trackPropagationConfigurables, ccdbLoader, collisions, tracks, trackPropagationProducts, registry); } + PROCESS_SWITCH(TrackPropagationTester, processReal, "Process Real Data", true); - void processStandard(soa::Join const& tracks, aod::Collisions const&, aod::BCsWithTimestamps const& bcs) + // ----------------------- + void processMc(aod::Collisions const& collisions, soa::Join const& tracks, aod::McParticles const&, aod::Collisions const&, aod::BCs const& bcs) { - if (bcs.size() == 0) { - return; - } - initCCDB(bcs.begin()); - - std::array dcaInfo; - - int lNAll = 0; - int lNaccTPC = 0; - int lNaccNotTPCOnly = 0; - int lNPropagated = 0; - bool passTPCclu = kFALSE; - bool passNotTPCOnly = kFALSE; - - for (auto& track : tracks) { - // Selection criteria - passTPCclu = kFALSE; - passNotTPCOnly = kFALSE; - lNAll++; - if (track.tpcNClsFound() >= minTPCClusters) { - passTPCclu = kTRUE; - lNaccTPC++; - } - if ((track.hasTPC() && !track.hasITS() && !track.hasTRD() && !track.hasTOF()) || propagateTPConly) { - passNotTPCOnly = kTRUE; - lNaccNotTPCOnly++; - } - - dcaInfo[0] = 999; - dcaInfo[1] = 999; - aod::track::TrackTypeEnum trackType = (aod::track::TrackTypeEnum)track.trackType(); - auto trackPar = getTrackPar(track); - // Only propagate tracks which have passed the innermost wall of the TPC (e.g. skipping loopers etc). Others fill unpropagated. - if (track.trackType() == aod::track::TrackIU && track.x() < minPropagationRadius && passTPCclu && passNotTPCOnly) { - if (track.has_collision()) { - auto const& collision = track.collision(); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackPar, maxPropagStep, matCorr, &dcaInfo); - trackType = aod::track::Track; - lNPropagated++; - } else { - if (propagateUnassociated) { - o2::base::Propagator::Instance()->propagateToDCABxByBz({mVtx->getX(), mVtx->getY(), mVtx->getZ()}, trackPar, maxPropagStep, matCorr, &dcaInfo); - trackType = aod::track::Track; - lNPropagated++; - } - } - } - FillTracksPar(track, trackType, trackPar); - if (fillTracksDCA) { - tracksDCA(dcaInfo[0], dcaInfo[1]); - } - } - // Fill only per table (not per track). ROOT FindBin is slow - histos.fill(HIST("hTrackCounter"), 0.5, lNAll); - histos.fill(HIST("hTrackCounter"), 1.5, lNaccTPC); - histos.fill(HIST("hTrackCounter"), 2.5, lNaccNotTPCOnly); - histos.fill(HIST("hTrackCounter"), 3.5, lNPropagated); - } - PROCESS_SWITCH(TrackPropagationTester, processStandard, "Process without covariance", true); - - void processCovariance(soa::Join const& tracks, aod::Collisions const&, aod::BCsWithTimestamps const& bcs) - { - if (bcs.size() == 0) { - return; - } - initCCDB(bcs.begin()); - - o2::dataformats::DCA dcaInfoCov; - o2::dataformats::VertexBase vtx; - - int lNAll = 0; - int lNaccTPC = 0; - int lNaccNotTPCOnly = 0; - int lNPropagated = 0; - bool passTPCclu = kFALSE; - bool passNotTPCOnly = kFALSE; - - for (auto& track : tracks) { - // Selection criteria - passTPCclu = kFALSE; - passNotTPCOnly = kFALSE; - lNAll++; - if (track.tpcNClsFound() >= minTPCClusters) { - passTPCclu = kTRUE; - lNaccTPC++; - } - if ((track.hasTPC() && !track.hasITS() && !track.hasTRD() && !track.hasTOF()) || propagateTPConly) { - passNotTPCOnly = kTRUE; - lNaccNotTPCOnly++; - } - - dcaInfoCov.set(999, 999, 999, 999, 999); - auto trackParCov = getTrackParCov(track); - aod::track::TrackTypeEnum trackType = (aod::track::TrackTypeEnum)track.trackType(); - // Only propagate tracks which have passed the innermost wall of the TPC (e.g. skipping loopers etc). Others fill unpropagated. - if (track.trackType() == aod::track::TrackIU && track.x() < minPropagationRadius && passTPCclu && passNotTPCOnly) { - if (track.has_collision()) { - auto const& collision = track.collision(); - vtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); - vtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(vtx, trackParCov, maxPropagStep, matCorr, &dcaInfoCov); - trackType = aod::track::Track; - lNPropagated++; - } else { - if (propagateUnassociated) { - vtx.setPos({mVtx->getX(), mVtx->getY(), mVtx->getZ()}); - vtx.setCov(mVtx->getSigmaX() * mVtx->getSigmaX(), 0.0f, mVtx->getSigmaY() * mVtx->getSigmaY(), 0.0f, 0.0f, mVtx->getSigmaZ() * mVtx->getSigmaZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(vtx, trackParCov, maxPropagStep, matCorr, &dcaInfoCov); - trackType = aod::track::Track; - lNPropagated++; - } - } - } - FillTracksPar(track, trackType, trackParCov); - if (fillTracksDCA) { - tracksDCA(dcaInfoCov.getY(), dcaInfoCov.getZ()); - } - // TODO do we keep the rho as 0? Also the sigma's are duplicated information - tracksParCovPropagated(std::sqrt(trackParCov.getSigmaY2()), std::sqrt(trackParCov.getSigmaZ2()), std::sqrt(trackParCov.getSigmaSnp2()), - std::sqrt(trackParCov.getSigmaTgl2()), std::sqrt(trackParCov.getSigma1Pt2()), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - tracksParCovExtensionPropagated(trackParCov.getSigmaY2(), trackParCov.getSigmaZY(), trackParCov.getSigmaZ2(), trackParCov.getSigmaSnpY(), - trackParCov.getSigmaSnpZ(), trackParCov.getSigmaSnp2(), trackParCov.getSigmaTglY(), trackParCov.getSigmaTglZ(), trackParCov.getSigmaTglSnp(), - trackParCov.getSigmaTgl2(), trackParCov.getSigma1PtY(), trackParCov.getSigma1PtZ(), trackParCov.getSigma1PtSnp(), trackParCov.getSigma1PtTgl(), - trackParCov.getSigma1Pt2()); - } - // Fill only per table (not per track). ROOT FindBin is slow - histos.fill(HIST("hTrackCounter"), 0.5, lNAll); - histos.fill(HIST("hTrackCounter"), 1.5, lNaccTPC); - histos.fill(HIST("hTrackCounter"), 2.5, lNaccNotTPCOnly); - histos.fill(HIST("hTrackCounter"), 3.5, lNPropagated); + ccdbLoader.initCCDBfromBCs(standardCCDBLoaderConfigurables, ccdb, bcs); + trackPropagation.fillTrackTables(trackPropagationConfigurables, ccdbLoader, collisions, tracks, trackPropagationProducts, registry); } - PROCESS_SWITCH(TrackPropagationTester, processCovariance, "Process with covariance", false); + PROCESS_SWITCH(TrackPropagationTester, processMc, "Process Monte Carlo", false); }; //**************************************************************************************** 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..1f210249089 --- /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 + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "Framework/ASoAHelpers.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CCDBTimeStampUtils.h" +#include "CommonUtils/NameConf.h" +#include "CommonUtils/ConfigurableParam.h" +#include "DataFormatsMCH/Cluster.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DetectorsBase/GRPGeomHelper.h" +#include "DetectorsBase/Propagator.h" +#include "Field/MagneticField.h" +#include "MathUtils/Cartesian.h" +#include "MCHGeometryTransformer/Transformations.h" +#include "MCHTracking/Track.h" +#include "MCHTracking/TrackExtrap.h" +#include "MCHTracking/TrackParam.h" +#include "MCHTracking/TrackFitter.h" +#include "MCHBase/TrackerParam.h" +#include "GlobalTracking/MatchGlobalFwd.h" +#include "ReconstructionDataFormats/TrackFwd.h" +#include "Common/DataModel/FwdTrackReAlignTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/CollisionAssociationTables.h" + +#include "TGeoGlobalMagField.h" +#include "Math/Vector4D.h" + +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/Common/Tools/MultModule.h b/Common/Tools/MultModule.h new file mode 100644 index 00000000000..cbdc9dc1711 --- /dev/null +++ b/Common/Tools/MultModule.h @@ -0,0 +1,1320 @@ +// 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 MultModule.h +/// \brief combined multiplicity + centrality module with autodetect features +/// \author ALICE + +#ifndef COMMON_TOOLS_MULTMODULE_H_ +#define COMMON_TOOLS_MULTMODULE_H_ + +#include +#include +#include +#include +#include +#include "Framework/AnalysisDataModel.h" +#include "Framework/Configurable.h" +#include "Framework/HistogramSpec.h" +#include "TableHelper.h" +#include "Common/Core/TPCVDriftManager.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/Centrality.h" +#include "PWGMM/Mult/DataModel/bestCollisionTable.h" +#include "TFormula.h" + +//__________________________________________ +// MultModule + +namespace o2 +{ +namespace common +{ +namespace multiplicity +{ + +// statics necessary for the configurables in this namespace +static constexpr int nParameters = 1; +static const std::vector tableNames{ + // multiplicity subcomponent + "FV0Mults", + "FV0AOuterMults", + "FT0Mults", + "FDDMults", + "ZDCMults", + "TrackletMults", + "TPCMults", + "PVMults", + "MultsExtra", + "MultSelections", + "FV0MultZeqs", + "FT0MultZeqs", + "FDDMultZeqs", + "PVMultZeqs", + "MultMCExtras", + "kMult2MCExtras", + "kMFTMults", + "kMultsGlobal", + + // centrality subcomponent + "CentRun2V0Ms", + "CentRun2V0As", + "CentRun2SPDTrks", + "CentRun2SPDClss", + "CentRun2CL0s", + "CentRun2CL1s", + "CentFV0As", + "CentFT0Ms", + "CentFT0As", + "CentFT0Cs", + "CentFT0CVariant1s", + "CentFDDMs", + "CentNTPVs", + "CentNGlobals", + "CentMFTs", + "BCCentFT0Ms", + "BCCentFT0As", + "BCCentFT0Cs"}; + +static constexpr int nTablesConst = 36; + +static const std::vector parameterNames{"enable"}; +static const int defaultParameters[nTablesConst][nParameters]{ + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}, + {-1}}; + +// table index : match order above +enum tableIndex { kFV0Mults, // standard + kFV0AOuterMults, // standard + kFT0Mults, // standard + kFDDMults, // standard + kZDCMults, // standard + kTrackletMults, // Run 2 + kTPCMults, // standard + kPVMults, // standard + kMultsExtra, // standard + kMultSelections, // event selection + kFV0MultZeqs, // zeq calib, standard + kFT0MultZeqs, // zeq calib, standard + kFDDMultZeqs, // zeq calib, standard + kPVMultZeqs, // zeq calib, standard + kMultMCExtras, // MC exclusive + kMult2MCExtras, // MC exclusive + kMFTMults, // requires MFT task + kMultsGlobal, // requires track selection task + + // centrality subcomponent + kCentRun2V0Ms, // Run 2 + kCentRun2V0As, // Run 2 + kCentRun2SPDTrks, // Run 2 + kCentRun2SPDClss, // Run 2 + kCentRun2CL0s, // Run 2 + kCentRun2CL1s, // Run 2 + kCentFV0As, // standard Run 3 + kCentFT0Ms, // standard Run 3 + kCentFT0As, // standard Run 3 + kCentFT0Cs, // standard Run 3 + kCentFT0CVariant1s, // standard Run 3 + kCentFDDMs, // standard Run 3 + kCentNTPVs, // standard Run 3 + kCentNGlobals, // requires track selection task + kCentMFTs, // requires MFT task + kBCCentFT0Ms, // bc centrality + kBCCentFT0As, // bc centrality + kBCCentFT0Cs, // bc centrality + kNTables }; + +struct products : o2::framework::ProducesGroup { + //__________________________________________________ + // multiplicity tables + o2::framework::Produces tableFV0; + o2::framework::Produces tableFV0AOuter; + o2::framework::Produces tableFT0; + o2::framework::Produces tableFDD; + o2::framework::Produces tableZDC; + o2::framework::Produces tableTracklet; + o2::framework::Produces tableTpc; + o2::framework::Produces tablePv; + o2::framework::Produces tableExtra; + o2::framework::Produces multSelections; + o2::framework::Produces tableFV0Zeqs; + o2::framework::Produces tableFT0Zeqs; + o2::framework::Produces tableFDDZeqs; + o2::framework::Produces tablePVZeqs; + o2::framework::Produces tableExtraMc; + o2::framework::Produces tableExtraMult2MCExtras; + o2::framework::Produces mftMults; + o2::framework::Produces multsGlobal; + + //__________________________________________________ + // centrality tables (per collision / default) + o2::framework::Produces centRun2V0M; + o2::framework::Produces centRun2V0A; + o2::framework::Produces centRun2SPDTracklets; + o2::framework::Produces centRun2SPDClusters; + o2::framework::Produces centRun2CL0; + o2::framework::Produces centRun2CL1; + o2::framework::Produces centFV0A; + o2::framework::Produces centFT0M; + o2::framework::Produces centFT0A; + o2::framework::Produces centFT0C; + o2::framework::Produces centFT0CVariant1; + o2::framework::Produces centFDDM; + o2::framework::Produces centNTPV; + o2::framework::Produces centNGlobals; + o2::framework::Produces centMFTs; + o2::framework::Produces bcCentFT0A; + o2::framework::Produces bcCentFT0C; + o2::framework::Produces bcCentFT0M; + + //__________________________________________________ + // centrality tables per BC + // FIXME - future development +}; + +// for providing temporary buffer +// FIXME ideally cursors could be readable +// to avoid duplicate memory allocation but ok +struct multEntry { + float multFV0A = 0.0f; + float multFV0C = 0.0f; + float multFV0AOuter = 0.0f; + float multFT0A = 0.0f; + float multFT0C = 0.0f; + float multFDDA = 0.0f; + float multFDDC = 0.0f; + float multZNA = 0.0f; + float multZNC = 0.0f; + float multZEM1 = 0.0f; + float multZEM2 = 0.0f; + float multZPA = 0.0f; + float multZPC = 0.0f; + int multTracklets = 0; + + int multNContribs = 0; // PVMult 0.8 + int multNContribsEta1 = 0; // PVMult 1.0 + int multNContribsEtaHalf = 0; // PVMult 0.5 + int multTPC = 0; // all TPC (PV contrib unchecked) + int multHasTPC = 0; // extras + int multHasITS = 0; // extras + int multHasTOF = 0; // extras + int multHasTRD = 0; // extras + int multITSOnly = 0; // extras + int multTPCOnly = 0; // extras + int multITSTPC = 0; // extras + int multAllTracksTPCOnly = 0; // extras + int multAllTracksITSTPC = 0; // extras + + float multFV0AZeq = -999.0f; + float multFV0CZeq = -999.0f; + float multFT0AZeq = -999.0f; + float multFT0CZeq = -999.0f; + float multFDDAZeq = -999.0f; + float multFDDCZeq = -999.0f; + float multNContribsZeq = 0; + + int multGlobalTracks = 0; // multsGlobal + int multNbrContribsEta05GlobalTrackWoDCA = 0; // multsGlobal + int multNbrContribsEta08GlobalTrackWoDCA = 0; // multsGlobal + int multNbrContribsEta10GlobalTrackWoDCA = 0; // multsGlobal + + int multMFTAllTracks = 0; // mft + int multMFTTracks = 0; // mft + + // For Run2 only + float posZ = -999.0f; + uint16_t spdClustersL0 = 0; + uint16_t spdClustersL1 = 0; +}; + +// strangenessBuilder: 1st-order configurables +struct standardConfigurables : o2::framework::ConfigurableGroup { + // self-configuration configurables + o2::framework::Configurable> enabledTables{"enabledTables", + {defaultParameters[0], nTablesConst, nParameters, tableNames, parameterNames}, + "Produce this table: -1 for autodetect; otherwise, 0/1 is false/true"}; + std::vector mEnabledTables; // Vector of enabled tables + + // Autoconfigure process functions + o2::framework::Configurable autoConfigureProcess{"autoConfigureProcess", false, "if true, will configure process function switches based on metadata"}; + + // do vertex-Z equalized or not + o2::framework::Configurable doVertexZeq{"doVertexZeq", 1, "if 1: do vertex Z eq mult table"}; + + // global track counter configurables + o2::framework::Configurable minPtGlobalTrack{"minPtGlobalTrack", 0.15, "min. pT for global tracks"}; + o2::framework::Configurable maxPtGlobalTrack{"maxPtGlobalTrack", 1e+10, "max. pT for global tracks"}; + o2::framework::Configurable minNclsITSGlobalTrack{"minNclsITSGlobalTrack", 5, "min. number of ITS clusters for global tracks"}; + o2::framework::Configurable minNclsITSibGlobalTrack{"minNclsITSibGlobalTrack", 1, "min. number of ITSib clusters for global tracks"}; + + // ccdb information + o2::framework::Configurable ccdbPathVtxZ{"ccdbPathVtxZ", "Centrality/Calibration", "The CCDB path for vertex-Z calibration"}; + o2::framework::Configurable ccdbPathCentrality{"ccdbPathCentrality", "Centrality/Estimators", "The CCDB path for centrality information"}; + o2::framework::Configurable reconstructionPass{"reconstructionPass", "", {"Apass to use when fetching the calibration tables. Empty (default) does not check for any pass. Use `metadata` to fetch it from the AO2D metadata. Otherwise it will override the metadata."}}; + + // centrality operation + o2::framework::Configurable generatorName{"generatorName", "", {"Specify if and only if this is MC. Typical: PYTHIA"}}; + o2::framework::Configurable embedINELgtZEROselection{"embedINELgtZEROselection", false, {"Option to do percentile 100.5 if not INELgtZERO"}}; +}; + +class MultModule +{ + public: + MultModule() + { + // constructor + mRunNumber = 0; + mRunNumberCentrality = 0; + lCalibLoaded = false; + lCalibObjects = nullptr; + hVtxZFV0A = nullptr; + hVtxZFT0A = nullptr; + hVtxZFT0C = nullptr; + hVtxZFDDA = nullptr; + hVtxZFDDC = nullptr; + hVtxZNTracks = nullptr; + } + + // internal: calib related, vtx-z profiles + int mRunNumber; + int mRunNumberCentrality; + bool lCalibLoaded; + TList* lCalibObjects; + TProfile* hVtxZFV0A; + TProfile* hVtxZFT0A; + TProfile* hVtxZFT0C; + TProfile* hVtxZFDDA; + TProfile* hVtxZFDDC; + TProfile* hVtxZNTracks; + + // declaration of structs here + // (N.B.: will be invisible to the outside, create your own copies) + o2::common::multiplicity::standardConfigurables internalOpts; + + //_________________________________________________ + // centrality-related objects + struct TagRun2V0MCalibration { + bool mCalibrationStored = false; + TFormula* mMCScale = nullptr; + float mMCScalePars[6] = {0.0}; + TH1* mhVtxAmpCorrV0A = nullptr; + TH1* mhVtxAmpCorrV0C = nullptr; + TH1* mhMultSelCalib = nullptr; + } Run2V0MInfo; + struct TagRun2V0ACalibration { + bool mCalibrationStored = false; + TH1* mhVtxAmpCorrV0A = nullptr; + TH1* mhMultSelCalib = nullptr; + } Run2V0AInfo; + struct TagRun2SPDTrackletsCalibration { + bool mCalibrationStored = false; + TH1* mhVtxAmpCorr = nullptr; + TH1* mhMultSelCalib = nullptr; + } Run2SPDTksInfo; + struct TagRun2SPDClustersCalibration { + bool mCalibrationStored = false; + TH1* mhVtxAmpCorrCL0 = nullptr; + TH1* mhVtxAmpCorrCL1 = nullptr; + TH1* mhMultSelCalib = nullptr; + } Run2SPDClsInfo; + struct TagRun2CL0Calibration { + bool mCalibrationStored = false; + TH1* mhVtxAmpCorr = nullptr; + TH1* mhMultSelCalib = nullptr; + } Run2CL0Info; + struct TagRun2CL1Calibration { + bool mCalibrationStored = false; + TH1* mhVtxAmpCorr = nullptr; + TH1* mhMultSelCalib = nullptr; + } Run2CL1Info; + struct CalibrationInfo { + std::string name = ""; + bool mCalibrationStored = false; + TH1* mhMultSelCalib = nullptr; + float mMCScalePars[6] = {0.0}; + TFormula* mMCScale = nullptr; + explicit CalibrationInfo(std::string name) + : name(name), + mCalibrationStored(false), + mhMultSelCalib(nullptr), + mMCScalePars{0.0}, + mMCScale(nullptr) + { + } + bool isSane(bool fatalize = false) + { + if (!mhMultSelCalib) { + return true; + } + for (int i = 1; i < mhMultSelCalib->GetNbinsX() + 1; i++) { + if (mhMultSelCalib->GetXaxis()->GetBinLowEdge(i) > mhMultSelCalib->GetXaxis()->GetBinUpEdge(i)) { + if (fatalize) { + LOG(fatal) << "Centrality calibration table " << name << " has bins with low edge > up edge"; + } + LOG(warning) << "Centrality calibration table " << name << " has bins with low edge > up edge"; + return false; + } + } + return true; + } + }; + + CalibrationInfo fv0aInfo = CalibrationInfo("FV0"); + CalibrationInfo ft0mInfo = CalibrationInfo("FT0"); + CalibrationInfo ft0aInfo = CalibrationInfo("FT0A"); + CalibrationInfo ft0cInfo = CalibrationInfo("FT0C"); + CalibrationInfo ft0cVariant1Info = CalibrationInfo("FT0Cvar1"); + CalibrationInfo fddmInfo = CalibrationInfo("FDD"); + CalibrationInfo ntpvInfo = CalibrationInfo("NTracksPV"); + CalibrationInfo nGlobalInfo = CalibrationInfo("NGlobal"); + CalibrationInfo mftInfo = CalibrationInfo("MFT"); + + template + void init(TConfigurables& opts, TInitContext& context) + { + // read in configurations from the task where it's used + internalOpts = opts; + internalOpts.mEnabledTables.resize(nTablesConst, 0); + + LOGF(info, "Configuring tables to generate"); + auto& workflows = context.services().template get(); + + TString listOfRequestors[nTablesConst]; + for (int i = 0; i < nTablesConst; i++) { + int f = internalOpts.enabledTables->get(tableNames[i].c_str(), "enable"); + if (f == 1) { + internalOpts.mEnabledTables[i] = 1; + listOfRequestors[i] = "manual enabling"; + } + if (f == -1) { + // autodetect this table in other devices + for (o2::framework::DeviceSpec const& device : workflows.devices) { + // Step 1: check if this device subscribed to the V0data table + for (auto const& input : device.inputs) { + if (o2::framework::DataSpecUtils::partialMatch(input.matcher, o2::header::DataOrigin("AOD"))) { + auto&& [origin, description, version] = o2::framework::DataSpecUtils::asConcreteDataMatcher(input.matcher); + std::string tableNameWithVersion = tableNames[i]; + if (version > 0) { + tableNameWithVersion += Form("_%03d", version); + } + if (input.matcher.binding == tableNameWithVersion) { + LOGF(info, "Device %s has subscribed to %s (version %i)", device.name, tableNames[i], version); + listOfRequestors[i].Append(Form("%s ", device.name.c_str())); + internalOpts.mEnabledTables[i] = 1; + } + } + } + } + } + } + + opts = internalOpts; + + // list enabled tables + for (int i = 0; i < nTablesConst; i++) { + // printout to be improved in the future + if (internalOpts.mEnabledTables[i]) { + LOGF(info, " -~> Table enabled: %s, requested by %s", tableNames[i], listOfRequestors[i].Data()); + } + } + + mRunNumber = 0; + mRunNumberCentrality = 0; + lCalibLoaded = false; + hVtxZFV0A = nullptr; + hVtxZFT0A = nullptr; + hVtxZFT0C = nullptr; + hVtxZFDDA = nullptr; + hVtxZFDDC = nullptr; + hVtxZNTracks = nullptr; + } + + //__________________________________________________ + template + o2::common::multiplicity::multEntry collisionProcessRun2(TCollision const& collision, TTracks const& tracks, TBC const& bc, TOutputGroup& cursors) + { + // initialize properties + o2::common::multiplicity::multEntry mults; + + mults.posZ = collision.posZ(); + mults.spdClustersL0 = bc.spdClustersL0(); + mults.spdClustersL1 = bc.spdClustersL1(); + //_______________________________________________________________________ + // forward detector signals, raw + if (collision.has_fv0a()) { + for (const auto& amplitude : collision.fv0a().amplitude()) { + mults.multFV0A += amplitude; + } + } + if (collision.has_fv0c()) { + for (const auto& amplitude : collision.fv0c().amplitude()) { + mults.multFV0C += amplitude; + } + } + if (collision.has_ft0()) { + auto ft0 = collision.ft0(); + for (const auto& amplitude : ft0.amplitudeA()) { + mults.multFT0A += amplitude; + } + for (const auto& amplitude : ft0.amplitudeC()) { + mults.multFT0C += amplitude; + } + } + if (collision.has_zdc()) { + auto zdc = collision.zdc(); + mults.multZNA = zdc.energyCommonZNA(); + mults.multZNC = zdc.energyCommonZNC(); + } + + //_______________________________________________________________________ + // determine if barrel track loop is required, do it (once!) if so but save CPU if not + if (internalOpts.mEnabledTables[kPVMults] || internalOpts.mEnabledTables[kTPCMults] || internalOpts.mEnabledTables[kTrackletMults]) { + // Try to do something Similar to https://github.com/alisw/AliPhysics/blob/22862a945004f719f8e9664c0264db46e7186a48/OADB/AliPPVsMultUtils.cxx#L541C26-L541C37 + for (const auto& track : tracks) { + // check whether the track is a tracklet + if (track.trackType() == o2::aod::track::Run2Tracklet) { + if (internalOpts.mEnabledTables[kTrackletMults]) { + mults.multTracklets++; + } + if (internalOpts.mEnabledTables[kPVMults]) { + if (std::abs(track.eta()) < 1.0) { + mults.multNContribsEta1++; // pvmults + if (std::abs(track.eta()) < 0.8) { + mults.multNContribs++; // pvmults + if (std::abs(track.eta()) < 0.5) { + mults.multNContribsEtaHalf++; // pvmults + } + } + } + } + } + // check whether the track is a global ITS-TPC track + if (track.tpcNClsFindable() > 0) { + if (internalOpts.mEnabledTables[kTPCMults]) { + mults.multTPC++; + } + } + } + } + + // fill standard cursors if required + if (internalOpts.mEnabledTables[kFV0Mults]) { + cursors.tableFV0(mults.multFV0A, mults.multFV0C); + } + if (internalOpts.mEnabledTables[kFT0Mults]) { + cursors.tableFT0(mults.multFT0A, mults.multFT0C); + } + if (internalOpts.mEnabledTables[kFDDMults]) { + cursors.tableFDD(mults.multFDDA, mults.multFDDC); + } + if (internalOpts.mEnabledTables[kZDCMults]) { + cursors.tableZDC(mults.multZNA, mults.multZNC, 0.0f, 0.0f, 0.0f, 0.0f); + } + if (internalOpts.mEnabledTables[kTrackletMults]) { // Tracklets only Run2 + cursors.tableTracklet(mults.multTracklets); + } + if (internalOpts.mEnabledTables[kTPCMults]) { + cursors.tableTpc(mults.multTPC); + } + if (internalOpts.mEnabledTables[kPVMults]) { + cursors.tablePv(mults.multNContribs, mults.multNContribsEta1, mults.multNContribsEtaHalf); + } + + return mults; + } + + //__________________________________________________ + template + o2::common::multiplicity::multEntry collisionProcessRun3(TCCDB const& ccdb, TMetadataInfo const& metadataInfo, TCollision const& collision, TTracks const& tracks, TBC const& bc, TOutputGroup& cursors) + { + // initialize properties + o2::common::multiplicity::multEntry mults; + + //_______________________________________________________________________ + // preparatory steps + if (internalOpts.doVertexZeq > 0) { + if (bc.runNumber() != mRunNumber) { + mRunNumber = bc.runNumber(); // mark this run as at least tried + if (internalOpts.reconstructionPass.value == "") { + lCalibObjects = ccdb->template getForRun(internalOpts.ccdbPathVtxZ, mRunNumber); + } else if (internalOpts.reconstructionPass.value == "metadata") { + std::map metadata; + metadata["RecoPassName"] = metadataInfo.get("RecoPassName"); + LOGF(info, "Loading CCDB for reconstruction pass (from metadata): %s", metadataInfo.get("RecoPassName")); + lCalibObjects = ccdb->template getSpecificForRun(internalOpts.ccdbPathVtxZ, mRunNumber, metadata); + } else { + std::map metadata; + metadata["RecoPassName"] = internalOpts.reconstructionPass.value; + LOGF(info, "Loading CCDB for reconstruction pass (from provided argument): %s", internalOpts.reconstructionPass.value); + lCalibObjects = ccdb->template getSpecificForRun(internalOpts.ccdbPathVtxZ, mRunNumber, metadata); + } + + if (lCalibObjects) { + hVtxZFV0A = static_cast(lCalibObjects->FindObject("hVtxZFV0A")); + hVtxZFT0A = static_cast(lCalibObjects->FindObject("hVtxZFT0A")); + hVtxZFT0C = static_cast(lCalibObjects->FindObject("hVtxZFT0C")); + hVtxZFDDA = static_cast(lCalibObjects->FindObject("hVtxZFDDA")); + hVtxZFDDC = static_cast(lCalibObjects->FindObject("hVtxZFDDC")); + hVtxZNTracks = static_cast(lCalibObjects->FindObject("hVtxZNTracksPV")); + lCalibLoaded = true; + // Capture error + if (!hVtxZFV0A || !hVtxZFT0A || !hVtxZFT0C || !hVtxZFDDA || !hVtxZFDDC || !hVtxZNTracks) { + LOGF(error, "Problem loading CCDB objects! Please check"); + lCalibLoaded = false; + } + } else { + LOGF(error, "Problem loading CCDB object! Please check"); + lCalibLoaded = false; + } + } + } + + //_______________________________________________________________________ + // forward detector signals, raw + if (collision.has_foundFV0()) { + const auto& fv0 = collision.foundFV0(); + for (size_t ii = 0; ii < fv0.amplitude().size(); ii++) { + auto amplitude = fv0.amplitude()[ii]; + auto channel = fv0.channel()[ii]; + mults.multFV0A += amplitude; + if (channel > 7) { + mults.multFV0AOuter += amplitude; + } + } + } else { + mults.multFV0A = -999.f; + mults.multFV0AOuter = -999.f; + } + if (collision.has_foundFT0()) { + const auto& ft0 = collision.foundFT0(); + for (const auto& amplitude : ft0.amplitudeA()) { + mults.multFT0A += amplitude; + } + for (const auto& amplitude : ft0.amplitudeC()) { + mults.multFT0C += amplitude; + } + } else { + mults.multFT0A = -999.f; + mults.multFT0C = -999.f; + } + if (collision.has_foundFDD()) { + const auto& fdd = collision.foundFDD(); + for (const auto& amplitude : fdd.chargeA()) { + mults.multFDDA += amplitude; + } + for (const auto& amplitude : fdd.chargeC()) { + mults.multFDDC += amplitude; + } + } else { + mults.multFDDA = -999.f; + mults.multFDDC = -999.f; + } + if (bc.has_zdc()) { + mults.multZNA = bc.zdc().amplitudeZNA(); + mults.multZNC = bc.zdc().amplitudeZNC(); + mults.multZEM1 = bc.zdc().amplitudeZEM1(); + mults.multZEM2 = bc.zdc().amplitudeZEM2(); + mults.multZPA = bc.zdc().amplitudeZPA(); + mults.multZPC = bc.zdc().amplitudeZPC(); + } else { + mults.multZNA = -999.f; + mults.multZNC = -999.f; + mults.multZEM1 = -999.f; + mults.multZEM2 = -999.f; + mults.multZPA = -999.f; + mults.multZPC = -999.f; + } + + // fill standard cursors if required + if (internalOpts.mEnabledTables[kTrackletMults]) { // Tracklets (only Run2) nothing to do (to be removed!) + cursors.tableTracklet(0); + } + if (internalOpts.mEnabledTables[kFV0Mults]) { + cursors.tableFV0(mults.multFV0A, mults.multFV0C); + } + if (internalOpts.mEnabledTables[kFV0AOuterMults]) { + cursors.tableFV0AOuter(mults.multFV0AOuter); + } + if (internalOpts.mEnabledTables[kFT0Mults]) { + cursors.tableFT0(mults.multFT0A, mults.multFT0C); + } + if (internalOpts.mEnabledTables[kFDDMults]) { + cursors.tableFDD(mults.multFDDA, mults.multFDDC); + } + if (internalOpts.mEnabledTables[kZDCMults]) { + cursors.tableZDC(mults.multZNA, mults.multZNC, mults.multZEM1, mults.multZEM2, mults.multZPA, mults.multZPC); + } + + //_______________________________________________________________________ + // forward detector signals, vertex-Z equalized + if (internalOpts.mEnabledTables[kFV0MultZeqs]) { + if (std::fabs(collision.posZ() && lCalibLoaded)) { + mults.multFV0AZeq = hVtxZFV0A->Interpolate(0.0) * mults.multFV0A / hVtxZFV0A->Interpolate(collision.posZ()); + } else { + mults.multFV0AZeq = 0.0f; + } + cursors.tableFV0Zeqs(mults.multFV0AZeq); + } + if (internalOpts.mEnabledTables[kFT0MultZeqs]) { + if (std::fabs(collision.posZ() && lCalibLoaded)) { + mults.multFT0AZeq = hVtxZFT0A->Interpolate(0.0) * mults.multFT0A / hVtxZFT0A->Interpolate(collision.posZ()); + mults.multFT0CZeq = hVtxZFT0C->Interpolate(0.0) * mults.multFT0C / hVtxZFT0C->Interpolate(collision.posZ()); + } else { + mults.multFT0AZeq = 0.0f; + mults.multFT0CZeq = 0.0f; + } + cursors.tableFT0Zeqs(mults.multFT0AZeq, mults.multFT0CZeq); + } + if (internalOpts.mEnabledTables[kFDDMultZeqs]) { + if (std::fabs(collision.posZ() && lCalibLoaded)) { + mults.multFDDAZeq = hVtxZFDDA->Interpolate(0.0) * mults.multFDDA / hVtxZFDDA->Interpolate(collision.posZ()); + mults.multFDDCZeq = hVtxZFDDC->Interpolate(0.0) * mults.multFDDC / hVtxZFDDC->Interpolate(collision.posZ()); + } else { + mults.multFDDAZeq = 0.0f; + mults.multFDDCZeq = 0.0f; + } + cursors.tableFDDZeqs(mults.multFDDAZeq, mults.multFDDCZeq); + } + + //_______________________________________________________________________ + // determine if barrel track loop is required, do it (once!) if so but save CPU if not + if (internalOpts.mEnabledTables[kTPCMults] || internalOpts.mEnabledTables[kPVMults] || internalOpts.mEnabledTables[kMultsExtra] || internalOpts.mEnabledTables[kPVMultZeqs] || internalOpts.mEnabledTables[kMultsGlobal]) { + // single loop to calculate all + for (const auto& track : tracks) { + if (track.hasTPC()) { + mults.multTPC++; + if (track.hasITS()) { + mults.multAllTracksITSTPC++; // multsextra + } else { + mults.multAllTracksTPCOnly++; // multsextra + } + } + // PV contributor checked explicitly + if (track.isPVContributor()) { + if (std::abs(track.eta()) < 1.0) { + mults.multNContribsEta1++; // pvmults + if (std::abs(track.eta()) < 0.8) { + mults.multNContribs++; // pvmults + if (std::abs(track.eta()) < 0.5) { + mults.multNContribsEtaHalf++; // pvmults + } + } + } + if (track.hasITS()) { + mults.multHasITS++; // multsextra + if (track.hasTPC()) + mults.multITSTPC++; // multsextra + if (!track.hasTPC() && !track.hasTOF() && !track.hasTRD()) { + mults.multITSOnly++; // multsextra + } + } + if (track.hasTPC()) { + mults.multHasTPC++; // multsextra + if (!track.hasITS() && !track.hasTOF() && !track.hasTRD()) { + mults.multTPCOnly++; // multsextra + } + } + if (track.hasTOF()) { + mults.multHasTOF++; // multsextra + } + if (track.hasTRD()) { + mults.multHasTRD++; // multsextra + } + } + + // global counters: do them only in case information is provided in tracks table + if constexpr (requires { tracks.isQualityTrack(); }) { + if (track.pt() < internalOpts.maxPtGlobalTrack.value && track.pt() > internalOpts.minPtGlobalTrack.value && std::fabs(track.eta()) < 1.0f && track.isPVContributor() && tracks.isQualityTrack()) { + if (track.itsNCls() < internalOpts.minNclsITSGlobalTrack || track.itsNClsInnerBarrel() < internalOpts.minNclsITSibGlobalTrack) { + continue; + } + mults.multNbrContribsEta10GlobalTrackWoDCA++; + + if (std::abs(track.eta()) < 0.8) { + mults.multNbrContribsEta08GlobalTrackWoDCA++; + } + if (std::abs(track.eta()) < 0.5) { + mults.multNbrContribsEta05GlobalTrackWoDCA++; + } + } + if (std::fabs(track.eta()) < 0.8 && track.tpcNClsFound() >= 80 && track.tpcNClsCrossedRows() >= 100) { + if (track.isGlobalTrack()) { + mults.multGlobalTracks++; + } + } + } // end constexpr requires track selection stuff + } + + cursors.multsGlobal(mults.multGlobalTracks, mults.multNbrContribsEta08GlobalTrackWoDCA, mults.multNbrContribsEta10GlobalTrackWoDCA, mults.multNbrContribsEta05GlobalTrackWoDCA); + } + + // fill track counters at this stage if requested + if (internalOpts.mEnabledTables[kTPCMults]) { + cursors.tableTpc(mults.multTPC); + } + if (internalOpts.mEnabledTables[kPVMults]) { + cursors.tablePv(mults.multNContribs, mults.multNContribsEta1, mults.multNContribsEtaHalf); + } + if (internalOpts.mEnabledTables[kMultsExtra]) { + cursors.tableExtra(collision.numContrib(), collision.chi2(), collision.collisionTimeRes(), + bc.runNumber(), collision.posZ(), collision.sel8(), + mults.multHasITS, mults.multHasTPC, mults.multHasTOF, mults.multHasTRD, + mults.multITSOnly, mults.multTPCOnly, mults.multITSTPC, + mults.multAllTracksTPCOnly, mults.multAllTracksITSTPC, + collision.trackOccupancyInTimeRange(), + collision.ft0cOccupancyInTimeRange(), + collision.flags()); + } + if (internalOpts.mEnabledTables[kPVMultZeqs]) { + if (std::fabs(collision.posZ()) && lCalibLoaded) { + mults.multNContribsZeq = hVtxZNTracks->Interpolate(0.0) * mults.multNContribs / hVtxZNTracks->Interpolate(collision.posZ()); + } else { + mults.multNContribsZeq = 0.0f; + } + cursors.tablePVZeqs(mults.multNContribsZeq); + } + + // return multiplicity object such that it is handled properly when computing centrality + return mults; + } + + //__________________________________________________ + template + void collisionProcessMonteCarlo(TMCCollision const& mccollision, TMCParticles const& mcparticles, TPDGService const& pdg, TOutputGroup& cursors) + { + int multFT0A = 0; + int multFV0A = 0; + int multFT0C = 0; + int multFDDA = 0; + int multFDDC = 0; + int multBarrelEta05 = 0; + int multBarrelEta08 = 0; + int multBarrelEta10 = 0; + for (auto const& mcPart : mcparticles) { + if (!mcPart.isPhysicalPrimary()) { + continue; + } + + auto charge = 0.; + auto* p = pdg->GetParticle(mcPart.pdgCode()); + if (p != nullptr) { + charge = p->Charge(); + } + if (std::abs(charge) < 1e-3) { + continue; // reject neutral particles in counters + } + + if (std::abs(mcPart.eta()) < 1.0) { + multBarrelEta10++; + if (std::abs(mcPart.eta()) < 0.8) { + multBarrelEta08++; + if (std::abs(mcPart.eta()) < 0.5) { + multBarrelEta05++; + } + } + } + if (-3.3 < mcPart.eta() && mcPart.eta() < -2.1) + multFT0C++; + if (3.5 < mcPart.eta() && mcPart.eta() < 4.9) + multFT0A++; + if (2.2 < mcPart.eta() && mcPart.eta() < 5.0) + multFV0A++; + if (-6.9 < mcPart.eta() && mcPart.eta() < -4.9) + multFDDC++; + if (4.7 < mcPart.eta() && mcPart.eta() < 6.3) + multFDDA++; + } + cursors.tableExtraMc(multFT0A, multFT0C, multFV0A, multFDDA, multFDDC, multBarrelEta05, multBarrelEta08, multBarrelEta10, mccollision.posZ()); + } + + //__________________________________________________ + template + void collisionProcessMFT(TCollision const& collision, TMFTTracks const& mfttracks, TBestCollisionsFwd const& retracks, TMultBuffer& mults, TOutputGroup& cursors) + { + int nAllTracks = 0; + int nTracks = 0; + + for (const auto& track : mfttracks) { + if (track.nClusters() >= 5) { // hardcoded for now + nAllTracks++; + } + } + + if (retracks.size() > 0) { + for (const auto& retrack : retracks) { + auto track = retrack.mfttrack(); + if (track.nClusters() < 5) { + continue; // min cluster requirement + } + if ((track.eta() > -2.0f) && (track.eta() < -3.9f)) { + continue; // too far to be of true interest + } + if (std::abs(retrack.bestDCAXY()) > 2.0f) { + continue; // does not point to PV properly + } + nTracks++; + } + } + cursors.mftMults(nAllTracks, nTracks); + mults[collision.globalIndex()].multMFTAllTracks = nAllTracks; + mults[collision.globalIndex()].multMFTTracks = nTracks; + } + + //__________________________________________________ + template + void ConfigureCentralityRun2(TCCDB& ccdb, TMetadata const& metadataInfo, TBC const& bc) + { + if (bc.runNumber() != mRunNumberCentrality) { + mRunNumberCentrality = bc.runNumber(); // mark that this run has been attempted already regardless of outcome + LOGF(info, "centrality loading procedure for timestamp=%llu, run number=%d", bc.timestamp(), bc.runNumber()); + TList* callst = nullptr; + // Check if the ccdb path is a root file + if (internalOpts.ccdbPathCentrality.value.find(".root") != std::string::npos) { + TFile f(internalOpts.ccdbPathCentrality.value.c_str(), "READ"); + f.GetObject(internalOpts.reconstructionPass.value.c_str(), callst); + if (!callst) { + f.ls(); + LOG(fatal) << "No calibration list " << internalOpts.reconstructionPass.value << " found."; + } + } else { + if (internalOpts.reconstructionPass.value == "") { + callst = ccdb->template getForRun(internalOpts.ccdbPathCentrality, bc.runNumber()); + } else if (internalOpts.reconstructionPass.value == "metadata") { + std::map metadata; + metadata["RecoPassName"] = metadataInfo.get("RecoPassName"); + LOGF(info, "Loading CCDB for reconstruction pass (from metadata): %s", metadataInfo.get("RecoPassName")); + callst = ccdb->template getSpecificForRun(internalOpts.ccdbPathCentrality, bc.runNumber(), metadata); + } else { + std::map metadata; + metadata["RecoPassName"] = internalOpts.reconstructionPass.value; + LOGF(info, "Loading CCDB for reconstruction pass (from provided argument): %s", internalOpts.reconstructionPass.value); + callst = ccdb->template getSpecificForRun(internalOpts.ccdbPathCentrality, bc.runNumber(), metadata); + } + } + + Run2V0MInfo.mCalibrationStored = false; + Run2V0AInfo.mCalibrationStored = false; + Run2SPDTksInfo.mCalibrationStored = false; + Run2SPDClsInfo.mCalibrationStored = false; + Run2CL0Info.mCalibrationStored = false; + Run2CL1Info.mCalibrationStored = false; + if (callst != nullptr) { + 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; + }; + + if (internalOpts.mEnabledTables[kCentRun2V0Ms]) { + LOGF(debug, "Getting new histograms with %d run number for %d run number", mRunNumber, bc.runNumber()); + 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", internalOpts.generatorName->c_str()).Data()); + if ((Run2V0MInfo.mhVtxAmpCorrV0A != nullptr) && (Run2V0MInfo.mhVtxAmpCorrV0C != nullptr) && (Run2V0MInfo.mhMultSelCalib != nullptr)) { + if (internalOpts.generatorName->length() != 0) { + if (Run2V0MInfo.mMCScale != nullptr) { + for (int ixpar = 0; ixpar < 6; ++ixpar) { + Run2V0MInfo.mMCScalePars[ixpar] = Run2V0MInfo.mMCScale->GetParameter(ixpar); + } + } else { + // continue filling with non-valid values (105) + LOGF(info, "MC Scale information from V0M for run %d not available", bc.runNumber()); + } + } + Run2V0MInfo.mCalibrationStored = true; + } else { + // continue filling with non-valid values (105) + LOGF(info, "Calibration information from V0M for run %d corrupted, will fill V0M tables with dummy values", bc.runNumber()); + } + } + if (internalOpts.mEnabledTables[kCentRun2V0As]) { + LOGF(debug, "Getting new histograms with %d run number for %d run number", mRunNumber, bc.runNumber()); + Run2V0AInfo.mhVtxAmpCorrV0A = getccdb("hVtx_fAmplitude_V0A_Normalized"); + Run2V0AInfo.mhMultSelCalib = getccdb("hMultSelCalib_V0A"); + if ((Run2V0AInfo.mhVtxAmpCorrV0A != nullptr) && (Run2V0AInfo.mhMultSelCalib != nullptr)) { + Run2V0AInfo.mCalibrationStored = true; + } else { + // continue filling with non-valid values (105) + LOGF(info, "Calibration information from V0A for run %d corrupted, will fill V0A tables with dummy values", bc.runNumber()); + } + } + if (internalOpts.mEnabledTables[kCentRun2SPDTrks]) { + LOGF(debug, "Getting new histograms with %d run number for %d run number", mRunNumber, bc.runNumber()); + Run2SPDTksInfo.mhVtxAmpCorr = getccdb("hVtx_fnTracklets_Normalized"); + Run2SPDTksInfo.mhMultSelCalib = getccdb("hMultSelCalib_SPDTracklets"); + if ((Run2SPDTksInfo.mhVtxAmpCorr != nullptr) && (Run2SPDTksInfo.mhMultSelCalib != nullptr)) { + Run2SPDTksInfo.mCalibrationStored = true; + } else { + // continue filling with non-valid values (105) + LOGF(info, "Calibration information from SPD tracklets for run %d corrupted, will fill SPD tracklets tables with dummy values", bc.runNumber()); + } + } + if (internalOpts.mEnabledTables[kCentRun2SPDClss]) { + LOGF(debug, "Getting new histograms with %d run number for %d run number", mRunNumber, bc.runNumber()); + Run2SPDClsInfo.mhVtxAmpCorrCL0 = getccdb("hVtx_fnSPDClusters0_Normalized"); + Run2SPDClsInfo.mhVtxAmpCorrCL1 = getccdb("hVtx_fnSPDClusters1_Normalized"); + Run2SPDClsInfo.mhMultSelCalib = getccdb("hMultSelCalib_SPDClusters"); + if ((Run2SPDClsInfo.mhVtxAmpCorrCL0 != nullptr) && (Run2SPDClsInfo.mhVtxAmpCorrCL1 != nullptr) && (Run2SPDClsInfo.mhMultSelCalib != nullptr)) { + Run2SPDClsInfo.mCalibrationStored = true; + } else { + // continue filling with non-valid values (105) + LOGF(info, "Calibration information from SPD clusters for run %d corrupted, will fill SPD clusters tables with dummy values", bc.runNumber()); + } + } + if (internalOpts.mEnabledTables[kCentRun2CL0s]) { + LOGF(debug, "Getting new histograms with %d run number for %d run number", mRunNumber, bc.runNumber()); + Run2CL0Info.mhVtxAmpCorr = getccdb("hVtx_fnSPDClusters0_Normalized"); + Run2CL0Info.mhMultSelCalib = getccdb("hMultSelCalib_CL0"); + if ((Run2CL0Info.mhVtxAmpCorr != nullptr) && (Run2CL0Info.mhMultSelCalib != nullptr)) { + Run2CL0Info.mCalibrationStored = true; + } else { + // continue filling with non-valid values (105) + LOGF(info, "Calibration information from CL0 multiplicity for run %d corrupted, will fill CL0 multiplicity tables with dummy values", bc.runNumber()); + } + } + if (internalOpts.mEnabledTables[kCentRun2CL1s]) { + LOGF(debug, "Getting new histograms with %d run number for %d run number", mRunNumber, bc.runNumber()); + Run2CL1Info.mhVtxAmpCorr = getccdb("hVtx_fnSPDClusters1_Normalized"); + Run2CL1Info.mhMultSelCalib = getccdb("hMultSelCalib_CL1"); + if ((Run2CL1Info.mhVtxAmpCorr != nullptr) && (Run2CL1Info.mhMultSelCalib != nullptr)) { + Run2CL1Info.mCalibrationStored = true; + } else { + // continue filling with non-valid values (105) + LOGF(info, "Calibration information from CL1 multiplicity for run %d corrupted, will fill CL1 multiplicity tables with dummy values", bc.runNumber()); + } + } + } else { + LOGF(info, "Centrality calibration is not available in CCDB for run=%d at timestamp=%llu, will fill tables with dummy values", bc.runNumber(), bc.timestamp()); + } + } + } + + //__________________________________________________ + template + void ConfigureCentralityRun3(TCCDB& ccdb, TMetadata const& metadataInfo, TBC const& bc) + { + if (bc.runNumber() != mRunNumberCentrality) { + mRunNumberCentrality = bc.runNumber(); // mark that this run has been attempted already regardless of outcome + LOGF(info, "centrality loading procedure for timestamp=%llu, run number=%d", bc.timestamp(), bc.runNumber()); + TList* callst = nullptr; + // Check if the ccdb path is a root file + if (internalOpts.ccdbPathCentrality.value.find(".root") != std::string::npos) { + TFile f(internalOpts.ccdbPathCentrality.value.c_str(), "READ"); + f.GetObject(internalOpts.reconstructionPass.value.c_str(), callst); + if (!callst) { + f.ls(); + LOG(fatal) << "No calibration list " << internalOpts.reconstructionPass.value << " found."; + } + } else { + if (internalOpts.reconstructionPass.value == "") { + callst = ccdb->template getForRun(internalOpts.ccdbPathCentrality, bc.runNumber()); + } else if (internalOpts.reconstructionPass.value == "metadata") { + std::map metadata; + metadata["RecoPassName"] = metadataInfo.get("RecoPassName"); + LOGF(info, "Loading CCDB for reconstruction pass (from metadata): %s", metadataInfo.get("RecoPassName")); + callst = ccdb->template getSpecificForRun(internalOpts.ccdbPathCentrality, bc.runNumber(), metadata); + } else { + std::map metadata; + metadata["RecoPassName"] = internalOpts.reconstructionPass.value; + LOGF(info, "Loading CCDB for reconstruction pass (from provided argument): %s", internalOpts.reconstructionPass.value); + callst = ccdb->template getSpecificForRun(internalOpts.ccdbPathCentrality, bc.runNumber(), metadata); + } + } + + fv0aInfo.mCalibrationStored = false; + ft0mInfo.mCalibrationStored = false; + ft0aInfo.mCalibrationStored = false; + ft0cInfo.mCalibrationStored = false; + ft0cVariant1Info.mCalibrationStored = false; + fddmInfo.mCalibrationStored = false; + ntpvInfo.mCalibrationStored = false; + nGlobalInfo.mCalibrationStored = false; + mftInfo.mCalibrationStored = false; + if (callst != nullptr) { + LOGF(info, "Getting new histograms with %d run number for %d run number", mRunNumber, bc.runNumber()); + auto getccdb = [callst, bc](struct CalibrationInfo& estimator, const o2::framework::Configurable generatorName) { // TODO: to consider the name inside the estimator structure + estimator.mhMultSelCalib = reinterpret_cast(callst->FindObject(TString::Format("hCalibZeq%s", estimator.name.c_str()).Data())); + estimator.mMCScale = reinterpret_cast(callst->FindObject(TString::Format("%s-%s", generatorName->c_str(), estimator.name.c_str()).Data())); + if (estimator.mhMultSelCalib != nullptr) { + if (generatorName->length() != 0) { + LOGF(info, "Retrieving MC calibration for %d, generator name: %s", bc.runNumber(), generatorName->c_str()); + if (estimator.mMCScale != nullptr) { + for (int ixpar = 0; ixpar < 6; ++ixpar) { + estimator.mMCScalePars[ixpar] = estimator.mMCScale->GetParameter(ixpar); + LOGF(info, "Parameter index %i value %.5f", ixpar, estimator.mMCScalePars[ixpar]); + } + } else { + LOGF(warning, "MC Scale information from %s for run %d not available", estimator.name.c_str(), bc.runNumber()); + } + } + estimator.mCalibrationStored = true; + estimator.isSane(); + } else { + LOGF(info, "Calibration information from %s for run %d not available, will fill this estimator with invalid values and continue (no crash).", estimator.name.c_str(), bc.runNumber()); + } + }; + + // invoke loading only for requested centralities + if (internalOpts.mEnabledTables[kCentFV0As]) + getccdb(fv0aInfo, internalOpts.generatorName); + if (internalOpts.mEnabledTables[kCentFT0Ms]) + getccdb(ft0mInfo, internalOpts.generatorName); + if (internalOpts.mEnabledTables[kCentFT0As]) + getccdb(ft0aInfo, internalOpts.generatorName); + if (internalOpts.mEnabledTables[kCentFT0Cs]) + getccdb(ft0cInfo, internalOpts.generatorName); + if (internalOpts.mEnabledTables[kCentFT0CVariant1s]) + getccdb(ft0cVariant1Info, internalOpts.generatorName); + if (internalOpts.mEnabledTables[kCentFDDMs]) + getccdb(fddmInfo, internalOpts.generatorName); + if (internalOpts.mEnabledTables[kCentNTPVs]) + getccdb(ntpvInfo, internalOpts.generatorName); + if (internalOpts.mEnabledTables[kCentNGlobals]) + getccdb(nGlobalInfo, internalOpts.generatorName); + if (internalOpts.mEnabledTables[kCentMFTs]) + getccdb(mftInfo, internalOpts.generatorName); + } else { + LOGF(info, "Centrality calibration is not available in CCDB for run=%d at timestamp=%llu, will fill tables with dummy values", bc.runNumber(), bc.timestamp()); + } + } + } + + //__________________________________________________ + template + void generateCentralitiesRun3(TCCDB& ccdb, TMetadata const& metadataInfo, TBCs const& bcs, TMultBuffer const& mults, TOutputGroup& cursors) + { + // takes multiplicity buffer and generates the desirable centrality values (if any) + + // first step: did someone actually ask for it? Otherwise, go home + if ( + internalOpts.mEnabledTables[kCentFV0As] || internalOpts.mEnabledTables[kCentFT0Ms] || + internalOpts.mEnabledTables[kCentFT0As] || internalOpts.mEnabledTables[kCentFT0Cs] || + internalOpts.mEnabledTables[kCentFT0CVariant1s] || internalOpts.mEnabledTables[kCentFDDMs] || + internalOpts.mEnabledTables[kCentNTPVs] || internalOpts.mEnabledTables[kCentNGlobals] || + internalOpts.mEnabledTables[kCentMFTs] || internalOpts.mEnabledTables[kBCCentFT0Ms] || + internalOpts.mEnabledTables[kBCCentFT0As] || internalOpts.mEnabledTables[kBCCentFT0Cs]) { + // check and update centrality calibration objects for Run 3 + const auto& firstbc = bcs.begin(); + ConfigureCentralityRun3(ccdb, metadataInfo, firstbc); + + /************************************************************ + * @brief Populates a table with data based on the given calibration information and multiplicity. + * + * @param table The table to populate. + * @param estimator The calibration information. + * @param multiplicity The multiplicity value. + *************************************************************/ + + auto populateTable = [&](auto& table, struct CalibrationInfo& estimator, float multiplicity, bool isInelGt0) { + const bool assignOutOfRange = internalOpts.embedINELgtZEROselection && !isInelGt0; + 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]); + }; + + float percentile = 105.0f; + float scaledMultiplicity = multiplicity; + if (estimator.mCalibrationStored) { + if (estimator.mMCScale != nullptr) { + scaledMultiplicity = scaleMC(multiplicity, estimator.mMCScalePars); + LOGF(debug, "Unscaled %s multiplicity: %f, scaled %s multiplicity: %f", estimator.name.c_str(), multiplicity, estimator.name.c_str(), scaledMultiplicity); + } + percentile = estimator.mhMultSelCalib->GetBinContent(estimator.mhMultSelCalib->FindFixBin(scaledMultiplicity)); + if (assignOutOfRange) + percentile = 100.5f; + } + LOGF(debug, "%s centrality/multiplicity percentile = %.0f for a zvtx eq %s value %.0f", estimator.name.c_str(), percentile, estimator.name.c_str(), scaledMultiplicity); + table(percentile); + return percentile; + }; + + // populate centralities per event + for (size_t iEv = 0; iEv < mults.size(); iEv++) { + bool isInelGt0 = (mults[iEv].multNContribsEta1 > 0); + if (internalOpts.mEnabledTables[kCentFV0As]) + populateTable(cursors.centFV0A, fv0aInfo, mults[iEv].multFV0AZeq, isInelGt0); + if (internalOpts.mEnabledTables[kCentFT0Ms]) + populateTable(cursors.centFT0M, ft0mInfo, mults[iEv].multFT0AZeq + mults[iEv].multFT0CZeq, isInelGt0); + if (internalOpts.mEnabledTables[kCentFT0As]) + populateTable(cursors.centFT0A, ft0aInfo, mults[iEv].multFT0AZeq, isInelGt0); + if (internalOpts.mEnabledTables[kCentFT0Cs]) + populateTable(cursors.centFT0C, ft0cInfo, mults[iEv].multFT0CZeq, isInelGt0); + if (internalOpts.mEnabledTables[kCentFT0CVariant1s]) + populateTable(cursors.centFT0CVariant1, ft0cVariant1Info, mults[iEv].multFT0CZeq, isInelGt0); + if (internalOpts.mEnabledTables[kCentFDDMs]) + populateTable(cursors.centFDDM, fddmInfo, mults[iEv].multFDDAZeq + mults[iEv].multFDDCZeq, isInelGt0); + if (internalOpts.mEnabledTables[kCentNTPVs]) + populateTable(cursors.centNTPV, ntpvInfo, mults[iEv].multNContribs, isInelGt0); + if (internalOpts.mEnabledTables[kCentNGlobals]) + populateTable(cursors.centNGlobals, nGlobalInfo, mults[iEv].multGlobalTracks, isInelGt0); + if (internalOpts.mEnabledTables[kCentMFTs]) + populateTable(cursors.centMFTs, mftInfo, mults[iEv].multMFTTracks, isInelGt0); + } + + // populate centralities per BC + for (size_t ibc = 0; ibc < bcs.size(); ibc++) { + float bcMultFT0A = 0; + float bcMultFT0C = 0; + + const auto& bc = bcs.rawIteratorAt(ibc); + if (bc.has_foundFT0()) { + const auto& ft0 = bc.foundFT0(); + for (const auto& amplitude : ft0.amplitudeA()) { + bcMultFT0A += amplitude; + } + for (const auto& amplitude : ft0.amplitudeC()) { + bcMultFT0C += amplitude; + } + } else { + bcMultFT0A = -999.f; + bcMultFT0C = -999.f; + } + + if (internalOpts.mEnabledTables[kBCCentFT0Ms]) + populateTable(cursors.bcCentFT0M, ft0mInfo, bcMultFT0A + bcMultFT0C, true); + if (internalOpts.mEnabledTables[kBCCentFT0As]) + populateTable(cursors.bcCentFT0A, ft0aInfo, bcMultFT0A, true); + if (internalOpts.mEnabledTables[kBCCentFT0Cs]) + populateTable(cursors.bcCentFT0C, ft0cInfo, bcMultFT0C, true); + } + } + } + //__________________________________________________ + template + void generateCentralitiesRun2(TCCDB& ccdb, TMetadata const& metadataInfo, TBCs const& bcs, TMultBuffer const& mults, TOutputGroup& cursors) + { + // takes multiplicity buffer and generates the desirable centrality values (if any) + // For Run 2 + if ( + internalOpts.mEnabledTables[kCentRun2V0Ms] || internalOpts.mEnabledTables[kCentRun2V0As] || + internalOpts.mEnabledTables[kCentRun2SPDTrks] || internalOpts.mEnabledTables[kCentRun2SPDClss] || + internalOpts.mEnabledTables[kCentRun2CL0s] || internalOpts.mEnabledTables[kCentRun2CL1s]) { + // check and update centrality calibration objects for Run 3 + const auto& firstbc = bcs.begin(); + ConfigureCentralityRun2(ccdb, metadataInfo, firstbc); + + 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]); + }; + + // populate centralities per event + for (size_t iEv = 0; iEv < mults.size(); iEv++) { + if (internalOpts.mEnabledTables[kCentRun2V0Ms]) { + float cV0M = 105.0f; + if (Run2V0MInfo.mCalibrationStored) { + float v0m; + if (Run2V0MInfo.mMCScale != nullptr) { + v0m = scaleMC(mults[iEv].multFV0A + mults[iEv].multFV0C, Run2V0MInfo.mMCScalePars); + LOGF(debug, "Unscaled v0m: %f, scaled v0m: %f", mults[iEv].multFV0A + mults[iEv].multFV0C, v0m); + } else { + v0m = mults[iEv].multFV0A * Run2V0MInfo.mhVtxAmpCorrV0A->GetBinContent(Run2V0MInfo.mhVtxAmpCorrV0A->FindFixBin(mults[iEv].posZ)) + + mults[iEv].multFV0C * Run2V0MInfo.mhVtxAmpCorrV0C->GetBinContent(Run2V0MInfo.mhVtxAmpCorrV0C->FindFixBin(mults[iEv].posZ)); + } + cV0M = Run2V0MInfo.mhMultSelCalib->GetBinContent(Run2V0MInfo.mhMultSelCalib->FindFixBin(v0m)); + } + LOGF(debug, "centRun2V0M=%.0f", cV0M); + // fill centrality columns + cursors.centRun2V0M(cV0M); + } + if (internalOpts.mEnabledTables[kCentRun2V0As]) { + float cV0A = 105.0f; + if (Run2V0AInfo.mCalibrationStored) { + float v0a = mults[iEv].multFV0A * Run2V0AInfo.mhVtxAmpCorrV0A->GetBinContent(Run2V0AInfo.mhVtxAmpCorrV0A->FindFixBin(mults[iEv].posZ)); + cV0A = Run2V0AInfo.mhMultSelCalib->GetBinContent(Run2V0AInfo.mhMultSelCalib->FindFixBin(v0a)); + } + LOGF(debug, "centRun2V0A=%.0f", cV0A); + // fill centrality columns + cursors.centRun2V0A(cV0A); + } + if (internalOpts.mEnabledTables[kCentRun2SPDTrks]) { + float cSPD = 105.0f; + if (Run2SPDTksInfo.mCalibrationStored) { + float spdm = mults[iEv].multTracklets * Run2SPDTksInfo.mhVtxAmpCorr->GetBinContent(Run2SPDTksInfo.mhVtxAmpCorr->FindFixBin(mults[iEv].posZ)); + cSPD = Run2SPDTksInfo.mhMultSelCalib->GetBinContent(Run2SPDTksInfo.mhMultSelCalib->FindFixBin(spdm)); + } + LOGF(debug, "centSPDTracklets=%.0f", cSPD); + cursors.centRun2SPDTracklets(cSPD); + } + if (internalOpts.mEnabledTables[kCentRun2SPDClss]) { + float cSPD = 105.0f; + if (Run2SPDClsInfo.mCalibrationStored) { + float spdm = mults[iEv].spdClustersL0 * Run2SPDClsInfo.mhVtxAmpCorrCL0->GetBinContent(Run2SPDClsInfo.mhVtxAmpCorrCL0->FindFixBin(mults[iEv].posZ)) + + mults[iEv].spdClustersL1 * Run2SPDClsInfo.mhVtxAmpCorrCL1->GetBinContent(Run2SPDClsInfo.mhVtxAmpCorrCL1->FindFixBin(mults[iEv].posZ)); + cSPD = Run2SPDClsInfo.mhMultSelCalib->GetBinContent(Run2SPDClsInfo.mhMultSelCalib->FindFixBin(spdm)); + } + LOGF(debug, "centSPDClusters=%.0f", cSPD); + cursors.centRun2SPDClusters(cSPD); + } + if (internalOpts.mEnabledTables[kCentRun2CL0s]) { + float cCL0 = 105.0f; + if (Run2CL0Info.mCalibrationStored) { + float cl0m = mults[iEv].spdClustersL0 * Run2CL0Info.mhVtxAmpCorr->GetBinContent(Run2CL0Info.mhVtxAmpCorr->FindFixBin(mults[iEv].posZ)); + cCL0 = Run2CL0Info.mhMultSelCalib->GetBinContent(Run2CL0Info.mhMultSelCalib->FindFixBin(cl0m)); + } + LOGF(debug, "centCL0=%.0f", cCL0); + cursors.centRun2CL0(cCL0); + } + if (internalOpts.mEnabledTables[kCentRun2CL1s]) { + float cCL1 = 105.0f; + if (Run2CL1Info.mCalibrationStored) { + float cl1m = mults[iEv].spdClustersL1 * Run2CL1Info.mhVtxAmpCorr->GetBinContent(Run2CL1Info.mhVtxAmpCorr->FindFixBin(mults[iEv].posZ)); + cCL1 = Run2CL1Info.mhMultSelCalib->GetBinContent(Run2CL1Info.mhMultSelCalib->FindFixBin(cl1m)); + } + LOGF(debug, "centCL1=%.0f", cCL1); + cursors.centRun2CL1(cCL1); + } + } + } + } +}; // end BuilderModule + +} // namespace multiplicity +} // namespace common +} // namespace o2 + +#endif // COMMON_TOOLS_MULTMODULE_H_ diff --git a/Common/Tools/StandardCCDBLoader.h b/Common/Tools/StandardCCDBLoader.h new file mode 100644 index 00000000000..6ba4c9be9a1 --- /dev/null +++ b/Common/Tools/StandardCCDBLoader.h @@ -0,0 +1,106 @@ +// 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 StandardCCDBLoader.cxx +/// \brief A simple object to handle ccdb queries +/// \author ALICE + +#ifndef COMMON_TOOLS_STANDARDCCDBLOADER_H_ +#define COMMON_TOOLS_STANDARDCCDBLOADER_H_ + +#include +#include +#include +#include +#include "Framework/AnalysisDataModel.h" + +//__________________________________________ +// Standard class to load stuff +// such as matLUT, B and mean Vertex +// partial requests possible. + +namespace o2 +{ +namespace common +{ + +// ConfigurableGroup with locations +struct StandardCCDBLoaderConfigurables : o2::framework::ConfigurableGroup { + std::string prefix = "ccdb"; + o2::framework::Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + o2::framework::Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; + o2::framework::Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + o2::framework::Configurable mVtxPath{"mVtxPath", "GLO/Calib/MeanVertex", "Path of the mean vertex file"}; +}; + +class StandardCCDBLoader +{ + public: + StandardCCDBLoader() + { + // constructor - null pointers + mMeanVtx = nullptr; + grpmag = nullptr; + lut = nullptr; + }; + + // commonly needed objects + const o2::dataformats::MeanVertexObject* mMeanVtx = nullptr; + o2::parameters::GRPMagField* grpmag = nullptr; + o2::base::MatLayerCylSet* lut = nullptr; + int runNumber = -1; + + template + void initCCDBfromBCs(TConfigurableGroup const& cGroup, TCCDB& ccdb, TBCs& bcs, bool getMeanVertex = true) + { + // instant load from BCs table. Bonus: protect also against empty bcs + if (bcs.size() == 0) { + return; + } + auto bc = bcs.begin(); + initCCDB(cGroup, ccdb, bc.runNumber(), getMeanVertex); + } + + template + void initCCDB(TConfigurableGroup const& cGroup, TCCDB& ccdb, int currentRunNumber, bool getMeanVertex = true) + { + if (runNumber == currentRunNumber) { + return; + } + + // load matLUT for this timestamp + if (!lut) { + LOG(info) << "Loading material look-up table for timestamp: " << currentRunNumber; + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->template getForRun(cGroup.lutPath.value, currentRunNumber)); + } else { + LOG(info) << "Material look-up table already in place. Not reloading."; + } + + grpmag = ccdb->template getForRun(cGroup.grpmagPath.value, currentRunNumber); + LOG(info) << "Setting global propagator magnetic field to current " << grpmag->getL3Current() << " A for run " << currentRunNumber << " from its GRPMagField CCDB object"; + o2::base::Propagator::initFieldFromGRP(grpmag); + LOG(info) << "Setting global propagator material propagation LUT"; + o2::base::Propagator::Instance()->setMatLUT(lut); + if (getMeanVertex) { + // only try this if explicitly requested + mMeanVtx = ccdb->template getForRun(cGroup.mVtxPath.value, currentRunNumber); + } else { + mMeanVtx = nullptr; + } + + runNumber = currentRunNumber; + } +}; + +} // namespace common +} // namespace o2 + +#endif // COMMON_TOOLS_STANDARDCCDBLOADER_H_ diff --git a/Common/Tools/TrackPropagationModule.h b/Common/Tools/TrackPropagationModule.h new file mode 100644 index 00000000000..fb957a87b9d --- /dev/null +++ b/Common/Tools/TrackPropagationModule.h @@ -0,0 +1,260 @@ +// 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 TrackPropagationModule.h +/// \brief track propagation module functionality to be used in tasks +/// \author ALICE + +#ifndef COMMON_TOOLS_TRACKPROPAGATIONMODULE_H_ +#define COMMON_TOOLS_TRACKPROPAGATIONMODULE_H_ + +#include +#include +#include +#include +#include +#include "Framework/AnalysisDataModel.h" +#include "Framework/Configurable.h" +#include "Framework/HistogramSpec.h" +#include "Common/Tools/TrackTuner.h" +#include "TableHelper.h" + +//__________________________________________ +// track propagation module +// +// this class is capable of performing the usual track propagation +// and table creation it is a demonstration of core service +// plug-in functionality that could be used to reduce the number of +// heavyweight (e.g. mat-LUT-using, propagating) core services to +// reduce overhead and make it easier to pipeline / parallelize +// bottlenecks in core services + +namespace o2 +{ +namespace common +{ + +struct TrackPropagationProducts : o2::framework::ProducesGroup { + o2::framework::Produces tracksParPropagated; + o2::framework::Produces tracksParExtensionPropagated; + o2::framework::Produces tracksParCovPropagated; + o2::framework::Produces tracksParCovExtensionPropagated; + o2::framework::Produces tracksDCA; + o2::framework::Produces tracksDCACov; + o2::framework::Produces tunertable; +}; + +struct TrackPropagationConfigurables : o2::framework::ConfigurableGroup { + std::string prefix = "trackPropagation"; + o2::framework::Configurable minPropagationRadius{"minPropagationDistance", o2::constants::geom::XTPCInnerRef + 0.1, "Only tracks which are at a smaller radius will be propagated, defaults to TPC inner wall"}; + // for TrackTuner only (MC smearing) + o2::framework::Configurable useTrackTuner{"useTrackTuner", false, "Apply track tuner corrections to MC"}; + o2::framework::Configurable useTrkPid{"useTrkPid", false, "use pid in tracking"}; + o2::framework::Configurable fillTrackTunerTable{"fillTrackTunerTable", false, "flag to fill track tuner table"}; + o2::framework::Configurable trackTunerConfigSource{"trackTunerConfigSource", aod::track_tuner::InputString, "1: input string; 2: TrackTuner Configurables"}; + o2::framework::Configurable trackTunerParams{"trackTunerParams", "debugInfo=0|updateTrackDCAs=1|updateTrackCovMat=1|updateCurvature=0|updateCurvatureIU=0|updatePulls=0|isInputFileFromCCDB=1|pathInputFile=Users/m/mfaggin/test/inputsTrackTuner/PbPb2022|nameInputFile=trackTuner_DataLHC22sPass5_McLHC22l1b2_run529397.root|pathFileQoverPt=Users/h/hsharma/qOverPtGraphs|nameFileQoverPt=D0sigma_Data_removal_itstps_MC_LHC22b1b.root|usePvRefitCorrections=0|qOverPtMC=-1.|qOverPtData=-1.", "TrackTuner parameter initialization (format: =|=)"}; + o2::framework::ConfigurableAxis axisPtQA{"axisPtQA", {o2::framework::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"}; +}; + +class TrackPropagationModule +{ + public: + TrackPropagationModule() + { + // constructor + } + + // controls behaviour + bool fillTracksCov = false; + bool fillTracksDCA = false; + bool fillTracksDCACov = false; + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + + // pointers to objs needed for operation + std::shared_ptr trackTunedTracks; + TrackTuner trackTunerObj; + + // Running variables + std::array mDcaInfo; + o2::dataformats::DCA mDcaInfoCov; + o2::dataformats::VertexBase mVtx; + o2::track::TrackParametrization mTrackPar; + o2::track::TrackParametrizationWithError mTrackParCov; + + template + void init(TConfigurableGroup const& cGroup, THistoRegistry& registry, TInitContext& initContext) + { + // Checking if the tables are requested in the workflow and enabling them + fillTracksCov = isTableRequiredInWorkflow(initContext, "TracksCov"); + fillTracksDCA = isTableRequiredInWorkflow(initContext, "TracksDCA"); + fillTracksDCACov = isTableRequiredInWorkflow(initContext, "TracksDCACov"); + + /// TrackTuner initialization + if (cGroup.useTrackTuner.value) { + std::string outputStringParams = ""; + switch (cGroup.trackTunerConfigSource.value) { + case o2::aod::track_tuner::InputString: + outputStringParams = trackTunerObj.configParams(cGroup.trackTunerParams.value); + break; + case o2::aod::track_tuner::Configurables: + outputStringParams = trackTunerObj.configParams(); + break; + + default: + LOG(fatal) << "TrackTuner configuration source not defined. Fix it! (Supported options: input string (1); Configurables (2))"; + break; + } + + trackTunerObj.getDcaGraphs(); + } + + trackTunedTracks = registry.template add("trackTunedTracks", "trackTunedTracks", o2::framework::kTH1D, {{1, 0.5f, 1.5f}}); + + // Histograms for track tuner + o2::framework::AxisSpec axisBinsDCA = {600, -0.15f, 0.15f, "#it{dca}_{xy} (cm)"}; + registry.template add("hDCAxyVsPtRec", "hDCAxyVsPtRec", o2::framework::kTH2F, {axisBinsDCA, cGroup.axisPtQA}); + registry.template add("hDCAxyVsPtMC", "hDCAxyVsPtMC", o2::framework::kTH2F, {axisBinsDCA, cGroup.axisPtQA}); + registry.template add("hDCAzVsPtRec", "hDCAzVsPtRec", o2::framework::kTH2F, {axisBinsDCA, cGroup.axisPtQA}); + registry.template add("hDCAzVsPtMC", "hDCAzVsPtMC", o2::framework::kTH2F, {axisBinsDCA, cGroup.axisPtQA}); + } + + template + void fillTrackTables(TConfigurableGroup const& cGroup, TCCDBLoader const& ccdbLoader, TCollisions const& collisions, TTracks const& tracks, TOutputGroup& cursors, THistoRegistry& registry) + { + if (fillTracksCov) { + cursors.tracksParCovPropagated.reserve(tracks.size()); + cursors.tracksParCovExtensionPropagated.reserve(tracks.size()); + if (fillTracksDCACov) { + cursors.tracksDCACov.reserve(tracks.size()); + } + } else { + cursors.tracksParPropagated.reserve(tracks.size()); + cursors.tracksParExtensionPropagated.reserve(tracks.size()); + if (fillTracksDCA) { + cursors.tracksDCA.reserve(tracks.size()); + } + } + + for (const auto& track : tracks) { + if (fillTracksCov) { + if (fillTracksDCA || fillTracksDCACov) { + mDcaInfoCov.set(999, 999, 999, 999, 999); + } + setTrackParCov(track, mTrackParCov); + if (cGroup.useTrkPid.value) { + mTrackParCov.setPID(track.pidForTracking()); + } + } else { + if (fillTracksDCA) { + mDcaInfo[0] = 999; + mDcaInfo[1] = 999; + } + setTrackPar(track, mTrackPar); + if (cGroup.useTrkPid.value) { + mTrackPar.setPID(track.pidForTracking()); + } + } + // auto trackParCov = getTrackParCov(track); + o2::aod::track::TrackTypeEnum trackType = (o2::aod::track::TrackTypeEnum)track.trackType(); + // std::array trackPxPyPz; + // std::array trackPxPyPzTuned = {0.0, 0.0, 0.0}; + double q2OverPtNew = -9999.; + // Only propagate tracks which have passed the innermost wall of the TPC (e.g. skipping loopers etc). Others fill unpropagated. + if (track.trackType() == o2::aod::track::TrackIU && track.x() < cGroup.minPropagationRadius.value) { + if (fillTracksCov) { + if constexpr (isMc) { // checking MC and fillCovMat block begins + // bool hasMcParticle = track.has_mcParticle(); + if (cGroup.useTrackTuner.value) { + trackTunedTracks->Fill(1); // all tracks + bool hasMcParticle = track.has_mcParticle(); + if (hasMcParticle) { + auto mcParticle = track.mcParticle(); + trackTunerObj.tuneTrackParams(mcParticle, mTrackParCov, matCorr, &mDcaInfoCov, trackTunedTracks); + q2OverPtNew = mTrackParCov.getQ2Pt(); + } + } + } // MC and fillCovMat block ends + } + bool isPropagationOK = true; + + if (track.has_collision()) { + auto const& collision = collisions.rawIteratorAt(track.collisionId()); + if (fillTracksCov) { + mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); + mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + isPropagationOK = o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, mTrackParCov, 2.f, matCorr, &mDcaInfoCov); + } else { + isPropagationOK = o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, mTrackPar, 2.f, matCorr, &mDcaInfo); + } + } else { + if (fillTracksCov) { + mVtx.setPos({ccdbLoader.mMeanVtx->getX(), ccdbLoader.mMeanVtx->getY(), ccdbLoader.mMeanVtx->getZ()}); + mVtx.setCov(ccdbLoader.mMeanVtx->getSigmaX() * ccdbLoader.mMeanVtx->getSigmaX(), 0.0f, ccdbLoader.mMeanVtx->getSigmaY() * ccdbLoader.mMeanVtx->getSigmaY(), 0.0f, 0.0f, ccdbLoader.mMeanVtx->getSigmaZ() * ccdbLoader.mMeanVtx->getSigmaZ()); + isPropagationOK = o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, mTrackParCov, 2.f, matCorr, &mDcaInfoCov); + } else { + isPropagationOK = o2::base::Propagator::Instance()->propagateToDCABxByBz({ccdbLoader.mMeanVtx->getX(), ccdbLoader.mMeanVtx->getY(), ccdbLoader.mMeanVtx->getZ()}, mTrackPar, 2.f, matCorr, &mDcaInfo); + } + } + if (isPropagationOK) { + trackType = o2::aod::track::Track; + } + // filling some QA histograms for track tuner test purpose + if (fillTracksCov) { + if constexpr (isMc) { // checking MC and fillCovMat block begins + if (track.has_mcParticle() && isPropagationOK) { + auto mcParticle1 = track.mcParticle(); + // && abs(mcParticle1.pdgCode())==211 + if (mcParticle1.isPhysicalPrimary()) { + registry.fill(HIST("hDCAxyVsPtRec"), mDcaInfoCov.getY(), mTrackParCov.getPt()); + registry.fill(HIST("hDCAxyVsPtMC"), mDcaInfoCov.getY(), mcParticle1.pt()); + registry.fill(HIST("hDCAzVsPtRec"), mDcaInfoCov.getZ(), mTrackParCov.getPt()); + registry.fill(HIST("hDCAzVsPtMC"), mDcaInfoCov.getZ(), mcParticle1.pt()); + } + } + } // MC and fillCovMat block ends + } + } + // Filling modified Q/Pt values at IU/production point by track tuner in track tuner table + if (cGroup.useTrackTuner.value && cGroup.fillTrackTunerTable.value) { + cursors.tunertable(q2OverPtNew); + } + // LOG(info) << " trackPropagation (this value filled in tuner table)--> " << q2OverPtNew; + if (fillTracksCov) { + cursors.tracksParPropagated(track.collisionId(), trackType, mTrackParCov.getX(), mTrackParCov.getAlpha(), mTrackParCov.getY(), mTrackParCov.getZ(), mTrackParCov.getSnp(), mTrackParCov.getTgl(), mTrackParCov.getQ2Pt()); + cursors.tracksParExtensionPropagated(mTrackParCov.getPt(), mTrackParCov.getP(), mTrackParCov.getEta(), mTrackParCov.getPhi()); + // TODO do we keep the rho as 0? Also the sigma's are duplicated information + cursors.tracksParCovPropagated(std::sqrt(mTrackParCov.getSigmaY2()), std::sqrt(mTrackParCov.getSigmaZ2()), std::sqrt(mTrackParCov.getSigmaSnp2()), + std::sqrt(mTrackParCov.getSigmaTgl2()), std::sqrt(mTrackParCov.getSigma1Pt2()), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + cursors.tracksParCovExtensionPropagated(mTrackParCov.getSigmaY2(), mTrackParCov.getSigmaZY(), mTrackParCov.getSigmaZ2(), mTrackParCov.getSigmaSnpY(), + mTrackParCov.getSigmaSnpZ(), mTrackParCov.getSigmaSnp2(), mTrackParCov.getSigmaTglY(), mTrackParCov.getSigmaTglZ(), mTrackParCov.getSigmaTglSnp(), + mTrackParCov.getSigmaTgl2(), mTrackParCov.getSigma1PtY(), mTrackParCov.getSigma1PtZ(), mTrackParCov.getSigma1PtSnp(), mTrackParCov.getSigma1PtTgl(), + mTrackParCov.getSigma1Pt2()); + if (fillTracksDCA) { + cursors.tracksDCA(mDcaInfoCov.getY(), mDcaInfoCov.getZ()); + } + if (fillTracksDCACov) { + cursors.tracksDCACov(mDcaInfoCov.getSigmaY2(), mDcaInfoCov.getSigmaZ2()); + } + } else { + cursors.tracksParPropagated(track.collisionId(), trackType, mTrackPar.getX(), mTrackPar.getAlpha(), mTrackPar.getY(), mTrackPar.getZ(), mTrackPar.getSnp(), mTrackPar.getTgl(), mTrackPar.getQ2Pt()); + cursors.tracksParExtensionPropagated(mTrackPar.getPt(), mTrackPar.getP(), mTrackPar.getEta(), mTrackPar.getPhi()); + if (fillTracksDCA) { + cursors.tracksDCA(mDcaInfo[0], mDcaInfo[1]); + } + } + } + } +}; + +} // namespace common +} // namespace o2 + +#endif // COMMON_TOOLS_TRACKPROPAGATIONMODULE_H_ diff --git a/DPG/Tasks/AOTEvent/dEdxVsOccupancyWithTrackQAinfo.cxx b/DPG/Tasks/AOTEvent/dEdxVsOccupancyWithTrackQAinfo.cxx index 36af0603ee8..c87fd48bc99 100644 --- a/DPG/Tasks/AOTEvent/dEdxVsOccupancyWithTrackQAinfo.cxx +++ b/DPG/Tasks/AOTEvent/dEdxVsOccupancyWithTrackQAinfo.cxx @@ -15,7 +15,7 @@ /// \author Igor Altsybeev #include -#include "map" +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" diff --git a/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx b/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx index c6dbbe1a17a..a76dc9ea0f7 100644 --- a/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx +++ b/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx @@ -15,7 +15,7 @@ /// \author Igor Altsybeev #include -#include "map" +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" diff --git a/DPG/Tasks/AOTTrack/qaEventTrack.cxx b/DPG/Tasks/AOTTrack/qaEventTrack.cxx index ffb64e1f9c2..09590267ed8 100644 --- a/DPG/Tasks/AOTTrack/qaEventTrack.cxx +++ b/DPG/Tasks/AOTTrack/qaEventTrack.cxx @@ -36,8 +36,8 @@ #include "Common/Core/TrackSelectionDefaults.h" #include "Common/TableProducer/PID/pidTOFBase.h" -#include "string" -#include "vector" +#include +#include using namespace o2; using namespace o2::framework; @@ -1562,7 +1562,7 @@ void qaEventTrack::fillRecoHistogramsGroupedTracks(const C& collision, const T& histos.fill(HIST("Tracks/signed1Pt"), track.signed1Pt()); histos.fill(HIST("Tracks/snp"), track.snp()); histos.fill(HIST("Tracks/tgl"), track.tgl()); - for (unsigned int i = 0; i < 64; i++) { + for (unsigned int i = 0; i < 32; i++) { if (track.flags() & (1 << i)) { histos.fill(HIST("Tracks/flags"), i); } diff --git a/DPG/Tasks/AOTTrack/qaImpPar.cxx b/DPG/Tasks/AOTTrack/qaImpPar.cxx index 1f7494c9395..2ff3ca3761c 100644 --- a/DPG/Tasks/AOTTrack/qaImpPar.cxx +++ b/DPG/Tasks/AOTTrack/qaImpPar.cxx @@ -34,9 +34,9 @@ #include "DataFormatsCalibration/MeanVertexObject.h" #include "CommonConstants/GeomConstants.h" -#include "iostream" -#include "vector" -#include "set" +#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..704d3fa89ad 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..67fba3b4989 --- /dev/null +++ b/DPG/Tasks/ITS/itsImpParStudies.cxx @@ -0,0 +1,699 @@ +// 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 + +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "ReconstructionDataFormats/DCA.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 "CCDB/BasicCCDBManager.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "Framework/RunningWorkflowInfo.h" +#include "CCDB/CcdbApi.h" +#include "DataFormatsCalibration/MeanVertexObject.h" +#include "CommonConstants/GeomConstants.h" + +#include "iostream" +#include "vector" +#include "set" + +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..589228edc5f 100644 --- a/EventFiltering/PWGCF/CFFilterAll.cxx +++ b/EventFiltering/PWGCF/CFFilterAll.cxx @@ -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/PWGHF/HFFilter.cxx b/EventFiltering/PWGHF/HFFilter.cxx index 6a9112c8c85..4c0d2d891de 100644 --- a/EventFiltering/PWGHF/HFFilter.cxx +++ b/EventFiltering/PWGHF/HFFilter.cxx @@ -45,13 +45,15 @@ #include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponseITS.h" + #include "PWGEM/PhotonMeson/DataModel/gammaTables.h" + #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsTrkCandHf.h" #include "EventFiltering/filterTables.h" #include "EventFiltering/PWGHF/HFFilterHelpers.h" -#include "PWGHF/Utils/utilsTrkCandHf.h" using namespace o2; using namespace o2::soa; @@ -76,7 +78,7 @@ struct HfFilter { // Main struct for HF triggers Configurable> nSigmaPidCuts{"nSigmaPidCuts", {cutsNsigma[0], 4, 8, labelsRowsNsigma, labelsColumnsNsigma}, "Nsigma cuts for ITS/TPC/TOF PID (except for V0 and cascades)"}; // min and max pts for tracks and bachelors (except for V0 and cascades) Configurable> ptCuts{"ptCuts", {cutsPt[0], 2, 10, labelsRowsCutsPt, labelsColumnsCutsPt}, "minimum and maximum pT for bachelor tracks (except for V0 and cascades)"}; - + Configurable> trackQaulityCuts{"trackQaulityCuts", {cutsTrackQuality[0], 2, 7, labelsColumnsPtThresholdsForFemto, labelsColumnsTrackQuality}, "Track quality cuts for proton and deuteron)"}; // parameters for high-pT triggers Configurable> ptThresholds{"ptThresholds", {cutsHighPtThresholds[0], 1, 2, labelsEmpty, labelsColumnsHighPtThresholds}, "pT treshold for high pT charm hadron candidates for kHighPt triggers in GeV/c"}; @@ -215,6 +217,7 @@ struct HfFilter { // Main struct for HF triggers helper.setCutsBtoJPsi(cutsBtoHadrons.cutsBtoJPsiX); helper.setNsigmaProtonCutsForFemto(std::array{nSigmaPidCuts->get(0u, 3u), nSigmaPidCuts->get(1u, 3u), nSigmaPidCuts->get(2u, 3u), nSigmaPidCuts->get(3u, 3u)}); helper.setNsigmaDeuteronCutsForFemto(std::array{nSigmaPidCuts->get(0u, 6u), nSigmaPidCuts->get(1u, 6u), nSigmaPidCuts->get(2u, 6u), nSigmaPidCuts->get(3u, 6u)}); + helper.setDeuteronTrackSelectionForFemto(trackQaulityCuts->get(1u, 0u), trackQaulityCuts->get(1u, 1u), trackQaulityCuts->get(1u, 2u), trackQaulityCuts->get(1u, 3u), trackQaulityCuts->get(1u, 4u), trackQaulityCuts->get(1u, 5u), trackQaulityCuts->get(1u, 6u)); helper.setNsigmaProtonCutsForCharmBaryons(nSigmaPidCuts->get(0u, 0u), nSigmaPidCuts->get(1u, 0u)); helper.setNsigmaPionKaonCutsForDzero(nSigmaPidCuts->get(0u, 1u), nSigmaPidCuts->get(1u, 1u)); helper.setNsigmaKaonCutsFor3Prongs(nSigmaPidCuts->get(0u, 2u), nSigmaPidCuts->get(1u, 2u)); diff --git a/EventFiltering/PWGHF/HFFilterCharmHadronSignals.cxx b/EventFiltering/PWGHF/HFFilterCharmHadronSignals.cxx index e3a9cf8044a..ab46a5e2504 100644 --- a/EventFiltering/PWGHF/HFFilterCharmHadronSignals.cxx +++ b/EventFiltering/PWGHF/HFFilterCharmHadronSignals.cxx @@ -32,6 +32,8 @@ #include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" + +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/EventFiltering/PWGHF/HFFilterHelpers.h b/EventFiltering/PWGHF/HFFilterHelpers.h index 6135e0a715d..72b2f71cae4 100644 --- a/EventFiltering/PWGHF/HFFilterHelpers.h +++ b/EventFiltering/PWGHF/HFFilterHelpers.h @@ -51,8 +51,11 @@ #include "Common/Core/RecoDecay.h" #include "Common/Core/trackUtilities.h" + +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" + #include "EventFiltering/filterTables.h" namespace o2::aod @@ -278,7 +281,7 @@ constexpr float massJPsi = o2::constants::physics::MassJPsi; static const o2::framework::AxisSpec ptAxis{50, 0.f, 50.f}; static const o2::framework::AxisSpec pAxis{50, 0.f, 10.f}; -static const o2::framework::AxisSpec kstarAxis{100, 0.f, 1.f}; +static const o2::framework::AxisSpec kstarAxis{200, 0.f, 2.f}; static const o2::framework::AxisSpec etaAxis{30, -1.5f, 1.5f}; static const o2::framework::AxisSpec nSigmaAxis{100, -10.f, 10.f}; static const o2::framework::AxisSpec alphaAxis{100, -1.f, 1.f}; @@ -313,6 +316,11 @@ constexpr float cutsNsigma[4][8] = { static const std::vector labelsColumnsNsigma = {"PrFromLc", "PiKaFromDZero", "KaFrom3Prong", "PrForFemto", "PiKaFromCharmBaryon", "SoftKaonFromXicResoToSigmaC", "DeForFemto", "KaPrFromBeautyToJPsi"}; static const std::vector labelsRowsNsigma = {"TPC", "TOF", "Comb", "ITS"}; +// track cut +constexpr float cutsTrackQuality[2][7] = {{0., 0., 0., 999., 999., 0., 0.}, + {90, 80, 0.83, 160., 1., 5., 0.}}; +static const std::vector labelsColumnsTrackQuality = {"minTpcCluster", "minTpcRow", "minTpcCrossedOverFound", "maxTpcShared", "maxTpcFracShared", "minItsCluster", "minItsIbCluster"}; + // high pt constexpr float cutsHighPtThresholds[1][2] = {{8., 8.}}; // 2-prongs, 3-prongs static const std::vector labelsColumnsHighPtThresholds = {"2Prongs", "3Prongs"}; @@ -489,6 +497,18 @@ class HfFilterHelper void setNsigmaProtonCutsForFemto(std::array nSigmaCuts) { mNSigmaPrCutsForFemto = nSigmaCuts; } void setNsigmaDeuteronCutsForFemto(std::array nSigmaCuts) { mNSigmaDeCutsForFemto = nSigmaCuts; } + + void setDeuteronTrackSelectionForFemto(float minTpcCluster, float minTpcRow, float minTpcCrossedOverFound, float maxTpcShared, float maxTpcFracShared, float minItsCluster, float minItsIbCluster) + { + mMinTpcCluster = minTpcCluster; + mMinTpcRow = minTpcRow; + mMinTpcCrossedOverFound = minTpcCrossedOverFound; + mMaxTpcShared = maxTpcShared; + mMaxTpcFracShared = maxTpcFracShared; + mMinItsCluster = minItsCluster; + mMinItsIbCluster = minItsIbCluster; + } + void setNsigmaProtonCutsForCharmBaryons(float nSigmaTpc, float nSigmaTof) { mNSigmaTpcPrCutForCharmBaryons = nSigmaTpc; @@ -754,7 +774,13 @@ class HfFilterHelper std::array mCosPaMinXiBach{-2.f, -2.f}; // minimum cosine of pointing angle for XiBachelor candidates std::array, kNBeautyParticles> mCutsBhad{}; // selections for B-hadron candidates (DeltaMass, CPA, DecayLength, ImpactParameterProduct) o2::framework::LabeledArray mCutsBhadToJPsi{}; // selections for B->JPsi candidates (PtMinMu, DeltaMass, CPA, DecayLength) - + float mMinTpcCluster{90.}; // Minimum number of TPC clusters required on a track + float mMinTpcRow{80.}; // Minimum number of TPC rows (pad rows) traversed by the track + float mMinTpcCrossedOverFound{0.83}; // Minimum ratio of crossed TPC rows over findable clusters + float mMaxTpcShared{160.}; // Maximum allowed number of shared TPC clusters between tracks + float mMaxTpcFracShared{1.}; // Maximum allowed fraction of shared TPC clusters relative to total clusters + float mMinItsCluster{1.}; // Minimum required number of ITS clusters + float mMinItsIbCluster{1.}; // Minimum required number of ITS clusters for IB // PID recalibrations int mTpcPidCalibrationOption{0}; // Option for TPC PID calibration (0 -> AO2D, 1 -> postcalibrations, 2 -> alternative bethe bloch parametrisation) std::array mHistMapPiPrKaDe{}; // Map for TPC PID postcalibrations for pions, kaon, protons and deuterons @@ -941,9 +967,9 @@ inline bool HfFilterHelper::isSelectedTrack4Femto(const T1& track, const T2& tra } float NSigma = std::sqrt(NSigmaTPC * NSigmaTPC + NSigmaTOF * NSigmaTOF); - + float momentum = track.p(); if (trackSpecies == kProtonForFemto) { - if (pt <= ptThresholdPidStrategy) { + if (momentum <= ptThresholdPidStrategy) { if (NSigma > nSigmaCuts[2]) { return false; } @@ -955,14 +981,37 @@ inline bool HfFilterHelper::isSelectedTrack4Femto(const T1& track, const T2& tra } // For deuterons: Determine whether to apply TOF based on pt threshold if (trackSpecies == kDeuteronForFemto) { + + if (track.tpcNClsFound() < mMinTpcCluster) { + return false; + } + if (track.tpcNClsCrossedRows() < mMinTpcRow) { + return false; + } + if (track.tpcCrossedRowsOverFindableCls() < mMinTpcCrossedOverFound) { + return false; + } + if (track.tpcNClsShared() > mMaxTpcShared) { + return false; + } + if (track.tpcFractionSharedCls() > mMaxTpcFracShared) { + return false; + } + if (track.itsNCls() < mMinItsCluster) { + return false; + } + if (track.itsNClsInnerBarrel() < mMinItsIbCluster) { + return false; + } + // Apply different PID strategy in different pt range // one side selection only - if (pt <= ptThresholdPidStrategy) { - if (NSigmaTPC < -nSigmaCuts[0] || NSigmaITS < -nSigmaCuts[3]) { // Use TPC and ITS below the threshold, NSigmaITS for deuteron with a lower limit + if (momentum <= ptThresholdPidStrategy) { + if (std::fabs(NSigmaTPC) > nSigmaCuts[0] || NSigmaITS < -nSigmaCuts[3]) { // Use TPC and ITS below the threshold, NSigmaITS for deuteron with a lower limit return false; } } else { - if (NSigmaTOF < -nSigmaCuts[1] || NSigmaTPC < -nSigmaCuts[0]) { // Use combined TPC and TOF above the threshold + if (NSigma > nSigmaCuts[2]) { // Use combined TPC and TOF above the threshold return false; } } @@ -970,11 +1019,11 @@ inline bool HfFilterHelper::isSelectedTrack4Femto(const T1& track, const T2& tra if (activateQA > 1) { hTPCPID->Fill(track.p(), NSigmaTPC); - if ((forceTof || track.hasTOF())) { + if ((!forceTof || track.hasTOF())) { if (trackSpecies == kProtonForFemto) - hTOFPID->Fill(track.p(), NSigmaTOF); - else if (trackSpecies == kDeuteronForFemto && pt > ptThresholdPidStrategy) - hTOFPID->Fill(track.p(), NSigmaTOF); + hTOFPID->Fill(momentum, NSigmaTOF); + else if (trackSpecies == kDeuteronForFemto && momentum > ptThresholdPidStrategy) + hTOFPID->Fill(momentum, NSigmaTOF); } } diff --git a/EventFiltering/PWGHF/HFFilterPrepareMLSamples.cxx b/EventFiltering/PWGHF/HFFilterPrepareMLSamples.cxx index 39e903e9f60..2a5dda41464 100644 --- a/EventFiltering/PWGHF/HFFilterPrepareMLSamples.cxx +++ b/EventFiltering/PWGHF/HFFilterPrepareMLSamples.cxx @@ -38,6 +38,8 @@ #include "Framework/runDataProcessing.h" #include "Common/Core/trackUtilities.h" + +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" 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/Femto3D/Core/femto3dPairTask.h b/PWGCF/Femto3D/Core/femto3dPairTask.h index 5627215ea55..db5949f4ae0 100755 --- a/PWGCF/Femto3D/Core/femto3dPairTask.h +++ b/PWGCF/Femto3D/Core/femto3dPairTask.h @@ -222,10 +222,12 @@ class FemtoPair } float GetPhiStarDiff(const float& radius = 1.2) const { - if (_first != NULL && _second != NULL) - return _first->phiStar(_magfield1, radius) - _second->phiStar(_magfield2, radius); - else + if (_first != NULL && _second != NULL) { + float dphi = _first->phiStar(_magfield1, radius) - _second->phiStar(_magfield2, radius); + return std::fabs(dphi) > o2::constants::math::PI ? (1.0 - 2.0 * o2::constants::math::PI / std::fabs(dphi)) * dphi : dphi; + } else { return 1000; + } } float GetAvgPhiStarDiff() const; @@ -327,8 +329,7 @@ float FemtoPair::GetAvgPhiStarDiff() const float res = 0.0; for (const auto& radius : TPCradii) { - const float dphi = GetPhiStarDiff(radius); - res += std::fabs(dphi) > o2::constants::math::PI ? (1.0 - 2.0 * o2::constants::math::PI / std::fabs(dphi)) * dphi : dphi; + res += GetPhiStarDiff(radius); } return res / TPCradii.size(); diff --git a/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx b/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx index bc91f8a25c2..83aa740795c 100644 --- a/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx +++ b/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx @@ -90,9 +90,10 @@ struct FemtoCorrelations { Configurable _particlePDGtoReject{"particlePDGtoRejectFromSecond", 0, "applied only if the particles are non-identical and only to the second particle in the pair!!!"}; Configurable> _rejectWithinNsigmaTOF{"rejectWithinNsigmaTOF", std::vector{-0.0f, 0.0f}, "TOF rejection Nsigma range for the particle specified with PDG to be rejected"}; + Configurable _dPhiMode{"dPhiMode", 0, "Flag to choose how to calc. dphi*: 0 - at a fixed TPC radius; 1 - average over different TPC radii;"}; + Configurable _radiusTPC{"radiusTPC", 1.2, "TPC radius to calculate phi_star for"}; Configurable _deta{"deta", 0.01, "minimum allowed defference in eta between two tracks in a pair"}; Configurable _dphi{"dphi", 0.01, "minimum allowed defference in phi_star between two tracks in a pair"}; - // Configurable _radiusTPC{"radiusTPC", 1.2, "TPC radius to calculate phi_star for"}; Configurable _avgSepTPC{"avgSepTPC", 10, "average sep. (cm) in TPC"}; Configurable _vertexNbinsToMix{"vertexNbinsToMix", 10, "Number of vertexZ bins for the mixing"}; @@ -310,15 +311,15 @@ struct FemtoCorrelations { LOGF(fatal, "kTbin value obtained for a pair exceeds the configured number of kT bins (3D)"); if (_fillDetaDphi % 2 == 0) - DoubleTrack_SE_histos_BC[multBin][kTbin]->Fill(Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); + DoubleTrack_SE_histos_BC[multBin][kTbin]->Fill(_dPhiMode.value == 0 ? Pair->GetPhiStarDiff(_radiusTPC) : Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); - if (_deta > 0 && _dphi > 0 && Pair->IsClosePair(_deta, _dphi)) + if (_deta > 0 && _dphi > 0 && (_dPhiMode.value == 0 ? Pair->IsClosePair(_deta, _dphi, _radiusTPC) : Pair->IsClosePair(_deta, _dphi))) continue; if (_avgSepTPC > 0 && Pair->IsClosePair(_avgSepTPC)) continue; if (_fillDetaDphi > 0) - DoubleTrack_SE_histos_AC[multBin][kTbin]->Fill(Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); + DoubleTrack_SE_histos_AC[multBin][kTbin]->Fill(_dPhiMode.value == 0 ? Pair->GetPhiStarDiff(_radiusTPC) : Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); kThistos[multBin][kTbin]->Fill(pair_kT); mThistos[multBin][kTbin]->Fill(Pair->GetMt()); // test @@ -359,21 +360,21 @@ struct FemtoCorrelations { if (_fillDetaDphi % 2 == 0) { if (!SE_or_ME) - DoubleTrack_SE_histos_BC[multBin][kTbin]->Fill(Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); + DoubleTrack_SE_histos_BC[multBin][kTbin]->Fill(_dPhiMode.value == 0 ? Pair->GetPhiStarDiff(_radiusTPC) : Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); else - DoubleTrack_ME_histos_BC[multBin][kTbin]->Fill(Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); + DoubleTrack_ME_histos_BC[multBin][kTbin]->Fill(_dPhiMode.value == 0 ? Pair->GetPhiStarDiff(_radiusTPC) : Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); } - if (_deta > 0 && _dphi > 0 && Pair->IsClosePair(_deta, _dphi)) + if (_deta > 0 && _dphi > 0 && (_dPhiMode.value == 0 ? Pair->IsClosePair(_deta, _dphi, _radiusTPC) : Pair->IsClosePair(_deta, _dphi))) continue; if (_avgSepTPC > 0 && Pair->IsClosePair(_avgSepTPC)) continue; if (_fillDetaDphi > 0) { if (!SE_or_ME) - DoubleTrack_SE_histos_AC[multBin][kTbin]->Fill(Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); + DoubleTrack_SE_histos_AC[multBin][kTbin]->Fill(_dPhiMode.value == 0 ? Pair->GetPhiStarDiff(_radiusTPC) : Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); else - DoubleTrack_ME_histos_AC[multBin][kTbin]->Fill(Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); + DoubleTrack_ME_histos_AC[multBin][kTbin]->Fill(_dPhiMode.value == 0 ? Pair->GetPhiStarDiff(_radiusTPC) : Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); } if (!SE_or_ME) { diff --git a/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx b/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx index be66280928e..b776d34e629 100644 --- a/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx +++ b/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx @@ -86,7 +86,8 @@ struct FemtoCorrelationsMC { Configurable _particlePDGtoReject{"particlePDGtoRejectFromSecond", 0, "applied only if the particles are non-identical and only to the second particle in the pair!!!"}; Configurable> _rejectWithinNsigmaTOF{"rejectWithinNsigmaTOF", std::vector{-0.0f, 0.0f}, "TOF rejection Nsigma range for the particle specified with PDG to be rejected"}; - // Configurable _radiusTPC{"radiusTPC", 1.2, "TPC radius to calculate phi_star for"}; + Configurable _dPhiMode{"dPhiMode", 0, "Flag to choose how to calc. dphi*: 0 - at a fixed TPC radius; 1 - average over different TPC radii;"}; + Configurable _radiusTPC{"radiusTPC", 1.2, "TPC radius to calculate phi_star for"}; Configurable _vertexNbinsToMix{"vertexNbinsToMix", 10, "Number of vertexZ bins for the mixing"}; Configurable> _centBins{"multBins", std::vector{0.0f, 100.0f}, "multiplicity percentile/centrality binning (min:0, max:100)"}; @@ -257,7 +258,7 @@ struct FemtoCorrelationsMC { LOGF(fatal, "kTbin value obtained for a pair exceeds the configured number of kT bins"); kThistos[centBin][kTbin]->Fill(pair_kT); - DoubleTrack_SE_histos[centBin][kTbin]->Fill(Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); + DoubleTrack_SE_histos[centBin][kTbin]->Fill(_dPhiMode.value == 0 ? Pair->GetPhiStarDiff(_radiusTPC) : Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); AvgSep_SE_histos[centBin][kTbin]->Fill(Pair->GetAvgSep()); Pair->ResetPair(); } @@ -281,7 +282,7 @@ struct FemtoCorrelationsMC { LOGF(fatal, "kTbin value obtained for a pair exceeds the configured number of kT bins"); kThistos[centBin][kTbin]->Fill(pair_kT); - DoubleTrack_SE_histos[centBin][kTbin]->Fill(Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); + DoubleTrack_SE_histos[centBin][kTbin]->Fill(_dPhiMode.value == 0 ? Pair->GetPhiStarDiff(_radiusTPC) : Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); AvgSep_SE_histos[centBin][kTbin]->Fill(Pair->GetAvgSep()); Pair->ResetPair(); } @@ -304,7 +305,7 @@ struct FemtoCorrelationsMC { if (kTbin > Resolution_histos[centBin].size() || kTbin > DoubleTrack_ME_histos[centBin].size()) LOGF(fatal, "kTbin value obtained for a pair exceeds the configured number of kT bins"); - DoubleTrack_ME_histos[centBin][kTbin]->Fill(Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); + DoubleTrack_ME_histos[centBin][kTbin]->Fill(_dPhiMode.value == 0 ? Pair->GetPhiStarDiff(_radiusTPC) : Pair->GetAvgPhiStarDiff(), Pair->GetEtaDiff()); AvgSep_ME_histos[centBin][kTbin]->Fill(Pair->GetAvgSep()); if (abs(ii->pdgCode()) != _particlePDG_1.value || abs(iii->pdgCode()) != _particlePDG_2.value) diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCorrection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCorrection.h index a26b6cbc966..9936a5430d6 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCorrection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCorrection.h @@ -110,8 +110,6 @@ class EfficiencyCorrection LOGF(fatal, notify("Unknown configuration for efficiency variables")); break; } - } else { - hLoaded[idx] = nullptr; } } } @@ -201,17 +199,18 @@ class EfficiencyCorrection auto bin = -1; if (config->confEffCorVariables.value == "pt") { - bin = hLoaded[partNo - 1]->FindBin(particle.pt()); + bin = hWeights->FindBin(particle.pt()); } else if (config->confEffCorVariables.value == "pt,eta") { - bin = hLoaded[partNo - 1]->FindBin(particle.pt(), particle.eta()); + bin = hWeights->FindBin(particle.pt(), particle.eta()); } else if (config->confEffCorVariables.value == "pt,mult") { - bin = hLoaded[partNo - 1]->FindBin(particle.pt(), particle.fdCollision().multV0M()); + bin = hWeights->FindBin(particle.pt(), particle.fdCollision().multV0M()); } else if (config->confEffCorVariables.value == "pt,eta,mult") { - bin = hLoaded[partNo - 1]->FindBin(particle.pt(), particle.eta(), particle.fdCollision().multV0M()); + bin = hWeights->FindBin(particle.pt(), particle.eta(), particle.fdCollision().multV0M()); } else { LOGF(fatal, notify("Unknown configuration for efficiency variables")); return weight; } + weight = hWeights->GetBinContent(bin); } @@ -229,11 +228,21 @@ class EfficiencyCorrection if (!hist) { return true; } - for (auto idx = 0; idx <= hist->GetNbinsX() + 1; idx++) { - if (hist->GetBinContent(idx) > 0) { - return false; + + const int nBinsX = hist->GetNbinsX() + 2; + const int nBinsY = hist->GetNbinsY() + 2; + const int nBinsZ = hist->GetNbinsZ() + 2; + + for (int x = 0; x < nBinsX; ++x) { + for (int y = 0; y < nBinsY; ++y) { + for (int z = 0; z < nBinsZ; ++z) { + if (hist->GetBinContent(x, y, z) != 0) { + return false; + } + } } } + return true; } @@ -247,11 +256,14 @@ class EfficiencyCorrection } if (isHistEmpty(hWeights)) { - LOGF(warn, notify("Histogram \"%s/%ld\" has been loaded, but it is empty"), config->confEffCorCCDBUrl.value, timestamp); + LOGF(warn, notify("Histogram \"%s/%ld\" has been loaded, but it is empty"), config->confEffCorCCDBPath.value, timestamp); } + auto clonedHist = static_cast(hWeights->Clone()); + clonedHist->SetDirectory(nullptr); + LOGF(info, notify("Successfully loaded %ld"), timestamp); - return hWeights; + return clonedHist; } auto getDimensionFromVariables() -> size_t @@ -266,7 +278,7 @@ class EfficiencyCorrection bool shouldFillHistograms{false}; o2::ccdb::BasicCCDBManager& ccdb{o2::ccdb::BasicCCDBManager::instance()}; - std::array hLoaded{}; + std::array hLoaded{nullptr, nullptr}; framework::HistogramRegistry* histRegistry{}; static constexpr std::string_view histDirectory{"EfficiencyCorrection"}; 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/Macros/calculateEfficiencyCorrection.cxx b/PWGCF/FemtoUniverse/Macros/calculateEfficiencyCorrection.cxx index e99331231e2..3880661d9f7 100644 --- a/PWGCF/FemtoUniverse/Macros/calculateEfficiencyCorrection.cxx +++ b/PWGCF/FemtoUniverse/Macros/calculateEfficiencyCorrection.cxx @@ -148,6 +148,10 @@ auto calculateEfficiencyCorrection(const fs::path& resultsPath, const fs::path& histWeights->Reset(); setAxisTitles(histWeights, projection); + auto* histCont{cloneHistogram(histPrimary, "hCont")}; + histCont->Reset(); + setAxisTitles(histCont, projection); + forEachBin(histPrimary, [&](int x, int y, int z) { auto primVal{histPrimary->GetBinContent(x, y, z)}; auto primErr{histPrimary->GetBinError(x, y, z)}; @@ -178,6 +182,9 @@ auto calculateEfficiencyCorrection(const fs::path& resultsPath, const fs::path& contErr = std::sqrt(std::pow(secErr / totalVal, 2) + std::pow((secVal * totalErr / std::pow(totalVal, 2)), 2)); } + histCont->SetBinContent(x, y, z, contVal); + histCont->SetBinError(x, y, z, contErr); + auto weightVal{0.}; auto weightErr{0.}; if (effVal > 0) { @@ -190,6 +197,7 @@ auto calculateEfficiencyCorrection(const fs::path& resultsPath, const fs::path& }); outputFile->WriteTObject(histEfficiency); + outputFile->WriteTObject(histCont); outputFile->WriteTObject(histWeights); outputFile->Close(); diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx index 955af5a6876..d35aa3fa779 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx @@ -16,20 +16,22 @@ #include #include -#include #include +#include #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" #include "Framework/HistogramRegistry.h" #include "Framework/ASoAHelpers.h" #include "Framework/RunningWorkflowInfo.h" #include "Framework/StepTHn.h" +#include "Framework/O2DatabasePDGPlugin.h" #include "DataFormatsParameters/GRPObject.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 "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" using namespace o2; using namespace o2::analysis::femto_universe; @@ -37,72 +39,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}, {50, -5, 5}}); } - /// 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 +127,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), }; return workflow; } diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx index c1a5d44174d..3e68a275452 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx @@ -19,6 +19,7 @@ #include #include + #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" #include "Framework/HistogramRegistry.h" @@ -27,6 +28,7 @@ #include "Framework/StepTHn.h" #include "Framework/O2DatabasePDGPlugin.h" #include "ReconstructionDataFormats/PID.h" + #include "Common/DataModel/PIDResponse.h" #include "Common/Core/RecoDecay.h" @@ -43,6 +45,7 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCalculator.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" 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/TableProducer/zdcQVectors.cxx b/PWGCF/Flow/TableProducer/zdcQVectors.cxx index 77f436b383e..f8ba2cbb0b7 100644 --- a/PWGCF/Flow/TableProducer/zdcQVectors.cxx +++ b/PWGCF/Flow/TableProducer/zdcQVectors.cxx @@ -429,8 +429,6 @@ struct ZdcQVectors { cal.atStep = 5; cal.atIteration = 5; } - } else { - LOGF(info, "No ccdb path given for calibration histos. Do not recenter."); } } 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 4b7df991de2..db8bb0df404 100644 --- a/PWGCF/Flow/Tasks/flowSP.cxx +++ b/PWGCF/Flow/Tasks/flowSP.cxx @@ -21,6 +21,7 @@ #include #include #include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -35,6 +36,7 @@ #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/Centrality.h" #include "Common/Core/RecoDecay.h" +#include "Common/DataModel/PIDResponse.h" #include "PWGCF/DataModel/SPTableZDC.h" #include "GFWWeights.h" @@ -50,12 +52,18 @@ using namespace o2::framework::expressions; struct FlowSP { // QA Plots - O2_DEFINE_CONFIGURABLE(cfgFillQAHistos, bool, true, "Fill histograms for event and track QA"); + O2_DEFINE_CONFIGURABLE(cfgFillEventQA, bool, true, "Fill histograms for event QA"); + O2_DEFINE_CONFIGURABLE(cfgFillTrackQA, bool, true, "Fill histograms for track QA"); + O2_DEFINE_CONFIGURABLE(cfgFillPIDQA, bool, true, "Fill histograms for PID QA"); + O2_DEFINE_CONFIGURABLE(cfgFillEventPlaneQA, bool, true, "Fill histograms for Event Plane QA"); + O2_DEFINE_CONFIGURABLE(cfgFillGeneralV1Histos, bool, true, "Fill histograms for vn analysis"); + O2_DEFINE_CONFIGURABLE(cfgFillQABefore, bool, true, "Fill QA histograms before cuts, only for processData"); // Flags to make and fill histograms O2_DEFINE_CONFIGURABLE(cfgFillMixedHarmonics, bool, true, "Flag to make and fill histos for mixed harmonics"); O2_DEFINE_CONFIGURABLE(cfgFillEventPlane, bool, true, "Flag to make and fill histos with Event Plane"); O2_DEFINE_CONFIGURABLE(cfgFillXandYterms, bool, true, "Flag to make and fill histos for with separate x and y terms for SPM"); O2_DEFINE_CONFIGURABLE(cfgFillChargeDependence, bool, true, "Flag to make and fill histos for charge dependent flow"); + O2_DEFINE_CONFIGURABLE(cfgFillPID, bool, true, "Flag to make and fill histos for PID flow"); // Centrality Estimators -> standard is FT0C O2_DEFINE_CONFIGURABLE(cfgCentFT0Cvariant1, bool, false, "Set centrality estimator to cfgCentFT0Cvariant1"); O2_DEFINE_CONFIGURABLE(cfgCentFT0M, bool, false, "Set centrality estimator to cfgCentFT0M"); @@ -71,23 +79,21 @@ struct FlowSP { O2_DEFINE_CONFIGURABLE(cfgTrackSelsEta, float, 0.8, "eta cut"); O2_DEFINE_CONFIGURABLE(cfgEvSelsVtxZ, float, 10, "vertex cut (cm)"); O2_DEFINE_CONFIGURABLE(cfgMagField, float, 99999, "Configurable magnetic field;default CCDB will be queried"); - O2_DEFINE_CONFIGURABLE(cfgCentMin, float, 0, "Minimum cenrality for selected events"); O2_DEFINE_CONFIGURABLE(cfgCentMax, float, 90, "Maximum cenrality for selected events"); // NUA and NUE weights O2_DEFINE_CONFIGURABLE(cfgFillWeights, bool, true, "Fill NUA weights"); - O2_DEFINE_CONFIGURABLE(cfgFillWeightsPOS, bool, false, "Fill NUA weights only for positive charges"); - O2_DEFINE_CONFIGURABLE(cfgFillWeightsNEG, bool, false, "Fill NUA weights only for negative charges"); + O2_DEFINE_CONFIGURABLE(cfgFillWeightsPOS, bool, true, "Fill NUA weights only for positive charges"); + O2_DEFINE_CONFIGURABLE(cfgFillWeightsNEG, bool, true, "Fill NUA weights only for negative charges"); // Additional track Selections O2_DEFINE_CONFIGURABLE(cfgTrackSelsUseAdditionalTrackCut, bool, false, "Bool to enable Additional Track Cut"); - O2_DEFINE_CONFIGURABLE(cfgTrackSelsDoubleTrackFunction, bool, true, "Include track cut at low pt"); - O2_DEFINE_CONFIGURABLE(cfgTrackSelsTrackCutSize, float, 0.06, "Spread of track cut"); O2_DEFINE_CONFIGURABLE(cfgTrackSelsDoDCApt, bool, false, "Apply Pt dependent DCAz cut"); O2_DEFINE_CONFIGURABLE(cfgTrackSelsDCApt1, float, 0.1, "DcaZ < a * b / pt^1.1 -> this sets a"); O2_DEFINE_CONFIGURABLE(cfgTrackSelsDCApt2, float, 0.035, "DcaZ < a * b / pt^1.1 -> this sets b"); + O2_DEFINE_CONFIGURABLE(cfgTrackSelsPIDNsigma, float, 2.0, "nSigma cut for PID"); // Additional event selections O2_DEFINE_CONFIGURABLE(cfgEvSelsUseAdditionalEventCut, bool, true, "Bool to enable Additional Event Cut"); - O2_DEFINE_CONFIGURABLE(cfgEvSelsnSigmaMultCuts, int, 1, "Sigma cut on Additional event cut: 1 (default), 2 or 3 sigma available"); + O2_DEFINE_CONFIGURABLE(cfgEvSelsnSigmaMultCuts, int, 3, "Sigma cut on Additional event cut: 1, 2 or 3 (default) sigma available"); O2_DEFINE_CONFIGURABLE(cfgEvSelsManualEventParameters, bool, false, "Use manual event parameters for the pile up fits. Needed for Cent estimaters other than FT0C"); O2_DEFINE_CONFIGURABLE(cfgEvSelsMultPv, std::vector, {}, "Multiplicity cuts for PV first 5 parameters cutLOW last 5 cutHIGH"); O2_DEFINE_CONFIGURABLE(cfgEvSelsMult, std::vector, {}, "Multiplicity cuts for T0C first 5 parameters cutLOW last 5 cutHIGH"); @@ -108,12 +114,15 @@ struct FlowSP { O2_DEFINE_CONFIGURABLE(cfgCCDBdir_SP, std::string, "", "ccdb dir for average event plane resolution in 1% centrality bins"); O2_DEFINE_CONFIGURABLE(cfgCCDB_NUA, std::string, "", "ccdb dir for NUA corrections"); O2_DEFINE_CONFIGURABLE(cfgCCDB_NUE, std::string, "", "ccdb dir for NUE corrections"); + O2_DEFINE_CONFIGURABLE(cfgCCDBdir_centrality, std::string, "", "ccdb dir for Centrality corrections"); + // Confogirable axis + ConfigurableAxis axisCentrality{"axisCentrality", {10, 0, 100}, "Centrality bins for vn "}; Filter collisionFilter = nabs(aod::collision::posZ) < cfgEvSelsVtxZ; Filter trackFilter = nabs(aod::track::eta) < cfgTrackSelsEta && aod::track::pt > cfgTrackSelsPtmin&& aod::track::pt < cfgTrackSelsPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && nabs(aod::track::dcaXY) < cfgTrackSelsDCAxy&& nabs(aod::track::dcaZ) < cfgTrackSelsDCAz; Filter trackFilterMC = nabs(aod::mcparticle::eta) < cfgTrackSelsEta && aod::mcparticle::pt > cfgTrackSelsPtmin&& aod::mcparticle::pt < cfgTrackSelsPtmax; using UsedCollisions = soa::Filtered>; - using UsedTracks = soa::Filtered>; + using UsedTracks = soa::Filtered>; // For MC Reco and Gen using CCs = soa::Filtered>; @@ -143,8 +152,11 @@ struct FlowSP { TProfile* hcorrQQx = nullptr; TProfile* hcorrQQy = nullptr; TProfile* hEvPlaneRes = nullptr; + TH1D* hCentrality = nullptr; + bool clQQ = false; bool clEvPlaneRes = false; + bool clCentrality = false; } cfg; @@ -175,11 +187,11 @@ struct FlowSP { evSel_MultCuts, evSel_kIsGoodITSLayersAll, evSel_isSelectedZDC, - nEventSelections, - evSel_CentCuts + evSel_CentCuts, + nEventSelections }; - enum TrackSelectionsUnFiltered { + enum TrackSelections { trackSel_ZeroCharge, trackSel_Eta, trackSel_Pt, @@ -209,7 +221,15 @@ struct FlowSP { kReco }; + enum ParticleType { + kUnidentified, + kPion, + kKaon, + kProton + }; + static constexpr std::string_view Charge[] = {"incl/", "pos/", "neg/"}; + static constexpr std::string_view Species[] = {"", "pion/", "kaon/", "proton/"}; static constexpr std::string_view Time[] = {"before/", "after/"}; void init(InitContext const&) @@ -238,14 +258,43 @@ struct FlowSP { AxisSpec axisT0a = {70, 0, 200000, "N_{ch} (T0A)"}; AxisSpec axisV0a = {70, 0, 200000, "N_{ch} (V0A)"}; AxisSpec axisMultpv = {40, 0, 4000, "N_{ch} (PV)"}; - AxisSpec axisShCl = {100, 0, 1, "Fraction shared cl. TPC"}; - AxisSpec axisCl = {100, 0, 160, "Number of cl. TPC"}; + AxisSpec axisShCl = {40, 0, 1, "Fraction shared cl. TPC"}; + AxisSpec axisCl = {80, 0, 160, "Number of cl. TPC"}; + AxisSpec axisNsigma = {100, -10, 10, "Nsigma for TPC and TOF"}; + AxisSpec axisdEdx = {300, 0, 300, "dEdx for PID"}; + AxisSpec axisBeta = {150, 0, 1.5, "Beta for PID"}; std::vector ptbinning = {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, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}; AxisSpec axisPt = {ptbinning, "#it{p}_{T} GeV/#it{c}"}; int ptbins = ptbinning.size() - 1; + registry.add("hEventCount", "Number of Event; Cut; #Events Passed Cut", {HistType::kTH1D, {{nEventSelections, 0, nEventSelections}}}); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_FilteredEvent + 1, "Filtered event"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_sel8 + 1, "Sel8"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_occupancy + 1, "kOccupancy"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kTVXinTRD + 1, "kTVXinTRD"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kNoSameBunchPileup + 1, "kNoSameBunchPileup"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsGoodZvtxFT0vsPV + 1, "kIsGoodZvtxFT0vsPV"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kNoCollInTimeRangeStandard + 1, "kNoCollInTimeRangeStandard"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsVertexITSTPC + 1, "kIsVertexITSTPC"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_MultCuts + 1, "Mult cuts (Alex)"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsGoodITSLayersAll + 1, "kkIsGoodITSLayersAll"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_isSelectedZDC + 1, "isSelected"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_CentCuts + 1, "Cenrality range"); + + registry.add("hTrackCount", "Number of Tracks; Cut; #Tracks Passed Cut", {HistType::kTH1D, {{nTrackSelections, 0, nTrackSelections}}}); + registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_Eta + 1, "Eta"); + registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_Pt + 1, "Pt"); + registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_DCAxy + 1, "DCAxy"); + registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_DCAz + 1, "DCAz"); + registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_GlobalTracks + 1, "GlobalTracks"); + registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_NCls + 1, "nClusters TPC"); + registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_FshCls + 1, "Frac. sh. Cls TPC"); + registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_TPCBoundary + 1, "TPC Boundary"); + registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_ZeroCharge + 1, "Only charged"); + registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_ParticleWeights + 1, "Apply weights"); + if (cfgFillWeights) { fWeights->setPtBins(ptbins, &ptbinning[0]); fWeights->init(true, false); @@ -257,47 +306,68 @@ struct FlowSP { fWeightsNEG->init(true, false); } - if (doprocessData || doprocessMCReco || doprocessMCGen) { - if (cfgFillQAHistos) { - registry.add("QA/after/hCentFT0C", " ; Cent FT0C (%); ", {HistType::kTH1D, {axisCent}}); - registry.add("QA/after/hCentFT0M", "; Cent FT0M (%); ", {HistType::kTH1D, {axisCent}}); - registry.add("QA/after/hCentFV0A", "; Cent FV0A (%); ", {HistType::kTH1D, {axisCent}}); - registry.add("QA/after/hCentNGlobal", "; Cent NGlobal (%); ", {HistType::kTH1D, {axisCent}}); + if (cfgFillEventQA) { + registry.add("QA/after/hCentFT0C", " ; Cent FT0C (%); ", {HistType::kTH1D, {axisCent}}); + registry.add("QA/after/hCentFT0M", "; Cent FT0M (%); ", {HistType::kTH1D, {axisCent}}); + registry.add("QA/after/hCentFV0A", "; Cent FV0A (%); ", {HistType::kTH1D, {axisCent}}); + registry.add("QA/after/hCentNGlobal", "; Cent NGlobal (%); ", {HistType::kTH1D, {axisCent}}); + registry.add("QA/after/globalTracks_centT0C", "", {HistType::kTH2D, {axisCent, axisNch}}); + registry.add("QA/after/globalTracks_centNGlobal", "", {HistType::kTH2D, {axisCent, axisNch}}); + registry.add("QA/after/PVTracks_centT0C", "", {HistType::kTH2D, {axisCent, axisMultpv}}); + registry.add("QA/after/PVTracks_centNGlobal", "", {HistType::kTH2D, {axisCent, axisMultpv}}); + registry.add("QA/after/globalTracks_PVTracks", "", {HistType::kTH2D, {axisMultpv, axisNch}}); + registry.add("QA/after/globalTracks_multT0A", "", {HistType::kTH2D, {axisT0a, axisNch}}); + registry.add("QA/after/globalTracks_multV0A", "", {HistType::kTH2D, {axisV0a, axisNch}}); + registry.add("QA/after/multV0A_multT0A", "", {HistType::kTH2D, {axisT0a, axisV0a}}); + registry.add("QA/after/multT0C_centT0C", "", {HistType::kTH2D, {axisCent, axisT0c}}); + registry.add("QA/after/CentFT0C_vs_CentFT0Cvariant1", " ; Cent FT0C (%); Cent FT0Cvariant1 (%) ", {HistType::kTH2D, {axisCent, axisCent}}); + registry.add("QA/after/CentFT0C_vs_CentFT0M", " ; Cent FT0C (%); Cent FT0M (%) ", {HistType::kTH2D, {axisCent, axisCent}}); + registry.add("QA/after/CentFT0C_vs_CentFV0A", " ; Cent FT0C (%); Cent FV0A (%) ", {HistType::kTH2D, {axisCent, axisCent}}); + registry.add("QA/after/CentFT0C_vs_CentNGlobal", " ; Cent FT0C (%); Cent NGlobal (%) ", {HistType::kTH2D, {axisCent, axisCent}}); + } - registry.add("QA/after/pt_phi", "", {HistType::kTH2D, {axisPt, axisPhiMod}}); - registry.add("QA/after/hPt_inclusive", "", {HistType::kTH1D, {axisPt}}); - registry.add("QA/after/hPt_positive", "", {HistType::kTH1D, {axisPt}}); - registry.add("QA/after/hPt_negative", "", {HistType::kTH1D, {axisPt}}); - registry.add("QA/after/globalTracks_centT0C", "", {HistType::kTH2D, {axisCent, axisNch}}); - registry.add("QA/after/globalTracks_centNGlobal", "", {HistType::kTH2D, {axisCent, axisNch}}); - registry.add("QA/after/PVTracks_centT0C", "", {HistType::kTH2D, {axisCent, axisMultpv}}); - registry.add("QA/after/PVTracks_centNGlobal", "", {HistType::kTH2D, {axisCent, axisMultpv}}); - registry.add("QA/after/globalTracks_PVTracks", "", {HistType::kTH2D, {axisMultpv, axisNch}}); - registry.add("QA/after/globalTracks_multT0A", "", {HistType::kTH2D, {axisT0a, axisNch}}); - registry.add("QA/after/globalTracks_multV0A", "", {HistType::kTH2D, {axisV0a, axisNch}}); - registry.add("QA/after/multV0A_multT0A", "", {HistType::kTH2D, {axisT0a, axisV0a}}); - registry.add("QA/after/multT0C_centT0C", "", {HistType::kTH2D, {axisCent, axisT0c}}); - - registry.add("QA/after/CentFT0C_vs_CentFT0Cvariant1", " ; Cent FT0C (%); Cent FT0Cvariant1 (%) ", {HistType::kTH2D, {axisCent, axisCent}}); - registry.add("QA/after/CentFT0C_vs_CentFT0M", " ; Cent FT0C (%); Cent FT0M (%) ", {HistType::kTH2D, {axisCent, axisCent}}); - registry.add("QA/after/CentFT0C_vs_CentFV0A", " ; Cent FT0C (%); Cent FV0A (%) ", {HistType::kTH2D, {axisCent, axisCent}}); - registry.add("QA/after/CentFT0C_vs_CentNGlobal", " ; Cent FT0C (%); Cent NGlobal (%) ", {HistType::kTH2D, {axisCent, axisCent}}); - - if (doprocessData || doprocessMCReco) { - // track QA for pos, neg, incl - registry.add("incl/QA/before/hPt", "", kTH1D, {axisPt}); - registry.add("incl/QA/before/hPhi", "", kTH1D, {axisPhi}); - registry.add("incl/QA/before/hEta", "", kTH1D, {axisEta}); - registry.add("incl/QA/before/hPhi_Eta_vz", "", kTH3D, {axisPhi, axisEta, axisVz}); - registry.add("incl/QA/before/hDCAxy_pt", "", kTH2D, {axisPt, axisDCAxy}); - registry.add("incl/QA/before/hDCAz_pt", "", kTH2D, {axisPt, axisDCAz}); - registry.add("incl/QA/before/hSharedClusters_pt", "", {HistType::kTH2D, {axisPt, axisShCl}}); - registry.add("incl/QA/before/hCrossedRows_pt", "", {HistType::kTH2D, {axisPt, axisCl}}); - registry.add("incl/QA/before/hCrossedRows_vs_SharedClusters", "", {HistType::kTH2D, {axisCl, axisShCl}}); - - registry.addClone("incl/QA/before/", "incl/QA/after/"); + if (doprocessData || doprocessMCReco) { + // track QA for pos, neg, incl + if (cfgFillPIDQA) { + registry.add("hPIDcounts", "", kTH2D, {{{4, 0, 4}, axisPt}}); + registry.get(HIST("hPIDcounts"))->GetXaxis()->SetBinLabel(1, "UFO"); + registry.get(HIST("hPIDcounts"))->GetXaxis()->SetBinLabel(2, "Pion"); + registry.get(HIST("hPIDcounts"))->GetXaxis()->SetBinLabel(3, "Kaon"); + registry.get(HIST("hPIDcounts"))->GetXaxis()->SetBinLabel(4, "Proton"); + + registry.add("incl/QA/after/hdEdxTPC_pt", "", {HistType::kTH2D, {axisPt, axisdEdx}}); + registry.add("incl/QA/after/hBetaTOF_pt", "", {HistType::kTH2D, {axisPt, axisBeta}}); + registry.add("incl/pion/QA/after/hNsigmaTPC_pt", "", {HistType::kTH2D, {axisPt, axisNsigma}}); + registry.add("incl/pion/QA/after/hNsigmaTOF_pt", "", {HistType::kTH2D, {axisPt, axisNsigma}}); + + if (cfgFillTrackQA) { + registry.add("incl/pion/QA/after/hPt", "", kTH1D, {axisPt}); + registry.add("incl/pion/QA/after/hPhi", "", kTH1D, {axisPhi}); + registry.add("incl/pion/QA/after/hEta", "", kTH1D, {axisEta}); + registry.add("incl/pion/QA/after/hPhi_Eta_vz", "", kTH3D, {axisPhi, axisEta, axisVz}); + registry.add("incl/pion/QA/after/hDCAxy_pt", "", kTH2D, {axisPt, axisDCAxy}); + registry.add("incl/pion/QA/after/hDCAz_pt", "", kTH2D, {axisPt, axisDCAz}); + registry.add("incl/pion/QA/after/hSharedClusters_pt", "", {HistType::kTH2D, {axisPt, axisShCl}}); + registry.add("incl/pion/QA/after/hCrossedRows_pt", "", {HistType::kTH2D, {axisPt, axisCl}}); + registry.add("incl/pion/QA/after/hCrossedRows_vs_SharedClusters", "", {HistType::kTH2D, {axisCl, axisShCl}}); } + if (cfgFillQABefore) + registry.addClone("incl/pion/QA/after/", "incl/pion/QA/before/"); + } + if (cfgFillTrackQA) { + registry.add("QA/after/pt_phi", "", {HistType::kTH2D, {axisPt, axisPhiMod}}); + registry.add("incl/QA/after/hPt", "", kTH1D, {axisPt}); + registry.add("incl/QA/after/hPhi", "", kTH1D, {axisPhi}); + registry.add("incl/QA/after/hEta", "", kTH1D, {axisEta}); + registry.add("incl/QA/after/hPhi_Eta_vz", "", kTH3D, {axisPhi, axisEta, axisVz}); + registry.add("incl/QA/after/hDCAxy_pt", "", kTH2D, {axisPt, axisDCAxy}); + registry.add("incl/QA/after/hDCAz_pt", "", kTH2D, {axisPt, axisDCAz}); + registry.add("incl/QA/after/hSharedClusters_pt", "", {HistType::kTH2D, {axisPt, axisShCl}}); + registry.add("incl/QA/after/hCrossedRows_pt", "", {HistType::kTH2D, {axisPt, axisCl}}); + registry.add("incl/QA/after/hCrossedRows_vs_SharedClusters", "", {HistType::kTH2D, {axisCl, axisShCl}}); } + if (cfgFillQABefore && (cfgFillTrackQA || cfgFillPIDQA)) + registry.addClone("incl/QA/after/", "incl/QA/before/"); if (doprocessMCReco) { registry.add("trackMCReco/after/hIsPhysicalPrimary", "", {HistType::kTH1D, {{2, 0, 2}}}); @@ -305,163 +375,166 @@ struct FlowSP { registry.add("trackMCReco/hTrackSize_Filtered", "", {HistType::kTH1D, {{100, 0, 20000}}}); registry.get(HIST("trackMCReco/after/hIsPhysicalPrimary"))->GetXaxis()->SetBinLabel(1, "Secondary"); registry.get(HIST("trackMCReco/after/hIsPhysicalPrimary"))->GetXaxis()->SetBinLabel(2, "Primary"); - registry.add("trackMCReco/after/incl/hPt_hadron", "", {HistType::kTH1D, {axisPt}}); registry.add("trackMCReco/after/incl/hPt_proton", "", {HistType::kTH1D, {axisPt}}); registry.add("trackMCReco/after/incl/hPt_pion", "", {HistType::kTH1D, {axisPt}}); registry.add("trackMCReco/after/incl/hPt_kaon", "", {HistType::kTH1D, {axisPt}}); - - registry.addClone("trackMCReco/after/incl/", "trackMCReco/after/pos/"); - registry.addClone("trackMCReco/after/incl/", "trackMCReco/after/neg/"); - + registry.addClone("trackMCReco/after/incl/", "trackMCReco/before/pos/"); + registry.addClone("trackMCReco/after/incl/", "trackMCReco/before/neg/"); registry.addClone("trackMCReco/after/", "trackMCReco/before/"); } - if (doprocessData) { - // track properties per centrality and per eta, pt bin - registry.add("incl/vnC_eta", "", kTProfile, {axisEtaVn}); - registry.add("incl/vnA_eta", "", kTProfile, {axisEtaVn}); - - registry.add("incl/vnC_pt", "", kTProfile, {axisPt}); - registry.add("incl/vnA_pt", "", kTProfile, {axisPt}); - registry.add("incl/vnC_pt_odd", "", kTProfile, {axisPt}); - registry.add("incl/vnA_pt_odd", "", kTProfile, {axisPt}); - - registry.add("incl/vnC_cent_minEta", "", kTProfile, {axisCent}); - registry.add("incl/vnA_cent_minEta", "", kTProfile, {axisCent}); - registry.add("incl/vnC_cent_plusEta", "", kTProfile, {axisCent}); - registry.add("incl/vnA_cent_plusEta", "", kTProfile, {axisCent}); - + if (cfgFillGeneralV1Histos) { + // track properties per centrality and per eta, pt bin + registry.add("incl/vnC_eta", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/vnA_eta", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/vnC_pt", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/vnA_pt", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/vnC_pt_odd", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/vnA_pt_odd", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/vnC_cent_minEta", "", kTProfile, {axisCent}); + registry.add("incl/vnA_cent_minEta", "", kTProfile, {axisCent}); + registry.add("incl/vnC_cent_plusEta", "", kTProfile, {axisCent}); + registry.add("incl/vnA_cent_plusEta", "", kTProfile, {axisCent}); + } + if (cfgFillPID) { + registry.add("incl/pion/vnC_eta", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/pion/vnA_eta", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/pion/vnC_pt", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/pion/vnA_pt", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/pion/vnC_pt_odd", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/pion/vnA_pt_odd", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/pion/vnC_cent_minEta", "", kTProfile, {axisCent}); + registry.add("incl/pion/vnA_cent_minEta", "", kTProfile, {axisCent}); + registry.add("incl/pion/vnC_cent_plusEta", "", kTProfile, {axisCent}); + registry.add("incl/pion/vnA_cent_plusEta", "", kTProfile, {axisCent}); + } if (cfgFillXandYterms) { - registry.add("incl/vnAx_eta", "", kTProfile, {axisEtaVn}); - registry.add("incl/vnAy_eta", "", kTProfile, {axisEtaVn}); - registry.add("incl/vnCx_eta", "", kTProfile, {axisEtaVn}); - registry.add("incl/vnCy_eta", "", kTProfile, {axisEtaVn}); - registry.add("incl/vnAx_pt", "", kTProfile, {axisPt}); - registry.add("incl/vnAy_pt", "", kTProfile, {axisPt}); - registry.add("incl/vnCx_pt", "", kTProfile, {axisPt}); - registry.add("incl/vnCy_pt", "", kTProfile, {axisPt}); - registry.add("incl/vnCx_pt_odd", "", kTProfile, {axisPt}); - registry.add("incl/vnAx_pt_odd", "", kTProfile, {axisPt}); - registry.add("incl/vnCy_pt_odd", "", kTProfile, {axisPt}); - registry.add("incl/vnAy_pt_odd", "", kTProfile, {axisPt}); + registry.add("incl/vnAx_eta", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/vnAy_eta", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/vnCx_eta", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/vnCy_eta", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/vnAx_pt", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/vnAy_pt", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/vnCx_pt", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/vnCy_pt", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/vnCx_pt_odd", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/vnAx_pt_odd", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/vnCy_pt_odd", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/vnAy_pt_odd", "", kTProfile2D, {axisPt, axisCentrality}); + if (cfgFillPID) { + registry.add("incl/pion/vnAx_eta", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/pion/vnAy_eta", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/pion/vnCx_eta", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/pion/vnCy_eta", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/pion/vnAx_pt", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/pion/vnAy_pt", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/pion/vnCx_pt", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/pion/vnCy_pt", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/pion/vnCx_pt_odd", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/pion/vnAx_pt_odd", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/pion/vnCy_pt_odd", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/pion/vnAy_pt_odd", "", kTProfile2D, {axisPt, axisCentrality}); + } } - if (cfgFillMixedHarmonics) { - registry.add("incl/v2/vnAxCxUx_pt_MH", "", kTProfile, {axisPt}); - registry.add("incl/v2/vnAxCyUx_pt_MH", "", kTProfile, {axisPt}); - registry.add("incl/v2/vnAxCyUy_pt_MH", "", kTProfile, {axisPt}); - registry.add("incl/v2/vnAyCxUy_pt_MH", "", kTProfile, {axisPt}); - + registry.add("incl/v2/vnAxCxUx_pt_MH", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/v2/vnAxCyUx_pt_MH", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/v2/vnAxCyUy_pt_MH", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/v2/vnAyCxUy_pt_MH", "", kTProfile2D, {axisPt, axisCentrality}); registry.add("incl/v2/vnAxCxUx_cent_MH", "", kTProfile, {axisCent}); registry.add("incl/v2/vnAxCyUx_cent_MH", "", kTProfile, {axisCent}); registry.add("incl/v2/vnAxCyUy_cent_MH", "", kTProfile, {axisCent}); registry.add("incl/v2/vnAyCxUy_cent_MH", "", kTProfile, {axisCent}); - - registry.add("incl/v2/vnAxCxUx_eta_MH", "", kTProfile, {axisEtaVn}); - registry.add("incl/v2/vnAxCyUx_eta_MH", "", kTProfile, {axisEtaVn}); - registry.add("incl/v2/vnAxCyUy_eta_MH", "", kTProfile, {axisEtaVn}); - registry.add("incl/v2/vnAyCxUy_eta_MH", "", kTProfile, {axisEtaVn}); - + registry.add("incl/v2/vnAxCxUx_eta_MH", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/v2/vnAxCyUx_eta_MH", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/v2/vnAxCyUy_eta_MH", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/v2/vnAyCxUy_eta_MH", "", kTProfile2D, {axisEtaVn, axisCentrality}); registry.addClone("incl/v2/", "incl/v3/"); + if (cfgFillPID) { + registry.add("incl/pion/v2/vnAxCxUx_pt_MH", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/pion/v2/vnAxCyUx_pt_MH", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/pion/v2/vnAxCyUy_pt_MH", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/pion/v2/vnAyCxUy_pt_MH", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/pion/v2/vnAxCxUx_cent_MH", "", kTProfile, {axisCent}); + registry.add("incl/pion/v2/vnAxCyUx_cent_MH", "", kTProfile, {axisCent}); + registry.add("incl/pion/v2/vnAxCyUy_cent_MH", "", kTProfile, {axisCent}); + registry.add("incl/pion/v2/vnAyCxUy_cent_MH", "", kTProfile, {axisCent}); + registry.add("incl/pion/v2/vnAxCxUx_eta_MH", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/pion/v2/vnAxCyUx_eta_MH", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/pion/v2/vnAxCyUy_eta_MH", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/pion/v2/vnAyCxUy_eta_MH", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.addClone("incl/pion/v2/", "incl/pion/v3/"); + } } - if (cfgFillEventPlane) { registry.add("incl/vnA_cent_EP", "", kTProfile, {axisCent}); registry.add("incl/vnC_cent_EP", "", kTProfile, {axisCent}); registry.add("incl/vnFull_cent_EP", "", kTProfile, {axisCent}); - registry.add("incl/vnA_pt_EP", "", kTProfile, {axisPt}); - registry.add("incl/vnC_pt_EP", "", kTProfile, {axisPt}); - registry.add("incl/vnFull_pt_EP", "", kTProfile, {axisPt}); - registry.add("incl/vnA_eta_EP", "", kTProfile, {axisEtaVn}); - registry.add("incl/vnC_eta_EP", "", kTProfile, {axisEtaVn}); - registry.add("incl/vnFull_eta_EP", "", kTProfile, {axisEtaVn}); + registry.add("incl/vnA_pt_EP", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/vnC_pt_EP", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/vnFull_pt_EP", "", kTProfile2D, {axisPt, axisCentrality}); + registry.add("incl/vnA_eta_EP", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/vnC_eta_EP", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/vnFull_eta_EP", "", kTProfile2D, {axisEtaVn, axisCentrality}); } - - if (cfgFillQAHistos) { - registry.add("QA/qAqCX", "", kTProfile, {axisCent}); - registry.add("QA/qAqCY", "", kTProfile, {axisCent}); - registry.add("QA/qAqCXY", "", kTProfile, {axisCent}); - registry.add("QA/qAXqCY", "", kTProfile, {axisCent}); - registry.add("QA/qAYqCX", "", kTProfile, {axisCent}); - registry.add("QA/qAXYqCXY", "", kTProfile, {axisCent}); - + if (cfgFillEventPlaneQA) { registry.add("QA/hSPplaneA", "hSPplaneA", kTH1D, {axisPhiPlane}); registry.add("QA/hSPplaneC", "hSPplaneC", kTH1D, {axisPhiPlane}); registry.add("QA/hSPplaneFull", "hSPplaneFull", kTH1D, {axisPhiPlane}); - - registry.add("QA/hCentFull", " ; Centrality (%); ", {HistType::kTH1D, {axisCent}}); - registry.add("QA/hCosPhiACosPhiC", "hCosPhiACosPhiC; Centrality(%); #LT Cos(#Psi^{A})Cos(#Psi^{C})#GT", kTProfile, {axisCent}); registry.add("QA/hSinPhiASinPhiC", "hSinPhiASinPhiC; Centrality(%); #LT Sin(#Psi^{A})Sin(#Psi^{C})#GT", kTProfile, {axisCent}); registry.add("QA/hSinPhiACosPhiC", "hSinPhiACosPhiC; Centrality(%); #LT Sin(#Psi^{A})Cos(#Psi^{C})#GT", kTProfile, {axisCent}); registry.add("QA/hCosPhiASinsPhiC", "hCosPhiASinsPhiC; Centrality(%); #LT Cos(#Psi^{A})Sin(#Psi^{C})#GT", kTProfile, {axisCent}); registry.add("QA/hFullEvPlaneRes", "hFullEvPlaneRes; Centrality(%); -#LT Cos(#Psi^{A} - #Psi^{C})#GT ", kTProfile, {axisCent}); - registry.add("QA/after/PsiA_vs_Cent", "", {HistType::kTH2D, {axisPhiPlane, axisCent}}); registry.add("QA/after/PsiC_vs_Cent", "", {HistType::kTH2D, {axisPhiPlane, axisCent}}); registry.add("QA/after/PsiFull_vs_Cent", "", {HistType::kTH2D, {axisPhiPlane, axisCent}}); - registry.add("QA/after/PsiA_vs_Vx", "", {HistType::kTH2D, {axisPhiPlane, axisVx}}); registry.add("QA/after/PsiC_vs_Vx", "", {HistType::kTH2D, {axisPhiPlane, axisVx}}); registry.add("QA/after/PsiFull_vs_Vx", "", {HistType::kTH2D, {axisPhiPlane, axisVx}}); - registry.add("QA/after/PsiA_vs_Vy", "", {HistType::kTH2D, {axisPhiPlane, axisVy}}); registry.add("QA/after/PsiC_vs_Vy", "", {HistType::kTH2D, {axisPhiPlane, axisVy}}); registry.add("QA/after/PsiFull_vs_Vy", "", {HistType::kTH2D, {axisPhiPlane, axisVy}}); - registry.add("QA/after/PsiA_vs_Vz", "", {HistType::kTH2D, {axisPhiPlane, axisVz}}); registry.add("QA/after/PsiC_vs_Vz", "", {HistType::kTH2D, {axisPhiPlane, axisVz}}); registry.add("QA/after/PsiFull_vs_Vz", "", {HistType::kTH2D, {axisPhiPlane, axisVz}}); } + if (cfgFillEventQA) { + registry.add("QA/qAqCX", "", kTProfile, {axisCent}); + registry.add("QA/qAqCY", "", kTProfile, {axisCent}); + registry.add("QA/qAqCXY", "", kTProfile, {axisCent}); + registry.add("QA/qAXqCY", "", kTProfile, {axisCent}); + registry.add("QA/qAYqCX", "", kTProfile, {axisCent}); + registry.add("QA/qAXYqCXY", "", kTProfile, {axisCent}); + registry.add("QA/hCentFull", " ; Centrality (%); ", {HistType::kTH1D, {axisCent}}); + } + } // end of doprocessData + if (cfgFillQABefore && (cfgFillEventQA || cfgFillPIDQA)) + registry.addClone("QA/after/", "QA/before/"); + + if (cfgFillPID || cfgFillPIDQA) { + registry.addClone("incl/pion/", "incl/kaon/"); + registry.addClone("incl/pion/", "incl/proton/"); + registry.addClone("incl/pion/", "incl/unidentified/"); } - - registry.addClone("QA/after/", "QA/before/"); - - if (cfgFillChargeDependence) { + if (cfgFillChargeDependence || cfgFillPIDQA) { registry.addClone("incl/", "pos/"); registry.addClone("incl/", "neg/"); } - } - - if (doprocessMCGen) { + } else if (doprocessMCGen) { registry.add("trackMCGen/nCollReconstructedPerMcCollision", "", {HistType::kTH1D, {{10, -5, 5}}}); - registry.add("trackMCGen/before/incl/hPt_hadron", "", {HistType::kTH1D, {axisPt}}); - registry.add("trackMCGen/before/incl/hPt_proton", "", {HistType::kTH1D, {axisPt}}); - registry.add("trackMCGen/before/incl/hPt_pion", "", {HistType::kTH1D, {axisPt}}); - registry.add("trackMCGen/before/incl/hPt_kaon", "", {HistType::kTH1D, {axisPt}}); - registry.add("trackMCGen/before/incl/phi_eta_vtxZ_gen", "", {HistType::kTH3D, {axisPhi, axisEta, axisVz}}); - registry.addClone("trackMCGen/before/incl/", "trackMCGen/before/pos/"); - registry.addClone("trackMCGen/before/incl/", "trackMCGen/before/neg/"); - registry.addClone("trackMCGen/before/", "trackMCGen/after/"); + registry.add("trackMCGen/after/incl/hPt_hadron", "", {HistType::kTH1D, {axisPt}}); + registry.add("trackMCGen/after/incl/hPt_proton", "", {HistType::kTH1D, {axisPt}}); + registry.add("trackMCGen/after/incl/hPt_pion", "", {HistType::kTH1D, {axisPt}}); + registry.add("trackMCGen/after/incl/hPt_kaon", "", {HistType::kTH1D, {axisPt}}); + registry.add("trackMCGen/after/incl/phi_eta_vtxZ_gen", "", {HistType::kTH3D, {axisPhi, axisEta, axisVz}}); + registry.addClone("trackMCGen/after/incl/", "trackMCGen/before/pos/"); + registry.addClone("trackMCGen/after/incl/", "trackMCGen/before/neg/"); + if (cfgFillQABefore) + registry.addClone("trackMCGen/after/", "trackMCGen/before/"); } - registry.add("hEventCount", "Number of Event; Cut; #Events Passed Cut", {HistType::kTH1D, {{nEventSelections, 0, nEventSelections}}}); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_FilteredEvent + 1, "Filtered event"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_sel8 + 1, "Sel8"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_occupancy + 1, "kOccupancy"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kTVXinTRD + 1, "kTVXinTRD"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kNoSameBunchPileup + 1, "kNoSameBunchPileup"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsGoodZvtxFT0vsPV + 1, "kIsGoodZvtxFT0vsPV"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kNoCollInTimeRangeStandard + 1, "kNoCollInTimeRangeStandard"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsVertexITSTPC + 1, "kIsVertexITSTPC"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_MultCuts + 1, "Mult cuts (Alex)"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_kIsGoodITSLayersAll + 1, "kkIsGoodITSLayersAll"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_isSelectedZDC + 1, "isSelected"); - registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_CentCuts + 1, "Cenrality range"); - - registry.add("hTrackCount", "Number of Tracks; Cut; #Tracks Passed Cut", {HistType::kTH1D, {{nTrackSelections, 0, nTrackSelections}}}); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_Eta + 1, "Eta"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_Pt + 1, "Pt"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_DCAxy + 1, "DCAxy"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_DCAz + 1, "DCAz"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_GlobalTracks + 1, "GlobalTracks"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_NCls + 1, "nClusters TPC"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_FshCls + 1, "Frac. sh. Cls TPC"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_TPCBoundary + 1, "TPC Boundary"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_ZeroCharge + 1, "Only charged"); - registry.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_ParticleWeights + 1, "Apply weights"); - if (cfgEvSelsUseAdditionalEventCut) { int twoSigma = 2; @@ -575,6 +648,55 @@ struct FlowSP { fPhiCutLow = new TF1("fPhiCutLow", "0.06/x+pi/18.0-0.06", 0, 100); fPhiCutHigh = new TF1("fPhiCutHigh", "0.1/x+pi/18.0+0.06", 0, 100); } + } // end of init + + template + int getTrackPID(TrackObject track) + { + + float usedNSigmaPi = -1; + float usedNSigmaKa = -1; + float usedNSigmaPr = -1; + + if (track.hasTOF() && track.hasTPC()) { + usedNSigmaPi = std::hypot(track.tofNSigmaPi(), track.tpcNSigmaPi()); + usedNSigmaKa = std::hypot(track.tofNSigmaKa(), track.tpcNSigmaKa()); + usedNSigmaPr = std::hypot(track.tofNSigmaPr(), track.tpcNSigmaPr()); + } else if (track.hasTOF()) { + usedNSigmaPi = track.tofNSigmaPi(); + usedNSigmaKa = track.tofNSigmaKa(); + usedNSigmaPr = track.tofNSigmaPr(); + } else if (track.hasTPC()) { + usedNSigmaPi = track.tpcNSigmaPi(); + usedNSigmaKa = track.tpcNSigmaKa(); + usedNSigmaPr = track.tpcNSigmaPr(); + } else { + return kUnidentified; // No PID information available + } + + std::unordered_map usedNSigma = {{usedNSigmaPi, kPion}, {usedNSigmaKa, kKaon}, {usedNSigmaPr, kProton}}; + + int nIdentified = 0; + int valPID = 0; + + for (const auto& nsigma : usedNSigma) { + if (std::abs(nsigma.first) < cfgTrackSelsPIDNsigma) { + valPID = nsigma.second; + nIdentified++; + } + } + + if (nIdentified == 0) { + // LOGF(warning, "No PID match found for |nSigma| < %.2f", cfgTrackSelsPIDNsigma); + return kUnidentified; // No PID match found + } else if (nIdentified == 1) { + return valPID; + } else { + // LOGF(warning, "Track identified as %i particles for |nSigma| < %.2f", nIdentified, cfgTrackSelsPIDNsigma); + return kUnidentified; // Multiple PID matches found + } + + return -1; } int getMagneticField(uint64_t timestamp) @@ -793,175 +915,206 @@ struct FlowSP { phimodn += o2::constants::math::PI / 18.0; // to center gap in the middle phimodn = fmod(phimodn, o2::constants::math::PI / 9.0); - if (cfgFillQAHistos) + if (cfgFillTrackQA) registry.fill(HIST("QA/before/pt_phi"), track.pt(), phimodn); if (cfgTrackSelsUseAdditionalTrackCut) { if (phimodn < fPhiCutHigh->Eval(track.pt()) && phimodn > fPhiCutLow->Eval(track.pt())) return false; // reject track } - if (cfgFillQAHistos) + if (cfgFillTrackQA) registry.fill(HIST("QA/after/pt_phi"), track.pt(), phimodn); registry.fill(HIST("hTrackCount"), trackSel_TPCBoundary); return true; } template - inline void fillEventQA(CollisionObject collision, TracksObject tracks) + inline void fillEventQA(CollisionObject collision, TracksObject tracks, double centWeight = 1.0) { + if (!cfgFillEventQA) + return; + static constexpr std::string_view Time[] = {"before", "after"}; - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hCentFT0C"), collision.centFT0C()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hCentNGlobal"), collision.centNGlobal()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hCentFT0M"), collision.centFT0M()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hCentFV0A"), collision.centFV0A()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/globalTracks_centT0C"), collision.centFT0C(), tracks.size()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PVTracks_centT0C"), collision.centFT0C(), collision.multNTracksPV()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/globalTracks_multT0A"), collision.multFT0A(), tracks.size()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/globalTracks_multV0A"), collision.multFV0A(), tracks.size()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/multV0A_multT0A"), collision.multFT0A(), collision.multFV0A()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/multT0C_centT0C"), collision.centFT0C(), collision.multFT0C()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentFT0Cvariant1"), collision.centFT0C(), collision.centFT0CVariant1()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentFT0M"), collision.centFT0C(), collision.centFT0M()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentFV0A"), collision.centFT0C(), collision.centFV0A()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentNGlobal"), collision.centFT0C(), collision.centNGlobal()); - - if constexpr (framework::has_type_v) { - double psiA = 1.0 * std::atan2(collision.qyA(), collision.qxA()); - double psiC = 1.0 * std::atan2(collision.qyC(), collision.qxC()); - double psiFull = 1.0 * std::atan2(collision.qyA() + collision.qyC(), collision.qxA() + collision.qxC()); - - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiA_vs_Cent"), psiA, collision.centFT0C()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiC_vs_Cent"), psiC, collision.centFT0C()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiFull_vs_Cent"), psiFull, collision.centFT0C()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiA_vs_Vx"), psiA, collision.vx()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiC_vs_Vx"), psiC, collision.vx()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiFull_vs_Vx"), psiFull, collision.vx()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiA_vs_Vy"), psiA, collision.vy()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiC_vs_Vy"), psiC, collision.vy()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiFull_vs_Vy"), psiFull, collision.vy()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiA_vs_Vz"), psiA, collision.posZ()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiC_vs_Vz"), psiC, collision.posZ()); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiFull_vs_Vz"), psiFull, collision.posZ()); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hCentFT0C"), collision.centFT0C(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hCentNGlobal"), collision.centNGlobal(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hCentFT0M"), collision.centFT0M(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hCentFV0A"), collision.centFV0A(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/globalTracks_centT0C"), collision.centFT0C(), tracks.size(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PVTracks_centT0C"), collision.centFT0C(), collision.multNTracksPV(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/globalTracks_multT0A"), collision.multFT0A(), tracks.size(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/globalTracks_multV0A"), collision.multFV0A(), tracks.size(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/multV0A_multT0A"), collision.multFT0A(), collision.multFV0A(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/multT0C_centT0C"), collision.centFT0C(), collision.multFT0C(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentFT0Cvariant1"), collision.centFT0C(), collision.centFT0CVariant1(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentFT0M"), collision.centFT0C(), collision.centFT0M(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentFV0A"), collision.centFT0C(), collision.centFV0A(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentNGlobal"), collision.centFT0C(), collision.centNGlobal(), centWeight); + + if (cfgFillEventPlaneQA) { + if constexpr (framework::has_type_v) { + double psiA = 1.0 * std::atan2(collision.qyA(), collision.qxA()); + double psiC = 1.0 * std::atan2(collision.qyC(), collision.qxC()); + double psiFull = 1.0 * std::atan2(collision.qyA() + collision.qyC(), collision.qxA() + collision.qxC()); + + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiA_vs_Cent"), psiA, collision.centFT0C(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiC_vs_Cent"), psiC, collision.centFT0C(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiFull_vs_Cent"), psiFull, collision.centFT0C(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiA_vs_Vx"), psiA, collision.vx(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiC_vs_Vx"), psiC, collision.vx(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiFull_vs_Vx"), psiFull, collision.vx(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiA_vs_Vy"), psiA, collision.vy(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiC_vs_Vy"), psiC, collision.vy(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiFull_vs_Vy"), psiFull, collision.vy(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiA_vs_Vz"), psiA, collision.posZ(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiC_vs_Vz"), psiC, collision.posZ(), centWeight); + registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiFull_vs_Vz"), psiFull, collision.posZ(), centWeight); + } } return; } - template - inline void fillHistograms(TrackObject track, float wacc, float weff, double ux, double uy, double uxMH, double uyMH, double uxMH2, double uyMH2, double qxA, double qyA, double qxC, double qyC, double corrQQx, double corrQQy, double corrQQ, double vnA, double vnC, double vnFull, double centrality) + template + inline void fillHistograms(TrackObject track, float wacc, float weff, double centWeight, double ux, double uy, double uxMH, double uyMH, double uxMH2, double uyMH2, double qxA, double qyA, double qxC, double qyC, double corrQQx, double corrQQy, double corrQQ, double vnA, double vnC, double vnFull, double centrality) { - registry.fill(HIST(Charge[ct]) + HIST("vnA_eta"), track.eta(), (uy * qyA + ux * qxA) / std::sqrt(std::fabs(corrQQ)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnC_eta"), track.eta(), (uy * qyC + ux * qxC) / std::sqrt(std::fabs(corrQQ)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnA_pt"), track.pt(), (uy * qyA + ux * qxA) / std::sqrt(std::fabs(corrQQ)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnC_pt"), track.pt(), (uy * qyC + ux * qxC) / std::sqrt(std::fabs(corrQQ)), wacc * weff); + double weight = wacc * weff * centWeight; + + if (cfgFillGeneralV1Histos) { + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnA_eta"), track.eta(), centrality, (uy * qyA + ux * qxA) / std::sqrt(std::fabs(corrQQ)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnC_eta"), track.eta(), centrality, (uy * qyC + ux * qxC) / std::sqrt(std::fabs(corrQQ)), weight); + + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnA_pt"), track.pt(), centrality, (uy * qyA + ux * qxA) / std::sqrt(std::fabs(corrQQ)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnC_pt"), track.pt(), centrality, (uy * qyC + ux * qxC) / std::sqrt(std::fabs(corrQQ)), weight); + } if (cfgFillMixedHarmonics) { - registry.fill(HIST(Charge[ct]) + HIST("v2/vnAxCxUx_eta_MH"), track.eta(), (uxMH * qxA * qxC) / corrQQx, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v2/vnAxCyUx_eta_MH"), track.eta(), (uxMH * qyA * qyC) / corrQQy, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v2/vnAxCyUy_eta_MH"), track.eta(), (uyMH * qxA * qyC) / corrQQx, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v2/vnAyCxUy_eta_MH"), track.eta(), (uyMH * qyA * qxC) / corrQQy, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v2/vnAxCxUx_eta_MH"), track.eta(), centrality, (uxMH * qxA * qxC) / corrQQx, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v2/vnAxCyUx_eta_MH"), track.eta(), centrality, (uxMH * qyA * qyC) / corrQQy, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v2/vnAxCyUy_eta_MH"), track.eta(), centrality, (uyMH * qxA * qyC) / corrQQx, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v2/vnAyCxUy_eta_MH"), track.eta(), centrality, (uyMH * qyA * qxC) / corrQQy, weight); - registry.fill(HIST(Charge[ct]) + HIST("v2/vnAxCxUx_pt_MH"), track.pt(), (uxMH * qxA * qxC) / corrQQx, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v2/vnAxCyUx_pt_MH"), track.pt(), (uxMH * qyA * qyC) / corrQQy, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v2/vnAxCyUy_pt_MH"), track.pt(), (uyMH * qxA * qyC) / corrQQx, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v2/vnAyCxUy_pt_MH"), track.pt(), (uyMH * qyA * qxC) / corrQQy, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v2/vnAxCxUx_pt_MH"), track.pt(), centrality, (uxMH * qxA * qxC) / corrQQx, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v2/vnAxCyUx_pt_MH"), track.pt(), centrality, (uxMH * qyA * qyC) / corrQQy, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v2/vnAxCyUy_pt_MH"), track.pt(), centrality, (uyMH * qxA * qyC) / corrQQx, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v2/vnAyCxUy_pt_MH"), track.pt(), centrality, (uyMH * qyA * qxC) / corrQQy, weight); - registry.fill(HIST(Charge[ct]) + HIST("v2/vnAxCxUx_cent_MH"), centrality, (uxMH * qxA * qxC) / corrQQx, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v2/vnAxCyUx_cent_MH"), centrality, (uxMH * qyA * qyC) / corrQQy, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v2/vnAxCyUy_cent_MH"), centrality, (uyMH * qxA * qyC) / corrQQx, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v2/vnAyCxUy_cent_MH"), centrality, (uyMH * qyA * qxC) / corrQQy, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v2/vnAxCxUx_cent_MH"), centrality, (uxMH * qxA * qxC) / corrQQx, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v2/vnAxCyUx_cent_MH"), centrality, (uxMH * qyA * qyC) / corrQQy, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v2/vnAxCyUy_cent_MH"), centrality, (uyMH * qxA * qyC) / corrQQx, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v2/vnAyCxUy_cent_MH"), centrality, (uyMH * qyA * qxC) / corrQQy, weight); // -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - registry.fill(HIST(Charge[ct]) + HIST("v3/vnAxCxUx_eta_MH"), track.eta(), (uxMH2 * qxA * qxC) / corrQQx, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v3/vnAxCyUx_eta_MH"), track.eta(), (uxMH2 * qyA * qyC) / corrQQy, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v3/vnAxCyUy_eta_MH"), track.eta(), (uyMH2 * qxA * qyC) / corrQQx, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v3/vnAyCxUy_eta_MH"), track.eta(), (uyMH2 * qyA * qxC) / corrQQy, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v3/vnAxCxUx_eta_MH"), track.eta(), centrality, (uxMH2 * qxA * qxC) / corrQQx, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v3/vnAxCyUx_eta_MH"), track.eta(), centrality, (uxMH2 * qyA * qyC) / corrQQy, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v3/vnAxCyUy_eta_MH"), track.eta(), centrality, (uyMH2 * qxA * qyC) / corrQQx, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v3/vnAyCxUy_eta_MH"), track.eta(), centrality, (uyMH2 * qyA * qxC) / corrQQy, weight); - registry.fill(HIST(Charge[ct]) + HIST("v3/vnAxCxUx_pt_MH"), track.pt(), (uxMH2 * qxA * qxC) / corrQQx, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v3/vnAxCyUx_pt_MH"), track.pt(), (uxMH2 * qyA * qyC) / corrQQy, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v3/vnAxCyUy_pt_MH"), track.pt(), (uyMH2 * qxA * qyC) / corrQQx, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v3/vnAyCxUy_pt_MH"), track.pt(), (uyMH2 * qyA * qxC) / corrQQy, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v3/vnAxCxUx_pt_MH"), track.pt(), centrality, (uxMH2 * qxA * qxC) / corrQQx, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v3/vnAxCyUx_pt_MH"), track.pt(), centrality, (uxMH2 * qyA * qyC) / corrQQy, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v3/vnAxCyUy_pt_MH"), track.pt(), centrality, (uyMH2 * qxA * qyC) / corrQQx, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v3/vnAyCxUy_pt_MH"), track.pt(), centrality, (uyMH2 * qyA * qxC) / corrQQy, weight); - registry.fill(HIST(Charge[ct]) + HIST("v3/vnAxCxUx_cent_MH"), centrality, (uxMH2 * qxA * qxC) / corrQQx, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v3/vnAxCyUx_cent_MH"), centrality, (uxMH2 * qyA * qyC) / corrQQy, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v3/vnAxCyUy_cent_MH"), centrality, (uyMH2 * qxA * qyC) / corrQQx, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("v3/vnAyCxUy_cent_MH"), centrality, (uyMH2 * qyA * qxC) / corrQQy, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v3/vnAxCxUx_cent_MH"), centrality, (uxMH2 * qxA * qxC) / corrQQx, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v3/vnAxCyUx_cent_MH"), centrality, (uxMH2 * qyA * qyC) / corrQQy, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v3/vnAxCyUy_cent_MH"), centrality, (uyMH2 * qxA * qyC) / corrQQx, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("v3/vnAyCxUy_cent_MH"), centrality, (uyMH2 * qyA * qxC) / corrQQy, weight); } if (cfgFillXandYterms) { - registry.fill(HIST(Charge[ct]) + HIST("vnAx_eta"), track.eta(), (ux * qxA) / std::sqrt(std::fabs(corrQQx)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnAy_eta"), track.eta(), (uy * qyA) / std::sqrt(std::fabs(corrQQy)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnCx_eta"), track.eta(), (ux * qxC) / std::sqrt(std::fabs(corrQQx)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnCy_eta"), track.eta(), (uy * qyC) / std::sqrt(std::fabs(corrQQy)), wacc * weff); - - registry.fill(HIST(Charge[ct]) + HIST("vnAx_pt"), track.pt(), (ux * qxA) / std::sqrt(std::fabs(corrQQx)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnAy_pt"), track.pt(), (uy * qyA) / std::sqrt(std::fabs(corrQQy)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnCx_pt"), track.pt(), (ux * qxC) / std::sqrt(std::fabs(corrQQx)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnCy_pt"), track.pt(), (uy * qyC) / std::sqrt(std::fabs(corrQQy)), wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnAx_eta"), track.eta(), centrality, (ux * qxA) / std::sqrt(std::fabs(corrQQx)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnAy_eta"), track.eta(), centrality, (uy * qyA) / std::sqrt(std::fabs(corrQQy)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCx_eta"), track.eta(), centrality, (ux * qxC) / std::sqrt(std::fabs(corrQQx)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCy_eta"), track.eta(), centrality, (uy * qyC) / std::sqrt(std::fabs(corrQQy)), weight); + + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnAx_pt"), track.pt(), centrality, (ux * qxA) / std::sqrt(std::fabs(corrQQx)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnAy_pt"), track.pt(), centrality, (uy * qyA) / std::sqrt(std::fabs(corrQQy)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCx_pt"), track.pt(), centrality, (ux * qxC) / std::sqrt(std::fabs(corrQQx)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCy_pt"), track.pt(), centrality, (uy * qyC) / std::sqrt(std::fabs(corrQQy)), weight); } if (cfgFillEventPlane) { - registry.fill(HIST(Charge[ct]) + HIST("vnA_eta_EP"), track.eta(), vnA, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnC_eta_EP"), track.eta(), vnC, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnFull_eta_EP"), track.eta(), vnFull, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnA_eta_EP"), track.eta(), centrality, vnA, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnC_eta_EP"), track.eta(), centrality, vnC, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnFull_eta_EP"), track.eta(), centrality, vnFull, weight); - registry.fill(HIST(Charge[ct]) + HIST("vnA_pt_EP"), track.pt(), vnA, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnC_pt_EP"), track.pt(), vnC, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnFull_pt_EP"), track.pt(), vnFull, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnA_pt_EP"), track.pt(), centrality, vnA, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnC_pt_EP"), track.pt(), centrality, vnC, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnFull_pt_EP"), track.pt(), centrality, vnFull, weight); - registry.fill(HIST(Charge[ct]) + HIST("vnA_cent_EP"), centrality, vnA, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnC_cent_EP"), centrality, vnC, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnFull_cent_EP"), centrality, vnFull, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnA_cent_EP"), centrality, vnA, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnC_cent_EP"), centrality, vnC, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnFull_cent_EP"), centrality, vnFull, weight); } // For integrated v1 take only tracks from eta>0. // Following https://arxiv.org/pdf/1306.4145 - if (track.eta() < 0 && cfgHarm == 1) { - registry.fill(HIST(Charge[ct]) + HIST("vnA_cent_minEta"), centrality, -1.0 * (uy * qyA + ux * qxA) / std::sqrt(std::fabs(corrQQ)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnC_cent_minEta"), centrality, -1.0 * (uy * qyC + ux * qxC) / std::sqrt(std::fabs(corrQQ)), wacc * weff); - - registry.fill(HIST(Charge[ct]) + HIST("vnA_pt_odd"), track.pt(), -1.0 * (uy * qyA + ux * qxA) / std::sqrt(std::fabs(corrQQ)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnC_pt_odd"), track.pt(), -1.0 * (uy * qyC + ux * qxC) / std::sqrt(std::fabs(corrQQ)), wacc * weff); - - if (cfgFillXandYterms) { - registry.fill(HIST(Charge[ct]) + HIST("vnAx_pt_odd"), track.pt(), -1.0 * (ux * qxA) / std::sqrt(std::fabs(corrQQx)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnAy_pt_odd"), track.pt(), -1.0 * (uy * qyA) / std::sqrt(std::fabs(corrQQy)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnCx_pt_odd"), track.pt(), -1.0 * (ux * qxC) / std::sqrt(std::fabs(corrQQx)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnCy_pt_odd"), track.pt(), -1.0 * (uy * qyC) / std::sqrt(std::fabs(corrQQy)), wacc * weff); - } - } else { - registry.fill(HIST(Charge[ct]) + HIST("vnA_cent_plusEta"), centrality, (uy * qyA + ux * qxA) / std::sqrt(std::fabs(corrQQ)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnC_cent_plusEta"), centrality, (uy * qyC + ux * qxC) / std::sqrt(std::fabs(corrQQ)), wacc * weff); + if (cfgFillGeneralV1Histos) { + if (track.eta() < 0 && cfgHarm == 1) { + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnA_cent_minEta"), centrality, -1.0 * (uy * qyA + ux * qxA) / std::sqrt(std::fabs(corrQQ)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnC_cent_minEta"), centrality, -1.0 * (uy * qyC + ux * qxC) / std::sqrt(std::fabs(corrQQ)), weight); - registry.fill(HIST(Charge[ct]) + HIST("vnA_pt_odd"), track.pt(), (uy * qyA + ux * qxA) / std::sqrt(std::fabs(corrQQ)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnC_pt_odd"), track.pt(), (uy * qyC + ux * qxC) / std::sqrt(std::fabs(corrQQ)), wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnA_pt_odd"), track.pt(), centrality, -1.0 * (uy * qyA + ux * qxA) / std::sqrt(std::fabs(corrQQ)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnC_pt_odd"), track.pt(), centrality, -1.0 * (uy * qyC + ux * qxC) / std::sqrt(std::fabs(corrQQ)), weight); - if (cfgFillXandYterms) { - registry.fill(HIST(Charge[ct]) + HIST("vnAx_pt_odd"), track.pt(), (ux * qxA) / std::sqrt(std::fabs(corrQQx)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnAy_pt_odd"), track.pt(), (uy * qyA) / std::sqrt(std::fabs(corrQQy)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnCx_pt_odd"), track.pt(), (ux * qxC) / std::sqrt(std::fabs(corrQQx)), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("vnCy_pt_odd"), track.pt(), (uy * qyC) / std::sqrt(std::fabs(corrQQy)), wacc * weff); + if (cfgFillXandYterms) { + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnAx_pt_odd"), track.pt(), centrality, -1.0 * (ux * qxA) / std::sqrt(std::fabs(corrQQx)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnAy_pt_odd"), track.pt(), centrality, -1.0 * (uy * qyA) / std::sqrt(std::fabs(corrQQy)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCx_pt_odd"), track.pt(), centrality, -1.0 * (ux * qxC) / std::sqrt(std::fabs(corrQQx)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCy_pt_odd"), track.pt(), centrality, -1.0 * (uy * qyC) / std::sqrt(std::fabs(corrQQy)), weight); + } + } else { + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnA_cent_plusEta"), centrality, (uy * qyA + ux * qxA) / std::sqrt(std::fabs(corrQQ)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnC_cent_plusEta"), centrality, (uy * qyC + ux * qxC) / std::sqrt(std::fabs(corrQQ)), weight); + + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnA_pt_odd"), track.pt(), centrality, (uy * qyA + ux * qxA) / std::sqrt(std::fabs(corrQQ)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnC_pt_odd"), track.pt(), centrality, (uy * qyC + ux * qxC) / std::sqrt(std::fabs(corrQQ)), weight); + + if (cfgFillXandYterms) { + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnAx_pt_odd"), track.pt(), centrality, (ux * qxA) / std::sqrt(std::fabs(corrQQx)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnAy_pt_odd"), track.pt(), centrality, (uy * qyA) / std::sqrt(std::fabs(corrQQy)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCx_pt_odd"), track.pt(), centrality, (ux * qxC) / std::sqrt(std::fabs(corrQQx)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCy_pt_odd"), track.pt(), centrality, (uy * qyC) / std::sqrt(std::fabs(corrQQy)), weight); + } } } } - template + template inline void fillTrackQA(TrackObject track, double vz, float wacc = 1, float weff = 1) { + if (!cfgFillTrackQA) + return; + static constexpr std::string_view Time[] = {"before/", "after/"}; + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt"), track.pt(), wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi"), track.phi(), wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hEta"), track.eta(), wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_vz"), track.phi(), track.eta(), vz, wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hDCAxy_pt"), track.pt(), track.dcaXY(), wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hDCAz_pt"), track.pt(), track.dcaZ(), wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hSharedClusters_pt"), track.pt(), track.tpcFractionSharedCls(), wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hCrossedRows_pt"), track.pt(), track.tpcNClsFound(), wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("QA/") + HIST(Time[ft]) + HIST("hCrossedRows_vs_SharedClusters"), track.tpcNClsFound(), track.tpcFractionSharedCls(), wacc * weff); + } + + template + inline void fillPIDQA(TrackObject track) + { + if (!cfgFillPIDQA) + return; - registry.fill(HIST(Charge[ct]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt"), track.pt(), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi"), track.phi(), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("QA/") + HIST(Time[ft]) + HIST("hEta"), track.eta(), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_vz"), track.phi(), track.eta(), vz, wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("QA/") + HIST(Time[ft]) + HIST("hDCAxy_pt"), track.pt(), track.dcaXY(), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("QA/") + HIST(Time[ft]) + HIST("hDCAz_pt"), track.pt(), track.dcaZ(), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("QA/") + HIST(Time[ft]) + HIST("hSharedClusters_pt"), track.pt(), track.tpcFractionSharedCls(), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("QA/") + HIST(Time[ft]) + HIST("hCrossedRows_pt"), track.pt(), track.tpcNClsFound(), wacc * weff); - registry.fill(HIST(Charge[ct]) + HIST("QA/") + HIST(Time[ft]) + HIST("hCrossedRows_vs_SharedClusters"), track.tpcNClsFound(), track.tpcFractionSharedCls(), wacc * weff); + registry.fill(HIST(Charge[ct]) + HIST("pion/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTOF_pt"), track.pt(), track.tofNSigmaPi()); + registry.fill(HIST(Charge[ct]) + HIST("pion/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTPC_pt"), track.pt(), track.tpcNSigmaPi()); + registry.fill(HIST(Charge[ct]) + HIST("kaon/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTOF_pt"), track.pt(), track.tofNSigmaKa()); + registry.fill(HIST(Charge[ct]) + HIST("kaon/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTPC_pt"), track.pt(), track.tpcNSigmaKa()); + registry.fill(HIST(Charge[ct]) + HIST("proton/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTOF_pt"), track.pt(), track.tofNSigmaPr()); + registry.fill(HIST(Charge[ct]) + HIST("proton/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTPC_pt"), track.pt(), track.tpcNSigmaPr()); + + registry.fill(HIST(Charge[ct]) + HIST("QA/") + HIST(Time[ft]) + HIST("hdEdxTPC_pt"), track.pt(), track.tpcSignal()); + registry.fill(HIST(Charge[ct]) + HIST("QA/") + HIST(Time[ft]) + HIST("hBetaTOF_pt"), track.pt(), track.beta()); } template @@ -1013,6 +1166,20 @@ struct FlowSP { } } + template + void fillAllQA(TrackObject track, double vtxz, bool pos) + { + fillTrackQA(track, vtxz); + fillPIDQA(track); + if (pos) { + fillTrackQA(track, vtxz); + fillPIDQA(track); + } else { + fillTrackQA(track, vtxz); + fillPIDQA(track); + } + } + void processData(UsedCollisions::iterator const& collision, aod::BCsWithTimestamps const&, UsedTracks const& tracks) { registry.fill(HIST("hEventCount"), evSel_FilteredEvent); @@ -1023,9 +1190,11 @@ struct FlowSP { if (bc.runNumber() != cfg.lastRunNumber) { // load corrections again for new run! cfg.correctionsLoaded = false; + cfg.clCentrality = false; cfg.lastRunNumber = bc.runNumber(); } - if (cfgFillQAHistos) + + if (cfgFillQABefore) fillEventQA(collision, tracks); loadCorrections(bc.timestamp()); @@ -1060,8 +1229,16 @@ struct FlowSP { // https://twiki.cern.ch/twiki/pub/ALICE/DirectedFlowAnalysisNote/vn_ZDC_ALICE_INT_NOTE_version02.pdf double psiFull = 1.0 * std::atan2(qyA + qyC, qxA + qxC); - if (cfgFillQAHistos) { + if (cfgFillEventQA) { registry.fill(HIST("QA/hCentFull"), centrality, 1); + registry.fill(HIST("QA/qAqCXY"), centrality, qxA * qxC + qyA * qyC); + registry.fill(HIST("QA/qAXqCY"), centrality, qxA * qyC); + registry.fill(HIST("QA/qAYqCX"), centrality, qyA * qxC); + registry.fill(HIST("QA/qAXYqCXY"), centrality, qyA * qxC + qxA * qyC); + registry.fill(HIST("QA/qAqCX"), centrality, qxA * qxC); + registry.fill(HIST("QA/qAqCY"), centrality, qyA * qyC); + } + if (cfgFillEventPlaneQA) { registry.fill(HIST("QA/hSPplaneA"), psiA, 1); registry.fill(HIST("QA/hSPplaneC"), psiC, 1); registry.fill(HIST("QA/hSPplaneFull"), psiFull, 1); @@ -1070,12 +1247,6 @@ struct FlowSP { registry.fill(HIST("QA/hSinPhiACosPhiC"), centrality, std::sin(psiA) * std::cos(psiC)); registry.fill(HIST("QA/hCosPhiASinsPhiC"), centrality, std::cos(psiA) * std::sin(psiC)); registry.fill(HIST("QA/hFullEvPlaneRes"), centrality, -1 * std::cos(psiA - psiC)); - registry.fill(HIST("QA/qAqCXY"), centrality, qxA * qxC + qyA * qyC); - registry.fill(HIST("QA/qAXqCY"), centrality, qxA * qyC); - registry.fill(HIST("QA/qAYqCX"), centrality, qyA * qxC); - registry.fill(HIST("QA/qAXYqCXY"), centrality, qyA * qxC + qxA * qyC); - registry.fill(HIST("QA/qAqCX"), centrality, qxA * qxC); - registry.fill(HIST("QA/qAqCY"), centrality, qyA * qyC); } if (centrality > cfgCentMax || centrality < cfgCentMin) @@ -1083,14 +1254,10 @@ struct FlowSP { registry.fill(HIST("hEventCount"), evSel_CentCuts); - if (cfgFillQAHistos) - fillEventQA(collision, tracks); - - double corrQQ = 1., corrQQx = 1., corrQQy = 1.; - // Load correlations and SP resolution needed for Scalar Product and event plane methods. // Only load once! // If not loaded set to 1 + double corrQQ = 1., corrQQx = 1., corrQQy = 1.; if (cfgCCDBdir_QQ.value.empty() == false) { if (!cfg.clQQ) { TList* hcorrList = ccdb->getForTimeStamp(cfgCCDBdir_QQ.value, bc.timestamp()); @@ -1116,11 +1283,25 @@ struct FlowSP { evPlaneRes = std::sqrt(evPlaneRes); } + double centWeight = 1.0; + if (cfgCCDBdir_centrality.value.empty() == false) { + if (!cfg.clCentrality) { + cfg.hCentrality = ccdb->getForTimeStamp(cfgCCDBdir_centrality.value, bc.timestamp()); + cfg.clCentrality = true; + } + centWeight = cfg.hCentrality->GetBinContent(cfg.hCentrality->FindBin(centrality)); + if (centWeight < 0) + LOGF(fatal, "Centrality weight cannot be negative.. abort for (%.2f)", centrality); + } + + fillEventQA(collision, tracks, centWeight); + for (const auto& track : tracks) { - if (cfgFillQAHistos) - registry.fill(HIST("QA/before/hPt_inclusive"), track.pt()); - // registry.fill(HIST("hTrackCount"), trackSel_FilteredTracks); + int trackPID = (cfgFillPID || cfgFillPIDQA) ? getTrackPID(track) : kUnidentified; + + if (cfgFillPIDQA) + registry.fill(HIST("hPIDcounts"), trackPID, track.pt()); float weff = 1., wacc = 1.; float weffP = 1., waccP = 1.; @@ -1132,18 +1313,41 @@ struct FlowSP { registry.fill(HIST("hTrackCount"), trackSel_ZeroCharge); bool pos = (track.sign() > 0) ? true : false; - // Fill QA histograms before track selection - if (cfgFillQAHistos) { - fillTrackQA(track, vtxz); - if (pos) - fillTrackQA(track, vtxz); - else - fillTrackQA(track, vtxz); + if (cfgFillQABefore) { + switch (trackPID) { + case kUnidentified: + fillAllQA(track, vtxz, pos); + break; + case kPion: + fillAllQA(track, vtxz, pos); + break; + case kKaon: + fillAllQA(track, vtxz, pos); + break; + case kProton: + fillAllQA(track, vtxz, pos); + break; + } } if (!trackSelected(track, field)) continue; + switch (trackPID) { + case kUnidentified: + fillAllQA(track, vtxz, pos); + break; + case kPion: + fillAllQA(track, vtxz, pos); + break; + case kKaon: + fillAllQA(track, vtxz, pos); + break; + case kProton: + fillAllQA(track, vtxz, pos); + break; + } + // Fill NUA weights if (cfgFillWeights) { fWeights->fill(track.phi(), track.eta(), vtxz, track.pt(), centrality, 0); @@ -1167,10 +1371,7 @@ struct FlowSP { registry.fill(HIST("hTrackCount"), trackSel_ParticleWeights); - if (cfgFillQAHistos) - registry.fill(HIST("QA/after/hPt_inclusive"), track.pt(), wacc * weff); - - // // constrain angle to 0 -> [0,0+2pi] + // constrain angle to 0 -> [0,0+2pi] auto phi = RecoDecay::constrainAngle(track.phi(), 0); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1188,20 +1389,16 @@ struct FlowSP { double vnC = std::cos(cfgHarm * (phi - psiC)) / evPlaneRes; double vnFull = std::cos(cfgHarm * (phi - psiFull)) / evPlaneRes; - fillHistograms(track, wacc, weff, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); - - if (cfgFillQAHistos) - fillTrackQA(track, vtxz, wacc, weff); + fillHistograms(track, wacc, weff, centWeight, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); + fillTrackQA(track, vtxz, wacc, weff); if (cfgFillChargeDependence) { if (pos) { - fillHistograms(track, wacc, weff, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); - if (cfgFillQAHistos) - fillTrackQA(track, vtxz, waccP, weffP); + fillHistograms(track, waccP, weffP, centWeight, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); + fillTrackQA(track, vtxz, waccP, weffP); } else { - fillHistograms(track, wacc, weff, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); - if (cfgFillQAHistos) - fillTrackQA(track, vtxz, waccN, weffN); + fillHistograms(track, waccN, weffN, centWeight, ux, uy, uxMH, uyMH, uxMH2, uyMH2, qxA, qyA, qxC, qyC, corrQQx, corrQQy, corrQQ, vnA, vnC, vnFull, centrality); + fillTrackQA(track, vtxz, waccN, weffN); } } } // end of track loop @@ -1227,7 +1424,7 @@ struct FlowSP { if (cfgCentNGlobal) centrality = collision.centNGlobal(); - if (cfgFillQAHistos) + if (cfgFillQABefore) fillEventQA(collision, tracks); if (!eventSelected(collision, filteredTracks.size())) @@ -1243,8 +1440,7 @@ struct FlowSP { return; } - if (cfgFillQAHistos) - fillEventQA(collision, tracks); + fillEventQA(collision, tracks); // LOGF(info, "Size of tracks: %i", tracks.size()); registry.fill(HIST("trackMCReco/hTrackSize_unFiltered"), tracks.size()); @@ -1258,16 +1454,14 @@ struct FlowSP { fillMCPtHistos(track, mcParticle.pdgCode()); - if (cfgFillQAHistos) - fillTrackQA(track, vtxz); + fillTrackQA(track, vtxz); if (!trackSelected(track, field)) continue; fillMCPtHistos(track, mcParticle.pdgCode()); - if (cfgFillQAHistos) - fillTrackQA(track, vtxz); + fillTrackQA(track, vtxz); } // end of track loop } @@ -1308,8 +1502,7 @@ struct FlowSP { if (cfgCentNGlobal) centrality = col.centNGlobal(); - if (cfgFillQAHistos) - fillEventQA(col, trackSlice); + fillEventQA(col, trackSlice); if (trackSlice.size() < 1) { colSelected = false; @@ -1326,56 +1519,55 @@ struct FlowSP { } registry.fill(HIST("hEventCount"), evSel_CentCuts); - if (cfgFillQAHistos) - fillEventQA(col, trackSlice); + fillEventQA(col, trackSlice); } // leave reconstructed collision loop - if (!colSelected) - continue; + if (!colSelected) + continue; - float vtxz = mcCollision.posZ(); + float vtxz = mcCollision.posZ(); - for (const auto& particle : partSlice) { - if (!particle.isPhysicalPrimary()) - continue; + for (const auto& particle : partSlice) { + if (!particle.isPhysicalPrimary()) + continue; - int charge = 0; + int charge = 0; - auto pdgCode = particle.pdgCode(); - auto pdgInfo = pdg->GetParticle(pdgCode); - if (pdgInfo != nullptr) { - charge = pdgInfo->Charge(); - } + auto pdgCode = particle.pdgCode(); + auto pdgInfo = pdg->GetParticle(pdgCode); + if (pdgInfo != nullptr) { + charge = pdgInfo->Charge(); + } - if (std::fabs(charge) < 1) - continue; + if (std::fabs(charge) < 1) + continue; - bool pos = (charge > 0) ? true : false; + bool pos = (charge > 0) ? true : false; - fillMCPtHistos(particle, pdgCode); + fillMCPtHistos(particle, pdgCode); - registry.fill(HIST("trackMCGen/before/incl/phi_eta_vtxZ_gen"), particle.phi(), particle.eta(), vtxz); + registry.fill(HIST("trackMCGen/before/incl/phi_eta_vtxZ_gen"), particle.phi(), particle.eta(), vtxz); - if (pos) { - registry.fill(HIST("trackMCGen/before/pos/phi_eta_vtxZ_gen"), particle.phi(), particle.eta(), vtxz); - } else { - registry.fill(HIST("trackMCGen/before/neg/phi_eta_vtxZ_gen"), particle.phi(), particle.eta(), vtxz); - } + if (pos) { + registry.fill(HIST("trackMCGen/before/pos/phi_eta_vtxZ_gen"), particle.phi(), particle.eta(), vtxz); + } else { + registry.fill(HIST("trackMCGen/before/neg/phi_eta_vtxZ_gen"), particle.phi(), particle.eta(), vtxz); + } - if (particle.eta() < -cfgTrackSelsEta || particle.eta() > cfgTrackSelsEta || particle.pt() < cfgTrackSelsPtmin || particle.pt() > cfgTrackSelsPtmax) - continue; + if (particle.eta() < -cfgTrackSelsEta || particle.eta() > cfgTrackSelsEta || particle.pt() < cfgTrackSelsPtmin || particle.pt() > cfgTrackSelsPtmax) + continue; - fillMCPtHistos(particle, pdgCode); + fillMCPtHistos(particle, pdgCode); - registry.fill(HIST("trackMCGen/after/incl/phi_eta_vtxZ_gen"), particle.phi(), particle.eta(), vtxz); + registry.fill(HIST("trackMCGen/after/incl/phi_eta_vtxZ_gen"), particle.phi(), particle.eta(), vtxz); - if (pos) { - registry.fill(HIST("trackMCGen/after/pos/phi_eta_vtxZ_gen"), particle.phi(), particle.eta(), vtxz); - } else { - registry.fill(HIST("trackMCGen/after/neg/phi_eta_vtxZ_gen"), particle.phi(), particle.eta(), vtxz); - } + if (pos) { + registry.fill(HIST("trackMCGen/after/pos/phi_eta_vtxZ_gen"), particle.phi(), particle.eta(), vtxz); + } else { + registry.fill(HIST("trackMCGen/after/neg/phi_eta_vtxZ_gen"), particle.phi(), particle.eta(), vtxz); } + } } } PROCESS_SWITCH(FlowSP, processMCGen, "Process analysis for MC generated events", false); 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..3bad6691449 100644 --- a/PWGCF/Flow/Tasks/flowZdcTask.cxx +++ b/PWGCF/Flow/Tasks/flowZdcTask.cxx @@ -322,6 +322,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}}}); @@ -501,28 +502,28 @@ 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++; } 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); 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 d5522e7e27a..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 @@ -126,9 +126,9 @@ struct ThreeParticleCorrelations { Configurable confRDSwitch{"confRDSwitch", true, "Switch for the radialDistanceFilter function"}; // Efficiency histograms - TH2D** hEffPions = new TH2D*[2]; - TH2D** hEffKaons = new TH2D*[2]; - TH2D** hEffProtons = new TH2D*[2]; + TH3D** hEffPions = new TH3D*[2]; + TH3D** hEffKaons = new TH3D*[2]; + TH3D** hEffProtons = new TH3D*[2]; // Correlation variables int triggSign, assocSign; @@ -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}}}); @@ -290,17 +307,17 @@ struct ThreeParticleCorrelations { ccdb->setURL("http://alice-ccdb.cern.ch"); ccdb->setCaching(true); TList* efficiencyList = ccdb->getForTimeStamp("Users/j/jstaa/Efficiency/ChargedParticles", 1); - hEffPions[0] = static_cast(efficiencyList->FindObject("hEfficiencyPionP")); - hEffPions[1] = static_cast(efficiencyList->FindObject("hEfficiencyPionN")); - hEffKaons[0] = static_cast(efficiencyList->FindObject("hEfficiencyKaonP")); - hEffKaons[1] = static_cast(efficiencyList->FindObject("hEfficiencyKaonN")); - hEffProtons[0] = static_cast(efficiencyList->FindObject("hEfficiencyProtonP")); - hEffProtons[1] = static_cast(efficiencyList->FindObject("hEfficiencyProtonN")); + hEffPions[0] = static_cast(efficiencyList->FindObject("hEfficiencyPionP")); + hEffPions[1] = static_cast(efficiencyList->FindObject("hEfficiencyPionN")); + hEffKaons[0] = static_cast(efficiencyList->FindObject("hEfficiencyKaonP")); + hEffKaons[1] = static_cast(efficiencyList->FindObject("hEfficiencyKaonN")); + hEffProtons[0] = static_cast(efficiencyList->FindObject("hEfficiencyProtonP")); + hEffProtons[1] = static_cast(efficiencyList->FindObject("hEfficiencyProtonN")); } //========================================================================================================================================================================================================================================================================== - 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)) { @@ -331,15 +348,15 @@ struct ThreeParticleCorrelations { rQARegistry.fill(HIST("hdEdx"), track.pt(), track.tpcSignal()); rQARegistry.fill(HIST("hBeta"), track.pt(), track.beta()); if (assocPID[0] == pionID) { // Pions - rQARegistry.fill(HIST("hPtPion"), track.pt(), collision.centFT0C(), 1. / trackEff(hEffPions, track)); + rQARegistry.fill(HIST("hPtPion"), track.pt(), collision.centFT0C(), 1. / trackEff(hEffPions, track, collision.centFT0C())); rQARegistry.fill(HIST("hdEdxPion"), track.pt(), track.tpcSignal()); rQARegistry.fill(HIST("hBetaPion"), track.pt(), track.beta()); } else if (assocPID[0] == kaonID) { // Kaons - rQARegistry.fill(HIST("hPtKaon"), track.pt(), collision.centFT0C(), 1. / trackEff(hEffKaons, track)); + rQARegistry.fill(HIST("hPtKaon"), track.pt(), collision.centFT0C(), 1. / trackEff(hEffKaons, track, collision.centFT0C())); rQARegistry.fill(HIST("hdEdxKaon"), track.pt(), track.tpcSignal()); rQARegistry.fill(HIST("hBetaKaon"), track.pt(), track.beta()); } else if (assocPID[0] == protonID) { // Protons - rQARegistry.fill(HIST("hPtProton"), track.pt(), collision.centFT0C(), 1. / trackEff(hEffProtons, track)); + rQARegistry.fill(HIST("hPtProton"), track.pt(), collision.centFT0C(), 1. / trackEff(hEffProtons, track, collision.centFT0C())); rQARegistry.fill(HIST("hdEdxProton"), track.pt(), track.tpcSignal()); rQARegistry.fill(HIST("hBetaProton"), track.pt(), track.beta()); } @@ -371,36 +388,36 @@ struct ThreeParticleCorrelations { if (candMass >= MassLambda0 - 4 * dGaussSigma && candMass <= MassLambda0 + 4 * dGaussSigma) { if (assocPID[0] == pionID) { // Pions - rSECorrRegistry.fill(HIST("hSameLambdaPion_SGNL"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffPions, associate)); + rSECorrRegistry.fill(HIST("hSameLambdaPion_SGNL"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffPions, associate, collision.centFT0C())); } else if (assocPID[0] == kaonID) { // Kaons - rSECorrRegistry.fill(HIST("hSameLambdaKaon_SGNL"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffKaons, associate)); + rSECorrRegistry.fill(HIST("hSameLambdaKaon_SGNL"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffKaons, associate, collision.centFT0C())); } else if (assocPID[0] == protonID) { // Protons - rSECorrRegistry.fill(HIST("hSameLambdaProton_SGNL"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffProtons, associate)); + rSECorrRegistry.fill(HIST("hSameLambdaProton_SGNL"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffProtons, associate, collision.centFT0C())); } } else if (candMass >= MassLambda0 - 8 * dGaussSigma && candMass <= MassLambda0 + 8 * dGaussSigma) { if (assocPID[0] == pionID) { // Pions - rSECorrRegistry.fill(HIST("hSameLambdaPion_SB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffPions, associate)); + rSECorrRegistry.fill(HIST("hSameLambdaPion_SB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffPions, associate, collision.centFT0C())); if (candMass >= MassLambda0 - 8 * dGaussSigma && candMass < MassLambda0 - 4 * dGaussSigma) { - rSECorrRegistry.fill(HIST("hSameLambdaPion_leftSB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffPions, associate)); + rSECorrRegistry.fill(HIST("hSameLambdaPion_leftSB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffPions, associate, collision.centFT0C())); } else if (candMass > MassLambda0 + 4 * dGaussSigma && candMass <= MassLambda0 + 8 * dGaussSigma) { - rSECorrRegistry.fill(HIST("hSameLambdaPion_rightSB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffPions, associate)); + rSECorrRegistry.fill(HIST("hSameLambdaPion_rightSB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffPions, associate, collision.centFT0C())); } } else if (assocPID[0] == kaonID) { // Kaons - rSECorrRegistry.fill(HIST("hSameLambdaKaon_SB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffKaons, associate)); + rSECorrRegistry.fill(HIST("hSameLambdaKaon_SB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffKaons, associate, collision.centFT0C())); if (candMass >= MassLambda0 - 8 * dGaussSigma && candMass < MassLambda0 - 4 * dGaussSigma) { - rSECorrRegistry.fill(HIST("hSameLambdaKaon_leftSB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffKaons, associate)); + rSECorrRegistry.fill(HIST("hSameLambdaKaon_leftSB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffKaons, associate, collision.centFT0C())); } else if (candMass > MassLambda0 + 4 * dGaussSigma && candMass <= MassLambda0 + 8 * dGaussSigma) { - rSECorrRegistry.fill(HIST("hSameLambdaKaon_rightSB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffKaons, associate)); + rSECorrRegistry.fill(HIST("hSameLambdaKaon_rightSB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffKaons, associate, collision.centFT0C())); } } else if (assocPID[0] == protonID) { // Protons - rSECorrRegistry.fill(HIST("hSameLambdaProton_SB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffProtons, associate)); + rSECorrRegistry.fill(HIST("hSameLambdaProton_SB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffProtons, associate, collision.centFT0C())); if (candMass >= MassLambda0 - 8 * dGaussSigma && candMass < MassLambda0 - 4 * dGaussSigma) { - rSECorrRegistry.fill(HIST("hSameLambdaProton_leftSB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffProtons, associate)); + rSECorrRegistry.fill(HIST("hSameLambdaProton_leftSB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffProtons, associate, collision.centFT0C())); } else if (candMass > MassLambda0 + 4 * dGaussSigma && candMass <= MassLambda0 + 8 * dGaussSigma) { - rSECorrRegistry.fill(HIST("hSameLambdaProton_rightSB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffProtons, associate)); + rSECorrRegistry.fill(HIST("hSameLambdaProton_rightSB"), deltaPhi, deltaEta, collision.centFT0C(), collision.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffProtons, associate, collision.centFT0C())); } } } @@ -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; } @@ -441,36 +457,36 @@ struct ThreeParticleCorrelations { if (candMass >= MassLambda0 - 4 * dGaussSigma && candMass <= MassLambda0 + 4 * dGaussSigma) { if (assocPID[0] == pionID) { // Pions - rMECorrRegistry.fill(HIST("hMixLambdaPion_SGNL"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffPions, associate)); + rMECorrRegistry.fill(HIST("hMixLambdaPion_SGNL"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffPions, associate, coll_1.centFT0C())); } else if (assocPID[0] == kaonID) { // Kaons - rMECorrRegistry.fill(HIST("hMixLambdaKaon_SGNL"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffKaons, associate)); + rMECorrRegistry.fill(HIST("hMixLambdaKaon_SGNL"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffKaons, associate, coll_1.centFT0C())); } else if (assocPID[0] == protonID) { // Protons - rMECorrRegistry.fill(HIST("hMixLambdaProton_SGNL"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffProtons, associate)); + rMECorrRegistry.fill(HIST("hMixLambdaProton_SGNL"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffProtons, associate, coll_1.centFT0C())); } } else if (candMass >= MassLambda0 - 8 * dGaussSigma && candMass <= MassLambda0 + 8 * dGaussSigma) { if (assocPID[0] == pionID) { // Pions - rMECorrRegistry.fill(HIST("hMixLambdaPion_SB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffPions, associate)); + rMECorrRegistry.fill(HIST("hMixLambdaPion_SB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffPions, associate, coll_1.centFT0C())); if (candMass >= MassLambda0 - 8 * dGaussSigma && candMass < MassLambda0 - 4 * dGaussSigma) { - rMECorrRegistry.fill(HIST("hMixLambdaPion_leftSB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffPions, associate)); + rMECorrRegistry.fill(HIST("hMixLambdaPion_leftSB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffPions, associate, coll_1.centFT0C())); } else if (candMass > MassLambda0 + 4 * dGaussSigma && candMass <= MassLambda0 + 8 * dGaussSigma) { - rMECorrRegistry.fill(HIST("hMixLambdaPion_rightSB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffPions, associate)); + rMECorrRegistry.fill(HIST("hMixLambdaPion_rightSB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffPions, associate, coll_1.centFT0C())); } } else if (assocPID[0] == kaonID) { // Kaons - rMECorrRegistry.fill(HIST("hMixLambdaKaon_SB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffKaons, associate)); + rMECorrRegistry.fill(HIST("hMixLambdaKaon_SB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffKaons, associate, coll_1.centFT0C())); if (candMass >= MassLambda0 - 8 * dGaussSigma && candMass < MassLambda0 - 4 * dGaussSigma) { - rMECorrRegistry.fill(HIST("hMixLambdaKaon_leftSB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffKaons, associate)); + rMECorrRegistry.fill(HIST("hMixLambdaKaon_leftSB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffKaons, associate, coll_1.centFT0C())); } else if (candMass > MassLambda0 + 4 * dGaussSigma && candMass <= MassLambda0 + 8 * dGaussSigma) { - rMECorrRegistry.fill(HIST("hMixLambdaKaon_rightSB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffKaons, associate)); + rMECorrRegistry.fill(HIST("hMixLambdaKaon_rightSB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffKaons, associate, coll_1.centFT0C())); } } else if (assocPID[0] == protonID) { // Protons - rMECorrRegistry.fill(HIST("hMixLambdaProton_SB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffProtons, associate)); + rMECorrRegistry.fill(HIST("hMixLambdaProton_SB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffProtons, associate, coll_1.centFT0C())); if (candMass >= MassLambda0 - 8 * dGaussSigma && candMass < MassLambda0 - 4 * dGaussSigma) { - rMECorrRegistry.fill(HIST("hMixLambdaProton_leftSB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffProtons, associate)); + rMECorrRegistry.fill(HIST("hMixLambdaProton_leftSB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffProtons, associate, coll_1.centFT0C())); } else if (candMass > MassLambda0 + 4 * dGaussSigma && candMass <= MassLambda0 + 8 * dGaussSigma) { - rMECorrRegistry.fill(HIST("hMixLambdaProton_rightSB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffProtons, associate)); + rMECorrRegistry.fill(HIST("hMixLambdaProton_rightSB"), deltaPhi, deltaEta, coll_1.centFT0C(), coll_1.posZ(), triggSign, associate.sign(), 1. / trackEff(hEffProtons, associate, coll_1.centFT0C())); } } } @@ -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(); @@ -778,7 +824,7 @@ struct ThreeParticleCorrelations { } template - double trackEff(TH2D** efficiencies, const TrackCand& track) + double trackEff(TH3D** efficiencies, const TrackCand& track, double centrality) { int index = -999; @@ -788,7 +834,7 @@ struct ThreeParticleCorrelations { index = 1; } - double efficiency = efficiencies[index]->GetBinContent(efficiencies[index]->FindBin(track.pt(), track.eta())); + double efficiency = efficiencies[index]->GetBinContent(efficiencies[index]->FindBin(track.pt(), track.eta(), centrality)); if (efficiency > 0) { return efficiency; } else { @@ -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/CMakeLists.txt b/PWGCF/TwoParticleCorrelations/Tasks/CMakeLists.txt index d150b6954db..83526365550 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/CMakeLists.txt +++ b/PWGCF/TwoParticleCorrelations/Tasks/CMakeLists.txt @@ -60,14 +60,10 @@ o2physics_add_dpl_workflow(neutron-proton-corr-zdc o2physics_add_dpl_workflow(di-hadron-cor SOURCES diHadronCor.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore O2Physics::AnalysisCCDB O2Physics::GFWCore COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(longrange-correlation SOURCES longrangeCorrelation.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore COMPONENT_NAME Analysis) - - - - 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 186ae77640a..063cc32378a 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx @@ -16,6 +16,7 @@ #include #include "TRandom3.h" +#include "TF1.h" #include #include @@ -35,24 +36,20 @@ #include "Common/DataModel/Centrality.h" #include "PWGCF/DataModel/CorrelationsDerived.h" #include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/PIDResponse.h" #include "PWGCF/Core/CorrelationContainer.h" #include "PWGCF/Core/PairCuts.h" +#include "PWGCF/GenericFramework/Core/GFWPowerArray.h" +#include "PWGCF/GenericFramework/Core/GFW.h" +#include "PWGCF/GenericFramework/Core/GFWCumulant.h" +#include "PWGCF/GenericFramework/Core/GFWWeights.h" #include "DataFormatsParameters/GRPObject.h" #include "DataFormatsParameters/GRPMagField.h" +#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}; @@ -64,6 +61,10 @@ struct DiHadronCor { O2_DEFINE_CONFIGURABLE(cfgCutPtMin, float, 0.2f, "minimum accepted track pT") O2_DEFINE_CONFIGURABLE(cfgCutPtMax, float, 10.0f, "maximum accepted track pT") O2_DEFINE_CONFIGURABLE(cfgCutEta, float, 0.8f, "Eta cut") + O2_DEFINE_CONFIGURABLE(cfgCutChi2prTPCcls, float, 2.5f, "max chi2 per TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgCutTPCclu, float, 70.0f, "minimum TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgCutITSclu, float, 5.0f, "minimum ITS clusters") + O2_DEFINE_CONFIGURABLE(cfgCutDCAz, float, 2.0f, "max DCA to vertex z") O2_DEFINE_CONFIGURABLE(cfgCutMerging, float, 0.0, "Merging cut on track merge") O2_DEFINE_CONFIGURABLE(cfgSelCollByNch, bool, true, "Select collisions by Nch or centrality") O2_DEFINE_CONFIGURABLE(cfgCutMultMin, int, 0, "Minimum multiplicity for collision") @@ -77,29 +78,64 @@ struct DiHadronCor { 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(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") + O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodZvtxFT0vsPV, bool, false, "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") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoCollInTimeRangeStandard, bool, false, "no collisions in specified time range") + O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodITSLayersAll, bool, true, "cut time intervals with dead ITS staves") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoCollInRofStandard, bool, false, "no other collisions in this Readout Frame with per-collision multiplicity above threshold") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoHighMultCollInPrevRof, bool, false, "veto an event if FT0C amplitude in previous ITS ROF is above threshold") + O2_DEFINE_CONFIGURABLE(cfgEvSelMultCorrelation, bool, true, "Multiplicity correlation cut") + O2_DEFINE_CONFIGURABLE(cfgEvSelV0AT0ACut, bool, true, "V0A T0A 5 sigma cut") + O2_DEFINE_CONFIGURABLE(cfgEvSelOccupancy, bool, true, "Occupancy cut") + 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, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260, 280, 300}, "multiplicity axis for histograms"}; + ConfigurableAxis axisCentrality{"axisCentrality", {VARIABLE_WIDTH, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, "centrality axis for histograms"}; + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.2, 1.4, 1.6, 1.8, 2, 2.5, 3, 4, 5, 6, 8, 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.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.2, 1.4, 1.6, 1.8, 2, 2.5, 3, 4, 5, 6, 8, 10}, "pt trigger axis for histograms"}; + ConfigurableAxis axisPtAssoc{"axisPtAssoc", {VARIABLE_WIDTH, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.2, 1.4, 1.6, 1.8, 2, 2.5, 3, 4, 5, 6, 8, 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, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260, 280, 300}, "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.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.2, 1.4, 1.6, 1.8, 2, 2.5, 3, 4, 5, 6, 8, 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 trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)); + 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 FilteredSmallGroupMcCollisions = soa::SmallGroups>; + + Preslice perCollision = aod::track::collisionId; + PresliceUnsorted collisionPerMCCollision = aod::mccollisionlabel::mcCollisionId; + + // Corrections + TH3D* mEfficiency = nullptr; + bool correctionsLoaded = false; // Define the outputs OutputObj same{"sameEvent"}; @@ -121,8 +157,17 @@ struct DiHadronCor { MixedEvent = 3 }; - using AodCollisions = soa::Filtered>; // aod::CentFT0Cs - using AodTracks = soa::Filtered>; + // persistent caches + std::vector efficiencyAssociatedCache; + + // Additional Event selection cuts - Copy from flowGenericFramework.cxx + TF1* fMultPVCutLow = nullptr; + TF1* fMultPVCutHigh = nullptr; + TF1* fMultCutLow = nullptr; + TF1* fMultCutHigh = nullptr; + TF1* fMultMultPVCut = nullptr; + TF1* fT0AV0AMean = nullptr; + TF1* fT0AV0ASigma = nullptr; void init(InitContext&) { @@ -138,22 +183,86 @@ struct DiHadronCor { LOGF(info, "Starting init"); + // Event Counter + registry.add("hEventCountSpecific", "Number of Event;; Count", {HistType::kTH1D, {{10, 0, 10}}}); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(1, "after sel8"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(2, "kNoSameBunchPileup"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(3, "kIsGoodZvtxFT0vsPV"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(4, "kNoCollInTimeRangeStandard"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(5, "kIsGoodITSLayersAll"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(6, "kNoCollInRofStandard"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(7, "kNoHighMultCollInPrevRof"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(8, "occupancy"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(9, "MultCorrelation"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(10, "cfgEvSelV0AT0ACut"); + if (cfgUseTentativeEventCounter) { + registry.add("hEventCountTentative", "Number of Event;; Count", {HistType::kTH1D, {{10, 0, 10}}}); + registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(1, "after sel8"); + registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(2, "kNoSameBunchPileup"); + registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(3, "kIsGoodZvtxFT0vsPV"); + registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(4, "kNoCollInTimeRangeStandard"); + registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(5, "kIsGoodITSLayersAll"); + registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(6, "kNoCollInRofStandard"); + registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(7, "kNoHighMultCollInPrevRof"); + registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(8, "occupancy"); + registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(9, "MultCorrelation"); + registry.get(HIST("hEventCountTentative"))->GetXaxis()->SetBinLabel(10, "cfgEvSelV0AT0ACut"); + } + + 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); + + 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); + } + // Make histograms to check the distributions after cuts registry.add("deltaEta_deltaPhi_same", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); // check to see the delta eta and delta phi distribution 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}}); registry.add("Nch_used", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); // histogram to see how many events are in the same and mixed event std::string hCentTitle = "Centrality distribution, Estimator " + std::to_string(cfgCentEstimator); 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)"}, @@ -162,9 +271,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; @@ -210,20 +319,65 @@ struct DiHadronCor { return cent; } + template + bool trackSelected(TTrack track) + { + return ((track.tpcNClsFound() >= cfgCutTPCclu) && (track.itsNCls() >= cfgCutITSclu)); + } + + void loadEfficiency(uint64_t timestamp) + { + if (correctionsLoaded) { + return; + } + if (cfgEfficiency.value.empty() == false) { + 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()); + } + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgEfficiency.value.c_str(), (void*)mEfficiency); + } + correctionsLoaded = true; + } + + bool getEfficiencyCorrection(float& weight_nue, float eta, float pt, float posZ) + { + float eff = 1.; + 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; + return true; + } + // fill multiple histograms 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 (!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); } } @@ -251,10 +405,19 @@ 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); @@ -263,15 +426,27 @@ struct DiHadronCor { int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + float triggerWeight = 1.0f; + float associatedWeight = 1.0f; // loop over all tracks for (auto const& track1 : tracks1) { + if (!trackSelected(track1)) + continue; + 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 (mEfficiency) { + associatedWeight = efficiencyAssociatedCache[track2.filteredIndex()]; + } + if (track1.pt() <= track2.pt()) continue; // skip if the trigger pt is less than the associate pt @@ -303,26 +478,140 @@ 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); - void processSame(AodCollisions::iterator const& collision, AodTracks const& tracks, aod::BCsWithTimestamps const&) + 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 (system == SameEvent && doprocessMCSame) + registry.fill(HIST("MCTrue/MCTrig_hist"), fSampleIndex, posZ, track1.pt(), triggerWeight); + + for (auto const& track2 : tracks2) { + + if (step >= CorrelationContainer::kCFStepTrackedOnlyPrim && !track2.isPhysicalPrimary()) + 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) + 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) + registry.fill(HIST("MCTrue/MCdeltaEta_deltaPhi_mixed"), deltaPhi, deltaEta, triggerWeight * associatedWeight); + } + } + } + } + + template + bool eventSelected(TCollision collision, const int multTrk, const float centrality, const bool fillCounter) { + registry.fill(HIST("hEventCountSpecific"), 0.5); + if (cfgEvSelkNoSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + // rejects collisions which are associated with the same "found-by-T0" bunch crossing + // https://indico.cern.ch/event/1396220/#1-event-selection-with-its-rof + return 0; + } + if (fillCounter && cfgEvSelkNoSameBunchPileup) + registry.fill(HIST("hEventCountSpecific"), 1.5); + if (cfgEvSelkIsGoodZvtxFT0vsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + // 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 + return 0; + } + if (fillCounter && cfgEvSelkIsGoodZvtxFT0vsPV) + registry.fill(HIST("hEventCountSpecific"), 2.5); + if (cfgEvSelkNoCollInTimeRangeStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + // no collisions in specified time range + return 0; + } + if (fillCounter && cfgEvSelkNoCollInTimeRangeStandard) + registry.fill(HIST("hEventCountSpecific"), 3.5); + if (cfgEvSelkIsGoodITSLayersAll && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + // from Jan 9 2025 AOT meeting + // cut time intervals with dead ITS staves + return 0; + } + if (fillCounter && cfgEvSelkIsGoodITSLayersAll) + registry.fill(HIST("hEventCountSpecific"), 4.5); + if (cfgEvSelkNoCollInRofStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + // no other collisions in this Readout Frame with per-collision multiplicity above threshold + return 0; + } + if (fillCounter && cfgEvSelkNoCollInRofStandard) + registry.fill(HIST("hEventCountSpecific"), 5.5); + if (cfgEvSelkNoHighMultCollInPrevRof && !collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { + // veto an event if FT0C amplitude in previous ITS ROF is above threshold + return 0; + } + if (fillCounter && cfgEvSelkNoHighMultCollInPrevRof) + registry.fill(HIST("hEventCountSpecific"), 6.5); + auto occupancy = collision.trackOccupancyInTimeRange(); + if (cfgEvSelOccupancy && (occupancy < cfgCutOccupancyLow || occupancy > cfgCutOccupancyHigh)) + return 0; + if (fillCounter && cfgEvSelOccupancy) + registry.fill(HIST("hEventCountSpecific"), 7.5); + + auto multNTracksPV = collision.multNTracksPV(); + if (cfgEvSelMultCorrelation) { + if (multNTracksPV < fMultPVCutLow->Eval(centrality)) + return 0; + if (multNTracksPV > fMultPVCutHigh->Eval(centrality)) + return 0; + if (multTrk < fMultCutLow->Eval(centrality)) + return 0; + if (multTrk > fMultCutHigh->Eval(centrality)) + return 0; + } + if (fillCounter && cfgEvSelMultCorrelation) + registry.fill(HIST("hEventCountSpecific"), 8.5); - auto bc = collision.bc_as(); + // V0A T0A 5 sigma cut + 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); - registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin + return 1; + } - fillYield(collision, tracks); + void processSame(FilteredCollisions::iterator const& collision, FilteredTracks const& tracks, aod::BCsWithTimestamps const&) + { + + auto bc = collision.bc_as(); float cent = getCentrality(collision); + if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), cent, true)) + return; + + 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; @@ -331,15 +620,20 @@ struct DiHadronCor { 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; @@ -350,10 +644,8 @@ 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(); if (cfgSelCollByNch && (tracks1.size() < cfgCutMultMin || tracks1.size() >= cfgCutMultMax)) continue; @@ -363,6 +655,10 @@ struct DiHadronCor { float cent1 = getCentrality(collision1); float 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)) continue; @@ -370,11 +666,212 @@ struct DiHadronCor { if (!cfgSelCollByNch && (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, FilteredSmallGroupMcCollisions const& collisions) + { + if (cfgVerbosity) { + LOGF(info, "processMCSame. MC collision: %d, particles: %d, collisions: %d", mcCollision.globalIndex(), mcParticles.size(), collisions.size()); + } + + float cent = -1; + for (const auto& collision : collisions) { + cent = getCentrality(collision); + } + + if (cfgSelCollByNch && (mcParticles.size() < cfgCutMultMin || mcParticles.size() >= cfgCutMultMax)) { + return; + } + if (!cfgSelCollByNch && (cent < cfgCutCentMin || cent >= cfgCutCentMax)) { + return; + } + + registry.fill(HIST("MCTrue/MCeventcount"), SameEvent); // because its same event i put it in the 1 bin + 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, FilteredSmallGroupMcCollisions 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; + for (const auto& collision : groupedCollisions) { + cent = getCentrality(collision); + } + + if (!cfgSelCollByNch && 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(FilteredMcCollisions::iterator const& mcCollision, FilteredMcParticles 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(FilteredMcCollisions const& mcCollisions, FilteredMcParticles const& mcParticles) + { + 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; + + 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 e2778112fa8..9a299ed8950 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx @@ -71,9 +71,10 @@ 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(V0Type, v0Type, int8_t); +DECLARE_SOA_COLUMN(V0PrmScd, v0PrmScd, int8_t); DECLARE_SOA_COLUMN(CorrFact, corrFact, float); } // namespace lambdatrack DECLARE_SOA_TABLE(LambdaTracks, "AOD", "LAMBDATRACKS", o2::soa::Index<>, @@ -88,9 +89,10 @@ DECLARE_SOA_TABLE(LambdaTracks, "AOD", "LAMBDATRACKS", o2::soa::Index<>, lambdatrack::Mass, lambdatrack::PosTrackId, lambdatrack::NegTrackId, - lambdatrack::V0Type, lambdatrack::CosPA, lambdatrack::DcaDau, + lambdatrack::V0Type, + lambdatrack::V0PrmScd, lambdatrack::CorrFact); using LambdaTrack = LambdaTracks::iterator; @@ -126,6 +128,7 @@ DECLARE_SOA_TABLE(LambdaMcGenTracks, "AOD", "LMCGENTRACKS", o2::soa::Index<>, lambdatrack::V0Type, lambdatrack::CosPA, lambdatrack::DcaDau, + lambdatrack::V0PrmScd, lambdatrack::CorrFact); using LambdaMcGenTrack = LambdaMcGenTracks::iterator; @@ -155,13 +158,11 @@ enum TrackLabels { kLambdaNotPrPiMinus, kAntiLambdaNotAntiPrPiPlus, kPassTrueLambdaSel, - kEffCorrPt, - kEffCorrPtRap, - kEffCorrPtRapPhi, + kEffCorrPtCent, + kEffCorrPtRapCent, kNoEffCorr, - kPFCorrPt, - kPFCorrPtRap, - kPFCorrPtRapPhi, + kPFCorrPtCent, + kPFCorrPtRapCent, kNoPFCorr, kGenTotAccLambda, kGenLambdaNoDau, @@ -205,6 +206,18 @@ enum CorrHistDim { ThreeDimCorr }; +enum PrmScdType { + kPrimary = 0, + kSecondary +}; + +enum PrmScdPairType { + kPP = 0, + kPS, + kSP, + kSS +}; + struct LambdaTableProducer { Produces lambdaCollisionTable; @@ -266,18 +279,12 @@ struct LambdaTableProducer { // V0s MC Configurable cHasMcFlag{"cHasMcFlag", true, "Has Mc Tag"}; Configurable cSelectTrueLambda{"cSelectTrueLambda", true, "Select True Lambda"}; - Configurable cSelectPrimaryV0{"cSelectPrimaryV0", true, "Select Primary V0"}; - Configurable cRecPrimaryLambda{"cRecPrimaryLambda", true, "Primary Reconstructed Lambda"}; - Configurable cRecSecondaryLambda{"cRecSecondaryLambda", false, "Secondary Reconstructed Lambda"}; + Configurable cSelMCPSV0{"cSelMCPSV0", true, "Select Primary/Secondary V0"}; Configurable cCheckRecoDauFlag{"cCheckRecoDauFlag", true, "Check for reco daughter PID"}; 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"}; @@ -297,21 +304,19 @@ 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&) { @@ -372,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}); @@ -460,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"); } @@ -739,20 +737,19 @@ struct LambdaTableProducer { } template - bool selPrimaryV0(V const& v0) + PrmScdType isPrimaryV0(V const& v0) { auto mcpart = v0.template mcParticle_as(); - // check for primary/secondary lambda - if (cRecPrimaryLambda && !mcpart.isPhysicalPrimary()) { + // check for secondary lambda + if (!mcpart.isPhysicalPrimary()) { histos.fill(HIST("Tracks/h1f_tracks_info"), kNotPrimaryLambda); - return false; - } else if (cRecSecondaryLambda && mcpart.isPhysicalPrimary()) { - histos.fill(HIST("Tracks/h1f_tracks_info"), kNotSecondaryLambda); - return false; + bSecondaryLambdaFlag = true; + return kSecondary; } - return true; + histos.fill(HIST("Tracks/h1f_tracks_info"), kNotSecondaryLambda); + return kPrimary; } template @@ -793,7 +790,7 @@ struct LambdaTableProducer { } // get information about secondary lambdas - if (cRecSecondaryLambda) { + if (bSecondaryLambdaFlag) { auto lambdaMothers = mcpart.template mothers_as(); if (std::abs(lambdaMothers[0].pdgCode()) == kSigmaMinus || std::abs(lambdaMothers[0].pdgCode()) == kSigma0 || std::abs(lambdaMothers[0].pdgCode()) == kSigmaPlus) { histos.fill(HIST("Tracks/h2f_lambda_from_sigma"), mcpart.pdgCode(), mcpart.pt()); @@ -807,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) { @@ -861,28 +822,24 @@ 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 objEff; delete histEff; } @@ -891,37 +848,21 @@ 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 !!!"); primFrac = 1.; } - delete objPrm; 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 @@ -1008,6 +949,7 @@ struct LambdaTableProducer { // initialize v0track objects ParticleType v0Type = kLambda; + PrmScdType v0PrmScdType = kPrimary; float mass = 0., corr_fact = 1.; for (auto const& v0 : v0tracks) { @@ -1032,36 +974,48 @@ struct LambdaTableProducer { continue; } + // 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()); - if (cSelectPrimaryV0 && !selPrimaryV0(v0)) { // check for Primary V0 - continue; + + if (cSelMCPSV0) { // Get Primary/Secondary Lambda + v0PrmScdType = isPrimaryV0(v0); } 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()); - // get correction factors and mass + // get correction factors corr_fact = (v0Type == kLambda) ? getCorrectionFactors(v0) : getCorrectionFactors(v0); - mass = (v0Type == kLambda) ? v0.mLambda() : v0.mAntiLambda(); // fill lambda qa if (v0Type == kLambda) { @@ -1076,9 +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(), 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); } } @@ -1087,10 +1040,11 @@ 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; + PrmScdType v0PrmScdType = kPrimary; float rap = 0.; for (auto const& mcpart : mcParticles) { @@ -1104,10 +1058,10 @@ struct LambdaTableProducer { } // check for Primary Lambda/AntiLambda - if (cGenPrimaryLambda && !mcpart.isPhysicalPrimary()) { - continue; - } else if (cGenSecondaryLambda && mcpart.isPhysicalPrimary()) { - continue; + if (mcpart.isPhysicalPrimary()) { + v0PrmScdType = kPrimary; + } else { + v0PrmScdType = kSecondary; } // Decide Eta/Rap @@ -1185,7 +1139,7 @@ struct LambdaTableProducer { // Fill Lambda McGen Table lambdaMCGenTrackTable(lambdaMCGenCollisionTable.lastIndex(), mcpart.px(), mcpart.py(), mcpart.pz(), mcpart.pt(), mcpart.eta(), mcpart.phi(), mcpart.y(), RecoDecay::m(mcpart.p(), mcpart.e()), - daughterIDs[0], daughterIDs[1], (int8_t)v0Type, -999., -999., 1.); + daughterIDs[0], daughterIDs[1], (int8_t)v0Type, -999., -999., v0PrmScdType, 1.); } } @@ -1206,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; @@ -1244,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) @@ -1254,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) @@ -1429,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}; @@ -1455,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&) { @@ -1473,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})"); @@ -1483,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}); @@ -1497,57 +1444,63 @@ struct LambdaR2Correlation { // Efficiency Histograms // Single Particle Efficiencies - histos.add("Reco/Efficiency/h1f_n1_pt_LaP", "#rho_{1}^{#Lambda}", kTH1F, {axisEfPt}); - histos.add("Reco/Efficiency/h1f_n1_pt_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH1F, {axisEfPt}); - histos.add("Reco/Efficiency/h3f_n1_ptetaphi_LaP", "#rho_{1}^{#Lambda}", kTH3F, {axisEfPt, axisEfEta, axisEfPhi}); - histos.add("Reco/Efficiency/h3f_n1_ptetaphi_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH3F, {axisEfPt, axisEfEta, axisEfPhi}); - histos.add("Reco/Efficiency/h3f_n1_ptrapphi_LaP", "#rho_{1}^{#Lambda}", kTH3F, {axisEfPt, axisEfRap, axisEfPhi}); - histos.add("Reco/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/h1d_n1_mass_LaP", "#rho_{1}^{#Lambda}", kTH1D, {axisMass}); - histos.add("Reco/h1d_n1_mass_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH1D, {axisMass}); - histos.add("Reco/h1d_n1_pt_LaP", "#rho_{1}^{#Lambda}", kTH1D, {axisPt}); - histos.add("Reco/h1d_n1_pt_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH1D, {axisPt}); - histos.add("Reco/h1d_n1_eta_LaP", "#rho_{1}^{#Lambda}", kTH1D, {axisEta}); - histos.add("Reco/h1d_n1_eta_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH1D, {axisEta}); - histos.add("Reco/h1d_n1_rap_LaP", "#rho_{1}^{#Lambda}", kTH1D, {axisRap}); - histos.add("Reco/h1d_n1_rap_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH1D, {axisRap}); - histos.add("Reco/h1d_n1_phi_LaP", "#rho_{1}^{#Lambda}", kTH1D, {axisPhi}); - histos.add("Reco/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/h2d_n1_rapphi_LaP", "#rho_{1}^{#Lambda}", kTH2D, {axisRap, axisPhi}); - histos.add("Reco/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/h2d_n1_pteta_LaP", "#rho_{1}^{#Lambda}", kTH2D, {axisPt, axisEta}); - histos.add("Reco/h2d_n1_pteta_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH2D, {axisPt, axisEta}); - - // rho2 for numerator of R2 - histos.add("Reco/h2d_n2_ptpt_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH2D, {axisPt, axisPt}); - histos.add("Reco/h2d_n2_ptpt_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH2D, {axisPt, axisPt}); - histos.add("Reco/h2d_n2_ptpt_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH2D, {axisPt, axisPt}); - histos.add("Reco/h2d_n2_etaeta_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH2D, {axisEta, axisEta}); - histos.add("Reco/h2d_n2_etaeta_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH2D, {axisEta, axisEta}); - histos.add("Reco/h2d_n2_etaeta_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH2D, {axisEta, axisEta}); - histos.add("Reco/h2d_n2_raprap_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH2D, {axisRap, axisRap}); - histos.add("Reco/h2d_n2_raprap_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH2D, {axisRap, axisRap}); - histos.add("Reco/h2d_n2_raprap_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH2D, {axisRap, axisRap}); - histos.add("Reco/h2d_n2_phiphi_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH2D, {axisPhi, axisPhi}); - histos.add("Reco/h2d_n2_phiphi_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH2D, {axisPhi, axisPhi}); - histos.add("Reco/h2d_n2_phiphi_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH2D, {axisPhi, axisPhi}); - - // rho2 for R2 Rap1Phi1Rap2Phi2 - histos.add("Reco/h2d_n2_rapphi_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH2D, {axisRapPhi, axisRapPhi}); - histos.add("Reco/h2d_n2_rapphi_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH2D, {axisRapPhi, axisRapPhi}); - histos.add("Reco/h2d_n2_rapphi_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH2D, {axisRapPhi, axisRapPhi}); - - // rho2 for R2 Qinv - histos.add("Reco/h1d_n2_qinv_LaP_LaM", "#rho_{2}^{#Lambda#bar{#Lambda}}", kTH1D, {axisQinv}); - histos.add("Reco/h1d_n2_qinv_LaP_LaP", "#rho_{2}^{#Lambda#Lambda}", kTH1D, {axisQinv}); - histos.add("Reco/h1d_n2_qinv_LaM_LaM", "#rho_{2}^{#bar{#Lambda}#bar{#Lambda}}", kTH1D, {axisQinv}); + 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) { @@ -1556,10 +1509,11 @@ struct LambdaR2Correlation { } } - template + template void fillPairHistos(U& p1, U& p2) { static constexpr std::string_view SubDirRecGen[] = {"Reco/", "McGen/"}; + static constexpr std::string_view SubDirPrmScd[] = {"PP/", "PS/", "SP/", "SS/"}; static constexpr std::string_view SubDirHist[] = {"LaP_LaM", "LaP_LaP", "LaM_LaM"}; float rap1 = (cDoEtaAnalysis) ? p1.eta() : p1.rap(); @@ -1574,30 +1528,29 @@ struct LambdaR2Correlation { float corfac = p1.corrFact() * p2.corrFact(); // fill rho2 histograms - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("h2d_n2_ptpt_") + HIST(SubDirHist[part_pair]), p1.pt(), p2.pt(), corfac); - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("h2d_n2_etaeta_") + HIST(SubDirHist[part_pair]), p1.eta(), p2.eta(), corfac); - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("h2d_n2_raprap_") + HIST(SubDirHist[part_pair]), p1.rap(), p2.rap(), corfac); - histos.fill(HIST(SubDirRecGen[rec_gen]) + 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("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("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 + template void analyzeSingles(T const& tracks) { static constexpr std::string_view SubDirRecGen[] = {"Reco/", "McGen/"}; + static constexpr std::string_view SubDirPrmScd[] = {"Primary/", "Secondary/"}; static constexpr std::string_view SubDirHist[] = {"LaP", "LaM"}; int ntrk = 0; @@ -1607,22 +1560,21 @@ struct LambdaR2Correlation { ++ntrk; // Efficiency Plots - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("Efficiency/h1f_n1_pt_") + HIST(SubDirHist[part]), track.pt()); - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("Efficiency/h3f_n1_ptetaphi_") + HIST(SubDirHist[part]), track.pt(), track.eta(), track.phi()); - histos.fill(HIST(SubDirRecGen[rec_gen]) + 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("h1d_n1_mass_") + HIST(SubDirHist[part]), track.mass()); - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("h1d_n1_pt_") + HIST(SubDirHist[part]), track.pt(), track.corrFact()); - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("h1d_n1_eta_") + HIST(SubDirHist[part]), track.eta(), track.corrFact()); - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("h1d_n1_phi_") + HIST(SubDirHist[part]), track.phi(), track.corrFact()); - histos.fill(HIST(SubDirRecGen[rec_gen]) + 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("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("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 @@ -1635,7 +1587,7 @@ struct LambdaR2Correlation { } } - template + template void analyzePairs(T const& trks_1, T const& trks_2) { for (auto const& trk_1 : trks_1) { @@ -1644,7 +1596,7 @@ struct LambdaR2Correlation { if (samelambda && ((trk_1.index() == trk_2.index()))) { continue; } - fillPairHistos(trk_1, trk_2); + fillPairHistos(trk_1, trk_2); } } } @@ -1653,22 +1605,50 @@ struct LambdaR2Correlation { using LambdaTracks = soa::Join; SliceCache cache; - Partition partLambdaTracks = (aod::lambdatrack::v0Type == (int8_t)kLambda) && (aod::lambdatrackext::trueLambdaFlag == true); - Partition partAntiLambdaTracks = (aod::lambdatrack::v0Type == (int8_t)kAntiLambda) && (aod::lambdatrackext::trueLambdaFlag == true); + Partition partPrimLambdaTracks = (aod::lambdatrack::v0Type == (int8_t)kLambda) && (aod::lambdatrackext::trueLambdaFlag == true) && (aod::lambdatrack::v0PrmScd == (int8_t)kPrimary); + Partition partPrimAntiLambdaTracks = (aod::lambdatrack::v0Type == (int8_t)kAntiLambda) && (aod::lambdatrackext::trueLambdaFlag == true) && (aod::lambdatrack::v0PrmScd == (int8_t)kPrimary); + Partition partSecdLambdaTracks = (aod::lambdatrack::v0Type == (int8_t)kLambda) && (aod::lambdatrackext::trueLambdaFlag == true) && (aod::lambdatrack::v0PrmScd == (int8_t)kSecondary); + Partition partSecdAntiLambdaTracks = (aod::lambdatrack::v0Type == (int8_t)kAntiLambda) && (aod::lambdatrackext::trueLambdaFlag == true) && (aod::lambdatrack::v0PrmScd == (int8_t)kSecondary); void processDataReco(LambdaCollisions::iterator const& collision, LambdaTracks const&) { histos.fill(HIST("Event/Reco/h1f_collision_posz"), collision.posZ()); histos.fill(HIST("Event/Reco/h1f_ft0m_mult_percentile"), collision.cent()); - auto lambdaTracks = partLambdaTracks->sliceByCached(aod::lambdatrack::lambdaCollisionId, collision.globalIndex(), cache); - auto antiLambdaTracks = partAntiLambdaTracks->sliceByCached(aod::lambdatrack::lambdaCollisionId, collision.globalIndex(), cache); - - analyzeSingles(lambdaTracks); - analyzeSingles(antiLambdaTracks); - analyzePairs(lambdaTracks, antiLambdaTracks); - analyzePairs(lambdaTracks, lambdaTracks); - analyzePairs(antiLambdaTracks, antiLambdaTracks); + 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); + auto antiLambdaSecdTracks = partSecdAntiLambdaTracks->sliceByCached(aod::lambdatrack::lambdaCollisionId, collision.globalIndex(), cache); + + analyzeSingles(lambdaPrimTracks); + analyzeSingles(antiLambdaPrimTracks); + + 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); @@ -1677,23 +1657,50 @@ struct LambdaR2Correlation { using LambdaMcGenTracks = aod::LambdaMcGenTracks; SliceCache cachemc; - Partition partLambdaMcGenTracks = aod::lambdatrack::v0Type == (int8_t)kLambda; - Partition partAntiLambdaMcGenTracks = aod::lambdatrack::v0Type == (int8_t)kAntiLambda; + Partition partMcPrimLambdaTracks = (aod::lambdatrack::v0Type == (int8_t)kLambda) && (aod::lambdatrack::v0PrmScd == (int8_t)kPrimary); + Partition partMcPrimAntiLambdaTracks = (aod::lambdatrack::v0Type == (int8_t)kAntiLambda) && (aod::lambdatrack::v0PrmScd == (int8_t)kPrimary); + Partition partMcSecdLambdaTracks = (aod::lambdatrack::v0Type == (int8_t)kLambda) && (aod::lambdatrack::v0PrmScd == (int8_t)kSecondary); + Partition partMcSecdAntiLambdaTracks = (aod::lambdatrack::v0Type == (int8_t)kAntiLambda) && (aod::lambdatrack::v0PrmScd == (int8_t)kSecondary); void processMCGen(LambdaMcGenCollisions::iterator const& mcgencol, LambdaMcGenTracks const&) { histos.fill(HIST("Event/McGen/h1f_collision_posz"), mcgencol.posZ()); histos.fill(HIST("Event/McGen/h1f_ft0m_mult_percentile"), mcgencol.cent()); - auto lambdaMcGenTracks = partLambdaMcGenTracks->sliceByCached(aod::lambdamcgentrack::lambdaMcGenCollisionId, mcgencol.globalIndex(), cachemc); - auto antiLambdaMcGenTracks = partAntiLambdaMcGenTracks->sliceByCached(aod::lambdamcgentrack::lambdaMcGenCollisionId, mcgencol.globalIndex(), cachemc); - - analyzeSingles(lambdaMcGenTracks); - analyzeSingles(antiLambdaMcGenTracks); - - analyzePairs(lambdaMcGenTracks, antiLambdaMcGenTracks); - analyzePairs(lambdaMcGenTracks, lambdaMcGenTracks); - analyzePairs(antiLambdaMcGenTracks, antiLambdaMcGenTracks); + 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); + auto antiLambdaSecdTracks = partMcSecdAntiLambdaTracks->sliceByCached(aod::lambdamcgentrack::lambdaMcGenCollisionId, mcgencol.globalIndex(), cachemc); + + analyzeSingles(lambdaPrimTracks); + analyzeSingles(antiLambdaPrimTracks); + + 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 ff2cfe9298d..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"); @@ -3188,6 +3188,17 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } + if (!nameStr.compare("muonQualityCutsMUONStandalone")) { + cut->AddCut(GetAnalysisCut("matchedMchMid")); + cut->AddCut(GetAnalysisCut("muonQualityCuts")); + return cut; + } + + if (!nameStr.compare("muonQualityCutsGlobal")) { + cut->AddCut(GetAnalysisCut("matchedGlobal")); + cut->AddCut(GetAnalysisCut("muonQualityCuts")); + return cut; + } // ----------------------------------------------------------- // Pair cuts if (!nameStr.compare("pairNoCut")) { @@ -3654,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; } @@ -3998,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); @@ -4277,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); @@ -4723,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); @@ -5531,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); @@ -5614,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 b13a55d026a..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); @@ -565,10 +567,11 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "TPCnSigKa_Corr_pIN", "TPC n-#sigma(K) Corr. vs pIN", false, 100, 0.0, 10.0, VarManager::kPin, 100, -5.0, 5.0, VarManager::kTPCnSigmaKa_Corr); hm->AddHistogram(histClass, "TPCnSigPr_Corr_pIN", "TPC n-#sigma(p) Corr. vs pIN", false, 100, 0.0, 10.0, VarManager::kPin, 100, -5.0, 5.0, VarManager::kTPCnSigmaPr_Corr); } - if (subGroupStr.Contains("tpcpid_nsigel")) { - hm->AddHistogram(histClass, "TPCnSigEl_TPCnSigPi", "TPC n-#sigma(e) . vs TPC n-#sigma(#pi)", false, 100, -5.0, 5.0, VarManager::kTPCnSigmaEl, 100, -5.0, 5.0, VarManager::kTPCnSigmaPi); - hm->AddHistogram(histClass, "TPCnSigEl_TPCnSigKa", "TPC n-#sigma(e) . vs TPC n-#sigma(K)", false, 100, -5.0, 5.0, VarManager::kTPCnSigmaEl, 100, -5.0, 5.0, VarManager::kTPCnSigmaKa); - hm->AddHistogram(histClass, "TPCnSigEl_TPCnSigPr", "TPC n-#sigma(e) . vs TPC n-#sigma(p)", false, 100, -5.0, 5.0, VarManager::kTPCnSigmaEl, 100, -5.0, 5.0, VarManager::kTPCnSigmaPr); + if (subGroupStr.Contains("tpcpidvspt")) { + hm->AddHistogram(histClass, "TPCnSigEl_Pt", "TPC n-#sigma(e). vs Pt", false, 200, 0.0, 20.0, VarManager::kPt, 100, -5.0, 5.0, VarManager::kTPCnSigmaEl); + hm->AddHistogram(histClass, "TPCnSigPi_Pt", "TPC n-#sigma(#pi). vs Pt", false, 200, 0.0, 20.0, VarManager::kPt, 100, -5.0, 5.0, VarManager::kTPCnSigmaPi); + hm->AddHistogram(histClass, "TPCnSigKa_Pt", "TPC n-#sigma(K). vs Pt", false, 200, 0.0, 20.0, VarManager::kPt, 100, -5.0, 5.0, VarManager::kTPCnSigmaKa); + hm->AddHistogram(histClass, "TPCnSigPr_Pt", "TPC n-#sigma(p). vs Pt", false, 200, 0.0, 20.0, VarManager::kPt, 100, -5.0, 5.0, VarManager::kTPCnSigmaPr); } } } @@ -937,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); @@ -971,14 +976,34 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "VtxZ_VtxNcontribReal", "VtxZ vs VtxNcontribReal", false, 240, -12.0, 12.0, VarManager::kVtxZ, 200, 0, 200.0, VarManager::kVtxNcontribReal); } if (subGroupStr.Contains("polarization")) { - hm->AddHistogram(histClass, "cosThetaHE", "", false, 100, -1., 1., VarManager::kCosThetaHE); - hm->AddHistogram(histClass, "cosThetaCS", "", false, 100, -1., 1., VarManager::kCosThetaCS); - hm->AddHistogram(histClass, "PhiHE", "", false, 100, -o2::constants::math::PI, o2::constants::math::PI, VarManager::kPhiHE); - hm->AddHistogram(histClass, "PhiCS", "", false, 100, -o2::constants::math::PI, o2::constants::math::PI, VarManager::kPhiCS); - hm->AddHistogram(histClass, "Mass_Pt_cosThetaHE", "", false, 100, 1.0, 5.0, VarManager::kMass, 250, 0.0, 25.0, VarManager::kPt, 40, -1., 1., VarManager::kCosThetaHE); - hm->AddHistogram(histClass, "Mass_Pt_cosThetaCS", "", false, 100, 1.0, 5.0, VarManager::kMass, 250, 0.0, 25.0, VarManager::kPt, 40, -1., 1., VarManager::kCosThetaCS); - hm->AddHistogram(histClass, "Mass_Pt_PhiHE", "", false, 100, 1.0, 5.0, VarManager::kMass, 250, 0.0, 25.0, VarManager::kPt, 40, -o2::constants::math::PI, o2::constants::math::PI, VarManager::kPhiHE); - hm->AddHistogram(histClass, "Mass_Pt_PhiCS", "", false, 100, 1.0, 5.0, VarManager::kMass, 250, 0.0, 25.0, VarManager::kPt, 40, -o2::constants::math::PI, o2::constants::math::PI, VarManager::kPhiCS); + if (subGroupStr.Contains("helicity")) { + hm->AddHistogram(histClass, "cosThetaHE", "", false, 100, -1., 1., VarManager::kCosThetaHE); + hm->AddHistogram(histClass, "phiHE", "", false, 100, 0, 2 * o2::constants::math::PI, VarManager::kPhiHE); + hm->AddHistogram(histClass, "phitildeHE", "", false, 100, 0, 2 * o2::constants::math::PI, VarManager::kPhiTildeHE); + hm->AddHistogram(histClass, "Mass_Pt_CosThetaHE", "", false, 100, 1.0, 5.0, VarManager::kMass, 40, 0.0, 20.0, VarManager::kPt, 20, -1., 1., VarManager::kCosThetaHE); + hm->AddHistogram(histClass, "Mass_Pt_PhiHE", "", false, 100, 1.0, 5.0, VarManager::kMass, 40, 0.0, 20.0, VarManager::kPt, 20, 0., 2 * o2::constants::math::PI, VarManager::kPhiHE); + hm->AddHistogram(histClass, "Mass_Pt_PhiTildeHE", "", false, 100, 1.0, 5.0, VarManager::kMass, 40, 0.0, 20.0, VarManager::kPt, 20, 0., 2 * o2::constants::math::PI, VarManager::kPhiTildeHE); + } + if (subGroupStr.Contains("collins-soper")) { + hm->AddHistogram(histClass, "cosThetaCS", "", false, 100, -1., 1., VarManager::kCosThetaCS); + hm->AddHistogram(histClass, "phiCS", "", false, 100, 0, 2 * o2::constants::math::PI, VarManager::kPhiCS); + hm->AddHistogram(histClass, "phitildeCS", "", false, 100, 0, 2 * o2::constants::math::PI, VarManager::kPhiTildeCS); + hm->AddHistogram(histClass, "Mass_Pt_CosThetaCS", "", false, 100, 1.0, 5.0, VarManager::kMass, 40, 0.0, 20.0, VarManager::kPt, 20, -1., 1., VarManager::kCosThetaCS); + hm->AddHistogram(histClass, "Mass_Pt_PhiCS", "", false, 100, 1.0, 5.0, VarManager::kMass, 40, 0.0, 20.0, VarManager::kPt, 20, 0., 2 * o2::constants::math::PI, VarManager::kPhiCS); + hm->AddHistogram(histClass, "Mass_Pt_PhiTildeCS", "", false, 100, 1.0, 5.0, VarManager::kMass, 40, 0.0, 20.0, VarManager::kPt, 20, 0., 2 * o2::constants::math::PI, VarManager::kPhiTildeCS); + } + if (subGroupStr.Contains("production")) { + hm->AddHistogram(histClass, "cosThetaPP", "", false, 100, -1., 1., VarManager::kCosThetaPP); + hm->AddHistogram(histClass, "phiPP", "", false, 100, 0, 2 * o2::constants::math::PI, VarManager::kPhiPP); + hm->AddHistogram(histClass, "phitildePP", "", false, 100, 0, 2 * o2::constants::math::PI, VarManager::kPhiTildePP); + hm->AddHistogram(histClass, "Mass_Pt_CosThetaPP", "", false, 100, 1.0, 5.0, VarManager::kMass, 40, 0.0, 20.0, VarManager::kPt, 20, -1., 1., VarManager::kCosThetaPP); + hm->AddHistogram(histClass, "Mass_Pt_PhiPP", "", false, 100, 1.0, 5.0, VarManager::kMass, 40, 0.0, 20.0, VarManager::kPt, 20, 0., 2 * o2::constants::math::PI, VarManager::kPhiPP); + hm->AddHistogram(histClass, "Mass_Pt_PhiTildePP", "", false, 100, 1.0, 5.0, VarManager::kMass, 40, 0.0, 20.0, VarManager::kPt, 20, 0., 2 * o2::constants::math::PI, VarManager::kPhiTildePP); + } + if (subGroupStr.Contains("random")) { + hm->AddHistogram(histClass, "cosThetaRM", "", false, 100, -1., 1., VarManager::kCosThetaRM); + hm->AddHistogram(histClass, "Mass_Pt_CosThetaRM", "", false, 200, 1.0, 5.0, VarManager::kMass, 40, 0.0, 20.0, VarManager::kPt, 20, -1., 1., VarManager::kCosThetaRM); + } } if (subGroupStr.Contains("upsilon")) { hm->AddHistogram(histClass, "MassUpsilon_Pt", "", false, 500, 7.0, 12.0, VarManager::kMass, 400, 0.0, 40.0, VarManager::kPt); @@ -1009,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")) { @@ -1228,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/MCSignalLibrary.cxx b/PWGDQ/Core/MCSignalLibrary.cxx index 584d3d8e7e1..4486a7c8ea9 100644 --- a/PWGDQ/Core/MCSignalLibrary.cxx +++ b/PWGDQ/Core/MCSignalLibrary.cxx @@ -610,19 +610,16 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } if (!nameStr.compare("eFromPromptLM")) { MCProng prong(2, {11, 101}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502, 402}, {true, true}); - prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from light mesons without B/D in decay history", {prong}, {-1}); return signal; } if (!nameStr.compare("eFromHbtoLM")) { MCProng prong(2, {11, 101}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {false}); - prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from light mesons with B hadron in decay history", {prong}, {-1}); return signal; } if (!nameStr.compare("eFromHctoLM")) { MCProng prong(2, {11, 101, 402}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false, {502}, {true}); - prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from light mesons from D hadron decays and no B in decay history", {prong}, {-1}); return signal; } @@ -655,44 +652,37 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } if (!nameStr.compare("muFromHb")) { MCProng prong(2, {13, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); - prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "muons from b->mu", {prong}, {-1}); return signal; } if (!nameStr.compare("muFromPromptHc")) { MCProng prong(2, {13, 402}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); - prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "muons from c->mu, without beauty in decay history", {prong}, {-1}); return signal; } if (!nameStr.compare("muFromHbtoHc")) { MCProng prong(3, {13, 402, 502}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); - prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "muons from b->c->mu", {prong}, {-1}); return signal; } if (!nameStr.compare("secondaryMuon")) { - MCProng prong(1); - prong.SetPDGcode(0, 13, true); + MCProng prong(1, {13}, {true}, {false}, {0}, {0}, {false}); prong.SetSourceBit(0, MCProng::kProducedInTransport); signal = new MCSignal(name, "muons produced during transport in detector", {prong}, {-1}); return signal; } if (!nameStr.compare("muFromPromptLM")) { MCProng prong(2, {13, 101}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502, 402}, {true, true}); - prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "muons from light mesons without B/D in decay history", {prong}, {-1}); return signal; } if (!nameStr.compare("muFromHbtoLM")) { MCProng prong(2, {13, 101}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {false}); - prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "muons from light mesons with B hadron in decay history", {prong}, {-1}); return signal; } if (!nameStr.compare("muFromHctoLM")) { MCProng prong(2, {13, 101, 402}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false, {502}, {true}); - prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "muons from light mesons from D hadron decays and no B in decay history", {prong}, {-1}); return signal; } diff --git a/PWGDQ/Core/VarManager.cxx b/PWGDQ/Core/VarManager.cxx index dc3c963be43..503101d303f 100644 --- a/PWGDQ/Core/VarManager.cxx +++ b/PWGDQ/Core/VarManager.cxx @@ -542,18 +542,26 @@ void VarManager::SetDefaultVarNames() fgVariableUnits[kMCVy] = "cm"; // TODO: check the unit fgVariableNames[kMCVz] = "MC vz"; fgVariableUnits[kMCVz] = "cm"; // TODO: check the unit - fgVariableNames[kMCCosThetaHE] = "cos#it{#theta}^{MC}_{HE}"; + fgVariableNames[kMCCosThetaHE] = "MC cos(#theta_{HE})"; fgVariableUnits[kMCCosThetaHE] = ""; - fgVariableNames[kMCPhiHE] = "#varphi^{MC}_{HE}"; - fgVariableUnits[kMCPhiHE] = "rad."; - fgVariableNames[kMCCosThetaCS] = "cos#it{#theta}^{MC}_{CS}"; + fgVariableNames[kMCPhiHE] = "MC #varphi_{HE}"; + fgVariableUnits[kMCPhiHE] = "rad"; + fgVariableNames[kMCPhiTildeHE] = "MC #tilde{#varphi}_{HE}"; + fgVariableUnits[kMCPhiTildeHE] = "rad"; + fgVariableNames[kMCCosThetaCS] = "MC cos(#theta_{CS})"; fgVariableUnits[kMCCosThetaCS] = ""; - fgVariableNames[kMCPhiCS] = "#varphi^{MC}_{CS}"; - fgVariableUnits[kMCPhiCS] = "rad."; - fgVariableNames[kMCCosThetaPP] = "cos#it{#theta}^{MC}_{PP}"; + fgVariableNames[kMCPhiCS] = "MC #varphi_{CS}"; + fgVariableUnits[kMCPhiCS] = "rad"; + fgVariableNames[kMCPhiTildeCS] = "MC #tilde{#varphi}_{CS}"; + fgVariableUnits[kMCPhiTildeCS] = "rad"; + fgVariableNames[kMCCosThetaPP] = "MC cos(#theta_{PP})"; fgVariableUnits[kMCCosThetaPP] = ""; - fgVariableNames[kMCPhiPP] = "#varphi^{MC}_{PP}"; - fgVariableUnits[kMCPhiPP] = "rad."; + fgVariableNames[kMCPhiPP] = "MC #varphi_{PP}"; + fgVariableUnits[kMCPhiPP] = "rad"; + fgVariableNames[kMCPhiTildePP] = "MC #tilde{#varphi}_{PP}"; + fgVariableUnits[kMCPhiTildePP] = "rad"; + fgVariableNames[kMCCosThetaRM] = "MC cos(#theta_{RM})"; + fgVariableUnits[kMCCosThetaRM] = ""; fgVariableNames[kCandidateId] = ""; fgVariableUnits[kCandidateId] = ""; fgVariableNames[kPairType] = "Pair type"; @@ -934,18 +942,26 @@ void VarManager::SetDefaultVarNames() fgVariableUnits[kDeltaPhi] = "rad."; fgVariableNames[kDeltaPhiSym] = "#Delta#phi"; fgVariableUnits[kDeltaPhiSym] = "rad."; - fgVariableNames[kCosThetaHE] = "cos#it{#theta}_{HE}"; + fgVariableNames[kCosThetaHE] = "cos#it{#theta}"; fgVariableUnits[kCosThetaHE] = ""; fgVariableNames[kPhiHE] = "#varphi_{HE}"; fgVariableUnits[kPhiHE] = "rad."; + fgVariableNames[kPhiTildeHE] = "#tilde{#varphi}_{HE}"; + fgVariableUnits[kPhiTildeHE] = "rad."; fgVariableNames[kCosThetaCS] = "cos#it{#theta}_{CS}"; fgVariableUnits[kCosThetaCS] = ""; fgVariableNames[kPhiCS] = "#varphi_{CS}"; fgVariableUnits[kPhiCS] = "rad."; + fgVariableNames[kPhiTildeCS] = "#tilde{#varphi}_{CS}"; + fgVariableUnits[kPhiTildeCS] = "rad."; fgVariableNames[kCosThetaPP] = "cos#it{#theta}_{PP}"; fgVariableUnits[kCosThetaPP] = ""; fgVariableNames[kPhiPP] = "#varphi_{PP}"; fgVariableUnits[kPhiPP] = "rad."; + fgVariableNames[kPhiTildePP] = "#tilde{#varphi}_{PP}"; + fgVariableUnits[kPhiTildePP] = "rad."; + fgVariableNames[kCosThetaRM] = "cos#it{#theta}_{RM}"; + fgVariableUnits[kCosThetaRM] = ""; fgVariableNames[kCosPhiVP] = "cos#it{#varphi}_{VP}"; fgVariableUnits[kCosPhiVP] = ""; fgVariableNames[kPhiVP] = "#varphi_{VP} - #Psi_{2}"; @@ -1462,11 +1478,15 @@ void VarManager::SetDefaultVarNames() fgVarNamesMap["kMCEta"] = kMCEta; fgVarNamesMap["kMCY"] = kMCY; fgVarNamesMap["kMCCosThetaHE"] = kMCCosThetaHE; - fgVarNamesMap["kMCCosThetaCS"] = kMCCosThetaCS; - fgVarNamesMap["kMCCosThetaPP"] = kMCCosThetaPP; fgVarNamesMap["kMCPhiHE"] = kMCPhiHE; + fgVarNamesMap["kMCPhiTildeHE"] = kMCPhiTildeHE; + fgVarNamesMap["kMCCosThetaCS"] = kMCCosThetaCS; fgVarNamesMap["kMCPhiCS"] = kMCPhiCS; + fgVarNamesMap["kMCPhiTildeCS"] = kMCPhiTildeCS; + fgVarNamesMap["kMCCosThetaPP"] = kMCCosThetaPP; fgVarNamesMap["kMCPhiPP"] = kMCPhiPP; + fgVarNamesMap["kMCPhiTildePP"] = kMCPhiTildePP; + fgVarNamesMap["kMCCosThetaRM"] = kMCCosThetaRM; fgVarNamesMap["kMCParticleGeneratorId"] = kMCParticleGeneratorId; fgVarNamesMap["kNMCParticleVariables"] = kNMCParticleVariables; fgVarNamesMap["kMCMotherPdgCode"] = kMCMotherPdgCode; @@ -1496,11 +1516,15 @@ void VarManager::SetDefaultVarNames() fgVarNamesMap["kVertexingProcCode"] = kVertexingProcCode; fgVarNamesMap["kVertexingChi2PCA"] = kVertexingChi2PCA; fgVarNamesMap["kCosThetaHE"] = kCosThetaHE; - fgVarNamesMap["kCosThetaCS"] = kCosThetaCS; - fgVarNamesMap["kCosThetaPP"] = kCosThetaPP; fgVarNamesMap["kPhiHE"] = kPhiHE; + fgVarNamesMap["kPhiTildeHE"] = kPhiTildeHE; + fgVarNamesMap["kCosThetaCS"] = kCosThetaCS; fgVarNamesMap["kPhiCS"] = kPhiCS; + fgVarNamesMap["kPhiTildeCS"] = kPhiTildeCS; + fgVarNamesMap["kCosThetaPP"] = kCosThetaPP; fgVarNamesMap["kPhiPP"] = kPhiPP; + fgVarNamesMap["kPhiTildePP"] = kPhiTildePP; + fgVarNamesMap["kCosThetaRM"] = kCosThetaRM; fgVarNamesMap["kCosPhiVP"] = kCosPhiVP; fgVarNamesMap["kPhiVP"] = kPhiVP; fgVarNamesMap["kDeltaPhiPair2"] = kDeltaPhiPair2; diff --git a/PWGDQ/Core/VarManager.h b/PWGDQ/Core/VarManager.h index b1e18ab7635..31c1f69a275 100644 --- a/PWGDQ/Core/VarManager.h +++ b/PWGDQ/Core/VarManager.h @@ -621,11 +621,15 @@ class VarManager : public TObject // MC pair variables kMCCosThetaHE, - kMCCosThetaCS, - kMCCosThetaPP, kMCPhiHE, + kMCPhiTildeHE, + kMCCosThetaCS, kMCPhiCS, + kMCPhiTildeCS, + kMCCosThetaPP, kMCPhiPP, + kMCPhiTildePP, + kMCCosThetaRM, // Pair variables kCandidateId, @@ -654,11 +658,15 @@ class VarManager : public TObject kVertexingProcCode, kVertexingChi2PCA, kCosThetaHE, - kCosThetaCS, - kCosThetaPP, kPhiHE, + kPhiTildeHE, + kCosThetaCS, kPhiCS, + kPhiTildeCS, + kCosThetaPP, kPhiPP, + kPhiTildePP, + kCosThetaRM, kCosPhiVP, kPhiVP, kDeltaPhiPair2, @@ -1098,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) @@ -2368,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(); @@ -2471,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 @@ -2814,53 +2829,128 @@ void VarManager::FillPair(T1 const& t1, T2 const& t2, float* values) } } - // TO DO: get the correct values from CCDB - double BeamMomentum = TMath::Sqrt(fgCenterOfMassEnergy * fgCenterOfMassEnergy / 4 - fgMassofCollidingParticle * fgMassofCollidingParticle); // GeV - ROOT::Math::PxPyPzEVector Beam1(0., 0., -BeamMomentum, fgCenterOfMassEnergy / 2); - ROOT::Math::PxPyPzEVector Beam2(0., 0., BeamMomentum, fgCenterOfMassEnergy / 2); - - // Boost to center of mass frame - ROOT::Math::Boost boostv12{v12.BoostToCM()}; - ROOT::Math::XYZVectorF v1_CM{(boostv12(v1).Vect()).Unit()}; - ROOT::Math::XYZVectorF v2_CM{(boostv12(v2).Vect()).Unit()}; - ROOT::Math::XYZVectorF Beam1_CM{(boostv12(Beam1).Vect()).Unit()}; - ROOT::Math::XYZVectorF Beam2_CM{(boostv12(Beam2).Vect()).Unit()}; - - // Helicity frame - ROOT::Math::XYZVectorF zaxis_HE{(v12.Vect()).Unit()}; - ROOT::Math::XYZVectorF yaxis_HE{(Beam1_CM.Cross(Beam2_CM)).Unit()}; - ROOT::Math::XYZVectorF xaxis_HE{(yaxis_HE.Cross(zaxis_HE)).Unit()}; - - // Collins-Soper frame - ROOT::Math::XYZVectorF zaxis_CS{((Beam1_CM.Unit() - Beam2_CM.Unit()).Unit())}; - ROOT::Math::XYZVectorF yaxis_CS{(Beam1_CM.Cross(Beam2_CM)).Unit()}; - ROOT::Math::XYZVectorF xaxis_CS{(yaxis_CS.Cross(zaxis_CS)).Unit()}; - - // Production frame - ROOT::Math::XYZVector normalVec = ROOT::Math::XYZVector(v12.Py(), -v12.Px(), 0.f); - - if (fgUsedVars[kCosThetaHE]) { - values[kCosThetaHE] = (t1.sign() > 0 ? zaxis_HE.Dot(v1_CM) : zaxis_HE.Dot(v2_CM)); - } - - if (fgUsedVars[kPhiHE]) { - values[kPhiHE] = (t1.sign() > 0 ? TMath::ATan2(yaxis_HE.Dot(v1_CM), xaxis_HE.Dot(v1_CM)) : TMath::ATan2(yaxis_HE.Dot(v2_CM), xaxis_HE.Dot(v2_CM))); - } - - if (fgUsedVars[kCosThetaCS]) { - values[kCosThetaCS] = (t1.sign() > 0 ? zaxis_CS.Dot(v1_CM) : zaxis_CS.Dot(v2_CM)); - } + // polarization parameters + bool useHE = fgUsedVars[kCosThetaHE] || fgUsedVars[kPhiHE]; // helicity frame + bool useCS = fgUsedVars[kCosThetaCS] || fgUsedVars[kPhiCS]; // Collins-Soper frame + bool usePP = fgUsedVars[kCosThetaPP]; // production plane frame + bool useRM = fgUsedVars[kCosThetaRM]; // Random frame + + if (useHE || useCS || usePP || useRM) { + // TO DO: get the correct values from CCDB + double BeamMomentum = TMath::Sqrt(fgCenterOfMassEnergy * fgCenterOfMassEnergy / 4 - fgMassofCollidingParticle * fgMassofCollidingParticle); // GeV + ROOT::Math::PxPyPzEVector Beam1(0., 0., -BeamMomentum, fgCenterOfMassEnergy / 2); + ROOT::Math::PxPyPzEVector Beam2(0., 0., BeamMomentum, fgCenterOfMassEnergy / 2); + + ROOT::Math::Boost boostv12{v12.BoostToCM()}; + ROOT::Math::XYZVectorF v1_CM{(boostv12(v1).Vect()).Unit()}; + ROOT::Math::XYZVectorF v2_CM{(boostv12(v2).Vect()).Unit()}; + ROOT::Math::XYZVectorF Beam1_CM{(boostv12(Beam1).Vect()).Unit()}; + ROOT::Math::XYZVectorF Beam2_CM{(boostv12(Beam2).Vect()).Unit()}; + + // using positive sign convention for the first track + ROOT::Math::XYZVectorF v_CM = (t1.sign() > 0 ? v1_CM : v2_CM); + + if (useHE) { + ROOT::Math::XYZVectorF zaxis_HE{(v12.Vect()).Unit()}; + ROOT::Math::XYZVectorF yaxis_HE{(Beam1_CM.Cross(Beam2_CM)).Unit()}; + ROOT::Math::XYZVectorF xaxis_HE{(yaxis_HE.Cross(zaxis_HE)).Unit()}; + if (fgUsedVars[kCosThetaHE]) + values[kCosThetaHE] = zaxis_HE.Dot(v_CM); + if (fgUsedVars[kPhiHE]) { + values[kPhiHE] = TMath::ATan2(yaxis_HE.Dot(v_CM), xaxis_HE.Dot(v_CM)); + if (values[kPhiHE] < 0) { + values[kPhiHE] += 2 * TMath::Pi(); // ensure phi is in [0, 2pi] + } + } + if (fgUsedVars[kPhiTildeHE]) { + if (fgUsedVars[kCosThetaHE] && fgUsedVars[kPhiHE]) { + if (values[kCosThetaHE] > 0) { + values[kPhiTildeHE] = values[kPhiHE] - 0.25 * TMath::Pi(); // phi_tilde = phi - pi/4 + if (values[kPhiTildeHE] < 0) { + values[kPhiTildeHE] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } else { + values[kPhiTildeHE] = values[kPhiHE] - 0.75 * TMath::Pi(); // phi_tilde = phi - 3pi/4 + if (values[kPhiTildeHE] < 0) { + values[kPhiTildeHE] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } + } else { + values[kPhiTildeHE] = -999; // not computable + } + } + } - if (fgUsedVars[kPhiCS]) { - values[kPhiCS] = (t1.sign() > 0 ? TMath::ATan2(yaxis_CS.Dot(v1_CM), xaxis_CS.Dot(v1_CM)) : TMath::ATan2(yaxis_CS.Dot(v2_CM), xaxis_CS.Dot(v2_CM))); - } + if (useCS) { + ROOT::Math::XYZVectorF zaxis_CS{(Beam1_CM - Beam2_CM).Unit()}; + ROOT::Math::XYZVectorF yaxis_CS{(Beam1_CM.Cross(Beam2_CM)).Unit()}; + ROOT::Math::XYZVectorF xaxis_CS{(yaxis_CS.Cross(zaxis_CS)).Unit()}; + if (fgUsedVars[kCosThetaCS]) + values[kCosThetaCS] = zaxis_CS.Dot(v_CM); + if (fgUsedVars[kPhiCS]) { + values[kPhiCS] = TMath::ATan2(yaxis_CS.Dot(v_CM), xaxis_CS.Dot(v_CM)); + if (values[kPhiCS] < 0) { + values[kPhiCS] += 2 * TMath::Pi(); // ensure phi is in [0, 2pi] + } + } + if (fgUsedVars[kPhiTildeCS]) { + if (fgUsedVars[kCosThetaCS] && fgUsedVars[kPhiCS]) { + if (values[kCosThetaCS] > 0) { + values[kPhiTildeCS] = values[kPhiCS] - 0.25 * TMath::Pi(); // phi_tilde = phi - pi/4 + if (values[kPhiTildeCS] < 0) { + values[kPhiTildeCS] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } else { + values[kPhiTildeCS] = values[kPhiCS] - 0.75 * TMath::Pi(); // phi_tilde = phi - 3pi/4 + if (values[kPhiTildeCS] < 0) { + values[kPhiTildeCS] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } + } else { + values[kPhiTildeCS] = -999; // not computable + } + } + } - if (fgUsedVars[kCosThetaPP]) { - values[kCosThetaPP] = (t1.sign() > 0 ? normalVec.Dot(v1_CM) : normalVec.Dot(v2_CM)); - } + if (usePP) { + ROOT::Math::XYZVector zaxis_PP = ROOT::Math::XYZVector(v12.Py(), -v12.Px(), 0.f); + 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) / std::sqrt(zaxis_PP.Mag2()); + } + if (fgUsedVars[kPhiPP]) { + values[kPhiPP] = TMath::ATan2(yaxis_PP.Dot(v_CM), xaxis_PP.Dot(v_CM)); + if (values[kPhiPP] < 0) { + values[kPhiPP] += 2 * TMath::Pi(); // ensure phi is in [0, 2pi] + } + } + if (fgUsedVars[kPhiTildePP]) { + if (fgUsedVars[kCosThetaPP] && fgUsedVars[kPhiPP]) { + if (values[kCosThetaPP] > 0) { + values[kPhiTildePP] = values[kPhiPP] - 0.25 * TMath::Pi(); // phi_tilde = phi - pi/4 + if (values[kPhiTildePP] < 0) { + values[kPhiTildePP] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } else { + values[kPhiTildePP] = values[kPhiPP] - 0.75 * TMath::Pi(); // phi_tilde = phi - 3pi/4 + if (values[kPhiTildePP] < 0) { + values[kPhiTildePP] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } + } else { + values[kPhiTildePP] = -999; // not computable + } + } + } - if (fgUsedVars[kPhiPP]) { - values[kPhiPP] = (t1.sign() > 0 ? TMath::ATan2((normalVec.Dot(v1_CM)), zaxis_HE.Dot(v1_CM)) : TMath::ATan2((normalVec.Dot(v2_CM)), zaxis_HE.Dot(v2_CM))); + if (useRM) { + double randomCostheta = gRandom->Uniform(-1., 1.); + double randomPhi = gRandom->Uniform(0., 2. * TMath::Pi()); + ROOT::Math::XYZVectorF zaxis_RM(randomCostheta, std::sqrt(1 - randomCostheta * randomCostheta) * std::cos(randomPhi), std::sqrt(1 - randomCostheta * randomCostheta) * std::sin(randomPhi)); + if (fgUsedVars[kCosThetaRM]) + values[kCosThetaRM] = zaxis_RM.Dot(v_CM); + } } if constexpr ((pairType == kDecayToEE) && ((fillMap & TrackCov) > 0 || (fillMap & ReducedTrackBarrelCov) > 0)) { @@ -3253,38 +3343,129 @@ void VarManager::FillPairMC(T1 const& t1, T2 const& t2, float* values) values[kMCEta] = v12.Eta(); values[kMCPhi] = v12.Phi(); values[kMCY] = -v12.Rapidity(); - double BeamMomentum = TMath::Sqrt(fgCenterOfMassEnergy * fgCenterOfMassEnergy / 4 - fgMassofCollidingParticle * fgMassofCollidingParticle); // GeV - ROOT::Math::PxPyPzEVector Beam1(0., 0., -BeamMomentum, fgCenterOfMassEnergy / 2); - ROOT::Math::PxPyPzEVector Beam2(0., 0., BeamMomentum, fgCenterOfMassEnergy / 2); - - // Boost to center of mass frame - ROOT::Math::Boost boostv12{v12.BoostToCM()}; - ROOT::Math::XYZVectorF v1_CM{(boostv12(v1).Vect()).Unit()}; - ROOT::Math::XYZVectorF v2_CM{(boostv12(v2).Vect()).Unit()}; - ROOT::Math::XYZVectorF Beam1_CM{(boostv12(Beam1).Vect()).Unit()}; - ROOT::Math::XYZVectorF Beam2_CM{(boostv12(Beam2).Vect()).Unit()}; - - if (fgUsedVars[kMCCosThetaHE] || fgUsedVars[kMCPhiHE]) { - ROOT::Math::XYZVectorF zaxis_HE{(v12.Vect()).Unit()}; - ROOT::Math::XYZVectorF yaxis_HE{(Beam1_CM.Cross(Beam2_CM)).Unit()}; - ROOT::Math::XYZVectorF xaxis_HE{(yaxis_HE.Cross(zaxis_HE)).Unit()}; - values[kMCCosThetaHE] = (t1.pdgCode() < 0 ? zaxis_HE.Dot(v1_CM) : zaxis_HE.Dot(v2_CM)); - values[kMCPhiHE] = (t1.pdgCode() < 0 ? TMath::ATan2(yaxis_HE.Dot(v1_CM), xaxis_HE.Dot(v1_CM)) : TMath::ATan2(yaxis_HE.Dot(v2_CM), xaxis_HE.Dot(v2_CM))); - } - - if (fgUsedVars[kMCCosThetaCS] || fgUsedVars[kMCPhiCS]) { - ROOT::Math::XYZVectorF zaxis_CS{((Beam1_CM.Unit() - Beam2_CM.Unit()).Unit())}; - ROOT::Math::XYZVectorF yaxis_CS{(Beam1_CM.Cross(Beam2_CM)).Unit()}; - ROOT::Math::XYZVectorF xaxis_CS{(yaxis_CS.Cross(zaxis_CS)).Unit()}; - values[kMCCosThetaCS] = (t1.pdgCode() < 0 ? zaxis_CS.Dot(v1_CM) : zaxis_CS.Dot(v2_CM)); - values[kMCPhiCS] = (t1.pdgCode() < 0 ? TMath::ATan2(yaxis_CS.Dot(v1_CM), xaxis_CS.Dot(v1_CM)) : TMath::ATan2(yaxis_CS.Dot(v2_CM), xaxis_CS.Dot(v2_CM))); - } - - if (fgUsedVars[kMCCosThetaPP] || fgUsedVars[kMCPhiPP]) { - ROOT::Math::XYZVectorF zaxis_HE{(v12.Vect()).Unit()}; - ROOT::Math::XYZVector normalVec = ROOT::Math::XYZVector(v12.Py(), -v12.Px(), 0.f); - values[kMCCosThetaPP] = (t1.pdgCode() < 0 ? normalVec.Dot(v1_CM) : normalVec.Dot(v2_CM)); - values[kMCPhiPP] = (t1.pdgCode() < 0 ? TMath::ATan2((normalVec.Dot(v1_CM)), zaxis_HE.Dot(v1_CM)) : TMath::ATan2((normalVec.Dot(v2_CM)), zaxis_HE.Dot(v2_CM))); + + // polarization parameters + bool useHE = fgUsedVars[kMCCosThetaHE] || fgUsedVars[kMCPhiHE]; // helicity frame + bool useCS = fgUsedVars[kMCCosThetaCS] || fgUsedVars[kMCPhiCS]; // Collins-Soper frame + bool usePP = fgUsedVars[kMCCosThetaPP]; // production plane frame + bool useRM = fgUsedVars[kMCCosThetaRM]; // Random frame + + if (useHE || useCS || usePP || useRM) { + // TO DO: get the correct values from CCDB + double BeamMomentum = TMath::Sqrt(fgCenterOfMassEnergy * fgCenterOfMassEnergy / 4 - fgMassofCollidingParticle * fgMassofCollidingParticle); // GeV + ROOT::Math::PxPyPzEVector Beam1(0., 0., -BeamMomentum, fgCenterOfMassEnergy / 2); + ROOT::Math::PxPyPzEVector Beam2(0., 0., BeamMomentum, fgCenterOfMassEnergy / 2); + + ROOT::Math::Boost boostv12{v12.BoostToCM()}; + ROOT::Math::XYZVectorF v1_CM{(boostv12(v1).Vect()).Unit()}; + ROOT::Math::XYZVectorF v2_CM{(boostv12(v2).Vect()).Unit()}; + ROOT::Math::XYZVectorF Beam1_CM{(boostv12(Beam1).Vect()).Unit()}; + ROOT::Math::XYZVectorF Beam2_CM{(boostv12(Beam2).Vect()).Unit()}; + + // using positive sign convention for the first track + ROOT::Math::XYZVectorF v_CM = (t1.pdgCode() > 0 ? v1_CM : v2_CM); + + if (useHE) { + ROOT::Math::XYZVectorF zaxis_HE{(v12.Vect()).Unit()}; + ROOT::Math::XYZVectorF yaxis_HE{(Beam1_CM.Cross(Beam2_CM)).Unit()}; + ROOT::Math::XYZVectorF xaxis_HE{(yaxis_HE.Cross(zaxis_HE)).Unit()}; + if (fgUsedVars[kMCCosThetaHE]) + values[kMCCosThetaHE] = zaxis_HE.Dot(v_CM); + if (fgUsedVars[kMCPhiHE]) { + values[kMCPhiHE] = TMath::ATan2(yaxis_HE.Dot(v_CM), xaxis_HE.Dot(v_CM)); + if (values[kMCPhiHE] < 0) { + values[kMCPhiHE] += 2 * TMath::Pi(); // ensure phi is in [0, 2pi] + } + } + if (fgUsedVars[kMCPhiTildeHE]) { + if (fgUsedVars[kMCCosThetaHE] && fgUsedVars[kMCPhiHE]) { + if (values[kMCCosThetaHE] > 0) { + values[kMCPhiTildeHE] = values[kMCPhiHE] - 0.25 * TMath::Pi(); // phi_tilde = phi - pi/4 + if (values[kMCPhiTildeHE] < 0) { + values[kMCPhiTildeHE] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } else { + values[kMCPhiTildeHE] = values[kMCPhiHE] - 0.75 * TMath::Pi(); // phi_tilde = phi - 3pi/4 + if (values[kMCPhiTildeHE] < 0) { + values[kMCPhiTildeHE] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } + } else { + values[kMCPhiTildeHE] = -999; // not computable + } + } + } + + if (useCS) { + ROOT::Math::XYZVectorF zaxis_CS{(Beam1_CM - Beam2_CM).Unit()}; + ROOT::Math::XYZVectorF yaxis_CS{(Beam1_CM.Cross(Beam2_CM)).Unit()}; + ROOT::Math::XYZVectorF xaxis_CS{(yaxis_CS.Cross(zaxis_CS)).Unit()}; + if (fgUsedVars[kMCCosThetaCS]) + values[kMCCosThetaCS] = zaxis_CS.Dot(v_CM); + if (fgUsedVars[kMCPhiCS]) { + values[kMCPhiCS] = TMath::ATan2(yaxis_CS.Dot(v_CM), xaxis_CS.Dot(v_CM)); + if (values[kMCPhiCS] < 0) { + values[kMCPhiCS] += 2 * TMath::Pi(); // ensure phi is in [0, 2pi] + } + } + if (fgUsedVars[kMCPhiTildeCS]) { + if (fgUsedVars[kMCCosThetaCS] && fgUsedVars[kMCPhiCS]) { + if (values[kMCCosThetaCS] > 0) { + values[kMCPhiTildeCS] = values[kMCPhiCS] - 0.25 * TMath::Pi(); // phi_tilde = phi - pi/4 + if (values[kMCPhiTildeCS] < 0) { + values[kMCPhiTildeCS] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } else { + values[kMCPhiTildeCS] = values[kMCPhiCS] - 0.75 * TMath::Pi(); // phi_tilde = phi - 3pi/4 + if (values[kMCPhiTildeCS] < 0) { + values[kMCPhiTildeCS] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } + } else { + values[kMCPhiTildeCS] = -999; // not computable + } + } + } + + if (usePP) { + ROOT::Math::XYZVector zaxis_PP = ROOT::Math::XYZVector(v12.Py(), -v12.Px(), 0.f); + ROOT::Math::XYZVector yaxis_PP{v12.Vect().Unit()}; + ROOT::Math::XYZVector xaxis_PP{(yaxis_PP.Cross(zaxis_PP)).Unit()}; + if (fgUsedVars[kMCCosThetaPP]) { + values[kMCCosThetaPP] = zaxis_PP.Dot(v_CM); + } + if (fgUsedVars[kMCPhiPP]) { + values[kMCPhiPP] = TMath::ATan2(yaxis_PP.Dot(v_CM), xaxis_PP.Dot(v_CM)); + if (values[kMCPhiPP] < 0) { + values[kMCPhiPP] += 2 * TMath::Pi(); // ensure phi is in [0, 2pi] + } + } + if (fgUsedVars[kMCPhiTildePP]) { + if (fgUsedVars[kMCCosThetaPP] && fgUsedVars[kMCPhiPP]) { + if (values[kMCCosThetaPP] > 0) { + values[kMCPhiTildePP] = values[kMCPhiPP] - 0.25 * TMath::Pi(); // phi_tilde = phi - pi/4 + if (values[kMCPhiTildePP] < 0) { + values[kMCPhiTildePP] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } else { + values[kMCPhiTildePP] = values[kMCPhiPP] - 0.75 * TMath::Pi(); // phi_tilde = phi - 3pi/4 + if (values[kMCPhiTildePP] < 0) { + values[kMCPhiTildePP] += 2 * TMath::Pi(); // ensure phi_tilde is in [0, 2pi] + } + } + } else { + values[kMCPhiTildePP] = -999; // not computable + } + } + } + + if (useRM) { + double randomCostheta = gRandom->Uniform(-1., 1.); + double randomPhi = gRandom->Uniform(0., 2. * TMath::Pi()); + ROOT::Math::XYZVectorF zaxis_RM(randomCostheta, std::sqrt(1 - randomCostheta * randomCostheta) * std::cos(randomPhi), std::sqrt(1 - randomCostheta * randomCostheta) * std::sin(randomPhi)); + if (fgUsedVars[kMCCosThetaRM]) + values[kMCCosThetaRM] = zaxis_RM.Dot(v_CM); + } } } @@ -3798,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.; @@ -3832,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()) + @@ -4098,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/Dilepton.h b/PWGEM/Dilepton/Core/Dilepton.h index ebe9e26ad50..95bd4a0b6f8 100644 --- a/PWGEM/Dilepton/Core/Dilepton.h +++ b/PWGEM/Dilepton/Core/Dilepton.h @@ -903,6 +903,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 +915,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 +927,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/SingleTrackQC.h b/PWGEM/Dilepton/Core/SingleTrackQC.h index 7ed467c2814..f5f8be20518 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQC.h @@ -231,7 +231,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); 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/skimmerPrimaryMuon.cxx b/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuon.cxx index 439e324ab3c..2558b46cb3a 100644 --- a/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuon.cxx +++ b/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuon.cxx @@ -393,6 +393,10 @@ struct skimmerPrimaryMuon { const auto& bc = collision.template bc_as(); initCCDB(bc); + if (!collision.isSelected()) { + continue; + } + const auto& fwdtracks_per_coll = fwdtracks.sliceBy(perCollision, collision.globalIndex()); for (const auto& fwdtrack : fwdtracks_per_coll) { if (fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { @@ -417,6 +421,10 @@ struct skimmerPrimaryMuon { const auto& bc = collision.template bc_as(); initCCDB(bc); + if (!collision.isSelected()) { + continue; + } + const auto& fwdtrackIdsThisCollision = fwdtrackIndices.sliceBy(fwdtrackIndicesPerCollision, collision.globalIndex()); for (const auto& fwdtrackId : fwdtrackIdsThisCollision) { const auto& fwdtrack = fwdtrackId.template fwdtrack_as(); @@ -435,6 +443,11 @@ struct skimmerPrimaryMuon { for (const auto& collision : collisions) { const auto& bc = collision.template bc_as(); initCCDB(bc); + + if (!collision.isSelected()) { + continue; + } + if (collision.swtaliastmp_raw() == 0) { continue; } @@ -462,6 +475,9 @@ struct skimmerPrimaryMuon { for (const auto& collision : collisions) { const auto& bc = collision.template bc_as(); initCCDB(bc); + if (!collision.isSelected()) { + continue; + } if (collision.swtaliastmp_raw() == 0) { continue; } @@ -484,6 +500,9 @@ struct skimmerPrimaryMuon { for (const auto& collision : collisions) { const auto& bc = collision.template bc_as(); initCCDB(bc); + if (!collision.isSelected()) { + continue; + } if (!collision.has_mcCollision()) { continue; } @@ -514,6 +533,9 @@ struct skimmerPrimaryMuon { for (const auto& collision : collisions) { const auto& bc = collision.template bc_as(); initCCDB(bc); + if (!collision.isSelected()) { + continue; + } if (!collision.has_mcCollision()) { continue; } diff --git a/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx b/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx index a202ad331c9..a24b62374f8 100644 --- a/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx +++ b/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx @@ -132,6 +132,7 @@ struct TreeCreatorElectronMLDDA { Configurable max_pin_for_downscaling_pion{"max_pin_for_downscaling_pion", 2.0, "max pin to apply down scaling factor to store pion"}; Configurable max_pin_for_downscaling_kaon{"max_pin_for_downscaling_kaon", 0.0, "max pin to apply down scaling factor to store kaon"}; Configurable max_pin_for_downscaling_proton{"max_pin_for_downscaling_proton", 2.0, "max pin to apply down scaling factor to store proton"}; + Configurable store_ele_band_only{"store_ele_band_only", false, "flag to store tracks around electron band only to reduce output size"}; struct : ConfigurableGroup { std::string prefix = "trackcut_group"; @@ -228,7 +229,7 @@ struct TreeCreatorElectronMLDDA { Configurable cfg_min_mass_ee{"cfg_min_mass_ee", 0.000, "min mass for ee from pi0 dalitz decay in GeV/c2"}; Configurable cfg_max_mass_ee{"cfg_max_mass_ee", 0.005, "max mass for ee from pi0 dalitz decay in GeV/c2"}; Configurable cfg_min_phiv_ee{"cfg_min_phiv_ee", 0.0, "min phiv for ee from pi0 dalitz decay in rad."}; - Configurable cfg_max_phiv_ee{"cfg_max_phiv_ee", 2.0, "max phiv for ee from pi0 dalitz decay in rad."}; + Configurable cfg_max_phiv_ee{"cfg_max_phiv_ee", M_PI / 2, "max phiv for ee from pi0 dalitz decay in rad."}; } dalitzcuts; // for RCT @@ -519,6 +520,10 @@ struct TreeCreatorElectronMLDDA { template void fillTrackTable(TCollision const& collision, TTrack const& track, const int pidlabel, const int tracktype, const bool isForValidation) { + if (store_ele_band_only && !isElectron(track)) { + return; + } + 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); diff --git a/PWGEM/Dilepton/Tasks/createResolutionMap.cxx b/PWGEM/Dilepton/Tasks/createResolutionMap.cxx index 8070c41ac61..557c3468be2 100644 --- a/PWGEM/Dilepton/Tasks/createResolutionMap.cxx +++ b/PWGEM/Dilepton/Tasks/createResolutionMap.cxx @@ -32,6 +32,7 @@ #include "Common/DataModel/Centrality.h" #include "Common/DataModel/CollisionAssociationTables.h" #include "Common/Core/trackUtilities.h" +#include "Common/CCDB/RCTSelectionFlags.h" #include "CCDB/BasicCCDBManager.h" #include "DataFormatsParameters/GRPMagField.h" @@ -45,6 +46,7 @@ #include "MCHTracking/TrackParam.h" #include "ReconstructionDataFormats/TrackFwd.h" #include "PWGEM/Dilepton/Utils/MCUtilities.h" +#include "Common/Core/fwdtrackUtilities.h" using namespace o2; using namespace o2::framework; @@ -52,17 +54,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,7 +68,7 @@ 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"}; @@ -87,8 +81,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.5f, +0.5f}, "deta bins for output histograms"}; + ConfigurableAxis ConfDeltaPhiBins{"ConfDeltaPhiBins", {200, -0.5f, +0.5f}, "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 +123,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_min_nclusters_MFT{"cfg_min_nclusters_MFT", 5, "min nclusters MFT"}; + Configurable cfg_min_nclusters_MCH{"min_min_nclusters_MCH", 5, "min nclusters MCH"}; + 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"}; } 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 +195,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; @@ -193,18 +215,22 @@ struct CreateResolutionMap { 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); + 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 +383,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 +432,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; + } + + 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; + } - // 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()); + 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 +509,173 @@ 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); + } 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 (muon.nClusters() < muoncuts.cfg_min_ncluster_mch) { + return; } - if (rAtAbsorberEnd < muoncuts.cfg_min_rabs || muoncuts.cfg_max_rabs < rAtAbsorberEnd) { + if (!isSelectedMuon(pt, eta, rAtAbsorberEnd, pDCA, muon.chi2(), muon.trackType(), dcaXY)) { return; } - if (rAtAbsorberEnd < 26.5) { - if (muon.pDca() > 594.f) { + 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; } SliceCache cache; @@ -581,9 +691,15 @@ struct CreateResolutionMap { 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 +711,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 +723,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); @@ -649,7 +774,7 @@ struct CreateResolutionMap { 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; } @@ -662,7 +787,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); @@ -683,7 +808,7 @@ struct CreateResolutionMap { 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; @@ -697,9 +822,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); @@ -722,14 +847,14 @@ struct CreateResolutionMap { 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; } 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; } @@ -741,9 +866,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); @@ -764,7 +889,7 @@ struct CreateResolutionMap { 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; 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..3f991854956 100644 --- a/PWGHF/Core/HfHelper.h +++ b/PWGHF/Core/HfHelper.h @@ -17,13 +17,15 @@ #ifndef PWGHF_CORE_HFHELPER_H_ #define PWGHF_CORE_HFHELPER_H_ -#include +#include +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) -#include "Math/GenVector/Boost.h" -#include "Math/Vector4D.h" -#include +#include +#include -#include "CommonConstants/PhysicsConstants.h" +#include +#include +#include #include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelectorPID.h" diff --git a/PWGHF/Core/HfMlResponseXic0ToXiPiKf.h b/PWGHF/Core/HfMlResponseXic0ToXiPiKf.h new file mode 100644 index 00000000000..d75bdcc4c10 --- /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 + +#include "PWGHF/Core/HfMlResponse.h" + +// 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..092210a22ca 100644 --- a/PWGHF/D2H/DataModel/ReducedDataModel.h +++ b/PWGHF/D2H/DataModel/ReducedDataModel.h @@ -23,13 +23,19 @@ #ifndef PWGHF_D2H_DATAMODEL_REDUCEDDATAMODEL_H_ #define PWGHF_D2H_DATAMODEL_REDUCEDDATAMODEL_H_ +#include +#include + +#include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisDataModel.h" #include "Framework/ASoA.h" -#include "ReconstructionDataFormats/Track.h" -#include "ReconstructionDataFormats/Vertex.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" @@ -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..255de80a079 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..8a236412a13 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..1055c891092 100644 --- a/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx @@ -24,7 +24,6 @@ #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" diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx index 8eac85d1878..d03f8d9eda0 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx @@ -37,13 +37,14 @@ #include "Common/DataModel/Qvectors.h" #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/D2H/DataModel/ReducedDataModel.h" #include "PWGHF/Utils/utilsTrkCandHf.h" -#include "PWGHF/D2H/Utils/utilsRedDataFormat.h" using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx index 3dc7cdcb08c..a424d95d95b 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx @@ -21,9 +21,9 @@ #include #include -#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" @@ -39,8 +39,9 @@ #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/DataModel/ReducedDataModel.h" #include "PWGHF/D2H/Utils/utilsRedDataFormat.h" using namespace o2; @@ -73,26 +74,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 +117,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 +145,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 +166,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 +225,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 +269,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 +387,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 +454,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 +475,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 +595,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 +614,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 +655,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 +670,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 +718,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 +730,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 +743,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 +784,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 +793,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 +820,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 +832,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 +922,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 +956,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 +1060,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 +1089,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 +1254,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 +1310,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 +1320,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 +1333,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 +1389,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 +1401,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 +1445,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 +1463,20 @@ 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}; @@ -1171,22 +1485,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 = candsDplus.sliceBy(candsDplusPerCollision, thisCollId); - auto V0sThisColl = V0s.sliceBy(candsV0PerCollision, thisCollId); - runDataCreation(collision, candsDThisColl, V0sThisColl, tracks, particlesMc, bcs); + 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}; + 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); + 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 +1537,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 +1587,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 +1633,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 +1688,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 +1741,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 +1764,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 +1791,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 +1840,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..b650e5bd4f0 100644 --- a/PWGHF/D2H/Tasks/taskD0.cxx +++ b/PWGHF/D2H/Tasks/taskD0.cxx @@ -25,10 +25,11 @@ #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 "PWGHF/Utils/utilsAnalysis.h" +#include "PWGHF/Utils/utilsEvSelHf.h" using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/D2H/Tasks/taskDplus.cxx b/PWGHF/D2H/Tasks/taskDplus.cxx index e67ec0dfa69..cbf6118ce68 100644 --- a/PWGHF/D2H/Tasks/taskDplus.cxx +++ b/PWGHF/D2H/Tasks/taskDplus.cxx @@ -26,10 +26,11 @@ #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 "PWGHF/Utils/utilsAnalysis.h" +#include "PWGHF/Utils/utilsEvSelHf.h" 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/taskLc.cxx b/PWGHF/D2H/Tasks/taskLc.cxx index be75dc055bf..cf3c070e6b7 100644 --- a/PWGHF/D2H/Tasks/taskLc.cxx +++ b/PWGHF/D2H/Tasks/taskLc.cxx @@ -25,8 +25,9 @@ #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "PWGHF/Core/HfHelper.h" #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" @@ -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..5b379e9e759 100644 --- a/PWGHF/D2H/Tasks/taskLcToK0sP.cxx +++ b/PWGHF/D2H/Tasks/taskLcToK0sP.cxx @@ -24,6 +24,7 @@ #include "Framework/runDataProcessing.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/D2H/Tasks/taskOmegac0ToOmegapi.cxx b/PWGHF/D2H/Tasks/taskOmegac0ToOmegapi.cxx index 7142b2d2e49..2550d41c386 100644 --- a/PWGHF/D2H/Tasks/taskOmegac0ToOmegapi.cxx +++ b/PWGHF/D2H/Tasks/taskOmegac0ToOmegapi.cxx @@ -23,6 +23,7 @@ #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" @@ -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..dbdd51410ce 100644 --- a/PWGHF/D2H/Tasks/taskSigmacToCascade.cxx +++ b/PWGHF/D2H/Tasks/taskSigmacToCascade.cxx @@ -26,6 +26,7 @@ #include "Common/Core/TrackSelectionDefaults.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/D2H/Tasks/taskXic.cxx b/PWGHF/D2H/Tasks/taskXic.cxx index 00b513cd1a4..3ef874240ec 100644 --- a/PWGHF/D2H/Tasks/taskXic.cxx +++ b/PWGHF/D2H/Tasks/taskXic.cxx @@ -28,6 +28,7 @@ #include "Framework/runDataProcessing.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" @@ -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..1e49bb8649b 100644 --- a/PWGHF/D2H/Tasks/taskXicc.cxx +++ b/PWGHF/D2H/Tasks/taskXicc.cxx @@ -23,6 +23,7 @@ #include "Framework/HistogramRegistry.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" @@ -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..a083e9713b2 100644 --- a/PWGHF/D2H/Utils/utilsRedDataFormat.h +++ b/PWGHF/D2H/Utils/utilsRedDataFormat.h @@ -16,9 +16,14 @@ #ifndef PWGHF_D2H_UTILS_UTILSREDDATAFORMAT_H_ #define PWGHF_D2H_UTILS_UTILSREDDATAFORMAT_H_ -#include "Framework/HistogramRegistry.h" +#include + +#include #include "CCDB/BasicCCDBManager.h" +#include "Framework/AnalysisHelpers.h" +#include "Framework/HistogramRegistry.h" + #include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/Utils/utilsEvSelHf.h" diff --git a/PWGHF/DataModel/CandidateReconstructionTables.h b/PWGHF/DataModel/CandidateReconstructionTables.h index 41b5ccbf905..014bfa3e32e 100644 --- a/PWGHF/DataModel/CandidateReconstructionTables.h +++ b/PWGHF/DataModel/CandidateReconstructionTables.h @@ -18,23 +18,24 @@ #ifndef PWGHF_DATAMODEL_CANDIDATERECONSTRUCTIONTABLES_H_ #define PWGHF_DATAMODEL_CANDIDATERECONSTRUCTIONTABLES_H_ -#include - -#include "Math/GenVector/Boost.h" -#include "Math/Vector4D.h" +#include +#include +#include -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/AnalysisDataModel.h" +#include +#include +#include #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 "PWGHF/Core/SelectorCuts.h" #include "PWGHF/Utils/utilsPid.h" +#include "PWGHF/Core/DecayChannels.h" // FIXME: temporary until propagated where needed 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..337abce14e0 100644 --- a/PWGHF/DataModel/DerivedTables.h +++ b/PWGHF/DataModel/DerivedTables.h @@ -16,17 +16,17 @@ #ifndef PWGHF_DATAMODEL_DERIVEDTABLES_H_ #define PWGHF_DATAMODEL_DERIVEDTABLES_H_ -#include +#include +#include -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoA.h" +#include +#include +#include #include "Common/Core/RecoDecay.h" - -#include "PWGLF/DataModel/mcCentrality.h" +#include "Common/DataModel/Centrality.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" namespace o2::aod { diff --git a/PWGHF/HFC/DataModel/CorrelationTables.h b/PWGHF/HFC/DataModel/CorrelationTables.h index 370f3738975..eaf0b4f3c4a 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 +#include // NOLINT +#include + +#include #include "Common/Core/RecoDecay.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" // NOLINT 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..73b07c61e83 100644 --- a/PWGHF/HFC/Macros/DhCorrelationExtraction.h +++ b/PWGHF/HFC/Macros/DhCorrelationExtraction.h @@ -17,22 +17,16 @@ #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..a4bdf3c3bb1 100644 --- a/PWGHF/HFC/Macros/DhCorrelationFitter.h +++ b/PWGHF/HFC/Macros/DhCorrelationFitter.h @@ -19,10 +19,9 @@ #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..cffe8b898c2 100644 --- a/PWGHF/HFC/TableProducer/correlatorD0D0bar.cxx +++ b/PWGHF/HFC/TableProducer/correlatorD0D0bar.cxx @@ -25,6 +25,7 @@ #include "Common/DataModel/TrackSelectionTables.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" diff --git a/PWGHF/HFC/TableProducer/correlatorD0D0barBarrelFullPid.cxx b/PWGHF/HFC/TableProducer/correlatorD0D0barBarrelFullPid.cxx index f92f8150abc..9e090a49c57 100644 --- a/PWGHF/HFC/TableProducer/correlatorD0D0barBarrelFullPid.cxx +++ b/PWGHF/HFC/TableProducer/correlatorD0D0barBarrelFullPid.cxx @@ -25,6 +25,7 @@ #include "Common/DataModel/TrackSelectionTables.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" diff --git a/PWGHF/HFC/TableProducer/correlatorD0Hadrons.cxx b/PWGHF/HFC/TableProducer/correlatorD0Hadrons.cxx index 7b6517f29dc..f2a7afc6bdc 100644 --- a/PWGHF/HFC/TableProducer/correlatorD0Hadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorD0Hadrons.cxx @@ -29,6 +29,7 @@ #include "Common/DataModel/TrackSelectionTables.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" diff --git a/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx b/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx index ef5791fadc8..ee0ab36ce91 100644 --- a/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx @@ -27,6 +27,7 @@ #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" diff --git a/PWGHF/HFC/TableProducer/correlatorDplusDminus.cxx b/PWGHF/HFC/TableProducer/correlatorDplusDminus.cxx index 2871d9f9793..3cbee2b072a 100644 --- a/PWGHF/HFC/TableProducer/correlatorDplusDminus.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDplusDminus.cxx @@ -25,6 +25,7 @@ #include "Common/DataModel/TrackSelectionTables.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" @@ -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..a1a8941779b 100644 --- a/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx @@ -27,6 +27,7 @@ #include "Common/DataModel/TrackSelectionTables.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" @@ -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..2b9ea57bfd5 100644 --- a/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx @@ -15,6 +15,7 @@ /// \author Samuele Cattaruzzi #include +#include #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" @@ -28,6 +29,7 @@ #include "Common/DataModel/TrackSelectionTables.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" @@ -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..d005659cc69 100644 --- a/PWGHF/HFC/TableProducer/correlatorDsHadronsReduced.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDsHadronsReduced.cxx @@ -20,6 +20,7 @@ #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/HFC/DataModel/CorrelationTables.h" #include "PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h" diff --git a/PWGHF/HFC/TableProducer/correlatorLcHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorLcHadrons.cxx index 506f98073ef..c76ec3d62d2 100644 --- a/PWGHF/HFC/TableProducer/correlatorLcHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorLcHadrons.cxx @@ -32,6 +32,7 @@ #include "Common/DataModel/TrackSelectionTables.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" @@ -530,8 +531,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 +778,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 +944,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 +993,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..77c31d17969 --- /dev/null +++ b/PWGHF/HFC/TableProducer/correlatorLcScHadrons.cxx @@ -0,0 +1,1077 @@ +// 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 +#include "TRandom3.h" + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#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 "CommonConstants/MathConstants.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" + +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..93c0fecd90d 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationD0Hadrons.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationD0Hadrons.cxx @@ -23,6 +23,7 @@ #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" diff --git a/PWGHF/HFC/Tasks/taskCorrelationDDbar.cxx b/PWGHF/HFC/Tasks/taskCorrelationDDbar.cxx index b45ce1b4a63..f7b50def0a4 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationDDbar.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationDDbar.cxx @@ -20,6 +20,7 @@ #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.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/HFC/Tasks/taskCorrelationDplusHadrons.cxx b/PWGHF/HFC/Tasks/taskCorrelationDplusHadrons.cxx index 73d703ffde1..339ab91a27c 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationDplusHadrons.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationDplusHadrons.cxx @@ -12,15 +12,18 @@ /// \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" @@ -586,7 +589,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) { @@ -633,7 +636,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..3375d71b86d 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx @@ -24,6 +24,7 @@ #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" @@ -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..791dd045f99 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationLcHadrons.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationLcHadrons.cxx @@ -17,12 +17,14 @@ #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" @@ -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..90f7b8524d9 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 -#include "CommonConstants/PhysicsConstants.h" +#include + +#include +#include + +#include "CommonConstants/MathConstants.h" + +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/PIDResponseTOF.h" namespace o2::analysis::hf_correlations { diff --git a/PWGHF/HFL/DataModel/ElectronSelectionTable.h b/PWGHF/HFL/DataModel/ElectronSelectionTable.h index e590ee1d94d..477011950e2 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 // NOLINT +#include + +#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..48cc13b74c4 --- /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 + +#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 "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" + +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..d551922b7d5 100644 --- a/PWGHF/TableProducer/candidateCreator2Prong.cxx +++ b/PWGHF/TableProducer/candidateCreator2Prong.cxx @@ -43,13 +43,16 @@ #include "Common/Core/trackUtilities.h" #include "Tools/KFparticle/KFUtilities.h" +#include "PWGLF/DataModel/mcCentrality.h" + #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 "PWGHF/Utils/utilsMcGen.h" using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/TableProducer/candidateCreator3Prong.cxx b/PWGHF/TableProducer/candidateCreator3Prong.cxx index 426c42c5771..145e84513db 100644 --- a/PWGHF/TableProducer/candidateCreator3Prong.cxx +++ b/PWGHF/TableProducer/candidateCreator3Prong.cxx @@ -43,7 +43,10 @@ #include "Common/Core/trackUtilities.h" #include "Tools/KFparticle/KFUtilities.h" +#include "PWGLF/DataModel/mcCentrality.h" + #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" @@ -52,10 +55,10 @@ #include "PWGHF/Utils/utilsTrkCandHf.h" 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 +953,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 +982,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 +993,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 +1009,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 +1026,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 +1061,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..b60e5e63a72 100644 --- a/PWGHF/TableProducer/candidateCreatorB0.cxx +++ b/PWGHF/TableProducer/candidateCreatorB0.cxx @@ -30,11 +30,12 @@ #include "Common/DataModel/CollisionAssociationTables.h" #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 "PWGHF/Utils/utilsMcGen.h" +#include "PWGHF/Utils/utilsTrkCandHf.h" using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/TableProducer/candidateCreatorBplus.cxx b/PWGHF/TableProducer/candidateCreatorBplus.cxx index f1d306cad12..fea1a2778b4 100644 --- a/PWGHF/TableProducer/candidateCreatorBplus.cxx +++ b/PWGHF/TableProducer/candidateCreatorBplus.cxx @@ -33,11 +33,12 @@ #include "Common/DataModel/CollisionAssociationTables.h" #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 "PWGHF/Utils/utilsMcGen.h" +#include "PWGHF/Utils/utilsTrkCandHf.h" using namespace o2; using namespace o2::analysis; diff --git a/PWGHF/TableProducer/candidateCreatorBs.cxx b/PWGHF/TableProducer/candidateCreatorBs.cxx index 5ce38797762..4f8128e474b 100644 --- a/PWGHF/TableProducer/candidateCreatorBs.cxx +++ b/PWGHF/TableProducer/candidateCreatorBs.cxx @@ -30,6 +30,7 @@ #include "Common/DataModel/CollisionAssociationTables.h" #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" diff --git a/PWGHF/TableProducer/candidateCreatorCascade.cxx b/PWGHF/TableProducer/candidateCreatorCascade.cxx index 25c7a343849..04faa873da7 100644 --- a/PWGHF/TableProducer/candidateCreatorCascade.cxx +++ b/PWGHF/TableProducer/candidateCreatorCascade.cxx @@ -33,7 +33,10 @@ #include "Common/Core/trackUtilities.h" +#include "PWGLF/DataModel/mcCentrality.h" + #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" 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..c8dbbf04b2b 100644 --- a/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx +++ b/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx @@ -36,6 +36,7 @@ #include "Common/Core/TrackSelectionDefaults.h" #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 @@ -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..ee784c35fae 100644 --- a/PWGHF/TableProducer/candidateCreatorSigmac0plusplusCascade.cxx +++ b/PWGHF/TableProducer/candidateCreatorSigmac0plusplusCascade.cxx @@ -26,6 +26,7 @@ #include "Common/Core/TrackSelectionDefaults.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx b/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx index b8d114a6583..754272af541 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) @@ -54,6 +55,7 @@ #include "Tools/KFparticle/KFUtilities.h" #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/mcCentrality.h" #include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/Core/SelectorCuts.h" @@ -242,16 +244,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 +268,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 +726,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 +741,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 +1203,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 +1219,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 +1692,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); - } - 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); + 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 +1751,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 +1810,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..69fea11d5c9 100644 --- a/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx +++ b/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx @@ -47,13 +47,13 @@ #include "Tools/KFparticle/KFUtilities.h" #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/mcCentrality.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/Utils/utilsBfieldCCDB.h" #include "PWGHF/Utils/utilsEvSelHf.h" 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..ae0102b33fe 100644 --- a/PWGHF/TableProducer/candidateSelectorD0.cxx +++ b/PWGHF/TableProducer/candidateSelectorD0.cxx @@ -27,6 +27,7 @@ #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" diff --git a/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx b/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx index 3efd7990991..5aa753b28d1 100644 --- a/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx @@ -26,6 +26,7 @@ #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" diff --git a/PWGHF/TableProducer/candidateSelectorDsToKKPi.cxx b/PWGHF/TableProducer/candidateSelectorDsToKKPi.cxx index b1aad60b510..9196ce735de 100644 --- a/PWGHF/TableProducer/candidateSelectorDsToKKPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorDsToKKPi.cxx @@ -26,6 +26,7 @@ #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" 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/candidateSelectorLcToK0sP.cxx b/PWGHF/TableProducer/candidateSelectorLcToK0sP.cxx index 7095fc2b8a1..53df1ed2dfe 100644 --- a/PWGHF/TableProducer/candidateSelectorLcToK0sP.cxx +++ b/PWGHF/TableProducer/candidateSelectorLcToK0sP.cxx @@ -29,6 +29,7 @@ #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" diff --git a/PWGHF/TableProducer/candidateSelectorOmegac0ToOmegaPi.cxx b/PWGHF/TableProducer/candidateSelectorOmegac0ToOmegaPi.cxx index 14ca3d917d0..24cb43ca348 100644 --- a/PWGHF/TableProducer/candidateSelectorOmegac0ToOmegaPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorOmegac0ToOmegaPi.cxx @@ -28,7 +28,7 @@ #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" @@ -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..81327bb70e1 100644 --- a/PWGHF/TableProducer/candidateSelectorXic0ToXiPiKf.cxx +++ b/PWGHF/TableProducer/candidateSelectorXic0ToXiPiKf.cxx @@ -12,6 +12,10 @@ /// \file candidateSelectorXic0ToXiPiKf.cxx /// \brief Xic0 → Xi Pi selection task /// \author Ran Tu , Fudan University +/// \author Tao Fang , Central China Normal University + +#include +#include #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" @@ -20,6 +24,9 @@ #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectorPID.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" @@ -39,6 +46,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 +124,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 +203,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 +225,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 +544,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..578cb27876d 100644 --- a/PWGHF/TableProducer/candidateSelectorXiccToPKPiPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorXiccToPKPiPi.cxx @@ -23,6 +23,7 @@ #include "Common/Core/TrackSelectorPID.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" 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..0f98525ceb1 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -50,6 +50,7 @@ #include "PWGLF/DataModel/LFStrangenessTables.h" #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" 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..7a8547cf32a 100644 --- a/PWGHF/TableProducer/treeCreatorDsToKKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorDsToKKPi.cxx @@ -17,6 +17,8 @@ /// \author Stefano Politanò , Politecnico & INFN, Torino /// \author Fabio Catalano , CERN +#include + #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" @@ -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..5ad144e472e 100644 --- a/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx @@ -410,7 +410,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) @@ -917,7 +917,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(); 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..5792492c39c 100644 --- a/PWGHF/TableProducer/treeCreatorOmegacSt.cxx +++ b/PWGHF/TableProducer/treeCreatorOmegacSt.cxx @@ -9,14 +9,16 @@ // 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 #include @@ -45,6 +47,7 @@ #include "PWGLF/DataModel/LFStrangenessTables.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/Utils/utilsTrkCandHf.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" using namespace o2; using namespace o2::framework; @@ -67,6 +70,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 +86,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 +100,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 +114,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 +127,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 +146,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 +156,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 +170,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 +183,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 +202,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 +223,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 +237,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 +257,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 +282,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 +317,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 +348,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 +360,22 @@ 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 { + 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 +403,9 @@ struct HfTreeCreatorOmegacSt { decayLengthGen, decayLengthXYGen, decayLengthCascGen, - decayLengthXYCascGen); + decayLengthXYCascGen, + origin, + decayChannel); mapMcPartToGenTable[mcParticle.globalIndex()] = outputTableGen.lastIndex(); } } @@ -368,7 +417,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 +504,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 +530,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 +539,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 +558,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 +580,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 +604,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 +633,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 +702,8 @@ struct HfTreeCreatorOmegacSt { massV0, track.tpcNSigmaPi(), track.tofNSigmaPi(), + track.tpcNSigmaKa(), + track.tofNSigmaKa(), v0TrackPr.tpcNSigmaPr(), v0TrackPr.tofNSigmaPr(), v0TrackPi.tpcNSigmaPi(), @@ -607,7 +716,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 +748,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 +788,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 +857,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 +883,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 +904,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..87355a4590b 100644 --- a/PWGHF/TableProducer/treeCreatorXic0ToXiPiKf.cxx +++ b/PWGHF/TableProducer/treeCreatorXic0ToXiPiKf.cxx @@ -14,12 +14,15 @@ /// 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 "Common/Core/RecoDecay.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" @@ -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..274421f8093 100644 --- a/PWGHF/Tasks/taskLcCentrality.cxx +++ b/PWGHF/Tasks/taskLcCentrality.cxx @@ -25,6 +25,7 @@ #include "Common/DataModel/Centrality.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" @@ -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..01cac4a9028 100644 --- a/PWGHF/Tasks/taskMcEfficiencyToXiPi.cxx +++ b/PWGHF/Tasks/taskMcEfficiencyToXiPi.cxx @@ -26,6 +26,7 @@ #include "Common/Core/RecoDecay.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" @@ -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..269cd7b21ea 100644 --- a/PWGHF/Tasks/taskMcValidation.cxx +++ b/PWGHF/Tasks/taskMcValidation.cxx @@ -32,7 +32,10 @@ #include "CCDB/BasicCCDBManager.h" #include "Common/DataModel/CollisionAssociationTables.h" +#include "PWGLF/DataModel/mcCentrality.h" + #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" @@ -1103,21 +1106,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..ad3943a7134 100644 --- a/PWGHF/Tasks/taskPidStudies.cxx +++ b/PWGHF/Tasks/taskPidStudies.cxx @@ -27,6 +27,7 @@ #include "Framework/runDataProcessing.h" #include "Framework/HistogramRegistry.h" +#include "Common/CCDB/ctpRateFetcher.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/Multiplicity.h" @@ -98,11 +99,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 +134,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 +155,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 +176,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 +187,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 +268,7 @@ struct HfTaskPidStudies { coll.trackOccupancyInTimeRange(), coll.centFT0C(), coll.centFT0M(), + interactionRate, flag); } else { const auto& bachTrack = candidate.template bachelor_as(); @@ -280,6 +290,7 @@ struct HfTaskPidStudies { coll.trackOccupancyInTimeRange(), coll.centFT0C(), coll.centFT0M(), + interactionRate, flag); } } @@ -328,6 +339,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..583e25fd01c 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..23c08d3ac3c 100644 --- a/PWGHF/Utils/utilsDerivedData.h +++ b/PWGHF/Utils/utilsDerivedData.h @@ -16,19 +16,18 @@ #ifndef PWGHF_UTILS_UTILSDERIVEDDATA_H_ #define PWGHF_UTILS_UTILSDERIVEDDATA_H_ -#include -#include +#include -#include "fairlogger/Logger.h" +#include +#include +#include -#include "Framework/AnalysisHelpers.h" -#include "Framework/Configurable.h" -#include "Framework/ASoA.h" +#include +#include +#include #include "Common/Core/RecoDecay.h" -#include "PWGHF/DataModel/DerivedTables.h" - // Macro to store nSigma for prong _id_ with PID hypothesis _hyp_ in an array #define GET_N_SIGMA_PRONG(_array_, _candidate_, _id_, _hyp_) \ _array_[0] = _candidate_.nSigTpc##_hyp_##_id_(); \ diff --git a/PWGHF/Utils/utilsEvSelHf.h b/PWGHF/Utils/utilsEvSelHf.h index 4103cd517de..5d57ffb5eff 100644 --- a/PWGHF/Utils/utilsEvSelHf.h +++ b/PWGHF/Utils/utilsEvSelHf.h @@ -18,19 +18,28 @@ #ifndef PWGHF_UTILS_UTILSEVSELHF_H_ #define PWGHF_UTILS_UTILSEVSELHF_H_ +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include #include // std::shared_ptr #include // std::string -#include "Framework/Configurable.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/HistogramSpec.h" -#include "Framework/OutputObjHeader.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" namespace o2::hf_occupancy diff --git a/PWGHF/Utils/utilsMcGen.h b/PWGHF/Utils/utilsMcGen.h index 863d7041102..73dac888c8e 100644 --- a/PWGHF/Utils/utilsMcGen.h +++ b/PWGHF/Utils/utilsMcGen.h @@ -17,14 +17,18 @@ #ifndef PWGHF_UTILS_UTILSMCGEN_H_ #define PWGHF_UTILS_UTILSMCGEN_H_ -#include - +#include #include -#include "CommonConstants/PhysicsConstants.h" +#include + +#include +#include +#include #include "Common/Core/RecoDecay.h" +#include "PWGHF/Core/DecayChannels.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" namespace hf_mc_gen @@ -82,6 +86,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 +96,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 +111,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 +121,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 +147,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 +177,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..3289e60c737 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 + +#include + +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" + 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..94fa2084370 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..57731df23ba 100644 --- a/PWGJE/DataModel/Jet.h +++ b/PWGJE/DataModel/Jet.h @@ -35,6 +35,7 @@ #include "PWGHF/DataModel/DerivedTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/V0SelectorTables.h" #include "PWGDQ/DataModel/ReducedInfoTables.h" namespace o2::aod @@ -244,8 +245,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..9d0ff6789b3 100644 --- a/PWGJE/JetFinders/jetFinder.cxx +++ b/PWGJE/JetFinders/jetFinder.cxx @@ -15,14 +15,35 @@ /// \author Jochen Klein /// \author Raymond Ehlers , ORNL +#include +#include +#include +#include +#include +#include +#include +#include +#include // IWYU pragma: keep (needed in tasks) + +#include +#include #include -#include "PWGJE/Core/JetFindingUtilities.h" +#include +#include + +#include +#include + #include "PWGJE/Core/JetDerivedDataUtilities.h" -#include "Framework/runDataProcessing.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" 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..68a874e2955 100644 --- a/PWGJE/JetFinders/jetFinderHF.cxx +++ b/PWGJE/JetFinders/jetFinderHF.cxx @@ -14,22 +14,38 @@ /// \author Nima Zardoshti /// \author Jochen Klein +#include +#include +#include +#include +#include +#include +#include +#include +#include // IWYU pragma: keep (needed in tasks) + +#include #include -#include "CommonConstants/PhysicsConstants.h" +#include +#include + +#include +#include -#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" 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..ece753369d9 100644 --- a/PWGJE/JetFinders/jetFinderV0.cxx +++ b/PWGJE/JetFinders/jetFinderV0.cxx @@ -13,22 +13,36 @@ // /// \author Nima Zardoshti +#include +#include +#include +#include +#include +#include +#include +#include +#include // IWYU pragma: keep (needed in tasks) + +#include #include -#include "CommonConstants/PhysicsConstants.h" +#include +#include + +#include +#include -#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" 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 bf72e3275d6..1c1261827de 100644 --- a/PWGJE/TableProducer/emcalCorrectionTask.cxx +++ b/PWGJE/TableProducer/emcalCorrectionTask.cxx @@ -18,28 +18,42 @@ /// \author Raymond Ehlers (raymond.ehlers@cern.ch) ORNL, Florian Jonas (florian.jonas@cern.ch) /// -#include +#include +#include +#include +#include #include +#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/AnalysisTask.h" +#include "Framework/AnalysisHelpers.h" #include "Framework/ASoA.h" +#include "Framework/Configurable.h" +#include "Framework/Expressions.h" +#include "Framework/HistogramSpec.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/InitContext.h" +#include "Framework/WorkflowSpec.h" #include "DetectorsBase/GeometryManager.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 "DataFormatsEMCAL/ClusterLabel.h" #include "DataFormatsEMCAL/Cell.h" #include "DataFormatsEMCAL/CellLabel.h" #include "DataFormatsEMCAL/Constants.h" @@ -49,7 +63,9 @@ #include "EMCALBase/NonlinearityHandler.h" #include "EMCALReconstruction/Clusterizer.h" #include "PWGJE/Core/JetUtilities.h" +#include "GPUROOTCartesianFwd.h" #include "TVector2.h" +#include "TH1.h" using namespace o2; using namespace o2::framework; @@ -97,6 +113,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; @@ -126,6 +143,11 @@ struct EmcalCorrectionTask { // EMCal geometry o2::emcal::Geometry* geometry; + std::vector> mExtraTimeShiftRunRanges; + + // Current run number + int runNumber{0}; + void init(InitContext const&) { LOG(debug) << "Start init!"; @@ -201,22 +223,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}}); @@ -246,10 +272,26 @@ 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 + // Affected run ranges (inclusive) are initialised here (min,max) + mExtraTimeShiftRunRanges.emplace_back(535365, 535645); // LHC23g-LHC23h + mExtraTimeShiftRunRanges.emplace_back(535725, 536126); // LHC23h-LHC23l + mExtraTimeShiftRunRanges.emplace_back(536199, 536202); // LHC23l-LHC23m + mExtraTimeShiftRunRanges.emplace_back(536239, 536346); // LHC23m-LHC23n + mExtraTimeShiftRunRanges.emplace_back(536565, 536590); // Commisioning-LHC23r + mExtraTimeShiftRunRanges.emplace_back(542280, 543854); // LHC23zv-LHC23zy + mExtraTimeShiftRunRanges.emplace_back(559544, 559856); // PbPb 2024 } // void process(aod::Collision const& collision, soa::Filtered const& fullTracks, aod::Calos const& cells) @@ -268,6 +310,10 @@ struct EmcalCorrectionTask { std::unordered_map numberCellsInBC; // Number of cells mapped to the global BC index of all BCs to check whether EMCal was readout for (const auto& bc : bcs) { LOG(debug) << "Next BC"; + + // get run number + runNumber = bc.runNumber(); + // Convert aod::Calo to o2::emcal::Cell which can be used with the clusterizer. // In particular, we need to filter only EMCAL cells. @@ -297,7 +343,7 @@ struct EmcalCorrectionTask { } cellsBC.emplace_back(cell.cellNumber(), amplitude, - cell.time() + getCellTimeShift(cell.cellNumber(), amplitude, o2::emcal::intToChannelType(cell.cellType())), + cell.time() + getCellTimeShift(cell.cellNumber(), amplitude, o2::emcal::intToChannelType(cell.cellType()), runNumber), o2::emcal::intToChannelType(cell.cellType())); cellIndicesBC.emplace_back(cell.globalIndex()); } @@ -342,7 +388,7 @@ struct EmcalCorrectionTask { // Store the clusters in the table where a matching collision could // be identified. - fillClusterTable(col, vertexPos, iClusterizer, cellIndicesBC, indexMapPair, trackGlobalIndex); + fillClusterTable(col, vertexPos, iClusterizer, cellIndicesBC, &indexMapPair, &trackGlobalIndex); } else { mHistManager.fill(HIST("hBCMatchErrors"), 2); } @@ -396,6 +442,9 @@ struct EmcalCorrectionTask { // Convert aod::Calo to o2::emcal::Cell which can be used with the clusterizer. // In particular, we need to filter only EMCAL cells. + // get run number + runNumber = bc.runNumber(); + // Get the collisions matched to the BC using foundBCId of the collision auto collisionsInFoundBC = collisions.sliceBy(collisionsPerFoundBC, bc.globalIndex()); auto cellsInBC = cells.sliceBy(mcCellsPerFoundBC, bc.globalIndex()); @@ -425,7 +474,7 @@ struct EmcalCorrectionTask { } cellsBC.emplace_back(cell.cellNumber(), amplitude, - cell.time() + getCellTimeShift(cell.cellNumber(), amplitude, o2::emcal::intToChannelType(cell.cellType())), + cell.time() + getCellTimeShift(cell.cellNumber(), amplitude, o2::emcal::intToChannelType(cell.cellType()), runNumber), o2::emcal::intToChannelType(cell.cellType())); cellIndicesBC.emplace_back(cell.globalIndex()); cellLabels.emplace_back(cell.mcParticleIds(), cell.amplitudeA()); @@ -470,7 +519,7 @@ struct EmcalCorrectionTask { // Store the clusters in the table where a matching collision could // be identified. - fillClusterTable(col, vertexPos, iClusterizer, cellIndicesBC, indexMapPair, trackGlobalIndex); + fillClusterTable(col, vertexPos, iClusterizer, cellIndicesBC, &indexMapPair, &trackGlobalIndex); } else { mHistManager.fill(HIST("hBCMatchErrors"), 2); } @@ -514,6 +563,7 @@ struct EmcalCorrectionTask { int previousCollisionId = 0; // Collision ID of the last unique BC. Needed to skip unordered collisions to ensure ordered collisionIds in the cluster table int nBCsProcessed = 0; int nCellsProcessed = 0; + for (const auto& bc : bcs) { LOG(debug) << "Next BC"; // Convert aod::Calo to o2::emcal::Cell which can be used with the clusterizer. @@ -521,6 +571,10 @@ struct EmcalCorrectionTask { // Get the collisions matched to the BC using global bc index of the collision // since we do not have event selection available here! + + // get run number + runNumber = bc.runNumber(); + auto collisionsInBC = collisions.sliceBy(collisionsPerBC, bc.globalIndex()); auto cellsInBC = cells.sliceBy(cellsPerFoundBC, bc.globalIndex()); @@ -536,7 +590,7 @@ struct EmcalCorrectionTask { for (const auto& cell : cellsInBC) { cellsBC.emplace_back(cell.cellNumber(), cell.amplitude(), - cell.time() + getCellTimeShift(cell.cellNumber(), cell.amplitude(), o2::emcal::intToChannelType(cell.cellType())), + cell.time() + getCellTimeShift(cell.cellNumber(), cell.amplitude(), o2::emcal::intToChannelType(cell.cellType()), runNumber), o2::emcal::intToChannelType(cell.cellType())); cellIndicesBC.emplace_back(cell.globalIndex()); } @@ -598,7 +652,7 @@ struct EmcalCorrectionTask { } PROCESS_SWITCH(EmcalCorrectionTask, processStandalone, "run stand alone analysis", false); - void cellsToCluster(size_t iClusterizer, const gsl::span cellsBC, std::optional> cellLabels = std::nullopt) + void cellsToCluster(size_t iClusterizer, const gsl::span cellsBC, gsl::span cellLabels = {}) { mClusterizers.at(iClusterizer)->findClusters(cellsBC); @@ -614,10 +668,10 @@ struct EmcalCorrectionTask { mClusterFactories.reset(); // in preparation for future O2 changes // mClusterFactories.setClusterizerSettings(mClusterDefinitions.at(iClusterizer).minCellEnergy, mClusterDefinitions.at(iClusterizer).timeMin, mClusterDefinitions.at(iClusterizer).timeMax, mClusterDefinitions.at(iClusterizer).recalcShowerShape5x5); - if (cellLabels) { - mClusterFactories.setContainer(*emcalClusters, cellsBC, *emcalClustersInputIndices, cellLabels); - } else { + if (cellLabels.empty()) { mClusterFactories.setContainer(*emcalClusters, cellsBC, *emcalClustersInputIndices); + } else { + mClusterFactories.setContainer(*emcalClusters, cellsBC, *emcalClustersInputIndices, cellLabels); } LOG(debug) << "Cluster factory set up."; @@ -634,24 +688,33 @@ struct EmcalCorrectionTask { } template - void fillClusterTable(Collision const& col, math_utils::Point3D const& vertexPos, size_t iClusterizer, const gsl::span cellIndicesBC, std::optional>, std::vector>>> const& indexMapPair = std::nullopt, std::optional> const& trackGlobalIndex = std::nullopt) + void fillClusterTable(Collision const& col, math_utils::Point3D const& vertexPos, size_t iClusterizer, const gsl::span cellIndicesBC, const std::tuple>, std::vector>>* indexMapPair = nullptr, const std::vector* trackGlobalIndex = nullptr) { + // average number of cells per cluster, only used the reseve a reasonable amount for the clustercells table + const size_t NAvgNcells = 3; // we found a collision, put the clusters into the none ambiguous table clusters.reserve(mAnalysisClusters.size()); - if (mClusterLabels.size() > 0) { + if (!mClusterLabels.empty()) { mcclusters.reserve(mClusterLabels.size()); } + clustercells.reserve(mAnalysisClusters.size() * NAvgNcells); + + // get the clusterType once + const auto clusterType = static_cast(mClusterDefinitions[iClusterizer]); + int cellindex = -1; unsigned int iCluster = 0; + float energy = 0.f; for (const auto& cluster : mAnalysisClusters) { + energy = cluster.E(); // Determine the cluster eta, phi, correcting for the vertex position. auto pos = cluster.getGlobalPosition(); pos = pos - vertexPos; // Normalize the vector and rescale by energy. - pos *= (cluster.E() / std::sqrt(pos.Mag2())); + pos *= (energy / std::sqrt(pos.Mag2())); // Correct for nonlinear behaviour - float nonlinCorrEnergy = cluster.E(); + float nonlinCorrEnergy = energy; if (!disableNonLin) { try { nonlinCorrEnergy = mNonlinearityHandler.getCorrectedClusterEnergy(cluster); @@ -662,19 +725,18 @@ struct EmcalCorrectionTask { // save to table LOG(debug) << "Writing cluster definition " - << static_cast(mClusterDefinitions.at(iClusterizer)) + << clusterType << " to table."; mHistManager.fill(HIST("hClusterType"), 1); - clusters(col, cluster.getID(), nonlinCorrEnergy, cluster.getCoreEnergy(), cluster.E(), + clusters(col, cluster.getID(), nonlinCorrEnergy, cluster.getCoreEnergy(), energy, pos.Eta(), TVector2::Phi_0_2pi(pos.Phi()), cluster.getM02(), cluster.getM20(), cluster.getNCells(), cluster.getClusterTime(), cluster.getIsExotic(), cluster.getDistanceToBadChannel(), cluster.getNExMax(), - static_cast(mClusterDefinitions.at(iClusterizer))); - if (mClusterLabels.size() > 0) { + clusterType); + if (!mClusterLabels.empty()) { mcclusters(mClusterLabels[iCluster].getLabels(), mClusterLabels[iCluster].getEnergyFractions()); } - clustercells.reserve(cluster.getNCells()); // loop over cells in cluster and save to table for (int ncell = 0; ncell < cluster.getNCells(); ncell++) { cellindex = cluster.getCellIndex(ncell); @@ -682,10 +744,16 @@ struct EmcalCorrectionTask { clustercells(clusters.lastIndex(), cellIndicesBC[cellindex]); } // end of cells of cluser loop // fill histograms - mHistManager.fill(HIST("hClusterE"), cluster.E()); + mHistManager.fill(HIST("hClusterE"), energy); 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) { @@ -701,20 +769,25 @@ struct EmcalCorrectionTask { template void fillAmbigousClusterTable(BC const& bc, size_t iClusterizer, const gsl::span cellIndicesBC, bool hasCollision) { + // average number of cells per cluster, only used the reseve a reasonable amount for the clustercells table + const size_t NAvgNcells = 3; int cellindex = -1; clustersAmbiguous.reserve(mAnalysisClusters.size()); if (mClusterLabels.size() > 0) { mcclustersAmbiguous.reserve(mClusterLabels.size()); } + clustercellsambiguous.reserve(mAnalysisClusters.size() * NAvgNcells); unsigned int iCluster = 0; + float energy = 0.f; for (const auto& cluster : mAnalysisClusters) { + energy = cluster.E(); auto pos = cluster.getGlobalPosition(); pos = pos - math_utils::Point3D{0., 0., 0.}; // Normalize the vector and rescale by energy. - pos *= (cluster.E() / std::sqrt(pos.Mag2())); + pos *= (energy / std::sqrt(pos.Mag2())); // Correct for nonlinear behaviour - float nonlinCorrEnergy = cluster.E(); + float nonlinCorrEnergy = energy; try { nonlinCorrEnergy = mNonlinearityHandler.getCorrectedClusterEnergy(cluster); } catch (o2::emcal::NonlinearityHandler::UninitException& e) { @@ -723,14 +796,14 @@ struct EmcalCorrectionTask { // We have our necessary properties. Now we store outputs - // LOG(debug) << "Cluster E: " << cluster.E(); + // LOG(debug) << "Cluster E: " << energy; if (!hasCollision) { mHistManager.fill(HIST("hClusterType"), 0); } else { mHistManager.fill(HIST("hClusterType"), 2); } clustersAmbiguous( - bc, cluster.getID(), nonlinCorrEnergy, cluster.getCoreEnergy(), cluster.E(), + bc, cluster.getID(), nonlinCorrEnergy, cluster.getCoreEnergy(), energy, pos.Eta(), TVector2::Phi_0_2pi(pos.Phi()), cluster.getM02(), cluster.getM20(), cluster.getNCells(), cluster.getClusterTime(), cluster.getIsExotic(), cluster.getDistanceToBadChannel(), @@ -738,7 +811,6 @@ struct EmcalCorrectionTask { if (mClusterLabels.size() > 0) { mcclustersAmbiguous(mClusterLabels[iCluster].getLabels(), mClusterLabels[iCluster].getEnergyFractions()); } - clustercellsambiguous.reserve(cluster.getNCells()); for (int ncell = 0; ncell < cluster.getNCells(); ncell++) { cellindex = cluster.getCellIndex(ncell); clustercellsambiguous(clustersAmbiguous.lastIndex(), @@ -873,7 +945,7 @@ struct EmcalCorrectionTask { // Apply shift of the cell time in data and MC // In MC this has to be done to shift the cell time, which is not calibrated to 0 due to the flight time of the particles to the EMCal surface (~15ns) // In data this is done to correct for the time walk effect - float getCellTimeShift(const int16_t cellID, const float cellEnergy, const emcal::ChannelType_t cellType) + float getCellTimeShift(const int16_t cellID, const float cellEnergy, const emcal::ChannelType_t cellType, const int runNumber) { if (!applyCellTimeCorrection) { return 0.f; @@ -909,6 +981,14 @@ struct EmcalCorrectionTask { else // Very high energy regime timeshift = 1.9; // Parameters extracted from LHC24aj (pp), but also usable for other periods } + // Temporary extra shift for bug in time calibraiton of apass4 Pb-Pb 2024, requires pos shift of 2*8.8 ns for low gain cells + if (cellType == emcal::ChannelType_t::LOW_GAIN) { + for (const auto& range : mExtraTimeShiftRunRanges) { + if (runNumber >= range.first && runNumber <= range.second) { + timeshift += 2 * 8.8; + } + } + } LOG(debug) << "Shift the cell time by " << timeshift << " + " << timesmear << " ns"; } return timeshift + timesmear; 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..40e233f9a90 100644 --- a/PWGJE/Tasks/fullJetSpectraPP.cxx +++ b/PWGJE/Tasks/fullJetSpectra.cxx @@ -8,14 +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. - -// 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 +#include +#include #include "CommonConstants/PhysicsConstants.h" #include "Framework/ASoA.h" @@ -25,6 +27,7 @@ #include "Framework/O2DatabasePDGPlugin.h" #include "Framework/runDataProcessing.h" #include "Framework/RunningWorkflowInfo.h" +#include "Framework/Logger.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" @@ -51,12 +54,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 +96,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 +112,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 +122,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 +232,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 +288,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 +326,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 +351,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 +390,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 +443,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 +485,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 +493,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 +505,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 +527,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 +563,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 +599,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 +624,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 +636,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 +669,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 +724,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 +742,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); + + // DEBUG: Let's verify what collision IDs we're actually seeing + LOGF(info, "[MCD DEBUG] Processing MC collision ID: %lld", collision.mcCollisionId()); - registry.fill(HIST("h_Detcollision_counter"), 0.5); - if (fabs(collision.posZ()) > VertexZCut) { + // 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 +820,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 +838,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); - 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, 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 +914,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 +929,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); + + // 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); // 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 +1038,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)); - registry.fill(HIST("h_Partcollision_counter"), 0.5); - if (fabs(mccollision.posZ()) > VertexZCut) { + /* 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)); + + // 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 +1148,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 +1240,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); + + // 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); - registry.fill(HIST("h_Matchedcollision_counter"), 0.5); - if (fabs(collision.posZ()) > VertexZCut) { // making double sure this condition is satisfied + // 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 +1335,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 +1364,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); - void processTracks(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, soa::Filtered const& clusters) + float totalEvents = mcdCount + mcpCount; // MCP and Matched should be the same, so don't double count + float actualSplitFrac = totalEvents > 0 ? mcdCount / totalEvents : 0.0f; + + 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("h_collisions_unweighted"), 0.5); - if (fabs(collision.posZ()) > VertexZCut) { + registry.fill(HIST("hCollisionsUnweighted"), 0.5); // allDetColl + if (std::fabs(collision.posZ()) > vertexZCut) { return; } - registry.fill(HIST("h_collisions_unweighted"), 1.5); + 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; } // 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 +1444,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 +1452,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 +1526,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 +1537,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 +1601,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 +1624,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 +1667,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 +1679,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 +1699,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 +1741,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(FullJetSpectrapp, processMBCollisionsWithMultiplicity, "MB Collisions for Full Jets Multiplicity Studies", false); + 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(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..d06405f1a32 100644 --- a/PWGLF/TableProducer/Nuspex/hypKfRecoTask.cxx +++ b/PWGLF/TableProducer/Nuspex/hypKfRecoTask.cxx @@ -16,6 +16,7 @@ #include #include #include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" @@ -39,10 +40,14 @@ #include "PWGLF/DataModel/LFHypernucleiKfTables.h" #include "TRandom3.h" #include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/TableProducer/PID/pidTPCBase.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "ReconstructionDataFormats/PID.h" +#include "MetadataHelper.h" // 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 +59,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 +154,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 +173,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 +218,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 +336,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 +349,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 +386,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 +450,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 +464,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 +475,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 +484,7 @@ struct HypKfRecoTask { void init(InitContext const&) { + isMC = false; mRunNumber = 0; dBz = 0; rand.SetSeed(0); @@ -456,18 +494,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 +563,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 +582,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 +652,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 +757,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 +783,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 +868,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 +882,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 +910,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 +930,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 +970,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 +978,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 +1002,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 +1027,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 +1064,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 +1083,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 +1107,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 +1130,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 +1143,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 +1153,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 +1195,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 +1216,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 +1297,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 +1333,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 +1346,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 +1361,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..9f700dd8405 100644 --- a/PWGLF/TableProducer/Nuspex/hyperhelium4sigmaRecoTask.cxx +++ b/PWGLF/TableProducer/Nuspex/hyperhelium4sigmaRecoTask.cxx @@ -13,8 +13,10 @@ /// \brief QA and analysis task for hyper-helium4sigma (He4S) /// \author Yuanzhe Wang -#include #include +#include +#include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -22,12 +24,19 @@ #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 "CommonConstants/PhysicsConstants.h" #include "PWGLF/DataModel/LFKinkDecayTables.h" #include "PWGLF/DataModel/LFHyperhelium4sigmaTables.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsBase/GeometryManager.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; @@ -39,10 +48,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 +142,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 +220,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 +233,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 +252,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 +421,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 +444,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 +592,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 +626,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 +675,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 +799,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 +813,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 +850,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 +868,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 +881,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 +917,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..205c0eda0a4 100644 --- a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx +++ b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx @@ -41,7 +41,6 @@ #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 "DataFormatsParameters/GRPMagField.h" @@ -267,12 +266,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 +280,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 +296,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 +325,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 +511,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 +557,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 +654,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 +811,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 +932,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 +940,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 +953,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 +962,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 +981,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 592c992f0ac..a33295b6021 100644 --- a/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx +++ b/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx @@ -110,13 +110,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 - + {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; @@ -135,22 +136,24 @@ class Particle float mass; int charge; float resolution; + float chargeFactor; std::vector betheParams; - static constexpr int kNumBetheParams = 5; + 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 betheParams.clear(); - for (int i = 0; i < kNumBetheParams; ++i) { + for (int i = 0; i < NNumBetheParams; ++i) { betheParams.push_back(bethe.get(name, i)); } } @@ -213,7 +216,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)"}; @@ -294,7 +297,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, @@ -366,10 +369,11 @@ struct TrHeAnalysis { histos.fill(HIST("histogram/pT"), track.pt()); histos.fill(HIST("histogram/p"), track.p()); histos.fill(HIST("histogram/TPCsignVsTPCmomentum"), - getRigidity(track), + getRigidity(track) * track.sign(), track.tpcSignal()); histos.fill(HIST("histogram/TOFbetaVsP"), - getRigidity(track), track.beta()); + getRigidity(track) * track.sign(), + track.beta()); if (enableTr && trRapCut) { if (std::abs(getTPCnSigma(track, particles.at(0))) < nsigmaTPCvar.nsigmaTPCTr) { @@ -386,22 +390,23 @@ 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; } histos.fill(HIST("histogram/H3/H3-TPCsignVsTPCmomentum"), - getRigidity(track), + getRigidity(track) * track.sign(), track.tpcSignal()); histos.fill(HIST("histogram/H3/H3-TOFbetaVsP"), - getRigidity(track), track.beta()); + getRigidity(track) * track.sign(), + track.beta()); float tPt = track.pt(); float tEta = track.eta(); 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(); @@ -437,17 +442,18 @@ struct TrHeAnalysis { continue; } histos.fill(HIST("histogram/He/He-TPCsignVsTPCmomentum"), - getRigidity(track), + getRigidity(track) * track.sign(), track.tpcSignal()); histos.fill(HIST("histogram/He/He-TOFbetaVsP"), - getRigidity(track), track.beta()); + getRigidity(track) * track.sign(), + track.beta()); float tPt = track.pt(); float tEta = track.eta(); 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(); @@ -520,10 +526,10 @@ struct TrHeAnalysis { histos.fill(HIST("histogram/pT"), track.pt()); histos.fill(HIST("histogram/p"), track.p()); histos.fill(HIST("histogram/TPCsignVsTPCmomentum"), - getRigidity(track) / (1.f * track.sign()), + getRigidity(track) * (1.f * track.sign()), track.tpcSignal()); histos.fill(HIST("histogram/TOFbetaVsP"), - track.p() / (1.f * track.sign()), track.beta()); + track.p() * (1.f * track.sign()), track.beta()); if (enableTr && trRapCut) { if (std::abs(track.tpcNSigmaTr()) < nsigmaTPCvar.nsigmaTPCTr) { if (track.itsChi2NCl() > cfgCutMaxChi2ItsH3) { @@ -539,22 +545,23 @@ 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; } histos.fill(HIST("histogram/H3/H3-TPCsignVsTPCmomentum"), - getRigidity(track) / (1.f * track.sign()), + getRigidity(track) * (1.f * track.sign()), track.tpcSignal()); histos.fill(HIST("histogram/H3/H3-TOFbetaVsP"), - track.p() / (1.f * track.sign()), track.beta()); + track.p() * (1.f * track.sign()), + track.beta()); float tPt = track.pt(); float tEta = track.eta(); float tPhi = track.phi(); 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(); @@ -589,17 +596,18 @@ struct TrHeAnalysis { continue; } histos.fill(HIST("histogram/He/He-TPCsignVsTPCmomentum"), - getRigidity(track), + getRigidity(track) * track.sign(), track.tpcSignal()); histos.fill(HIST("histogram/He/He-TOFbetaVsP"), - getRigidity(track), track.beta()); + getRigidity(track) * track.sign(), + track.beta()); float tPt = track.pt(); float tEta = track.eta(); float tPhi = track.phi(); 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(); @@ -629,26 +637,35 @@ 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 kNumLayers = 8; - constexpr int kBitsPerLayer = 4; - constexpr int kBitMask = (1 << kBitsPerLayer) - 1; + constexpr int NNumLayers = 8; + constexpr int NBitsPerLayer = 4; + constexpr int NBitMask = (1 << NBitsPerLayer) - 1; int sum = 0, n = 0; - for (int i = 0; i < kNumLayers; i++) { - int clsSize = (track.itsClusterSizes() >> (kBitsPerLayer * i)) & kBitMask; + for (int i = 0; i < NNumLayers; i++) { + int clsSize = (track.itsClusterSizes() >> (NBitsPerLayer * i)) & NBitMask; sum += clsSize; if (clsSize) n++; @@ -663,6 +680,15 @@ 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(T const& track) + { + 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)); + return mass; + } }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/TableProducer/Strangeness/CMakeLists.txt b/PWGLF/TableProducer/Strangeness/CMakeLists.txt index 6d9f2c04646..2b8a1d37438 100644 --- a/PWGLF/TableProducer/Strangeness/CMakeLists.txt +++ b/PWGLF/TableProducer/Strangeness/CMakeLists.txt @@ -111,6 +111,11 @@ o2physics_add_dpl_workflow(strangenessbuilder PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DCAFitter KFParticle::KFParticle O2Physics::TPCDriftManager COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(strangenessbuildertester + SOURCES strangenessbuildertester.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DCAFitter KFParticle::KFParticle O2Physics::TPCDriftManager + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(v0-selector SOURCES v0selector.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore 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..61f9e2f5086 100644 --- a/PWGLF/TableProducer/Strangeness/hStrangeCorrelationFilter.cxx +++ b/PWGLF/TableProducer/Strangeness/hStrangeCorrelationFilter.cxx @@ -30,7 +30,7 @@ #include "Common/DataModel/Centrality.h" #include "CCDB/BasicCCDBManager.h" #include "TF1.h" -#include "string" +#include #include #include "EventFiltering/Zorro.h" 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/TableProducer/Strangeness/strangenessbuildertester.cxx b/PWGLF/TableProducer/Strangeness/strangenessbuildertester.cxx index 0d7afc0990a..b2a1f5bd96a 100644 --- a/PWGLF/TableProducer/Strangeness/strangenessbuildertester.cxx +++ b/PWGLF/TableProducer/Strangeness/strangenessbuildertester.cxx @@ -40,6 +40,7 @@ #include "DataFormatsCalibration/MeanVertexObject.h" #include "CommonConstants/GeomConstants.h" #include "PWGLF/Utils/strangenessBuilderModule.h" +#include "Common/Tools/TrackPropagationModule.h" #include "Common/Tools/StandardCCDBLoader.h" // The Run 3 AO2D stores the tracks at the point of innermost update. For a track with ITS this is the innermost (or second innermost) @@ -85,6 +86,11 @@ struct StrangenessBuilderTester { o2::pwglf::strangenessbuilder::preSelectOpts preSelectOpts; o2::pwglf::strangenessbuilder::BuilderModule strangenessBuilderModule; + // track propagation + o2::common::TrackPropagationProducts trackPropagationProducts; + o2::common::TrackPropagationConfigurables trackPropagationConfigurables; + o2::common::TrackPropagationModule trackPropagation; + // registry HistogramRegistry histos{"histos"}; @@ -96,41 +102,42 @@ struct StrangenessBuilderTester { ccdb->setURL(ccdburl.value); // task-specific + trackPropagation.init(trackPropagationConfigurables, histos, initContext); strangenessBuilderModule.init(baseOpts, v0BuilderOpts, cascadeBuilderOpts, preSelectOpts, histos, initContext); } void processRealData(soa::Join const& collisions, aod::V0s const& v0s, aod::Cascades const& cascades, aod::TrackedCascades const& trackedCascades, FullTracksExtIU const& tracks, aod::BCsWithTimestamps const& bcs) { ccdbLoader.initCCDBfromBCs(standardCCDBLoaderConfigurables, ccdb, bcs); + trackPropagation.fillTrackTables(trackPropagationConfigurables, ccdbLoader, collisions, tracks, trackPropagationProducts, histos); strangenessBuilderModule.dataProcess(ccdb, histos, collisions, static_cast(nullptr), v0s, cascades, trackedCascades, tracks, bcs, static_cast(nullptr), products); } void processMonteCarlo(soa::Join const& collisions, aod::McCollisions const& mccollisions, aod::V0s const& v0s, aod::Cascades const& cascades, aod::TrackedCascades const& trackedCascades, FullTracksExtLabeledIU const& tracks, aod::BCsWithTimestamps const& bcs, aod::McParticles const& mcParticles) { ccdbLoader.initCCDBfromBCs(standardCCDBLoaderConfigurables, ccdb, bcs); + trackPropagation.fillTrackTables(trackPropagationConfigurables, ccdbLoader, collisions, tracks, trackPropagationProducts, histos); strangenessBuilderModule.dataProcess(ccdb, histos, collisions, mccollisions, v0s, cascades, trackedCascades, tracks, bcs, mcParticles, products); } void processRealDataWithPID(soa::Join const& collisions, aod::V0s const& v0s, aod::Cascades const& cascades, aod::TrackedCascades const& trackedCascades, FullTracksExtIUWithPID const& tracks, aod::BCsWithTimestamps const& bcs) { ccdbLoader.initCCDBfromBCs(standardCCDBLoaderConfigurables, ccdb, bcs); + trackPropagation.fillTrackTables(trackPropagationConfigurables, ccdbLoader, collisions, tracks, trackPropagationProducts, histos); strangenessBuilderModule.dataProcess(ccdb, histos, collisions, static_cast(nullptr), v0s, cascades, trackedCascades, tracks, bcs, static_cast(nullptr), products); } void processMonteCarloWithPID(soa::Join const& collisions, aod::McCollisions const& mccollisions, aod::V0s const& v0s, aod::Cascades const& cascades, aod::TrackedCascades const& trackedCascades, FullTracksExtLabeledIUWithPID const& tracks, aod::BCsWithTimestamps const& bcs, aod::McParticles const& mcParticles) { ccdbLoader.initCCDBfromBCs(standardCCDBLoaderConfigurables, ccdb, bcs); + trackPropagation.fillTrackTables(trackPropagationConfigurables, ccdbLoader, collisions, tracks, trackPropagationProducts, histos); strangenessBuilderModule.dataProcess(ccdb, histos, collisions, mccollisions, v0s, cascades, trackedCascades, tracks, bcs, mcParticles, products); } PROCESS_SWITCH(StrangenessBuilderTester, processRealData, "process real data", true); - PROCESS_SWITCH(StrangenessBuilderTester, processRealDataRun2, "process real data (Run 2)", false); PROCESS_SWITCH(StrangenessBuilderTester, processMonteCarlo, "process monte carlo", false); - PROCESS_SWITCH(StrangenessBuilderTester, processMonteCarloRun2, "process monte carlo (Run 2)", false); PROCESS_SWITCH(StrangenessBuilderTester, processRealDataWithPID, "process real data", false); - PROCESS_SWITCH(StrangenessBuilderTester, processRealDataRun2WithPID, "process real data (Run 2)", false); PROCESS_SWITCH(StrangenessBuilderTester, processMonteCarloWithPID, "process monte carlo", false); - PROCESS_SWITCH(StrangenessBuilderTester, processMonteCarloRun2WithPID, "process monte carlo (Run 2)", false); }; //**************************************************************************************** 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..20e1604e206 100644 --- a/PWGLF/Tasks/Nuspex/angularCorrelationsInJets.cxx +++ b/PWGLF/Tasks/Nuspex/angularCorrelationsInJets.cxx @@ -19,6 +19,7 @@ #include #include #include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -66,7 +67,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 +123,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 +138,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 +149,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 +160,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 +222,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 +314,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 +421,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 +451,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 +463,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 +474,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 +505,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 +517,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 +528,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 +541,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 +569,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 +596,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 +620,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 +652,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 +672,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 +689,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 +712,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 +763,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 +817,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 +841,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 +881,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 +944,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 +957,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 +991,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 +1033,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 +1053,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 +1109,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 +1346,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/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..3acfbad4d10 100644 --- a/PWGLF/Tasks/Strangeness/lambdaJetpolarization.cxx +++ b/PWGLF/Tasks/Strangeness/lambdaJetpolarization.cxx @@ -27,6 +27,7 @@ #include #include #include +#include "TProfile2D.h" #include "PWGLF/DataModel/lambdaJetpolarization.h" #include @@ -53,13 +54,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 +95,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 +112,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 +135,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 +219,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 +253,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,6 +314,40 @@ 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; @@ -655,6 +708,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 +779,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 +850,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 +974,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 +984,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 +999,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 +1069,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 +1084,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 +1132,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 +1146,6 @@ struct LfMyV0s { if (!AcceptEvent(collision)) { return; } - registryData.fill(HIST("hNEvents"), 8.5); int V0NumbersPerEvent = 0; int V0NumbersPerEventsel = 0; @@ -1087,6 +1213,94 @@ 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()); + double PLambda = sqrt(v0.px() * v0.px() + v0.py() * v0.py() + v0.pz() * v0.pz()); + double ELambda = sqrt(v0.mLambda() * v0.mLambda() + PLambda * PLambda); + double protonE = sqrt(massPr * massPr + pos.px() * pos.px() + pos.py() * pos.py() + pos.pz() * pos.pz()); + TMatrixD pLabV0(4, 1); + pLabV0(0, 0) = ELambda; + pLabV0(1, 0) = v0.px(); + pLabV0(2, 0) = v0.py(); + pLabV0(3, 0) = v0.pz(); + + TMatrixD pLabproton(4, 1); + pLabproton(0, 0) = protonE; + pLabproton(1, 0) = pos.px(); + pLabproton(2, 0) = pos.py(); + pLabproton(3, 0) = pos.pz(); + + TMatrixD V0InV0(4, 1); + V0InV0 = LorentzTransInV0frame(ELambda, v0.px(), v0.py(), v0.pz()) * pLabV0; + registryLongitudinalPolarization.fill(HIST("V0pxInRest_frame"), V0InV0(1, 0)); + registryLongitudinalPolarization.fill(HIST("V0pyInRest_frame"), V0InV0(2, 0)); + registryLongitudinalPolarization.fill(HIST("V0pzInRest_frame"), V0InV0(3, 0)); + + TMatrixD protonInV0(4, 1); + protonInV0 = LorentzTransInV0frame(ELambda, v0.px(), v0.py(), v0.pz()) * pLabproton; + double protonPInV0 = sqrt(protonInV0(1, 0) * protonInV0(1, 0) + protonInV0(2, 0) * protonInV0(2, 0) + protonInV0(3, 0) * protonInV0(3, 0)); + + double protonCosThetainV0 = protonInV0(3, 0) / protonPInV0; + + 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()); + + double PLambda = sqrt(v0.px() * v0.px() + v0.py() * v0.py() + v0.pz() * v0.pz()); + double ELambda = sqrt(v0.mAntiLambda() * v0.mAntiLambda() + PLambda * PLambda); + double protonE = sqrt(massPr * massPr + neg.px() * neg.px() + neg.py() * neg.py() + neg.pz() * neg.pz()); + + TMatrixD pLabproton(4, 1); + pLabproton(0, 0) = protonE; + pLabproton(1, 0) = neg.px(); + pLabproton(2, 0) = neg.py(); + pLabproton(3, 0) = neg.pz(); + + TMatrixD protonInV0(4, 1); + protonInV0 = LorentzTransInV0frame(ELambda, v0.px(), v0.py(), v0.pz()) * pLabproton; + double protonPInV0 = sqrt(protonInV0(1, 0) * protonInV0(1, 0) + protonInV0(2, 0) * protonInV0(2, 0) + protonInV0(3, 0) * protonInV0(3, 0)); + + double protonCosThetainV0 = protonInV0(3, 0) / protonPInV0; + + 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 ad63fdfe27c..9badfb4b4ba 100644 --- a/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx +++ b/PWGLF/Tasks/Strangeness/taskLambdaSpinCorr.cxx @@ -16,6 +16,9 @@ #include #include +#include +#include +#include "Math/Vector2D.h" #include "Math/Vector3D.h" #include "Math/Vector4D.h" #include "Math/GenVector/Boost.h" @@ -45,11 +48,23 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using std::array; +using namespace o2::aod::rctsel; struct LfTaskLambdaSpinCorr { Service ccdb; + + 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; // mixing + Configurable cosCalculation{"cosCalculation", 1, "cos calculation"}; + Configurable mixingCombination{"mixingCombination", 1, "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"}; Configurable nMix{"nMix", 5, "number of event mixing"}; @@ -59,6 +74,8 @@ struct LfTaskLambdaSpinCorr { // fill output Configurable additionalEvSel{"additionalEvSel", false, "additionalEvSel"}; Configurable additionalEvSel3{"additionalEvSel3", false, "additionalEvSel3"}; + Configurable additionalEvSel4{"additionalEvSel4", false, "additionalEvSel4"}; + Configurable additionalEvSel5{"additionalEvSel5", false, "additionalEvSel5"}; Configurable fillGEN{"fillGEN", false, "filling generated histograms"}; Configurable fillQA{"fillQA", false, "filling QA histograms"}; @@ -103,14 +120,17 @@ struct LfTaskLambdaSpinCorr { ConfigurableAxis configthnAxisPol{"configthnAxisPol", {VARIABLE_WIDTH, -1.0, -0.6, -0.2, 0, 0.2, 0.4, 0.8}, "Pol"}; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - + RCTFlagsChecker rctChecker; void init(o2::framework::InitContext&) { + rctChecker.init(rctCut.cfgEvtRCTFlagCheckerLabel, rctCut.cfgEvtRCTFlagCheckerZDCCheck, rctCut.cfgEvtRCTFlagCheckerLimitAcceptAsBad); 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("hRDiff", "hRDiff", kTH1F, {{640, 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); histos.add("hSparseAntiLambdaAntiLambda", "hSparseAntiLambdaAntiLambda", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisInvMass, configthnAxisPol, configcentAxis, thnAxisInvMasspair}, true); @@ -237,8 +257,10 @@ struct LfTaskLambdaSpinCorr { double centrality, int datatype) { - auto particle1Dummy = ROOT::Math::PxPyPzMVector(particle1.Px(), particle1.Py(), particle1.Pz(), 1.115683); - auto particle2Dummy = ROOT::Math::PxPyPzMVector(particle2.Px(), particle2.Py(), particle2.Pz(), 1.115683); + // auto particle1Dummy = ROOT::Math::PxPyPzMVector(particle1.Px(), particle1.Py(), particle1.Pz(), 1.115683); + // auto particle2Dummy = ROOT::Math::PxPyPzMVector(particle2.Px(), particle2.Py(), particle2.Pz(), 1.115683); + auto particle1Dummy = ROOT::Math::PxPyPzMVector(particle1.Px(), particle1.Py(), particle1.Pz(), particle1.M()); + auto particle2Dummy = ROOT::Math::PxPyPzMVector(particle2.Px(), particle2.Py(), particle2.Pz(), particle2.M()); auto pairDummy = particle1Dummy + particle2Dummy; // auto pairParticle = particle1 + particle2; @@ -260,7 +282,18 @@ struct LfTaskLambdaSpinCorr { auto proton1LambdaRF = boostLambda1ToCM(proton1pairCM); auto proton2LambdaRF = boostLambda2ToCM(proton2pairCM); - double cosThetaDiff = proton1LambdaRF.Vect().Unit().Dot(proton2LambdaRF.Vect().Unit()); + 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 deltaR = TMath::Sqrt(TMath::Power(particle1.Eta() - particle2.Eta(), 2.0) + TMath::Power(particle1.Phi() - particle2.Phi(), 2.0)); if (datatype == 0) { if (tag1 && tag3) { @@ -395,17 +428,37 @@ struct LfTaskLambdaSpinCorr { void processData(EventCandidates::iterator const& collision, AllTrackCandidates const& /*tracks*/, ResoV0s const& V0s) { + 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] = getLambdaTags(v0, collision); @@ -482,6 +535,14 @@ struct LfTaskLambdaSpinCorr { { 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; @@ -492,26 +553,53 @@ struct LfTaskLambdaSpinCorr { if (additionalEvSel && (!collision1.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { continue; } - if (additionalEvSel3 && (!collision1.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision1.selection_bit(aod::evsel::kNoITSROFrameBorder))) { + 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(tracksPerCollisionV0, collision1.globalIndex()); auto groupV02 = V0s.sliceBy(tracksPerCollisionV0, collision1.globalIndex()); 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()) { @@ -542,9 +630,14 @@ struct LfTaskLambdaSpinCorr { if (postrack1.globalIndex() == postrack2.globalIndex() || negtrack1.globalIndex() == negtrack2.globalIndex()) { 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)); 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()) { @@ -560,13 +653,33 @@ struct LfTaskLambdaSpinCorr { if (lambdaTag1 != lambdaTag3 || aLambdaTag1 != aLambdaTag3) { continue; } - if (std::abs(t1.pt() - t3.pt()) > ptMix) { + // if (std::abs(t1.pt() - t3.pt()) > ptMix) { + // continue; + // } + // if (std::abs(t1.eta() - t3.eta()) > etaMix) { + // continue; + // } + // if (std::abs(t1.phi() - t3.phi()) > phiMix) { + // continue; + // } + auto mixPairSumPt = t3.pt() + t2.pt(); + auto mixPairR = TMath::Sqrt(TMath::Power(t3.phi() - t2.phi(), 2.0) + TMath::Power(t3.eta() - t2.eta(), 2.0)); + histos.fill(HIST("hPtDiff"), TMath::Abs(mixPairSumPt - samePairSumPt)); + histos.fill(HIST("hRDiff"), TMath::Abs(mixPairR - samePairR)); + if (mixingCombination == 0 && std::abs(t1.pt() - t3.pt()) > ptMix) { continue; } - if (std::abs(t1.eta() - t3.eta()) > etaMix) { + if (mixingCombination == 0 && std::abs(t1.eta() - t3.eta()) > etaMix) { continue; } - if (std::abs(t1.phi() - t3.phi()) > phiMix) { + if (mixingCombination == 0 && std::abs(t1.phi() - t3.phi()) > phiMix) { + continue; + } + + if (mixingCombination == 1 && std::abs(mixPairSumPt - samePairSumPt) > ptMix) { + continue; + } + if (mixingCombination == 1 && std::abs(mixPairR - samePairR) > etaMix) { continue; } if (lambdaTag2) { @@ -591,17 +704,17 @@ struct LfTaskLambdaSpinCorr { } 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; pairStatus[t3.index()][t2.index()] = true; // LOGF(info, "v0 id: (%d, %d)", t3.index(), t2.index()); if (pairfound) { diff --git a/PWGLF/Utils/strangenessBuilderModule.h b/PWGLF/Utils/strangenessBuilderModule.h index ad538a1f001..2c982acddee 100644 --- a/PWGLF/Utils/strangenessBuilderModule.h +++ b/PWGLF/Utils/strangenessBuilderModule.h @@ -10,7 +10,7 @@ // or submit itself to any jurisdiction. /// \file strangenessBuilderModule.h -/// \brief strangeness builder module +/// \brief strangeness builder module /// \author ALICE // simple checkers, but ensure 8 bit integers @@ -184,80 +184,80 @@ static constexpr float defaultOmMassWindowParameters[1][4] = {{1.43210e-03, 2.03 static constexpr float defaultLifetimeCuts[1][4] = {{20, 60, 40, 20}}; struct products : o2::framework::ProducesGroup { - //__________________________________________________ - // V0 tables - o2::framework::Produces v0indices; // standard part of V0Datas - o2::framework::Produces v0cores; // standard part of V0Datas - o2::framework::Produces v0covs; // for decay chain reco - - //__________________________________________________ - // cascade tables - o2::framework::Produces cascidx; // standard part of CascDatas - o2::framework::Produces kfcascidx; // standard part of KFCascDatas - o2::framework::Produces tracascidx; // standard part of TraCascDatas - o2::framework::Produces cascdata; // standard part of CascDatas - o2::framework::Produces kfcascdata; // standard part of KFCascDatas - o2::framework::Produces tracascdata; // standard part of TraCascDatas - o2::framework::Produces casccovs; // for decay chain reco - o2::framework::Produces kfcasccovs; // for decay chain reco - o2::framework::Produces tracasccovs; // for decay chain reco - - //__________________________________________________ - // interlink tables - o2::framework::Produces v0dataLink; // de-refs V0s -> V0Data - o2::framework::Produces cascdataLink; // de-refs Cascades -> CascData - o2::framework::Produces kfcascdataLink; // de-refs Cascades -> KFCascData - o2::framework::Produces tracascdataLink; // de-refs Cascades -> TraCascData - - //__________________________________________________ - // secondary auxiliary tables - o2::framework::Produces v0trackXs; // for decay chain reco - o2::framework::Produces cascTrackXs; // for decay chain reco - - //__________________________________________________ - // further auxiliary / optional if desired - o2::framework::Produces cascbb; - o2::framework::Produces v0daucovs; // covariances of daughter tracks - o2::framework::Produces v0daucovIUs; // covariances of daughter tracks - o2::framework::Produces v0dauPositions; // auxiliary debug information - o2::framework::Produces v0dauPositionsIU; // auxiliary debug information - o2::framework::Produces v0ivanovs; // information for Marian's tests - - //__________________________________________________ - // MC information: V0 - o2::framework::Produces v0labels; // MC labels for V0s - o2::framework::Produces v0mccores; // mc info storage - o2::framework::Produces v0CoreMCLabels; // interlink V0Cores -> V0MCCores - o2::framework::Produces v0mccollref; // references collisions from V0MCCores - - // MC information: Cascades - o2::framework::Produces casclabels; // MC labels for cascades - o2::framework::Produces kfcasclabels; // MC labels for KF cascades - o2::framework::Produces tracasclabels; // MC labels for tracked cascades - o2::framework::Produces bbtags; // bb tags (inv structure tagging in mc) - o2::framework::Produces cascmccores; // mc info storage - o2::framework::Produces cascCoreMClabels; // interlink CascCores -> CascMCCores - o2::framework::Produces cascmccollrefs; // references MC collisions from MC cascades - - //__________________________________________________ - // cascade interlinks - // FIXME: commented out until strangederivedbuilder adjusted accordingly - // o2::framework::Produces cascToTraRefs; // cascades -> tracked - // o2::framework::Produces cascToKFRefs; // cascades -> KF - // o2::framework::Produces traToCascRefs; // tracked -> cascades - // o2::framework::Produces kfToCascRefs; // KF -> cascades - - //__________________________________________________ - // Findable tags - o2::framework::Produces v0FoundTag; - o2::framework::Produces cascFoundTag; + //__________________________________________________ + // V0 tables + o2::framework::Produces v0indices; // standard part of V0Datas + o2::framework::Produces v0cores; // standard part of V0Datas + o2::framework::Produces v0covs; // for decay chain reco + + //__________________________________________________ + // cascade tables + o2::framework::Produces cascidx; // standard part of CascDatas + o2::framework::Produces kfcascidx; // standard part of KFCascDatas + o2::framework::Produces tracascidx; // standard part of TraCascDatas + o2::framework::Produces cascdata; // standard part of CascDatas + o2::framework::Produces kfcascdata; // standard part of KFCascDatas + o2::framework::Produces tracascdata; // standard part of TraCascDatas + o2::framework::Produces casccovs; // for decay chain reco + o2::framework::Produces kfcasccovs; // for decay chain reco + o2::framework::Produces tracasccovs; // for decay chain reco + + //__________________________________________________ + // interlink tables + o2::framework::Produces v0dataLink; // de-refs V0s -> V0Data + o2::framework::Produces cascdataLink; // de-refs Cascades -> CascData + o2::framework::Produces kfcascdataLink; // de-refs Cascades -> KFCascData + o2::framework::Produces tracascdataLink; // de-refs Cascades -> TraCascData + + //__________________________________________________ + // secondary auxiliary tables + o2::framework::Produces v0trackXs; // for decay chain reco + o2::framework::Produces cascTrackXs; // for decay chain reco + + //__________________________________________________ + // further auxiliary / optional if desired + o2::framework::Produces cascbb; + o2::framework::Produces v0daucovs; // covariances of daughter tracks + o2::framework::Produces v0daucovIUs; // covariances of daughter tracks + o2::framework::Produces v0dauPositions; // auxiliary debug information + o2::framework::Produces v0dauPositionsIU; // auxiliary debug information + o2::framework::Produces v0ivanovs; // information for Marian's tests + + //__________________________________________________ + // MC information: V0 + o2::framework::Produces v0labels; // MC labels for V0s + o2::framework::Produces v0mccores; // mc info storage + o2::framework::Produces v0CoreMCLabels; // interlink V0Cores -> V0MCCores + o2::framework::Produces v0mccollref; // references collisions from V0MCCores + + // MC information: Cascades + o2::framework::Produces casclabels; // MC labels for cascades + o2::framework::Produces kfcasclabels; // MC labels for KF cascades + o2::framework::Produces tracasclabels; // MC labels for tracked cascades + o2::framework::Produces bbtags; // bb tags (inv structure tagging in mc) + o2::framework::Produces cascmccores; // mc info storage + o2::framework::Produces cascCoreMClabels; // interlink CascCores -> CascMCCores + o2::framework::Produces cascmccollrefs; // references MC collisions from MC cascades + + //__________________________________________________ + // cascade interlinks + // FIXME: commented out until strangederivedbuilder adjusted accordingly + // o2::framework::Produces cascToTraRefs; // cascades -> tracked + // o2::framework::Produces cascToKFRefs; // cascades -> KF + // o2::framework::Produces traToCascRefs; // tracked -> cascades + // o2::framework::Produces kfToCascRefs; // KF -> cascades + + //__________________________________________________ + // Findable tags + o2::framework::Produces v0FoundTag; + o2::framework::Produces cascFoundTag; }; // strangenessBuilder: 1st-order configurables struct coreConfigurables : o2::framework::ConfigurableGroup { o2::framework::Configurable> enabledTables{"enabledTables", - {defaultParameters[0], nTables, nParameters, tableNames, parameterNames}, - "Produce this table: -1 for autodetect; otherwise, 0/1 is false/true"}; + {defaultParameters[0], nTables, nParameters, tableNames, parameterNames}, + "Produce this table: -1 for autodetect; otherwise, 0/1 is false/true"}; std::vector mEnabledTables; // Vector of enabled tables // first order deduplication implementation @@ -371,7 +371,7 @@ class BuilderModule // constructor } - // mass windows + // mass windows float getMassSigmaK0Short(float pt) { return preSelectOpts.massCutK0->get("constant") + pt * preSelectOpts.massCutK0->get("linear") + preSelectOpts.massCutK0->get("expoConstant") * TMath::Exp(-pt / preSelectOpts.massCutK0->get("expoRelax")); @@ -494,7 +494,7 @@ class BuilderModule std::vector ao2dV0toV0List; // index to relate v0s -> v0List std::vector v0Map; // index to relate v0List -> v0sFromCascades - // declaration of structs here + // declaration of structs here // (N.B.: will be invisible to the outside, create your own copies) o2::pwglf::strangenessbuilder::coreConfigurables baseOpts; o2::pwglf::strangenessbuilder::v0Configurables v0BuilderOpts; @@ -504,11 +504,11 @@ class BuilderModule template void init(TBaseConfigurables const& inputBaseOpts, TV0Configurables const& inputV0BuilderOpts, TCascadeConfigurables const& inputCascadeBuilderOpts, TPreSelOpts const& inputPreSelectOpts, THistoRegistry& histos, TInitContext& context) { - // read in configurations from the task where it's used + // read in configurations from the task where it's used // could be grouped even further, but should work baseOpts = inputBaseOpts; - v0BuilderOpts = inputV0BuilderOpts; - cascadeBuilderOpts = inputCascadeBuilderOpts; + v0BuilderOpts = inputV0BuilderOpts; + cascadeBuilderOpts = inputCascadeBuilderOpts; preSelectOpts = inputPreSelectOpts; // setup bookkeeping histogram @@ -679,11 +679,6 @@ class BuilderModule straHelper.cascadeselections.maxDaughterEta = cascadeBuilderOpts.maxDaughterEta; } - bool verifyMask(uint8_t bitmap, uint8_t mask) - { - return (bitmap & mask) == mask; - } - // for sorting template std::vector sort_indices(const std::vector& v, bool doSorting = false) @@ -773,7 +768,6 @@ class BuilderModule // } } - //__________________________________________________ template void prepareBuildingLists(THistoRegistry& histos, TCollisions const& collisions, TMCCollisions const& mcCollisions, TV0s const& v0s, TCascades const& cascades, TTracks const& tracks, TMCParticles const& mcParticles) @@ -1428,10 +1422,7 @@ class BuilderModule histos.fill(HIST("hPreselectionV0s"), maskV0Preselection); - if (!verifyMask(maskV0Preselection, selGamma) && - !verifyMask(maskV0Preselection, selK0Short) && - !verifyMask(maskV0Preselection, selLambda) && - !verifyMask(maskV0Preselection, selAntiLambda)) { + if (maskV0Preselection == 0) { products.v0dataLink(-1, -1); continue; } @@ -1991,10 +1982,7 @@ class BuilderModule histos.fill(HIST("hPreselectionCascades"), maskCascadePreselection); - if (!verifyMask(maskCascadePreselection, selXiMinus) && - !verifyMask(maskCascadePreselection, selXiPlus) && - !verifyMask(maskCascadePreselection, selOmegaMinus) && - !verifyMask(maskCascadePreselection, selOmegaPlus)) { + if (maskCascadePreselection == 0) { products.cascdataLink(-1); interlinks.cascadeToCascCores.push_back(-1); continue; 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 5bf47f2021b..0336638dade 100644 --- a/PWGMM/UE/Tasks/dedxAnalysis.cxx +++ b/PWGMM/UE/Tasks/dedxAnalysis.cxx @@ -20,7 +20,6 @@ #include "Common/DataModel/EventSelection.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" @@ -38,7 +37,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 { @@ -49,6 +48,16 @@ struct DedxAnalysis { OutputObjHandlingPolicy::AnalysisObject, true, true}; + // Constant values + static constexpr int kEtaIntervals = 8; + static constexpr int kParticlesType = 4; + float tpcCut = 0.6; + float pionMin = 0.35; + float pionMax = 0.45; + float elTofCut = 0.1; + float pionTofCut = 1.0; + float invMassCut = 0.01; + float invMassCutGamma = 0.0015; // Configurable Parameters // Tracks cuts @@ -59,6 +68,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"}; @@ -83,10 +94,11 @@ 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[4] = {"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[4] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; - static constexpr double EtaCut[9] = {-0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8}; + 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"}; + static constexpr double EtaCut[kEtaIntervals + 1] = {-0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8}; Configurable> calibrationFactorNeg{"calibrationFactorNeg", {50.4011, 50.4764, 50.186, 49.2955, 48.8222, 49.4273, 49.9292, 50.0556}, "negative calibration factors"}; 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}, ""}; @@ -105,6 +117,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; } @@ -113,7 +126,8 @@ struct DedxAnalysis { void init(InitContext const&) { - AxisSpec dedxAxis{100, 0.0, 100.0, "dE/dx MIP (a. u.)"}; + AxisSpec dedxAxis{100, 0.0, 100.0, "dE/dx (a. u.)"}; + AxisSpec ptAxis = {binP, "pT (GeV/c)"}; AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; AxisSpec pAxis = {binP, "#it{p}/Z (GeV/c)"}; if (calibrationMode) { @@ -167,8 +181,16 @@ struct DedxAnalysis { "hdEdx_vs_eta_vs_p_Pos_calibrated_TOF", "dE/dx", HistType::kTH3F, {{etaAxis}, {dedxAxis}, {pAxis}}); + // pt vs p + registryDeDx.add( + "hp_vs_pt_all_Neg", "p_vs_pT", HistType::kTH2F, + {{ptAxis}, {pAxis}}); + registryDeDx.add( + "hp_vs_pt_all_Pos", "p_vs_pT", HistType::kTH2F, + {{ptAxis}, {pAxis}}); + // De/Dx for ch and v0 particles - for (int i = 0; i < 4; ++i) { + for (int i = 0; i < kParticlesType; ++i) { registryDeDx.add(kDedxvsMomentumPos[i].data(), "dE/dx", HistType::kTH3F, {{pAxis}, {dedxAxis}, {etaAxis}}); registryDeDx.add(kDedxvsMomentumNeg[i].data(), "dE/dx", HistType::kTH3F, @@ -235,14 +257,14 @@ struct DedxAnalysis { if (!passedSingleTrackSelection(ntrack, collision)) return false; - if (ptrack.tpcInnerParam() > 0.6) { + if (ptrack.tpcInnerParam() > tpcCut) { if (!ptrack.hasTOF()) return false; if (std::abs(ptrack.tofNSigmaPi()) > nsigmaTOFmax) return false; } - if (ntrack.tpcInnerParam() > 0.6) { + if (ntrack.tpcInnerParam() > tpcCut) { if (!ntrack.hasTOF()) return false; if (std::abs(ntrack.tofNSigmaPi()) > nsigmaTOFmax) @@ -267,14 +289,14 @@ struct DedxAnalysis { if (!passedSingleTrackSelection(ntrack, collision)) return false; - if (ptrack.tpcInnerParam() > 0.6) { + if (ptrack.tpcInnerParam() > tpcCut) { if (!ptrack.hasTOF()) return false; if (std::abs(ptrack.tofNSigmaPr()) > nsigmaTOFmax) return false; } - if (ntrack.tpcInnerParam() > 0.6) { + if (ntrack.tpcInnerParam() > tpcCut) { if (!ntrack.hasTOF()) return false; if (std::abs(ntrack.tofNSigmaPi()) > nsigmaTOFmax) @@ -300,14 +322,14 @@ struct DedxAnalysis { if (!passedSingleTrackSelection(ntrack, collision)) return false; - if (ptrack.tpcInnerParam() > 0.6) { + if (ptrack.tpcInnerParam() > tpcCut) { if (!ptrack.hasTOF()) return false; if (std::abs(ptrack.tofNSigmaPi()) > nsigmaTOFmax) return false; } - if (ntrack.tpcInnerParam() > 0.6) { + if (ntrack.tpcInnerParam() > tpcCut) { if (!ntrack.hasTOF()) return false; if (std::abs(ntrack.tofNSigmaPr()) > nsigmaTOFmax) @@ -332,14 +354,14 @@ struct DedxAnalysis { if (!passedSingleTrackSelection(ntrack, collision)) return false; - if (ptrack.tpcInnerParam() > 0.6) { + if (ptrack.tpcInnerParam() > tpcCut) { if (!ptrack.hasTOF()) return false; if (std::abs(ptrack.tofNSigmaEl()) > nsigmaTOFmax) return false; } - if (ntrack.tpcInnerParam() > 0.6) { + if (ntrack.tpcInnerParam() > tpcCut) { if (!ntrack.hasTOF()) return false; if (std::abs(ntrack.tofNSigmaEl()) > nsigmaTOFmax) @@ -361,14 +383,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 < 0.0 || centrality > 100.0) - centrality = 1.0; - // Kaons for (const auto& trk : tracks) { @@ -382,7 +413,7 @@ struct DedxAnalysis { float signedP = trk.sign() * trk.tpcInnerParam(); // MIP calibration for pions - if (trk.tpcInnerParam() >= 0.35 && trk.tpcInnerParam() <= 0.45) { + if (trk.tpcInnerParam() >= pionMin && trk.tpcInnerParam() <= pionMax) { if (calibrationMode) { if (signedP < 0) { registryDeDx.fill(HIST("hdEdx_vs_eta_Neg_Pi"), trk.eta(), trk.tpcSignal()); @@ -391,7 +422,7 @@ struct DedxAnalysis { } } else { - for (int i = 0; i < 8; ++i) { + for (int i = 0; i < kEtaIntervals; ++i) { if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { if (signedP < 0) { registryDeDx.fill(HIST("hdEdx_vs_eta_Neg_calibrated_Pi"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i)); @@ -409,7 +440,7 @@ struct DedxAnalysis { registryDeDx.fill(HIST("hbeta_vs_p_Pos"), signedP, trk.beta()); } // Electrons from TOF - if (std::abs(trk.beta() - 1) < 0.1) { // beta cut + if (std::abs(trk.beta() - 1) < elTofCut) { // beta cut if (calibrationMode) { if (signedP < 0) { registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Neg_El"), trk.eta(), trk.tpcSignal(), std::abs(signedP)); @@ -417,7 +448,7 @@ struct DedxAnalysis { registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Pos_El"), trk.eta(), trk.tpcSignal(), signedP); } } else { - for (int i = 0; i < 8; ++i) { + for (int i = 0; i < kEtaIntervals; ++i) { if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { if (signedP < 0) { registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Neg_calibrated_El"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), std::abs(signedP)); @@ -429,7 +460,7 @@ struct DedxAnalysis { } } // pions from TOF - if (trk.beta() > 1. && trk.beta() < 1.05) { // beta cut + if (trk.beta() > pionTofCut && trk.beta() < pionTofCut + 0.05) { // beta cut if (calibrationMode) { if (signedP < 0) { registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Neg_TOF"), trk.eta(), trk.tpcSignal(), std::abs(signedP)); @@ -437,7 +468,7 @@ struct DedxAnalysis { registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Pos_TOF"), trk.eta(), trk.tpcSignal(), signedP); } } else { - for (int i = 0; i < 8; ++i) { + for (int i = 0; i < kEtaIntervals; ++i) { if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { if (signedP < 0) { registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Neg_calibrated_TOF"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), std::abs(signedP)); @@ -452,12 +483,14 @@ struct DedxAnalysis { registryDeDx.fill(HIST("hdEdx_vs_phi"), trk.phi(), trk.tpcSignal()); if (!calibrationMode) { - for (int i = 0; i < 8; ++i) { + for (int i = 0; i < kEtaIntervals; ++i) { if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { if (signedP > 0) { registryDeDx.fill(HIST(kDedxvsMomentumPos[0]), signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); + registryDeDx.fill(HIST("hp_vs_pt_all_Pos"), trk.pt(), signedP); } else { registryDeDx.fill(HIST(kDedxvsMomentumNeg[0]), std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); + registryDeDx.fill(HIST("hp_vs_pt_all_Neg"), trk.pt(), std::abs(signedP)); } } } @@ -506,11 +539,11 @@ struct DedxAnalysis { float invMass = std::sqrt((eNegPi + ePosPi) * (eNegPi + ePosPi) - ((pxNeg + pxPos) * (pxNeg + pxPos) + (pyNeg + pyPos) * (pyNeg + pyPos) + (pzNeg + pzPos) * (pzNeg + pzPos))); - if (std::abs(invMass - MassK0Short) > 0.01) { + if (std::abs(invMass - MassK0Short) > invMassCut) { continue; } - for (int i = 0; i < 8; ++i) { + for (int i = 0; i < kEtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(kDedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); } @@ -528,11 +561,11 @@ struct DedxAnalysis { float invMass = std::sqrt((eNegPi + ePosPr) * (eNegPi + ePosPr) - ((pxNeg + pxPos) * (pxNeg + pxPos) + (pyNeg + pyPos) * (pyNeg + pyPos) + (pzNeg + pzPos) * (pzNeg + pzPos))); - if (std::abs(invMass - MassLambda) > 0.01) { + if (std::abs(invMass - MassLambda) > invMassCut) { continue; } - for (int i = 0; i < 8; ++i) { + for (int i = 0; i < kEtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(kDedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); } @@ -550,11 +583,11 @@ struct DedxAnalysis { float invMass = std::sqrt((eNegPr + ePosPi) * (eNegPr + ePosPi) - ((pxNeg + pxPos) * (pxNeg + pxPos) + (pyNeg + pyPos) * (pyNeg + pyPos) + (pzNeg + pzPos) * (pzNeg + pzPos))); - if (std::abs(invMass - MassLambda) > 0.01) { + if (std::abs(invMass - MassLambda) > invMassCut) { continue; } - for (int i = 0; i < 8; ++i) { + for (int i = 0; i < kEtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(kDedxvsMomentumNeg[2]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); } @@ -572,11 +605,11 @@ struct DedxAnalysis { float invMass = std::sqrt((eNegEl + ePosEl) * (eNegEl + ePosEl) - ((pxNeg + pxPos) * (pxNeg + pxPos) + (pyNeg + pyPos) * (pyNeg + pyPos) + (pzNeg + pzPos) * (pzNeg + pzPos))); - if (std::abs(invMass - gammaMass) > 0.0015) { + if (std::abs(invMass - gammaMass) > invMassCutGamma) { continue; } - for (int i = 0; i < 8; ++i) { + for (int i = 0; i < kEtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { registryDeDx.fill(HIST(kDedxvsMomentumNeg[3]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); } diff --git a/PWGUD/AQC/udQC.cxx b/PWGUD/AQC/udQC.cxx index b3bc5198a0f..ddaf01338df 100644 --- a/PWGUD/AQC/udQC.cxx +++ b/PWGUD/AQC/udQC.cxx @@ -14,6 +14,7 @@ /// \author Paul Buehler, paul.buehler@oeaw.ac.at /// \since 04.05.2023 +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" @@ -191,8 +192,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 +254,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 +262,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 +287,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 +435,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 +527,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 +568,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 +683,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 +701,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 +735,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 +757,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..4288ef89e80 100644 --- a/PWGUD/Core/SGTrackSelector.h +++ b/PWGUD/Core/SGTrackSelector.h @@ -21,7 +21,7 @@ #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" #include "Framework/O2DatabasePDGPlugin.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/SGSelector.h" #include diff --git a/PWGUD/Core/UPCJpsiCentralBarrelCorrHelper.h b/PWGUD/Core/UPCJpsiCentralBarrelCorrHelper.h index 0857d6bab1d..955601495e6 100644 --- a/PWGUD/Core/UPCJpsiCentralBarrelCorrHelper.h +++ b/PWGUD/Core/UPCJpsiCentralBarrelCorrHelper.h @@ -19,7 +19,7 @@ #include #include #include "CommonConstants/MathConstants.h" -#include "random" +#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..6b0e37adca0 --- /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 + +#include "Framework/Logger.h" +#include "Framework/HistogramRegistry.h" +#include "CommonConstants/MathConstants.h" +#include "CommonConstants/PhysicsConstants.h" + +#include "PWGUD/Core/UPCTauCentralBarrelHelperRL.h" + +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..072ae2d961c 100644 --- a/PWGUD/Tasks/eventByevent.cxx +++ b/PWGUD/Tasks/eventByevent.cxx @@ -13,7 +13,7 @@ #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include #include diff --git a/PWGUD/Tasks/exclusivePentaquark.cxx b/PWGUD/Tasks/exclusivePentaquark.cxx index 95da9600f67..c63dc7fce68 100644 --- a/PWGUD/Tasks/exclusivePentaquark.cxx +++ b/PWGUD/Tasks/exclusivePentaquark.cxx @@ -11,7 +11,7 @@ #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include #include "TLorentzVector.h" diff --git a/PWGUD/Tasks/exclusivePhi.cxx b/PWGUD/Tasks/exclusivePhi.cxx index 8f764f2bfff..634d17a5d8e 100644 --- a/PWGUD/Tasks/exclusivePhi.cxx +++ b/PWGUD/Tasks/exclusivePhi.cxx @@ -13,7 +13,7 @@ #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include #include "TLorentzVector.h" diff --git a/PWGUD/Tasks/exclusivePhiLeptons.cxx b/PWGUD/Tasks/exclusivePhiLeptons.cxx index ea7e92f61dd..b212dd21723 100644 --- a/PWGUD/Tasks/exclusivePhiLeptons.cxx +++ b/PWGUD/Tasks/exclusivePhiLeptons.cxx @@ -12,7 +12,7 @@ #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include #include "TLorentzVector.h" diff --git a/PWGUD/Tasks/exclusivePhiLeptonsTrees.cxx b/PWGUD/Tasks/exclusivePhiLeptonsTrees.cxx index e1ef9b8f3b4..00abada06d4 100644 --- a/PWGUD/Tasks/exclusivePhiLeptonsTrees.cxx +++ b/PWGUD/Tasks/exclusivePhiLeptonsTrees.cxx @@ -12,7 +12,7 @@ #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include #include "TLorentzVector.h" diff --git a/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx b/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx index 238ecac1245..14ffcc415a4 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, @@ -512,7 +520,7 @@ struct ExclusiveRhoTo4Pi { 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 occupancyCut{"occupancyCut", 1000, "Occupancy Cut"}; Configurable pvCut{"pvCut", 1.0, "Use Only PV tracks"}; Configurable numPVContrib{"numPVContrib", 4, "Number of PV Contributors"}; @@ -837,7 +845,6 @@ 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; using UDCollisions = soa::Filtered>; // using UDCollision = UDCollisions::iterator; @@ -923,6 +930,18 @@ struct ExclusiveRhoTo4Pi { return; } + // 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; + } + // Selecting Events with net charge = 0 if (numPionMinusTracks == numPiMinus && numPiPlusTracks == numPiPlus) { @@ -964,7 +983,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(), @@ -1037,7 +1056,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(), @@ -1174,7 +1193,7 @@ struct ExclusiveRhoTo4Pi { 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; @@ -1303,7 +1322,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(), diff --git a/PWGUD/Tasks/exclusiveTwoProtons.cxx b/PWGUD/Tasks/exclusiveTwoProtons.cxx index 72032b06906..b7cf9b84004 100644 --- a/PWGUD/Tasks/exclusiveTwoProtons.cxx +++ b/PWGUD/Tasks/exclusiveTwoProtons.cxx @@ -11,7 +11,7 @@ #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include #include "TLorentzVector.h" diff --git a/PWGUD/Tasks/exclusiveTwoProtonsSG.cxx b/PWGUD/Tasks/exclusiveTwoProtonsSG.cxx index 0e0aa7c83dd..0ac54805c69 100644 --- a/PWGUD/Tasks/exclusiveTwoProtonsSG.cxx +++ b/PWGUD/Tasks/exclusiveTwoProtonsSG.cxx @@ -11,7 +11,7 @@ #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include #include "TLorentzVector.h" diff --git a/PWGUD/Tasks/polarisationRho.cxx b/PWGUD/Tasks/polarisationRho.cxx index 994c921a6df..c10e86baad6 100644 --- a/PWGUD/Tasks/polarisationRho.cxx +++ b/PWGUD/Tasks/polarisationRho.cxx @@ -11,7 +11,7 @@ #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include #include "TLorentzVector.h" diff --git a/PWGUD/Tasks/sgD0Analyzer.cxx b/PWGUD/Tasks/sgD0Analyzer.cxx index b5c35b9deec..58b01cbe281 100644 --- a/PWGUD/Tasks/sgD0Analyzer.cxx +++ b/PWGUD/Tasks/sgD0Analyzer.cxx @@ -17,7 +17,7 @@ #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" #include "Framework/O2DatabasePDGPlugin.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/SGSelector.h" #include "Common/DataModel/PIDResponse.h" diff --git a/PWGUD/Tasks/sgExclOmega.cxx b/PWGUD/Tasks/sgExclOmega.cxx index 3e24048e621..0a816e1dc0e 100644 --- a/PWGUD/Tasks/sgExclOmega.cxx +++ b/PWGUD/Tasks/sgExclOmega.cxx @@ -17,7 +17,7 @@ #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" #include "Framework/O2DatabasePDGPlugin.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/SGSelector.h" #include "Common/DataModel/PIDResponse.h" diff --git a/PWGUD/Tasks/sgExclusivePhi.cxx b/PWGUD/Tasks/sgExclusivePhi.cxx index 679d1677593..df10373e571 100644 --- a/PWGUD/Tasks/sgExclusivePhi.cxx +++ b/PWGUD/Tasks/sgExclusivePhi.cxx @@ -13,7 +13,7 @@ #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include #include "TLorentzVector.h" diff --git a/PWGUD/Tasks/sgExclusivePhiITSselections.cxx b/PWGUD/Tasks/sgExclusivePhiITSselections.cxx index 76c56e609f5..2d8bc72c0f6 100644 --- a/PWGUD/Tasks/sgExclusivePhiITSselections.cxx +++ b/PWGUD/Tasks/sgExclusivePhiITSselections.cxx @@ -13,7 +13,7 @@ #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include #include "TLorentzVector.h" diff --git a/PWGUD/Tasks/sgFourPiAnalyzer.cxx b/PWGUD/Tasks/sgFourPiAnalyzer.cxx index fb437863ed8..6a6abfc4628 100644 --- a/PWGUD/Tasks/sgFourPiAnalyzer.cxx +++ b/PWGUD/Tasks/sgFourPiAnalyzer.cxx @@ -17,7 +17,7 @@ #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" #include "Framework/O2DatabasePDGPlugin.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/SGSelector.h" #include "PWGUD/Core/SGTrackSelector.h" diff --git a/PWGUD/Tasks/sgInclJpsi.cxx b/PWGUD/Tasks/sgInclJpsi.cxx index 7e0557ef5f0..f5001af7c10 100644 --- a/PWGUD/Tasks/sgInclJpsi.cxx +++ b/PWGUD/Tasks/sgInclJpsi.cxx @@ -17,7 +17,7 @@ #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" #include "Framework/O2DatabasePDGPlugin.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/SGSelector.h" #include "Common/DataModel/PIDResponse.h" diff --git a/PWGUD/Tasks/sgSixPiAnalyzer.cxx b/PWGUD/Tasks/sgSixPiAnalyzer.cxx index 215c5d236a1..c3561ad7026 100644 --- a/PWGUD/Tasks/sgSixPiAnalyzer.cxx +++ b/PWGUD/Tasks/sgSixPiAnalyzer.cxx @@ -17,7 +17,7 @@ #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" #include "Framework/O2DatabasePDGPlugin.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/SGSelector.h" #include "PWGUD/Core/SGTrackSelector.h" diff --git a/PWGUD/Tasks/sgSpectraAnalyzer.cxx b/PWGUD/Tasks/sgSpectraAnalyzer.cxx index cffb6014300..afd766e0992 100644 --- a/PWGUD/Tasks/sgSpectraAnalyzer.cxx +++ b/PWGUD/Tasks/sgSpectraAnalyzer.cxx @@ -17,7 +17,7 @@ #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" #include "Framework/O2DatabasePDGPlugin.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/SGSelector.h" #include "PWGUD/Core/SGTrackSelector.h" diff --git a/PWGUD/Tasks/sgTwoPiAnalyzer.cxx b/PWGUD/Tasks/sgTwoPiAnalyzer.cxx index b7015745448..e1568bb1838 100644 --- a/PWGUD/Tasks/sgTwoPiAnalyzer.cxx +++ b/PWGUD/Tasks/sgTwoPiAnalyzer.cxx @@ -17,7 +17,7 @@ #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" #include "Framework/O2DatabasePDGPlugin.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include "PWGUD/Core/SGSelector.h" #include "PWGUD/Core/SGTrackSelector.h" diff --git a/PWGUD/Tasks/upcForward.cxx b/PWGUD/Tasks/upcForward.cxx index 3a3c6ec722d..bebcf0b2be2 100644 --- a/PWGUD/Tasks/upcForward.cxx +++ b/PWGUD/Tasks/upcForward.cxx @@ -18,7 +18,7 @@ for now AO2D.root I am using is #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" #include "Common/DataModel/EventSelection.h" -#include "iostream" +#include #include #include #include diff --git a/PWGUD/Tasks/upcPhotonuclearAnalysisJMG.cxx b/PWGUD/Tasks/upcPhotonuclearAnalysisJMG.cxx index 81834492eca..eb16b83f315 100644 --- a/PWGUD/Tasks/upcPhotonuclearAnalysisJMG.cxx +++ b/PWGUD/Tasks/upcPhotonuclearAnalysisJMG.cxx @@ -11,10 +11,17 @@ /// /// \brief /// \author Josué Martínez García, josuem@cern.ch +/// \file upcPhotonuclearAnalysisJMG.cxx + +#include #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" +#include "CCDB/BasicCCDBManager.h" +#include "Framework/StepTHn.h" +#include "CommonConstants/MathConstants.h" +#include #include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/TrackSelection.h" @@ -22,38 +29,91 @@ #include "Common/Core/trackUtilities.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "PWGCF/Core/CorrelationContainer.h" +#include "DataFormatsParameters/GRPObject.h" #include "PWGUD/DataModel/UDTables.h" +#include "PWGUD/Core/UPCPairCuts.h" #include "PWGUD/Core/UPCTauCentralBarrelHelperRL.h" 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 nEvenstMixed{"nEvenstMixed", 3, {"Events to be 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 +132,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; - using FullSGUDCollision = soa::Join::iterator; - using FullUDTracks = soa::Join; + // Output definitions + OutputObj sameGapSideA{"sameEventGapSideA"}; + OutputObj mixedGapSideA{"mixedEventGapSideA"}; + OutputObj sameGapSideC{"sameEventGapSideC"}; + OutputObj mixedGapSideC{"mixedEventGapSideC"}; + + UPCPairCuts mPairCuts; + bool doPairCuts = false; void init(InitContext const&) { @@ -83,9 +170,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 +180,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 +202,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 +215,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 +233,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 +246,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 +259,39 @@ 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, -5.0f, 0.0f, 5.0f, 10.0f}; + std::vector gapSideBinsEdges{VARIABLE_WIDTH, -0.5, 0.5, 1.5}; + + SliceCache cache; + + // Binning only on PosZ without multiplicity + // using BinningType = ColumnBinningPolicy; + using BinningType = ColumnBinningPolicy; + BinningType bindingOnVtx{{vtxBinsEdges, {gapSideBinsEdges}}, true}; + SameKindPair pairs{bindingOnVtx, nEvenstMixed, -1, &cache}; + + // ColumnBinningPolicy bindingOnVtx{{vtxBinsEdges, multBinsEdges}, true}; + + // SameKindPair, + // FullUDTracks, + // ColumnBinningPolicy> + // pair{bindingOnVtx, 5, -1, &cache}; template bool isCollisionCutSG(CSG const& collision, int SideGap) @@ -199,25 +301,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 +375,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 +447,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 +461,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 +486,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 +503,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 +517,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 +542,105 @@ 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; + } + // LOGF(debug, "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; + + for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { + if (collision1.size() == 0 || collision2.size() == 0) { + // LOGF(debug, "One or both collisions are empty."); + continue; + } + + float multiplicity = 0; + if (collision1.gapSide() == 0 && collision2.gapSide() == 0) { // gap on side A + if (isCollisionCutSG(collision1, 0) == false && isCollisionCutSG(collision2, 0) == false) { + continue; + } + // LOGF(debug, "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(debug, "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; + } + // LOGF(debug, "In the pairs loop, gap side C"); + multiplicity = tracks1.size(); + if (fillCollisionUD(mixedGapSideC, multiplicity) == false) { + return; + } + fillCorrelationsUD(mixedGapSideC, tracks1, tracks2, multiplicity, collision1.posZ()); + // LOGF(debug, "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..fc215ea1822 100644 --- a/PWGUD/Tasks/upcPionAnalysis.cxx +++ b/PWGUD/Tasks/upcPionAnalysis.cxx @@ -13,7 +13,7 @@ #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" -#include "iostream" +#include #include "PWGUD/DataModel/UDTables.h" #include #include diff --git a/PWGUD/Tasks/upcRhoAnalysis.cxx b/PWGUD/Tasks/upcRhoAnalysis.cxx index 1395d66c04b..2bb9865cf34 100644 --- a/PWGUD/Tasks/upcRhoAnalysis.cxx +++ b/PWGUD/Tasks/upcRhoAnalysis.cxx @@ -23,7 +23,7 @@ #include "Framework/AnalysisDataModel.h" #include "Framework/runDataProcessing.h" -#include "random" +#include #include "TLorentzVector.h" #include "Common/DataModel/PIDResponse.h" diff --git a/PWGUD/Tasks/upcRhoPrimeAnalysis.cxx b/PWGUD/Tasks/upcRhoPrimeAnalysis.cxx index 64559cc10dd..d4048806854 100644 --- a/PWGUD/Tasks/upcRhoPrimeAnalysis.cxx +++ b/PWGUD/Tasks/upcRhoPrimeAnalysis.cxx @@ -20,7 +20,7 @@ #include "Framework/runDataProcessing.h" #include "Math/Vector4D.h" // similiar to TLorentzVector (which is now legacy apparently) -#include "random" +#include #include "Common/DataModel/PIDResponse.h" 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..40375c48614 100644 --- a/Tutorials/PWGUD/UDTutorial_05.cxx +++ b/Tutorials/PWGUD/UDTutorial_05.cxx @@ -10,7 +10,7 @@ // or submit itself to any jurisdiction. // -#include "iostream" +#include #include "TLorentzVector.h" #include "TDatabasePDG.h" diff --git a/Tutorials/PWGUD/UDTutorial_07.cxx b/Tutorials/PWGUD/UDTutorial_07.cxx index f2a5616f00d..0060b68293e 100644 --- a/Tutorials/PWGUD/UDTutorial_07.cxx +++ b/Tutorials/PWGUD/UDTutorial_07.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. // -#include "iostream" +#include #include #include #include "Framework/runDataProcessing.h"