Project
Loading...
Searching...
No Matches
DigitReaderSpec.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
14#include "TFile.h"
15#include "TTree.h"
18#include "Headers/DataHeader.h"
25#include "Framework/Task.h"
28#include "Framework/Logger.h"
29#include <vector>
30
31using namespace o2::framework;
32
33namespace o2
34{
35namespace ctp
36{
37
38class DigitReader : public Task
39{
40 public:
41 DigitReader() = delete;
42 DigitReader(bool useMC);
43 ~DigitReader() override = default;
44 void init(InitContext& ic) final;
45 void run(ProcessingContext& pc) final;
46
47 protected:
48 void connectTree(const std::string& filename);
49
50 std::vector<o2::ctp::CTPDigit> mDigits, *mDigitsPtr = &mDigits;
52 std::unique_ptr<TFile> mFile;
53 std::unique_ptr<TTree> mTree;
54
55 bool mUseMC = false; // use MC truth
56 bool mUseIRFrames = false; // selected IRFrames mode
57 std::string mDigTreeName = "o2sim";
58 std::string mDigitBranchName = "CTPDigits";
59 std::string mLumiBranchName = "CTPLumi";
60};
61
63{
64 if (useMC) {
65 LOG(info) << "CTP : truth = data as CTP inputs are already digital";
66 }
67}
68
70{
72 ic.options().get<std::string>("ctp-digit-infile"));
73 if (ic.options().hasOption("ignore-irframes") && !ic.options().get<bool>("ignore-irframes")) {
74 mUseIRFrames = true;
75 }
77}
78
80{
81 gsl::span<const o2::dataformats::IRFrame> irFrames{};
82 // LOG(info) << "Using IRs:" << mUseIRFrames;
83 if (mUseIRFrames) {
84 irFrames = pc.inputs().get<gsl::span<o2::dataformats::IRFrame>>("driverInfo");
85 }
86 auto ent = mTree->GetReadEntry();
87 if (!mUseIRFrames) {
88 ent++;
89 assert(ent < mTree->GetEntries()); // this should not happen
90 mTree->GetEntry(ent);
91 LOG(info) << "DigitReader pushes " << mDigits.size() << " digits at entry " << ent;
92 pc.outputs().snapshot(Output{"CTP", "DIGITS", 0}, mDigits);
93 pc.outputs().snapshot(Output{"CTP", "LUMI", 0}, mLumi);
94 if (mTree->GetReadEntry() + 1 >= mTree->GetEntries()) {
96 pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
97 }
98 } else {
99 std::vector<o2::ctp::CTPDigit> digitSel;
100 if (irFrames.size()) { // we assume the IRFrames are in the increasing order
101 if (ent < 0) {
102 ent++;
103 }
105 // MC digits are already aligned
106 irfSel.setSelectedIRFrames(irFrames, 0, 0, 0, true);
107 const auto irMin = irfSel.getIRFrames().front().getMin(); // use processed IRframes for rough comparisons (possible shift!)
108 const auto irMax = irfSel.getIRFrames().back().getMax();
109 LOGP(info, "Selecting IRFrame {}-{}", irMin.asString(), irMax.asString());
110 while (ent < mTree->GetEntries()) {
111 if (ent > mTree->GetReadEntry()) {
112 mTree->GetEntry(ent);
113 }
114 if (mDigits.front().intRecord <= irMax && mDigits.back().intRecord >= irMin) { // THere is overlap
115 for (int i = 0; i < (int)mDigits.size(); i++) {
116 const auto& dig = mDigits[i];
117 // if(irfSel.check(dig.intRecord)) { // adding selected digit
118 if (dig.intRecord >= irMin && dig.intRecord <= irMax) {
119 digitSel.push_back(dig);
120 LOG(info) << "adding:" << dig.intRecord << " ent:" << ent;
121 }
122 }
123 }
124 if (mDigits.back().intRecord < irMax) { // need to check the next entry
125 ent++;
126 continue;
127 }
128 break; // push collected data
129 }
130 }
131 pc.outputs().snapshot(Output{"CTP", "DIGITS", 0}, digitSel);
132 pc.outputs().snapshot(Output{"CTP", "LUMI", 0}, mLumi); // add full lumi for this TF
133 if (!irFrames.size() || irFrames.back().isLast()) {
135 pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
136 }
137 }
138}
139
140void DigitReader::connectTree(const std::string& filename)
141{
142 mTree.reset(nullptr); // in case it was already loaded
143 mFile.reset(TFile::Open(filename.c_str()));
144 assert(mFile && !mFile->IsZombie());
145 mTree.reset((TTree*)mFile->Get(mDigTreeName.c_str()));
146 assert(mTree);
147 if (mTree->GetBranch(mDigitBranchName.c_str())) {
148 mTree->SetBranchAddress(mDigitBranchName.c_str(), &mDigitsPtr);
149 } else {
150 LOGP(warn, "Digits branch {} is absent", mDigitBranchName);
151 }
152 if (mTree->GetBranch(mLumiBranchName.c_str())) {
153 mTree->SetBranchAddress(mLumiBranchName.c_str(), &mLumiPtr);
154 } else {
155 LOGP(warn, "Lumi branch {} is absent", mLumiBranchName);
156 }
157 mTree->SetBranchAddress(mDigitBranchName.c_str(), &mDigitsPtr);
158 LOG(info) << "Loaded tree from " << filename << " with " << mTree->GetEntries() << " entries";
159}
160
161DataProcessorSpec getDigitsReaderSpec(bool useMC, const std::string& defFile)
162{
163 return DataProcessorSpec{
164 "ctp-digit-reader",
165 Inputs{},
166 Outputs{{"CTP", "DIGITS", 0, Lifetime::Timeframe},
167 {"CTP", "LUMI", 0, o2::framework::Lifetime::Timeframe}},
168 AlgorithmSpec{adaptFromTask<DigitReader>(useMC)},
169 Options{
170 {"ctp-digit-infile", VariantType::String, defFile, {"Name of the input digit file"}},
171 {"input-dir", VariantType::String, "none", {"Input directory"}}}};
172}
173
174} // namespace ctp
175
176} // namespace o2
A const (ready only) version of MCTruthContainer.
definition of CTPDigit, CTPInputDigit
int32_t i
Class to check if give InteractionRecord or IRFrame is selected by the external IRFrame vector.
Definition of the Names Generator class.
std::vector< o2::ctp::CTPDigit > mDigits
void init(InitContext &ic) final
std::unique_ptr< TFile > mFile
~DigitReader() override=default
std::unique_ptr< TTree > mTree
o2::ctp::LumiInfo mLumi
void run(ProcessingContext &pc) final
std::vector< o2::ctp::CTPDigit > * mDigitsPtr
void connectTree(const std::string &filename)
o2::ctp::LumiInfo * mLumiPtr
bool hasOption(const char *key) const
void snapshot(const Output &spec, T const &object)
ConfigParamRegistry const & options()
Definition InitContext.h:33
decltype(auto) get(R binding, int part=0) const
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
virtual void endOfStream(EndOfStreamContext &context)
This is invoked whenever we have an EndOfStream event.
Definition Task.h:43
void setSelectedIRFrames(const SPAN &sp, size_t bwd=0, size_t fwd=0, long shift=0, bool removeOverlaps=true)
framework::DataProcessorSpec getDigitsReaderSpec(bool propagateMC=true, const std::string &defFile="ctpdigits.root")
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > Options
std::vector< InputSpec > Inputs
std::vector< OutputSpec > Outputs
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string filename()
static std::string rectifyDirectory(const std::string_view p)
static std::string concat_string(Ts const &... ts)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"