Project
Loading...
Searching...
No Matches
IRFrameSelector.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
15
17#include "Framework/Logger.h"
18#include <TFile.h>
19#include <TTree.h>
20#include <TKey.h>
21
22using namespace o2::utils;
23
24gsl::span<const o2::dataformats::IRFrame> IRFrameSelector::getMatchingFrames(const o2::dataformats::IRFrame& fr)
25{
26 // extract span of IRFrames matching to fr
27 auto lower = std::lower_bound(mFrames.begin(), mFrames.end(), o2::dataformats::IRFrame{fr.getMin(), fr.getMin()});
28 if (lower == mFrames.end() || *lower > fr) {
29 return {};
30 }
31 auto upper = std::upper_bound(lower, mFrames.end(), o2::dataformats::IRFrame{fr.getMax(), fr.getMax()});
32 return {&*lower, size_t(std::distance(lower, upper))};
33}
34
35long IRFrameSelector::check(o2::dataformats::IRFrame fr, size_t bwd, size_t fwd)
36{
37 // check if fr overlaps with at least 1 entry in the frames container, if needed expand fr by -bwd and fwd BCs from 2 sides
38 long ans = -1;
39 if (bwd) {
40 fr.setMin(fr.getMin().toLong() > bwd ? fr.getMin() - bwd : o2::InteractionRecord{0, 0});
41 }
42 if (fwd) {
44 }
45 // find entry which overlaps or above fr
46 auto fullcheck = [&fr, this]() -> long {
47 auto lower = std::lower_bound(this->mFrames.begin(), this->mFrames.end(), fr);
48 if (lower == this->mFrames.end()) {
49 this->mLastBoundID = this->mFrames.size();
50 } else {
51 this->mLastBoundID = std::distance(this->mFrames.begin(), lower);
52 return fr.isOutside(*lower) == o2::dataformats::IRFrame::Inside ? this->mLastBoundID : -1;
53 }
54 return -1;
55 };
56
57 if (mLastBoundID < 0) { // 1st call, do full search
58 ans = fullcheck();
59 } else { // we assume that the new query is in the vicinity of the previous one
60 int steps = 0;
61 constexpr int MaxSteps = 3;
62 if (fr.getMin() >= mLastIRFrameChecked.getMin()) { // check entries including and following mLastBoundID
63 for (; mLastBoundID < (long)mFrames.size(); mLastBoundID++) {
64 auto res = fr.isOutside(mFrames[mLastBoundID]);
66 break; // no point in checking further
68 ans = mLastBoundID;
69 break;
70 }
71 if (++steps == MaxSteps) {
72 ans = fullcheck();
73 break;
74 }
75 }
76 } else { // check entries preceding mLastBoundID
77 if (mLastBoundID >= (long)mFrames.size()) {
78 mLastBoundID = (long)mFrames.size() - 1;
79 }
80 for (; mLastBoundID >= 0; mLastBoundID--) {
81 auto res = fr.isOutside(mFrames[mLastBoundID]);
83 mLastBoundID++; // no point in checking further
84 break;
86 ans = mLastBoundID;
87 break;
88 }
89 if (++steps == MaxSteps) {
90 ans = fullcheck();
91 break;
92 }
93 }
94 if (mLastBoundID < 0) {
95 mLastBoundID = 0;
96 }
97 }
98 }
99 mLastIRFrameChecked = fr;
100 return ans;
101}
102
103size_t IRFrameSelector::loadIRFrames(const std::string& fname)
104{
105 // read IRFrames to filter from the file
106 std::unique_ptr<TFile> tfl(TFile::Open(fname.c_str()));
107 if (!tfl || tfl->IsZombie()) {
108 LOGP(fatal, "Cannot open selected IRFrames file {}", fname);
109 }
110 auto klst = gDirectory->GetListOfKeys();
111 TIter nextkey(klst);
112 TKey* key;
113 std::string clVec{TClass::GetClass("std::vector<o2::dataformats::IRFrame>")->GetName()};
114 bool done = false;
115 bool toBeSorted = false;
116 while ((key = (TKey*)nextkey())) {
117 std::string kcl(key->GetClassName());
118 if (kcl == clVec) {
119 auto* v = (std::vector<o2::dataformats::IRFrame>*)tfl->GetObjectUnchecked(key->GetName());
120 if (!v) {
121 LOGP(fatal, "Failed to extract IRFrames vector {} from {}", key->GetName(), fname);
122 }
123 mOwnList.insert(mOwnList.end(), v->begin(), v->end());
124 LOGP(info, "Loaded {} IRFrames from vector {} of {}", mOwnList.size(), key->GetName(), fname);
125 done = true;
126 break;
127 } else if (kcl == "TTree") {
128 std::unique_ptr<TTree> tr((TTree*)tfl->Get(key->GetName()));
129 if (!tr->GetBranch("IRFrames")) {
130 LOGP(fatal, "Did not find branch IRFrames in the tree {}", key->GetName());
131 }
132 std::vector<o2::dataformats::IRFrame> tmpv, *tpmvPtr = &tmpv;
133 tr->SetBranchAddress("IRFrames", &tpmvPtr);
134 for (int i = 0; i < (int)tr->GetEntries(); i++) {
135 tr->GetEntry(i);
136 mOwnList.insert(mOwnList.end(), tmpv.begin(), tmpv.end());
137 }
138 done = true;
139 LOGP(info, "Loaded {} IRFrames from tree {} of {}", mOwnList.size(), key->GetName(), fname);
140 break;
141 } else if (kcl == "TDirectoryFile") {
142 TTree* bcRanges = (TTree*)tfl->Get(fmt::format("{}/O2bcranges", key->GetName()).data());
143 if (!bcRanges) {
144 continue;
145 }
146 LOGP(info, "Loading BCrange trees in the directory {}", key->GetName());
147 ULong64_t minBC, maxBC;
148 bcRanges->SetBranchAddress("fBCstart", &minBC);
149 bcRanges->SetBranchAddress("fBCend", &maxBC);
150 for (int i = 0; i < (int)bcRanges->GetEntries(); i++) {
151 bcRanges->GetEntry(i);
152 mOwnList.emplace_back(InteractionRecord::long2IR(minBC), InteractionRecord::long2IR(maxBC));
153 }
154 done = true;
155 toBeSorted = true;
156 }
157 }
158
159 if (toBeSorted) {
160 LOGP(info, "Sorting {} IRFrames", mOwnList.size());
161 std::sort(mOwnList.begin(), mOwnList.end(), [](const auto& a, const auto& b) { return a.getMin() < b.getMin(); });
162 }
163 if (!true) {
164 LOGP(fatal, "Did not find neither tree nor vector of IRFrames in {}", fname);
165 }
166 setSelectedIRFrames(mOwnList);
167 return mOwnList.size();
168}
169
170void IRFrameSelector::setOwnList(const std::vector<o2::dataformats::IRFrame>& lst, bool toBeSorted)
171{
172 clear();
173 mOwnList.insert(mOwnList.end(), lst.begin(), lst.end());
174 if (toBeSorted) {
175 std::sort(mOwnList.begin(), mOwnList.end(), [](const auto& a, const auto& b) { return a.getMin() < b.getMin(); });
176 }
177 setSelectedIRFrames(mOwnList, 0, 0, 0, false);
178}
179
180void IRFrameSelector::print(bool lst) const
181{
182 LOGP(info, "Last query stopped at entry {} for IRFrame {}:{}", mLastBoundID,
183 mLastIRFrameChecked.getMin().asString(), mLastIRFrameChecked.getMax().asString());
184 if (lst) {
185 size_t i = 0;
186 for (const auto& f : mFrames) {
187 LOGP(info, "Frame#{}: {}:{}", i++, f.getMin().asString(), f.getMax().asString());
188 }
189 }
190}
191
193{
194 mIsSet = false;
195 mOwnList.clear();
196 mLastIRFrameChecked.getMin().clear(); // invalidate
197 mLastBoundID = -1;
198 mFrames = {};
199}
200
201void IRFrameSelector::applyMargins(size_t bwd, size_t fwd, long shift, bool removeOverlaps)
202{
203 // apply shift and margin to all IRFrames by converting them to IRFrame.getMin() - fwd + shift, IRFrame.getMax() + bwd + shift
204 LOGP(debug, "applyMargins({},{},{})", bwd, fwd, removeOverlaps);
205 if ((!fwd && !bwd && !shift) || !mIsSet || !mFrames.size()) {
206 return;
207 }
208 mLastBoundID = -1;
209 std::vector<o2::dataformats::IRFrame> lst;
210 long shiftBwd = bwd - shift, shiftFwd = fwd + shift;
211
212 for (const auto& fr : mFrames) {
213 auto irmin = fr.getMin();
214 auto irmax = fr.getMax();
215 if (shiftBwd > 0) {
216 irmin = fr.getMin().toLong() > shiftBwd ? fr.getMin() - shiftBwd : o2::InteractionRecord{0, 0};
217 } else {
218 irmin = (o2::InteractionRecord::MaxGlobalBCs - fr.getMin().toLong()) > -shiftBwd ? fr.getMin() - shiftBwd : o2::InteractionRecord::getIRMaxBC();
219 }
220 if (shiftFwd > 0) {
221 irmax = (o2::InteractionRecord::MaxGlobalBCs - fr.getMax().toLong()) > shiftFwd ? fr.getMax() + shiftFwd : o2::InteractionRecord::getIRMaxBC();
222 } else {
223 irmax = fr.getMax().toLong() > -shiftFwd ? fr.getMax() + shiftFwd : o2::InteractionRecord{0, 0};
224 }
225 LOGP(debug, "before removerlap: {}:{} -> {}:{}", fr.getMin().toLong(), fr.getMax().toLong(), irmin.toLong(), irmax.toLong());
226 if (removeOverlaps && lst.size() && lst.back().getMax() >= irmin) {
227 lst.back().setMax(irmax);
228 } else {
229 lst.emplace_back(irmin, irmax).info = fr.info;
230 }
231 }
232 mOwnList.swap(lst);
233 mFrames = gsl::span<const o2::dataformats::IRFrame>(mOwnList.data(), mOwnList.size());
234}
int32_t i
bool done
Class to check if give InteractionRecord or IRFrame is selected by the external IRFrame vector.
uint32_t res
Definition RawData.h:0
std::ostringstream debug
StringRef key
Relation isOutside(const Bracket< T > &t) const
Definition Bracket.h:230
void setMax(T v) noexcept
Definition Bracket.h:132
void setMin(T v) noexcept
Definition Bracket.h:138
void setOwnList(const std::vector< o2::dataformats::IRFrame > &lst, bool toBeSorted)
void print(bool lst=false) const
size_t loadIRFrames(const std::string &fname)
void applyMargins(size_t bwd, size_t fwd, long shift, bool removeOverlaps=true)
long check(o2::dataformats::IRFrame fr, size_t bwd=0, size_t fwd=0)
gsl::span< const o2::dataformats::IRFrame > getMatchingFrames(const o2::dataformats::IRFrame &fr)
void setSelectedIRFrames(const SPAN &sp, size_t bwd=0, size_t fwd=0, long shift=0, bool removeOverlaps=true)
const GLdouble * v
Definition glcorearb.h:832
GLdouble f
Definition glcorearb.h:310
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
static constexpr InteractionRecord getIRMaxBC()
std::string asString() const
static constexpr int64_t MaxGlobalBCs
static InteractionRecord long2IR(int64_t l)