1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
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.
21 // Mario Sitta <sitta@to.infn.it>
22 //*************************************************************************
25 /* $Id: AliITSUv11Layer.cxx */
26 // General Root includes
28 // Root Geometry includes
30 #include <TGeoManager.h>
31 #include <TGeoVolume.h>
34 #include <TGeoTube.h> // contaings TGeoTubeSeg
37 #include <TGeoCompositeShape.h>
38 #include <TGeoMatrix.h>
39 #include "AliITSUv11Layer.h"
40 #include "AliITSUGeomTGeo.h"
41 using namespace TMath;
43 const Double_t AliITSUv11Layer::fgkDefaultSensorThick = 300*fgkmicron;
44 const Double_t AliITSUv11Layer::fgkDefaultLadderThick = 1*fgkcm;
46 ClassImp(AliITSUv11Layer)
50 //________________________________________________________________________
51 AliITSUv11Layer::AliITSUv11Layer():
67 // Standard constructor
71 //________________________________________________________________________
72 AliITSUv11Layer::AliITSUv11Layer(Int_t debug):
73 AliITSv11Geometry(debug),
88 // Constructor setting debugging level
92 //________________________________________________________________________
93 AliITSUv11Layer::AliITSUv11Layer(Int_t lay, Int_t debug):
94 AliITSv11Geometry(debug),
109 // Constructor setting layer number and debugging level
113 //________________________________________________________________________
114 AliITSUv11Layer::AliITSUv11Layer(Int_t lay, Bool_t turbo, Int_t debug):
115 AliITSv11Geometry(debug),
130 // Constructor setting layer number and debugging level
131 // for a "turbo" layer (i.e. where ladders overlap in phi)
135 //________________________________________________________________________
136 AliITSUv11Layer::AliITSUv11Layer(const AliITSUv11Layer &s):
137 AliITSv11Geometry(s.GetDebug()),
138 fLayerNumber(s.fLayerNumber),
140 fLayRadius(s.fLayRadius),
141 fZLength(s.fZLength),
142 fSensorThick(s.fSensorThick),
143 fLadderThick(s.fLadderThick),
144 fLadderWidth(s.fLadderWidth),
145 fLadderTilt(s.fLadderTilt),
146 fNLadders(s.fNLadders),
147 fNModules(s.fNModules),
156 //________________________________________________________________________
157 AliITSUv11Layer& AliITSUv11Layer::operator=(const AliITSUv11Layer &s)
160 // Assignment operator
162 if(&s == this) return *this;
164 fLayerNumber = s.fLayerNumber;
166 fLayRadius = s.fLayRadius;
167 fZLength = s.fZLength;
168 fSensorThick = s.fSensorThick;
169 fLadderThick = s.fLadderThick;
170 fLadderWidth = s.fLadderWidth;
171 fLadderTilt = s.fLadderTilt;
172 fNLadders = s.fNLadders;
173 fNModules = s.fNModules;
174 fIsTurbo = s.fIsTurbo;
175 fDetTypeID = s.fDetTypeID;
179 //________________________________________________________________________
180 AliITSUv11Layer::~AliITSUv11Layer() {
186 //________________________________________________________________________
187 void AliITSUv11Layer::CreateLayer(TGeoVolume *moth,const TGeoManager *mgr){
189 // Creates the actual Layer and places inside its mother volume
192 // moth : the TGeoVolume owing the volume structure
193 // mgr : the GeoManager (used only to get the proper material)
199 // Created: 17 Jun 2011 Mario Sitta
200 // Updated: 08 Jul 2011 Mario Sitta
205 Double_t xpos, ypos, zpos;
209 // Check if the user set the proper parameters
210 if (fLayRadius <= 0) AliFatal(Form("Wrong layer radius (%f)",fLayRadius));
211 if (fZLength <= 0) AliFatal(Form("Wrong layer length (%f)",fZLength));
212 if (fNLadders <= 0) AliFatal(Form("Wrong number of ladders (%d)",fNLadders));
213 if (fNModules <= 0) AliFatal(Form("Wrong number of modules (%d)",fNModules));
215 if (fLadderThick <= 0) {
216 AliInfo(Form("Ladder thickness wrong or not set (%f), using default (%f)",
217 fLadderThick,fgkDefaultLadderThick));
218 fLadderThick = fgkDefaultLadderThick;
221 if (fSensorThick <= 0) {
222 AliInfo(Form("Sensor thickness wrong or not set (%f), using default (%f)",
223 fSensorThick,fgkDefaultSensorThick));
224 fSensorThick = fgkDefaultSensorThick;
227 if (fSensorThick > fLadderThick) {
228 AliWarning(Form("Sensor thickness (%f) is greater than ladder thickness (%f), fixing",
229 fSensorThick,fLadderThick));
230 fSensorThick = fLadderThick;
234 // If a Turbo layer is requested, do it and exit
236 CreateLayerTurbo(moth, mgr);
241 // First create the ladder container
242 alpha = (360./(2*fNLadders))*DegToRad();
244 // fLadderWidth = fLayRadius*Tan(alpha);
246 rmin = 0.98*fLayRadius;
247 rmax = 1.02*Sqrt( fLadderWidth*fLadderWidth +
248 (rmin+fLadderThick)*(rmin+fLadderThick) );
250 TGeoTube *layer = new TGeoTube(rmin, rmax, 0.5*fZLength);
253 // We have all shapes: now create the real volumes
254 TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$");
256 snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSLayerPattern(),fLayerNumber);
257 TGeoVolume *layVol = new TGeoVolume(volname, layer, medAir);
258 layVol->SetUniqueID(fDetTypeID);
260 // layVol->SetVisibility(kFALSE);
261 layVol->SetVisibility(kTRUE);
262 layVol->SetLineColor(1);
264 TGeoVolume *laddVol = CreateLadder();
267 // Now build up the layer
268 alpha = 360./fNLadders;
269 Double_t r = fLayRadius + ((TGeoBBox*)laddVol->GetShape())->GetDY();
270 for (Int_t j=0; j<fNLadders; j++) {
271 Double_t phi = j*alpha + fPhi0;
272 xpos = r*CosD(phi);// r*SinD(-phi);
273 ypos = r*SinD(phi);// r*CosD(-phi);
276 layVol->AddNode(laddVol, j, new TGeoCombiTrans( xpos, ypos, zpos,
277 new TGeoRotation("",phi,0,0)));
281 // Finally put everything in the mother volume
282 moth->AddNode(layVol, 1, 0);
285 // Upgrade geometry is served
289 //________________________________________________________________________
290 void AliITSUv11Layer::CreateLayerTurbo(TGeoVolume *moth,
291 const TGeoManager *mgr){
293 // Creates the actual Layer and places inside its mother volume
294 // A so-called "turbo" layer is a layer where ladders overlap in phi
295 // User can set width and tilt angle, no check is performed here
296 // to avoid volume overlaps
299 // moth : the TGeoVolume owing the volume structure
300 // mgr : the GeoManager (used only to get the proper material)
306 // Created: 08 Jul 2011 Mario Sitta
307 // Updated: 08 Mar 2012 Mario Sitta Correct way to compute container R
313 Double_t rmin, rmax, rladd, rcont, d;
314 Double_t xpos, ypos, zpos;
315 Double_t alpha, gamma;
318 // Check if the user set the proper (remaining) parameters
319 if (fLadderWidth <= 0)
320 AliFatal(Form("Wrong ladder width (%f)",fLadderWidth));
321 if (Abs(fLadderTilt) > 45)
322 AliWarning(Form("Ladder tilt angle (%f) greater than 45deg",fLadderTilt));
325 // First create the ladder container
326 // d is half the diagonal of the ladder section
327 // rladd is the radius at the ladder's center-of-gravity
328 // alpha here is the angle between the diagonal and rladd
329 d = 0.5*Sqrt(fLadderThick*fLadderThick + fLadderWidth*fLadderWidth);
330 alpha = ACos(0.5*fLadderThick/d)*RadToDeg();
331 gamma = alpha - fLadderTilt;
332 rladd = fLayRadius + 0.5*fLadderThick;
334 // rcont is the radius of the air container
335 rcont = RadiusOfTurboContainer();
340 rmin = 0.98*Sqrt( rladd*rladd + d*d - 2*rladd*d*CosD(gamma) );
342 rmax = 1.02*Sqrt( rladd*rladd + d*d + 2*rladd*d*CosD(gamma) );
344 TGeoTube *layer = new TGeoTube(rmin, rmax, 0.5*fZLength);
347 // We have all shapes: now create the real volumes
348 TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$");
350 snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSLayerPattern(), fLayerNumber);
351 TGeoVolume *layVol = new TGeoVolume(volname, layer, medAir);
352 layVol->SetUniqueID(fDetTypeID);
353 layVol->SetVisibility(kTRUE);
354 layVol->SetLineColor(1);
355 TGeoVolume *laddVol = CreateLadder();
358 // Now build up the layer
361 // Now build up the layer
362 alpha = 360./fNLadders;
363 Double_t r = fLayRadius + ((TGeoBBox*)laddVol->GetShape())->GetDY();
364 for (Int_t j=0; j<fNLadders; j++) {
365 Double_t phi = j*alpha + fPhi0;
366 xpos = r*CosD(phi);// r*SinD(-phi);
367 ypos = r*SinD(phi);// r*CosD(-phi);
370 layVol->AddNode(laddVol, j, new TGeoCombiTrans( xpos, ypos, zpos,
371 new TGeoRotation("", phi-fLadderTilt,0,0)));
375 // Finally put everything in the mother volume
376 moth->AddNode(layVol, 1, 0);
381 //________________________________________________________________________
382 TGeoVolume* AliITSUv11Layer::CreateLadder(const TGeoManager *mgr){
384 // Creates the actual Ladder
387 // mgr : the GeoManager (used only to get the proper material)
393 // Created: 22 Jun 2011 Mario Sitta
397 Double_t xlen, ylen, zlen;
398 Double_t xpos, ypos, zpos, zmod;
402 // First create all needed shapes
403 alpha = (360./(2*fNLadders))*DegToRad();
406 xlen = fLayRadius*Tan(alpha);
407 if (fIsTurbo) xlen = 0.5*fLadderWidth;
408 ylen = 0.5*fLadderThick;
411 TGeoBBox *ladder = new TGeoBBox(xlen, ylen, zlen);
414 // We have all shapes: now create the real volumes
415 TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$");
417 snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSLadderPattern(), fLayerNumber);
418 TGeoVolume *laddVol = new TGeoVolume(volname, ladder, medAir);
420 // laddVol->SetVisibility(kFALSE);
421 laddVol->SetVisibility(kTRUE);
422 laddVol->SetLineColor(2);
423 TGeoVolume *modVol = CreateModule(ladder->GetDX(), ladder->GetDY(),
427 // Now build up the ladder
428 zmod = ((TGeoBBox*)modVol->GetShape())->GetDZ();
429 for (Int_t j=0; j<fNModules; j++) {
432 zpos = -ladder->GetDZ() + j*2*zmod + zmod;
433 laddVol->AddNode(modVol, j, new TGeoTranslation(xpos, ypos, zpos));
437 // Done, return the ladder
441 //________________________________________________________________________
442 TGeoVolume* AliITSUv11Layer::CreateModule(const Double_t xlad,
445 const TGeoManager *mgr){
447 // Creates the actual Module
450 // xlad,ylad,zlad : the ladder dimensions
451 // mgr : the GeoManager (used only to get the proper material)
457 // Created: 22 Jun 2011 Mario Sitta
461 Double_t xlen, ylen, zlen;
462 Double_t xpos, ypos, zpos;
465 // First create all needed shapes
468 TGeoBBox *module = new TGeoBBox(xlad, ylad, zlad/fNModules);
471 xlen = module->GetDX();
472 ylen = 0.5*fSensorThick;
473 zlen = module->GetDZ();
474 TGeoBBox *sensor = new TGeoBBox(xlen, ylen, zlen);
477 // We have all shapes: now create the real volumes
478 // TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$");
479 TGeoMedium *medSi = mgr->GetMedium("ITS_SI$");
481 snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSModulePattern() ,fLayerNumber);
482 // TGeoVolume *modVol = new TGeoVolume(volname, module, medAir);
483 TGeoVolume *modVol = new TGeoVolume(volname, module, medSi);
484 modVol->SetVisibility(kFALSE);
485 modVol->SetLineColor(1);
487 snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSSensorPattern(), fLayerNumber);
488 TGeoVolume *sensVol = new TGeoVolume(volname, sensor, medSi);
489 sensVol->SetVisibility(kTRUE);
490 sensVol->SetLineColor(8);
491 sensVol->SetLineWidth(1);
492 sensVol->SetFillColor(sensVol->GetLineColor());
493 sensVol->SetFillStyle(4000); // 0% transparent
496 // Now build up the module
498 ypos = -module->GetDY() + sensor->GetDY();
501 modVol->AddNode(sensVol, 1, new TGeoTranslation(xpos, ypos, zpos));
504 // Done, return the module
508 //________________________________________________________________________
509 Double_t AliITSUv11Layer::RadiusOfTurboContainer(){
511 // Computes the inner radius of the air container for the Turbo configuration
512 // as the radius of either the circle tangent to the ladder or the circle
513 // passing for the ladder's lower vertex
516 // none (all needed parameters are class members)
521 // the radius of the container if >0, else flag to use the lower vertex
523 // Created: 08 Mar 2012 Mario Sitta
526 Double_t rr, delta, z, lladd, rladd;
528 if (fLadderThick > 89.) // Very big angle: avoid overflows since surely
529 return -1; // the radius from lower vertex is the right value
531 rladd = fLayRadius + 0.5*fLadderThick;
532 delta = (0.5*fLadderThick)/CosD(fLadderTilt);
533 z = (0.5*fLadderThick)*TanD(fLadderTilt);
536 lladd = (0.5*fLadderWidth) - z;
538 if ( (rr*SinD(fLadderTilt) < lladd) )
539 return (rr*CosD(fLadderTilt));
544 //________________________________________________________________________
545 void AliITSUv11Layer::SetLadderTilt(const Double_t t)
548 // Sets the Ladder tilt angle (for turbo layers only)
551 // t : the ladder tilt angle
557 // Created: 08 Jul 2011 Mario Sitta
563 AliError("Not a Turbo layer");
567 //________________________________________________________________________
568 void AliITSUv11Layer::SetLadderWidth(const Double_t w){
570 // Sets the Ladder width (for turbo layers only)
573 // w : the ladder width
579 // Created: 08 Jul 2011 Mario Sitta
585 AliError("Not a Turbo layer");