7 #include <phparameter/PHParameters.h>
19 #include <Geant4/G4AssemblyVolume.hh>
20 #include <Geant4/G4Box.hh>
21 #include <Geant4/G4ExtrudedSolid.hh>
22 #include <Geant4/G4IntersectionSolid.hh>
23 #include <Geant4/G4LogicalVolume.hh>
24 #include <Geant4/G4Material.hh>
25 #include <Geant4/G4PVPlacement.hh>
26 #include <Geant4/G4RotationMatrix.hh>
27 #include <Geant4/G4String.hh>
28 #include <Geant4/G4SubtractionSolid.hh>
29 #include <Geant4/G4SystemOfUnits.hh>
30 #include <Geant4/G4ThreeVector.hh>
31 #include <Geant4/G4Transform3D.hh>
32 #include <Geant4/G4Tubs.hh>
33 #include <Geant4/G4TwoVector.hh>
34 #include <Geant4/G4UserLimits.hh>
35 #include <Geant4/G4VPhysicalVolume.hh>
36 #include <Geant4/G4VSolid.hh>
38 #include <CGAL/Boolean_set_operations_2.h>
39 #include <CGAL/Circular_kernel_intersections.h>
40 #include <CGAL/Exact_circular_kernel_2.h>
41 #include <CGAL/Object.h>
42 #include <CGAL/point_generators_2.h>
44 #include <boost/lexical_cast.hpp>
45 #include <boost/tokenizer.hpp>
56 typedef CGAL::Circle_2<PHG4OuterHcalDetector::Circular_k>
Circle_2;
58 typedef CGAL::Line_2<PHG4OuterHcalDetector::Circular_k>
Line_2;
59 typedef CGAL::Segment_2<PHG4OuterHcalDetector::Circular_k>
Segment_2;
73 , m_FieldSetup(nullptr)
75 , m_ScintiMotherAssembly(nullptr)
76 , m_SteelCutoutForMagnetG4Solid(nullptr)
77 , m_InnerRadius(m_Params->get_double_param(
"inner_radius") *
cm)
78 , m_OuterRadius(m_Params->get_double_param(
"outer_radius") *
cm)
79 , m_SizeZ(m_Params->get_double_param(
"size_z") *
cm)
81 , m_ScintiTileXLower(NAN)
82 , m_ScintiTileXUpper(NAN)
83 , m_ScintiTileZ(m_SizeZ)
84 , m_ScintiTileThickness(m_Params->get_double_param(
"scinti_tile_thickness") *
cm)
85 , m_ScintiGap(m_Params->get_double_param(
"scinti_gap") *
cm)
86 , m_ScintiInnerRadius(m_Params->get_double_param(
"scinti_inner_radius") *
cm)
87 , m_ScintiOuterRadius(m_Params->get_double_param(
"scinti_outer_radius") *
cm)
88 , m_TiltAngle(m_Params->get_double_param(
"tilt_angle") *
deg)
89 , m_EnvelopeInnerRadius(m_InnerRadius)
90 , m_EnvelopeOuterRadius(m_OuterRadius)
91 , m_EnvelopeZ(m_SizeZ)
92 , m_VolumeEnvelope(NAN)
94 , m_VolumeScintillator(NAN)
95 , m_NumScintiPlates(m_Params->get_int_param(PHG4HcalDefs::
scipertwr) * m_Params->get_int_param(
"n_towers"))
96 , m_NumScintiTiles(m_Params->get_int_param(
"n_scinti_tiles"))
97 , m_ActiveFlag(m_Params->get_int_param(
"active"))
98 , m_AbsorberActiveFlag(m_Params->get_int_param(
"absorberactive"))
100 , m_ScintiLogicNamePrefix(
"HcalOuterScinti")
143 Line_2 s2(p_in_1, p_upperedge);
147 Circle_2 outer_circle(sc1, sc2, sc3);
148 vector<CGAL::Object> res;
149 CGAL::intersection(outer_circle, perp, std::back_inserter(res));
151 vector<CGAL::Object>::const_iterator iter;
152 for (iter = res.begin(); iter != res.end(); ++iter)
154 CGAL::Object obj = *iter;
155 if (
const std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned> *
point = CGAL::object_cast<std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned>>(&obj))
157 if (CGAL::to_double(
point->first.x()) > CGAL::to_double(p_upperedge.x()))
159 double deltax = CGAL::to_double(
point->first.x()) - CGAL::to_double(p_upperedge.x());
160 double deltay = CGAL::to_double(
point->first.y()) - CGAL::to_double(p_upperedge.y());
169 cout <<
"CGAL::Object type not pair..." << endl;
176 Line_2 s3(p_in_1, p_loweredge);
177 Line_2 l_lower = s3.perpendicular(p_loweredge);
179 Circle_2 inner_circle(ic1, ic2, ic3);
181 CGAL::intersection(inner_circle, l_lower, std::back_inserter(res));
186 for (iter = res.begin(); iter != res.end(); ++iter)
188 CGAL::Object obj = *iter;
189 if (
const std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned> *
point = CGAL::object_cast<std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned>>(&obj))
191 if (CGAL::to_double(
point->first.x()) > minx)
193 minx = CGAL::to_double(
point->first.x());
194 double deltax = CGAL::to_double(
point->first.x()) - CGAL::to_double(p_loweredge.x());
195 double deltay = CGAL::to_double(
point->first.y()) - CGAL::to_double(p_loweredge.y());
219 double xcoord =
m_ScintiGap / 2. * cos(angle_mid_scinti /
rad) + mid_radius;
220 double ycoord =
m_ScintiGap / 2. * sin(angle_mid_scinti /
rad) + 0;
222 Line_2 s2(p_in_1, p_loweredge);
225 Circle_2 inner_circle(sc1, sc2, sc3);
226 vector<CGAL::Object> res;
227 CGAL::intersection(inner_circle, perp, std::back_inserter(res));
229 vector<CGAL::Object>::const_iterator iter;
230 for (iter = res.begin(); iter != res.end(); ++iter)
232 CGAL::Object obj = *iter;
233 if (
const std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned> *
point = CGAL::object_cast<std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned>>(&obj))
235 if (CGAL::to_double(
point->first.x()) > 0)
243 cout <<
"CGAL::Object type not pair..." << endl;
247 Circle_2 outer_circle(so1, so2, so3);
249 CGAL::intersection(outer_circle, perp, std::back_inserter(res));
251 for (iter = res.begin(); iter != res.end(); ++iter)
253 CGAL::Object obj = *iter;
254 if (
const std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned> *
point = CGAL::object_cast<std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned>>(&obj))
256 if (CGAL::to_double(
point->first.x()) > CGAL::to_double(p_loweredge.x()))
264 cout <<
"CGAL::Object type not pair..." << endl;
271 double xmidpoint = cos(phi_midpoint) * mid_radius;
272 double ymidpoint = sin(phi_midpoint) * mid_radius;
275 double xcoordup = xmidpoint -
m_ScintiGap / 2. * sin(angle_mid_scinti /
rad);
276 double ycoordup = ymidpoint -
m_ScintiGap / 2. * cos(angle_mid_scinti /
rad);
282 Line_2 sup(mid_upperscint, p_upperedge);
283 Line_2 perp = sup.perpendicular(p_upperedge);
285 Circle_2 inner_circle(sc1, sc2, sc3);
286 vector<CGAL::Object> res;
287 CGAL::intersection(inner_circle, perp, std::back_inserter(res));
288 vector<CGAL::Object>::const_iterator iter;
290 for (iter = res.begin(); iter != res.end(); ++iter)
292 CGAL::Object obj = *iter;
293 if (
const std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned> *
point = CGAL::object_cast<std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned>>(&obj))
295 if (CGAL::to_double(
point->first.x()) > pxmax)
297 pxmax = CGAL::to_double(
point->first.x());
304 cout <<
"CGAL::Object type not pair..." << endl;
308 Circle_2 outer_circle(so1, so2, so3);
310 CGAL::intersection(outer_circle, perp, std::back_inserter(res));
311 for (iter = res.begin(); iter != res.end(); ++iter)
313 CGAL::Object obj = *iter;
314 if (
const std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned> *
point = CGAL::object_cast<std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned>>(&obj))
316 if (CGAL::to_double(
point->first.x()) > CGAL::to_double(p_loweredge.x()))
324 cout <<
"CGAL::Object type not pair..." << endl;
331 G4TwoVector v1(CGAL::to_double(upperleft.x()), CGAL::to_double(upperleft.y()));
332 G4TwoVector v2(CGAL::to_double(upperright.x()), CGAL::to_double(upperright.y()));
333 G4TwoVector v3(CGAL::to_double(lowerright.x()), CGAL::to_double(lowerright.y()));
334 G4TwoVector v4(CGAL::to_double(lowerleft.x()), CGAL::to_double(lowerleft.y()));
335 std::vector<G4TwoVector> vertexes;
336 vertexes.push_back(v1);
337 vertexes.push_back(v2);
338 vertexes.push_back(v3);
339 vertexes.push_back(v4);
351 return steel_plate_uncut;
366 return steel_cut_solid;
371 Line_2 secant(lowleft, upleft);
374 double xmid = (CGAL::to_double(lowleft.x()) + CGAL::to_double(upleft.x())) / 2.;
375 double ymid = (CGAL::to_double(lowleft.y()) + CGAL::to_double(upleft.y())) / 2.;
377 Line_2 sekperp = secant.perpendicular(midpoint);
379 Circle_2 inner_circle(sc1, sc2, sc3);
380 vector<CGAL::Object> res;
381 CGAL::intersection(inner_circle, sekperp, std::back_inserter(res));
382 vector<CGAL::Object>::const_iterator iter;
385 for (iter = res.begin(); iter != res.end(); ++iter)
387 CGAL::Object obj = *iter;
388 if (
const std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned> *
point = CGAL::object_cast<std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned>>(&obj))
390 if (CGAL::to_double(
point->first.x()) > pxmax)
392 pxmax = CGAL::to_double(
point->first.x());
399 cout <<
"CGAL::Object type not pair..." << endl;
402 Line_2 leftside = sekperp.perpendicular(tangtouch);
403 CGAL::Object result = CGAL::intersection(upedge, leftside);
408 result = CGAL::intersection(lowedge, leftside);
455 boost::char_separator<char> sep(
"_");
456 boost::tokenizer<boost::char_separator<char>> tok((*it)->GetName(), sep);
457 boost::tokenizer<boost::char_separator<char>>::const_iterator tokeniter;
458 for (tokeniter = tok.begin(); tokeniter != tok.end(); ++tokeniter)
460 if (*tokeniter ==
"impr")
463 if (tokeniter != tok.end())
465 int layer_id = boost::lexical_cast<
int>(*tokeniter);
470 int tower_id = (*it)->GetCopyNo() - layer_id;
472 pair<int, int> layer_twr = make_pair(layer_id, tower_id);
476 cout <<
"invalid scintillator row " << layer_id
483 cout <<
PHWHERE <<
" Error parsing " << (*it)->GetName()
484 <<
" for mother volume number " << endl;
530 sumshift = sumshift - 2 * shiftup;
542 double xp = cos(phi) * middlerad;
543 double yp = sin(phi) * middlerad;
550 phi = -atan(yo / xo);
556 phi = -atan(yo / xo);
562 double ypos = sin(phi) * middlerad;
563 double xpos = cos(phi) * middlerad;
581 name <<
"OuterHcalSteel_" << i;
607 double inner_offset =
offset;
617 fill_n(zsteelcut, 4, NAN);
619 double steel_offset = 1 *
cm + steel_overhang;
622 double steel_inner_offset = steel_offset;
623 xsteelcut[0] = steel_x_inner + steel_magnet_cutout_x;
624 xsteelcut[1] = xsteelcut[0];
626 xsteelcut[3] = xsteelcut[2];
633 inner_offset = offset - magnet_cutout_x;
655 z[0] += scinti_gap_neighbor / 2.;
656 z[1] += scinti_gap_neighbor / 2.;
657 z[2] -= scinti_gap_neighbor / 2.;
658 z[3] -= scinti_gap_neighbor / 2.;
662 z[0] =
x_at_y(leftsidelow, leftsidehigh, x[0]);
664 z[1] =
x_at_y(leftsidelow, leftsidehigh, x[1]);
668 z[2] =
x_at_y(rightsidelow, rightsidehigh, x[2]);
670 z[3] =
x_at_y(rightsidelow, rightsidehigh, x[3]);
674 double x0 =
m_InnerRadius - (steel_inner_offset - steel_magnet_cutout_x);
675 double z0 =
x_at_y(leftsidelow, leftsidehigh, x0);
678 zsteelcut[3] =
x_at_y(leftsidelow, leftsidehigh, xpos);
681 double z2 =
x_at_y(rightsidelow, rightsidehigh, x2);
682 zsteelcut[1] = z2 + 1 *
cm;
683 zsteelcut[2] = z2 + 1 *
cm;
684 vector<G4TwoVector> vertexes;
685 for (
int j = 0; j < 4; j++)
688 vertexes.push_back(v);
700 name <<
"scintillator_" << i <<
"_left";
705 rotm->rotateX(90 *
deg);
707 name <<
"scintillator_" << i <<
"_right";
722 vector<G4TwoVector> vertexes;
723 for (
int j = 0; j < 4; j++)
730 vertexes.push_back(v);
746 x[0] = CGAL::to_double(p0.x());
747 x[1] = CGAL::to_double(p1.x());
749 double newx = fabs(x[0]) + fabs(x[1]);
753 CGAL::Object result = CGAL::intersection(l, s);
756 xret = CGAL::to_double(ipoint->x());
760 cout <<
PHWHERE <<
" failed for y = " << yin << endl;
761 cout <<
"p0(x): " << CGAL::to_double(p0.x()) <<
", p0(y): " << CGAL::to_double(p0.y()) << endl;
762 cout <<
"p1(x): " << CGAL::to_double(p1.x()) <<
", p1(y): " << CGAL::to_double(p1.y()) << endl;
866 cout <<
"both number of crossings and tilt angle are set" << endl;
867 cout <<
"using number of crossings to determine tilt angle" << endl;
875 Circle_2 inner_circle(pin1, pin2, pin3);
877 Circle_2 mid_circle(pmid1, pmid2, pmid3);
879 Circle_2 outer_circle(pout1, pout2, pout3);
880 Line_2 l_up(pnull, phightmp);
881 vector<CGAL::Object> res;
882 CGAL::intersection(outer_circle, l_up, std::back_inserter(res));
884 vector<CGAL::Object>::const_iterator iter;
885 for (iter = res.begin(); iter != res.end(); ++iter)
887 CGAL::Object obj = *iter;
888 if (
const std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned> *
point = CGAL::object_cast<std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned>>(&obj))
890 if (CGAL::to_double(
point->first.x()) > 0)
898 cout <<
"CGAL::Object type not pair..." << endl;
902 Line_2 l_right(plow, upperright);
905 CGAL::intersection(mid_circle, l_right, std::back_inserter(res));
906 for (iter = res.begin(); iter != res.end(); ++iter)
908 CGAL::Object obj = *iter;
909 if (
const std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned> *
point = CGAL::object_cast<std::pair<CGAL::Circular_arc_point_2<PHG4OuterHcalDetector::Circular_k>,
unsigned>>(&obj))
911 if (CGAL::to_double(
point->first.x()) > 0)
919 cout <<
"CGAL::Object type not pair..." << endl;
924 double ll = sqrt((CGAL::to_double(midpoint.x()) -
m_InnerRadius) * (CGAL::to_double(midpoint.x()) -
m_InnerRadius) + CGAL::to_double(midpoint.y()) * CGAL::to_double(midpoint.y()));
925 double upside = sqrt(CGAL::to_double(midpoint.x()) * CGAL::to_double(midpoint.x()) + CGAL::to_double(midpoint.y()) * CGAL::to_double(midpoint.y()));
929 tiltangle = tiltangle *
rad;
952 Circle_2 inner_circle(sc1, sc2, sc3);
953 vector<CGAL::Object> res;
954 CGAL::intersection(inner_circle, s2, std::back_inserter(res));
958 <<
" too large, no intersection with inner radius" << endl;
966 cout <<
"Outer Hcal Detector:" << endl;
967 if (what ==
"ALL" || what ==
"VOLUME")
984 cout <<
"could not locate volume " << volume->
GetName()
985 <<
" in Inner Hcal scintillator map" << endl;