|
18 | 18 | /// \brief Task to produce PID tables for TPC split for each particle. |
19 | 19 | /// Only the tables for the mass hypotheses requested are filled, and only for the requested table size ("Full" or "Tiny"). The others are sent empty. |
20 | 20 | /// |
21 | | -#include <utility> |
22 | 21 | #include <map> |
23 | 22 | #include <memory> |
24 | 23 | #include <string> |
| 24 | +#include <utility> |
25 | 25 | #include <vector> |
26 | 26 | // ROOT includes |
27 | 27 | #include "TFile.h" |
28 | 28 | #include "TRandom.h" |
29 | 29 | #include "TSystem.h" |
30 | 30 |
|
31 | 31 | // O2 includes |
| 32 | +#include "MetadataHelper.h" |
| 33 | +#include "TableHelper.h" |
| 34 | +#include "pidTPCBase.h" |
| 35 | + |
| 36 | +#include "Common/Core/PID/TPCPIDResponse.h" |
| 37 | +#include "Common/DataModel/EventSelection.h" |
| 38 | +#include "Common/DataModel/Multiplicity.h" |
| 39 | +#include "Common/DataModel/PIDResponseTPC.h" |
| 40 | +#include "Tools/ML/model.h" |
| 41 | + |
32 | 42 | #include "CCDB/BasicCCDBManager.h" |
| 43 | +#include "CCDB/CcdbApi.h" |
| 44 | +#include "Framework/ASoAHelpers.h" |
| 45 | +#include "Framework/AnalysisDataModel.h" |
33 | 46 | #include "Framework/AnalysisTask.h" |
34 | 47 | #include "Framework/runDataProcessing.h" |
35 | | -#include "Framework/ASoAHelpers.h" |
36 | 48 | #include "ReconstructionDataFormats/Track.h" |
37 | | -#include "CCDB/CcdbApi.h" |
38 | | -#include "Common/DataModel/PIDResponseTPC.h" |
39 | | -#include "Common/Core/PID/TPCPIDResponse.h" |
40 | | -#include "Framework/AnalysisDataModel.h" |
41 | | -#include "Common/DataModel/Multiplicity.h" |
42 | | -#include "Common/DataModel/EventSelection.h" |
43 | | -#include "TableHelper.h" |
44 | | -#include "Tools/ML/model.h" |
45 | | -#include "pidTPCBase.h" |
46 | | -#include "MetadataHelper.h" |
47 | 49 |
|
48 | 50 | using namespace o2; |
49 | 51 | using namespace o2::framework; |
@@ -155,8 +157,10 @@ struct tpcPid { |
155 | 157 | void init(o2::framework::InitContext& initContext) |
156 | 158 | { |
157 | 159 | // Protection for process flags |
158 | | - if ((doprocessStandard && doprocessMcTuneOnData) || (!doprocessStandard && !doprocessMcTuneOnData)) { |
159 | | - LOG(fatal) << "pid-tpc must have only one of the options 'processStandard' OR 'processMcTuneOnData' enabled. Please check your configuration."; |
| 160 | + if (!((doprocessStandard && !doprocessStandard2 && !doprocessMcTuneOnData) || |
| 161 | + (!doprocessStandard && doprocessStandard2 && !doprocessMcTuneOnData) || |
| 162 | + (!doprocessStandard && !doprocessStandard2 && doprocessMcTuneOnData))) { |
| 163 | + LOG(fatal) << "pid-tpc must have only one of the options 'processStandard', 'processStandard2', 'processMcTuneOnData' enabled. Please check your configuration."; |
160 | 164 | } |
161 | 165 | response = new o2::pid::tpc::Response(); |
162 | 166 | // Checking the tables are requested in the workflow and enabling them |
@@ -552,6 +556,98 @@ struct tpcPid { |
552 | 556 | Partition<TrksMC> mcnotTPCStandaloneTracks = (aod::track::tpcNClsFindable > static_cast<uint8_t>(0)) && ((aod::track::itsClusterSizes > static_cast<uint32_t>(0)) || (aod::track::trdPattern > static_cast<uint8_t>(0)) || (aod::track::tofExpMom > 0.f && aod::track::tofChi2 > 0.f)); // To count number of tracks for use in NN array |
553 | 557 | Partition<TrksMC> mctracksWithTPC = (aod::track::tpcNClsFindable > (uint8_t)0); |
554 | 558 |
|
| 559 | + void processStandard2(Coll const& collisions, Trks const& tracks, aod::DEdxsCorrected const& dedxscorrected, aod::BCsWithTimestamps const& bcs) |
| 560 | + { |
| 561 | + const uint64_t outTable_size = tracks.size(); |
| 562 | + const uint64_t dedxscorrected_size = dedxscorrected.size(); |
| 563 | + |
| 564 | + if (dedxscorrected_size != outTable_size) { |
| 565 | + LOG(fatal) << "Size of dEdx corrected table does not match size of tracks! dEdx size: " << dedxscorrected_size << ", tracks size: " << outTable_size; |
| 566 | + } |
| 567 | + |
| 568 | + auto reserveTable = [&outTable_size](const Configurable<int>& flag, auto& table) { |
| 569 | + if (flag.value != 1) { |
| 570 | + return; |
| 571 | + } |
| 572 | + table.reserve(outTable_size); |
| 573 | + }; |
| 574 | + |
| 575 | + // Prepare memory for enabled tables |
| 576 | + reserveTable(pidFullEl, tablePIDFullEl); |
| 577 | + reserveTable(pidFullMu, tablePIDFullMu); |
| 578 | + reserveTable(pidFullPi, tablePIDFullPi); |
| 579 | + reserveTable(pidFullKa, tablePIDFullKa); |
| 580 | + reserveTable(pidFullPr, tablePIDFullPr); |
| 581 | + reserveTable(pidFullDe, tablePIDFullDe); |
| 582 | + reserveTable(pidFullTr, tablePIDFullTr); |
| 583 | + reserveTable(pidFullHe, tablePIDFullHe); |
| 584 | + reserveTable(pidFullAl, tablePIDFullAl); |
| 585 | + |
| 586 | + reserveTable(pidTinyEl, tablePIDTinyEl); |
| 587 | + reserveTable(pidTinyMu, tablePIDTinyMu); |
| 588 | + reserveTable(pidTinyPi, tablePIDTinyPi); |
| 589 | + reserveTable(pidTinyKa, tablePIDTinyKa); |
| 590 | + reserveTable(pidTinyPr, tablePIDTinyPr); |
| 591 | + reserveTable(pidTinyDe, tablePIDTinyDe); |
| 592 | + reserveTable(pidTinyTr, tablePIDTinyTr); |
| 593 | + reserveTable(pidTinyHe, tablePIDTinyHe); |
| 594 | + reserveTable(pidTinyAl, tablePIDTinyAl); |
| 595 | + |
| 596 | + const uint64_t tracksForNet_size = (skipTPCOnly) ? notTPCStandaloneTracks.size() : tracksWithTPC.size(); |
| 597 | + std::vector<float> network_prediction; |
| 598 | + |
| 599 | + if (useNetworkCorrection) { |
| 600 | + network_prediction = createNetworkPrediction(collisions, tracks, bcs, tracksForNet_size); |
| 601 | + } |
| 602 | + |
| 603 | + uint64_t count_tracks = 0; |
| 604 | + uint64_t count_tracks2 = 0; |
| 605 | + |
| 606 | + for (auto const& trk : tracks) { |
| 607 | + // Loop on Tracks |
| 608 | + |
| 609 | + const auto& bc = trk.has_collision() ? collisions.iteratorAt(trk.collisionId()).bc_as<aod::BCsWithTimestamps>() : bcs.begin(); |
| 610 | + auto dedx_corr = dedxscorrected.iteratorAt(count_tracks2); |
| 611 | + count_tracks2++; |
| 612 | + if (useCCDBParam && ccdbTimestamp.value == 0 && !ccdb->isCachedObjectValid(ccdbPath.value, bc.timestamp())) { // Updating parametrisation only if the initial timestamp is 0 |
| 613 | + if (recoPass.value == "") { |
| 614 | + LOGP(info, "Retrieving latest TPC response object for timestamp {}:", bc.timestamp()); |
| 615 | + } else { |
| 616 | + LOGP(info, "Retrieving TPC Response for timestamp {} and recoPass {}:", bc.timestamp(), recoPass.value); |
| 617 | + } |
| 618 | + response = ccdb->getSpecific<o2::pid::tpc::Response>(ccdbPath.value, bc.timestamp(), metadata); |
| 619 | + headers = ccdbApi.retrieveHeaders(ccdbPath.value, metadata, bc.timestamp()); |
| 620 | + if (!response) { |
| 621 | + LOGP(warning, "!! Could not find a valid TPC response object for specific pass name {}! Falling back to latest uploaded object.", metadata["RecoPassName"]); |
| 622 | + response = ccdb->getForTimeStamp<o2::pid::tpc::Response>(ccdbPath.value, bc.timestamp()); |
| 623 | + headers = ccdbApi.retrieveHeaders(ccdbPath.value, nullmetadata, bc.timestamp()); |
| 624 | + if (!response) { |
| 625 | + LOGP(fatal, "Could not find ANY TPC response object for the timestamp {}!", bc.timestamp()); |
| 626 | + } |
| 627 | + } |
| 628 | + LOG(info) << "Successfully retrieved TPC PID object from CCDB for timestamp " << bc.timestamp() << ", period " << headers["LPMProductionTag"] << ", recoPass " << headers["RecoPassName"]; |
| 629 | + response->PrintAll(); |
| 630 | + } |
| 631 | + auto makePidTablesDefault = [&trk, &dedx_corr, &collisions, &network_prediction, &count_tracks, &tracksForNet_size, this](const int flagFull, auto& tableFull, const int flagTiny, auto& tableTiny, const o2::track::PID::ID pid) { |
| 632 | + makePidTables(flagFull, tableFull, flagTiny, tableTiny, pid, dedx_corr.tpcSignalCorrected(), trk, collisions, network_prediction, count_tracks, tracksForNet_size); |
| 633 | + }; |
| 634 | + |
| 635 | + makePidTablesDefault(pidFullEl, tablePIDFullEl, pidTinyEl, tablePIDTinyEl, o2::track::PID::Electron); |
| 636 | + makePidTablesDefault(pidFullMu, tablePIDFullMu, pidTinyMu, tablePIDTinyMu, o2::track::PID::Muon); |
| 637 | + makePidTablesDefault(pidFullPi, tablePIDFullPi, pidTinyPi, tablePIDTinyPi, o2::track::PID::Pion); |
| 638 | + makePidTablesDefault(pidFullKa, tablePIDFullKa, pidTinyKa, tablePIDTinyKa, o2::track::PID::Kaon); |
| 639 | + makePidTablesDefault(pidFullPr, tablePIDFullPr, pidTinyPr, tablePIDTinyPr, o2::track::PID::Proton); |
| 640 | + makePidTablesDefault(pidFullDe, tablePIDFullDe, pidTinyDe, tablePIDTinyDe, o2::track::PID::Deuteron); |
| 641 | + makePidTablesDefault(pidFullTr, tablePIDFullTr, pidTinyTr, tablePIDTinyTr, o2::track::PID::Triton); |
| 642 | + makePidTablesDefault(pidFullHe, tablePIDFullHe, pidTinyHe, tablePIDTinyHe, o2::track::PID::Helium3); |
| 643 | + makePidTablesDefault(pidFullAl, tablePIDFullAl, pidTinyAl, tablePIDTinyAl, o2::track::PID::Alpha); |
| 644 | + |
| 645 | + if (trk.hasTPC() && (!skipTPCOnly || trk.hasITS() || trk.hasTRD() || trk.hasTOF())) { |
| 646 | + count_tracks++; // Increment network track counter only if track has TPC, and (not skipping TPConly) or (is not TPConly) |
| 647 | + } |
| 648 | + } |
| 649 | + } |
| 650 | + PROCESS_SWITCH(tpcPid, processStandard2, "Creating PID tables with Corrected dEdx", false); |
555 | 651 | void processMcTuneOnData(CollMC const& collisionsMc, TrksMC const& tracksMc, aod::BCsWithTimestamps const& bcs, aod::McParticles const&) |
556 | 652 | { |
557 | 653 | gRandom->SetSeed(0); // Ensure unique seed from UUID for each process call |
|
0 commit comments