Skip to content

Commit 0d5bdca

Browse files
committed
Utility macros for CTF manipulations
1 parent d343f1e commit 0d5bdca

File tree

4 files changed

+347
-0
lines changed

4 files changed

+347
-0
lines changed

Detectors/CTF/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# or submit itself to any jurisdiction.
1111

1212
add_subdirectory(workflow)
13+
add_subdirectory(utils)
1314

1415
o2_add_test(itsmft
1516
PUBLIC_LINK_LIBRARIES O2::ITSMFTReconstruction

Detectors/CTF/utils/CMakeLists.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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+
# setup files to be installed (only ROOT macros for the moment) NOT using GLOB,
13+
# as we should be mindful of what we install. if we have lot of files here, it's
14+
# probably because most of them should be elsewhere in the first place ...
15+
16+
install(FILES extractCTF.C
17+
dumpCTF.C
18+
DESTINATION share/macro/)
19+
20+
o2_add_test_root_macro(extractCTF.C
21+
PUBLIC_LINK_LIBRARIES O2::CTFWorkflow
22+
LABELS ctf)
23+
24+
o2_add_test_root_macro(dumpCTF.C
25+
PUBLIC_LINK_LIBRARIES O2::CTFWorkflow
26+
LABELS ctf)

Detectors/CTF/utils/dumpCTF.C

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
#if !defined(__CLING__) || defined(__ROOTCLING__)
2+
3+
#include "DetectorsCommonDataFormats/EncodedBlocks.h"
4+
#include "DetectorsCommonDataFormats/NameConf.h"
5+
#include "DetectorsCommonDataFormats/CTFHeader.h"
6+
#include "DataFormatsITSMFT/CTF.h"
7+
#include "DataFormatsTPC/CTF.h"
8+
#include "DataFormatsTRD/CTF.h"
9+
#include "DataFormatsFT0/CTF.h"
10+
#include "DataFormatsFV0/CTF.h"
11+
#include "DataFormatsFDD/CTF.h"
12+
#include "DataFormatsTOF/CTF.h"
13+
#include "DataFormatsMID/CTF.h"
14+
#include "DataFormatsMCH/CTF.h"
15+
#include "DataFormatsEMCAL/CTF.h"
16+
#include "DataFormatsPHOS/CTF.h"
17+
#include "DataFormatsCPV/CTF.h"
18+
#include "DataFormatsZDC/CTF.h"
19+
#include "DataFormatsHMP/CTF.h"
20+
#include "DataFormatsCTP/CTF.h"
21+
22+
#endif
23+
24+
using DetID = o2::detectors::DetID;
25+
26+
template <typename T>
27+
bool readFromTree(TTree& tree, const std::string brname, T& dest, int ev = 0)
28+
{
29+
auto* br = tree.GetBranch(brname.c_str());
30+
if (br && br->GetEntries() > ev) {
31+
auto* ptr = &dest;
32+
br->SetAddress(&ptr);
33+
br->GetEntry(ev);
34+
br->ResetAddress();
35+
return true;
36+
}
37+
return false;
38+
}
39+
40+
template <typename C>
41+
void dumpDetCTF(int ctfID, DetID det, TTree& treeIn, int ncolls)
42+
{
43+
std::vector<o2::ctf::BufferType> buff;
44+
buff.resize(sizeof(C));
45+
C::readFromTree(buff, treeIn, det.getName(), ctfID);
46+
const auto ctf = C::getImage(buff.data());
47+
ctf.dump(det.getName(), ncolls);
48+
}
49+
50+
void dumpCTF(const std::string& fnameIn, int ctfID = 0, const std::string selDet = "all", int ncolls = 20)
51+
{
52+
std::unique_ptr<TFile> flIn(TFile::Open(fnameIn.c_str()));
53+
std::unique_ptr<TTree> treeIn((TTree*)flIn->Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()));
54+
if (treeIn->GetEntries() <= ctfID) {
55+
LOG(ERROR) << "File " << fnameIn << " has only " << treeIn->GetEntries() << " entries, requested : " << ctfID;
56+
treeIn.reset();
57+
return;
58+
}
59+
60+
o2::ctf::CTFHeader ctfHeader;
61+
if (!readFromTree(*treeIn, "CTFHeader", ctfHeader, ctfID)) {
62+
throw std::runtime_error("did not find CTFHeader");
63+
}
64+
65+
DetID::mask_t detsTF = ctfHeader.detectors & DetID::getMask(selDet);
66+
if (detsTF.none()) {
67+
LOG(ERROR) << "Nothing is selected with mask " << selDet << " CTF constains " << DetID::getNames(ctfHeader.detectors);
68+
treeIn.reset();
69+
return;
70+
}
71+
72+
LOG(INFO) << ctfHeader;
73+
74+
if (detsTF[DetID::ITS]) {
75+
dumpDetCTF<o2::itsmft::CTF>(ctfID, DetID::ITS, *treeIn, ncolls);
76+
}
77+
78+
if (detsTF[DetID::MFT]) {
79+
dumpDetCTF<o2::itsmft::CTF>(ctfID, DetID::MFT, *treeIn, ncolls);
80+
}
81+
82+
if (detsTF[DetID::TPC]) {
83+
dumpDetCTF<o2::tpc::CTF>(ctfID, DetID::TPC, *treeIn, ncolls);
84+
}
85+
86+
if (detsTF[DetID::TRD]) {
87+
dumpDetCTF<o2::trd::CTF>(ctfID, DetID::TRD, *treeIn, ncolls);
88+
}
89+
90+
if (detsTF[DetID::TOF]) {
91+
dumpDetCTF<o2::tof::CTF>(ctfID, DetID::TOF, *treeIn, ncolls);
92+
}
93+
94+
if (detsTF[DetID::FT0]) {
95+
dumpDetCTF<o2::ft0::CTF>(ctfID, DetID::FT0, *treeIn, ncolls);
96+
}
97+
98+
if (detsTF[DetID::FV0]) {
99+
dumpDetCTF<o2::fv0::CTF>(ctfID, DetID::FV0, *treeIn, ncolls);
100+
}
101+
102+
if (detsTF[DetID::FDD]) {
103+
dumpDetCTF<o2::fdd::CTF>(ctfID, DetID::FDD, *treeIn, ncolls);
104+
}
105+
106+
if (detsTF[DetID::MCH]) {
107+
dumpDetCTF<o2::mch::CTF>(ctfID, DetID::MCH, *treeIn, ncolls);
108+
}
109+
110+
if (detsTF[DetID::MID]) {
111+
dumpDetCTF<o2::mid::CTF>(ctfID, DetID::MID, *treeIn, ncolls);
112+
}
113+
114+
if (detsTF[DetID::ZDC]) {
115+
dumpDetCTF<o2::zdc::CTF>(ctfID, DetID::ZDC, *treeIn, ncolls);
116+
}
117+
118+
if (detsTF[DetID::EMC]) {
119+
dumpDetCTF<o2::emcal::CTF>(ctfID, DetID::EMC, *treeIn, ncolls);
120+
}
121+
122+
if (detsTF[DetID::PHS]) {
123+
dumpDetCTF<o2::phos::CTF>(ctfID, DetID::PHS, *treeIn, ncolls);
124+
}
125+
126+
if (detsTF[DetID::CPV]) {
127+
dumpDetCTF<o2::cpv::CTF>(ctfID, DetID::CPV, *treeIn, ncolls);
128+
}
129+
130+
if (detsTF[DetID::HMP]) {
131+
dumpDetCTF<o2::hmpid::CTF>(ctfID, DetID::HMP, *treeIn, ncolls);
132+
}
133+
134+
if (detsTF[DetID::CTP]) {
135+
dumpDetCTF<o2::ctp::CTF>(ctfID, DetID::CTP, *treeIn, ncolls);
136+
}
137+
138+
treeIn.reset();
139+
}

Detectors/CTF/utils/extractCTF.C

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
#if !defined(__CLING__) || defined(__ROOTCLING__)
2+
3+
#include "DetectorsCommonDataFormats/EncodedBlocks.h"
4+
#include "DetectorsCommonDataFormats/NameConf.h"
5+
#include "DetectorsCommonDataFormats/CTFHeader.h"
6+
#include "DataFormatsITSMFT/CTF.h"
7+
#include "DataFormatsTPC/CTF.h"
8+
#include "DataFormatsTRD/CTF.h"
9+
#include "DataFormatsFT0/CTF.h"
10+
#include "DataFormatsFV0/CTF.h"
11+
#include "DataFormatsFDD/CTF.h"
12+
#include "DataFormatsTOF/CTF.h"
13+
#include "DataFormatsMID/CTF.h"
14+
#include "DataFormatsMCH/CTF.h"
15+
#include "DataFormatsEMCAL/CTF.h"
16+
#include "DataFormatsPHOS/CTF.h"
17+
#include "DataFormatsCPV/CTF.h"
18+
#include "DataFormatsZDC/CTF.h"
19+
#include "DataFormatsHMP/CTF.h"
20+
#include "DataFormatsCTP/CTF.h"
21+
22+
#endif
23+
24+
using DetID = o2::detectors::DetID;
25+
26+
template <typename T>
27+
bool readFromTree(TTree& tree, const std::string brname, T& dest, int ev = 0)
28+
{
29+
auto* br = tree.GetBranch(brname.c_str());
30+
if (br && br->GetEntries() > ev) {
31+
auto* ptr = &dest;
32+
br->SetAddress(&ptr);
33+
br->GetEntry(ev);
34+
br->ResetAddress();
35+
return true;
36+
}
37+
return false;
38+
}
39+
40+
template <typename C>
41+
void writeToTree(TTree& tree, const std::vector<o2::ctf::BufferType>& buff, DetID det)
42+
{
43+
const auto ctfImage = C::getImage(buff.data());
44+
ctfImage.appendToTree(tree, det.getName());
45+
}
46+
47+
template <typename T>
48+
size_t appendToTree(TTree& tree, const std::string brname, T& ptr)
49+
{
50+
size_t s = 0;
51+
auto* br = tree.GetBranch(brname.c_str());
52+
auto* pptr = &ptr;
53+
if (br) {
54+
br->SetAddress(&pptr);
55+
} else {
56+
br = tree.Branch(brname.c_str(), &pptr);
57+
}
58+
int res = br->Fill();
59+
if (res < 0) {
60+
throw std::runtime_error(fmt::format("Failed to fill CTF branch {}", brname));
61+
}
62+
s += res;
63+
br->ResetAddress();
64+
return s;
65+
}
66+
67+
template <typename C>
68+
void extractDetCTF(int ctfID, DetID det, TTree& treeIn, TTree& treeOut)
69+
{
70+
std::vector<o2::ctf::BufferType> buff;
71+
buff.resize(sizeof(C));
72+
C::readFromTree(buff, treeIn, det.getName(), ctfID);
73+
writeToTree<C>(treeOut, buff, det);
74+
}
75+
76+
void extractCTF(int ctfID,
77+
const std::string& fnameIn,
78+
const std::string& fnameOut,
79+
const std::string selDet = "all")
80+
{
81+
std::unique_ptr<TFile> flIn(TFile::Open(fnameIn.c_str()));
82+
std::unique_ptr<TTree> treeIn((TTree*)flIn->Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()));
83+
if (treeIn->GetEntries() <= ctfID) {
84+
LOG(ERROR) << "File " << fnameIn << " has only " << treeIn->GetEntries() << " entries, requested : " << ctfID;
85+
treeIn.reset();
86+
return;
87+
}
88+
89+
o2::ctf::CTFHeader ctfHeader;
90+
if (!readFromTree(*treeIn, "CTFHeader", ctfHeader, ctfID)) {
91+
throw std::runtime_error("did not find CTFHeader");
92+
}
93+
94+
LOG(INFO) << ctfHeader;
95+
DetID::mask_t detsTF = ctfHeader.detectors & DetID::getMask(selDet);
96+
if (detsTF.none()) {
97+
LOG(ERROR) << "Nothing is selected with mask " << selDet << " CTF constains " << DetID::getNames(ctfHeader.detectors);
98+
treeIn.reset();
99+
return;
100+
}
101+
ctfHeader.detectors = detsTF;
102+
103+
TFile flOut(fnameOut.c_str(), "recreate");
104+
std::unique_ptr<TTree> treeOut = std::make_unique<TTree>(std::string(o2::base::NameConf::CTFTREENAME).c_str(), "O2 CTF tree");
105+
106+
if (detsTF[DetID::ITS]) {
107+
extractDetCTF<o2::itsmft::CTF>(ctfID, DetID::ITS, *treeIn, *treeOut);
108+
}
109+
110+
if (detsTF[DetID::MFT]) {
111+
extractDetCTF<o2::itsmft::CTF>(ctfID, DetID::MFT, *treeIn, *treeOut);
112+
}
113+
114+
if (detsTF[DetID::TPC]) {
115+
extractDetCTF<o2::tpc::CTF>(ctfID, DetID::TPC, *treeIn, *treeOut);
116+
}
117+
118+
if (detsTF[DetID::TRD]) {
119+
extractDetCTF<o2::trd::CTF>(ctfID, DetID::TRD, *treeIn, *treeOut);
120+
}
121+
122+
if (detsTF[DetID::TOF]) {
123+
extractDetCTF<o2::tof::CTF>(ctfID, DetID::TOF, *treeIn, *treeOut);
124+
}
125+
126+
if (detsTF[DetID::FT0]) {
127+
extractDetCTF<o2::ft0::CTF>(ctfID, DetID::FT0, *treeIn, *treeOut);
128+
}
129+
130+
if (detsTF[DetID::FV0]) {
131+
extractDetCTF<o2::fv0::CTF>(ctfID, DetID::FV0, *treeIn, *treeOut);
132+
}
133+
134+
if (detsTF[DetID::FDD]) {
135+
extractDetCTF<o2::fdd::CTF>(ctfID, DetID::FDD, *treeIn, *treeOut);
136+
}
137+
138+
if (detsTF[DetID::MCH]) {
139+
extractDetCTF<o2::mch::CTF>(ctfID, DetID::MCH, *treeIn, *treeOut);
140+
}
141+
142+
if (detsTF[DetID::MID]) {
143+
extractDetCTF<o2::mid::CTF>(ctfID, DetID::MID, *treeIn, *treeOut);
144+
}
145+
146+
if (detsTF[DetID::ZDC]) {
147+
extractDetCTF<o2::zdc::CTF>(ctfID, DetID::ZDC, *treeIn, *treeOut);
148+
}
149+
150+
if (detsTF[DetID::EMC]) {
151+
extractDetCTF<o2::emcal::CTF>(ctfID, DetID::EMC, *treeIn, *treeOut);
152+
}
153+
154+
if (detsTF[DetID::PHS]) {
155+
extractDetCTF<o2::phos::CTF>(ctfID, DetID::PHS, *treeIn, *treeOut);
156+
}
157+
158+
if (detsTF[DetID::CPV]) {
159+
extractDetCTF<o2::cpv::CTF>(ctfID, DetID::CPV, *treeIn, *treeOut);
160+
}
161+
162+
if (detsTF[DetID::HMP]) {
163+
extractDetCTF<o2::hmpid::CTF>(ctfID, DetID::HMP, *treeIn, *treeOut);
164+
}
165+
166+
if (detsTF[DetID::CTP]) {
167+
extractDetCTF<o2::ctp::CTF>(ctfID, DetID::CTP, *treeIn, *treeOut);
168+
}
169+
170+
appendToTree(*treeOut, "CTFHeader", ctfHeader);
171+
172+
treeOut->SetEntries(1);
173+
174+
LOG(INFO) << "Wrote CTFs of entry " << ctfID << " for " << DetID::getNames(ctfHeader.detectors) << " to " << fnameOut;
175+
176+
treeOut->Write();
177+
treeOut.reset();
178+
flOut.Close();
179+
180+
treeIn.reset();
181+
}

0 commit comments

Comments
 (0)