16 #include "GeoModelKernel/GeoElement.h"
17 #include "GeoModelKernel/GeoMaterial.h"
18 #include "GeoModelKernel/GeoFullPhysVol.h"
19 #include "GeoModelKernel/GeoPhysVol.h"
20 #include "GeoModelKernel/GeoVPhysVol.h"
21 #include "GeoModelKernel/GeoLogVol.h"
22 #include "GeoModelKernel/GeoBox.h"
23 #include "GeoModelKernel/GeoCons.h"
24 #include "GeoModelKernel/GeoPcon.h"
25 #include "GeoModelKernel/GeoGenericTrap.h"
26 #include "GeoModelKernel/GeoNameTag.h"
27 #include "GeoModelKernel/GeoTransform.h"
28 #include "GeoModelKernel/GeoIdentifierTag.h"
29 #include "GeoModelKernel/Units.h"
36 #include "GaudiKernel/MsgStream.h"
37 #include "GaudiKernel/ISvcLocator.h"
38 #include "GaudiKernel/PhysicalConstants.h"
39 #include "GaudiKernel/StatusCode.h"
44 #define SI GeoModelKernelUnits
52 ISvcLocator *svcLocator = Gaudi::svcLocator();
53 SmartIF<StoreGateSvc>
detStore{svcLocator->service(
"DetectorStore")};
55 throw std::runtime_error(
"Error in EndcapCryostatConstruction, cannot access DetectorStore");
60 SmartIF<IRDBAccessSvc> rdbAccess{svcLocator->service(
"RDBAccessSvc")};
61 if(!rdbAccess.isValid()){
62 throw std::runtime_error(
"EMECConstruction: cannot locate RDBAccessSvc!");
65 SmartIF<IGeoModelSvc> geoModelSvc{svcLocator->service(
"GeoModelSvc")};
66 if(!geoModelSvc.isValid()) {
67 throw std::runtime_error(
"EMECAccordionConstruction: cannot locate GeoModelSvc!");
71 IRDBRecordset_ptr DB_EmecGeometry = rdbAccess->getRecordsetPtr(
"EmecGeometry", larVersionKey.
tag(), larVersionKey.
node());
72 if(DB_EmecGeometry->size() == 0){
73 DB_EmecGeometry = rdbAccess->getRecordsetPtr(
"EmecGeometry",
"EmecGeometry-00");
76 IRDBRecordset_ptr emecWheelParameters = rdbAccess->getRecordsetPtr(
"EmecWheelParameters", larVersionKey.
tag(), larVersionKey.
node());
77 if(emecWheelParameters->size() == 0){
78 emecWheelParameters = rdbAccess->getRecordsetPtr(
"EmecWheelParameters",
"EmecWheelParameters-00");
82 IRDBRecordset_ptr emecMagicNumbers = rdbAccess->getRecordsetPtr(
"EmecMagicNumbers", larVersionKey.
tag(), larVersionKey.
node());
83 if(emecMagicNumbers->size() == 0){
84 emecMagicNumbers = rdbAccess->getRecordsetPtr(
"EmecMagicNumbers",
"EmecMagicNumbers-00");
87 IRDBRecordset_ptr coldContraction = rdbAccess->getRecordsetPtr(
"ColdContraction", larVersionKey.
tag(), larVersionKey.
node());
88 if(coldContraction->size() == 0){
89 coldContraction = rdbAccess->getRecordsetPtr(
"ColdContraction",
"ColdContraction-00");
93 if(emecFan->size() == 0){
94 emecFan = rdbAccess->getRecordsetPtr(
"EmecFan",
"EmecFan-00");
112 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setWheelParameters: wrong number of absorbers. (NABS = " +
std::to_string(
m_innerNoAbsorbes) +
") for Inner Wheel, expected 256!");
115 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setWheelParameters: wrong number of waves. (NACC = " +
std::to_string(
m_innerNoAbsorbes ) +
") for Inner Wheel, expected 6!");
118 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setWheelParameters: wrong width of absorber lips. (STRAIGHTSTARTSECTION = " +
std::to_string(
m_innerNoAbsorbes/
SI::mm) +
"), expected 2 mm!" );
121 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setWheelParameters: wrong width of absorber active zone. (ACTIVELENGTH = " +
std::to_string(
m_innerWaveZoneWidth/
SI::mm) +
"), expected 510 mm!");
138 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setWheelParameters: wrong number of absorbers. (NABS = " +
std::to_string (
m_outerNoAbsorbes) +
") for Outer Wheel, expected 768!");
141 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setWheelParameters: wrong number of waves. (NACC = " +
std::to_string(
m_outerNoAbsorbes) +
") for Outer Wheel, expected 9!" );
168 m_kContraction = (*coldContraction)[0]->getDouble(
"ABSORBERCONTRACTION");
182 double eleInvContraction = (*coldContraction)[0]->getDouble(
"ELECTRODEINVCONTRACTION");
193 m_innerWheel = innerWheel;
194 const GeoShape* shape = innerWheel->getLogVol()->getShape();
195 if (shape->type() !=
"Pcon") {
196 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setInnerWheel: unexpected shape type '"+ shape->type() +
"', expected 'Pcon'!");
198 const GeoPcon* pcon =
static_cast<const GeoPcon*
>(shape);
199 auto nplanes = pcon->getNPlanes();
201 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setInnerWheel: wrong number of Z planes '" +
std::to_string(nplanes) +
"', expected '2'!");
203 for (
unsigned int i = 0;
i < nplanes; ++
i)
205 m_zWheelInner[
i] = pcon->getZPlane(
i);
206 m_rMinInner[
i] = pcon->getRMinPlane(
i);
207 m_rMaxInner[
i] = pcon->getRMaxPlane(
i);
210 m_nameInnerWheel = innerWheel->getLogVol()->getName();
219 m_outerWheel = outerWheel;
220 const GeoShape* shape = outerWheel->getLogVol()->getShape();
221 if (shape->type() !=
"Pcon") {
222 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setOuterWheel: unexpected shape type '"+ shape->type() +
"', expected 'Pcon'!");
225 const GeoPcon* pcon =
static_cast<const GeoPcon*
>(shape);
226 auto nplanes = pcon->getNPlanes();
228 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setOuterWheel: wrong number of Z planes" +
std::to_string(nplanes) +
"', expected '3'!" );
230 for (
unsigned int i = 0;
i < nplanes; ++
i)
232 m_zWheelOuter[
i] = pcon->getZPlane(
i);
233 m_rMinOuter[
i] = pcon->getRMinPlane(
i);
234 m_rMaxOuter[
i] = pcon->getRMaxPlane(
i);
237 m_nameOuterWheel = outerWheel->getLogVol()->getName();
248 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setInnerWheelSlices: Inner Wheel volume is not set!" );
251 m_innerWheelRminIncrement = (m_rMinInner[1] - m_rMinInner[0])/(m_zWheelInner[1] - m_zWheelInner[0]);
252 m_innerWheelRmaxIncrement = (m_rMaxInner[1] - m_rMaxInner[0])/(m_zWheelInner[1] - m_zWheelInner[0]);
253 m_innerWheelZmin = m_zWheelInner[0];
254 m_innerWheelZmax = m_zWheelInner[1];
256 m_innerWheelZ[0] = m_innerWheelZmin;
257 m_innerWheelZ[1] = m_innerWheelZ[0] + m_innerLipWidth;
258 m_innerWheelZ[2] = m_innerWheelZ[1] + m_innerQuaterWaveWidth;
259 for (
int i = 3;
i < s_innerNoBlades - 1; ++
i)
261 m_innerWheelZ[
i] = m_innerWheelZ[
i - 1] + m_innerHalfWaveWidth;
263 m_innerWheelZ[s_innerNoBlades] = m_innerWheelZmax;
264 m_innerWheelZ[s_innerNoBlades - 1] = m_innerWheelZ[s_innerNoBlades] - m_innerLipWidth;
265 for (
int i = 0;
i < s_innerNoBlades + 1; ++
i)
267 m_innerWheelRmin[
i] = m_rMinInner[0] + (m_innerWheelZ[
i] - m_innerWheelZ[0])*m_innerWheelRminIncrement;
268 m_innerWheelRmax[
i] = m_rMaxInner[0] + (m_innerWheelZ[
i] - m_innerWheelZ[0])*m_innerWheelRmaxIncrement;
280 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setOuterWheelSlices: Outer Wheel volume is not set!");
283 m_outerWheelRminIncrement[0] = (m_rMinOuter[1] - m_rMinOuter[0])/(m_zWheelOuter[1] - m_zWheelOuter[0]);
284 m_outerWheelRminIncrement[1] = (m_rMinOuter[2] - m_rMinOuter[1])/(m_zWheelOuter[2] - m_zWheelOuter[1]);
285 m_outerWheelRmaxIncrement[0] = (m_rMaxOuter[1] - m_rMaxOuter[0])/(m_zWheelOuter[1] - m_zWheelOuter[0]);
286 m_outerWheelRmaxIncrement[1] = (m_rMaxOuter[2] - m_rMaxOuter[1])/(m_zWheelOuter[2] - m_zWheelOuter[1]);
287 m_outerWheelZmin = m_zWheelOuter[0];
288 m_outerWheelZmax = m_zWheelOuter[2];
290 m_outerWheelZ[0] = m_outerWheelZmin;
291 m_outerWheelZ[1] = m_outerWheelZ[0] + m_outerLipWidth;
292 m_outerWheelZ[2] = m_outerWheelZ[1] + m_outerQuaterWaveWidth;
293 for (
int i = 3;
i < s_outerNoBlades - 1; ++
i)
295 m_outerWheelZ[
i] = m_outerWheelZ[
i - 1] + m_outerHalfWaveWidth;
297 m_outerWheelZ[s_outerNoBlades] = m_outerWheelZmax;
298 m_outerWheelZ[s_outerNoBlades - 1] = m_outerWheelZ[s_outerNoBlades] - m_outerLipWidth;
299 for (
int i = 0;
i < s_outerNoBlades + 1; ++
i)
301 m_outerWheelRmin[
i] = m_rMinOuter[0] + (m_outerWheelZ[
i] - m_outerWheelZ[0])*m_outerWheelRminIncrement[0];
302 m_outerWheelRmax[
i] = m_rMaxOuter[0] + (m_outerWheelZ[
i] - m_outerWheelZ[0])*m_outerWheelRmaxIncrement[0];
303 if (m_outerWheelRmax[
i] > m_rMaxOuter[2]) m_outerWheelRmax[
i] = m_rMaxOuter[2];
313 const GeoMaterial* material)
315 if (
name ==
"LiquidArgon") m_materialLiquidArgon = material;
316 else if (
name ==
"Kapton") m_materialKapton = material;
317 else if (
name ==
"Lead" ) m_materialLead = material;
318 else if (
name ==
"Steel" ) m_materialSteel = material;
319 else if (
name ==
"Glue" ) m_materialGlue = material;
322 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setMaterial: unexpected material name '" +
name +
"'!");
332 double& llip1,
double& ylip1,
333 double& llip2,
double& ylip2)
const
382 double cosa =
A[k1].dot(
A[k2])/(
A[k1].norm()*
A[k2].norm());
383 double ang = std::acos(cosa)/(k2 - k1);
386 double rmin = B[1].norm();
387 double rmax =
A[14].norm();
392 llip1 = (C[2] - D[2]).
norm();
393 ylip1 = (D[2] - B[1]).
norm() + llip1/2.;
396 llip2 = (C[3] - D[3]).
norm();
397 ylip2 = (D[3] - B[14]).
norm() + llip2/2.;
406 double& llip1,
double& ylip1,
407 double& llip2,
double& ylip2)
const
468 double cosa =
A[k1].dot(
A[k2])/(
A[k1].norm()*
A[k2].norm());
469 double ang = std::acos(cosa)/(k2 - k1);
472 double rmin = B[1].norm();
473 double rmax =
A[19].norm();
478 llip1 = (C[2] - D[2]).
norm();
479 ylip1 = (D[2] - B[1]).
norm() + llip1/2.;
482 llip2 = (C[3] - D[3]).
norm();
483 ylip2 = (D[3] - B[20]).
norm() + llip2/2.;
492 double rmin,
double rmax,
double zdel,
497 double xmin = std::sqrt(wmin*wmin - zdel*zdel)/2.;
498 double dxmin = (thickness/2.)*(wmin/zdel);
501 double xmax = std::sqrt(wmax*wmax - zdel*zdel)/2.;
502 double dxmax = (thickness/2.)*(wmax/zdel);
503 double xtmp = (
xmax + dxmax);
504 double ymax = std::sqrt(rmax*rmax - xtmp*xtmp);
523 double zmax,
double rmax)
const
531 plane.
m_d = -plane.
m_n.dot(pmin);
541 double zmax,
double rmax,
548 double d =
v.x()*pbot.y() -
v.y()*pbot.x();
549 double r = ptop.norm();
550 double l = std::sqrt(
r*
r -
d*
d);
551 double wmin = std::sqrt(rmin*rmin -
d*
d);
552 double wmax = std::sqrt(rmax*rmax -
d*
d);
553 double ymin = ptop.y() -
v.y()*(
l - wmin);
554 double ymax = ptop.y() -
v.y()*(
l - wmax);
558 v = (pmax - pmin).normalized();
562 plane.
m_d = -plane.
m_n.dot(pmin);
591 double pz1,
double pr1min,
double pr1max,
592 double pz2,
double pr2min,
double pr2max)
const
594 double z1 = pz1, r1min = pr1min, r1max = pr1max;
595 double z2 = pz2, r2min = pr2min, r2max = pr2max;
599 r1min -= (r2min - r1min);
600 r1max -= (r2max - r1max);
605 r2min += (r2min - r1min);
606 r2max += (r2max - r1max);
610 std::vector<GeoThreeVector> v3(8);
611 double kx = (icase == 2) ? 1 : -1;
614 for (
int i = 0;
i < 8; ++
i)
630 v3[0] = IntersectionPoint(v3[0], v3[3], botPlane);
631 v3[1] = IntersectionPoint(v3[1], v3[2], botPlane);
632 v3[4] = IntersectionPoint(v3[4], v3[7], botPlane);
633 v3[5] = IntersectionPoint(v3[5], v3[6], botPlane);
637 v3[3] = IntersectionPoint(v3[0], v3[3], topPlane);
638 v3[2] = IntersectionPoint(v3[1], v3[2], topPlane);
639 v3[7] = IntersectionPoint(v3[4], v3[7], topPlane);
640 v3[6] = IntersectionPoint(v3[5], v3[6], topPlane);
644 v3[0] = (v3[0] + v3[4])/2.;
645 v3[1] = (v3[1] + v3[5])/2.;
646 v3[2] = (v3[2] + v3[6])/2.;
647 v3[3] = (v3[3] + v3[7])/2.;
652 v3[4] = (v3[0] + v3[4])/2.;
653 v3[5] = (v3[1] + v3[5])/2.;
654 v3[6] = (v3[2] + v3[6])/2.;
655 v3[7] = (v3[3] + v3[7])/2.;
667 std::vector<GeoTwoVector>
v2(8);
668 for (
int i = 0;
i < 8;
i += 2)
670 double xmid = (v3[
i + 1].x() + v3[
i].x())/2.;
671 double xdel = (v3[
i + 1].x() - v3[
i].x())*xscale/2.;
675 return new GeoGenericTrap((pz2 - pz1)/2.,
v2);
686 for (
int islice = 0; islice < s_innerNoBlades; ++islice)
688 name = m_nameInnerWheel + m_nameSlice + m_nameSuffix[islice];
689 double dz = 0.5*(m_innerWheelZ[islice+1] - m_innerWheelZ[islice]);
690 solid =
new GeoCons(m_innerWheelRmin[islice], m_innerWheelRmin[islice+1],
691 m_innerWheelRmax[islice], m_innerWheelRmax[islice+1],
693 m_innerSlice[islice] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialLiquidArgon));
694 m_innerSliceOffset[islice] =
GeoThreeVector(0., 0., m_innerWheelZ[islice] + dz);
706 for (
int islice = 0; islice < s_outerNoBlades; ++islice)
708 name = m_nameOuterWheel + m_nameSlice + m_nameSuffix[islice];
709 double dz = 0.5*(m_outerWheelZ[islice+1] - m_outerWheelZ[islice]);
710 solid =
new GeoCons(m_outerWheelRmin[islice], m_outerWheelRmin[islice+1],
711 m_outerWheelRmax[islice], m_outerWheelRmax[islice+1],
713 m_outerSlice[islice] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialLiquidArgon));
714 m_outerSliceOffset[islice] =
GeoThreeVector(0., 0., m_outerWheelZ[islice] + dz);
725 double innerLipPosition1,
726 double innerLipLength2,
727 double innerLipPosition2)
729 double dx,
dy, dz, xoffset, yoffset, zoffset;
735 dx = 0.5*m_innerAbsorberThickness;
736 dy = 0.5*innerLipLength1;
737 dz = 0.5*m_innerLipWidth;
738 name = m_nameInnerWheel + m_nameAbsorber + m_nameSuffix[iblade];
739 solid =
new GeoBox(
dx,
dy, dz);
740 m_innerAbsorber[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialSteel));
742 name = m_nameInnerWheel + m_nameGlue + m_nameSuffix[iblade];
743 solid =
new GeoBox(
dx*m_innerGlueRatio,
dy, dz);
744 m_innerGlue[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialGlue));
746 name = m_nameInnerWheel + m_nameLead + m_nameSuffix[iblade];
747 solid =
new GeoBox(
dx*m_innerLeadRatio,
dy, dz);
748 m_innerLead[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialLead));
750 name = m_nameInnerWheel + m_nameElectrode + m_nameSuffix[iblade];
751 dx = 0.5*m_innerElectrodeThickness;
752 solid =
new GeoBox(
dx,
dy, dz);
753 m_innerElectrode[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialKapton));
757 yoffset = m_innerWheelRmin[1] + innerLipPosition1;
758 zoffset = m_innerWheelZmin + dz;
759 m_innerAbsorberOffset[iblade] =
GeoThreeVector(xoffset, yoffset, zoffset);
760 m_innerElectrodeOffset[iblade] =
GeoThreeVector(xoffset, yoffset, zoffset);
763 iblade = s_innerNoBlades - 1;
764 dx = 0.5*m_innerAbsorberThickness;
765 dy = 0.5*innerLipLength2;
766 dz = 0.5*m_innerLipWidth;
767 name = m_nameInnerWheel + m_nameAbsorber + m_nameSuffix[iblade];
768 solid =
new GeoBox(
dx,
dy, dz);
769 m_innerAbsorber[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialSteel));
771 name = m_nameInnerWheel + m_nameGlue + m_nameSuffix[iblade];
772 solid =
new GeoBox(
dx*m_innerGlueRatio,
dy, dz);
773 m_innerGlue[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialGlue));
775 name = m_nameInnerWheel + m_nameLead + m_nameSuffix[iblade];
776 solid =
new GeoBox(
dx*m_innerLeadRatio,
dy, dz);
777 m_innerLead[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialLead));
779 name = m_nameInnerWheel + m_nameElectrode + m_nameSuffix[iblade];
780 dx = 0.5*m_innerElectrodeThickness;
781 solid =
new GeoBox(
dx,
dy, dz);
782 m_innerElectrode[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialKapton));
786 yoffset = m_innerWheelRmin[s_innerNoBlades - 1] + innerLipPosition2;
787 zoffset = m_innerWheelZmax - dz;
788 m_innerAbsorberOffset[iblade] =
GeoThreeVector(xoffset, yoffset, zoffset);
789 m_innerElectrodeOffset[iblade] =
GeoThreeVector(xoffset, yoffset, zoffset);
798 double outerLipPosition1,
799 double outerLipLength2,
800 double outerLipPosition2)
802 double dx,
dy, dz, xoffset, yoffset, zoffset;
808 dx = 0.5*m_outerAbsorberThickness;
809 dy = 0.5*outerLipLength1;
810 dz = 0.5*m_outerLipWidth;
811 name = m_nameOuterWheel + m_nameAbsorber + m_nameSuffix[iblade];
812 solid =
new GeoBox(
dx,
dy, dz);
813 m_outerAbsorber[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialSteel));
815 name = m_nameOuterWheel + m_nameGlue + m_nameSuffix[iblade];
816 solid =
new GeoBox(
dx*m_outerGlueRatio,
dy, dz);
817 m_outerGlue[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialGlue));
819 name = m_nameOuterWheel + m_nameLead + m_nameSuffix[iblade];
820 solid =
new GeoBox(
dx*m_outerLeadRatio,
dy, dz);
821 m_outerLead[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialLead));
823 name = m_nameOuterWheel + m_nameElectrode + m_nameSuffix[iblade];
824 dx = 0.5*m_outerElectrodeThickness;
825 solid =
new GeoBox(
dx,
dy, dz);
826 m_outerElectrode[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialKapton));
830 yoffset = m_outerWheelRmin[1] + outerLipPosition1;
831 zoffset = m_outerWheelZmin + dz;
832 m_outerAbsorberOffset[iblade] =
GeoThreeVector(xoffset, yoffset, zoffset);
833 m_outerElectrodeOffset[iblade] =
GeoThreeVector(xoffset, yoffset, zoffset);
836 iblade = s_outerNoBlades - 1;
837 dx = 0.5*m_outerAbsorberThickness;
838 dy = 0.5*outerLipLength2;
839 dz = 0.5*m_outerLipWidth;
840 name = m_nameOuterWheel + m_nameAbsorber + m_nameSuffix[iblade];
841 solid =
new GeoBox(
dx,
dy, dz);
842 m_outerAbsorber[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialSteel));
844 name = m_nameOuterWheel + m_nameGlue + m_nameSuffix[iblade];
845 solid =
new GeoBox(
dx*m_outerGlueRatio,
dy, dz);
846 m_outerGlue[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialGlue));
848 name = m_nameOuterWheel + m_nameLead + m_nameSuffix[iblade];
849 solid =
new GeoBox(
dx*m_outerLeadRatio,
dy, dz);
850 m_outerLead[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialLead));
852 name = m_nameOuterWheel + m_nameElectrode + m_nameSuffix[iblade];
853 dx = 0.5*m_outerElectrodeThickness;
854 solid =
new GeoBox(
dx,
dy, dz);
855 m_outerElectrode[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialKapton));
859 yoffset = m_outerWheelRmin[s_outerNoBlades -1] + outerLipPosition2;
860 zoffset = m_outerWheelZmax - dz;
861 m_outerAbsorberOffset[iblade] =
GeoThreeVector(xoffset, yoffset, zoffset);
862 m_outerElectrodeOffset[iblade] =
GeoThreeVector(xoffset, yoffset, zoffset);
877 for (
int iblade = 1; iblade < s_innerNoBlades - 1; ++iblade)
879 int icase = (iblade%2 == 0) ? 2 : 3;
880 if (iblade == 1) icase = 1;
881 if (iblade == s_innerNoBlades - 2) icase = 4;
883 double z1 = m_innerWheelZ[iblade];
884 double r1min = m_innerWheelRmin[iblade];
885 double r1max = m_innerWheelRmax[iblade];
886 double z2 = m_innerWheelZ[iblade + 1];
887 double r2min = m_innerWheelRmin[iblade + 1];
888 double r2max = m_innerWheelRmax[iblade + 1];
891 name = m_nameInnerWheel + m_nameAbsorber + m_nameSuffix[iblade];
892 solid = constructBlade(icase, innerCorners, 1., z1, r1min, r1max, z2, r2min, r2max);
893 m_innerAbsorber[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialSteel));
895 name = m_nameInnerWheel + m_nameGlue + m_nameSuffix[iblade];
896 solid = constructBlade(icase, innerCorners, m_innerGlueRatio, z1, r1min, r1max, z2, r2min, r2max);
897 m_innerGlue[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialGlue));
899 name = m_nameInnerWheel + m_nameLead + m_nameSuffix[iblade];
900 solid = constructBlade(icase, innerCorners, m_innerLeadRatio, z1, r1min, r1max, z2, r2min, r2max);
901 m_innerLead[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialLead));
903 name = m_nameInnerWheel + m_nameElectrode + m_nameSuffix[iblade];
904 solid = constructBlade(icase, innerElectrodeCorners, 1., z1, r1min, r1max, z2, r2min, r2max);
905 m_innerElectrode[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialKapton));
908 m_innerAbsorberOffset[iblade] =
GeoThreeVector(0., 0., (z1 + z2)/2.);
909 m_innerElectrodeOffset[iblade] =
GeoThreeVector(0., 0., (z1 + z2)/2.);
925 for (
int iblade = 1; iblade < s_outerNoBlades - 1; ++iblade)
927 int icase = (iblade%2 == 0) ? 2 : 3;
928 if (iblade == 1) icase = 1;
929 if (iblade == s_outerNoBlades - 2) icase = 4;
931 double z1 = m_outerWheelZ[iblade];
932 double r1min = m_outerWheelRmin[iblade];
933 double r1max = m_outerWheelRmax[iblade];
934 double z2 = m_outerWheelZ[iblade + 1];
935 double r2min = m_outerWheelRmin[iblade + 1];
936 double r2max = m_outerWheelRmax[iblade + 1];
939 name = m_nameOuterWheel + m_nameAbsorber + m_nameSuffix[iblade];
940 solid = constructBlade(icase, outerCorners, 1., z1, r1min, r1max, z2, r2min, r2max);
941 m_outerAbsorber[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialSteel));
943 name = m_nameOuterWheel + m_nameGlue + m_nameSuffix[iblade];
944 solid = constructBlade(icase, outerCorners, m_outerGlueRatio, z1, r1min, r1max, z2, r2min, r2max);
945 m_outerGlue[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialGlue));
947 name = m_nameOuterWheel + m_nameLead + m_nameSuffix[iblade];
948 solid = constructBlade(icase, outerCorners, m_outerLeadRatio, z1, r1min, r1max, z2, r2min, r2max);
949 m_outerLead[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialLead));
952 name = m_nameOuterWheel + m_nameElectrode + m_nameSuffix[iblade];
953 solid = constructBlade(icase, outerElectrodeCorners, 1., z1, r1min, r1max, z2, r2min, r2max);
954 m_outerElectrode[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialKapton));
957 m_outerAbsorberOffset[iblade] =
GeoThreeVector(0., 0., (z1 + z2)/2.);
958 m_outerElectrodeOffset[iblade] =
GeoThreeVector(0., 0., (z1 + z2)/2.);
968 for (
int iblade = 0; iblade < s_innerNoBlades; ++iblade)
970 m_innerGlue[iblade]->add(m_innerLead[iblade]);
971 m_innerAbsorber[iblade]->add(m_innerGlue[iblade]);
981 for (
int iblade = 0; iblade < s_outerNoBlades; ++iblade)
983 m_outerGlue[iblade]->add(m_outerLead[iblade]);
984 m_outerAbsorber[iblade]->add(m_outerGlue[iblade]);
994 if (!makeSlices)
return;
995 for (
int islice = 0; islice < s_innerNoBlades; ++islice)
997 double x = m_innerSliceOffset[islice].x();
998 double y = m_innerSliceOffset[islice].y();
999 double z = m_innerSliceOffset[islice].z();
1000 m_innerWheel->add(
new GeoTransform(GeoTrf::Translate3D(
x,
y,
z)));
1001 m_innerWheel->add(m_innerSlice[islice]);
1011 if (!makeSlices)
return;
1012 for (
int islice = 0; islice < s_outerNoBlades; ++islice)
1014 double x = m_outerSliceOffset[islice].x();
1015 double y = m_outerSliceOffset[islice].y();
1016 double z = m_outerSliceOffset[islice].z();
1017 m_outerWheel->add(
new GeoTransform(GeoTrf::Translate3D(
x,
y,
z)));
1018 m_outerWheel->add(m_outerSlice[islice]);
1031 int nphi = (makeSectors) ? m_innerNoElectrodes/innerNoSectors : m_innerNoElectrodes;
1032 double dphi =
SI::twopi/m_innerNoElectrodes;
1033 GeoPhysVol* mother =
nullptr;
1036 for (
int iphi = 0; iphi < nphi; ++iphi)
1039 int copyNo = iphi + 1;
1040 for (
int iblade = 0; iblade < s_innerNoBlades; ++iblade)
1042 if (makeSlices) mother = m_innerSlice[iblade];
1043 if (makeSectors) mother = m_innerSector[iblade];
1044 if (makeSlices || makeSectors)
1046 double x = m_innerElectrodeOffset[iblade].x();
1047 double y = m_innerElectrodeOffset[iblade].y();
1049 GeoTrf::Translate3D translation(
x,
y,
z);
1050 mother->add(
new GeoIdentifierTag(copyNo));
1051 mother->add(
new GeoTransform(
rotation*translation));
1052 mother->add(m_innerElectrode[iblade]);
1056 double x = m_innerElectrodeOffset[iblade].x();
1057 double y = m_innerElectrodeOffset[iblade].y();
1058 double z = m_innerElectrodeOffset[iblade].z();
1059 GeoTrf::Translate3D translation(
x,
y,
z);
1060 m_innerWheel->add(
new GeoIdentifierTag(copyNo));
1061 m_innerWheel->add(
new GeoTransform(
rotation*translation));
1062 m_innerWheel->add(m_innerElectrode[iblade]);
1068 for (
int iphi = 0; iphi < nphi; ++iphi)
1071 int copyNo = iphi + 1;
1072 for (
int iblade = 0; iblade < s_innerNoBlades; ++iblade)
1074 if (makeSlices) mother = m_innerSlice[iblade];
1075 if (makeSectors) mother = m_innerSector[iblade];
1076 if (makeSlices || makeSectors)
1078 double x = m_innerAbsorberOffset[iblade].x();
1079 double y = m_innerAbsorberOffset[iblade].y();
1081 GeoTrf::Translate3D translation(
x,
y,
z);
1082 mother->add(
new GeoIdentifierTag(copyNo));
1083 mother->add(
new GeoTransform(
rotation*translation));
1084 mother->add(m_innerAbsorber[iblade]);
1088 double x = m_innerAbsorberOffset[iblade].x();
1089 double y = m_innerAbsorberOffset[iblade].y();
1090 double z = m_innerAbsorberOffset[iblade].z();
1091 GeoTrf::Translate3D translation(
x,
y,
z);
1092 m_innerWheel->add(
new GeoIdentifierTag(copyNo));
1093 m_innerWheel->add(
new GeoTransform(
rotation*translation));
1094 m_innerWheel->add(m_innerAbsorber[iblade]);
1109 int nphi = (makeSectors) ? m_outerNoElectrodes/outerNoSectors : m_outerNoElectrodes;
1110 double dphi =
SI::twopi/m_outerNoElectrodes;
1111 GeoPhysVol* mother =
nullptr;
1114 for (
int iphi = 0; iphi < nphi; ++iphi)
1117 int copyNo = iphi + 1;
1118 for (
int iblade = 0; iblade < s_outerNoBlades; ++iblade)
1120 if (makeSlices) mother = m_outerSlice[iblade];
1121 if (makeSectors) mother = m_outerSector[iblade];
1122 if (makeSlices || makeSectors)
1124 double x = m_outerElectrodeOffset[iblade].x();
1125 double y = m_outerElectrodeOffset[iblade].y();
1127 GeoTrf::Translate3D translation(
x,
y,
z);
1128 mother->add(
new GeoIdentifierTag(copyNo));
1129 mother->add(
new GeoTransform(
rotation*translation));
1130 mother->add(m_outerElectrode[iblade]);
1134 double x = m_outerElectrodeOffset[iblade].x();
1135 double y = m_outerElectrodeOffset[iblade].y();
1136 double z = m_outerElectrodeOffset[iblade].z();
1137 GeoTrf::Translate3D translation(
x,
y,
z);
1138 m_outerWheel->add(
new GeoIdentifierTag(copyNo));
1139 m_outerWheel->add(
new GeoTransform(
rotation*translation));
1140 m_outerWheel->add(m_outerElectrode[iblade]);
1146 for (
int iphi = 0; iphi < nphi; ++iphi)
1149 int copyNo = iphi + 1;
1150 for (
int iblade = 0; iblade < s_outerNoBlades; ++iblade)
1152 if (makeSlices) mother = m_outerSlice[iblade];
1153 if (makeSectors) mother = m_outerSector[iblade];
1154 if (makeSlices || makeSectors)
1156 double x = m_outerAbsorberOffset[iblade].x();
1157 double y = m_outerAbsorberOffset[iblade].y();
1159 GeoTrf::Translate3D translation(
x,
y,
z);
1160 mother->add(
new GeoIdentifierTag(copyNo));
1161 mother->add(
new GeoTransform(
rotation*translation));
1162 mother->add(m_outerAbsorber[iblade]);
1166 double x = m_outerAbsorberOffset[iblade].x();
1167 double y = m_outerAbsorberOffset[iblade].y();
1168 double z = m_outerAbsorberOffset[iblade].z();
1169 GeoTrf::Translate3D translation(
x,
y,
z);
1170 m_outerWheel->add(
new GeoIdentifierTag(copyNo));
1171 m_outerWheel->add(
new GeoTransform(
rotation*translation));
1172 m_outerWheel->add(m_outerAbsorber[iblade]);
1185 bool makeSectors =
false;
1186 int innerNoSectors = 0;
1190 setInnerWheelSlices();
1193 double innerUncutBladeWidthMin, innerUncutBladeWidthMax;
1194 double innerLipLength1, innerLipPosition1;
1195 double innerLipLength2, innerLipPosition2;
1196 getInnerAbsorberData(innerUncutBladeWidthMin, innerUncutBladeWidthMax,
1197 innerLipLength1, innerLipPosition1,
1198 innerLipLength2, innerLipPosition2);
1199 innerUncutBladeWidthMin *= m_kContraction;
1200 innerUncutBladeWidthMax *= m_kContraction;
1201 innerLipLength1 *= m_kContraction;
1202 innerLipPosition1 *= m_kContraction;
1203 innerLipLength2 *= m_kContraction;
1204 innerLipPosition2 *= m_kContraction;
1208 double wmin, wmax, thickness, rmin, rmax, zdel;
1212 wmin = innerUncutBladeWidthMin;
1213 wmax = innerUncutBladeWidthMax;
1214 thickness = m_innerAbsorberThickness;
1215 rmin = m_innerWheelRmin[1];
1216 rmax = m_innerWheelRmax[s_innerNoBlades - 1];
1217 zdel = m_innerHalfWaveWidth;
1218 getBladeCorners(wmin, wmax, thickness, rmin, rmax, zdel, innerCorners);
1222 thickness = m_innerElectrodeThickness;
1223 getBladeCorners(wmin, wmax, thickness, rmin, rmax, zdel, innerElectrodeCorners);
1229 m_innerGlueRatio = (m_innerLeadThickness + 2*m_innerGlueThickness)/m_innerAbsorberThickness;
1230 m_innerLeadRatio = m_innerLeadThickness/m_innerAbsorberThickness;
1233 constructInnerLips(innerLipLength1, innerLipPosition1, innerLipLength2, innerLipPosition2);
1236 constructInnerBlades(innerCorners, innerElectrodeCorners);
1239 constructInnerSlices();
1246 placeInnerGlueAndLead();
1247 placeInnerSlices(makeSlices);
1249 placeInnerAccordion(innerNoSectors, makeSlices, makeSectors);
1259 bool makeSectors =
false;
1260 int outerNoSectors = 0;
1264 setOuterWheelSlices();
1267 double outerUncutBladeWidthMin, outerUncutBladeWidthMax;
1268 double outerLipLength1, outerLipPosition1;
1269 double outerLipLength2, outerLipPosition2;
1270 getOuterAbsorberData(outerUncutBladeWidthMin, outerUncutBladeWidthMax,
1271 outerLipLength1, outerLipPosition1,
1272 outerLipLength2, outerLipPosition2);
1273 outerUncutBladeWidthMin *= m_kContraction;
1274 outerUncutBladeWidthMax *= m_kContraction;
1275 outerLipLength1 *= m_kContraction;
1276 outerLipPosition1 *= m_kContraction;
1277 outerLipLength2 *= m_kContraction;
1278 outerLipPosition2 *= m_kContraction;
1282 double wmin, wmax, thickness, rmin, rmax, zdel;
1286 wmin = outerUncutBladeWidthMin;
1287 wmax = outerUncutBladeWidthMax;
1288 thickness = m_outerAbsorberThickness;
1289 rmin = m_outerWheelRmin[1];
1290 rmax = m_outerWheelRmax[s_outerNoBlades - 1];
1291 zdel = m_outerHalfWaveWidth;
1292 getBladeCorners(wmin, wmax, thickness, rmin, rmax, zdel, outerCorners);
1296 thickness = m_outerElectrodeThickness;
1297 getBladeCorners(wmin, wmax, thickness, rmin, rmax, zdel, outerElectrodeCorners);
1303 m_outerGlueRatio = (m_outerLeadThickness + 2*m_outerGlueThickness)/m_outerAbsorberThickness;
1304 m_outerLeadRatio = m_outerLeadThickness/m_outerAbsorberThickness;
1307 constructOuterLips(outerLipLength1, outerLipPosition1, outerLipLength2, outerLipPosition2);
1310 constructOuterBlades(outerCorners, outerElectrodeCorners);
1313 constructOuterSlices();
1320 placeOuterGlueAndLead();
1321 placeOuterSlices(makeSlices);
1323 placeOuterAccordion(outerNoSectors, makeSlices, makeSectors);