Report problems to ATLAS LXR Team (with time and IP address indicated)

The LXR Cross Referencer

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Architecture: linux ]
Version: head ] [ nightly ] [ GaudiDev ]
  Links to LXR source navigation pages for stable releases [ 12.*.* ]   [ 13.*.* ]   [ 14.*.* ]   [ 15.*.* ] 

001 #include "MuonGeoModel/FeetToroidBuilderRDB.h"
002 #include "AthenaKernel/getMessageSvc.h"
003 
004 #include "RDBAccessSvc/IRDBRecord.h"
005 #include "RDBAccessSvc/IRDBRecordset.h"
006 #include "RDBAccessSvc/IRDBAccessSvc.h"
007 
008 #include "MuonGeoModel/ArrayFunction.h"
009 
010 #include "GeoModelKernel/GeoBox.h"
011 #include "GeoModelKernel/GeoTube.h"
012 #include "GeoModelKernel/GeoPcon.h"  
013 #include "GeoModelKernel/GeoTrd.h"
014 #include "GeoModelKernel/GeoTrap.h"
015 #include "GeoModelKernel/GeoPara.h"
016 #include "GeoModelKernel/GeoPgon.h"
017 #include "GeoModelKernel/GeoMaterial.h"
018 #include "GeoModelKernel/GeoLogVol.h"
019 #include "GeoModelKernel/GeoPhysVol.h"
020 #include "GeoModelKernel/GeoFullPhysVol.h"
021 #include "GeoModelKernel/GeoTransform.h"
022 #include "GeoModelKernel/GeoAlignableTransform.h"
023 #include "GeoModelKernel/GeoNameTag.h"
024 #include "GeoModelKernel/GeoShapeShift.h"
025 #include "GeoModelKernel/GeoShapeUnion.h"
026 #include "GeoModelKernel/GeoShapeSubtraction.h"
027 #include "GeoModelKernel/GeoSerialTransformer.h" 
028 #include "GeoModelKernel/GeoIdentifierTag.h"
029 #include "GeoModelSvc/StoredMaterialManager.h"
030 
031 #include "StoreGate/StoreGateSvc.h"
032 #include "CLHEP/GenericFunctions/Variable.hh"
033 
034 #include <stdexcept>
035 #include <vector>
036 #include <iomanip>  
037 
038 #include <sstream>
039 typedef std::stringstream  my_sstream;
040 typedef std::ostringstream my_osstream;
041 
042 using namespace Genfun;
043 using namespace GeoXF;
044 
045 namespace MuonGM {
046 FeetToroidBuilderRDB::FeetToroidBuilderRDB( StoreGateSvc  *pDetStore,
047                                     IRDBAccessSvc *pRDBAccess, 
048                                     std::string    geoTag,
049                                     std::string    geoNode )    :
050     m_pRDBAccess(pRDBAccess), 
051     m_pDetStore (pDetStore)
052 {
053     //  std::cout<<" FeetToroidBuilderRDB constructor "<<std::endl;
054     
055   MsgStream log( Athena::getMessageSvc(), "MuGM:FeetToroidBuildRDB" );
056   log << MSG::INFO << "Fetching data with tag <" << geoTag << ">" << endreq;
057 
058   m_Abrt = pRDBAccess->getRecordset("ABRT", geoTag, geoNode);
059   if (m_Abrt->size() == 0) {
060       log<<MSG::WARNING<<"Table ABRT not found in tag <"  <<  geoTag <<  ">"  <<" reading table ABRT-00" <<endreq;
061       m_Abrt = pRDBAccess->getRecordset("ABRT","ABRT-00");
062   }
063   m_Feet = pRDBAccess->getRecordset("FEET", geoTag, geoNode);
064   if (m_Feet->size() == 0) {
065       log<<MSG::WARNING<<"Table FEET not found in tag <"  <<  geoTag <<  ">"  <<" reading table FEET-00" <<endreq;
066       m_Feet = pRDBAccess->getRecordset("FEET","FEET-00");
067   }
068   m_Aect = pRDBAccess->getRecordset("AECT", geoTag, geoNode);
069   if (m_Aect->size() == 0) {
070       log<<MSG::WARNING<<"Table ABRT not found in tag <"  <<  geoTag <<  ">"  <<" reading table AECT-00" <<endreq;
071       m_Aect = pRDBAccess->getRecordset("AECT","AECT-00");
072   }
073   m_Rail = pRDBAccess->getRecordset("RAIL", geoTag, geoNode);
074   if (m_Rail->size() == 0) {
075       log<<MSG::WARNING<<"Table RAIL not found in tag <"  <<  geoTag <<  ">"  <<" reading table RAIL-00" <<endreq;
076       m_Rail = pRDBAccess->getRecordset("RAIL","RAIL-00");
077   }
078 
079   //  std::cout <<" FeetToroidBuilderRDB : maxDim "<< maxDim <<" nFeet "<< nFeet <<" nVertex "<< nVertex <<std::endl;
080 
081   std::string Iron = "Iron";
082   std::string Aluminium = "Alum";
083 
084 }
085 
086 void FeetToroidBuilderRDB::buildStandardFeet( GeoPhysVol* container ) 
087 {
088 //------------------------------------------------------------------------------------------
089 //  Builds Standard Feet (all but the two outermost feet pairs) -- sideplates, bottom plate, 
090 //  inner and top vertical plates  
091 //------------------------------------------------------------------------------------------
092 
093   const StoredMaterialManager*  theMaterialManager;
094   if ( StatusCode::SUCCESS != m_pDetStore->retrieve( theMaterialManager, "MATERIALS" ) ) 
095   {
096     return;
097   } 
098 
099 //------------ Feet General Parameters ---------------------------------//
100   double zPositionFeet[maxDim];
101   zPositionFeet[0] = -(*m_Feet)[0]->getFloat("ZPOSFEE5") * mm;
102   zPositionFeet[1] = -(*m_Feet)[0]->getFloat("ZPOSFEE4") * mm;
103   zPositionFeet[2] = -(*m_Feet)[0]->getFloat("ZPOSFEE3") * mm;
104   zPositionFeet[3] = -(*m_Feet)[0]->getFloat("ZPOSFEE2") * mm;
105   zPositionFeet[4] =  (*m_Feet)[0]->getFloat("ZPOSFEE1") * mm;
106   zPositionFeet[5] =  (*m_Feet)[0]->getFloat("ZPOSFEE2") * mm;
107   zPositionFeet[6] =  (*m_Feet)[0]->getFloat("ZPOSFEE3") * mm;
108   zPositionFeet[7] =  (*m_Feet)[0]->getFloat("ZPOSFEE4") * mm;
109   zPositionFeet[8] =  (*m_Feet)[0]->getFloat("ZPOSFEE5") * mm;
110 
111    const double thicknessSidePlate   = (*m_Feet)[0]->getFloat("MAINPLDZ") * mm;
112    const double thicknessBottomPlate = (*m_Feet)[0]->getFloat("MNPLPEHE") * mm;
113    const double thicknessLargePlate  = (*m_Feet)[0]->getFloat("VCNPLXWI") * mm;
114    const double thicknessOuterPlate  = (*m_Feet)[0]->getFloat("SLACPLYH") * mm;
115 
116    const std::string feetMaterial = getMaterial( "Iron" );
117 //------------ Standard Feet Parameters ----------------------------------------------
118    const double zWidth = (*m_Feet)[0]->getFloat("MNPLZSEP") * mm;
119 
120    double xPosVertexStandFeet[maxDim], yPosVertexStandFeet[maxDim];
121 
122    xPosVertexStandFeet[0] = (*m_Feet)[0]->getFloat("MAINPLXB") * mm;
123    yPosVertexStandFeet[0] = (*m_Feet)[0]->getFloat("MAINPLYB") * mm;
124    xPosVertexStandFeet[1] = (*m_Feet)[0]->getFloat("MAINPLXC") * mm;
125    yPosVertexStandFeet[1] = (*m_Feet)[0]->getFloat("MAINPLYC") * mm;
126    xPosVertexStandFeet[2] = (*m_Feet)[0]->getFloat("MAINPLXE") * mm;
127    yPosVertexStandFeet[2] = (*m_Feet)[0]->getFloat("MAINPLYE") * mm;  
128    xPosVertexStandFeet[3] = (*m_Feet)[0]->getFloat("MAINPLXF") * mm;
129    yPosVertexStandFeet[3] = (*m_Feet)[0]->getFloat("MAINPLYF") * mm;
130    xPosVertexStandFeet[4] = (*m_Feet)[0]->getFloat("MAINPLXG") * mm;
131    yPosVertexStandFeet[4] = (*m_Feet)[0]->getFloat("MAINPLYG") * mm;
132    xPosVertexStandFeet[5] = (*m_Feet)[0]->getFloat("MAINPLXH") * mm;
133    yPosVertexStandFeet[5] = (*m_Feet)[0]->getFloat("MAINPLYH") * mm;
134    xPosVertexStandFeet[6] = (*m_Feet)[0]->getFloat("MAINPLXI") * mm;
135    yPosVertexStandFeet[6] = (*m_Feet)[0]->getFloat("MAINPLYI") * mm;
136    xPosVertexStandFeet[7] = (*m_Feet)[0]->getFloat("MAINPLXJ") * mm;
137    yPosVertexStandFeet[7] = (*m_Feet)[0]->getFloat("MAINPLYJ") * mm;
138    xPosVertexStandFeet[8] = (*m_Feet)[0]->getFloat("MAINPLXA") * mm;
139    yPosVertexStandFeet[8] = (*m_Feet)[0]->getFloat("MAINPLYA") * mm;
140 
141    const double xPosVertexC1StandFeet        = (*m_Feet)[0]->getFloat("MAIPLXC1") * mm;
142    const double yPosVertexC1StandFeet        = (*m_Feet)[0]->getFloat("MAIPLYC1") * mm;
143    const double xPosFoot                     = (*m_Feet)[0]->getFloat("STDFOOXP") * mm;
144    const double yPosFoot                     = (*m_Feet)[0]->getFloat("STDFOOYP") * mm;
145    const double xSecCentreCutoutStandFeet    = (*m_Feet)[0]->getFloat("MPLXEXTR") * mm;
146    const double ySecCentreCutoutStandFeet    = (*m_Feet)[0]->getFloat("MPLYEXTR") * mm;
147    const double SecradiusCutout              = (*m_Feet)[0]->getFloat("MPLREXTR") * mm;
148    const double HeightCutCom                 = (*m_Feet)[0]->getFloat("MPLAHCEC") * mm;
149    const double xCentreCutoutStandFeet       = (*m_Feet)[0]->getFloat("MAPLRCXC") * mm;
150    const double yCentreCutoutStandFeet       = (*m_Feet)[0]->getFloat("MAPLRCYC") * mm;
151    const double radiusCutout                 = (*m_Feet)[0]->getFloat("MNPLRCRA") * mm;
152    const double phiMinCutout                 =  135.   * deg; // fstd PHMINCUT
153    const double phiMaxCutout                 =  292.5  * deg; // fstd PHMAXCUT
154    const double yMinLargePlate               = (*m_Feet)[0]->getFloat("VCNPLDYE") * mm;  
155    const double yHeightLargePlate            = (*m_Feet)[0]->getFloat("VCNPLYHE") * mm;  
156    const double xPosLargePlateStandFeet      = (*m_Feet)[0]->getFloat("VECPXPOS") * mm;
157    const double thicknessInnerPlate          = (*m_Feet)[0]->getFloat("UCNPLXWI") * mm;
158    const double zWidthBotP                   = (*m_Feet)[0]->getFloat("GRNDPLZL") * mm;
159    const double zWidthMiniP                  = (*m_Feet)[0]->getFloat("MINCPLZL")* mm;
160    const double yHeightMiniP                 = (*m_Feet)[0]->getFloat("MINCPLYH")* mm;
161    const double xlengthMiniP                 = (*m_Feet)[0]->getFloat("MINCPLXW")* mm;
162    const double xPosMiniConnPlateStandFeet   = (*m_Feet)[0]->getFloat("MICPXPOS") * mm;
163    const double yPosMiniConnPlateStandFeet   = (*m_Feet)[0]->getFloat("MICPYPOS") * mm;
164    const double zWidthOuterP                 = (*m_Feet)[0]->getFloat("SLACPLZL") * mm;
165    const double lengthOuterPlate             = (*m_Feet)[0]->getFloat("SLACPLXW") * mm;
166 
167    // std::cout<<" FeetToroidBuilderRDBn:: Oracle reading finished " <<std::endl;
168 //----------------------------------------------------------------------------//
169   
170   const double tolerance = 0.5*mm;
171   
172   for (int i = 0; i < nVertex; i++)
173   {
174   xPosVertexStandFeet[i] = xPosVertexStandFeet[i] + xPosFoot;
175   yPosVertexStandFeet[i] = yPosVertexStandFeet[i] + yPosFoot;
176   }
177 
178   // auxiliary arrays to store z, x positions, and rotation angles for all volumes to be replicated 
179   const int nZPosMax = 2 * ( maxDim - 2 );
180   const int nXPosMax = 2;
181   double zPosAux[ nZPosMax * nXPosMax ],  xPosAux[ nZPosMax * nXPosMax ],  
182      rotAngleAux[ nZPosMax * nXPosMax ];
183   
184   //------------------------------------------------------------------------------------------
185   // Standard Feet properties
186       
187   const double xPosMiniP    = xPosMiniConnPlateStandFeet + xPosFoot;
188   const double yPosMiniP    = yPosMiniConnPlateStandFeet + yPosFoot;
189   
190   const double yMinLargeP   = yMinLargePlate + yPosFoot;
191   
192   const double xPosVertexC1 = xPosVertexC1StandFeet + xPosFoot;
193   const double yPosVertexC1 = yPosVertexC1StandFeet + yPosFoot;
194   
195   // polygonal shape of side-plate envelope
196   const double* xPosVertex = xPosVertexStandFeet;         // x,y positions of vertices
197   const double* yPosVertex = yPosVertexStandFeet; 
198   
199   // cutout circle (segment) for Barrel Toroid coils .  
200   const double xPosCentreCutout    = xCentreCutoutStandFeet + xPosFoot;  // x-position of centre
201   const double yPosCentreCutout    = yCentreCutoutStandFeet + yPosFoot;  // y-position of centre 
202   const double xPosSecCentreCutout = xSecCentreCutoutStandFeet + xPosFoot; // x-position of centre second circle for cutout
203   const double yPosSecCentreCutout = ySecCentreCutoutStandFeet + yPosFoot; // y-position of centre second circle for cutout   
204   
205 // large vertical plate (between the two side plates) 
206   const double xMeanLargePlate     = xPosLargePlateStandFeet + xPosFoot; // x position of centre
207 
208 //y-position of small inner vertical plate (on top; where Voussoirs are mounted)
209   const double yPosInnerPlateStd   = 0.5 * ( yPosVertex[4] + yPosVertex[5] );
210 
211 //------------------------------------------------------------------------------------------
212 //  Build side plates 
213 //  - the base shape is a union of three trapezoids, from which a protruding edge 
214 //    (by means of a box), and the space for the Barrel Toroid coil (by means of a two tubes 
215 //    and two boxes) are cut out  
216 //------------------------------------------------------------------------------------------
217 
218   double pDy = thicknessSidePlate/2;
219 
220 //------------------------------------------------------------------------------------------
221 // base shape
222 //------------------------------------------------------------------------------------------
223 // first (base) trapezoid (vertices 1,2,8,9, counter-clockwise) 
224 // - note that axes don't coincide with global coordinates
225   double pDzTrap1    = 0.5 * ( xPosVertex[0] - xPosVertex[8] );
226   double pDx1Trap1   = 0.5 * ( yPosVertex[7] - yPosVertex[8] );
227   double pDx3Trap1   = 0.5 * ( yPosVertex[1] - yPosVertex[0] ); 
228   double pThetaTrap1 = atan( 0.5 * ( pDx3Trap1 - pDx1Trap1 ) / pDzTrap1 );
229 
230   GeoTrap* sTrap1 = new GeoTrap( pDzTrap1, pThetaTrap1, 0,
231                                  pDy, pDx1Trap1 - tolerance, pDx1Trap1 - tolerance, 0,
232                                  pDy, pDx3Trap1 - tolerance, pDx3Trap1 - tolerance, 0 );
233   
234 // positioning (not the final one)
235   HepTransform3D trlTrap1 = HepTranslate3D( yPosVertex[8] + 0.5 * ( pDx1Trap1 + pDx3Trap1 ), 0,
236                                             xPosVertex[8] + pDzTrap1 );
237 
238 //------------------------------------------------------------------------------------------
239 // second (middle) trapezoid: the vertices are 2,3; the intersection point of the
240 // lines through (3,6), (7,8); and 8 (counter-clockwise) 
241 // - note that axes don't coincide with global coordinates
242   double dx12 = fabs( xPosVertex[1] - xPosVertex[2] );
243   double dy12 = fabs( yPosVertex[1] - yPosVertex[2] );
244   double beta = atan( dx12/dy12 );  // inclination angle (~22.5 deg)
245 
246   double dx17      = fabs( xPosVertex[1] - xPosVertex[7] );
247   double dy17      = fabs( yPosVertex[1] - yPosVertex[7] );
248   double aux       = dy17 + dx17 * tan(beta);
249   double cosBeta   = cos(beta);
250   double sinBeta   = sin(beta);
251   double pDzTrap2  = 0.5 * ( dx17/cosBeta - aux * sinBeta );
252   double pDx3Trap2 = 0.5 * dy12/cosBeta;
253  
254   double dx25      = fabs( xPosVertex[2] - xPosVertex[5] );
255   double dy25      = fabs( yPosVertex[2] - yPosVertex[5] );
256   double gamma1    = atan( dy25/dx25 );
257   double gamma2    = atan( dy17/dx17 );
258   double pDx1Trap2 = pDx3Trap2 - pDzTrap2 * ( tan( gamma2 + beta ) + tan( gamma1 - beta ) ); 
259 
260   double tanTheta    = 0.5 * ( pDx1Trap2 - pDx3Trap2 )/pDzTrap2 + tan( gamma1 - beta );
261   double pThetaTrap2 = atan(tanTheta);
262 
263   GeoTrap* sTrap2 = new GeoTrap( pDzTrap2, pThetaTrap2, 0,
264                                  pDy, pDx1Trap2 - tolerance, pDx1Trap2 - tolerance, 0,
265                                  pDy, pDx3Trap2 - tolerance, pDx3Trap2 - tolerance, 0 );
266   
267 // position/orientation relative to first trapezoid
268   double pDxMeanTrap2  = 0.5 * ( pDx1Trap2 + pDx3Trap2 ); 
269   HepTransform3D trlTrap2 = HepTranslate3D( yPosVertex[1] + dy17/2 + pDxMeanTrap2 * cosBeta, 0,
270                                             xPosVertex[1] - dx17/2 - pDxMeanTrap2 * sinBeta );
271   trlTrap2 = trlTrap2 * trlTrap1.inverse();
272   HepTransform3D xfTrap2 = trlTrap2 * HepRotateY3D(beta);
273   
274 //----------------------------------------------------------------------------------------
275 // third (top) trapezoid (vertices 3,4,5,6, counter-clockwise)
276 // - note that axes don't coincide with global coordinates
277   double pDzTrap3    = 0.5 * ( xPosVertex[3] - xPosVertex[4] );
278   double pDx1Trap3   = 0.5 * ( yPosVertex[4] - yPosVertex[5] );
279   double pDx3Trap3   = 0.5 * ( yPosVertex[3] - yPosVertex[2] ); 
280   double pThetaTrap3 = atan( 0.5 * ( pDx1Trap3 - pDx3Trap3 )/pDzTrap3 );
281 
282   GeoTrap* sTrap3 = new GeoTrap( pDzTrap3, pThetaTrap3, 0,
283                                  pDy, pDx1Trap3 - tolerance, pDx1Trap3 - tolerance, 0,
284                                  pDy, pDx3Trap3 - tolerance, pDx3Trap3 - tolerance, 0 );
285 
286 // position relative to first trapezoid
287   HepTransform3D xfTrap3 = HepTranslate3D( yPosVertex[4] - 0.5 * ( pDx1Trap3 + pDx3Trap3 ), 0,
288                                            xPosVertex[4] + pDzTrap3 );
289   xfTrap3 = xfTrap3 * trlTrap1.inverse();
290 
291 // MiniConn Plates
292   //ss 12/02/2007 never used GeoBox* sMiniConnPlate = new GeoBox( yHeightMiniP/2 - tolerance, zWidthMiniP/2, xlengthMiniP/2 );
293 //empty MiniConn plates
294   GeoBox* sEmptyMiniConnPlate = new GeoBox( yHeightMiniP/2, zWidthMiniP/4, xlengthMiniP/2
295                                             + tolerance );
296   
297   HepTransform3D trlMiniConnPlate = HepTranslate3D( yPosMiniP, 0, xPosMiniP );
298   trlMiniConnPlate = trlMiniConnPlate * trlTrap1.inverse();
299   HepTransform3D xfMiniConnPlate = trlMiniConnPlate * HepRotateY3D(beta);
300 
301 //------------------------------------------------------------------------------------------
302 // shapes to be cut out
303 //------------------------------------------------------------------------------------------
304 // box to cut out the protruding edge of the middle trapezoid (uses vertices 6,7)
305   double dx56   = fabs( xPosVertex[5] - xPosVertex[6] );
306   double dy56   = fabs( yPosVertex[5] - yPosVertex[6] );
307   double dxBox1 = 2 * sqrt( dx56 * dx56 + dy56 * dy56 ); // some 'large enough' value
308   double dzBox1 = pDzTrap2;                              // some 'large enough' value
309   
310   GeoBox* sEmptyBox1 = new GeoBox( dxBox1, 2 * pDy, dzBox1 );    
311   
312 // position/orientation relative to first trapezoid
313   double alpha1 = atan( dx56/dy56 );    // inclination angle of cutout box
314   HepTransform3D trlEmptyBox1 = HepTranslate3D( yPosVertex[5] - dzBox1 * sin(alpha1), 0, 
315                                                 xPosVertex[5] - dzBox1 * cos(alpha1) );
316   trlEmptyBox1 = trlEmptyBox1 * trlTrap1.inverse();  
317   HepTransform3D xfEmptyBox1 = trlEmptyBox1 * HepRotateY3D(alpha1);
318 
319   
320 //------------------------------------------------------------------------------------------
321 // tube to cut out the space for the Barrel Toroid coils
322   GeoTube* sEmptyTube1 = new GeoTube(0, radiusCutout, 2 * pDy );
323 
324 // position/orientation relative to first trapezoid
325   HepTransform3D trlEmptyTube1 = HepTranslate3D( yPosCentreCutout, 0, xPosCentreCutout );
326   trlEmptyTube1 = trlEmptyTube1 * trlTrap1.inverse();                                           
327   HepTransform3D xfEmptyTube1 = trlEmptyTube1 * HepRotateX3D( M_PI/2 ) * HepRotateY3D( M_PI );
328   
329 //-------------------------------------------------------------------------------------------
330 // tube to Second cut out the space for the Barrel Toroid coil (2) ---?
331   GeoTube* sEmptyTube2 = new GeoTube(0, SecradiusCutout, 2 * pDy );
332   
333 // position/orientation relative to fist trapezoid
334   HepTransform3D trlEmptyTube2 = HepTranslate3D( yPosSecCentreCutout, 0, xPosSecCentreCutout );
335   trlEmptyTube2 = trlEmptyTube2 * trlTrap1.inverse();
336   HepTransform3D xfEmptyTube2 = trlEmptyTube2 * HepRotateX3D( M_PI/2 ) * HepRotateY3D( M_PI );
337   
338   
339 //------------------------------------------------------------------------------------------
340 // boxes to cut out the space for the Barrel Toroid coils
341 //  some 'large enough' values
342   GeoBox* sEmptyBox2 = new GeoBox( SecradiusCutout, 2 * pDy, pDzTrap2 ); 
343   
344 // position/orientation relative to first trapezoid
345   double alpha2 = phiMaxCutout - 3 * M_PI/2;
346   HepTransform3D trlEmptyBox2 = HepTranslate3D( yPosSecCentreCutout + pDzTrap2 * sin(alpha2), 0, 
347                                                 xPosSecCentreCutout + pDzTrap2 * cos(alpha2) );
348   trlEmptyBox2 = trlEmptyBox2 * trlTrap1.inverse();  
349   HepTransform3D xfEmptyBox2 = trlEmptyBox2 * HepRotateY3D(alpha2);
350 
351 // some 'large enough' values  
352   GeoBox* sEmptyBox3 = new GeoBox( radiusCutout/2, 2 * pDy, pDzTrap2 );  
353   double alpha3 = phiMinCutout - M_PI/2;
354   HepTransform3D trlEmptyBox3 = HepTranslate3D( HepRotateY3D(alpha3) * 
355                                 HepPoint3D( radiusCutout/2, 0, pDzTrap2 ) ) * 
356                                 HepTranslate3D( yPosCentreCutout, 0, xPosCentreCutout );
357   trlEmptyBox3 = trlEmptyBox3 * trlTrap1.inverse();  
358   HepTransform3D xfEmptyBox3 = trlEmptyBox3 * HepRotateY3D(alpha3);
359 
360   GeoBox* sEmptyBox4 = new GeoBox( HeightCutCom/2, 2 * pDy, 
361                                    (xPosSecCentreCutout - xPosCentreCutout)/2 );
362   HepTransform3D trlEmptyBox4 = HepTranslate3D( yPosSecCentreCutout - 
363                                 SecradiusCutout + HeightCutCom/2, 0,
364                                 (xPosSecCentreCutout + xPosCentreCutout)/2 );
365   
366   trlEmptyBox4 = trlEmptyBox4 * trlTrap1.inverse();
367   
368 //------------------------------------------------------------------------------------------
369 // unite the three trapezoids to obtain the side-plate base shape, cut out the 
370 // tube and various boxes
371 //------------------------------------------------------------------------------------------
372   const GeoShape& sSidePlate = sTrap1->add( (*sTrap2) << xfTrap2 ).
373                                        subtract( (*sEmptyBox1) << xfEmptyBox1 ).
374                                        subtract( (*sEmptyBox2) << xfEmptyBox2 ).
375                                        subtract( (*sEmptyBox3) << xfEmptyBox3 ).
376                                        subtract( (*sEmptyTube1) << xfEmptyTube1 ).
377                                        subtract( (*sEmptyTube2) << xfEmptyTube2 ).
378                                        subtract( (*sEmptyBox4) << trlEmptyBox4 ).
379                                        subtract( (*sEmptyMiniConnPlate) << xfMiniConnPlate ).
380 //                                     add( (*sMiniConnPlate) << xfMiniConnPlate ).
381                                        add( (*sTrap3) << xfTrap3 );
382   
383   GeoLogVol*  lSidePlate = new GeoLogVol( "StdFeetSidePlate", 
384                                           &sSidePlate, 
385                                           theMaterialManager->getMaterial(feetMaterial) );
386   GeoPhysVol* pSidePlate = new GeoPhysVol(lSidePlate);
387 
388 //------------------------------------------------------------------------------------------
389 // replicate and position
390 //------------------------------------------------------------------------------------------
391 // array of z positions
392   const int nZPosSidePlate = nZPosMax;
393   double zPosSidePlate[nZPosSidePlate];
394   for ( int i = 1; i < nFeet - 1; i++ ) 
395   {  
396      zPosSidePlate[ 2 * i - 2 ] = zPositionFeet[i] - zWidth/2;
397      zPosSidePlate[ 2 * i - 1 ] = zPositionFeet[i] + zWidth/2;
398 // DHW     zPosSidePlate[ 2 * i - 2 ] = zPositionFeet[i] - zWidth/2 + thicknessSidePlate/2;    
399 //         zPosSidePlate[ 2 * i - 1 ] = zPositionFeet[i] + zWidth/2 - thicknessSidePlate/2;    
400   }
401 
402 // array of x positions
403   const int nXPos = nXPosMax;
404 // final x-position of first trapezoid centre
405   double xMeanSidePlate = 0.5 * ( xPosVertex[0] + xPosVertex[8] );    
406   double xPosSidePlate[nXPos] = { -xMeanSidePlate, xMeanSidePlate };
407 
408 // array of rotation angles (to flip shapes around x-axis)
409   double rotAngleSidePlate[nXPos] = { M_PI, 0 };
410     
411 // fill auxiliary arrays 
412   for ( int i = 0; i < nZPosSidePlate * nXPos; i++ )  
413   {
414      int ii = i % nZPosSidePlate, 
415          jj = i / nZPosSidePlate;
416      zPosAux[i]     = zPosSidePlate[ii];
417      xPosAux[i]     = xPosSidePlate[jj];
418      rotAngleAux[i] = rotAngleSidePlate[jj]; 
419   }
420 
421   GENFUNCTION fRotSidePlate  = ArrayFunction( rotAngleAux, rotAngleAux + nZPosSidePlate * nXPos ); 
422   GENFUNCTION fTrlZSidePlate = ArrayFunction( zPosAux,     zPosAux     + nZPosSidePlate * nXPos ); 
423   GENFUNCTION fTrlXSidePlate = ArrayFunction( xPosAux,     xPosAux     + nZPosSidePlate * nXPos ); 
424   
425 // final y-pos. of first trapezoid centre
426   double yMean = yPosVertex[8] + 0.5 * ( pDx1Trap1 + pDx3Trap1 );            
427   TRANSFUNCTION XFSidePlate = Pow( HepTranslateZ3D(1.0), fTrlZSidePlate ) * 
428                               Pow( HepTranslateX3D(1.0), fTrlXSidePlate ) * 
429                               HepTranslateY3D(yMean) *     // const. displacement along y
430                               HepRotateX3D( M_PI/2 ) *     // const. rotations to bring shape into...
431                               HepRotateY3D( M_PI/2 ) *     // ...correct orientation  
432                               Pow( HepRotateX3D(1.0), fRotSidePlate ); 
433 
434   GeoSerialTransformer* sxSidePlate = new GeoSerialTransformer( pSidePlate, &XFSidePlate, 
435                                                                 nZPosSidePlate * nXPos );
436   container->add(sxSidePlate);
437 
438 //------------------------------------------------------------------------------------------
439 //  Build large vertical plates, located between the side-plate pairs
440 //------------------------------------------------------------------------------------------
441 
442   
443   double dyLargePlate = 0.5 * yHeightLargePlate;
444   double dzLargePlate = zWidth/2 - thicknessSidePlate;
445   
446   GeoBox* sLargePlate = new GeoBox( thicknessLargePlate/2, dyLargePlate, dzLargePlate );
447   GeoLogVol*  lLargePlate = new GeoLogVol( "StdFeetLargePlate", 
448                                            sLargePlate, 
449                                            theMaterialManager->getMaterial(feetMaterial) );
450   GeoPhysVol* pLargePlate = new GeoPhysVol(lLargePlate);
451 
452 //------------------------------------------------------------------------------------------
453 // replicate and position   
454 // array of z positions (will be used later also for inner vertical, cover, and bottom plates)
455   const int nZPosPlate = maxDim - 2;
456   double zPosPlate[nZPosPlate];
457   for ( int i = 0; i < nZPosPlate; i++ )  zPosPlate[i] = zPositionFeet[ i + 1 ]; 
458 
459 // array of x positions
460   double xPosLargePlate[nXPos] = { -xMeanLargePlate, xMeanLargePlate };
461 
462 // fill auxiliary arrays 
463   for ( int i = 0; i < nZPosPlate * nXPos; i++ )  
464   {
465      int ii = i % nZPosPlate, 
466          jj = i / nZPosPlate;
467      zPosAux[i] = zPosPlate[ii];
468      xPosAux[i] = xPosLargePlate[jj];
469   }
470 
471   GENFUNCTION fTrlZLargePlate = ArrayFunction( zPosAux, zPosAux + nZPosPlate * nXPos ); 
472   GENFUNCTION fTrlXLargePlate = ArrayFunction( xPosAux, xPosAux + nZPosPlate * nXPos ); 
473   
474   double yPosLargePlate = yMinLargeP + dyLargePlate;
475   TRANSFUNCTION XFLargePlate = Pow( HepTranslateZ3D(1.0), fTrlZLargePlate ) * 
476                                Pow( HepTranslateX3D(1.0), fTrlXLargePlate ) * 
477                                HepTranslateY3D(yPosLargePlate); 
478 
479   GeoSerialTransformer* sxLargePlate = new GeoSerialTransformer( pLargePlate, &XFLargePlate, 
480                                                                  nZPosPlate * nXPos );
481   container->add(sxLargePlate);
482 
483 //------------------------------------------------------------------------------------------
484 //  Build outer inclined (cover) plates, which cover the Barrel Toroid coil cutouts
485 //------------------------------------------------------------------------------------------
486   
487   GeoBox* sCoverPlate = new GeoBox( thicknessOuterPlate/2 - tolerance, lengthOuterPlate/2, 
488                                     zWidthOuterP/2 );
489   GeoLogVol*  lCoverPlate = new GeoLogVol( "StdFeetCoverPlate", 
490                                            sCoverPlate, 
491                                            theMaterialManager->getMaterial(feetMaterial) );
492   GeoPhysVol* pCoverPlate = new GeoPhysVol(lCoverPlate);
493 
494 //------------------------------------------------------------------------------------------
495 // replicate and position   
496 // array of x positions
497   double DIAG = sqrt ( thicknessOuterPlate * thicknessOuterPlate + lengthOuterPlate * 
498                        lengthOuterPlate );
499   double alphaCP = atan(thicknessOuterPlate/lengthOuterPlate);
500   double betaCP  = atan(dy12/dx12);
501   
502   double xMeanCoverPlate = xPosVertexC1 + (yHeightMiniP * sinBeta) - 
503                                                             (DIAG * cos(alphaCP + betaCP))/2;
504   double xPosCoverPlate[nXPos] = { -xMeanCoverPlate, xMeanCoverPlate };
505 
506 // array of inclination angles (different for left and right cover plates)
507   double rotAngleCoverPlate[nXPos] = { -beta, beta };
508 
509 // fill auxiliary arrays 
510   for ( int i = 0; i < nZPosPlate * nXPos; i++ )  
511   {
512      int ii = i % nZPosPlate, 
513          jj = i / nZPosPlate;
514      zPosAux[i]     = zPosPlate[ii];
515      xPosAux[i]     = xPosCoverPlate[jj];
516      rotAngleAux[i] = rotAngleCoverPlate[jj]; 
517   }
518 
519   GENFUNCTION fRotCoverPlate  = ArrayFunction( rotAngleAux, rotAngleAux + nZPosPlate * nXPos ); 
520   GENFUNCTION fTrlZCoverPlate = ArrayFunction( zPosAux,     zPosAux     + nZPosPlate * nXPos ); 
521   GENFUNCTION fTrlXCoverPlate = ArrayFunction( xPosAux,     xPosAux     + nZPosPlate * nXPos ); 
522   
523   double yPosCoverPlate = yPosVertexC1 + (DIAG * sin(betaCP + alphaCP))/2 - (yHeightMiniP * cosBeta);
524   TRANSFUNCTION XFCoverPlate = Pow( HepTranslateZ3D(1.0), fTrlZCoverPlate ) * 
525                                Pow( HepTranslateX3D(1.0), fTrlXCoverPlate ) * 
526                                HepTranslateY3D(yPosCoverPlate) * 
527                                Pow( HepRotateZ3D(1.0), fRotCoverPlate ); 
528 
529   GeoSerialTransformer* sxCoverPlate = new GeoSerialTransformer( pCoverPlate, &XFCoverPlate, 
530                                                                  nZPosPlate * nXPos );
531   container->add(sxCoverPlate);
532 
533 //------------------------------------------------------------------------------------------
534 //  Build inner (top) vertical plates, on which the Feet Voussoirs are mounted
535 //------------------------------------------------------------------------------------------
536   
537   GeoBox* sInnerPlate = new GeoBox( thicknessInnerPlate/2 - tolerance, pDx1Trap3, zWidth/2 );
538 
539   GeoLogVol*  lInnerPlate = new GeoLogVol( "StdFeetInnerPlate", 
540                                            sInnerPlate, 
541                                            theMaterialManager->getMaterial(feetMaterial) );
542   GeoPhysVol* pInnerPlate = new GeoPhysVol(lInnerPlate);
543 
544 //------------------------------------------------------------------------------------------
545 // replicate and position   
546 // array of x positions
547   double xPosInnerPlate[nXPos] = { -xPosVertex[4] + thicknessInnerPlate/2, 
548                                     xPosVertex[4] - thicknessInnerPlate/2 };
549 
550 // fill auxiliary arrays 
551   for ( int i = 0; i < nZPosPlate * nXPos; i++ )  
552   {
553      int ii = i % nZPosPlate, 
554          jj = i / nZPosPlate;
555      zPosAux[i] = zPosPlate[ii];
556      xPosAux[i] = xPosInnerPlate[jj];
557   }
558 
559   GENFUNCTION fTrlZInnerPlate = ArrayFunction( zPosAux, zPosAux + nZPosPlate * nXPos ); 
560   GENFUNCTION fTrlXInnerPlate = ArrayFunction( xPosAux, xPosAux + nZPosPlate * nXPos ); 
561   
562   TRANSFUNCTION XFInnerPlate = Pow( HepTranslateZ3D(1.0), fTrlZInnerPlate ) * 
563                                Pow( HepTranslateX3D(1.0), fTrlXInnerPlate ) * 
564                                HepTranslateY3D(yPosInnerPlateStd); 
565 
566   GeoSerialTransformer* sxInnerPlate = new GeoSerialTransformer( pInnerPlate, &XFInnerPlate, 
567                                                                  nZPosPlate * nXPos );
568   container->add(sxInnerPlate);
569 
570 //------------------------------------------------------------------------------------------
571 //  Build bottom plates
572 //------------------------------------------------------------------------------------------
573   
574   GeoBox* sBottomPlate = new GeoBox( pDzTrap1, thicknessBottomPlate/2 - tolerance, zWidthBotP/2 );
575   GeoLogVol*  lBottomPlate = new GeoLogVol( "StdFeetBottomPlate", 
576                                             sBottomPlate, 
577                                             theMaterialManager->getMaterial(feetMaterial) );
578   GeoPhysVol* pBottomPlate = new GeoPhysVol(lBottomPlate);
579 
580 //------------------------------------------------------------------------------------------
581 // replicate and position   
582 // array of x positions
583   double xPosBottomPlate[nXPos] = { -0.5 * ( xPosVertex[0] + xPosVertex[8] ), 
584                                      0.5 * ( xPosVertex[0] + xPosVertex[8] ) };
585 
586 // fill auxiliary arrays 
587   for ( int i = 0; i < nZPosPlate * nXPos; i++ )  
588   {
589      int ii = i % nZPosPlate, 
590          jj = i / nZPosPlate;
591      zPosAux[i] = zPosPlate[ii];
592      xPosAux[i] = xPosBottomPlate[jj];
593   }
594 
595   GENFUNCTION fTrlZBottomPlate = ArrayFunction( zPosAux, zPosAux + nZPosPlate * nXPos ); 
596   GENFUNCTION fTrlXBottomPlate = ArrayFunction( xPosAux, xPosAux + nZPosPlate * nXPos ); 
597   
598   double yPosBottomPlate = yPosVertex[0] - thicknessBottomPlate/2;
599   TRANSFUNCTION XFBottomPlate = Pow( HepTranslateZ3D(1.0), fTrlZBottomPlate ) * 
600                                 Pow( HepTranslateX3D(1.0), fTrlXBottomPlate ) * 
601                                 HepTranslateY3D(yPosBottomPlate); 
602 
603   GeoSerialTransformer* sxBottomPlate = new GeoSerialTransformer( pBottomPlate, &XFBottomPlate, 
604                                         nZPosPlate * nXPos );
605   container->add(sxBottomPlate);
606 
607 }
608 
609 void FeetToroidBuilderRDB::buildExtremityFeet( GeoPhysVol* container ) 
610 {
611 //------------------------------------------------------------------------------------------
612 //  Builds Extremity Feet (i.e., the two outermost feet pairs) -- sideplates, bottom plate, 
613 //  inner and top vertical plates  
614 //------------------------------------------------------------------------------------------
615 
616   const StoredMaterialManager*  theMaterialManager;
617   if ( StatusCode::SUCCESS != m_pDetStore->retrieve( theMaterialManager, "MATERIALS" ) ) 
618   {
619     return;
620   } 
621 
622   const int maxDimExtr = 12; 
623   const int nVertexExtr= 12;
624 
625 //------------ Feet General Parameters ---------------------------------//
626    double zPositionFeet[maxDim];
627    zPositionFeet[0] = -(*m_Feet)[0]->getFloat("ZPOSFEE5") * mm;
628    zPositionFeet[1] = -(*m_Feet)[0]->getFloat("ZPOSFEE4") * mm;
629    zPositionFeet[2] = -(*m_Feet)[0]->getFloat("ZPOSFEE3") * mm;
630    zPositionFeet[3] = -(*m_Feet)[0]->getFloat("ZPOSFEE2") * mm;
631    zPositionFeet[4] =  (*m_Feet)[0]->getFloat("ZPOSFEE1") * mm;
632    zPositionFeet[5] =  (*m_Feet)[0]->getFloat("ZPOSFEE2") * mm;
633    zPositionFeet[6] =  (*m_Feet)[0]->getFloat("ZPOSFEE3") * mm;
634    zPositionFeet[7] =  (*m_Feet)[0]->getFloat("ZPOSFEE4") * mm;
635    zPositionFeet[8] =  (*m_Feet)[0]->getFloat("ZPOSFEE5") * mm;
636                                                                               //
637    const double thicknessSidePlate   = (*m_Feet)[0]->getFloat("MAINPLDZ") * mm;               //
638    const double thicknessBottomPlate = (*m_Feet)[0]->getFloat("MNPLPEHE") * mm;               //
639    const double thicknessLargePlate  = (*m_Feet)[0]->getFloat("EXVCPTHI") * mm;               //
640    const double thicknessOuterPlate  = (*m_Feet)[0]->getFloat("SLACPLYH") * mm;               //
641                                                                                  //
642    const std::string feetMaterial = getMaterial( "Iron" );
643 //------------ Extremity Feet Parameters -------------------------------//
644    const double zWidth = (*m_Feet)[0]->getFloat("EXMPZSEP") * mm;
645  
646    double xPosVertexExtrFeet[maxDimExtr], yPosVertexExtrFeet[maxDimExtr];
647 
648         xPosVertexExtrFeet[0] = (*m_Feet)[0]->getFloat("MAINPLXB") * mm;
649         yPosVertexExtrFeet[0] = (*m_Feet)[0]->getFloat("MAINPLYB") * mm;
650         xPosVertexExtrFeet[1] = (*m_Feet)[0]->getFloat("MAINPLXC") * mm;
651         yPosVertexExtrFeet[1] = (*m_Feet)[0]->getFloat("MAINPLYC") * mm;
652         xPosVertexExtrFeet[2] = (*m_Feet)[0]->getFloat("MAINPLXE") * mm;
653         yPosVertexExtrFeet[2] = (*m_Feet)[0]->getFloat("MAINPLYE") * mm;
654         xPosVertexExtrFeet[3] = (*m_Feet)[0]->getFloat("EXMPLAXF") * mm;
655         yPosVertexExtrFeet[3] = (*m_Feet)[0]->getFloat("EXMPLAYF") * mm;
656         xPosVertexExtrFeet[4] = (*m_Feet)[0]->getFloat("EXMPLXF1") * mm; // ?
657         yPosVertexExtrFeet[4] = (*m_Feet)[0]->getFloat("EXMPLYF1") * mm;
658         xPosVertexExtrFeet[5] = (*m_Feet)[0]->getFloat("EXMPLXF2") * mm; // ?
659         yPosVertexExtrFeet[5] = (*m_Feet)[0]->getFloat("EXMPLYF2") * mm;
660         xPosVertexExtrFeet[6] = (*m_Feet)[0]->getFloat("EXMPLXF6") * mm;
661         yPosVertexExtrFeet[6] = (*m_Feet)[0]->getFloat("EXMPLYF6") * mm;
662         xPosVertexExtrFeet[7] = (*m_Feet)[0]->getFloat("EXMPLXF7") * mm;
663         yPosVertexExtrFeet[7] = (*m_Feet)[0]->getFloat("EXMPLYF7") * mm;
664         xPosVertexExtrFeet[8] = (*m_Feet)[0]->getFloat("EXMPLAXH") * mm;
665         yPosVertexExtrFeet[8] = (*m_Feet)[0]->getFloat("EXMPLAYH") * mm;
666         xPosVertexExtrFeet[9] = (*m_Feet)[0]->getFloat("EXMPLAXI") * mm;
667         yPosVertexExtrFeet[9] = -812.6 * cm;
668         xPosVertexExtrFeet[10]= (*m_Feet)[0]->getFloat("MAINPLXJ")* mm;
669         yPosVertexExtrFeet[10]= (*m_Feet)[0]->getFloat("MAINPLYJ")* mm;
670         xPosVertexExtrFeet[11]= (*m_Feet)[0]->getFloat("MAINPLXA")* mm;
671         yPosVertexExtrFeet[11]= (*m_Feet)[0]->getFloat("MAINPLYA")* mm;
672         
673    const double xPosFoot              = (*m_Feet)[0]->getFloat("STDFOOXP") * mm;
674    const double yPosFoot              = (*m_Feet)[0]->getFloat("STDFOOYP") * mm;        
675    const double xPosVertexC1ExtrFeet  = (*m_Feet)[0]->getFloat("EXMPLXC1") * mm;
676    const double yPosVertexC1ExtrFeet  = (*m_Feet)[0]->getFloat("EXMPLYC1") * mm;
677    const double xPosVertexF3ExtrFeet  = (*m_Feet)[0]->getFloat("EXMPLXF3") * mm;
678    const double yPosVertexF3ExtrFeet  = (*m_Feet)[0]->getFloat("EXMPLYF3") * mm;
679    const double xPosVertexF4ExtrFeet  = (*m_Feet)[0]->getFloat("EXMPLXF4") * mm;
680    const double yPosVertexF4ExtrFeet  = (*m_Feet)[0]->getFloat("EXMPLYF4") * mm;
681    const double xPosVertexF5ExtrFeet  = (*m_Feet)[0]->getFloat("EXMPLXF5") * mm;
682    const double yPosVertexF5ExtrFeet  = (*m_Feet)[0]->getFloat("EXMPLYF5") * mm;
683    const double xPosVertexDExtrFeet   = (*m_Feet)[0]->getFloat("EXMPLAXD") * mm;
684    const double yPosVertexDExtrFeet   = (*m_Feet)[0]->getFloat("EXMPLAYD") * mm;
685    const double xPosVertexC3ExtrFeet  = (*m_Feet)[0]->getFloat("EXMPLXC3") * mm;
686    const double yPosVertexC3ExtrFeet  = (*m_Feet)[0]->getFloat("EXMPLYC3") * mm;
687    const double xPosVertexC4ExtrFeet  = (*m_Feet)[0]->getFloat("EXMPLXC4") * mm;
688    const double yPosVertexC4ExtrFeet  = (*m_Feet)[0]->getFloat("EXMPLYC4") * mm;
689    const double xPosVertexC5ExtrFeet  = (*m_Feet)[0]->getFloat("EXMPLXC5") * mm;
690    const double yPosVertexC5ExtrFeet  = (*m_Feet)[0]->getFloat("EXMPLYC5") * mm;
691    const double xPosVertexC1aExtrFeet = (*m_Feet)[0]->getFloat("EXMPXC1A") * mm;
692    const double yPosVertexC1aExtrFeet = (*m_Feet)[0]->getFloat("EXMPYC1A") * mm;
693    const double xPosVertexC1bExtrFeet = (*m_Feet)[0]->getFloat("EXMPXC1B") * mm;
694    //const double yPosVertexC1bExtrFeet = (*m_Feet)[0]->getFloat("EXMPYC1B") * mm;
695    
696    const double SecradiusCutExtr      = (*m_Feet)[0]->getFloat("EXMPRCRA") * mm;
697    //const double xPosSecCentreCutout   = (*m_Feet)[0]->getFloat("EXMPRCXC") * mm;
698    //const double yPosSecCentreCutout   = (*m_Feet)[0]->getFloat("EXMPRCYC") * mm;
699    
700    const double xCentreCutoutExtrFeet = (*m_Feet)[0]->getFloat("MAPLRCXC") * mm;
701    const double yCentreCutoutExtrFeet = (*m_Feet)[0]->getFloat("MAPLRCYC") * mm;
702    const double radiusCutout          = (*m_Feet)[0]->getFloat("MNPLRCRA") * mm;
703    const double yMinLargePlateExtr    = (*m_Feet)[0]->getFloat("EXVCPLAY") * mm; //-988.5
704    const double yMaxLargePlate        = -840.5 * cm; 
705    const double xPosLargePlateExtrFeet= (*m_Feet)[0]->getFloat("EXVCPLAX") * mm;
706    const double lengthInclinedPlate   =  74.21 * cm; //????
707 //   const double angleInclinedPlateExtrFeet  = ANGIPL;
708    const double thicknessInnerPlate   = (*m_Feet)[0]->getFloat("UCNPLXWI")* mm;
709    const double yHeightInnerPlateExtr = (*m_Feet)[0]->getFloat("UCNPLYHE")* mm;
710    const double yPosCentreInnerTopPlateExtrFeet = (*m_Feet)[0]->getFloat("UPCPYPOS") * mm;
711    const double lengthOuterPlate      = (*m_Feet)[0]->getFloat("SLACPLXW") * mm;
712    const double yoffsetCutCoverPlateExtr        = (*m_Feet)[0]->getFloat("EXSPRCOF") * mm;
713    const double radiusCutCoverPlateExtr         = (*m_Feet)[0]->getFloat("EXSPRCRA") * mm;       
714    const double zWidthMiniPExtr       = (*m_Feet)[0]->getFloat("EXMCPZLE") * mm;
715    const double yHeightMiniPExtr      = (*m_Feet)[0]->getFloat("EXMCPYHE") * mm; 
716    const double xlengthMiniPExtr      = (*m_Feet)[0]->getFloat("MINCPLXW") * mm;
717    const double xPosMiniConnPlateExtrFeet       = (*m_Feet)[0]->getFloat("EXMCPXPO") * mm;
718    const double yPosMiniConnPlateExtrFeet       = (*m_Feet)[0]->getFloat("EXMCPYPO") * mm;
719    const double zWidthBotExtr         = (*m_Feet)[0]->getFloat("EXGPZLEN") * mm;                
720    const double zWidthOuterPExtr      = (*m_Feet)[0]->getFloat("EXSCPZLE") * mm;
721    const double yHeightCutInclinedPlate         = (*m_Feet)[0]->getFloat("EXVCPYCU") * mm;
722    const double zLengthCutInclinedPlate         = (*m_Feet)[0]->getFloat("EXVCPXCU") * mm;
723    const double xWidthTopPlateExtr    = (*m_Feet)[0]->getFloat("EXCFVXWI") * mm;
724    const double yHeightTopPlateExtr   = (*m_Feet)[0]->getFloat("EXCFVYHE") * mm;
725    const double zLengthTopPlateExtr   = (*m_Feet)[0]->getFloat("EXCFVZLE") * mm;
726 //----------------------------------------------------------------------------//
727   
728 
729   const double tolerance = 0.5*mm;
730 
731   // auxiliary arrays to store z, x positions, and rotation angles for all volumes to be replicated 
732   const int nZPosMax = 4;
733   const int nXPosMax = 2;
734   double zPosAux[ nZPosMax * nXPosMax ],  xPosAux[ nZPosMax * nXPosMax ],  rotAngleAux[ nZPosMax * nXPosMax ];
735   
736   //------------------------------------------------------------------------------------------
737   // Feet general properties
738   
739   for (int i = 0; i < nVertexExtr; i++)
740   {
741   xPosVertexExtrFeet[i] = xPosVertexExtrFeet[i] + xPosFoot;
742   yPosVertexExtrFeet[i] = yPosVertexExtrFeet[i] + yPosFoot;
743   }
744   yPosVertexExtrFeet[9] = yPosVertexExtrFeet[9] - yPosFoot;
745     
746   const double yPosCentrInPlateExtr = yPosCentreInnerTopPlateExtrFeet + yPosFoot;
747   
748   //------------------------------------------------------------------------------------------
749   // Extremity Feet properties  
750   const double xPosMiniPExtr   = xPosMiniConnPlateExtrFeet + xPosFoot;
751   const double yPosMiniPExtr   = yPosMiniConnPlateExtrFeet + yPosFoot;
752   
753   const double xPosVertC1Extr = xPosVertexC1ExtrFeet + xPosFoot;
754   const double yPosVertC1Extr = yPosVertexC1ExtrFeet + yPosFoot;
755   const double xPosVertF3Extr = xPosVertexF3ExtrFeet + xPosFoot;
756   const double yPosVertF3Extr = yPosVertexF3ExtrFeet + yPosFoot;
757   const double xPosVertF4Extr = xPosVertexF4ExtrFeet + xPosFoot;
758   const double yPosVertF4Extr = yPosVertexF4ExtrFeet + yPosFoot;
759   const double xPosVertF5Extr = xPosVertexF5ExtrFeet + xPosFoot;
760   const double yPosVertF5Extr = yPosVertexF5ExtrFeet + yPosFoot;
761   const double xPosVertDExtr  = xPosVertexDExtrFeet + xPosFoot;
762   const double yPosVertDExtr  = yPosVertexDExtrFeet + yPosFoot;
763   const double xPosVertC3Extr = xPosVertexC3ExtrFeet + xPosFoot;
764   const double yPosVertC3Extr = yPosVertexC3ExtrFeet + yPosFoot;
765   const double xPosVertC4Extr = xPosVertexC4ExtrFeet + xPosFoot;
766   const double yPosVertC4Extr = yPosVertexC4ExtrFeet + yPosFoot;
767   const double xPosVertC5Extr = xPosVertexC5ExtrFeet + xPosFoot;
768   const double yPosVertC5Extr = yPosVertexC5ExtrFeet + yPosFoot;
769   const double xPosVertC1aExtr= xPosVertexC1aExtrFeet + xPosFoot;
770   const double yPosVertC1aExtr= yPosVertexC1aExtrFeet + yPosFoot;
771   const double xPosVertC1bExtr= xPosVertexC1bExtrFeet + xPosFoot;
772   //const double yPosVertC1bExtr= yPosVertexC1bExtrFeet + yPosFoot;
773       
774   // polygonal shape of side-plate envelope
775   const double* xPosVertex = xPosVertexExtrFeet;         // x,y positions of vertices
776   const double* yPosVertex = yPosVertexExtrFeet;
777   
778   // cutout circle (segment) for Barrel Toroid coils
779   const double xPosCentreCutout = xCentreCutoutExtrFeet + xPosFoot;  // x-position of centre
780   const double yPosCentreCutout = yCentreCutoutExtrFeet + yPosFoot;  // y-position of centre
781 
782   const double yPosSecCentreCut = yPosCentreCutout + yPosFoot;
783   const double xPosSecCentreCut = xPosCentreCutout + xPosFoot;
784   
785   // large vertical plate (between the two side plates)
786   const double yMinLargePlate  = yMinLargePlateExtr + yPosFoot; 
787   const double xMeanLargePlate = (xPosLargePlateExtrFeet - thicknessLargePlate/2) + xPosFoot;  // x position of centre
788   
789   // large inclined plate (between the two side plates)
790 //  const double angleInclinedPlate  = angleInclinedPlateExtrFeet;  // inclination angle
791 
792 //------------------------------------------------------------------------------------------
793 //  Build side plate: the base shape is a union of two trapezoids and two boxes, from 
794 //  which a protruding edge (by means of a box), and the space for the Barrel Toroid coil  
795 //  (by means of a tube and three boxes) are cut out  
796 //------------------------------------------------------------------------------------------
797 
798   double pDy = thicknessSidePlate/2;
799 
800 //------------------------------------------------------------------------------------------
801 // base shape
802 //------------------------------------------------------------------------------------------
803 // first (base) trapezoid (vertices 1, 2, 11, 12, counter-clockwise) 
804 // - note that axes don't coincide with global coordinates
805   double pDzTrap1    = 0.5 * ( xPosVertex[0]  - xPosVertex[11] );
806   double pDx1Trap1   = 0.5 * ( yPosVertex[10] - yPosVertex[11] );
807   double pDx3Trap1   = 0.5 * ( yPosVertex[1]  - yPosVertex[0] ); 
808   double pThetaTrap1 = atan( 0.5 * ( pDx3Trap1 - pDx1Trap1 )/pDzTrap1 );
809 
810   GeoTrap* sTrap1 = new GeoTrap( pDzTrap1, pThetaTrap1, 0,
811                                  pDy - tolerance, pDx1Trap1 - tolerance, pDx1Trap1 - tolerance, 0,
812                                  pDy - tolerance, pDx3Trap1 - tolerance, pDx3Trap1 - tolerance, 0 );
813   
814   // positioning (not the final one)
815   HepTransform3D trlTrap1 = HepTranslate3D( yPosVertex[11] + 0.5 * ( pDx1Trap1 + pDx3Trap1 ), 0,
816                                             xPosVertex[11] + pDzTrap1 );
817 
818   
819   //------------------------------------------------------------------------------------------
820   // second (middle) trapezoid: the vertices are 2, 3; the intersection point of the
821   // lines through (3,9), (10,11); and 11 (counter-clockwise) 
822   // - note that axes don't coincide with global coordinates
823   double dx12 = fabs( xPosVertex[1] - xPosVertex[2] );
824   double dy12 = fabs( yPosVertex[2] - yPosVertex[1] );
825   double beta = atan( dx12/dy12 );  // inclination angle (~22.5 deg)
826 
827   double dx110     = fabs( xPosVertex[1] - xPosVertex[10] );
828   double dy110     = fabs( yPosVertex[1] - yPosVertex[10] );
829   double aux       = dy110 + dx110 * tan(beta);
830   double cosBeta   = cos(beta);
831   double sinBeta   = sin(beta);
832   double pDzTrap2  = 0.5 * ( dx110/cosBeta - aux * sinBeta );
833   double pDx3Trap2 = 0.5 * dy12/cosBeta;
834 
835   double dx28      = fabs( xPosVertex[2] - xPosVertex[8] );
836   double dy28      = fabs( yPosVertex[2] - yPosVertex[8] );
837   double gamma1    = atan( dy28/dx28 );
838   double gamma2    = atan( dy110/dx110 );
839   double pDx1Trap2 = pDx3Trap2 - pDzTrap2 * ( tan( gamma2 + beta ) + tan( gamma1 - beta ) ); 
840 
841   double tanTheta    = 0.5 * ( pDx1Trap2 - pDx3Trap2 )/pDzTrap2 + tan( gamma1 - beta );
842   double pThetaTrap2 = atan(tanTheta);
843 
844   GeoTrap* sTrap2 = new GeoTrap( pDzTrap2, pThetaTrap2, 0,
845                                  pDy - tolerance, pDx1Trap2 - tolerance, pDx1Trap2 - tolerance, 0,
846                                  pDy - tolerance, pDx3Trap2 - tolerance, pDx3Trap2 - tolerance, 0 );
847   
848   // position/orientation relative to first trapezoid
849   double pDxMeanTrap2  = 0.5 * ( pDx1Trap2 + pDx3Trap2 ); 
850   HepTransform3D trlTrap2 = HepTranslate3D( yPosVertex[1] + dy110/2 + pDxMeanTrap2 * cosBeta, 0,
851                                             xPosVertex[1] - dx110/2 - pDxMeanTrap2 * sinBeta );
852   trlTrap2 = trlTrap2 * trlTrap1.inverse();
853   HepTransform3D xfTrap2 = trlTrap2 * HepRotateY3D(beta);
854 
855   
856   //----------------------------------------------------------------------------------------
857   // first top box (vertices 7, (x8,y3), (x4,y3), (x4,y7), counter-clockwise) 
858   // - note that axes don't coincide with global coordinates
859   double pDxTopBox1 = 0.5 * ( yPosVertex[6] - yPosVertex[2] );
860   double pDzTopBox1 = 0.5 * ( xPosVertex[3] - xPosVertex[7] );
861 
862   GeoBox* sTopBox1 = new GeoBox( pDxTopBox1 - tolerance, pDy, pDzTopBox1 );
863   
864   // position/orientation relative to first trapezoid
865   HepTransform3D xfTopBox1 = HepTranslate3D( yPosVertex[2] + pDxTopBox1, 0, xPosVertex[7] + pDzTopBox1 );
866   xfTopBox1 = xfTopBox1 * trlTrap1.inverse();
867 
868   
869   //----------------------------------------------------------------------------------------
870   // second top box (vertices 4, 5, (x5,y6), (x4,y6), counter-clockwise) 
871   // - note that axes don't coincide with global coordinates
872   double pDxTopBox2  = 0.5 * ( yPosVertex[4] - yPosVertex[5] );
873   double pDzTopBox2  = 0.5 * ( xPosVertex[3] - xPosVertex[4] );
874 
875   GeoBox* sTopBox2 = new GeoBox( pDxTopBox2 - tolerance, pDy, pDzTopBox2 );
876   
877   //position/orientation relative to first trapezoid
878   HepTransform3D xfTopBox2 = HepTranslate3D( yPosVertex[5] + pDxTopBox2, 0, xPosVertex[5] + pDzTopBox2 );
879   xfTopBox2 = xfTopBox2 * trlTrap1.inverse();
880   
881   //----------------------------------------------------------------------------------------------
882   // third top (middle) box (vertices (x4,y6),(x4,y7),(xf3,y7),(xf3,y6) )
883   // - note that axes don't coincide with global coordinates
884   double pDzTopBox3  = 0.5 * ( xPosVertex[3] - xPosVertF3Extr );
885   double pDxTopBox3  = 0.5 * ( yPosVertex[5] - yPosVertex[6] );
886   
887   GeoBox* sTopBox3 = new GeoBox( pDxTopBox3 - tolerance, pDy, pDzTopBox3 );
888   
889   // position/orientation relative to first trapezoid
890   HepTransform3D xfTopBox3 = HepTranslate3D( yPosVertex[6] + pDxTopBox3, 0, xPosVertF3Extr + pDzTopBox3 );
891   xfTopBox3 = xfTopBox3 * trlTrap1.inverse();  
892   
893   //-----------------------------------------------------------------------------------------------------
894   // last top (bottom) box (vertices (x8,y3),8,(x4,y8),3)
895   // note that axes don't coincide with global coordinates
896   double pDzTopBox4  = 0.5 * ( xPosVertex[2] - xPosVertex[7] );
897   double pDxTopBox4  = 0.5 * ( yPosVertex[2] - yPosVertex[7] );
898   
899   GeoBox* sTopBox4 = new GeoBox( pDxTopBox4 - tolerance, pDy - tolerance, pDzTopBox4 - tolerance );
900   
901   // position/orientation relative to first trapezoid
902   HepTransform3D xfTopBox4 = HepTranslate3D( yPosVertex[7] + pDxTopBox4, 0, xPosVertex[7] + pDzTopBox4 );
903   xfTopBox4 = xfTopBox4 * trlTrap1.inverse();
904   
905   //------------------------
906   // first cutout from first top box
907   // double pDyF1F2     = 0.5 * (yPosVertex[4] - yPosVertex[5]);
908   double pDxF3F2        = 0.5 * (-xPosVertF3Extr + xPosVertex[5]);
909   double pDyF2F3        = 0.5 * (yPosVertex[5] - yPosVertF3Extr);
910   double alphaF2F3      = atan( pDyF2F3/pDxF3F2 );
911   
912   GeoPara* sEmptyPara = new GeoPara( pDyF2F3, 2*pDy, pDxF3F2, 0, alphaF2F3, 0 );
913 
914 //position/orientation relative to first trapezoid
915   HepTransform3D trlEmptyPara = HepTranslate3D( yPosVertex[5],  0, (xPosVertex[5] + xPosVertF3Extr)/2 );
916   trlEmptyPara = trlEmptyPara * trlTrap1.inverse();
917   
918   
919 //-----------------------------------------
920 //second cutout from first top box
921   double pDxF4F3        = 0.5 * (xPosVertF3Extr - xPosVertF4Extr);
922   double pDxF5F4        = xPosVertF4Extr - xPosVertF5Extr;
923   double pDzF5F4        = 0.5 * (yPosVertF5Extr - yPosVertF4Extr);
924   
925   GeoTrd* sEmptyTrap    = new GeoTrd( pDxF4F3 + pDxF5F4, pDxF4F3, 2*pDy, 2*pDy, pDzF5F4 + tolerance);
926   
927   //position/orientation relative to first trapezoid
928   HepTransform3D trlEmptyTrap = HepTranslate3D( (yPosVertF4Extr + yPosVertF5Extr)/2, 0, 
929                                                 (xPosVertF3Extr + xPosVertF4Extr)/2 );
930   trlEmptyTrap = trlEmptyTrap * trlTrap1.inverse(); 
931   HepTransform3D xfEmptyTrap = trlEmptyTrap * HepRotateY3D( 3*M_PI/2 );
932   
933 
934   //MiniConnExtr plates
935   //ss 12/02/2007 never used GeoBox* sMiniConnPlateExtr = new GeoBox(yHeightMiniPExtr/2, zWidthMiniPExtr/2, xlengthMiniPExtr/2 );
936   GeoBox* sEmptyMiniConnPlateExtr = new GeoBox( yHeightMiniPExtr/2 + tolerance, zWidthMiniPExtr/4,
937                                                 xlengthMiniPExtr/2 + tolerance );
938   
939   HepTransform3D trlMiniConnPlateExtr = HepTranslate3D( yPosMiniPExtr, 0, xPosMiniPExtr );
940   trlMiniConnPlateExtr = trlMiniConnPlateExtr * trlTrap1.inverse();
941   HepTransform3D xfMiniConnPlateExtr = trlMiniConnPlateExtr * HepRotateY3D(beta);
942 
943   //------------------------------------------------------------------------------------------
944   // shapes to be cut out
945   //------------------------------------------------------------------------------------------
946   // box to cut out the protruding edge of the middle trapezoid (uses vertices 9,10)
947   double dx89        = fabs( xPosVertex[8] - xPosVertex[9] );
948   double dy89        = fabs( yPosVertex[8] - yPosVertex[9] );
949   double dxEmptyBox1 = 2 * sqrt( dx89 * dx89 + dy89 * dy89 ); // some 'large enough' value
950   double dzEmptyBox1 = pDzTrap2;                          // some 'large enough' value
951   
952   GeoBox* sEmptyBox1 = new GeoBox( dxEmptyBox1, 2*pDy, dzEmptyBox1 );    
953   
954   // position/orientation relative to first trapezoid
955   double alpha1 = atan( dx89/dy89 );    // inclination angle of cutout box
956   HepTransform3D trlEmptyBox1 = HepTranslate3D( yPosVertex[8] - dzEmptyBox1 * sin(alpha1), 0, 
957                                                 xPosVertex[8] - dzEmptyBox1 * cos(alpha1) );
958   trlEmptyBox1 = trlEmptyBox1 * trlTrap1.inverse();  
959   HepTransform3D xfEmptyBox1 = trlEmptyBox1 * HepRotateY3D(alpha1);
960 
961   
962   //------------------------------------------------------------------------------------------
963   // tubes to cut out the space for the Barrel Toroid coils
964   GeoTube* sEmptyTube = new GeoTube(0, radiusCutout, 2*pDy );
965 
966   // position/orientation relative to first trapezoid
967   HepTransform3D trlEmptyTube = HepTranslate3D( yPosCentreCutout, 0, xPosCentreCutout );
968   trlEmptyTube = trlEmptyTube * trlTrap1.inverse();                                           
969   HepTransform3D xfEmptyTube = trlEmptyTube * HepRotateX3D( M_PI/2 ) * HepRotateY3D( M_PI );
970   
971   GeoTube* sEmptyTube2 = new GeoTube( 0, SecradiusCutExtr, 2*pDy );
972   HepTransform3D trlEmptyTube2 = HepTranslate3D( yPosSecCentreCut, 0, xPosSecCentreCut );
973   trlEmptyTube2 = trlEmptyTube2 * trlTrap1.inverse();
974   HepTransform3D xfEmptyTube2 = trlEmptyTube2 * HepRotateX3D( M_PI/2 ) * HepRotateY3D( M_PI );
975 
976   
977   //------------------------------------------------------------------------------------------
978   // first box to cut out space for the Barrel Toroid Coils 
979   double lengthC1C1a = sqrt ( (xPosVertC1Extr - xPosVertC1aExtr) * (xPosVertC1Extr - xPosVertC1aExtr) +
980                               (yPosVertC1Extr - yPosVertC1aExtr) * (yPosVertC1Extr - yPosVertC1aExtr) );
981   //double dxC1C1a     = xPosVertC1Extr - xPosVertC1aExtr; 
982   
983   GeoBox* sEmptyBox2 = new GeoBox( radiusCutout - tolerance, 2 * pDy, lengthC1C1a/2 );  // some 'large enough' values 
984 
985   // position/orientation relative to first trapezoid
986   HepTransform3D trlEmptyBox2 = HepTranslate3D( HepRotateY3D(beta) * HepPoint3D( radiusCutout, 0, -lengthC1C1a/2 ) ) *
987                                                 HepTranslate3D( yPosVertC1Extr, 0, xPosVertC1Extr );
988   trlEmptyBox2 = trlEmptyBox2 * trlTrap1.inverse();  
989   HepTransform3D xfEmptyBox2 = trlEmptyBox2 * HepRotateY3D(beta);
990 
991 
992 //------------------------------------------------------------------------------------------
993 // second box to cut out space for the Barrel Toroid Coils
994   
995   GeoBox* sEmptyBox3 = new GeoBox( radiusCutout/2, 2*pDy, (xPosVertC1aExtr - xPosVertC1bExtr)/2 );  
996   
997 // position/orientation relative to first trapezoid
998   HepTransform3D trlEmptyBox3 = HepTranslate3D( yPosVertC1aExtr + radiusCutout/2, 0, 
999                                                (xPosVertC1aExtr + xPosVertC1bExtr)/2 );
1000   trlEmptyBox3 = trlEmptyBox3 * trlTrap1.inverse();  
1001   HepTransform3D xfEmptyBox3 = trlEmptyBox3;
1002   
1003 //------------------------------------------------------------------------------------------
1004 // third box to cut out the remaining space for the Barrel Toroid Coils 
1005 
1006   double lengthC5C4   = sqrt( (xPosVertC5Extr - xPosVertC4Extr) * (xPosVertC5Extr - xPosVertC4Extr) + 
1007                               (yPosVertC4Extr - yPosVertC5Extr) *
1008                               (yPosVertC4Extr - yPosVertC5Extr) );
1009   //double dyC5C4             = yPosVertC4Extr - yPosVertC5Extr;
1010   double alphaC4C5    = atan( (xPosVertC4Extr - xPosVertC5Extr)/(yPosVertC4Extr - yPosVertC5Extr) );
1011 
1012 
1013   GeoBox* sEmptyBox4 = new GeoBox(lengthC5C4/2 - tolerance, 3 * pDy, radiusCutout/2 );  
1014   
1015 // position/orientation relative to first trapezoid
1016   HepTransform3D trlEmptyBox4 = HepTranslate3D( HepRotateY3D(-alphaC4C5) * 
1017                                 HepPoint3D( -lengthC5C4/2, 0, radiusCutout/2 ) ) *
1018                                 HepTranslate3D( yPosVertC4Extr, 0, xPosVertC4Extr );
1019   trlEmptyBox4 = trlEmptyBox4 * trlTrap1.inverse();  
1020   HepTransform3D xfEmptyBox4 = trlEmptyBox4 * HepRotateY3D(-alphaC4C5);  
1021 
1022 //------------------------------------------------------------------------------------------------
1023 // last box to cut out the remaining space for the Barrel Toroid Coils
1024   
1025   double lengthDC3      = sqrt( (xPosVertDExtr - xPosVertC3Extr) * (xPosVertDExtr - xPosVertC3Extr) + 
1026                                 (yPosVertDExtr - yPosVertC3Extr) *
1027                                 (yPosVertDExtr - yPosVertC3Extr) );
1028 //   double lengthDC1   = sqrt( (xPosVertDExtr - xPosVertC1Extr) * (xPosVertDExtr - xPosVertC1Extr) + 
1029 //                                 (yPosVertDExtr - yPosVertC1Extr) *
1030 //                              (yPosVertDExtr - xPosVertC1Extr) );
1031 //   double dxDC3               = xPosVertDExtr - xPosVertC3Extr;
1032   double alphaDC3       = atan( (yPosVertDExtr - yPosVertC3Extr)/(xPosVertDExtr - xPosVertC3Extr) );
1033   
1034   GeoBox* sEmptyBox5    = new GeoBox( radiusCutout, 2 * pDy, lengthDC3/2 - tolerance );
1035   
1036 // position/orientation relative to first trapezoid
1037   HepTransform3D trlEmptyBox5 = HepTranslate3D( HepRotateY3D(alphaDC3) * HepPoint3D( -radiusCutout, 0, -lengthDC3/2 ) ) *
1038                                 HepTranslate3D( yPosVertDExtr, 0, xPosVertDExtr );
1039   trlEmptyBox5 = trlEmptyBox5 * trlTrap1.inverse();
1040   HepTransform3D xfEmptyBox5 = trlEmptyBox5 * HepRotateY3D(alphaDC3);
1041 
1042   
1043 //------------------------------------------------------------------------------------------
1044 // unite the two trapezoids and two top boxes to obtain the side-plate base shape, 
1045 // cut out the tube and various boxes
1046 //------------------------------------------------------------------------------------------
1047   const GeoShape& sSidePlate = sTrap1->add( (*sTrap2) << xfTrap2 ).
1048                                        subtract( (*sEmptyBox1) << xfEmptyBox1 ).
1049                                        subtract( (*sEmptyBox2) << xfEmptyBox2 ).
1050                                        subtract( (*sEmptyBox3) << xfEmptyBox3 ).
1051                                        subtract( (*sEmptyBox4) << xfEmptyBox4 ).
1052                                        subtract( (*sEmptyBox5) << xfEmptyBox5 ).
1053                                        subtract( (*sEmptyTube) << xfEmptyTube ).
1054                                        subtract( (*sEmptyTube2) << xfEmptyTube2 ).
1055                                        subtract( (*sEmptyMiniConnPlateExtr) << xfMiniConnPlateExtr ).
1056 //                                     add( (*sMiniConnPlateExtr) << xfMiniConnPlateExtr ).
1057                                        add( (*sTopBox1) << xfTopBox1 ).
1058                                        add( (*sTopBox2) << xfTopBox2 ).
1059                                        add( (*sTopBox3) << xfTopBox3 ).
1060                                        add( (*sTopBox4) << xfTopBox4 ).
1061                                        subtract( (*sEmptyPara) << trlEmptyPara ).
1062                                        subtract( (*sEmptyTrap) << xfEmptyTrap );
1063 
1064   GeoLogVol*  lSidePlate = new GeoLogVol( "ExtrFeetSidePlate", 
1065                                           &sSidePlate, 
1066                                           theMaterialManager->getMaterial(feetMaterial) );
1067   // std::cout<<" FeetToroidBuilderRDBn::buildExtremityFeet  ExtrFeetSidePlate "<<std::endl;
1068   GeoPhysVol* pSidePlate = new GeoPhysVol(lSidePlate);
1069 
1070 
1071 //------------------------------------------------------------------------------------------
1072 // replicate and position
1073 //------------------------------------------------------------------------------------------
1074 // array of z positions
1075   const int nZPosSidePlate = nZPosMax;
1076   double zPosSidePlate[nZPosSidePlate];
1077   for ( int i = 0; i < 2; i++ ) 
1078   {  
1079      double zPos = ( i  ?  zPositionFeet[0]  :  zPositionFeet[ nFeet - 1 ] );
1080      zPosSidePlate[ 2*i ]     = zPos - zWidth/2;
1081      zPosSidePlate[ 2*i + 1 ] = zPos + zWidth/2;
1082 // DHW zPosSidePlate[ 2*i ]     = zPos - zWidth/2 + thicknessSidePlate/2;    
1083 //     zPosSidePlate[ 2*i + 1 ] = zPos + zWidth/2 - thicknessSidePlate/2;    
1084   }
1085 
1086 // array of x positions
1087   const int nXPos = nXPosMax;
1088 // final x-position of first trapezoid centre
1089   double xMeanSidePlate = 0.5 * ( xPosVertex[0] + xPosVertex[11] );
1090   double xPosSidePlate[nXPos] = { -xMeanSidePlate, xMeanSidePlate };
1091 
1092 // array of rotation angles (to flip shapes around x-axis)
1093   double rotAngleSidePlate[nXPos] = { M_PI, 0 };
1094     
1095 // fill auxiliary arrays 
1096   for ( int i = 0; i < nZPosSidePlate * nXPos; i++ )  
1097   {
1098      int ii = i % nZPosSidePlate, 
1099          jj = i / nZPosSidePlate;
1100      zPosAux[i]     = zPosSidePlate[ii];
1101      xPosAux[i]     = xPosSidePlate[jj];
1102      rotAngleAux[i] = rotAngleSidePlate[jj]; 
1103   }
1104 
1105   GENFUNCTION fRotSidePlate  = ArrayFunction( rotAngleAux, rotAngleAux + nZPosSidePlate * nXPos ); 
1106   GENFUNCTION fTrlZSidePlate = ArrayFunction( zPosAux,     zPosAux     + nZPosSidePlate * nXPos ); 
1107   GENFUNCTION fTrlXSidePlate = ArrayFunction( xPosAux,     xPosAux     + nZPosSidePlate * nXPos ); 
1108   
1109   double yMean = yPosVertex[11] + 0.5 * ( pDx1Trap1 + pDx3Trap1 );            // final y-pos. of first trapezoid centre
1110   TRANSFUNCTION XFSidePlate = Pow( HepTranslateZ3D(1.0), fTrlZSidePlate ) * 
1111                               Pow( HepTranslateX3D(1.0), fTrlXSidePlate ) * 
1112                               HepTranslateY3D(yMean) *                       // const. displacement along y
1113                               HepRotateX3D( M_PI/2 ) *                       // const. rotations to bring shape into...
1114                               HepRotateY3D( M_PI/2 ) *                       // ...correct orientation  
1115                               Pow( HepRotateX3D(1.0), fRotSidePlate ); 
1116 
1117    GeoSerialTransformer* sxSidePlate = new GeoSerialTransformer( pSidePlate, &XFSidePlate, nZPosSidePlate * nXPos );
1118    container->add(sxSidePlate);
1119 
1120 //------------------------------------------------------------------------------------------
1121 //  Build large vertical plates, located between the side-plate pairs
1122 //------------------------------------------------------------------------------------------
1123   
1124   double dyLargePlate = 0.5 * ( yMaxLargePlate - yMinLargePlate );
1125   double dzLargePlate = zWidth/2 - thicknessSidePlate;
1126   
1127   GeoBox* sLargePlate = new GeoBox( thicknessLargePlate/2, dyLargePlate, dzLargePlate - tolerance );
1128 
1129   GeoLogVol*  lLargePlate = new GeoLogVol( "ExtrFeetLargePlate", 
1130                                            sLargePlate, 
1131                                            theMaterialManager->getMaterial(feetMaterial) );
1132   // std::cout<<" FeetToroidBuilderRDBn::buildExtremityFeet  ExtrFeetLargePlate "<<std::endl;
1133   GeoPhysVol* pLargePlate = new GeoPhysVol(lLargePlate);
1134 
1135 //------------------------------------------------------------------------------------------
1136 // replicate and position   
1137 // array of z positions (will be used later also for inner vertical, cover, and bottom plates)
1138   const int nZPosPlate = 2;
1139   double zPosPlate[nZPosPlate] = { zPositionFeet[0], zPositionFeet[ nFeet - 1 ] };
1140 
1141 // array of x positions
1142   double xPosLargePlate[nXPos] = { -xMeanLargePlate, xMeanLargePlate };
1143 
1144 // fill auxiliary arrays 
1145   for ( int i = 0; i < nZPosPlate * nXPos; i++ )  
1146   {
1147      int ii = i % nZPosPlate, 
1148          jj = i / nZPosPlate;
1149      zPosAux[i] = zPosPlate[ii];
1150      xPosAux[i] = xPosLargePlate[jj];
1151   }
1152 
1153   GENFUNCTION fTrlZLargePlate = ArrayFunction( zPosAux, zPosAux + nZPosPlate * nXPos ); 
1154   GENFUNCTION fTrlXLargePlate = ArrayFunction( xPosAux, xPosAux + nZPosPlate * nXPos ); 
1155   
1156   double yPosLargePlate = yMinLargePlate + dyLargePlate;
1157   TRANSFUNCTION XFLargePlate = Pow( HepTranslateZ3D(1.0), fTrlZLargePlate ) * 
1158                                Pow( HepTranslateX3D(1.0), fTrlXLargePlate ) * 
1159                                HepTranslateY3D(yPosLargePlate); 
1160 
1161   GeoSerialTransformer* sxLargePlate = new GeoSerialTransformer( pLargePlate, &XFLargePlate, nZPosPlate * nXPos );
1162   container->add(sxLargePlate);
1163 
1164 //------------------------------------------------------------------------------------------
1165 //  Build inner inclined plates, located between the side-plate pairs 
1166 //------------------------------------------------------------------------------------------  
1167 
1168   const GeoShape* sInclPlate = new GeoBox( thicknessLargePlate/2, lengthInclinedPlate/2, dzLargePlate - tolerance );
1169 
1170   GeoBox* sEmptyBoxInclPlate = new GeoBox( thicknessLargePlate, yHeightCutInclinedPlate/2 + tolerance, 
1171                                            zLengthCutInclinedPlate/2 );
1172   
1173 //position of EmptyBox centre relative to centre of Inclined Plate
1174   HepTransform3D trlEmptyBoxInclPlate = HepTranslate3D( 0, lengthInclinedPlate/2 - yHeightCutInclinedPlate/2 , 0 );
1175   
1176   const GeoShape& sInclinedPlate = sInclPlate->subtract( (*sEmptyBoxInclPlate) << trlEmptyBoxInclPlate );
1177   
1178   GeoLogVol*  lInclinedPlate = new GeoLogVol( "ExtrFeetInclinedPlate", 
1179                                               &sInclinedPlate, 
1180                                               theMaterialManager->getMaterial(feetMaterial) );
1181   // std::cout<<" FeetToroidBuilderRDBn::buildExtremityFeet  ExtrFeetInclinedPlate "<<std::endl;
1182   GeoPhysVol* pInclinedPlate = new GeoPhysVol(lInclinedPlate);
1183 
1184 //------------------------------------------------------------------------------------------
1185 // replicate and position   
1186 // array of x positions
1187   
1188   double xMeanInclinedPlate = -(lengthInclinedPlate * sinBeta)/2 - (thicknessLargePlate * cosBeta)/2 + 
1189                                 xMeanLargePlate + thicknessLargePlate/2;
1190   
1191   double xPosInclinedPlate[nXPos] = { -xMeanInclinedPlate, xMeanInclinedPlate };
1192 
1193 // array of inclination angles (different for left and right plates)
1194   double rotAngleInclinedPlate[nXPos] = { -beta, beta };
1195 
1196 // fill auxiliary arrays 
1197   for ( int i = 0; i < nZPosPlate * nXPos; i++ )  
1198   {
1199      int ii = i % nZPosPlate, 
1200          jj = i / nZPosPlate;
1201      zPosAux[i]     = zPosPlate[ii];
1202      xPosAux[i]     = xPosInclinedPlate[jj];
1203      rotAngleAux[i] = rotAngleInclinedPlate[jj]; 
1204   }
1205 
1206   GENFUNCTION fRotInclinedPlate  = ArrayFunction( rotAngleAux, rotAngleAux + nZPosPlate * nXPos ); 
1207   GENFUNCTION fTrlZInclinedPlate = ArrayFunction( zPosAux,     zPosAux     + nZPosPlate * nXPos ); 
1208   GENFUNCTION fTrlXInclinedPlate = ArrayFunction( xPosAux,     xPosAux     + nZPosPlate * nXPos ); 
1209   
1210   double yMeanInclinedPlate = yPosLargePlate + dyLargePlate + (lengthInclinedPlate * cosBeta)/2 - 
1211                               (thicknessLargePlate * sinBeta)/2;
1212   
1213   TRANSFUNCTION XFInclinedPlate = Pow( HepTranslateZ3D(1.0), fTrlZInclinedPlate ) * 
1214                                   Pow( HepTranslateX3D(1.0), fTrlXInclinedPlate ) * 
1215                                   HepTranslateY3D(yMeanInclinedPlate) * 
1216                                   Pow( HepRotateZ3D(1.0), fRotInclinedPlate ); 
1217 
1218   GeoSerialTransformer* sxInclinedPlate = new GeoSerialTransformer( pInclinedPlate, 
1219                                                                     &XFInclinedPlate, 
1220                                                                     nZPosPlate * nXPos );
1221   container->add(sxInclinedPlate);
1222 
1223 //------------------------------------------------------------------------------------------
1224 //  Build outer inclined (cover) plates, which cover the Barrel Toroid coil cutouts
1225 //------------------------------------------------------------------------------------------  
1226 
1227   const GeoShape* sCoverPlateExtr = new GeoBox( thicknessOuterPlate/2 - tolerance, lengthOuterPlate/2, 
1228                                                 zWidthOuterPExtr/2 );
1229 
1230   GeoTube* sEmptyCoverTube        = new GeoTube( 0, radiusCutCoverPlateExtr, 2*thicknessOuterPlate );
1231   
1232 //position of EmptyCover centre relative to centre of CoverPlate
1233   HepTransform3D trlEmptyCoverTube;
1234   trlEmptyCoverTube = HepTranslateY3D( -yoffsetCutCoverPlateExtr );
1235   HepTransform3D xfEmptyCoverTube = trlEmptyCoverTube * HepRotateY3D( M_PI/2 );
1236   
1237   const GeoShape& sCoverPlate = sCoverPlateExtr->subtract( (*sEmptyCoverTube) << xfEmptyCoverTube );
1238 
1239   GeoLogVol*  lCoverPlate = new GeoLogVol( "ExtrFeetCoverPlate", 
1240                                            &sCoverPlate, 
1241                                            theMaterialManager->getMaterial(feetMaterial) );
1242   // std::cout<<" FeetToroidBuilderRDBn::buildExtremityFeet  ExtrFeetCoverPlate "<<std::endl;
1243   GeoPhysVol* pCoverPlate = new GeoPhysVol(lCoverPlate);
1244 
1245 //------------------------------------------------------------------------------------------
1246 // replicate and position   
1247   
1248   double DIAGExtr    = sqrt ( thicknessOuterPlate * thicknessOuterPlate + lengthOuterPlate * lengthOuterPlate );
1249   double alphaCPExtr = atan(thicknessOuterPlate/lengthOuterPlate);
1250   double betaCPExtr  = atan(dy12/dx12);
1251 
1252   // array of x positions
1253   double xMeanCoverPlate = xPosVertC1Extr + (yHeightMiniPExtr * sin(beta)) - (DIAGExtr * cos(betaCPExtr + alphaCPExtr))/2;
1254   double xPosCoverPlate[nXPos] = { -xMeanCoverPlate, xMeanCoverPlate };
1255 
1256   // array of inclination angles (different for left and right cover plates)
1257   double rotAngleCoverPlate[nXPos] = { -beta, beta };
1258 
1259   // fill auxiliary arrays 
1260   for ( int i = 0; i < nZPosPlate * nXPos; i++ )  
1261   {
1262      int ii = i % nZPosPlate, 
1263          jj = i / nZPosPlate;
1264      zPosAux[i]     = zPosPlate[ii];
1265      xPosAux[i]     = xPosCoverPlate[jj];
1266      rotAngleAux[i] = rotAngleCoverPlate[jj]; 
1267   }
1268 
1269   GENFUNCTION fRotCoverPlate  = ArrayFunction( rotAngleAux, rotAngleAux + nZPosPlate * nXPos ); 
1270   GENFUNCTION fTrlZCoverPlate = ArrayFunction( zPosAux,     zPosAux     + nZPosPlate * nXPos ); 
1271   GENFUNCTION fTrlXCoverPlate = ArrayFunction( xPosAux,     xPosAux     + nZPosPlate * nXPos ); 
1272   
1273   double yPosCoverPlate = yPosVertC1Extr + (DIAGExtr *  sin(betaCPExtr + alphaCPExtr))/2 - yHeightMiniPExtr * cos(beta);
1274   TRANSFUNCTION XFCoverPlate = Pow( HepTranslateZ3D(1.0), fTrlZCoverPlate ) * 
1275                                Pow( HepTranslateX3D(1.0), fTrlXCoverPlate ) * 
1276                                HepTranslateY3D(yPosCoverPlate) * 
1277                                Pow( HepRotateZ3D(1.0), fRotCoverPlate ); 
1278 
1279   GeoSerialTransformer* sxCoverPlate = new GeoSerialTransformer( pCoverPlate, &XFCoverPlate, nZPosPlate * nXPos );
1280   container->add(sxCoverPlate);
1281 
1282 //------------------------------------------------------------------------------------------
1283 //  Build inner (top) vertical plates, on which the Top Voussoirs plates are mounted
1284 //------------------------------------------------------------------------------------------
1285   
1286   GeoBox* sInnerTopPlate = new GeoBox( thicknessInnerPlate/2 - tolerance, yHeightInnerPlateExtr/2, zWidth/2 );
1287  
1288   GeoLogVol*  lInnerTopPlate = new GeoLogVol( "ExtrFeetInnerPlate", 
1289                                            sInnerTopPlate, 
1290                                            theMaterialManager->getMaterial(feetMaterial) );
1291   // std::cout<<" FeetToroidBuilderRDBn::buildExtremityFeet  ExtrFeetInnerPlate "<<std::endl;
1292   GeoPhysVol* pInnerTopPlate = new GeoPhysVol(lInnerTopPlate);
1293 
1294 //------------------------------------------------------------------------------------------
1295 // replicate and position array of x positions
1296   double xPosInnerTopPlate[nXPos] = { -xPosVertex[6] + thicknessInnerPlate/2, xPosVertex[6] - thicknessInnerPlate/2 };
1297 
1298 // fill auxiliary arrays 
1299   for ( int i = 0; i < nZPosPlate * nXPos; i++ )  
1300   {
1301      int ii = i % nZPosPlate, 
1302          jj = i / nZPosPlate;
1303      zPosAux[i] = zPosPlate[ii];
1304      xPosAux[i] = xPosInnerTopPlate[jj];
1305   }
1306 
1307   GENFUNCTION fTrlZInnerTopPlate = ArrayFunction( zPosAux, zPosAux + nZPosPlate * nXPos ); 
1308   GENFUNCTION fTrlXInnerTopPlate = ArrayFunction( xPosAux, xPosAux + nZPosPlate * nXPos ); 
1309   
1310   TRANSFUNCTION XFInnerTopPlate = Pow( HepTranslateZ3D(1.0), fTrlZInnerTopPlate ) * 
1311                                Pow( HepTranslateX3D(1.0), fTrlXInnerTopPlate ) * 
1312                                HepTranslateY3D(yPosCentrInPlateExtr); 
1313 
1314   GeoSerialTransformer* sxInnerTopPlate = new GeoSerialTransformer( pInnerTopPlate, &XFInnerTopPlate, 
1315                                                                     nZPosPlate * nXPos );
1316   container->add(sxInnerTopPlate);
1317 
1318   //------------------------------------------------------------------------------------------
1319   //Build inner Top Voussoirs plates
1320   //------------------------------------------------------------------------------------------
1321 
1322   GeoBox* sInnerTopVoussPlate     = new GeoBox( xWidthTopPlateExtr/2 - tolerance, yHeightTopPlateExtr/2, 
1323                                                 zLengthTopPlateExtr/2 );
1324 
1325   GeoLogVol*  lInnerTopVoussPlate = new GeoLogVol( "ExtrFeetInnerTopVoussPlate", 
1326                                            sInnerTopVoussPlate, 
1327                                            theMaterialManager->getMaterial(feetMaterial) );
1328   // std::cout<<" FeetToroidBuilderRDBn::buildExtremityFeet  ExtrFeetInnerTopVoussPlate "<<std::endl;
1329   GeoPhysVol* pInnerTopVoussPlate = new GeoPhysVol(lInnerTopVoussPlate);
1330 
1331   //------------------------------------------------------------------------------------------
1332   // replicate and position   
1333 
1334   // array of x positions
1335   double xPosInnerTopVoussPlate[nXPos] = { -xPosVertex[6] + thicknessInnerPlate + xWidthTopPlateExtr/2,
1336                                             xPosVertex[6] - thicknessInnerPlate - xWidthTopPlateExtr/2 };
1337 
1338   // fill auxiliary arrays 
1339   for ( int i = 0; i < nZPosPlate * nXPos; i++ )  
1340   {
1341      int ii = i % nZPosPlate, 
1342          jj = i / nZPosPlate;
1343      zPosAux[i] = zPosPlate[ii];
1344      xPosAux[i] = xPosInnerTopVoussPlate[jj];
1345   }
1346 
1347   GENFUNCTION fTrlZInnerTopVoussPlate = ArrayFunction( zPosAux, zPosAux + nZPosPlate * nXPos ); 
1348   GENFUNCTION fTrlXInnerTopVoussPlate = ArrayFunction( xPosAux, xPosAux + nZPosPlate * nXPos ); 
1349  
1350   TRANSFUNCTION XFInnerTopVoussPlate = Pow( HepTranslateZ3D(1.0), fTrlZInnerTopVoussPlate ) * 
1351                                Pow( HepTranslateX3D(1.0), fTrlXInnerTopVoussPlate ) * 
1352                                HepTranslateY3D(yPosCentrInPlateExtr); 
1353 
1354   GeoSerialTransformer* sxInnerTopVoussPlate = new GeoSerialTransformer( pInnerTopVoussPlate, 
1355                                                                          &XFInnerTopVoussPlate, nZPosPlate * nXPos );
1356   container->add(sxInnerTopVoussPlate);
1357 
1358 //------------------------------------------------------------------------------------------
1359 //  Build bottom plates
1360 //------------------------------------------------------------------------------------------
1361   
1362   GeoBox* sBottomPlate = new GeoBox( pDzTrap1, thicknessBottomPlate/2 - tolerance, zWidthBotExtr/2 );
1363 
1364   GeoLogVol*  lBottomPlate = new GeoLogVol( "ExtrFeetBottomPlate", 
1365                                             sBottomPlate, 
1366                                             theMaterialManager->getMaterial(feetMaterial) );
1367   // std::cout<<" FeetToroidBuilderRDBn::buildExtremityFeet  ExtrFeetBottomPlate "<<std::endl;
1368   GeoPhysVol* pBottomPlate = new GeoPhysVol(lBottomPlate);
1369 
1370   //------------------------------------------------------------------------------------------
1371   // replicate and position   
1372 
1373   // array of x positions
1374   double xPosBottomPlate[nXPos] = { -0.5 * ( xPosVertex[0] + xPosVertex[11] ), 
1375                                      0.5 * ( xPosVertex[0] + xPosVertex[11] ) };
1376 
1377   // fill auxiliary arrays 
1378   for ( int i = 0; i < nZPosPlate * nXPos; i++ )  
1379   {
1380      int ii = i % nZPosPlate, 
1381          jj = i / nZPosPlate;
1382      zPosAux[i] = zPosPlate[ii];
1383      xPosAux[i] = xPosBottomPlate[jj];
1384   }
1385 
1386   GENFUNCTION fTrlZBottomPlate = ArrayFunction( zPosAux, zPosAux + nZPosPlate * nXPos ); 
1387   GENFUNCTION fTrlXBottomPlate = ArrayFunction( xPosAux, xPosAux + nZPosPlate * nXPos ); 
1388   
1389   double yPosBottomPlate = yPosVertex[0] - thicknessBottomPlate/2;
1390   TRANSFUNCTION XFBottomPlate = Pow( HepTranslateZ3D(1.0), fTrlZBottomPlate ) * 
1391                                 Pow( HepTranslateX3D(1.0), fTrlXBottomPlate ) * 
1392                                 HepTranslateY3D(yPosBottomPlate); 
1393 
1394   GeoSerialTransformer* sxBottomPlate = new GeoSerialTransformer( pBottomPlate, &XFBottomPlate, nZPosPlate * nXPos );
1395   container->add(sxBottomPlate);
1396 
1397   // std::cout<<" FeetToroidBuilderRDB::buildExtremityFeet  sxBottomPlate  "<<std::endl;
1398 }
1399 
1400 void FeetToroidBuilderRDB::buildFeetGirders( GeoPhysVol* container ) 
1401 {
1402   //------------------------------------------------------------------------------------------
1403   //  Builds Feet Girders (i.e., 'bridges' between feet pairs adjacent in z)   
1404   //------------------------------------------------------------------------------------------
1405 
1406   const StoredMaterialManager*  theMaterialManager;
1407   if ( StatusCode::SUCCESS != m_pDetStore->retrieve( theMaterialManager, "MATERIALS" ) ) 
1408   {
1409     return;
1410   } 
1411 
1412   const int NumGir = 3;
1413 
1414 //------------ Feet General Parameters ---------------------------------//
1415    double zPositionFeet[maxDim];
1416      zPositionFeet[0] = -(*m_Feet)[0]->getFloat("ZPOSFEE5") * mm;
1417      zPositionFeet[1] = -(*m_Feet)[0]->getFloat("ZPOSFEE4") * mm;
1418      zPositionFeet[2] = -(*m_Feet)[0]->getFloat("ZPOSFEE3") * mm;
1419      zPositionFeet[3] = -(*m_Feet)[0]->getFloat("ZPOSFEE2") * mm;
1420      zPositionFeet[4] =  (*m_Feet)[0]->getFloat("ZPOSFEE1") * mm;
1421      zPositionFeet[5] =  (*m_Feet)[0]->getFloat("ZPOSFEE2") * mm;
1422      zPositionFeet[6] =  (*m_Feet)[0]->getFloat("ZPOSFEE3") * mm;
1423      zPositionFeet[7] =  (*m_Feet)[0]->getFloat("ZPOSFEE4") * mm;
1424      zPositionFeet[8] =  (*m_Feet)[0]->getFloat("ZPOSFEE5") * mm;  
1425 
1426    const std::string feetMaterial = getMaterial( "Iron" );
1427 
1428    //const double zWidthStandFeet = (*m_Feet)[0]->getFloat("MNPLZSEP") * mm;
1429 
1430 //------------------ Extremity Feet Parameters -------------------------------//
1431 
1432 //   const double zWidthExtrFeet = (*m_Feet)[0]->getFloat("EXMPZSEP") * mm;
1433 
1434 //------------------ Standard Feet Girder Parameters -------------------------//
1435    const double zTotalLengthGirder12            = (*m_Feet)[0]->getFloat("G12UPXWI") * mm;
1436    const double zInnerPlateSmall2LargeGirder12  = (*m_Feet)[0]->getFloat("G12IPSLX") * mm;
1437    const double zInnerPlateLarge2LargeGirder12  = (*m_Feet)[0]->getFloat("G12IPLLX") * mm;
1438    const double zInnerPlateLarge2SmallGirder12  = (*m_Feet)[0]->getFloat("G12IPLSX") * mm;
1439    const double zLengthSideBottomPlateGirder12  = (*m_Feet)[0]->getFloat("G12RPXWI") * mm;
1440    const double zLengthCentralBotPlateGirder12  = (*m_Feet)[0]->getFloat("G12LPXW1") * mm;      
1441 
1442    const double zTotalLengthGirder23            = (*m_Feet)[0]->getFloat("G23UPXWI") * mm;
1443    const double zInnerPlateSmall2LargeGirder23  = (*m_Feet)[0]->getFloat("G23IPSLX") * mm;
1444    const double zInnerPlateLarge2LargeGirder23  = (*m_Feet)[0]->getFloat("G23IPLLX") * mm;
1445    const double zInnerPlateLarge2SmallGirder23  = (*m_Feet)[0]->getFloat("G23IPLSX") * mm;
1446    const double zLengthSideBottomPlateGirder23  = (*m_Feet)[0]->getFloat("G23RPXWI") * mm;
1447    const double zLengthCentralBotPlateGirder23  = (*m_Feet)[0]->getFloat("G23LPXW1") * mm;
1448 
1449    const double zTotalLengthGirder34            = (*m_Feet)[0]->getFloat("G34UPXWI") * mm;
1450    const double zInnerPlateSmall2LargeGirder34  = (*m_Feet)[0]->getFloat("G34IPSLX") * mm;
1451    const double zInnerPlateLarge2LargeGirder34  = (*m_Feet)[0]->getFloat("G34IPLLX") * mm;
1452    const double zInnerPlateLarge2SmallGirder34  = (*m_Feet)[0]->getFloat("G34IPLSX") * mm;
1453    const double zLengthSideBottomPlateGirder34  = (*m_Feet)[0]->getFloat("G34RPXWI") * mm;
1454    const double zLengthCentralBotPlateGirder34  = (*m_Feet)[0]->getFloat("G34LPXW1") * mm;   
1455 
1456    const double zoffsetInSPG    = (*m_Feet)[0]->getFloat("G12IPSXO") * mm;
1457    const double thicknessInnerPG= (*m_Feet)[0]->getFloat("G12IPXWI") * mm;
1458    const double zWidthUpMPG     = (*m_Feet)[0]->getFloat("G12UMPWI") * mm;
1459    const double zWidthSMPG      = (*m_Feet)[0]->getFloat("G12SMPWI") * mm;
1460    const double yTotHeightG     = (*m_Feet)[0]->getFloat("G12LPYHT") * mm;
1461    const double xWidthTopPG     = (*m_Feet)[0]->getFloat("G12UPZLE") * mm;
1462    const double xLengthUpMPG    = (*m_Feet)[0]->getFloat("G12UMPZL") * mm;
1463    const double xWidthBotPG     = (*m_Feet)[0]->getFloat("G12BPZLE") * mm;
1464    const double thicknessSPG    = (*m_Feet)[0]->getFloat("G12RPZLE") * mm;
1465    const double thicknessSMPG   = (*m_Feet)[0]->getFloat("G12SMPZL") * mm;
1466    const double yHeightUpMPG    = (*m_Feet)[0]->getFloat("G12UMPYH") * mm;
1467    const double yHeightTopPG    = (*m_Feet)[0]->getFloat("G12UPYTH") * mm;
1468    const double yHeightBotPG    = (*m_Feet)[0]->getFloat("G12LPYTH") * mm;
1469    const double zLengthSlBotPG  = (*m_Feet)[0]->getFloat("G12LPX12") * mm;
1470    const double xWidthInPG      = (*m_Feet)[0]->getFloat("G12BPZLE") * mm;
1471    const double yHeightInLPG    = (*m_Feet)[0]->getFloat("G12LPYH1") * mm;
1472    const double yHeightInSPG    = (*m_Feet)[0]->getFloat("G12LPYH2") * mm;
1473    const double yHeightSMPG     = (*m_Feet)[0]->getFloat("G12RPYDI") * mm;
1474    const double xMeanStd        = (*m_Feet)[0]->getFloat("GIRDXPOS") * mm;
1475    const double yPosFoot        = (*m_Feet)[0]->getFloat("STDFOOYP") * mm;
1476    const double G12UPypo        = (*m_Feet)[0]->getFloat("G12UPYPO") * mm;
1477    const double GirdYHei        = (*m_Feet)[0]->getFloat("GIRDYHEI") * mm;
1478 //----------------------------------------------------------------------------//  
1479 
1480   const double tolerance = 0.5*mm;
1481   
1482   double zTotLengthG[NumGir];
1483   double zInnerS2LG[NumGir];
1484   double zInnerL2LG[NumGir];
1485   double zInnerL2SG[NumGir];
1486   double zLengthSBotPG[NumGir];
1487   double zLengthCBotPG[NumGir];
1488 
1489   // auxiliary arrays to store z, x positions, and rotation angles for all volumes to be replicated 
1490   const int nZPos = 2;
1491   const int nXPos = 2;
1492 
1493   double zPosAux[ nZPos * nXPos ],  xPosAux[ nZPos * nXPos ];//,  rotAngleAux[ nZPos * nXPos ];
1494     
1495   //------------------------------------------------------------------------------------------
1496   //  Girder12 properties 
1497   zTotLengthG[2]   = zTotalLengthGirder12;
1498   zInnerS2LG[2]    = zInnerPlateSmall2LargeGirder12;
1499   zInnerL2LG[2]    = zInnerPlateLarge2LargeGirder12;
1500   zInnerL2SG[2]    = zInnerPlateLarge2SmallGirder12;
1501   zLengthSBotPG[2] = zLengthSideBottomPlateGirder12;
1502   zLengthCBotPG[2] = zLengthCentralBotPlateGirder12;
1503   
1504   //   Girder23 properties
1505   zTotLengthG[1]   = zTotalLengthGirder23;
1506   zInnerS2LG[1]    = zInnerPlateSmall2LargeGirder23;
1507   zInnerL2LG[1]    = zInnerPlateLarge2LargeGirder23;
1508   zInnerL2SG[1]    = zInnerPlateLarge2SmallGirder23;
1509   zLengthSBotPG[1] = zLengthSideBottomPlateGirder23;
1510   zLengthCBotPG[1] = zLengthCentralBotPlateGirder23;
1511   
1512   //   Girder34 properties
1513   zTotLengthG[0]   = zTotalLengthGirder34;
1514   zInnerS2LG[0]    = zInnerPlateSmall2LargeGirder34;
1515   zInnerL2LG[0]    = zInnerPlateLarge2LargeGirder34;
1516   zInnerL2SG[0]    = zInnerPlateLarge2SmallGirder34;
1517   zLengthSBotPG[0] = zLengthSideBottomPlateGirder34;
1518   zLengthCBotPG[0] = zLengthCentralBotPlateGirder34;
1519 
1520     // for side plate of girder
1521   const double yHeightTopSPG    = yHeightSMPG;
1522   const double yHeightBotSPG    = yTotHeightG - yHeightSMPG;
1523   
1524   // for slanted bottom plate    
1525   double deltaH = yHeightInLPG - yHeightInSPG;
1526   double alphaG = atan( deltaH/zLengthSlBotPG );
1527   
1528 //  const double yMeanStd       = HeightG + yHeightTopPG/2 + yPosFoot + yHeightGirder;
1529 //    const double yMeanStd     = G12UPypo + yPosFoot;
1530     const double yMeanStd = G12UPypo + yPosFoot + GirdYHei;
1531 
1532   //------------------------------------------------------------------------------------------
1533   //  Loop on Standard Feet. Do everything within the loop: 
1534   //   - determine z-length and z-position of Girder centre
1535   //   - build Standard Feet Girder
1536   //   - replicate the built shapes (front/back (z), right/left (x))
1537   //------------------------------------------------------------------------------------------
1538   
1539   for ( int i = 1; i < 4; i++ )            // girders at +/-z are identical 
1540   {
1541      double zMinStd   = zPositionFeet[i];     
1542      double zMaxStd   = zPositionFeet[ i + 1 ];     
1543 //   double deltaZStd = zMaxStd - zMinStd - zWidthStandFeet; 
1544      double zMeanStd  = 0.5 * ( zMinStd + zMaxStd );
1545 
1546      int i3;
1547      i3 = i - 1;
1548   
1549      // use loop variable to label (slightly) different girder volumes
1550      my_osstream os;
1551      os << std::setw(2) << std::setfill('0') << i;
1552 
1553 
1554   //------------------------------------------------------------------------------------------
1555   //  Build Feet Girder12
1556   //------------------------------------------------------------------------------------------
1557 
1558     // top plate
1559     const GeoShape* sTopPlateGirder     = new GeoBox( xWidthTopPG/2, yHeightTopPG/2 - tolerance, zTotLengthG[i3]/2 );
1560     
1561     // two small plates
1562     GeoBox* sSmallPlateGirder           = new GeoBox( xWidthInPG/2 - tolerance, yHeightInSPG/2 - tolerance, thicknessInnerPG/2 );
1563     
1564     //two large plates
1565     GeoBox* sLargePlateGirder           = new GeoBox( xWidthInPG/2 - tolerance, yHeightInLPG/2 - tolerance, thicknessInnerPG/2 );
1566     
1567     //two side (Top) Plates
1568     GeoBox* sSideTopPlateGirder         = new GeoBox( thicknessSPG/2 - tolerance, yHeightTopSPG/2 - tolerance, zTotLengthG[i3]/2 );
1569     
1570     //two side (bottom) plates
1571     GeoBox* sSideBotPlateGirder         = new GeoBox( thicknessSPG/2 - tolerance, yHeightBotSPG/2 - tolerance, zLengthSBotPG[i3]/2 );
1572     
1573     // two upper mini plates
1574     GeoBox* sUpperMiniPlateGirder       = new GeoBox( xLengthUpMPG/2, yHeightUpMPG/2 - tolerance, zWidthUpMPG/2 );
1575     
1576     //four side mini plates
1577     GeoBox* sMiniPlateGirder            = new GeoBox( thicknessSMPG/2 - tolerance, yHeightSMPG/2 - tolerance, zWidthSMPG/2 );
1578     
1579     //bottom plate
1580     GeoBox* sBottomPlateGirder          = new GeoBox( xWidthBotPG/2 - tolerance, yHeightBotPG/2 - tolerance, zLengthCBotPG[i3]/2 );
1581     
1582     //slanted plates
1583     GeoPara* sSlantedPlateGirder_1      = new GeoPara( (zLengthSlBotPG - tolerance)/(2 * cos(alphaG)), yHeightBotPG/2, xWidthBotPG/2,
1584                                                      -alphaG, 0, 0 );
1585     GeoPara* sSlantedPlateGirder_2      = new GeoPara( (zLengthSlBotPG - tolerance)/(2 * cos(alphaG)), yHeightBotPG/2, xWidthBotPG/2,
1586                                                      alphaG, 0, 0 );
1587     //two upper bottom plate
1588     GeoBox* sUpBotPlateGirder           = new GeoBox( xWidthBotPG/2 - tolerance, yHeightBotPG/2 - tolerance, 
1589                                                         zTotLengthG[i3]/4 - zLengthCBotPG[i3]/4 - zLengthSlBotPG/2 - tolerance );
1590 
1591 
1592     //position of shapes' centres relative to center of top plate
1593     
1594     //two small plates
1595     HepTransform3D trlSmallRPlateGirder         = HepTranslate3D( 0, -yHeightInSPG/2 - yHeightTopPG/2,
1596                                                                  -zTotLengthG[i3]/2 + zoffsetInSPG + thicknessInnerPG/2);
1597     HepTransform3D trlSmallLPlateGirder         = HepTranslate3D( 0, -yHeightInSPG/2 - yHeightTopPG/2,
1598                                                                  -zTotLengthG[i3]/2 + zoffsetInSPG + thicknessInnerPG/2
1599                                                                  + zInnerS2LG[i3] + zInnerL2LG[i3] + zInnerL2SG[i3]);
1600     
1601     //two large plates
1602     HepTransform3D trlLargeRPlateGirder         = HepTranslate3D( 0, -yHeightInLPG/2 - yHeightTopPG/2, 
1603                                                                  -zTotLengthG[i3]/2 + zoffsetInSPG + zInnerS2LG[i3] 
1604                                                                     + thicknessInnerPG/2 );
1605     HepTransform3D trlLargeLPlateGirder         = HepTranslate3D( 0, -yHeightInLPG/2 - yHeightTopPG/2, 
1606                                                                  -zTotLengthG[i3]/2 + zoffsetInSPG + zInnerS2LG[i3]
1607                                                                   + thicknessInnerPG/2 + zInnerL2LG[i3]);
1608     
1609     //two upper mini plates
1610     HepTransform3D trlUpperMiniRPlateGirder     = HepTranslate3D( 0, yHeightUpMPG/2 + yHeightTopPG/2, zTotLengthG[i3]/2 - zWidthUpMPG/2 );
1611     HepTransform3D trlUpperMiniLPlateGirder     = HepTranslate3D( 0, yHeightUpMPG/2 + yHeightTopPG/2, -zTotLengthG[i3]/2 + zWidthUpMPG/2 );
1612     
1613     //two side (top) plates
1614     HepTransform3D trlInnerSideTopPlateGirder   = HepTranslate3D( -xWidthBotPG/2 - thicknessSPG/2, -yHeightTopSPG/2 - yHeightTopPG/2, 0 );
1615     HepTransform3D trlOuterSideTopPlateGirder   = HepTranslate3D( xWidthBotPG/2 + thicknessSPG/2, -yHeightTopSPG/2 - yHeightTopPG/2, 0 );
1616     
1617     //two side (bottom) plates
1618     HepTransform3D trlInnerSideBotPlateGirder   = HepTranslate3D( -xWidthBotPG/2 - thicknessSPG/2,
1619                                                                  -yHeightTopSPG - yHeightBotSPG/2 - yHeightTopPG/2, 0 );
1620     HepTransform3D trlOuterSideBotPlateGirder   = HepTranslate3D( xWidthBotPG/2 + thicknessSPG/2,
1621                                                                  -yHeightTopSPG - yHeightBotSPG/2 - yHeightTopPG/2, 0 );
1622     
1623     //four side mini plates
1624     HepTransform3D trlInnerMiniRPlateGirder     = HepTranslate3D( -xWidthBotPG/2 - thicknessSPG - thicknessSMPG/2, -yHeightTopSPG/2
1625                                                                     - yHeightTopPG/2, zTotLengthG[i3]/2 - zWidthSMPG/2 );
1626     HepTransform3D trlInnerMiniLPlateGirder     = HepTranslate3D( -xWidthBotPG/2 - thicknessSPG - thicknessSMPG/2, -yHeightTopSPG/2
1627                                                                     -yHeightTopPG/2, -zTotLengthG[i3]/2 + zWidthSMPG/2 );
1628     HepTransform3D trlOuterMiniRPlateGirder     = HepTranslate3D( xWidthBotPG/2 + thicknessSPG + thicknessSMPG/2, -yHeightTopSPG/2
1629                                                                     - yHeightTopPG/2, zTotLengthG[i3]/2 - zWidthSMPG/2 );
1630     HepTransform3D trlOuterMiniLPlateGirder     = HepTranslate3D( xWidthBotPG/2 + thicknessSPG + thicknessSMPG/2, -yHeightTopSPG/2
1631                                                                     -yHeightTopPG/2, -zTotLengthG[i3]/2 + zWidthSMPG/2 );
1632     
1633     //bottom plate
1634     HepTransform3D trlBottomPlateGirder         = HepTranslate3D( 0, -yHeightInLPG - yHeightBotPG/2 - yHeightTopPG/2, 0 );
1635     
1636     //slanted plate
1637     HepTransform3D trlSlantedPlateGirder_1      = HepTranslate3D( 0, -deltaH/2 - yHeightInSPG - yHeightTopPG/2 - yHeightBotPG/2,
1638                                                                  zLengthCBotPG[i3]/2 + zLengthSlBotPG/2 ) *
1639                                                                  HepRotateX3D(-alphaG) * HepRotateY3D( M_PI/2 );
1640     HepTransform3D trlSlantedPlateGirder_2      = HepTranslate3D( 0, -deltaH/2 - yHeightInSPG - yHeightTopPG/2 - yHeightBotPG/2,
1641                                                                  -zLengthCBotPG[i3]/2 - zLengthSlBotPG/2 ) * 
1642                                                                 HepRotateX3D(alphaG) * HepRotateY3D( M_PI/2 );
1643 
1644     //two upper bottom plates
1645     HepTransform3D trlUpBotRPlateGirder         = HepTranslate3D( 0, -yHeightInSPG - yHeightBotPG/2 - yHeightTopPG/2, 
1646                                                                     zTotLengthG[i3]/4 + zLengthSlBotPG/2 + zLengthCBotPG[i3]/4 );
1647     HepTransform3D trlUpBotLPlateGirder         = HepTranslate3D( 0, -yHeightInSPG - yHeightBotPG/2 - yHeightTopPG/2,
1648                                                                     -zTotLengthG[i3]/4 - zLengthSlBotPG/2 - zLengthCBotPG[i3]/4 );
1649 
1650     
1651     const GeoShape& sStdGirder = sTopPlateGirder->add( (*sSmallPlateGirder)      << trlSmallRPlateGirder ).
1652                                                     add( (*sSmallPlateGirder)    << trlSmallLPlateGirder ).
1653                                                     add( (*sLargePlateGirder)    << trlLargeRPlateGirder ).
1654                                                     add( (*sLargePlateGirder)    << trlLargeLPlateGirder ).
1655                                                     add( (*sUpperMiniPlateGirder)<< trlUpperMiniRPlateGirder ).
1656                                                     add( (*sUpperMiniPlateGirder)<< trlUpperMiniLPlateGirder ).
1657                                                     add( (*sSideTopPlateGirder)  << trlInnerSideTopPlateGirder ).
1658                                                     add( (*sSideTopPlateGirder)  << trlOuterSideTopPlateGirder ).
1659                                                     add( (*sSideBotPlateGirder)  << trlInnerSideBotPlateGirder ).
1660                                                     add( (*sSideBotPlateGirder)  << trlOuterSideBotPlateGirder ).
1661                                                     add( (*sMiniPlateGirder)     << trlInnerMiniRPlateGirder ).
1662                                                     add( (*sMiniPlateGirder)     << trlInnerMiniLPlateGirder ).
1663                                                     add( (*sMiniPlateGirder)     << trlOuterMiniRPlateGirder ).
1664                                                     add( (*sMiniPlateGirder)     << trlOuterMiniLPlateGirder ).
1665                                                     add( (*sBottomPlateGirder)   << trlBottomPlateGirder ).
1666                                                     add( (*sUpBotPlateGirder)    << trlUpBotRPlateGirder ).
1667                                                     add( (*sSlantedPlateGirder_1)<< trlSlantedPlateGirder_1 ).
1668                                                     add( (*sSlantedPlateGirder_2)<< trlSlantedPlateGirder_2 ).
1669                                                     add( (*sUpBotPlateGirder)    << trlUpBotLPlateGirder );
1670 
1671      GeoLogVol*  lStdGirder = new GeoLogVol( "StdFeetGirder" + os.str(), 
1672                                              &sStdGirder, 
1673                                              theMaterialManager->getMaterial(feetMaterial) );
1674      GeoPhysVol* pStdGirder = new GeoPhysVol(lStdGirder);
1675      
1676      //---------------------------------------------------------------------------------------
1677      // replicate and position 
1678      //---------------------------------------------------------------------------------------
1679 
1680      // array of z-positions of girder centres
1681      double zPos[nZPos] = { -zMeanStd, zMeanStd };
1682 
1683      // array of x positions
1684      double xPos[nXPos] = { -xMeanStd, xMeanStd };
1685     
1686      // fill auxiliary arrays 
1687      for ( int j = 0; j < nZPos * nXPos; j++ )  
1688      {
1689         int jj = j % nZPos, 
1690             kk = j / nZPos;
1691         zPosAux[j] = zPos[jj];
1692         xPosAux[j] = xPos[kk];
1693      }
1694 
1695      GENFUNCTION fTrlZ = ArrayFunction( zPosAux, zPosAux + nZPos * nXPos ); 
1696      GENFUNCTION fTrlX = ArrayFunction( xPosAux, xPosAux + nZPos * nXPos ); 
1697   
1698      TRANSFUNCTION XFStdGirder = Pow( HepTranslateZ3D(1.0), fTrlZ ) * 
1699                                  Pow( HepTranslateX3D(1.0), fTrlX ) * 
1700                                  HepTranslateY3D(yMeanStd);             // const. displacement along y
1701 
1702      GeoSerialTransformer* sxStdGirder = new GeoSerialTransformer( pStdGirder, &XFStdGirder, nZPos * nXPos );
1703      container->add(sxStdGirder);
1704 
1705      // std::cout<<" FeetToroidBuilderRDB::buildFeetGirders   sxStdGirder "<<std::endl;
1706 
1707   }   
1708   
1709 
1710 }
1711 
1712 
1713 
1714 
1715 void FeetToroidBuilderRDB::buildFeetRailSupports( GeoPhysVol* container ) 
1716 {
1717   //------------------------------------------------------------------------------------------
1718   //  Builds Rail Supports on Feet    
1719   //------------------------------------------------------------------------------------------
1720 
1721   const StoredMaterialManager*  theMaterialManager;
1722   if ( StatusCode::SUCCESS != m_pDetStore->retrieve( theMaterialManager, "MATERIALS" ) ) 
1723   {
1724     return;
1725   } 
1726 
1727 
1728 //------------ Feet General Parameters ---------------------------------//
1729    double zPositionFeet[maxDim];
1730    zPositionFeet[0] = -(*m_Feet)[0]->getFloat("ZPOSFEE5") * mm;
1731    zPositionFeet[1] = -(*m_Feet)[0]->getFloat("ZPOSFEE4") * mm;
1732    zPositionFeet[2] = -(*m_Feet)[0]->getFloat("ZPOSFEE3") * mm;
1733    zPositionFeet[3] = -(*m_Feet)[0]->getFloat("ZPOSFEE2") * mm;
1734    zPositionFeet[4] =  (*m_Feet)[0]->getFloat("ZPOSFEE1") * mm;
1735    zPositionFeet[5] =  (*m_Feet)[0]->getFloat("ZPOSFEE2") * mm;
1736    zPositionFeet[6] =  (*m_Feet)[0]->getFloat("ZPOSFEE3") * mm;
1737    zPositionFeet[7] =  (*m_Feet)[0]->getFloat("ZPOSFEE4") * mm;
1738    zPositionFeet[8] =  (*m_Feet)[0]->getFloat("ZPOSFEE5") * mm;
1739                                                                
1740    const std::string feetMaterial = getMaterial( "Iron" );
1741 //----------------------------------------------------------------------------//
1742    const double xPosFoot             = (*m_Feet)[0]->getFloat("STDFOOXP") * mm;
1743    const double yPosFoot             = (*m_Feet)[0]->getFloat("STDFOOYP") * mm;
1744    //const double zWidthStandFeet      = (*m_Feet)[0]->getFloat("MNPLZSEP") * mm;
1745    const double yPosVertex4StandFeet = (*m_Feet)[0]->getFloat("MAINPLYF") * mm;
1746 
1747 //------------------ Extremity Feet Parameters -------------------------------//
1748    //const double zWidthExtrFeet      = (*m_Feet)[0]->getFloat("EXMPZSEP") * mm;
1749    const double yPosVertex4ExtrFeet = (*m_Feet)[0]->getFloat("EXMPLAYF") * mm;
1750 
1751 //------------------ Feet Rail Support Parameters ----------------------------//
1752    const double xPosRailSuppFeet   = (*m_Feet)[0]->getFloat("EXRSPOSX") * mm;
1753    const double xWidth             = (*m_Feet)[0]->getFloat("XWIDTH")   * mm;
1754    const double thicknessMidPlate  = (*m_Feet)[0]->getFloat("MIDLLYTH") * mm;
1755    const double zWidthMidPlate     = (*m_Feet)[0]->getFloat("CENTRLEZ") * mm;
1756    const double zWidthTopPlate     = (*m_Feet)[0]->getFloat("UPPERLEZ") * mm;
1757    const double zWidthBotPlate     = (*m_Feet)[0]->getFloat("LOWERLEZ") * mm;
1758    //const double zWidthCentralPlateRailSuppFeet           = (*m_Feet)[0]->getFloat("CENTRLEZ") * mm;
1759    const double xCentrWidth        = (*m_Feet)[0]->getFloat("CENTRXTH") * mm;
1760    const double yHeightCentrTB     = 29.0 * cm;
1761    const double yHeightVertPlate   = (*m_Feet)[0]->getFloat("CENTRHEY") * mm;
1762    const double thicknessVerPlate  = (*m_Feet)[0]->getFloat("VERTIZTH") * mm;
1763    const double thicknessBotBot    = (*m_Feet)[0]->getFloat("EXTREHEY") * mm;
1764    const double zLengthBotBot      = (*m_Feet)[0]->getFloat("EXTRELEZ") * mm;
1765    const double yHeightStd         = (*m_Feet)[0]->getFloat("TOTALHEY") * mm;
1766    const double thicknessTopPlate  = (*m_Feet)[0]->getFloat("UPPERHEY") * mm;
1767    const double thicknessBotPlate  = (*m_Feet)[0]->getFloat("LOWERHEY") * mm;
1768    const double zWidthTopPlateExtr = (*m_Feet)[0]->getFloat("EXRSUZLE") * mm;
1769    const double deltaTopBotPlateExtr   = (*m_Feet)[0]->getFloat("EXRSLDZL")* mm;
1770    const double thicknessBotBotExtr= (*m_Feet)[0]->getFloat("EXRSEYHE") * mm;
1771    const double yHeightCentrPlateExtr  = (*m_Feet)[0]->getFloat("EXRSCYHE") * mm;
1772    const double zLengthCentrPlateExtr  = (*m_Feet)[0]->getFloat("EXRSCZLE") * mm;
1773    const double zWidthMidPlateExtr = (*m_Feet)[0]->getFloat("EXRSMZLE") * mm;
1774    const double xCentrWidthExtr    = (*m_Feet)[0]->getFloat("EXRSCXWI") * mm;
1775    const double xWidthMidPlateExtr = (*m_Feet)[0]->getFloat("EXRSMXWI") * mm;
1776    const double xWidthVertPlateExtr= (*m_Feet)[0]->getFloat("EXRSVXWI") * mm;
1777    const double yHeightExtr        = (*m_Feet)[0]->getFloat("EXRSTYHE")   * mm;
1778    const double thicknessBotPlateExtr  = (*m_Feet)[0]->getFloat("EXRSLYHE")   * mm;
1779    const double zLengthBotBotExtr  = (*m_Feet)[0]->getFloat("EXRSEZOF")   * mm;
1780    const double zoffsetRSExtr      = (*m_Feet)[0]->getFloat("EXRSZOFF")   * mm;
1781    const double zoffsetVertRSExtr  = (*m_Feet)[0]->getFloat("EXRSVZI1") * mm;
1782    const double zoffsetBotBotExtr  = (*m_Feet)[0]->getFloat("EXRSEZOF") * mm;
1783    const double zLengthMidCutExtr  = (*m_Feet)[0]->getFloat("EXRSMCWI") * mm;
1784    const double DepthMidCutExtr    = (*m_Feet)[0]->getFloat("EXRSMCDE") * mm;
1785    const double zoffsetMidCutExtr  = (*m_Feet)[0]->getFloat("EXRSMCZO") * mm;
1786    const double radiusBotCutOutExtr= (*m_Feet)[0]->getFloat("EXRSC2Z2") * mm;
1787    const double zLengthBotCutOutExtr   = 55.0 * cm;
1788    const double yHeightBotCutOutExtr   = 32.0 * cm;
1789    const double zoffsetBotCutExtr  = (*m_Feet)[0]->getFloat("EXRSC1ZP") * mm;
1790 
1791 // auxiliary arrays to store z, x positions, and rotation angles for all volumes to be replicated 
1792   const int nZPosMax = maxDim - 2;
1793   const int nXPosMax = 2;
1794   double zPosAux1[ nZPosMax * nXPosMax ], zPosAux2[ nZPosMax * nXPosMax ],  
1795          xPosAux1[ nZPosMax * nXPosMax ],  rotAngleAux[ nZPosMax * nXPosMax ],
1796          xPosAux2[ nZPosMax * nXPosMax ], xPosAux[ nZPosMax * nXPosMax ];
1797     
1798   //------------------------------------------------------------------------------------------
1799   // common Rail Support properties      
1800   const double zposVertPlateExtr = zLengthCentrPlateExtr/2 - zoffsetVertRSExtr;
1801   const double zoffsetExtr       = zLengthCentrPlateExtr/2 - zoffsetVertRSExtr - zWidthMidPlateExtr/2 - zoffsetRSExtr;
1802   
1803   const double zWidthBotPlateExtr = zWidthTopPlateExtr - deltaTopBotPlateExtr; 
1804 
1805 //
1806 
1807   // common positioning variable for rail support centre
1808   const double xMean = xPosRailSuppFeet + xPosFoot;
1809   const double xMeanMinusRailSuppExtr = xPosRailSuppFeet + xPosFoot;
1810   const double xMeanPlusRailSuppExtr  = xPosRailSuppFeet + xPosFoot;
1811   
1812   const double tolerance = 0.5 * mm;    
1813 
1814   // positioning variable for rail support centre
1815   const double yMeanStd = yPosVertex4StandFeet + yHeightStd/2 + yPosFoot - thicknessBotBot/2;  // from Standard Foot top pos.    
1816 
1817   // positioning variable for rail support centre
1818   const double yMeanExtr = yPosVertex4ExtrFeet + yHeightExtr/2 + yPosFoot
1819                              - thicknessBotBotExtr/2;  // from Extremity Foot top pos.
1820 
1821   //-------------------------------------------------------------------------------------------
1822   // Build Standard Feet Rail Support seven boxes
1823   //--------------------------------------------
1824   
1825   // build base shape
1826   //-----------------------------
1827   
1828   // middle plate
1829   const GeoShape* sMiddleRailSuppPlateStd = new GeoBox( xWidth/2, thicknessMidPlate/2, zWidthMidPlate/2 );
1830   
1831   // top plate
1832   GeoBox* sTopRailSuppPlate               = new GeoBox( xWidth/2, thicknessTopPlate/2 - tolerance, zWidthTopPlate/2 );
1833 
1834 // two bottom plate
1835   GeoBox* sBotRailSuppPlate               = new GeoBox( xWidth/2, thicknessBotPlate/2 - tolerance, 
1836                                                         zWidthBotPlate/2 );
1837   GeoBox* sBotBotRailSuppPlate            = new GeoBox( xWidth/2, thicknessBotBot/2 - tolerance, 
1838                                                         zLengthBotBot/2 - tolerance );
1839   
1840   // two central plates
1841   GeoBox* sTopBotCentrRailSuppPlate       = new GeoBox( xCentrWidth/2, yHeightCentrTB/2 - tolerance, zWidthMidPlate/2 - tolerance );
1842   
1843   // two Vertical plates
1844   GeoBox* sVertRailSuppPlate             = new GeoBox( xWidth/2, yHeightVertPlate/2 - tolerance, thicknessVerPlate/2 - tolerance );
1845 
1846     // position of shapes' centres relative to centre of middle plate
1847     
1848     //top plate
1849     HepTransform3D trlTopRailSuppPlate  = HepTranslate3D( 0, yHeightCentrTB + thicknessMidPlate/2 + thicknessTopPlate/2, 0 );
1850     
1851     //two bottom plates
1852     HepTransform3D trlBotRailSuppPlate  = HepTranslate3D( 0, -yHeightCentrTB - thicknessMidPlate/2 - thicknessBotPlate/2, 0 );
1853     HepTransform3D trlBotBotRailPlate   = HepTranslate3D( 0, -yHeightCentrTB - thicknessMidPlate/2 - thicknessBotPlate - 
1854                                                         thicknessBotBot/2, 0 );
1855                                                         
1856     // two vertical plates
1857     HepTransform3D trlVert1RailPlate    = HepTranslate3D( 0, 0, zWidthMidPlate/2 + thicknessVerPlate/2 );
1858     HepTransform3D trlVert2RailPlate    = HepTranslate3D( 0, 0, -zWidthMidPlate/2 - thicknessVerPlate/2 );
1859     
1860     // two central plates
1861     HepTransform3D trlTopCentrRailPlate = HepTranslate3D( 0, yHeightCentrTB/2 + thicknessMidPlate/2, 0 );
1862     HepTransform3D trlBotCentrRailPlate = HepTranslate3D( 0, -yHeightCentrTB/2 - thicknessMidPlate/2, 0 );
1863     
1864 
1865   //------------------------------------------------------------------------------------------
1866   //  Build Standard Feet Rail Support
1867   //------------------------------------------------------------------------------------------
1868    
1869   
1870   //add shapes' to middle plate
1871 
1872 const GeoShape& sRailSuppStd = sMiddleRailSuppPlateStd->add( (*sTopRailSuppPlate) << trlTopRailSuppPlate ).
1873                                                         add( (*sBotRailSuppPlate) << trlBotRailSuppPlate ).
1874                                                         add( (*sBotBotRailSuppPlate) << trlBotBotRailPlate ).
1875                                                         add( (*sTopBotCentrRailSuppPlate) << trlTopCentrRailPlate ).
1876                                                         add( (*sTopBotCentrRailSuppPlate) << trlBotCentrRailPlate ).
1877                                                         add( (*sVertRailSuppPlate) << trlVert1RailPlate ).
1878                                                         add( (*sVertRailSuppPlate) << trlVert2RailPlate );
1879 
1880 
1881   
1882   GeoLogVol*  lRailSuppStd = new GeoLogVol( "StdFeetRailSupport", 
1883                                             &sRailSuppStd, 
1884                                             theMaterialManager->getMaterial(feetMaterial) );
1885   GeoPhysVol* pRailSuppStd = new GeoPhysVol(lRailSuppStd);
1886 
1887 
1888   //------------------------------------------------------------------------------------------
1889   // replicate and position
1890   //------------------------------------------------------------------------------------------
1891   // array of z-positions of rail support centres
1892   double zPosStd[nZPosMax];
1893   for ( int i = 1; i < nFeet - 1; i++ )   zPosStd[ i - 1 ] = zPositionFeet[i];    
1894 
1895   // array of x positions
1896   double xPos[nXPosMax] = { -xMean, xMean };
1897   
1898   // fill auxiliary arrays 
1899   for ( int i = 0; i < nZPosMax * nXPosMax; i++ )  
1900   {
1901      int ii = i % nZPosMax, 
1902          jj = i / nZPosMax;
1903      zPosAux1[i] = zPosStd[ii];
1904      xPosAux[i]  = xPos[jj];
1905   }
1906 
1907   GENFUNCTION fTrlZStd = ArrayFunction( zPosAux1, zPosAux1 + nZPosMax * nXPosMax ); 
1908   GENFUNCTION fTrlXStd = ArrayFunction( xPosAux,  xPosAux  + nZPosMax * nXPosMax ); 
1909   
1910   TRANSFUNCTION XFRailSuppStd = Pow( HepTranslateZ3D(1.0), fTrlZStd ) * 
1911                                 Pow( HepTranslateX3D(1.0), fTrlXStd ) * 
1912                                 HepTranslateY3D(yMeanStd);               // const. displacement along y
1913 
1914   GeoSerialTransformer* sxRailSuppStd = new GeoSerialTransformer( pRailSuppStd, &XFRailSuppStd, nZPosMax * nXPosMax );
1915   container->add(sxRailSuppStd);
1916 
1917   // std::cout<<" FeetToroidBuilderRDB::buildFeetRailSupports  sxRailSuppStd  "<<std::endl;
1918 
1919 
1920   //------------------------------------------------------------------------------------------
1921   //  Build Extremity Feet Rail Supports Minus
1922   //------------------------------------------------------------------------------------------
1923    
1924   
1925   // build base shape
1926   //-----------------------------
1927   
1928   // middle plate
1929   const GeoShape* sCentralMinusRailSuppPlateExtr = new GeoBox( xCentrWidthExtr/2, yHeightCentrPlateExtr/2, zLengthCentrPlateExtr/2 );
1930   
1931   // top plate
1932   GeoBox* sTopRailSuppPlateExtr           = new GeoBox( xWidth/2, thicknessTopPlate/2 - tolerance, zWidthTopPlateExtr/2 );
1933 
1934 // two bottom plate
1935   GeoBox* sBotRailSuppPlateExtr          = new GeoBox( xWidth/2, thicknessBotPlateExtr/2 - tolerance,
1936                                                        zWidthBotPlateExtr/2 );
1937   GeoBox* sBotBotRailSuppPlateExtr       = new GeoBox( xWidth/2, thicknessBotBotExtr/2 - tolerance, 
1938                                                        zLengthBotBotExtr/2 );
1939   
1940   // cutout in bottom plates
1941   GeoBox* sBotBoxCutRailSuppPlateExtr     = new GeoBox( radiusBotCutOutExtr/2 +