Project
Loading...
Searching...
No Matches
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// --- Standard library ---
13#include <fstream>
14#include <algorithm>
15
16// --- ROOT system ---
17
18#include <fairlogger/Logger.h>
19
20#include "FOCALBase/Geometry.h"
21
22using namespace o2::focal;
23
24bool Geometry::sInit = false;
25Geometry* Geometry::sGeom = nullptr;
26
27//_________________________________________________________________________
29{
30 std::fill_n(mPixelLayerLocations.begin(), 20, -1);
31 std::fill_n(mSegments.begin(), 100, -100);
32 std::fill_n(mNumberOfLayersInSegments.begin(), 100, -1);
33 std::fill_n(mLocalLayerZ.begin(), 100, 0.0);
34 std::fill_n(mLocalSegmentsZ.begin(), 100, 0.0);
35 std::fill_n(mLayerThickness.begin(), 100, 0.0);
36
37 *this = geo;
38}
39
40//_________________________________________________________________________
42{
43
44 if (sGeom == nullptr) {
45 sGeom = new Geometry();
46 sGeom->init();
47 } else {
48 if (sInit == false) {
49 sGeom = new Geometry();
50 sGeom->init();
51 }
52 }
53
54 return sGeom;
55}
56
57//_________________________________________________________________________
59{
60
61 if (sGeom == nullptr) {
62 sGeom = new Geometry();
63 sGeom->init(filename);
64 } else {
65 if (sInit == false) {
66 sGeom = new Geometry();
67 sGeom->init(filename);
68 }
69 }
70 return sGeom;
71}
72
73//_________________________________________________________________________
74void Geometry::init(std::string filename)
75{
76 if (filename != "default") {
78 } else {
80 }
81
83 sInit = true;
84}
85
86//_________________________________________________________________________
88{
91 sInit = true;
92}
93
94//_________________________________________________________________________
96{
97 mGeometryComposition.reserve(1000);
98
99 int nlayers = mNPadLayers + mNPixelLayers + mNHCalLayers;
100
102 for (int i = 0; i < nlayers; i++) {
103 if (i < mNPadLayers + mNPixelLayers) {
104 // Check whether it is a pixel layer
105 int isPixel = 0;
106 for (int iPix = 0; iPix < mNPixelLayers && !isPixel; iPix++) {
107 LOG(debug) << "Check pixel layer idx " << iPix << " loc " << mPixelLayerLocations[iPix] << " i= " << i;
108 if (i == mPixelLayerLocations[iPix]) {
109 isPixel = 1;
110 }
111 }
112
113 if (isPixel) {
114 // create pixel compositions
115 LOG(debug) << "Adding pixel layer at layer " << i;
116 for (auto& icomp : mPixelCompositionBase) {
117 icomp.setLayerNumber(i);
118 mGeometryComposition.push_back(icomp);
119 }
121 } else {
122 // create pad compositions
123 for (auto& icomp : mPadCompositionBase) {
124 icomp.setLayerNumber(i);
125 mGeometryComposition.push_back(icomp);
126 }
128 }
129 } else {
130 // create hcal compositions
131 for (auto& icomp : mHCalCompositionBase) {
132 icomp.setLayerNumber(i);
133 mGeometryComposition.push_back(icomp);
134 }
136 }
137 } // end loop over nlayers
138
139 for (int i = 0; i < nlayers; i++) {
140 mLocalLayerZ[i] = 0;
141 for (int j = 0; j < i; j++) {
143 }
144 }
145 for (int i = 0; i < nlayers; i++) {
147 }
148
149 mLocalLayerZ[nlayers] = -1;
150
152 for (auto& icomp : mFrontMatterCompositionBase) {
153 icomp.setLayerNumber(-1);
154 mGeometryComposition.push_back(icomp);
155 }
156
158 for (auto& icomp : mGeometryComposition) {
159 if (icomp.layer() >= 0) {
160 icomp.setCenterZ(mFrontMatterLayerThickness + mLocalLayerZ[icomp.layer()] + icomp.centerZ() + icomp.sizeZ() / 2);
161 } else {
162 icomp.setCenterZ(icomp.centerZ() + icomp.sizeZ() / 2);
163 }
164 }
165}
166
167//_________________________________________________________________________
169{
170
171 LOG(warning) << " Default parameters are not used ";
173 mGlobal_FOCAL_Z0 = 500;
174}
175
176//_________________________________________________________________________
177void Geometry::setParameters(std::string geometryfile)
178{
180 mGlobal_FOCAL_Z0 = 700.0;
181 mInsertFrontPadLayers = false;
182 // PAD setup
183 mGlobal_Pad_Size = 1.0; // pad size
184 mGlobal_PAD_NX = 9; // number of X pads in wafer
185 mGlobal_PAD_NY = 8; // number of Y pads in wafer
186 mGlobal_PAD_NX_Tower = 5; // number of X wafers in tower
187 mGlobal_PAD_NY_Tower = 1; // number of Y wafers in tower
188 mGlobal_PPTOL = 0.0; // tolerance between the wafers
189 mGlobal_PAD_SKIN = 0.2; // dead area (guard ring) on the wafer
190 mGlobal_PIX_SKIN = 0.004;
191 // PIX setup
192 mGlobal_Pixel_Readout = false;
193 mGlobal_Pixel_Size = 0.005; // pixel size
194 mGlobal_PIX_SizeX = 3.0; // sensor size X
195 mGlobal_PIX_SizeY = 2.74; // sensor size Y
197 mGlobal_PIX_OffsetY = 0.09;
198 mGlobal_PIX_NX_Tower = 15; // number of sensors in X
199 mGlobal_PIX_NY_Tower = 3; // number of sensors in Y
200
202 mGlobal_Tower_NY = 11;
203
204 mNPixelLayers = 4;
209
210 mTowerSizeX = 0;
211 mTowerSizeY = 0;
212 mWaferSizeX = 0;
213 mWaferSizeY = 0;
214
215 std::ifstream fin(geometryfile);
216 if (fin.fail()) {
217 LOG(error) << "No geometry file for FoCAL. Use default ones";
219 return;
220 } else {
221 LOG(info) << "Using geometry file " << geometryfile;
222 }
223
224 std::vector<Composition> padCompDummy(10);
225 std::vector<Composition> hCalCompDummy(10);
226 std::vector<Composition> pixelCompDummy(10);
227 std::vector<Composition> frontMatterCompDummy(10);
228 int nPad = 0;
229 int hHCal = 0;
230 int nPixel = 0;
231 int nFrontMatter = 0;
232
233 int npadlayers = 0;
234 int npixlayers = 0;
235 int pixl[10];
236
237 std::string input;
238
239 LOG(info) << "Loading FOCAL geometry file ";
240 while (getline(fin, input)) {
241 LOG(debug) << "Read string :: " << input.c_str();
242 const char* p = std::strpbrk("#", input.c_str());
243 if (p != nullptr) {
244 LOG(debug) << "Skipping comment";
245 continue;
246 }
247
248 std::vector<std::string> tokens;
249 std::stringstream str(input);
250 std::string tmpStr;
251 while (getline(str, tmpStr, ' ')) {
252 if (tmpStr.empty()) {
253 continue;
254 }
255 tokens.push_back(tmpStr);
256 }
257
258 std::string command = tokens[0];
259 LOG(debug) << "command: " << command;
260
261 if (command.find("COMPOSITION") != std::string::npos)
262 {
263 std::string material = tokens[1];
264 float cx = std::stof(tokens[2]);
265 float cy = std::stof(tokens[3]);
266 float dx = std::stof(tokens[4]);
267 float dy = std::stof(tokens[5]);
268 float dz = std::stof(tokens[6]);
269 float cz = 0;
270
271 LOG(debug) << "Material :: " << material;
272 LOG(debug) << "cx/cy/dx/dy/dz :: " << cx << " / " << cy << " / " << dx << " / " << dy << " / " << dz;
273
274 int stack;
275 if (command.find("PAD") != std::string::npos) {
276 sscanf(command.c_str(), "COMPOSITION_PAD_S%d", &stack);
277 padCompDummy.emplace_back(material, stack, stack, 0, cx, cy, cz, dx, dy, dz);
278 nPad++;
279 }
280
281 if (command.find("HCAL") != std::string::npos) {
282 sscanf(command.c_str(), "COMPOSITION_HCAL_S%d", &stack);
283 hCalCompDummy.emplace_back(material, stack, stack, 0, cx, cy, cz, dx, dy, dz);
284 hHCal++;
285 }
286
287 if (command.find("PIX") != std::string::npos) {
288 sscanf(command.c_str(), "COMPOSITION_PIX_S%d", &stack);
289 pixelCompDummy.emplace_back(material, stack, stack, 0, cx, cy, cz, dx, dy, dz);
292 nPixel++;
293 }
294
295 if (command.find("FM") != std::string::npos) {
296 sscanf(command.c_str(), "COMPOSITION_FM_S%d", &stack);
297 frontMatterCompDummy.emplace_back(material, stack, stack, 0, cx, cy, cz, dx, dy, dz);
298 nFrontMatter++;
299 }
300 } // end if COMPOSITION
301
302 if (command.find("GLOBAL") != std::string::npos) {
303
304 if (command.find("PAD_SIZE") != std::string::npos) {
305 mGlobal_Pad_Size = std::stof(tokens[1]);
306 LOG(debug) << "Pad sensor size is set to : " << mGlobal_Pad_Size;
307 }
308
309 if (command.find("PAD_NX") != std::string::npos) {
310 mGlobal_PAD_NX = std::stoi(tokens[1]);
311 LOG(debug) << "No. sensors per pad wafer in X direction : " << mGlobal_PAD_NX;
312 }
313
314 if (command.find("PAD_NY") != std::string::npos) {
315 mGlobal_PAD_NY = std::stoi(tokens[1]);
316 LOG(debug) << "No. sensors per pad wafer in Y direction : " << mGlobal_PAD_NY;
317 }
318
319 if (command.find("PAD_SUPERMODULE_X") != std::string::npos) {
320 mGlobal_PAD_NX_Tower = std::stoi(tokens[1]);
321 LOG(debug) << "Number of pad wafers per module in X direction : " << mGlobal_PAD_NX_Tower;
322 }
323
324 if (command.find("PAD_SUPERMODULE_Y") != std::string::npos) {
325 mGlobal_PAD_NY_Tower = std::stoi(tokens[1]);
326 LOG(debug) << "Number of pad wafers per module in Y direction : " << mGlobal_PAD_NY_Tower;
327 }
328
329 if (command.find("PIX_NX") != std::string::npos) {
330 mGlobal_PIX_NX_Tower = std::stoi(tokens[1]);
331 LOG(debug) << "Number of pixels sensors per module in X direction : " << mGlobal_PIX_NX_Tower;
332 }
333
334 if (command.find("PIX_NY") != std::string::npos) {
335 mGlobal_PIX_NY_Tower = std::stoi(tokens[1]);
336 LOG(debug) << "Number of pixels sensors per module in Y direction : " << mGlobal_PIX_NY_Tower;
337 }
338
339 if (command.find("PAD_PPTOL") != std::string::npos) {
340 mGlobal_PPTOL = std::stof(tokens[1]);
341 LOG(debug) << "Distance between pad sensors : " << mGlobal_PPTOL;
342 }
343
344 if (command.find("PAD_SKIN") != std::string::npos) {
345 mGlobal_PAD_SKIN = std::stof(tokens[1]);
346 LOG(debug) << "Pad wafer skin : " << mGlobal_PAD_SKIN;
347 }
348
349 if (command.find("FOCAL_Z") != std::string::npos) {
350 mGlobal_FOCAL_Z0 = std::stof(tokens[1]);
351 LOG(debug) << "Z-Location of the FoCAL is set to : " << mGlobal_FOCAL_Z0;
352 }
353
354 if (command.find("DetectorOpen_Right") != std::string::npos) {
355 mGlobal_DetectorOpening_Right = std::stof(tokens[1]);
356 LOG(debug) << "Detector opening on the right : " << mGlobal_DetectorOpening_Right;
357 }
358
359 if (command.find("DetectorOpen_Left") != std::string::npos) {
360 mGlobal_DetectorOpening_Left = std::stof(tokens[1]);
361 LOG(debug) << "Detector opening on the left : " << mGlobal_DetectorOpening_Left;
362 }
363
364 if (command.find("HCAL_TOWER_SIZE") != std::string::npos) {
365 mGlobal_HCAL_Tower_Size = std::stof(tokens[1]);
366 LOG(debug) << "The size of the HCAL readout tower will be : " << mGlobal_HCAL_Tower_Size;
367 }
368
369 if (command.find("HCAL_PITCH_SIZE") != std::string::npos) {
370 mGlobal_HCAL_Pitch_Size = std::stof(tokens[1]);
371 LOG(debug) << "The distance between fibers is : " << mGlobal_HCAL_Pitch_Size;
372 }
373
374 if (command.find("HCAL_TOWER_NX") != std::string::npos) {
375 mGlobal_HCAL_Tower_NX = std::stoi(tokens[1]);
376 LOG(debug) << "The number of the HCAL readout towers in X will be : " << mGlobal_HCAL_Tower_NX;
377 }
378
379 if (command.find("HCAL_TOWER_NY") != std::string::npos) {
380 mGlobal_HCAL_Tower_NY = std::stoi(tokens[1]);
381 LOG(debug) << "The number of the HCAL readout towers in Y will be : " << mGlobal_HCAL_Tower_NY;
382 }
383
384 if (command.find("HCAL_BEAMPIPE") != std::string::npos) {
385 mGlobal_HCAL_BeamPipeHole_Size = std::stof(tokens[1]);
386 LOG(debug) << "The HCAL beam pipe openning : " << mGlobal_HCAL_BeamPipeHole_Size;
387 }
388
389 if (command.find("PIX_OffsetX") != std::string::npos) {
390 mGlobal_PIX_OffsetX = std::stof(tokens[1]);
391 LOG(debug) << "Pixel offset from the beam pipe will be: " << mGlobal_PIX_OffsetX;
392 }
393
394 if (command.find("PIX_OffsetY") != std::string::npos) {
395 mGlobal_PIX_OffsetY = std::stof(tokens[1]);
396 LOG(debug) << "Pixel offset from the top of module will be: " << mGlobal_PIX_OffsetY;
397 }
398
399 if (command.find("PIX_SKIN") != std::string::npos) {
400 mGlobal_PIX_SKIN = std::stof(tokens[1]);
401 LOG(debug) << "Pixel sensor skin : " << mGlobal_PIX_SKIN;
402 }
403
404 if (command.find("TOWER_TOLX") != std::string::npos) {
405 mGlobal_TOWER_TOLX = std::stof(tokens[1]);
406 mGlobal_Gap_Material = tokens[2];
407 LOG(debug) << "Distance between modules in X direction : " << mGlobal_TOWER_TOLX << ", Material : " << mGlobal_Gap_Material;
408 }
409
410 if (command.find("TOWER_TOLY") != std::string::npos) {
411 mGlobal_TOWER_TOLY = std::stof(tokens[1]);
412 mGlobal_Gap_Material = tokens[2];
413 LOG(debug) << "Distance between modules in Y direction : " << mGlobal_TOWER_TOLY << " Material : " << mGlobal_Gap_Material;
414 }
415
416 if (command.find("MIDDLE_TOWER_OFFSET") != std::string::npos) {
417 mGlobal_Middle_Tower_Offset = std::stof(tokens[1]);
418 LOG(debug) << "Middle tower offset will be: " << mGlobal_Middle_Tower_Offset;
419 }
420
421 if (command.find("Tower_NX") != std::string::npos) {
422 mGlobal_Tower_NX = std::stof(tokens[1]);
423 LOG(debug) << "Number of FOCAL modules in x direction is set to : " << mGlobal_Tower_NX;
424 }
425
426 if (command.find("Tower_NY") != std::string::npos) {
427 mGlobal_Tower_NY = std::stof(tokens[1]);
428 LOG(debug) << "Number of FOCAL modules in y direction is set to : " << mGlobal_Tower_NY;
429 }
430 } // end if GLOBAL
431
432 if (command.find("COMMAND") != std::string::npos) {
433
434 if (command.find("NUMBER_OF_PAD_LAYERS") != std::string::npos) {
435 npadlayers = std::stoi(tokens[1]);
436 LOG(debug) << "Number of pad layers " << npadlayers;
437 }
438
439 if (command.find("NUMBER_OF_HCAL_LAYERS") != std::string::npos) {
440 mNHCalLayers = std::stoi(tokens[1]);
441 LOG(debug) << "Number of HCAL layers " << mNHCalLayers;
442 }
443
444 if (command.find("NUMBER_OF_SEGMENTS") != std::string::npos) {
445 mNumberOfSegments = std::stoi(tokens[1]);
446 LOG(debug) << "Number of Segments " << mNumberOfSegments;
447 }
448
449 if (command.find("INSERT_PIX") != std::string::npos) {
450 sscanf(command.c_str(), "COMMAND_INSERT_PIX_AT_L%d", &pixl[npixlayers]);
451 LOG(debug) << "Number of pixel layer " << npixlayers << " : location " << pixl[npixlayers];
452 npixlayers++;
453 }
454
455 if (command.find("COMMAND_PIXEL_READOUT_ON") != std::string::npos) {
457 mGlobal_Pixel_Size = std::stof(tokens[1]);
458 LOG(debug) << "Pixel readout on (for MASPS): pixel size is set to : " << mGlobal_Pixel_Size;
459 }
460
461 if (command.find("COMMAND_INSERT_FRONT_PAD_LAYERS") != std::string::npos) {
463 LOG(debug) << "Insert two pad layers in front of ECAL for charged particle veto!";
464 }
465
466 if (command.find("COMMAND_INSERT_HCAL_READOUT") != std::string::npos) {
468 LOG(debug) << "Insert Aluminium 1cm thick layer behind HCAL to simulate readout SiPM material !";
469 }
470 } // end if COMMAND
471
472 if (command.find("VIRTUAL") != std::string::npos) {
473
474 int segment, minlayer, maxLayer, isPixel;
475 float padSize, sensitiveThickness, pixelTreshold;
476
477 if (command.find("N_SEGMENTS") != std::string::npos) {
478 mVirtualNSegments = std::stoi(tokens[1]);
479 LOG(debug) << "Number of Virtual Segments is set to : " << mVirtualNSegments;
480 }
481
482 if (command.find("SEGMENT_LAYOUT") != std::string::npos) {
483 minlayer = std::stoi(tokens[1]);
484 maxLayer = std::stoi(tokens[2]);
485 padSize = std::stof(tokens[3]);
486 sensitiveThickness = std::stof(tokens[4]);
487 isPixel = std::stoi(tokens[5]);
488 pixelTreshold = std::stof(tokens[6]);
489
490 if (mVirtualSegmentComposition.size() == 0) {
491 if (mVirtualNSegments <= 0) {
492 LOG(debug) << "Making 20 segments";
493 for (int seg = 0; seg < 20; seg++) {
494 mVirtualSegmentComposition.emplace_back();
495 }
497 } else {
498 LOG(debug) << "Making " << mVirtualNSegments << " segments";
499 for (int seg = 0; seg < mVirtualNSegments; seg++) {
500 mVirtualSegmentComposition.emplace_back();
501 }
502 }
503 }
504
505 sscanf(command.c_str(), "VIRTUAL_SEGMENT_LAYOUT_N%d", &segment);
507 continue;
508 }
510 mVirtualSegmentComposition[segment].mMaxLayer = maxLayer;
511 mVirtualSegmentComposition[segment].mPadSize = padSize;
512 mVirtualSegmentComposition[segment].mRelativeSensitiveThickness = sensitiveThickness;
513 mVirtualSegmentComposition[segment].mPixelTreshold = pixelTreshold;
514 mVirtualSegmentComposition[segment].mIsPixel = isPixel;
515
516 LOG(debug) << "Segment number " << segment << " defined with (minLayer, maxLayer, padSize, isPixel): ("
517 << minlayer << ", " << maxLayer << ", " << padSize << ", " << isPixel << ")";
518 } // end if SEGMENT_LAYOUT
519
520 } // end if VIRTUAL
521
522 } // end while
523
526 mNPixelLayers = npixlayers;
527 for (int i = 0; i < npixlayers; i++) {
528 mPixelLayerLocations[i] = pixl[i];
529 }
530
531 mNPadLayers = npadlayers;
532 LOG(debug) << "mNPadLayers, mNPixelLayers, mNHCalLayers, mNumberOfSegments :: " << mNPadLayers << " / " << mNPixelLayers << " / " << mNHCalLayers << " / " << mNumberOfSegments;
533
535
536 if (mNumberOfSegments >= 100) {
537 LOG(warning) << "You reached the segments limits! Setting Number of segments to: 100";
539 LOG(warning) << "New number of segments: " << mNumberOfSegments;
541 }
544 for (int i = 0; i < mNumberOfSegments; i++) {
546 }
547 LOG(debug) << "Number of segments: " << mNumberOfSegments;
548 } else {
549 for (int i = 0; i < mNumberOfSegments; i++) {
551 }
552 }
553
555
556 float center_z = 0;
557
558 mPadCompositionBase.reserve(200);
559 mHCalCompositionBase.reserve(200);
560 mPixelCompositionBase.reserve(200);
561 mFrontMatterCompositionBase.reserve(200);
562
563 for (auto& tmpComp : padCompDummy) {
564 LOG(debug) << "Material(pad layer) " << tmpComp.material();
565 LOG(debug) << "layer / stack / id :: " << tmpComp.layer() << " / " << tmpComp.stack() << " / " << tmpComp.id();
566 LOG(debug) << "center x,y,dz :: " << tmpComp.sizeX() << " / " << tmpComp.sizeY() << " / " << tmpComp.sizeZ();
567 if (tmpComp.material().compare("SiPad")) { // materials other than SiPad
568 mPadCompositionBase.emplace_back(tmpComp.material(), tmpComp.layer(), tmpComp.stack(), tmpComp.id(),
569 tmpComp.centerX(), tmpComp.centerY(), center_z,
570 mTowerSizeX, mTowerSizeY, tmpComp.sizeZ());
571 if (mTowerSizeX < tmpComp.sizeX()) {
572 mTowerSizeX = tmpComp.sizeX();
573 }
574 if (mTowerSizeY < tmpComp.sizeY()) {
575 mTowerSizeY = tmpComp.sizeY();
576 }
577 } else {
578 for (int itowerX = 0; itowerX < mGlobal_PAD_NX_Tower; itowerX++) {
579 for (int itowerY = 0; itowerY < mGlobal_PAD_NY_Tower; itowerY++) {
580 for (int ix = 0; ix < mGlobal_PAD_NX; ix++) {
581 for (int iy = 0; iy < mGlobal_PAD_NY; iy++) {
582 auto [x, y] = getGeoPadCenterLocal(itowerX, itowerY, iy, ix);
583 mPadCompositionBase.emplace_back("SiPad", tmpComp.layer(), tmpComp.stack(),
585 x, y, center_z,
586 mGlobal_Pad_Size, mGlobal_Pad_Size, tmpComp.sizeZ());
589 }
592 }
593 }
594 }
595 } // end for itowerY
596 } // end for itowerX
597 } // end else
598 center_z += tmpComp.getThickness();
599 } // end loop over pad layer compositions
600 LOG(debug) << "============ Created all pad layer compositions (" << mPadCompositionBase.size() << " volumes)";
601
602 mPadLayerThickness = center_z;
603
605
606 center_z = 0;
607 for (auto& tmpComp : pixelCompDummy) {
608 LOG(debug) << "Material (pixel layer) " << tmpComp.material();
609 LOG(debug) << "layer / stack / id :: " << tmpComp.layer() << " / " << tmpComp.stack() << " / " << tmpComp.id();
610 LOG(debug) << "center x,y,dz :: " << tmpComp.sizeX() << " / " << tmpComp.sizeY() << " / " << tmpComp.sizeZ();
611 if (tmpComp.material().compare("SiPix")) {
612 mPixelCompositionBase.emplace_back(tmpComp.material(), mPixelLayerLocations[0], tmpComp.stack(), tmpComp.id(),
613 tmpComp.centerX(), tmpComp.centerY(), center_z, mTowerSizeX, mTowerSizeY, tmpComp.sizeZ());
614 } else {
615 for (int ix = 0; ix < mGlobal_PIX_NX_Tower; ix++) {
616 for (int iy = 0; iy < mGlobal_PIX_NY_Tower; iy++) {
617 auto [pixX, pixY] = getGeoPixCenterLocal(iy, ix);
618 mPixelCompositionBase.emplace_back("SiPix", tmpComp.layer(), tmpComp.stack(), ix + iy * mGlobal_PIX_NX_Tower,
619 pixX, pixY, center_z,
620 mGlobal_PIX_SizeX, mGlobal_PIX_SizeY, tmpComp.sizeZ());
621 }
622 }
623 }
624 center_z += tmpComp.getThickness();
625 }
626 LOG(debug) << "============ Created all pixel layer compositions (" << mPixelCompositionBase.size() << " volumes)";
627 mPixelLayerThickness = center_z;
628
629 // Add HCal Layers
630 center_z = 0;
631 for (auto& tmpComp : hCalCompDummy) {
632 LOG(debug) << "Material (hcal) " << tmpComp.material();
633 LOG(debug) << "layer / stack / id :: " << tmpComp.layer() << " / " << tmpComp.stack() << " / " << tmpComp.id();
634 LOG(debug) << "center x,y,dz :: " << tmpComp.sizeX() << " / " << tmpComp.sizeY() << " / " << tmpComp.sizeZ();
635 mHCalCompositionBase.emplace_back(tmpComp.material(), tmpComp.layer(), tmpComp.stack(), tmpComp.id(),
636 tmpComp.centerX(), tmpComp.centerY(), mNHCalLayers == 1 ? 0. : center_z, // if we decided to use the spagetti HCAL it will be only one layer with two compositions
637 tmpComp.sizeX(), tmpComp.sizeY(), tmpComp.sizeZ());
638 if (mNHCalLayers == 1) {
639 center_z = tmpComp.getThickness();
640 } else {
641 center_z += tmpComp.getThickness();
642 }
643 }
644 LOG(debug) << "============ Created all hcal compositions (" << mHCalCompositionBase.size() << " volumes)";
645 mHCalLayerThickness = center_z;
646 center_z = 0;
647
648 if (mNHCalLayers == 1 && hHCal > 2) {
650 } else if (mNHCalLayers == 1 && hHCal == 2) {
652 } else {
654 }
655
657 LOG(debug) << " end of SetParameters ";
658}
659
660//_________________________________________________________________________
662{
663
664 for (auto& icomp : mGeometryComposition) {
665 if (icomp.layer() == layer && icomp.stack() == stack) {
666 return &icomp;
667 }
668 }
669 return nullptr;
670}
671
672//_________________________________________________________________________
673std::vector<const Composition*> Geometry::getFOCALMicroModule(int layer) const
674{
675
676 std::vector<const Composition*> layerComposition;
677
678 if (layer == -1) {
679 for (auto& icomp : mGeometryComposition) {
680 layerComposition.push_back(&icomp);
681 }
682 } else {
683 for (auto& icomp : mGeometryComposition) {
684 if (icomp.layer() == layer) {
685 layerComposition.push_back(&icomp);
686 }
687 }
688 }
689 return layerComposition;
690}
691
692//_________________________________________________________________________
694std::tuple<double, double, double> Geometry::getGeoTowerCenter(int tower, int segment) const
695{
696 int id = tower;
697 int itowerx = id % getNumberOfTowersInX();
698 int itowery = id / getNumberOfTowersInX();
699
700 float dwx = getTowerSizeX() + getTowerGapSizeX();
701 float dwy = getTowerSizeY() + getTowerGapSizeY();
702
703 double x = itowerx * dwx + 0.5 * dwx - 0.5 * getFOCALSizeX();
704 double y = itowery * dwy + 0.5 * dwy - 0.5 * getFOCALSizeY();
705 if (itowerx == 0 && itowery == 5) {
707 }
708 if (itowerx == 1 && itowery == 5) {
710 }
711
712 // From here is HCal stuff
714 auto [status, nCols, nRows] = getVirtualNColRow(segment);
715 int ix = id % nCols;
716 int iy = id / nRows;
717
718 switch (mHCALDesign) {
720 float padSize = mVirtualSegmentComposition[segment].mPadSize;
721 double hCALsizeX = nCols * padSize;
722 double hCALsizeY = nRows * padSize;
723
724 x = ix * padSize + 0.5 * padSize - 0.5 * hCALsizeX;
725 y = iy * padSize + 0.5 * padSize - 0.5 * hCALsizeY;
726 break;
727 }
729 float towerSize = getHCALTowerSize() / 7; // To be set from outside (number of channels on x & y)
730 y = iy * towerSize + 0.5 * towerSize - 0.5 * towerSize * nRows;
731 x = ix * towerSize + 0.5 * towerSize - 0.5 * towerSize * nCols;
732 break;
733 }
734 case HCALDesgin::Sheets: {
737 double hCALsizeX = comp1.sizeX() * 2; // Size of two sheet in X
738 double hCALsizeY = getHCALTowersInY() * (comp1.sizeY() + comp2.sizeY()) * 2; // To be set in a better way
739
740 x = ix * hCALsizeX / getHCALTowersInX() + 0.5 * hCALsizeX / getHCALTowersInX() - 0.5 * hCALsizeX;
741 y = iy * hCALsizeY / getHCALTowersInY() + 0.5 * hCALsizeY / getHCALTowersInY() - 0.5 * hCALsizeY;
742 break;
743 }
744 default:
745 break;
746 }
747 }
748
749 /*
751 // define beam pipe radius, calculate half of the tower diagonal in XY
752 // and remove every tower which center is closer than the sum of the two...
753 double beamPipeRadius = 3.6; // in cm TODO: check if this is OK
754 double towerHalfDiag = std::sqrt(2)*0.5*getTowerSizeX(); // tower half diagonal
755 double minRadius = beamPipeRadius+towerHalfDiag;
756 //
757 if((x*x+y*y) < (minRadius*minRadius)){ // comparing the tower center position with the minimum distance in second powers.
758 //mDisableTowers.push_back(Tower+1);
759 //return false;
760 }
761 */
762
763 return {x, y, getFOCALZ0()};
764}
765
766//_________________________________________________________________________
767std::tuple<double, double, double> Geometry::getGeoCompositionCenter(int tower, int layer, int stack) const
768{
769 auto [status, segment] = getVirtualSegmentFromLayer(layer);
770 auto [towX, towY, towZ] = getGeoTowerCenter(tower, segment);
771 double z = towZ;
772
774 if (comp1 == nullptr) {
775 z = z + mLocalLayerZ[layer] - getFOCALSizeZ() / 2;
776 } else {
777 z = comp1->centerZ() - getFOCALSizeZ() / 2 + getFOCALZ0();
778 }
779 return {towX, towY, z};
780}
781
782//_________________________________________________________________________
784std::tuple<double, double, double> Geometry::getGeoPadCenter(int tower, int layer, int stack, int row, int col) const
785{
786 auto [x, y, z] = getGeoCompositionCenter(tower, layer, stack);
787 int itowerx = tower % mGlobal_PAD_NX_Tower;
788 int itowery = tower / mGlobal_PAD_NX_Tower;
789 auto [padX, padY] = getGeoPadCenterLocal(itowerx, itowery, row, col);
790
791 return {x + padX, y + padY, z};
792}
793
794//_________________________________________________________________________
796std::tuple<double, double> Geometry::getGeoPadCenterLocal(int towerX, int towerY, int row, int col) const
797{
799 /*
800 (0,0)
801 ___________________
802 | __ __
803 | |__| |__|
804 | __ __
805 | |__| |__|
806 | __ __
807 | |__| |__|
808 |
809 */
812 x = x - 0.5 * getTowerSizeX();
813 y = y + 0.5 * mTowerSizeY;
814 return {x, y};
815}
816
818std::tuple<double, double> Geometry::getGeoPixCenterLocal(int row, int col) const
819{
821 /*
822 (0,0)
823 ___________________
824 | __ __
825 | |__| |__|
826 | __ __
827 | |__| |__|
828 | __ __
829 | |__| |__|
830 |
831 */
832 double x = +col * (mGlobal_PIX_SizeX + 2.0 * mGlobal_PIX_SKIN) + 0.5 * mGlobal_PIX_SizeX;
833 double y = -row * (mGlobal_PIX_SizeY + 2.0 * mGlobal_PIX_SKIN) - 0.5 * mGlobal_PIX_SizeY;
834 x = x - 0.5 * mTowerSizeX;
836 return {x, y};
837}
838
839//_________________________________________________________________________
841{
842 return mTowerSizeX;
843 // return mGlobal_NX_NY_Pads*(mGlobal_Pad_Size+mGlobal_PPTOL)-mGlobal_PPTOL+2*mGlobal_PAD_SKIN;
844}
845
846//_________________________________________________________________________
848{
849 return mTowerSizeY;
850 // return mGlobal_NX_NY_Pads*(mGlobal_Pad_Size+mGlobal_PPTOL)-mGlobal_PPTOL+2*mGlobal_PAD_SKIN;
851}
852
853//_________________________________________________________________________
858
859//_________________________________________________________________________
864
865//_________________________________________________________________________
867{
868
869 double ret = 0;
870 for (int i = 0; i < mNPadLayers + mNPixelLayers + mNHCalLayers; i++) {
871 ret += mLayerThickness[i];
872 }
873 ret = ret + mFrontMatterLayerThickness;
874 return ret;
875}
876
877//_________________________________________________________________________
879{
880
881 double ret = 0;
882 for (int i = 0; i < mNPadLayers + mNPixelLayers; i++) {
883 ret += mLayerThickness[i];
884 }
885 ret = ret + mFrontMatterLayerThickness;
886 return ret;
887}
888
889//_________________________________________________________________________
891{
892
893 // Determines the ECAL z center of mass with respect to the FOCAL
894 double centerZ = mFrontMatterLayerThickness + mLocalLayerZ[0] + getECALSizeZ() / 2;
895 return centerZ;
896}
897
898//_________________________________________________________________________
900{
901
902 double ret = 0;
904 ret += mLayerThickness[i];
905 }
906 return ret;
907}
908
909//_________________________________________________________________________
911{
912
914 return centerZ;
915}
916
917//_________________________________________________________________________
918// this returns the following quantities for the pad position location
919// layer depth
920// pad row and col in the wafer
921// wafer id in the brick, where the pad belongs to
922std::tuple<int, int, int, int, int, int, int> Geometry::getPadPositionId2RowColStackLayer(int id) const
923{
924
928 int number = id - 1;
929 int padid = (number & 0xfff);
930 int stack = (number >> 12) & 0x000f;
931 // lay = (number >> 16) & 0x00ff;
932 int lay = (number >> 16) & 0x000f;
933
934 // seg = fSegments[lay];
935 auto [status, seg] = getVirtualSegmentFromLayer(lay); // NOTE: to be checked since this overrides the initialization above
936 /*col = padid%mGlobal_PAD_NX;
937 row = padid/mGlobal_PAD_NX;*/
938 int waferx = 0;
939 int wafery = 0;
940 int col = 0;
941 int row = 0;
942
943 // This gives the (col,row) of the pixel sensor
944 if (getVirtualIsPixel(seg)) {
945 col = padid % mGlobal_PIX_NX_Tower;
946 row = padid / mGlobal_PIX_NX_Tower;
947 } else {
948 col = padid % mGlobal_PAD_NX;
949 int remainder = (padid - col) / mGlobal_PAD_NX;
950 row = remainder % mGlobal_PAD_NY;
951 remainder = (remainder - row) / mGlobal_PAD_NY;
952 waferx = remainder % mGlobal_PAD_NX_Tower;
953 wafery = remainder / mGlobal_PAD_NX_Tower;
954 }
955 /*cout << "FROM GEOMETRY stack/lay/seg/waferx/wafery/col/row :: " << stack << " / " << lay << " / " << seg << " / "
956 << waferx << " / " << wafery << " / " << col << " / " << row << endl;*/
957 if (getVirtualIsHCal(seg)) {
958 auto [status, nCols, nRows] = getVirtualNColRow(seg);
959 col = id % nCols;
960 row = id / nRows;
961 }
962
963 return {row, col, stack, lay, seg, waferx, wafery};
964}
965
966//_________________________________________________________________________
969{
970
971 double ret = 0;
972 if (seg < 0 || seg > mNumberOfSegments) {
973 ret = getFOCALZ0();
974 } else {
975 for (int i = 0; i < seg; i++) {
976 ret += mLocalSegmentsZ[i];
977 }
978 }
979 ret = ret + mLocalSegmentsZ[seg] / 2 + getFOCALZ0() - getFOCALSizeZ() / 2;
980 return ret;
981}
982
983//_________________________________________________________________________
988{
994
995 std::vector<int> layerType;
996 for (int j = 0; j < mNPixelLayers + mNPadLayers + mNHCalLayers; j++) {
997 layerType.push_back(0);
998 }
999 for (int i = 0; i < mNPixelLayers; i++) {
1000 layerType[mPixelLayerLocations[i]] = -1;
1001 }
1002
1003 int low = 0;
1004 int start = 0;
1005 int high = 0;
1006 for (int i = 0; i < mNumberOfSegments; i++) {
1008 for (int j = start; j < mNPixelLayers + mNPadLayers + mNHCalLayers; j++) {
1009 if (layerType[j] == -1) {
1010 mSegments[j] = i;
1011 start++;
1012 } else {
1013 mSegments[j] = i;
1014 low++;
1015 start++;
1016 }
1017 if (low >= high) {
1018 break;
1019 }
1020 }
1021 }
1022}
1023
1024//_________________________________________________________________________
1028int Geometry::getPixelNumber(int vol0, int vol1, int /*vol2*/, double x, double y) const
1029{
1030 int ret = 0;
1031 if (mGlobal_Pixel_Readout == false) {
1032 ret = -1;
1033 return ret;
1034 }
1035 int id = vol0;
1036 // int tower = vol1;
1037 // int brick = vol2; /// meaning 0 in the current design
1038
1039 auto [row, col, stack, layer, segment, waferX, waferY] = getPadPositionId2RowColStackLayer(id);
1040 auto [pixX, pixY] = getGeoPixCenterLocal(row, col);
1041
1042 double x_loc = x - pixX;
1043 double y_loc = y - pixY;
1044 double pixel_nbr_x = ((x_loc + 0.5 * getGlobalPixelWaferSizeX()) / (mGlobal_Pixel_Size));
1045 double pixel_nbr_y = ((y_loc + 0.5 * getGlobalPixelWaferSizeY()) / (mGlobal_Pixel_Size));
1046
1047 int pixel_number_x;
1048 pixel_number_x = static_cast<int>(pixel_nbr_x);
1049 // if(pixel_number_x-pixel_nbr_x>0.5){
1050 // pixel_number_x = pixel_number_x+1;
1051 // }
1052
1053 int pixel_number_y;
1054 pixel_number_y = static_cast<int>(pixel_nbr_y);
1055 // if(pixel_number_y-pixel_nbr_y>0.5){
1056 // pixel_number_y = pixel_number_y+1;
1057 // }
1058 ret = (pixel_number_x << 16) | pixel_number_y;
1059 // cout<<x<<" "<<y<<" "<<x0<<" "<<y0<<" "<<x_loc<<" "<<y_loc<<" "<<pixel_number_x<<" "<<pixel_number_y<<" "<<ret<<endl;
1060 return ret;
1061}
1062
1063//_________________________________________________________________________
1084
1085//_________________________________________________________________________
1087{
1088 return std::find(mDisableTowers.begin(), mDisableTowers.end(), tower) != mDisableTowers.end();
1089}
1090
1091//_________________________________________________________________________
1093std::tuple<double, double, double> Geometry::getGeoPixelCenter(int pixel, int tower, int layer, int stack, int row, int col) const
1094{
1095 auto [x0, y0, z0] = getGeoPadCenter(tower, layer, stack, row, col);
1096
1097 int pixel_y = pixel & 0xff;
1098 int pixel_x = (pixel >> 8) & 0xff;
1099
1100 double x1, y1;
1101 x1 = pixel_x * mGlobal_Pixel_Size + 0.5 * mGlobal_Pixel_Size - 0.5 * mGlobal_Pad_Size;
1102 y1 = pixel_y * mGlobal_Pixel_Size + 0.5 * mGlobal_Pixel_Size - 0.5 * mGlobal_Pad_Size;
1103
1104 return {x1 + x0, y1 + y0, z0};
1105}
1106
1107std::tuple<bool, int, int, int, int> Geometry::getVirtualInfo(double x, double y, double z) const
1108{
1109 //
1110 // Calculate col, row, layer, (virtual) segment from x,y,z
1111 // returns false if outside volume
1112 //
1113 int col = -1, row = -1;
1114 auto [status, layer, segment] = getVirtualLayerSegment(z);
1115
1116 if (!status) {
1117 return {false, col, row, layer, segment};
1118 }
1119 if (segment == -1) {
1120 return {false, col, row, layer, segment};
1121 }
1122 if (std::abs(x) > (getFOCALSizeX() + 2 * getMiddleTowerOffset()) / 2) {
1123 return {false, col, row, layer, segment};
1124 }
1125 if (std::abs(y) > getFOCALSizeY() / 2) {
1126 return {false, col, row, layer, segment};
1127 }
1128
1130 float towerSize = getHCALTowerSize();
1131 double beamPipeRadius = 3.0; // in cm TODO check the number is OK (different hardcoded values are used elsewhere)
1132 double minRadius = beamPipeRadius + towerSize / 2.;
1133
1134 double hCALsizeX = getHCALTowersInX() * towerSize;
1135 double hCALsizeY = getHCALTowersInY() * towerSize;
1136
1137 if (x < minRadius && x > -minRadius && y < minRadius && y > -minRadius) {
1138 x = x < 0 ? x - 0.001 : x + 0.001;
1139 y = y < 0 ? y - 0.001 : y + 0.001;
1140 }
1141
1142 switch (mHCALDesign) {
1143 case HCALDesgin::Sandwich: {
1144 row = (int)((y + hCALsizeY / 2) / (towerSize));
1145 col = (int)((x + hCALsizeX / 2) / (towerSize));
1146 break;
1147 }
1148 case HCALDesgin::Spaghetti: {
1149 row = (int)((y + hCALsizeY / 2) / (towerSize / 7));
1150 col = (int)((x + hCALsizeX / 2) / (towerSize / 7));
1151 break;
1152 }
1153 case HCALDesgin::Sheets: {
1156 double hCALsizeX = comp1.sizeX() * 2; // Size of two sheet in X
1157 double hCALsizeY = getHCALTowersInY() * (comp1.sizeY() + comp2.sizeY()) * 2; // To be set in a better way
1158
1159 if (y < getHCALBeamPipeHoleSize() / 2 && y > -getHCALBeamPipeHoleSize() / 2) {
1160 if (x < 0) {
1161 x += 1.0; // remove the offset around the beam pipe
1162 } else {
1163 x -= 1.0; // remove the offset around the beam pipe
1164 }
1165 }
1166
1167 row = (int)((y + hCALsizeY / 2) / (hCALsizeY / getHCALTowersInY()));
1168 if (x > 0) {
1169 x = x - 0.15 - 0.06;
1170 }
1171 col = (int)((x - 0.15 + hCALsizeX / 2) / ((hCALsizeX - 0.15 * 2 - 0.06 * 2) / getHCALTowersInX()));
1172 break;
1173 }
1174 default:
1175 break;
1176 }
1177 } else {
1178 row = (int)((y + getFOCALSizeY() / 2) / mVirtualSegmentComposition[segment].mPadSize);
1179 // if it is the towers right and left of the beam pipe, adjust x so the offset is removed
1180 // if(y < 4.2 && y > - 4.2) { // TO BE set from outside or somewhere else -4,4 is the y position of the middle towers
1181 // x = x < 0 ? x + GetMiddleTowerOffset() : x - GetMiddleTowerOffset();
1182 // }
1183 col = (int)((x + getFOCALSizeX() / 2) / mVirtualSegmentComposition[segment].mPadSize);
1184 }
1185 return {true, col, row, layer, segment};
1186}
1187
1188//_______________________________________________________________________
1189std::tuple<bool, double, double, double> Geometry::getXYZFromColRowSeg(int col, int row, int segment) const
1190{
1191
1192 double x = 0.0, y = 0.0, z = 0.0;
1193 if (segment > mVirtualNSegments) {
1194 return {false, x, y, z};
1195 }
1196
1198 float towerSize = getHCALTowerSize();
1199 double hCALsizeX = getHCALTowersInX() * towerSize;
1200 double hCALsizeY = getHCALTowersInY() * towerSize;
1201
1202 switch (mHCALDesign) {
1203 case HCALDesgin::Sandwich: {
1204 y = -1 * hCALsizeY / 2 + ((float)row + 0.5) * (towerSize);
1205 x = -1 * hCALsizeX / 2 + ((float)col + 0.5) * (towerSize);
1206 break;
1207 }
1208 case HCALDesgin::Spaghetti: {
1209 y = -1 * hCALsizeY / 2 + ((float)row + 0.5) * (towerSize / 7);
1210 x = -1 * hCALsizeX / 2 + ((float)col + 0.5) * (towerSize / 7);
1211 break;
1212 }
1213 case HCALDesgin::Sheets: {
1216 double hCALsizeX = comp1.sizeX() * 2; // Size of two sheet in X
1217 double hCALsizeY = getHCALTowersInY() * (comp1.sizeY() + comp2.sizeY()) * 2; // To be set in a better way
1218
1219 y = -1 * hCALsizeY / 2 + ((float)row + 0.5) * (hCALsizeY / getHCALTowersInY());
1220 x = -1 * hCALsizeX / 2 + ((float)col + 0.5) * (hCALsizeX / getHCALTowersInX());
1221 break;
1222 }
1223 default:
1224 break;
1225 }
1226 } else {
1227 y = -1 * getFOCALSizeY() / 2 + ((float)row + 0.5) * mVirtualSegmentComposition[segment].mPadSize;
1228 x = -1 * getFOCALSizeX() / 2 + ((float)col + 0.5) * mVirtualSegmentComposition[segment].mPadSize;
1229 // Middle towers offset
1230 // if(y < 4.2 && y > - 4.2) { // TO BE set from outside or somewhere else -4,4 is the y position of the middle towers
1231 // x = x < 0 ? x - GetMiddleTowerOffset() : x + GetMiddleTowerOffset();
1232 // }
1233 }
1234
1235 if (std::abs(x) > (getFOCALSizeX() + 2 * getMiddleTowerOffset()) / 2) {
1236 return {false, x, y, z};
1237 }
1238 if (std::abs(y) > getFOCALSizeY() / 2) {
1239 return {false, x, y, z};
1240 }
1242 return {true, x, y, z};
1243}
1244
1245//_______________________________________________________________________
1246std::tuple<bool, int, int> Geometry::getVirtualNColRow(int segment) const
1247{
1248
1249 // ix + iy*mGlobal_PAD_NX + itowerX*mGlobal_PAD_NX*mGlobal_PAD_NY + itowerY*mGlobal_PAD_NX_Tower*mGlobal_PAD_NX*mGlobal_PAD_NY
1250 int nCol = -1, nRow = -1;
1251 if (mVirtualSegmentComposition.size() == 0) {
1252 return {false, nCol, nRow};
1253 }
1254 if ((segment < 0) || (segment >= mVirtualNSegments)) {
1255 return {false, nCol, nRow};
1256 }
1257 nCol = (int)(getFOCALSizeX() / mVirtualSegmentComposition[segment].mPadSize + 0.001);
1258 nRow = (int)(getFOCALSizeY() / mVirtualSegmentComposition[segment].mPadSize + 0.001);
1260 switch (mHCALDesign) {
1261 case HCALDesgin::Sandwich: {
1262 nCol = getHCALTowersInX();
1263 nRow = getHCALTowersInY();
1264 break;
1265 }
1266 case HCALDesgin::Spaghetti: {
1267 nCol = getHCALTowersInX() * 7; // To be set from outside (number of channels in each tower on x)
1268 nRow = getHCALTowersInY() * 7; // To be set from outside (number of channels in each tower on y)
1269 break;
1270 }
1271 case HCALDesgin::Sheets: {
1272 nCol = getHCALTowersInX();
1273 nRow = getHCALTowersInY();
1274 break;
1275 }
1276 default:
1277 break;
1278 }
1279 }
1280 return {true, nCol, nRow};
1281}
1282
1283//_______________________________________________________________________
1285{
1286
1287 return mVirtualNSegments;
1288}
1289
1290//_______________________________________________________________________
1291std::tuple<bool, int, int> Geometry::getVirtualLayerSegment(float z) const
1292{
1293
1294 int layer = -1;
1295 int segment = -1;
1296
1297 z = z - getFOCALZ0() + getFOCALSizeZ() / 2; // z from front face (excluding fron matter)
1298 float emLayersZ = mNPadLayers * mPadLayerThickness + mNPixelLayers * mPixelLayerThickness; // Pixel layers replace pad layers
1299 if (z < emLayersZ) {
1301 while (layer >= 0 && z < mLocalLayerZ[layer]) {
1302 layer--;
1303 }
1304 } else {
1305 z = z - emLayersZ;
1307 }
1308
1309 if ((layer < 0) || (layer >= (mNPadLayers + mNPixelLayers + mNHCalLayers))) {
1310 return {false, layer, segment};
1311 }
1312
1313 segment = -1;
1314 for (int nSeg = 0; nSeg < mVirtualNSegments; nSeg++) {
1315 if ((layer >= mVirtualSegmentComposition[nSeg].mMinLayer) && (layer <= mVirtualSegmentComposition[nSeg].mMaxLayer)) {
1316 segment = nSeg;
1317 break;
1318 }
1319 }
1320
1321 if (segment == mVirtualNSegments) {
1322 return {false, layer, segment};
1323 }
1324 return {true, layer, segment};
1325}
1326
1327//_______________________________________________________________________
1328std::tuple<bool, int> Geometry::getVirtualSegmentFromLayer(int layer) const
1329{
1330
1331 int segment = -1;
1332 for (int nSeg = 0; nSeg < mVirtualNSegments; nSeg++) {
1333 // cout << "Segment boundaries " << nSeg << " : " << mVirtualSegmentComposition[nSeg].fMinLayer << " " << mVirtualSegmentComposition[nSeg].fMaxLayer << endl;
1334 if ((layer >= mVirtualSegmentComposition[nSeg].mMinLayer) && (layer <= mVirtualSegmentComposition[nSeg].mMaxLayer)) {
1335 segment = nSeg;
1336 break;
1337 }
1338 }
1339 if (segment == mVirtualNSegments) {
1340 return {false, segment};
1341 }
1342 return {true, segment};
1343}
1344
1345//_______________________________________________________________________
1347{
1348 auto [status, layer, segment] = getVirtualLayerSegment(z);
1349 return segment;
1350}
1351
1352//_______________________________________________________________________
1354{
1355 if (mVirtualSegmentComposition.size() == 0) {
1356 return -1;
1357 }
1358 return mVirtualSegmentComposition[segment].mPadSize;
1359}
1360
1361//_______________________________________________________________________
1363{
1364
1365 if (mVirtualSegmentComposition.size() == 0) {
1366 return -1;
1367 }
1368 return mVirtualSegmentComposition[segment].mRelativeSensitiveThickness;
1369}
1370
1371//_______________________________________________________________________
1373{
1374
1375 if (mVirtualSegmentComposition.size() == 0) {
1376 return -1;
1377 }
1378 return mVirtualSegmentComposition[segment].mPixelTreshold;
1379}
1380
1381//________________________________________________________________________
1383{
1384
1385 if (mVirtualSegmentComposition.size() == 0) {
1386 return -1;
1387 }
1388
1389 float size = 0;
1390 for (int nLay = mVirtualSegmentComposition[segment].mMinLayer; nLay <= mVirtualSegmentComposition[segment].mMaxLayer; nLay++) {
1391 size += mLayerThickness[nLay];
1392 }
1393 return size;
1394}
1395
1396//________________________________________________________________________
1398{
1399
1400 if (mVirtualSegmentComposition.size() == 0) {
1401 return -1;
1402 }
1403
1404 float before = 0;
1405 float thickness = 0;
1406
1407 for (int nLay = 0; nLay < mVirtualSegmentComposition[segment].mMinLayer; nLay++) {
1408 before += mLayerThickness[nLay];
1409 }
1410 for (int nLay = mVirtualSegmentComposition[segment].mMinLayer; nLay <= mVirtualSegmentComposition[segment].mMaxLayer; nLay++) {
1411 thickness += mLayerThickness[nLay];
1412 }
1413 return getFOCALZ0() - getFOCALSizeZ() / 2 + before + thickness / 2;
1414}
1415
1416//________________________________________________________________________
1418{
1419
1420 if (mVirtualSegmentComposition.size() == 0) {
1421 return false;
1422 }
1423
1424 if ((segment < 0) || (segment >= mVirtualNSegments)) {
1425 return false;
1426 }
1427
1428 return (mVirtualSegmentComposition[segment].mIsPixel == 1);
1429}
1430
1431//________________________________________________________________________
1433{
1434
1435 if (mVirtualSegmentComposition.size() == 0) {
1436 return false;
1437 }
1438
1439 if ((segment < 0) || (segment >= mVirtualNSegments)) {
1440 return false;
1441 }
1442 return (mVirtualSegmentComposition[segment].mIsPixel == 2);
1443}
1444
1445//________________________________________________________________________
1447{
1448 //
1449 // Get the number of layers in a given segment
1450 //
1451 if (mVirtualSegmentComposition.size() == 0) {
1452 return -1;
1453 }
1454
1455 if ((segment < 0) || (segment >= mVirtualNSegments)) {
1456 return -1;
1457 }
1458 return (mVirtualSegmentComposition[segment].mMaxLayer - mVirtualSegmentComposition[segment].mMinLayer + 1);
1459}
1460
1461//_______________________________________________________________________
1463{
1464 //
1465 // Get the number of first layer in a given segment
1466 //
1467 if (mVirtualSegmentComposition.size() == 0) {
1468 return -1;
1469 }
1470
1471 if ((segment < 0) || (segment >= mVirtualNSegments)) {
1472 return -1;
1473 }
1474 return mVirtualSegmentComposition[segment].mMinLayer;
1475}
1476
1477//_______________________________________________________________________
1479{
1480 //
1481 // Get the number of first layer in a given segment
1482 //
1483 if (mVirtualSegmentComposition.size() == 0) {
1484 return -1;
1485 }
1486
1487 if ((segment < 0) || (segment >= mVirtualNSegments)) {
1488 return -1;
1489 }
1490 return mVirtualSegmentComposition[segment].mMaxLayer;
1491}
o2::mch::mapping::CathodeSegmentation seg
int32_t i
uint32_t j
Definition RawData.h:0
uint32_t col
Definition RawData.h:4
uint32_t stack
Definition RawData.h:1
std::ostringstream debug
float centerZ() const
Definition Composition.h:57
float sizeX() const
Definition Composition.h:58
float sizeY() const
Definition Composition.h:59
double getTowerGapSizeY() const
Definition Geometry.h:133
double getFOCALSizeY() const
Definition Geometry.cxx:860
std::vector< VirtualSegment > mVirtualSegmentComposition
Definition Geometry.h:244
float mHCalLayerThickness
Definition Geometry.h:239
std::tuple< int, int, int, int, int, int, int > getPadPositionId2RowColStackLayer(int id) const
Definition Geometry.cxx:922
int getNumberOfTowersInX() const
Definition Geometry.h:129
std::tuple< bool, double, double, double > getXYZFromColRowSeg(int col, int row, int segment) const
double getTowerGapSizeX() const
Definition Geometry.h:132
double getHCALSizeZ() const
Definition Geometry.cxx:899
std::array< float, 100 > mLocalSegmentsZ
Definition Geometry.h:235
float mFrontMatterLayerThickness
segment location in z
Definition Geometry.h:236
double getGlobalPixelWaferSizeY() const
Definition Geometry.h:136
double getECALSizeZ() const
Definition Geometry.cxx:878
int getHCALTowersInY() const
Definition Geometry.h:109
std::vector< Composition > mFrontMatterCompositionBase
Definition Geometry.h:173
float getVirtualPadSize(int segment) const
bool getVirtualIsHCal(int segment) const
float mGlobal_DetectorOpening_Left
Definition Geometry.h:190
int getVirtualNSegments() const
std::tuple< bool, int, int, int, int > getVirtualInfo(double x, double y, double z) const
std::list< int > mDisableTowers
Definition Geometry.h:241
std::array< float, 100 > mLayerThickness
Definition Geometry.h:240
float mGlobal_DetectorOpening_Right
Definition Geometry.h:189
double getGlobalPixelWaferSizeX() const
Definition Geometry.h:135
double getFOCALSizeZ() const
Definition Geometry.cxx:866
std::tuple< double, double > getGeoPadCenterLocal(int towerX, int towerY, int row, int col) const
this gives local position of the pad with respect to the wafer
Definition Geometry.cxx:796
std::tuple< double, double, double > getGeoPixelCenter(int pixel_id, int tower, int layer, int stack, int row, int col) const
this gives global position of the pixel
int getPixelNumber(int vol0, int vol1, int vol2, double x, double y) const
void init(const std::string geoFile)
Definition Geometry.cxx:74
float getHCALTowerSize() const
Definition Geometry.h:107
static Geometry * getInstance()
Definition Geometry.cxx:41
float getVirtualRelativeSensitiveThickness(int segment) const
std::tuple< bool, int, int > getVirtualNColRow(int segment) const
float mGlobal_PIX_OffsetX
Definition Geometry.h:196
std::array< float, 100 > mLocalLayerZ
Definition Geometry.h:234
float mGlobal_PIX_OffsetY
Definition Geometry.h:197
int getVirtualSegment(float z) const
int getVirtualMaxLayerInSegment(int segment) const
int getHCALTowersInX() const
Definition Geometry.h:108
std::vector< Composition > mPixelCompositionBase
Definition Geometry.h:175
double getHCALCenterZ() const
Definition Geometry.cxx:910
std::tuple< double, double, double > getGeoCompositionCenter(int tower, int layer, int stack) const
Definition Geometry.cxx:767
std::tuple< double, double, double > getGeoTowerCenter(int tower, int segment=-1) const
this gives global position of the center of tower
Definition Geometry.cxx:694
double getTowerSizeX() const
Definition Geometry.cxx:840
std::vector< const Composition * > getFOCALMicroModule(int layer) const
Definition Geometry.cxx:673
std::vector< Composition > mPadCompositionBase
Definition Geometry.h:174
float mGlobal_HCAL_Pitch_Size
Definition Geometry.h:219
std::array< int, 20 > mPixelLayerLocations
Definition Geometry.h:206
const Composition * getComposition(int layer, int stack) const
Definition Geometry.cxx:661
void setUpLayerSegmentMap()
Definition Geometry.cxx:987
std::array< int, 100 > mNumberOfLayersInSegments
Definition Geometry.h:231
float getHCALBeamPipeHoleSize() const
Definition Geometry.h:144
HCALDesgin mHCALDesign
Definition Geometry.h:221
double getFOCALZ0() const
Definition Geometry.h:128
bool getVirtualIsPixel(int segment) const
float getMiddleTowerOffset() const
Definition Geometry.h:140
std::tuple< bool, int, int > getVirtualLayerSegment(float z) const
std::vector< Composition > mHCalCompositionBase
Definition Geometry.h:176
double getFOCALSizeX() const
Definition Geometry.cxx:854
float mGlobal_HCAL_BeamPipeHole_Size
Definition Geometry.h:220
double getTowerSizeY() const
Definition Geometry.cxx:847
float getVirtualSegmentSizeZ(int segment) const
std::vector< Composition > mGeometryComposition
Definition Geometry.h:172
int getVirtualMinLayerInSegment(int segment) const
bool disabledTower(int tower)
std::tuple< bool, int > getVirtualSegmentFromLayer(int layer) const
float mGlobal_Middle_Tower_Offset
Definition Geometry.h:213
float getVirtualSegmentZ(int segment) const
std::tuple< double, double, double > getGeoPadCenter(int tower, int layer, int stack, int row, int col) const
this gives global position of the pad
Definition Geometry.cxx:784
double getECALCenterZ() const
Definition Geometry.cxx:890
float mGlobal_HCAL_Tower_Size
Definition Geometry.h:216
std::array< int, 100 > mSegments
Definition Geometry.h:230
int getVirtualNLayersInSegment(int segment) const
float getVirtualPixelTreshold(int segment) const
std::tuple< double, double > getGeoPixCenterLocal(int row, int col) const
this gives local position of the pad with respect to the wafer
Definition Geometry.cxx:818
double getFOCALSegmentZ(int seg) const
Definition Geometry.cxx:968
float mPixelLayerThickness
Definition Geometry.h:238
bool mInsertFrontHCalReadoutMaterial
Definition Geometry.h:226
std::string mGlobal_Gap_Material
Definition Geometry.h:214
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint segment
Definition glcorearb.h:4945
GLuint GLfloat GLfloat GLfloat GLfloat y1
Definition glcorearb.h:5034
GLsizeiptr size
Definition glcorearb.h:659
GLenum GLuint GLenum GLuint GLuint GLuint minlayer
Definition glcorearb.h:2506
GLuint GLfloat GLfloat GLfloat x1
Definition glcorearb.h:5034
GLint y
Definition glcorearb.h:270
GLuint GLfloat x0
Definition glcorearb.h:5034
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
GLuint start
Definition glcorearb.h:469
GLuint GLfloat GLfloat y0
Definition glcorearb.h:5034
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
std::string filename()
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< int > row
const std::string str