Skip to content
Merged
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
154 changes: 154 additions & 0 deletions PWGEM/Dilepton/Tasks/matchingMFT.cxx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.

Check failure on line 1 in PWGEM/Dilepton/Tasks/matchingMFT.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[name/workflow-file]

Name of a workflow file must match the name of the main struct in it (without the PWG prefix). (Class implementation files should be in "Core" directories.)

Check failure on line 1 in PWGEM/Dilepton/Tasks/matchingMFT.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[name/o2-task]

Specify task name only when it cannot be derived from the struct name. Only append to the default name.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
Expand Down Expand Up @@ -56,7 +56,7 @@
using MyFwdTracks = soa::Join<aod::FwdTracks, aod::FwdTracksCov, aod::McFwdTrackLabels>;
using MyMFTTracks = soa::Join<o2::aod::MFTTracks, aod::McMFTTrackLabels>;

Configurable<std::string> ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"};

Check failure on line 59 in PWGEM/Dilepton/Tasks/matchingMFT.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[name/configurable]

Use lowerCamelCase for names of configurables and use the same name for the struct member as for the JSON string. (Declare the type and names on the same line.)
Configurable<std::string> grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"};
Configurable<std::string> geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"};
Configurable<float> minPt{"minPt", 0.01, "min pt for muon"};
Expand All @@ -65,6 +65,10 @@
Configurable<float> maxEtaSA{"maxEtaSA", -2.5, "max. eta acceptance for MCH-MID"};
Configurable<float> minEtaGL{"minEtaGL", -3.6, "min. eta acceptance for MFT-MCH-MID"};
Configurable<float> maxEtaGL{"maxEtaGL", -2.5, "max. eta acceptance for MFT-MCH-MID"};
Configurable<float> minPtMFTsa{"minPtMFTsa", 0.01, "min pt for MFTsa"};
Configurable<float> maxPtMFTsa{"maxPtMFTsa", 1e+10, "max pt for MFTsa"};
Configurable<float> minEtaMFTsa{"minEtaMFTsa", -3.6, "min. eta acceptance for MFTsa"};
Configurable<float> maxEtaMFTsa{"maxEtaMFTsa", -2.4, "max. eta acceptance for MFTsa"};
Configurable<float> minRabs{"minRabs", 17.6, "min. R at absorber end"};
Configurable<float> midRabs{"midRabs", 26.5, "middle R at absorber end for pDCA cut"};
Configurable<float> maxRabs{"maxRabs", 89.5, "max. R at absorber end"};
Expand Down Expand Up @@ -211,6 +215,24 @@
fRegistry.add("MFTMCHMID/primary/correct/hDeltaPhi_Neg", "#varphi resolution;p_{T}^{gen} (GeV/c);#varphi^{rec} - #varphi^{gen} (rad.)", kTH2F, {{100, 0, 10}, {400, -0.2, +0.2}}, false);
fRegistry.addClone("MFTMCHMID/primary/correct/", "MFTMCHMID/primary/wrong/");
fRegistry.addClone("MFTMCHMID/primary/", "MFTMCHMID/secondary/");

fRegistry.add("MFT/primary/hPt", "pT;p_{T} (GeV/c)", kTH1D, {{1000, 0.0f, 10}}, false);
fRegistry.add("MFT/primary/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2D, {{180, 0, 2 * M_PI}, {80, -5.f, -1.f}}, false);
fRegistry.add("MFT/primary/hSign", "sign;sign", kTH1D, {{3, -1.5, +1.5}}, false);
fRegistry.add("MFT/primary/hChi2MFT", "chi2 MFT/ndf;chi2 MFT/ndf", kTH1D, {{100, 0.0f, 10}}, false);
fRegistry.add("MFT/primary/hNclustersMFT", "NclustersMFT;Nclusters MFT", kTH1D, {{11, -0.5f, 10.5}}, false);
fRegistry.add("MFT/primary/hMFTClusterMap", "MFT cluster map", kTH1D, {{1024, -0.5, 1023.5}}, false);
fRegistry.add("MFT/primary/hDCAxy2D", "DCA x vs. y;DCA_{x} (cm);DCA_{y} (cm)", kTH2D, {{200, -0.5, 0.5}, {200, -0.5, +0.5}}, false);
fRegistry.add("MFT/primary/hDCAxy", "DCAxy;DCA_{xy} (cm);", kTH1D, {{100, 0, 1}}, false);
fRegistry.add("MFT/primary/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm);", kTH2D, {{100, 0, 1}, {200, -0.1, 0.1}}, false);
fRegistry.add("MFT/primary/hProdVtxZ", "prod. vtx Z of track;V_{z} (cm)", kTH1D, {{200, -100, 100}}, false);
fRegistry.add("MFT/primary/hRelDeltaPt", "pT resolution;p_{T}^{gen} (GeV/c);(p_{T}^{rec} - p_{T}^{gen})/p_{T}^{gen}", kTH2D, {{200, 0, 10}, {1000, -1, +9}}, false);
fRegistry.add("MFT/primary/hDeltaEta_Pos", "#eta resolution;p_{T}^{gen} (GeV/c);#eta^{rec} - #eta^{gen}", kTH2D, {{200, 0, 10}, {400, -0.2, +0.2}}, false);
fRegistry.add("MFT/primary/hDeltaEta_Neg", "#eta resolution;p_{T}^{gen} (GeV/c);#eta^{rec} - #eta^{gen}", kTH2D, {{200, 0, 10}, {400, -0.2, +0.2}}, false);
fRegistry.add("MFT/primary/hDeltaPhi_Pos", "#varphi resolution;p_{T}^{gen} (GeV/c);#varphi^{rec} - #varphi^{gen} (rad.)", kTH2D, {{200, 0, 10}, {400, -0.2, +0.2}}, false);
fRegistry.add("MFT/primary/hDeltaPhi_Neg", "#varphi resolution;p_{T}^{gen} (GeV/c);#varphi^{rec} - #varphi^{gen} (rad.)", kTH2D, {{200, 0, 10}, {400, -0.2, +0.2}}, false);
fRegistry.add("MFT/primary/hCorrectAsocc", "correct mfttrack-to-collision association", kTH1F, {{2, -0.5, +1.5}}, false);
fRegistry.addClone("MFT/primary/", "MFT/secondary/");
}

bool isSelected(const float pt, const float eta, const float rAtAbsorberEnd, const float pDCA, const float chi2_per_ndf, const uint8_t trackType, const float dcaXY)
Expand Down Expand Up @@ -254,7 +276,7 @@
{
uint64_t mftClusterSizesAndTrackFlags = track.mftClusterSizesAndTrackFlags();
uint16_t clmap = 0;
for (unsigned int layer = 0; layer < 10; layer++) {

Check failure on line 279 in PWGEM/Dilepton/Tasks/matchingMFT.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.
if ((mftClusterSizesAndTrackFlags >> (layer * 6)) & 0x3f) {
clmap |= (1 << layer);
}
Expand Down Expand Up @@ -397,7 +419,7 @@
return;
}

if (std::abs(mcParticle_MCHMID.pdgCode()) != 13) { // select true muon

Check failure on line 422 in PWGEM/Dilepton/Tasks/matchingMFT.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.

Check failure on line 422 in PWGEM/Dilepton/Tasks/matchingMFT.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[pdg/explicit-code]

Avoid hard-coded PDG codes. Use named values from PDG_t or o2::constants::physics::Pdg instead.
return;
}

Expand Down Expand Up @@ -767,10 +789,133 @@
// }
}

template <typename TCollisions, typename TMFTTracks>
void fillMFTsa(TCollisions const& collisions, TMFTTracks const& mfttracks)
{
for (const auto& collision : collisions) {
if (!collision.has_mcCollision()) {
continue;
}
if (cfgRequireGoodRCT && !rctChecker.checkTable(collision)) {
continue;
}
float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()};
if (centralities[cfgCentEstimator] < cfgCentMin || cfgCentMax < centralities[cfgCentEstimator]) {
continue;
}

auto mftsaPerCollision = mfttracks.sliceBy(perCollision_MFT, collision.globalIndex());
for (const auto& mfttrack : mftsaPerCollision) {
if (!mfttrack.has_mcParticle()) {
continue;
}
auto mcParticle = mfttrack.template mcParticle_as<aod::McParticles>();
bool isPrimary = mcParticle.isPhysicalPrimary() || mcParticle.producedByGenerator();
float phiGen = mcParticle.phi();
o2::math_utils::bringTo02Pi(phiGen);

int ndf = 2 * mfttrack.nClusters() - 5;

if (mfttrack.nClusters() < minNclustersMFT) {
continue;
}

if (mfttrack.chi2() / ndf < 0 || maxChi2MFT < mfttrack.chi2() / ndf) {
continue;
}

if (requireMFTHitMap) {
std::vector<bool> hasMFTs{hasMFT<0, 1>(mfttrack), hasMFT<2, 3>(mfttrack), hasMFT<4, 5>(mfttrack), hasMFT<6, 7>(mfttrack), hasMFT<8, 9>(mfttrack)};
for (int i = 0; i < static_cast<int>(requiredMFTDisks->size()); i++) {
if (!hasMFTs[requiredMFTDisks->at(i)]) {
return;
}
}
}

// propagate MFTsa track to PV
std::array<double, 3> dcaInfOrig{999.f, 999.f, 999.f};
std::vector<double> v1; // Temporary null vector for the computation of the covariance matrix
SMatrix55 tcovs(v1.begin(), v1.end());
SMatrix5 tpars(mfttrack.x(), mfttrack.y(), mfttrack.phi(), mfttrack.tgl(), mfttrack.signed1Pt());
o2::track::TrackParCovFwd trackPar{mfttrack.z(), tpars, tcovs, mfttrack.chi2()};
trackPar.propagateToDCAhelix(mBz, {collision.posX(), collision.posY(), collision.posZ()}, dcaInfOrig);
v1.clear();
v1.shrink_to_fit();
float dcaX = dcaInfOrig[0];
float dcaY = dcaInfOrig[1];
float dcaZ = dcaInfOrig[2];
float dcaXY = std::sqrt(dcaX * dcaX + dcaY * dcaY);

float pt = trackPar.getPt();
float eta = trackPar.getEta();
float phi = trackPar.getPhi();
o2::math_utils::bringTo02Pi(phi);

if (pt < minPtMFTsa || maxPtMFTsa < pt) {
continue;
}
if (eta < minEtaMFTsa || maxEtaMFTsa < eta) {
continue;
}
if (maxDCAxy < dcaXY) {
continue;
}

if (isPrimary) {
fRegistry.fill(HIST("MFT/primary/hPt"), pt);
fRegistry.fill(HIST("MFT/primary/hEtaPhi"), phi, eta);
fRegistry.fill(HIST("MFT/primary/hSign"), mfttrack.sign());
fRegistry.fill(HIST("MFT/primary/hNclustersMFT"), mfttrack.nClusters());
fRegistry.fill(HIST("MFT/primary/hChi2MFT"), mfttrack.chi2() / ndf);
fRegistry.fill(HIST("MFT/primary/hMFTClusterMap"), mftClusterMap(mfttrack));
fRegistry.fill(HIST("MFT/primary/hDCAxy2D"), dcaX, dcaY);
fRegistry.fill(HIST("MFT/primary/hDCAxy"), dcaXY);
fRegistry.fill(HIST("MFT/primary/hDCAxyz"), dcaXY, dcaZ);
fRegistry.fill(HIST("MFT/primary/hCorrectAsocc"), mcParticle.mcCollisionId() == collision.mcCollisionId());

fRegistry.fill(HIST("MFT/primary/hProdVtxZ"), mcParticle.vz());
fRegistry.fill(HIST("MFT/primary/hRelDeltaPt"), mcParticle.pt(), (pt - mcParticle.pt()) / mcParticle.pt());
if (mfttrack.sign() > 0) {
fRegistry.fill(HIST("MFT/primary/hDeltaEta_Pos"), mcParticle.pt(), eta - mcParticle.eta());
fRegistry.fill(HIST("MFT/primary/hDeltaPhi_Pos"), mcParticle.pt(), phi - phiGen);
} else {
fRegistry.fill(HIST("MFT/primary/hDeltaEta_Neg"), mcParticle.pt(), eta - mcParticle.eta());
fRegistry.fill(HIST("MFT/primary/hDeltaPhi_Neg"), mcParticle.pt(), phi - phiGen);
}

} else {
fRegistry.fill(HIST("MFT/secondary/hPt"), pt);
fRegistry.fill(HIST("MFT/secondary/hEtaPhi"), phi, eta);
fRegistry.fill(HIST("MFT/secondary/hSign"), mfttrack.sign());
fRegistry.fill(HIST("MFT/secondary/hNclustersMFT"), mfttrack.nClusters());
fRegistry.fill(HIST("MFT/secondary/hChi2MFT"), mfttrack.chi2() / ndf);
fRegistry.fill(HIST("MFT/secondary/hMFTClusterMap"), mftClusterMap(mfttrack));
fRegistry.fill(HIST("MFT/secondary/hDCAxy2D"), dcaX, dcaY);
fRegistry.fill(HIST("MFT/secondary/hDCAxy"), dcaXY);
fRegistry.fill(HIST("MFT/secondary/hDCAxyz"), dcaXY, dcaZ);
fRegistry.fill(HIST("MFT/secondary/hCorrectAsocc"), mcParticle.mcCollisionId() == collision.mcCollisionId());

fRegistry.fill(HIST("MFT/secondary/hProdVtxZ"), mcParticle.vz());
fRegistry.fill(HIST("MFT/secondary/hRelDeltaPt"), mcParticle.pt(), (pt - mcParticle.pt()) / mcParticle.pt());
if (mfttrack.sign() > 0) {
fRegistry.fill(HIST("MFT/secondary/hDeltaEta_Pos"), mcParticle.pt(), eta - mcParticle.eta());
fRegistry.fill(HIST("MFT/secondary/hDeltaPhi_Pos"), mcParticle.pt(), phi - phiGen);
} else {
fRegistry.fill(HIST("MFT/secondary/hDeltaEta_Neg"), mcParticle.pt(), eta - mcParticle.eta());
fRegistry.fill(HIST("MFT/secondary/hDeltaPhi_Neg"), mcParticle.pt(), phi - phiGen);
}
}

} // end of mfttrack loop
} // end of collision loop
}

SliceCache cache;
PresliceUnsorted<aod::FwdTracks> fwdtracksPerMCHTrack = aod::fwdtrack::matchMCHTrackId;
PresliceUnsorted<aod::FwdTracks> perMFTTrack = o2::aod::fwdtrack::matchMFTTrackId;
Preslice<aod::FwdTracks> perCollision = o2::aod::fwdtrack::collisionId;
Preslice<aod::MFTTracks> perCollision_MFT = o2::aod::fwdtrack::collisionId;
Preslice<aod::FwdTrackAssoc> fwdtrackIndicesPerCollision = aod::track_association::collisionId;
PresliceUnsorted<aod::FwdTrackAssoc> fwdtrackIndicesPerFwdTrack = aod::track_association::fwdtrackId;

Expand All @@ -791,6 +936,9 @@
} // end of fwdtrack loop
} // end of collision loop

// only for MFTsa
fillMFTsa(collisions, mfttracks);

for (const auto& collision : collisions) {
auto bc = collision.template bc_as<aod::BCsWithTimestamps>();
initCCDB(bc);
Expand Down Expand Up @@ -850,6 +998,9 @@
} // end of fwdtrack loop
} // end of collision loop

// only for MFTsa
fillMFTsa(collisions, mfttracks);

for (const auto& collision : collisions) {
auto bc = collision.template bc_as<aod::BCsWithTimestamps>();
initCCDB(bc);
Expand Down Expand Up @@ -916,6 +1067,9 @@
} // end of fwdtrack loop
} // end of collision loop

// only for MFTsa
fillMFTsa(collisions, mfttracks);

for (const auto& collision : collisions) {
auto bc = collision.template bc_as<aod::BCsWithTimestamps>();
initCCDB(bc);
Expand Down Expand Up @@ -963,5 +1117,5 @@
};
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
{
return WorkflowSpec{adaptAnalysisTask<matchingMFT>(cfgc, TaskName{"matching-mft"})};

Check failure on line 1120 in PWGEM/Dilepton/Tasks/matchingMFT.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[name/o2-task]

Device names matching-mft and matching-m-f-t generated from the specified task name matching-mft and from the struct name matchingMFT, respectively, differ in hyphenation. Consider fixing capitalisation of the struct name to MatchingMft and removing TaskName.
}
Loading