CMS 3D CMS Logo

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