Project
Loading...
Searching...
No Matches
Utils.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
12#include <cmath>
13#include <memory>
14#include <regex>
15#include <string>
16#include <string_view>
17#include <fmt/format.h>
18#include <fmt/printf.h>
19
20#include "TSystem.h"
21#include "TObject.h"
22#include "TClass.h"
23#include "TKey.h"
24#include "TObjArray.h"
25#include "TCanvas.h"
26#include "TH1.h"
27#include "TFile.h"
28#include "TChain.h"
29#include "TGrid.h"
30
32#include "Framework/Logger.h"
33#include "TPCBase/Mapper.h"
34#include "TPCBase/Utils.h"
35
36using namespace o2::tpc;
37
40const std::vector<std::string> utils::tokenize(const std::string_view input, const std::string_view pattern)
41{
42 // passing -1 as the submatch index parameter performs splitting
43 std::regex re(pattern.data());
44 std::cregex_token_iterator
45 first{input.begin(), input.end(), re, -1},
46 last;
47 return {first, last};
48}
49
50TH1* utils::getBinInfoXY(int& binx, int& biny, float& bincx, float& bincy)
51{
52 TObject* select = gPad->GetSelected();
53 if (!select) {
54 return nullptr;
55 }
56 if (!select->InheritsFrom("TH2")) {
57 gPad->SetUniqueID(0);
58 return nullptr;
59 }
60
61 TH1* h = (TH1*)select;
62 gPad->GetCanvas()->FeedbackMode(kTRUE);
63
64 const int px = gPad->GetEventX();
65 const int py = gPad->GetEventY();
66 const float xx = gPad->AbsPixeltoX(px);
67 const float x = gPad->PadtoX(xx);
68 const float yy = gPad->AbsPixeltoY(py);
69 const float y = gPad->PadtoX(yy);
70 binx = h->GetXaxis()->FindBin(x);
71 biny = h->GetYaxis()->FindBin(y);
72 bincx = h->GetXaxis()->GetBinCenter(binx);
73 bincy = h->GetYaxis()->GetBinCenter(biny);
74
75 return h;
76}
77
78void utils::addFECInfo()
79{
80 using namespace o2::tpc;
81 const int event = gPad->GetEvent();
82 if (event != 51) {
83 return;
84 }
85
86 int binx, biny;
87 float bincx, bincy;
88 TH1* h = utils::getBinInfoXY(binx, biny, bincx, bincy);
89 if (!h) {
90 return;
91 }
92
93 const float binValue = h->GetBinContent(binx, biny);
94 const int row = int(std::floor(bincx));
95 const int cpad = int(std::floor(bincy));
96
97 const auto& mapper = Mapper::instance();
98
99 const int roc = h->GetUniqueID();
100 if (roc < 0 || roc >= (int)ROC::MaxROC) {
101 return;
102 }
103 if (row < 0 || row >= (int)mapper.getNumberOfRowsROC(roc)) {
104 return;
105 }
106 const int nPads = mapper.getNumberOfPadsInRowROC(roc, row);
107 const int pad = cpad + nPads / 2;
108 if (pad < 0 || pad >= (int)nPads) {
109 return;
110 }
111 const int channel = mapper.getPadNumberInROC(PadROCPos(roc, row, pad));
112 const int padOffset = (roc > 35) * Mapper::getPadsInIROC();
113
114 const auto& fecInfo = mapper.getFECInfo(PadROCPos(roc, row, pad));
115 const int cruNumber = mapper.getCRU(ROC(roc).getSector(), channel + padOffset);
116 const CRU cru(cruNumber);
117 const PartitionInfo& partInfo = mapper.getMapPartitionInfo()[cru.partition()];
118 const int nFECs = partInfo.getNumberOfFECs();
119 const int fecOffset = (nFECs + 1) / 2;
120 const int fecInPartition = fecInfo.getIndex() - partInfo.getSectorFECOffset();
121 const int dataWrapperID = fecInPartition >= fecOffset;
122 const int globalLinkID = (fecInPartition % fecOffset) + dataWrapperID * 12;
123
124 const std::string title = fmt::format(
125 "#splitline{{#lower[.1]{{#scale[.5]{{"
126 "{}{:02d} ({:02d}) row: {:02d}, pad: {:03d}, globalpad: {:05d} (in roc)"
127 "}}}}}}{{#scale[.5]{{FEC: "
128 "{:02d}, Chip: {:02d}, Chn: {:02d}, CRU: {:d}, Link: {:02d} ({}{:02d}), Value: {:.3f}"
129 "}}}}",
130 (roc / 18 % 2 == 0) ? "A" : "C", roc % 18, roc, row, pad, channel, fecInfo.getIndex(), fecInfo.getSampaChip(),
131 fecInfo.getSampaChannel(), cruNumber % CRU::CRUperSector, globalLinkID, dataWrapperID ? "B" : "A", globalLinkID % 12, binValue);
132
133 h->SetTitle(title.data());
134}
135
136void utils::saveCanvases(TObjArray& arr, std::string_view outDir, std::string_view types, std::string_view singleOutFileName, std::string nameAdd)
137{
138 if (types.size()) {
139 for (auto c : arr) {
140 utils::saveCanvas(*static_cast<TCanvas*>(c), outDir, types, nameAdd);
141 }
142 }
143
144 if (singleOutFileName.size()) {
145 const auto outFileNames = o2::utils::Str::tokenize(singleOutFileName.data(), ',');
146 for (const auto& outFileName : outFileNames) {
147 auto fileName = fmt::format("{}/{}", outDir, outFileName);
148 if (o2::utils::Str::endsWith(outFileName, ".root")) {
149 std::unique_ptr<TFile> outFile(TFile::Open(fileName.data(), "recreate"));
150 arr.Write(arr.GetName(), TObject::kSingleKey);
151 outFile->Close();
152 } else if (o2::utils::Str::endsWith(outFileName, ".pdf")) {
153 const auto nCanv = arr.GetEntries();
154 for (int i = 0; i < nCanv; ++i) {
155 auto fileName2 = fileName;
156 if (i == 0) {
157 fileName2 += "(";
158 } else if (i == nCanv - 1) {
159 fileName2 += ")";
160 }
161 auto c = static_cast<TCanvas*>(arr.UncheckedAt(i));
162 c->Print(fileName2.data(), fmt::format("Title:{}", c->GetTitle()).data());
163 }
164 }
165 }
166 }
167}
168
169void utils::saveCanvases(std::vector<TCanvas*>& canvases, std::string_view outDir, std::string_view types, std::string_view singleOutFileName, std::string nameAdd)
170{
171 TObjArray arr;
172 for (auto c : canvases) {
173 arr.Add(c);
174 }
175
176 saveCanvases(arr, outDir, types, singleOutFileName, nameAdd);
177}
178
179void utils::saveCanvas(TCanvas& c, std::string_view outDir, std::string_view types, std::string nameAdd)
180{
181 if (!types.size()) {
182 return;
183 }
184 const auto typesVec = tokenize(types, ",");
185 for (const auto& type : typesVec) {
186 c.SaveAs(fmt::format("{}/{}{}.{}", outDir, c.GetName(), nameAdd, type).data());
187 }
188}
189
190std::vector<CalPad*> utils::readCalPads(const std::string_view fileName, const std::vector<std::string>& calPadNames)
191{
192 using CalPadMapType = std::unordered_map<std::string, CalPad>;
193
194 std::vector<CalPad*> calPads(calPadNames.size());
195
196 std::unique_ptr<TFile> file(TFile::Open(fileName.data()));
197 if (!file || !file->IsOpen() || file->IsZombie()) {
198 return calPads;
199 }
200
201 // check if we have a map of calPads
202 auto firstKey = (TKey*)file->GetListOfKeys()->At(0);
203 const auto clMap = TClass::GetClass(typeid(CalPadMapType));
204 if (std::string_view(firstKey->GetClassName()) == std::string_view(clMap->GetName())) {
205 auto calPadMap = firstKey->ReadObject<CalPadMapType>();
206 for (size_t iCalPad = 0; iCalPad < calPadNames.size(); ++iCalPad) {
207 calPads[iCalPad] = new CalPad(calPadMap->at(calPadNames[iCalPad]));
208 }
209 delete calPadMap;
210 } else {
211 for (size_t iCalPad = 0; iCalPad < calPadNames.size(); ++iCalPad) {
212 file->GetObject(calPadNames[iCalPad].data(), calPads[iCalPad]);
213 }
214 }
215
216 return calPads;
217}
218
219std::vector<CalPad*> utils::readCalPads(const std::string_view fileName, const std::string_view calPadNames)
220{
221 auto calPadNamesVec = tokenize(calPadNames, ",");
222 return readCalPads(fileName, calPadNamesVec);
223}
224
225//______________________________________________________________________________
226void utils::mergeCalPads(std::string_view outputFileName, std::string_view inputFileNames, std::string_view calPadNames, bool average)
227{
228 using namespace o2::tpc;
229
230 const auto calPadNamesVec = utils::tokenize(calPadNames, ",");
231
232 std::string_view cmd = "ls";
233 if (inputFileNames.rfind(".root") == std::string_view::npos) {
234 cmd = "cat";
235 }
236 auto files = gSystem->GetFromPipe(TString::Format("%s %s", cmd.data(), inputFileNames.data()));
237 std::unique_ptr<TObjArray> arrFiles(files.Tokenize("\n"));
238
239 std::vector<CalPad*> mergedCalPads;
240
241 for (auto ofile : *arrFiles) {
242 auto calPads = utils::readCalPads(ofile->GetName(), calPadNamesVec);
243 if (!calPads.size()) {
244 continue;
245 }
246 if (!mergedCalPads.size()) {
247 mergedCalPads = calPads;
248 } else {
249 for (size_t iCalPad = 0; iCalPad < calPads.size(); ++iCalPad) {
250 auto calPadName = calPadNamesVec[iCalPad];
251 auto calPadMerged = mergedCalPads[iCalPad];
252 calPadMerged->setName(calPadName);
253 auto calPadToMerge = calPads[iCalPad];
254
255 *calPadMerged += *calPadToMerge;
256
257 delete calPadToMerge;
258 }
259 }
260 }
261
262 if (average) {
263 const auto n = arrFiles->GetEntriesFast();
264 if (n > 0) {
265 for (auto calPad : mergedCalPads) {
266 *calPad /= n;
267 }
268 }
269 }
270
271 std::unique_ptr<TFile> outFile(TFile::Open(outputFileName.data(), "recreate"));
272 for (auto calPad : mergedCalPads) {
273 outFile->WriteObject(calPad, calPad->getName().data());
274 }
275}
276
277//______________________________________________________________________________
278TChain* utils::buildChain(std::string_view command, std::string_view treeName, std::string_view treeTitle, bool checkSubDir)
279{
280 const TString files = gSystem->GetFromPipe(command.data());
281 std::unique_ptr<TObjArray> arrFiles(files.Tokenize("\n"));
282 if (!arrFiles->GetEntriesFast()) {
283 LOGP(error, "command '{}' did not return results", command);
284 return nullptr;
285 }
286
287 auto c = new TChain(treeName.data(), treeTitle.data());
288 for (const auto o : *arrFiles) {
289 if (o2::utils::Str::beginsWith(o->GetName(), "alien://") && !gGrid && !TGrid::Connect("alien://")) {
290 LOGP(fatal, "could not open alien connection to read {}", o->GetName());
291 }
292
293 if (checkSubDir) {
294 std::unique_ptr<TFile> f(TFile::Open(o->GetName()));
295 if (!f->IsOpen() || f->IsZombie()) {
296 continue;
297 }
298 for (auto ok : *f->GetListOfKeys()) {
299 auto k = static_cast<TKey*>(ok);
300 if (std::string_view(k->GetClassName()) != "TDirectoryFile") {
301 continue;
302 }
303 auto df = f->Get<TDirectoryFile>(k->GetName());
304 if (df->GetListOfKeys() && df->GetListOfKeys()->FindObject(treeName.data())) {
305 const auto fullTreePath = fmt::format("{}/{}", df->GetName(), treeName);
306 c->AddFile(o->GetName(), TTree::kMaxEntries, fullTreePath.data());
307 LOGP(info, "Adding file '{}', with tree {}", o->GetName(), fullTreePath);
308 }
309 }
310 } else {
311 LOGP(info, "Adding file '{}'", o->GetName());
312 c->AddFile(o->GetName());
313 }
314 }
315
316 return c;
317}
int32_t i
bool o
uint32_t roc
Definition RawData.h:3
uint32_t c
Definition RawData.h:2
Class for time synchronization of RawReader instances.
@ CRUperSector
Definition CRU.h:30
unsigned char partition() const
Definition CRU.h:63
static Mapper & instance(const std::string mappingDir="")
Definition Mapper.h:44
static constexpr unsigned short getPadsInIROC()
Definition Mapper.h:409
Pad and row inside a ROC.
Definition PadROCPos.h:37
unsigned char getNumberOfFECs() const
unsigned char getSectorFECOffset() const
@ MaxROC
Definition ROC.h:47
Sector getSector() const
get sector
Definition ROC.h:105
struct _cl_event * event
Definition glcorearb.h:2982
GLdouble n
Definition glcorearb.h:1982
GLint GLenum GLint x
Definition glcorearb.h:403
GLsizei GLenum GLenum * types
Definition glcorearb.h:2516
GLint first
Definition glcorearb.h:399
GLdouble f
Definition glcorearb.h:310
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLboolean * data
Definition glcorearb.h:298
const std::vector< std::string > tokenize(const std::string_view input, const std::string_view pattern)
Definition Utils.cxx:40
std::vector< CalPad * > readCalPads(const std::string_view fileName, const std::vector< std::string > &calPadNames)
Definition Utils.cxx:190
void saveCanvases(TObjArray &arr, std::string_view outDir, std::string_view types="png,pdf", std::string_view rootFileName="", std::string nameAdd="")
Definition Utils.cxx:136
Global TPC definitions and constants.
Definition SimTraits.h:167
CalDet< float > CalPad
Definition CalDet.h:492
static bool beginsWith(const std::string &s, const std::string &start)
static std::vector< std::string > tokenize(const std::string &src, char delim, bool trimToken=true, bool skipEmpty=true)
static bool endsWith(const std::string &s, const std::string &ending)
std::vector< int > row
std::array< uint16_t, 5 > pattern