13#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
15#include <fmt/format.h>
24#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) && defined(DEBUG_STREAMER)
26o2::utils::DebugStreamer::DebugStreamer()
28 ROOT::EnableThreadSafety();
31void o2::utils::DebugStreamer::setStreamer(
const char* outFile,
const char* option,
const size_t id)
33 if (!isStreamerSet(
id)) {
34 mTreeStreamer[
id] = std::make_unique<o2::utils::TreeStreamRedirector>(fmt::format(
"{}_{}.root", outFile,
id).
data(), option);
40 setStreamer(outFile, option,
id);
41 return getStreamer(
id);
44void o2::utils::DebugStreamer::flush(
const size_t id)
46 if (isStreamerSet(
id)) {
47 mTreeStreamer[
id].reset();
51void o2::utils::DebugStreamer::flush()
53 for (
const auto& pair : mTreeStreamer) {
58bool o2::utils::DebugStreamer::checkStream(
const StreamFlags streamFlag,
const size_t samplingID,
const float weight)
60 const bool isStreamerSet = ((getStreamFlags() & streamFlag) == streamFlag);
66 const auto sampling = getSamplingTypeFrequency(streamFlag);
68 auto sampleTrack = [&]() {
69 if (samplingID == -1) {
70 LOGP(fatal,
"Sampling type sampleID not supported for stream flag {}", (
int)streamFlag);
73 static thread_local std::unordered_map<StreamFlags, std::pair<size_t, bool>> idMap;
75 if (idMap[streamFlag].
first != samplingID) {
76 idMap[streamFlag] = std::pair<size_t, bool>{samplingID, (getRandom() < sampling.second)};
78 return idMap[streamFlag].second;
83 return (getRandom() < sampling.second);
88 static tbb::concurrent_unordered_map<int, tbb::concurrent_unordered_map<size_t, bool>> refIDs;
92 auto it = refIDs[
index].find(samplingID);
98 const bool storeTrk = sampleTrack();
99 refIDs[
index][samplingID] = storeTrk;
104 return (
weight * getRandom() < sampling.second);
110float o2::utils::DebugStreamer::getRandom(
float min,
float max)
113 static thread_local std::mt19937 generator(std::random_device{}());
115 const float rnd =
distr(generator);
119int o2::utils::DebugStreamer::getIndex(
const StreamFlags streamFlag)
122 uint32_t
v = streamFlag;
124 v =
v - ((
v >> 1) & 0x55555555);
125 v = (
v & 0x33333333) + ((
v >> 2) & 0x33333333);
126 const uint32_t ind = (((
v + (
v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24);
130std::pair<o2::utils::SamplingTypes, float> o2::utils::DebugStreamer::getSamplingTypeFrequency(
const StreamFlags streamFlag)
132 const int ind =
getIndex(streamFlag);
136std::string o2::utils::DebugStreamer::getUniqueTreeName(
const char*
tree,
const size_t id)
const {
return fmt::format(
"{}_{}",
tree, getNTrees(
id)); }
138size_t o2::utils::DebugStreamer::getCPUID() {
return std::hash<std::thread::id>{}(std::this_thread::get_id()); }
142 auto it = mTreeStreamer.find(
id);
143 if (it != mTreeStreamer.end()) {
144 return (it->second).get();
150int o2::utils::DebugStreamer::getNTrees(
const size_t id)
const {
return isStreamerSet(
id) ? getStreamerPtr(
id)->
GetFile()->GetListOfKeys()->GetEntries() : -1; }
152void o2::utils::DebugStreamer::mergeTrees(
const char* inpFile,
const char* outFile,
const char* option)
154 TFile fInp(inpFile,
"READ");
155 std::unordered_map<std::string, TList>
lists;
156 for (
TObject* keyAsObj : *fInp.GetListOfKeys()) {
157 const auto key =
dynamic_cast<TKey*
>(keyAsObj);
158 TTree*
tree = (TTree*)fInp.Get(
key->GetName());
160 const int entries =
tree->GetListOfBranches()->GetEntries();
161 const std::string brName =
key->GetName();
162 const std::string nameBr = brName.substr(0, brName.find_last_of(
"_"));
166 TFile fOut(outFile,
"RECREATE");
168 auto tree = TTree::MergeTrees(&
list.second, option);
173void o2::utils::DebugStreamer::enableStream(
const StreamFlags streamFlag)
176 streamlevel = streamFlag | streamlevel;
177 setStreamFlags(streamlevel);
180void o2::utils::DebugStreamer::disableStream(
const StreamFlags streamFlag)
183 streamlevel = (~streamFlag) & streamlevel;
184 setStreamFlags(streamlevel);
#define O2ParamImpl(classname)
Definition of class for writing debug informations.
static const ParameterDebugStreamer & Instance()
GLuint GLuint GLfloat weight
constexpr auto getIndex(const container_T &container, typename container_T::const_iterator iter) -> typename container_T::source_type
@ sampleIDGlobal
in case different streamers have access to the same IDs use this gloabl ID
@ sampleAll
use all data (default)
@ sampleID
sample every n IDs (per example track)
@ sampleWeights
perform sampling on weights, defined where the streamer is called
@ sampleRandom
sample randomly every n points
StreamFlags
struct defining the flags which can be used to check if a certain debug streamer is used
struct for setting and storing the streamer level
int sampleIDGlobal[StreamFlags::streamFlagsCount]
storage of reference streamer used for sampleIDFromOtherStreamer
float samplingFrequency[StreamFlags::streamFlagsCount]
frequency which is used for the sampling (0.1 -> 10% is written if sampling is used)
SamplingTypes samplingType[StreamFlags::streamFlagsCount]
flag to store what will be streamed
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))
std::uniform_int_distribution< unsigned long long > distr