CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/Geometry/HcalAlgo/src/DDHCalEndcapAlgo.cc

Go to the documentation of this file.
00001 
00002 // File: DDHCalEndcapAlgo.cc
00003 //   adapted from CCal(G4)HcalEndcap.cc
00004 // Description: Geometry factory class for Hcal Endcap
00006 
00007 #include <cmath>
00008 #include <algorithm>
00009 
00010 namespace std{} using namespace std;
00011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00012 #include "DetectorDescription/Base/interface/DDutils.h"
00013 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
00014 #include "DetectorDescription/Core/interface/DDSolid.h"
00015 #include "DetectorDescription/Core/interface/DDMaterial.h"
00016 #include "DetectorDescription/Core/interface/DDCurrentNamespace.h"
00017 #include "DetectorDescription/Core/interface/DDSplit.h"
00018 #include "Geometry/HcalAlgo/interface/DDHCalEndcapAlgo.h"
00019 #include "CLHEP/Units/GlobalPhysicalConstants.h"
00020 #include "CLHEP/Units/GlobalSystemOfUnits.h"
00021 
00022 DDHCalEndcapAlgo::DDHCalEndcapAlgo():
00023   modMat(0),modType(0),sectionModule(0),layerN(0),layerN0(0),layerN1(0),
00024   layerN2(0),layerN3(0),layerN4(0),layerN5(0),thick(0),trimLeft(0),
00025   trimRight(0),zminBlock(0),zmaxBlock(0),rinBlock1(0),routBlock1(0),
00026   rinBlock2(0),routBlock2(0),layerType(0),layerT(0),scintT(0) {
00027   LogDebug("HCalGeom") << "DDHCalEndcapAlgo info: Creating an instance";
00028 }
00029 
00030 DDHCalEndcapAlgo::~DDHCalEndcapAlgo() {}
00031 
00032 int DDHCalEndcapAlgo::getLayer(unsigned int i, unsigned int j) const {
00033 
00034   switch (i) {
00035   case 0: 
00036     return layerN0[j];
00037     break;
00038 
00039   case 1: 
00040     return layerN1[j];
00041     break;
00042 
00043   case 2: 
00044     return layerN2[j];
00045     break;
00046 
00047   case 3: 
00048     return layerN3[j];
00049     break;
00050 
00051   case 4: 
00052     return layerN4[j];
00053     break;
00054 
00055   case 5: 
00056     return layerN5[j];
00057     break;
00058 
00059   default:
00060     return 0;
00061   }
00062 }
00063 
00064 double DDHCalEndcapAlgo::getTrim(unsigned int i, unsigned int j) const {
00065  
00066  if (j == 0)
00067     return trimLeft[i];
00068   else
00069     return trimRight[j];
00070 }
00071 
00072 void DDHCalEndcapAlgo::initialize(const DDNumericArguments & nArgs,
00073                                   const DDVectorArguments & vArgs,
00074                                   const DDMapArguments & ,
00075                                   const DDStringArguments & sArgs,
00076                                   const DDStringVectorArguments & vsArgs) {
00077 
00078   int i,j;
00079   genMaterial   = sArgs["MaterialName"];
00080   rotation      = sArgs["Rotation"];
00081   nsectors      = int (nArgs["Sector"]);
00082   nsectortot    = int (nArgs["SectorTot"]);
00083   nEndcap       = int (nArgs["Endcap"]);
00084   rotHalf       = sArgs["RotHalf"];
00085   rotns         = sArgs["RotNameSpace"];
00086   zShift        = nArgs["ZShift"];
00087 
00088   zFront        = nArgs["ZFront"];
00089   zEnd          = nArgs["ZEnd"];
00090   ziNose        = nArgs["ZiNose"];
00091   ziL0Nose      = nArgs["ZiL0Nose"];
00092   ziBody        = nArgs["ZiBody"];
00093   ziL0Body      = nArgs["ZiL0Body"];
00094   z0Beam        = nArgs["Z0Beam"];
00095   ziDip         = nArgs["ZiDip"];
00096   dzStep        = nArgs["DzStep"];
00097   zShiftHac2    = nArgs["ZShiftHac2"];
00098   double gap    = nArgs["Gap"];
00099   double z1     = nArgs["Z1"];
00100   double r1     = nArgs["R1"];
00101   rout          = nArgs["Rout"];
00102   heboxDepth    = nArgs["HEboxDepth"];
00103   drEnd         = nArgs["DrEnd"];
00104   double etamin = nArgs["Etamin"];
00105   angBot        = nArgs["AngBot"];
00106   angGap        = nArgs["AngGap"];
00107 
00108   LogDebug("HCalGeom") << "DDHCalEndcapAlgo debug: General material " 
00109                        << genMaterial << "\tSectors "  << nsectors << ",  " 
00110                        << nsectortot << "\tEndcaps " << nEndcap  
00111                        << "\tRotation matrix for half " << rotns 
00112                        << ":" << rotHalf << "\n\tzFront " << zFront << " zEnd "
00113                        << zEnd << " ziNose " << ziNose << " ziL0Nose " 
00114                        << ziL0Nose << " ziBody " << ziBody  << " ziL0Body " 
00115                        << ziL0Body << " z0Beam " << z0Beam << " ziDip " 
00116                        << ziDip << " dzStep " << dzStep << " Gap " << gap 
00117                        << " z1 " << z1 << "\n\tr1 " << r1 << " rout " << rout
00118                        << " HeboxDepth " << heboxDepth << " drEnd " << drEnd 
00119                        << "\tetamin " << etamin << " Bottom angle " << angBot
00120                        << " Gap angle " << angGap << " Z-Shift " << zShift
00121                        << " " << zShiftHac2;
00122 
00123   //Derived quantities
00124   angTop   = 2.0 * atan (exp(-etamin));
00125   slope    = tan(angGap);
00126   z1Beam   = z1 - r1/slope;
00127   ziKink   = z1Beam + rout/slope;
00128   riKink   = ziKink*tan(angBot);
00129   riDip    = ziDip*tan(angBot);
00130   roDip    = rout - heboxDepth;
00131   dzShift  = (z1Beam - z0Beam) - gap/sin(angGap);
00132   LogDebug("HCalGeom") << "DDHCalEndcapAlgo debug: angTop " 
00133                        << angTop/CLHEP::deg  <<"\tSlope " << slope 
00134                        << "\tDzShift " << dzShift << "\n\tz1Beam " << z1Beam 
00135                        << "\tziKink" << ziKink << "\triKink " << riKink 
00136                        << "\triDip " << riDip << "\n\troDip " << roDip 
00137                        << "\tRotation " << rotation;
00138 
00140   //Modules
00141   absMat        = sArgs["AbsMat"];
00142   modules       = int(nArgs["Modules"]);
00143   LogDebug("HCalGeom") << "DDHCalEndcapAlgo debug: Number of modules " 
00144                        << modules << " and absorber material " << absMat;
00145 
00146   modName       = vsArgs["ModuleName"];
00147   modMat        = vsArgs["ModuleMat"];
00148   modType       = dbl_to_int(vArgs["ModuleType"]);
00149   sectionModule = dbl_to_int(vArgs["SectionModule"]);
00150   thick         = vArgs["ModuleThick"];
00151   trimLeft      = vArgs["TrimLeft"]; 
00152   trimRight     = vArgs["TrimRight"]; 
00153   eModule       = dbl_to_int(vArgs["EquipModule"]);
00154   layerN        = dbl_to_int(vArgs["LayerN"]);
00155   layerN0       = dbl_to_int(vArgs["LayerN0"]);
00156   layerN1       = dbl_to_int(vArgs["LayerN1"]);
00157   layerN2       = dbl_to_int(vArgs["LayerN2"]);
00158   layerN3       = dbl_to_int(vArgs["LayerN3"]);
00159   layerN4       = dbl_to_int(vArgs["LayerN4"]);
00160   layerN5       = dbl_to_int(vArgs["LayerN5"]);
00161   for (i = 0; i < modules; i++) {
00162     LogDebug("HCalGeom") << "DDHCalEndcapAlgo debug: " << modName[i] <<" type "
00163                          << modType[i] << " Sections " << sectionModule[i] 
00164                          << " thickness of absorber/air " << thick[i] 
00165                          << " trim " << trimLeft[i] << ", " << trimRight[i] 
00166                          << " equip module " << eModule[i] << " with "
00167                          << layerN[i] << " layers";
00168     if (i == 0) {
00169       for (j = 0; j < layerN[i]; j++) {
00170         LogDebug("HCalGeom") << "\t " << layerN0[j] << "/" << layerN0[j+1];
00171       }
00172     } else if (i == 1) {
00173       for (j = 0; j < layerN[i]; j++) {
00174         LogDebug("HCalGeom") << "\t " << layerN1[j] << "/" << layerN1[j+1];
00175       }
00176     } else if (i == 2) {
00177       for (j = 0; j < layerN[i]; j++) {
00178         LogDebug("HCalGeom") << "\t " << layerN2[j];
00179       }
00180     } else if (i == 3) {
00181       for (j = 0; j < layerN[i]; j++) {
00182         LogDebug("HCalGeom") << "\t " << layerN3[j];
00183       }
00184     } else if (i == 4) {
00185       for (j = 0; j < layerN[i]; j++) {
00186         LogDebug("HCalGeom") << "\t " << layerN4[j];
00187       }
00188     } else if (i == 5) {
00189       for (j = 0; j < layerN[i]; j++) {
00190         LogDebug("HCalGeom") << "\t " << layerN5[j];
00191       }
00192     }
00193   }
00194   
00196   //Layers
00197   phiSections = int(nArgs["PhiSections"]);
00198   phiName     = vsArgs["PhiName"];
00199   layers      = int(nArgs["Layers"]);
00200   layerName   = vsArgs["LayerName"];
00201   layerType   = dbl_to_int(vArgs["LayerType"]);
00202   layerT      = vArgs["LayerT"];
00203   scintT      = vArgs["ScintT"];
00204   scintMat    = sArgs["ScintMat"];
00205   plastMat    = sArgs["PlastMat"];
00206   rotmat      = sArgs["RotMat"];
00207   LogDebug("HCalGeom") << "DDHCalEndcapAlgo debug: Phi Sections " 
00208                        << phiSections;
00209   for (i = 0; i < phiSections; i++) 
00210     LogDebug("HCalGeom") << "\tName[" << i << "] : " << phiName[i];
00211   LogDebug("HCalGeom") << "\tPlastic: " << plastMat << "\tScintillator: "
00212                        << scintMat << "\tRotation matrix " << rotns << ":" 
00213                        << rotmat << "\n\tNumber of layers " << layers;
00214   for (i = 0; i < layers; i++) {
00215     LogDebug("HCalGeom") << "\t" << layerName[i] << "\tType " << layerType[i]
00216                          << "\tThickness " << layerT[i] << "\tScint.Thick " 
00217                          << scintT[i];
00218   }
00219 
00221   // Derive bounding of the modules
00222   int module = 0;
00223   // Layer 0 (Nose)
00224   if (modules > 0) {
00225     zminBlock.push_back(ziL0Nose);
00226     zmaxBlock.push_back(zminBlock[module] + layerT[0] + 0.5*dzStep);
00227     rinBlock1.push_back(zminBlock[module] * tan(angTop));
00228     rinBlock2.push_back(zmaxBlock[module] * tan(angTop));
00229     routBlock1.push_back((zminBlock[module] - z1Beam) * slope);
00230     routBlock2.push_back((zmaxBlock[module] - z1Beam) * slope);
00231     module++;
00232   }
00233 
00234   // Layer 0 (Body)
00235   if (modules > 1) {
00236     zminBlock.push_back(ziL0Body);
00237     zmaxBlock.push_back(zminBlock[module] + layerT[0] + 0.5*dzStep);
00238     rinBlock1.push_back(zminBlock[module] * tan(angBot));
00239     rinBlock2.push_back(zmaxBlock[module] * tan(angBot));
00240     routBlock1.push_back(zminBlock[module] * tan(angTop));
00241     routBlock2.push_back(zmaxBlock[module] * tan(angTop));
00242     module++;
00243   }
00244 
00245   // Hac1
00246   if (modules > 2) {
00247     zminBlock.push_back(ziNose);
00248     zmaxBlock.push_back(ziBody);
00249     rinBlock1.push_back(zminBlock[module] * tan(angTop));
00250     rinBlock2.push_back(zmaxBlock[module] * tan(angTop));
00251     routBlock1.push_back((zminBlock[module] - z1Beam) * slope);
00252     routBlock2.push_back((zmaxBlock[module] - z1Beam) * slope);
00253     module++;
00254   }
00255 
00256   // Hac2
00257   if (modules > 3) {
00258     zminBlock.push_back(ziBody);
00259     zmaxBlock.push_back(zminBlock[module] + layerN[3]*dzStep);
00260     rinBlock1.push_back(zminBlock[module] * tan(angBot));
00261     rinBlock2.push_back(zmaxBlock[module] * tan(angBot));
00262     routBlock1.push_back((zmaxBlock[module-1] - z1Beam) * slope);
00263     routBlock2.push_back(rout);
00264     module++;
00265   }
00266 
00267   // Hac3
00268   if (modules > 4) {
00269     zminBlock.push_back(zmaxBlock[module-1]);
00270     zmaxBlock.push_back(zminBlock[module] + layerN[4]*dzStep);
00271     rinBlock1.push_back(zminBlock[module] * tan(angBot));
00272     rinBlock2.push_back(zmaxBlock[module] * tan(angBot));
00273     routBlock1.push_back(rout);
00274     routBlock2.push_back(rout);
00275     module++;
00276   }
00277 
00278   // Hac4
00279   if (modules > 5) {
00280     zminBlock.push_back(zmaxBlock[module-1]);
00281     zmaxBlock.push_back(zminBlock[module] + layerN[5]*dzStep);
00282     rinBlock1.push_back(zminBlock[module] * tan(angBot));
00283     rinBlock2.push_back(zmaxBlock[module] * tan(angBot));
00284     routBlock1.push_back(rout);
00285     routBlock2.push_back(roDip);
00286     module++;
00287   }
00288 
00289   for (i = 0; i < module; i++)
00290     LogDebug("HCalGeom") << "DDHCalEndcapAlgo debug: Module " << i 
00291                          << "\tZ/Rin/Rout " << zminBlock[i] << ", " 
00292                          << zmaxBlock[i] << "/ " << rinBlock1[i] << ", " 
00293                          << rinBlock2[i] << "/ " << routBlock1[i] << ", " 
00294                          << routBlock2[i];
00295 
00296   idName      = sArgs["MotherName"];
00297   idNameSpace = DDCurrentNamespace::ns();
00298   idOffset = int (nArgs["IdOffset"]); 
00299   DDName parentName = parent().name(); 
00300   LogDebug("HCalGeom") << "DDHCalEndcapAlgo debug: Parent " << parentName 
00301                        << " idName " << idName << " NameSpace " << idNameSpace
00302                        << " Offset " << idOffset;
00303 
00304   tolPos      = nArgs["TolPos"];
00305   tolAbs      = nArgs["TolAbs"];
00306   LogDebug("HCalGeom") << "DDHCalEndcapAlgo debug: Tolerances - Positioning "
00307                        << tolPos << " Absorber " << tolAbs;
00308 }
00309 
00311 // DDHCalEndcapAlgo methods...
00313 
00314 void DDHCalEndcapAlgo::execute(DDCompactView& cpv) {
00315   
00316   LogDebug("HCalGeom") << "==>> Constructing DDHCalEndcapAlgo...";
00317   constructGeneralVolume(cpv);
00318   LogDebug("HCalGeom") << "<<== End of DDHCalEndcapAlgo construction ...";
00319 }
00320 
00321 //----------------------start here for DDD work!!! ---------------
00322 
00323 void DDHCalEndcapAlgo::constructGeneralVolume(DDCompactView& cpv) {
00324   
00325   LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: General volume...";
00326   bool proto = true;
00327   for (int i=0; i<3; i++) 
00328     if (equipModule(i) > 0) proto = false;
00329 
00330   DDRotation    rot;
00331   if (DDSplit(getRotation()).first == "NULL") rot = DDRotation();
00332   else rot = DDRotation(DDName(DDSplit(getRotation()).first,DDSplit(getRotation()).second));
00333   LogDebug("HCalGeom") << " First " << DDSplit(getRotation()).first
00334                        << " Second " << DDSplit(getRotation()).second 
00335                        << " Rotation " << rot;
00336   DDTranslation r0(0,0,getZShift());
00337   double alpha = CLHEP::pi/getNsectors();
00338   double dphi  = getNsectortot()*CLHEP::twopi/getNsectors();
00339 
00341   //vertical walls are allowed in SolidPolyhedra
00342   double delz = 0;
00343 
00344   vector<double> pgonZ, pgonRmin, pgonRmax;
00345   if (proto) {
00346     double zf = getZiBody() + getZShiftHac2();
00347     pgonZ.push_back(zf - getDzShift()); 
00348     pgonRmin.push_back(zf * tan(getAngBot())); 
00349     pgonRmax.push_back((zf - getZ1Beam())*getSlope()); 
00350   } else {
00351     pgonZ.push_back(getZFront()   - getDzShift()); 
00352     pgonRmin.push_back(getZFront()   * tan(getAngTop())); 
00353     pgonRmax.push_back((getZFront()   - getZ1Beam())*getSlope()); 
00354     pgonZ.push_back(getZiL0Body() - getDzShift()); 
00355     pgonRmin.push_back(getZiL0Body() * tan(getAngTop())); 
00356     pgonRmax.push_back((getZiL0Body() - getZ1Beam())*getSlope()); 
00357     pgonZ.push_back(getZiL0Body() - getDzShift()); 
00358     pgonRmin.push_back(getZiL0Body() * tan(getAngBot())); 
00359     pgonRmax.push_back((getZiL0Body() - getZ1Beam())*getSlope()); 
00360   }
00361   pgonZ.push_back(getZiKink()   - getDzShift()); 
00362   pgonRmin.push_back(getRinKink()); 
00363   pgonRmax.push_back(getRout()); 
00364   pgonZ.push_back(getZiDip()    - getDzShift()); 
00365   pgonRmin.push_back(getRinDip()); 
00366   pgonRmax.push_back(getRout()); 
00367   pgonZ.push_back(getZiDip()    - getDzShift() + delz); 
00368   pgonRmin.push_back(getRinDip()); 
00369   pgonRmax.push_back(getRoutDip()); 
00370   pgonZ.push_back(getZEnd()     - getDzShift()); 
00371   pgonRmin.push_back(getZEnd() * tan(getAngBot())); 
00372   pgonRmax.push_back(getRoutDip()); 
00373   pgonZ.push_back(getZEnd()); 
00374   pgonRmin.push_back(getZEnd() * tan(getAngBot())); 
00375   pgonRmax.push_back(getRoutDip()); 
00376 
00377   string name("Null");
00378   unsigned int i=0;
00379   DDSolid solid;
00380   solid = DDSolidFactory::polyhedra(DDName(idName, idNameSpace),
00381                                     getNsectortot(), -alpha, dphi, pgonZ, 
00382                                     pgonRmin, pgonRmax);
00383   LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " 
00384                        << DDName(idName, idNameSpace) << " Polyhedra made of "
00385                        << getGenMat() << " with " << getNsectortot() 
00386                        << " sectors from " << -alpha/CLHEP::deg << " to " 
00387                        << (-alpha+dphi)/CLHEP::deg << " and with " 
00388                        << pgonZ.size() << " sections";
00389   for (i = 0; i <pgonZ.size(); i++) 
00390     LogDebug("HCalGeom") << "\t\tZ = " << pgonZ[i] << "\tRmin = " <<pgonRmin[i]
00391                          << "\tRmax = " << pgonRmax[i];
00392 
00393   DDName matname(DDSplit(getGenMat()).first, DDSplit(getGenMat()).second); 
00394   DDMaterial matter(matname);
00395   DDLogicalPart genlogic(DDName(idName, idNameSpace), matter, solid);
00396 
00397   DDName parentName = parent().name(); 
00398   cpv.position(DDName(idName, idNameSpace), parentName, 1, r0, rot);
00399   LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " 
00400                        << DDName(idName, idNameSpace) << " number 1 positioned"
00401                        << " in " << parentName << " at " << r0 << " with " 
00402                        << rot;
00403   if (getEndcaps() != 1) {
00404     rot = DDRotation(DDName(rotHalf,rotns));
00405    cpv.position(DDName(idName, idNameSpace), parentName, 2, r0, rot);
00406     LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " 
00407                          << DDName(idName, idNameSpace) << " number 2 "
00408                          << "positioned in " << parentName  << " at " << r0
00409                          << " with " << rot;
00410   }
00411 
00412   //Forward half
00413   name  = idName + "Front";
00414   vector<double> pgonZMod, pgonRminMod, pgonRmaxMod;
00415   for (i=0; i < (pgonZ.size()-1); i++) {
00416     pgonZMod.push_back(pgonZ[i] + getDzShift()); 
00417     pgonRminMod.push_back(pgonRmin[i]); 
00418     pgonRmaxMod.push_back(pgonRmax[i]); 
00419   }
00420   solid = DDSolidFactory::polyhedra(DDName(name, idNameSpace),
00421                                     getNsectortot(), -alpha, dphi, pgonZMod,
00422                                     pgonRminMod, pgonRmaxMod);
00423   LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " << DDName(name,idNameSpace)
00424                        << " Polyhedra made of " << getGenMat() << " with "
00425                        << getNsectortot() << " sectors from " 
00426                        << -alpha/CLHEP::deg << " to " 
00427                        << (-alpha+dphi)/CLHEP::deg << " and with "
00428                        << pgonZMod.size() << " sections ";
00429   for (i = 0; i < pgonZMod.size(); i++) 
00430     LogDebug("HCalGeom") << "\t\tZ = " << pgonZMod[i] << "\tRmin = " 
00431                          << pgonRminMod[i] << "\tRmax = " << pgonRmaxMod[i];
00432   DDLogicalPart genlogich(DDName(name, idNameSpace), matter, solid);
00433 
00434   cpv.position(genlogich, genlogic, 1, DDTranslation(0.0, 0.0, -getDzShift()),
00435         DDRotation());
00436   LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " << genlogich.name() 
00437                        << " number 1 positioned in " << genlogic.name() 
00438                        << " at (0,0," << -getDzShift() << ") with no rotation";
00439   
00440   //Construct sector (from -alpha to +alpha)
00441   name  = idName + "Module";
00442   solid =   DDSolidFactory::polyhedra(DDName(name, idNameSpace),
00443                                       1, -alpha, 2*alpha, pgonZMod,
00444                                       pgonRminMod, pgonRmaxMod);
00445   LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " << DDName(name,idNameSpace)
00446                        << " Polyhedra made of " << getGenMat() 
00447                        <<" with 1 sector from " << -alpha/CLHEP::deg << " to " 
00448                        << alpha/CLHEP::deg << " and with " << pgonZMod.size() 
00449                        << " sections";
00450   for (i = 0; i < pgonZMod.size(); i++) 
00451     LogDebug("HCalGeom") << "\t\tZ = " << pgonZMod[i] << "\tRmin = " 
00452                          << pgonRminMod[i] << "\tRmax = " << pgonRmaxMod[i];
00453 
00454   DDLogicalPart seclogic(DDName(name, idNameSpace), matter, solid);
00455   
00456   for (int ii=0; ii<getNsectortot(); ii++) {
00457     double phi    = ii*2*alpha;
00458     double phideg = phi/CLHEP::deg;
00459     
00460     DDRotation rotation;
00461     string rotstr("NULL");
00462     if (phideg != 0) {
00463       rotstr = "R"; 
00464       if (phideg < 100) rotstr = "R0"; 
00465       rotstr = rotstr + dbl_to_string(phideg);
00466       rotation = DDRotation(DDName(rotstr, rotns)); 
00467       if (!rotation) {
00468         LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: Creating a new "
00469                              << "rotation " << rotstr << "\t" << 90 << "," 
00470                              << phideg << ","  << 90 << "," << (phideg+90)
00471                              << ", 0, 0";
00472         rotation = DDrot(DDName(rotstr, rotns), 90*CLHEP::deg, 
00473                          phideg*CLHEP::deg, 90*CLHEP::deg, 
00474                          (90+phideg)*CLHEP::deg, 0*CLHEP::deg,  0*CLHEP::deg);
00475       } //if !rotation
00476     } //if phideg!=0
00477   
00478    cpv.position(seclogic, genlogich, ii+1, DDTranslation(0.0, 0.0, 0.0), rotation);
00479     LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " << seclogic.name() 
00480                          << " number " << ii+1 << " positioned in " 
00481                          << genlogich.name() << " at (0,0,0) with " <<rotation;
00482   }
00483   
00484   //Construct the things inside the sector
00485   constructInsideSector(seclogic, cpv);
00486 
00487   //Backward half
00488   name  = idName + "Back";
00489   vector<double> pgonZBack, pgonRminBack, pgonRmaxBack;
00490   pgonZBack.push_back(getZEnd() - getDzShift()); 
00491   pgonRminBack.push_back(pgonZBack[0]*tan(getAngBot()) + getDrEnd()); 
00492   pgonRmaxBack.push_back(getRoutDip()); 
00493   pgonZBack.push_back(getZEnd()); 
00494   pgonRminBack.push_back(pgonZBack[1]*tan(getAngBot()) + getDrEnd()); 
00495   pgonRmaxBack.push_back(getRoutDip()); 
00496   solid = DDSolidFactory::polyhedra(DDName(name, idNameSpace),
00497                                     getNsectortot(), -alpha, dphi, pgonZBack,
00498                                     pgonRminBack, pgonRmaxBack);
00499   LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " << DDName(name,idNameSpace)
00500                        << " Polyhedra made of " << getAbsMat() << " with " 
00501                        << getNsectortot() << " sectors from " 
00502                        << -alpha/CLHEP::deg << " to " 
00503                        << (-alpha+dphi)/CLHEP::deg << " and with " 
00504                        << pgonZBack.size()      << " sections";
00505   for (i = 0; i < pgonZBack.size(); i++) 
00506     LogDebug("HCalGeom") << "\t\tZ = " << pgonZBack[i] << "\tRmin = " 
00507                          << pgonRminBack[i] << "\tRmax = " << pgonRmaxBack[i];
00508   DDName absMatname(DDSplit(getAbsMat()).first, DDSplit(getAbsMat()).second); 
00509   DDMaterial absMatter(absMatname);
00510   DDLogicalPart glog(DDName(name, idNameSpace), absMatter, solid);
00511 
00512   cpv.position(glog, genlogic, 1, DDTranslation(0.0, 0.0, 0.0), DDRotation());
00513   LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " << glog.name() 
00514                        << " number 1 positioned in "  << genlogic.name() 
00515                        << " at (0,0,0) with no rotation";
00516 }
00517 
00518 
00519 void DDHCalEndcapAlgo::constructInsideSector(DDLogicalPart sector, DDCompactView& cpv) {
00520   
00521   LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: Modules (" << getModules()
00522                        << ") ...";
00523   double alpha = CLHEP::pi/getNsectors();
00524 
00525   for (int i = 0; i < getModules(); i++) {
00526     string  name   = idName + getModName(i);
00527     DDName matname(DDSplit(getModMat(i)).first, DDSplit(getModMat(i)).second); 
00528     DDMaterial matter(matname);
00529     
00530     if (equipModule(i)>0) {
00531       int nsec = getSectionModule(i);
00532 
00534       //vertical walls are allowed in SolidPolyhedra
00535       double deltaz = 0;
00536     
00537       vector<double> pgonZ, pgonRmin, pgonRmax;
00538       if (nsec == 3) {
00539         double zf = getZminBlock(i) + getZShiftHac2();
00540         pgonZ.push_back(zf);
00541         pgonRmin.push_back(zf*tan(getAngBot())); 
00542         pgonRmax.push_back((zf-getZ1Beam())*getSlope());
00543         pgonZ.push_back(getZiKink());  
00544         pgonRmin.push_back(getRinKink()); 
00545         pgonRmax.push_back(getRout());
00546       } else {
00547         pgonZ.push_back(getZminBlock(i));
00548         pgonRmin.push_back(getRinBlock1(i)); 
00549         pgonRmax.push_back(getRoutBlock1(i));
00550       }
00551       if (nsec == 4) {
00552         pgonZ.push_back(getZiDip());
00553         pgonRmin.push_back(getRinDip());
00554         pgonRmax.push_back(getRout());
00555         pgonZ.push_back(pgonZ[1] + deltaz);
00556         pgonRmin.push_back(pgonRmin[1]); 
00557         pgonRmax.push_back(getRoutDip());
00558       }
00559       pgonZ.push_back(getZmaxBlock(i));
00560       pgonRmin.push_back(getRinBlock2(i)); 
00561       pgonRmax.push_back(getRoutBlock2(i));
00562 
00563       //Solid & volume
00564       DDSolid solid;
00565       solid = DDSolidFactory::polyhedra(DDName(name, idNameSpace), 
00566                                         1, -alpha, 2*alpha,
00567                                         pgonZ, pgonRmin, pgonRmax);
00568       LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " 
00569                            << DDName(name,idNameSpace) << " Polyhedra made of "
00570                            << getModMat(i) << " with 1 sector from "
00571                            << -alpha/CLHEP::deg << " to " << alpha/CLHEP::deg 
00572                            << " and with " << nsec << " sections";
00573       for (unsigned int k=0; k<pgonZ.size(); k++)
00574         LogDebug("HCalGeom") << "\t\tZ = " << pgonZ[k] << "\tRmin = "
00575                              << pgonRmin[k] << "\tRmax = " << pgonRmax[k];
00576     
00577       DDLogicalPart glog(DDName(name, idNameSpace), matter, solid);
00578 
00579      cpv.position(glog, sector, i+1, DDTranslation(0.0, 0.0, 0.0), DDRotation());
00580       LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " << glog.name() 
00581                            << " number " << i+1 << " positioned in " 
00582                            << sector.name() << " at (0,0,0) with no rotation";
00583       
00584       if (getModType(i) == 0) 
00585         constructInsideModule0 (glog, i, cpv);
00586       else
00587         constructInsideModule  (glog, i, cpv);
00588     }
00589   }
00590   
00591 }
00592 
00593 void DDHCalEndcapAlgo::parameterLayer0(int mod, int layer, int iphi, 
00594                                        double& yh, double& bl, double& tl, 
00595                                        double& alp, double& xpos, double& ypos,
00596                                        double& zpos) {
00597 
00598   //Given module and layer number compute parameters of trapezoid
00599   //and positioning parameters
00600   double alpha = CLHEP::pi/getNsectors();
00601   LogDebug("HCalGeom") << "Input " << iphi << " " << layer << " " << iphi
00602                        << " Alpha " << alpha/CLHEP::deg;
00603 
00604   double zi, zo;
00605   if (iphi == 0) {
00606     zi = getZminBlock(mod);
00607     zo = zi + getLayerT(layer);
00608   } else {
00609     zo = getZmaxBlock(mod);
00610     zi = zo - getLayerT(layer);
00611   }
00612   double rin, rout;
00613   if (mod == 0) {
00614     rin  = zo * tan(getAngTop());
00615     rout = (zi - getZ1Beam()) * getSlope();
00616   } else {
00617     rin  = zo * tan(getAngBot());
00618     rout = zi * tan(getAngTop());
00619   }
00620   yh   = 0.5 * (rout - rin);
00621   bl   = 0.5 * rin * tan (alpha);
00622   tl   = 0.5 * rout * tan(alpha);
00623   xpos = 0.5 * (rin + rout);
00624   ypos = 0.5 * (bl + tl);
00625   zpos = 0.5 * (zi + zo);
00626   yh  -= getTrim(mod,iphi);
00627   bl  -= getTrim(mod,iphi);
00628   tl  -= getTrim(mod,iphi);
00629   alp  = atan(0.5 * tan(alpha));
00630   if (iphi == 0) {
00631     ypos  = -ypos;
00632   } else {
00633     alp  = -alp;
00634   }
00635   LogDebug("HCalGeom") << "Output Dimensions " << yh << " " << bl << " "
00636                        << tl << " " << alp/CLHEP::deg << " Position " << xpos 
00637                        << " " << ypos << " " << zpos;
00638 }
00639 
00640 
00641 void DDHCalEndcapAlgo::parameterLayer(int iphi, double rinF, double routF,
00642                                       double rinB, double routB, double zi,
00643                                       double zo, double& yh1, double& bl1,
00644                                       double& tl1, double& yh2, double& bl2,
00645                                       double& tl2, double& alp, double& theta,
00646                                       double& phi, double& xpos, double& ypos,
00647                                       double& zpos) {
00648 
00649   //Given rin, rout compute parameters of the trapezoid and 
00650   //position of the trapezoid for a standrd layer
00651   double alpha = CLHEP::pi/getNsectors();
00652   LogDebug("HCalGeom") << "Input " << iphi << " Front " << rinF << " " << routF
00653                        << " " << zi << " Back " << rinB << " " << routB << " "
00654                        << zo << " Alpha " << alpha/CLHEP::deg;
00655 
00656   yh1 = 0.5 * (routF - rinB);
00657   bl1 = 0.5 * rinB  * tan(alpha);
00658   tl1 = 0.5 * routF * tan(alpha);
00659   yh2 = 0.5 * (routF - rinB);
00660   bl2 = 0.5 * rinB  * tan(alpha);
00661   tl2 = 0.5 * routF * tan(alpha);
00662   double dx  = 0.25* (bl2+tl2-bl1-tl1);
00663   double dy  = 0.5 * (rinB+routF-rinB-routF);
00664   xpos = 0.25*(rinB+routF+rinB+routF);
00665   ypos = 0.25*(bl2+tl2+bl1+tl1);
00666   zpos = 0.5*(zi+zo);
00667   alp  = atan(0.5 * tan(alpha));
00668   //  ypos-= getTolPos();
00669   if (iphi == 0) {
00670     ypos  = -ypos;
00671   } else {
00672     alp  = -alp;
00673     dx   = -dx;
00674   }
00675   double r   = sqrt (dx*dx + dy*dy);
00676   theta= atan (r/(zo-zi));
00677   phi  = atan2 (dy, dx);
00678   LogDebug("HCalGeom") << "Output Dimensions " << yh1 << " " << bl1 << " "
00679                        << tl1 << " " << yh2 << " " << bl2 << " " << tl2
00680                        << " " << alp/CLHEP::deg << " " << theta/CLHEP::deg
00681                        << " " << phi/CLHEP::deg << " Position " << xpos << " "
00682                        << ypos << " " << zpos;
00683 }
00684 
00685 
00686 void DDHCalEndcapAlgo::constructInsideModule0(DDLogicalPart module, int mod, DDCompactView& cpv) {
00687   
00688   LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: \t\tInside module0 ..."<<mod;
00689 
00691   //Pointers to the Rotation Matrices and to the Materials
00692   string rotstr = getRotMat();
00693   DDRotation rot(DDName(rotstr, rotns));
00694   DDName matName(DDSplit(getAbsMat()).first, DDSplit(getAbsMat()).second);
00695   DDMaterial matabsorbr(matName);
00696   DDName plasName(DDSplit(getPlastMat()).first, DDSplit(getPlastMat()).second);
00697   DDMaterial matplastic(plasName);
00698 
00699   int     layer  = getLayer(mod,0);
00700   int     layer0 = getLayer(mod,1);
00701   string  name;
00702   double  xpos, ypos, zpos;
00703   DDSolid solid;
00704   DDLogicalPart glog, plog;
00705   for (int iphi = 0; iphi < getPhi(); iphi++) {
00706     double yh, bl, tl, alp;
00707     parameterLayer0(mod, layer, iphi, yh, bl, tl, alp, xpos, ypos, zpos);
00708     name = module.name().name()+getLayerName(layer)+getPhiName(iphi);
00709     solid = DDSolidFactory::trap(DDName(name, idNameSpace), 
00710                                  0.5*getLayerT(layer), 0, 0, yh,
00711                                  bl, tl, alp, yh, bl, tl, alp);
00712     LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " << solid.name() 
00713                          << " Trap made of " << getPlastMat() 
00714                          << " of dimensions " << 0.5*getLayerT(layer) 
00715                          << ", 0, 0, " << yh << ", " << bl << ", " << tl 
00716                          << ", " << alp/CLHEP::deg << ", " << yh << ", " << bl 
00717                          << ", " << tl << ", " << alp/CLHEP::deg;
00718     glog = DDLogicalPart(solid.ddname(), matplastic, solid);
00719 
00720     DDTranslation r1(xpos, ypos, zpos);
00721     cpv.position(glog, module, idOffset+layer+1, r1, rot);
00722     LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " << glog.name() 
00723                          << " number " << idOffset+layer+1 << " positioned in "
00724                          << module.name() << " at " << r1 << " with " << rot;
00725     //Now construct the layer of scintillator inside this
00726     int copyNo = layer0*10 + getLayerType(layer);
00727     name = getModName(mod)+getLayerName(layer)+getPhiName(iphi);
00728     constructScintLayer (glog, getScintT(layer), yh, bl, tl, alp, name, copyNo, cpv);
00729   }
00730 
00731   //Now the absorber layer
00732   double zi = getZminBlock(mod) + getLayerT(layer);
00733   double zo = zi + 0.5*getDzStep();
00734   double rinF, routF, rinB, routB;
00735   if (mod == 0) {
00736     rinF  = zi * tan(getAngTop());
00737     routF =(zi - getZ1Beam()) * getSlope();
00738     rinB  = zo * tan(getAngTop());
00739     routB =(zo - getZ1Beam()) * getSlope();
00740   } else {
00741     rinF  = zi * tan(getAngBot());
00742     routF = zi * tan(getAngTop());
00743     rinB  = zo * tan(getAngBot());
00744     routB = zo * tan(getAngTop());
00745   }
00746   LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: Module " << mod << " Front "
00747                        << zi << ", " << rinF << ", " << routF << " Back "
00748                        << zo << ", " << rinB << ", " << routB;
00749   double yh1, bl1, tl1, yh2, bl2, tl2, theta, phi, alp;
00750   parameterLayer(0, rinF, routF, rinB, routB, zi, zo, yh1, bl1, tl1, yh2, bl2, 
00751                  tl2, alp, theta, phi, xpos, ypos, zpos);
00752   double fact = getTolAbs();
00753   LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: Trim " << fact << " Param "
00754                        << yh1 << ", " << bl1 << ", " << tl1 << ", " << yh2
00755                        << ", " << bl2 << ", " << tl2;
00756   bl1 -= fact;
00757   tl1 -= fact;
00758   bl2 -= fact;
00759   tl2 -= fact;
00760 
00761   name = module.name().name()+"Absorber";
00762   solid = DDSolidFactory::trap(DDName(name, idNameSpace), 
00763                                0.5*getThick(mod), theta, phi, yh1,
00764                                bl1, tl1, alp, yh2, bl2, tl2, alp);
00765   LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " << solid.name() 
00766                        << " Trap made of " << getAbsMat() << " of dimensions " 
00767                        << 0.5*getThick(mod) << ", " << theta/CLHEP::deg << ", "
00768                        << phi/CLHEP::deg << ", " << yh1 << ", " << bl1 << ", " 
00769                        << tl1 << ", " << alp/CLHEP::deg << ", " << yh2 << ", "
00770                        << bl2 << ", " << tl2 << ", " << alp/CLHEP::deg;
00771   glog = DDLogicalPart(solid.ddname(), matabsorbr, solid);
00772 
00773   DDTranslation r2(xpos, ypos, zpos);
00774   cpv.position(glog, module, 1, r2, rot);
00775   LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " << glog.name() 
00776                        << " number 1 positioned in " << module.name() << " at "
00777                        << r2 << " with " << rot;
00778 }
00779 
00780 
00781 void DDHCalEndcapAlgo::constructInsideModule(DDLogicalPart module, int mod, DDCompactView& cpv) {
00782   
00783   LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: \t\tInside module ..." <<mod;
00784 
00786   //Pointers to the Rotation Matrices and to the Materials
00787   string rotstr = getRotMat();
00788   DDRotation rot(DDName(rotstr, rotns));
00789   DDName matName(DDSplit(getGenMat()).first, DDSplit(getGenMat()).second);
00790   DDMaterial matter(matName);
00791   DDName plasName(DDSplit(getPlastMat()).first, DDSplit(getPlastMat()).second);
00792   DDMaterial matplastic(plasName);
00793 
00794   double  alpha = CLHEP::pi/getNsectors();
00795   double  zi    = getZminBlock(mod);
00796 
00797   for (int i = 0; i < getLayerN(mod); i++) {
00798     string name;
00799     DDSolid solid;
00800     DDLogicalPart glog, plog;
00801     int     layer  = getLayer(mod,i);
00802     double  zo     = zi + 0.5*getDzStep();
00803 
00804     for (int iphi = 0; iphi < getPhi(); iphi++) {
00805       double  ziAir = zo - getThick(mod);
00806       double  rinF, rinB;
00807       if (layer == 1) {
00808         rinF  = ziAir * tan(getAngTop());
00809         rinB  = zo    * tan(getAngTop());
00810       } else {
00811         rinF  = ziAir * tan(getAngBot());
00812         rinB  = zo    * tan(getAngBot());
00813       }
00814       double routF = (ziAir - getZ1Beam()) * getSlope();
00815       double routB = (zo    - getZ1Beam()) * getSlope();
00816       if (routF > getRoutBlock2(mod)) routF =  getRoutBlock2(mod);
00817       if (routB > getRoutBlock2(mod)) routB =  getRoutBlock2(mod);
00818       LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: Layer " << i << " Phi "
00819                            << iphi << " Front " << ziAir << ", " << rinF
00820                            << ", " << routF << " Back " << zo << ", " << rinB
00821                            << ", " << routB;
00822       double yh1, bl1, tl1, yh2, bl2, tl2, theta, phi, alp;
00823       double xpos, ypos, zpos;
00824       parameterLayer(iphi, rinF, routF, rinB, routB, ziAir, zo, yh1, bl1, tl1, 
00825                      yh2, bl2, tl2, alp, theta, phi, xpos, ypos, zpos);
00826       
00827       name = module.name().name()+getLayerName(layer)+getPhiName(iphi)+"Air";
00828       solid = DDSolidFactory::trap(DDName(name, idNameSpace), 
00829                                    0.5*getThick(mod), theta, phi, yh1,
00830                                    bl1, tl1, alp, yh2, bl2, tl2, alp);
00831       LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " << solid.name() 
00832                            << " Trap made of " << getGenMat() 
00833                            << " of dimensions " << 0.5*getThick(mod) << ", " 
00834                            << theta/CLHEP::deg << ", " << phi/CLHEP::deg
00835                            << ", " << yh1 << ", " << bl1 << ", " << tl1 << ", "
00836                            << alp/CLHEP::deg << ", " << yh2 << ", " << bl2 
00837                            << ", " << tl2 << ", " << alp/CLHEP::deg;
00838       glog = DDLogicalPart(solid.ddname(), matter, solid);
00839 
00840       DDTranslation r1(xpos, ypos, zpos);
00841       cpv.position(glog, module, layer+1, r1, rot);
00842       LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " << glog.name() 
00843                            << " number " << layer+1 << " positioned in " 
00844                            << module.name() << " at " << r1 << " with " << rot;
00845 
00846       //Now the plastic with scintillators
00847       double yh = 0.5 * (routF - rinB) - getTrim(mod,iphi);
00848       double bl = 0.5 * rinB  * tan(alpha) - getTrim(mod,iphi);
00849       double tl = 0.5 * routF * tan(alpha) - getTrim(mod,iphi);
00850       name = module.name().name()+getLayerName(layer)+getPhiName(iphi);
00851       solid = DDSolidFactory::trap(DDName(name, idNameSpace), 
00852                                    0.5*getLayerT(layer), 0, 0, yh,
00853                                    bl, tl, alp, yh, bl, tl, alp);
00854       LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " << solid.name() 
00855                            << " Trap made of " << getPlastMat() 
00856                            << " of dimensions " << 0.5*getLayerT(layer) 
00857                            << ", 0, 0, " << yh << ", " << bl << ", " << tl
00858                            << ", " << alp/CLHEP::deg << ", " << yh << ", " 
00859                            << bl << ", " << tl << ", " << alp/CLHEP::deg;
00860       plog = DDLogicalPart(solid.ddname(), matplastic, solid);
00861 
00862       ypos = 0.5*(routF+rinB) - xpos;
00863       DDTranslation r2(0., ypos, 0.);
00864       cpv.position(plog, glog, idOffset+layer+1, r2, DDRotation());
00865       LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " << plog.name() 
00866                            << " number " << idOffset+layer+1 
00867                            << " positioned in " << glog.name() << " at " << r2
00868                            << " with no rotation";
00869 
00870       //Constructin the scintillators inside
00871       int copyNo = layer*10 + getLayerType(layer);
00872       name = getModName(mod)+getLayerName(layer)+getPhiName(iphi);
00873       constructScintLayer (plog, getScintT(layer), yh,bl,tl, alp,name,copyNo, cpv);
00874       zo += 0.5*getDzStep();
00875     } // End of loop over phi indices
00876     zi = zo - 0.5*getDzStep();
00877   }   // End of loop on layers
00878 }
00879 
00880  
00881 void DDHCalEndcapAlgo::constructScintLayer(DDLogicalPart detector, double dz,
00882                                            double yh, double bl, double tl, 
00883                                            double alp, string nm, int id, DDCompactView& cpv) {
00884 
00885   DDName matname(DDSplit(getScintMat()).first, DDSplit(getScintMat()).second);
00886   DDMaterial matter(matname);
00887   string name = idName+"Scintillator"+nm;
00888 
00889   DDSolid solid = DDSolidFactory::trap(DDName(name, idNameSpace), 0.5*dz, 0, 0,
00890                                        yh, bl, tl, alp, yh, bl, tl, alp);
00891   LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " << DDName(name,idNameSpace)
00892                        << " Trap made of " << getScintMat() <<" of dimensions "
00893                        << 0.5*dz << ", 0, 0, " << yh << ", "  << bl << ", " 
00894                        << tl << ", " << alp/CLHEP::deg << ", " << yh << ", " 
00895                        << bl << ", " << tl << ", " << alp/CLHEP::deg;
00896 
00897   DDLogicalPart glog(solid.ddname(), matter, solid); 
00898 
00899   cpv.position(glog, detector, id, DDTranslation(0,0,0), DDRotation());
00900   LogDebug("HCalGeom") << "DDHCalEndcapAlgo test: " << glog.name() 
00901                        << " number " << id << " positioned in " 
00902                        << detector.name() << " at (0,0,0) with no rotation";
00903 
00904 }