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"
42 const Double_t AliITSUv11Layer::fgkDefaultSensorThick = 300*fgkmicron;
43 const Double_t AliITSUv11Layer::fgkDefaultLadderThick = 1*fgkcm;
45 ClassImp(AliITSUv11Layer)
49 //________________________________________________________________________
50 AliITSUv11Layer::AliITSUv11Layer():
65 // Standard constructor
69 //________________________________________________________________________
70 AliITSUv11Layer::AliITSUv11Layer(Int_t debug):
71 AliITSv11Geometry(debug),
85 // Constructor setting debugging level
89 //________________________________________________________________________
90 AliITSUv11Layer::AliITSUv11Layer(Int_t lay, Int_t debug):
91 AliITSv11Geometry(debug),
105 // Constructor setting layer number and debugging level
109 //________________________________________________________________________
110 AliITSUv11Layer::AliITSUv11Layer(Int_t lay, Bool_t turbo, Int_t debug):
111 AliITSv11Geometry(debug),
125 // Constructor setting layer number and debugging level
126 // for a "turbo" layer (i.e. where ladders overlap in phi)
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),
150 //________________________________________________________________________
151 AliITSUv11Layer& AliITSUv11Layer::operator=(const AliITSUv11Layer &s)
154 // Assignment operator
156 if(&s == this) return *this;
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;
172 //________________________________________________________________________
173 AliITSUv11Layer::~AliITSUv11Layer() {
179 //________________________________________________________________________
180 void AliITSUv11Layer::CreateLayer(TGeoVolume *moth,
181 const TGeoManager *mgr){
183 // Creates the actual Layer and places inside its mother volume
186 // moth : the TGeoVolume owing the volume structure
187 // mgr : the GeoManager (used only to get the proper material)
193 // Created: 17 Jun 2011 Mario Sitta
194 // Updated: 08 Jul 2011 Mario Sitta
201 Double_t xpos, ypos, zpos;
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));
211 if (fLadderThick <= 0) {
212 AliInfo(Form("Ladder thickness wrong or not set (%f), using default (%f)",
213 fLadderThick,fgkDefaultLadderThick));
214 fLadderThick = fgkDefaultLadderThick;
217 if (fSensorThick <= 0) {
218 AliInfo(Form("Sensor thickness wrong or not set (%f), using default (%f)",
219 fSensorThick,fgkDefaultSensorThick));
220 fSensorThick = fgkDefaultSensorThick;
223 if (fSensorThick > fLadderThick) {
224 AliWarning(Form("Sensor thickness (%f) is greater than ladder thickness (%f), fixing",
225 fSensorThick,fLadderThick));
226 fSensorThick = fLadderThick;
230 // If a Turbo layer is requested, do it and exit
232 CreateLayerTurbo(moth, mgr);
237 // First create the ladder container
238 alpha = (360./(2*fNLadders))*TMath::DegToRad();
239 fLadderWidth = fLayRadius*TMath::Tan(alpha);
241 rmin = 0.98*fLayRadius;
242 rmax = 1.02*TMath::Sqrt( fLadderWidth*fLadderWidth +
243 (rmin+fLadderThick)*(rmin+fLadderThick) );
245 TGeoTube *layer = new TGeoTube(rmin, rmax, 0.5*fZLength);
248 // We have all shapes: now create the real volumes
249 TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$");
251 snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSLayerPattern(),fLayerNumber);
252 TGeoVolume *layVol = new TGeoVolume(volname, layer, medAir);
253 layVol->SetUniqueID(fDetTypeID);
255 // layVol->SetVisibility(kFALSE);
256 layVol->SetVisibility(kTRUE);
257 layVol->SetLineColor(1);
259 TGeoVolume *laddVol = CreateLadder();
262 // Now build up the layer
263 alpha = 360./fNLadders;
264 Double_t r = fLayRadius + ((TGeoBBox*)laddVol->GetShape())->GetDY();
265 for (Int_t j=0; j<fNLadders; j++) {
266 Double_t theta = j*alpha;
267 xpos = r*SinD(theta);
268 ypos = r*CosD(theta);
270 layVol->AddNode(laddVol, j, new TGeoCombiTrans( xpos, ypos, zpos,
271 new TGeoRotation("",-theta,0,0)));
275 // Finally put everything in the mother volume
276 moth->AddNode(layVol, 1, 0);
279 // Upgrade geometry is served
283 //________________________________________________________________________
284 void AliITSUv11Layer::CreateLayerTurbo(TGeoVolume *moth,
285 const TGeoManager *mgr){
287 // Creates the actual Layer and places inside its mother volume
288 // A so-called "turbo" layer is a layer where ladders overlap in phi
289 // User can set width and tilt angle, no check is performed here
290 // to avoid volume overlaps
293 // moth : the TGeoVolume owing the volume structure
294 // mgr : the GeoManager (used only to get the proper material)
300 // Created: 08 Jul 2011 Mario Sitta
301 // Updated: 08 Mar 2012 Mario Sitta Correct way to compute container R
307 Double_t rmin, rmax, rladd, rcont, d;
308 Double_t xpos, ypos, zpos;
309 Double_t alpha, gamma;
312 // Check if the user set the proper (remaining) parameters
313 if (fLadderWidth <= 0)
314 AliFatal(Form("Wrong ladder width (%f)",fLadderWidth));
315 if (TMath::Abs(fLadderTilt) > 45)
316 AliWarning(Form("Ladder tilt angle (%f) greater than 45deg",fLadderTilt));
319 // First create the ladder container
320 // d is half the diagonal of the ladder section
321 // rladd is the radius at the ladder's center-of-gravity
322 // alpha here is the angle between the diagonal and rladd
323 d = 0.5*TMath::Sqrt(fLadderThick*fLadderThick + fLadderWidth*fLadderWidth);
324 alpha = TMath::ACos(0.5*fLadderThick/d)*TMath::RadToDeg();
325 gamma = alpha - fLadderTilt;
326 rladd = fLayRadius + 0.5*fLadderThick;
328 // rcont is the radius of the air container
329 rcont = RadiusOfTurboContainer();
334 rmin = 0.98*TMath::Sqrt( rladd*rladd + d*d - 2*rladd*d*CosD(gamma) );
336 rmax = 1.02*TMath::Sqrt( rladd*rladd + d*d + 2*rladd*d*CosD(gamma) );
338 TGeoTube *layer = new TGeoTube(rmin, rmax, 0.5*fZLength);
341 // We have all shapes: now create the real volumes
342 TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$");
344 snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSLayerPattern(), fLayerNumber);
345 TGeoVolume *layVol = new TGeoVolume(volname, layer, medAir);
346 layVol->SetUniqueID(fDetTypeID);
347 layVol->SetVisibility(kTRUE);
348 layVol->SetLineColor(1);
349 TGeoVolume *laddVol = CreateLadder();
352 // Now build up the layer
355 // Now build up the layer
356 alpha = 360./fNLadders;
357 Double_t r = fLayRadius + ((TGeoBBox*)laddVol->GetShape())->GetDY();
358 for (Int_t j=0; j<fNLadders; j++) {
359 Double_t theta = j*alpha;
360 xpos = r*SinD(theta);
361 ypos = r*CosD(theta);
363 layVol->AddNode(laddVol, j, new TGeoCombiTrans( xpos, ypos, zpos,
364 new TGeoRotation("",-theta+fLadderTilt,0,0)));
368 // Finally put everything in the mother volume
369 moth->AddNode(layVol, 1, 0);
374 //________________________________________________________________________
375 TGeoVolume* AliITSUv11Layer::CreateLadder(const TGeoManager *mgr){
377 // Creates the actual Ladder
380 // mgr : the GeoManager (used only to get the proper material)
386 // Created: 22 Jun 2011 Mario Sitta
390 Double_t xlen, ylen, zlen;
391 Double_t xpos, ypos, zpos, zmod;
395 // First create all needed shapes
396 alpha = (360./(2*fNLadders))*TMath::DegToRad();
399 xlen = fLayRadius*TMath::Tan(alpha);
400 ylen = 0.5*fLadderThick;
403 TGeoBBox *ladder = new TGeoBBox(xlen, ylen, zlen);
406 // We have all shapes: now create the real volumes
407 TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$");
409 snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSLadderPattern(), fLayerNumber);
410 TGeoVolume *laddVol = new TGeoVolume(volname, ladder, medAir);
412 // laddVol->SetVisibility(kFALSE);
413 laddVol->SetVisibility(kTRUE);
414 laddVol->SetLineColor(2);
415 TGeoVolume *modVol = CreateModule(ladder->GetDX(), ladder->GetDY(),
419 // Now build up the ladder
420 zmod = ((TGeoBBox*)modVol->GetShape())->GetDZ();
421 for (Int_t j=0; j<fNModules; j++) {
424 zpos = -ladder->GetDZ() + j*2*zmod + zmod;
425 laddVol->AddNode(modVol, j, new TGeoTranslation(xpos, ypos, zpos));
429 // Done, return the ladder
433 //________________________________________________________________________
434 TGeoVolume* AliITSUv11Layer::CreateModule(const Double_t xlad,
437 const TGeoManager *mgr){
439 // Creates the actual Module
442 // xlad,ylad,zlad : the ladder dimensions
443 // mgr : the GeoManager (used only to get the proper material)
449 // Created: 22 Jun 2011 Mario Sitta
453 Double_t xlen, ylen, zlen;
454 Double_t xpos, ypos, zpos;
457 // First create all needed shapes
460 TGeoBBox *module = new TGeoBBox(xlad, ylad, zlad/fNModules);
463 xlen = module->GetDX();
464 ylen = 0.5*fSensorThick;
465 zlen = module->GetDZ();
466 TGeoBBox *sensor = new TGeoBBox(xlen, ylen, zlen);
469 // We have all shapes: now create the real volumes
470 TGeoMedium *medAir = mgr->GetMedium("ITS_AIR$");
471 TGeoMedium *medSi = mgr->GetMedium("ITS_SI$");
473 snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSModulePattern() ,fLayerNumber);
474 TGeoVolume *modVol = new TGeoVolume(volname, module, medAir);
475 modVol->SetVisibility(kFALSE);
476 modVol->SetLineColor(1);
478 snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSSensorPattern(), fLayerNumber);
479 TGeoVolume *sensVol = new TGeoVolume(volname, sensor, medSi);
480 sensVol->SetVisibility(kTRUE);
481 sensVol->SetLineColor(8);
482 sensVol->SetLineWidth(1);
483 sensVol->SetFillColor(sensVol->GetLineColor());
484 sensVol->SetFillStyle(4000); // 0% transparent
487 // Now build up the module
489 ypos = -module->GetDY() + sensor->GetDY();
492 modVol->AddNode(sensVol, 1, new TGeoTranslation(xpos, ypos, zpos));
495 // Done, return the module
499 //________________________________________________________________________
500 Double_t AliITSUv11Layer::RadiusOfTurboContainer(){
502 // Computes the inner radius of the air container for the Turbo configuration
503 // as the radius of either the circle tangent to the ladder or the circle
504 // passing for the ladder's lower vertex
507 // none (all needed parameters are class members)
512 // the radius of the container if >0, else flag to use the lower vertex
514 // Created: 08 Mar 2012 Mario Sitta
517 Double_t rr, delta, z, lladd, rladd;
519 if (fLadderThick > 89.) // Very big angle: avoid overflows since surely
520 return -1; // the radius from lower vertex is the right value
522 rladd = fLayRadius + 0.5*fLadderThick;
523 delta = (0.5*fLadderThick)/CosD(fLadderTilt);
524 z = (0.5*fLadderThick)*TanD(fLadderTilt);
527 lladd = (0.5*fLadderWidth) - z;
529 if ( (rr*SinD(fLadderTilt) < lladd) )
530 return (rr*CosD(fLadderTilt));
535 //________________________________________________________________________
536 void AliITSUv11Layer::SetLadderTilt(const Double_t t){
538 // Sets the Ladder tilt angle (for turbo layers only)
541 // t : the ladder tilt angle
547 // Created: 08 Jul 2011 Mario Sitta
553 AliError("Not a Turbo layer");
557 //________________________________________________________________________
558 void AliITSUv11Layer::SetLadderWidth(const Double_t w){
560 // Sets the Ladder width (for turbo layers only)
563 // w : the ladder width
569 // Created: 08 Jul 2011 Mario Sitta
575 AliError("Not a Turbo layer");