Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 182 additions & 0 deletions PWGCF/DataModel/singletrackselector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
// 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 create a table for single track selection.
/// \author Sofia Tomassini
/// \since 30 May 2023

#ifndef PWGCF_DATAMODEL_SINGLETRACKSELECTOR_H_
#define PWGCF_DATAMODEL_SINGLETRACKSELECTOR_H_

#include "Framework/ASoA.h"
#include "Framework/AnalysisDataModel.h"
#include "Common/DataModel/PIDResponse.h"
#include "Framework/Logger.h"
#include "Common/DataModel/Multiplicity.h"

namespace o2::aod
{
namespace singletrackselector
{
template <typename binningType>
typename binningType::binned_t packInTable(const float& valueToBin)
{
if (valueToBin <= binningType::binned_min) {
return binningType::underflowBin;
} else if (valueToBin >= binningType::binned_max) {
return binningType::overflowBin;
} else {
return static_cast<typename binningType::binned_t>(valueToBin / binningType::bin_width);
}
}

template <typename binningType>
float unPack(const typename binningType::binned_t& b)
{
return static_cast<float>(binningType::bin_width * b);
}

template <typename binningType>
typename binningType::binned_t packInTableOffset(const float& valueToBin)
{
if (valueToBin <= binningType::binned_min) {
return binningType::underflowBin;
} else if (valueToBin >= binningType::binned_max) {
return binningType::overflowBin;
} else {
return static_cast<typename binningType::binned_t>(((valueToBin - (binningType::binned_max - binningType::binned_min) * 0.5) / binningType::bin_width));
}
}

template <typename binningType>
float unPackOffset(const typename binningType::binned_t& b)
{
return static_cast<float>((binningType::binned_max - binningType::binned_min) * 0.5 + binningType::bin_width * b);
}

namespace storedcrossedrows
{
struct binning {
public:
typedef int8_t binned_t;
static constexpr int nbins = (1 << 8 * sizeof(binned_t)) - 2;
static constexpr binned_t overflowBin = nbins >> 1;
static constexpr binned_t underflowBin = -(nbins >> 1);
static constexpr float binned_max = 253.5;
static constexpr float binned_min = -0.5;
static constexpr float bin_width = (binned_max - binned_min) / nbins;
};
} // namespace storedcrossedrows

namespace nsigma
{
struct binning {
public:
typedef int8_t binned_t;
static constexpr int nbins = (1 << 8 * sizeof(binned_t)) - 2;
static constexpr binned_t overflowBin = nbins >> 1;
static constexpr binned_t underflowBin = -(nbins >> 1);
static constexpr float binned_max = 10.0;
static constexpr float binned_min = -10.0;
static constexpr float bin_width = (binned_max - binned_min) / nbins;
};
} // namespace nsigma

DECLARE_SOA_INDEX_COLUMN(Collision, collision); // Index to the collision
DECLARE_SOA_COLUMN(HasTOF, hasTOF, bool);
DECLARE_SOA_COLUMN(HasITS, hasITS, bool);
DECLARE_SOA_COLUMN(Px, px, float); // Momentum of the track
DECLARE_SOA_COLUMN(Py, py, float); // Momentum of the track
DECLARE_SOA_COLUMN(Pz, pz, float); // Momentum of the track
DECLARE_SOA_DYNAMIC_COLUMN(P, p,
[](float px, float py, float pz) -> float { return std::sqrt(px * px + py * py + pz * pz); }); // Momentum of the track
DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt,
[](float px, float py) -> float { return std::sqrt(px * px + py * py); }); // Momentum of the track
DECLARE_SOA_COLUMN(TPCInnerParam, tpcInnerParam, float); // vertex position along z
DECLARE_SOA_COLUMN(TPCSignal, tpcSignal, float); // vertex position along z
DECLARE_SOA_COLUMN(Beta, beta, float);
DECLARE_SOA_COLUMN(DcaXY, dcaXY, float); // impact parameter of the track
DECLARE_SOA_COLUMN(DcaZ, dcaZ, float); // impact parameter of the track
DECLARE_SOA_COLUMN(TPCNClsFound, tpcNClsFound, float); // Number of TPC clusters
DECLARE_SOA_COLUMN(TPCCrossedRowsOverFindableCls, tpcCrossedRowsOverFindableCls, float);
DECLARE_SOA_COLUMN(TPCChi2NCl, tpcChi2NCl, float); // TPC chi2
DECLARE_SOA_COLUMN(ITSNCls, itsNCls, float); // Number of ITS clusters
DECLARE_SOA_COLUMN(ITSChi2NCl, itsChi2NCl, float); // ITS chi2
DECLARE_SOA_COLUMN(Sign, sign, int8_t);
DECLARE_SOA_COLUMN(Eta, eta, float);
DECLARE_SOA_COLUMN(Phi, phi, float);
DECLARE_SOA_COLUMN(StoredCrossedRows, storedCrossedRows, storedcrossedrows::binning::binned_t);
DECLARE_SOA_COLUMN(StoredTOFNSigmaPr, storedTofNSigmaPr, nsigma::binning::binned_t);
DECLARE_SOA_COLUMN(StoredTPCNSigmaPr, storedTpcNSigmaPr, nsigma::binning::binned_t);
DECLARE_SOA_COLUMN(StoredTOFNSigmaDe, storedTofNSigmaDe, nsigma::binning::binned_t);
DECLARE_SOA_COLUMN(StoredTPCNSigmaDe, storedTpcNSigmaDe, nsigma::binning::binned_t);

DECLARE_SOA_DYNAMIC_COLUMN(CrossedRows, tpcNClsCrossedRows,
[](storedcrossedrows::binning::binned_t binned) -> float { return singletrackselector::unPackOffset<storedcrossedrows::binning>(binned); });
DECLARE_SOA_DYNAMIC_COLUMN(TOFNSigmaPr, tofNSigmaPr,
[](nsigma::binning::binned_t nsigma_binned) -> float { return singletrackselector::unPack<nsigma::binning>(nsigma_binned); });
DECLARE_SOA_DYNAMIC_COLUMN(TPCNSigmaPr, tpcNSigmaPr,
[](nsigma::binning::binned_t nsigma_binned) -> float { return singletrackselector::unPack<nsigma::binning>(nsigma_binned); });
DECLARE_SOA_DYNAMIC_COLUMN(TOFNSigmaDe, tofNSigmaDe,
[](nsigma::binning::binned_t nsigma_binned) -> float { return singletrackselector::unPack<nsigma::binning>(nsigma_binned); });
DECLARE_SOA_DYNAMIC_COLUMN(TPCNSigmaDe, tpcNSigmaDe,
[](nsigma::binning::binned_t nsigma_binned) -> float { return singletrackselector::unPack<nsigma::binning>(nsigma_binned); });

DECLARE_SOA_DYNAMIC_COLUMN(Energy, energy,
[](float px, float py, float pz, float mass) -> float { return sqrt(px * px + py * py + pz * pz + mass * mass); });

DECLARE_SOA_COLUMN(GlobalIndex, globalIndex, int64_t); // Index to the collision
DECLARE_SOA_COLUMN(Mult, mult, int); // Multiplicity of the collision
DECLARE_SOA_COLUMN(PosZ, posZ, int); // Vertex of the collision

} // namespace singletrackselector

DECLARE_SOA_TABLE(SingleTrackSel, "AOD", "STSEL", // Table of the variables for single track selection.
o2::soa::Index<>,
singletrackselector::CollisionId,
singletrackselector::HasITS,
singletrackselector::HasTOF,
singletrackselector::Px,
singletrackselector::Py,
singletrackselector::Pz,
singletrackselector::TPCInnerParam,
singletrackselector::TPCSignal,
singletrackselector::Beta,
singletrackselector::DcaXY,
singletrackselector::DcaZ,
singletrackselector::TPCNClsFound,
singletrackselector::TPCCrossedRowsOverFindableCls,
singletrackselector::TPCChi2NCl,
singletrackselector::ITSNCls,
singletrackselector::ITSChi2NCl,
singletrackselector::Sign,
singletrackselector::Eta,
singletrackselector::Phi,
singletrackselector::StoredCrossedRows,
singletrackselector::StoredTOFNSigmaPr,
singletrackselector::StoredTPCNSigmaPr,
singletrackselector::StoredTOFNSigmaDe,
singletrackselector::StoredTPCNSigmaDe,
singletrackselector::P<singletrackselector::Px, singletrackselector::Py, singletrackselector::Pz>,
singletrackselector::Pt<singletrackselector::Px, singletrackselector::Py>,
singletrackselector::CrossedRows<singletrackselector::StoredCrossedRows>,
singletrackselector::TOFNSigmaPr<singletrackselector::StoredTOFNSigmaPr>,
singletrackselector::TPCNSigmaPr<singletrackselector::StoredTPCNSigmaPr>,
singletrackselector::TOFNSigmaDe<singletrackselector::StoredTOFNSigmaDe>,
singletrackselector::TPCNSigmaDe<singletrackselector::StoredTPCNSigmaDe>,
singletrackselector::Energy<singletrackselector::Px, singletrackselector::Py, singletrackselector::Pz>);

DECLARE_SOA_TABLE(SingleCollSel, "AOD", "SCSEL", // Table of the variables for single track selection.
singletrackselector::GlobalIndex,
singletrackselector::Mult,
singletrackselector::PosZ);
} // namespace o2::aod
#endif // PWGCF_DATAMODEL_SINGLETRACKSELECTOR_H_
5 changes: 5 additions & 0 deletions PWGCF/TableProducer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,8 @@ o2physics_add_dpl_workflow(dptdpt-filter
SOURCES dptdptfilter.cxx
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore
COMPONENT_NAME Analysis)

o2physics_add_dpl_workflow(single-track-selector
SOURCES singletrackselector.cxx
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore
COMPONENT_NAME Analysis)
111 changes: 111 additions & 0 deletions PWGCF/TableProducer/singletrackselector.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// 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 create a table applying some basic cuts on the ITS and DCA.
/// \author Sofia Tomassini
/// \since 31 May 2023

#include <Framework/AnalysisDataModel.h>
#include <fairlogger/Logger.h>
#include "Framework/AnalysisTask.h"
#include "Framework/runDataProcessing.h"
#include "Common/DataModel/PIDResponse.h"
#include "Common/DataModel/Multiplicity.h"
#include "Common/DataModel/TrackSelectionTables.h"
#include "Common/DataModel/EventSelection.h"
#include "Common/DataModel/FT0Corrected.h"

#include "PWGCF/DataModel/singletrackselector.h"

#include "TDatabasePDG.h"

using namespace o2;
using namespace o2::framework;
using namespace o2::framework::expressions;
using namespace o2::track;
using namespace o2::aod;

struct singleTrackSelector {

Configurable<int> applyEvSel{"applyEvSel", 2, "Flag to apply rapidity cut: 0 -> no event selection, 1 -> Run 2 event selection, 2 -> Run 3 event selection"};
Configurable<float> cutDcaXy{"cutDcaXy", 0.12, ""};
Configurable<float> cutPtMin{"cutPtMin", 0.4, "Minimum cut in pT"};
Configurable<float> cutTPCNSigmaPr{"cutTPCNSigmaPr", 5.f, "Cut on the TPC nsigma for protons"};
Configurable<float> cutTPCNSigmaDe{"cutTPCNSigmaDe", 5.f, "Cut on the TPC nsigma for deuteron"};

using Trks = soa::Join<aod::Tracks, aod::TracksExtra, aod::pidEvTimeFlags, aod::TracksDCA,
aod::pidTPCFullEl, aod::pidTPCFullPi, aod::pidTPCFullKa, aod::pidTPCFullPr,
aod::pidTOFFullEl, aod::pidTOFFullMu, aod::pidTOFFullPi, aod::pidTOFFullKa, aod::pidTOFFullPr,
aod::pidTPCFullDe, aod::pidTOFFullDe, aod::pidTOFbeta,
aod::TrackSelection>;
using Coll = soa::Join<aod::Collisions, aod::Mults, aod::EvSels, aod::FT0sCorrected>;

Produces<o2::aod::SingleTrackSel> tableRow;
Produces<o2::aod::SingleCollSel> tableRowColl;

Filter eventFilter = (applyEvSel.node() == 0) ||
((applyEvSel.node() == 1) && (aod::evsel::sel7 == true)) ||
((applyEvSel.node() == 2) && (aod::evsel::sel8 == true));
Filter vertexFilter = ((o2::aod::collision::posZ < 15.f) && (o2::aod::collision::posZ > -15.f));
Filter trackFilter = ((o2::aod::track::itsChi2NCl <= 36.f) && (o2::aod::track::itsChi2NCl >= 0.f) && (o2::aod::track::tpcChi2NCl >= 0.f) && (o2::aod::track::tpcChi2NCl <= 4.f));

void process(soa::Filtered<Coll>::iterator const& collision, soa::Filtered<Trks> const& tracks)
{
tableRow.reserve(tracks.size());
tableRowColl(collision.globalIndex(),
collision.multTPC(),
collision.posZ());

for (auto& track : tracks) {
if (track.pt() < cutPtMin) {
continue;
}
if (abs(track.dcaXY()) > cutDcaXy) {
continue;
}
if (abs(track.tpcNSigmaPr()) > cutTPCNSigmaPr) {
continue;
}
if (abs(track.tpcNSigmaDe()) > cutTPCNSigmaDe) {
continue;
}
tableRow(tableRowColl.lastIndex(),
track.hasITS(),
track.hasTOF(),
track.px(),
track.py(),
track.pz(),
track.tpcInnerParam(),
track.tpcSignal(),
track.beta(),
track.dcaXY(),
track.dcaZ(),
track.tpcNClsFound(),
track.tpcFoundOverFindableCls(),
track.tpcChi2NCl(),
track.itsNCls(),
track.itsChi2NCl(),
track.sign(),
track.eta(),
track.phi(),
singletrackselector::packInTableOffset<singletrackselector::storedcrossedrows::binning>(track.tpcNClsCrossedRows()),
singletrackselector::packInTable<singletrackselector::nsigma::binning>(track.tofNSigmaPr()),
singletrackselector::packInTable<singletrackselector::nsigma::binning>(track.tpcNSigmaPr()),
singletrackselector::packInTable<singletrackselector::nsigma::binning>(track.tofNSigmaDe()),
singletrackselector::packInTable<singletrackselector::nsigma::binning>(track.tpcNSigmaDe()));
}
}
};

WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
{
return WorkflowSpec{adaptAnalysisTask<singleTrackSelector>(cfgc)};
}