14 #include <GaudiKernel/SystemOfUnits.h>
25 #include <TTreeReader.h>
49 if (stationIndex !=
other.stationIndex)
return stationIndex <
other.stationIndex;
50 if (stationEta !=
other.stationEta)
return stationEta <
other.stationEta;
51 if (stationPhi !=
other.stationPhi)
return stationPhi <
other.stationPhi;
52 return multilayer <
other.multilayer;
59 unsigned int nGasGaps{0};
62 double ActiveWidthS{0.};
63 double ActiveWidthL{0.};
64 double ActiveHeightR{0.};
65 double stripPitch{0.};
67 double moduleHeight{0.};
68 double moduleWidthS{0.};
69 double moduleWidthL{0.};
82 double stripLength{0.};
125 static const std::map<int, std::string> stationDict{
126 {55,
"MMS"}, {56,
"MML"}
134 ostr<<
"channel (gasGap/number): ";
136 ostr<<std::setfill(
'0')<<std::setw(4)<<
channel.channel<<
", ";
143 ostr<<
"Mmlayer (gasGap): ";
144 ostr<<
layer.gasGap<<
", ";
150 std::set<MmChamber> to_ret{};
151 std::cout<<
"Read the MicroMegas geometry tree dump from "<<
inputFile<<std::endl;
154 std::cerr<<__FILE__<<
":"<<__LINE__<<
" Failed to open "<<
inputFile<<std::endl;
159 std::cerr<<__FILE__<<
":"<<__LINE__<<
" The file "<<
inputFile<<
" does not contain the 'MmGeoModelTree'"<<std::endl;
164 TTreeReaderValue<unsigned short> stationIndex{
treeReader,
"stationIndex"};
165 TTreeReaderValue<short> stationEta{
treeReader,
"stationEta"};
166 TTreeReaderValue<short> stationPhi{
treeReader,
"stationPhi"};
167 TTreeReaderValue<short> multilayer{
treeReader,
"multilayer"};
172 TTreeReaderValue<std::vector<float>> stripLength{
treeReader,
"stripLength"};
174 TTreeReaderValue<std::vector<bool>> isStereo{
treeReader,
"isStereo"};
175 TTreeReaderValue<std::vector<float>> locStripCenterX{
treeReader,
"locStripCenterX"};
176 TTreeReaderValue<std::vector<float>> locStripCenterY{
treeReader,
"locStripCenterY"};
178 TTreeReaderValue<std::vector<float>> stripCenterX{
treeReader,
"stripCenterX"};
179 TTreeReaderValue<std::vector<float>> stripCenterY{
treeReader,
"stripCenterY"};
180 TTreeReaderValue<std::vector<float>> stripCenterZ{
treeReader,
"stripCenterZ"};
181 TTreeReaderValue<std::vector<float>> stripLeftEdgeX{
treeReader,
"stripLeftEdgeX"};
182 TTreeReaderValue<std::vector<float>> stripLeftEdgeY{
treeReader,
"stripLeftEdgeY"};
183 TTreeReaderValue<std::vector<float>> stripLeftEdgeZ{
treeReader,
"stripLeftEdgeZ"};
184 TTreeReaderValue<std::vector<float>> stripRightEdgeX{
treeReader,
"stripRightEdgeX"};
185 TTreeReaderValue<std::vector<float>> stripRightEdgeY{
treeReader,
"stripRightEdgeY"};
186 TTreeReaderValue<std::vector<float>> stripRightEdgeZ{
treeReader,
"stripRightEdgeZ"};
189 TTreeReaderValue<float> ActiveHeightR{
treeReader,
"ActiveHeightR"};
190 TTreeReaderValue<float> ActiveWidthS{
treeReader,
"ActiveWidthS"};
191 TTreeReaderValue<float> ActiveWidthL{
treeReader,
"ActiveWidthL"};
194 TTreeReaderValue<float> moduleHeight{
treeReader,
"moduleHeight"};
195 TTreeReaderValue<float> moduleWidthS{
treeReader,
"moduleWidthS"};
196 TTreeReaderValue<float> moduleWidthL{
treeReader,
"moduleWidthL"};
198 TTreeReaderValue<float> stripPitch{
treeReader,
"stripPitch"};
201 TTreeReaderValue<std::vector<float>> geoModelTransformX{
treeReader,
"GeoModelTransformX"};
202 TTreeReaderValue<std::vector<float>> geoModelTransformY{
treeReader,
"GeoModelTransformY"};
203 TTreeReaderValue<std::vector<float>> geoModelTransformZ{
treeReader,
"GeoModelTransformZ"};
205 TTreeReaderValue<std::vector<float>> alignableNodeX{
treeReader,
"AlignableNodeX"};
206 TTreeReaderValue<std::vector<float>> alignableNodeY{
treeReader,
"AlignableNodeY"};
207 TTreeReaderValue<std::vector<float>> alignableNodeZ{
treeReader,
"AlignableNodeZ"};
209 TTreeReaderValue<std::vector<float>> stripRotCol1X{
treeReader,
"stripRotLinearCol1X"};
210 TTreeReaderValue<std::vector<float>> stripRotCol1Y{
treeReader,
"stripRotLinearCol1Y"};
211 TTreeReaderValue<std::vector<float>> stripRotCol1Z{
treeReader,
"stripRotLinearCol1Z"};
213 TTreeReaderValue<std::vector<float>> stripRotCol2X{
treeReader,
"stripRotLinearCol2X"};
214 TTreeReaderValue<std::vector<float>> stripRotCol2Y{
treeReader,
"stripRotLinearCol2Y"};
215 TTreeReaderValue<std::vector<float>> stripRotCol2Z{
treeReader,
"stripRotLinearCol2Z"};
217 TTreeReaderValue<std::vector<float>> stripRotCol3X{
treeReader,
"stripRotLinearCol3X"};
218 TTreeReaderValue<std::vector<float>> stripRotCol3Y{
treeReader,
"stripRotLinearCol3Y"};
219 TTreeReaderValue<std::vector<float>> stripRotCol3Z{
treeReader,
"stripRotLinearCol3Z"};
221 TTreeReaderValue<std::vector<float>> stripRotTransX{
treeReader,
"stripRotTranslationX"};
222 TTreeReaderValue<std::vector<float>> stripRotTransY{
treeReader,
"stripRotTranslationY"};
223 TTreeReaderValue<std::vector<float>> stripRotTransZ{
treeReader,
"stripRotTranslationZ"};
225 TTreeReaderValue<std::vector<uint8_t>> stripRotGasGap{
treeReader,
"stripRotGasGap"};
227 TTreeReaderValue<std::vector<float>> firstStripPosX{
treeReader,
"firstStripPosX"};
228 TTreeReaderValue<std::vector<float>> firstStripPosY{
treeReader,
"firstStripPosY"};
230 TTreeReaderValue<std::vector<int>> readoutSide{
treeReader,
"stripReadoutSide"};
241 newchamber.stationEta = (*stationEta);
242 newchamber.stationPhi = (*stationPhi);
243 newchamber.multilayer = (*multilayer);
246 newchamber.ActiveHeightR = (*ActiveHeightR);
247 newchamber.ActiveWidthS = (*ActiveWidthS);
248 newchamber.ActiveWidthL = (*ActiveWidthL);
249 newchamber.stripPitch = (*stripPitch);
250 newchamber.moduleHeight = (*moduleHeight);
251 newchamber.moduleWidthS = (*moduleWidthS);
252 newchamber.moduleWidthL = (*moduleWidthL);
254 Amg::Vector3D geoTrans{(*geoModelTransformX)[0], (*geoModelTransformY)[0], (*geoModelTransformZ)[0]};
256 geoRot.col(0) =
Amg::Vector3D((*geoModelTransformX)[1], (*geoModelTransformY)[1], (*geoModelTransformZ)[1]);
257 geoRot.col(1) =
Amg::Vector3D((*geoModelTransformX)[2], (*geoModelTransformY)[2], (*geoModelTransformZ)[2]);
258 geoRot.col(2) =
Amg::Vector3D((*geoModelTransformX)[3], (*geoModelTransformY)[3], (*geoModelTransformZ)[3]);
261 geoRot.col(0) =
Amg::Vector3D((*alignableNodeX)[1], (*alignableNodeY)[1], (*alignableNodeZ)[1]);
262 geoRot.col(1) =
Amg::Vector3D((*alignableNodeX)[2], (*alignableNodeY)[2], (*alignableNodeZ)[2]);
263 geoRot.col(2) =
Amg::Vector3D((*alignableNodeX)[3], (*alignableNodeY)[3], (*alignableNodeZ)[3]);
264 geoTrans =
Amg::Vector3D{(*alignableNodeX)[0], (*alignableNodeY)[0], (*alignableNodeZ)[0]};
267 for (
size_t s = 0;
s < stripCenterX->size(); ++
s){
270 newStrip.locCenter =
Amg::Vector2D{(*locStripCenterX)[
s], (*locStripCenterY)[
s]};
271 newStrip.leftEdge =
Amg::Vector3D{(*stripLeftEdgeX)[
s], (*stripLeftEdgeY)[
s], (*stripLeftEdgeZ)[
s]};
272 newStrip.rightEdge =
Amg::Vector3D{(*stripRightEdgeX)[
s], (*stripRightEdgeY)[
s], (*stripRightEdgeZ)[
s]};
274 newStrip.gasGap = (*gasGap)[
s];
275 newStrip.channel = (*channel)[
s];
276 newStrip.isStereo = (*isStereo)[
s];
277 newStrip.stripLength = (*stripLength)[
s];
278 newchamber.channels.insert(std::move(newStrip));
281 for (
size_t l = 0;
l < stripRotGasGap->size(); ++
l){
283 newLayer.
gasGap = (*stripRotGasGap)[
l];
285 stripRot.col(0) =
Amg::Vector3D((*stripRotCol1X)[
l],(*stripRotCol1Y)[
l], (*stripRotCol1Z)[
l]);
286 stripRot.col(1) =
Amg::Vector3D((*stripRotCol2X)[
l],(*stripRotCol2Y)[
l], (*stripRotCol2Z)[
l]);
287 stripRot.col(2) =
Amg::Vector3D((*stripRotCol3X)[
l],(*stripRotCol3Y)[
l], (*stripRotCol3Z)[
l]);
288 Amg::Vector3D layTrans{(*stripRotTransX)[
l], (*stripRotTransY)[
l], (*stripRotTransZ)[
l]};
290 newLayer.firstStripPos =
Amg::Vector2D{(*firstStripPosX)[
l], (*firstStripPosY)[
l]};
291 newLayer.readoutSide = (*readoutSide)[
l];
292 newLayer.firstStrip = (*firstStrip)[
l];
293 newLayer.nStrips = (*nStrips)[
l];
295 newchamber.layers.insert(std::move(newLayer));
298 auto insert_itr = to_ret.insert(std::move(newchamber));
299 if (!insert_itr.second) {
300 std::stringstream
err{};
301 err<<__FILE__<<
":"<<__LINE__<<
" The chamber "<<(*insert_itr.first).stationIndex
302 <<
" has already been inserted. "<<std::endl;
303 throw std::runtime_error(
err.str());
306 std::cout<<
"File parsing is finished. Found in total "<<to_ret.size()<<
" readout element dumps "<<std::endl;
310 #define TEST_BASICPROP(attribute, propName) \
311 if (std::abs(1.*test.attribute - 1.*reference.attribute) > tolerance) { \
312 std::cerr<<"runMmGeoComparison() "<<__LINE__<<": The chamber "<<reference \
313 <<" differs w.r.t "<<propName<<" "<< reference.attribute \
314 <<" (ref) vs. " <<test.attribute << " (test)" \
315 <<", delta: "<<reference.attribute - test.attribute << std::endl; \
316 chamberOkay = false; \
323 std::string the_arg{
argv[
arg]};
324 if (the_arg ==
"--refFile" &&
arg +1 <
argc) {
325 refFile = std::string{
argv[
arg+1]};
327 }
else if (the_arg ==
"--testFile" &&
arg + 1 <
argc) {
332 if (refFile.empty()) {
333 std::cerr<<
"Please parse the path of the reference file via --refFile "<<std::endl;
337 std::cerr<<
"Please parse the path of the test file via --testFile "<<std::endl;
344 std::set<MmChamber> refChambers =
readTreeDump(refFile);
345 if (refChambers.empty()) {
346 std::cerr<<
"The file "<<refFile<<
" should contain at least one chamber "<<std::endl;
350 if (testChambers.empty()) {
351 std::cerr<<
"The file "<<
testFile<<
" should contain at least one chamber "<<std::endl;
354 int return_code = EXIT_SUCCESS;
357 std::set<MmChamber>::const_iterator test_itr = testChambers.find(
reference);
359 if (test_itr == testChambers.end()) {
360 std::cerr<<
"runMmGeoComparison() "<<__LINE__<<
": The chamber "<<
reference
361 <<
" is not part of the testing "<<std::endl;
362 return_code = EXIT_FAILURE;
365 bool chamberOkay{
true};
370 std::cerr<<
"runMmGeoComparison() "<<__LINE__<<
": The alignable nodes are at differnt places for "
391 for (
const MmLayer& refLayer :
reference.layers) {
392 std::set<MmLayer>::const_iterator lay_itr =
test.layers.find(refLayer);
393 if (lay_itr ==
test.layers.end()) {
394 std::cerr<<
"runMmGeoComparison() "<<__LINE__<<
": in "<<
test<<
" "
395 <<refLayer<<
" is not found. "<<std::endl;
399 const MmLayer& testLayer{*lay_itr};
400 if (!
Amg::isIdentity(refLayer.transform.inverse()* testLayer.transform)){
401 std::cerr<<
"runMmGeoComparison() "<<__LINE__<<
": in "<<
test<<
" "
402 <<testLayer<<
" differs w.r.t. reference. delta: "
403 <<
Amg::toString(refLayer.transform.inverse()*testLayer.transform)<<std::endl;
406 if (refLayer.firstStrip != testLayer.firstStrip) {
407 std::cerr<<
"runMmGeoComparison() "<<__LINE__<<
": in "<<
test<<
" "
408 <<testLayer.gasGap<<
" starts from different strip "<<refLayer.firstStrip<<
" vs. "
409 <<testLayer.firstStrip<<std::endl;
412 if (refLayer.nStrips != testLayer.nStrips) {
413 std::cerr<<
"runMmGeoComparison() "<<__LINE__<<
": in "<<
test<<
" "
414 <<testLayer.gasGap<<
" has different number of strips "<<refLayer.nStrips<<
" vs. "
415 <<testLayer.nStrips<<std::endl;
419 if (
false && (refLayer.firstStripPos- testLayer.firstStripPos).mag() >
tolerance) {
420 std::cerr<<
"runMmGeoComparison() "<<__LINE__<<
": in "<<
test<<
" "
421 <<testLayer.gasGap<<
" has different starting position "
424 <<
"difference: "<<
Amg::toString(refLayer.firstStripPos- testLayer.firstStripPos, 2)
425 <<
" / "<<(refLayer.firstStripPos- testLayer.firstStripPos).
mag()/
reference.stripPitch
430 if (!chamberOkay)
continue;
431 unsigned int failedEta{0}, lastGap{0};
433 std::set<MmChamber::MmChannel>::const_iterator strip_itr =
test.channels.find(refStrip);
434 if (strip_itr ==
test.channels.end()) {
435 std::cerr<<
"runMmGeoComparison() "<<__LINE__<<
": in "<<
test<<
" "
436 <<refStrip<<
" is not found. "<<std::endl;
440 if (lastGap != refStrip.
gasGap) {
441 lastGap = refStrip.
gasGap;
451 if (failedEta <= 10) {
455 (testStrip.rightEdge - testStrip.leftEdge).
unit()};
456 const double centerDist = stripDir.dot(testStrip.globCenter - refStrip.
globCenter);
457 const double leftDist = stripDir.dot(testStrip.leftEdge -refStrip.
globCenter);
458 const double rightDist = stripDir.dot(testStrip.rightEdge - refStrip.
globCenter);
460 std::cerr<<
"runMmGeoComparison() "<<__LINE__<<
": In "
463 <<
" does not describe the same stereo strip as "
466 <<
". Distances to the left-edge/center/right-edge: "
467 <<leftDist<<
"/"<<centerDist<<
"/"<<rightDist<<
", dot: "
468 <<std::acos(std::clamp(stripDir.dot(testDir),- 1., 1.)) /
Gaudi::Units::deg<<std::endl;
476 return_code = EXIT_FAILURE;