Project
Loading...
Searching...
No Matches
DigitWriterSpec.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
13
17#include "Headers/DataHeader.h"
23#include <array>
24#include <string>
25#include <algorithm>
26
27using namespace o2::framework;
29
30namespace o2::its3
31{
32
33template <typename T>
36
37DataProcessorSpec getITS3DigitWriterSpec(bool mctruth, bool doStag, bool dec, bool calib)
38{
39 std::string detStr = o2::detectors::DetID::getName(o2::detectors::DetID::IT3);
40 std::string detStrL = dec ? "o2_" : ""; // for decoded digits prepend by o2
41 const int mLayers = doStag ? 7 : 1;
42 detStrL += detStr;
43 std::transform(detStrL.begin(), detStrL.end(), detStrL.begin(), ::tolower);
44
45 auto digitSizes = std::make_shared<std::vector<size_t>>(mLayers, 0);
46 auto digitSizeGetter = [digitSizes](std::vector<o2::itsmft::Digit> const& inDigits, DataRef const& ref) {
47 auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
48 (*digitSizes)[dh->subSpecification] = inDigits.size();
49 };
50 auto rofSizes = std::make_shared<std::vector<size_t>>(mLayers, 0);
51 auto rofSizeGetter = [rofSizes](std::vector<o2::itsmft::ROFRecord> const& inROFs, DataRef const& ref) {
52 auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
53 (*rofSizes)[dh->subSpecification] = inROFs.size();
54 };
55 // the callback to be set as hook for custom action when the writer is closed
56 auto finishWriting = [](TFile* outputfile, TTree* outputtree) {
57 const auto* brArr = outputtree->GetListOfBranches();
58 int64_t nent = 0;
59 for (const auto* brc : *brArr) {
60 int64_t n = ((const TBranch*)brc)->GetEntries();
61 if (nent && (nent != n)) {
62 LOG(error) << "Branches have different number of entries";
63 }
64 nent = n;
65 }
66 outputtree->SetEntries(nent);
67 outputtree->Write("", TObject::kOverwrite);
68 outputfile->Close();
69 };
70
71 // handler for labels
72 // This is necessary since we can't store the original label buffer in a ROOT entry -- as is -- if it exceeds a certain size.
73 // We therefore convert it to a special split class.
74 auto fillLabels = [detStr, digitSizes, rofSizes](TBranch& branch, std::vector<char> const& labelbuffer, DataRef const& ref) {
76 auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
77 auto layer = static_cast<size_t>(dh->subSpecification);
78 LOG(info) << detStr << ": WRITING " << labels.getNElements() << " LABELS FOR LAYER " << layer << " WITH " << (*digitSizes)[layer] << " DIGITS IN " << (*rofSizes)[layer] << " ROFS";
79
81 auto ptr = &outputcontainer;
83 outputcontainer.adopt(labelbuffer);
84 br->Fill();
85 br->ResetAddress();
86 };
87
88 auto getIndex = [](DataRef const& ref) -> size_t {
89 auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
90 return static_cast<size_t>(dh->subSpecification);
91 };
92 auto getName = [&doStag](std::string base, size_t index) -> std::string {
93 if (doStag) {
94 return base += "_" + std::to_string(index);
95 }
96 return base;
97 };
98
99 std::vector<InputSpec> vecInpSpecDig, vecInpSpecROF, vecInpSpecLbl;
100 vecInpSpecDig.reserve(mLayers);
101 vecInpSpecROF.reserve(mLayers);
102 vecInpSpecLbl.reserve(mLayers);
103 for (int iLayer = 0; iLayer < mLayers; iLayer++) {
104 vecInpSpecDig.emplace_back(getName("digits", iLayer), "IT3", "DIGITS", iLayer);
105 vecInpSpecROF.emplace_back(getName("digitsROF", iLayer), "IT3", "DIGITSROF", iLayer);
106 vecInpSpecLbl.emplace_back(getName("digitsMCTR", iLayer), "IT3", "DIGITSMCTR", iLayer);
107 }
108
109 return MakeRootTreeWriterSpec((detStr + "DigitWriter" + (dec ? "_dec" : "")).c_str(),
110 (detStrL + "digits.root").c_str(),
111 MakeRootTreeWriterSpec::TreeAttributes{.name = "o2sim", .title = "Digits tree"},
113 // in case of labels we first read them as std::vector<char> and process them correctly in the fillLabels hook
115 detStr + "Digit", "digit-branch",
116 mLayers,
117 digitSizeGetter,
118 getIndex,
119 getName},
121 detStr + "DigitROF", "digit-rof-branch",
122 mLayers,
123 rofSizeGetter,
124 getIndex,
125 getName},
127 "IT3DigitMCTruth", "digit-mctruth-branch",
128 (mctruth ? mLayers : 0),
129 fillLabels,
130 getIndex,
131 getName})();
132}
133
134} // namespace o2::its3
135 // end namespace o2
std::vector< std::string > labels
std::string getName(const TDataMember *dm, int index, int size)
A const (ready only) version of MCTruthContainer.
Definition of the ITSMFT digit.
o2::framework::DataAllocator::SubSpecificationType SubSpecificationType
A special IO container - splitting a given vector to enable ROOT IO.
Definition of the ITSMFT ROFrame (trigger) record.
Configurable generator for RootTreeWriter processor spec.
TBranch * ptr
A read-only version of MCTruthContainer allowing for storage optimisation.
void adopt(gsl::span< const char > const input)
"adopt" (without taking ownership) from an existing buffer
static constexpr const char * getName(ID id)
names of defined detectors
Definition DetID.h:146
o2::header::DataHeader::SubSpecificationType SubSpecificationType
Generate a processor spec for the RootTreeWriter utility.
static TBranch * remapBranch(TBranch &branchRef, T **newdata)
GLdouble n
Definition glcorearb.h:1982
GLuint index
Definition glcorearb.h:781
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
GLint ref
Definition glcorearb.h:291
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
o2::framework::DataProcessorSpec getITS3DigitWriterSpec(bool mctruth=true, bool doStag=false, bool dec=false, bool calib=false)
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"