33 namespace MD = MultiDimensional;
46 if (name !=
"Total Sum of Weights") {
49 MSG_ERROR(
string(
"A histogram with name '") + name +
string(
"' is already present! Not adding"));
55 MSG_ERROR(
string(
"Invalid histogram definition for histogram '") + name +
56 string(
"'! Not adding. The Sesame Street Count is on his way."));
63 {name,
HistogramDefinition{hasUnderOverFlow, binSizes, ranges, shouldCompress, withErrors}});
74 void Histos::addHistogramDefinition(
const string& name,
const MD::BinEdgeList& binEdges,
75 bool hasUnderOverFlow,
bool shouldCompress,
bool withErrors) {
76 auto it = _histogramDefs.find(name);
77 if (it != _histogramDefs.end() && name !=
"Total Sum of Weights") {
78 MSG_ERROR(
string(
"A histogram with name '") + name +
string(
"' is already present! Not adding"));
81 auto resdef = _histogramDefs.emplace(name,
HistogramDefinition{hasUnderOverFlow, binEdges, shouldCompress, withErrors});
83 MSG_ERROR(
string(
"Invalid histogram definition for histogram '") + name +
string(
"'! Not adding. The Sesame Street Count is on his way."));
89 for(
auto& elem: _dictionaries->schemeDefs().getFFSchemeNames()) {
96 void Histos::createProjectedHistogram(
const string& oldName,
const string& newName,
97 const set<uint16_t>& collapsedIndexPositions) {
98 auto itNew = _histogramDefs.find(newName);
99 auto itOld = _histogramDefs.find(oldName);
100 if (itNew != _histogramDefs.end()) {
101 MSG_ERROR(
string(
"Histogram '") + newName +
string(
"' already exists. Not projecting"));
104 if (itOld == _histogramDefs.end()) {
105 MSG_ERROR(
string(
"Cannot find histogram '") + oldName +
string(
"'. Not projecting"));
109 for(
auto itPos = collapsedIndexPositions.crbegin(); itPos != collapsedIndexPositions.crend(); ++itPos) {
110 newBinEdges.erase(newBinEdges.begin() + *itPos);
112 if(newBinEdges.size() == 0) {
113 MSG_ERROR(
string(
"You are trying to project all the dimensions of histogram '") + oldName +
string(
"'! Mascalzone!"));
117 itOld->second.shouldCompress(),
118 itOld->second.shouldKeepErrors()});
119 if (!resdef.second) {
120 MSG_ERROR(
string(
"Invalid histogram definition for histogram '") + newName +
121 string(
"'! Not adding. The Sesame Street Count is on his way."));
125 auto itHistoOld = _histograms.find(oldName);
126 for(
auto& elemScheme: itHistoOld->second) {
127 resScheme.first->second.emplace(elemScheme.first,
HistogramSet{elemScheme.second, resdef.first->first, resdef.first->second, collapsedIndexPositions});
133 void Histos::removeHistogram(
const string& name) {
134 auto it = _histogramDefs.find(name);
135 if (it == _histogramDefs.end()) {
136 MSG_ERROR(
string(
"Cannot find histogram '") + name +
string(
"'. Not removing"));
139 _histogramDefs.erase(it);
140 _histograms.erase(name);
144 void Histos::setHistogramCompression(
const std::string& name,
bool value) {
145 auto it = _histogramDefs.find(name);
146 if (it == _histogramDefs.end()) {
147 MSG_ERROR(
string(
"Cannot find histogram '") + name +
string(
"'. Not setting compression"));
150 it->second.setCompression(value);
153 void Histos::setHistogramKeepErrors(
const std::string& name,
bool value) {
154 auto it = _histogramDefs.find(name);
155 if (it == _histogramDefs.end()) {
156 MSG_ERROR(
string(
"Cannot find histogram '") + name +
string(
"'. Not setting compression"));
159 it->second.setKeepErrors(value);
163 auto it = _histogramDefs.find(name);
164 if (it == _histogramDefs.end()) {
165 MSG_ERROR(
string(
"Cannot find histogram '") + name +
string(
"'. Not adding fixed data."));
168 it->second.addFixedData(data);
171 void Histos::resetHistogramFixedData(
const std::string& name) {
172 auto it = _histogramDefs.find(name);
173 if (it == _histogramDefs.end()) {
174 MSG_ERROR(
string(
"Cannot find histogram '") + name +
string(
"'. Not resetting fixed data."));
177 it->second.resetFixedData();
180 void Histos::init() {
182 for(
auto& elem: _histograms) {
185 for(
auto& elem: _dictionaries->schemeDefs().getFFSchemeNames()) {
186 for(
auto& elem2: _histograms) {
187 bool compress = _histogramDefs.find(elem2.first)->second.shouldCompress();
191 for(
auto& elem: _histogramDefs) {
192 elem.second.setKeepErrors(elem.second.shouldKeepErrors() || *getSetting<bool>(
"KeepErrors"));
198 _currentEventId = eventId;
201 void Histos::clear() {
203 _histogramDefs.clear();
204 _currentEventId.clear();
205 _initialized =
false;
209 auto it = _histogramDefs.find(name);
210 if(it != _histogramDefs.end()) {
211 return it->second.getIndexing().valueToPos(value);
213 throw Error(
"Histogram name not found. You can't handle the truth!");
216 size_t Histos::size()
const {
217 return _histogramDefs.size();
220 bool Histos::canFill(
const string& name,
const vector<double>& values) {
221 auto it = _histogramDefs.find(name);
222 if(it != _histogramDefs.end()) {
223 return it->second.getIndexing().isValid(values);
225 MSG_ERROR(
string(
"Can't find name ") +
string(name) +
string(
" in histogram request."));
229 void Histos::checkExists(
const string& name) {
230 auto it = _histograms.find(name);
231 if(it == _histograms.end()) {
232 MSG_ERROR(
string(
"The histogram '") +
string(name) +
string(
"' does not exist. The Dude does not abide."));
236 const HistogramSet* Histos::getEntry(
const string& name,
const string& scheme)
const {
237 auto it = _histograms.find(name);
238 if(it != _histograms.end()) {
239 auto it2 = it->second.find(scheme);
240 if(it2 != it->second.end()) {
243 MSG_ERROR(
string(
"Can't find scheme ") +
string(scheme) +
string(
" in histogram request. Returning empty histogram list. Hey Stella!!! (Check addHistogram is applied before initRun)"));
246 MSG_ERROR(
string(
"Can't find name ") +
string(name) +
string(
" in histogram request. Returning empty histogram list. Hey Stella!!! (Check addHistogram is applied before initRun)"));
250 HistogramSet* Histos::getEntry(
const string& name,
const string& scheme) {
251 auto it = _histograms.find(name);
252 if(it != _histograms.end()) {
253 auto it2 = it->second.find(scheme);
254 if(it2 != it->second.end()) {
257 MSG_ERROR(
string(
"Can't find scheme ") +
string(scheme) +
string(
" in histogram request. Returning empty histogram list. Hey Stella!!! (Check addHistogram is applied before initRun)"));
260 MSG_ERROR(
string(
"Can't find name ") +
string(name) +
string(
" in histogram request. Returning empty histogram list. Hey Stella!!! (Check addHistogram is applied before initRun)"));
264 EventUIDGroup Histos::getHistogramEventIds(
const string& name,
const string& scheme)
const {
265 auto entry = getEntry(name, scheme);
266 if(entry !=
nullptr) {
267 return entry->getEventIdsInHistogram();
269 MSG_ERROR(
"Wrong name/scheme in histogram request. Returning empty eventID list.");
276 auto it = _histogramDefs.find(name);
277 if(it != _histogramDefs.end()) {
278 return it->second.getIndexing().edges();
280 MSG_ERROR(
string(
"Can't find name ") +
string(name) +
281 string(
" in histogram request. Returning empty bin edges list. Hey Stella!!! (Check addHistogram is "
282 "applied before initRun)"));
286 IndexList Histos::getHistogramShape(
const string& name)
const {
287 auto it = _histogramDefs.find(name);
288 if (it != _histogramDefs.end()) {
289 return it->second.getIndexing().dims();
291 MSG_ERROR(
string(
"Can't find name ") +
string(name) +
292 string(
" in histogram request. Returning empty bin edges list. Hey Stella!!! (Check addHistogram is "
293 "applied before initRun)"));
297 bool Histos::getUnderOverFlows(
const string& name)
const {
298 auto it = _histogramDefs.find(name);
299 if (it != _histogramDefs.end()) {
300 return it->second.getIndexing().hasUnderOverFlow();
302 MSG_ERROR(
string(
"Can't find name ") +
string(name) +
303 string(
" in histogram request."));
307 vector<Tensor> Histos::getExternalData(
const string& scheme, vector<LabelsList> labels)
const {
308 vector<Tensor> result;
309 result.reserve(labels.size());
310 transform(labels.begin(), labels.end(), back_inserter(result),
312 return _dictionaries->externalData().getExternalVectors(scheme, val);
318 auto entry = getEntry(name, scheme);
319 if(entry !=
nullptr) {
320 auto externalData = getExternalData(scheme, entry->getHistogramLabels());
321 return entry->specializeEventHistograms(externalData);
323 MSG_ERROR(
"Wrong name/scheme in histogram request. Returning empty histogram map");
327 IOHistogram Histos::getHistogram(
const string& name,
const string& scheme)
const {
328 auto entry = getEntry(name, scheme);
329 if(entry !=
nullptr) {
330 auto externalData = getExternalData(scheme, entry->getHistogramLabels());
331 return entry->specializeSumHistogram(externalData);
333 MSG_ERROR(
"Wrong name/scheme in histogram request. Returning empty histogram.");
337 vector<string> Histos::getHistogramNames()
const {
338 vector<string> result;
339 transform(_histogramDefs.begin(), _histogramDefs.end(), back_inserter(result), [](
const pair<string, HistogramDefinition>& val) ->
string {
return val.first; });
343 vector<EventUID> Histos::getEventIDRepsForHisto(
const string& name,
const string& scheme)
const {
344 auto entry = getEntry(name, scheme);
345 if(entry !=
nullptr) {
346 return entry->getEventUIDRepresentatives();
373 bool Histos::isValidHistogram(
const string& name,
size_t dim)
const {
374 auto it = _histogramDefs.find(name);
375 if (it == _histogramDefs.end())
378 auto& def = it->second;
379 valid &= (def.getIndexing().rank() == dim);
385 static unique_ptr<TH1D> createTH1D(
const string& name,
const vector<vector<double>>& edges) {
386 Int_t nbinsX =
static_cast<Int_t
>(edges[0].size()) - 1;
387 unique_ptr<TH1D> result(
new TH1D{name.c_str(), name.c_str(), nbinsX, edges[0].data()});
391 static unique_ptr<TH2D> createTH2D(
const string& name,
const vector<vector<double>>& edges) {
392 Int_t nbinsX =
static_cast<Int_t
>(edges[0].size()) - 1;
393 Int_t nbinsY =
static_cast<Int_t
>(edges[1].size()) - 1;
394 unique_ptr<TH2D> result(
new TH2D{name.c_str(), name.c_str(), nbinsX, edges[0].data(), nbinsY, edges[1].data()});
398 static unique_ptr<TH3D> createTH3D(
const string& name,
const vector<vector<double>>& edges) {
399 Int_t nbinsX =
static_cast<Int_t
>(edges[0].size()) - 1;
400 Int_t nbinsY =
static_cast<Int_t
>(edges[1].size()) - 1;
401 Int_t nbinsZ =
static_cast<Int_t
>(edges[2].size()) - 1;
402 unique_ptr<TH3D> result(
new TH3D{name.c_str(), name.c_str(), nbinsX, edges[0].data(), nbinsY, edges[1].data(), nbinsZ, edges[2].data()});
407 TH1D& rootHistogram,
bool hasUnderOverFlow,
bool add =
false) {
408 ASSERT(dimensions.size() == 1);
409 size_t base = hasUnderOverFlow ? 0 : 1;
410 ASSERT(rootHistogram.GetNbinsX() + 2 * (1 - base) == dimensions[0]);
412 array<double, 4> stats;
414 entries = rootHistogram.GetEntries();
415 rootHistogram.GetStats(stats.data());
417 for (
IndexType i1 = 0; i1 < dimensions[0]; ++i1) {
418 double value = input[i1].sumWi;
419 double err2 = input[i1].sumWi2;
423 value += rootHistogram.GetBinContent(static_cast<Int_t>(i1 + base));
424 err2 += pow(rootHistogram.GetBinError(static_cast<Int_t>(i1 + base)), 2);
426 rootHistogram.SetBinContent(static_cast<Int_t>(i1 + base), value);
427 rootHistogram.SetBinError(static_cast<Int_t>(i1 + base), sqrt(err2));
428 entries +=
static_cast<double>(input[i1].n);
430 rootHistogram.SetEntries(entries);
431 rootHistogram.PutStats(stats.data());
434 static void evalToTH2D(
const IOHistogram& input,
const IndexList& dimensions, TH2D& rootHistogram,
436 ASSERT(dimensions.size() == 2);
437 size_t base = hasUnderOverFlow ? 0 : 1;
438 ASSERT(rootHistogram.GetNbinsX() + 2 * (1 - base) == dimensions[0]);
439 ASSERT(rootHistogram.GetNbinsY() + 2 * (1 - base) == dimensions[1]);
441 array<double, 7> stats;
443 entries = rootHistogram.GetEntries();
444 rootHistogram.GetStats(stats.data());
446 for (
IndexType i1 = 0; i1 < dimensions[0]; ++i1) {
447 for (
IndexType i2 = 0; i2 < dimensions[1]; ++i2) {
448 double value = input[calcCoords({i1, i2})].sumWi;
449 double err2 = input[calcCoords({i1, i2})].sumWi2;
453 value += rootHistogram.GetBinContent(static_cast<Int_t>(i1 + base), static_cast<Int_t>(i2 + base));
455 pow(rootHistogram.GetBinError(static_cast<Int_t>(i1 + base), static_cast<Int_t>(i2 + base)), 2);
457 rootHistogram.SetBinContent(static_cast<Int_t>(i1 + base), static_cast<Int_t>(i2 + base), value);
458 rootHistogram.SetBinError(static_cast<Int_t>(i1 + base), static_cast<Int_t>(i2 + base), sqrt(err2));
459 entries +=
static_cast<double>(input[calcCoords({i1, i2})].n);
462 rootHistogram.SetEntries(entries);
463 rootHistogram.PutStats(stats.data());
466 static void evalToTH3D(
const IOHistogram& input,
const IndexList& dimensions, TH3D& rootHistogram,
469 ASSERT(dimensions.size() == 3);
470 size_t base = hasUnderOverFlow ? 0 : 1;
471 ASSERT(rootHistogram.GetNbinsX() + 2 * (1 - base) == dimensions[0]);
472 ASSERT(rootHistogram.GetNbinsY() + 2 * (1 - base) == dimensions[1]);
473 ASSERT(rootHistogram.GetNbinsZ() + 2 * (1 - base) == dimensions[2]);
475 array<double, 11> stats;
477 entries = rootHistogram.GetEntries();
478 rootHistogram.GetStats(stats.data());
480 for (
IndexType i1 = 0; i1 < dimensions[0]; ++i1) {
481 for (
IndexType i2 = 0; i2 < dimensions[1]; ++i2) {
482 for (
IndexType i3 = 0; i3 < dimensions[2]; ++i3) {
483 double value = input[calcCoords({i1, i2, i3})].sumWi;
484 double err2 = input[calcCoords({i1, i2, i3})].sumWi2;
489 rootHistogram.GetBinContent(static_cast<Int_t>(i1 + base), static_cast<Int_t>(i2 + base),
490 static_cast<Int_t>(i3 + base));
492 pow(rootHistogram.GetBinError(static_cast<Int_t>(i1 + base), static_cast<Int_t>(i2 + base),
493 static_cast<Int_t>(i3 + base)),
496 rootHistogram.SetBinContent(static_cast<Int_t>(i1 + base), static_cast<Int_t>(i2 + base),
497 static_cast<Int_t>(i3 + base), value);
498 rootHistogram.SetBinError(static_cast<Int_t>(i1 + base), static_cast<Int_t>(i2 + base),
499 static_cast<Int_t>(i3 + base), sqrt(err2));
500 entries +=
static_cast<double>(input[calcCoords({i1, i2, i3})].n);
504 rootHistogram.SetEntries(entries);
505 rootHistogram.PutStats(stats.data());
508 bool Histos::isValidHistogram(
const string& name,
const TH1D& h)
const {
509 auto it = _histogramDefs.find(name);
510 if (it == _histogramDefs.end())
513 auto& def = it->second;
514 valid &= (def.getIndexing().rank() == 1);
516 size_t base = def.getIndexing().hasUnderOverFlow() ? 1 : 0;
517 valid &= (h.GetNbinsX() + 2 * base == def.getIndexing().dims()[0]);
522 bool Histos::isValidHistogram(
const string& name,
const TH2D& h)
const {
523 auto it = _histogramDefs.find(name);
524 if (it == _histogramDefs.end())
527 auto& def = it->second;
528 valid &= (def.getIndexing().rank() == 2);
530 size_t base = def.getIndexing().hasUnderOverFlow() ? 1 : 0;
531 valid &= (h.GetNbinsX() + 2 * base == def.getIndexing().dims()[0]);
532 valid &= (h.GetNbinsY() + 2 * base == def.getIndexing().dims()[1]);
537 bool Histos::isValidHistogram(
const string& name,
const TH3D& h)
const {
538 auto it = _histogramDefs.find(name);
539 if (it == _histogramDefs.end())
542 auto& def = it->second;
543 valid &= (def.getIndexing().rank() == 3);
545 size_t base = def.getIndexing().hasUnderOverFlow() ? 1 : 0;
546 valid &= (h.GetNbinsX() + 2 * base == def.getIndexing().dims()[0]);
547 valid &= (h.GetNbinsY() + 2 * base == def.getIndexing().dims()[1]);
548 valid &= (h.GetNbinsZ() + 2 * base == def.getIndexing().dims()[2]);
554 EventIdGroupDict<unique_ptr<TH1D>> Histos::getHistograms1D(
const string& name,
const string& scheme)
const {
555 if(isValidHistogram(name, 1)) {
556 auto hammerHistos = getHistograms(name, scheme);
557 if (hammerHistos.size() > 0) {
558 auto& def = _histogramDefs.find(name)->second;
559 EventIdGroupDict<unique_ptr<TH1D>> result;
560 for (
auto it =
begin(hammerHistos); it !=
end(hammerHistos); ++it) {
561 auto th1d = createTH1D(name, def.getIndexing().edges());
562 evalToTH1D(it->second, def.getIndexing().dims(), *th1d, def.getIndexing().hasUnderOverFlow());
563 result.insert(make_pair(it->first, move(th1d)));
568 MSG_ERROR(
"Wrong name/scheme/dimensionality in histogram request. Returning empty histogram list");
569 return EventIdGroupDict<unique_ptr<TH1D>>{};
572 EventIdGroupDict<unique_ptr<TH2D>> Histos::getHistograms2D(
const string& name,
const string& scheme)
const {
573 if (isValidHistogram(name, 2)) {
574 auto hammerHistos = getHistograms(name, scheme);
575 if (hammerHistos.size() > 0) {
576 EventIdGroupDict<unique_ptr<TH2D>> result;
577 auto& def = _histogramDefs.find(name)->second;
578 function<PositionType(const IndexList&)> fun = [&](
const IndexList& val) ->
PositionType {
return def.getIndexing().indicesToPos(val); };
579 for (
auto it =
begin(hammerHistos); it !=
end(hammerHistos); ++it) {
580 auto th2d = createTH2D(name, def.getIndexing().edges());
581 evalToTH2D(it->second, def.getIndexing().dims(), *th2d, fun, def.getIndexing().hasUnderOverFlow());
582 result.insert(make_pair(it->first, move(th2d)));
587 MSG_ERROR(
"Wrong name/scheme/dimensionality in histogram request. Returning empty histogram list");
588 return EventIdGroupDict<unique_ptr<TH2D>>{};
591 EventIdGroupDict<unique_ptr<TH3D>> Histos::getHistograms3D(
const string& name,
const string& scheme)
const {
592 if (isValidHistogram(name, 3)) {
593 auto hammerHistos = getHistograms(name, scheme);
594 if (hammerHistos.size() > 0) {
595 EventIdGroupDict<unique_ptr<TH3D>> result;
596 auto& def = _histogramDefs.find(name)->second;
597 function<PositionType(const IndexList&)> fun = [&](
const IndexList& val) ->
PositionType {
return def.getIndexing().indicesToPos(val); };
598 for (
auto it =
begin(hammerHistos); it !=
end(hammerHistos); ++it) {
599 auto th3d = createTH3D(name, def.getIndexing().edges());
600 evalToTH3D(it->second, def.getIndexing().dims(), *th3d, fun, def.getIndexing().hasUnderOverFlow());
601 result.insert(make_pair(it->first, move(th3d)));
606 MSG_ERROR(
"Wrong name/scheme/dimensionality in histogram request. Returning empty histogram list");
607 return EventIdGroupDict<unique_ptr<TH3D>>{};
610 unique_ptr<TH1D> Histos::getHistogram1D(
const string& name,
const string& scheme)
const {
611 if (isValidHistogram(name, 1)) {
612 auto hammerHisto = getHistogram(name, scheme);
613 if (hammerHisto.size() > 0) {
614 auto& def = _histogramDefs.find(name)->second;
615 auto th1d = createTH1D(name, def.getIndexing().edges());
616 evalToTH1D(hammerHisto, def.getIndexing().dims(), *th1d, def.getIndexing().hasUnderOverFlow());
620 MSG_ERROR(
"Wrong name/scheme/dimensionality in histogram request. Returning empty histogram list");
621 return unique_ptr<TH1D>{};
624 unique_ptr<TH2D> Histos::getHistogram2D(
const string& name,
const string& scheme)
const {
625 if (isValidHistogram(name, 2)) {
626 auto hammerHisto = getHistogram(name, scheme);
627 if (hammerHisto.size() > 0) {
628 auto& def = _histogramDefs.find(name)->second;
629 function<PositionType(const IndexList&)> fun =
631 auto th2d = createTH2D(name, def.getIndexing().edges());
632 evalToTH2D(hammerHisto, def.getIndexing().dims(), *th2d, fun, def.getIndexing().hasUnderOverFlow());
636 MSG_ERROR(
"Wrong name/scheme/dimensionality in histogram request. Returning empty histogram list");
637 return unique_ptr<TH2D>{};
640 unique_ptr<TH3D> Histos::getHistogram3D(
const string& name,
const string& scheme)
const {
641 if (isValidHistogram(name, 3)) {
642 auto hammerHisto = getHistogram(name, scheme);
643 if (hammerHisto.size() > 0) {
644 auto& def = _histogramDefs.find(name)->second;
645 function<PositionType(const IndexList&)> fun =
647 auto th3d = createTH3D(name, def.getIndexing().edges());
648 evalToTH3D(hammerHisto, def.getIndexing().dims(), *th3d, fun, def.getIndexing().hasUnderOverFlow());
652 MSG_ERROR(
"Wrong name/scheme/dimensionality in histogram request. Returning empty histogram list");
653 return unique_ptr<TH3D>{};
656 void Histos::setHistogram1D(
const string& name,
const string& scheme,
657 TH1D& rootHistogram)
const {
658 if (isValidHistogram(name, rootHistogram)) {
659 auto hammerHisto = getHistogram(name, scheme);
660 if (hammerHisto.size() > 0) {
661 auto& def = _histogramDefs.find(name)->second;
662 evalToTH1D(hammerHisto, def.getIndexing().dims(), rootHistogram, def.getIndexing().hasUnderOverFlow());
665 MSG_ERROR(
string(
"Wrong scheme in setting ROOT histogram '") + name +
string(
"'. Not set."));
669 MSG_ERROR(
string(
"The Hammer and ROOT histograms corresponding to '") + name +
string(
"' have incompatible layouts. Not set."));
673 void Histos::setHistogram2D(
const string& name,
const string& scheme,
674 TH2D& rootHistogram)
const {
675 if (isValidHistogram(name, rootHistogram)) {
676 auto hammerHisto = getHistogram(name, scheme);
677 if (hammerHisto.size() > 0) {
678 auto& def = _histogramDefs.find(name)->second;
679 function<PositionType(const IndexList&)> fun =
681 evalToTH2D(hammerHisto, def.getIndexing().dims(), rootHistogram, fun, def.getIndexing().hasUnderOverFlow());
684 MSG_ERROR(
string(
"Wrong scheme in setting ROOT histogram '") + name +
string(
"'. Not set."));
688 MSG_ERROR(
string(
"The Hammer and ROOT histograms corresponding to '") + name +
string(
"' have incompatible layouts. Not set."));
692 void Histos::setHistogram3D(
const string& name,
const string& scheme,
693 TH3D& rootHistogram)
const {
694 if (isValidHistogram(name, rootHistogram)) {
695 auto hammerHisto = getHistogram(name, scheme);
696 if (hammerHisto.size() > 0) {
697 auto& def = _histogramDefs.find(name)->second;
698 function<PositionType(const IndexList&)> fun =
700 evalToTH3D(hammerHisto, def.getIndexing().dims(), rootHistogram, fun, def.getIndexing().hasUnderOverFlow());
703 MSG_ERROR(
string(
"Wrong scheme in setting ROOT histogram '") + name +
string(
"'. Not set."));
707 MSG_ERROR(
string(
"The Hammer and ROOT histograms corresponding to '") + name +
string(
"' have incompatible layouts. Not set."));
711 void Histos::setHistograms1D(
const string& name,
const string& scheme,
713 if (isValidHistogram(name, *(rootHistograms.begin()->second))) {
714 auto hammerHistos = getHistograms(name, scheme);
715 if (hammerHistos.size() > 0) {
716 auto& def = _histogramDefs.find(name)->second;
717 for (
auto it =
begin(hammerHistos); it !=
end(hammerHistos); ++it) {
718 auto itRoot = rootHistograms.find(it->first);
719 if(itRoot == rootHistograms.end()) {
720 auto th1d = createTH1D(name, def.getIndexing().edges());
721 auto res = rootHistograms.insert(make_pair(it->first, move(th1d)));
724 evalToTH1D(it->second, def.getIndexing().dims(), *(itRoot->second), def.getIndexing().hasUnderOverFlow());
728 MSG_ERROR(
string(
"Wrong scheme in setting ROOT histogram '") + name +
string(
"'. Not set."));
732 MSG_ERROR(
string(
"The Hammer and ROOT histograms corresponding to '") + name +
string(
"' have incompatible layouts. Not set."));
736 void Histos::setHistograms2D(
const string& name,
const string& scheme,
738 if (isValidHistogram(name, *(rootHistograms.begin()->second))) {
739 auto hammerHistos = getHistograms(name, scheme);
740 if (hammerHistos.size() > 0) {
741 auto& def = _histogramDefs.find(name)->second;
742 function<PositionType(const IndexList&)> fun =
744 for (
auto it =
begin(hammerHistos); it !=
end(hammerHistos); ++it) {
745 auto itRoot = rootHistograms.find(it->first);
746 if (itRoot == rootHistograms.end()) {
747 auto th2d = createTH2D(name, def.getIndexing().edges());
748 auto res = rootHistograms.insert(make_pair(it->first, move(th2d)));
751 evalToTH2D(it->second, def.getIndexing().dims(), *(itRoot->second), fun, def.getIndexing().hasUnderOverFlow());
755 MSG_ERROR(
string(
"Wrong scheme in setting ROOT histogram '") + name +
string(
"'. Not set."));
759 MSG_ERROR(
string(
"The Hammer and ROOT histograms corresponding to '") + name +
string(
"' have incompatible layouts. Not set."));
763 void Histos::setHistograms3D(
const string& name,
const string& scheme,
765 if (isValidHistogram(name, *(rootHistograms.begin()->second))) {
766 auto hammerHistos = getHistograms(name, scheme);
767 if (hammerHistos.size() > 0) {
768 auto& def = _histogramDefs.find(name)->second;
769 function<PositionType(const IndexList&)> fun =
771 for (
auto it =
begin(hammerHistos); it !=
end(hammerHistos); ++it) {
772 auto itRoot = rootHistograms.find(it->first);
773 if (itRoot == rootHistograms.end()) {
774 auto th3d = createTH3D(name, def.getIndexing().edges());
775 auto res = rootHistograms.insert(make_pair(it->first, move(th3d)));
778 evalToTH3D(it->second, def.getIndexing().dims(), *(itRoot->second), fun, def.getIndexing().hasUnderOverFlow());
782 MSG_ERROR(
string(
"Wrong scheme in setting ROOT histogram '") + name +
string(
"'. Not set."));
786 MSG_ERROR(
string(
"The Hammer and ROOT histograms corresponding to '") + name +
string(
"' have incompatible layouts. Not set."));
792 void Histos::fillHisto(
const string& name,
const string& scheme,
const IndexList& binPosition,
Tensor& value,
double extraWeight) {
793 auto itDef = _histogramDefs.find(name);
794 if(itDef == _histogramDefs.end()) {
795 MSG_ERROR(
string(
"Unable to find histogram ") + name +
string(
". Histogram not filled."));
800 Tensor temp = itDef->second.getFixedData(_currentEventId, scheme, newlabs);
801 bool processed =
false;
802 if (temp.
rank() > 0) {
805 newdims = temp.
dims();
806 if (!
isZero(extraWeight - 1.0)) {
812 if (!
isZero(extraWeight - 1.0)) {
813 temp = value * extraWeight;
817 auto entry = getEntry(name, scheme);
818 if(entry ==
nullptr) {
819 MSG_ERROR(
string(
"Unable to find histogram ") + name +
string(
". Histogram not filled."));
822 Histogram* histo = entry->getHistogram(_currentEventId);
823 if(histo ==
nullptr) {
824 auto id = entry->addEventId(_currentEventId, newlabs);
825 histo = entry->getHistogram(
id);
826 if(histo ==
nullptr) {
827 histo = entry->addHistogram(
id,
makeHistogram(name, itDef->second, newdims, newlabs));
831 histo->
fillBin(temp, binPosition);
834 histo->
fillBin(value, binPosition);
838 Log& Histos::getLog()
const {
839 return Log::getLog(
"Hammer.Histos");
842 void Histos::defineSettings() {
844 addSetting<bool>(
"KeepErrors",
false);
847 bool Histos::writeDefinition(flatbuffers::FlatBufferBuilder* msgwriter,
const string& name)
const {
848 auto ithisto = _histogramDefs.find(name);
849 if (ithisto != _histogramDefs.end()) {
850 ithisto->second.write(msgwriter, name);
857 bool Histos::writeHistogram(flatbuffers::FlatBufferBuilder* msgwriter,
const string& histogramName,
const string& schemeName,
const EventUID& eventIDs)
const {
858 auto ithisto = _histograms.find(histogramName);
859 if (ithisto != _histograms.end()) {
860 auto itscheme = ithisto->second.find(schemeName);
861 if(itscheme != ithisto->second.end()) {
862 auto serialScheme = msgwriter->CreateString(schemeName);
863 auto res = itscheme->second.write(msgwriter, eventIDs);
864 res->add_scheme(serialScheme);
865 auto out = res->Finish();
866 msgwriter->Finish(out);
874 string Histos::readDefinition(
const Serial::FBHistoDefinition* msgreader,
bool merge) {
875 if (msgreader !=
nullptr) {
876 auto itdef = _histogramDefs.find(msgreader->name()->c_str());
877 if(itdef == _histogramDefs.end()) {
878 itdef = _histogramDefs.emplace(msgreader->name()->c_str(),
HistogramDefinition{msgreader}).first;
882 if(!itdef->second.checkDefinition(msgreader)) {
883 MSG_ERROR(
"Invalid merge for histogram '" + itdef->first +
"': definitions do not match.");
894 MSG_ERROR(
"Invalid record for histogram definition");
899 HistoInfo Histos::readHistogram(
const Serial::FBHistogram* msgreader,
bool merge) {
900 if (msgreader !=
nullptr) {
901 auto ithisto = _histograms.find(msgreader->name()->c_str());
902 if(ithisto == _histograms.end()) {
905 MSG_ERROR(
string(
"Unable to add read histogram '") + msgreader->name()->c_str() + string(
"'."));
910 auto itscheme = ithisto->second.find(msgreader->scheme()->c_str());
911 if(itscheme == ithisto->second.end()) {
912 auto res2 = ithisto->second.emplace(msgreader->scheme()->c_str(),
HistogramSet{});
914 MSG_ERROR(
string(
"Unable to add read histogram '") + ithisto->first +
string(
"'."));
917 itscheme = res2.first;
919 auto itdef = _histogramDefs.find(ithisto->first);
920 if(itdef == _histogramDefs.end()) {
921 MSG_ERROR(
string(
"Unable to add read histogram '") + ithisto->first +
string(
"': definition not found."));
924 auto result = itscheme->second.read(msgreader, itdef->second, merge);
925 if(result.size() > 0) {
926 return HistoInfo{ithisto->first, itscheme->first, result};
929 MSG_ERROR(
"Invalid merge for histogram '" + ithisto->first +
"'");
934 MSG_ERROR(
"Invalid record for histogram");
std::set< ProcessUID > EventUID
const MD::BinnedIndexing< MD::SequentialIndexing > & getIndexing() const
Multidimensional histogram class with Tensor as cell bins.
LabelsList labels() const
get the labels of all the indices at once
Container class for values of WC and FF vectors.
std::vector< std::vector< double >> BinEdgeList
std::vector< BinContents > IOHistogram
std::set< EventUID > EventUIDGroup
Non-sparse tensor indexer.
Message logging routines.
Hammer histogram manager.
bool hasUnderOverFlow() const
std::map< std::string, T > HistoNameDict
std::shared_ptr< IContainer > SharedTensorData
size_t rank() const
rank of the tensor
auto begin(reversion_wrapper< T > w)
HistoNameDict< SchemeDict< HistogramSet > > _histograms
std::vector< IndexType > IndexList
HistoNameDict< HistogramDefinition > _histogramDefs
UMap< EventUIDGroup, T > EventIdGroupDict
Multidimensional tensor class with complex numbers as elements.
bool isZero(const std::complex< double > val)
Container class for Scheme Definitions.
std::vector< IndexLabel > LabelsList
std::map< SchemeName, T > SchemeDict
Tensor & dot(const Tensor &other, const UniqueLabelsList &indices={})
contract this tensor with another and stores the result in this tensor
DictionaryManager * _dictionaries
Binned tensor (histogram) indexer.
IndexList dims() const
get the dimensions of all the indices at once
std::vector< BinRange > BinRangeList
void fillBin(const Tensor &value, Args...rest)
set the value of a histogram bin based on the bin indices
void addHistogramDefinition(const std::string &histogramName, const IndexList &binSizes, bool hasUnderOverFlow=true, const MD::BinRangeList &ranges={}, bool shouldCompress=false, bool withErrors=false)
auto end(reversion_wrapper< T > w)
Serialization related typedefs and includes.
std::vector< double > BinValue
Global container class for amplitudes, rates, FFs, data.