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 = 
static_cast<const 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 = 
static_cast<const 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);