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/GeoPublisher.h"
30 #include "GeoModelKernel/Units.h"
37 #include "GaudiKernel/MsgStream.h"
38 #include "GaudiKernel/ISvcLocator.h"
39 #include "GaudiKernel/PhysicalConstants.h"
40 #include "GaudiKernel/StatusCode.h"
45 #define SI GeoModelKernelUnits
53 ISvcLocator *svcLocator = Gaudi::svcLocator();
54 SmartIF<StoreGateSvc>
detStore{svcLocator->service(
"DetectorStore")};
56 throw std::runtime_error(
"Error in EndcapCryostatConstruction, cannot access DetectorStore");
61 SmartIF<IRDBAccessSvc> rdbAccess{svcLocator->service(
"RDBAccessSvc")};
62 if(!rdbAccess.isValid()){
63 throw std::runtime_error(
"EMECConstruction: cannot locate RDBAccessSvc!");
66 SmartIF<IGeoModelSvc> geoModelSvc{svcLocator->service(
"GeoModelSvc")};
67 if(!geoModelSvc.isValid()) {
68 throw std::runtime_error(
"EMECAccordionConstruction: cannot locate GeoModelSvc!");
72 IRDBRecordset_ptr DB_EmecGeometry = rdbAccess->getRecordsetPtr(
"EmecGeometry", larVersionKey.
tag(), larVersionKey.
node());
73 if(DB_EmecGeometry->size() == 0){
74 DB_EmecGeometry = rdbAccess->getRecordsetPtr(
"EmecGeometry",
"EmecGeometry-00");
77 IRDBRecordset_ptr emecWheelParameters = rdbAccess->getRecordsetPtr(
"EmecWheelParameters", larVersionKey.
tag(), larVersionKey.
node());
78 if(emecWheelParameters->size() == 0){
79 emecWheelParameters = rdbAccess->getRecordsetPtr(
"EmecWheelParameters",
"EmecWheelParameters-00");
83 IRDBRecordset_ptr emecMagicNumbers = rdbAccess->getRecordsetPtr(
"EmecMagicNumbers", larVersionKey.
tag(), larVersionKey.
node());
84 if(emecMagicNumbers->size() == 0){
85 emecMagicNumbers = rdbAccess->getRecordsetPtr(
"EmecMagicNumbers",
"EmecMagicNumbers-00");
88 IRDBRecordset_ptr coldContraction = rdbAccess->getRecordsetPtr(
"ColdContraction", larVersionKey.
tag(), larVersionKey.
node());
89 if(coldContraction->size() == 0){
90 coldContraction = rdbAccess->getRecordsetPtr(
"ColdContraction",
"ColdContraction-00");
94 if(emecFan->size() == 0){
95 emecFan = rdbAccess->getRecordsetPtr(
"EmecFan",
"EmecFan-00");
113 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setWheelParameters: wrong number of absorbers. (NABS = " +
std::to_string(
m_innerNoAbsorbes) +
") for Inner Wheel, expected 256!");
116 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setWheelParameters: wrong number of waves. (NACC = " +
std::to_string(
m_innerNoAbsorbes ) +
") for Inner Wheel, expected 6!");
119 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setWheelParameters: wrong width of absorber lips. (STRAIGHTSTARTSECTION = " +
std::to_string(
m_innerNoAbsorbes/
SI::mm) +
"), expected 2 mm!" );
122 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setWheelParameters: wrong width of absorber active zone. (ACTIVELENGTH = " +
std::to_string(
m_innerWaveZoneWidth/
SI::mm) +
"), expected 510 mm!");
139 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setWheelParameters: wrong number of absorbers. (NABS = " +
std::to_string (
m_outerNoAbsorbes) +
") for Outer Wheel, expected 768!");
142 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setWheelParameters: wrong number of waves. (NACC = " +
std::to_string(
m_outerNoAbsorbes) +
") for Outer Wheel, expected 9!" );
169 m_kContraction = (*coldContraction)[0]->getDouble(
"ABSORBERCONTRACTION");
183 double eleInvContraction = (*coldContraction)[0]->getDouble(
"ELECTRODEINVCONTRACTION");
194 m_innerWheel = innerWheel;
195 const GeoShape* shape = innerWheel->getLogVol()->getShape();
196 if (shape->type() !=
"Pcon") {
197 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setInnerWheel: unexpected shape type '"+ shape->type() +
"', expected 'Pcon'!");
199 const GeoPcon* pcon = (GeoPcon *)shape;
200 auto nplanes = pcon->getNPlanes();
202 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setInnerWheel: wrong number of Z planes '" +
std::to_string(nplanes) +
"', expected '2'!");
204 for (
unsigned int i = 0;
i < nplanes; ++
i)
206 m_zWheelInner[
i] = pcon->getZPlane(
i);
207 m_rMinInner[
i] = pcon->getRMinPlane(
i);
208 m_rMaxInner[
i] = pcon->getRMaxPlane(
i);
211 m_nameInnerWheel = innerWheel->getLogVol()->getName();
220 m_outerWheel = outerWheel;
221 const GeoShape* shape = outerWheel->getLogVol()->getShape();
222 if (shape->type() !=
"Pcon") {
223 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setOuterWheel: unexpected shape type '"+ shape->type() +
"', expected 'Pcon'!");
226 const GeoPcon* pcon = (GeoPcon *)shape;
227 auto nplanes = pcon->getNPlanes();
229 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setOuterWheel: wrong number of Z planes" +
std::to_string(nplanes) +
"', expected '3'!" );
231 for (
unsigned int i = 0;
i < nplanes; ++
i)
233 m_zWheelOuter[
i] = pcon->getZPlane(
i);
234 m_rMinOuter[
i] = pcon->getRMinPlane(
i);
235 m_rMaxOuter[
i] = pcon->getRMaxPlane(
i);
238 m_nameOuterWheel = outerWheel->getLogVol()->getName();
249 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setInnerWheelSlices: Inner Wheel volume is not set!" );
252 m_innerWheelRminIncrement = (m_rMinInner[1] - m_rMinInner[0])/(m_zWheelInner[1] - m_zWheelInner[0]);
253 m_innerWheelRmaxIncrement = (m_rMaxInner[1] - m_rMaxInner[0])/(m_zWheelInner[1] - m_zWheelInner[0]);
254 m_innerWheelZmin = m_zWheelInner[0];
255 m_innerWheelZmax = m_zWheelInner[1];
257 m_innerWheelZ[0] = m_innerWheelZmin;
258 m_innerWheelZ[1] = m_innerWheelZ[0] + m_innerLipWidth;
259 m_innerWheelZ[2] = m_innerWheelZ[1] + m_innerQuaterWaveWidth;
260 for (
int i = 3;
i < s_innerNoBlades - 1; ++
i)
262 m_innerWheelZ[
i] = m_innerWheelZ[
i - 1] + m_innerHalfWaveWidth;
264 m_innerWheelZ[s_innerNoBlades] = m_innerWheelZmax;
265 m_innerWheelZ[s_innerNoBlades - 1] = m_innerWheelZ[s_innerNoBlades] - m_innerLipWidth;
266 for (
int i = 0;
i < s_innerNoBlades + 1; ++
i)
268 m_innerWheelRmin[
i] = m_rMinInner[0] + (m_innerWheelZ[
i] - m_innerWheelZ[0])*m_innerWheelRminIncrement;
269 m_innerWheelRmax[
i] = m_rMaxInner[0] + (m_innerWheelZ[
i] - m_innerWheelZ[0])*m_innerWheelRmaxIncrement;
281 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setOuterWheelSlices: Outer Wheel volume is not set!");
284 m_outerWheelRminIncrement[0] = (m_rMinOuter[1] - m_rMinOuter[0])/(m_zWheelOuter[1] - m_zWheelOuter[0]);
285 m_outerWheelRminIncrement[1] = (m_rMinOuter[2] - m_rMinOuter[1])/(m_zWheelOuter[2] - m_zWheelOuter[1]);
286 m_outerWheelRmaxIncrement[0] = (m_rMaxOuter[1] - m_rMaxOuter[0])/(m_zWheelOuter[1] - m_zWheelOuter[0]);
287 m_outerWheelRmaxIncrement[1] = (m_rMaxOuter[2] - m_rMaxOuter[1])/(m_zWheelOuter[2] - m_zWheelOuter[1]);
288 m_outerWheelZmin = m_zWheelOuter[0];
289 m_outerWheelZmax = m_zWheelOuter[2];
291 m_outerWheelZ[0] = m_outerWheelZmin;
292 m_outerWheelZ[1] = m_outerWheelZ[0] + m_outerLipWidth;
293 m_outerWheelZ[2] = m_outerWheelZ[1] + m_outerQuaterWaveWidth;
294 for (
int i = 3;
i < s_outerNoBlades - 1; ++
i)
296 m_outerWheelZ[
i] = m_outerWheelZ[
i - 1] + m_outerHalfWaveWidth;
298 m_outerWheelZ[s_outerNoBlades] = m_outerWheelZmax;
299 m_outerWheelZ[s_outerNoBlades - 1] = m_outerWheelZ[s_outerNoBlades] - m_outerLipWidth;
300 for (
int i = 0;
i < s_outerNoBlades + 1; ++
i)
302 m_outerWheelRmin[
i] = m_rMinOuter[0] + (m_outerWheelZ[
i] - m_outerWheelZ[0])*m_outerWheelRminIncrement[0];
303 m_outerWheelRmax[
i] = m_rMaxOuter[0] + (m_outerWheelZ[
i] - m_outerWheelZ[0])*m_outerWheelRmaxIncrement[0];
304 if (m_outerWheelRmax[
i] > m_rMaxOuter[2]) m_outerWheelRmax[
i] = m_rMaxOuter[2];
314 const GeoMaterial* material)
316 if (
name ==
"LiquidArgon") m_materialLiquidArgon = material;
317 else if (
name ==
"Kapton") m_materialKapton = material;
318 else if (
name ==
"Lead" ) m_materialLead = material;
319 else if (
name ==
"Steel" ) m_materialSteel = material;
320 else if (
name ==
"Glue" ) m_materialGlue = material;
323 throw std::runtime_error(
"LArGeo::EMECAccordionConstruction::setMaterial: unexpected material name '" +
name +
"'!");
333 double& llip1,
double& ylip1,
334 double& llip2,
double& ylip2)
const
383 double cosa =
A[k1].dot(
A[k2])/(
A[k1].norm()*
A[k2].norm());
384 double ang = std::acos(cosa)/(k2 - k1);
387 double rmin = B[1].norm();
388 double rmax =
A[14].norm();
393 llip1 = (C[2] - D[2]).
norm();
394 ylip1 = (D[2] - B[1]).
norm() + llip1/2.;
397 llip2 = (C[3] - D[3]).
norm();
398 ylip2 = (D[3] - B[14]).
norm() + llip2/2.;
407 double& llip1,
double& ylip1,
408 double& llip2,
double& ylip2)
const
469 double cosa =
A[k1].dot(
A[k2])/(
A[k1].norm()*
A[k2].norm());
470 double ang = std::acos(cosa)/(k2 - k1);
473 double rmin = B[1].norm();
474 double rmax =
A[19].norm();
479 llip1 = (C[2] - D[2]).
norm();
480 ylip1 = (D[2] - B[1]).
norm() + llip1/2.;
483 llip2 = (C[3] - D[3]).
norm();
484 ylip2 = (D[3] - B[20]).
norm() + llip2/2.;
493 double rmin,
double rmax,
double zdel,
498 double xmin = std::sqrt(wmin*wmin - zdel*zdel)/2.;
499 double dxmin = (thickness/2.)*(wmin/zdel);
502 double xmax = std::sqrt(wmax*wmax - zdel*zdel)/2.;
503 double dxmax = (thickness/2.)*(wmax/zdel);
504 double xtmp = (
xmax + dxmax);
505 double ymax = std::sqrt(rmax*rmax - xtmp*xtmp);
524 double zmax,
double rmax)
const
532 plane.
m_d = -plane.
m_n.dot(pmin);
542 double zmax,
double rmax,
549 double d =
v.x()*pbot.y() -
v.y()*pbot.x();
550 double r = ptop.norm();
551 double l = std::sqrt(
r*
r -
d*
d);
552 double wmin = std::sqrt(rmin*rmin -
d*
d);
553 double wmax = std::sqrt(rmax*rmax -
d*
d);
554 double ymin = ptop.y() -
v.y()*(
l - wmin);
555 double ymax = ptop.y() -
v.y()*(
l - wmax);
559 v = (pmax - pmin).normalized();
563 plane.
m_d = -plane.
m_n.dot(pmin);
592 double pz1,
double pr1min,
double pr1max,
593 double pz2,
double pr2min,
double pr2max)
const
595 double z1 = pz1, r1min = pr1min, r1max = pr1max;
596 double z2 = pz2, r2min = pr2min, r2max = pr2max;
600 r1min -= (r2min - r1min);
601 r1max -= (r2max - r1max);
606 r2min += (r2min - r1min);
607 r2max += (r2max - r1max);
611 std::vector<GeoThreeVector> v3(8);
612 double kx = (icase == 2) ? 1 : -1;
615 for (
int i = 0;
i < 8; ++
i)
631 v3[0] = IntersectionPoint(v3[0], v3[3], botPlane);
632 v3[1] = IntersectionPoint(v3[1], v3[2], botPlane);
633 v3[4] = IntersectionPoint(v3[4], v3[7], botPlane);
634 v3[5] = IntersectionPoint(v3[5], v3[6], botPlane);
638 v3[3] = IntersectionPoint(v3[0], v3[3], topPlane);
639 v3[2] = IntersectionPoint(v3[1], v3[2], topPlane);
640 v3[7] = IntersectionPoint(v3[4], v3[7], topPlane);
641 v3[6] = IntersectionPoint(v3[5], v3[6], topPlane);
645 v3[0] = (v3[0] + v3[4])/2.;
646 v3[1] = (v3[1] + v3[5])/2.;
647 v3[2] = (v3[2] + v3[6])/2.;
648 v3[3] = (v3[3] + v3[7])/2.;
653 v3[4] = (v3[0] + v3[4])/2.;
654 v3[5] = (v3[1] + v3[5])/2.;
655 v3[6] = (v3[2] + v3[6])/2.;
656 v3[7] = (v3[3] + v3[7])/2.;
668 std::vector<GeoTwoVector>
v2(8);
669 for (
int i = 0;
i < 8;
i += 2)
671 double xmid = (v3[
i + 1].x() + v3[
i].x())/2.;
672 double xdel = (v3[
i + 1].x() - v3[
i].x())*xscale/2.;
676 return new GeoGenericTrap((pz2 - pz1)/2.,
v2);
687 for (
int islice = 0; islice < s_innerNoBlades; ++islice)
689 name = m_nameInnerWheel + m_nameSlice + m_nameSuffix[islice];
690 double dz = 0.5*(m_innerWheelZ[islice+1] - m_innerWheelZ[islice]);
691 solid =
new GeoCons(m_innerWheelRmin[islice], m_innerWheelRmin[islice+1],
692 m_innerWheelRmax[islice], m_innerWheelRmax[islice+1],
694 m_innerSlice[islice] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialLiquidArgon));
695 m_innerSliceOffset[islice] =
GeoThreeVector(0., 0., m_innerWheelZ[islice] + dz);
707 for (
int islice = 0; islice < s_outerNoBlades; ++islice)
709 name = m_nameOuterWheel + m_nameSlice + m_nameSuffix[islice];
710 double dz = 0.5*(m_outerWheelZ[islice+1] - m_outerWheelZ[islice]);
711 solid =
new GeoCons(m_outerWheelRmin[islice], m_outerWheelRmin[islice+1],
712 m_outerWheelRmax[islice], m_outerWheelRmax[islice+1],
714 m_outerSlice[islice] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialLiquidArgon));
715 m_outerSliceOffset[islice] =
GeoThreeVector(0., 0., m_outerWheelZ[islice] + dz);
726 double innerLipPosition1,
727 double innerLipLength2,
728 double innerLipPosition2)
730 double dx,
dy, dz, xoffset, yoffset, zoffset;
736 dx = 0.5*m_innerAbsorberThickness;
737 dy = 0.5*innerLipLength1;
738 dz = 0.5*m_innerLipWidth;
739 name = m_nameInnerWheel + m_nameAbsorber + m_nameSuffix[iblade];
740 solid =
new GeoBox(
dx,
dy, dz);
741 m_innerAbsorber[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialSteel));
743 name = m_nameInnerWheel + m_nameGlue + m_nameSuffix[iblade];
744 solid =
new GeoBox(
dx*m_innerGlueRatio,
dy, dz);
745 m_innerGlue[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialGlue));
747 name = m_nameInnerWheel + m_nameLead + m_nameSuffix[iblade];
748 solid =
new GeoBox(
dx*m_innerLeadRatio,
dy, dz);
749 m_innerLead[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialLead));
751 name = m_nameInnerWheel + m_nameElectrode + m_nameSuffix[iblade];
752 dx = 0.5*m_innerElectrodeThickness;
753 solid =
new GeoBox(
dx,
dy, dz);
754 m_innerElectrode[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialKapton));
758 yoffset = m_innerWheelRmin[1] + innerLipPosition1;
759 zoffset = m_innerWheelZmin + dz;
760 m_innerAbsorberOffset[iblade] =
GeoThreeVector(xoffset, yoffset, zoffset);
761 m_innerElectrodeOffset[iblade] =
GeoThreeVector(xoffset, yoffset, zoffset);
764 iblade = s_innerNoBlades - 1;
765 dx = 0.5*m_innerAbsorberThickness;
766 dy = 0.5*innerLipLength2;
767 dz = 0.5*m_innerLipWidth;
768 name = m_nameInnerWheel + m_nameAbsorber + m_nameSuffix[iblade];
769 solid =
new GeoBox(
dx,
dy, dz);
770 m_innerAbsorber[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialSteel));
772 name = m_nameInnerWheel + m_nameGlue + m_nameSuffix[iblade];
773 solid =
new GeoBox(
dx*m_innerGlueRatio,
dy, dz);
774 m_innerGlue[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialGlue));
776 name = m_nameInnerWheel + m_nameLead + m_nameSuffix[iblade];
777 solid =
new GeoBox(
dx*m_innerLeadRatio,
dy, dz);
778 m_innerLead[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialLead));
780 name = m_nameInnerWheel + m_nameElectrode + m_nameSuffix[iblade];
781 dx = 0.5*m_innerElectrodeThickness;
782 solid =
new GeoBox(
dx,
dy, dz);
783 m_innerElectrode[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialKapton));
787 yoffset = m_innerWheelRmin[s_innerNoBlades - 1] + innerLipPosition2;
788 zoffset = m_innerWheelZmax - dz;
789 m_innerAbsorberOffset[iblade] =
GeoThreeVector(xoffset, yoffset, zoffset);
790 m_innerElectrodeOffset[iblade] =
GeoThreeVector(xoffset, yoffset, zoffset);
799 double outerLipPosition1,
800 double outerLipLength2,
801 double outerLipPosition2)
803 double dx,
dy, dz, xoffset, yoffset, zoffset;
809 dx = 0.5*m_outerAbsorberThickness;
810 dy = 0.5*outerLipLength1;
811 dz = 0.5*m_outerLipWidth;
812 name = m_nameOuterWheel + m_nameAbsorber + m_nameSuffix[iblade];
813 solid =
new GeoBox(
dx,
dy, dz);
814 m_outerAbsorber[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialSteel));
816 name = m_nameOuterWheel + m_nameGlue + m_nameSuffix[iblade];
817 solid =
new GeoBox(
dx*m_outerGlueRatio,
dy, dz);
818 m_outerGlue[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialGlue));
820 name = m_nameOuterWheel + m_nameLead + m_nameSuffix[iblade];
821 solid =
new GeoBox(
dx*m_outerLeadRatio,
dy, dz);
822 m_outerLead[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialLead));
824 name = m_nameOuterWheel + m_nameElectrode + m_nameSuffix[iblade];
825 dx = 0.5*m_outerElectrodeThickness;
826 solid =
new GeoBox(
dx,
dy, dz);
827 m_outerElectrode[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialKapton));
831 yoffset = m_outerWheelRmin[1] + outerLipPosition1;
832 zoffset = m_outerWheelZmin + dz;
833 m_outerAbsorberOffset[iblade] =
GeoThreeVector(xoffset, yoffset, zoffset);
834 m_outerElectrodeOffset[iblade] =
GeoThreeVector(xoffset, yoffset, zoffset);
837 iblade = s_outerNoBlades - 1;
838 dx = 0.5*m_outerAbsorberThickness;
839 dy = 0.5*outerLipLength2;
840 dz = 0.5*m_outerLipWidth;
841 name = m_nameOuterWheel + m_nameAbsorber + m_nameSuffix[iblade];
842 solid =
new GeoBox(
dx,
dy, dz);
843 m_outerAbsorber[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialSteel));
845 name = m_nameOuterWheel + m_nameGlue + m_nameSuffix[iblade];
846 solid =
new GeoBox(
dx*m_outerGlueRatio,
dy, dz);
847 m_outerGlue[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialGlue));
849 name = m_nameOuterWheel + m_nameLead + m_nameSuffix[iblade];
850 solid =
new GeoBox(
dx*m_outerLeadRatio,
dy, dz);
851 m_outerLead[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialLead));
853 name = m_nameOuterWheel + m_nameElectrode + m_nameSuffix[iblade];
854 dx = 0.5*m_outerElectrodeThickness;
855 solid =
new GeoBox(
dx,
dy, dz);
856 m_outerElectrode[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialKapton));
860 yoffset = m_outerWheelRmin[s_outerNoBlades -1] + outerLipPosition2;
861 zoffset = m_outerWheelZmax - dz;
862 m_outerAbsorberOffset[iblade] =
GeoThreeVector(xoffset, yoffset, zoffset);
863 m_outerElectrodeOffset[iblade] =
GeoThreeVector(xoffset, yoffset, zoffset);
878 for (
int iblade = 1; iblade < s_innerNoBlades - 1; ++iblade)
880 int icase = (iblade%2 == 0) ? 2 : 3;
881 if (iblade == 1) icase = 1;
882 if (iblade == s_innerNoBlades - 2) icase = 4;
884 double z1 = m_innerWheelZ[iblade];
885 double r1min = m_innerWheelRmin[iblade];
886 double r1max = m_innerWheelRmax[iblade];
887 double z2 = m_innerWheelZ[iblade + 1];
888 double r2min = m_innerWheelRmin[iblade + 1];
889 double r2max = m_innerWheelRmax[iblade + 1];
892 name = m_nameInnerWheel + m_nameAbsorber + m_nameSuffix[iblade];
893 solid = constructBlade(icase, innerCorners, 1., z1, r1min, r1max, z2, r2min, r2max);
894 m_innerAbsorber[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialSteel));
896 name = m_nameInnerWheel + m_nameGlue + m_nameSuffix[iblade];
897 solid = constructBlade(icase, innerCorners, m_innerGlueRatio, z1, r1min, r1max, z2, r2min, r2max);
898 m_innerGlue[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialGlue));
900 name = m_nameInnerWheel + m_nameLead + m_nameSuffix[iblade];
901 solid = constructBlade(icase, innerCorners, m_innerLeadRatio, z1, r1min, r1max, z2, r2min, r2max);
902 m_innerLead[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialLead));
904 name = m_nameInnerWheel + m_nameElectrode + m_nameSuffix[iblade];
905 solid = constructBlade(icase, innerElectrodeCorners, 1., z1, r1min, r1max, z2, r2min, r2max);
906 m_innerElectrode[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialKapton));
909 m_innerAbsorberOffset[iblade] =
GeoThreeVector(0., 0., (z1 + z2)/2.);
910 m_innerElectrodeOffset[iblade] =
GeoThreeVector(0., 0., (z1 + z2)/2.);
926 for (
int iblade = 1; iblade < s_outerNoBlades - 1; ++iblade)
928 int icase = (iblade%2 == 0) ? 2 : 3;
929 if (iblade == 1) icase = 1;
930 if (iblade == s_outerNoBlades - 2) icase = 4;
932 double z1 = m_outerWheelZ[iblade];
933 double r1min = m_outerWheelRmin[iblade];
934 double r1max = m_outerWheelRmax[iblade];
935 double z2 = m_outerWheelZ[iblade + 1];
936 double r2min = m_outerWheelRmin[iblade + 1];
937 double r2max = m_outerWheelRmax[iblade + 1];
940 name = m_nameOuterWheel + m_nameAbsorber + m_nameSuffix[iblade];
941 solid = constructBlade(icase, outerCorners, 1., z1, r1min, r1max, z2, r2min, r2max);
942 m_outerAbsorber[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialSteel));
944 name = m_nameOuterWheel + m_nameGlue + m_nameSuffix[iblade];
945 solid = constructBlade(icase, outerCorners, m_outerGlueRatio, z1, r1min, r1max, z2, r2min, r2max);
946 m_outerGlue[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialGlue));
948 name = m_nameOuterWheel + m_nameLead + m_nameSuffix[iblade];
949 solid = constructBlade(icase, outerCorners, m_outerLeadRatio, z1, r1min, r1max, z2, r2min, r2max);
950 m_outerLead[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialLead));
953 name = m_nameOuterWheel + m_nameElectrode + m_nameSuffix[iblade];
954 solid = constructBlade(icase, outerElectrodeCorners, 1., z1, r1min, r1max, z2, r2min, r2max);
955 m_outerElectrode[iblade] =
new GeoPhysVol(
new GeoLogVol(
name, solid, m_materialKapton));
958 m_outerAbsorberOffset[iblade] =
GeoThreeVector(0., 0., (z1 + z2)/2.);
959 m_outerElectrodeOffset[iblade] =
GeoThreeVector(0., 0., (z1 + z2)/2.);
969 for (
int iblade = 0; iblade < s_innerNoBlades; ++iblade)
971 m_innerGlue[iblade]->add(m_innerLead[iblade]);
972 m_innerAbsorber[iblade]->add(m_innerGlue[iblade]);
982 for (
int iblade = 0; iblade < s_outerNoBlades; ++iblade)
984 m_outerGlue[iblade]->add(m_outerLead[iblade]);
985 m_outerAbsorber[iblade]->add(m_outerGlue[iblade]);
995 if (!makeSlices)
return;
996 for (
int islice = 0; islice < s_innerNoBlades; ++islice)
998 double x = m_innerSliceOffset[islice].x();
999 double y = m_innerSliceOffset[islice].y();
1000 double z = m_innerSliceOffset[islice].z();
1001 m_innerWheel->add(
new GeoTransform(GeoTrf::Translate3D(
x,
y,
z)));
1002 m_innerWheel->add(m_innerSlice[islice]);
1012 if (!makeSlices)
return;
1013 for (
int islice = 0; islice < s_outerNoBlades; ++islice)
1015 double x = m_outerSliceOffset[islice].x();
1016 double y = m_outerSliceOffset[islice].y();
1017 double z = m_outerSliceOffset[islice].z();
1018 m_outerWheel->add(
new GeoTransform(GeoTrf::Translate3D(
x,
y,
z)));
1019 m_outerWheel->add(m_outerSlice[islice]);
1032 int nphi = (makeSectors) ? m_innerNoElectrodes/innerNoSectors : m_innerNoElectrodes;
1033 double dphi =
SI::twopi/m_innerNoElectrodes;
1034 GeoPhysVol* mother =
nullptr;
1037 for (
int iphi = 0; iphi < nphi; ++iphi)
1040 int copyNo = iphi + 1;
1041 for (
int iblade = 0; iblade < s_innerNoBlades; ++iblade)
1043 if (makeSlices) mother = m_innerSlice[iblade];
1044 if (makeSectors) mother = m_innerSector[iblade];
1045 if (makeSlices || makeSectors)
1047 double x = m_innerElectrodeOffset[iblade].x();
1048 double y = m_innerElectrodeOffset[iblade].y();
1050 GeoTrf::Translate3D translation(
x,
y,
z);
1051 mother->add(
new GeoIdentifierTag(copyNo));
1052 mother->add(
new GeoTransform(
rotation*translation));
1053 mother->add(m_innerElectrode[iblade]);
1057 double x = m_innerElectrodeOffset[iblade].x();
1058 double y = m_innerElectrodeOffset[iblade].y();
1059 double z = m_innerElectrodeOffset[iblade].z();
1060 GeoTrf::Translate3D translation(
x,
y,
z);
1061 m_innerWheel->add(
new GeoIdentifierTag(copyNo));
1062 m_innerWheel->add(
new GeoTransform(
rotation*translation));
1063 m_innerWheel->add(m_innerElectrode[iblade]);
1069 for (
int iphi = 0; iphi < nphi; ++iphi)
1072 int copyNo = iphi + 1;
1073 for (
int iblade = 0; iblade < s_innerNoBlades; ++iblade)
1075 if (makeSlices) mother = m_innerSlice[iblade];
1076 if (makeSectors) mother = m_innerSector[iblade];
1077 if (makeSlices || makeSectors)
1079 double x = m_innerAbsorberOffset[iblade].x();
1080 double y = m_innerAbsorberOffset[iblade].y();
1082 GeoTrf::Translate3D translation(
x,
y,
z);
1083 mother->add(
new GeoIdentifierTag(copyNo));
1084 mother->add(
new GeoTransform(
rotation*translation));
1085 mother->add(m_innerAbsorber[iblade]);
1089 double x = m_innerAbsorberOffset[iblade].x();
1090 double y = m_innerAbsorberOffset[iblade].y();
1091 double z = m_innerAbsorberOffset[iblade].z();
1092 GeoTrf::Translate3D translation(
x,
y,
z);
1093 m_innerWheel->add(
new GeoIdentifierTag(copyNo));
1094 m_innerWheel->add(
new GeoTransform(
rotation*translation));
1095 m_innerWheel->add(m_innerAbsorber[iblade]);
1110 int nphi = (makeSectors) ? m_outerNoElectrodes/outerNoSectors : m_outerNoElectrodes;
1111 double dphi =
SI::twopi/m_outerNoElectrodes;
1112 GeoPhysVol* mother =
nullptr;
1115 for (
int iphi = 0; iphi < nphi; ++iphi)
1118 int copyNo = iphi + 1;
1119 for (
int iblade = 0; iblade < s_outerNoBlades; ++iblade)
1121 if (makeSlices) mother = m_outerSlice[iblade];
1122 if (makeSectors) mother = m_outerSector[iblade];
1123 if (makeSlices || makeSectors)
1125 double x = m_outerElectrodeOffset[iblade].x();
1126 double y = m_outerElectrodeOffset[iblade].y();
1128 GeoTrf::Translate3D translation(
x,
y,
z);
1129 mother->add(
new GeoIdentifierTag(copyNo));
1130 mother->add(
new GeoTransform(
rotation*translation));
1131 mother->add(m_outerElectrode[iblade]);
1135 double x = m_outerElectrodeOffset[iblade].x();
1136 double y = m_outerElectrodeOffset[iblade].y();
1137 double z = m_outerElectrodeOffset[iblade].z();
1138 GeoTrf::Translate3D translation(
x,
y,
z);
1139 m_outerWheel->add(
new GeoIdentifierTag(copyNo));
1140 m_outerWheel->add(
new GeoTransform(
rotation*translation));
1141 m_outerWheel->add(m_outerElectrode[iblade]);
1147 for (
int iphi = 0; iphi < nphi; ++iphi)
1150 int copyNo = iphi + 1;
1151 for (
int iblade = 0; iblade < s_outerNoBlades; ++iblade)
1153 if (makeSlices) mother = m_outerSlice[iblade];
1154 if (makeSectors) mother = m_outerSector[iblade];
1155 if (makeSlices || makeSectors)
1157 double x = m_outerAbsorberOffset[iblade].x();
1158 double y = m_outerAbsorberOffset[iblade].y();
1160 GeoTrf::Translate3D translation(
x,
y,
z);
1161 mother->add(
new GeoIdentifierTag(copyNo));
1162 mother->add(
new GeoTransform(
rotation*translation));
1163 mother->add(m_outerAbsorber[iblade]);
1167 double x = m_outerAbsorberOffset[iblade].x();
1168 double y = m_outerAbsorberOffset[iblade].y();
1169 double z = m_outerAbsorberOffset[iblade].z();
1170 GeoTrf::Translate3D translation(
x,
y,
z);
1171 m_outerWheel->add(
new GeoIdentifierTag(copyNo));
1172 m_outerWheel->add(
new GeoTransform(
rotation*translation));
1173 m_outerWheel->add(m_outerAbsorber[iblade]);
1186 bool makeSectors =
false;
1187 int innerNoSectors = 0;
1191 setInnerWheelSlices();
1194 double innerUncutBladeWidthMin, innerUncutBladeWidthMax;
1195 double innerLipLength1, innerLipPosition1;
1196 double innerLipLength2, innerLipPosition2;
1197 getInnerAbsorberData(innerUncutBladeWidthMin, innerUncutBladeWidthMax,
1198 innerLipLength1, innerLipPosition1,
1199 innerLipLength2, innerLipPosition2);
1200 innerUncutBladeWidthMin *= m_kContraction;
1201 innerUncutBladeWidthMax *= m_kContraction;
1202 innerLipLength1 *= m_kContraction;
1203 innerLipPosition1 *= m_kContraction;
1204 innerLipLength2 *= m_kContraction;
1205 innerLipPosition2 *= m_kContraction;
1209 double wmin, wmax, thickness, rmin, rmax, zdel;
1213 wmin = innerUncutBladeWidthMin;
1214 wmax = innerUncutBladeWidthMax;
1215 thickness = m_innerAbsorberThickness;
1216 rmin = m_innerWheelRmin[1];
1217 rmax = m_innerWheelRmax[s_innerNoBlades - 1];
1218 zdel = m_innerHalfWaveWidth;
1219 getBladeCorners(wmin, wmax, thickness, rmin, rmax, zdel, innerCorners);
1223 thickness = m_innerElectrodeThickness;
1224 getBladeCorners(wmin, wmax, thickness, rmin, rmax, zdel, innerElectrodeCorners);
1230 m_innerGlueRatio = (m_innerLeadThickness + 2*m_innerGlueThickness)/m_innerAbsorberThickness;
1231 m_innerLeadRatio = m_innerLeadThickness/m_innerAbsorberThickness;
1234 constructInnerLips(innerLipLength1, innerLipPosition1, innerLipLength2, innerLipPosition2);
1237 constructInnerBlades(innerCorners, innerElectrodeCorners);
1240 constructInnerSlices();
1247 placeInnerGlueAndLead();
1248 placeInnerSlices(makeSlices);
1250 placeInnerAccordion(innerNoSectors, makeSlices, makeSectors);
1260 bool makeSectors =
false;
1261 int outerNoSectors = 0;
1265 setOuterWheelSlices();
1268 double outerUncutBladeWidthMin, outerUncutBladeWidthMax;
1269 double outerLipLength1, outerLipPosition1;
1270 double outerLipLength2, outerLipPosition2;
1271 getOuterAbsorberData(outerUncutBladeWidthMin, outerUncutBladeWidthMax,
1272 outerLipLength1, outerLipPosition1,
1273 outerLipLength2, outerLipPosition2);
1274 outerUncutBladeWidthMin *= m_kContraction;
1275 outerUncutBladeWidthMax *= m_kContraction;
1276 outerLipLength1 *= m_kContraction;
1277 outerLipPosition1 *= m_kContraction;
1278 outerLipLength2 *= m_kContraction;
1279 outerLipPosition2 *= m_kContraction;
1283 double wmin, wmax, thickness, rmin, rmax, zdel;
1287 wmin = outerUncutBladeWidthMin;
1288 wmax = outerUncutBladeWidthMax;
1289 thickness = m_outerAbsorberThickness;
1290 rmin = m_outerWheelRmin[1];
1291 rmax = m_outerWheelRmax[s_outerNoBlades - 1];
1292 zdel = m_outerHalfWaveWidth;
1293 getBladeCorners(wmin, wmax, thickness, rmin, rmax, zdel, outerCorners);
1297 thickness = m_outerElectrodeThickness;
1298 getBladeCorners(wmin, wmax, thickness, rmin, rmax, zdel, outerElectrodeCorners);
1304 m_outerGlueRatio = (m_outerLeadThickness + 2*m_outerGlueThickness)/m_outerAbsorberThickness;
1305 m_outerLeadRatio = m_outerLeadThickness/m_outerAbsorberThickness;
1308 constructOuterLips(outerLipLength1, outerLipPosition1, outerLipLength2, outerLipPosition2);
1311 constructOuterBlades(outerCorners, outerElectrodeCorners);
1314 constructOuterSlices();
1321 placeOuterGlueAndLead();
1322 placeOuterSlices(makeSlices);
1324 placeOuterAccordion(outerNoSectors, makeSlices, makeSectors);