Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:20:44

0001 #include "PHG4Prototype2OuterHcalDetector.h"
0002 
0003 #include <phparameter/PHParameters.h>
0004 
0005 #include <g4main/PHG4Detector.h>  // for PHG4Detector
0006 
0007 #include <Geant4/G4AssemblyVolume.hh>
0008 #include <Geant4/G4Box.hh>
0009 #include <Geant4/G4Colour.hh>
0010 #include <Geant4/G4ExtrudedSolid.hh>
0011 #include <Geant4/G4LogicalVolume.hh>
0012 #include <Geant4/G4Material.hh>
0013 #include <Geant4/G4PVPlacement.hh>
0014 #include <Geant4/G4RotationMatrix.hh>  // for G4RotationMatrix
0015 #include <Geant4/G4String.hh>          // for G4String
0016 #include <Geant4/G4SystemOfUnits.hh>
0017 #include <Geant4/G4ThreeVector.hh>  // for G4ThreeVector
0018 #include <Geant4/G4TwoVector.hh>
0019 #include <Geant4/G4VPhysicalVolume.hh>  // for G4VPhysicalVolume
0020 #include <Geant4/G4VSolid.hh>           // for G4VSolid
0021 #include <Geant4/G4VisAttributes.hh>
0022 
0023 #include <boost/format.hpp>
0024 
0025 #include <cmath>
0026 #include <iostream>  // for operator<<, endl
0027 #include <sstream>
0028 #include <utility>  // for pair, make_pair
0029 #include <vector>   // for vector, vector<>::...
0030 
0031 class PHCompositeNode;
0032 
0033 using namespace std;
0034 
0035 static const string scintimothername = "OuterHcalScintiMother";
0036 static const string steelplatename = "OuterHcalSteelPlate";
0037 
0038 PHG4Prototype2OuterHcalDetector::PHG4Prototype2OuterHcalDetector(PHG4Subsystem* subsys, PHCompositeNode* Node, PHParameters* parameters, const std::string& dnam)
0039   : PHG4Detector(subsys, Node, dnam)
0040   , m_Params(parameters)
0041   , m_OuterHcalSteelPlate(nullptr)
0042   , m_OuterHcalAssembly(nullptr)
0043   , m_SteelPlateCornerUpperLeft(1777.6 * mm, -433.5 * mm)
0044   , m_SteelPlateCornerUpperRight(2600.4 * mm, -417.4 * mm)
0045   , m_SteelPlateCornerLowerRight(2601.2 * mm, -459.8 * mm)
0046   , m_SteelPlateCornerLowerLeft(1770.9 * mm, -459.8 * mm)
0047   ,
0048 
0049   m_ScintiUoneFrontSize(166.2 * mm)
0050   , m_ScintiUoneCornerUpperLeft(0 * mm, 0 * mm)
0051   , m_ScintiUoneCornerUpperRight(828.9 * mm, 0 * mm)
0052   , m_ScintiUoneCornerLowerRight(828.9 * mm, -240.54 * mm)
0053   , m_ScintiUoneCornerLowerLeft(0 * mm, -m_ScintiUoneFrontSize)
0054   ,
0055 
0056   m_ScintiU2CornerUpperLeft(0 * mm, 0 * mm)
0057   , m_ScintiU2CornerUpperRight(828.9 * mm, -74.3 * mm)
0058   , m_ScintiU2CornerLowerRight(828.9 * mm, -320.44 * mm)
0059   , m_ScintiU2CornerLowerLeft(0 * mm, -171.0 * mm)
0060   ,
0061 
0062   m_ScintiT9DistanceToCorner(0.86 * mm)
0063   , m_ScintiT9FrontSize(241.5 * mm)
0064   , m_ScintiT9CornerUpperLeft(0 * mm, 0 * mm)
0065   , m_ScintiT9CornerUpperRight(697.4 * mm, -552.2 * mm)
0066   , m_ScintiT9CornerLowerRight(697.4 * mm, -697.4 * mm / tan(47.94 / 180. * M_PI) - m_ScintiT9FrontSize)
0067   , m_ScintiT9CornerLowerLeft(0 * mm, -m_ScintiT9FrontSize)
0068   ,
0069 
0070   m_ScintiT10FrontSize(241.4 * mm)
0071   , m_ScintiT10CornerUpperLeft(0 * mm, 0 * mm)
0072   , m_ScintiT10CornerUpperRight(697.4 * mm, -629.3 * mm)
0073   , m_ScintiT10CornerLowerRight(697.4 * mm, -697.4 * mm / tan(44.2 / 180. * M_PI) - m_ScintiT10FrontSize)
0074   , m_ScintiT10CornerLowerLeft(0 * mm, -m_ScintiT10FrontSize)
0075   ,
0076 
0077   m_ScintiT11FrontSize(241.4 * mm)
0078   , m_ScintiT11CornerUpperLeft(0 * mm, 0 * mm)
0079   , m_ScintiT11CornerUpperRight(697.4 * mm, -717.1 * mm)
0080   , m_ScintiT11CornerLowerRight(697.4 * mm, -697.4 * mm / tan(42.47 / 180. * M_PI) - m_ScintiT11FrontSize)
0081   , m_ScintiT11CornerLowerLeft(0 * mm, -m_ScintiT11FrontSize)
0082   ,
0083 
0084   m_ScintiT12FrontSize(312.7 * mm)
0085   , m_ScintiT12CornerUpperLeft(0 * mm, 0 * mm)
0086   , m_ScintiT12CornerUpperRight(697.4 * mm, -761.8 * mm)
0087   , m_ScintiT12CornerLowerRight(392.9 * mm, -827.7)
0088   , m_ScintiT12CornerLowerLeft(0 * mm, -m_ScintiT12FrontSize)
0089   ,
0090 
0091   m_ScintiX(828.9)
0092   , m_ScintiXHiEta(697.4 * mm + 121.09 * mm)
0093   , m_SteelZ(1600. * mm)
0094   , m_SizeZ(m_SteelZ)
0095   , m_ScintiTileZ(m_SteelZ)
0096   , m_ScintiTileThickness(7 * mm)
0097   , m_ScintiBoxSmaller(0.02 * mm)
0098   ,  // blargh - off by 20 microns bc scinti tilt angle, need to revisit at some point
0099   m_GapBetweenTiles(1 * mm)
0100   , m_ScintiGap(8.5 * mm)
0101   , m_TiltAngle(12 * deg)
0102   , m_DeltaPhi(2 * M_PI / 320.)
0103   , m_VolumeSteel(NAN)
0104   , m_VolumeScintillator(NAN)
0105   , m_NScintiPlates(20)
0106   , m_NSteelPlates(m_NScintiPlates + 1)
0107   , m_ActiveFlag(m_Params->get_int_param("active"))
0108   , m_AbsorberActiveFlag(m_Params->get_int_param("absorberactive"))
0109   , m_Layer(0)
0110 {
0111 }
0112 
0113 PHG4Prototype2OuterHcalDetector::~PHG4Prototype2OuterHcalDetector()
0114 {
0115   delete m_OuterHcalAssembly;
0116 }
0117 
0118 //_______________________________________________________________
0119 //_______________________________________________________________
0120 int PHG4Prototype2OuterHcalDetector::IsInPrototype2OuterHcal(G4VPhysicalVolume* volume) const
0121 {
0122   G4LogicalVolume* logvol = volume->GetLogicalVolume();
0123   if (m_AbsorberActiveFlag && logvol == m_OuterHcalSteelPlate)
0124   {
0125     return -1;
0126   }
0127   if (m_ActiveFlag && m_ActiveVolumeSet.find(logvol) != m_ActiveVolumeSet.end())
0128   {
0129     return 1;
0130   }
0131   return 0;
0132 }
0133 
0134 G4LogicalVolume*
0135 PHG4Prototype2OuterHcalDetector::ConstructSteelPlate(G4LogicalVolume* /*hcalenvelope*/)
0136 {
0137   if (!m_OuterHcalSteelPlate)
0138   {
0139     G4VSolid* steel_plate;
0140     std::vector<G4TwoVector> vertexes;
0141     vertexes.push_back(m_SteelPlateCornerUpperLeft);
0142     vertexes.push_back(m_SteelPlateCornerUpperRight);
0143     vertexes.push_back(m_SteelPlateCornerLowerRight);
0144     vertexes.push_back(m_SteelPlateCornerLowerLeft);
0145     G4TwoVector zero(0, 0);
0146     steel_plate = new G4ExtrudedSolid("OuterHcalSteelPlateSolid",
0147                                       vertexes,
0148                                       m_SizeZ / 2.0,
0149                                       zero, 1.0,
0150                                       zero, 1.0);
0151 
0152     m_VolumeSteel = steel_plate->GetCubicVolume() * m_NSteelPlates;
0153     m_OuterHcalSteelPlate = new G4LogicalVolume(steel_plate, G4Material::GetMaterial("Steel_A36"), "OuterHcalSteelPlate", 0, 0, 0);
0154     G4VisAttributes visattchk;
0155     visattchk.SetVisibility(true);
0156     visattchk.SetForceSolid(false);
0157     visattchk.SetColour(G4Colour::Blue());
0158     m_OuterHcalSteelPlate->SetVisAttributes(visattchk);
0159   }
0160   return m_OuterHcalSteelPlate;
0161 }
0162 
0163 G4LogicalVolume*
0164 PHG4Prototype2OuterHcalDetector::ConstructScintillatorBox(G4LogicalVolume* hcalenvelope)
0165 {
0166   int copynum = 0;
0167   G4VSolid* scintiboxsolid = new G4Box(scintimothername, m_ScintiX / 2., (m_ScintiGap - m_ScintiBoxSmaller) / 2., m_ScintiTileZ / 2.);
0168   //  DisplayVolume(scintiboxsolid,hcalenvelope);
0169   G4LogicalVolume* scintiboxlogical = new G4LogicalVolume(scintiboxsolid, G4Material::GetMaterial("G4_AIR"), G4String(scintimothername), 0, 0, 0);
0170   G4VisAttributes* hcalVisAtt = new G4VisAttributes();
0171   hcalVisAtt->SetVisibility(true);
0172   hcalVisAtt->SetForceSolid(false);
0173   hcalVisAtt->SetColour(G4Colour::Red());
0174   G4LogicalVolume* scintiu1_logic = ConstructScintiTileU1(hcalenvelope);
0175   scintiu1_logic->SetVisAttributes(hcalVisAtt);
0176 
0177   hcalVisAtt = new G4VisAttributes();
0178   hcalVisAtt->SetVisibility(true);
0179   hcalVisAtt->SetForceSolid(false);
0180   hcalVisAtt->SetColour(G4Colour::Cyan());
0181   G4LogicalVolume* scintiu2_logic = ConstructScintiTileU2(hcalenvelope);
0182   scintiu2_logic->SetVisAttributes(hcalVisAtt);
0183   G4RotationMatrix* Rot;
0184   Rot = new G4RotationMatrix();
0185   Rot->rotateX(-90 * deg);
0186   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());
0187 
0188   Rot = new G4RotationMatrix();
0189   Rot->rotateX(-90 * deg);
0190   copynum++;
0191   new G4PVPlacement(Rot, G4ThreeVector(-m_ScintiX / 2., 0, -m_GapBetweenTiles / 2.), scintiu1_logic, (boost::format("OuterScinti_%d") % copynum).str(), scintiboxlogical, false, copynum, OverlapCheck());
0192 
0193   Rot = new G4RotationMatrix();
0194   Rot->rotateX(90 * deg);
0195   copynum++;
0196   new G4PVPlacement(Rot, G4ThreeVector(-m_ScintiX / 2., 0, m_GapBetweenTiles / 2.), scintiu1_logic, (boost::format("OuterScinti_%d") % copynum).str(), scintiboxlogical, false, copynum, OverlapCheck());
0197 
0198   Rot = new G4RotationMatrix();
0199   Rot->rotateX(90 * deg);
0200   copynum++;
0201   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());
0202 
0203   return scintiboxlogical;
0204 }
0205 
0206 G4LogicalVolume*
0207 PHG4Prototype2OuterHcalDetector::ConstructScintiTileU1(G4LogicalVolume* /*hcalenvelope*/)
0208 {
0209   std::vector<G4TwoVector> vertexes;
0210   vertexes.push_back(m_ScintiUoneCornerUpperLeft);
0211   vertexes.push_back(m_ScintiUoneCornerUpperRight);
0212   vertexes.push_back(m_ScintiUoneCornerLowerRight);
0213   vertexes.push_back(m_ScintiUoneCornerLowerLeft);
0214   G4TwoVector zero(0, 0);
0215   G4VSolid* scintiu1 = new G4ExtrudedSolid("OuterHcalScintiU1",
0216                                            vertexes,
0217                                            m_ScintiTileThickness / 2.0,
0218                                            zero, 1.0,
0219                                            zero, 1.0);
0220 
0221   G4LogicalVolume* scintiu1_logic = new G4LogicalVolume(scintiu1, G4Material::GetMaterial("G4_POLYSTYRENE"), "OuterHcalScintiU1", nullptr, nullptr, nullptr);
0222   //   DisplayVolume(scintiu1,hcalenvelope);
0223   m_ActiveVolumeSet.insert(scintiu1_logic);
0224   return scintiu1_logic;
0225 }
0226 
0227 G4LogicalVolume*
0228 PHG4Prototype2OuterHcalDetector::ConstructScintiTileU2(G4LogicalVolume* /*hcalenvelope*/)
0229 {
0230   std::vector<G4TwoVector> vertexes;
0231   vertexes.push_back(m_ScintiU2CornerUpperLeft);
0232   vertexes.push_back(m_ScintiU2CornerUpperRight);
0233   vertexes.push_back(m_ScintiU2CornerLowerRight);
0234   vertexes.push_back(m_ScintiU2CornerLowerLeft);
0235   G4TwoVector zero(0, 0);
0236   G4VSolid* scintiu2 = new G4ExtrudedSolid("OuterHcalScintiU2",
0237                                            vertexes,
0238                                            m_ScintiTileThickness / 2.0,
0239                                            zero, 1.0,
0240                                            zero, 1.0);
0241 
0242   G4LogicalVolume* scintiu2_logic = new G4LogicalVolume(scintiu2, G4Material::GetMaterial("G4_POLYSTYRENE"), "OuterHcalScintiU2", nullptr, nullptr, nullptr);
0243   //   DisplayVolume(scintiu2,hcalenvelope);
0244   m_ActiveVolumeSet.insert(scintiu2_logic);
0245   return scintiu2_logic;
0246 }
0247 
0248 G4LogicalVolume*
0249 PHG4Prototype2OuterHcalDetector::ConstructScintillatorBoxHiEta(G4LogicalVolume* hcalenvelope)
0250 {
0251   int copynum = 0;
0252   G4VSolid* scintiboxsolid = new G4Box(scintimothername, m_ScintiX / 2., (m_ScintiGap - m_ScintiBoxSmaller) / 2., m_ScintiTileZ / 2.);
0253   //  DisplayVolume(scintiboxsolid,hcalenvelope);
0254   G4LogicalVolume* scintiboxlogical = new G4LogicalVolume(scintiboxsolid, G4Material::GetMaterial("G4_AIR"), G4String(scintimothername), 0, 0, 0);
0255 
0256   G4VisAttributes hcalVisAtt;
0257   hcalVisAtt.SetVisibility(true);
0258   hcalVisAtt.SetForceSolid(false);
0259   hcalVisAtt.SetColour(G4Colour::Magenta());
0260   G4LogicalVolume* scintit9_logic = ConstructScintiTile9(hcalenvelope);
0261   scintit9_logic->SetVisAttributes(hcalVisAtt);
0262 
0263   double distance_to_corner = -m_SizeZ / 2. + m_ScintiT9DistanceToCorner;
0264   G4RotationMatrix* Rot;
0265   Rot = new G4RotationMatrix();
0266   Rot->rotateX(90 * deg);
0267   new G4PVPlacement(Rot, G4ThreeVector(-m_ScintiXHiEta / 2., 0, distance_to_corner), scintit9_logic, (boost::format("OuterScinti_%d") % copynum).str(), scintiboxlogical, false, copynum, OverlapCheck());
0268 
0269   hcalVisAtt.SetVisibility(true);
0270   hcalVisAtt.SetForceSolid(false);
0271   hcalVisAtt.SetColour(G4Colour::Blue());
0272   G4LogicalVolume* scintit10_logic = ConstructScintiTile10(hcalenvelope);
0273   scintit10_logic->SetVisAttributes(hcalVisAtt);
0274 
0275   distance_to_corner += m_ScintiT9FrontSize + m_GapBetweenTiles;
0276   Rot = new G4RotationMatrix();
0277   Rot->rotateX(90 * deg);
0278   copynum++;
0279   new G4PVPlacement(Rot, G4ThreeVector(-m_ScintiXHiEta / 2., 0, distance_to_corner), scintit10_logic, (boost::format("OuterScinti_%d") % copynum).str(), scintiboxlogical, false, copynum, OverlapCheck());
0280 
0281   hcalVisAtt.SetVisibility(true);
0282   hcalVisAtt.SetForceSolid(false);
0283   hcalVisAtt.SetColour(G4Colour::Yellow());
0284   G4LogicalVolume* scintit11_logic = ConstructScintiTile11(hcalenvelope);
0285   scintit11_logic->SetVisAttributes(hcalVisAtt);
0286 
0287   distance_to_corner += m_ScintiT10FrontSize + m_GapBetweenTiles;
0288   Rot = new G4RotationMatrix();
0289   Rot->rotateX(90 * deg);
0290   copynum++;
0291   new G4PVPlacement(Rot, G4ThreeVector(-m_ScintiXHiEta / 2., 0, distance_to_corner), scintit11_logic, (boost::format("OuterScinti_%d") % copynum).str(), scintiboxlogical, false, copynum, OverlapCheck());
0292 
0293   hcalVisAtt.SetVisibility(true);
0294   hcalVisAtt.SetForceSolid(false);
0295   hcalVisAtt.SetColour(G4Colour::Cyan());
0296   G4LogicalVolume* scintit12_logic = ConstructScintiTile12(hcalenvelope);
0297   scintit12_logic->SetVisAttributes(hcalVisAtt);
0298 
0299   distance_to_corner += m_ScintiT11FrontSize + m_GapBetweenTiles;
0300   Rot = new G4RotationMatrix();
0301   Rot->rotateX(90 * deg);
0302   copynum++;
0303   new G4PVPlacement(Rot, G4ThreeVector(-m_ScintiXHiEta / 2., 0, distance_to_corner), scintit12_logic, (boost::format("OuterScinti_%d") % copynum).str(), scintiboxlogical, false, copynum, OverlapCheck());
0304   //DisplayVolume(scintiboxlogical,hcalenvelope);
0305   return scintiboxlogical;
0306 }
0307 G4LogicalVolume*
0308 PHG4Prototype2OuterHcalDetector::ConstructScintiTile9(G4LogicalVolume* /*hcalenvelope*/)
0309 {
0310   std::vector<G4TwoVector> vertexes;
0311   vertexes.push_back(m_ScintiT9CornerUpperLeft);
0312   vertexes.push_back(m_ScintiT9CornerUpperRight);
0313   vertexes.push_back(m_ScintiT9CornerLowerRight);
0314   vertexes.push_back(m_ScintiT9CornerLowerLeft);
0315   G4TwoVector zero(0, 0);
0316   G4VSolid* scintit9 = new G4ExtrudedSolid("OuterHcalScintiT9",
0317                                            vertexes,
0318                                            m_ScintiTileThickness / 2.0,
0319                                            zero, 1.0,
0320                                            zero, 1.0);
0321 
0322   G4LogicalVolume* scintit9_logic = new G4LogicalVolume(scintit9, G4Material::GetMaterial("G4_POLYSTYRENE"), "OuterHcalScintiT9", nullptr, nullptr, nullptr);
0323   //     DisplayVolume(scintit9,hcalenvelope);
0324   m_ActiveVolumeSet.insert(scintit9_logic);
0325   return scintit9_logic;
0326 }
0327 
0328 G4LogicalVolume*
0329 PHG4Prototype2OuterHcalDetector::ConstructScintiTile10(G4LogicalVolume* /*hcalenvelope*/)
0330 {
0331   std::vector<G4TwoVector> vertexes;
0332   vertexes.push_back(m_ScintiT10CornerUpperLeft);
0333   vertexes.push_back(m_ScintiT10CornerUpperRight);
0334   vertexes.push_back(m_ScintiT10CornerLowerRight);
0335   vertexes.push_back(m_ScintiT10CornerLowerLeft);
0336   G4TwoVector zero(0, 0);
0337   G4VSolid* scintit10 = new G4ExtrudedSolid("OuterHcalScintiT10",
0338                                             vertexes,
0339                                             m_ScintiTileThickness / 2.0,
0340                                             zero, 1.0,
0341                                             zero, 1.0);
0342 
0343   G4LogicalVolume* scintit10_logic = new G4LogicalVolume(scintit10, G4Material::GetMaterial("G4_POLYSTYRENE"), "OuterHcalScintiT10", nullptr, nullptr, nullptr);
0344   //     DisplayVolume(scintit10,hcalenvelope);
0345   m_ActiveVolumeSet.insert(scintit10_logic);
0346   return scintit10_logic;
0347 }
0348 
0349 G4LogicalVolume*
0350 PHG4Prototype2OuterHcalDetector::ConstructScintiTile11(G4LogicalVolume* /*hcalenvelope*/)
0351 {
0352   std::vector<G4TwoVector> vertexes;
0353   vertexes.push_back(m_ScintiT11CornerUpperLeft);
0354   vertexes.push_back(m_ScintiT11CornerUpperRight);
0355   vertexes.push_back(m_ScintiT11CornerLowerRight);
0356   vertexes.push_back(m_ScintiT11CornerLowerLeft);
0357   G4TwoVector zero(0, 0);
0358   G4VSolid* scintit11 = new G4ExtrudedSolid("OuterHcalScintiT11",
0359                                             vertexes,
0360                                             m_ScintiTileThickness / 2.0,
0361                                             zero, 1.0,
0362                                             zero, 1.0);
0363 
0364   G4LogicalVolume* scintit11_logic = new G4LogicalVolume(scintit11, G4Material::GetMaterial("G4_POLYSTYRENE"), "OuterHcalScintiT11", nullptr, nullptr, nullptr);
0365   //     DisplayVolume(scintit11,hcalenvelope);
0366   m_ActiveVolumeSet.insert(scintit11_logic);
0367   return scintit11_logic;
0368 }
0369 
0370 G4LogicalVolume*
0371 PHG4Prototype2OuterHcalDetector::ConstructScintiTile12(G4LogicalVolume* /*hcalenvelope*/)
0372 {
0373   std::vector<G4TwoVector> vertexes;
0374   vertexes.push_back(m_ScintiT12CornerUpperLeft);
0375   vertexes.push_back(m_ScintiT12CornerUpperRight);
0376   vertexes.push_back(m_ScintiT12CornerLowerRight);
0377   vertexes.push_back(m_ScintiT12CornerLowerLeft);
0378   G4TwoVector zero(0, 0);
0379   G4VSolid* scintit12 = new G4ExtrudedSolid("OuterHcalScintiT12",
0380                                             vertexes,
0381                                             m_ScintiTileThickness / 2.0,
0382                                             zero, 1.0,
0383                                             zero, 1.0);
0384 
0385   G4LogicalVolume* scintit12_logic = new G4LogicalVolume(scintit12, G4Material::GetMaterial("G4_POLYSTYRENE"), "OuterHcalScintiT12", nullptr, nullptr, nullptr);
0386   //     DisplayVolume(scintit12,hcalenvelope);
0387   m_ActiveVolumeSet.insert(scintit12_logic);
0388   return scintit12_logic;
0389 }
0390 
0391 // Construct the envelope and the call the
0392 // actual outer hcal construction
0393 void PHG4Prototype2OuterHcalDetector::ConstructMe(G4LogicalVolume* logicWorld)
0394 {
0395   G4ThreeVector g4vec(m_Params->get_double_param("place_x") * cm,
0396                       m_Params->get_double_param("place_y") * cm,
0397                       m_Params->get_double_param("place_z") * cm);
0398   G4RotationMatrix Rot;
0399   Rot.rotateX(m_Params->get_double_param("rot_x") * deg);
0400   Rot.rotateY(m_Params->get_double_param("rot_y") * deg);
0401   Rot.rotateZ(m_Params->get_double_param("rot_z") * deg);
0402   //  ConstructScintillatorBoxHiEta(logicWorld);
0403   m_OuterHcalAssembly = new G4AssemblyVolume();
0404   //ConstructSteelPlate(hcal_envelope_log);
0405   // return;
0406   ConstructOuterHcal(logicWorld);
0407   m_OuterHcalAssembly->MakeImprint(logicWorld, g4vec, &Rot, 0, OverlapCheck());
0408   // this is rather pathetic - there is no way to extract the name when a volume is added
0409   // to the assembly. The only thing we can do is get an iterator over the placed volumes
0410   // in the order in which they were placed. Since this code does not install the scintillators
0411   // for the Al version, parsing the volume names to get the id does not work since it changes
0412   // So now we loop over all volumes and store them in a map for fast lookup of the row
0413   int isteel = 0;
0414   int iscinti = 0;
0415   vector<G4VPhysicalVolume*>::iterator it = m_OuterHcalAssembly->GetVolumesIterator();
0416   for (unsigned int i = 0; i < m_OuterHcalAssembly->TotalImprintedVolumes(); i++)
0417   {
0418     string volname = (*it)->GetName();
0419     if (volname.find(steelplatename) != string::npos)
0420     {
0421       m_SteelPlateIdMap.insert(make_pair(volname, isteel));
0422       ++isteel;
0423     }
0424     else if (volname.find(scintimothername) != string::npos)
0425     {
0426       m_ScintillatorIdMap.insert(make_pair(volname, iscinti));
0427       ++iscinti;
0428     }
0429     ++it;
0430   }
0431   // print out volume names and their assigned id
0432   // map<string,int>::const_iterator iter;
0433   // for (iter = m_SteelPlateIdMap.begin(); iter != m_SteelPlateIdMap.end(); ++iter)
0434   // {
0435   //   cout << iter->first << ", " << iter->second << endl;
0436   // }
0437   // for (iter = m_ScintillatorIdMap.begin(); iter != m_ScintillatorIdMap.end(); ++iter)
0438   // {
0439   //   cout << iter->first << ", " << iter->second << endl;
0440   // }
0441 
0442   return;
0443 }
0444 
0445 int PHG4Prototype2OuterHcalDetector::ConstructOuterHcal(G4LogicalVolume *hcalenvelope)
0446 {
0447   G4LogicalVolume* steel_plate = ConstructSteelPlate(hcalenvelope);  // bottom steel plate
0448   G4LogicalVolume* scintibox = nullptr;
0449   if (m_Params->get_int_param("hi_eta"))
0450   {
0451     scintibox = ConstructScintillatorBoxHiEta(hcalenvelope);
0452   }
0453   else
0454   {
0455     scintibox = ConstructScintillatorBox(hcalenvelope);
0456   }
0457   double phi = 0.;
0458   double phislat = 0.;
0459   // the coordinate of the center of the bottom of the bottom steel plate
0460   // to get the radius of the circle which is the center of the scintillator box
0461   double bottom_xmiddle_steel_tile = (m_SteelPlateCornerLowerRight.x() - m_SteelPlateCornerLowerLeft.x()) / 2. + m_SteelPlateCornerLowerLeft.x();
0462   double bottom_ymiddle_steel_tile = m_SteelPlateCornerLowerRight.y();
0463   double middlerad = sqrt(bottom_xmiddle_steel_tile * bottom_xmiddle_steel_tile + bottom_ymiddle_steel_tile * bottom_ymiddle_steel_tile);
0464   double philow = atan((bottom_ymiddle_steel_tile - m_ScintiGap / 2.) / bottom_xmiddle_steel_tile);
0465   double scintiangle = GetScintiAngle();
0466   for (int i = 0; i < m_NSteelPlates; i++)
0467   {
0468     G4RotationMatrix Rot;
0469     Rot.rotateZ(phi * rad);
0470     G4ThreeVector g4vec(0, 0, 0);
0471     m_OuterHcalAssembly->AddPlacedVolume(steel_plate, g4vec, &Rot);
0472     if (i > 0)
0473     {
0474       double ypos = sin(phi + philow) * middlerad;
0475       double xpos = cos(phi + philow) * middlerad;
0476       // the center of the scintillator is not the center of the inner hcal
0477       // but depends on the tilt angle. Therefore we need to shift
0478       // the center from the mid point
0479       ypos += sin((-m_TiltAngle) / rad - phi);
0480       xpos -= cos((-m_TiltAngle) / rad - phi);
0481       G4RotationMatrix Rota;
0482       Rota.rotateZ(scintiangle + phislat);
0483       G4ThreeVector g4vec(xpos, ypos, 0);
0484 
0485       m_OuterHcalAssembly->AddPlacedVolume(scintibox, g4vec, &Rota);
0486       phislat += m_DeltaPhi;
0487     }
0488     phi += m_DeltaPhi;
0489   }
0490   return 0;
0491 }
0492 
0493 // calculate the angle of the bottom scintillator. It is the angle of the top edge
0494 // of the steel plate
0495 double
0496 PHG4Prototype2OuterHcalDetector::GetScintiAngle()
0497 {
0498   double xlen = m_SteelPlateCornerUpperRight.x() - m_SteelPlateCornerUpperLeft.x();
0499   double ylen = m_SteelPlateCornerUpperRight.y() - m_SteelPlateCornerUpperLeft.y();
0500   double angle = atan(ylen / xlen);
0501   return angle;
0502 }
0503 
0504 void PHG4Prototype2OuterHcalDetector::Print(const string& what) const
0505 {
0506   cout << "Outer Hcal Detector:" << endl;
0507   if (what == "ALL" || what == "VOLUME")
0508   {
0509     cout << "Volume Steel: " << m_VolumeSteel / cm3 << " cm^3" << endl;
0510     cout << "Volume Scintillator: " << m_VolumeScintillator / cm3 << " cm^3" << endl;
0511   }
0512   return;
0513 }
0514 
0515 int PHG4Prototype2OuterHcalDetector::get_scinti_row_id(const string& volname)
0516 {
0517   int id = -9999;
0518   auto it = m_ScintillatorIdMap.find(volname);
0519   if (it != m_ScintillatorIdMap.end())
0520   {
0521     id = it->second;
0522   }
0523   else
0524   {
0525     cout << "unknown scintillator volume name: " << volname << endl;
0526   }
0527 
0528   return id;
0529 }
0530 
0531 int PHG4Prototype2OuterHcalDetector::get_steel_plate_id(const string& volname)
0532 {
0533   int id = -9999;
0534   auto it = m_SteelPlateIdMap.find(volname);
0535   if (it != m_SteelPlateIdMap.end())
0536   {
0537     id = it->second;
0538   }
0539   else
0540   {
0541     cout << "unknown steel volume name: " << volname << endl;
0542   }
0543   return id;
0544 }