ATLAS Offline Software
Loading...
Searching...
No Matches
runMdtGeoComparison.cxx File Reference
#include <GeoPrimitives/GeoPrimitivesHelpers.h>
#include <GeoPrimitives/GeoPrimitivesToStringConverter.h>
#include "GeoModelHelpers/TransformToStringConverter.h"
#include <MuonCablingData/MdtCablingData.h>
#include <MuonReadoutGeometryR4/MuonDetectorDefs.h>
#include <GaudiKernel/SystemOfUnits.h>
#include <iostream>
#include "Acts/Utilities/UnitVectors.hpp"
#include "Acts/Definitions/Units.hpp"
#include <PathResolver/PathResolver.h>
#include <TFile.h>
#include <TTreeReader.h>

Go to the source code of this file.

Classes

struct  MdtChamber
 Helper struct to represent a full Mdt chamber. More...
struct  MdtChamber::TubePositioning

Macros

#define TEST_BASICPROP(attribute, propName)
#define TEST_TUBEPROP(attribute, propName)

Functions

Amg::Vector3D makeDir (const double theta, const double phi)
std::ostream & operator<< (std::ostream &ostr, const MdtChamber &chamb)
 Translation of the station Index -> station Name.
std::set< MdtChamberreadTreeDump (const std::string &inputFile)
int main1 (int argc, char **argv)
int main (int argc, char **argv)

Variables

constexpr double tolerance = 10 * Gaudi::Units::micrometer

Macro Definition Documentation

◆ TEST_BASICPROP

#define TEST_BASICPROP ( attribute,
propName )
Value:
if (std::abs(1.*test.attribute - 1.*reference.attribute) > tolerance) { \
std::cerr<<"runMdtGeoComparision() "<<__LINE__<<": "<<test \
<<" differs w.r.t "<<propName<<" "<< reference.attribute \
<<" (ref) vs. " <<test.attribute << " (test)" << std::endl; \
chamberOkay = false; \
}

Definition at line 113 of file runMdtGeoComparison.cxx.

113#define TEST_BASICPROP(attribute, propName) \
114 if (std::abs(1.*test.attribute - 1.*reference.attribute) > tolerance) { \
115 std::cerr<<"runMdtGeoComparision() "<<__LINE__<<": "<<test \
116 <<" differs w.r.t "<<propName<<" "<< reference.attribute \
117 <<" (ref) vs. " <<test.attribute << " (test)" << std::endl; \
118 chamberOkay = false; \
119 }

◆ TEST_TUBEPROP

#define TEST_TUBEPROP ( attribute,
propName )
Value:
if (std::abs(1.*refTube.attribute - 1.*testTube.attribute) > tolerance) { \
std::cerr<<"runMdtGeoComparision() "<<__LINE__<<": In "<<test<<" the tubes (" \
<<layer<<","<<std::setfill('0')<<std::setw(3)<<tube<<")" \
<<" differ w.r.t "<<propName<<". " \
<< refTube.attribute <<" (ref) vs. " <<testTube.attribute \
<< " (test)" << std::endl; \
chamberOkay = false; \
}

Definition at line 121 of file runMdtGeoComparison.cxx.

121#define TEST_TUBEPROP(attribute, propName) \
122 if (std::abs(1.*refTube.attribute - 1.*testTube.attribute) > tolerance) { \
123 std::cerr<<"runMdtGeoComparision() "<<__LINE__<<": In "<<test<<" the tubes (" \
124 <<layer<<","<<std::setfill('0')<<std::setw(3)<<tube<<")" \
125 <<" differ w.r.t "<<propName<<". " \
126 << refTube.attribute <<" (ref) vs. " <<testTube.attribute \
127 << " (test)" << std::endl; \
128 chamberOkay = false; \
129 }

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 395 of file runMdtGeoComparison.cxx.

396{
397 int ret = 1;
398 try {
399 ret = main1 (argc, argv);
400 }
401 catch (const std::exception& e) {
402 std::cerr << e.what() << "\n";
403 }
404 return ret;
405}
int main1()
Definition testRead.cxx:68

◆ main1()

int main1 ( int argc,
char ** argv )

check whether the files are xroot d -> otherwise call path resovler

Parse the tree dump

Start to loop over the chambers

We do not care whether the orientation of the coordinate system along the wire flips for negative chambers or not

The ultimate goal is to have the tube positioned at the same place. We maybe need the origin position later when we are adding the alignable transforms...

Check the tube transformations

Remember the tube staggering is in the (x-y) plane. Allow for deviations in the z-axis due to different cutouts

In cases where the tube coordinate systems are not aligned, there's no point in checking the position of the reaodout

Definition at line 249 of file runMdtGeoComparison.cxx.

249 {
250 std::string refFile{}, testFile{};
251
252 for (int arg = 1; arg < argc; ++arg) {
253 std::string the_arg{argv[arg]};
254 if (the_arg == "--refFile" && arg +1 < argc) {
255 refFile = std::string{argv[arg+1]};
256 ++arg;
257 } else if (the_arg == "--testFile" && arg + 1 < argc) {
258 testFile = std::string{argv[arg+1]};
259 ++arg;
260 }
261 }
262 if (refFile.empty()) {
263 std::cerr<<"Please parse the path of the reference file via --refFile "<<std::endl;
264 return EXIT_FAILURE;
265 }
266 if (testFile.empty()) {
267 std::cerr<<"Please parse the path of the test file via --testFile "<<std::endl;
268 return EXIT_FAILURE;
269 }
271 if (!refFile.starts_with( "root://")) refFile = PathResolver::FindCalibFile(refFile);
272 if (!testFile.starts_with( "root://")) testFile = PathResolver::FindCalibFile(testFile);
274 std::set<MdtChamber> refChambers = readTreeDump(refFile);
275 if (refChambers.empty()) {
276 std::cerr<<"The file "<<refFile<<" should contain at least one chamber "<<std::endl;
277 return EXIT_FAILURE;
278 }
279 std::set<MdtChamber> testChambers = readTreeDump(testFile);
280 if (testChambers.empty()) {
281 std::cerr<<"The file "<<testFile<<" should contain at least one chamber "<<std::endl;
282 return EXIT_FAILURE;
283 }
284 int return_code = EXIT_SUCCESS;
285 unsigned int goodChamb{0};
287 for (const MdtChamber& reference : refChambers) {
288 std::set<MdtChamber>::const_iterator test_itr = testChambers.find(reference);
289
290 if (test_itr == testChambers.end()) {
291 std::cerr<<"The chamber "<<reference<<" is not part of the testing "<<std::endl;
292 return_code = EXIT_FAILURE;
293 continue;
294 }
295 bool chamberOkay = true;
296 const MdtChamber& test = {*test_itr};
298 TEST_BASICPROP(numLayers, "number of layers");
299 TEST_BASICPROP(numTubes, "number of tubes");
300 TEST_BASICPROP(tubePitch, "tube pitch");
301 TEST_BASICPROP(tubeRadius, "tube radius");
302
303 const Amg::Transform3D distortion = test.geoModelTransform.inverse() * reference.geoModelTransform;
306 bool flippedChamb = {reference.id.eta < 0 && Amg::doesNotDeform(distortion * Amg::getRotateX3D(M_PI))};
307 if (!Amg::doesNotDeform(distortion) && !flippedChamb) {
308 std::cerr<<"runMdtGeoComparision() "<<__LINE__<<": The chamber coordinate systems rotate differently for "
309 <<reference<<". Difference in the coordinate transformation: "<<Amg::toString(distortion)
310 <<" --- refTrf: "<<Amg::toString(reference.geoModelTransform)
311 <<" --- testTrf: "<<Amg::toString(test.geoModelTransform)<<std::endl;
312 chamberOkay = false;
313 }
316 if (distortion.translation().mag() > tolerance) {
317 std::cout<<"The origins of the chamber coordinate systems are not exactly at the same point for "
318 <<reference<<". Translation shift: "<<Amg::toString(distortion.translation(), 2)<<std::endl;
319 }
321 bool stagFailure{false}, alignFailure{false}, readoutOrient{false};
322 for (unsigned int layer = 1; layer<= std::min(reference.numLayers, test.numLayers) ; ++layer) {
323 for (unsigned int tube = 1; tube <= std::min(reference.numTubes, test.numTubes); ++tube) {
324 using TubePositioning = MdtChamber::TubePositioning;
325 const TubePositioning& refTube = reference.getTube(layer, tube);
326 const TubePositioning& testTube = test.getTube(layer, tube);
327 const Amg::Transform3D tubeDistortion = testTube.localToGlobal.inverse() * refTube.localToGlobal;
328 bool flippedTube{reference.id.eta < 0 && Amg::doesNotDeform(tubeDistortion * Amg::getRotateX3D(M_PI))};
329
330 if (!alignFailure && !(Amg::doesNotDeform(tubeDistortion) || flippedTube)) {
331 std::cerr<<"runMdtGeoComparision() "<<__LINE__<<": In chamber "<<reference<<" the tube reference systems for ("<<layer<<", "
332 <<std::setfill('0')<<std::setw(3)<<tube<<") are not exactly aligned. "<<GeoTrf::toString(tubeDistortion)<<std::endl;
333 alignFailure = true;
334 }
337 if (!stagFailure && tubeDistortion.translation().perp() > tolerance) {
338 std::cerr<<"runMdtGeoComparision() "<<__LINE__<<": Misplaced staggering found in "<<reference<<" the tube ("<<layer
339 <<", "<<std::setfill('0')<<std::setw(3)<<tube<<") "
340 << Amg::toString(tubeDistortion.translation(), 3)<<", mag: "<<tubeDistortion.translation().mag()<<
341 ", perp: "<<tubeDistortion.translation().perp()<<std::endl;
342 if (tube > 1) stagFailure = true;
343 }
344
345 // TEST_TUBEPROP(tubeLength, "tube length");
346 // TEST_TUBEPROP(wireLength, "wire length");
347 TEST_TUBEPROP(activeLength, "active length");
350 if (alignFailure || readoutOrient) continue;
351 const Amg::Transform3D refSystem = refTube.localToGlobal.inverse();
352
353 const Amg::Vector3D refRO = refSystem * refTube.readoutPos;
354 const Amg::Vector3D testRO = refSystem* testTube.readoutPos;
355 if (refRO.z()* testRO.z() < 0.){
356 std::cerr<<"runMdtGeoComparision() "<<__LINE__<<": The readout is on different sites for chamber: "<<reference<<
357 ", layer "<<layer<<", tube: "<<std::setfill('0')<<std::setw(3)<<tube<<". "
358 <<Amg::toString(refRO, 2)<<" vs. "<<Amg::toString(testRO)<<std::endl;
359 readoutOrient = true;
360 }
361 }
362 if (stagFailure || alignFailure) {
363 chamberOkay = false;
364 }
365 }
366 if (!chamberOkay) {
367 return_code = EXIT_FAILURE;
368 continue;
369 }
370 const Amg::Transform3D alignableDistort = test.alignableTransform.inverse()*(reference.alignableTransform );
371 if (!Amg::doesNotDeform(alignableDistort) || alignableDistort.translation().mag() > tolerance) {
372 std::cerr<<"runMdtGeoComparision() "<<__LINE__<<": The alignable nodes are at differnt places for "
373 <<test<<". " <<GeoTrf::toString(alignableDistort, true)<<" chamber length: "<<
374 (reference.tubePitch * (1.*reference.numTubes + 0.5))<<std::endl;
375 chamberOkay = false;
376
377 } else {
378 std::cout<<"runMdtGeoComparision() "<<__LINE__<<": Found perfect agreement between new & old geometry for "<<reference<<std::endl;
379 ++goodChamb;
380 }
381 }
382 for (const MdtChamber& test : testChambers) {
383 if (!refChambers.count(test)) {
384 std::cerr<<"runMdtGeoComparision() "<<__LINE__<<": "<<test<<" is only in the test set."<<std::endl;
385 return_code = EXIT_FAILURE;
386 }
387 }
388 std::cout<<"runMdtGeoComparision() "<<__LINE__<<": "<<goodChamb<<"/"<<refChambers.size()<<" chambers are in perfect agreement. "<<std::endl;
389
390 return return_code;
391
392}
#define M_PI
static std::string FindCalibFile(const std::string &logical_file_name)
Amg::Transform3D getRotateX3D(double angle)
get a rotation transformation around X-axis
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
bool doesNotDeform(const Amg::Transform3D &trans)
Checks whether the linear part of the transformation rotates or stetches any of the basis vectors.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
@ layer
Definition HitInfo.h:79
#define TEST_TUBEPROP(attribute, propName)
#define TEST_BASICPROP(attribute, propName)
std::set< MdtChamber > readTreeDump(const std::string &inputFile)
Helper struct to represent a full Mdt chamber.

◆ makeDir()

Amg::Vector3D makeDir ( const double theta,
const double phi )

Definition at line 30 of file runMdtGeoComparison.cxx.

30 {
31 using namespace Acts::UnitLiterals;
32 return Acts::makeDirectionFromPhiTheta(phi *1._degree, theta* 1._degree);
33}
Scalar phi() const
phi method
Scalar theta() const
theta method

◆ operator<<()

std::ostream & operator<< ( std::ostream & ostr,
const MdtChamber & chamb )

Translation of the station Index -> station Name.

Dictionary taken from https://gitlab.cern.ch/atlas/athena/-/blob/main/DetectorDescription/IdDictParser/data/IdDictMuonSpectrometer_R.09.03.xml

Definition at line 97 of file runMdtGeoComparison.cxx.

97 {
98 static const std::map<int, std::string> stationDict{
99 {0, "BIL"}, {1, "BIS"}, {7, "BIR"},
100 {2, "BML"}, {3, "BMS"}, {8, "BMF"}, {53, "BME"}, {54, "BMG"}, {52, "BIM"},
101 {4, "BOL"}, {5, "BOS"}, {9, "BOF"}, {10, "BOG"},
102 {6, "BEE"}, {14, "EEL"}, {15, "EES"},
103 {13, "EIL"}, {49, "EIS"},
104 {17, "EML"}, {18, "EMS"},
105 {20, "EOL"}, {21, "EOS"}
106 };
107 ostr<<stationDict.at(chamb.id.stationIndex)<<" "<<chamb.id<<" "<<chamb.design;
108 return ostr;
109}
chamberIdentifier id

◆ readTreeDump()

std::set< MdtChamber > readTreeDump ( const std::string & inputFile)

Information to access each tube individually

Readout the information of each tube specifically

Definition at line 131 of file runMdtGeoComparison.cxx.

131 {
132 std::set<MdtChamber> to_ret{};
133 std::cout<<"Read the Mdt geometry tree dump from "<<inputFile<<std::endl;
134 std::unique_ptr<TFile> inFile{TFile::Open(inputFile.c_str())};
135 if (!inFile || !inFile->IsOpen()) {
136 std::cerr<<__FILE__<<":"<<__LINE__<<" Failed to open "<<inputFile<<std::endl;
137 return to_ret;
138 }
139 TTreeReader treeReader("MdtGeoModelTree", inFile.get());
140 if (treeReader.IsInvalid()){
141 std::cerr<<__FILE__<<":"<<__LINE__<<" The file "<<inputFile<<" does not contain the 'MdtGeoModelTree'"<<std::endl;
142 return to_ret;
143 }
144
145 TTreeReaderValue<unsigned short> stationIndex{treeReader, "stationIndex"};
146 TTreeReaderValue<short> stationEta{treeReader, "stationEta"};
147 TTreeReaderValue<short> stationPhi{treeReader, "stationPhi"};
148 TTreeReaderValue<short> stationML{treeReader, "stationMultiLayer"};
149 TTreeReaderValue<std::string> chamberDesign{treeReader,"chamberDesign"};
150
151 TTreeReaderValue<double> tubeRadius{treeReader, "tubeRadius"};
152 TTreeReaderValue<double> tubePitch{treeReader, "tubePitch"};
153 TTreeReaderValue<unsigned short> numTubes{treeReader, "numTubes"};
154 TTreeReaderValue<unsigned short> numLayers{treeReader, "numLayers"};
155
156 TTreeReaderValue<std::vector<float>> geoModelTransformX{treeReader, "GeoModelTransformX"};
157 TTreeReaderValue<std::vector<float>> geoModelTransformY{treeReader, "GeoModelTransformY"};
158 TTreeReaderValue<std::vector<float>> geoModelTransformZ{treeReader, "GeoModelTransformZ"};
159
160 TTreeReaderValue<std::vector<float>> alignableNodeX{treeReader, "AlignableNodeX"};
161 TTreeReaderValue<std::vector<float>> alignableNodeY{treeReader, "AlignableNodeY"};
162 TTreeReaderValue<std::vector<float>> alignableNodeZ{treeReader, "AlignableNodeZ"};
163
164
166 TTreeReaderValue<std::vector<unsigned short>> tubeLayer{treeReader, "tubeLayer"};
167 TTreeReaderValue<std::vector<unsigned short>> tubeNumber{treeReader, "tubeNumber"};
168
169 TTreeReaderValue<std::vector<double>> tubeLength{treeReader, "tubeLength"};
170 TTreeReaderValue<std::vector<double>> activeTubeLength{treeReader, "activeTubeLength"};
171 TTreeReaderValue<std::vector<double>> wireLength{treeReader, "wireLength"};
172
173 TTreeReaderValue<std::vector<float>> tubeTransformTransX{treeReader, "tubeTransformTranslationX"};
174 TTreeReaderValue<std::vector<float>> tubeTransformTransY{treeReader, "tubeTransformTranslationY"};
175 TTreeReaderValue<std::vector<float>> tubeTransformTransZ{treeReader, "tubeTransformTranslationZ"};
176
177 TTreeReaderValue<std::vector<float>> tubeTransformCol0Theta{treeReader, "tubeTransformLinearCol0Theta"};
178 TTreeReaderValue<std::vector<float>> tubeTransformCol0Phi{treeReader, "tubeTransformLinearCol0Phi"};
179
180 TTreeReaderValue<std::vector<float>> tubeTransformCol1Theta{treeReader, "tubeTransformLinearCol1Theta"};
181 TTreeReaderValue<std::vector<float>> tubeTransformCol1Phi{treeReader, "tubeTransformLinearCol1Phi"};
182
183 TTreeReaderValue<std::vector<float>> tubeTransformCol2Theta{treeReader, "tubeTransformLinearCol2Theta"};
184 TTreeReaderValue<std::vector<float>> tubeTransformCol2Phi{treeReader, "tubeTransformLinearCol2Phi"};
185
186 TTreeReaderValue<std::vector<float>> readOutPosX{treeReader, "readOutPosX"};
187 TTreeReaderValue<std::vector<float>> readOutPosY{treeReader, "readOutPosY"};
188 TTreeReaderValue<std::vector<float>> readOutPosZ{treeReader, "readOutPosZ"};
189
190 while (treeReader.Next()) {
191 MdtChamber newchamber{};
192
193 newchamber.id.stationIndex = (*stationIndex);
194 newchamber.id.eta = (*stationEta);
195 newchamber.id.phi = (*stationPhi);
196 newchamber.id.multilayer = (*stationML);
197 newchamber.design = (*chamberDesign);
198
199 newchamber.tubeRadius = (*tubeRadius);
200 newchamber.tubePitch = (*tubePitch);
201
202 newchamber.numTubes = (*numTubes);
203 newchamber.numLayers = (*numLayers);
204
205 Amg::RotationMatrix3D geoRot{Amg::RotationMatrix3D::Identity()};
206 geoRot.col(0) = Amg::Vector3D((*geoModelTransformX)[1], (*geoModelTransformY)[1], (*geoModelTransformZ)[1]);
207 geoRot.col(1) = Amg::Vector3D((*geoModelTransformX)[2], (*geoModelTransformY)[2], (*geoModelTransformZ)[2]);
208 geoRot.col(2) = Amg::Vector3D((*geoModelTransformX)[3], (*geoModelTransformY)[3], (*geoModelTransformZ)[3]);
209 Amg::Vector3D geoTrans{(*geoModelTransformX)[0], (*geoModelTransformY)[0], (*geoModelTransformZ)[0]};
210 newchamber.geoModelTransform = Amg::getTransformFromRotTransl(std::move(geoRot), std::move(geoTrans));
211
212 geoRot.col(0) = Amg::Vector3D((*alignableNodeX)[1], (*alignableNodeY)[1], (*alignableNodeZ)[1]);
213 geoRot.col(1) = Amg::Vector3D((*alignableNodeX)[2], (*alignableNodeY)[2], (*alignableNodeZ)[2]);
214 geoRot.col(2) = Amg::Vector3D((*alignableNodeX)[3], (*alignableNodeY)[3], (*alignableNodeZ)[3]);
215 geoTrans = Amg::Vector3D{(*alignableNodeX)[0], (*alignableNodeY)[0], (*alignableNodeZ)[0]};
216 newchamber.alignableTransform = Amg::getTransformFromRotTransl(std::move(geoRot), std::move(geoTrans));
217
218
220 for (size_t t = 0; t < tubeLayer->size(); ++t){
221 using TubePositioning = MdtChamber::TubePositioning;
222 TubePositioning newTube{};
223 newTube.layerNum = (*tubeLayer)[t];
224 newTube.tubeNum = (*tubeNumber)[t];
225 newTube.tubeLength = (*tubeLength)[t];
226 newTube.wireLength = (*wireLength)[t];
227 Amg::RotationMatrix3D tubeRot{Amg::RotationMatrix3D::Identity()};
228 tubeRot.col(0) = makeDir((*tubeTransformCol0Theta)[t], (*tubeTransformCol0Phi)[t]);
229 tubeRot.col(1) = makeDir((*tubeTransformCol1Theta)[t], (*tubeTransformCol1Phi)[t]);
230 tubeRot.col(2) = makeDir((*tubeTransformCol2Theta)[t], (*tubeTransformCol2Phi)[t]);
231 Amg::Vector3D tubeTrans{(*tubeTransformTransX)[t],(*tubeTransformTransY)[t], (*tubeTransformTransZ)[t]};
232 newTube.localToGlobal = Amg::getTransformFromRotTransl(std::move(tubeRot), std::move(tubeTrans));
233 newTube.readoutPos = Amg::Vector3D{(*readOutPosX)[t],(*readOutPosY)[t],(*readOutPosZ)[t]};
234 newchamber.insertTube(std::move(newTube));
235 }
236
237 auto insert_itr = to_ret.insert(std::move(newchamber));
238 if (!insert_itr.second) {
239 std::stringstream err{};
240 err<<__FILE__<<":"<<__LINE__<<" The chamber "<<(*insert_itr.first).id
241 <<" has already been inserted. "<<std::endl;
242 throw std::runtime_error(err.str());
243 }
244 }
245 std::cout<<"File parsing is finished. Found in total "<<to_ret.size()<<" readout element dumps "<<std::endl;
246 return to_ret;
247}
double tubeLength
Eigen::Matrix< double, 3, 3 > RotationMatrix3D
Amg::Transform3D getTransformFromRotTransl(Amg::RotationMatrix3D rot, Amg::Vector3D transl_vec)
constexpr unsigned int numLayers()
Definition HIEventDefs.h:23
constexpr uint8_t stationPhi
station Phi 1 to 8
str inFile
Definition makeTOC.py:5
Amg::Vector3D makeDir(const double theta, const double phi)
int8_t & multilayer
Phi sector of the MDT station.
int8_t & eta
Station of the chamber (i.e, BIL,BIS,etc.).
int8_t & phi
Eta of the MDT station.
unsigned int layerNum
Layer to which the tube belongs.
Amg::Transform3D geoModelTransform
Transformation of the underlying GeoModel element.
void insertTube(TubePositioning &&newTube)
double tubePitch
Pitch between two tubes.
unsigned int numLayers
Number of tube layers.
unsigned int numTubes
Number of tubes.
Amg::Transform3D alignableTransform
Transformation of the underlying Alignable node.
double tubeRadius
Inner tube radius.

Variable Documentation

◆ tolerance

double tolerance = 10 * Gaudi::Units::micrometer
constexpr

Definition at line 111 of file runMdtGeoComparison.cxx.