CMS 3D CMS Logo

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

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