CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/SLHCUpgradeSimulations/Geometry/src/DDPixBarStackLayerAlgo.cc

Go to the documentation of this file.
00001 
00002 // File: DDPixBarStackLayerAlgo.cc
00003 // Description: Make one layer of stacked pixel barrel detector
00005 
00006 #include <cmath>
00007 #include <algorithm>
00008 
00009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010 #include "DetectorDescription/Base/interface/DDutils.h"
00011 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
00012 #include "DetectorDescription/Core/interface/DDSolid.h"
00013 #include "DetectorDescription/Core/interface/DDMaterial.h"
00014 #include "DetectorDescription/Core/interface/DDCurrentNamespace.h"
00015 #include "DetectorDescription/Core/interface/DDSplit.h"
00016 #include "SLHCUpgradeSimulations/Geometry/interface/DDPixBarStackLayerAlgo.h"
00017 #include "CLHEP/Units/PhysicalConstants.h"
00018 #include "CLHEP/Units/SystemOfUnits.h"
00019 
00020 
00022 // Constructor
00023 DDPixBarStackLayerAlgo::DDPixBarStackLayerAlgo() {
00024   LogDebug("PixelGeom") <<"DDPixBarStackLayerAlgo info: Creating an instance";
00025 }
00026 
00028 // Destructor
00029 DDPixBarStackLayerAlgo::~DDPixBarStackLayerAlgo() {}
00030 
00032 // Initialization of algorithm
00033 void DDPixBarStackLayerAlgo::initialize(const DDNumericArguments & nArgs,
00034                                    const DDVectorArguments & vArgs,
00035                                    const DDMapArguments & ,
00036                                    const DDStringArguments & sArgs,
00037                                    const DDStringVectorArguments & vsArgs) {
00038 
00039 
00040 // Retrieve the variables from the XML files
00041   idNameSpace = DDCurrentNamespace::ns();
00042   DDName parentName = parent().name();
00043 
00044   VolumeMaterial    = sArgs["VolumeMaterial"];
00045   number    = int(nArgs["Ladders"]);
00046   layerDz   = nArgs["LayerDz"];
00047   sensorEdge= nArgs["SensorEdge"];
00048   coolDz    = nArgs["CoolDz"];
00049   coolWidth = nArgs["CoolWidth"];
00050   coolSide  = nArgs["CoolSide"];
00051   coolThick = nArgs["CoolThick"];
00052   moduleRadius  = nArgs["ModuleRadius"];
00053   coolMat   = sArgs["CoolMaterial"];
00054   tubeMat   = sArgs["CoolTubeMaterial"];
00055   ladderNameUp  = sArgs["LadderNameUp"];
00056   ladderNameDown  = sArgs["LadderNameDown"];
00057   ladderWidth = nArgs["LadderWidth"];
00058   ladderThick = nArgs["LadderThick"];
00059   module_offset  = nArgs["ModuleOffset"];
00060   layout = int(nArgs["LayoutType"]);
00061   activeWidth = nArgs["ActiveWidth"];
00062 
00063 // Debug messages
00064   //std::cout <<"\nStack sensor with sensorEdge = "<<sensorEdge<<"\tand width = "<<activeWidth<<"\t at R = "<<moduleRadius;
00065   LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo debug: Parent " << parentName 
00066                         << " NameSpace " << idNameSpace << "\n"
00067                         << "\tLadders " << number << "\tGeneral Material " 
00068                         << VolumeMaterial << "\tLength " << layerDz << "\tSensorEdge "
00069                         << sensorEdge << "\tSpecification of Cooling Pieces:\n"
00070                         << "\tLength " << coolDz << " Width " << coolWidth 
00071                         << " Side " << coolSide << " Thickness of Shell " 
00072                         << coolThick << " Radial distance " << moduleRadius 
00073                         << " Materials " << coolMat << ", " << tubeMat;
00074 
00075   LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo debug: Ladder " 
00076                         << ladderNameUp << " width/thickness " << ladderWidth
00077                         << ", " << ladderThick;
00078 }
00079 
00080 
00082 // The algorithm itself
00083 void DDPixBarStackLayerAlgo::execute(DDCompactView& cpv) {
00084   if ((number%2==1)&&(layout==1)) { 
00085         number+=1;
00086         std::cout << "\nAsking for an invalid layout ... Adjusting the number of ladders to compensate.\n";
00087   }
00088   // Keep a running tally to check that there are no phi gaps.
00089   double phi_coverage = 0.0;            // Running total of Phi coverage
00090   bool covered=0;                       // Set to 1 when there is at least 2Pi of coverage in phi
00091   double dphi = CLHEP::twopi/number;            // Phi difference between successive ladders
00092   double phi_offset = module_offset;    // Phi rotation of the ladders
00093   double radius_offset = 0.0;           // Distance from <R> that the stacks are shifted in or out
00094   double deltaX, deltaY;                // Offset to correct for ladder thickness
00095   double r_vol_inner = 0.0;             // Define the cylinder that the stacks are in
00096   double r_vol_outer = 0.0;             // 
00097   double phi_coverage_pinn =0.0;        // phi coverage, phi_coverage_pinn = phi_left + phi_right
00098   double phi_left    = 0.0;             // 
00099   double phi_right   = 0.0;             //
00100 
00101 
00102   // Set parameters for the Phi Rotated Stacks as default
00103   double d1 = (ladderThick)*tan(phi_offset);
00104   double d2 = (ladderThick)/cos(phi_offset);
00105   double d3 = (moduleRadius+d2);
00106   double d4 = ((activeWidth/2.0)-d1);
00107   double r_right = sqrt( d3*d3 + d4*d4 + 2*d3*d4*sin(phi_offset)) ;     // Radius of the outer edge of the active area
00108   phi_right=acos(       (r_right*r_right + d3*d3 - d4*d4)/
00109                         (2*d3*r_right)
00110                 );
00111   double d5 = sqrt(d1*d1+d2*d2);
00112   double d6 = (moduleRadius-d5);
00113   double r_left = sqrt ( d4*d4 + d6*d6 - 2*d4*d6*sin(phi_offset) ) ;     // Radius of the inner edge of the active area
00114   phi_left=acos(        (r_left*r_left + d6*d6 - d4*d4)/
00115                         (2*d6*r_left)
00116                );
00117   if (r_right> r_left ) {r_vol_outer=r_right;r_vol_inner=r_left;}
00118   if (r_left > r_right) {r_vol_outer=r_left;r_vol_inner=r_right;}
00119 
00120   phi_coverage_pinn=phi_left+phi_right;
00121   //std::cout << "\nDetermining the radii, r_in="<<r_vol_inner   <<" mod_R="<<moduleRadius<<" r_out="<<r_vol_outer;
00122   // Set parameters if High-Low Stacks are requested
00123   if(layout) {
00124     phi_offset = 0.0;
00125     phi_coverage_pinn = 0.0; // Determin for each ladder when placed
00126     double R_Curvature = ((4*moduleRadius*moduleRadius)+(ladderWidth*ladderWidth/4))/(4*moduleRadius);  // The radius of the ends of the inner stack
00127     double r2 = (R_Curvature+ladderThick);
00128     double r1 = sqrt((R_Curvature*R_Curvature)-(ladderWidth*ladderWidth/4.0))-(ladderThick);
00129 
00130     radius_offset = (r1-r2)/2.0;
00131     r_vol_inner = r1-(ladderThick);
00132     r_vol_outer = sqrt((ladderWidth*ladderWidth/4.0)+((r2+ladderThick)*(r2+ladderThick)));
00133     // phi_left and phi_right depend on R so they will be determined later
00134     // std::cout << "\nDetermining the radii, r_in="<<r_vol_inner   <<" r1="<<r1<< " R_c="<<R_Curvature<<" r2="<<r2<<" r_out="<<r_vol_outer;
00135   }
00136 
00137   double r_vol_innerT;
00138   if(r_vol_inner>r_vol_outer) {
00139     r_vol_innerT=r_vol_inner;
00140     r_vol_inner=r_vol_outer-30;
00141     r_vol_outer=r_vol_innerT+30;
00142   }
00143 
00144   std::string name;
00145 
00146   int component_copy_no=1;
00147   double phi0 = 90*CLHEP::deg;
00148   double phi =0*CLHEP::deg;
00149   double phix=0*CLHEP::deg;
00150   double phiy=0*CLHEP::deg;
00151   DDTranslation tran;
00152   DDRotation rot;
00153 
00154 
00155   //std::cout << "\nDDPixBarStackLayerAlgo test: r_mid_L_inner/r_mid_L_outer " << r_vol_inner << ", " << r_vol_outer ;
00156   //<< " d1/d2 " << d1 << ", " << d2 
00157   //<< " x1/x2 " << x1 << ", " << x2;
00158 
00159 
00160 //------------------------------------------------------------------------------------------------------------
00161 // Define the volume in which the layer exists
00162 
00163   DDName mother = parent().name();
00164   std::string idName = DDSplit(mother).first;
00165 
00166   DDSolid solid = DDSolidFactory::tubs(DDName(idName, idNameSpace), 0.5*layerDz, r_vol_inner, r_vol_outer, 0, CLHEP::twopi);
00167 
00168   DDName matname(DDSplit(VolumeMaterial).first, DDSplit(VolumeMaterial).second);
00169   DDMaterial matter(matname);
00170   DDLogicalPart layer(solid.ddname(), matter, solid);
00171 
00172   LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo test: " 
00173                         << DDName(idName, idNameSpace) << " Tubs made of " 
00174                         << VolumeMaterial << " from 0 to " << CLHEP::twopi/CLHEP::deg 
00175                         << " with Rin " << r_vol_inner << " Rout " << r_vol_outer 
00176                         << " ZHalf " << 0.5*layerDz;
00177 
00178 //------------------------------------------------------------------------------------------------------------
00179 // Define the cool tube
00180 
00181   name = idName + "CoolTube";
00182   solid = DDSolidFactory::trap(DDName(name,idNameSpace), 0.5*coolDz, 0, 0, coolWidth/2, coolSide/2, coolSide/2, 0, coolWidth/2, coolSide/2, coolSide/2, 0);
00183 
00184   matter = DDMaterial(DDName(DDSplit(tubeMat).first, DDSplit(tubeMat).second));
00185   DDLogicalPart coolTube(solid.ddname(), matter, solid);
00186 
00187   LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo test: " <<solid.name() 
00188                         << " Trap made of " << tubeMat << " of dimensions " 
00189                         << 0.5*coolDz << ", 0, 0, " << coolWidth/2 << ", " << coolSide/2 
00190                         << ", " << coolSide/2 << ", 0, " << coolWidth/2 << ", " << coolSide/2 << ", " 
00191                         << coolSide/2 << ", 0";
00192 
00193 
00194 //------------------------------------------------------------------------------------------------------------
00195 // Define the coolant within the cool tube = same as cooltube - wall thickness
00196 
00197   name = idName + "Coolant";
00198 
00199   solid = DDSolidFactory::trap(DDName(name,idNameSpace), 0.5*coolDz, 0, 0, coolWidth/2-coolThick, coolSide/2-coolThick, coolSide/2-coolThick, 0, coolWidth/2-coolThick, coolSide/2-coolThick, coolSide/2-coolThick, 0);
00200   matter = DDMaterial(DDName(DDSplit(coolMat).first, DDSplit(coolMat).second));
00201   DDLogicalPart cool(solid.ddname(), matter, solid);
00202 
00203   LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo test: " <<solid.name() 
00204                         << " Trap made of " << tubeMat << " of dimensions " 
00205                         << 0.5*coolDz << ", 0, 0, " << coolWidth/2-coolThick << ", " << coolSide/2-coolThick 
00206                         << ", " << coolSide/2-coolThick << ", 0, " << coolWidth/2-coolThick << ", " << coolSide/2-coolThick << ", " 
00207                         << coolSide/2-coolThick << ", 0";
00208 
00209  
00210 //------------------------------------------------------------------------------------------------------------
00211 // Put coolant in the cool tube
00212 
00213   cpv.position (cool, coolTube, 1, DDTranslation(0.0, 0.0, 0.0), DDRotation());
00214 
00215   LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo test: " << cool.name() 
00216                         << " number 1 positioned in " << coolTube.name() 
00217                         << " at (0,0,0) with no rotation";
00218 
00219 //------------------------------------------------------------------------------------------------------------
00220 // Define the ladder
00221 
00222   DDName ladderFullUp(DDSplit(ladderNameUp).first, DDSplit(ladderNameUp).second);
00223   DDName ladderFullDown(DDSplit(ladderNameDown).first, DDSplit(ladderNameDown).second);
00224 
00225 //------------------------------------------------------------------------------------------------------------
00226 
00227 
00228 // Iterate over the number of modules
00229 
00230   for (int i=0; i<number; i++) {
00231         
00232     double phi_coverage_i=0.0;
00233     // First the modules
00234     phi = phi0 + i*dphi;
00235     phix = phi + (90*CLHEP::deg) - phi_offset ;
00236     phiy = phix + (90*CLHEP::deg) ;
00237 
00238     deltaX= 0.5*ladderThick*cos(phi-phi_offset);
00239     deltaY= 0.5*ladderThick*sin(phi-phi_offset);
00240 
00241     double radius;
00242     if((i%2)==0) radius=moduleRadius-radius_offset;
00243     else radius=moduleRadius+radius_offset;
00244 
00245     //inner layer of stack
00246     tran = DDTranslation(radius*cos(phi)-deltaX, radius*sin(phi)-deltaY, 0);
00247     name = idName + dbl_to_string(component_copy_no);
00248     rot = DDrot(DDName(name,idNameSpace), 90*CLHEP::deg, phix, 90*CLHEP::deg, phiy, 0.,0.);
00249 
00250     cpv.position (ladderFullDown, layer, component_copy_no, tran, rot);
00251 
00252     LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo test: " << ladderFullDown 
00253                             << " number " << component_copy_no
00254                             << " positioned in " << layer.name()
00255                             << " at " << tran
00256                             << " with " << rot;
00257     component_copy_no++;
00258 
00259 
00260     //outer layer of stack
00261     tran = DDTranslation(radius*cos(phi)+deltaX, radius*sin(phi)+deltaY, 0);
00262     name = idName + dbl_to_string(component_copy_no);
00263     rot = DDrot(DDName(name,idNameSpace), 90*CLHEP::deg, phix, 90*CLHEP::deg, phiy, 0.,0.);
00264 
00265     cpv.position (ladderFullUp, layer, component_copy_no, tran, rot);
00266 
00267     LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo test: " << ladderFullUp 
00268                             << " number " << component_copy_no
00269                             << " positioned in " << layer.name()
00270                             << " at " << tran
00271                             << " with " << rot;
00272     component_copy_no++;
00273     // Running total of phi coverage
00274     phi_coverage_i=phi_coverage_pinn;
00275     if(layout) {
00276         phi_coverage_i=2*atan2((activeWidth/2.0),(radius+ladderThick));
00277     }
00278 
00279     phi_coverage += phi_coverage_i;
00280     //std::cout<<"\nLooking at phi = "<< phi<<"\tNumber "<<component_copy_no-1<<"\t with "<<phi_coverage_i<<"\trad of coverage for a total coverage of "<<phi_coverage;
00281     if (phi_coverage>CLHEP::twopi&&covered==0) {
00282        //std::cout<<"\nPhi coverage is achieved after "<<(component_copy_no-1)/2.0<<" ladders for R="<<radius/10.0<<" cm.\t and "<<number<<" ladders were asked for";
00283        covered=1;
00284     }
00285 
00286  
00287   }
00288   //std::cout<<"\nLayer covered "<<phi_coverage<<" radians in phi.   (2Pi="<<CLHEP::twopi<<")";
00289   if (phi_coverage<CLHEP::twopi) { throw cms::Exception("DDPixBarStackLayerAlgo")
00290       <<"\nAsking for a Geometry with gaps in phi.\n";}
00291 
00292 // Iterate over the number of cooltubes
00293 
00294   double coolOffset = 0.5*ladderWidth - 0.5*coolSide;
00295 
00296   for (int i=0; i<number; i++) {
00297     phi = phi0 + i*dphi;
00298     phix = phi + (90*CLHEP::deg) - phi_offset;
00299     phiy = phix + (90*CLHEP::deg) ;
00300 
00301     deltaX= coolOffset*cos(90*CLHEP::deg-phi+phi_offset);
00302     deltaY= coolOffset*sin(90*CLHEP::deg-phi+phi_offset);
00303 
00304     double radius;              
00305     if((i%2)==0) radius=moduleRadius-radius_offset;
00306     else radius=moduleRadius+radius_offset;
00307 
00308     tran = DDTranslation(radius*cos(phi)-deltaX, radius*sin(phi)+deltaY, 0);
00309 
00310     name = idName + "xxx"+dbl_to_string(i+10000);
00311 
00312     rot = DDrot(DDName(name,idNameSpace), 90*CLHEP::deg, phix, 90*CLHEP::deg, phiy, 0.,0.);
00313     cpv.position (coolTube, layer, i+1, tran, rot);
00314     LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo test: " << coolTube.name() 
00315                           << " number " << i+1 << " positioned in " 
00316                           << layer.name() << " at " << tran << " with "<< rot;
00317   }
00318 
00319 
00320  // End algorithm
00321 }