Project
Loading...
Searching...
No Matches
convert-geometry.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 <boost/program_options.hpp>
13#include <iostream>
14#include <stdexcept>
15#include <TGeoManager.h>
16#include <TFile.h>
17#include <sstream>
18#include <tuple>
19#include <vector>
20#include <string>
21#include "TGeoPhysicalNode.h"
22#include <rapidjson/document.h>
23#include <rapidjson/ostreamwrapper.h>
24#include <rapidjson/stringbuffer.h>
25#include <rapidjson/writer.h>
26#include <gsl/span>
27#include <cmath>
28#include <array>
30
31namespace po = boost::program_options;
32
33std::vector<std::string> splitString(const std::string& src, char delim)
34{
35 std::stringstream ss(src);
36 std::string token;
37 std::vector<std::string> tokens;
38
39 while (std::getline(ss, token, delim)) {
40 if (!token.empty()) {
41 tokens.push_back(std::move(token));
42 }
43 }
44
45 return tokens;
46}
47
48TGeoManager* readFromFile(std::string filename)
49{
50 TFile* f = TFile::Open(filename.c_str());
51 if (f->IsZombie()) {
52 throw std::runtime_error("can not open " + filename);
53 }
54
55 auto possibleGeoNames = {"ccdb_object", "ALICE", "FAIRGeom", "MCH-ONLY", "MCH-BASICS"};
56
57 TGeoManager* geo{nullptr};
58
59 for (auto name : possibleGeoNames) {
60 geo = static_cast<TGeoManager*>(f->Get(name));
61 if (geo) {
62 break;
63 }
64 }
65 if (!geo) {
66 f->ls();
67 throw std::runtime_error("could not find ALICE geometry (using ccdb_object, ALICE or FAIRGeom names)");
68 }
69 return geo;
70}
71
72template <typename WRITER>
73void matrix2json(const TGeoHMatrix& matrix, WRITER& w)
74{
75
76 constexpr double rad2deg = 180.0 / 3.14159265358979323846;
77
78 const Double_t* t = matrix.GetTranslation();
79 const Double_t* m = matrix.GetRotationMatrix();
80 gsl::span<double> mat(const_cast<double*>(m), 9);
81 auto [yaw, pitch, roll] = o2::mch::geo::matrix2angles(mat);
82 w.Key("tx");
83 w.Double(t[0]);
84 w.Key("ty");
85 w.Double(t[1]);
86 w.Key("tz");
87 w.Double(t[2]);
88 w.Key("yaw");
89 w.Double(rad2deg * yaw);
90 w.Key("pitch");
91 w.Double(rad2deg * pitch);
92 w.Key("roll");
93 w.Double(rad2deg * roll);
94}
95
96std::tuple<bool, uint16_t> isMCH(std::string alignableName)
97{
98 auto parts = splitString(alignableName, '/');
99 bool aliroot = parts[0] == "MUON";
100 bool o2 = parts[0] == "MCH";
101 if (!o2 && !aliroot) {
102 return {false, 0};
103 }
104 auto id = std::stoi(parts[1].substr(2));
105 bool ok = (aliroot && (id <= 15)) || (o2 && (id <= 19));
106 uint16_t deId{0};
107 if (ok && parts.size() > 2) {
108 deId = std::stoi(parts[2].substr(2));
109 }
110 return {ok, deId};
111}
112
113template <typename WRITER>
114void writeMatrix(const char* name, const TGeoHMatrix* matrix, WRITER& w)
115{
116 if (matrix) {
117 w.Key(name);
118 w.StartObject();
119 matrix2json(*matrix, w);
120 w.EndObject();
121 }
122}
123
126void convertGeom(const TGeoManager& geom)
127{
128 rapidjson::OStreamWrapper osw(std::cout);
129 rapidjson::Writer<rapidjson::OStreamWrapper> writer(osw);
130
131 writer.StartObject();
132 writer.Key("alignables");
133 writer.StartArray();
134
135 for (auto i = 0; i < geom.GetNAlignable(); i++) {
136 auto ae = geom.GetAlignableEntry(i);
137 std::string symname = ae->GetName();
138 auto [mch, deId] = isMCH(symname);
139 if (!mch) {
140 continue;
141 }
142 writer.StartObject();
143 if (deId > 0) {
144 writer.Key("deid");
145 writer.Int(deId);
146 }
147 writer.Key("symname");
148 writer.String(symname.c_str());
149 auto pn = ae->GetPhysicalNode();
150 const TGeoHMatrix* matrix{nullptr};
151 bool aligned{false};
152 if (pn) {
153 matrix = pn->GetMatrix();
154 aligned = pn->IsAligned();
155 } else {
156 matrix = ae->GetGlobalOrig();
157 aligned = false;
158 }
159 writeMatrix("transform", matrix, writer);
160 writer.Key("aligned");
161 writer.Bool(aligned);
162 writer.EndObject();
163 }
164 writer.EndArray();
165 writer.EndObject();
166}
167
168int main(int argc, char** argv)
169{
170 po::variables_map vm;
171 po::options_description options;
172
173 // clang-format off
174 options.add_options()
175 ("help,h","help")
176 ("geom",po::value<std::string>()->required(),"geometry.root file");
177 // clang-format on
178
179 po::options_description cmdline;
180 cmdline.add(options);
181
182 po::store(po::command_line_parser(argc, argv).options(cmdline).run(), vm);
183
184 if (vm.count("help")) {
185 std::cout << "This program extract MCH geometry transformation from "
186 "a geometry root file and write them in json format.\n";
187 std::cout << "\n";
188 std::cout << options << "\n";
189 std::cout << "\n";
190 std::cout << "Note that the json format can then be further manipulated using e.g."
191 "the jq utility\n";
192 std::cout << "For instance sorting by deid:\n";
193 std::cout << "cat output.json | jq '.alignables|=sort_by(.deid)'\n";
194 std::cout << "\n";
195 return 2;
196 }
197
198 try {
199 po::notify(vm);
200 } catch (boost::program_options::error& e) {
201 std::cout << "Error: " << e.what() << "\n";
202 std::cout << options << "\n";
203 exit(1);
204 }
205
206 TGeoManager* geom = readFromFile(vm["geom"].as<std::string>());
207
208 if (geom) {
209 convertGeom(*geom);
210 return 0;
211 } else {
212 return 3;
213 }
214 return 0;
215}
int32_t i
std::vector< std::string > splitString(const std::string &src, char delim)
std::tuple< bool, uint16_t > isMCH(std::string alignableName)
void matrix2json(const TGeoHMatrix &matrix, WRITER &w)
void writeMatrix(const char *name, const TGeoHMatrix *matrix, WRITER &w)
void convertGeom(const TGeoManager &geom)
TGeoManager * readFromFile(std::string filename)
const GLfloat * m
Definition glcorearb.h:4066
GLenum src
Definition glcorearb.h:1767
GLuint const GLchar * name
Definition glcorearb.h:781
GLdouble f
Definition glcorearb.h:310
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
std::tuple< double, double, double > matrix2angles(gsl::span< double > rot)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string filename()
constexpr double rad2deg
#define main