CMS 3D CMS Logo

DDPixBarStackLayerAlgo.cc
Go to the documentation of this file.
1 // File: DDPixBarStackLayerAlgo.cc
3 // Description: Make one layer of stacked pixel barrel detector
5 
6 #include <cmath>
7 #include <algorithm>
8 
16 #include "CLHEP/Units/PhysicalConstants.h"
17 #include "CLHEP/Units/SystemOfUnits.h"
18 
19 
21 // Constructor
23  LogDebug("PixelGeom") <<"DDPixBarStackLayerAlgo info: Creating an instance";
24 }
25 
27 // Destructor
29 
31 // Initialization of algorithm
33  const DDVectorArguments & vArgs,
34  const DDMapArguments & ,
35  const DDStringArguments & sArgs,
36  const DDStringVectorArguments & vsArgs) {
37 
38 
39 // Retrieve the variables from the XML files
41  DDName parentName = parent().name();
42 
43  VolumeMaterial = sArgs["VolumeMaterial"];
44  number = int(nArgs["Ladders"]);
45  layerDz = nArgs["LayerDz"];
46  sensorEdge= nArgs["SensorEdge"];
47  coolDz = nArgs["CoolDz"];
48  coolWidth = nArgs["CoolWidth"];
49  coolSide = nArgs["CoolSide"];
50  coolThick = nArgs["CoolThick"];
51  moduleRadius = nArgs["ModuleRadius"];
52  coolMat = sArgs["CoolMaterial"];
53  tubeMat = sArgs["CoolTubeMaterial"];
54  ladderNameUp = sArgs["LadderNameUp"];
55  ladderNameDown = sArgs["LadderNameDown"];
56  ladderWidth = nArgs["LadderWidth"];
57  ladderThick = nArgs["LadderThick"];
58  module_offset = nArgs["ModuleOffset"];
59  layout = int(nArgs["LayoutType"]);
60  activeWidth = nArgs["ActiveWidth"];
61 
62 // Debug messages
63  //std::cout <<"\nStack sensor with sensorEdge = "<<sensorEdge<<"\tand width = "<<activeWidth<<"\t at R = "<<moduleRadius;
64  LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo debug: Parent " << parentName
65  << " NameSpace " << idNameSpace << "\n"
66  << "\tLadders " << number << "\tGeneral Material "
67  << VolumeMaterial << "\tLength " << layerDz << "\tSensorEdge "
68  << sensorEdge << "\tSpecification of Cooling Pieces:\n"
69  << "\tLength " << coolDz << " Width " << coolWidth
70  << " Side " << coolSide << " Thickness of Shell "
71  << coolThick << " Radial distance " << moduleRadius
72  << " Materials " << coolMat << ", " << tubeMat;
73 
74  LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo debug: Ladder "
75  << ladderNameUp << " width/thickness " << ladderWidth
76  << ", " << ladderThick;
77 }
78 
79 
81 // The algorithm itself
83  if ((number%2==1)&&(layout==1)) {
84  number+=1;
85  std::cout << "\nAsking for an invalid layout ... Adjusting the number of ladders to compensate.\n";
86  }
87  // Keep a running tally to check that there are no phi gaps.
88  double phi_coverage = 0.0; // Running total of Phi coverage
89  bool covered=0; // Set to 1 when there is at least 2Pi of coverage in phi
90  double dphi = CLHEP::twopi/number; // Phi difference between successive ladders
91  double phi_offset = module_offset; // Phi rotation of the ladders
92  double radius_offset = 0.0; // Distance from <R> that the stacks are shifted in or out
93  double deltaX, deltaY; // Offset to correct for ladder thickness
94  double r_vol_inner = 0.0; // Define the cylinder that the stacks are in
95  double r_vol_outer = 0.0; //
96  double phi_coverage_pinn =0.0; // phi coverage, phi_coverage_pinn = phi_left + phi_right
97  double phi_left = 0.0; //
98  double phi_right = 0.0; //
99 
100 
101  // Set parameters for the Phi Rotated Stacks as default
102  double d1 = (ladderThick)*tan(phi_offset);
103  double d2 = (ladderThick)/cos(phi_offset);
104  double d3 = (moduleRadius+d2);
105  double d4 = ((activeWidth/2.0)-d1);
106  double r_right = sqrt( d3*d3 + d4*d4 + 2*d3*d4*sin(phi_offset)) ; // Radius of the outer edge of the active area
107  phi_right=acos( (r_right*r_right + d3*d3 - d4*d4)/
108  (2*d3*r_right)
109  );
110  double d5 = sqrt(d1*d1+d2*d2);
111  double d6 = (moduleRadius-d5);
112  double r_left = sqrt ( d4*d4 + d6*d6 - 2*d4*d6*sin(phi_offset) ) ; // Radius of the inner edge of the active area
113  phi_left=acos( (r_left*r_left + d6*d6 - d4*d4)/
114  (2*d6*r_left)
115  );
116  if (r_right> r_left ) {r_vol_outer=r_right;r_vol_inner=r_left;}
117  if (r_left > r_right) {r_vol_outer=r_left;r_vol_inner=r_right;}
118 
119  phi_coverage_pinn=phi_left+phi_right;
120  //std::cout << "\nDetermining the radii, r_in="<<r_vol_inner <<" mod_R="<<moduleRadius<<" r_out="<<r_vol_outer;
121  // Set parameters if High-Low Stacks are requested
122  if(layout) {
123  phi_offset = 0.0;
124  phi_coverage_pinn = 0.0; // Determin for each ladder when placed
125  double R_Curvature = ((4*moduleRadius*moduleRadius)+(ladderWidth*ladderWidth/4))/(4*moduleRadius); // The radius of the ends of the inner stack
126  double r2 = (R_Curvature+ladderThick);
127  double r1 = sqrt((R_Curvature*R_Curvature)-(ladderWidth*ladderWidth/4.0))-(ladderThick);
128 
129  radius_offset = (r1-r2)/2.0;
130  r_vol_inner = r1-(ladderThick);
131  r_vol_outer = sqrt((ladderWidth*ladderWidth/4.0)+((r2+ladderThick)*(r2+ladderThick)));
132  // phi_left and phi_right depend on R so they will be determined later
133  // std::cout << "\nDetermining the radii, r_in="<<r_vol_inner <<" r1="<<r1<< " R_c="<<R_Curvature<<" r2="<<r2<<" r_out="<<r_vol_outer;
134  }
135 
136  double r_vol_innerT;
137  if(r_vol_inner>r_vol_outer) {
138  r_vol_innerT=r_vol_inner;
139  r_vol_inner=r_vol_outer-30;
140  r_vol_outer=r_vol_innerT+30;
141  }
142 
144 
145  int component_copy_no=1;
146  double phi0 = 90*CLHEP::deg;
147  double phi =0*CLHEP::deg;
148  double phix=0*CLHEP::deg;
149  double phiy=0*CLHEP::deg;
150  DDTranslation tran;
151  DDRotation rot;
152 
153 
154  //std::cout << "\nDDPixBarStackLayerAlgo test: r_mid_L_inner/r_mid_L_outer " << r_vol_inner << ", " << r_vol_outer ;
155  //<< " d1/d2 " << d1 << ", " << d2
156  //<< " x1/x2 " << x1 << ", " << x2;
157 
158 
159 //------------------------------------------------------------------------------------------------------------
160 // Define the volume in which the layer exists
161 
162  DDName mother = parent().name();
163  std::string idName = DDSplit(mother).first;
164 
165  DDSolid solid = DDSolidFactory::tubs(DDName(idName, idNameSpace), 0.5*layerDz, r_vol_inner, r_vol_outer, 0, CLHEP::twopi);
166 
168  DDMaterial matter(matname);
169  DDLogicalPart layer(solid.ddname(), matter, solid);
170 
171  LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo test: "
172  << DDName(idName, idNameSpace) << " Tubs made of "
173  << VolumeMaterial << " from 0 to " << CLHEP::twopi/CLHEP::deg
174  << " with Rin " << r_vol_inner << " Rout " << r_vol_outer
175  << " ZHalf " << 0.5*layerDz;
176 
177 //------------------------------------------------------------------------------------------------------------
178 // Define the cool tube
179 
180  name = idName + "CoolTube";
181  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);
182 
183  matter = DDMaterial(DDName(DDSplit(tubeMat).first, DDSplit(tubeMat).second));
184  DDLogicalPart coolTube(solid.ddname(), matter, solid);
185 
186  LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo test: " <<solid.name()
187  << " Trap made of " << tubeMat << " of dimensions "
188  << 0.5*coolDz << ", 0, 0, " << coolWidth/2 << ", " << coolSide/2
189  << ", " << coolSide/2 << ", 0, " << coolWidth/2 << ", " << coolSide/2 << ", "
190  << coolSide/2 << ", 0";
191 
192 
193 //------------------------------------------------------------------------------------------------------------
194 // Define the coolant within the cool tube = same as cooltube - wall thickness
195 
196  name = idName + "Coolant";
197 
199  matter = DDMaterial(DDName(DDSplit(coolMat).first, DDSplit(coolMat).second));
200  DDLogicalPart cool(solid.ddname(), matter, solid);
201 
202  LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo test: " <<solid.name()
203  << " Trap made of " << tubeMat << " of dimensions "
204  << 0.5*coolDz << ", 0, 0, " << coolWidth/2-coolThick << ", " << coolSide/2-coolThick
205  << ", " << coolSide/2-coolThick << ", 0, " << coolWidth/2-coolThick << ", " << coolSide/2-coolThick << ", "
206  << coolSide/2-coolThick << ", 0";
207 
208 
209 //------------------------------------------------------------------------------------------------------------
210 // Put coolant in the cool tube
211 
212  cpv.position (cool, coolTube, 1, DDTranslation(0.0, 0.0, 0.0), DDRotation());
213 
214  LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo test: " << cool.name()
215  << " number 1 positioned in " << coolTube.name()
216  << " at (0,0,0) with no rotation";
217 
218 //------------------------------------------------------------------------------------------------------------
219 // Define the ladder
220 
221  DDName ladderFullUp(DDSplit(ladderNameUp).first, DDSplit(ladderNameUp).second);
222  DDName ladderFullDown(DDSplit(ladderNameDown).first, DDSplit(ladderNameDown).second);
223 
224 //------------------------------------------------------------------------------------------------------------
225 
226 
227 // Iterate over the number of modules
228 
229  for (int i=0; i<number; i++) {
230 
231  double phi_coverage_i=0.0;
232  // First the modules
233  phi = phi0 + i*dphi;
234  phix = phi + (90*CLHEP::deg) - phi_offset ;
235  phiy = phix + (90*CLHEP::deg) ;
236 
237  deltaX= 0.5*ladderThick*cos(phi-phi_offset);
238  deltaY= 0.5*ladderThick*sin(phi-phi_offset);
239 
240  double radius;
241  if((i%2)==0) radius=moduleRadius-radius_offset;
242  else radius=moduleRadius+radius_offset;
243 
244  //inner layer of stack
245  tran = DDTranslation(radius*cos(phi)-deltaX, radius*sin(phi)-deltaY, 0);
246  name = idName + std::to_string(component_copy_no);
247  rot = DDrot(DDName(name,idNameSpace), 90*CLHEP::deg, phix, 90*CLHEP::deg, phiy, 0.,0.);
248 
249  cpv.position (ladderFullDown, layer, component_copy_no, tran, rot);
250 
251  LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo test: " << ladderFullDown
252  << " number " << component_copy_no
253  << " positioned in " << layer.name()
254  << " at " << tran
255  << " with " << rot;
256  component_copy_no++;
257 
258 
259  //outer layer of stack
260  tran = DDTranslation(radius*cos(phi)+deltaX, radius*sin(phi)+deltaY, 0);
261  name = idName + std::to_string(component_copy_no);
262  rot = DDrot(DDName(name,idNameSpace), 90*CLHEP::deg, phix, 90*CLHEP::deg, phiy, 0.,0.);
263 
264  cpv.position (ladderFullUp, layer, component_copy_no, tran, rot);
265 
266  LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo test: " << ladderFullUp
267  << " number " << component_copy_no
268  << " positioned in " << layer.name()
269  << " at " << tran
270  << " with " << rot;
271  component_copy_no++;
272  // Running total of phi coverage
273  phi_coverage_i=phi_coverage_pinn;
274  if(layout) {
275  phi_coverage_i=2*atan2((activeWidth/2.0),(radius+ladderThick));
276  }
277 
278  phi_coverage += phi_coverage_i;
279  //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;
280  if (phi_coverage>CLHEP::twopi&&covered==0) {
281  //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";
282  covered=1;
283  }
284 
285 
286  }
287  //std::cout<<"\nLayer covered "<<phi_coverage<<" radians in phi. (2Pi="<<CLHEP::twopi<<")";
288  if (phi_coverage<CLHEP::twopi) { throw cms::Exception("DDPixBarStackLayerAlgo")
289  <<"\nAsking for a Geometry with gaps in phi.\n";}
290 
291 // Iterate over the number of cooltubes
292 
293  double coolOffset = 0.5*ladderWidth - 0.5*coolSide;
294 
295  for (int i=0; i<number; i++) {
296  phi = phi0 + i*dphi;
297  phix = phi + (90*CLHEP::deg) - phi_offset;
298  phiy = phix + (90*CLHEP::deg) ;
299 
300  deltaX= coolOffset*cos(90*CLHEP::deg-phi+phi_offset);
301  deltaY= coolOffset*sin(90*CLHEP::deg-phi+phi_offset);
302 
303  double radius;
304  if((i%2)==0) radius=moduleRadius-radius_offset;
305  else radius=moduleRadius+radius_offset;
306 
307  tran = DDTranslation(radius*cos(phi)-deltaX, radius*sin(phi)+deltaY, 0);
308 
309  name = idName + "xxx" + std::to_string(i+10000);
310 
311  rot = DDrot(DDName(name,idNameSpace), 90*CLHEP::deg, phix, 90*CLHEP::deg, phiy, 0.,0.);
312  cpv.position (coolTube, layer, i+1, tran, rot);
313  LogDebug("PixelGeom") << "DDPixBarStackLayerAlgo test: " << coolTube.name()
314  << " number " << i+1 << " positioned in "
315  << layer.name() << " at " << tran << " with "<< rot;
316  }
317 
318 
319  // End algorithm
320 }
#define LogDebug(id)
void initialize(const DDNumericArguments &nArgs, const DDVectorArguments &vArgs, const DDMapArguments &mArgs, const DDStringArguments &sArgs, const DDStringVectorArguments &vsArgs)
void execute(DDCompactView &cpv)
const N & name() const
Definition: DDBase.h:78
DDMaterial is used to define and access material information.
Definition: DDMaterial.h:41
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
void position(const DDLogicalPart &self, const DDLogicalPart &parent, std::string copyno, const DDTranslation &trans, const DDRotation &rot, const DDDivision *div=NULL)
DDName is used to identify DDD entities uniquely.
Definition: DDName.h:16
static std::string & ns()
type of data representation of DDCompactView
Definition: DDCompactView.h:90
A DDSolid represents the shape of a part.
Definition: DDSolid.h:37
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DDTranslation
Definition: DDTranslation.h:7
Represents a uniquely identifyable rotation matrix.
Definition: DDTransform.h:64
U second(std::pair< T, U > const &p)
T sqrt(T t)
Definition: SSEVec.h:18
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
A DDLogicalPart aggregates information concerning material, solid and sensitveness ...
Definition: DDLogicalPart.h:92
static DDSolid tubs(const DDName &name, double zhalf, double rIn, double rOut, double startPhi, double deltaPhi)
Definition: DDSolid.cc:863
static DDSolid trap(const DDName &name, double pDz, double pTheta, double pPhi, double pDy1, double pDx1, double pDx2, double pAlp1, double pDy2, double pDx3, double pDx4, double pAlp2)
Definition: DDSolid.cc:794
DDRotation DDrot(const DDName &name, DDRotationMatrix *rot)
Definition of a uniquely identifiable rotation matrix named by DDName name.
Definition: DDRotation.cc:90
std::pair< std::string, std::string > DDSplit(const std::string &n)
split into (name,namespace), separator = &#39;:&#39;
Definition: DDSplit.cc:4
const std::string & name() const
Returns the name.
Definition: DDName.cc:90
const N & ddname() const
Definition: DDBase.h:80