Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:22:06

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