ATLAS Offline Software
TRTDetectorFactory_Full.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
8 
16 
18 #include "InDetIdentifier/TRT_ID.h"
19 
20 #include "ArrayFunction.h"
21 
25 
26 #include "GeoModelKernel/GeoTube.h"
27 #include "GeoModelKernel/GeoTrd.h"
28 #include "GeoModelKernel/GeoLogVol.h"
29 #include "GeoModelKernel/GeoNameTag.h"
30 #include "GeoModelKernel/GeoPhysVol.h"
31 #include "GeoModelKernel/GeoFullPhysVol.h"
32 #include "GeoModelKernel/GeoTransform.h"
33 #include "GeoModelKernel/GeoAlignableTransform.h"
34 #include "GeoModelKernel/GeoSerialDenominator.h"
35 #include "GeoModelKernel/GeoSerialTransformer.h"
36 #include "GeoModelKernel/GeoShapeShift.h"
37 #include "GeoModelKernel/GeoShapeUnion.h"
38 #include "GeoModelKernel/GeoIdentifierTag.h"
39 #include "GeoModelKernel/GeoSerialIdentifier.h"
40 #include "GeoModelKernel/GeoElement.h"
41 #include "GeoModelKernel/GeoMaterial.h"
42 #include "GeoModelKernel/GeoDefinitions.h"
43 #include "GeoModelKernel/Units.h"
44 
45 #include "GeoGenericFunctions/AbsFunction.h"
46 #include "GeoGenericFunctions/Variable.h"
47 #include "GeoGenericFunctions/Sin.h"
48 #include "GeoGenericFunctions/Cos.h"
49 
52 #include "StoreGate/StoreGateSvc.h"
53 
54 #include <vector>
55 #include <sstream>
56 #include <cmath>
57 
58 //TK: get rid of these and use GeoGenfun:: and GeoXF:: instead
59 using namespace GeoGenfun;
60 using namespace GeoXF;
61 
62 // Helper functions. Temporarily here (hopefully)
63 inline void rotate(double angler, GeoTrf::Vector2D& vector)
64 {
65  double s1 = std::sin(angler);
66  double c = std::cos(angler);
67  double xx = vector.x();
68  double yy = vector.y();
69  vector.x() = c*xx - s1*yy;
70  vector.y() = s1*xx + c*yy;
71 }
72 
73 inline double angle(const GeoTrf::Vector2D& a, const GeoTrf::Vector2D& b)
74 {
75  double ptot2 = a.mag2()*b.mag2();
76  return ptot2 <= 0.0 ? 0.0 : std::acos(a.dot(b)/std::sqrt(ptot2));
77 }
78 
79 inline double magn(GeoTrf::Vector2D& vector)
80 {
81  return std::sqrt(vector.x()*vector.x() + vector.y()*vector.y());
82 }
84 //
86  const ITRT_StrawStatusSummaryTool* sumTool, // added for Argon
87  bool useOldActiveGasMixture,
88  bool DC2CompatibleBarrelCoordinates,
89  int overridedigversion,
90  bool alignable,
91  bool doArgon,
92  bool doKrypton,
93  bool useDynamicAlignmentFolders)
94  : InDetDD::DetectorFactoryBase(athenaComps),
95  m_useOldActiveGasMixture(useOldActiveGasMixture),
96  m_DC2CompatibleBarrelCoordinates(DC2CompatibleBarrelCoordinates),
97  m_overridedigversion(overridedigversion),
98  m_alignable(alignable),
99  m_sumTool(sumTool),
100  m_strawsvcavailable(0),
101  m_doArgon(doArgon),
102  m_doKrypton(doKrypton),
103  m_useDynamicAlignFolders(useDynamicAlignmentFolders)
104 {
105 }
107 
108 
110 //
111 // The method that actually returns the TRT_DetectorManager, which was created
112 // and filled by the create() method
113 //
115 {
116  //TK: Maybe check that m_detectorManager!=0 ?
117  return m_detectorManager;
118 }
120 
121 
122 
124 //
125 // This is where the actual building of the geometry is performed.
126 //
127 // The purpose of this is to create a new TRT_DetectorManager and fill it with
128 // all the information relevant for detector description.
129 //
130 // The TRT_DetectorManager itself, along with helper classes, descriptors, etc.
131 // is located in InDetDetDescr/InDetReadoutGeometry.
132 //
133 void TRTDetectorFactory_Full::create(GeoPhysVol *world)
134 {
135  // Create a new detectormanager.
137 
138  //---------------------- Initialize the parameter interface ------------------------//
139 
140  ATH_MSG_DEBUG( " Getting primary numbers from the Detector Description Database " );
142  m_data.reset(parameterInterface);
143 
144  //---------------------- Initialize the InnerDetector material manager ------------------------//
145 
146  m_materialManager = std::make_unique<InDetMaterialManager>("TRT_MaterialManager", getAthenaComps());
147  m_materialManager->addScalingTable(parameterInterface->scalingTable());
148 
149  //---------------------- Check if the folder TRT/Cond/StatusHT is in place ------------------------//
150  m_strawsvcavailable = false;
151  if (m_doArgon || m_doKrypton){
152  m_strawsvcavailable = detStore()->contains<TRTCond::StrawStatusMultChanContainer>("/TRT/Cond/StatusHT") &&
153  m_sumTool->getStrawStatusHTContainer() != nullptr;
154  }
155  // --------------------- In a normal reconstruction or digitization job, the folder will not be available at this point. No reason for warnings here.
156  ATH_MSG_INFO( "The folder of /TRT/Cond/StatusHT is available? " << m_strawsvcavailable) ;
157  if (!m_strawsvcavailable) ATH_MSG_DEBUG("The folder of /TRT/Cond/StatusHT is NOT available, WHOLE TRT RUNNING XENON" );
158  if (!m_doArgon ) ATH_MSG_DEBUG("Tool setup will force to NOT to use ARGON. Ignore this warning if you are running RECONSTRUCTION or DIGI, but cross-check if you are running SIMULATION");
159  if (!m_doKrypton) ATH_MSG_DEBUG( "Tool setup will force to NOT to use KRYPTON. Ignore this warning if you are running RECONSTRUCTION or DIGI, but cross-check if you are running SIMULATION");
160 
161 
162  //---------------------- Initialize ID Helper ------------------------------------//
163 
164  // Initialize the ID helper:
165 // bool idHelperInitialized=false;
166 
167  const TRT_ID *idHelper = nullptr;
168 
169  if (detStore()->retrieve(idHelper, "TRT_ID").isFailure()) {
170  ATH_MSG_ERROR( "Could not retrieve TRT ID Helper");
171  }
172 
173  m_detectorManager->setIdHelper(idHelper,false);
174 
175  //---------------------- Set and Print Version Information ------------------------------------//
176 
177  //Set active gas type information.
180 
181  // Set Version information
182  // Some of these get overwritten for new configurations.
183  std::string versionTag = m_data->versionTag;
184  std::string versionName = "DC2";
185  std::string layout = "Final";
186  std::string description = "DC2 Geometry";
187  int versionMajorNumber = 2;
188  int versionMinorNumber = 1;
189  int versionPatchNumber = 0;
190 
191  if (m_data->initialLayout) layout = "Initial";
192  //In principle we dont need to let the minor number reflect the
193  //gastype anymore, but it doesn't hurt:
194  if (m_useOldActiveGasMixture) versionMinorNumber = 0;
196  versionMajorNumber = 3;
197  versionName = "Rome";
198  description = "Geometry for Rome 2005";
199  }
200 
201  if (m_data->isCosmicRun) {
202  layout = "SR1";
203  description = "Geometry for SR1";
204  }
205 
206 
207  // If new configuration we get the version information from the database.
208  // The version numbers can be incremented as one sees fit.
209  // In principle they should be changed whenever there are any code changes.
210  if (!m_data->oldConfiguration) {
211  versionName = m_data->versionName;
212  layout = m_data->layout;
213  description = m_data->versionDescription;
214  versionMajorNumber = 4;
215  versionMinorNumber = 1;
216  versionPatchNumber = 1;
217  }
218 
219  InDetDD::Version version(versionTag,
220  versionName,
221  layout,
222  description,
223  versionMajorNumber,
224  versionMinorNumber,
225  versionPatchNumber);
226 
228 
229 
230  // Print version information.
231  ATH_MSG_INFO( "In TRT Detector Factory (For DC2 and later geometries)" );
232  ATH_MSG_INFO( " " << version.fullDescription() );
233 
234 
235  //---------- Set flags for which parts of the detector are built -----------//
236 
237  std::string barrelLabel = "Barrel";
238  std::string endcapA_WheelAB_Label = "EndcapA_WheelAB";
239  std::string endcapC_WheelAB_Label = "EndcapC_WheelAB";
240  std::string endcapA_WheelC_Label = "EndcapA_WheelC";
241  std::string endcapC_WheelC_Label = "EndcapC_WheelC";
242 
243  // Check if old naming scheme (which was a bit confusing with endcap C label)
244  if (m_data->partPresent("EndcapAB_Plus")) {
245  barrelLabel = "Barrel";
246  endcapA_WheelAB_Label = "EndcapAB_Plus";
247  endcapC_WheelAB_Label = "EndcapAB_Minus";
248  endcapA_WheelC_Label = "EndcapC_Plus";
249  endcapC_WheelC_Label = "EndcapC_Minus";
250  }
251 
252 
253  bool barrelPresent = m_data->partPresent(barrelLabel);
254  bool endcapABPlusPresent = m_data->partPresent(endcapA_WheelAB_Label);
255  bool endcapABMinusPresent = m_data->partPresent(endcapC_WheelAB_Label);
256  bool endcapCPlusPresent = m_data->partPresent(endcapA_WheelC_Label);
257  bool endcapCMinusPresent = m_data->partPresent(endcapC_WheelC_Label);
258  // Overall transform (probably will always be identifty - but just in case)
259  GeoTrf::Transform3D trtTransform = m_data->partTransform("TRT");
260 
261  // For old configurations we need to set which parts are present.
262  //
263  if (m_data->oldConfiguration) {
264  if (m_data->isCosmicRun) {
265  endcapABPlusPresent = false;
266  endcapABMinusPresent = false;
267  endcapCPlusPresent = false;
268  endcapCMinusPresent = false;
269  }
270  if (m_data->initialLayout) {
271  endcapCPlusPresent = false;
272  endcapCMinusPresent = false;
273  }
274  }
275 
276 
277  //---------- Alignmnent and Conditions -----------//
278 
279 
280  // Register the channels for alignment constants
281  // and the level corresponding to the channel.
282  // Not the levels are an internal definition . They are not the same as
283  // the usual alignment levels
284  const int AlignmentLevelSubWheel = 1; // Level 2 in endcap. Not used in barrel
285  const int AlignmentLevelModule = 2; // Level 2 in barrel. Deprecated (wheel level) in endcap.
286  const int AlignmentLevelTop = 3; // Level 1
287 
288  if (m_alignable) {
289 
292  m_detectorManager->addFolder("/TRT/Align");
293  m_detectorManager->addChannel("/TRT/Align/TRT", AlignmentLevelTop, InDetDD::global);
294 
295  if (barrelPresent) {
296  m_detectorManager->addChannel("/TRT/Align/B0", AlignmentLevelModule, InDetDD::global);
297  m_detectorManager->addChannel("/TRT/Align/B1", AlignmentLevelModule, InDetDD::global);
298  m_detectorManager->addChannel("/TRT/Align/B2", AlignmentLevelModule, InDetDD::global);
299  }
300  if (endcapABPlusPresent) { // EndcapA
301  m_detectorManager->addChannel("/TRT/Align/L2A", AlignmentLevelSubWheel, InDetDD::global);
302  }
303  if (endcapABMinusPresent) {// EndcapC
304  m_detectorManager->addChannel("/TRT/Align/L2C", AlignmentLevelSubWheel, InDetDD::global);
305  }
306  }
307 
308  else {
310 
311  m_detectorManager->addGlobalFolder("/TRT/AlignL1/TRT");
312  m_detectorManager->addChannel("/TRT/AlignL1/TRT", AlignmentLevelTop, InDetDD::global);
313  m_detectorManager->addFolder("/TRT/AlignL2");
314 
315  if (barrelPresent) {
316  m_detectorManager->addChannel("/TRT/AlignL2/B0", AlignmentLevelModule, InDetDD::global);
317  m_detectorManager->addChannel("/TRT/AlignL2/B1", AlignmentLevelModule, InDetDD::global);
318  m_detectorManager->addChannel("/TRT/AlignL2/B2", AlignmentLevelModule, InDetDD::global);
319  }
320 
321  if (endcapABPlusPresent) { // EndcapA
322  m_detectorManager->addChannel("/TRT/AlignL2/L2A", AlignmentLevelSubWheel, InDetDD::global);
323  }
324  if (endcapABMinusPresent) {// EndcapC
325  m_detectorManager->addChannel("/TRT/AlignL2/L2C", AlignmentLevelSubWheel, InDetDD::global);
326  }
327  }
328 
329  // Unchanged in Run1 and new Run2 schema
330  m_detectorManager->addSpecialFolder("/TRT/Calib/DX");
331  }
332 
333 
334 
335  //Uncomment for testing:
336  // m_data->ShowValues();
337 
338  //---------- Digitization Version Info for dig. and recon r-t -----------//
339  if (m_overridedigversion < 0 ) {
340  m_detectorManager->setDigitizationVersion(m_data->digversion,m_data->digversionname);
341  } else {
343  ATH_MSG_INFO( "Digversion overridden via joboptions from "
344  << m_data->digversion << " ('" << m_data->digversionname << "') to "
347  }
348 
349 
350  //----------------------Initialize the numerology------------------------//
351 
352  for (unsigned int m=0;m<m_data->nBarrelRings;m++) {
353  m_detectorManager->getNumerology()->setNBarrelLayers(m, m_data->barrelNumberOfStrawLayersInModule[m]);
354  }
355 
357  //Note: This next line is now consistent with TRT_TestBeamDetDescr.
358  m_detectorManager->getNumerology()->setNBarrelPhi(m_data->nBarrelModulesUsed);
359 
360  unsigned int nEndcapWheels = 0;
361  if (endcapABPlusPresent||endcapABMinusPresent) nEndcapWheels += m_data->endcapNumberOfAWheels + m_data->endcapNumberOfBWheels;
362  if (endcapCPlusPresent||endcapCMinusPresent) nEndcapWheels += m_data->endcapNumberOfCWheels;
363 
366 
367  for (unsigned int w=0;w<m_detectorManager->getNumerology()->getNEndcapWheels();w++) {
368  unsigned int nlayers;
369  if ( w < m_data->endcapNumberOfAWheels )
370  nlayers = m_data->endCapNumberOfStrawLayersPerWheelA;
371  else if ( w < ( m_data->endcapNumberOfAWheels + m_data->endcapNumberOfBWheels ) )
372  nlayers = m_data->endCapNumberOfStrawLayersPerWheelB;
373  else
374  nlayers = m_data->endCapNumberOfStrawLayersPerWheelC;
376  }
377 
378  //---------------------- Top level volumes ------------------------//
379 
380  GeoNodePtr<GeoNameTag> topLevelNameTag(new GeoNameTag("TRT"));
381  // The top level volumes
382  GeoFullPhysVol *pBarrelVol = nullptr;
383  GeoFullPhysVol *pEndCapABPlus = nullptr;
384  GeoFullPhysVol *pEndCapCPlus = nullptr;
385  GeoFullPhysVol *pEndCapABMinus = nullptr;
386  GeoFullPhysVol *pEndCapCMinus = nullptr;
387 
388 
389 
390  //
391  // Barrel volume:
392  //
393 
394  if (barrelPresent) {
395  GeoTube* sBarrelVol = new GeoTube( m_data->virtualBarrelInnerRadius,
396  m_data->virtualBarrelOuterRadius,
397  m_data->virtualBarrelVolumeLength );
398 
399 
400  GeoLogVol *lBarrelVol = new GeoLogVol("TRTBarrel", sBarrelVol, m_materialManager->getMaterial("trt::CO2"));
401  pBarrelVol = new GeoFullPhysVol(lBarrelVol);
402 
403  ATH_MSG_DEBUG( "Virtual TRT Barrel volume defined by RMin = "<<m_data->virtualBarrelInnerRadius
404  <<", Rmax = "<<m_data->virtualBarrelOuterRadius<<" Zmax = "<<m_data->virtualBarrelVolumeLength );
405 
406  // Common Endcap volumes (one for forward, one for backward):
407  //GeoPhysVol *pCommonEndcapVolume[2];
408 
409  GeoAlignableTransform * barrelTransform =
410  new GeoAlignableTransform(trtTransform * m_data->partTransform(barrelLabel));
411 
412  world->add(topLevelNameTag);
413  world->add(barrelTransform);
414  world->add(pBarrelVol);
415  m_detectorManager->addTreeTop(pBarrelVol);
416  // Use barrel_ec_id = -1 (+ve and -ve barrel is treated as one alignable object)
417  Identifier id = idHelper->barrel_ec_id(-1);
418  m_detectorManager->addAlignableTransform(AlignmentLevelTop, id, barrelTransform, pBarrelVol); // global if other selected
419 
420  }
421 
422  //
423  // End-cap volume AB:
424  //
425  GeoLogVol * lEndCapVolumeAB = nullptr;
426  if (endcapABPlusPresent || endcapABMinusPresent) {
427  GeoTube * sEndCapVolumeAB_unshifted = new GeoTube (m_data->innerRadiusOfEndCapVolumeAB,
428  m_data->outerRadiusOfEndCapVolumeAB,
429  m_data->lengthOfEndCapVolumeAB/2.);
430  const GeoShape & sEndCapVolumeAB
431  = ( *sEndCapVolumeAB_unshifted << GeoTrf::TranslateZ3D(m_data->positionOfEndCapVolumeAB));
432 
433  lEndCapVolumeAB = new GeoLogVol("TRTEndcapWheelAB", &sEndCapVolumeAB, m_materialManager->getMaterial("trt::CO2"));
434  }
435 
436  if (endcapABPlusPresent) {
437  pEndCapABPlus = new GeoFullPhysVol(lEndCapVolumeAB);
438 
439  GeoAlignableTransform * transform =
440  new GeoAlignableTransform(trtTransform * m_data->partTransform(endcapA_WheelAB_Label));
441 
442  world->add(topLevelNameTag);
443  world->add(transform);
444  world->add(new GeoIdentifierTag(0));
445  world->add(pEndCapABPlus);
446  m_detectorManager->addTreeTop(pEndCapABPlus);
447  Identifier id = idHelper->barrel_ec_id(2);
448  m_detectorManager->addAlignableTransform(AlignmentLevelTop, id, transform, pEndCapABPlus); // global if other selected
449  }
450 
451  if (endcapABMinusPresent) {
452  pEndCapABMinus = new GeoFullPhysVol(lEndCapVolumeAB);
453 
454  GeoAlignableTransform * transform =
455  new GeoAlignableTransform(trtTransform * m_data->partTransform(endcapC_WheelAB_Label) * GeoTrf::RotateY3D(180*GeoModelKernelUnits::deg));
456 
457  world->add(topLevelNameTag);
458  world->add(transform);
459  world->add(new GeoIdentifierTag(1));
460  world->add(pEndCapABMinus);
461  m_detectorManager->addTreeTop(pEndCapABMinus);
462  Identifier id = idHelper->barrel_ec_id(-2);
463  m_detectorManager->addAlignableTransform(AlignmentLevelTop, id, transform, pEndCapABMinus); // global if other selected
464  }
465 
466  //
467  // End-cap volume C:
468  //
469  GeoLogVol * lEndCapVolumeC = nullptr;
470  if (endcapCPlusPresent || endcapCMinusPresent) {
471  GeoTube * sEndCapVolumeC_unshifted = new GeoTube (m_data->innerRadiusOfEndCapVolumeC,
472  m_data->outerRadiusOfEndCapVolumeC,
473  m_data->lengthOfEndCapVolumeC/2.);
474  const GeoShape & sEndCapVolumeC
475  = ( *sEndCapVolumeC_unshifted << GeoTrf::TranslateZ3D(m_data->positionOfEndCapVolumeC));
476 
477  lEndCapVolumeC = new GeoLogVol("TRTEndcapWheelC", &sEndCapVolumeC, m_materialManager->getMaterial("trt::CO2"));
478  }
479 
480  if (endcapCPlusPresent) {
481  pEndCapCPlus = new GeoFullPhysVol(lEndCapVolumeC);
482 
483  GeoAlignableTransform * transform =
484  new GeoAlignableTransform(trtTransform * m_data->partTransform(endcapA_WheelC_Label));
485 
486  world->add(topLevelNameTag);
487  world->add(transform);
488  world->add(new GeoIdentifierTag(0));
489  world->add(pEndCapCPlus);
490  m_detectorManager->addTreeTop(pEndCapCPlus);
491  }
492 
493  if (endcapCMinusPresent) {
494  pEndCapCMinus = new GeoFullPhysVol(lEndCapVolumeC);
495 
496  GeoAlignableTransform * transform =
497  new GeoAlignableTransform(trtTransform * m_data->partTransform(endcapC_WheelC_Label) * GeoTrf::RotateY3D(180*GeoModelKernelUnits::deg));
498 
499  world->add(topLevelNameTag);
500  world->add(transform);
501  world->add(new GeoIdentifierTag(0));
502  world->add(pEndCapCMinus);
503  m_detectorManager->addTreeTop(pEndCapCMinus);
504  }
505 
506  // Pointers to the Endcap volumes (index 0: for forward, index 1: for backward):
507  GeoFullPhysVol *pCommonEndcapAB[2];
508  GeoFullPhysVol *pCommonEndcapC[2];
509 
510  pCommonEndcapAB[0] = pEndCapABPlus;
511  pCommonEndcapAB[1] = pEndCapABMinus;
512  pCommonEndcapC[0] = pEndCapCPlus;
513  pCommonEndcapC[1] = pEndCapCMinus;
514 
515 
516  //-----------------------------------------------------------------------//
517  // //
518  // Extra Material //
519  // //
520  //-----------------------------------------------------------------------//
521  if (pBarrelVol) {
522  InDetDD::ExtraMaterial xMat(m_data->distortedMatManager());
523  xMat.add(pBarrelVol, "TRTBarrel");
524  }
525  if (pEndCapABPlus) {
526  InDetDD::ExtraMaterial xMat(m_data->distortedMatManager());
527  xMat.add(pEndCapABPlus, "TRTEndcap");
528  xMat.add(pEndCapABPlus, "TRTEndcapA");
529  }
530  if (pEndCapABMinus) {
531  InDetDD::ExtraMaterial xMat(m_data->distortedMatManager());
532  xMat.add(pEndCapABMinus, "TRTEndcap");
533  xMat.add(pEndCapABMinus, "TRTEndcapC");
534  }
535 
536  // Just for completeness
537  if (pEndCapCPlus) {
538  InDetDD::ExtraMaterial xMat(m_data->distortedMatManager());
539  xMat.add(pEndCapCPlus, "TRTEndcap_WheelC");
540  xMat.add(pEndCapCPlus, "TRTEndcapA_WheelC");
541  }
542  if (pEndCapCMinus) {
543  InDetDD::ExtraMaterial xMat(m_data->distortedMatManager());
544  xMat.add(pEndCapCMinus, "TRTEndcap_WheelC");
545  xMat.add(pEndCapCMinus, "TRTEndcapC_WheelC");
546  }
547 
548 
549 
550  //-----------------------------------------------------------------------//
551  // //
552  // Barrel //
553  // //
554  //-----------------------------------------------------------------------//
555 
556 
557  if (pBarrelVol) {
558  //-----------------------------------------------------------------------//
559  // //
560  // Barrel Outer and Inner Supports //
561  // //
562  //-----------------------------------------------------------------------//
563  // Barrel inner support:
564  GeoTube *sBarrelInnerSupport = new GeoTube(m_data->innerRadiusOfBarrelVolume,
565  m_data->innerRadiusOfBarrelVolume + m_data->thicknessOfBarrelInnerSupport,
566  m_data->lengthOfBarrelVolume/2);
567 
568  //ugly, but necessary check due to changes in database.
569  GeoLogVol *lBarrelInnerSupport = new GeoLogVol("BarrelInnerSupport", sBarrelInnerSupport,
570  m_materialManager->getMaterial("trt::BarrelInnerSupport") ?
571  m_materialManager->getMaterial("trt::BarrelInnerSupport") :
572  m_materialManager->getMaterial("trt::BarrelSupport") );
573 
574 
575  GeoPhysVol *pBarrelInnerSupport = new GeoPhysVol(lBarrelInnerSupport);
576  pBarrelVol->add(pBarrelInnerSupport);
577 
578  // Barrel outer support:
579  GeoTube *sBarrelOuterSupport = new GeoTube(m_data->outerRadiusOfBarrelVolume - m_data->thicknessOfBarrelOuterSupport,
580  m_data->outerRadiusOfBarrelVolume, m_data->lengthOfBarrelVolume/2);
581 
582  GeoLogVol *lBarrelOuterSupport = new GeoLogVol("BarrelOuterSupport", sBarrelOuterSupport,
583  m_materialManager->getMaterial("trt::BarrelOuterSupport") ?
584  m_materialManager->getMaterial("trt::BarrelOuterSupport") :
585  m_materialManager->getMaterial("trt::BarrelSupport") );
586 
587 
588  GeoPhysVol *pBarrelOuterSupport = new GeoPhysVol(lBarrelOuterSupport);
589  pBarrelVol->add(pBarrelOuterSupport);
590 
591 
592 
593  if (m_data->includeBarServiceAndFlange) {
594 
595  //-----------------------------------------------------------------------//
596  // //
597  // Barrel End Flange region //
598  // //
599  //-----------------------------------------------------------------------//
600 
601 
602  GeoTube *sEndFlangeRegion = new GeoTube(m_data->barFlangeRMin, m_data->barFlangeRMax,
603  (m_data->barFlangeZMax - m_data->barFlangeZMin)/2);
604  GeoLogVol *lEndFlangeRegion = new GeoLogVol("EndFlangeRegion", sEndFlangeRegion,
605  m_materialManager->getMaterial("trt::EndFlangeRegion") );
606 
607  GeoPhysVol *pEndFlangeRegion = new GeoPhysVol(lEndFlangeRegion);
608 
609  double zPosEndFlange = (m_data->barFlangeZMin+m_data->barFlangeZMax)/2;
610  GeoTransform *xfEndFlangeRegionPlus = new GeoTransform(GeoTrf::TranslateZ3D(zPosEndFlange));
611  GeoTransform *xfEndFlangeRegionMinus = new GeoTransform(GeoTrf::TranslateZ3D(-zPosEndFlange));
612 
613  pBarrelVol->add(xfEndFlangeRegionPlus);
614  pBarrelVol->add(pEndFlangeRegion);
615  pBarrelVol->add(xfEndFlangeRegionMinus);
616  pBarrelVol->add(pEndFlangeRegion);
617 
618 
619  //-----------------------------------------------------------------------//
620  // //
621  // Barrel service region //
622  // //
623  //-----------------------------------------------------------------------//
624 
625  GeoTube *sServices = new GeoTube(m_data->barServicesRMin, m_data->barServicesRMax,
626  (m_data->barServicesZMax - m_data->barServicesZMin)/2);
627  GeoLogVol *lServices = new GeoLogVol("Services", sServices,
628  m_materialManager->getMaterial("trt::Services") );
629 
630  GeoPhysVol *pServices = new GeoPhysVol(lServices);
631 
632  double zPosServices = (m_data->barServicesZMin+m_data->barServicesZMax)/2;
633  GeoTransform *xfServicesPlus = new GeoTransform(GeoTrf::TranslateZ3D(zPosServices));
634  GeoTransform *xfServicesMinus = new GeoTransform(GeoTrf::TranslateZ3D(-zPosServices));
635 
636  pBarrelVol->add(xfServicesPlus);
637  pBarrelVol->add(pServices);
638  pBarrelVol->add(xfServicesMinus);
639  pBarrelVol->add(pServices);
640 
641  }
642 
643 
644 
645  //-----------------------------------------------------------------------//
646  // //
647  // Barrel Modules //
648  // //
649  //-----------------------------------------------------------------------//
650 
651  std::vector<InDetDD::TRT_BarrelDescriptor *> bDescriptor;
652 
653  // Create some shared stuff to stick into each module.
654 
655  // The cooling tube:
656  GeoTube *sCoolingTube = new GeoTube(0, m_data->barrelOuterRadiusOfCoolingTube, m_data->lengthOfBarrelVolume/2.0);
657  GeoLogVol *lCoolingTube = new GeoLogVol("CoolingTube",sCoolingTube,m_materialManager->getMaterial("trt::CoolingTube"));
658  GeoPhysVol *pCoolingTube = new GeoPhysVol(lCoolingTube);
659 
660  GeoTube *sCoolingFluid = new GeoTube(0, m_data->barrelInnerRadiusOfCoolingTube, m_data->lengthOfBarrelVolume/2.0);
661  GeoLogVol *lCoolingFluid = new GeoLogVol("CoolingFluid",sCoolingFluid,m_materialManager->getMaterial("trt::CoolingFluid"));
662  GeoPhysVol*pCoolingFluid = new GeoPhysVol(lCoolingFluid);
663 
664  pCoolingTube->add(pCoolingFluid);
665 
666  double lengthOfInnerDeadRegion= m_data->lengthOfDeadRegion;
667  double lengthOfActiveGas = (m_data->barrelLengthOfStraw-m_data->barrelLengthOfTwister)/2.0 - m_data->lengthOfDeadRegion - lengthOfInnerDeadRegion;
668  double activeGasZPositionNormalStraws = (lengthOfActiveGas + m_data->barrelLengthOfTwister) / 2. + lengthOfInnerDeadRegion;
669 
670  lengthOfInnerDeadRegion = m_data->barrelLengthOfLargeDeadRegion;
671  lengthOfActiveGas = (m_data->barrelLengthOfStraw-m_data->barrelLengthOfTwister)/2.0 - m_data->lengthOfDeadRegion - lengthOfInnerDeadRegion;
672  double activeGasZPositionStrawsWithLargeDeadRegion = (lengthOfActiveGas + m_data->barrelLengthOfTwister) / 2. + lengthOfInnerDeadRegion;
673 
674  // The modules themselves.
675  for (size_t iABC=0;iABC<m_data->nBarrelRings;iABC++) {
676 
677  // Create a shape for the modules of each layer (shell)
678  // STS: Initialize raditator and shell LogVol
679  GeoLogVol *lRad = nullptr;
680  GeoLogVol *lShell = nullptr;
681 
682  // The shell volume:
683  std::ostringstream shellstream;
684  shellstream << "Shell" << iABC;
685  GeoTrf::Vector2D shellCorner1(m_data->shellCornerXPosition[iABC][0],m_data->shellCornerYPosition[iABC][0]);
686  GeoTrf::Vector2D shellCorner2(m_data->shellCornerXPosition[iABC][1],m_data->shellCornerYPosition[iABC][1]);
687  GeoTrf::Vector2D shellCorner3(m_data->shellCornerXPosition[iABC][2],m_data->shellCornerYPosition[iABC][2]);
688  GeoTrf::Vector2D shellCorner4(m_data->shellCornerXPosition[iABC][3],m_data->shellCornerYPosition[iABC][3]);
689  GeoTrf::Transform3D shellPosition(GeoTrf::Transform3D::Identity());
690  if ( shellCorner1.y() <= 0 ) { ATH_MSG_DEBUG( "shellCorner1 is <= 0 (" << shellCorner1 << ")"); }
691  if ( shellCorner2.y() <= 0 ) { ATH_MSG_DEBUG( "shellCorner2 is <= 0 (" << shellCorner2 << ")"); }
692  if ( shellCorner3.y() <= 0 ) { ATH_MSG_DEBUG( "shellCorner3 is <= 0 (" << shellCorner3 << ")" ); }
693  if ( shellCorner4.y() <= 0 ) { ATH_MSG_DEBUG( "shellCorner4 is <= 0 (" << shellCorner4 << ")"); }
694  const GeoShape * sShell = makeModule(m_data->lengthOfBarrelVolume,
695  shellCorner1,shellCorner2,shellCorner3,shellCorner4,shellPosition);
696 
697  // STS: We have three different shellmodules and radiators densities.
698  std::ostringstream layerstr;
699  layerstr << iABC;
700 
701  std::string shellMatName = "trt::ModuleShell"+layerstr.str();
702  std::string shellName = "ModuleShell"+layerstr.str();
703 
704  const GeoMaterial * shellMat = m_materialManager->getMaterial(shellMatName);
705  if (!shellMat) shellMat = m_materialManager->getMaterial("trt::ModuleShell");
706  lShell = new GeoLogVol(shellName, sShell, shellMat);
707 
708  //---------------------------------------------------------------------------------------------------------------
709  // Some shared stuff for all of the modules within a layer:
710 
711  // Make a Radiator
712  GeoTrf::Transform3D radAbsolutePosition(GeoTrf::Transform3D::Identity());
713  const GeoShape * sRad = makeModule(m_data->lengthOfBarrelVolume,
714  shellCorner1,shellCorner2,shellCorner3,shellCorner4,
715  radAbsolutePosition,m_data->barrelThicknessOfModuleWalls);
716 
717  // FibreRadiator will have three different densities for each type of module
718  std::string radMatName = "trt::FibreRadiator"+layerstr.str();
719  std::string radName = "FibreRadiator"+layerstr.str();
720 
721  const GeoMaterial * radMat = m_materialManager->getMaterial(radMatName);
722  if (!radMat) radMat = m_materialManager->getMaterial("trt::FibreRadiator");
723 
724  lRad = new GeoLogVol(radName, sRad, radMat);
725 
726  //---------------------------------------------------------------------------------------------------------------
727  // Place the cooling tubes in the Radiator
728  GeoTransform *xCool1 = new GeoTransform(shellPosition.inverse()
729  *GeoTrf::Translate3D(m_data->barrelXOfCoolingTube[iABC][0],m_data->barrelYOfCoolingTube[iABC][0],0));
730  GeoTransform *xCool2 = new GeoTransform(shellPosition.inverse()
731  *GeoTrf::Translate3D(m_data->barrelXOfCoolingTube[iABC][1],m_data->barrelYOfCoolingTube[iABC][1],0));
732 
733  //----------------------------------------------------------------------------------------------------------------
734  // Parameterize all of the straws and put them within the radiator.
735 
736  // Figure out how many straws have a large dead region
737  size_t nStrawsWithLargeDeadRegion = 0;
738  if (iABC==0) {
739  for (size_t iLayer = 0; iLayer<m_data->barrelNumberOfLayersWithLargeDeadRegion; iLayer++) {
740  nStrawsWithLargeDeadRegion += m_data->barrelNumberOfStrawsInStrawLayer[iABC][iLayer];
741  }
742  }
743 
744  // Generators:
745  GeoTrf::TranslateX3D Xx(1.0);
746  GeoTrf::TranslateY3D Xy(1.0);
747 
748  GENFUNCTION fx = ArrayFunction(&m_data->strawXPosition[iABC][0+nStrawsWithLargeDeadRegion],
749  &m_data->strawXPosition[iABC][0]+m_data->barrelNumberOfStrawsInModule[iABC]);
750  //TK: why ..[0]+n and not ..[n] ?
751  GENFUNCTION fy = ArrayFunction(&m_data->strawYPosition[iABC][0+nStrawsWithLargeDeadRegion],
752  &m_data->strawYPosition[iABC][0]+m_data->barrelNumberOfStrawsInModule[iABC]);
753  TRANSFUNCTION tx1 = Pow(Xx,fx)*Pow(Xy,fy);
754 
755  //Functions for straw with large dead regions
756  GENFUNCTION fxDead = ArrayFunction(&m_data->strawXPosition[iABC][0], &m_data->strawXPosition[iABC][0+nStrawsWithLargeDeadRegion]);
757  GENFUNCTION fyDead = ArrayFunction(&m_data->strawYPosition[iABC][0], &m_data->strawYPosition[iABC][0+nStrawsWithLargeDeadRegion]);
758  TRANSFUNCTION tx1Dead = Pow(Xx,fxDead)*Pow(Xy,fyDead);
759 
760  //TK: Quick fix, might waste a few KB of memory.
761  //TK: only use when iABC==0
762  GENFUNCTION fxAll = ArrayFunction(&m_data->strawXPosition[iABC][0], &m_data->strawXPosition[iABC][0]+m_data->barrelNumberOfStrawsInModule[iABC]);
763  GENFUNCTION fyAll = ArrayFunction(&m_data->strawYPosition[iABC][0], &m_data->strawYPosition[iABC][0]+m_data->barrelNumberOfStrawsInModule[iABC]);
764  TRANSFUNCTION tx1All = Pow(Xx,fxAll)*Pow(Xy,fyAll);
765 
766 
768  //Calculation of needed transforms
769  //First get the global and local positions of the two alignment straws:
770  //USE HEP2VECTORS!!!
771 
772  GeoTrf::Vector3D Align1Global(m_data->barrelXOfFirstGlobalAlignmentStraw[iABC], m_data->barrelYOfFirstGlobalAlignmentStraw[iABC], 0);
773  GeoTrf::Vector3D Align2Global(m_data->barrelXOfSecondGlobalAlignmentStraw[iABC], m_data->barrelYOfSecondGlobalAlignmentStraw[iABC],0);
774  GeoTrf::Vector3D Align1Local(m_data->strawXPosition[iABC][0],m_data->strawYPosition[iABC][0],0);
775  GeoTrf::Vector3D Align2Local(m_data->strawXPosition[iABC][m_data->barrelIndexOfSecondGlobalAlignmentStraw[iABC]],
776  m_data->strawYPosition[iABC][m_data->barrelIndexOfSecondGlobalAlignmentStraw[iABC]],0);
777 
778  //We need to make first a translation which puts the first alignment straw into place:
779 
780  //And we need to make a rotation which puts the second one on its position:
781 
782  GeoTrf::Vector2D local12((Align2Local - Align1Local).x(),(Align2Local - Align1Local).y());
783  GeoTrf::Vector2D global12((Align2Global - Align1Global).x(),(Align2Global - Align1Global).y());
784  double zrotang = global12.phi()-local12.phi();
785 
786  //Here we combine these two into a GeoTrf::Transform3D:
787 
788  GeoTrf::Transform3D absStrawXForm = GeoTrf::Translate3D(Align1Global.x(),Align1Global.y(),Align1Global.z())
789  *GeoTrf::RotateZ3D( zrotang )
790  *GeoTrf::Translate3D(-Align1Local.x(),-Align1Local.y(),-Align1Local.z());
791 
792  //
794 
795  //Why not use radiator instead of shell?
796  TRANSFUNCTION tx2=shellPosition.inverse()*absStrawXForm*tx1;
797  TRANSFUNCTION tx2Dead=shellPosition.inverse()*absStrawXForm*tx1Dead;
798  TRANSFUNCTION tx2All=shellPosition.inverse()*absStrawXForm*tx1All;
799  if (iABC==0) {
800  //TK: move rest of ...All stuff here?
801  m_detectorManager->setBarrelTransformField(iABC,tx2All.clone());
802  } else {
803  m_detectorManager->setBarrelTransformField(iABC,tx2.clone());
804  }
805 
806  // Adds one straw from each layer (reformulate..) (should be done via m_data from database)
807  double oldx=-999*GeoModelKernelUnits::cm, oldz=-999*GeoModelKernelUnits::cm;
808  unsigned int c=0;
809  size_t iLayer=0;
810  while (c< m_data->barrelNumberOfStrawsInModule[iABC] ) {
811 
812  GeoTrf::Vector3D p(0,0,0);
813  if (iABC==0)
814  p = tx2All(c)*p;
815  else
816  p = tx2(c)*p;
817 
818  double x = p.x();
819  double z = p.z();
820 
821  //TK: use arrays!! update this...
822  if (sqrt((x-oldx)*(x-oldx)+ (z-oldz)*(z-oldz))> 5*GeoModelKernelUnits::cm) {
823  iLayer++;
824  bDescriptor.push_back(new InDetDD::TRT_BarrelDescriptor());
825  m_detectorManager->setBarrelDescriptor(bDescriptor.back());
826  bDescriptor.back()->setStrawTransformField(m_detectorManager->barrelTransformField(iABC),c);
827 
828  //TK: Next, we are providing information about the Z
829  //dimensions of the active gas, to be used for reconstruction
830  //purposes. Personally I find "strawZDead" to be a slightly
831  //confusing choice of name for that method.
832 
833  if((iABC==0)&&(iLayer<=m_data->barrelNumberOfLayersWithLargeDeadRegion )) {
834  //TK: these things should come back from makestraw...
835  double lengthOfActiveGas=
836  (m_data->barrelLengthOfStraw-m_data->barrelLengthOfTwister)/2.0 - m_data->lengthOfDeadRegion-m_data->barrelLengthOfLargeDeadRegion;
837  double startZOfActiveGas=activeGasZPositionStrawsWithLargeDeadRegion-lengthOfActiveGas/2.0;
838  bDescriptor.back()->strawZPos(activeGasZPositionStrawsWithLargeDeadRegion);
839  bDescriptor.back()->strawZDead(startZOfActiveGas);
840  bDescriptor.back()->strawLength(lengthOfActiveGas);
841  } else {
842  double lengthOfActiveGas=(m_data->barrelLengthOfStraw-m_data->barrelLengthOfTwister)/2.0 - 2*m_data->lengthOfDeadRegion;
843  double startZOfActiveGas=activeGasZPositionNormalStraws-lengthOfActiveGas/2.0;
844  bDescriptor.back()->strawZPos(activeGasZPositionNormalStraws);
845  bDescriptor.back()->strawZDead(startZOfActiveGas);
846  bDescriptor.back()->strawLength(lengthOfActiveGas);
847  }
848 
849  }
850  bDescriptor.back()->addStraw(z,x);
851  oldx=x; oldz=z;
852  c++;
853 
854  }
855 
856 
857 
858  // Now create m_data->nBarrelModulesUsed unique modules within each layer.
859  pBarrelVol->add(new GeoSerialIdentifier(0));
860  for (size_t iMod = 0; iMod<m_data->nBarrelModulesUsed;iMod++) {
861  double delta = iMod*360*GeoModelKernelUnits::deg/m_data->nBarrelModules;
862 
863 
864 
865 
866  GeoFullPhysVol * pShell = new GeoFullPhysVol(lShell);
867 
868  // This is where the shell is pushed out to its place
869  //GeoTransform * xfx1 = new GeoTransform(GeoTrf::RotateZ3D(delta)*shellPosition);
870  GeoAlignableTransform * xfx1 = new GeoAlignableTransform(GeoTrf::RotateZ3D(delta)*shellPosition);
871  pBarrelVol->add(xfx1);
872  pBarrelVol->add(pShell);
873 
874  // Register the alignable transfrom to the manager
875  // +ve and -ve are part of the same barrel. We use barrel_ec = -1.
876  Identifier idModule = idHelper->module_id(-1, iMod, iABC);
877  // In barrel frame (generally the same as the global frame)
878  m_detectorManager->addAlignableTransform(AlignmentLevelModule, idModule, xfx1, pShell, pBarrelVol);
879 
880  // Add the substructure here:
881  pShell->add(new GeoIdentifierTag(iABC));
882  Identifier TRT_Identifier = idHelper->straw_id(1, iMod, iABC, 1, 1);
883  int strawStatusHT = TRTCond::StrawStatus::Good;
884  if (m_strawsvcavailable && (m_doArgon || m_doKrypton)) strawStatusHT = m_sumTool->getStatusHT(TRT_Identifier, Gaudi::Hive::currentContext());
885  ActiveGasMixture agm = DecideGasMixture(strawStatusHT);
886 
887  // Make a radiator
888  GeoNodePtr<GeoPhysVol> pRad(new GeoPhysVol(lRad));
889  pRad->add(xCool1);
890  pRad->add(pCoolingTube);
891  pRad->add(xCool2);
892  pRad->add(pCoolingTube);
893  pRad->add(new GeoSerialIdentifier(0));
894 
895  GeoNodePtr<GeoPhysVol> pHoleForMixedStraw;
896  GeoNodePtr<GeoPhysVol> pHoleForMixedStrawWithLargeDeadRegion;
897 
898  switch (agm)
899  {
900  case GM_ARGON:
901  ATH_MSG_DEBUG( "Marking Argon straws from /TRT/Cond/StatusHT:\t"
902  << idHelper->print_to_string(TRT_Identifier));
903  pHoleForMixedStraw = makeStraw(false, GM_ARGON);
904  pHoleForMixedStrawWithLargeDeadRegion = makeStraw(true, GM_ARGON);
905  break;
906  case GM_KRYPTON:
907  ATH_MSG_DEBUG( "Marking Krypton straws from /TRT/Cond/StatusHT:\t"
908  << idHelper->print_to_string(TRT_Identifier));
909  pHoleForMixedStraw = makeStraw(false, GM_KRYPTON);
910  pHoleForMixedStrawWithLargeDeadRegion = makeStraw(true, GM_KRYPTON);
911  break;
912  case GM_XENON:
913  ATH_MSG_DEBUG( "Marking Xenon straws from /TRT/Cond/StatusHT:\t"
914  << idHelper->print_to_string(TRT_Identifier) );
915  pHoleForMixedStraw = makeStraw();
916  pHoleForMixedStrawWithLargeDeadRegion = makeStraw(true);
917  break;
918  default:
919  ATH_MSG_FATAL( "Unexpected gas mixture: " << agm );
920  throw std::runtime_error("Unexpected gas mixture");
921  return;
922  }
923 
924  GeoNodePtr<GeoSerialTransformer> serialTransformer = new GeoSerialTransformer(pHoleForMixedStraw
925  , &tx2
926  , m_data->barrelNumberOfStrawsInModule[iABC]-nStrawsWithLargeDeadRegion);
927 
928  if (iABC==0) {
929  GeoNodePtr<GeoSerialTransformer> serialTransformerDead = new GeoSerialTransformer(pHoleForMixedStrawWithLargeDeadRegion
930  , &tx2Dead
931  , nStrawsWithLargeDeadRegion);
932  pRad->add(serialTransformerDead);
933  }
934  pRad->add(serialTransformer);
935 
936  pShell->add(pRad);
937 
938  //-------------------------------------------------------------------//
939  // //
940  // Barrel readout: //
941  // //
942  //-------------------------------------------------------------------//
943 
944  //
945  // Get the number of straw layers in each module:
946  //
947 
948  unsigned int nStrawLayers = m_detectorManager->getNumerology()->getNBarrelLayers(iABC);
949  for (unsigned int iStrawLayer=0;iStrawLayer<nStrawLayers; iStrawLayer++) { // limit stored as float!
950 
951  unsigned int jStrawLayer=iStrawLayer;
952  if (iABC>0) jStrawLayer += m_detectorManager->getNumerology()->getNBarrelLayers(0);
953  if (iABC>1) jStrawLayer += m_detectorManager->getNumerology()->getNBarrelLayers(1);
954  //TK: just go from jStrawLayer=layerstart;jStrawLayer<layerend ?
955 
956  InDetDD::TRT_BarrelDescriptor *bD=bDescriptor[jStrawLayer];
957 
958  InDetDD::TRT_BarrelElement *element0 = new InDetDD::TRT_BarrelElement(pShell, bD, 0 , iABC, iMod, iStrawLayer, idHelper, m_detectorManager->conditions());
959  InDetDD::TRT_BarrelElement *element1 = new InDetDD::TRT_BarrelElement(pShell, bD, 1 , iABC, iMod, iStrawLayer, idHelper, m_detectorManager->conditions());
960 
963  }
964 
965  }//End "for (size_t iMod = ..." loop.
966 
967  }
968 
969  // Set up the nearest neighbor pointers: in R.
970  for (unsigned int e=0;e<2;e++) {
971  for (unsigned int iMod=0;iMod<m_data->nBarrelModulesUsed; iMod++) {
972  InDetDD::TRT_BarrelElement *prev=nullptr;
973  for (unsigned int iABC=0;iABC<m_data->nBarrelRings;iABC++) {
974  for (unsigned int s=0;s<m_detectorManager->getNumerology()->getNBarrelLayers(iABC); s++) {
976  if (prev && current) {
977  prev->setNextInR(current);
978  current->setPreviousInR(prev);
979  }
980  prev=current;
981  }
982  }
983  }
984  }
985 
986  // Set up the nearest neighbor pointers: in Phi.
987  for (unsigned int e=0;e<2;e++) {
988  for (unsigned int iABC=0;iABC<m_data->nBarrelRings;iABC++) {
989  for (unsigned int s=0;s<m_detectorManager->getNumerology()->getNBarrelLayers(iABC); s++) {
990  InDetDD::TRT_BarrelElement *prev=nullptr;
991  for (unsigned int iMod=0;iMod<m_data->nBarrelModulesUsed; iMod++) {
993  if (prev && current) {
994  prev->setNextInPhi(current);
995  current->setPreviousInPhi(prev);
996  }
997  prev=current;
998  }
999  if (m_data->nBarrelModulesUsed==m_data->nBarrelModules) { // Full complement; then, we wrap!:
1001  InDetDD::TRT_BarrelElement *last =m_detectorManager->getBarrelElement(e,iABC,m_data->nBarrelModules-1,s);
1002  if (first && last) {
1003  first->setPreviousInPhi(last);
1004  last->setNextInPhi(first);
1005  }
1006  }
1007  }
1008  }
1009  }
1010  }//end of if (pBarrelVol)
1011 
1012 
1013 
1014  //-----------------------------------------------------------------------//
1015  // //
1016  // Endcap Modules //
1017  // //
1018  //-----------------------------------------------------------------------//
1019 
1020  // TK: This part could really use some cleanup and reordering.
1021  // There is no need to repeat the same code for A, B & C endcaps.
1022 
1023 
1024  // if none of the endcaps is being built we can return.
1025  if (!(endcapABPlusPresent || endcapABMinusPresent || endcapCPlusPresent || endcapCMinusPresent)){
1026  return;
1027  }
1028  unsigned int firstIndexOfA = 0;
1029  unsigned int firstIndexOfB = m_data->endcapNumberOfAWheels;
1030  unsigned int firstIndexOfC = m_data->endcapNumberOfAWheels + m_data->endcapNumberOfBWheels;
1031 
1032  unsigned int indexUpperBound = firstIndexOfA + m_detectorManager->getNumerology()->getNEndcapWheels();
1033 
1034  if (m_data->initialLayout) indexUpperBound = firstIndexOfC; // No wheel C.
1035 
1036  const unsigned int nSides = 2;
1037  const unsigned int nStrawLayMaxEc = 8;//hardcoded...
1038 
1039  unsigned int iiSide, iiWheel, iiPlane, iiPhi, counter; //set of counters
1040  int sign;
1041  double zdelta = 0.024; // try to make smaller gaps for Endcap Inner/OuterSupportGapper
1042  GeoTransform *xfRadiator, *xfPlane, *xfHeatExchanger, *xfFaradayFoilFront, *xfFaradayFoilBack;
1043  GeoTransform *xfInnerSupportGapperA,*xfOuterSupportGapperA, *xfInnerSupportGapperB, *xfOuterSupportGapperB;
1044  GeoFullPhysVol *childPlane = nullptr;
1045 
1046 
1047  double RotationsOfStrawPlanes[nStrawLayMaxEc]; //8 is hardcoded
1048  double shiftForEachRotation = m_data->endCapShiftForEachRotation; // in units of deltaPhi
1049  RotationsOfStrawPlanes[0] = 0.;
1050 
1051  bool oldGeometry = true;
1052  // Temporary way to determine old from new
1053  if (shiftForEachRotation < 0) oldGeometry = false;
1054 
1055  if (oldGeometry) {
1056  // For old geometry
1057  for (counter = 1; counter < nStrawLayMaxEc; counter++)
1058  {
1059  RotationsOfStrawPlanes[counter] = RotationsOfStrawPlanes[counter-1] + shiftForEachRotation;
1060  if (RotationsOfStrawPlanes[counter] >= 1.)
1061  RotationsOfStrawPlanes[counter] -= 1.;
1062  }
1063  } else {
1064  // New geometry
1065  double RotationsOfStrawPlanesTmp[nStrawLayMaxEc] = {0,0,0,0,2,2,2,2};
1066  for (counter = 0; counter < nStrawLayMaxEc; counter++)
1067  {
1068  RotationsOfStrawPlanes[counter] = (counter * shiftForEachRotation) + RotationsOfStrawPlanesTmp[counter];
1069  }
1070  }
1071 
1072  // Create and initialize by 0 arrays of descriptors
1073  std::vector<InDetDD::TRT_EndcapDescriptor*> descriptorsAB[nSides][nStrawLayMaxEc];
1074  std::vector<InDetDD::TRT_EndcapDescriptor*> descriptorsC[nSides][nStrawLayMaxEc];
1075  InDetDD::TRT_EndcapDescriptor* pDescriptor = nullptr;
1076  InDetDD::TRT_EndcapElement* element = nullptr;
1077 
1078  for(iiSide = 0; iiSide<nSides; iiSide++) {
1079  for(iiPlane = 0; iiPlane < nStrawLayMaxEc; iiPlane++) {
1080  descriptorsAB[iiSide][iiPlane].resize (m_data->nEndcapPhi);
1081  descriptorsC[iiSide][iiPlane].resize (m_data->nEndcapPhi);
1082  }
1083  }
1084 
1085 
1086 
1087  // Do Wheels A and B if one of them is present
1088  if (endcapABPlusPresent || endcapABMinusPresent) {
1089  // -------------- Wheel A -----------------------
1090 
1091  // Inner/Outer supports
1092  GeoTube* sInnerSupportA = new GeoTube(m_data->endCapInnerRadiusOfSupportA,
1093  m_data->endCapInnerRadiusOfSupportA + m_data->endCapRadialThicknessOfInnerSupportA,
1094  m_data->endCapLengthOfWheelsA/2);
1095  GeoLogVol* lInnerSupportA = new GeoLogVol("InnerSupportA", sInnerSupportA, m_materialManager->getMaterial("trt::InnerSupportA"));
1096  GeoPhysVol* pInnerSupportA = new GeoPhysVol(lInnerSupportA);
1097 
1098  GeoTube* sOuterSupportA = new GeoTube(m_data->endCapOuterRadiusOfSupportA - m_data->endCapRadialThicknessOfOuterSupportA,
1099  m_data->endCapOuterRadiusOfSupportA, m_data->endCapLengthOfWheelsA/2);
1100  GeoLogVol* lOuterSupportA = new GeoLogVol("OuterSupportA", sOuterSupportA, m_materialManager->getMaterial("trt::OuterSupportA"));
1101  GeoPhysVol* pOuterSupportA = new GeoPhysVol(lOuterSupportA);
1102 
1103  // Straw plane
1104  GeoNodePtr<GeoFullPhysVol> pStrawPlaneA_Kr;
1105  GeoNodePtr<GeoFullPhysVol> pStrawPlaneA_Ar;
1106  if (m_doKrypton)
1107  pStrawPlaneA_Kr = makeStrawPlane(firstIndexOfA, GM_KRYPTON);
1108  if (m_doArgon)
1109  pStrawPlaneA_Ar = makeStrawPlane(firstIndexOfA, GM_ARGON);
1110  GeoIntrusivePtr<GeoFullPhysVol> pStrawPlaneA = makeStrawPlane(firstIndexOfA);
1111 
1112 
1113  //TK:
1114  // Instead of this confusing stuf (main, thin, middle??), make:
1115  // 1) An array which gives the exact thicknesses of the various radiators
1116  // 2) A "makeradiator" method like makestrawplane which checks
1117  // internally whether it already has created a radiator of a
1118  // given thickness.
1119  //
1120  // Then just loop over the radiators
1121  //
1122 
1123  // Radiators
1124  GeoTube* sMainRadiatorA = new GeoTube(m_data->endCapInnerRadiusOfSupportA + m_data->endCapRadialThicknessOfInnerSupportA,
1125  m_data->endCapOuterRadiusOfSupportA - m_data->endCapRadialThicknessOfOuterSupportA
1126  - m_data->endCapRadialDistFromRadToOuterSupportA, m_data->endCapMainRadiatorThicknessA/2);
1127  GeoLogVol* lMainRadiatorA = new GeoLogVol("MainRadiatorA",sMainRadiatorA, m_materialManager->getMaterial("trt::FoilRadiatorAC"));
1128  GeoPhysVol* pMainRadiatorA = new GeoPhysVol(lMainRadiatorA);
1129 
1130  GeoTube* sThinRadiatorA = new GeoTube(m_data->endCapInnerRadiusOfSupportA + m_data->endCapRadialThicknessOfInnerSupportA,
1131  m_data->endCapOuterRadiusOfSupportA - m_data->endCapRadialThicknessOfOuterSupportA
1132  - m_data->endCapRadialDistFromRadToOuterSupportA, m_data->endCapThinRadiatorThicknessA/2);
1133  GeoLogVol* lThinRadiatorA = new GeoLogVol("ThinRadiatorA",sThinRadiatorA, m_materialManager->getMaterial("trt::FoilRadiatorAC"));
1134  GeoPhysVol* pThinRadiatorA = new GeoPhysVol(lThinRadiatorA);
1135 
1136  // Wheel
1137  GeoTube* sWheelA = new GeoTube( m_data->endCapInnerRadiusOfSupportA,m_data->endCapOuterRadiusOfSupportA, m_data->endCapLengthOfWheelsA/2);
1138  GeoLogVol* lWheelA = new GeoLogVol("WheelA", sWheelA, m_materialManager->getMaterial("trt::CO2"));
1139 
1140  // This is the straw pitch.
1141  double deltaPhiForStrawsA = 360.*GeoModelKernelUnits::deg/m_data->endcapNumberOfStrawsInStrawLayer_AWheels;
1142 
1143 
1144  // In reality the positive and negative endcaps are built identical, both in
1145  // geometry and readout. The offline numbering however keeps phi numbering going
1146  // in the same direction as global phi (righthanded direction).
1147 
1148  // For the latest version we build +ve and negative endcaps identical.
1149  // We also build the descriptors identical apart from the setting of startphi.
1150  //
1151  // The mapping is fixed (this must be reproduced in the sensitive
1152  // detector and readout geometry) The mapping is 1-1 for the
1153  // +ve endcap, for the -ve endcap it is as follows:
1154  //
1155  // ***************************************************************
1156  // * Negative endcap (Endcap C) mapping. *
1157  // * *
1158  // * nSectors = 32 *
1159  // * nStraws = num straws in sector *
1160  // * sector -> (nSectors + nSectors/2 - sector - 1) % nSectors *
1161  // * straw -> nStraws - 1 - straw *
1162  // ***************************************************************
1163  //
1164  // For compatibility with old (wrong geometry) we rotate the strawlayers
1165  // differently for the negative endcap than we do for the positive endcap.
1166  // This is to allow the sensitive detector and readout geometry to have
1167  // the same code for both layouts.
1168  //
1169  // Below we refere to online as the physical readout and offline as the offline
1170  // identifier convetions.
1171  // iiPhi corresponds to the "online" readout phi sector. This goes
1172  // right handed in positive endcap and left handed in negative, where handedness
1173  // is wrt to global frame.
1174  // iiPhiOffline is the offline numbering which is always right handed.
1175 
1176  for(iiSide=0; iiSide<nSides; iiSide++) {
1177  // Wheel A
1178  if (pCommonEndcapAB[iiSide]) {
1179 
1180  double WheelPlacerA = m_data->endCapPositionOfFirstWheelA[iiSide];
1181 
1182  for(iiWheel=firstIndexOfA; iiWheel < firstIndexOfB; iiWheel++)
1183  {
1184  //prepair to place wheel
1185  WheelPlacerA += m_data->endCapDistanceBetweenWheelCentersA[iiSide][iiWheel] ;
1186 
1187  GeoFullPhysVol* pWheelA = new GeoFullPhysVol(lWheelA);
1188 
1189  GeoAlignableTransform * xfAlignableModule = nullptr;
1190 
1191  // Place planes in the wheel
1192  for (iiPlane = 0; iiPlane < m_data->endCapNumberOfStrawLayersPerWheelA; iiPlane++)
1193  {
1194 
1195 
1196 
1197  // WheelA is subdivided into 4 alignable objects. (Every 4th straw layer)
1198  // We create an alignable transform for each alignable module
1199  // and multiply this by the transform for every straw layer in the "alignable module"
1200  // The tranform is by default Identity.
1201  if (iiPlane % 4 == 0) {
1202  // Register alignable node
1203  int barrel_ec = (iiSide) ? -2 : +2;
1204  xfAlignableModule = new GeoAlignableTransform(GeoTrf::Transform3D::Identity());
1205  Identifier idSubModule = idHelper->layer_id(barrel_ec, 0, iiWheel, iiPlane);
1206  // We pass the parent volume as the local delta for this correction is the same as a local delta
1207  // on the transformation of the wheel.
1208  m_detectorManager->addAlignableTransform(AlignmentLevelSubWheel, idSubModule, xfAlignableModule, pWheelA);
1209  }
1210 
1211  // phiPlane is phi of straw 0, sector 0 (online numbering)
1212  double phiPlane = m_data->endCapPhiOfFirstStraw + RotationsOfStrawPlanes[iiPlane%nStrawLayMaxEc]*deltaPhiForStrawsA;
1213 
1214  // For compatibility with old geometry we have to shift every eighth wheel by 1 straw pitch.
1215  if(iiSide && oldGeometry && (iiPlane%8 == 0)) {
1216  phiPlane += deltaPhiForStrawsA;
1217  }
1218 
1219  int bar_ec = (iiSide) ? -2 : +2;
1220  Identifier TRT_Identifier = idHelper->straw_id(bar_ec, 1, iiWheel, 1, 1);
1221  int strawStatusHT = TRTCond::StrawStatus::Good;
1222  if (m_strawsvcavailable && (m_doArgon || m_doKrypton)) strawStatusHT = m_sumTool->getStatusHT(TRT_Identifier, Gaudi::Hive::currentContext());
1223  ActiveGasMixture agm = DecideGasMixture(strawStatusHT);
1224 
1225  // Ruslan: insert plane with Ar-straws
1226  // Artem: same for Kr
1227  switch (agm)
1228  {
1229  case GM_ARGON:
1230  ATH_MSG_DEBUG( "Marking Argon straws from /TRT/Cond/StatusHT:\t"
1231  << idHelper->print_to_string(TRT_Identifier) );
1232  childPlane = pStrawPlaneA_Ar->clone();
1233  break;
1234  case GM_KRYPTON:
1235  ATH_MSG_DEBUG( "Marking Krypton straws from /TRT/Cond/StatusHT:\t"
1236  << idHelper->print_to_string(TRT_Identifier) );
1237  childPlane = pStrawPlaneA_Kr->clone();
1238  break;
1239  case GM_XENON:
1240  ATH_MSG_DEBUG( "Marking Xenon straws from /TRT/Cond/StatusHT:\t"
1241  << idHelper->print_to_string(TRT_Identifier) );
1242  childPlane = pStrawPlaneA->clone();
1243  break;
1244  default:
1245  ATH_MSG_FATAL( "Unexpected gas mixture: " << agm );
1246  throw std::runtime_error("Unexpected gas mixture");
1247  return;
1248  }
1249 
1250 
1251  xfPlane = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionA[iiPlane] - m_data->endCapLengthOfWheelsA/2)*GeoTrf::RotateZ3D(phiPlane));
1252 
1253  if (xfAlignableModule) pWheelA->add(xfAlignableModule);
1254  pWheelA->add(xfPlane);
1255  pWheelA->add(new GeoIdentifierTag(iiPlane));
1256  pWheelA->add(childPlane);
1257 
1258  // Create descriptors
1259  // Just do it for the first wheel
1260  if(iiWheel==firstIndexOfA && iiPlane < nStrawLayMaxEc)
1261  for(iiPhi = 0; iiPhi < m_data->nEndcapPhi; iiPhi++)
1262  {
1263 
1264  pDescriptor = new InDetDD::TRT_EndcapDescriptor();
1265  m_detectorManager->setEndcapDescriptor(pDescriptor);
1266 
1267  pDescriptor->nStraws() = m_data->endcapNumberOfStrawsInStrawLayer_AWheels/m_data->nEndcapPhi;
1268  pDescriptor->strawPitch() = deltaPhiForStrawsA;
1269 
1270  double startPhi = phiPlane + iiPhi * pDescriptor->strawPitch() * pDescriptor->nStraws();
1271 
1272  // For negative endcap the startPhi is the last straw in the physical sector
1273  // phi -> phi + strawPitch*(n-1)
1274  // it then gets rotated 180 around y axis
1275  // phi -> pi - phi
1276  if (iiSide) {
1277  startPhi = GeoModelKernelUnits::pi - (startPhi + pDescriptor->strawPitch() * (pDescriptor->nStraws() - 1));
1278  }
1279 
1280  // Make sure its between -pi and pi.
1281  if (startPhi <= -GeoModelKernelUnits::pi) startPhi += 2*GeoModelKernelUnits::pi;
1282  if (startPhi > GeoModelKernelUnits::pi) startPhi -= 2*GeoModelKernelUnits::pi;
1283 
1284  pDescriptor->startPhi() = startPhi;
1285 
1286  pDescriptor->strawLength() = m_data->endCapOuterRadiusOfSupportA - m_data->endCapRadialThicknessOfOuterSupportA
1287  - 2*m_data->lengthOfDeadRegion - m_data->endCapRadialThicknessOfInnerSupportA - m_data->endCapInnerRadiusOfSupportA;
1288  pDescriptor->innerRadius() = m_data->endCapInnerRadiusOfSupportA + m_data->endCapRadialThicknessOfInnerSupportA
1289  + m_data->lengthOfDeadRegion;
1290  pDescriptor->setStrawTransformField(m_detectorManager->endcapTransformField(0),iiPhi*pDescriptor->nStraws());
1291 
1292  descriptorsAB[iiSide][iiPlane%nStrawLayMaxEc][iiPhi] = pDescriptor;
1293  }
1294  // Create elements
1295  for(iiPhi = 0; iiPhi < m_data->nEndcapPhi; iiPhi++)
1296  {
1297  // m_data->nEndcapPhi assumed to be even.
1298  // For positive endcap online == offline. For negative endcap we rotate 180 deg about y axis so
1299  // sector 0 -> 15, 15 -> 0, 16 -> 31, 31 -> 16, etc. This is achieved with
1300  // sector -> (nSectors + nSectors/2 - sector - 1) % nSectors
1301  int iiPhiOffline = (iiSide==0) ? iiPhi : (3*m_data->nEndcapPhi/2 - iiPhi - 1)% m_data->nEndcapPhi;
1302  element = new InDetDD::TRT_EndcapElement(childPlane,
1303  descriptorsAB[iiSide][iiPlane%nStrawLayMaxEc][iiPhi],
1304  iiSide==0,
1305  iiWheel,
1306  iiPlane,
1307  iiPhiOffline,
1308  idHelper,
1311  }
1312  }
1313  // Place radiators in the wheel
1314  for (counter = 1; counter <= m_data->endCapNumberOfStrawLayersPerWheelA; counter++)
1315  {
1316  if (counter % 4 == 1)
1317  {
1318  xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionA[counter-1] - m_data->endCapLengthOfWheelsA/2
1319  - m_data->outerRadiusOfStraw - m_data->endCapThinRadiatorThicknessA/2));
1320  pWheelA->add(xfRadiator);
1321  pWheelA->add(pThinRadiatorA);
1322  }
1323 
1324  if (counter % 4 == 0)
1325  {
1326  xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionA[counter-1] - m_data->endCapLengthOfWheelsA/2
1327  + m_data->outerRadiusOfStraw + m_data->endCapThinRadiatorThicknessA/2));
1328  pWheelA->add(xfRadiator);
1329  pWheelA->add(pThinRadiatorA);
1330  continue;
1331  }
1332 
1333  xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionA[counter-1] - m_data->endCapLengthOfWheelsA/2
1334  + m_data->outerRadiusOfStraw + m_data->endCapMainRadiatorThicknessA/2));
1335  pWheelA->add(xfRadiator);
1336  pWheelA->add(pMainRadiatorA);
1337  }
1338  // Place Inner/Outer supports in the wheel
1339  pWheelA->add(pInnerSupportA);
1340  pWheelA->add(pOuterSupportA);
1341 
1342  // Place wheel in the Endcap Volume
1343  GeoAlignableTransform * xfWheel = new GeoAlignableTransform( GeoTrf::TranslateZ3D(WheelPlacerA) );
1344 
1345  pCommonEndcapAB[iiSide]->add(xfWheel);
1346  pCommonEndcapAB[iiSide]->add(new GeoIdentifierTag(iiWheel));
1347  pCommonEndcapAB[iiSide]->add(pWheelA);
1348 
1349  // Register alignable node
1350  int barrel_ec = (iiSide) ? -2 : +2;
1351  Identifier idModule = idHelper->module_id(barrel_ec, 0, iiWheel);
1352  m_detectorManager->addAlignableTransform(AlignmentLevelModule, idModule, xfWheel, pWheelA);
1353 
1354  if (m_data->includeECFoilHeatExchangerAndMembranes) {
1355 
1356  // Faraday Foils added
1357  // same Faraday foils for both wheel A and B
1358  // KaptonFoil radius is between R_max of InnerSupport and R_min of OuterSupport....STS
1359  GeoTube* sFaradayFoilWheelAB = new GeoTube(m_data->endCapInnerRadiusOfSupportA + m_data->endCapRadialThicknessOfInnerSupportA,
1360  m_data->endCapOuterRadiusOfSupportA - m_data->endCapRadialThicknessOfOuterSupportA,
1361  m_data->endCapFaradayFoilThickness/2);
1362  GeoLogVol* lFaradayFoilWheelAB = new GeoLogVol("FaradayKaptonFoil",sFaradayFoilWheelAB, m_materialManager->getMaterial("trt::FaradayFoilMaterial"));
1363  GeoIntrusivePtr<GeoPhysVol> pFaradayFoilWheelAB{new GeoPhysVol(lFaradayFoilWheelAB)};
1364 
1365  // Heat Exchanger added
1366  GeoTube* sHeatExchangerA = new GeoTube(m_data->endCapRMinOfHeatExchanger,m_data->endCapRMaxOfHeatExchanger,m_data->endCapHeatExchangerThicknessA/2);
1367  GeoLogVol* lHeatExchangerA = new GeoLogVol("HeatExchangerA",sHeatExchangerA, m_materialManager->getMaterial("trt::HeatExchangerAMat"));
1368  GeoIntrusivePtr<GeoPhysVol> pHeatExchangerA{new GeoPhysVol(lHeatExchangerA)};
1369 
1370  // Inner/Outer Support Gapper added
1371  GeoTube* sInnerSupportGapperA = new GeoTube(m_data->endCapInnerRadiusOfSupportA,
1372  m_data->endCapInnerRadiusOfSupportA + m_data->endCapRadialThicknessOfInnerSupportA,
1373  m_data->endCapHeatExchangerThicknessA/2 + m_data->endCapFaradayFoilThickness/2 + zdelta);
1374  GeoLogVol* lInnerSupportGapperA = new GeoLogVol("InnerSupportGapperA", sInnerSupportGapperA, m_materialManager->getMaterial("trt::InnerSupportA"));
1375  GeoIntrusivePtr<GeoPhysVol> pInnerSupportGapperA{new GeoPhysVol(lInnerSupportGapperA)};
1376 
1377  GeoTube* sOuterSupportGapperA = new GeoTube(m_data->endCapOuterRadiusOfSupportA - m_data->endCapRadialThicknessOfOuterSupportA,
1378  m_data->endCapOuterRadiusOfSupportA,
1379  m_data->endCapHeatExchangerThicknessA/2 + m_data->endCapFaradayFoilThickness/2 + zdelta);
1380  GeoLogVol* lOuterSupportGapperA = new GeoLogVol("OuterSupportGapperA", sOuterSupportGapperA, m_materialManager->getMaterial("trt::OuterSupportA"));
1381  GeoIntrusivePtr<GeoPhysVol> pOuterSupportGapperA{new GeoPhysVol(lOuterSupportGapperA)};
1382 
1383  if(iiWheel<=firstIndexOfB-1)
1384  {
1385  xfFaradayFoilFront = new GeoTransform(GeoTrf::TranslateZ3D(WheelPlacerA
1386  - m_data->endCapLengthOfWheelsA/2
1387  - m_data->endCapFaradayFoilThickness/2.0));
1388  xfFaradayFoilBack = new GeoTransform(GeoTrf::TranslateZ3D(WheelPlacerA
1389  + m_data->endCapLengthOfWheelsA/2
1390  + m_data->endCapFaradayFoilThickness/2.0));
1391  pCommonEndcapAB[iiSide]->add(xfFaradayFoilFront);
1392  pCommonEndcapAB[iiSide]->add(pFaradayFoilWheelAB);
1393  pCommonEndcapAB[iiSide]->add(xfFaradayFoilBack);
1394  pCommonEndcapAB[iiSide]->add(pFaradayFoilWheelAB);
1395  }
1396  // Place HeatExchanger after putiing wheel only. No heat exchanger after the last wheel.
1397 
1398  // Ditto for Inner/OuterSupportGapper
1399  if(iiWheel<firstIndexOfB-1)
1400  {
1401  xfHeatExchanger = new GeoTransform(GeoTrf::TranslateZ3D( WheelPlacerA
1402  + m_data->endCapLengthOfWheelsA/2
1403  + m_data->endCapFaradayFoilThickness
1404  + m_data->endCapHeatExchangerThicknessA/2));
1405  pCommonEndcapAB[iiSide]->add(xfHeatExchanger);
1406  pCommonEndcapAB[iiSide]->add(pHeatExchangerA);
1407 
1408  xfInnerSupportGapperA = new GeoTransform(GeoTrf::TranslateZ3D( WheelPlacerA
1409  + m_data->endCapLengthOfWheelsA/2
1410  + m_data->endCapFaradayFoilThickness
1411  + m_data->endCapHeatExchangerThicknessA/2));
1412  xfOuterSupportGapperA = new GeoTransform(GeoTrf::TranslateZ3D( WheelPlacerA
1413  + m_data->endCapLengthOfWheelsA/2
1414  + m_data->endCapFaradayFoilThickness
1415  + m_data->endCapHeatExchangerThicknessA/2));
1416  pCommonEndcapAB[iiSide]->add(xfInnerSupportGapperA);
1417  pCommonEndcapAB[iiSide]->add(pInnerSupportGapperA);
1418  pCommonEndcapAB[iiSide]->add(xfOuterSupportGapperA);
1419  pCommonEndcapAB[iiSide]->add(pOuterSupportGapperA);
1420  }
1421 
1422  } //include membrane, heat exchanger and foil
1423  } // iiWheel loop for Wheel A
1424  } // if (pCommonEndcapAB[iiSide]) block for Wheel A
1425  } // iiSide loop for Wheel A
1426 
1427 
1428 
1429  // --------------- Wheel B ----------------------------
1430 
1431  //Check here that (m_data->endcapNumberOfStrawsInStrawLayer_AWheels == m_data->endcapNumberOfStrawsInStrawLayer_BWheels) !!
1432  //We assume this in several places!
1433 
1434  // Inner/Outer supports
1435 
1436  GeoTube* sInnerSupportB = new GeoTube(m_data->endCapInnerRadiusOfSupportB,
1437  m_data->endCapInnerRadiusOfSupportB + m_data->endCapRadialThicknessOfInnerSupportB,
1438  m_data->endCapLengthOfWheelsB/2);
1439  GeoLogVol* lInnerSupportB = new GeoLogVol("InnerSupportB", sInnerSupportB, m_materialManager->getMaterial("trt::InnerSupportB"));
1440  GeoPhysVol* pInnerSupportB = new GeoPhysVol(lInnerSupportB);
1441 
1442  GeoTube* sOuterSupportB = new GeoTube(m_data->endCapOuterRadiusOfSupportB - m_data->endCapRadialThicknessOfOuterSupportB,
1443  m_data->endCapOuterRadiusOfSupportB, m_data->endCapLengthOfWheelsB/2);
1444  GeoLogVol* lOuterSupportB = new GeoLogVol("OuterSupportB", sOuterSupportB, m_materialManager->getMaterial("trt::OuterSupportB"));
1445  GeoPhysVol* pOuterSupportB = new GeoPhysVol(lOuterSupportB);
1446 
1447  // Straw plane
1448  GeoFullPhysVol* pStrawPlaneB_Kr = nullptr;
1449  GeoFullPhysVol* pStrawPlaneB_Ar = nullptr;
1450  if (m_doKrypton)
1451  pStrawPlaneB_Kr = makeStrawPlane(firstIndexOfB,GM_KRYPTON);
1452  if (m_doArgon)
1453  pStrawPlaneB_Ar = makeStrawPlane(firstIndexOfB,GM_ARGON);
1454  GeoIntrusivePtr<GeoFullPhysVol> pStrawPlaneB {makeStrawPlane(firstIndexOfB)};
1455 
1456  // Radiators
1457 
1458  GeoTube* sMainRadiatorB = new GeoTube(m_data->endCapInnerRadiusOfSupportB + m_data->endCapRadialThicknessOfInnerSupportB, //TK: no dist between rad&support at inner??????????????????????????????????????
1459  m_data->endCapOuterRadiusOfSupportB - m_data->endCapRadialThicknessOfOuterSupportB
1460  - m_data->endCapRadialDistFromRadToOuterSupportB, m_data->endCapMainRadiatorThicknessB/2);
1461  GeoLogVol* lMainRadiatorB = new GeoLogVol("MainRadiatorB",sMainRadiatorB, m_materialManager->getMaterial("trt::FoilRadiatorB"));
1462  GeoPhysVol* pMainRadiatorB = new GeoPhysVol(lMainRadiatorB);
1463 
1464  GeoTube* sThinRadiatorB = new GeoTube(m_data->endCapInnerRadiusOfSupportB + m_data->endCapRadialThicknessOfInnerSupportB,
1465  m_data->endCapOuterRadiusOfSupportB - m_data->endCapRadialThicknessOfOuterSupportB
1466  - m_data->endCapRadialDistFromRadToOuterSupportB,
1467  m_data->endCapThinRadiatorThicknessB/2);
1468  GeoLogVol* lThinRadiatorB = new GeoLogVol("ThinRadiatorB",sThinRadiatorB, m_materialManager->getMaterial("trt::FoilRadiatorB"));
1469  GeoPhysVol* pThinRadiatorB = new GeoPhysVol(lThinRadiatorB);
1470 
1471  GeoTube* sMiddleRadiatorB = new GeoTube(m_data->endCapInnerRadiusOfSupportB + m_data->endCapRadialThicknessOfInnerSupportB,
1472  m_data->endCapOuterRadiusOfSupportB - m_data->endCapRadialThicknessOfOuterSupportB
1473  - m_data->endCapRadialDistFromRadToOuterSupportB, m_data->endCapMiddleRadiatorThicknessB/2);
1474  GeoLogVol* lMiddleRadiatorB = new GeoLogVol("MiddleRadiatorB",sMiddleRadiatorB, m_materialManager->getMaterial("trt::FoilRadiatorB"));
1475  GeoPhysVol* pMiddleRadiatorB = new GeoPhysVol(lMiddleRadiatorB);
1476 
1477  // Wheel
1478  //TK: endCapAmountWheelLengthExceedsSumOfLayer = ...................
1479  GeoTube* sWheelB = new GeoTube( m_data->endCapInnerRadiusOfSupportB,m_data->endCapOuterRadiusOfSupportB, m_data->endCapLengthOfWheelsB/2);
1480  GeoLogVol* lWheelB = new GeoLogVol("WheelB", sWheelB, m_materialManager->getMaterial("trt::CO2"));
1481 
1482  // This is the straw pitch.
1483  double deltaPhiForStrawsB = 360.*GeoModelKernelUnits::deg/m_data->endcapNumberOfStrawsInStrawLayer_BWheels;
1484 
1485  for(iiSide=0; iiSide<nSides; iiSide++) {
1486 
1487  double WheelPlacerB = m_data->endCapPositionOfFirstWheelB[iiSide];
1488 
1489  // Wheel B
1490  if (pCommonEndcapAB[iiSide]) {
1491  for(iiWheel=firstIndexOfB; iiWheel < firstIndexOfC; iiWheel++)
1492  {
1493  //prepair to place wheel
1494  WheelPlacerB += m_data->endCapDistanceBetweenWheelCentersB[iiSide][iiWheel];
1495 
1496  GeoFullPhysVol* pWheelB = new GeoFullPhysVol(lWheelB);
1497 
1498  GeoAlignableTransform * xfAlignableModule = nullptr;
1499 
1500  // Place planes in the wheel
1501  for (iiPlane = 0; iiPlane < m_data->endCapNumberOfStrawLayersPerWheelB; iiPlane++)
1502  {
1503 
1504  // Each wheel in WheelB is subdivided into 2 alignable objects (every 4th straw layer)
1505  // We create an alignable transform for each alignable module
1506  // and multiply this by the transform for every straw layer in the "alignable module"
1507  // The tranform is by default Identity.
1508  if (iiPlane % 4 == 0) {
1509  // Register alignable node
1510  int barrel_ec = (iiSide) ? -2 : +2;
1511  xfAlignableModule = new GeoAlignableTransform(GeoTrf::Transform3D::Identity());
1512  Identifier idSubModule = idHelper->layer_id(barrel_ec, 0, iiWheel, iiPlane);
1513  // We pass the parent volume as the local delta for this correction is the same as a local delta
1514  // on the transformation of the wheel.
1515  m_detectorManager->addAlignableTransform(AlignmentLevelSubWheel, idSubModule, xfAlignableModule, pWheelB);
1516  }
1517 
1518  int bar_ec = (iiSide) ? -2 : +2;
1519  Identifier TRT_Identifier = idHelper->straw_id(bar_ec, 1, iiWheel, 1, 1);
1520  int strawStatusHT = TRTCond::StrawStatus::Good;
1521  if (m_strawsvcavailable && (m_doArgon || m_doKrypton)) strawStatusHT = m_sumTool->getStatusHT(TRT_Identifier, Gaudi::Hive::currentContext());
1522  ActiveGasMixture agm = DecideGasMixture(strawStatusHT);
1523 
1524  //Ruslan: insert plane with Ar-straws
1525  //Artem: same for Kr
1526  switch (agm)
1527  {
1528  case GM_ARGON:
1529  ATH_MSG_DEBUG( "Marking Argon straws from /TRT/Cond/StatusHT:\t"
1530  << idHelper->print_to_string(TRT_Identifier) );
1531  childPlane = pStrawPlaneB_Ar->clone();
1532  break;
1533  case GM_KRYPTON:
1534  ATH_MSG_DEBUG( "Marking Krypton straws from /TRT/Cond/StatusHT:\t"
1535  << idHelper->print_to_string(TRT_Identifier));
1536  childPlane = pStrawPlaneB_Kr->clone();
1537  break;
1538  case GM_XENON:
1539  ATH_MSG_DEBUG( "Marking Xenon straws from /TRT/Cond/StatusHT:\t"
1540  << idHelper->print_to_string(TRT_Identifier));
1541  childPlane = pStrawPlaneB->clone();
1542  break;
1543  default:
1544  ATH_MSG_FATAL( "Unexpected gas mixture: " << agm);
1545  throw std::runtime_error("Unexpected gas mixture");
1546  return;
1547  }
1548 
1549  // phiPlane is phi of straw 0, sector 0 (online numbering)
1550  double phiPlane = m_data->endCapPhiOfFirstStraw + RotationsOfStrawPlanes[iiPlane%nStrawLayMaxEc]*deltaPhiForStrawsB;
1551 
1552  // For compatibility with old geometry we have to shift every eighth wheel by 1 straw pitch.
1553  if(iiSide && oldGeometry && (iiPlane%8 == 0)) {
1554  phiPlane += deltaPhiForStrawsB;
1555  }
1556 
1557  xfPlane = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionB[iiPlane]
1558  - m_data->endCapLengthOfWheelsB/2)*GeoTrf::RotateZ3D(phiPlane));
1559 
1560  if (xfAlignableModule) pWheelB->add(xfAlignableModule);
1561  pWheelB->add(xfPlane);
1562  pWheelB->add(new GeoIdentifierTag(iiPlane));
1563  pWheelB->add(childPlane);
1564 
1565  // Create elements
1566  for(iiPhi = 0; iiPhi < m_data->nEndcapPhi; iiPhi++)
1567  {
1568  // m_data->nEndcapPhi assumed to be even.
1569  // For positive endcap online == offline. For negative endcap we rotate 180 deg about y axis so
1570  // sector 0 -> 15, 15 -> 0, 16 -> 31, 31 -> 16, etc. This is achieved with
1571  // sector -> (nSectors + nSectors/2 - sector - 1) % nSectors
1572  int iiPhiOffline = (iiSide==0) ? iiPhi : (3*m_data->nEndcapPhi/2 - iiPhi - 1)% m_data->nEndcapPhi;
1573  element = new InDetDD::TRT_EndcapElement(childPlane,
1574  descriptorsAB[iiSide][iiPlane%nStrawLayMaxEc][iiPhi],
1575  iiSide==0,
1576  iiWheel,
1577  iiPlane,
1578  iiPhiOffline,
1579  idHelper,
1582  }
1583  }
1584 
1585  // Place radiators in the wheel
1586  for (counter = 1; counter <= m_data->endCapNumberOfStrawLayersPerWheelB; counter++)
1587  {
1588  // Main radiators
1589  if (counter % 4 != 0)
1590  {
1591  xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionB[counter-1] - m_data->endCapLengthOfWheelsB/2
1592  + m_data->outerRadiusOfStraw + m_data->endCapMainRadiatorThicknessB/2));
1593  pWheelB->add(xfRadiator);
1594  pWheelB->add(pMainRadiatorB);
1595  }
1596 
1597  // Thin radiators
1598  if (counter == 1 || counter == 8)
1599  {
1600  sign = counter == 1? -1 : 1;
1601  xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionB[counter-1] - m_data->endCapLengthOfWheelsB/2 + sign*(m_data->outerRadiusOfStraw + m_data->endCapThinRadiatorThicknessB/2)));
1602  pWheelB->add(xfRadiator);
1603  pWheelB->add(pThinRadiatorB);
1604  }
1605 
1606  // Middle radiators
1607  if (counter == 4 || counter == 5)
1608  {
1609  sign = counter == 4 ? 1 : -1;
1610  xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionB[counter-1] - m_data->endCapLengthOfWheelsB/2 + sign*(m_data->outerRadiusOfStraw + m_data->endCapMiddleRadiatorThicknessB/2)));
1611  pWheelB->add(xfRadiator);
1612  pWheelB->add(pMiddleRadiatorB);
1613  }
1614  }
1615 
1616  // Place Inner/Outer supports in the wheel
1617  pWheelB->add(pInnerSupportB);
1618  pWheelB->add(pOuterSupportB);
1619 
1620  // Place wheel in the Endcap Volume
1621  GeoAlignableTransform * xfWheel = new GeoAlignableTransform(GeoTrf::TranslateZ3D( WheelPlacerB ));
1622 
1623 
1624  pCommonEndcapAB[iiSide]->add(xfWheel);
1625  pCommonEndcapAB[iiSide]->add(new GeoIdentifierTag(iiWheel));
1626  pCommonEndcapAB[iiSide]->add(pWheelB);
1627 
1628  // Register alignable node
1629  int barrel_ec = (iiSide) ? -2 : +2;
1630  Identifier idModule = idHelper->module_id(barrel_ec, 0, iiWheel);
1631  m_detectorManager->addAlignableTransform(AlignmentLevelModule, idModule, xfWheel, pWheelB);
1632 
1633 
1634  if (m_data->includeECFoilHeatExchangerAndMembranes) {
1635 
1636  // Faraday Foils added
1637  // same Faraday foils for both wheel A and B
1638  // KaptonFoil radius is between R_max of InnerSupport and R_min of OuterSupport.....STS
1639  GeoTube* sFaradayFoilWheelAB = new GeoTube(m_data->endCapInnerRadiusOfSupportB + m_data->endCapRadialThicknessOfInnerSupportB,
1640  m_data->endCapOuterRadiusOfSupportB - m_data->endCapRadialThicknessOfOuterSupportB,
1641  m_data->endCapFaradayFoilThickness/2);
1642  GeoLogVol* lFaradayFoilWheelAB = new GeoLogVol("FaradayKaptonFoil",sFaradayFoilWheelAB, m_materialManager->getMaterial("trt::FaradayFoilMaterial"));
1643  GeoIntrusivePtr<GeoPhysVol> pFaradayFoilWheelAB{new GeoPhysVol(lFaradayFoilWheelAB)};
1644 
1645  // Heat Exchanger
1646  GeoTube* sHeatExchangerB = new GeoTube(m_data->endCapRMinOfHeatExchanger,m_data->endCapRMaxOfHeatExchanger,m_data->endCapHeatExchangerThicknessB/2);
1647 
1648  GeoLogVol* lHeatExchangerB = new GeoLogVol("HeatExchangerB", sHeatExchangerB, m_materialManager->getMaterial("trt::HeatExchangerBMat"));
1649  GeoIntrusivePtr<GeoPhysVol> pHeatExchangerB{new GeoPhysVol(lHeatExchangerB)};
1650 
1651  // Inner/Outer Support Gapper added
1652  GeoTube* sInnerSupportGapperB = new GeoTube(m_data->endCapInnerRadiusOfSupportB,
1653  m_data->endCapInnerRadiusOfSupportB + m_data->endCapRadialThicknessOfInnerSupportB,
1654  m_data->endCapHeatExchangerThicknessB/2 + m_data->endCapFaradayFoilThickness/2 + zdelta);
1655  GeoLogVol* lInnerSupportGapperB = new GeoLogVol("InnerSupportGapperB", sInnerSupportGapperB, m_materialManager->getMaterial("trt::InnerSupportB"));
1656  GeoIntrusivePtr<GeoPhysVol> pInnerSupportGapperB{new GeoPhysVol(lInnerSupportGapperB)};
1657 
1658  GeoTube* sOuterSupportGapperB = new GeoTube(m_data->endCapOuterRadiusOfSupportB - m_data->endCapRadialThicknessOfOuterSupportB,
1659  m_data->endCapOuterRadiusOfSupportB,
1660  m_data->endCapHeatExchangerThicknessB/2 + m_data->endCapFaradayFoilThickness/2 + zdelta);
1661  GeoLogVol* lOuterSupportGapperB = new GeoLogVol("OuterSupportGapperB", sOuterSupportGapperB, m_materialManager->getMaterial("trt::OuterSupportB"));
1662  GeoIntrusivePtr<GeoPhysVol> pOuterSupportGapperB{new GeoPhysVol(lOuterSupportGapperB)};
1663 
1664  // Place kapton foils on a wheel just like a sandwitch
1665  if(iiWheel-firstIndexOfB<firstIndexOfC-firstIndexOfB)
1666  {
1667  xfFaradayFoilFront = new GeoTransform(GeoTrf::TranslateZ3D(WheelPlacerB
1668  - m_data->endCapLengthOfWheelsB/2
1669  - m_data->endCapFaradayFoilThickness/2.0));
1670  xfFaradayFoilBack = new GeoTransform(GeoTrf::TranslateZ3D(WheelPlacerB
1671  + m_data->endCapLengthOfWheelsB/2
1672  + m_data->endCapFaradayFoilThickness/2.0));
1673 
1674  pCommonEndcapAB[iiSide]->add(xfFaradayFoilFront);
1675  pCommonEndcapAB[iiSide]->add(pFaradayFoilWheelAB);
1676  pCommonEndcapAB[iiSide]->add(xfFaradayFoilBack);
1677  pCommonEndcapAB[iiSide]->add(pFaradayFoilWheelAB);
1678  }
1679 
1680  // Place HeatExchanger after putiing wheel only. No heat exchanger after the last wheel
1681  // Ditto for Inner/OuterSupportGapper
1682  if(iiWheel-firstIndexOfB<firstIndexOfC-firstIndexOfB-1)
1683  {
1684  xfHeatExchanger = new GeoTransform(GeoTrf::TranslateZ3D( WheelPlacerB
1685  + m_data->endCapLengthOfWheelsB/2
1686  + m_data->endCapFaradayFoilThickness
1687  + m_data->endCapHeatExchangerThicknessB/2));
1688  pCommonEndcapAB[iiSide]->add(xfHeatExchanger);
1689  pCommonEndcapAB[iiSide]->add(pHeatExchangerB);
1690 
1691  xfInnerSupportGapperB = new GeoTransform(GeoTrf::TranslateZ3D(WheelPlacerB
1692  + m_data->endCapLengthOfWheelsB/2
1693  + m_data->endCapFaradayFoilThickness
1694  + m_data->endCapHeatExchangerThicknessB/2));
1695 
1696  xfOuterSupportGapperB = new GeoTransform(GeoTrf::TranslateZ3D(WheelPlacerB
1697  + m_data->endCapLengthOfWheelsB/2
1698  + m_data->endCapFaradayFoilThickness
1699  + m_data->endCapHeatExchangerThicknessB/2));
1700  pCommonEndcapAB[iiSide]->add(xfInnerSupportGapperB);
1701  pCommonEndcapAB[iiSide]->add(pInnerSupportGapperB);
1702  pCommonEndcapAB[iiSide]->add(xfOuterSupportGapperB);
1703  pCommonEndcapAB[iiSide]->add(pOuterSupportGapperB);
1704  }
1705  } // include foil, heat exchanger and membrane
1706  }// iiWheel loop for Wheel B
1707  } // if (pCommonEndcapAB[iiSide]) block for Wheel B
1708  } // iiSide loop for Wheel B
1709 
1710  } // end AB
1711 
1712 
1713 
1714 
1715 
1716 
1717 
1718 
1719  if (m_data->includeECFoilHeatExchangerAndMembranes) {
1720  // Membranes
1721 
1722  GeoTube* sMbrane = new GeoTube(m_data->endCapRMinOfMbrane, m_data->endCapRMaxOfMbrane, m_data->endCapThicknessOfMbrane/2.0);
1723  GeoLogVol* lMbrane = new GeoLogVol("Membrane", sMbrane, m_materialManager->getMaterial("trt::EndCapMbrane"));
1724  GeoPhysVol* pMbrane = new GeoPhysVol(lMbrane);
1725 
1726  GeoTransform *xfMbraneWheelA1 = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapZMinOfMbraneWheelA1 + m_data->endCapThicknessOfMbrane/2.0));
1727  GeoTransform *xfMbraneWheelA2 = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapZMinOfMbraneWheelA2 + m_data->endCapThicknessOfMbrane/2.0));
1728  GeoTransform *xfMbraneWheelB1 = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapZMinOfMbraneWheelB1 + m_data->endCapThicknessOfMbrane/2.0));
1729  GeoTransform *xfMbraneWheelB2 = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapZMinOfMbraneWheelB2 + m_data->endCapThicknessOfMbrane/2.0));
1730 
1731  for(iiSide=0; iiSide<nSides; iiSide++) {
1732  pCommonEndcapAB[iiSide]->add(xfMbraneWheelA1);
1733  pCommonEndcapAB[iiSide]->add(pMbrane);
1734  pCommonEndcapAB[iiSide]->add(xfMbraneWheelA2);
1735  pCommonEndcapAB[iiSide]->add(pMbrane);
1736  pCommonEndcapAB[iiSide]->add(xfMbraneWheelB1);
1737  pCommonEndcapAB[iiSide]->add(pMbrane);
1738  pCommonEndcapAB[iiSide]->add(xfMbraneWheelB2);
1739  pCommonEndcapAB[iiSide]->add(pMbrane);
1740  }
1741  }
1742 
1743 
1744 
1745  // ---------------- Wheel C ---------------------------
1746  // Not present in initial layout
1747  if (endcapCPlusPresent || endcapCMinusPresent) {
1748  // Inner/Outer supports
1749  GeoTube* sInnerSupportC = new GeoTube(m_data->endCapInnerRadiusOfSupportC, m_data->endCapInnerRadiusOfSupportC
1750  + m_data->endCapRadialThicknessOfInnerSupportC, m_data->endCapLengthOfWheelsC/2);
1751  GeoLogVol* lInnerSupportC = new GeoLogVol("InnerSupportC", sInnerSupportC, m_materialManager->getMaterial("trt::InnerSupportC"));
1752  GeoPhysVol* pInnerSupportC = new GeoPhysVol(lInnerSupportC);
1753 
1754  GeoTube* sOuterSupportC = new GeoTube(m_data->endCapOuterRadiusOfSupportC - m_data->endCapRadialThicknessOfOuterSupportC,
1755  m_data->endCapOuterRadiusOfSupportC, m_data->endCapLengthOfWheelsC/2);
1756  GeoLogVol* lOuterSupportC = new GeoLogVol("OuterSupportC", sOuterSupportC, m_materialManager->getMaterial("trt::OuterSupportC"));
1757  GeoPhysVol* pOuterSupportC = new GeoPhysVol(lOuterSupportC);
1758 
1759  // Straw plane
1760  GeoIntrusivePtr<GeoFullPhysVol> pStrawPlaneC = makeStrawPlane(firstIndexOfC);
1761 
1762  // Radiators
1763  GeoTube* sMainRadiatorC = new GeoTube(m_data->endCapInnerRadiusOfSupportC + m_data->endCapRadialThicknessOfInnerSupportC,
1764  m_data->endCapOuterRadiusOfSupportC - m_data->endCapRadialThicknessOfOuterSupportC
1765  - m_data->endCapRadialDistFromRadToOuterSupportC, m_data->endCapMainRadiatorThicknessC/2);
1766  GeoLogVol* lMainRadiatorC = new GeoLogVol("MainRadiatorC",sMainRadiatorC, m_materialManager->getMaterial("trt::FoilRadiatorAC"));
1767  GeoPhysVol* pMainRadiatorC = new GeoPhysVol(lMainRadiatorC);
1768 
1769  GeoTube* sThinRadiatorC = new GeoTube(m_data->endCapInnerRadiusOfSupportC + m_data->endCapRadialThicknessOfInnerSupportC,
1770  m_data->endCapOuterRadiusOfSupportC - m_data->endCapRadialThicknessOfOuterSupportC
1771  - m_data->endCapRadialDistFromRadToOuterSupportC, m_data->endCapThinRadiatorThicknessC/2);
1772  GeoLogVol* lThinRadiatorC = new GeoLogVol("ThinRadiatorC",sThinRadiatorC, m_materialManager->getMaterial("trt::FoilRadiatorAC"));
1773  GeoPhysVol* pThinRadiatorC = new GeoPhysVol(lThinRadiatorC);
1774 
1775  // Wheel
1776  GeoTube* sWheelC = new GeoTube( m_data->endCapInnerRadiusOfSupportC,m_data->endCapOuterRadiusOfSupportC, m_data->endCapLengthOfWheelsC/2);
1777  GeoLogVol* lWheelC = new GeoLogVol("WheelC", sWheelC, m_materialManager->getMaterial("trt::CO2"));
1778 
1779  // This is the straw pitch.
1780  double deltaPhiForStrawsC = 360.*GeoModelKernelUnits::deg/m_data->endcapNumberOfStrawsInStrawLayer_CWheels;
1781 
1782  for(iiSide=0; iiSide<nSides; iiSide++) {
1783  // Wheel C
1784  if (pCommonEndcapC[iiSide]) {
1785  for(iiWheel=firstIndexOfC; iiWheel < indexUpperBound; iiWheel++)
1786  {
1787  GeoFullPhysVol* pWheelC = new GeoFullPhysVol(lWheelC);
1788 
1789  // Place planes in the wheel
1790  for (iiPlane = 0; iiPlane < m_data->endCapNumberOfStrawLayersPerWheelC; iiPlane++)
1791  {
1792  // phiPlane is phi of straw 0, sector 0 (online numbering)
1793  double phiPlane = m_data->endCapPhiOfFirstStraw + RotationsOfStrawPlanes[iiPlane%nStrawLayMaxEc]*deltaPhiForStrawsC;
1794 
1795  // For compatibility with old geometry we have to shift every eighth wheel by 1 straw pitch.
1796  if(iiSide && oldGeometry && (iiPlane%8 == 0)) {
1797  phiPlane += deltaPhiForStrawsC;
1798  }
1799 
1800 
1801  childPlane = pStrawPlaneC->clone();
1802 
1803  xfPlane = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionC[iiPlane]
1804  - m_data->endCapLengthOfWheelsC/2)*GeoTrf::RotateZ3D(phiPlane));
1805  pWheelC->add(xfPlane);
1806  pWheelC->add(new GeoIdentifierTag(iiPlane));
1807  pWheelC->add(childPlane);
1808 
1809  // Create descriptors
1810  // Just do it for the first wheel
1811  if(iiWheel==firstIndexOfC && iiPlane < nStrawLayMaxEc)
1812  for(iiPhi = 0; iiPhi < m_data->nEndcapPhi; iiPhi++)
1813  {
1814  pDescriptor = new InDetDD::TRT_EndcapDescriptor();
1815  m_detectorManager->setEndcapDescriptor(pDescriptor);
1816 
1817  pDescriptor->nStraws() = m_data->endcapNumberOfStrawsInStrawLayer_CWheels/m_data->nEndcapPhi;
1818  pDescriptor->strawPitch() = deltaPhiForStrawsC;
1819 
1820 
1821  double startPhi = phiPlane + iiPhi * pDescriptor->strawPitch() * pDescriptor->nStraws();
1822 
1823  // For negative endcap the startPhi is the last straw in the physical sector, it then gets
1824  // rotated 180 around y axis (phi -> pi - phi)
1825  if (iiSide) {
1826  startPhi = GeoModelKernelUnits::pi - (startPhi + pDescriptor->strawPitch() * (pDescriptor->nStraws() - 1));
1827  }
1828 
1829  // Make sure its between -pi and pi.
1830  if (startPhi <= -GeoModelKernelUnits::pi) startPhi += 2*GeoModelKernelUnits::pi;
1831  if (startPhi > GeoModelKernelUnits::pi) startPhi -= 2*GeoModelKernelUnits::pi;
1832 
1833 
1834  pDescriptor->startPhi() = startPhi;
1835 
1836  pDescriptor->strawLength() = m_data->endCapOuterRadiusOfSupportC - m_data->endCapRadialThicknessOfOuterSupportC
1837  - 2*m_data->lengthOfDeadRegion - m_data->endCapRadialThicknessOfInnerSupportC - m_data->endCapInnerRadiusOfSupportC;
1838  pDescriptor->innerRadius() = m_data->endCapInnerRadiusOfSupportC + m_data->endCapRadialThicknessOfInnerSupportC + m_data->lengthOfDeadRegion;
1839  pDescriptor->setStrawTransformField(m_detectorManager->endcapTransformField(2),iiPhi*pDescriptor->nStraws());
1840 
1841 
1842  descriptorsC[iiSide][iiPlane%nStrawLayMaxEc][iiPhi] = pDescriptor;
1843  }
1844 
1845  // Create elements
1846  for(iiPhi = 0; iiPhi < m_data->nEndcapPhi; iiPhi++)
1847  {
1848  // m_data->nEndcapPhi assumed to be even.
1849  // For positive endcap online == offline. For negative endcap we rotate 180 deg about y axis so
1850  // sector 0 -> 15, 15 -> 0, 16 -> 31, 31 -> 16, etc. This is achieved with
1851  // sector -> (nSectors + nSectors/2 - sector - 1) % nSectors
1852  int iiPhiOffline = (iiSide==0) ? iiPhi : (3*m_data->nEndcapPhi/2 - iiPhi - 1)% m_data->nEndcapPhi;
1853  element = new InDetDD::TRT_EndcapElement(childPlane,
1854  descriptorsC[iiSide][iiPlane%nStrawLayMaxEc][iiPhi],
1855  iiSide==0,
1856  iiWheel,
1857  iiPlane,
1858  iiPhiOffline,
1859  idHelper,
1862  }
1863  }
1864 
1865  // Place radiators in the wheel
1866  for (counter = 1; counter <= m_data->endCapNumberOfStrawLayersPerWheelC; counter++)
1867  {
1868  if (counter % 4 == 1)
1869  {
1870  xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionC[counter-1] - m_data->endCapLengthOfWheelsC/2
1871  - m_data->lengthOfDeadRegion - m_data->endCapThinRadiatorThicknessC/2));
1872  pWheelC->add(xfRadiator);
1873  pWheelC->add(pThinRadiatorC);
1874  }
1875 
1876  if (counter % 4 == 0)
1877  {
1878  xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionC[counter-1] - m_data->endCapLengthOfWheelsC/2
1879  + m_data->outerRadiusOfStraw + m_data->endCapThinRadiatorThicknessC/2));
1880  pWheelC->add(xfRadiator);
1881  pWheelC->add(pThinRadiatorC);
1882  continue;
1883  }
1884 
1885  xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionC[counter-1] - m_data->endCapLengthOfWheelsC/2
1886  + m_data->outerRadiusOfStraw + m_data->endCapMainRadiatorThicknessC/2));
1887  pWheelC->add(xfRadiator);
1888  pWheelC->add(pMainRadiatorC);
1889  }
1890 
1891  // Place Inner/Outer supports in the wheel
1892  pWheelC->add(pInnerSupportC);
1893  pWheelC->add(pOuterSupportC);
1894 
1895  // Place wheel in the Endcap Volume
1896  GeoAlignableTransform * xfWheel
1897  = new GeoAlignableTransform(GeoTrf::TranslateZ3D(m_data->endCapPositionOfFirstWheelC
1898  + (iiWheel - firstIndexOfC)*m_data->endCapDistanceBetweenWheelCentersC));
1899 
1900  pCommonEndcapC[iiSide]->add(xfWheel);
1901  pCommonEndcapC[iiSide]->add(new GeoIdentifierTag(iiWheel));
1902  pCommonEndcapC[iiSide]->add(pWheelC);
1903 
1904  // Register alignable node
1905  int barrel_ec = (iiSide) ? -2 : +2;
1906  Identifier idModule = idHelper->module_id(barrel_ec, 0, iiWheel);
1907  m_detectorManager->addAlignableTransform(AlignmentLevelModule, idModule, xfWheel, pWheelC);
1908 
1909 
1910  } // iiWheel loop for Wheel C
1911  } // if (pCommonEndcapC[iiSide]) block for Wheel C
1912  } // iiSide loop for Wheel C
1913 
1914  } // End Wheel C
1915 
1916 
1917  // Set up the nearest neighbor pointers: in Z
1918  for (iiSide=0; iiSide<2; iiSide++)
1919  for(iiPhi=0; iiPhi<m_data->nEndcapPhi; iiPhi++)
1920  {
1921  InDetDD::TRT_EndcapElement *prev = nullptr;
1922  for (iiWheel=0; iiWheel<indexUpperBound; iiWheel++)
1923  for (iiPlane=0; iiPlane<m_detectorManager->getNumerology()->getNEndcapLayers(iiWheel); iiPlane++)
1924  {
1925  InDetDD::TRT_EndcapElement *current = m_detectorManager->getEndcapElement(iiSide, iiWheel, iiPlane, iiPhi);
1926  if (prev && current)
1927  {
1928  prev->setNextInZ(current);
1929  current->setPreviousInZ(prev);
1930  }
1931  prev=current;
1932  }
1933  }
1934 }
1935 
1937 
1938 
1939 
1941 // //
1942 // Here follows private helper methods, used to construct the barrel module //
1943 // forms (makeModule), the barrel straws (makeStraw) and the endcap straw //
1944 // planes (makeStrawPlane) //
1945 // //
1947 
1948 
1949 
1951 //
1952 const GeoShape * TRTDetectorFactory_Full::makeModule ( double length, const GeoTrf::Vector2D& corner1, const GeoTrf::Vector2D& corner2,
1953  const GeoTrf::Vector2D& corner3, const GeoTrf::Vector2D& corner4, GeoTrf::Transform3D & modulePosition, double shrinkDist/*=0*/) const {
1954 
1955 
1956  // This method takes the absolute coordinates of the four corners,
1957  // constructs the relevant shape, centered around the intersections
1958  // of its diagonals, and returns it along with the absolute
1959  // coordinates of that center (modulePosition).
1960  //
1961  // We know that the four corners _approximately_ can be described as
1962  // the union of two isosceles triangles with same side-lengths and
1963  // different bases.
1964  //
1965  // shrinkDist is for the radiator, which must be similar to the
1966  // shell, but shrunken by some distance.
1967 
1968  // First we calculate the relative vectors of the edges:
1969 
1970  GeoTrf::Vector2D delta12 = corner1 - corner2; GeoTrf::Vector2D delta23 = corner2 - corner3;
1971  GeoTrf::Vector2D delta34 = corner3 - corner4; GeoTrf::Vector2D delta14 = corner1 - corner4;
1972 
1973  // We also need the diagonals.
1974  GeoTrf::Vector2D delta24 = corner2 - corner4;
1975  GeoTrf::Vector2D delta13 = corner1 - corner3;
1976 
1977  // Then we find out which way the module bends (NB: .angle returns the UNSIGNED angle!).
1978  double openingAngleOfFirstCorner= angle(delta12,delta14);
1979  int sign = ( openingAngleOfFirstCorner < 90*GeoModelKernelUnits::deg ? 1 : -1);
1980 
1981  // If our approximation with triangles were correct, three of the
1982  // lengths (of edges and diagonals) would be equal. We force this
1983  // instead.
1984  //
1985  // (Whether the involved diagonal is 2-4 or 1-3 depends on the sign).
1986  double commonSide = (magn(delta14) + magn(delta23) + (sign==1?magn(delta24):magn(delta13)) ) / 3.;
1987  double base1 = magn(delta12); // Inner base
1988  double base2 = magn(delta34); // Outer base
1989 
1990  if (shrinkDist!=0) {
1991  // Since the moving corners bit above doesnt work, we do this instead:
1992  double cosAlpha= sqrt(commonSide*commonSide-0.25*base1*base1)/commonSide;
1993  commonSide -= (1+1/cosAlpha)*shrinkDist;
1994  base1 -= 2*shrinkDist;
1995  base2 -= 2*shrinkDist;
1996  }
1997 
1998  double height1 = sqrt (commonSide*commonSide-0.25*base1*base1);
1999  double height2 = sqrt (commonSide*commonSide-0.25*base2*base2);
2000  double rot = atan(base2/height2/2)-atan(base1/height1/2);
2001  double epsilon = 1*GeoModelKernelUnits::micrometer; // needed to ensure perfect overlaps.
2002  GeoTrd *trd1 = new GeoTrd(base1/2+epsilon, epsilon, length/2, length/2, height1/2);
2003  GeoTrd *trd2 = new GeoTrd(epsilon, base2/2+epsilon, length/2, length/2, height2/2);
2004 
2005  double gamma = atan((base2/2+epsilon)*2/height2);
2006  double r = sqrt((base2/2+epsilon)*(base2/2+epsilon) + height2*height2/4);
2007  GeoTrf::Transform3D xForm=GeoTrf::Translate3D(r*sin(sign*(gamma-rot)),0,height1/2-r*cos(gamma-rot))*GeoTrf::RotateY3D(sign*rot);
2008  const GeoShape & sShell = (*trd1).add((*trd2)<<xForm);
2009 
2010  // We now have the shape we want. We only have left to transform
2011  // its position to where we want it.
2012  //
2013  // First, the actual positions of the four corners of
2014  // the constructed shape.
2015  GeoTrf::Vector2D actualCorner1, actualCorner2, actualCorner3, actualCorner4;
2016  actualCorner1 = corner1;
2017  actualCorner2 = corner1 + GeoTrf::Vector2D(0,base1);
2018  if (sign==1) {
2019  actualCorner4 = corner1 + GeoTrf::Vector2D(height1,base1/2);
2020  actualCorner3 = actualCorner4 + GeoTrf::Vector2D(-base2*sin(rot),base2*cos(rot));
2021  } else {
2022  actualCorner3 = corner1 + GeoTrf::Vector2D(height1,base1/2);
2023  actualCorner4 = actualCorner3 + GeoTrf::Vector2D(-base2*sin(rot),-base2*cos(rot));
2024  }
2025  // The center of our shape is at
2026  GeoTrf::Vector2D center= corner1 + GeoTrf::Vector2D(height1/2,base1/2);
2027 
2028  // Let us turn the whole module
2029  double modRot = (-delta12).phi()-GeoTrf::Vector2D(0,1).phi();
2030 
2031  // std::cout << "TK: modRot : "<< modRot/GeoModelKernelUnits::degree<<" degrees"<<std::endl;
2032  rotate(modRot,actualCorner1);
2033  rotate(modRot,actualCorner2);
2034  rotate(modRot,actualCorner3);
2035  rotate(modRot,actualCorner4);
2036  rotate(modRot,center);
2037 
2038  // Finally, the shape is moved where it fits best with the original corner coordinates.
2039 
2040  GeoTrf::Vector2D displacement = 0.25*( (corner1+corner2+corner3+corner4) - (actualCorner1+actualCorner2+actualCorner3+actualCorner4) );
2041  // .. << ::DEBUG << std::cout << "TK: makeModule : moving a total of (micrometer) " << displacement.mag()/GeoModelKernelUnits::micrometer<< std::endl;
2042  // std::cout << "TK: makeModule : moving due to 1 (micrometer) " << 0.25*(corner1-actualCorner1).mag()/GeoModelKernelUnits::micrometer<< std::endl;
2043  // std::cout << "TK: makeModule : moving due to 2 (micrometer) " << 0.25*(corner2-actualCorner2).mag()/GeoModelKernelUnits::micrometer<< std::endl;
2044  // std::cout << "TK: makeModule : moving due to 3 (micrometer) " << 0.25*(corner3-actualCorner3).mag()/GeoModelKernelUnits::micrometer<< std::endl;
2045  // std::cout << "TK: makeModule : moving due to 4 (micrometer) " << 0.25*(corner4-actualCorner4).mag()/GeoModelKernelUnits::micrometer<< std::endl;
2046  center += displacement;
2047  actualCorner1 += displacement;
2048  actualCorner2 += displacement;
2049  actualCorner3 += displacement;
2050  actualCorner4 += displacement;
2051 
2052  // GeoTrf::Vector2D remainingOffset = -0.25*( (corner1+corner2+corner3+corner4) - (actualCorner1+actualCorner2+actualCorner3+actualCorner4) );
2053  // std::cout << "TK: makeModule : remaining total offset (should be zero) (micrometer) " << remainingOffset.mag()/GeoModelKernelUnits::micrometer<< std::endl;
2054  // std::cout << "TK: makeModule : 1 remaining offset (micrometer) " << (corner1-actualCorner1).mag()/GeoModelKernelUnits::micrometer<< std::endl;
2055  // std::cout << "TK: makeModule : 2 remaining offset (micrometer) " << (corner2-actualCorner2).mag()/GeoModelKernelUnits::micrometer<< std::endl;
2056  // std::cout << "TK: makeModule : 3 remaining offset (micrometer) " << (corner3-actualCorner3).mag()/GeoModelKernelUnits::micrometer<< std::endl;
2057  // std::cout << "TK: makeModule : 4 remaining offset (micrometer) " << (corner4-actualCorner4).mag()/GeoModelKernelUnits::micrometer<< std::endl;
2058 
2059  // The final positioning includes a few 90deg rotations because the axis's in the GeoTrd's are different from the actual axis's.
2060  modulePosition = GeoTrf::TranslateY3D(center.y())*GeoTrf::TranslateX3D(center.x())*GeoTrf::RotateZ3D(90.0*GeoModelKernelUnits::deg)*GeoTrf::RotateX3D(90.0*GeoModelKernelUnits::deg)*GeoTrf::RotateY3D(modRot);
2061 
2062  return &sShell;
2063 }
2065 
2066 
2067 
2069 
2070 //
2071 GeoPhysVol * TRTDetectorFactory_Full::makeStraw(bool hasLargeDeadRegion, ActiveGasMixture gasMixture) {
2072 
2073  double lengthOfInnerDeadRegion= hasLargeDeadRegion ? m_data->barrelLengthOfLargeDeadRegion : m_data->lengthOfDeadRegion ;
2074  double lengthOfActiveGas = (m_data->barrelLengthOfStraw-m_data->barrelLengthOfTwister)/2.0 - m_data->lengthOfDeadRegion - lengthOfInnerDeadRegion;
2075  double posA = (lengthOfActiveGas + m_data->barrelLengthOfTwister) / 2. + lengthOfInnerDeadRegion; // middle of lengthOfActiveGas
2076  double posInnerDeadRegion = ( m_data->barrelLengthOfTwister + lengthOfInnerDeadRegion ) / 2;
2077 
2078  // Straws:
2079  GeoTube *sHole = new GeoTube(0,m_data->barrelOuterRadiusOfStrawHole, m_data->barrelLengthOfStraw/2.0);
2080  GeoLogVol *lHole = new GeoLogVol("Hole", sHole, m_materialManager->getMaterial("trt::CO2"));
2081  GeoPhysVol *pHole = new GeoPhysVol(lHole);
2082 
2083  // Straws:
2084  GeoTube *sStraw = new GeoTube(0,m_data->outerRadiusOfStraw, m_data->barrelLengthOfStraw/2.0);
2085  GeoLogVol *lStrawMixed = new GeoLogVol("StrawM", sStraw, m_materialManager->getMaterial("trt::Straw"));
2086  GeoPhysVol *pStrawMixed = new GeoPhysVol(lStrawMixed);
2087 
2088  // Dead regions:
2089  GeoShape *sDeadRegion = new GeoTube(m_data->outerRadiusOfWire , m_data->innerRadiusOfStraw , m_data->lengthOfDeadRegion/2 );
2090  GeoLogVol *lDeadRegion = nullptr;
2091  if (gasMixture == GM_ARGON)
2092  lDeadRegion = new GeoLogVol("DeadRegion_Ar", sDeadRegion, m_materialManager->getMaterial("trt::ArCO2O2"));
2093  else if (gasMixture == GM_KRYPTON)
2094  lDeadRegion = new GeoLogVol("DeadRegion_Kr", sDeadRegion, m_materialManager->getMaterial("trt::KrCO2O2"));
2095  else
2096  lDeadRegion = new GeoLogVol("DeadRegion", sDeadRegion, m_materialManager->getMaterial((m_useOldActiveGasMixture ? "trt:XeCO2CF4" : "trt::XeCO2O2")));
2097  GeoPhysVol *pDeadRegion = new GeoPhysVol(lDeadRegion);
2098 
2099  // InnerDeadRegions, part II:
2100  GeoShape * sInnerDeadRegion = new GeoTube(m_data->outerRadiusOfWire , m_data->innerRadiusOfStraw, lengthOfInnerDeadRegion/2 );
2101  GeoLogVol * lInnerDeadRegion = nullptr;
2102  if (gasMixture == GM_ARGON)
2103  lInnerDeadRegion = new GeoLogVol("InnerDeadRegion_Ar", sInnerDeadRegion, m_materialManager->getMaterial("trt::ArCO2O2"));
2104  else if(gasMixture == GM_KRYPTON)
2105  lInnerDeadRegion = new GeoLogVol("InnerDeadRegion_Kr", sInnerDeadRegion, m_materialManager->getMaterial("trt::KrCO2O2"));
2106  else
2107  lInnerDeadRegion = new GeoLogVol("InnerDeadRegion", sInnerDeadRegion, m_materialManager->getMaterial((m_useOldActiveGasMixture ? "trt:XeCO2CF4" : "trt::XeCO2O2")));
2108  GeoPhysVol* pInnerDeadRegion = new GeoPhysVol(lInnerDeadRegion);
2109 
2110  // Twisters:
2111  GeoShape *sTwister = new GeoTube(m_data->outerRadiusOfWire , m_data->innerRadiusOfStraw, m_data->barrelLengthOfTwister/2);
2112  GeoLogVol *lTwister = new GeoLogVol("Twister", sTwister, m_materialManager->getMaterial("trt::Twister"));
2113  GeoPhysVol *pTwister = new GeoPhysVol(lTwister);
2114 
2115  // Wires:
2116  GeoShape *sWire = new GeoTube( 0,m_data->outerRadiusOfWire,m_data->barrelLengthOfStraw/2.0);
2117  GeoLogVol *lWire = new GeoLogVol("Wire", sWire, m_materialManager->getMaterial("trt::Wire"));
2118  GeoPhysVol *pWire = new GeoPhysVol(lWire);
2119 
2120  // NB please see comments in TRT_BarrelElement::getAbsoluteTransform before re-organizing
2121  // the next few paragraphs!!.
2122 
2123  // Gas for mixed straws, part I:
2124  GeoTube *sGasMA = new GeoTube(m_data->outerRadiusOfWire , m_data->innerRadiusOfStraw,lengthOfActiveGas/2.0);
2125  GeoLogVol * lGasMA = nullptr;
2126  if (gasMixture == GM_ARGON)
2127  lGasMA = new GeoLogVol("GasMA_Ar", sGasMA, m_materialManager->getMaterial("trt::ArCO2O2"));
2128  else if (gasMixture == GM_KRYPTON)
2129  lGasMA = new GeoLogVol("GasMA_Kr", sGasMA, m_materialManager->getMaterial("trt::KrCO2O2"));
2130  else
2131  lGasMA = new GeoLogVol("GasMA", sGasMA, m_materialManager->getMaterial((m_useOldActiveGasMixture ? "trt:XeCO2CF4" : "trt::XeCO2O2")));
2132  GeoNameTag *nGasMAPos = new GeoNameTag("GasMAPos");
2133  GeoTransform *xGasMAPos = new GeoTransform(GeoTrf::RotateY3D(M_PI)*GeoTrf::TranslateZ3D(-posA));//the rotation of pi is to... digitization (TK)
2134  GeoNameTag *nGasMANeg = new GeoNameTag("GasMANeg");
2135  GeoTransform *xGasMANeg = new GeoTransform(GeoTrf::TranslateZ3D(-posA));
2136  GeoPhysVol *pGasMA = new GeoPhysVol(lGasMA);
2137 
2138  // Assemble gas within straws
2139  GeoSerialIdentifier *id = new GeoSerialIdentifier(0);
2140  pStrawMixed->add(id);
2141  pStrawMixed->add(nGasMANeg);
2142  pStrawMixed->add(xGasMANeg);
2143  pStrawMixed->add(pGasMA);
2144  pStrawMixed->add(nGasMAPos);
2145  pStrawMixed->add(xGasMAPos);
2146  pStrawMixed->add(pGasMA);
2147 
2148  // Outer Dead region for mixed straws, part II:
2149  GeoSerialDenominator *nDeadMA = new GeoSerialDenominator("DeadRegionL");
2150  GeoTransform *xDeadPosMA = new GeoTransform(GeoTrf::TranslateZ3D(+(m_data->barrelLengthOfStraw-m_data->lengthOfDeadRegion)/2.0));
2151  GeoTransform *xDeadNegMA = new GeoTransform(GeoTrf::TranslateZ3D(-(m_data->barrelLengthOfStraw-m_data->lengthOfDeadRegion)/2.0));
2152 
2153  // Assemble dead regions within straws:
2154  pStrawMixed->add(nDeadMA);
2155  pStrawMixed->add(xDeadPosMA);
2156  pStrawMixed->add(pDeadRegion);
2157  pStrawMixed->add(xDeadNegMA);
2158  pStrawMixed->add(pDeadRegion);
2159 
2160  // InnerDeadRegions, part III:
2161  GeoSerialDenominator *nInnerDeadMA = new GeoSerialDenominator("InnerDeadRegionL");
2162  GeoTransform *xInnerDeadPosMA = new GeoTransform(GeoTrf::TranslateZ3D(+posInnerDeadRegion));
2163  GeoTransform *xInnerDeadNegMA = new GeoTransform(GeoTrf::TranslateZ3D(-posInnerDeadRegion));
2164  // add to mixedStraw:
2165  pStrawMixed->add(nInnerDeadMA);
2166  pStrawMixed->add(xInnerDeadPosMA);
2167  pStrawMixed->add(pInnerDeadRegion);
2168  pStrawMixed->add(xInnerDeadNegMA);
2169  pStrawMixed->add(pInnerDeadRegion);
2170 
2171  // Assemble twisters within straws.
2172  GeoNameTag *nTwister = new GeoNameTag("TwisterM");
2173  pStrawMixed->add(nTwister);
2174  pStrawMixed->add(pTwister);
2175 
2176  // Assemble wires within straws.
2177  GeoNameTag *nWire = new GeoNameTag("WireM");
2178  pStrawMixed->add(nWire);
2179  pStrawMixed->add(pWire);
2180 
2181  pHole->add(pStrawMixed);
2182 
2183  return pHole;
2184 }
2186 
2187 
2188 
2190 //
2191 //GeoFullPhysVol * TRTDetectorFactory_Full::makeStrawPlane(size_t w) const {
2192 GeoFullPhysVol * TRTDetectorFactory_Full::makeStrawPlane(size_t w, ActiveGasMixture gasMixture) {
2193  // -----------------------------------------------------------------------------------//
2194  // //
2195  // There are twelve straw planes; however there are only two kinds, one for sector //
2196  // A & B, and one for sector C. We call the first "type 1" and the second "type 2" //
2197  // In order to economize, we shall only create two planes. //
2198  // -----------------------------------------------------------------------------------//
2199 
2200  size_t nstraws=0;
2201 
2202  //A and B wheels have similar straw planes, but the C wheels are different.
2203  // const size_t firstIndexOfC = 15; //hardcoded
2204  const size_t firstIndexOfC = 14; //hardcoded
2205 
2206  unsigned iplane = 0;
2207  if (gasMixture == GM_ARGON) {
2208  iplane = 1;
2209  }
2210  else if (gasMixture == GM_KRYPTON) {
2211  iplane = 2;
2212  }
2213 
2214  if (w>=firstIndexOfC) {
2215  if (m_type2Planes[iplane] != nullptr) {
2216  return m_type2Planes[iplane];
2217  }
2218  nstraws=m_data->endcapNumberOfStrawsInStrawLayer_CWheels;
2219  }
2220  else {
2221  if (m_type1Planes[iplane] != nullptr) {
2222  return m_type1Planes[iplane];
2223  }
2224  nstraws=m_data->endcapNumberOfStrawsInStrawLayer_AWheels;
2225  //Check here that (m_data->endcapNumberOfStrawsInStrawLayer_AWheels == m_data->endcapNumberOfStrawsInStrawLayer_BWheels) !!
2226  }
2227 
2228  double MultiplierForStrawLength = 0.999;//TK: update... to avoid conflicts? should be 0.9999??
2229 
2230  double ldead = m_data->lengthOfDeadRegion;
2231  double r0 = m_data->outerRadiusOfWire;
2232  double r1 = m_data->innerRadiusOfStraw;
2233  double r2 = m_data->outerRadiusOfStraw;
2234 
2235  double R0, R1;
2236  if (w >= firstIndexOfC) {
2237  //C wheels:
2238  R0 = m_data->endcapOuterRadiusOfInnerSupport_wheelC;
2239  R1 = m_data->endcapInnerRadiusOfOuterSupport_wheelC;
2240  } else {
2241  //A and B wheels:
2242  R0 = m_data->endcapOuterRadiusOfInnerSupport_wheelAB;
2243  R1 = m_data->endcapInnerRadiusOfOuterSupport_wheelAB;
2244  }
2245 
2246  double Length = (R1-R0)*MultiplierForStrawLength;//TK update
2247  double pos = 0.5*(R0+R1);
2248 
2249 
2250  GeoFullPhysVol *pStrawPlane=nullptr;//TK update
2251  GeoTube *sStrawPlane = new GeoTube(R0,R1,r2);
2252  GeoLogVol *lStrawPlane = new GeoLogVol("StrawPlane", sStrawPlane, m_materialManager->getMaterial("trt::CO2"));
2253  pStrawPlane = new GeoFullPhysVol(lStrawPlane); //TK update
2254 
2255 
2256  GeoTube *sStraw = new GeoTube( 0, r2, Length/2.0);
2257  GeoLogVol *lStraw = new GeoLogVol("Straw",sStraw, m_materialManager->getMaterial("trt::Straw"));
2258  GeoPhysVol *pStraw = new GeoPhysVol(lStraw);
2259 
2260  // Positioning of straws :
2261  double dphi = 2*M_PI/ nstraws;
2262  GeoTrf::RotateZ3D Rz(1.0);// Radians!
2263  GeoTrf::TranslateX3D Tx(1.0);// MM! TK: actually this doesnt need to be interpreted as mm? Just as a dimensionless 1. (i guess)
2264  GeoTrf::TranslateY3D Ty(1.0);// MM!
2265  Variable i;
2266  Sin sin;
2267  Cos cos;
2268  TRANSFUNCTION tx = Pow(Tx,pos*cos(dphi*i))*Pow(Ty,pos*sin(dphi*i))*Pow(Rz,dphi*i)*GeoTrf::RotateY3D(-90*GeoModelKernelUnits::deg);
2269  GeoSerialTransformer *serialTransformer=new GeoSerialTransformer(pStraw, &tx, nstraws);
2270  pStrawPlane->add(new GeoSerialIdentifier(0));
2271  pStrawPlane->add(serialTransformer);
2272 
2273  // Give this parameterization also to the readout geometry:
2274  if (w<firstIndexOfC) {
2277  }
2278  else {
2280  }
2281 
2282  // Gas :
2283  // (Function TRTConstructionOfTube::ConstructAndPosition #2)
2284  GeoTube *sGas = new GeoTube (r0,r1,(Length-2*ldead)/2);
2285  GeoLogVol *lGas = nullptr;
2286  if (gasMixture == GM_ARGON)
2287  lGas = new GeoLogVol("Gas_Ar", sGas, m_materialManager->getMaterial("trt::ArCO2O2"));
2288  else if (gasMixture == GM_KRYPTON)
2289  lGas = new GeoLogVol("Gas_Kr", sGas, m_materialManager->getMaterial("trt::KrCO2O2"));
2290  else
2291  lGas = new GeoLogVol("Gas", sGas, m_materialManager->getMaterial((m_useOldActiveGasMixture ? "trt::XeCO2CF4" : "trt::XeCO2O2")));
2292  GeoPhysVol *pGas = new GeoPhysVol(lGas);
2293  pStraw->add(pGas);
2294 
2295  // Dead region :
2296  GeoTube *sDeadRegion = new GeoTube(r0,r1,ldead/2);
2297  GeoLogVol *lDeadRegion = nullptr;
2298  if (gasMixture == GM_ARGON)
2299  lDeadRegion = new GeoLogVol("DeadRegion_Ar",sDeadRegion,m_materialManager->getMaterial("trt::ArCO2O2"));
2300  else if (gasMixture == GM_KRYPTON)
2301  lDeadRegion = new GeoLogVol("DeadRegion_Kr",sDeadRegion,m_materialManager->getMaterial("trt::KrCO2O2"));
2302  else
2303  lDeadRegion = new GeoLogVol("DeadRegion",sDeadRegion,m_materialManager->getMaterial((m_useOldActiveGasMixture ? "trt::XeCO2CF4" : "trt::XeCO2O2")));
2304  GeoPhysVol *pDeadRegion = new GeoPhysVol(lDeadRegion);
2305 
2306  GeoTransform *xDeadPos = new GeoTransform(GeoTrf::TranslateZ3D(+(Length/2-ldead/2)));
2307  GeoTransform *xDeadNeg = new GeoTransform(GeoTrf::TranslateZ3D(-(Length/2-ldead/2)));
2308  pStraw->add(xDeadPos);
2309  pStraw->add(pDeadRegion);
2310  pStraw->add(xDeadNeg);
2311  pStraw->add(pDeadRegion);
2312 
2313 
2314  // Wire :
2315  GeoTube *sWire = new GeoTube( 0, r0, Length/2);
2316  GeoLogVol *lWire = new GeoLogVol("Wire", sWire, m_materialManager->getMaterial("trt::Wire"));
2317  GeoPhysVol *pWire = new GeoPhysVol(lWire);
2318  pStraw->add(pWire);
2319 
2320  if (w>=firstIndexOfC) {
2321  m_type2Planes[iplane] = pStrawPlane;
2322  }
2323  else {
2324  m_type1Planes[iplane] = pStrawPlane;
2325  }
2326  return pStrawPlane;
2327 
2328 }
2329 
2330 
2332  {
2333  ActiveGasMixture return_agm = GM_XENON;
2334  if (m_strawsvcavailable && m_doArgon && (strawStatusHT == TRTCond::StrawStatus::Dead ||
2335  strawStatusHT == TRTCond::StrawStatus::Argon))
2336  return_agm = GM_ARGON;
2337  else if (m_strawsvcavailable && m_doKrypton && (strawStatusHT == TRTCond::StrawStatus::Krypton))
2338  return_agm = GM_KRYPTON;
2339  else if (m_strawsvcavailable && strawStatusHT != TRTCond::StrawStatus::Xenon &&
2340  strawStatusHT != TRTCond::StrawStatus::Good &&
2341  strawStatusHT != TRTCond::StrawStatus::Dead &&
2342  strawStatusHT != TRTCond::StrawStatus::Argon &&
2343  strawStatusHT != TRTCond::StrawStatus::Krypton &&
2344  strawStatusHT != TRTCond::StrawStatus::EmulateArgon &&
2345  strawStatusHT != TRTCond::StrawStatus::EmulateKrypton)
2346  {
2347  msg(MSG::FATAL) << "Unexpected StatusHT value: " << strawStatusHT << endmsg;
2348  throw std::runtime_error("Unexpected StatusHT value");
2349  }
2350  return return_agm;
2351  }
2352 
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
TRTDetectorFactory_Full::TRTDetectorFactory_Full
TRTDetectorFactory_Full(InDetDD::AthenaComps *athenaComps, const ITRT_StrawStatusSummaryTool *sumTool, bool useOldActiveGasMixture, bool DC2CompatibleBarrelCoordinates, int overridedigversion, bool alignable, bool doArgon, bool doKrypton, bool useDynamicAlignmentFolders)
Definition: TRTDetectorFactory_Full.cxx:85
beamspotman.r
def r
Definition: beamspotman.py:676
fillPileUpNoiseLumi.current
current
Definition: fillPileUpNoiseLumi.py:52
TRT_DetDescrDB_ParameterInterface.h
InDetDD::TRT_DetectorManager::manageBarrelElement
void manageBarrelElement(TRT_BarrelElement *barrel)
Definition: TRT_DetectorManager.cxx:92
InDetDD::TRT_DetectorManager::conditions
const TRT_Conditions * conditions() const
Conditions interface (mostly for internal use):-------------------------—.
Definition: TRT_DetectorManager.cxx:509
magn
double magn(GeoTrf::Vector2D &vector)
Definition: TRTDetectorFactory_Full.cxx:79
TRT_ID::layer_id
Identifier layer_id(int barrel_ec, int phi_module, int layer_or_wheel, int straw_layer) const
For an individual straw layer.
Definition: TRT_ID.h:500
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
InDetDD::TRT_DetectorManager::addAlignableTransform
void addAlignableTransform(int level, const Identifier &id, GeoAlignableTransform *transform, const GeoVFullPhysVol *child=0, const GeoVFullPhysVol *frameVol=0)
Add alignable transforms: GeoModel/CLHEP based.
Definition: TRT_DetectorManager.cxx:282
InDetDD::TRT_BarrelElement
Definition: TRT_BarrelElement.h:44
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
InDetDD::InDetDetectorManager::addSpecialFolder
void addSpecialFolder(const std::string &key)
Definition: InDetDetectorManager.cxx:71
TRTDetectorFactory_Full::GM_KRYPTON
@ GM_KRYPTON
Definition: TRTDetectorFactory_Full.h:69
TRTDetectorFactory_Full::m_doArgon
bool m_doArgon
Definition: TRTDetectorFactory_Full.h:101
TRT_DetDescrDB_ParameterInterface
Definition: TRT_DetDescrDB_ParameterInterface.h:16
TRTDetectorFactory_Full::m_alignable
bool m_alignable
Definition: TRTDetectorFactory_Full.h:98
rotate
void rotate(double angler, GeoTrf::Vector2D &vector)
Definition: TRTDetectorFactory_Full.cxx:63
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
InDetDD::TRT_DetectorManager::setEndcapDescriptor
void setEndcapDescriptor(const TRT_EndcapDescriptor *endcapDescriptor)
Definition: TRT_DetectorManager.cxx:591
CondAttrListCollection.h
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
python.Constants.FATAL
int FATAL
Definition: Control/AthenaCommon/python/Constants.py:19
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
PlotCalibFromCool.yy
yy
Definition: PlotCalibFromCool.py:714
InDetDD::TRT_EndcapElement::setNextInZ
void setNextInZ(const TRT_EndcapElement *element)
Set Next in Z.
Definition: TRT_EndcapElement.cxx:88
InDetDD::TRT_EndcapDescriptor::innerRadius
double & innerRadius()
The inner radius:
Definition: TRT_EndcapDescriptor.cxx:49
GeoNodePtr.h
InDetDD::timedependent_run2
@ timedependent_run2
Definition: InDetDD_Defs.h:19
TRTCond::StrawStatusMultChanContainer
Definition: StrawStatusMultChanContainer.h:19
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
InDetDD::TRT_DetectorManager::getBarrelElement
const TRT_BarrelElement * getBarrelElement(unsigned int positive, unsigned int moduleIndex, unsigned int phiIndex, unsigned int strawLayerIndex) const
Access Barrel Elements:---------------—(Fast)-------------------------—.
Definition: TRT_DetectorManager.cxx:103
InDetDD::TRT_DetectorManager::setBarrelTransformField
void setBarrelTransformField(size_t i, const GeoXF::Function *field)
Definition: TRT_DetectorManager.cxx:186
InDetDD::AthenaComps
Class to hold various Athena components.
Definition: InDetDDAthenaComps.h:21
InDetDD::TRT_BarrelDescriptor
Definition: TRT_BarrelDescriptor.h:40
InDetDD::TRT_Numerology::setNBarrelLayers
void setNBarrelLayers(unsigned int module, unsigned int nLayers)
Definition: TRT_Numerology.cxx:25
TRT_ID.h
This is an Identifier helper class for the TRT subdetector. This class is a factory for creating comp...
TRTDetectorFactory_Full::GM_XENON
@ GM_XENON
Definition: TRTDetectorFactory_Full.h:68
M_PI
#define M_PI
Definition: ActiveFraction.h:11
InDetDD::TRT_EndcapElement
Definition: TRT_EndcapElement.h:44
TRTDetectorFactory_Full::GM_ARGON
@ GM_ARGON
Definition: TRTDetectorFactory_Full.h:70
deg
#define deg
Definition: SbPolyhedron.cxx:17
InDetDD::InDetDetectorManager::setVersion
void setVersion(const Version &version)
Definition: InDetDetectorManager.cxx:43
InDetDD::TRT_Numerology::setNEndcapLayers
void setNEndcapLayers(unsigned int wheel, unsigned int nLayers)
Definition: TRT_Numerology.cxx:29
InDetDD::Version
Definition: Version.h:24
GeoNodePtr
GeoIntrusivePtr< T > GeoNodePtr
Definition: GeoNodePtr.h:12
InDetDD::TRT_EndcapDescriptor::nStraws
unsigned int & nStraws()
The number of straws in a module:
Definition: TRT_EndcapDescriptor.cxx:33
InDetDD::static_run1
@ static_run1
Definition: InDetDD_Defs.h:19
ExtraMaterial.h
TRT_ID::barrel_ec_id
Identifier barrel_ec_id(int barrel_ec) const
For +/-barrel or +/-endcap id.
Definition: TRT_ID.h:417
TRTDetectorFactory_Full::m_type1Planes
GeoFullPhysVol * m_type1Planes[3]
Definition: TRTDetectorFactory_Full.h:105
TRTDetectorFactory_Full::makeStraw
GeoPhysVol * makeStraw(bool hasLargeDeadRegion=false, ActiveGasMixture gasMixture=GM_XENON)
Definition: TRTDetectorFactory_Full.cxx:2071
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
InDetDD::global
@ global
Definition: InDetDD_Defs.h:16
TRTDetectorFactory_Full::m_materialManager
std::unique_ptr< InDetMaterialManager > m_materialManager
Definition: TRTDetectorFactory_Full.h:92
IdDictManager.h
TRTDetectorFactory_Full::m_data
std::unique_ptr< TRTParameterInterface > m_data
Definition: TRTDetectorFactory_Full.h:93
TRTDetectorFactory_Full::DecideGasMixture
ActiveGasMixture DecideGasMixture(int strawStatusHT)
Definition: TRTDetectorFactory_Full.cxx:2331
TRTDetectorFactory_Full::makeModule
const GeoShape * makeModule(double length, const GeoTrf::Vector2D &corner1, const GeoTrf::Vector2D &corner2, const GeoTrf::Vector2D &corner3, const GeoTrf::Vector2D &corner4, GeoTrf::Transform3D &absolutePosition, double shrinkDist=0) const
Definition: TRTDetectorFactory_Full.cxx:1952
InDetDD::TRT_DetectorManager::barrelTransformField
const GeoXF::Function * barrelTransformField(size_t i) const
Definition: TRT_DetectorManager.cxx:191
InDetDD::DetectorFactoryBase::msg
MsgStream & msg(MSG::Level lvl) const
Definition: InDetDetectorFactoryBase.h:37
x
#define x
InDetDD::InDetDetectorManager::addAlignFolderType
void addAlignFolderType(const AlignFolderType alignfolder)
Definition: InDetDetectorManager.cxx:81
TRTCond::StrawStatus::Dead
@ Dead
Definition: StrawStatus.h:18
InDetDD::TRT_BarrelElement::setNextInPhi
void setNextInPhi(const TRT_BarrelElement *element)
Sets the next-in-phi detector.
Definition: TRT_BarrelElement.cxx:77
TRTDetectorFactory_Full::m_useOldActiveGasMixture
bool m_useOldActiveGasMixture
Definition: TRTDetectorFactory_Full.h:95
ITRT_StrawStatusSummaryTool::getStatusHT
virtual int getStatusHT(const Identifier, const EventContext &) const =0
InDetDD::ExtraMaterial::add
void add(GeoPhysVol *parent, const std::string &parentName, double zPos=0)
Definition: ExtraMaterial.cxx:42
pi
#define pi
Definition: TileMuonFitter.cxx:65
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
TRTDetectorFactory_Full::m_DC2CompatibleBarrelCoordinates
bool m_DC2CompatibleBarrelCoordinates
Definition: TRTDetectorFactory_Full.h:96
InDetDD::TRT_BarrelElement::setNextInR
void setNextInR(const TRT_BarrelElement *element)
Sets the next-in-r detector.
Definition: TRT_BarrelElement.cxx:87
TRTCond::StrawStatus::EmulateKrypton
@ EmulateKrypton
Definition: StrawStatus.h:18
InDetDD::TRT_EndcapDescriptor
class TRT_EndcapDescriptor
Definition: TRT_EndcapDescriptor.h:30
InDetDD::TRT_DetectorManager::addTreeTop
void addTreeTop(const PVLink &)
Definition: TRT_DetectorManager.cxx:87
GeoGenfun::ArrayFunction
Definition: ArrayFunction.h:16
InDetDD::TRT_DetectorManager::manageEndcapElement
void manageEndcapElement(TRT_EndcapElement *endcap)
Definition: TRT_DetectorManager.cxx:98
InDetDD::TRT_EndcapDescriptor::setStrawTransformField
void setStrawTransformField(const GeoXF::Function *xf, size_t offsetInto)
Sets the transform field for straws and offset.
Definition: TRT_EndcapDescriptor.cxx:28
cm
const double cm
Definition: Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/tools/FCAL_ChannelMap.cxx:25
InDetDD::TRT_Numerology::setNBarrelRings
void setNBarrelRings(unsigned int ring)
Definition: TRT_Numerology.cxx:33
Version.h
InDetDD::TRT_Numerology::getNEndcapWheels
unsigned int getNEndcapWheels() const
GeoPrimitives.h
TRTDetectorFactory_Full::getDetectorManager
virtual const InDetDD::TRT_DetectorManager * getDetectorManager() const override
Definition: TRTDetectorFactory_Full.cxx:114
TRTDetectorFactory_Full::create
virtual void create(GeoPhysVol *world) override
Definition: TRTDetectorFactory_Full.cxx:133
TRT_EndcapElement.h
TRT_DetDescrDB_ParameterInterface::scalingTable
IRDBRecordset_ptr scalingTable() const
Definition: TRT_DetDescrDB_ParameterInterface.h:31
TRT_EndcapDescriptor.h
InDetDD::TRT_DetectorManager::getNumerology
TRT_Numerology * getNumerology()
Access Numerological information:---------------------------------------—.
Definition: TRT_DetectorManager.cxx:46
TRTDetectorFactory_Full::m_sumTool
const ITRT_StrawStatusSummaryTool * m_sumTool
Definition: TRTDetectorFactory_Full.h:99
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
InDetDD_Defs.h
InDetDD::TRT_Numerology::setNEndcapWheels
void setNEndcapWheels(unsigned int wheel)
Definition: TRT_Numerology.cxx:41
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
InDetDD::TRT_DetectorManager::endcapTransformField
const GeoXF::Function * endcapTransformField(size_t i) const
Definition: TRT_DetectorManager.cxx:200
InDetDD::DetectorFactoryBase::detStore
StoreGateSvc * detStore()
Definition: InDetDetectorFactoryBase.h:27
TrigVtx::gamma
@ gamma
Definition: TrigParticleTable.h:26
lumiFormat.i
int i
Definition: lumiFormat.py:85
z
#define z
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
AlignableTransformContainer.h
angle
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
Definition: TRTDetectorFactory_Full.cxx:73
InDetDD::InDetDetectorManager::addFolder
void addFolder(const std::string &key)
Definition: InDetDetectorManager.cxx:66
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
TRTDetectorFactory_Full::ActiveGasMixture
ActiveGasMixture
Definition: TRTDetectorFactory_Full.h:67
TRT_PAI_physicsConstants::r0
const double r0
electron radius{cm}
Definition: TRT_PAI_physicsConstants.h:20
sign
int sign(int a)
Definition: TRT_StrawNeighbourSvc.h:107
InDetDDAthenaComps.h
InDetDD::InDetDetectorManager::addGlobalFolder
void addGlobalFolder(const std::string &key)
Definition: InDetDetectorManager.cxx:76
TRT_BarrelDescriptor.h
InDetDD::TRT_Numerology::setNBarrelPhi
void setNBarrelPhi(unsigned int phi)
Definition: TRT_Numerology.cxx:37
InDetDD::TRT_Numerology::getNBarrelLayers
unsigned int getNBarrelLayers(unsigned int iMod) const
python.SystemOfUnits.micrometer
int micrometer
Definition: SystemOfUnits.py:71
TRT_BarrelElement.h
ITRT_StrawStatusSummaryTool
Definition: ITRT_StrawStatusSummaryTool.h:27
TRTCond::StrawStatus::EmulateArgon
@ EmulateArgon
Definition: StrawStatus.h:18
TRTCond::StrawStatus::Good
@ Good
Definition: StrawStatus.h:18
InDetDD::TRT_DetectorManager::getEndcapElement
const TRT_EndcapElement * getEndcapElement(unsigned int positive, unsigned int wheelIndex, unsigned int strawLayerIndex, unsigned int phiIndex) const
Access Endcap Elements:---------------—(Fast)--------------------------—.
Definition: TRT_DetectorManager.cxx:119
InDetDD::TRT_EndcapDescriptor::startPhi
double & startPhi()
The starting phi (angular!!)
Definition: TRT_EndcapDescriptor.cxx:41
ArrayFunction.h
AtlasDetectorID::print_to_string
std::string print_to_string(Identifier id, const IdContext *context=0) const
or provide the printout in string form
Definition: AtlasDetectorID.cxx:655
TRTCond::StrawStatus::Xenon
@ Xenon
Definition: StrawStatus.h:18
InDetDD::TRT_DetectorManager::setGasType
void setGasType(const ActiveGasType &)
Definition: TRT_DetectorManager.cxx:210
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
InDetDD::TRT_DetectorManager::digitizationVersionName
const std::string & digitizationVersionName() const
Definition: TRT_DetectorManager.cxx:220
InDetDD::TRT_Numerology::setNEndcapPhi
void setNEndcapPhi(unsigned int phi)
Definition: TRT_Numerology.cxx:45
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Variable
Wrapper around a histogram which allows for some additional filling patterns and data manipulation.
Definition: Trigger/TrigCost/TrigCostAnalysis/src/Variable.h:39
TRTDetectorFactory_Full::m_detectorManager
InDetDD::TRT_DetectorManager * m_detectorManager
Definition: TRTDetectorFactory_Full.h:91
InDetDD::TRT_DetectorManager::setIdHelper
void setIdHelper(const TRT_ID *idHelper, bool owns=true)
Get the ID helper: -----------------------------------------------------—.
Definition: TRT_DetectorManager.cxx:140
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
InDetDD::TRT_DetectorManager::oldgas
@ oldgas
Definition: TRT_DetectorManager.h:89
get_generator_info.version
version
Definition: get_generator_info.py:33
InDetDD::TRT_EndcapDescriptor::strawPitch
double & strawPitch()
The straw pitch (angular!!)
Definition: TRT_EndcapDescriptor.cxx:37
TRTDetectorFactory_Full::m_useDynamicAlignFolders
bool m_useDynamicAlignFolders
Definition: TRTDetectorFactory_Full.h:103
TRT_ID
Definition: TRT_ID.h:84
InDetDD::TRT_DetectorManager
The Detector Manager for all TRT Detector elements, it acts as the interface to the detector elements...
Definition: TRT_DetectorManager.h:69
a
TList * a
Definition: liststreamerinfos.cxx:10
InDetDD::TRT_DetectorManager::newgas
@ newgas
Definition: TRT_DetectorManager.h:89
TRTDetectorFactory_Full::m_type2Planes
GeoFullPhysVol * m_type2Planes[3]
Definition: TRTDetectorFactory_Full.h:106
y
#define y
TRTDetectorFactory_Full::m_overridedigversion
int m_overridedigversion
Definition: TRTDetectorFactory_Full.h:97
GeoGenfun
Definition: ArrayFunction.cxx:7
InDetDD
Message Stream Member.
Definition: FakeTrackBuilder.h:8
InDetDD::TRT_EndcapDescriptor::strawLength
double & strawLength()
Definition: TRT_EndcapDescriptor.cxx:45
InDetDD::TRT_DetectorManager::digitizationVersion
unsigned int digitizationVersion() const
Get and set information about digitization version ---------------------—.
Definition: TRT_DetectorManager.cxx:215
DeMoScan.first
bool first
Definition: DeMoScan.py:536
InDetDD::TRT_DetectorManager::setEndcapTransformField
void setEndcapTransformField(size_t i, const GeoXF::Function *field)
Definition: TRT_DetectorManager.cxx:195
InDetDD::TRT_DetectorManager::setDigitizationVersion
void setDigitizationVersion(const unsigned int &, const std::string &name)
Definition: TRT_DetectorManager.cxx:225
TRT_Numerology.h
ITRT_StrawStatusSummaryTool::getStrawStatusHTContainer
virtual const StrawStatusContainer * getStrawStatusHTContainer() const =0
InDetDD::TRT_Numerology::getNEndcapLayers
unsigned int getNEndcapLayers(unsigned int iWheel) const
TRTDetectorFactory_Full::m_strawsvcavailable
bool m_strawsvcavailable
Definition: TRTDetectorFactory_Full.h:100
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
python.IoTestsLib.w
def w
Definition: IoTestsLib.py:200
InDetDD::InDetDetectorManager::addChannel
void addChannel(const std::string &key, int level, FrameType frame)
Alignment access.
Definition: InDetDetectorManager.cxx:56
test_pyathena.counter
counter
Definition: test_pyathena.py:15
InDetDD::ExtraMaterial
Definition: ExtraMaterial.h:23
TRTCond::StrawStatus::Argon
@ Argon
Definition: StrawStatus.h:18
StoreGateSvc.h
python.compressB64.c
def c
Definition: compressB64.py:93
length
double length(const pvec &v)
Definition: FPGATrackSimLLPDoubletHoughTransformTool.cxx:26
TileDCSDataPlotter.tx
tx
Definition: TileDCSDataPlotter.py:878
TRTCond::StrawStatus::Krypton
@ Krypton
Definition: StrawStatus.h:18
InDetDD::DetectorFactoryBase::getAthenaComps
InDetDD::AthenaComps * getAthenaComps()
Definition: InDetDetectorFactoryBase.h:42
InDetDD::TRT_DetectorManager::setBarrelDescriptor
void setBarrelDescriptor(const TRT_BarrelDescriptor *barrelDescriptor)
Set TRT_Barrel/EndcapDescriptor pointer to the internal sets to delete them in the destructor.
Definition: TRT_DetectorManager.cxx:586
TRTDetectorFactory_Full.h
TRT_ID::module_id
Identifier module_id(int barrel_ec, int phi_module, int layer_or_wheel) const
For an individual module phi sector.
Definition: TRT_ID.h:448
TRT_ID::straw_id
Identifier straw_id(int barrel_ec, int phi_module, int layer_or_wheel, int straw_layer, int straw) const
Three ways of getting id for a single straw:
Definition: TRT_ID.h:581
TRTDetectorFactory_Full::makeStrawPlane
GeoFullPhysVol * makeStrawPlane(size_t w, ActiveGasMixture gasMixture=GM_XENON)
Definition: TRTDetectorFactory_Full.cxx:2192
description
std::string description
glabal timer - how long have I taken so far?
Definition: hcg.cxx:88
TRTDetectorFactory_Full::m_doKrypton
bool m_doKrypton
Definition: TRTDetectorFactory_Full.h:102
Identifier
Definition: IdentifierFieldParser.cxx:14