25constexpr HistogramRegistry::HistName::HistName(
char const*
const name)
32HistogramRegistry::HistogramRegistry(
char const*
const name, std::vector<HistogramSpec> histSpecs,
OutputObjHandlingPolicy policy,
bool sortHistos,
bool createRegistryDir)
33 : mName(
name), mPolicy(policy), mCreateRegistryDir(createRegistryDir), mSortHistos(sortHistos), mRegistryKey(), mRegistryValue()
35 mRegistryKey.fill(0u);
36 for (
auto& histSpec : histSpecs) {
46 std::memset(desc.str,
'_', 16);
48 s << std::hex << lhash;
49 s << std::hex << mTaskHash;
50 s << std::hex << reinterpret_cast<uint64_t>(
this);
51 std::memcpy(desc.str,
s.str().data(), 12);
60 header.createContainer = mCreateRegistryDir ? 1 : 0;
72 validateHistName(histSpec.
name, histSpec.
hash);
74 for (
auto i = 0u;
i < MAX_REGISTRY_SIZE; ++
i) {
76 std::visit([&](
const auto& sharedPtr) { rawPtr = sharedPtr.get(); }, mRegistryValue[imask(idx +
i)]);
78 registerName(histSpec.
name);
79 mRegistryKey[imask(idx +
i)] = histSpec.
hash;
82 return mRegistryValue[imask(idx +
i)];
85 LOGF(fatal, R
"(Internal array of HistogramRegistry "%s" is full.)", mName);
90void HistogramRegistry::validateHistName(
const std::string&
name,
const uint32_t hash)
93 if (mRegisteredNames.size() == MAX_REGISTRY_SIZE) {
94 LOGF(fatal, R
"(HistogramRegistry "%s" is full! It can hold only %d histograms.)", mName, MAX_REGISTRY_SIZE);
98 auto it = std::find(mRegistryKey.begin(), mRegistryKey.end(),
hash);
99 if (it != mRegistryKey.end()) {
100 auto idx = it - mRegistryKey.begin();
101 std::string collidingName{};
102 std::visit([&](
const auto& hist) { collidingName = hist->GetName(); }, mRegistryValue[
idx]);
103 LOGF(fatal, R
"(Hash collision in HistogramRegistry "%s"! Please rename histogram "%s" or "%s".)", mName, name, collidingName);
107 if (!std::regex_match(
name, std::regex(
"([a-zA-Z0-9])(([\\/_-])?[a-zA-Z0-9])*"))) {
108 LOGF(fatal, R
"(Histogram name "%s" contains invalid characters. Only letters, numbers, and (except for the beginning or end of the word) the special characters '/', '_', '-' are allowed.)", name);
114 return insert(histSpec);
119 return insert({
name, title, histConfigSpec, callSumw2});
124 return insert({
name, title, {histType, axes}, callSumw2});
129 return add(
name.c_str(), title, histType, axes, callSumw2);
135 auto doInsertClone = [&](
const auto& sharedPtr) {
136 if (!sharedPtr.get()) {
139 std::string sourceName{((TNamed*)sharedPtr.get())->GetName()};
141 if (sourceName.rfind(
source, 0) == 0) {
143 if (sourceName.size() !=
source.size() && (
source.back() !=
'/' ||
target.back() !=
'/')) {
147 if (sourceName.size() ==
source.size() &&
target.back() ==
'/') {
148 LOGF(fatal,
"Cannot turn histogram into folder!");
150 std::string targetName{
target};
151 targetName += sourceName.substr(sourceName.find(
source) +
source.size());
152 insertClone(targetName.data(), sharedPtr);
156 for (
auto& histVariant : mRegistryValue) {
157 std::visit(doInsertClone, histVariant);
165 auto iter = mRegistryKey.begin();
166 while ((iter = std::find(iter, mRegistryKey.end(), histName.hash)) != mRegistryKey.end()) {
167 const char* curName =
nullptr;
168 std::visit([&](
auto&& hist) {
if(hist) { curName = hist->GetName(); } }, mRegistryValue[iter - mRegistryKey.begin()]);
170 if (strcmp(curName, histName.str) == 0) {
181 std::visit([&fillFraction, &
size](
auto&& hist) {
size =
HistFiller::getSize(hist, fillFraction); }, mRegistryValue[getHistIndex(histName)]);
189 for (
auto j = 0u;
j < MAX_REGISTRY_SIZE; ++
j) {
197 for (
auto&
value : mRegistryValue) {
198 std::visit([](
auto&& hist) { hist.reset(); },
value);
205 std::vector<double> fillFractions{0.1, 0.25, 0.5};
206 std::vector<double> totalSizes(fillFractions.size());
209 bool containsSparseHist{};
210 auto printHistInfo = [&](
auto&& hist) {
212 using T = std::decay_t<
decltype(*hist)>;
214 if (hist->InheritsFrom(THnSparse::Class())) {
216 containsSparseHist =
true;
219 std::vector<double>
sizes;
220 std::string sizeInfo{};
222 std::transform(std::begin(fillFractions), std::end(fillFractions), std::back_inserter(
sizes), [&hist](
auto& fraction) {
return HistFiller::getSize(hist, fraction); });
223 for (
int i = 0;
i < fillFractions.size(); ++
i) {
224 sizeInfo += fmt::format(
"{:.2f} kB ({:.0f} %)",
sizes[
i] * 1024, fillFractions[
i] * 100);
225 if (
i != fillFractions.size() - 1) {
231 sizes.resize(fillFractions.size(),
size);
232 sizeInfo = fmt::format(
"{:.2f} kB",
sizes[0] * 1024);
234 std::transform(totalSizes.begin(), totalSizes.end(),
sizes.begin(), totalSizes.begin(), std::plus<double>());
235 LOGF(info,
"Hist %03d: %-35s %-19s [%s]", nHistos, hist->GetName(), hist->IsA()->GetName(), sizeInfo);
237 if (showAxisDetails) {
239 if constexpr (std::is_base_of_v<THnBase, T>) {
240 nDim = hist->GetNdimensions();
241 }
else if constexpr (std::is_base_of_v<TH1, T>) {
242 nDim = hist->GetDimension();
244 TAxis* axis{
nullptr};
245 for (
int d = 0;
d < nDim; ++
d) {
246 if constexpr (std::is_base_of_v<THnBase, T> || std::is_base_of_v<StepTHn, T>) {
247 axis = hist->GetAxis(
d);
250 axis = hist->GetXaxis();
252 axis = hist->GetYaxis();
254 axis = hist->GetZaxis();
257 LOGF(info,
"- Axis %d: %-20s (%d bins)",
d, axis->GetTitle(), axis->GetNbins());
263 std::string titleString{
"======================== HistogramRegistry ========================"};
265 LOGF(info,
"%s", titleString);
266 LOGF(info,
"%s\"%s\"", std::string((
int)(0.5 * titleString.size() - (1 + 0.5 * mName.size())),
' '), mName);
267 for (
auto& curHistName : mRegisteredNames) {
268 std::visit(printHistInfo, mRegistryValue[getHistIndex(HistName{curHistName.data()})]);
270 std::string totalSizeInfo{};
271 if (containsSparseHist) {
272 for (
int i = 0;
i < totalSizes.size(); ++
i) {
273 totalSizeInfo += fmt::format(
"{:.2f} MB ({:.0f} %)", totalSizes[
i], fillFractions[
i] * 100);
274 if (
i != totalSizes.size() - 1) {
275 totalSizeInfo +=
", ";
279 totalSizeInfo = fmt::format(
"{:.2f} MB", totalSizes[0]);
281 LOGF(info,
"%s", std::string(titleString.size(),
'='), titleString);
282 LOGF(info,
"Total: %d histograms, ca. %s", nHistos, totalSizeInfo);
284 LOGF(info,
"Due to index collisions, histograms were shifted by %d registry slots in total.",
lookup);
286 LOGF(info,
"%s", std::string(titleString.size(),
'='), titleString);
293 auto finalList = mRegisteredNames;
294 auto caseInsensitiveCompare = [](
const std::string&
s1,
const std::string& s2) {
295 return std::lexicographical_compare(
s1.begin(),
s1.end(), s2.begin(), s2.end(),
296 [](
char c1,
char c2) { return std::tolower(static_cast<unsigned char>(c1)) < std::tolower(static_cast<unsigned char>(c2)); });
299 std::sort(finalList.begin(), finalList.end(), caseInsensitiveCompare);
301 for (
auto& curHistName : finalList) {
302 TNamed* rawPtr =
nullptr;
303 std::visit([&](
const auto& sharedPtr) { rawPtr = (TNamed*)sharedPtr.get(); }, mRegistryValue[getHistIndex(HistName{curHistName.data()})]);
308 callback(*
this, rawPtr);
313std::deque<std::string> HistogramRegistry::splitPath(
const std::string& pathAndNameUser)
315 std::istringstream pathAndNameStream(pathAndNameUser);
316 std::deque<std::string> pathAndName;
318 while (std::getline(pathAndNameStream, curDir,
'/')) {
319 pathAndName.push_back(curDir);
325void HistogramRegistry::registerName(
const std::string&
name)
327 if (
name.empty() ||
name.back() ==
'/') {
328 LOGF(fatal,
"Invalid name for a histogram.");
330 std::deque<std::string>
path = splitPath(
name);
331 std::string cumulativeName{};
333 for (
auto& step :
path) {
335 LOGF(fatal, R
"(Found empty group name in path for histogram "%s".)", name);
337 cumulativeName += step;
338 for (
auto& curName : mRegisteredNames) {
340 if (cumulativeName == curName) {
341 LOGF(fatal, R
"(Histogram name "%s" is not compatible with existing names.)", name);
345 if (curName.rfind(cumulativeName, 0) == 0 && curName.size() > cumulativeName.size() && curName.at(cumulativeName.size()) ==
'/') {
346 LOGF(fatal, R
"(Histogram name "%s" is not compatible with existing names.)", name);
351 cumulativeName += "/";
353 mRegisteredNames.push_back(
name);
356void HistFiller::badHistogramFill(
char const*
name)
358 LOGF(fatal,
"The number of arguments in fill function called for histogram %s is incompatible with histogram dimensions.",
name);
362HistPtr HistogramRegistry::insertClone(
const HistName& histName,
const std::shared_ptr<T> originalHist)
364 validateHistName(histName.str, histName.hash);
365 for (
auto i = 0u;
i < MAX_REGISTRY_SIZE; ++
i) {
367 std::visit([&](
const auto& sharedPtr) { rawPtr = sharedPtr.get(); }, mRegistryValue[imask(histName.idx +
i)]);
369 registerName(histName.str);
370 mRegistryKey[imask(histName.idx +
i)] = histName.hash;
371 mRegistryValue[imask(histName.idx +
i)] = std::shared_ptr<T>(
static_cast<T*
>(originalHist->Clone(histName.str)));
373 return mRegistryValue[imask(histName.idx +
i)];
376 LOGF(fatal, R
"(Internal array of HistogramRegistry "%s" is full.)", mName);
380template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TH1>);
381template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TH2>);
382template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TH3>);
383template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TProfile>);
384template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TProfile2D>);
385template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<TProfile3D>);
386template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<THnSparse>);
387template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<THn>);
388template HistPtr HistogramRegistry::insertClone(
const HistName&,
const std::shared_ptr<StepTHn>);
393 auto histVariant =
add(
name, title, histConfigSpec, callSumw2);
394 if (
auto histPtr = std::get_if<std::shared_ptr<T>>(&histVariant)) {
397 throw runtime_error_f(R
"(Histogram type specified in add<>("%s") does not match the actual type of the histogram!)", name);
404 auto histVariant =
add(
name, title, histType, axes, callSumw2);
405 if (
auto histPtr = std::get_if<std::shared_ptr<T>>(&histVariant)) {
408 throw runtime_error_f(R
"(Histogram type specified in add<>("%s") does not match the actual type of the histogram!)", name);
412template std::shared_ptr<TH1> HistogramRegistry::add<TH1>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
413template std::shared_ptr<TH1> HistogramRegistry::add<TH1>(
char const*
const name,
char const*
const title,
HistType histType,
const std::vector<AxisSpec>& axes,
bool callSumw2);
414template std::shared_ptr<TH2> HistogramRegistry::add<TH2>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
415template std::shared_ptr<TH2> HistogramRegistry::add<TH2>(
char const*
const name,
char const*
const title,
HistType histType,
const std::vector<AxisSpec>& axes,
bool callSumw2);
416template std::shared_ptr<TH3> HistogramRegistry::add<TH3>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
417template std::shared_ptr<TH3> HistogramRegistry::add<TH3>(
char const*
const name,
char const*
const title,
HistType histType,
const std::vector<AxisSpec>& axes,
bool callSumw2);
418template std::shared_ptr<TProfile> HistogramRegistry::add<TProfile>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
419template std::shared_ptr<TProfile> HistogramRegistry::add<TProfile>(
char const*
const name,
char const*
const title,
HistType histType,
const std::vector<AxisSpec>& axes,
bool callSumw2);
420template std::shared_ptr<TProfile2D> HistogramRegistry::add<TProfile2D>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
421template std::shared_ptr<TProfile2D> HistogramRegistry::add<TProfile2D>(
char const*
const name,
char const*
const title,
HistType histType,
const std::vector<AxisSpec>& axes,
bool callSumw2);
422template std::shared_ptr<TProfile3D> HistogramRegistry::add<TProfile3D>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
423template std::shared_ptr<TProfile3D> HistogramRegistry::add<TProfile3D>(
char const*
const name,
char const*
const title,
HistType histType,
const std::vector<AxisSpec>& axes,
bool callSumw2);
424template std::shared_ptr<THn> HistogramRegistry::add<THn>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
425template std::shared_ptr<THn> HistogramRegistry::add<THn>(
char const*
const name,
char const*
const title,
HistType histType,
const std::vector<AxisSpec>& axes,
bool callSumw2);
426template std::shared_ptr<THnSparse> HistogramRegistry::add<THnSparse>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
427template std::shared_ptr<THnSparse> HistogramRegistry::add<THnSparse>(
char const*
const name,
char const*
const title,
HistType histType,
const std::vector<AxisSpec>& axes,
bool callSumw2);
428template std::shared_ptr<StepTHn> HistogramRegistry::add<StepTHn>(
char const*
const name,
char const*
const title,
const HistogramConfigSpec& histConfigSpec,
bool callSumw2);
429template std::shared_ptr<StepTHn> HistogramRegistry::add<StepTHn>(
char const*
const name,
char const*
const title,
HistType histType,
const std::vector<AxisSpec>& axes,
bool callSumw2);
unsigned short int uint16_t
std::vector< std::string > header
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error s
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events d
constexpr uint32_t runtime_hash(char const *str)
bool contains(const HistName &histName)
double getSize(const HistName &histName, double fillFraction=1.)
void fill(const HistName &histName, Ts... positionAndWeight)
void addClone(const std::string &source, const std::string &target)
void print(bool showAxisDetails=false)
void setHash(uint32_t hash)
HistPtr add(const HistogramSpec &histSpec)
void apply(std::function< void(HistogramRegistry const &, TNamed *named)> callback) const
OutputRef ref(uint16_t idx, uint16_t pipelineSize) const
void clean()
deletes all the histograms from the registry
GLuint GLsizei const GLuint const GLintptr const GLsizeiptr * sizes
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
GLuint const GLchar * name
GLsizei GLsizei GLchar * source
GLsizei const GLfloat * value
GLint GLint GLsizei GLsizei GLsizei depth
GLsizei const GLchar *const * path
Defining ITS Vertex explicitly as messageable.
@ HistogramRegistrySource
std::variant< std::shared_ptr< THn >, std::shared_ptr< THnSparse >, std::shared_ptr< TH3 >, std::shared_ptr< TH2 >, std::shared_ptr< TH1 >, std::shared_ptr< TProfile3D >, std::shared_ptr< TProfile2D >, std::shared_ptr< TProfile >, std::shared_ptr< StepTHn > > HistPtr
RuntimeErrorRef runtime_error_f(const char *,...)
OutputObjHandlingPolicy
Policy enum to determine OutputObj handling when writing.
static HistPtr createHistVariant(const HistogramSpec &histSpec)
static double getSize(std::shared_ptr< T > hist, double fillFraction=1.)