00001
00002
00003
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
00023 DDPixBarTPGStackLayerAlgo::DDPixBarTPGStackLayerAlgo() {
00024 LogDebug("PixelGeom") <<"DDPixBarTPGStackLayerAlgo info: Creating an instance";
00025 }
00026
00028
00029 DDPixBarTPGStackLayerAlgo::~DDPixBarTPGStackLayerAlgo() {}
00030
00032
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
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
00067
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
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
00092 double phi_coverage = 0.0;
00093 bool covered=0;
00094 double dphi = CLHEP::twopi/number;
00095 double phi_offset = module_offset;
00096 double radius_offset = 0.0;
00097 double deltaX, deltaY;
00098 double deltaX2, deltaY2;
00099 double r_vol_inner = 0.0;
00100 double r_vol_outer = 0.0;
00101 double phi_coverage_pinn =0.0;
00102 double phi_left = 0.0;
00103 double phi_right = 0.0;
00104
00105
00106
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)) ;
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) ) ;
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
00126
00127 if(layout) {
00128 phi_offset = 0.0;
00129 phi_coverage_pinn = 0.0;
00130 double R_Curvature = ((4*moduleRadius*moduleRadius)+(ladderWidth*ladderWidth/4))/(4*moduleRadius);
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
00138
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
00160
00161
00162
00163
00164
00165
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
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
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
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
00225
00226 DDName ladderFullUp(DDSplit(ladderNameUp).first, DDSplit(ladderNameUp).second);
00227 DDName ladderFullDown(DDSplit(ladderNameDown).first, DDSplit(ladderNameDown).second);
00228
00229
00230
00231
00232
00233
00234 for (int i=0; i<number; i++) {
00235
00236 double phi_coverage_i=0.0;
00237
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
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
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
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
00285 if (phi_coverage>CLHEP::twopi&&covered==0) {
00286
00287 covered=1;
00288 }
00289
00290
00291 }
00292
00293 if (phi_coverage<CLHEP::twopi) { throw cms::Exception("DDPixBarTPGStackLayerAlgo")
00294 <<"\nAsking for a Geometry with gaps in phi.\n";}
00295
00296
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
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
00351 }