ATLAS Offline Software
Loading...
Searching...
No Matches
LArRecoMaterialTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// ***************************************************************************
6// LArCalorimeter/LArDetDescr/LArRecoMaterialTool.cxx
7// -------------------------------------------------------------
8//****************************************************************************
9
10#include "LArRecoMaterialTool.h"
11
12#include "GaudiKernel/Bootstrap.h"
13#include "Gaudi/Property.h"
14#include "GaudiKernel/IService.h"
15#include "GaudiKernel/IToolSvc.h"
16#include <vector>
17
19#include "GeoModelKernel/GeoFullPhysVol.h"
20#include "GeoModelKernel/Units.h"
21#include "GaudiKernel/SystemOfUnits.h"
22
25
26#include <iostream>
27#include <iomanip>
28
30 const std::string& name,
31 const IInterface* parent)
32 : base_class(type, name, parent)
33{
34}
35
36StatusCode
38{
39 ATH_CHECK( detStore()->retrieve (m_calo_id, "CaloCell_ID") );
40 ATH_CHECK( detStore()->retrieve (m_dm_id, "CaloDM_ID") );
41
42 // These vectors will contain the results :
43 m_alignvol_number.resize(0);
44 m_alignvol_mass.resize(0);
45 m_alignvol_x0.resize(0);
46 m_alignvol_dEdX.resize(0);
47 m_alignvol_aveA.resize(0);
48 m_alignvol_aveZ.resize(0);
49
50 // ---------- Fill arrays :
51
52 // going though the full tree is too slow to be used as default,
53 // if you want to do it set this flag to true :
54 // ( will become a property at some point ! )
56
57 this->ScanTree();
58 //this->print();
59
60
61 // ---------- That's it
62
63
64 ATH_MSG_INFO (" LArRecoMaterialTool successfully initialized ");
65 return StatusCode::SUCCESS;
66}
67
68bool
70 double& mass, double& volume,
71 double& x0, double& dEdx,
72 double& aveA, double& aveZ
73 ) const
74{
75 bool result = false;
76
77 for ( unsigned int i = 0; i < m_alignvol_number.size(); i++ )
78 {
79 if ( m_alignvol_number[i] == alvol ) {
80 mass = m_alignvol_mass[i];
81 x0 = m_alignvol_x0[i];
82 dEdx = m_alignvol_dEdX[i];
83 aveA = m_alignvol_aveA[i];
84 aveZ = m_alignvol_aveZ[i];
85 // FIXME
86 volume = 1000.;
87 result = true;
88 }
89 }
90
91 return result;
92}
93
94void
96 double& x0, double& dEdx,
97 double& aveA, double& aveZ
98 ) const
99{
100 // FIXME ! should take real LAr numbers
101 density = 1.;
102 x0 = 5.;
103 dEdx = 1.1e-24;
104 aveA = 39.948;
105 aveZ = 18.;
106
107}
108
109void
111{
112
113 for ( unsigned int i = 0; i < m_alignvol_number.size(); i++ )
114 {
115 ATH_MSG_INFO (" + Result for ALIGNVOL " << m_alignvol_number[i]);
116 ATH_MSG_INFO (" - mass [gram] " << m_alignvol_mass[i]);
117 ATH_MSG_INFO (" - X0 " << m_alignvol_x0[i]);
118 ATH_MSG_INFO (" - DeDx " << m_alignvol_dEdX[i]);
119 ATH_MSG_INFO (" - AverageA " << m_alignvol_aveA[i]);
120 ATH_MSG_INFO (" - AverageZ " << m_alignvol_aveZ[i]);
121 }
122}
123
124void
126{
127 double mass = 0.;
128 double x0 = 0.;
129 double dEdx = 0.;
130 double aveA = 0.;
131 double aveZ = 0.;
132
133 bool result = false;
134
135 ATH_MSG_INFO (" Entering method ScanTree() ");
136
137 result = this->ScanCRYO(CaloSubdetNames::LARCRYO_B,mass,x0,dEdx,aveA,aveZ);
138 result = this->ScanCRYO(CaloSubdetNames::LARCRYO_EC_POS,mass,x0,dEdx,aveA,aveZ);
139 result = this->ScanCRYO(CaloSubdetNames::LARCRYO_EC_NEG,mass,x0,dEdx,aveA,aveZ);
140 result = this->ScanCRYO(CaloSubdetNames::SOLENOID,mass,x0,dEdx,aveA,aveZ);
141
142 result = this->ScanPS(CaloSubdetNames::PRESAMPLER_B_POS,mass,x0,dEdx,aveA,aveZ);
143 result = this->ScanPS(CaloSubdetNames::PRESAMPLER_B_NEG,mass,x0,dEdx,aveA,aveZ);
144
145 result = this->ScanEMB(CaloSubdetNames::EMB_POS,mass,x0,dEdx,aveA,aveZ);
146 result = this->ScanEMB(CaloSubdetNames::EMB_NEG,mass,x0,dEdx,aveA,aveZ);
147
148 result = this->ScanPS(CaloSubdetNames::PRESAMPLER_EC_POS,mass,x0,dEdx,aveA,aveZ);
149 result = this->ScanPS(CaloSubdetNames::PRESAMPLER_EC_NEG,mass,x0,dEdx,aveA,aveZ);
150
151 result = this->ScanEMEC(CaloSubdetNames::EMEC_POS,mass,x0,dEdx,aveA,aveZ);
152 result = this->ScanEMEC(CaloSubdetNames::EMEC_NEG,mass,x0,dEdx,aveA,aveZ);
153
154 result = this->ScanHEC(CaloSubdetNames::HEC1_POS,mass,x0,dEdx,aveA,aveZ);
155 result = this->ScanHEC(CaloSubdetNames::HEC1_NEG,mass,x0,dEdx,aveA,aveZ);
156 result = this->ScanHEC(CaloSubdetNames::HEC2_POS,mass,x0,dEdx,aveA,aveZ);
157 result = this->ScanHEC(CaloSubdetNames::HEC2_NEG,mass,x0,dEdx,aveA,aveZ);
158
159 result = this->ScanFCAL(CaloSubdetNames::FCAL1_POS,mass,x0,dEdx,aveA,aveZ);
160 result = this->ScanFCAL(CaloSubdetNames::FCAL1_NEG,mass,x0,dEdx,aveA,aveZ);
161 result = this->ScanFCAL(CaloSubdetNames::FCAL2_POS,mass,x0,dEdx,aveA,aveZ);
162 result = this->ScanFCAL(CaloSubdetNames::FCAL2_NEG,mass,x0,dEdx,aveA,aveZ);
163 result = this->ScanFCAL(CaloSubdetNames::FCAL3_POS,mass,x0,dEdx,aveA,aveZ);
164 result = this->ScanFCAL(CaloSubdetNames::FCAL3_NEG,mass,x0,dEdx,aveA,aveZ);
165
166 if (!result)
167 ATH_MSG_INFO (" If seems to have failed ?");
168
169 return;
170}
171
172bool
174 double& mass, double& x0, double& dEdx,
175 double& aveA, double& aveZ)
176{
177 mass = 0.;
178 x0 = 0.;
179 dEdx = 0.;
180 aveA = 0.;
181 aveZ = 0.;
182
183 if ( alvol != CaloSubdetNames::LARCRYO_B
186 && alvol != CaloSubdetNames::SOLENOID ) {
187 ATH_MSG_INFO ("method ScanCryo does not support CaloSubdetNames::ALIGNVOL " << (int) alvol);
188 return false;
189 }
190
191 // For EC, link to GeoModel does not exist (yet) : take barrel numbers
192
193 // Shortcut :
195 {
196 //if ( alvol == CaloSubdetNames::LARCRYO_B || alvol == CaloSubdetNames::SOLENOID) {
197 mass = 3.61158e+07 ;
198 x0 = 89.411;
199 dEdx = 7.47033e-24 ;
200 aveA = 27.9728;
201 aveZ = 13.4253 ;
202#if 0
203 } else {
204 mass = 3.61158e+07 ;
205 x0 = 89.411;
206 dEdx = 7.47033e-24 ;
207 aveA = 27.9728;
208 aveZ = 13.4253 ;
209 }
210#endif
211 }
212#if 0
213 // Dead code as long as m_parseGeoModelForMaterial is false.
214 // Comment out to avoid coverity warnings.
215 else {
216
217 // Go for it :
218 m_child_massFractions.clear();
219 m_child_volumeFractions.clear();
220 m_child_x0Fractions.clear();
221 m_child_dEdXFractions.clear();
222 m_child_averageAFractions.clear();
223 m_child_averageZFractions.clear();
224 m_child_Rho.clear();
225 m_child_Volume.clear();
226 m_child_Mass.clear();
227
228 double childVolume = 0.;
229 double childMass = 0.;
230 double childX0 = 0.;
231 double childDeDx = 0.;
232 double childAverageA = 0.;
233 double childAverageZ = 0.;
234 double childRho = 0.;
235
236 const StoredPhysVol* storedPV = 0;
237 std::string key = map_av(alvol);
238 if(detStore()->contains<StoredPhysVol>(key))
239 {
240 if(detStore()->retrieve(storedPV,key)==StatusCode::FAILURE)
241 {
242 ATH_MSG_INFO ("Unable to retrieve Stored PV " << key);
243 }
244 }
245
246 if (!storedPV) {
247 ATH_MSG_INFO ("no Volume for " << key);
248 return false;
249 }
250
251 const GeoFullPhysVol* larTopVolLink = storedPV->getPhysVol();
252
253 // get the number of direct childs
254 unsigned int larChilds = larTopVolLink->getNChildVols();
255
256 for (unsigned int ichild = 0; ichild<larChilds; ++ichild){
257
258 bool stop = false;
259
260 // Skip some some of the children : list will get longer in future
261 if ( alvol == CaloSubdetNames::LARCRYO_B &&
262 larTopVolLink->getNameOfChildVol(ichild) == "Total LAR Volume") stop = true;
263 if ( alvol == CaloSubdetNames::SOLENOID &&
264 larTopVolLink->getNameOfChildVol(ichild) == "Total LAR Volume") stop = true;
265
266 if (!stop) {
267
268 ATH_MSG_DEBUG ("CaloSubdetNames::ALIGNVOL " << (int) alvol
269 <<" Direct Child " << ichild << " - with name : "
270 << larTopVolLink->getNameOfChildVol(ichild));
271
272 PVConstLink childVolLink = larTopVolLink->getChildVol(ichild);
273
274 m_massFractions.clear();
275 m_volumeFractions.clear();
276 m_x0Fractions.clear();
277 m_dEdXFractions.clear();
278 m_averageAFractions.clear();
279 m_averageZFractions.clear();
280
281 this->blendGeoVolume(childVolLink,
282 m_volumeFractions,
283 m_massFractions,
284 m_x0Fractions,
285 m_dEdXFractions,
286 m_averageAFractions,
287 m_averageZFractions);
288
289 this->averageFraction(m_volumeFractions,
290 m_massFractions,
291 m_x0Fractions,
292 m_dEdXFractions,
293 m_averageAFractions,
294 m_averageZFractions,
295 childMass, childVolume,
296 childX0, childDeDx,
297 childAverageA, childAverageZ, childRho );
298
299 m_child_x0Fractions.push_back( childX0 );
300 m_child_dEdXFractions.push_back( childDeDx );
301 m_child_averageAFractions.push_back( childAverageA );
302 m_child_averageZFractions.push_back( childAverageZ );
303 m_child_Rho.push_back( childRho );
304 m_child_Volume.push_back( childVolume );
305 m_child_Mass.push_back( childMass );
306
307 }
308 }
309
310 // Now do the final average and store it :
311
312 ATH_MSG_DEBUG ("Final average for CaloSubdetNames::ALIGNVOL " << (int) alvol
313 << " !!!!! ");
314
315 this->averageFraction(m_child_Volume, m_child_Mass,
316 m_child_x0Fractions,
317 m_child_dEdXFractions,
318 m_child_averageAFractions,
319 m_child_averageZFractions,
320 childMass, childVolume,
321 childX0, childDeDx,
322 childAverageA, childAverageZ, childRho );
323
324 mass = childMass/GeoModelKernelUnits::gram;
325 x0 = childX0;
326 dEdx = childDeDx;
327 aveA = childAverageA;
328 aveZ = childAverageZ;
329 }
330#endif
331
332 m_alignvol_number.push_back( alvol );
333 m_alignvol_mass.push_back( mass );
334 m_alignvol_x0.push_back( x0 );
335 m_alignvol_dEdX.push_back( dEdx );
336 m_alignvol_aveA.push_back( aveA );
337 m_alignvol_aveZ.push_back( aveZ );
338
339 return true;
340}
341
342bool
344 double& mass, double& x0, double& dEdx,
345 double& aveA, double& aveZ)
346{
347 mass = 0.;
348 x0 = 0.;
349 dEdx = 0.;
350 aveA = 0.;
351 aveZ = 0.;
352
357 ) {
358 ATH_MSG_INFO ("method ScanCryo does not support CaloSubdetNames::ALIGNVOL " << (int) alvol);
359 return false;
360 }
361
362 // for EMEC take Barrel numbers
363
364 // Shortcut :
368 {
369 mass = 1.80785e+06 ;
370 x0 = 141.837;
371 dEdx = 3.55847e-24;
372 aveA = 39.5576;
373 aveZ = 17.8274;
374 }
375
376 else {
377
378 // Go for it :
379 m_child_massFractions.clear();
381 m_child_x0Fractions.clear();
382 m_child_dEdXFractions.clear();
385 m_child_Rho.clear();
386 m_child_Volume.clear();
387 m_child_Mass.clear();
388
389 double childVolume = 0.;
390 double childMass = 0.;
391 double childX0 = 0.;
392 double childDeDx = 0.;
393 double childAverageA = 0.;
394 double childAverageZ = 0.;
395 double childRho = 0.;
396
397 StoredPhysVol* storedPV = nullptr;
398 std::string key = map_av(alvol);
399 if(detStore()->contains<StoredPhysVol>(key))
400 {
401 if(detStore()->retrieve(storedPV,key)==StatusCode::FAILURE)
402 {
403 ATH_MSG_INFO ("Unable to retrieve Stored PV " << key);
404 }
405 }
406
407 if (!storedPV) {
408 ATH_MSG_INFO ("no Volume for " << key);
409 return false;
410 }
411
412 const GeoFullPhysVol* larTopVolLink = storedPV->getPhysVol();
413
414 // get the number of direct childs
415 unsigned int larChilds = larTopVolLink->getNChildVols();
416
417 for (unsigned int ichild = 0; ichild<larChilds; ++ichild){
418
419 bool stop = false;
420
421 // Skip some some of the children : list will get longer in future
422 //if ( alvol == CaloSubdetNames::LARCRYO_B &&
423 // larTopVolLink->getNameOfChildVol(ichild) == "Total LAR Volume") stop = true;
424
425 if (!stop) {
426
427 ATH_MSG_DEBUG ("CaloSubdetNames::ALIGNVOL " << (int) alvol
428 <<" Direct Child " << ichild << " - with name : "
429 << larTopVolLink->getNameOfChildVol(ichild));
430
431 PVConstLink childVolLink = larTopVolLink->getChildVol(ichild);
432
433 m_massFractions.clear();
434 m_volumeFractions.clear();
435 m_x0Fractions.clear();
436 m_dEdXFractions.clear();
437 m_averageAFractions.clear();
438 m_averageZFractions.clear();
439
440 this->blendGeoVolume(childVolLink,
447
454 childMass, childVolume,
455 childX0, childDeDx,
456 childAverageA, childAverageZ, childRho );
457
458 m_child_x0Fractions.push_back( childX0 );
459 m_child_dEdXFractions.push_back( childDeDx );
460 m_child_averageAFractions.push_back( childAverageA );
461 m_child_averageZFractions.push_back( childAverageZ );
462 m_child_Rho.push_back( childRho );
463 m_child_Volume.push_back( childVolume );
464 m_child_Mass.push_back( childMass );
465
466 }
467 }
468
469 // Now do the final average and store it :
470
471 ATH_MSG_DEBUG ("Final average for CaloSubdetNames::ALIGNVOL " << (int) alvol
472 << " !!!!! ");
473
479 childMass, childVolume,
480 childX0, childDeDx,
481 childAverageA, childAverageZ, childRho );
482
483 mass = childMass*(1./GeoModelKernelUnits::gram);
484 x0 = childX0;
485 dEdx = childDeDx;
486 aveA = childAverageA;
487 aveZ = childAverageZ;
488 }
489
490 m_alignvol_number.push_back( alvol );
491 m_alignvol_mass.push_back( mass );
492 m_alignvol_x0.push_back( x0 );
493 m_alignvol_dEdX.push_back( dEdx );
494 m_alignvol_aveA.push_back( aveA );
495 m_alignvol_aveZ.push_back( aveZ );
496
497 return true;
498}
499
500bool
502 double& mass, double& x0, double& dEdx,
503 double& aveA, double& aveZ)
504{
505 mass = 0.;
506 x0 = 0.;
507 dEdx = 0.;
508 aveA = 0.;
509 aveZ = 0.;
510
511 if ( alvol != CaloSubdetNames::EMB_POS &&
512 alvol != CaloSubdetNames::EMB_NEG ) {
513 ATH_MSG_INFO ("method ScanEMB does not support CaloSubdetNames::ALIGNVOL " << (int) alvol);
514 return false;
515 }
516
517 // Shortcut :
519 {
520 mass = 9.40439e+07 ;
521 x0 = 93.9601;
522 dEdx = 6.0789e-24;
523 aveA = 98.5676;
524 aveZ = 39.7406;
525 }
526 else {
527
528 // Here we go :
529 m_child_massFractions.clear();
531 m_child_x0Fractions.clear();
532 m_child_dEdXFractions.clear();
535 m_child_Rho.clear();
536 m_child_Volume.clear();
537 m_child_Mass.clear();
538
539 double childVolume = 0.;
540 double childMass = 0.;
541 double childX0 = 0.;
542 double childDeDx = 0.;
543 double childAverageA = 0.;
544 double childAverageZ = 0.;
545 double childRho = 0.;
546
547 StoredPhysVol* storedPV = nullptr;
548 std::string key = map_av(alvol);
549 if(detStore()->contains<StoredPhysVol>(key))
550 {
551 if(detStore()->retrieve(storedPV,key)==StatusCode::FAILURE)
552 {
553 ATH_MSG_INFO ("Unable to retrieve Stored PV " << key);
554 }
555 }
556
557 if (!storedPV) {
558 ATH_MSG_INFO ("no Volume for " << key);
559 mass = 0.;
560 x0 = 0.;
561 dEdx = 0.;
562 aveA = 0.;
563 aveZ = 0.;
564 return false;
565 }
566
567 const GeoFullPhysVol* larTopVolLink = storedPV->getPhysVol();
568
569 // get the number of direct childs
570 unsigned int larChilds = larTopVolLink->getNChildVols();
571
572 for (unsigned int ichild = 0; ichild<larChilds; ++ichild){
573
574 bool stop = false;
575
576 // Skip some some of the children : list will get longer in future
577 //if ( alvol == CaloSubdetNames::LARCRYO_B &&
578 // larTopVolLink->getNameOfChildVol(ichild) == "Total LAR Volume") stop = true;
579
580 if (!stop) {
581
582 ATH_MSG_DEBUG ("CaloSubdetNames::ALIGNVOL " << (int) alvol
583 <<" Direct Child " << ichild << " - with name : "
584 << larTopVolLink->getNameOfChildVol(ichild));
585
586 PVConstLink childVolLink = larTopVolLink->getChildVol(ichild);
587
588 m_massFractions.clear();
589 m_volumeFractions.clear();
590 m_x0Fractions.clear();
591 m_dEdXFractions.clear();
592 m_averageAFractions.clear();
593 m_averageZFractions.clear();
594
595 this->blendGeoVolume(childVolLink,
602
609 childMass, childVolume,
610 childX0, childDeDx,
611 childAverageA, childAverageZ, childRho );
612
613 m_child_x0Fractions.push_back( childX0 );
614 m_child_dEdXFractions.push_back( childDeDx );
615 m_child_averageAFractions.push_back( childAverageA );
616 m_child_averageZFractions.push_back( childAverageZ );
617 m_child_Rho.push_back( childRho );
618 m_child_Volume.push_back( childVolume );
619 m_child_Mass.push_back( childMass );
620
621 }
622 }
623
624 // Now do the final average and store it :
625
626 ATH_MSG_DEBUG ("Final average for CaloSubdetNames::ALIGNVOL " << (int) alvol
627 << " !!!!! ");
628
634 childMass, childVolume,
635 childX0, childDeDx,
636 childAverageA, childAverageZ, childRho );
637
638 mass = childMass*(1./GeoModelKernelUnits::gram);
639 x0 = childX0;
640 dEdx = childDeDx;
641 aveA = childAverageA;
642 aveZ = childAverageZ;
643 }
644
645 m_alignvol_number.push_back( alvol );
646 m_alignvol_mass.push_back( mass );
647 m_alignvol_x0.push_back( x0 );
648 m_alignvol_dEdX.push_back( dEdx );
649 m_alignvol_aveA.push_back( aveA );
650 m_alignvol_aveZ.push_back( aveZ );
651
652 return true;
653}
654
655bool
657 double& mass, double& x0, double& dEdx,
658 double& aveA, double& aveZ)
659{
660 mass = 0.;
661 x0 = 0.;
662 dEdx = 0.;
663 aveA = 0.;
664 aveZ = 0.;
665
666 if ( alvol != CaloSubdetNames::EMEC_POS && alvol != CaloSubdetNames::EMEC_NEG ) {
667 ATH_MSG_INFO ("method ScanEMEM does not support CaloSubdetNames::ALIGNVOL " << (int) alvol);
668 return false;
669 }
670
671 // EMEC use a couple of custom volumes :
672 // LAr::EMEC::OuterWheel::Absorber has volume=0 mm**3 and 5 elements
673 // LAr::EMEC::OuterWheel::Electrode has volume=0 mm**3 and 5 elements
674 // ==> with volume = 0 avarages cannot work !!!
675 // Take EMB's density for now ....
676 mass = 9.40439e+07 ;
677 x0 = 93.9601;
678 dEdx = 6.0789e-24;
679 aveA = 98.5676;
680 aveZ = 39.7406;
681
682
683 m_alignvol_number.push_back( alvol );
684 m_alignvol_mass.push_back( mass );
685 m_alignvol_x0.push_back( x0 );
686 m_alignvol_dEdX.push_back( dEdx );
687 m_alignvol_aveA.push_back( aveA );
688 m_alignvol_aveZ.push_back( aveZ );
689
690 return true;
691}
692
693bool
695 double& mass, double& x0, double& dEdx,
696 double& aveA, double& aveZ)
697{
698 mass = 0.;
699 x0 = 0.;
700 dEdx = 0.;
701 aveA = 0.;
702 aveZ = 0.;
703
704 if ( alvol != CaloSubdetNames::HEC1_POS &&
705 alvol != CaloSubdetNames::HEC1_NEG &&
706 alvol != CaloSubdetNames::HEC2_POS &&
707 alvol != CaloSubdetNames::HEC2_NEG ) {
708 ATH_MSG_INFO ("method ScanEMB does not support CaloSubdetNames::ALIGNVOL "
709 << (int) alvol);
710 return false;
711 }
712
713 // Shortcut :
715 {
716 mass = 6.06935e+06;
717 x0 = 91.1845;
718 dEdx = 1.14141e-23;
719 aveA = 58.9808;
720 aveZ = 26.8777;
721 }
722 else {
723
724 // Here we go :
725 m_child_massFractions.clear();
727 m_child_x0Fractions.clear();
728 m_child_dEdXFractions.clear();
731 m_child_Rho.clear();
732 m_child_Volume.clear();
733 m_child_Mass.clear();
734
735 double childVolume = 0.;
736 double childMass = 0.;
737 double childX0 = 0.;
738 double childDeDx = 0.;
739 double childAverageA = 0.;
740 double childAverageZ = 0.;
741 double childRho = 0.;
742
743 StoredPhysVol* storedPV = nullptr;
744 std::string key = map_av(alvol);
745 if(detStore()->contains<StoredPhysVol>(key))
746 {
747 if(detStore()->retrieve(storedPV,key)==StatusCode::FAILURE)
748 {
749 ATH_MSG_INFO ("Unable to retrieve Stored PV " << key);
750 }
751 }
752
753 if (!storedPV) {
754 ATH_MSG_INFO ("no Volume for " << key);
755 mass = 0.;
756 x0 = 0.;
757 dEdx = 0.;
758 aveA = 0.;
759 aveZ = 0.;
760 return false;
761 }
762
763 const GeoFullPhysVol* larTopVolLink = storedPV->getPhysVol();
764
765 // get the number of direct childs
766 unsigned int larChilds = larTopVolLink->getNChildVols();
767
768 for (unsigned int ichild = 0; ichild<larChilds; ++ichild){
769
770 bool stop = false;
771
772 // Skip some some of the children : list will get longer in future
773 //if ( alvol == CaloSubdetNames::LARCRYO_B &&
774 // larTopVolLink->getNameOfChildVol(ichild) == "Total LAR Volume") stop = true;
775
776 if (!stop) {
777
778 ATH_MSG_DEBUG ("CaloSubdetNames::ALIGNVOL " << (int) alvol
779 <<" Direct Child " << ichild << " - with name : "
780 << larTopVolLink->getNameOfChildVol(ichild));
781
782 PVConstLink childVolLink = larTopVolLink->getChildVol(ichild);
783
784 m_massFractions.clear();
785 m_volumeFractions.clear();
786 m_x0Fractions.clear();
787 m_dEdXFractions.clear();
788 m_averageAFractions.clear();
789 m_averageZFractions.clear();
790
791 this->blendGeoVolume(childVolLink,
798
805 childMass, childVolume,
806 childX0, childDeDx,
807 childAverageA, childAverageZ, childRho );
808
809 m_child_x0Fractions.push_back( childX0 );
810 m_child_dEdXFractions.push_back( childDeDx );
811 m_child_averageAFractions.push_back( childAverageA );
812 m_child_averageZFractions.push_back( childAverageZ );
813 m_child_Rho.push_back( childRho );
814 m_child_Volume.push_back( childVolume );
815 m_child_Mass.push_back( childMass );
816
817 }
818 }
819
820 // Now do the final average and store it :
821
822 ATH_MSG_DEBUG ("Final average for CaloSubdetNames::ALIGNVOL " << (int) alvol
823 << " !!!!! ");
824
830 childMass, childVolume,
831 childX0, childDeDx,
832 childAverageA, childAverageZ, childRho );
833
834 mass = childMass*(1./GeoModelKernelUnits::gram);
835 x0 = childX0;
836 dEdx = childDeDx;
837 aveA = childAverageA;
838 aveZ = childAverageZ;
839 }
840
841 m_alignvol_number.push_back( alvol );
842 m_alignvol_mass.push_back( mass );
843 m_alignvol_x0.push_back( x0 );
844 m_alignvol_dEdX.push_back( dEdx );
845 m_alignvol_aveA.push_back( aveA );
846 m_alignvol_aveZ.push_back( aveZ );
847
848 return true;
849}
850
851bool
853 double& mass, double& x0, double& dEdx,
854 double& aveA, double& aveZ)
855{
856 mass = 0.;
857 x0 = 0.;
858 dEdx = 0.;
859 aveA = 0.;
860 aveZ = 0.;
861
862 if ( alvol != CaloSubdetNames::FCAL1_POS &&
863 alvol != CaloSubdetNames::FCAL1_NEG &&
864 alvol != CaloSubdetNames::FCAL2_POS &&
865 alvol != CaloSubdetNames::FCAL2_NEG &&
866 alvol != CaloSubdetNames::FCAL3_POS &&
867 alvol != CaloSubdetNames::FCAL3_NEG ) {
868 ATH_MSG_INFO ("method ScanEMB does not support CaloSubdetNames::ALIGNVOL "
869 << (int) alvol);
870 return false;
871 }
872
873 // Shortcut :
875 {
877 mass = 47825.7;
878 x0 = 127.627;
879 dEdx = 4.36158e-24;
880 aveA = 42.5374;
881 aveZ = 19.2601;
882 }
883 else if (alvol == CaloSubdetNames::FCAL2_POS || alvol == CaloSubdetNames::FCAL2_NEG) {
884 mass = 1.77759e+06;
885 x0 = 81.6747;
886 dEdx = 1.9157e-23;
887 aveA = 159.937;
888 aveZ = 64.5724;
889 }
890 else if (alvol == CaloSubdetNames::FCAL3_POS || alvol == CaloSubdetNames::FCAL3_NEG) {
891 mass = 1.80016e+06;
892 x0 = 82.9447;
893 dEdx = 1.86512e-23;
894 aveA = 158.884;
895 aveZ = 64.1669;
896 }
897
898 }
899
900 else {
901
902 // Here we go :
903 m_child_massFractions.clear();
905 m_child_x0Fractions.clear();
906 m_child_dEdXFractions.clear();
909 m_child_Rho.clear();
910 m_child_Volume.clear();
911 m_child_Mass.clear();
912
913 double childVolume = 0.;
914 double childMass = 0.;
915 double childX0 = 0.;
916 double childDeDx = 0.;
917 double childAverageA = 0.;
918 double childAverageZ = 0.;
919 double childRho = 0.;
920
921 StoredPhysVol* storedPV = nullptr;
922 std::string key = map_av(alvol);
923 if(detStore()->contains<StoredPhysVol>(key))
924 {
925 if(detStore()->retrieve(storedPV,key)==StatusCode::FAILURE)
926 {
927 ATH_MSG_INFO ("Unable to retrieve Stored PV " << key);
928 }
929 }
930
931 if (!storedPV) {
932 ATH_MSG_INFO ("no Volume for " << key);
933 mass = 0.;
934 x0 = 0.;
935 dEdx = 0.;
936 aveA = 0.;
937 aveZ = 0.;
938 return false;
939 }
940
941 const GeoFullPhysVol* larTopVolLink = storedPV->getPhysVol();
942
943 // get the number of direct childs
944 unsigned int larChilds = larTopVolLink->getNChildVols();
945
946 for (unsigned int ichild = 0; ichild<larChilds; ++ichild){
947
948 bool stop = false;
949
950 // Skip some some of the children : list will get longer in future
951 //if ( alvol == CaloSubdetNames::LARCRYO_B &&
952 // larTopVolLink->getNameOfChildVol(ichild) == "Total LAR Volume") stop = true;
953
954 if (!stop) {
955
956 ATH_MSG_DEBUG ("CaloSubdetNames::ALIGNVOL " << (int) alvol
957 <<" Direct Child " << ichild << " - with name : "
958 << larTopVolLink->getNameOfChildVol(ichild));
959
960 PVConstLink childVolLink = larTopVolLink->getChildVol(ichild);
961
962 m_massFractions.clear();
963 m_volumeFractions.clear();
964 m_x0Fractions.clear();
965 m_dEdXFractions.clear();
966 m_averageAFractions.clear();
967 m_averageZFractions.clear();
968
969 this->blendGeoVolume(childVolLink,
976
983 childMass, childVolume,
984 childX0, childDeDx,
985 childAverageA, childAverageZ, childRho );
986
987 m_child_x0Fractions.push_back( childX0 );
988 m_child_dEdXFractions.push_back( childDeDx );
989 m_child_averageAFractions.push_back( childAverageA );
990 m_child_averageZFractions.push_back( childAverageZ );
991 m_child_Rho.push_back( childRho );
992 m_child_Volume.push_back( childVolume );
993 m_child_Mass.push_back( childMass );
994
995 }
996 }
997
998 // Now do the final average and store it :
999
1000 ATH_MSG_DEBUG ("Final average for CaloSubdetNames::ALIGNVOL " << (int) alvol
1001 << " !!!!! ");
1002
1008 childMass, childVolume,
1009 childX0, childDeDx,
1010 childAverageA, childAverageZ, childRho );
1011
1012 mass = childMass*(1./GeoModelKernelUnits::gram);
1013 x0 = childX0;
1014 dEdx = childDeDx;
1015 aveA = childAverageA;
1016 aveZ = childAverageZ;
1017 }
1018
1019 m_alignvol_number.push_back( alvol );
1020 m_alignvol_mass.push_back( mass );
1021 m_alignvol_x0.push_back( x0 );
1022 m_alignvol_dEdX.push_back( dEdx );
1023 m_alignvol_aveA.push_back( aveA );
1024 m_alignvol_aveZ.push_back( aveZ );
1025
1026 return true;
1027}
1028
1029void
1030LArRecoMaterialTool::blendGeoVolume(GeoPVConstLink& geoVolLink,
1031 std::vector<double>& volume,
1032 std::vector<double>& mass,
1033 std::vector<double>& x0,
1034 std::vector<double>& dEdX,
1035 std::vector<double>& aveA,
1036 std::vector<double>& aveZ) const
1037{
1038
1039 const GeoLogVol* currentVol = geoVolLink->getLogVol();
1040 if (currentVol){
1041 this->addMaterialFraction(*currentVol, volume, mass, x0, dEdX, aveA, aveZ);
1042 unsigned int currentVolChilds = geoVolLink->getNChildVols();
1043 for (unsigned int ichild = 0; ichild < currentVolChilds; ichild++){
1044 GeoPVConstLink childVolumeLink = geoVolLink->getChildVol(ichild);
1045 this->blendGeoVolume(childVolumeLink, volume, mass, x0, dEdX, aveA, aveZ);
1046 }
1047 }
1048}
1049
1050void
1052 std::vector<double>& volume,
1053 std::vector<double>& mass,
1054 std::vector<double>& x0,
1055 std::vector<double>& dEdX,
1056 std::vector<double>& aveA,
1057 std::vector<double>& aveZ) const
1058{
1059 const GeoShape* childShape = geoVol.getShape();
1060 const GeoMaterial* childMaterial = geoVol.getMaterial();
1061
1062 double childVolume = childShape->volume();
1063
1064 double childNumberOfElements = childMaterial->getNumElements();
1065 double childX0 = childMaterial->getRadLength ();
1066 double childDeDx = childMaterial->getDeDxMin();
1067 double childRho = childMaterial->getDensity();
1068
1069 ATH_MSG_DEBUG ("addMaterialFraction : " << geoVol.getName()
1070 << " has volume=" << childVolume << " mm**3 and "
1071 << childNumberOfElements << " elements ");
1072
1073 for (unsigned int iEl=0; iEl<childNumberOfElements; iEl++){
1074 const GeoElement* geoEl = childMaterial->getElement(iEl);
1075 double fraction = childMaterial->getFraction(iEl);
1076
1077 ATH_MSG_DEBUG (" direct child : " << geoEl->getName() << " fraction = " << fraction
1078 << " A= " << geoEl->getA()*(1./GeoModelKernelUnits::gram) << " Z= " << geoEl->getZ());
1079
1080 volume.push_back(fraction*childVolume);
1081 mass.push_back(fraction*childVolume*childRho);
1082 x0.push_back(fraction*childX0);
1083 dEdX.push_back(fraction*childDeDx);
1084 aveA.push_back(fraction*(geoEl->getA()*(1./GeoModelKernelUnits::gram)));
1085 aveZ.push_back(fraction*(geoEl->getZ()));
1086 }
1087
1088}
1089
1090void
1091LArRecoMaterialTool::averageFraction (std::vector<double>& volumeFractions,
1092 std::vector<double>& massFractions,
1093 std::vector<double>& x0Fractions,
1094 std::vector<double>& dEdXFractions,
1095 std::vector<double>& averageAFractions,
1096 std::vector<double>& averageZFractions,
1097 double& childMass, double& childVolume,
1098 double& childX0, double& childDeDx,
1099 double& childAverageA, double& childAverageZ, double& childRho )
1100{
1101 unsigned int parsedVolumes = massFractions.size();
1102 ATH_MSG_DEBUG (" averageFraction : will average over... "
1103 << parsedVolumes << " elements ");
1104
1105 childMass = 0.;
1106 childVolume = 0.;
1107 childX0 = 0.;
1108 childDeDx = 0.;
1109 childAverageA = 0.;
1110 childAverageZ = 0.;
1111 childRho = 0.;
1112
1113 for (unsigned int ivols = 0; ivols < parsedVolumes; ++ivols) {
1114 childMass += massFractions[ivols];
1115 childVolume += volumeFractions[ivols];
1116 }
1117
1118 for (unsigned int ivolfrac = 0; ivolfrac < parsedVolumes; ++ivolfrac){
1119 double volfrac = volumeFractions[ivolfrac]/childVolume;
1120 childX0 += volfrac * x0Fractions[ivolfrac];
1121 childDeDx += volfrac * dEdXFractions[ivolfrac];
1122 double massfrac = massFractions[ivolfrac]/childMass;
1123 childAverageA += massfrac * averageAFractions[ivolfrac];
1124 childAverageZ += massfrac * averageZFractions[ivolfrac];
1125 }
1126
1127 if (childVolume != 0) {
1128 childRho = childMass/(GeoModelKernelUnits::gram*childVolume);
1129 }
1130
1131 ATH_MSG_DEBUG ("");
1132 ATH_MSG_DEBUG (" + averaged over " << parsedVolumes << " volumes ");
1133 ATH_MSG_DEBUG (" - volume [mm^3] : " << childVolume);
1134 ATH_MSG_DEBUG (" - mass [gram] : " << childMass*(1./GeoModelKernelUnits::gram));
1135 ATH_MSG_DEBUG (" - rho [gram/mm^3] : " << childRho);
1136 ATH_MSG_DEBUG (" - X0 : " << childX0);
1137 ATH_MSG_DEBUG (" - DeDx : " << childDeDx);
1138 ATH_MSG_DEBUG (" - AverageA : " << childAverageA);
1139 ATH_MSG_DEBUG (" - AverageZ : " << childAverageZ);
1140 ATH_MSG_DEBUG ("");
1141
1142}
1143
1144std::string
1146{
1147 switch(alvol)
1148 {
1150 return std::string("LARCRYO_B");
1152 return std::string("LARCRYO_EC_POS");
1154 return std::string("LARCRYO_EC_NEG");
1156 return std::string("SOLENOID");
1158 return std::string("PRESAMPLER_B_POS");
1160 return std::string("PRESAMPLER_B_NEG");
1162 return std::string("EMB_POS");
1164 return std::string("EMB_NEG");
1166 return std::string("PRESAMPLER_EC_POS");
1168 return std::string("PRESAMPLER_EC_NEG");
1170 return std::string("EMEC_POS");
1172 return std::string("EMEC_NEG");
1174 return std::string("HEC1_POS");
1176 return std::string("HEC1_NEG");
1178 return std::string("HEC2_POS");
1180 return std::string("HEC2_NEG");
1182 return std::string("FCAL1_POS");
1184 return std::string("FCAL1_NEG");
1186 return std::string("FCAL2_POS");
1188 return std::string("FCAL2_NEG");
1190 return std::string("FCAL3_POS");
1192 return std::string("FCAL3_NEG");
1193 default:
1194 return std::string("");
1195 }
1196}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
ALIGNVOL
LAr Alignable volumes.
const CaloCell_ID * m_calo_id
LArRecoMaterialTool(const std::string &type, const std::string &name, const IInterface *parent)
std::vector< double > m_child_massFractions
void print() const override
virtual StatusCode initialize() override
std::vector< double > m_child_Volume
std::string map_av(CaloSubdetNames::ALIGNVOL alvol)
std::vector< double > m_alignvol_x0
std::vector< double > m_child_Rho
std::vector< double > m_alignvol_aveA
bool ScanHEC(CaloSubdetNames::ALIGNVOL alvol, double &mass, double &x0, double &dEdx, double &aveA, double &aveZ)
std::vector< double > m_child_averageAFractions
const CaloDM_ID * m_dm_id
std::vector< double > m_child_volumeFractions
std::vector< double > m_child_Mass
std::vector< double > m_dEdXFractions
std::vector< double > m_child_x0Fractions
std::vector< double > m_x0Fractions
bool ScanFCAL(CaloSubdetNames::ALIGNVOL alvol, double &mass, double &x0, double &dEdx, double &aveA, double &aveZ)
std::vector< double > m_child_averageZFractions
void ScanTree()
Private method called at initialisation : fills all arrays by calling the "optimised" methods.
bool ScanPS(CaloSubdetNames::ALIGNVOL alvol, double &mass, double &x0, double &dEdx, double &aveA, double &aveZ)
std::vector< double > m_child_dEdXFractions
std::vector< double > m_averageAFractions
std::vector< double > m_alignvol_dEdX
void addMaterialFraction(const GeoLogVol &geoVol, std::vector< double > &volume, std::vector< double > &mass, std::vector< double > &x0, std::vector< double > &dEdX, std::vector< double > &aveA, std::vector< double > &aveZ) const
Private method to add material.
std::vector< CaloSubdetNames::ALIGNVOL > m_alignvol_number
void averageFraction(std::vector< double > &volumeFractions, std::vector< double > &massFractions, std::vector< double > &x0Fractions, std::vector< double > &dEdXFractions, std::vector< double > &aveAFractions, std::vector< double > &aveZFractions, double &mass, double &volume, double &x0, double &dEdx, double &aveA, double &aveZ, double &rho)
Private method to average results stored in private arrays.
std::vector< double > m_volumeFractions
bool ScanEMB(CaloSubdetNames::ALIGNVOL alvol, double &mass, double &x0, double &dEdx, double &aveA, double &aveZ)
std::vector< double > m_massFractions
bool ScanEMEC(CaloSubdetNames::ALIGNVOL alvol, double &mass, double &x0, double &dEdx, double &aveA, double &aveZ)
std::vector< double > m_alignvol_aveZ
void blendGeoVolume(GeoPVConstLink &geoVolLink, std::vector< double > &volume, std::vector< double > &mass, std::vector< double > &x0, std::vector< double > &dEdX, std::vector< double > &aveA, std::vector< double > &aveZ) const
Private method to blend GeoLogVolume.
std::vector< double > m_averageZFractions
std::vector< double > m_alignvol_mass
virtual bool get_material(CaloSubdetNames::ALIGNVOL alvol, double &mass, double &volume, double &x0, double &dEdx, double &aveA, double &aveZ) const override
bool ScanCRYO(CaloSubdetNames::ALIGNVOL alvol, double &mass, double &x0, double &dEdx, double &aveA, double &aveZ)
Private optimised methods for each subsystem.
bool m_parseGeoModelForMaterial
Private bool set at initialisation : decides if the GeoModel is parsed or bypassed.
virtual void get_default_material(double &density, double &x0, double &dEdx, double &aveA, double &aveZ) const override
default material used to fill the envelope
GeoFullPhysVol * getPhysVol()
Destructor.
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:114