Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHG4Prototype2OuterHcalDetector.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHG4Prototype2OuterHcalDetector.cc
2 
3 #include <phparameter/PHParameters.h>
4 
5 #include <g4main/PHG4Detector.h> // for PHG4Detector
6 
7 #include <Geant4/G4AssemblyVolume.hh>
8 #include <Geant4/G4Box.hh>
9 #include <Geant4/G4Colour.hh>
10 #include <Geant4/G4ExtrudedSolid.hh>
11 #include <Geant4/G4LogicalVolume.hh>
12 #include <Geant4/G4Material.hh>
13 #include <Geant4/G4PVPlacement.hh>
14 #include <Geant4/G4RotationMatrix.hh> // for G4RotationMatrix
15 #include <Geant4/G4String.hh> // for G4String
16 #include <Geant4/G4SystemOfUnits.hh>
17 #include <Geant4/G4ThreeVector.hh> // for G4ThreeVector
18 #include <Geant4/G4TwoVector.hh>
19 #include <Geant4/G4VPhysicalVolume.hh> // for G4VPhysicalVolume
20 #include <Geant4/G4VSolid.hh> // for G4VSolid
21 #include <Geant4/G4VisAttributes.hh>
22 
23 #include <boost/format.hpp>
24 
25 #include <cmath>
26 #include <iostream> // for operator<<, endl
27 #include <sstream>
28 #include <utility> // for pair, make_pair
29 #include <vector> // for vector, vector<>::...
30 
31 class PHCompositeNode;
32 
33 using namespace std;
34 
35 static const string scintimothername = "OuterHcalScintiMother";
36 static const string steelplatename = "OuterHcalSteelPlate";
37 
39  : PHG4Detector(subsys, Node, dnam)
40  , m_Params(parameters)
41  , m_OuterHcalSteelPlate(nullptr)
42  , m_OuterHcalAssembly(nullptr)
43  , m_SteelPlateCornerUpperLeft(1777.6 * mm, -433.5 * mm)
44  , m_SteelPlateCornerUpperRight(2600.4 * mm, -417.4 * mm)
45  , m_SteelPlateCornerLowerRight(2601.2 * mm, -459.8 * mm)
46  , m_SteelPlateCornerLowerLeft(1770.9 * mm, -459.8 * mm)
47  ,
48 
49  m_ScintiUoneFrontSize(166.2 * mm)
50  , m_ScintiUoneCornerUpperLeft(0 * mm, 0 * mm)
51  , m_ScintiUoneCornerUpperRight(828.9 * mm, 0 * mm)
52  , m_ScintiUoneCornerLowerRight(828.9 * mm, -240.54 * mm)
53  , m_ScintiUoneCornerLowerLeft(0 * mm, -m_ScintiUoneFrontSize)
54  ,
55 
56  m_ScintiU2CornerUpperLeft(0 * mm, 0 * mm)
57  , m_ScintiU2CornerUpperRight(828.9 * mm, -74.3 * mm)
58  , m_ScintiU2CornerLowerRight(828.9 * mm, -320.44 * mm)
59  , m_ScintiU2CornerLowerLeft(0 * mm, -171.0 * mm)
60  ,
61 
62  m_ScintiT9DistanceToCorner(0.86 * mm)
63  , m_ScintiT9FrontSize(241.5 * mm)
64  , m_ScintiT9CornerUpperLeft(0 * mm, 0 * mm)
65  , m_ScintiT9CornerUpperRight(697.4 * mm, -552.2 * mm)
66  , m_ScintiT9CornerLowerRight(697.4 * mm, -697.4 * mm / tan(47.94 / 180. * M_PI) - m_ScintiT9FrontSize)
67  , m_ScintiT9CornerLowerLeft(0 * mm, -m_ScintiT9FrontSize)
68  ,
69 
70  m_ScintiT10FrontSize(241.4 * mm)
71  , m_ScintiT10CornerUpperLeft(0 * mm, 0 * mm)
72  , m_ScintiT10CornerUpperRight(697.4 * mm, -629.3 * mm)
73  , m_ScintiT10CornerLowerRight(697.4 * mm, -697.4 * mm / tan(44.2 / 180. * M_PI) - m_ScintiT10FrontSize)
74  , m_ScintiT10CornerLowerLeft(0 * mm, -m_ScintiT10FrontSize)
75  ,
76 
77  m_ScintiT11FrontSize(241.4 * mm)
78  , m_ScintiT11CornerUpperLeft(0 * mm, 0 * mm)
79  , m_ScintiT11CornerUpperRight(697.4 * mm, -717.1 * mm)
80  , m_ScintiT11CornerLowerRight(697.4 * mm, -697.4 * mm / tan(42.47 / 180. * M_PI) - m_ScintiT11FrontSize)
81  , m_ScintiT11CornerLowerLeft(0 * mm, -m_ScintiT11FrontSize)
82  ,
83 
84  m_ScintiT12FrontSize(312.7 * mm)
85  , m_ScintiT12CornerUpperLeft(0 * mm, 0 * mm)
86  , m_ScintiT12CornerUpperRight(697.4 * mm, -761.8 * mm)
87  , m_ScintiT12CornerLowerRight(392.9 * mm, -827.7)
88  , m_ScintiT12CornerLowerLeft(0 * mm, -m_ScintiT12FrontSize)
89  ,
90 
91  m_ScintiX(828.9)
92  , m_ScintiXHiEta(697.4 * mm + 121.09 * mm)
93  , m_SteelZ(1600. * mm)
94  , m_SizeZ(m_SteelZ)
95  , m_ScintiTileZ(m_SteelZ)
96  , m_ScintiTileThickness(7 * mm)
97  , m_ScintiBoxSmaller(0.02 * mm)
98  , // blargh - off by 20 microns bc scinti tilt angle, need to revisit at some point
99  m_GapBetweenTiles(1 * mm)
100  , m_ScintiGap(8.5 * mm)
101  , m_TiltAngle(12 * deg)
102  , m_DeltaPhi(2 * M_PI / 320.)
103  , m_VolumeSteel(NAN)
104  , m_VolumeScintillator(NAN)
105  , m_NScintiPlates(20)
106  , m_NSteelPlates(m_NScintiPlates + 1)
107  , m_ActiveFlag(m_Params->get_int_param("active"))
108  , m_AbsorberActiveFlag(m_Params->get_int_param("absorberactive"))
109  , m_Layer(0)
110 {
111 }
112 
114 {
115  delete m_OuterHcalAssembly;
116 }
117 
118 //_______________________________________________________________
119 //_______________________________________________________________
121 {
122  G4LogicalVolume* logvol = volume->GetLogicalVolume();
124  {
125  return -1;
126  }
127  if (m_ActiveFlag && m_ActiveVolumeSet.find(logvol) != m_ActiveVolumeSet.end())
128  {
129  return 1;
130  }
131  return 0;
132 }
133 
134 G4LogicalVolume*
136 {
138  {
139  G4VSolid* steel_plate;
140  std::vector<G4TwoVector> vertexes;
141  vertexes.push_back(m_SteelPlateCornerUpperLeft);
142  vertexes.push_back(m_SteelPlateCornerUpperRight);
143  vertexes.push_back(m_SteelPlateCornerLowerRight);
144  vertexes.push_back(m_SteelPlateCornerLowerLeft);
145  G4TwoVector zero(0, 0);
146  steel_plate = new G4ExtrudedSolid("OuterHcalSteelPlateSolid",
147  vertexes,
148  m_SizeZ / 2.0,
149  zero, 1.0,
150  zero, 1.0);
151 
152  m_VolumeSteel = steel_plate->GetCubicVolume() * m_NSteelPlates;
153  m_OuterHcalSteelPlate = new G4LogicalVolume(steel_plate, G4Material::GetMaterial("Steel_A36"), "OuterHcalSteelPlate", 0, 0, 0);
154  G4VisAttributes visattchk;
155  visattchk.SetVisibility(true);
156  visattchk.SetForceSolid(false);
157  visattchk.SetColour(G4Colour::Blue());
158  m_OuterHcalSteelPlate->SetVisAttributes(visattchk);
159  }
160  return m_OuterHcalSteelPlate;
161 }
162 
163 G4LogicalVolume*
165 {
166  int copynum = 0;
167  G4VSolid* scintiboxsolid = new G4Box(scintimothername, m_ScintiX / 2., (m_ScintiGap - m_ScintiBoxSmaller) / 2., m_ScintiTileZ / 2.);
168  // DisplayVolume(scintiboxsolid,hcalenvelope);
169  G4LogicalVolume* scintiboxlogical = new G4LogicalVolume(scintiboxsolid, G4Material::GetMaterial("G4_AIR"), G4String(scintimothername), 0, 0, 0);
170  G4VisAttributes* hcalVisAtt = new G4VisAttributes();
171  hcalVisAtt->SetVisibility(true);
172  hcalVisAtt->SetForceSolid(false);
173  hcalVisAtt->SetColour(G4Colour::Red());
174  G4LogicalVolume* scintiu1_logic = ConstructScintiTileU1(hcalenvelope);
175  scintiu1_logic->SetVisAttributes(hcalVisAtt);
176 
177  hcalVisAtt = new G4VisAttributes();
178  hcalVisAtt->SetVisibility(true);
179  hcalVisAtt->SetForceSolid(false);
180  hcalVisAtt->SetColour(G4Colour::Cyan());
181  G4LogicalVolume* scintiu2_logic = ConstructScintiTileU2(hcalenvelope);
182  scintiu2_logic->SetVisAttributes(hcalVisAtt);
183  G4RotationMatrix* Rot;
184  Rot = new G4RotationMatrix();
185  Rot->rotateX(-90 * deg);
186  new G4PVPlacement(Rot, G4ThreeVector(-m_ScintiX / 2., 0, -m_ScintiUoneFrontSize - m_GapBetweenTiles / 2. - m_GapBetweenTiles), scintiu2_logic, (boost::format("OuterScinti_%d") % copynum).str(), scintiboxlogical, false, copynum, OverlapCheck());
187 
188  Rot = new G4RotationMatrix();
189  Rot->rotateX(-90 * deg);
190  copynum++;
191  new G4PVPlacement(Rot, G4ThreeVector(-m_ScintiX / 2., 0, -m_GapBetweenTiles / 2.), scintiu1_logic, (boost::format("OuterScinti_%d") % copynum).str(), scintiboxlogical, false, copynum, OverlapCheck());
192 
193  Rot = new G4RotationMatrix();
194  Rot->rotateX(90 * deg);
195  copynum++;
196  new G4PVPlacement(Rot, G4ThreeVector(-m_ScintiX / 2., 0, m_GapBetweenTiles / 2.), scintiu1_logic, (boost::format("OuterScinti_%d") % copynum).str(), scintiboxlogical, false, copynum, OverlapCheck());
197 
198  Rot = new G4RotationMatrix();
199  Rot->rotateX(90 * deg);
200  copynum++;
201  new G4PVPlacement(Rot, G4ThreeVector(-m_ScintiX / 2., 0, m_ScintiUoneFrontSize + m_GapBetweenTiles / 2. + m_GapBetweenTiles), scintiu2_logic, (boost::format("OuterScinti_%d") % copynum).str(), scintiboxlogical, false, copynum, OverlapCheck());
202 
203  return scintiboxlogical;
204 }
205 
206 G4LogicalVolume*
208 {
209  std::vector<G4TwoVector> vertexes;
210  vertexes.push_back(m_ScintiUoneCornerUpperLeft);
211  vertexes.push_back(m_ScintiUoneCornerUpperRight);
212  vertexes.push_back(m_ScintiUoneCornerLowerRight);
213  vertexes.push_back(m_ScintiUoneCornerLowerLeft);
214  G4TwoVector zero(0, 0);
215  G4VSolid* scintiu1 = new G4ExtrudedSolid("OuterHcalScintiU1",
216  vertexes,
217  m_ScintiTileThickness / 2.0,
218  zero, 1.0,
219  zero, 1.0);
220 
221  G4LogicalVolume* scintiu1_logic = new G4LogicalVolume(scintiu1, G4Material::GetMaterial("G4_POLYSTYRENE"), "OuterHcalScintiU1", nullptr, nullptr, nullptr);
222  // DisplayVolume(scintiu1,hcalenvelope);
223  m_ActiveVolumeSet.insert(scintiu1_logic);
224  return scintiu1_logic;
225 }
226 
227 G4LogicalVolume*
229 {
230  std::vector<G4TwoVector> vertexes;
231  vertexes.push_back(m_ScintiU2CornerUpperLeft);
232  vertexes.push_back(m_ScintiU2CornerUpperRight);
233  vertexes.push_back(m_ScintiU2CornerLowerRight);
234  vertexes.push_back(m_ScintiU2CornerLowerLeft);
235  G4TwoVector zero(0, 0);
236  G4VSolid* scintiu2 = new G4ExtrudedSolid("OuterHcalScintiU2",
237  vertexes,
238  m_ScintiTileThickness / 2.0,
239  zero, 1.0,
240  zero, 1.0);
241 
242  G4LogicalVolume* scintiu2_logic = new G4LogicalVolume(scintiu2, G4Material::GetMaterial("G4_POLYSTYRENE"), "OuterHcalScintiU2", nullptr, nullptr, nullptr);
243  // DisplayVolume(scintiu2,hcalenvelope);
244  m_ActiveVolumeSet.insert(scintiu2_logic);
245  return scintiu2_logic;
246 }
247 
248 G4LogicalVolume*
250 {
251  int copynum = 0;
252  G4VSolid* scintiboxsolid = new G4Box(scintimothername, m_ScintiX / 2., (m_ScintiGap - m_ScintiBoxSmaller) / 2., m_ScintiTileZ / 2.);
253  // DisplayVolume(scintiboxsolid,hcalenvelope);
254  G4LogicalVolume* scintiboxlogical = new G4LogicalVolume(scintiboxsolid, G4Material::GetMaterial("G4_AIR"), G4String(scintimothername), 0, 0, 0);
255 
256  G4VisAttributes hcalVisAtt;
257  hcalVisAtt.SetVisibility(true);
258  hcalVisAtt.SetForceSolid(false);
259  hcalVisAtt.SetColour(G4Colour::Magenta());
260  G4LogicalVolume* scintit9_logic = ConstructScintiTile9(hcalenvelope);
261  scintit9_logic->SetVisAttributes(hcalVisAtt);
262 
263  double distance_to_corner = -m_SizeZ / 2. + m_ScintiT9DistanceToCorner;
264  G4RotationMatrix* Rot;
265  Rot = new G4RotationMatrix();
266  Rot->rotateX(90 * deg);
267  new G4PVPlacement(Rot, G4ThreeVector(-m_ScintiXHiEta / 2., 0, distance_to_corner), scintit9_logic, (boost::format("OuterScinti_%d") % copynum).str(), scintiboxlogical, false, copynum, OverlapCheck());
268 
269  hcalVisAtt.SetVisibility(true);
270  hcalVisAtt.SetForceSolid(false);
271  hcalVisAtt.SetColour(G4Colour::Blue());
272  G4LogicalVolume* scintit10_logic = ConstructScintiTile10(hcalenvelope);
273  scintit10_logic->SetVisAttributes(hcalVisAtt);
274 
275  distance_to_corner += m_ScintiT9FrontSize + m_GapBetweenTiles;
276  Rot = new G4RotationMatrix();
277  Rot->rotateX(90 * deg);
278  copynum++;
279  new G4PVPlacement(Rot, G4ThreeVector(-m_ScintiXHiEta / 2., 0, distance_to_corner), scintit10_logic, (boost::format("OuterScinti_%d") % copynum).str(), scintiboxlogical, false, copynum, OverlapCheck());
280 
281  hcalVisAtt.SetVisibility(true);
282  hcalVisAtt.SetForceSolid(false);
283  hcalVisAtt.SetColour(G4Colour::Yellow());
284  G4LogicalVolume* scintit11_logic = ConstructScintiTile11(hcalenvelope);
285  scintit11_logic->SetVisAttributes(hcalVisAtt);
286 
287  distance_to_corner += m_ScintiT10FrontSize + m_GapBetweenTiles;
288  Rot = new G4RotationMatrix();
289  Rot->rotateX(90 * deg);
290  copynum++;
291  new G4PVPlacement(Rot, G4ThreeVector(-m_ScintiXHiEta / 2., 0, distance_to_corner), scintit11_logic, (boost::format("OuterScinti_%d") % copynum).str(), scintiboxlogical, false, copynum, OverlapCheck());
292 
293  hcalVisAtt.SetVisibility(true);
294  hcalVisAtt.SetForceSolid(false);
295  hcalVisAtt.SetColour(G4Colour::Cyan());
296  G4LogicalVolume* scintit12_logic = ConstructScintiTile12(hcalenvelope);
297  scintit12_logic->SetVisAttributes(hcalVisAtt);
298 
299  distance_to_corner += m_ScintiT11FrontSize + m_GapBetweenTiles;
300  Rot = new G4RotationMatrix();
301  Rot->rotateX(90 * deg);
302  copynum++;
303  new G4PVPlacement(Rot, G4ThreeVector(-m_ScintiXHiEta / 2., 0, distance_to_corner), scintit12_logic, (boost::format("OuterScinti_%d") % copynum).str(), scintiboxlogical, false, copynum, OverlapCheck());
304  //DisplayVolume(scintiboxlogical,hcalenvelope);
305  return scintiboxlogical;
306 }
307 G4LogicalVolume*
309 {
310  std::vector<G4TwoVector> vertexes;
311  vertexes.push_back(m_ScintiT9CornerUpperLeft);
312  vertexes.push_back(m_ScintiT9CornerUpperRight);
313  vertexes.push_back(m_ScintiT9CornerLowerRight);
314  vertexes.push_back(m_ScintiT9CornerLowerLeft);
315  G4TwoVector zero(0, 0);
316  G4VSolid* scintit9 = new G4ExtrudedSolid("OuterHcalScintiT9",
317  vertexes,
318  m_ScintiTileThickness / 2.0,
319  zero, 1.0,
320  zero, 1.0);
321 
322  G4LogicalVolume* scintit9_logic = new G4LogicalVolume(scintit9, G4Material::GetMaterial("G4_POLYSTYRENE"), "OuterHcalScintiT9", nullptr, nullptr, nullptr);
323  // DisplayVolume(scintit9,hcalenvelope);
324  m_ActiveVolumeSet.insert(scintit9_logic);
325  return scintit9_logic;
326 }
327 
328 G4LogicalVolume*
330 {
331  std::vector<G4TwoVector> vertexes;
332  vertexes.push_back(m_ScintiT10CornerUpperLeft);
333  vertexes.push_back(m_ScintiT10CornerUpperRight);
334  vertexes.push_back(m_ScintiT10CornerLowerRight);
335  vertexes.push_back(m_ScintiT10CornerLowerLeft);
336  G4TwoVector zero(0, 0);
337  G4VSolid* scintit10 = new G4ExtrudedSolid("OuterHcalScintiT10",
338  vertexes,
339  m_ScintiTileThickness / 2.0,
340  zero, 1.0,
341  zero, 1.0);
342 
343  G4LogicalVolume* scintit10_logic = new G4LogicalVolume(scintit10, G4Material::GetMaterial("G4_POLYSTYRENE"), "OuterHcalScintiT10", nullptr, nullptr, nullptr);
344  // DisplayVolume(scintit10,hcalenvelope);
345  m_ActiveVolumeSet.insert(scintit10_logic);
346  return scintit10_logic;
347 }
348 
349 G4LogicalVolume*
351 {
352  std::vector<G4TwoVector> vertexes;
353  vertexes.push_back(m_ScintiT11CornerUpperLeft);
354  vertexes.push_back(m_ScintiT11CornerUpperRight);
355  vertexes.push_back(m_ScintiT11CornerLowerRight);
356  vertexes.push_back(m_ScintiT11CornerLowerLeft);
357  G4TwoVector zero(0, 0);
358  G4VSolid* scintit11 = new G4ExtrudedSolid("OuterHcalScintiT11",
359  vertexes,
360  m_ScintiTileThickness / 2.0,
361  zero, 1.0,
362  zero, 1.0);
363 
364  G4LogicalVolume* scintit11_logic = new G4LogicalVolume(scintit11, G4Material::GetMaterial("G4_POLYSTYRENE"), "OuterHcalScintiT11", nullptr, nullptr, nullptr);
365  // DisplayVolume(scintit11,hcalenvelope);
366  m_ActiveVolumeSet.insert(scintit11_logic);
367  return scintit11_logic;
368 }
369 
370 G4LogicalVolume*
372 {
373  std::vector<G4TwoVector> vertexes;
374  vertexes.push_back(m_ScintiT12CornerUpperLeft);
375  vertexes.push_back(m_ScintiT12CornerUpperRight);
376  vertexes.push_back(m_ScintiT12CornerLowerRight);
377  vertexes.push_back(m_ScintiT12CornerLowerLeft);
378  G4TwoVector zero(0, 0);
379  G4VSolid* scintit12 = new G4ExtrudedSolid("OuterHcalScintiT12",
380  vertexes,
381  m_ScintiTileThickness / 2.0,
382  zero, 1.0,
383  zero, 1.0);
384 
385  G4LogicalVolume* scintit12_logic = new G4LogicalVolume(scintit12, G4Material::GetMaterial("G4_POLYSTYRENE"), "OuterHcalScintiT12", nullptr, nullptr, nullptr);
386  // DisplayVolume(scintit12,hcalenvelope);
387  m_ActiveVolumeSet.insert(scintit12_logic);
388  return scintit12_logic;
389 }
390 
391 // Construct the envelope and the call the
392 // actual outer hcal construction
393 void PHG4Prototype2OuterHcalDetector::ConstructMe(G4LogicalVolume* logicWorld)
394 {
395  G4ThreeVector g4vec(m_Params->get_double_param("place_x") * cm,
396  m_Params->get_double_param("place_y") * cm,
397  m_Params->get_double_param("place_z") * cm);
398  G4RotationMatrix Rot;
399  Rot.rotateX(m_Params->get_double_param("rot_x") * deg);
400  Rot.rotateY(m_Params->get_double_param("rot_y") * deg);
401  Rot.rotateZ(m_Params->get_double_param("rot_z") * deg);
402  // ConstructScintillatorBoxHiEta(logicWorld);
403  m_OuterHcalAssembly = new G4AssemblyVolume();
404  //ConstructSteelPlate(hcal_envelope_log);
405  // return;
406  ConstructOuterHcal(logicWorld);
407  m_OuterHcalAssembly->MakeImprint(logicWorld, g4vec, &Rot, 0, OverlapCheck());
408  // this is rather pathetic - there is no way to extract the name when a volume is added
409  // to the assembly. The only thing we can do is get an iterator over the placed volumes
410  // in the order in which they were placed. Since this code does not install the scintillators
411  // for the Al version, parsing the volume names to get the id does not work since it changes
412  // So now we loop over all volumes and store them in a map for fast lookup of the row
413  int isteel = 0;
414  int iscinti = 0;
415  vector<G4VPhysicalVolume*>::iterator it = m_OuterHcalAssembly->GetVolumesIterator();
416  for (unsigned int i = 0; i < m_OuterHcalAssembly->TotalImprintedVolumes(); i++)
417  {
418  string volname = (*it)->GetName();
419  if (volname.find(steelplatename) != string::npos)
420  {
421  m_SteelPlateIdMap.insert(make_pair(volname, isteel));
422  ++isteel;
423  }
424  else if (volname.find(scintimothername) != string::npos)
425  {
426  m_ScintillatorIdMap.insert(make_pair(volname, iscinti));
427  ++iscinti;
428  }
429  ++it;
430  }
431  // print out volume names and their assigned id
432  // map<string,int>::const_iterator iter;
433  // for (iter = m_SteelPlateIdMap.begin(); iter != m_SteelPlateIdMap.end(); ++iter)
434  // {
435  // cout << iter->first << ", " << iter->second << endl;
436  // }
437  // for (iter = m_ScintillatorIdMap.begin(); iter != m_ScintillatorIdMap.end(); ++iter)
438  // {
439  // cout << iter->first << ", " << iter->second << endl;
440  // }
441 
442  return;
443 }
444 
445 int PHG4Prototype2OuterHcalDetector::ConstructOuterHcal(G4LogicalVolume *hcalenvelope)
446 {
447  G4LogicalVolume* steel_plate = ConstructSteelPlate(hcalenvelope); // bottom steel plate
448  G4LogicalVolume* scintibox = nullptr;
449  if (m_Params->get_int_param("hi_eta"))
450  {
451  scintibox = ConstructScintillatorBoxHiEta(hcalenvelope);
452  }
453  else
454  {
455  scintibox = ConstructScintillatorBox(hcalenvelope);
456  }
457  double phi = 0.;
458  double phislat = 0.;
459  // the coordinate of the center of the bottom of the bottom steel plate
460  // to get the radius of the circle which is the center of the scintillator box
461  double bottom_xmiddle_steel_tile = (m_SteelPlateCornerLowerRight.x() - m_SteelPlateCornerLowerLeft.x()) / 2. + m_SteelPlateCornerLowerLeft.x();
462  double bottom_ymiddle_steel_tile = m_SteelPlateCornerLowerRight.y();
463  double middlerad = sqrt(bottom_xmiddle_steel_tile * bottom_xmiddle_steel_tile + bottom_ymiddle_steel_tile * bottom_ymiddle_steel_tile);
464  double philow = atan((bottom_ymiddle_steel_tile - m_ScintiGap / 2.) / bottom_xmiddle_steel_tile);
465  double scintiangle = GetScintiAngle();
466  for (int i = 0; i < m_NSteelPlates; i++)
467  {
468  G4RotationMatrix Rot;
469  Rot.rotateZ(phi * rad);
470  G4ThreeVector g4vec(0, 0, 0);
471  m_OuterHcalAssembly->AddPlacedVolume(steel_plate, g4vec, &Rot);
472  if (i > 0)
473  {
474  double ypos = sin(phi + philow) * middlerad;
475  double xpos = cos(phi + philow) * middlerad;
476  // the center of the scintillator is not the center of the inner hcal
477  // but depends on the tilt angle. Therefore we need to shift
478  // the center from the mid point
479  ypos += sin((-m_TiltAngle) / rad - phi);
480  xpos -= cos((-m_TiltAngle) / rad - phi);
481  G4RotationMatrix Rota;
482  Rota.rotateZ(scintiangle + phislat);
483  G4ThreeVector g4vec(xpos, ypos, 0);
484 
485  m_OuterHcalAssembly->AddPlacedVolume(scintibox, g4vec, &Rota);
486  phislat += m_DeltaPhi;
487  }
488  phi += m_DeltaPhi;
489  }
490  return 0;
491 }
492 
493 // calculate the angle of the bottom scintillator. It is the angle of the top edge
494 // of the steel plate
495 double
497 {
500  double angle = atan(ylen / xlen);
501  return angle;
502 }
503 
504 void PHG4Prototype2OuterHcalDetector::Print(const string& what) const
505 {
506  cout << "Outer Hcal Detector:" << endl;
507  if (what == "ALL" || what == "VOLUME")
508  {
509  cout << "Volume Steel: " << m_VolumeSteel / cm3 << " cm^3" << endl;
510  cout << "Volume Scintillator: " << m_VolumeScintillator / cm3 << " cm^3" << endl;
511  }
512  return;
513 }
514 
516 {
517  int id = -9999;
518  auto it = m_ScintillatorIdMap.find(volname);
519  if (it != m_ScintillatorIdMap.end())
520  {
521  id = it->second;
522  }
523  else
524  {
525  cout << "unknown scintillator volume name: " << volname << endl;
526  }
527 
528  return id;
529 }
530 
532 {
533  int id = -9999;
534  auto it = m_SteelPlateIdMap.find(volname);
535  if (it != m_SteelPlateIdMap.end())
536  {
537  id = it->second;
538  }
539  else
540  {
541  cout << "unknown steel volume name: " << volname << endl;
542  }
543  return id;
544 }