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
16#include "Framework/DataRef.h"
21#include "Headers/DataHeader.h"
27#include <vector>
28#include <string>
29#include <algorithm>
30
31using namespace o2::framework;
33
34namespace o2
35{
36namespace itsmft
37{
38
39template <typename T>
42
45template <int N>
46DataProcessorSpec getDigitWriterSpec(bool mctruth, bool dec, bool calib)
47{
50 std::string detStr = o2::detectors::DetID::getName(N);
51 std::string detStrL = dec ? "o2_" : ""; // for decoded digits prepend by o2
52 detStrL += detStr;
53 std::transform(detStrL.begin(), detStrL.end(), detStrL.begin(), ::tolower);
54 auto digitSizes = std::make_shared<std::array<size_t, NLayers>>();
55 auto digitSizeGetter = [digitSizes](std::vector<o2::itsmft::Digit> const& inDigits, DataRef const& ref) {
56 auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
57 (*digitSizes)[dh->subSpecification] = inDigits.size();
58 };
59 auto rofSizes = std::make_shared<std::array<size_t, NLayers>>();
60 auto rofSizeGetter = [rofSizes](std::vector<o2::itsmft::ROFRecord> const& inROFs, DataRef const& ref) {
61 auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
62 (*rofSizes)[dh->subSpecification] = inROFs.size();
63 };
64
65 // the callback to be set as hook for custom action when the writer is closed
66 auto finishWriting = [](TFile* outputfile, TTree* outputtree) {
67 const auto* brArr = outputtree->GetListOfBranches();
68 int64_t nent = 0;
69 for (const auto* brc : *brArr) {
70 int64_t n = ((const TBranch*)brc)->GetEntries();
71 if (nent && (nent != n)) {
72 LOG(error) << "Branches have different number of entries";
73 }
74 nent = n;
75 }
76 outputtree->SetEntries(nent);
77 // do not use TTree::Write .. as this writes to default directory (not the associated file)
78 // instead of outputtree->Write("", TObject::kOverwrite)
79 // --> better use TFile::Write or TFile::WriteObject
80 outputfile->Write("", TObject::kOverwrite);
81 outputfile->Close();
82 };
83
84 // handler for labels
85 // This is necessary since we can't store the original label buffer in a ROOT entry -- as is -- if it exceeds a certain size.
86 // We therefore convert it to a special split class.
87 auto fillLabels = [digitSizes, rofSizes](TBranch& branch, std::vector<char> const& labelbuffer, DataRef const& ref) {
89 auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
90 auto layer = static_cast<size_t>(dh->subSpecification);
91 LOG(info) << "WRITING " << labels.getNElements() << " LABELS FOR " << layer << " WITH " << (*digitSizes)[layer] << " DIGITS IN " << (*rofSizes)[layer] << " ROFS";
92
94 auto ptr = &outputcontainer;
96 outputcontainer.adopt(labelbuffer);
97 br->Fill();
98 br->ResetAddress();
99 };
100
101 auto getIndex = [](DataRef const& ref) -> size_t {
102 auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
103 return static_cast<size_t>(dh->subSpecification);
104 };
105 auto getName = [](std::string base, size_t index) -> std::string {
107 return base += "_" + std::to_string(index);
108 }
109 return base;
110 };
111 return MakeRootTreeWriterSpec((detStr + "DigitWriter" + (dec ? "_dec" : "")).c_str(),
112 (detStrL + "digits.root").c_str(),
113 MakeRootTreeWriterSpec::TreeAttributes{.name = "o2sim", .title = detStr + " Digits tree"},
116 detStr + "Digit", "digit-branch",
117 NLayers,
118 digitSizeGetter,
119 getIndex,
120 getName},
121 BranchDefinition<std::vector<itsmft::ROFRecord>>{InputSpec{detStr + "digitsROF", ConcreteDataTypeMatcher{Origin, "DIGITSROF"}},
122 detStr + "DigitROF", "digit-rof-branch",
123 NLayers,
124 rofSizeGetter,
125 getIndex,
126 getName},
127 BranchDefinition<std::vector<char>>{InputSpec{detStr + "_digitsMCTR", ConcreteDataTypeMatcher{Origin, "DIGITSMCTR"}},
128 detStr + "DigitMCTruth", "digit-mctruth-branch",
129 (mctruth ? NLayers : 0),
130 fillLabels,
131 getIndex,
132 getName},
133 BranchDefinition<std::vector<itsmft::MC2ROFRecord>>{InputSpec{detStr + "_digitsMC2ROF", ConcreteDataTypeMatcher{Origin, "DIGITSMC2ROF"}},
134 detStr + "DigitMC2ROF", "digit-mc2rof-branch",
135 (mctruth ? NLayers : 0),
136 getIndex,
137 getName},
139 detStr + "Calib", "digit-calib-branch",
140 (calib ? 1 : 0)})();
141}
142
143DataProcessorSpec getITSDigitWriterSpec(bool mctruth, bool dec, bool calib)
144{
145 return getDigitWriterSpec<o2::detectors::DetID::ITS>(mctruth, dec, calib);
146}
147
148DataProcessorSpec getMFTDigitWriterSpec(bool mctruth, bool dec, bool calib)
149{
150 return getDigitWriterSpec<o2::detectors::DetID::MFT>(mctruth, dec, calib);
151}
152
153} // end namespace itsmft
154} // 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
Calibration data from GBT data.
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
static constexpr ID ITS
Definition DetID.h:63
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
constexpr o2::header::DataOrigin gDataOriginMFT
Definition DataHeader.h:572
constexpr o2::header::DataOrigin gDataOriginITS
Definition DataHeader.h:570
Defining PrimaryVertex explicitly as messageable.
DataProcessorSpec getDigitWriterSpec(bool mctruth, bool dec, bool calib)
o2::framework::DataProcessorSpec getITSDigitWriterSpec(bool mctruth=true, bool dec=false, bool calib=false)
o2::framework::DataProcessorSpec getMFTDigitWriterSpec(bool mctruth=true, bool dec=false, bool calib=false)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
static constexpr int getNLayers()
static constexpr bool supportsStaggering() noexcept
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"