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
244 changes: 122 additions & 122 deletions Common/TableProducer/PID/pidTPC.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -426,164 +426,164 @@ struct tpcPid {
count_tracks++; // Increment network track counter only if track has TPC, and (not skipping TPConly) or (is not TPConly)
}
}
}
}

PROCESS_SWITCH(tpcPid, processStandard, "Creating PID tables for real data", !(bool)mcTuneDeDxOnData.value);
PROCESS_SWITCH(tpcPid, processStandard, "Creating PID tables for real data", !(bool)mcTuneDeDxOnData.value);

void processMc(CollMC const& collisionsMc, TrksMC const& tracksMc, aod::BCsWithTimestamps const&)
{
void processMc(CollMC const& collisionsMc, TrksMC const& tracksMc, aod::BCsWithTimestamps const&)
{

auto converter = o2::delphes::TrackSmearer(); // converter for pdgCode -> PID mass
const uint64_t outTable_size = tracksMc.size();
auto converter = o2::delphes::TrackSmearer(); // converter for pdgCode -> PID mass
const uint64_t outTable_size = tracksMc.size();

auto reserveTable = [&outTable_size](const Configurable<int>& flag, auto& table) {
if (flag.value != 1) {
return;
}
table.reserve(outTable_size);
};

// Prepare memory for enabled tables
reserveTable(pidEl, tablePIDEl);
reserveTable(pidMu, tablePIDMu);
reserveTable(pidPi, tablePIDPi);
reserveTable(pidKa, tablePIDKa);
reserveTable(pidPr, tablePIDPr);
reserveTable(pidDe, tablePIDDe);
reserveTable(pidTr, tablePIDTr);
reserveTable(pidHe, tablePIDHe);
reserveTable(pidAl, tablePIDAl);
reserveTable(mcTuneDeDxOnData, tableTuneOnData);

const uint64_t tracksForNet_size = (skipTPCOnly) ? notTPCStandaloneTracks.size() : tracksWithTPC.size();
std::vector<float> network_prediction;

if (useNetworkCorrection) {
network_prediction = createNetworkPrediction(collisionsMc, tracksMc, tracksForNet_size);
auto reserveTable = [&outTable_size](const Configurable<int>& flag, auto& table) {
if (flag.value != 1) {
return;
}
table.reserve(outTable_size);
};

uint64_t count_tracks = 0;
// Prepare memory for enabled tables
reserveTable(pidEl, tablePIDEl);
reserveTable(pidMu, tablePIDMu);
reserveTable(pidPi, tablePIDPi);
reserveTable(pidKa, tablePIDKa);
reserveTable(pidPr, tablePIDPr);
reserveTable(pidDe, tablePIDDe);
reserveTable(pidTr, tablePIDTr);
reserveTable(pidHe, tablePIDHe);
reserveTable(pidAl, tablePIDAl);
reserveTable(mcTuneDeDxOnData, tableTuneOnData);

for (auto const& trk : tracksMc) {
// Loop on Tracks
if (trk.has_collision()) {
const auto& bc = collisionsMc.iteratorAt(trk.collisionId()).bc_as<aod::BCsWithTimestamps>();
if (useCCDBParam && ccdbTimestamp.value == 0 && !ccdb->isCachedObjectValid(ccdbPath.value, bc.timestamp())) { // Updating parametrisation only if the initial timestamp is 0
if (recoPass.value == "") {
LOGP(info, "Retrieving latest TPC response object for timestamp {}:", bc.timestamp());
} else {
LOGP(info, "Retrieving TPC Response for timestamp {} and recoPass {}:", bc.timestamp(), recoPass.value);
}
response = ccdb->getSpecific<o2::pid::tpc::Response>(ccdbPath.value, bc.timestamp(), metadata);
const uint64_t tracksForNet_size = (skipTPCOnly) ? notTPCStandaloneTracks.size() : tracksWithTPC.size();
std::vector<float> network_prediction;

if (useNetworkCorrection) {
network_prediction = createNetworkPrediction(collisionsMc, tracksMc, tracksForNet_size);
}

uint64_t count_tracks = 0;

for (auto const& trk : tracksMc) {
// Loop on Tracks
if (trk.has_collision()) {
const auto& bc = collisionsMc.iteratorAt(trk.collisionId()).bc_as<aod::BCsWithTimestamps>();
if (useCCDBParam && ccdbTimestamp.value == 0 && !ccdb->isCachedObjectValid(ccdbPath.value, bc.timestamp())) { // Updating parametrisation only if the initial timestamp is 0
if (recoPass.value == "") {
LOGP(info, "Retrieving latest TPC response object for timestamp {}:", bc.timestamp());
} else {
LOGP(info, "Retrieving TPC Response for timestamp {} and recoPass {}:", bc.timestamp(), recoPass.value);
}
response = ccdb->getSpecific<o2::pid::tpc::Response>(ccdbPath.value, bc.timestamp(), metadata);
if (!response) {
LOGP(warning, "!! Could not find a valid TPC response object for specific pass name {}! Falling back to latest uploaded object.", recoPass.value);
response = ccdb->getForTimeStamp<o2::pid::tpc::Response>(ccdbPath.value, bc.timestamp());
if (!response) {
LOGP(warning, "!! Could not find a valid TPC response object for specific pass name {}! Falling back to latest uploaded object.", recoPass.value);
response = ccdb->getForTimeStamp<o2::pid::tpc::Response>(ccdbPath.value, bc.timestamp());
if (!response) {
LOGP(fatal, "Could not find ANY TPC response object for the timestamp {}!", bc.timestamp());
}
LOGP(fatal, "Could not find ANY TPC response object for the timestamp {}!", bc.timestamp());
}
response->PrintAll();
}
response->PrintAll();
}
}

// Check and fill enabled tables
auto makeTablePid = [&trk, &collisionsMc, &network_prediction, &count_tracks, &tracksForNet_size, this](const int flag, auto& table, const o2::track::PID::ID pid) {
if (flag != 1) {
// Check and fill enabled tables
auto makeTablePid = [&trk, &collisionsMc, &network_prediction, &count_tracks, &tracksForNet_size, this](const int flag, auto& table, const o2::track::PID::ID pid) {
if (flag != 1) {
return;
}
if (!trk.hasTPC()) {
table(aod::pidtpc_tiny::binning::underflowBin);
return;
}
if (skipTPCOnly) {
if (!trk.hasITS() && !trk.hasTRD() && !trk.hasTOF()) {
table(aod::pidtpc_tiny::binning::underflowBin);
return;
}
}
auto expSignal = response->GetExpectedSignal(trk, pid);
auto expSigma = response->GetExpectedSigma(collisionsMc.iteratorAt(trk.collisionId()), trk, pid);
if (expSignal < 0. || expSigma < 0.) { // skip if expected signal invalid
table(aod::pidtpc_tiny::binning::underflowBin);
return;
}

if (useNetworkCorrection) {

// Here comes the application of the network. The output--dimensions of the network dtermine the application: 1: mean, 2: sigma, 3: sigma asymmetric
// For now only the option 2: sigma will be used. The other options are kept if there would be demand later on
if (network.getNumOutputNodes() == 1) {
aod::pidutils::packInTable<aod::pidtpc_tiny::binning>((trk.tpcSignal() - network_prediction[count_tracks + tracksForNet_size * pid] * expSignal) / expSigma, table);
} else if (network.getNumOutputNodes() == 2) {
aod::pidutils::packInTable<aod::pidtpc_tiny::binning>((trk.tpcSignal() / expSignal - network_prediction[2 * (count_tracks + tracksForNet_size * pid)]) / (network_prediction[2 * (count_tracks + tracksForNet_size * pid) + 1] - network_prediction[2 * (count_tracks + tracksForNet_size * pid)]), table);
} else if (network.getNumOutputNodes() == 3) {
if (trk.tpcSignal() / expSignal >= network_prediction[3 * (count_tracks + tracksForNet_size * pid)]) {
aod::pidutils::packInTable<aod::pidtpc_tiny::binning>((trk.tpcSignal() / expSignal - network_prediction[3 * (count_tracks + tracksForNet_size * pid)]) / (network_prediction[3 * (count_tracks + tracksForNet_size * pid) + 1] - network_prediction[3 * (count_tracks + tracksForNet_size * pid)]), table);
} else {
aod::pidutils::packInTable<aod::pidtpc_tiny::binning>((trk.tpcSignal() / expSignal - network_prediction[3 * (count_tracks + tracksForNet_size * pid)]) / (network_prediction[3 * (count_tracks + tracksForNet_size * pid)] - network_prediction[3 * (count_tracks + tracksForNet_size * pid) + 2]), table);
}
} else {
LOGF(fatal, "Network output-dimensions incompatible!");
}
} else {
aod::pidutils::packInTable<aod::pidtpc_tiny::binning>(response->GetNumberOfSigma(collisionsMc.iteratorAt(trk.collisionId()), trk, pid), table);
}
};

makeTablePid(pidEl.value, tablePIDEl, o2::track::PID::Electron);
makeTablePid(pidMu.value, tablePIDMu, o2::track::PID::Muon);
makeTablePid(pidPi.value, tablePIDPi, o2::track::PID::Pion);
makeTablePid(pidKa.value, tablePIDKa, o2::track::PID::Kaon);
makeTablePid(pidPr.value, tablePIDPr, o2::track::PID::Proton);
makeTablePid(pidDe.value, tablePIDDe, o2::track::PID::Deuteron);
makeTablePid(pidTr.value, tablePIDTr, o2::track::PID::Triton);
makeTablePid(pidHe.value, tablePIDHe, o2::track::PID::Helium3);
makeTablePid(pidAl.value, tablePIDAl, o2::track::PID::Alpha);

// Check and fill enabled tables
auto makeTableMc = [&trk, &collisionsMc, &network_prediction, &count_tracks, &tracksForNet_size, this](const int flag, auto& table, const o2::track::PID::ID pid) {
if (flag != 1) {
return;
} else {

if (!trk.hasTPC()) {
table(aod::pidtpc_tiny::binning::underflowBin);
table(-999.f);
return;
}
if (skipTPCOnly) {
if (!trk.hasITS() && !trk.hasTRD() && !trk.hasTOF()) {
table(aod::pidtpc_tiny::binning::underflowBin);
table(-999.f);
return;
}
}

auto expSignal = response->GetExpectedSignal(trk, pid);
auto expSigma = response->GetExpectedSigma(collisionsMc.iteratorAt(trk.collisionId()), trk, pid);
if (expSignal < 0. || expSigma < 0.) { // skip if expected signal invalid
table(aod::pidtpc_tiny::binning::underflowBin);
table(-999.f);
return;
}

if (useNetworkCorrection) {

// Here comes the application of the network. The output--dimensions of the network dtermine the application: 1: mean, 2: sigma, 3: sigma asymmetric
// For now only the option 2: sigma will be used. The other options are kept if there would be demand later on
if (network.getNumOutputNodes() == 1) {
aod::pidutils::packInTable<aod::pidtpc_tiny::binning>((trk.tpcSignal() - network_prediction[count_tracks + tracksForNet_size * pid] * expSignal) / expSigma, table);
} else if (network.getNumOutputNodes() == 2) {
aod::pidutils::packInTable<aod::pidtpc_tiny::binning>((trk.tpcSignal() / expSignal - network_prediction[2 * (count_tracks + tracksForNet_size * pid)]) / (network_prediction[2 * (count_tracks + tracksForNet_size * pid) + 1] - network_prediction[2 * (count_tracks + tracksForNet_size * pid)]), table);
} else if (network.getNumOutputNodes() == 3) {
if (trk.tpcSignal() / expSignal >= network_prediction[3 * (count_tracks + tracksForNet_size * pid)]) {
aod::pidutils::packInTable<aod::pidtpc_tiny::binning>((trk.tpcSignal() / expSignal - network_prediction[3 * (count_tracks + tracksForNet_size * pid)]) / (network_prediction[3 * (count_tracks + tracksForNet_size * pid) + 1] - network_prediction[3 * (count_tracks + tracksForNet_size * pid)]), table);
} else {
aod::pidutils::packInTable<aod::pidtpc_tiny::binning>((trk.tpcSignal() / expSignal - network_prediction[3 * (count_tracks + tracksForNet_size * pid)]) / (network_prediction[3 * (count_tracks + tracksForNet_size * pid)] - network_prediction[3 * (count_tracks + tracksForNet_size * pid) + 2]), table);
}
} else {
LOGF(fatal, "Network output-dimensions incompatible!");
}
} else {
aod::pidutils::packInTable<aod::pidtpc_tiny::binning>(response->GetNumberOfSigma(collisionsMc.iteratorAt(trk.collisionId()), trk, pid), table);
}
};

makeTablePid(pidEl.value, tablePIDEl, o2::track::PID::Electron);
makeTablePid(pidMu.value, tablePIDMu, o2::track::PID::Muon);
makeTablePid(pidPi.value, tablePIDPi, o2::track::PID::Pion);
makeTablePid(pidKa.value, tablePIDKa, o2::track::PID::Kaon);
makeTablePid(pidPr.value, tablePIDPr, o2::track::PID::Proton);
makeTablePid(pidDe.value, tablePIDDe, o2::track::PID::Deuteron);
makeTablePid(pidTr.value, tablePIDTr, o2::track::PID::Triton);
makeTablePid(pidHe.value, tablePIDHe, o2::track::PID::Helium3);
makeTablePid(pidAl.value, tablePIDAl, o2::track::PID::Alpha);

// Check and fill enabled tables
auto makeTableMc = [&trk, &collisionsMc, &network_prediction, &count_tracks, &tracksForNet_size, this](const int flag, auto& table, const o2::track::PID::ID pid) {
if (flag != 1) {
return;
auto mean = network_prediction[2 * (count_tracks + tracksForNet_size * pid)] * expSignal; // Absolute mean, i.e. the mean dE/dx value of the data in that slice, not the mean of the NSigma distribution
auto sigma = (network_prediction[2 * (count_tracks + tracksForNet_size * pid) + 1] - network_prediction[2 * (count_tracks + tracksForNet_size * pid)]) * expSignal;
table(gRandom->Gaus(mean, sigma));
} else {

if (!trk.hasTPC()) {
table(-999.f);
return;
}
if (skipTPCOnly) {
if (!trk.hasITS() && !trk.hasTRD() && !trk.hasTOF()) {
table(-999.f);
return;
}
}

auto expSignal = response->GetExpectedSignal(trk, pid);
auto expSigma = response->GetExpectedSigma(collisionsMc.iteratorAt(trk.collisionId()), trk, pid);
if (expSignal < 0. || expSigma < 0.) { // skip if expected signal invalid
table(-999.f);
return;
}

if (useNetworkCorrection) {
auto mean = network_prediction[2 * (count_tracks + tracksForNet_size * pid)] * expSignal; // Absolute mean, i.e. the mean dE/dx value of the data in that slice, not the mean of the NSigma distribution
auto sigma = (network_prediction[2 * (count_tracks + tracksForNet_size * pid) + 1] - network_prediction[2 * (count_tracks + tracksForNet_size * pid)]) * expSignal;
table(gRandom->Gaus(mean, sigma));
} else {
table(gRandom->Gaus(expSignal, expSigma));
}
table(gRandom->Gaus(expSignal, expSigma));
}
};
}
};

// For the MC tracks
makeTableMc(mcTuneDeDxOnData.value, tableTuneOnData, converter.getIndexPDG(trk.mcParticle().pdgCode()));
// For the MC tracks
makeTableMc(mcTuneDeDxOnData.value, tableTuneOnData, converter.getIndexPDG(trk.mcParticle().pdgCode()));

if (trk.hasTPC() && (!skipTPCOnly || trk.hasITS() || trk.hasTRD() || trk.hasTOF())) {
count_tracks++; // Increment network track counter only if track has TPC, and (not skipping TPConly) or (is not TPConly)
}
if (trk.hasTPC() && (!skipTPCOnly || trk.hasITS() || trk.hasTRD() || trk.hasTOF())) {
count_tracks++; // Increment network track counter only if track has TPC, and (not skipping TPConly) or (is not TPConly)
}
}
}

PROCESS_SWITCH(tpcPid, processMc, "Creating PID tables for MC identity", (bool)mcTuneDeDxOnData.value);
PROCESS_SWITCH(tpcPid, processMc, "Creating PID tables for MC identity", (bool)mcTuneDeDxOnData.value);
};

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