EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
vtx-builder.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file vtx-builder.C
1 
2 // Number of barrel layers;
3 #define _LAYER_NUM_ 4
4 
5 // Used volume names;
6 #define _STAVE_NAME_ "VtxStave"
7 #define _CHIP_NAME_ "VtxChip"
8 
9 void vtx_builder()
10 {
11  // Detector name will be "VTX"; should be consistent through
12  // all the simulation.C->digitization.C->reconstruction.C chain;
13  auto vtx = new EicGeoParData("VTX");
14 
15  // Hardcode TGeo file name (no versioning, etc);
16  vtx->SetFileName("vtx.root");
17 
18  //
19  // Hardcode all the geometry parameters for simplicity; NB: for most part of
20  // EicRoot detector types respective variables (like chip dimensions below)
21  // are EicGeoParData inherited class variables which get saved in the
22  // output file containing TGeo information; units are [cm] everywhere;
23  //
24 
25  // Layer installation radii, number of staves per layer;
26  double radius[_LAYER_NUM_] = { 4.0, 6.0, 8.0, 10.0};
27  unsigned staveNum[_LAYER_NUM_] = { 26, 39, 52, 65};
28  unsigned staveNumMax = staveNum[_LAYER_NUM_-1], staveNumSum = 0;
29 
30  // Silicon chip size;
31  double chipWidth = 1.000;
32  double chipLength = 2.000;
33  double chipThickness = 0.002;
34 
35  int chipsPerStave = 10;
36 
37  // Stave size; take more or less realistic fill factor;
38  double staveWidth = chipWidth + 0.100;
39  double staveLength = chipsPerStave*(chipLength + 0.010);
40  // Will yield ~0.3% rad.length per layer (a la ALICE MAPS);
41  double staveThickness = 0.030;
42 
43  // Assume can live with the same extra Z-slope angle (in degrees) for all layers;
44  double staveSlope = 10.0;
45 
46  // Create stave volume; use artificial carbon-like material with X0=10cm;
47  auto stave = new TGeoBBox(_STAVE_NAME_, staveWidth/2, staveLength/2, staveThickness/2);
48  auto vstave = new TGeoVolume(_STAVE_NAME_, stave, vtx->GetMedium("X0=10cm"));
49 
50  // Create chip volume;
51  auto chip = new TGeoBBox(_CHIP_NAME_, chipWidth/2, chipLength/2, chipThickness/2);
52  auto vchip = new TGeoVolume(_CHIP_NAME_, chip, vtx->GetMedium("silicon"));
53 
54  // Place chips into stave volume;
55  {
56  double step = chipLength + (staveLength - chipsPerStave*chipLength)/chipsPerStave;
57  for(int ichip=0; ichip<chipsPerStave; ichip++) {
58  double yOffset = (ichip - (chipsPerStave-1)/2.0)*step;
59 
60  vstave->AddNode(vchip, ichip, new TGeoCombiTrans(0.0, yOffset, 0.0, 0));
61  } //for ichip
62  }
63 
64  // Running variable to count stave copies placed into the MASTER volume;
65  unsigned staveCounter = 0;
66 
67  // Let it be a single logical group (all the staves are identical in all layers);
68  // ~3D indices for all chips are [stave,layer,chip] per convention;
69  unsigned group = vtx->AddLogicalVolumeGroup(_LAYER_NUM_, staveNumMax, chipsPerStave);
70 
71  // Calculate total number of staves;
72  for(unsigned ilayer=0; ilayer<_LAYER_NUM_; ilayer++)
73  staveNumSum += staveNum[ilayer];
74 
75  // And then there is a single map needed which encodes GEANT->logical id conversion;
76  auto xmap = vtx->CreateNewMap();
77  // Volumes are defined in this order (from innermost to upmost); specify max expected
78  // copy number on every level; innermost volumes are assumed sensitive (in GEANT sense)
79  // per default in the simulation.C script;
80  xmap->AddGeantVolumeLevel(_CHIP_NAME_, chipsPerStave);
81  xmap->AddGeantVolumeLevel(_STAVE_NAME_, staveNumSum);
82  xmap->SetSingleSensorContainerVolume(_CHIP_NAME_);
83 
84  // Loop through all barrel layers;
85  for(unsigned ilayer=0; ilayer<_LAYER_NUM_; ilayer++) {
86  // Loop through all the staves in this layer;
87  for(unsigned istave=0; istave<staveNum[ilayer]; istave++) {
88  // Loop through all chips in this stave and add mapping table entry for each of them;
89  //for(int ichip=0; ichip<chipsPerStave; ichip++) {
90  for(unsigned ichip=0; ichip<chipsPerStave; ichip++) {
91  // So GEANT indices (copy numbers) [chip,stave] are mapped onto 3D logical
92  // indices [layer,stave,chip];
93  UInt_t geant[2] = {ichip, staveCounter}, logical[3] = {ilayer, istave, ichip};
94 
95  if (vtx->SetMappingTableEntry(xmap, geant, group, logical)) {
96  cout << "Failed to set mapping table entry!" << endl;
97  exit(0);
98  } //if
99  } //for ichip
100 
101  // Calculate rotation angle and TGeo rotation matrix;
102  {
103  double degAngle = istave*360.0/staveNum[ilayer];
104  double radAngle = degAngle*TMath::Pi()/180.0;
105 
106  auto rw = new TGeoRotation();
107 
108  double fullAngle = degAngle + staveSlope;
109  rw->SetAngles(90.0, 0.0 - fullAngle, 180.0, 0.0, 90.0, 90.0 - fullAngle);
110 
111  // Place volume copy in the master assembly container;
112  vtx->GetTopVolume()->AddNode(vstave, staveCounter++,
113  new TGeoCombiTrans(radius[ilayer]*sin(radAngle),
114  radius[ilayer]*cos(radAngle), 0.0, rw));
115  }
116  } //for istave
117  } //for ilayer
118 
119  // Define color patterns;
120  vtx->GetColorTable()->AddPatternMatch("VtxStave", kGray);
121  vtx->GetTransparencyTable()->AddPatternMatch("VtxStave", 40);
122  vtx->GetColorTable()->AddPatternMatch("VtxChip", kYellow);
123 
124  // A unified user call which places assembled detector volume in a proper place in MASTER (top)
125  // coordinate system, puts this MASTER (top) volume into GEANT volume tree, and dumps this tree
126  // together with EicRoot mapping table in one file;
127  vtx->FinalizeOutput();
128 
129  // Yes, always exit;
130  exit(0);
131 } // vtx_builder()
132