36 #include <calobase/RawTowerDefs.h>
37 #include <calobase/RawTowerGeom.h>
38 #include <calobase/RawTowerGeomContainer.h>
39 #include <calobase/RawTowerGeomContainer_Cylinderv1.h>
40 #include <calobase/RawTowerGeomv1.h>
44 #include <Geant4/G4LogicalVolume.hh>
45 #include <Geant4/G4Material.hh>
46 #include <Geant4/G4PVPlacement.hh>
47 #include <Geant4/G4PhysicalConstants.hh>
48 #include <Geant4/G4String.hh>
49 #include <Geant4/G4SystemOfUnits.hh>
50 #include <Geant4/G4ThreeVector.hh>
51 #include <Geant4/G4Transform3D.hh>
52 #include <Geant4/G4Tubs.hh>
53 #include <Geant4/G4Types.hh>
54 #include <Geant4/G4UserLimits.hh>
80 std::cout <<
"PHG4SpacalDetector::Constructor - Fatal Error - invalid geometry object!" << std::endl;
141 std::cout <<
"PHG4SpacalDetector::Construct::" <<
GetName()
142 <<
" - Start. Print Geometry:" << std::endl;
148 std::cout <<
"PHG4SpacalDetector::Construct - ERROR - not yet support unsymmetric system. Let me know if you need it. - Jin" << std::endl;
154 std::cout <<
"PHG4SpacalDetector::Construct - ERROR - zmin >= zmax!" << std::endl;
159 G4Tubs *cylinder_solid =
new G4Tubs(G4String(
GetName()),
167 G4LogicalVolume *cylinder_logic =
new G4LogicalVolume(cylinder_solid, cylinder_mat,
GetName(),
nullptr,
nullptr,
nullptr);
183 std::cout <<
"PHG4SpacalDetector::Construct::" <<
GetName()
184 <<
" - start constructing " <<
_geom->
get_sector_map().size() <<
" sectors in total. " << std::endl;
189 G4LogicalVolume *sec_logic = psec.first;
190 const G4Transform3D &sec_trans = psec.second;
194 const int sec = val.first;
195 const double rot = val.second;
197 G4Transform3D sec_place = G4RotateZ3D(rot) * sec_trans;
199 std::ostringstream
name;
200 name <<
GetName() <<
"_sec" << sec;
201 G4PVPlacement *calo_phys =
nullptr;
204 calo_phys =
new G4PVPlacement(
nullptr, G4ThreeVector(0, -(
_geom->
get_radius()) *
cm, 0), sec_logic,
205 G4String(name.str()), logicWorld,
false, sec,
210 calo_phys =
new G4PVPlacement(sec_place, sec_logic,
211 G4String(name.str()), cylinder_logic,
false, sec,
223 std::ostringstream geonode;
239 geonode.str(),
"PHObject");
251 std::ostringstream geonode;
267 geonode.str(),
"PHObject");
279 std::cout <<
"PHG4SpacalDetector::Construct::" <<
GetName()
280 <<
" - Completed. Print Geometry:" << std::endl;
285 std::pair<G4LogicalVolume *, G4Transform3D>
295 G4LogicalVolume *sec_logic =
new G4LogicalVolume(sec_solid, cylinder_mat,
311 G4Transform3D fiber_place(G4RotateZ3D(rot) * G4TranslateZ3D(z) * G4TranslateX3D(
_geom->
get_half_radius() *
cm) * G4RotateY3D(halfpi));
313 std::ostringstream
name;
314 name <<
GetName() <<
"_fiber_" << fiber_count;
316 G4PVPlacement *fiber_physi =
new G4PVPlacement(fiber_place, fiber_logic,
317 G4String(name.str()), sec_logic,
false, fiber_count,
330 std::cout <<
"PHG4SpacalDetector::Construct_AzimuthalSeg::" <<
GetName()
331 <<
" - constructed " << fiber_count <<
" fibers" << std::endl;
336 <<
"fiber_length = " << fiber_length
337 <<
"_geom->get_azimuthal_distance() = "
344 return std::make_pair(sec_logic, G4Transform3D::Identity);
356 G4LogicalVolume *fiber_logic =
new G4LogicalVolume(fiber_solid, clading_mat,
364 G4Tubs *core_solid =
new G4Tubs(
371 G4LogicalVolume *core_logic =
new G4LogicalVolume(core_solid, core_mat,
380 G4PVPlacement *core_physi =
new G4PVPlacement(
nullptr, G4ThreeVector(), core_logic,
382 false, 0, overlapcheck_fiber);
390 std::cout <<
"PHG4SpacalDetector::Print::" <<
GetName() <<
" - Print Geometry:" << std::endl;
402 std::cout <<
PHWHERE <<
"Run Node missing, doing nothing." << std::endl;
403 throw std::runtime_error(
"Failed to find Run node in PHG4SpacalDetector::AddGeometryNode");
421 std::cout <<
PHWHERE <<
" " << geonodename
422 <<
" Node missing, doing nothing." << std::endl;
423 throw std::runtime_error(
424 "Failed to find " + geonodename +
" node in PHG4SpacalDetector::AddGeometryNode");
442 int first_layer = -1;
446 for (miter = begin_end.first; miter != begin_end.second; ++miter)
457 first_cellgeo = miter->second;
479 std::cout <<
"PHG4SpacalDetector::AddGeometryNode::" <<
GetName()
480 <<
" - Fatal Error - unsupported cell binning method "
491 std::cout <<
"inconsistent binning method from " <<
m_CellBinning
492 <<
" layer " << cellgeo->
get_layer() <<
": "
498 std::cout <<
"radius of layer " << cellgeo->
get_layer() <<
" is "
499 << cellgeo->
get_radius() <<
" which smaller than radius "
500 << inner_radius <<
" of first layer in list " << first_layer
505 std::cout <<
"mixing number of phibins, fisrt layer: " <<
m_NumPhiBins
506 <<
" layer " << cellgeo->
get_layer() <<
": "
512 std::cout <<
"mixing number of phimin, fisrt layer: " <<
m_PhiMin
513 <<
" layer " << cellgeo->
get_layer() <<
": "
519 std::cout <<
"mixing phisteps first layer: " <<
m_PhiStep <<
" layer "
528 std::cout <<
"mixing number of EtaBins , first layer: "
535 std::cout <<
"mixing etamin, fisrt layer: " <<
m_EtaMin <<
" layer "
542 std::cout <<
"mixing eta steps first layer: " <<
m_EtaStep
543 <<
" layer " << cellgeo->
get_layer() <<
": "
554 std::cout <<
"mixing number of z bins , first layer: " <<
m_NumEtaBins
555 <<
" layer " << cellgeo->
get_layer() <<
": "
571 std::cout <<
"PHG4SpacalDetector::AddGeometryNode - ERROR - can not find first layer of cells "
612 std::cout <<
"PHG4SpacalDetector::AddGeometryNode - Tower geometry " << key <<
" already exists" << std::endl;
615 if (fabs(tg->get_center_x() -
x) > 1
e-4)
617 std::cout <<
"PHG4SpacalDetector::AddGeometryNode - Fatal Error - duplicated Tower geometry " << key <<
" with existing x = " << tg->
get_center_x() <<
" and expected x = " << x
622 if (fabs(tg->get_center_y() -
y) > 1
e-4)
624 std::cout <<
"PHG4SpacalDetector::AddGeometryNode - Fatal Error - duplicated Tower geometry " << key <<
" with existing y = " << tg->get_center_y() <<
" and expected y = " << y
628 if (fabs(tg->get_center_z() -
z) > 1
e-4)
630 std::cout <<
"PHG4SpacalDetector::AddGeometryNode - Fatal Error - duplicated Tower geometry " << key <<
" with existing z= " << tg->get_center_z() <<
" and expected z = " <<
z
639 std::cout <<
"PHG4SpacalDetector::AddGeometryNode - building tower geometry " << key <<
"" << std::endl;
658 const std::pair<double, double> z_range = first_cellgeo->
get_zbounds(
ibin);
660 const double eta1 = -log(tan(atan2(r, z_range.first) / 2.));
661 const double eta2 = -log(tan(atan2(r, z_range.second) / 2.));
681 std::cout <<
"PHG4SpacalDetector::AddGeometryNode - Tower geometry " << key <<
" already exists" << std::endl;
684 if (fabs(tg->get_center_x() -
x) > 1
e-4)
686 std::cout <<
"PHG4SpacalDetector::AddGeometryNode - Fatal Error - duplicated Tower geometry " << key <<
" with existing x = " << tg->
get_center_x() <<
" and expected x = " << x
691 if (fabs(tg->get_center_y() -
y) > 1
e-4)
693 std::cout <<
"PHG4SpacalDetector::AddGeometryNode - Fatal Error - duplicated Tower geometry " << key <<
" with existing y = " << tg->get_center_y() <<
" and expected y = " << y
697 if (fabs(tg->get_center_z() -
z) > 1
e-4)
699 std::cout <<
"PHG4SpacalDetector::AddGeometryNode - Fatal Error - duplicated Tower geometry " << key <<
" with existing z= " << tg->get_center_z() <<
" and expected z = " <<
z
708 std::cout <<
"PHG4SpacalDetector::AddGeometryNode - building tower geometry " << key <<
"" << std::endl;
723 std::cout <<
"PHG4SpacalDetector::AddGeometryNode - ERROR - unsupported cell geometry "
745 std::cout <<
PHWHERE <<
"DST Node missing, doing nothing." << std::endl;
753 std::cout <<
"PHG4SpacalDetector::AddCellGeometryNode - Could not locate geometry node "
754 << geonodename << std::endl;
760 std::cout <<
"PHG4SpacalDetector::AddCellGeometryNode- incoming geometry:"
783 std::cout <<
"PHG4SpacalDetector::AddCellGeometryNode- Fatal Error -"
784 <<
" require to work with a version of SPACAL geometry of PHG4CylinderGeom_Spacalv3 or higher. "
785 <<
"However the incoming geometry has version "
786 << layergeom_raw->ClassName() << std::endl;
812 const double deltaphi = 2. * M_PI / nphibin;
814 using map_z_tower_z_ID_t = std::map<double, int>;
815 map_z_tower_z_ID_t map_z_tower_z_ID;
818 for (
const auto &tower_pair : tower_map)
820 const int &tower_ID = tower_pair.first;
826 const int &tower_ID_z = tower_z_phi_ID.first;
827 const int &tower_ID_phi = tower_z_phi_ID.second;
829 if (tower_ID_phi == 0)
833 + sector_map.begin()->second;
839 map_z_tower_z_ID[tower.
centralZ] = tower_ID_z;
844 assert(!std::isnan(phi_min));
851 for (
auto &z_tower_z_ID : map_z_tower_z_ID)
853 tower_z_ID_eta_bin_map[z_tower_z_ID.second] = eta_bin;
862 for (
const auto &tower_pair : tower_map)
864 const int &tower_ID = tower_pair.first;
869 const int &tower_ID_z = tower_z_phi_ID.first;
870 const int &tower_ID_phi = tower_z_phi_ID.second;
871 const int &
etabin = tower_z_ID_eta_bin_map[tower_ID_z];
879 auto z_to_eta = [&tower_radial](
const double &
z)
880 {
return -log(tan(0.5 * atan2(tower_radial,
z))); };
882 const double eta_central = z_to_eta(tower.
centralZ);
884 const double deta = (z_to_eta(tower.
centralZ + dz) - z_to_eta(tower.
centralZ - dz)) / 2;
887 for (
int sub_tower_ID_y = 0; sub_tower_ID_y < tower.
NSubtowerY;
892 const int sub_tower_etabin = etabin * layergeom->
get_n_subtower_eta() + sub_tower_ID_y;
894 const std::pair<double, double> etabounds(eta_central - deta + sub_tower_ID_y * 2 * deta / tower.
NSubtowerY,
895 eta_central - deta + (sub_tower_ID_y + 1) * 2 * deta / tower.
NSubtowerY);
897 const std::pair<double, double> zbounds(tower.
centralZ - dz + sub_tower_ID_y * 2 * dz / tower.
NSubtowerY,
901 layerseggeo->
set_zbounds(sub_tower_etabin, zbounds);