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
123 changes: 103 additions & 20 deletions Common/Tools/PID/pidTPCModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <Framework/AnalysisDataModel.h>
#include <Framework/AnalysisHelpers.h>
#include <Framework/Configurable.h>
#include <Framework/RunningWorkflowInfo.h>
#include <Framework/runDataProcessing.h>
#include <ReconstructionDataFormats/PID.h>

Expand Down Expand Up @@ -84,14 +85,15 @@

struct pidTPCConfigurables : o2::framework::ConfigurableGroup {
std::string prefix = "pidTPC";
o2::framework::Configurable<std::string> paramfile{"param-file", "", "Path to the parametrization object, if empty the parametrization is not taken from file"};

Check failure on line 88 in Common/Tools/PID/pidTPCModule.h

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.)
o2::framework::Configurable<std::string> ccdbPath{"ccdbPath", "Analysis/PID/TPC/Response", "Path of the TPC parametrization on the CCDB"};
o2::framework::Configurable<std::string> recoPass{"recoPass", "", "Reconstruction pass name for CCDB query (automatically takes latest object for timestamp if blank)"};
o2::framework::Configurable<int64_t> ccdbTimestamp{"ccdb-timestamp", 0, "timestamp of the object used to query in CCDB the detector response. Exceptions: -1 gets the latest object, 0 gets the run dependent timestamp"};

Check failure on line 91 in Common/Tools/PID/pidTPCModule.h

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.)
// Parameters for loading network from a file / downloading the file
o2::framework::Configurable<bool> useNetworkCorrection{"useNetworkCorrection", 0, "(bool) Wether or not to use the network correction for the TPC dE/dx signal"};
o2::framework::Configurable<bool> autofetchNetworks{"autofetchNetworks", 1, "(bool) Automatically fetches networks from CCDB for the correct run number"};
o2::framework::Configurable<bool> skipTPCOnly{"skipTPCOnly", false, "Flag to skip TPC only tracks (faster but affects the analyses that use TPC only tracks)"};
o2::framework::Configurable<int> skipTPCOnly{"skipTPCOnly", -1, "Flag to skip TPC only tracks (faster but affects the analyses that use TPC only tracks). 0: do not skip, 1: skip, -1: check if needed by specific tasks"};
o2::framework::Configurable<std::vector<std::string>> devicesRequiringTPCOnlyPID{"devicesRequiringTPCOnlyPID", std::vector<std::string>{"photon-conversion-builder"}, "List of device names of tasks requiring TPC-only tracks to have TPC PID calculated"};
o2::framework::Configurable<std::string> networkPathLocally{"networkPathLocally", "network.onnx", "(std::string) Path to the local .onnx file. If autofetching is enabled, then this is where the files will be downloaded"};
o2::framework::Configurable<std::string> networkPathCCDB{"networkPathCCDB", "Analysis/PID/TPC/ML", "Path on CCDB"};
o2::framework::Configurable<bool> enableNetworkOptimizations{"enableNetworkOptimizations", 1, "(bool) If the neural network correction is used, this enables GraphOptimizationLevel::ORT_ENABLE_EXTENDED in the ONNX session"};
Expand All @@ -100,14 +102,14 @@
o2::framework::Configurable<int> savedEdxsCorrected{"savedEdxsCorrected", -1, {"Save table with corrected dE/dx calculated on the spot. 0: off, 1: on, -1: auto"}};
o2::framework::Configurable<bool> useCorrecteddEdx{"useCorrecteddEdx", false, "(bool) If true, use corrected dEdx value in Nsigma calculation instead of the one in the AO2D"};

o2::framework::Configurable<int> pidFullEl{"pid-full-el", -1, {"Produce PID information for the Electron mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}};

Check failure on line 105 in Common/Tools/PID/pidTPCModule.h

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.)
o2::framework::Configurable<int> pidFullMu{"pid-full-mu", -1, {"Produce PID information for the Muon mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}};

Check failure on line 106 in Common/Tools/PID/pidTPCModule.h

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.)
o2::framework::Configurable<int> pidFullPi{"pid-full-pi", -1, {"Produce PID information for the Pion mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}};

Check failure on line 107 in Common/Tools/PID/pidTPCModule.h

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.)
o2::framework::Configurable<int> pidFullKa{"pid-full-ka", -1, {"Produce PID information for the Kaon mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}};

Check failure on line 108 in Common/Tools/PID/pidTPCModule.h

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.)
o2::framework::Configurable<int> pidFullPr{"pid-full-pr", -1, {"Produce PID information for the Proton mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}};

Check failure on line 109 in Common/Tools/PID/pidTPCModule.h

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.)
o2::framework::Configurable<int> pidFullDe{"pid-full-de", -1, {"Produce PID information for the Deuterons mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}};

Check failure on line 110 in Common/Tools/PID/pidTPCModule.h

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.)
o2::framework::Configurable<int> pidFullTr{"pid-full-tr", -1, {"Produce PID information for the Triton mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}};

Check failure on line 111 in Common/Tools/PID/pidTPCModule.h

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.)
o2::framework::Configurable<int> pidFullHe{"pid-full-he", -1, {"Produce PID information for the Helium3 mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}};

Check failure on line 112 in Common/Tools/PID/pidTPCModule.h

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.)
o2::framework::Configurable<int> pidFullAl{"pid-full-al", -1, {"Produce PID information for the Alpha mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}};
o2::framework::Configurable<int> pidTinyEl{"pid-tiny-el", -1, {"Produce PID information for the Electron mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}};
o2::framework::Configurable<int> pidTinyMu{"pid-tiny-mu", -1, {"Produce PID information for the Muon mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}};
Expand Down Expand Up @@ -244,6 +246,59 @@
LOGF(info, "***************************************************");
}

if (pidTPCopts.skipTPCOnly.value == -1) {
LOGF(info, "***************************************************");
LOGF(info, " the skipTPConly flag has a value of -1! ");
LOGF(info, " ---> autodetecting TPC-only track necessity now ");
LOGF(info, "***************************************************");
// print list of devices that are being checked for
for (std::size_t devIdx{0}; devIdx < pidTPCopts.devicesRequiringTPCOnlyPID->size(); devIdx++) {
LOGF(info, "Will search for #%i device requiring TPC PID for TPC only: %s", devIdx, pidTPCopts.devicesRequiringTPCOnlyPID->at(devIdx));
}
LOGF(info, "***************************************************");

// assume that TPC tracks are not needed, but check if tasks
// requiring them are present in the chain
pidTPCopts.skipTPCOnly.value = 1;

// loop over devices in this execution
auto& workflows = context.services().template get<o2::framework::RunningWorkflowInfo const>();
for (o2::framework::DeviceSpec const& device : workflows.devices) {
// Look for propagation service
if (device.name.compare("propagation-service") == 0) {
LOGF(info, " ---> propagation service detected, checking if photons enabled...");
for (auto const& option : device.options) {
// check for photon generation enabled or not
if (option.name.compare("v0BuilderOpts.generatePhotonCandidates") == 0) {
if (option.defaultValue.get<bool>()) {
LOGF(info, " ---> propagation service: photons enabled, will calculate TPC PID for TPC only tracks.");
pidTPCopts.skipTPCOnly.value = 0;
} else {
LOGF(info, " ---> propagation service: photons disabled, TPC PID not required for TPC-only tracks");
}
}
}
}

// Check 2: specific tasks that require TPC PID based on configurable
for (std::size_t devIdx{0}; devIdx < pidTPCopts.devicesRequiringTPCOnlyPID->size(); devIdx++) {
if (device.name.compare(pidTPCopts.devicesRequiringTPCOnlyPID->at(devIdx)) == 0) {
LOGF(info, " ---> %s detected! ", pidTPCopts.devicesRequiringTPCOnlyPID->at(devIdx));
LOGF(info, " ---> enabling TPC only track TPC PID calculations now.");
pidTPCopts.skipTPCOnly.value = 0;
}
}
}

if (pidTPCopts.skipTPCOnly.value == 1) {
LOGF(info, "***************************************************");
LOGF(info, "No need for TPC only information detected. Will not generate Nsigma for TPC only tracks");
LOGF(info, "If this is unexpected behaviour and a necessity was not identified, please add the");
LOGF(info, "corresponding task to the list 'devicesRequiringTPCOnlyPID' in pidTPCModule::Init()");
}
LOGF(info, "***************************************************");
}

// initialize PID response
response = new o2::pid::tpc::Response();

Expand Down Expand Up @@ -330,12 +385,16 @@
LOG(info) << "Successfully retrieved TPC PID object from CCDB for timestamp " << time << ", period " << headers["LPMProductionTag"] << ", recoPass " << headers["RecoPassName"];
metadata["RecoPassName"] = headers["RecoPassName"]; // Force pass number for NN request to match retrieved BB
o2::parameters::GRPLHCIFData* grpo = ccdb->template getForTimeStamp<o2::parameters::GRPLHCIFData>(pidTPCopts.cfgPathGrpLhcIf.value, time);
LOG(info) << " collision type::" << CollisionSystemType::getCollisionTypeFromGrp(grpo);
collsys = CollisionSystemType::getCollisionTypeFromGrp(grpo);
if (collsys == CollisionSystemType::kCollSyspp) {
irSource = std::string("T0VTX");
if (grpo) {
LOG(info) << " collision type::" << CollisionSystemType::getCollisionTypeFromGrp(grpo);
collsys = CollisionSystemType::getCollisionTypeFromGrp(grpo);
if (collsys == CollisionSystemType::kCollSyspp) {
irSource = std::string("T0VTX");
} else {
irSource = std::string("ZNC hadronic");
}
} else {
irSource = std::string("ZNC hadronic");
LOGF(info, "No grpo object found. irSource will remain undefined.");
}
response->PrintAll();
}
Expand Down Expand Up @@ -412,12 +471,16 @@
LOG(info) << "Successfully retrieved TPC PID object from CCDB for timestamp " << bc.timestamp() << ", period " << headers["LPMProductionTag"] << ", recoPass " << headers["RecoPassName"];
metadata["RecoPassName"] = headers["RecoPassName"]; // Force pass number for NN request to match retrieved BB
o2::parameters::GRPLHCIFData* grpo = ccdb->template getForTimeStamp<o2::parameters::GRPLHCIFData>(pidTPCopts.cfgPathGrpLhcIf.value, bc.timestamp());
LOG(info) << "Collision type::" << CollisionSystemType::getCollisionTypeFromGrp(grpo);
collsys = CollisionSystemType::getCollisionTypeFromGrp(grpo);
if (collsys == CollisionSystemType::kCollSyspp) {
irSource = std::string("T0VTX");
if (grpo) {
LOG(info) << "Collision type::" << CollisionSystemType::getCollisionTypeFromGrp(grpo);
collsys = CollisionSystemType::getCollisionTypeFromGrp(grpo);
if (collsys == CollisionSystemType::kCollSyspp) {
irSource = std::string("T0VTX");
} else {
irSource = std::string("ZNC hadronic");
}
} else {
irSource = std::string("ZNC hadronic");
LOGF(info, "No grpo object found. irSource will remain undefined.");
}
response->PrintAll();
}
Expand Down Expand Up @@ -458,11 +521,19 @@
size_t i = 0;
for (const auto& collision : collisions) {
const auto& bc = collision.template bc_as<B>();
hadronicRateForCollision[i] = mRateFetcher.fetch(ccdb.service, bc.timestamp(), bc.runNumber(), irSource) * 1.e-3;
if (irSource.compare("") != 0) {
hadronicRateForCollision[i] = mRateFetcher.fetch(ccdb.service, bc.timestamp(), bc.runNumber(), irSource) * 1.e-3;
} else {
hadronicRateForCollision[i] = 0.0f;
}
i++;
}
auto bc = bcs.begin();
hadronicRateBegin = mRateFetcher.fetch(ccdb.service, bc.timestamp(), bc.runNumber(), irSource) * 1.e-3; // kHz
if (irSource.compare("") != 0) {
hadronicRateBegin = mRateFetcher.fetch(ccdb.service, bc.timestamp(), bc.runNumber(), irSource) * 1.e-3; // kHz
} else {
hadronicRateBegin = 0.0f;
}

// Filling a std::vector<float> to be evaluated by the network
// Evaluation on single tracks brings huge overhead: Thus evaluation is done on one large vector
Expand Down Expand Up @@ -685,11 +756,19 @@
size_t i = 0;
for (const auto& collision : cols) {
const auto& bc = collision.template bc_as<aod::BCsWithTimestamps>();
hadronicRateForCollision[i] = mRateFetcher.fetch(ccdb.service, bc.timestamp(), bc.runNumber(), irSource) * 1.e-3;
if (irSource.compare("") != 0) {
hadronicRateForCollision[i] = mRateFetcher.fetch(ccdb.service, bc.timestamp(), bc.runNumber(), irSource) * 1.e-3;
} else {
hadronicRateForCollision[i] = 0.0f;
}
i++;
}
auto bc = bcs.begin();
hadronicRateBegin = mRateFetcher.fetch(ccdb.service, bc.timestamp(), bc.runNumber(), irSource) * 1.e-3; // kHz
if (irSource.compare("") != 0) {
hadronicRateBegin = mRateFetcher.fetch(ccdb.service, bc.timestamp(), bc.runNumber(), irSource) * 1.e-3; // kHz
} else {
hadronicRateBegin = 0.0f;
}
}

for (auto const& trk : tracks) {
Expand Down Expand Up @@ -797,12 +876,16 @@
}
LOG(info) << "Successfully retrieved TPC PID object from CCDB for timestamp " << bc.timestamp() << ", period " << headers["LPMProductionTag"] << ", recoPass " << headers["RecoPassName"];
o2::parameters::GRPLHCIFData* grpo = ccdb->template getForTimeStamp<o2::parameters::GRPLHCIFData>(pidTPCopts.cfgPathGrpLhcIf.value, bc.timestamp());
LOG(info) << "Collisions type::" << CollisionSystemType::getCollisionTypeFromGrp(grpo);
collsys = CollisionSystemType::getCollisionTypeFromGrp(grpo);
if (collsys == CollisionSystemType::kCollSyspp) {
irSource = std::string("T0VTX");
if (grpo) {
LOG(info) << "Collisions type::" << CollisionSystemType::getCollisionTypeFromGrp(grpo);
collsys = CollisionSystemType::getCollisionTypeFromGrp(grpo);
if (collsys == CollisionSystemType::kCollSyspp) {
irSource = std::string("T0VTX");
} else {
irSource = std::string("ZNC hadronic");
}
} else {
irSource = std::string("ZNC hadronic");
LOGF(info, "No grpo object found. irSource will remain undefined.");
}
response->PrintAll();
}
Expand Down
Loading