clusterizer,reconstructor + many fixes (Magnus,Stefan)
[u/mrichter/AliRoot.git] / ITS / UPGRADE / AliITSUv11Layer.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 //*************************************************************************
17 // This class Defines the Geometry for the ITS Upgrade using TGeo
18 // This is a work class used to study different configurations
19 // during the development of the new ITS structure.
20 //
21 //  Mario Sitta <sitta@to.infn.it>
22 //*************************************************************************
23
24
25 /* $Id: AliITSUv11Layer.cxx  */
26 // General Root includes
27 #include <TMath.h>
28 // Root Geometry includes
29 //#include <AliLog.h>
30 #include <TGeoManager.h>
31 #include <TGeoVolume.h>
32 #include <TGeoPcon.h>
33 #include <TGeoCone.h>
34 #include <TGeoTube.h> // contaings TGeoTubeSeg
35 #include <TGeoArb8.h>
36 #include <TGeoXtru.h>
37 #include <TGeoCompositeShape.h>
38 #include <TGeoMatrix.h>
39 #include "AliITSUv11Layer.h"
40 #include "AliITSUGeomTGeo.h"
41
42 const Double_t AliITSUv11Layer::fgkDefaultSensorThick = 300*fgkmicron;
43 const Double_t AliITSUv11Layer::fgkDefaultLadderThick =   1*fgkcm;
44
45 ClassImp(AliITSUv11Layer)
46
47 #define SQ(A) (A)*(A)
48
49 //________________________________________________________________________
50 AliITSUv11Layer::AliITSUv11Layer(): 
51   AliITSv11Geometry(),
52   fLayerNumber(0),
53   fLayRadius(0),
54   fZLength(0),
55   fSensorThick(0),
56   fLadderThick(0),
57   fLadderWidth(0),
58   fLadderTilt(0),
59   fNLadders(0),
60   fNModules(0),
61   fDetTypeID(0),
62   fIsTurbo(0)
63 {
64   //
65   // Standard constructor
66   //
67 }
68
69 //________________________________________________________________________
70 AliITSUv11Layer::AliITSUv11Layer(Int_t debug): 
71   AliITSv11Geometry(debug),
72   fLayerNumber(0),
73   fLayRadius(0),
74   fZLength(0),
75   fSensorThick(0),
76   fLadderThick(0),
77   fLadderWidth(0),
78   fLadderTilt(0),
79   fNLadders(0),
80   fNModules(0),
81   fDetTypeID(0),
82   fIsTurbo(0)
83 {
84   //
85   // Constructor setting debugging level
86   //
87 }
88
89 //________________________________________________________________________
90 AliITSUv11Layer::AliITSUv11Layer(Int_t lay, Int_t debug): 
91   AliITSv11Geometry(debug),
92   fLayerNumber(lay),
93   fLayRadius(0),
94   fZLength(0),
95   fSensorThick(0),
96   fLadderThick(0),
97   fLadderWidth(0),
98   fLadderTilt(0),
99   fNLadders(0),
100   fNModules(0),
101   fDetTypeID(0),
102   fIsTurbo(0)
103 {
104   //
105   // Constructor setting layer number and debugging level
106   //
107 }
108
109 //________________________________________________________________________
110 AliITSUv11Layer::AliITSUv11Layer(Int_t lay, Bool_t turbo, Int_t debug): 
111   AliITSv11Geometry(debug),
112   fLayerNumber(lay),
113   fLayRadius(0),
114   fZLength(0),
115   fSensorThick(0),
116   fLadderThick(0),
117   fLadderWidth(0),
118   fLadderTilt(0),
119   fNLadders(0),
120   fNModules(0),
121   fDetTypeID(0),
122   fIsTurbo(turbo)
123 {
124   //
125   // Constructor setting layer number and debugging level
126   // for a "turbo" layer (i.e. where ladders overlap in phi)
127   //
128 }
129
130 //________________________________________________________________________
131 AliITSUv11Layer::AliITSUv11Layer(const AliITSUv11Layer &s):
132   AliITSv11Geometry(s.GetDebug()),
133   fLayerNumber(s.fLayerNumber),
134   fLayRadius(s.fLayRadius),
135   fZLength(s.fZLength),
136   fSensorThick(s.fSensorThick),
137   fLadderThick(s.fLadderThick),
138   fLadderWidth(s.fLadderWidth),
139   fLadderTilt(s.fLadderTilt),
140   fNLadders(s.fNLadders),
141   fNModules(s.fNModules),
142   fDetTypeID(0),
143   fIsTurbo(s.fIsTurbo)
144 {
145   //
146   // Copy constructor
147   //
148 }
149
150 //________________________________________________________________________
151 AliITSUv11Layer& AliITSUv11Layer::operator=(const AliITSUv11Layer &s)
152 {
153   //
154   // Assignment operator 
155   //
156   if(&s == this) return *this;
157
158   fLayerNumber = s.fLayerNumber;
159   fLayRadius   = s.fLayRadius;
160   fZLength     = s.fZLength;
161   fSensorThick = s.fSensorThick;
162   fLadderThick = s.fLadderThick;
163   fLadderWidth = s.fLadderWidth;
164   fLadderTilt  = s.fLadderTilt;
165   fNLadders    = s.fNLadders;
166   fNModules    = s.fNModules;
167   fIsTurbo     = s.fIsTurbo;
168   fDetTypeID   = s.fDetTypeID;
169   return *this;
170 }
171
172 //________________________________________________________________________
173 AliITSUv11Layer::~AliITSUv11Layer() {
174   //
175   // Destructor
176   //
177 }
178
179 //________________________________________________________________________
180 void AliITSUv11Layer::CreateLayer(TGeoVolume *moth,
181                                      const TGeoManager *mgr){
182 //
183 // Creates the actual Layer and places inside its mother volume
184 //
185 // Input:
186 //         moth : the TGeoVolume owing the volume structure
187 //         mgr  : the GeoManager (used only to get the proper material)
188 //
189 // Output:
190 //
191 // Return:
192 //
193 // Created:      17 Jun 2011  Mario Sitta
194 // Updated:      08 Jul 2011  Mario Sitta
195 //
196
197
198   // Local variables
199   char volname[30];
200   Double_t rmin, rmax;
201   Double_t xpos, ypos, zpos;
202   Double_t alpha;
203
204
205   // Check if the user set the proper parameters
206   if (fLayRadius <= 0) AliFatal(Form("Wrong layer radius (%f)",fLayRadius));
207   if (fZLength   <= 0) AliFatal(Form("Wrong layer length (%f)",fZLength));
208   if (fNLadders  <= 0) AliFatal(Form("Wrong number of ladders (%d)",fNLadders));
209   if (fNModules  <= 0) AliFatal(Form("Wrong number of modules (%d)",fNModules));
210
211   if (fLadderThick <= 0) {
212     AliInfo(Form("Ladder thickness wrong or not set (%f), using default (%f)",
213                  fLadderThick,fgkDefaultLadderThick));
214     fLadderThick = fgkDefaultLadderThick;
215   }
216
217   if (fSensorThick <= 0) {
218     AliInfo(Form("Sensor thickness wrong or not set (%f), using default (%f)",
219                  fSensorThick,fgkDefaultSensorThick));
220     fSensorThick = fgkDefaultSensorThick;
221   }
222
223   if (fSensorThick > fLadderThick) {
224     AliWarning(Form("Sensor thickness (%f) is greater than ladder thickness (%f), fixing",
225                  fSensorThick,fLadderThick));
226     fSensorThick = fLadderThick;
227   }
228
229
230   // If a Turbo layer is requested, do it and exit
231   if (fIsTurbo) {
232     CreateLayerTurbo(moth, mgr);
233     return;
234   }
235
236
237   // First create the ladder container
238   alpha = (360./(2*fNLadders))*TMath::DegToRad();
239
240   //  fLadderWidth = fLayRadius*TMath::Tan(alpha);
241
242   rmin = 0.98*fLayRadius;
243   rmax = 1.02*TMath::Sqrt( fLadderWidth*fLadderWidth +
244                           (rmin+fLadderThick)*(rmin+fLadderThick) );
245
246   TGeoTube *layer = new TGeoTube(rmin, rmax, 0.5*fZLength);
247
248
249   // We have all shapes: now create the real volumes
250   TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$");
251
252   snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSLayerPattern(),fLayerNumber);
253   TGeoVolume *layVol = new TGeoVolume(volname, layer, medAir);
254   layVol->SetUniqueID(fDetTypeID);
255
256 //  layVol->SetVisibility(kFALSE);
257   layVol->SetVisibility(kTRUE);
258   layVol->SetLineColor(1);
259
260   TGeoVolume *laddVol = CreateLadder();
261
262
263   // Now build up the layer
264   alpha = 360./fNLadders;
265   Double_t r = fLayRadius + ((TGeoBBox*)laddVol->GetShape())->GetDY();
266   for (Int_t j=0; j<fNLadders; j++) {
267     Double_t theta = j*alpha;
268     xpos = r*SinD(theta);
269     ypos = r*CosD(theta);
270     zpos = 0.;
271     layVol->AddNode(laddVol, j, new TGeoCombiTrans( xpos, ypos, zpos,
272                                   new TGeoRotation("",-theta,0,0)));
273   }
274
275
276   // Finally put everything in the mother volume
277   moth->AddNode(layVol, 1, 0);
278
279
280   // Upgrade geometry is served
281   return;
282 }
283
284 //________________________________________________________________________
285 void AliITSUv11Layer::CreateLayerTurbo(TGeoVolume *moth,
286                                           const TGeoManager *mgr){
287 //
288 // Creates the actual Layer and places inside its mother volume
289 // A so-called "turbo" layer is a layer where ladders overlap in phi
290 // User can set width and tilt angle, no check is performed here
291 // to avoid volume overlaps
292 //
293 // Input:
294 //         moth : the TGeoVolume owing the volume structure
295 //         mgr  : the GeoManager (used only to get the proper material)
296 //
297 // Output:
298 //
299 // Return:
300 //
301 // Created:      08 Jul 2011  Mario Sitta
302 // Updated:      08 Mar 2012  Mario Sitta  Correct way to compute container R
303 //
304
305
306   // Local variables
307   char volname[30];
308   Double_t rmin, rmax, rladd, rcont, d;
309   Double_t xpos, ypos, zpos;
310   Double_t alpha, gamma;
311
312
313   // Check if the user set the proper (remaining) parameters
314   if (fLadderWidth <= 0)
315     AliFatal(Form("Wrong ladder width (%f)",fLadderWidth));
316   if (TMath::Abs(fLadderTilt) > 45)
317     AliWarning(Form("Ladder tilt angle (%f) greater than 45deg",fLadderTilt));
318
319
320   // First create the ladder container
321   // d is half the diagonal of the ladder section
322   // rladd is the radius at the ladder's center-of-gravity
323   // alpha here is the angle between the diagonal and rladd
324   d = 0.5*TMath::Sqrt(fLadderThick*fLadderThick + fLadderWidth*fLadderWidth);
325   alpha = TMath::ACos(0.5*fLadderThick/d)*TMath::RadToDeg();
326   gamma = alpha - fLadderTilt;
327   rladd = fLayRadius + 0.5*fLadderThick;
328
329   // rcont is the radius of the air container
330   rcont = RadiusOfTurboContainer();
331   
332   if (rcont > 0)
333     rmin = 0.98*rcont;
334   else
335     rmin = 0.98*TMath::Sqrt( rladd*rladd + d*d - 2*rladd*d*CosD(gamma) );
336   
337   rmax = 1.02*TMath::Sqrt( rladd*rladd + d*d + 2*rladd*d*CosD(gamma) );
338   
339   TGeoTube *layer = new TGeoTube(rmin, rmax, 0.5*fZLength);
340
341
342   // We have all shapes: now create the real volumes
343   TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$");
344
345   snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSLayerPattern(), fLayerNumber);
346   TGeoVolume *layVol = new TGeoVolume(volname, layer, medAir);
347   layVol->SetUniqueID(fDetTypeID);
348   layVol->SetVisibility(kTRUE);
349   layVol->SetLineColor(1);
350   TGeoVolume *laddVol = CreateLadder();
351
352
353   // Now build up the layer
354
355
356   // Now build up the layer
357   alpha = 360./fNLadders;
358   Double_t r = fLayRadius + ((TGeoBBox*)laddVol->GetShape())->GetDY();
359   for (Int_t j=0; j<fNLadders; j++) {
360     Double_t theta = j*alpha;
361     xpos = r*SinD(theta);
362     ypos = r*CosD(theta);
363     zpos = 0.;
364     layVol->AddNode(laddVol, j, new TGeoCombiTrans( xpos, ypos, zpos,
365                                  new TGeoRotation("",-theta+fLadderTilt,0,0)));
366   }
367
368
369   // Finally put everything in the mother volume
370   moth->AddNode(layVol, 1, 0);
371
372   return;
373 }
374
375 //________________________________________________________________________
376 TGeoVolume* AliITSUv11Layer::CreateLadder(const TGeoManager *mgr){
377 //
378 // Creates the actual Ladder
379 //
380 // Input:
381 //         mgr  : the GeoManager (used only to get the proper material)
382 //
383 // Output:
384 //
385 // Return:
386 //
387 // Created:      22 Jun 2011  Mario Sitta
388 //
389
390   char volname[30];
391   Double_t xlen, ylen, zlen;
392   Double_t xpos, ypos, zpos, zmod;
393   Double_t alpha;
394
395
396   // First create all needed shapes
397   alpha = (360./(2*fNLadders))*TMath::DegToRad();
398
399   // The ladder
400   xlen = fLayRadius*TMath::Tan(alpha);
401   if (fIsTurbo) xlen = 0.5*fLadderWidth;
402   ylen = 0.5*fLadderThick;
403   zlen = 0.5*fZLength;
404
405   TGeoBBox *ladder = new TGeoBBox(xlen, ylen, zlen);
406
407
408   // We have all shapes: now create the real volumes
409   TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$");
410
411   snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSLadderPattern(), fLayerNumber);
412   TGeoVolume *laddVol = new TGeoVolume(volname, ladder, medAir);
413
414 //  laddVol->SetVisibility(kFALSE);
415   laddVol->SetVisibility(kTRUE);
416   laddVol->SetLineColor(2);
417   TGeoVolume *modVol = CreateModule(ladder->GetDX(), ladder->GetDY(),
418                                     ladder->GetDZ());
419
420
421   // Now build up the ladder
422   zmod = ((TGeoBBox*)modVol->GetShape())->GetDZ();
423   for (Int_t j=0; j<fNModules; j++) {
424     xpos = 0.;
425     ypos = 0.;
426     zpos = -ladder->GetDZ() + j*2*zmod + zmod;
427     laddVol->AddNode(modVol, j, new TGeoTranslation(xpos, ypos, zpos));
428   }
429
430
431   // Done, return the ladder
432   return laddVol;
433 }
434
435 //________________________________________________________________________
436 TGeoVolume* AliITSUv11Layer::CreateModule(const Double_t xlad,
437                                                    const Double_t ylad,
438                                                    const Double_t zlad,
439                                                    const TGeoManager *mgr){
440 //
441 // Creates the actual Module
442 //
443 // Input:
444 //         xlad,ylad,zlad : the ladder dimensions
445 //         mgr  : the GeoManager (used only to get the proper material)
446 //
447 // Output:
448 //
449 // Return:
450 //
451 // Created:      22 Jun 2011  Mario Sitta
452 //
453
454   char volname[30];
455   Double_t xlen, ylen, zlen;
456   Double_t xpos, ypos, zpos;
457
458
459   // First create all needed shapes
460
461   // The module
462   TGeoBBox *module = new TGeoBBox(xlad, ylad, zlad/fNModules);
463
464   // The sensor
465   xlen = module->GetDX();
466   ylen = 0.5*fSensorThick;
467   zlen = module->GetDZ();
468   TGeoBBox *sensor = new TGeoBBox(xlen, ylen, zlen);
469
470
471   // We have all shapes: now create the real volumes
472   //  TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$");
473   TGeoMedium *medSi  = mgr->GetMedium("ITS_SI$");
474
475   snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSModulePattern() ,fLayerNumber);
476   //  TGeoVolume *modVol = new TGeoVolume(volname, module, medAir);
477   TGeoVolume *modVol = new TGeoVolume(volname, module, medSi);
478   modVol->SetVisibility(kFALSE);
479   modVol->SetLineColor(1);
480
481   snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSSensorPattern(), fLayerNumber);
482   TGeoVolume *sensVol = new TGeoVolume(volname, sensor, medSi);
483   sensVol->SetVisibility(kTRUE);
484   sensVol->SetLineColor(8);
485   sensVol->SetLineWidth(1);
486   sensVol->SetFillColor(sensVol->GetLineColor());
487   sensVol->SetFillStyle(4000); // 0% transparent
488
489
490   // Now build up the module
491   xpos = 0.;
492   ypos = -module->GetDY() + sensor->GetDY();
493   zpos = 0.;
494
495   modVol->AddNode(sensVol, 1, new TGeoTranslation(xpos, ypos, zpos));
496
497
498   // Done, return the module
499   return modVol;
500 }
501
502 //________________________________________________________________________
503 Double_t AliITSUv11Layer::RadiusOfTurboContainer(){
504 //
505 // Computes the inner radius of the air container for the Turbo configuration
506 // as the radius of either the circle tangent to the ladder or the circle
507 // passing for the ladder's lower vertex
508 //
509 // Input:
510 //         none (all needed parameters are class members)
511 //
512 // Output:
513 //
514 // Return:
515 //        the radius of the container if >0, else flag to use the lower vertex
516 //
517 // Created:      08 Mar 2012  Mario Sitta
518 //
519
520   Double_t rr, delta, z, lladd, rladd;
521
522   if (fLadderThick > 89.) // Very big angle: avoid overflows since surely
523     return -1;            // the radius from lower vertex is the right value
524
525   rladd = fLayRadius + 0.5*fLadderThick;
526   delta = (0.5*fLadderThick)/CosD(fLadderTilt);
527   z     = (0.5*fLadderThick)*TanD(fLadderTilt);
528
529   rr = rladd - delta;
530   lladd = (0.5*fLadderWidth) - z;
531
532   if ( (rr*SinD(fLadderTilt) < lladd) )
533     return (rr*CosD(fLadderTilt));
534   else
535     return -1;
536 }
537
538 //________________________________________________________________________
539 void AliITSUv11Layer::SetLadderTilt(const Double_t t){
540 //
541 // Sets the Ladder tilt angle (for turbo layers only)
542 //
543 // Input:
544 //         t :  the ladder tilt angle
545 //
546 // Output:
547 //
548 // Return:
549 //
550 // Created:      08 Jul 2011  Mario Sitta
551 //
552
553   if (fIsTurbo)
554     fLadderTilt = t;
555   else
556     AliError("Not a Turbo layer");
557
558 }
559
560 //________________________________________________________________________
561 void AliITSUv11Layer::SetLadderWidth(const Double_t w){
562 //
563 // Sets the Ladder width (for turbo layers only)
564 //
565 // Input:
566 //         w :  the ladder width
567 //
568 // Output:
569 //
570 // Return:
571 //
572 // Created:      08 Jul 2011  Mario Sitta
573 //
574
575   if (fIsTurbo)
576     fLadderWidth = w;
577   else
578     AliError("Not a Turbo layer");
579
580 }