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/DDPixBarStackLayerAlgo.h"
00017 #include "CLHEP/Units/PhysicalConstants.h"
00018 #include "CLHEP/Units/SystemOfUnits.h"
00019
00020
00022
00023 DDPixBarStackLayerAlgo::DDPixBarStackLayerAlgo() {
00024 LogDebug("PixelGeom") <<"DDPixBarStackLayerAlgo info: Creating an instance";
00025 }
00026
00028
00029 DDPixBarStackLayerAlgo::~DDPixBarStackLayerAlgo() {}
00030
00032
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
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
00064
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
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
00089 double phi_coverage = 0.0;
00090 bool covered=0;
00091 double dphi = CLHEP::twopi/number;
00092 double phi_offset = module_offset;
00093 double radius_offset = 0.0;
00094 double deltaX, deltaY;
00095 double r_vol_inner = 0.0;
00096 double r_vol_outer = 0.0;
00097 double phi_coverage_pinn =0.0;
00098 double phi_left = 0.0;
00099 double phi_right = 0.0;
00100
00101
00102
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)) ;
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) ) ;
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
00122
00123 if(layout) {
00124 phi_offset = 0.0;
00125 phi_coverage_pinn = 0.0;
00126 double R_Curvature = ((4*moduleRadius*moduleRadius)+(ladderWidth*ladderWidth/4))/(4*moduleRadius);
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
00134
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
00156
00157
00158
00159
00160
00161
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
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
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
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
00221
00222 DDName ladderFullUp(DDSplit(ladderNameUp).first, DDSplit(ladderNameUp).second);
00223 DDName ladderFullDown(DDSplit(ladderNameDown).first, DDSplit(ladderNameDown).second);
00224
00225
00226
00227
00228
00229
00230 for (int i=0; i<number; i++) {
00231
00232 double phi_coverage_i=0.0;
00233
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
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
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
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
00281 if (phi_coverage>CLHEP::twopi&&covered==0) {
00282
00283 covered=1;
00284 }
00285
00286
00287 }
00288
00289 if (phi_coverage<CLHEP::twopi) { throw cms::Exception("DDPixBarStackLayerAlgo")
00290 <<"\nAsking for a Geometry with gaps in phi.\n";}
00291
00292
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
00321 }