Project
Loading...
Searching...
No Matches
MisalignmentManager.cxx
Go to the documentation of this file.
1// Copyright 2020-2022 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 "Framework/Logger.h"
16
17#include "TFile.h"
18#include "TStopwatch.h"
19#include "TGeoManager.h"
20
21#include <string>
22#include <filesystem>
23#include <memory>
24#include <algorithm>
25#include <optional>
26#include <vector>
27
28namespace fs = std::filesystem;
29
30namespace o2::its3::align
31{
32
33void MisalignmentManager::createBackup(const fs::path& src, const fs::path& dest)
34{
35 if (fs::exists(dest)) {
36 LOGP(info, "Previous orignal file found, using this as src");
37 } else {
38 if (!fs::exists(src)) {
39 LOGP(fatal, "File {} does not exist", src.c_str());
40 }
41 LOGP(info, "Trying to backup file to {}", dest.c_str());
42 try {
43 fs::rename(src, dest);
44 } catch (const fs::filesystem_error& err) {
45 LOGP(fatal, "Cannot create backup file for Hit-File: {}", err.what());
46 }
47 }
48}
49
51{
52 LOGP(info, "{:*^90}", " ITS3 LOCAL MISALIGNMENT START ");
53
54 TStopwatch timer;
55 timer.Start();
56
58 MisAligner.init();
59
60 const fs::path oldHitFileSrc{fs::current_path().string() + "/" + o2::conf::DigiParams::Instance().digitizationgeometry_prefix + "_HitsIT3.root"};
61 const fs::path oldHitFileDest{fs::current_path().string() + "/" + o2::conf::DigiParams::Instance().digitizationgeometry_prefix + "_HitsIT3_Orig.root"};
62 createBackup(oldHitFileSrc, oldHitFileDest);
63
64 std::unique_ptr<TFile> origFile{TFile::Open(oldHitFileDest.c_str(), "READ")};
65 if (origFile == nullptr || origFile->IsZombie()) {
66 LOGP(fatal, "Original file {} cannot be opened", oldHitFileDest.c_str());
67 }
68
69 std::unique_ptr<TTree> origTree{origFile->Get<TTree>("o2sim")};
70 if (origTree == nullptr) {
71 LOGP(fatal, "Cannot get hit-tree from orignal file");
72 }
73 std::vector<o2::itsmft::Hit> origHits, *origHitsPtr{&origHits};
74 origTree->SetBranchAddress("IT3Hit", &origHitsPtr);
75
76 std::unique_ptr<TFile> newFile{TFile::Open(oldHitFileSrc.c_str(), "RECREATE")};
77 if (newFile == nullptr || newFile->IsZombie()) {
78 LOGP(fatal, "New file {} cannot be opened", oldHitFileSrc.c_str());
79 }
80
81 auto newTree = std::make_unique<TTree>("o2sim", "o2sim");
82 std::vector<o2::itsmft::Hit> newHits, *newHitsPtr{nullptr};
83 newTree->Branch("IT3Hit", &newHitsPtr);
84
85 LOGP(info, "Preparations done; starting hit loop");
86 auto nEntries = origTree->GetEntries();
87 ULong64_t totalOrigHits{0}, totalNewHits{0};
88 for (Long64_t iEntry{0}; origTree->LoadTree(iEntry) >= 0; ++iEntry) {
89 if (origTree->GetEntry(iEntry) <= 0) {
90 continue;
91 }
92
93 const auto progress = (iEntry * 100) / nEntries;
94 LOG_IF(info, progress % 10 == 0) << "Processing event " << iEntry << " / " << nEntries;
95
96 newHits.clear();
97 newHits.reserve(origHits.size());
98 for (const auto& origHit : origHits) {
99 if (auto newHit = MisAligner.processHit(iEntry, origHit)) {
100 newHits.emplace_back(*newHit);
101 }
102 }
103
104 newHitsPtr = &newHits;
105 newTree->Fill();
106
107 totalNewHits += newHits.size();
108 totalOrigHits += origHits.size();
109 }
110
111 newFile->WriteTObject(newTree.get());
112
113 timer.Stop();
114
115 MisAligner.printStats();
116
117 auto totalDiscardedHits = totalOrigHits - totalNewHits;
118 LOGP(info, "Summary: Total orignal Hits {}", totalOrigHits);
119 LOGP(info, "Summary: Total misaligned Hits {} ({:.2f}%)", totalNewHits, static_cast<float>(totalNewHits) / static_cast<float>(totalOrigHits) * 100);
120 LOGP(info, "Summary: Total discarded Hits {} ({:.2f}%)", totalDiscardedHits, static_cast<float>(totalDiscardedHits) / static_cast<float>(totalOrigHits) * 100);
121 LOGP(info, "Summary: Misalignment took {:.2f}s", timer.CpuTime());
122 LOGP(info, "{:*^90}", " ITS3 LOCAL MISALIGNMENT END ");
123}
124
125std::string MisalignmentManager::appendStem(const std::string& filename, const std::string& add)
126{
127 fs::path filepath{filename};
128 auto stem = filepath.stem().string();
129 auto extension = filepath.extension().string();
130 return stem + add + extension;
131}
132
133std::vector<std::string> MisalignmentManager::split(const std::string& s, char delimiter)
134{
135 std::vector<std::string> tokens;
136 std::string token;
137 std::istringstream tokenStream(s);
138 while (std::getline(tokenStream, token, delimiter)) {
139 if (!token.empty()) {
140 tokens.push_back(token);
141 }
142 }
143 return tokens;
144}
145
146void MisalignmentManager::navigate(const std::string& path)
147{
148 if (!gGeoManager->cd(path.c_str())) {
149 LOGP(fatal, "Cannot navigate to {}", path);
150 }
151}
152
154{
155 const int layerID{sensor / 2};
156 const int sensorID{sensor % 2};
157 return fmt::format("/cave/barrel_1/ITSV_2/ITSUWrapVol0_1/ITS3Layer{}_0/ITS3CarbonForm{}_{}",
158 layerID, layerID, sensorID);
159}
160
161void MisalignmentManager::applyGlobalMatrixVolume(const std::string& path, const TGeoHMatrix& globalMatrix)
162{
163 gGeoManager->CdTop();
164 TGeoHMatrix* pgMatrix{nullptr};
165 TGeoHMatrix gAccMatrix;
166 std::string curPath{};
167 for (const auto& comp : split(path)) {
168 curPath += "/" + comp;
169 navigate(curPath);
170 pgMatrix = gGeoManager->GetCurrentMatrix();
171 gAccMatrix.Multiply(pgMatrix);
172 }
173 navigate(path);
174 auto node = gGeoManager->GetCurrentNode();
175 if (node == nullptr) {
176 LOGP(fatal, "Nullptr for node at {}", path);
177 }
178 auto motherVol = node->GetMotherVolume();
179 if (motherVol == nullptr) {
180 LOGP(fatal, "Nullptr for motherVol at {}", path);
181 }
182 // Compute the inverse of the accumulated global transformation matrix
183 auto gAccMatrix1 = gAccMatrix.Inverse();
184 // Compute the relative transformation matrix for the volume
185 auto relativeMatrix = globalMatrix;
186 relativeMatrix.MultiplyLeft(gAccMatrix1);
187
188 auto nodemat = dynamic_cast<TGeoNodeMatrix*>(node);
189 nodemat->SetMatrix(new TGeoHMatrix(globalMatrix));
190
191 // Force the container volume of the object to update itself
192 motherVol->Voxelize("");
193}
194
195} // namespace o2::its3::align
GLenum src
Definition glcorearb.h:1767
GLsizei const GLchar *const * path
Definition glcorearb.h:3591
std::string filename()
std::string digitizationgeometry_prefix
Definition DigiParams.h:30
static std::string appendStem(const std::string &filename, const std::string &add)
static void navigate(const std::string &path)
static std::string composePathSensor(int sensor)
static void createBackup(const std::filesystem::path &src, const std::filesystem::path &dest)
static std::vector< std::string > split(const std::string &s, char delimiter='/')
static void applyGlobalMatrixVolume(const std::string &path, const TGeoHMatrix &globalMatrix)