Add protectio skipping QA for detectors not present in the simulation
[u/mrichter/AliRoot.git] / ITS / AliITSv11GeometrySPD.cxx
CommitLineData
db486a6e 1/**************************************************************************
59da35b6 2 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
db486a6e 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 **************************************************************************/
592651e2 15//
db486a6e 16// This class Defines the Geometry for the ITS services and support cones
17// outside of the ceneteral volume (except for the Ceneteral support
18// cylinders. Other classes define the rest of the ITS. Specificaly the ITS
592651e2 19// The SSD support cone, SSD Support centeral cylinder, SDD support cone,
db486a6e 20// The SDD cupport centeral cylinder, the SPD Thermal Sheald, The supports
21// and cable trays on both the RB26 (muon dump) and RB24 sides, and all of
592651e2 22// the cabling from the ladders/stave ends out past the TPC.
23//
db486a6e 24
543b7370 25/* $Id$ */
592651e2 26
db486a6e 27// General Root includes
28#include <Riostream.h>
29#include <TMath.h>
30#include <TLatex.h>
31#include <TCanvas.h>
32#include <TPolyLine.h>
297369a1 33#include <TPolyMarker.h>
db486a6e 34// Root Geometry includes
db486a6e 35#include <TGeoVolume.h>
592651e2 36#include <TGeoTube.h> // contains TGeoTubeSeg
db486a6e 37#include <TGeoArb8.h>
38#include <TGeoEltu.h>
39#include <TGeoXtru.h>
db486a6e 40#include <TGeoMatrix.h>
a53658c6 41#include <TGeoMaterial.h>
42#include <TGeoMedium.h>
592651e2 43#include <TGeoCompositeShape.h>
44// AliRoot includes
a53658c6 45#include "AliMagF.h"
46#include "AliRun.h"
592651e2 47// Declaration file
db486a6e 48#include "AliITSv11GeometrySPD.h"
49
50ClassImp(AliITSv11GeometrySPD)
51
52#define SQ(A) (A)*(A)
53
54//______________________________________________________________________
59da35b6 55Int_t AliITSv11GeometrySPD::CreateSPDCentralMaterials(Int_t &medOffset, Int_t &matOffset) const
592651e2 56{
59da35b6 57 // Define the specific materials used for the ITS SPD central
a53658c6 58 // detectors. Note, These are the same old names. By the ALICE
59 // naming convension, these should start out at ITS SPD ....
60 // This data has been taken from AliITSvPPRasymmFMD::CreateMaterials().
61 // Intputs:
62 // Int_t &medOffset The starting number of the list of media
63 // Int_t &matOffset The starting number of the list of Materials
64 // Outputs:
65 // Int_t &medOffset The ending number of the list of media
66 // Int_t &matOffset The ending number of the list of Materials
67 // Return:
68 // the last material number used +1 (the next avaiable material number).
69 //Begin_Html
70 /*
71 <img src="http://alice.pd.infn.it/latestdr/all-sections-module.ps"
72 title="SPD Sector drawing with all cross sections defined">
73 <p>The SPD Sector definition.
74 <img src="http://alice.pd.infn.it/latestdr/assembly-10-modules.ps"
75 titile="SPD All Sectors end view with thermal sheald">
76 <p>The SPD all sector end view with thermal sheald.
77 <img src="http://alice.pd.infn.it/latestdr/assembly.ps"
78 title="SPD side view cross section">
79 <p>SPD side view cross section with condes and thermal shealds.
80 <img src="http://alice.pd.infn.it/latestdr/SECTION-A_A.jpg"
81 title="Cross setion A-A"><p>Cross section A-A
82 <img src="http://alice.pd.infn.it/latestdr/SECTION-B_B.jpg"
83 title="Cross section B-B"><p>Cross section B-B
84 <img src="http://alice.pd.infn.it/latestdr/SECTION-C_C.jpg"
85 title-"Cross section C-C"><p>Cross section C-C
86 <img src="http://alice.pd.infn.it/latestdr/SECTION-D_D.jpg"
87 title="Cross section D-D"><p>Cross section D-D
88 <img src="http://alice.pd.infn.it/latestdr/SECTION-F_F.jpg"
89 title="Cross section F-F"><p>Cross section F-F
90 <img src="http://alice.pd.infn.it/latestdr/SECTION-G_G.jpg"
91 title="Cross section G-G"><p>Cross section G-G
92 */
93 //End_Html
94 const Double_t ktmaxfd = 0.1*fgkDegree; // Degree
95 const Double_t kstemax = 1.0*fgkcm; // cm
96 const Double_t kdeemax = 0.1; // Fraction of particle's energy 0<deemax<=1
97 const Double_t kepsil = 1.0E-4; //
98 const Double_t kstmin = 0.0*fgkcm; // cm "Default value used"
99 const Double_t ktmaxfdAir = 0.1*fgkDegree; // Degree
100 const Double_t kstemaxAir = 1.0000E+00*fgkcm; // cm
297369a1 101 const Double_t kdeemaxAir = 0.1; //Fraction of particle's energy 0<deemax<=1
a53658c6 102 const Double_t kepsilAir = 1.0E-4;//
103 const Double_t kstminAir = 0.0*fgkcm; // cm "Default value used"
104 const Double_t ktmaxfdSi = 0.1*fgkDegree; // .10000E+01; // Degree
105 const Double_t kstemaxSi = 0.0075*fgkcm; // .10000E+01; // cm
106 const Double_t kdeemaxSi = 0.1; // Fraction of particle's energy 0<deemax<=1
107 const Double_t kepsilSi = 1.0E-4;//
108 const Double_t kstminSi = 0.0*fgkcm; // cm "Default value used"
109 //
110 Int_t matindex=matOffset;
111 Int_t medindex=medOffset;
112 Double_t params[8]={8*0.0};
113 TGeoMaterial *mat;
114 TGeoMixture *mix;
115 TGeoMedium *med;
116 //
117 Int_t ifield = (gAlice->Field()->Integ());
118 Double_t fieldm = (gAlice->Field()->Max());
119 params[1] = (Double_t) ifield;
120 params[2] = fieldm;
121 params[3] = ktmaxfdSi;
122 params[4] = kstemaxSi;
123 params[5] = kdeemaxSi;
124 params[6] = kepsilSi;
125 params[7] = kstminSi;
126
127 mat = new TGeoMaterial("SI",28.086,14.0,2.33*fgkgcm3,
128 TGeoMaterial::kMatStateSolid,25.0*fgkCelsius,
129 0.0*fgkPascal);
130 mat->SetIndex(matindex);
131 med = new TGeoMedium("SI",medindex++,mat,params);
132 //med = new TGeoMedium("SI",medindex++,matindex++,0,ifield,
133 // fieldm,ktmaxfdSi,kstemaxSi,kdeemaxSi,kepsilSi,kstminSi);
134 //
135 mat = new TGeoMaterial("SPD SI CHIP",28.086,14.0,2.33*fgkgcm3,
136 TGeoMaterial::kMatStateSolid,25.0*fgkCelsius,
137 0.0*fgkPascal);
138 mat->SetIndex(matindex);
139 med = new TGeoMedium("SPD SI CHIP",medindex++,mat,params);
140 //med = new TGeoMedium("SPD SI CHIP",medindex++,matindex++,0,ifield,
141 // fieldm,ktmaxfdSi,kstemaxSi,kdeemaxSi,kepsilSi,kstminSi);
142 //
143 mat = new TGeoMaterial("SPD SI BUS",28.086,14.0,2.33*fgkgcm3,
144 TGeoMaterial::kMatStateSolid,25.0*fgkCelsius,
145 0.0*fgkPascal);
146 mat->SetIndex(matindex);
147 med = new TGeoMedium("SPD SI BUS",medindex++,mat,params);
148 //med = new TGeoMedium("SPD SI BUS",medindex++,matindex++,0,ifield,
149 // fieldm,ktmaxfdSi,kstemaxSi,kdeemaxSi,kepsilSi,kstminSi);
150 //
297369a1 151 // Carbon fiber by fractional weight "C (M55J)"
152 mix = new TGeoMixture("C (M55J)",4,1.9866*fgkgcm3);
a53658c6 153 mix->SetIndex(matindex);
297369a1 154 // Carbon by fractional weight
155 mix->DefineElement(0,12.0107,6.0,0.908508078);
156 // Nitrogen by fractional weight
157 mix->DefineElement(1,14.0067,7.0,0.010387573);
158 // Oxigen by fractional weight
159 mix->DefineElement(2,15.9994,8.0,0.055957585);
160 // Hydrogen by fractional weight
161 mix->DefineElement(3,1.00794,1.0,0.025146765);
a53658c6 162 mix->SetPressure(0.0*fgkPascal);
163 mix->SetTemperature(25.0*fgkCelsius);
164 mix->SetState(TGeoMaterial::kMatStateSolid);
165 params[3] = ktmaxfd;
166 params[4] = kstemax;
167 params[5] = kdeemax;
168 params[6] = kepsil;
169 params[7] = kstmin;
170 med = new TGeoMedium("ITSspdCarbonFiber",medindex++,mix,params);
171 //med = new TGeoMedium("ITSspdCarbonFiber",medindex++,matindex++,0,ifield,
172 // fieldm,ktmaxfd,kstemax,kdeemax,kepsil,kstmin);
173 //
297369a1 174 // Carbon fiber by fractional weight
175 mix = new TGeoMixture("Air",4,1.20479E-3*fgkgcm3);
a53658c6 176 mix->SetIndex(matindex);
177 mix->DefineElement(0,12.0107,6.0,0.000124); // Carbon by fractional weight
178 mix->DefineElement(1,14.0067,7.0,0.755267); // Nitrogen by fractional weight
179 mix->DefineElement(2,15.9994,8.0,0.231781); // Oxigen by fractional weight
180 mix->DefineElement(3,39.948,18.0,0.012827); // Argon by fractional weight
181 mix->SetPressure(101325.0*fgkPascal); // 1 atmosphere
182 mix->SetTemperature(25.0*fgkCelsius);
183 mix->SetState(TGeoMaterial::kMatStateGas);
184 params[3] = ktmaxfdAir;
185 params[4] = kstemaxAir;
186 params[5] = kdeemaxAir;
187 params[6] = kepsilAir;
188 params[7] = kstminAir;
189 med = new TGeoMedium("ITSspdAir",medindex++,mix,params);
190 //med = new TGeoMedium("ITSspdAir",medindex++,matindex++,0,ifield,
191 // fieldm,ktmaxfdAir,kstemaxAir,kdeemaxAir,kepsilAir,kstminAir);
192 //
297369a1 193 // Carbon fiber by fractional weight
194 mix = new TGeoMixture("INOX",9,8.03*fgkgcm3);
a53658c6 195 mix->SetIndex(matindex);
196 mix->DefineElement(0,12.0107, 6.0,0.0003); // Carbon by fractional weight
197 mix->DefineElement(1,54.9380,25.0,0.02); // Iron by fractional weight
198 mix->DefineElement(2,28.0855,14.0,0.01); // Sodium by fractional weight
199 mix->DefineElement(3,30.9738,15.0,0.00045); // by fractional weight
200 mix->DefineElement(4,32.066 ,16.0,0.0003); // by fractional weight
201 mix->DefineElement(5,58.6928,28.0,0.12); // Nickel by fractional weight
202 mix->DefineElement(6,55.9961,24.0,0.17); // by fractional weight
203 mix->DefineElement(7,95.84 ,42.0,0.025); // by fractional weight
204 mix->DefineElement(8,55.845 ,26.0,0.654); // by fractional weight
205 mix->SetPressure(0.0*fgkPascal); //
206 mix->SetTemperature(25.0*fgkCelsius);
207 mix->SetState(TGeoMaterial::kMatStateSolid);
208 params[3] = ktmaxfdAir;
209 params[4] = kstemaxAir;
210 params[5] = kdeemaxAir;
211 params[6] = kepsilAir;
212 params[7] = kstminAir;
213 med = new TGeoMedium("ITSspdStainlessSteel",medindex++,mix,params);
297369a1 214 //med =new TGeoMedium("ITSspdStainlessSteel",medindex++,matindex++,0,ifield,
a53658c6 215 // fieldm,ktmaxfdAir,kstemaxAir,kdeemaxAir,kepsilAir,kstminAir);
216 //
297369a1 217 // Carbon fiber by fractional weight
a53658c6 218 mix->SetIndex(matindex);
297369a1 219 mix = new TGeoMixture("Freon",2,1.63*fgkgcm3);
a53658c6 220 mix->DefineElement(0,12.0107,6.0,4); // Carbon by fractional weight
221 mix->DefineElement(1,18.9984032,9.0,10); // Florine by fractional weight
222 mix->SetPressure(101325.0*fgkPascal); // 1 atmosphere
223 mix->SetTemperature(25.0*fgkCelsius);
224 mix->SetState(TGeoMaterial::kMatStateLiquid);
225 params[3] = ktmaxfdAir;
226 params[4] = kstemaxAir;
227 params[5] = kdeemaxAir;
228 params[6] = kepsilAir;
229 params[7] = kstminAir;
230 med = new TGeoMedium("ITSspdCoolingFluid",medindex++,mix,params);
231 //med = new TGeoMedium("ITSspdCoolingFluid",medindex++,matindex++,0,ifield,
232 // fieldm,ktmaxfdAir,kstemaxAir,kdeemaxAir,kepsilAir,kstminAir);
233 //
234 medOffset = medindex;
235 matOffset = matindex;
236 return matOffset;
237}
238//______________________________________________________________________
59da35b6 239void AliITSv11GeometrySPD::InitSPDCentral(Int_t offset,TVirtualMC *vmc) const {
240 // Do any SPD Central detector related initilizations, setting
a53658c6 241 // transport cuts for example.
242 // Some GEANT3 Physics switches
243 // "MULTS"
244 // Multiple scattering. The variable IMULS controls this process. For
245 // more information see [PHYS320 or 325 or 328].
246 // 0 - No multiple scattering.
592651e2 247 // 1 - Multiple scattering according to Moliļæ½re theory. Default setting.
a53658c6 248 // 2 - Same as 1. Kept for backward compatibility.
249 // 3 - Pure Gaussian scattering according to the Rossi formula.
250 // "DRAY"
297369a1 251 // delta ray production. The variable IDRAY controls this process.
252 // See [PHYS430]
a53658c6 253 // 0 - No delta rays production.
254 // 1 - delta rays production with generation of . Default setting.
255 // 2 - delta rays production without generation of .
256 // "LOSS"
257 // Continuous energy loss. The variable ILOSS controls this process.
258 // 0 - No continuous energy loss, IDRAY is set to 0.
259 // 1 - Continuous energy loss with generation of delta rays above
297369a1 260 // DCUTE (common/GCUTS/) and restricted Landau fluctuations below DCUTE.
a53658c6 261 // 2 - Continuous energy loss without generation of delta rays and full
262 // Landau-Vavilov-Gauss fluctuations. In this case the variable IDRAY
297369a1 263 // is forced to 0 to avoid double counting of fluctuations. Default
264 // setting.
a53658c6 265 // 3 - Same as 1, kept for backward compatibility.
297369a1 266 // 4 - Energy loss without fluctuation. The value obtained from the
267 // tables is used directly.
a53658c6 268 // Intputs:
269 // Int_t offset The material/medium index offset.
270 // TVirturalMC *vmc The pointer to the virtual Monte Carlo default gMC.
271 // Outputs:
272 // none.
273 // Return:
274 // none.
275 Int_t i,n=4;
276
277 for(i=0;i<n;i++){
278 vmc->Gstpar(i+offset,"CUTGAM",30.0*fgkKeV);
279 vmc->Gstpar(i+offset,"CUTELE",30.0*fgkKeV);
280 vmc->Gstpar(i+offset,"CUTNEU",30.0*fgkKeV);
281 vmc->Gstpar(i+offset,"CUTHAD",30.0*fgkKeV);
282 vmc->Gstpar(i+offset,"CUTMUO",30.0*fgkKeV);
283 vmc->Gstpar(i+offset,"BCUTE",30.0*fgkKeV);
284 vmc->Gstpar(i+offset,"BCUTM",30.0*fgkKeV);
285 vmc->Gstpar(i+offset,"DCUTE",30.0*fgkKeV);
286 vmc->Gstpar(i+offset,"DCUTM",30.0*fgkKeV);
287 //vmc->Gstpar(i+offset,"PPCUTM",);
288 //vmc->Gstpar(i+offset,"PAIR",);
289 //vmc->Gstpar(i+offset,"COMPT",);
290 //vmc->Gstpar(i+offset,"PHOT",);
291 //vmc->Gstpar(i+offset,"PFIS",);
292 vmc->Gstpar(i+offset,"DRAY",1);
293 //vmc->Gstpar(i+offset,"ANNI",);
294 //vmc->Gstpar(i+offset,"BREM",);
295 //vmc->Gstpar(i+offset,"HADR",);
296 //vmc->Gstpar(i+offset,"MUNU",);
297 //vmc->Gstpar(i+offset,"DCAY",);
298 vmc->Gstpar(i+offset,"LOSS",1);
299 //vmc->Gstpar(i+offset,"MULS",);
300 //vmc->Gstpar(i+offset,"GHCOR1",);
301 //vmc->Gstpar(i+offset,"BIRK1",);
302 //vmc->Gstpar(i+offset,"BRIK2",);
303 //vmc->Gstpar(i+offset,"BRIK3",);
304 //vmc->Gstpar(i+offset,"LABS",);
305 //vmc->Gstpar(i+offset,"SYNC",);
306 //vmc->Gstpar(i+offset,"STRA",);
307 } // end for i
308}
309//______________________________________________________________________
310void AliITSv11GeometrySPD::SPDSector(TGeoVolume *moth,TGeoManager *mgr){
311 // Position of the Carbon Fiber Assembly based on distance
312 // of closest point of SPD stave to beam pipe figures
313 // all-sections-modules.ps of 7.22mm at section A-A.
314 // Inputs:
315 // TGeoVolume *moth the mother volume which this
316 // object/volume is to be placed in.
317 // Outputs:
318 // none.
319 // Return:
320 // none.
321 const Double_t kSPDclossesStaveAA = 7.22*fgkmm;
322 const Double_t kSectorStartingAngle = -72.0*fgkDegree;
323 const Double_t kNSectorsTotal = 10.; // number
324 const Double_t kSectorRelativeAngle = 360./kNSectorsTotal*fgkDegree;
325 const Double_t kBeamPipeRadius = 0.5*60.0*fgkmm;
326 //
327 Int_t i;
328 Double_t angle,radiusSector,xAAtubeCenter0,yAAtubeCenter0;
329 Double_t staveThicknessAA=1.03*fgkmm; // get from stave geometry.
330 TGeoCombiTrans *secRot=new TGeoCombiTrans();
331 TGeoVolume *vCarbonFiberSector;
332 TGeoMedium *medSPDcf;
333
334 medSPDcf = mgr->GetMedium("ITSspdCarbonFiber");
335 vCarbonFiberSector = new TGeoVolumeAssembly("ITSSPDCarbonFiberSectorV");
336 vCarbonFiberSector->SetMedium(medSPDcf);
337 CarbonFiberSector(vCarbonFiberSector,xAAtubeCenter0,yAAtubeCenter0);
592651e2 338 //SectorPlusStaves(vCarbonFiberSector,xAAtubeCenter0,yAAtubeCenter0);
339 vCarbonFiberSector->SetVisibility(kTRUE); // logical volume
a53658c6 340 // Compute the radial shift out of the sectors.
341 radiusSector = kBeamPipeRadius+kSPDclossesStaveAA+staveThicknessAA;
342 radiusSector *= radiusSector; // squaring;
343 radiusSector -= xAAtubeCenter0*xAAtubeCenter0;
344 radiusSector = -yAAtubeCenter0+TMath::Sqrt(radiusSector);
345 angle = kSectorStartingAngle;
346 secRot->RotateZ(angle);
347 for(i=0;i<(Int_t)kNSectorsTotal;i++){
348 secRot->SetDx(-radiusSector*TMath::Sin(angle/fgkRadian));
349 secRot->SetDy(radiusSector*TMath::Cos(angle/fgkRadian));
350 //secRot->RegisterYourself();
351 moth->AddNode(vCarbonFiberSector,i+1,new TGeoCombiTrans(*secRot));
543b7370 352 if(GetDebug(5)){
353 printf("i=%d angle=%g angle[rad]=%g radiusSector=%g x=%g y=%g \n",
354 i,angle,angle/fgkRadian,radiusSector,
355 -radiusSector*TMath::Sin(angle/fgkRadian),
356 radiusSector*TMath::Cos(angle/fgkRadian));
357 } // end if GetDebug(5)
a53658c6 358 angle += kSectorRelativeAngle;
359 secRot->RotateZ(kSectorRelativeAngle);
360 } // end for i
543b7370 361 if(GetDebug(3)){
a53658c6 362 moth->PrintNodes();
363 } // end if GetDebug().
364 delete secRot;
365}
366//______________________________________________________________________
367void AliITSv11GeometrySPD::CarbonFiberSector(TGeoVolume *moth,
368 Double_t &xAAtubeCenter0,
369 Double_t &yAAtubeCenter0,
370 TGeoManager *mgr){
db486a6e 371 // Define the detail SPD Carbon fiber support Sector geometry.
372 // Based on the drawings ALICE-Pixel "Construzione Profilo Modulo"
373 // March 25 2004 and ALICE-SUPPORTO "construzione Profilo Modulo"
374 // Define Outside radii as negitive, Outside in the sence that the
375 // center of the arc is outside of the object.
376 // February 16 2004.
377 // Inputs:
a53658c6 378 // TGeoVolume *moth The mother volume to put this object
db486a6e 379 // Outputs:
a53658c6 380 // Double_t &xAAtubeCenter0 The x location of the outer surface
381 // of the cooling tube center for tube 0.
382 // This location helps determine where
383 // this sector is to be located (information
384 // used for this is the distance the
385 // center of the #0 detector is from the
386 // beam pipe. Measurements taken at
387 // cross section A-A.
388 // Double_t &yAAtubeCenter0 The y location of the outer surface
389 // of the cooling tube center for tube 0
390 // This location helps determine where
391 // this sector is to be located (information
392 // used for this is the distance the
393 // center of the #0 detector is from the
394 // beam pipe. Measurements taken at
395 // cross section A-A.
396 // TGeoManager *mgr The TGeoManager as needed, default is
397 // gGeoManager.
db486a6e 398 // Return:
bf86817c 399 // none.
db486a6e 400 TGeoMedium *medSPDcf = 0; // SPD support cone Carbon Fiber materal number.
401 //TGeoMedium *medSPDfs = 0; // SPD support cone inserto stesalite 4411w.
402 //TGeoMedium *medSPDfo = 0; // SPD support cone foam, Rohacell 50A.
403 TGeoMedium *medSPDss = 0; // SPD support cone screw material,Stainless
404 TGeoMedium *medSPDair = 0; // SPD support cone Air
405 //TGeoMedium *medSPDal = 0; // SPD support cone SDD mounting bracket Al
406 TGeoMedium *medSPDcoolfl = 0; // SPD cooling fluid, Freeon
407 medSPDcf = mgr->GetMedium("ITSspdCarbonFiber");
408 //medSPDfs = mgr->GetMedium("ITSspdStaselite4411w");
409 //medSPDfo = mgr->GetMedium("ITSspdRohacell50A");
a53658c6 410 medSPDss = mgr->GetMedium("ITSspdStainlessSteel");
db486a6e 411 medSPDair= mgr->GetMedium("ITSspdAir");
412 medSPDcoolfl= mgr->GetMedium("ITSspdCoolingFluid");
413 //
414 const Double_t ksecDz = 0.5*500.0*fgkmm;
415 const Double_t ksecLen = 30.0*fgkmm;
416 const Double_t ksecCthick = 0.20*fgkmm;
417 const Double_t ksecDipLength = 3.2*fgkmm;
418 const Double_t ksecDipRadii = 0.4*fgkmm;
419 //const Double_t ksecCoolingTubeExtraDepth = 0.86*fgkmm;
a53658c6 420 // These positions, ksecX*,ksecY* are the center of curvatures
421 // for the different point around the SPD sector. The radii,
422 // inner and outer, are the radous of curvature about the centers
423 // ksecX* and ksecY*. To draw this SPD sector, first plot all of
424 // the ksecX and ksecY points and draw circles of the specified
425 // radius about these points. Connect the circles, such that the
426 // lines are tangent to the circles, in accordance with the
427 // radii being "Inside" or "Outside". These lines and the
428 // corresponding arc's are the surface of this SPD sector.
db486a6e 429 const Double_t ksecX0 = -10.725*fgkmm;
430 const Double_t ksecY0 = -14.853*fgkmm;
431 const Double_t ksecR0 = -0.8*fgkmm; // Outside
432 const Double_t ksecX1 = -13.187*fgkmm;
433 const Double_t ksecY1 = -19.964*fgkmm;
434 const Double_t ksecR1 = +0.6*fgkmm; // Inside
a53658c6 435 //const Double_t ksecDip0 = 5.9*fgkmm;
db486a6e 436 //
437 const Double_t ksecX2 = -3.883*fgkmm;
438 const Double_t ksecY2 = -17.805*fgkmm;
439 const Double_t ksecR2 = +0.80*fgkmm; // Inside Guess.
440 const Double_t ksecX3 = -3.123*fgkmm;
441 const Double_t ksecY3 = -14.618*fgkmm;
442 const Double_t ksecR3 = -0.6*fgkmm; // Outside
a53658c6 443 //const Double_t ksecDip1 = 8.035*fgkmm;
db486a6e 444 //
445 const Double_t ksecX4 = +11.280*fgkmm;
446 const Double_t ksecY4 = -14.473*fgkmm;
447 const Double_t ksecR4 = +0.8*fgkmm; // Inside
448 const Double_t ksecX5 = +19.544*fgkmm;
449 const Double_t ksecY5 = +10.961*fgkmm;
450 const Double_t ksecR5 = +0.8*fgkmm; // Inside
a53658c6 451 //const Double_t ksecDip2 = 4.553*fgkmm;
db486a6e 452 //
453 const Double_t ksecX6 = +10.830*fgkmm;
454 const Double_t ksecY6 = +16.858*fgkmm;
455 const Double_t ksecR6 = +0.6*fgkmm; // Inside
456 const Double_t ksecX7 = +11.581*fgkmm;
457 const Double_t ksecY7 = +13.317*fgkmm;
458 const Double_t ksecR7 = -0.6*fgkmm; // Outside
a53658c6 459 //const Double_t ksecDip3 = 6.978*fgkmm;
db486a6e 460 //
461 const Double_t ksecX8 = -0.733*fgkmm;
462 const Double_t ksecY8 = +17.486*fgkmm;
463 const Double_t ksecR8 = +0.6*fgkmm; // Inside
464 const Double_t ksecX9 = +0.562*fgkmm;
592651e2 465 //const Double_t ksecY9 = +14.486*fgkmm; // correction by
466 const Double_t ksecY9 = +14.107*fgkmm; // Alberto
db486a6e 467 const Double_t ksecR9 = -0.6*fgkmm; // Outside
a53658c6 468 //const Double_t ksecDip4 = 6.978*fgkmm;
db486a6e 469 //
470 const Double_t ksecX10 = -12.252*fgkmm;
471 const Double_t ksecY10 = +16.298*fgkmm;
472 const Double_t ksecR10 = +0.6*fgkmm; // Inside
473 const Double_t ksecX11 = -10.445*fgkmm;
474 const Double_t ksecY11 = +13.162*fgkmm;
475 const Double_t ksecR11 = -0.6*fgkmm; // Outside
a53658c6 476 //const Double_t ksecDip5 = 6.978*fgkmm;
db486a6e 477 //
478 const Double_t ksecX12 = -22.276*fgkmm;
479 const Double_t ksecY12 = +12.948*fgkmm;
480 const Double_t ksecR12 = +0.85*fgkmm; // Inside
481 //const Double_t ksecX13 = *fgkmm;
482 //const Double_t ksecY13 = *fgkmm;
483 const Double_t ksecR13 = -0.8*fgkmm; // Outside
484 const Double_t ksecAngleSide13 = 36.0*fgkDegree;
485 //
a53658c6 486 const Int_t ksecNRadii = 20;
db486a6e 487 const Int_t ksecNPointsPerRadii = 4;
488 const Int_t ksecNCoolingTubeDips = 6;
489 // Since the Rounded parts are aproximated by a regular polygon and
490 // a cooling tube of the propper diameter must fit, a scaling factor
491 // increases the size of the polygon for the tube to fit.
492 //const Double_t ksecRCoolScale = 1./TMath::Cos(TMath::Pi()/
493 // (Double_t)ksecNPointsPerRadii);
494 const Double_t ksecZEndLen = 30.00*fgkmm;
495 //const Double_t ksecZFlangLen= 45.00*fgkmm;
496 const Double_t ksecTl = 0.860*fgkmm;
497 const Double_t ksecCthick2 = 0.600*fgkmm;
a53658c6 498 //const Double_t ksecCthick3 = 1.800*fgkmm;
499 //const Double_t ksecSidelen = 22.00*fgkmm;
500 //const Double_t ksecSideD5 = 3.679*fgkmm;
501 //const Double_t ksecSideD12 = 7.066*fgkmm;
db486a6e 502 const Double_t ksecRCoolOut = 2.400*fgkmm;
503 const Double_t ksecRCoolIn = 2.000*fgkmm;
504 const Double_t ksecDl1 = 5.900*fgkmm;
505 const Double_t ksecDl2 = 8.035*fgkmm;
506 const Double_t ksecDl3 = 4.553*fgkmm;
507 const Double_t ksecDl4 = 6.978*fgkmm;
508 const Double_t ksecDl5 = 6.978*fgkmm;
509 const Double_t ksecDl6 = 6.978*fgkmm;
a53658c6 510 const Double_t ksecCoolTubeThick = 0.04*fgkmm;
511 const Double_t ksecCoolTubeROuter = 2.6*fgkmm;
512 const Double_t ksecCoolTubeFlatX = 3.696*fgkmm;
513 const Double_t ksecCoolTubeFlatY = 0.68*fgkmm;
514 //const Double_t ksecBeamX0 = 0.0*fgkmm; // guess
515 //const Double_t ksecBeamY0 = (15.223+40.)*fgkmm; // guess
516 //
517 const Int_t ksecNPoints = (ksecNPointsPerRadii+1)*ksecNRadii + 8;
518 Double_t secX[ksecNRadii] = {ksecX0,ksecX1,-1000.0,ksecX2 ,ksecX3 ,-1000.0,
519 ksecX4,ksecX5,-1000.0,ksecX6 ,ksecX7 ,-1000.0,
520 ksecX8,ksecX9,-1000.0,ksecX10,ksecX11,-1000.0,
521 ksecX12,-1000.0};
522 Double_t secY[ksecNRadii] = {ksecY0,ksecY1,-1000.0,ksecY2 ,ksecY3 ,-1000.0,
523 ksecY4,ksecY5,-1000.0,ksecY6 ,ksecY7 ,-1000.0,
524 ksecY8,ksecY9,-1000.0,ksecY10,ksecY11,-1000.0,
525 ksecY12,-1000.0};
526 Double_t secR[ksecNRadii] ={ksecR0 ,ksecR1 ,-.5*ksecDipLength-ksecDipRadii,
527 ksecR2 ,ksecR3 ,-.5*ksecDipLength-ksecDipRadii,
528 ksecR4 ,ksecR5 ,-.5*ksecDipLength-ksecDipRadii,
529 ksecR6 ,ksecR7 ,-.5*ksecDipLength-ksecDipRadii,
530 ksecR8 ,ksecR9 ,-.5*ksecDipLength-ksecDipRadii,
531 ksecR10,ksecR11,-.5*ksecDipLength-ksecDipRadii,
532 ksecR12,ksecR13};/*
533 Double_t secDip[ksecNRadii]={0.0,0.0,ksecDip0,0.0,0.0,ksecDip1,
534 0.0,0.0,ksecDip2,0.0,0.0,ksecDip3,
535 0.0,0.0,ksecDip4,0.0,0.0,ksecDip5,
536 0.0,0.0};*/
537 Double_t secX2[ksecNRadii];
538 Double_t secY2[ksecNRadii];
539 Double_t secR2[ksecNRadii] = {
540 ksecR0,ksecR1,ksecRCoolOut,ksecR2,ksecR3,ksecRCoolOut,ksecR4,ksecR5,
541 ksecRCoolOut,ksecR6,ksecR7,ksecRCoolOut,ksecR8,ksecR9,ksecRCoolOut,
542 ksecR10,ksecR11,ksecRCoolOut,ksecR12,ksecR13};
543 Double_t secDip2[ksecNCoolingTubeDips]={ksecDl1,ksecDl2,ksecDl3,
544 ksecDl4,ksecDl5,ksecDl6};
545 Double_t secX3[ksecNRadii];
546 Double_t secY3[ksecNRadii];
db486a6e 547 const Int_t ksecDipIndex[ksecNCoolingTubeDips] = {2,5,8,11,14,17};
548 Double_t secAngleStart[ksecNRadii];
549 Double_t secAngleEnd[ksecNRadii];
a53658c6 550 Double_t secAngleStart2[ksecNRadii];
551 Double_t secAngleEnd2[ksecNRadii];
552 Double_t secAngleTurbo[ksecNCoolingTubeDips] = {0.0,0.0,0.0,0.0,0.0,0.0};
553 //Double_t secAngleStart3[ksecNRadii];
554 //Double_t secAngleEnd3[ksecNRadii];
555 Double_t xpp[ksecNPoints],ypp[ksecNPoints];
556 Double_t xpp2[ksecNPoints],ypp2[ksecNPoints];
557 Double_t *xp[ksecNRadii],*xp2[ksecNRadii];
558 Double_t *yp[ksecNRadii],*yp2[ksecNRadii];
db486a6e 559 TGeoXtru *sA0,*sA1,*sB0,*sB1;
560 TGeoEltu *sTA0,*sTA1;
592651e2 561 TGeoTube *sTB0,*sTB1; //,*sM0;
db486a6e 562 TGeoRotation *rot;
563 TGeoTranslation *trans;
564 TGeoCombiTrans *rotrans;
565 Double_t t,t0,t1,a,b,x0,y0,x1,y1;
a53658c6 566 Int_t i,j,k,m;
567 Bool_t tst;
db486a6e 568
569 if(moth==0){
a53658c6 570 Error("CarbonFiberSector","moth=%p",moth);
571 return;
db486a6e 572 } // end if moth==0
a53658c6 573 //SetDebug(3);
574 for(i=0;i<ksecNRadii;i++){
575 xp[i] = &(xpp[i*(ksecNPointsPerRadii+1)]);
576 yp[i] = &(ypp[i*(ksecNPointsPerRadii+1)]);
577 xp2[i] = &(xpp2[i*(ksecNPointsPerRadii+1)]);
578 yp2[i] = &(ypp2[i*(ksecNPointsPerRadii+1)]);
579 secX2[i] = secX[i];
580 secY2[i] = secY[i];
581 secX3[i] = secX[i];
582 secY3[i] = secY[i];
583 } // end for i
db486a6e 584
a53658c6 585 // Find starting and ending angles for all but cooling tube sections
db486a6e 586 secAngleStart[0] = 0.5*ksecAngleSide13;
587 for(i=0;i<ksecNRadii-2;i++){
a53658c6 588 tst = kFALSE;
589 for(j=0;j<ksecNCoolingTubeDips;j++) tst = tst||i==ksecDipIndex[j];
590 if(tst) continue;
591 tst = kFALSE;
592 for(j=0;j<ksecNCoolingTubeDips;j++) tst = tst||(i+1)==ksecDipIndex[j];
593 if(tst) j = i+2;
594 else j = i+1;
595 AnglesForRoundedCorners(secX[i],secY[i],secR[i],
596 secX[j],secY[j],secR[j],t0,t1);
597 secAngleEnd[i] = t0;
598 secAngleStart[j] = t1;
599 if(secR[i]>0.0&&secR[j]>0.0)if(secAngleStart[i]>secAngleEnd[i])
600 secAngleEnd[i] += 360.0;
601 secAngleStart2[i] = secAngleStart[i];
602 secAngleEnd2[i] = secAngleEnd[i];
db486a6e 603 } // end for i
604 secAngleEnd[ksecNRadii-2] = secAngleStart[ksecNRadii-2] +
a53658c6 605 (secAngleEnd[ksecNRadii-5]-
606 secAngleStart[ksecNRadii-5]);
db486a6e 607 if(secAngleEnd[ksecNRadii-2]<0.0) secAngleEnd[ksecNRadii-2] += 360.0;
608 secAngleStart[ksecNRadii-1] = secAngleEnd[ksecNRadii-2] - 180.0;
609 secAngleEnd[ksecNRadii-1] = secAngleStart[0];
a53658c6 610 secAngleStart2[ksecNRadii-2] = secAngleStart[ksecNRadii-2];
611 secAngleEnd2[ksecNRadii-2] = secAngleEnd[ksecNRadii-2];
612 secAngleStart2[ksecNRadii-1] = secAngleStart[ksecNRadii-1];
613 secAngleEnd2[ksecNRadii-1] = secAngleEnd[ksecNRadii-1];
614 // Find location of circle last rounded corner.
db486a6e 615 i = 0;
616 j = ksecNRadii-2;
617 t0 = TanD(secAngleStart[i]-90.);
618 t1 = TanD(secAngleEnd[j]-90.);
619 t = secY[i] - secY[j];
a53658c6 620 // Note, secR[i=0] <0; secR[j=18]>0; and secR[j+1=19] <0
db486a6e 621 t += (-secR[i]+secR[j+1])*SinD(secAngleStart[i]);
622 t -= (secR[j]-secR[j+1])*SinD(secAngleEnd[j]);
623 t += t1*secX[j] - t0*secX[i];
624 t += t1*(secR[j]-secR[j+1])*CosD(secAngleEnd[j]);
625 t -= t0*(-secR[i]+secR[j+1])*CosD(secAngleStart[i]);
626 secX[ksecNRadii-1] = t/(t1-t0);
627 secY[ksecNRadii-1] = TanD(90.+0.5*ksecAngleSide13)*
a53658c6 628 (secX[ksecNRadii-1]-secX[0]) + secY[0];
629 secX2[ksecNRadii-1] = secX[ksecNRadii-1];
630 secY2[ksecNRadii-1] = secY[ksecNRadii-1];
631 secX3[ksecNRadii-1] = secX[ksecNRadii-1];
632 secY3[ksecNRadii-1] = secY[ksecNRadii-1];
633 // find location of cooling tube centers
634 for(i=0;i<ksecNCoolingTubeDips;i++){
635 j = ksecDipIndex[i];
636 x0 = secX[j-1] + TMath::Abs(secR[j-1])*CosD(secAngleEnd[j-1]);
637 y0 = secY[j-1] + TMath::Abs(secR[j-1])*SinD(secAngleEnd[j-1]);
638 x1 = secX[j+1] + TMath::Abs(secR[j+1])*CosD(secAngleStart[j+1]);
639 y1 = secY[j+1] + TMath::Abs(secR[j+1])*SinD(secAngleStart[j+1]);
640 t0 = TMath::Sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
641 t = secDip2[i]/t0;
642 a = x0+(x1-x0)*t;
643 b = y0+(y1-y0)*t;
644 if(i==0){ // get location of tube center->Surface for locating
645 // this sector around the beam pipe. This needs to be
646 // double checked, but I need my notes for that, Bjorn Nilsen
647 xAAtubeCenter0 = x0+(x1-x0)*t*0.5;
648 yAAtubeCenter0 = y0+(y1-y0)*t*0.5;
649 } // end if i==0
650 if(a+b*(a-x0)/(b-y0)>0.0){
651 secX[j] = a + TMath::Abs(y1-y0)*2.0*ksecDipRadii/t0;
652 secY[j] = b - TMath::Sign(2.0*ksecDipRadii,y1-y0)*(x1-x0)/t0;
653 secX2[j] = a + TMath::Abs(y1-y0)*ksecTl/t0;
654 secY2[j] = b - TMath::Sign(ksecTl,y1-y0)*(x1-x0)/t0;
655 secX3[j] = a + TMath::Abs(y1-y0)*(2.0*ksecDipRadii-
656 0.5*ksecCoolTubeFlatY)/t0;
657 secY3[j] = b - TMath::Sign(2.0*ksecDipRadii-0.5*ksecCoolTubeFlatY,
658 y1-y0)*(x1-x0)/t0;
659 }else{
660 secX[j] = a - TMath::Abs(y1-y0)*2.0*ksecDipRadii/t0;
661 secY[j] = b + TMath::Sign(2.0*ksecDipRadii,y1-y0)*(x1-x0)/t0;
662 secX2[j] = a - TMath::Abs(y1-y0)*ksecTl/t0;
663 secY2[j] = b + TMath::Sign(ksecTl,y1-y0)*(x1-x0)/t0;
664 secX3[j] = a - TMath::Abs(y1-y0)*(2.0*ksecDipRadii-
665 0.5*ksecCoolTubeFlatY)/t0;
666 secY3[j] = b + TMath::Sign(2.0*ksecDipRadii-0.5*ksecCoolTubeFlatY,
667 y1-y0)*(x1-x0)/t0;
668 } // end if
669 // Set up Start and End angles to correspond to start/end of dips.
670 t1 = (secDip2[i]-TMath::Abs(secR[j]))/t0;
671 secAngleStart[j] = TMath::RadToDeg()*TMath::ATan2(
672 y0+(y1-y0)*t1-secY[j],x0+(x1-x0)*t1-secX[j]);
673 if(secAngleStart[j]<0.0) secAngleStart[j] += 360.0;
674 secAngleStart2[j] = secAngleStart[j];
675 t1 = (secDip2[i]+TMath::Abs(secR[j]))/t0;
676 secAngleEnd[j] = TMath::RadToDeg()*TMath::ATan2(
677 y0+(y1-y0)*t1-secY[j],x0+(x1-x0)*t1-secX[j]);
678 if(secAngleEnd[j]<0.0) secAngleEnd[j] += 360.0;
679 secAngleEnd2[j] = secAngleEnd[j];
680 if(secAngleEnd[j]>secAngleStart[j]) secAngleEnd[j] -= 360.0;
681 secR[j] = TMath::Sqrt(secR[j]*secR[j]+4.0*ksecDipRadii*ksecDipRadii);
682 } // end for i
297369a1 683 // Special cases
a53658c6 684 secAngleStart2[8] -= 360.;
685 secAngleStart2[11] -= 360.;
bf86817c 686 //
297369a1 687 fSPDsectorPoints0.Set(ksecNCoolingTubeDips);
688 fSPDsectorPoints1.Set(ksecNCoolingTubeDips);
689 //
690 for(i=0;i<ksecNCoolingTubeDips;i++){
691 // Find index in xpp[] and ypp[] corresponding to where the
692 // SPD ladders are to be attached. Order them according to
693 // the ALICE numbering schema. Using array of indexes (+-1 for
694 // cooling tubes. For any "bend/dip/edge, there are
695 // ksecNPointsPerRadii+1 points involved.
696 if(i==0) j=1;
697 else if(i==1) j=0;
698 else j=i;
699 fSPDsectorPoints0[i] = (ksecDipIndex[j]-1)*(ksecNPointsPerRadii+1)+
700 (ksecNPointsPerRadii);
701 fSPDsectorPoints1[i] = (ksecDipIndex[j]+1)*(ksecNPointsPerRadii+1);
702 } // end for i
a53658c6 703 SPDsectorShape(ksecNRadii,secX,secY,secR,secAngleStart,secAngleEnd,
704 ksecNPointsPerRadii,m,xp,yp);
705 // Fix up dips to be square.
706 for(i=0;i<ksecNCoolingTubeDips;i++){
707 j = ksecDipIndex[i];
708 t = 0.5*ksecDipLength+ksecDipRadii;
709 t0 = TMath::RadToDeg()*TMath::ATan(2.0*ksecDipRadii/t);
710 t1 = secAngleEnd[j] + t0;
711 t0 = secAngleStart[j] - t0;
712 x0 = xp[j][1] = secX[j] + t*CosD(t0);
713 y0 = yp[j][1] = secY[j] + t*SinD(t0);
714 x1 = xp[j][ksecNPointsPerRadii-1] = secX[j] + t*CosD(t1);
715 y1 = yp[j][ksecNPointsPerRadii-1] = secY[j] + t*SinD(t1);
716 t0 = 1./((Double_t)(ksecNPointsPerRadii-2));
717 for(k=2;k<ksecNPointsPerRadii-1;k++){// extra points spread them out.
718 t = ((Double_t)(k-1))*t0;
719 xp[j][k] = x0+(x1-x0)*t;
720 yp[j][k] = y0+(y1-y0)*t;
db486a6e 721 } // end for k
a53658c6 722 secAngleTurbo[i] = -TMath::RadToDeg()*TMath::ATan2(y1-y0,x1-x0);
723 if(GetDebug(3)){
724 cout <<"i="<<i<<" angle="<<secAngleTurbo[i]<<" x0,y0{"
725 <<x0<<","<<y0<<"} x1y1={"<<x1<<","<<y1<<"}"<<endl;
726 } // end if
727 } // end for i
db486a6e 728 sA0 = new TGeoXtru(2);
297369a1 729 // This shape needs to be access later to mount the SPD sector to.
730 //fSPDsectorShapeName = "ITS SPD Carbon fiber support Sector A0";
731 //sA0->SetName(fSPDsectorShapeName.Data());
db486a6e 732 sA0->SetName("ITS SPD Carbon fiber support Sector A0");
a53658c6 733 sA0->DefinePolygon(m,xpp,ypp);
db486a6e 734 sA0->DefineSection(0,-ksecDz);
735 sA0->DefineSection(1,ksecDz);
736 //
543b7370 737 //printf("SectorA#%d ",0);
a53658c6 738 InsidePoint(xpp[m-1],ypp[m-1],xpp[0],ypp[0],xpp[1],ypp[1],
739 ksecCthick,xpp2[0],ypp2[0]);
740 for(i=1;i<m-1;i++){
741 j = i/(ksecNPointsPerRadii+1);
543b7370 742 //printf("SectorA#%d ",i);
a53658c6 743 InsidePoint(xpp[i-1],ypp[i-1],xpp[i],ypp[i],xpp[i+1],ypp[i+1],
744 ksecCthick,xpp2[i],ypp2[i]);
745 } // end for i
543b7370 746 //printf("SectorA#%d ",m);
a53658c6 747 InsidePoint(xpp[m-2],ypp[m-2],xpp[m-1],ypp[m-1],xpp[0],ypp[0],
748 ksecCthick,xpp2[m-1],ypp2[m-1]);
749 // Fix center value of cooling tube dip.
750 // find location of cooling tube centers
751 for(i=0;i<ksecNCoolingTubeDips;i++){
752 j = ksecDipIndex[i];
753 x0 = xp2[j][1];
754 y0 = yp2[j][1];
755 x1 = xp2[j][ksecNPointsPerRadii-1];
756 y1 = yp2[j][ksecNPointsPerRadii-1];
757 t0 = TMath::Sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
758 t = secDip2[i]/t0;
759 for(k=2;k<ksecNPointsPerRadii-1;k++){// extra points spread them out.
760 t = ((Double_t)(k-1))*t0;
761 xp2[j][k] = x0+(x1-x0)*t;
762 yp2[j][k] = y0+(y1-y0)*t;
763 } // end for k
764 } // end for i
db486a6e 765 sA1 = new TGeoXtru(2);
766 sA1->SetName("ITS SPD Carbon fiber support Sector Air A1");
a53658c6 767 sA1->DefinePolygon(m,xpp2,ypp2);
db486a6e 768 sA1->DefineSection(0,-ksecDz);
769 sA1->DefineSection(1,ksecDz);
770 //
a53658c6 771 // Error in TGeoEltu. Semi-axis X must be < Semi-axis Y (?).
db486a6e 772 sTA0 = new TGeoEltu("ITS SPD Cooling Tube TA0",
a53658c6 773 0.5* ksecCoolTubeFlatY, 0.5* ksecCoolTubeFlatX,ksecDz);
db486a6e 774 sTA1 = new TGeoEltu("ITS SPD Cooling Tube coolant TA1",
775 sTA0->GetA()-ksecCoolTubeThick,
776 sTA0->GetB()-ksecCoolTubeThick,ksecDz);
777 //
a53658c6 778 SPDsectorShape(ksecNRadii,secX2,secY2,secR2,secAngleStart2,secAngleEnd2,
779 ksecNPointsPerRadii,m,xp,yp);
db486a6e 780 //
781 sB0 = new TGeoXtru(2);
782 sB0->SetName("ITS SPD Carbon fiber support Sector End B0");
a53658c6 783 sB0->DefinePolygon(m,xpp,ypp);
db486a6e 784 sB0->DefineSection(0,ksecDz);
785 sB0->DefineSection(1,ksecDz+ksecZEndLen);
786 //
543b7370 787 //printf("SectorB#%d ",0);
a53658c6 788 InsidePoint(xpp[m-1],ypp[m-1],xpp[0],ypp[0],xpp[1],ypp[1],
789 ksecCthick2,xpp2[0],ypp2[0]);
790 for(i=1;i<m-1;i++){
791 t = ksecCthick2;
792 for(k=0;k<ksecNCoolingTubeDips;k++)
793 if((i/(ksecNPointsPerRadii+1))==ksecDipIndex[k])
794 if(!(ksecDipIndex[k]*(ksecNPointsPerRadii+1)==i ||
795 ksecDipIndex[k]*(ksecNPointsPerRadii+1)+
796 ksecNPointsPerRadii==i ))
797 t = ksecRCoolOut-ksecRCoolIn;
543b7370 798 //printf("SectorB#%d ",i);
a53658c6 799 InsidePoint(xpp[i-1],ypp[i-1],xpp[i],ypp[i],xpp[i+1],ypp[i+1],
800 t,xpp2[i],ypp2[i]);
543b7370 801 } // end for
802 //printf("SectorB#%d ",m);
a53658c6 803 InsidePoint(xpp[m-2],ypp[m-2],xpp[m-1],ypp[m-1],xpp[0],ypp[0],
804 ksecCthick2,xpp2[m-1],ypp2[m-1]);
db486a6e 805 sB1 = new TGeoXtru(2);
806 sB1->SetName("ITS SPD Carbon fiber support Sector Air End B1");
a53658c6 807 sB1->DefinePolygon(m,xpp2,ypp2);
db486a6e 808 sB1->DefineSection(0,ksecDz);
809 sB1->DefineSection(1,ksecDz+ksecLen);
810 sTB0 = new TGeoTube("ITS SPD Cooling Tube End TB0",0.0,
a53658c6 811 0.5*ksecCoolTubeROuter,0.5*ksecLen);
db486a6e 812 sTB1 = new TGeoTube("ITS SPD Cooling Tube End coolant TB0",0.0,
813 sTB0->GetRmax()-ksecCoolTubeThick,0.5*ksecLen);
814 //
543b7370 815 //sM0 = new TGeoTube("ITS SPD Sensitive Virutual Volume M0",0.0,8.0,
816 // sA0->GetZ(1)+sB0->GetZ(1));
a53658c6 817 //
543b7370 818 if(GetDebug(3)){
a53658c6 819 if(medSPDcf) medSPDcf->Dump();
543b7370 820 else printf("medSPDcf=0\n");
a53658c6 821 if(medSPDss) medSPDss->Dump();
543b7370 822 else printf("medSPDss=0\n");
a53658c6 823 if(medSPDair) medSPDair->Dump();
543b7370 824 else printf("medSPDAir=0\n");
a53658c6 825 if(medSPDcoolfl) medSPDcoolfl->Dump();
543b7370 826 else printf("medSPDcoolfl=0\n");
827 //sM0->InspectShape();
db486a6e 828 sA0->InspectShape();
829 sA1->InspectShape();
830 sB0->InspectShape();
831 sB1->InspectShape();
832 } // end if GetDebug
833 //
543b7370 834 TGeoVolume *vA0,*vA1,*vTA0,*vTA1,*vB0,*vB1,*vTB0,*vTB1;
835 TGeoVolumeAssembly *vM0;
836 vM0 = new TGeoVolumeAssembly("ITSSPDSensitiveVirtualvolumeM0");
837 //vM0 = new TGeoVolume("ITSSPDSensitiveVirtualvolumeM0",sM0,medSPDair);
838 //vM0->SetVisibility(kTRUE);
839 //vM0->SetLineColor(7); // light Blue
840 //vM0->SetLineWidth(1);
841 //vM0->SetFillColor(vM0->GetLineColor());
842 //vM0->SetFillStyle(4090); // 90% transparent
592651e2 843 // ALBERTO
297369a1 844 fSPDsectorShapeName = "ITSSPDCarbonFiberSupportSectorA0";
845 vA0 = new TGeoVolume(fSPDsectorShapeName,sA0,medSPDcf);
846 //vA0 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorA0",sA0,medSPDcf);
db486a6e 847 vA0->SetVisibility(kTRUE);
848 vA0->SetLineColor(4); // Blue
849 vA0->SetLineWidth(1);
850 vA0->SetFillColor(vA0->GetLineColor());
851 vA0->SetFillStyle(4010); // 10% transparent
852 vA1 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorAirA1",sA1,medSPDair);
853 vA1->SetVisibility(kTRUE);
854 vA1->SetLineColor(7); // light Blue
855 vA1->SetLineWidth(1);
856 vA1->SetFillColor(vA1->GetLineColor());
857 vA1->SetFillStyle(4090); // 90% transparent
858 vTA0 = new TGeoVolume("ITSSPDCoolingTubeTA0",sTA0,medSPDss);
859 vTA0->SetVisibility(kTRUE);
860 vTA0->SetLineColor(1); // Black
861 vTA0->SetLineWidth(1);
862 vTA0->SetFillColor(vTA0->GetLineColor());
863 vTA0->SetFillStyle(4000); // 0% transparent
864 vTA1 = new TGeoVolume("ITSSPDCoolingTubeFluidTA1",sTA1,medSPDcoolfl);
865 vTA1->SetVisibility(kTRUE);
866 vTA1->SetLineColor(6); // Purple
867 vTA1->SetLineWidth(1);
868 vTA1->SetFillColor(vTA1->GetLineColor());
869 vTA1->SetFillStyle(4000); // 0% transparent
870 vB0 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorEndB0",sB0,medSPDcf);
871 vB0->SetVisibility(kTRUE);
872 vB0->SetLineColor(4); // Blue
873 vB0->SetLineWidth(1);
874 vB0->SetFillColor(vB0->GetLineColor());
875 vB0->SetFillStyle(4010); // 10% transparent
a53658c6 876 vB1 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorEndAirB1",
877 sB1,medSPDair);
db486a6e 878 vB1->SetVisibility(kTRUE);
879 vB1->SetLineColor(7); // light Blue
880 vB1->SetLineWidth(1);
881 vB1->SetFillColor(vB1->GetLineColor());
882 vB1->SetFillStyle(4090); // 90% transparent
883 vTB0 = new TGeoVolume("ITSSPDCoolingTubeEndTB0",sTB0,medSPDss);
884 vTB0->SetVisibility(kTRUE);
885 vTB0->SetLineColor(1); // Black
886 vTB0->SetLineWidth(1);
887 vTB0->SetFillColor(vTB0->GetLineColor());
888 vTB0->SetFillStyle(4000); // 0% transparent
889 vTB1 = new TGeoVolume("ITSSPDCoolingTubeEndFluidTB1",sTB1,medSPDcoolfl);
890 vTB1->SetVisibility(kTRUE);
891 vTB1->SetLineColor(6); // Purple
892 vTB1->SetLineWidth(1);
893 vTB1->SetFillColor(vTB1->GetLineColor());
894 vTB1->SetFillStyle(4000); // 0% transparent
895 //
297369a1 896 StavesInSector(vM0);
a53658c6 897 moth->AddNode(vM0,1,0); // Add virtual volume to mother
db486a6e 898 vA0->AddNode(vA1,1,0); // Put air inside carbon fiber.
899 vB0->AddNode(vB1,1,0); // Put air inside carbon fiber.
900 vTA0->AddNode(vTA1,1,0); // Put air inside carbon fiber.
901 vTB0->AddNode(vTB1,1,0); // Put air inside carbon fiber.
902 for(i=0;i<ksecNCoolingTubeDips;i++){
a53658c6 903 x0 = secX3[ksecDipIndex[i]];
904 y0 = secY3[ksecDipIndex[i]];
905 t = 90.0-secAngleTurbo[i];
906 trans = new TGeoTranslation("",x0,y0,0.5*(sB1->GetZ(0)+sB1->GetZ(1)));
db486a6e 907 vB1->AddNode(vTB0,i+1,trans);
a53658c6 908 rot = new TGeoRotation("",0.0,0.0,t);
909 rotrans = new TGeoCombiTrans("",x0,y0,0.0,rot);
910 vM0->AddNode(vTA0,i+1,rotrans);
911 //delete rot; // rot owned by AliITSv11GeometerySPD::CarbonFiberSector
db486a6e 912 } // end for i
a53658c6 913 vM0->AddNode(vA0,1,0);
914 vM0->AddNode(vB0,1,0);
915 // Reflection.
916 vM0->AddNode(vB0,2,new TGeoRotation("",90.,0.,90.,90.,180.,0.));
543b7370 917 if(GetDebug(3)){
a53658c6 918 vM0->PrintNodes();
db486a6e 919 vA0->PrintNodes();
920 vA1->PrintNodes();
921 vB0->PrintNodes();
922 vB1->PrintNodes();
a53658c6 923 vTA0->PrintNodes();
924 vTA1->PrintNodes();
925 vTB0->PrintNodes();
926 vTB1->PrintNodes();
db486a6e 927 } // end if GetDebug
928 //
db486a6e 929}
a53658c6 930//----------------------------------------------------------------------
297369a1 931Bool_t AliITSv11GeometrySPD::GetSectorMountingPoints(Int_t index,
932 Double_t &x0,Double_t &y0,
933 Double_t &x1,Double_t &y1,TGeoManager *mgr)const{
934 // Return's the mounting locations needed to mount the SPD ladders
935 // on the SPD Carbon fiber Sectors (A cross section). Coordinate
936 // system is that of the carbon fiber sector TVolume
937 // "ITSSPDCarbonFiberSupportSectorA0". Index numbering is as follows
938 // /5
939 // /\/4
940 // 1\ \/3
941 // 0|___\/2
942 // Inputs:
943 // Int_t index the index for which location on the SPD sector [0-5]
944 // Outputs:
945 // Double_t &x0 The x0 location or the ladder sector [cm]
946 // Double_t &y0 The y0 location of the ladder sector [cm]
947 // Double_t &x1 The x1 location or the ladder sector [cm]
948 // Double_t &y1 The y1 location of the ladder sector [cm]
949 // TGeoManager *mgr The Geometry manager to use [gGeoManager]
950 // Return:
951 // Returns kTRUE if no problems incountered. Returns kFALSE
952 // if a problem was incountered (for example the shape has
953 // not been found.
954 TGeoVolume *spdSectorV=0;
955 TGeoXtru *spdSector=0;
956 Int_t ixy0,ixy1;
957
958 x0 = x1 = y0 = y1 = 0.0;
959 if(index<0 || index>fSPDsectorPoints0.GetSize()){
960 Error("GetSectorMountingPoints","index=%d size=%d",index,
961 fSPDsectorPoints0.GetSize());
962 return kFALSE;
963 }// end if
964 spdSectorV = mgr->GetVolume(fSPDsectorShapeName.Data());
965 if(spdSectorV==0){
966 Error("GetSectorMountingPoints","spdSectorV==0 name=%s",
967 fSPDsectorShapeName.Data());
968 return kFALSE;
969 } // end if
970 spdSector = dynamic_cast<TGeoXtru*>(spdSectorV->GetShape());
971 if(spdSector==0){
972 Error("GetSectorMountingPoints","spdSector==0");
973 return kFALSE;
974 } // end if
975 ixy0 = fSPDsectorPoints0.At(index);
976 ixy1 = fSPDsectorPoints1.At(index);
977 x0 = spdSector->GetX(ixy0);
978 y0 = spdSector->GetY(ixy0);
979 x1 = spdSector->GetX(ixy1);
980 y1 = spdSector->GetY(ixy1);
981 return kTRUE;
982}
983//----------------------------------------------------------------------
a53658c6 984void AliITSv11GeometrySPD::SPDsectorShape(Int_t n,const Double_t *xc,
985const Double_t *yc,const Double_t *r,const Double_t *ths,const Double_t *the,
986 Int_t npr,Int_t &m,Double_t **xp,Double_t **yp){
987 // Code to compute the points that make up the shape of the SPD
988 // Carbon fiber support sections
989 // Inputs:
990 // Int_t n Size of arrays xc,yc, and r.
991 // Double_t *xc Array of x values for radii centers.
992 // Double_t *yc Array of y values for radii centers.
993 // Double_t *r Array of signed radii values.
994 // Double_t *ths Array of starting angles [degrees].
995 // Double_t *the Array of ending angles [degrees].
996 // Int_t npr The number of lines segments to aproximate the arc.
997 // Outputs:
998 // Int_t m The number of enetries in the arrays *xp[npr+1]
999 // and *yp[npr+1].
1000 // Double_t **xp Array of x coordinate values of the line segments
1001 // which make up the SPD support sector shape.
1002 // Double_t **yp Array of y coordinate values of the line segments
1003 // which make up the SPD support sector shape.
1004 // Return:
1005 // none.
1006 Int_t i,k;
1007 Double_t t,t0,t1;
1008
1009 m = n*(npr+1);
1010 if(GetDebug(2)){
1011 cout <<" X \t Y \t R \t S \t E"<< m <<endl;
1012 for(i=0;i<n;i++){
1013 cout <<"{"<< xc[i] <<",";
1014 cout << yc[i] <<",";
1015 cout << r[i] <<",";
1016 cout << ths[i] <<",";
1017 cout << the[i] <<"},"<< endl;
1018 } // end for i
1019 } // end if GetDebug
1020 //
1021 if(GetDebug(3)) cout <<"Double_t sA0 = ["<< n*(npr+1)+1<<"][";
1022 if(GetDebug(4)) cout <<"3]{";
1023 else if(GetDebug(3)) cout <<"2]{";
1024 t0 = (Double_t)npr;
1025 for(i=0;i<n;i++){
1026 t1 = (the[i]-ths[i])/t0;
1027 if(GetDebug(5)) cout<<"t1="<< t1<<endl;
1028 for(k=0;k<=npr;k++){
1029 t=ths[i]+((Double_t)k)*t1;
1030 xp[i][k] = TMath::Abs(r[i])*CosD(t)+xc[i];
1031 yp[i][k] = TMath::Abs(r[i])*SinD(t)+yc[i];
1032 if(GetDebug(3)){
1033 cout << "{"<<xp[i][k]<<","<<yp[i][k];
1034 if(GetDebug(4)) cout <<","<<t;
1035 cout <<"},";
1036 } // end if GetDebug
1037 } // end for k
1038 if(GetDebug(3)) cout << endl;
1039 } // end of i
1040 if(GetDebug(3)) cout<<"{"<<xp[0][0]<<","<<yp[0][0];
1041 if(GetDebug(4)) cout<<","<< ths[0];
1042 if(GetDebug(3)) cout<<"}}"<<endl;
1043 //
1044 return;
1045}
db486a6e 1046//----------------------------------------------------------------------
1047void AliITSv11GeometrySPD::CreateFigure0(const Char_t *filepath,
a53658c6 1048 const Char_t *type,
1049 TGeoManager *mgr){
db486a6e 1050 // Creates Figure 0 for the documentation of this class. In this
1051 // specific case, it creates the X,Y cross section of the SPD suport
1052 // section, center and ends. The output is written to a standard
1053 // file name to the path specificed.
1054 // Inputs:
1055 // const Char_t *filepath Path where the figure is to be drawn
1056 // const Char_t *type The type of file, default is gif.
a53658c6 1057 // TGeoManager *mgr The TGeoManager default gGeoManager
db486a6e 1058 // Output:
1059 // none.
1060 // Return:
1061 // none.
1062 TGeoXtru *sA0,*sA1,*sB0,*sB1;
1063 //TPolyMarker *pmA,*pmB;
1064 TPolyLine plA0,plA1,plB0,plB1;
1065 TCanvas *canvas;
1066 TLatex txt;
a53658c6 1067 Double_t x=0.0,y=0.0;
1068 Int_t i,kNRadii=6;
db486a6e 1069
a53658c6 1070 if(strcmp(filepath,"")){
1071 Error("CreateFigure0","filepath=%s type=%s",filepath,type);
1072 } // end if
1073 //
1074 sA0 = (TGeoXtru*) mgr->GetVolume(
db486a6e 1075 "ITSSPDCarbonFiberSupportSectorA0_1")->GetShape();
a53658c6 1076 sA1 = (TGeoXtru*) mgr->GetVolume(
db486a6e 1077 "ITSSPDCarbonFiberSupportSectorAirA1_1")->GetShape();
a53658c6 1078 sB0 = (TGeoXtru*) mgr->GetVolume(
db486a6e 1079 "ITSSPDCarbonFiberSupportSectorEndB0_1")->GetShape();
a53658c6 1080 sB1 = (TGeoXtru*) mgr->GetVolume(
db486a6e 1081 "ITSSPDCarbonFiberSupportSectorEndAirB1_1")->GetShape();
1082 //pmA = new TPolyMarker();
1083 //pmA.SetMarkerStyle(2); // +
1084 //pmA.SetMarkerColor(7); // light blue
1085 //pmB = new TPolyMarker();
1086 //pmB.SetMarkerStyle(5); // X
1087 //pmB.SetMarkerColor(6); // purple
a53658c6 1088 plA0.SetPolyLine(sA0->GetNvert());
db486a6e 1089 plA0.SetLineColor(1); // black
1090 plA0.SetLineStyle(1);
a53658c6 1091 plA1.SetPolyLine(sA1->GetNvert());
db486a6e 1092 plA1.SetLineColor(2); // red
1093 plA1.SetLineStyle(1);
a53658c6 1094 plB0.SetPolyLine(sB0->GetNvert());
db486a6e 1095 plB0.SetLineColor(3); // Green
1096 plB0.SetLineStyle(2);
1097 plB1.SetPolyLine(sB1->GetNvert());
1098 plB1.SetLineColor(4); // Blue
1099 plB1.SetLineStyle(2);
1100 //for(i=0;i<kNRadii;i++) pmA.SetPoint(i,xyB1p[i][0],xyB1p[i][1]);
1101 //for(i=0;i<kNRadii;i++) pmB.SetPoint(i,xyB1p[i][0],xyB1p[i][1]);
1102 for(i=0;i<sA0->GetNvert();i++) plA0.SetPoint(i,sA0->GetX(i),sA0->GetY(i));
1103 for(i=0;i<sA1->GetNvert();i++) plA1.SetPoint(i,sA1->GetX(i),sA1->GetY(i));
1104 for(i=0;i<sB0->GetNvert();i++) plB0.SetPoint(i,sB0->GetX(i),sB0->GetY(i));
1105 for(i=0;i<sB1->GetNvert();i++) plB1.SetPoint(i,sB1->GetX(i),sB1->GetY(i));
1106 canvas = new TCanvas("AliITSv11GeometrySPDFig0","",1000,1000);
a53658c6 1107 canvas->Range(-3.,-3.,3.,3.);
1108 txt.SetTextSize(0.05);
db486a6e 1109 txt.SetTextAlign(33);
1110 txt.SetTextColor(1);
a53658c6 1111 txt.DrawLatex(2.9,2.9,"Section A-A outer Carbon Fiber surface");
db486a6e 1112 txt.SetTextColor(2);
a53658c6 1113 txt.DrawLatex(2.9,2.5,"Section A-A Inner Carbon Fiber surface");
db486a6e 1114 txt.SetTextColor(3);
a53658c6 1115 txt.DrawLatex(2.9,2.1,"Section E-E outer Carbon Fiber surface");
db486a6e 1116 txt.SetTextColor(4);
a53658c6 1117 txt.DrawLatex(2.9,1.7,"Section E-E Inner Carbon Fiber surface");
db486a6e 1118 plA0.Draw();
1119 plA1.Draw();
1120 plB0.Draw();
1121 plB1.Draw();
1122 //pmA.Draw();
1123 //pmB.Draw();
1124 //
a53658c6 1125 x = 1.0;
1126 y = -2.5;
db486a6e 1127 Char_t chr[3];
1128 for(i=0;i<kNRadii;i++){
1129 sprintf(chr,"%2d",i);txt.DrawLatex(x-0.1,y,chr);
a53658c6 1130 sprintf(chr,"%8.4f",5.000);txt.DrawLatex(x,y,chr);
1131 sprintf(chr,"%8.4f",5.000);txt.DrawLatex(x+0.5,y,chr);
1132 sprintf(chr,"%8.4f",5.000);txt.DrawLatex(x+1.0,y,chr);
1133 sprintf(chr,"%8.4f",5.000);txt.DrawLatex(x+1.5,y,chr);
1134 sprintf(chr,"%8.4f",5.000);txt.DrawLatex(x+2.0,y,chr);
1135 if(kTRUE) txt.DrawLatex(x+2.5,y,"A-A/E-E");
db486a6e 1136 else txt.DrawLatex(x+2.5,y,"E-E");
1137 } // end for i
1138 txt.DrawLatex(x,y,"x_{c} mm");
1139 txt.DrawLatex(x+0.5,y,"y_{c} mm");
1140 txt.DrawLatex(x+1.0,y,"R mm");
1141 txt.DrawLatex(x+1.5,y,"#theta_{start}^{#circle}");
1142 txt.DrawLatex(x+2.0,y,"#theta_{end}^{#circle}");
1143 txt.DrawLatex(x+2.5,y,"Section");
1144 //
1145}
592651e2 1146
297369a1 1147//______________________________________________________________________
1148TGeoVolume* AliITSv11GeometrySPD::CreateLadder(Int_t layer,Double_t &length,
1149 Double_t &width,Double_t &thickness, TGeoManager *mgr){
592651e2 1150 // Creates the "ladder" = silicon sensor + 5 chips.
1151 // All parts are implemented as TGeoBBox and inserted
1152 // into a container which is the return value of this method.
592651e2 1153 // The sizes of the components come from drawings
32b9c3dd 1154 // of the Technical office of INFN Padova.
297369a1 1155 // Due to the requirement to specify the sensitive volume
1156 // separately from the rest, the sensor is implemented as the
1157 // sum of a central sensitive part + a guard ring.
32b9c3dd 1158 // Also the bump-bondings are added in form of small cylinders.
592651e2 1159 // ---
1160 // Arguments:
1161 // - the layer which will own this ladder (MUST be 1 or 2)
1162 // - the used TGeoManager
1163 // ---
1164 // Returns:
1165 // - the container TGeoBBox (return value)
1166 // - the size of the container box (arguments passed by reference)
1167 // ---
1168 // NOTE 1
297369a1 1169 // Here and in the other methods which contribute to the stave
1170 // definition a convention is used for the naming of the three
1171 // dimensions of the volumes:
1172 // - 'length' refers to the size in the Z direction of the
1173 // ALICE reference frame
1174 // - 'width' refers to the "large" dimension orthogonal to
1175 // Z axis in the local reference frame of the
1176 // object being implemented (e.g., 15.95 mm for
1177 // the chips)
1178 // - 'thickness' refers to the "small" dimension orthogonal to
1179 // Z axis, which is also the direction along which
1180 // the components are superimposed on each other
592651e2 1181 // ---
1182 // NOTE 2
297369a1 1183 // all sizes taken are expressed in mm in drawings, and this is
1184 // kept as is, to avoid confusion the conversion is made
1185 // multiplying by the conversion factor
592651e2 1186
1187 // ** CRITICAL CHECK **
1188 // layer number can be ONLY 1 or 2
32b9c3dd 1189 if (layer != 1 && layer != 2) AliFatal("Layer number MUST be 1 or 2");
592651e2 1190
1191 // instantiate all required media
32b9c3dd 1192 TGeoMedium *medAir = mgr->GetMedium("Air");
592651e2 1193 TGeoMedium *medSPDSiChip = mgr->GetMedium("SPD SI CHIP");
32b9c3dd 1194 TGeoMedium *medSi = mgr->GetMedium("Si");
1195 TGeoMedium *medBumpBond = mgr->GetMedium("BumpBond");
592651e2 1196
32b9c3dd 1197 // ** Define sizes **
592651e2 1198 // they are expressed in mm in the drawings so they require conversion
32b9c3dd 1199 // 'length' is in the direction of the detector length (Z axis)
592651e2 1200 // 'thickness' is obvious
32b9c3dd 1201 // 'width' is in the direction orthogonal to 'width' and 'thickness'
297369a1 1202
32b9c3dd 1203 // for the chip, also the spacing between them is required
1204 Double_t chipThickness = fgkmm * 0.150;
1205 Double_t chipWidth = fgkmm * 15.950;
1206 Double_t chipLength = fgkmm * 13.600;
1207 Double_t chipSpacing = fgkmm * 0.400;
1208
1209 // for the sensor, we define the area of sensitive volume
1210 // while the guard ring is added as a separate piece
1211 Double_t sensThickness = fgkmm * 0.200;
1212 Double_t sensLength = fgkmm * 69.600;
1213 Double_t sensWidth = fgkmm * 13.920;
1214 Double_t guardRingWidth = fgkmm * 0.560;
1215
1216 // bump bond is defined as a small stripe of height = 0.012 mm
1217 // and a suitable width to keep the same volume it has
1218 // before being compressed (a line of spheres of 0.025 mm radius)
1219 Double_t bbLength = fgkmm * 0.042;
1220 Double_t bbWidth = sensWidth;
1221 Double_t bbThickness = fgkmm * 0.012;
297369a1 1222 Double_t bbPos = 0.080; // Z position w.r. to left pixel edge
592651e2 1223
32b9c3dd 1224 // ** Create volumes **
1225 // the container is the return value, and is built as a box
297369a1 1226 // whose edges exactly enclose the stuff we inserted here,
1227 // filled with air. Its name depends on the layer number.
32b9c3dd 1228 width = chipWidth;
1229 length = sensLength + 2.0*guardRingWidth;
1230 thickness = sensThickness + chipThickness + bbThickness;
297369a1 1231 TGeoVolume *container = mgr->MakeBox(Form("LAY%d_LADDER", layer),
1232 medAir, 0.5*thickness, 0.5*width, 0.5*length);
32b9c3dd 1233 // the chip is a simple box:
297369a1 1234 TGeoVolume *volChip = mgr->MakeBox("CHIP", medSPDSiChip,
1235 0.5*chipThickness, 0.5*chipWidth, 0.5*chipLength);
1236
1237 // the sensor is the union of a box and a border, to separate
1238 // sensitive part from the rest the sensitive volume (inner part)
1239 // is named according to the owner layer. To compute the shape
1240 // subtraction which is needed for this we create two shapes,
1241 // which are two boxes with the same center. The smaller one is
1242 // then used to define the sensor, while the subtraction of the two
32b9c3dd 1243 // is used for the guard ring.
297369a1 1244 TGeoBBox *shSens = new TGeoBBox(0.5*sensThickness, 0.5*sensWidth,
1245 0.5*sensLength);
1246 TGeoBBox *shIn = new TGeoBBox(sensThickness, 0.5*sensWidth,
1247 0.5*sensLength);
1248 TGeoBBox *shOut = new TGeoBBox(0.5*sensThickness,
1249 0.5*sensWidth + guardRingWidth,
1250 0.5*sensLength + guardRingWidth);
32b9c3dd 1251 shIn->SetName("innerBox");
1252 shOut->SetName("outerBox");
297369a1 1253 TGeoCompositeShape *shBorder = new TGeoCompositeShape("",
1254 "outerBox-innerBox");
1255 TGeoVolume *volSens = new TGeoVolume(Form("LAY%d_SENSOR", layer),
1256 shSens, medSi);
32b9c3dd 1257 TGeoVolume *volBorder = new TGeoVolume("GUARD_RING", shBorder, medSi);
297369a1 1258
32b9c3dd 1259 // one line of bumpbonds
297369a1 1260 TGeoVolume *volBB = mgr->MakeBox("BB", medBumpBond, 0.5*bbThickness,
1261 0.5*bbWidth, 0.5*bbLength);
1262
32b9c3dd 1263 // set colors of all objects for visualization
592651e2 1264 volSens->SetLineColor(kYellow + 1);
1265 volChip->SetLineColor(kGreen);
32b9c3dd 1266 volBorder->SetLineColor(kYellow + 3);
592651e2 1267
297369a1 1268 // translations for the chip box: direction of length and
1269 // thickness (moved down)
592651e2 1270 TGeoTranslation *trChip[5] = {0, 0, 0, 0, 0};
32b9c3dd 1271 Double_t x = 0.5 * (chipThickness - thickness);
1272 Double_t y = 0.0;
1273 Double_t z = 0.0;
592651e2 1274 Int_t i;
1275 for (i = 0; i < 5; i++) {
297369a1 1276 z = -0.5*length + guardRingWidth + (Double_t)i*chipSpacing +
1277 ((Double_t)(i) + 0.5)*chipLength;
592651e2 1278 trChip[i] = new TGeoTranslation(x, y, z);
297369a1 1279 } // end for i
592651e2 1280
297369a1 1281 // translation for the sensor parts: direction of width (moved
1282 // to edge of container) and thickness (moved up)
32b9c3dd 1283 x = 0.5 * (thickness - sensThickness);
1284 y = 0.5 * (width - sensWidth - 2.0*guardRingWidth);
1285 z = 0.0;
1286 TGeoTranslation *trSens = new TGeoTranslation(x, y, z);
1287
1288 // translation for the bump bonds:
1289 // keep same y used for sensors, but change the Z
1290 TGeoTranslation *trBB[160];
1291 //x = 0.5 * (thickness - bbThickness) + 0.5*sensThickness;
1292 x = 0.5 * (thickness - bbThickness) - sensThickness;
1293 z = -0.5 * sensLength + guardRingWidth + fgkmm*0.425 - bbPos;
1294 for (i = 0; i < 160; i++) {
1295 trBB[i] = new TGeoTranslation(x, y, z);
1296 switch(i) {
1297 case 31:
1298 case 63:
1299 case 95:
1300 case 127:
1301 z += fgkmm * 0.625 + fgkmm * 0.2;
1302 break;
1303 default:
1304 z += fgkmm * 0.425;
297369a1 1305 } // end switch
1306 } // end for i
32b9c3dd 1307
592651e2 1308 // add nodes to container
1309 container->AddNode(volSens, 1, trSens);
32b9c3dd 1310 container->AddNode(volBorder, 1, trSens);
1311 for (i = 0; i < 160; i++) container->AddNode(volBB, i, trBB[i]);
297369a1 1312 for (i = 0; i < 5; i++){
1313 container->AddNode(volChip, i + 2, trChip[i]);
1314 } // end for i
592651e2 1315
1316 // return the container
1317 return container;
1318}
592651e2 1319/*
297369a1 1320//______________________________________________________________________
1321TGeoVolume* AliITSv11GeometrySPD::CreateGroundingFoilSingle(Bool_t kaptonLayer,
1322 Double_t &length, Double_t &width, Double_t &thickness, TGeoManager *mgr){
592651e2 1323 //
1324 // Creates the grounding foil layer made in Kapton.
297369a1 1325 // Both layers of the grounding foil have the same shape, but
1326 // with small differences in the size of some parts (holes,
1327 // overall size). The Kapton layer is a little bit wider and
1328 // has smaller holes.
592651e2 1329 // ---
297369a1 1330 // The complete object is created as the superimposition of
1331 // an XTRU with some holes
592651e2 1332 // ---
1333 // Whenever possible, the size of the parts is parameterized with
1334 // variable names, even if their value is fixed according
1335 // to the design parameters given by engineers' drawings.
1336 // ---
1337 // Returns: a TGeoVolume object which contains all parts of this layer
1338 //
1339
297369a1 1340 // The shape of the grounding foil is an irregular polygon, which
1341 // can easily be implemented as a TGeoXtru using the corners as
1342 // reference points:
592651e2 1343 //
297369a1 1344 // 0 1
1345 // +-----------------------------------------------------------------------------+
1346 // | 7 6 3 |
1347 // | +--------------+ +----------------+ 2
1348 // | O | | |
1349 // | 9 /-----+ 8 +------+ 4
1350 // | / 5
1351 // | 11 /--------------/ 10
1352 // +-------------/
1353 // 13 12
592651e2 1354 //
297369a1 1355 // in total: 14 points (X is just a referencem but is unused in
1356 // the implementation. The whole shape can be subdivided into
1357 // sectors delimited by vertical lines passing througth the
1358 // points in the lower part of the shape. This convention is
1359 // used to names their length which is different for each one
1360 // (the widths, instead, are common for some)
592651e2 1361 // instantiate the media:
1362 // - kapton/aluminum for the pysical volumes
297369a1 1363 TGeoMedium *material = kaptonLayer ? mgr->GetMedium("KAPTON") :
1364 mgr->GetMedium("AL");
592651e2 1365
1366 // label
1367 char type[3];
1368 if (kaptonLayer) {
1369 strcpy(type, "KP");
1370 thickness = fgkmm * 0.05;
1371 }
1372 else {
1373 strcpy(type, "AL");
1374 thickness = fgkmm * 0.02;
1375 }
1376
1377 // define the length of all sectors (from leftmost to rightmost)
1378 Int_t i;
297369a1 1379 Double_t sectorLength[] = {140.71,2.48,26.78,4.0,10.0,24.4,10.0,24.81};
592651e2 1380 if (!kaptonLayer) {
1381 sectorLength[0] -= 0.2;
1382 sectorLength[4] -= 0.2;
1383 sectorLength[5] += 0.4;
1384 sectorLength[6] -= 0.4;
1385 }
1386 length = 0.0;
1387 for (i = 0; i < 8; i++) {
1388 sectorLength[i] *= fgkmm;
1389 length += sectorLength[i];
1390 }
1391
297369a1 1392 // as shown in the drawing, we have three different widths in
1393 // this shape:
592651e2 1394 Double_t widthMax = fgkmm * 15.95;
1395 Double_t widthMed1 = fgkmm * 15.00;
1396 Double_t widthMed2 = fgkmm * 11.00;
1397 Double_t widthMin = fgkmm * 4.40;
1398 if (!kaptonLayer) {
1399 widthMax -= fgkmm * 0.4;
1400 widthMed1 -= fgkmm * 0.4;
1401 widthMed2 -= fgkmm * 0.4;
1402 widthMin -= fgkmm * 0.4;
1403 }
1404 width = widthMax;
1405
297369a1 1406 // the vertices of the polygon are arrays correctly ordered in
1407 // the counterclockwise direction: initially we place the point
1408 // 0 in the origin, and all others will be defined accordingly
592651e2 1409 Double_t x[14], y[14];
1410 x[ 0] = 0.0;
1411 y[ 0] = 0.0;
1412
1413 x[ 1] = x[0] + length;
1414 y[ 1] = 0.0;
1415
1416 x[ 2] = x[1];
1417 y[ 2] = -widthMin;
1418
1419 x[ 3] = x[2] - sectorLength[7];
1420 y[ 3] = y[2];
1421
1422 x[ 4] = x[3];
1423 y[ 4] = -widthMed2;
1424
1425 x[ 5] = x[4] - sectorLength[6];
1426 y[ 5] = y[4];
1427
1428 x[ 6] = x[5];
1429 y[ 6] = -widthMin;
1430
1431 x[ 7] = x[6] - sectorLength[5];
1432 y[ 7] = y[6];
1433
1434 x[ 8] = x[7];
1435 y[ 8] = -widthMed2;
1436
1437 x[ 9] = x[8] - sectorLength[4];
1438 y[ 9] = y[8];
1439
1440 x[10] = x[9] - sectorLength[3];
1441 y[10] = -widthMed1;
1442
1443 x[11] = x[10] - sectorLength[2];
1444 y[11] = y[10];
1445
1446 x[12] = x[11] - sectorLength[1];
1447 y[12] = -widthMax;
1448
1449 x[13] = x[0];
1450 y[13] = -widthMax;
1451
297369a1 1452 // then, we shift all points in such a way that the origin will
1453 // be at the centers
592651e2 1454 for (i = 0; i < 14; i++) {
1455 x[i] -= 0.5*length;
1456 y[i] += 0.5*width;
1457 }
1458
1459 // create the shape
1460 char shName[200];
1461 sprintf(shName, "SH_%sGFOIL_FULL", type);
1462 TGeoXtru *shGroundFull = new TGeoXtru(2);
1463 shGroundFull->SetName(shName);
1464 shGroundFull->DefinePolygon(14, x, y);
1465 shGroundFull->DefineSection(0, -0.5*thickness, 0., 0., 1.0);
1466 shGroundFull->DefineSection(1, 0.5*thickness, 0., 0., 1.0);
1467
297369a1 1468 // this volume contains some holes which are here implemented
1469 // as simple boxes of fixed size, which are displaced along the
1470 // shape itself and then composed using the facilities of the
1471 // TGeo package
1472
592651e2 1473 Double_t holeLength = fgkmm * 10.00;
1474 Double_t holeWidth = fgkmm * 7.50;
297369a1 1475 Double_t holeSepX0 = fgkmm * 7.05;//separation between center
1476 //of first hole and left border
1477 Double_t holeSepXC = fgkmm * 14.00;//separation between the
1478 // centers of two consecutive holes
1479 Double_t holeSepX1 = fgkmm * 15.42;//separation between centers
1480 // of 5th and 6th hole
1481 Double_t holeSepX2 = fgkmm * 22.00;//separation between centers
1482 // of 10th and 11th hole
592651e2 1483 if (!kaptonLayer) {
1484 holeSepX0 -= fgkmm * 0.2;
1485 holeLength += fgkmm * 0.4;
1486 holeWidth += fgkmm * 0.4;
1487 }
1488
1489 // X position of hole center (will change for each hole)
1490 Double_t holeX = -0.5*length;
1491 // Y position of center of all holes (= 4.4 mm from upper border)
1492 Double_t holeY = 0.5*(width - holeWidth) - widthMin;
1493 //if (!kaptonLayer) holeY += 0.02;
1494
1495 // create a shape for the holes (common)
1496 char holeName[200];
1497 sprintf(holeName, "%sHOLE", type);
1498 TGeoBBox *shHole = 0;
297369a1 1499 shHole = new TGeoBBox(holeName,0.5*holeLength,0.5*holeWidth,thickness);
592651e2 1500
1501 // insert the holes in the XTRU shape:
297369a1 1502 // starting from the first value of X, they are simply shifted
1503 // along this axis
592651e2 1504 char trName[200];
1505 TGeoTranslation *transHole[11];
1506 TString strComposite(shName);
1507 strComposite.Append("-(");
1508 for (Int_t i = 0; i < 11; i++) {
1509 // set the position of the hole, depending on index
1510 if (i == 0) {
1511 holeX += holeSepX0;
1512 }
1513 else if (i < 4) {
1514 holeX += holeSepXC;
1515 }
1516 else if (i == 4) {
1517 holeX += holeSepX1;
1518 }
1519 else if (i < 10) {
1520 holeX += holeSepXC;
1521 }
1522 else {
1523 holeX += holeSepX2;
1524 }
1525 sprintf(trName, "%sTR%d", type, i);
1526 transHole[i] = new TGeoTranslation(trName, holeX, holeY, 0.0);
1527 transHole[i]->RegisterYourself();
1528 strComposite.Append(holeName);
1529 strComposite.Append(":");
1530 strComposite.Append(trName);
1531 if (i < 10) strComposite.Append("+");
59da35b6 1532 //MM cout << holeX << endl;
592651e2 1533 }
1534 strComposite.Append(")");
59da35b6 1535 //MM cout << strComposite.Data() << endl;
592651e2 1536
1537 // create composite shape (with holes)
297369a1 1538 TGeoCompositeShape *shGround = new TGeoCompositeShape(
1539 Form("SH_%sGFOIL", type), strComposite.Data());
592651e2 1540
1541 // create the volume
297369a1 1542 TGeoVolume *vol = new TGeoVolume(Form("%sGFOIL",type),shGround,
1543 material);
592651e2 1544 return vol;
1545}
1546*/
297369a1 1547//______________________________________________________________________
1548TGeoVolume* AliITSv11GeometrySPD::CreateGroundingFoilSingle(
1549 Bool_t kaptonLayer, Double_t &length, Double_t &width,
1550 Double_t &thickness, TGeoManager *mgr){
592651e2 1551 // Creates the grounding foil layer made in Kapton.
1552 // Both layers of the grounding foil have the same shape, but with small
1553 // differences in the size of some parts (holes, overall size).
1554 // The Kapton layer is a little bit wider and has smaller holes.
1555 // ---
1556 // The complete object is created as the sum of the following parts:
1557 // 1) the part which is connected to the chips, which is a
1558 // simple BOX with some box-shaped holes at regular intervals
1559 // 2) a trapezoidal connection where the Y size changes
1560 // 3) another box with a unique hole of the same shape and size as above
1561 // 4) another trapezoidal connection where the Y size changes
1562 // 5) a final part which is built as a sequence of 4 BOX volumes
297369a1 1563 // where the first and the third are equal and the others have
1564 // same size in Y.
592651e2 1565 // ---
1566 // Whenever possible, the size of the parts is parameterized with
1567 // variable names, even if their value is fixed according
1568 // to the design parameters given by engineers' drawings.
1569 // ---
1570 // Returns: a TGeoVolume object which contanis all parts of this layer
1571 //
1572
1573 // instantiate the media:
1574 // - vacuum for the container volume
1575 // - kapton for the pysical volumes
1576 TGeoMedium *vacuum = mgr->GetMedium("VACUUM");
1577 TGeoMedium *material = mgr->GetMedium("KAPTON");
1578
1579 // === Define size of all elements ===
1580 Double_t sizeZ = fgkmm * 0.05;
1581
1582 Double_t part1X = fgkmm * 140.71;
1583 Double_t part2X = fgkmm * 2.48;
1584 Double_t part3X = fgkmm * 26.78;
1585 Double_t part4X = fgkmm * 4.00;
1586 Double_t part5X = fgkmm * 10.00;
1587 Double_t part6X = fgkmm * 24.40;
1588 Double_t part7X = fgkmm * 10.00;
1589 Double_t part8X = fgkmm * 24.81;
1590
1591 Double_t sizeYMax = fgkmm * 15.95;
1592 Double_t sizeYMed1 = fgkmm * 15.00;
1593 Double_t sizeYMed2 = fgkmm * 11.00;
1594 Double_t sizeYMin = fgkmm * 4.40;
1595
1596 Double_t holeX = fgkmm * 10.00;
1597 Double_t holeY = fgkmm * 7.50;
297369a1 1598 Double_t holeSepX = fgkmm * 14.00; // separation between the
1599 // centers of two consecutive
1600 // holes
1601 Double_t holeSepX1 = fgkmm * 1.42; // to be added after 4th hole
1602 // in volume 1
1603 Double_t holeFirstX = fgkmm * 7.05; // position of center of first
1604 // hole
1605 Double_t holeSepY = fgkmm * 4.40; // dist between hole's and
1606 // volume's upper border
1607 Double_t holeAloneX = fgkmm * 13.28; // position of hole center
1608 // in box "part 3"
1609
592651e2 1610 // correct data in case we are on Aluminum foil
1611 if (!kaptonLayer) {
1612 material = mgr->GetMedium("AL");
1613 sizeZ = fgkmm * 0.02;
1614 part1X -= fgkmm * 0.2;
1615 part5X -= fgkmm * 0.2;
1616 part6X += fgkmm * 0.4;
1617 part7X -= fgkmm * 0.4;
1618
1619 sizeYMax -= fgkmm * 0.4;
1620 sizeYMed1 -= fgkmm * 0.4;
1621 sizeYMed2 -= fgkmm * 0.4;
1622 sizeYMin -= fgkmm * 0.4;
1623
1624 holeX += fgkmm * 0.4;
1625 holeY += fgkmm * 0.4;
1626 holeFirstX -= fgkmm * 0.2;
1627 holeSepY -= fgkmm * 0.4;
1628 }
1629
1630 // define names for the object
1631 char type[4];
1632 if (kaptonLayer) strcpy(type, "KAP"); else strcpy(type, "ALU");
1633
1634 // compute full length and width
297369a1 1635 length = part1X + part2X + part3X + part4X + part5X + part6X +
1636 part7X + part8X;
592651e2 1637 width = sizeYMax;
1638 thickness = sizeZ;
1639
297369a1 1640 // grounding foil world, bounded exactly around the limits
1641 // of the structure
1642 TGeoVolume *container = mgr->MakeBox(Form("GFOIL_%s", type),
1643 vacuum, 0.5*length, 0.5*sizeYMax, 0.5*sizeZ);
1644
592651e2 1645 // === PART 1: box with holes ===
297369a1 1646
592651e2 1647 TGeoBBox *shBox1 = 0, *shHole = 0;
297369a1 1648 shBox1 = new TGeoBBox(Form("GF%s_BOX1", type), 0.5*part1X,
1649 0.5*sizeYMax, 0.5*sizeZ);
1650 shHole = new TGeoBBox(Form("GF%s_HOLE", type), 0.5*holeX, 0.5*holeY,
1651 0.5*sizeZ + 0.01);
1652
592651e2 1653 // define the position of all holes and compose the expression
1654 // to define the composite shape (box - holes)
1655 Double_t firstX = -0.5*part1X + holeFirstX;
1656 Double_t transY = 0.5*sizeYMax - holeSepY - 0.5*holeY;
1657 Double_t transX;
1658 TGeoTranslation *transHole[10];
1659 TString strComposite(Form("%s - (", shBox1->GetName()));
1660 for (Int_t i = 0; i < 10; i++) {
1661 transX = firstX + (Double_t)i * holeSepX;
1662 if (i > 4) transX += holeSepX1;
297369a1 1663 transHole[i] = new TGeoTranslation(Form("TGF%s_HOLE%d",type,i),
1664 transX, transY, 0.0);
592651e2 1665 transHole[i]->RegisterYourself();
297369a1 1666 strComposite.Append(Form("%s:%s", shHole->GetName(),
1667 transHole[i]->GetName()));
1668 if (i < 9) strComposite.Append("+");
1669 else strComposite.Append(")");
1670 } // end for i
592651e2 1671 // create composite shape
297369a1 1672 TGeoCompositeShape *shPart1 = new TGeoCompositeShape(
1673 Form("GF%s_PART1_SHAPE", type), strComposite.Data());
592651e2 1674 // create the volume
297369a1 1675 TGeoVolume *volPart1 = new TGeoVolume(Form("GF%s_PART1", type),
1676 shPart1, material);
1677
592651e2 1678 // === PART 2: first trapezoidal connection
1679
1680 TGeoArb8 *shTrap1 = new TGeoArb8(0.5*sizeZ);
1681 shTrap1->SetVertex(0, -0.5*part2X, 0.5*sizeYMax);
1682 shTrap1->SetVertex(1, 0.5*part2X, 0.5*sizeYMax);
1683 shTrap1->SetVertex(2, 0.5*part2X, 0.5*sizeYMax - sizeYMed1);
1684 shTrap1->SetVertex(3, -0.5*part2X, -0.5*sizeYMax);
1685 shTrap1->SetVertex(4, -0.5*part2X, 0.5*sizeYMax);
1686 shTrap1->SetVertex(5, 0.5*part2X, 0.5*sizeYMax);
1687 shTrap1->SetVertex(6, 0.5*part2X, 0.5*sizeYMax - sizeYMed1);
1688 shTrap1->SetVertex(7, -0.5*part2X, -0.5*sizeYMax);
297369a1 1689 TGeoVolume *volPart2 = new TGeoVolume(Form("GF%s_PART2", type),
1690 shTrap1, material);
592651e2 1691
1692 // === PART 3: other box with one hole
1693
1694 TGeoBBox *shBox2 = 0;
297369a1 1695 shBox2 = new TGeoBBox(Form("GF%s_BOX2", type), 0.5*part3X,
1696 0.5*sizeYMed1, 0.5*sizeZ);
592651e2 1697
1698 // define the position of the hole
1699 transX = holeAloneX - 0.5*part3X;
297369a1 1700 TGeoTranslation *transHoleAlone = new TGeoTranslation(
1701 Form("TGF%s_HOLE_ALONE", type), transX, transY, 0.0);
592651e2 1702 transHoleAlone->RegisterYourself();
1703 // create composite shape
297369a1 1704 TGeoCompositeShape *shPart3 = new TGeoCompositeShape(
1705 Form("GF%sPART3_SHAPE", type),
1706 Form("%s - %s:%s", shBox2->GetName(),
1707 shHole->GetName(), transHoleAlone->GetName()));
592651e2 1708 // create the volume
297369a1 1709 TGeoVolume *volPart3 = new TGeoVolume(Form("GF%s_PART3", type),
1710 shPart3, material);
592651e2 1711
1712 // === PART 4: second trapezoidal connection
1713
1714 TGeoArb8 *shTrap2 = new TGeoArb8(0.5*sizeZ);
1715 shTrap2->SetVertex(0, -0.5*part4X, 0.5*sizeYMed1);
1716 shTrap2->SetVertex(1, 0.5*part4X, 0.5*sizeYMed1);
1717 shTrap2->SetVertex(2, 0.5*part4X, 0.5*sizeYMed1 - sizeYMed2);
1718 shTrap2->SetVertex(3, -0.5*part4X, -0.5*sizeYMed1);
1719 shTrap2->SetVertex(4, -0.5*part4X, 0.5*sizeYMed1);
1720 shTrap2->SetVertex(5, 0.5*part4X, 0.5*sizeYMed1);
1721 shTrap2->SetVertex(6, 0.5*part4X, 0.5*sizeYMed1 - sizeYMed2);
1722 shTrap2->SetVertex(7, -0.5*part4X, -0.5*sizeYMed1);
297369a1 1723 TGeoVolume *volPart4 = new TGeoVolume(Form("GF%s_PART4", type),
1724 shTrap2, material);
592651e2 1725
1726 // === PART 5 --> 8: sequence of boxes ===
1727
297369a1 1728 TGeoVolume *volPart5 = mgr->MakeBox(Form("GF%s_BOX3", type),
1729 material, 0.5*part5X, 0.5*sizeYMed2, 0.5*sizeZ);
1730 TGeoVolume *volPart6 = mgr->MakeBox(Form("GF%s_BOX4", type),
1731 material, 0.5*part6X, 0.5*sizeYMin , 0.5*sizeZ);
1732 TGeoVolume *volPart7 = mgr->MakeBox(Form("GF%s_BOX5", type),
1733 material, 0.5*part7X, 0.5*sizeYMed2, 0.5*sizeZ);
1734 TGeoVolume *volPart8 = mgr->MakeBox(Form("GF%s_BOX6", type),
1735 material, 0.5*part8X, 0.5*sizeYMin , 0.5*sizeZ);
592651e2 1736
1737 // === SET COLOR ===
1738 if (kaptonLayer) {
1739 volPart1->SetLineColor(kRed + 3);
1740 volPart2->SetLineColor(kRed + 3);
1741 volPart3->SetLineColor(kRed + 3);
1742 volPart4->SetLineColor(kRed + 3);
1743 volPart5->SetLineColor(kRed + 3);
1744 volPart6->SetLineColor(kRed + 3);
1745 volPart7->SetLineColor(kRed + 3);
1746 volPart8->SetLineColor(kRed + 3);
297369a1 1747 }else{
592651e2 1748 volPart1->SetLineColor(kGreen);
1749 volPart2->SetLineColor(kGreen);
1750 volPart3->SetLineColor(kGreen);
1751 volPart4->SetLineColor(kGreen);
1752 volPart5->SetLineColor(kGreen);
1753 volPart6->SetLineColor(kGreen);
1754 volPart7->SetLineColor(kGreen);
1755 volPart8->SetLineColor(kGreen);
297369a1 1756 } // end if (kaptonLayer)
592651e2 1757
1758 // === TRANSLATION OF ALL PARTS ===
1759
1760 transX = 0.5*(part1X - length);
1761 TGeoTranslation *transPart1 = new TGeoTranslation(transX, 0.0, 0.0);
1762 transX += 0.5*(part1X + part2X);
1763 TGeoTranslation *transPart2 = new TGeoTranslation(transX, 0.0, 0.0);
1764 transX += 0.5*(part2X + part3X);
1765 transY = 0.5*(sizeYMax - sizeYMed1);
1766 TGeoTranslation *transPart3 = new TGeoTranslation(transX, transY, 0.0);
1767 transX += 0.5*(part3X + part4X);
1768 TGeoTranslation *transPart4 = new TGeoTranslation(transX, transY, 0.0);
1769 transX += 0.5*(part4X + part5X);
1770 transY = 0.5*(sizeYMax - sizeYMed2);
1771 TGeoTranslation *transPart5 = new TGeoTranslation(transX, transY, 0.0);
1772 transX += 0.5*(part5X + part6X);
1773 transY = 0.5*(sizeYMax - sizeYMin);
1774 TGeoTranslation *transPart6 = new TGeoTranslation(transX, transY, 0.0);
1775 transX += 0.5*(part6X + part7X);
1776 transY = 0.5*(sizeYMax - sizeYMed2);
1777 TGeoTranslation *transPart7 = new TGeoTranslation(transX, transY, 0.0);
1778 transX += 0.5*(part7X + part8X);
1779 transY = 0.5*(sizeYMax - sizeYMin);
1780 TGeoTranslation *transPart8 = new TGeoTranslation(transX, transY, 0.0);
1781
1782 // add the partial volumes to the container
1783 container->AddNode(volPart1, 1, transPart1);
1784 container->AddNode(volPart2, 2, transPart2);
1785 container->AddNode(volPart3, 3, transPart3);
1786 container->AddNode(volPart4, 4, transPart4);
1787 container->AddNode(volPart5, 5, transPart5);
1788 container->AddNode(volPart6, 6, transPart6);
1789 container->AddNode(volPart7, 7, transPart7);
1790 container->AddNode(volPart8, 8, transPart8);
1791
1792 return container;
1793}
1794
297369a1 1795//______________________________________________________________________
1796TGeoVolume* AliITSv11GeometrySPD::CreateGroundingFoil(Double_t &thickness,
1797 TGeoManager *mgr){
592651e2 1798 // Joins two Kapton and two Aluminum layers of the grounding foil
1799 // in order to create the complete grounding foil for a whole stave.
1800 // into a unique container volume, which is returned as output.
297369a1 1801 // The use of the TGeoXtru shape requires that in the separate
1802 // foils, the Z axis lies perpendicularly to the polygonal basis
1803 // of this shape; this caused the components to have their Z
1804 // axis corresponding to the X axis of the ALICE reference frame
1805 // and vieceversa; to correct this, a rotation is necessary
1806 // around their middle axis, to exchange X and Z axes and displace
1807 // the object correctly in the ALICE frame.
592651e2 1808 // ---
1809 // Arguments:
297369a1 1810 // - the sizes of the container box (passed by reference and
1811 // filled here)
592651e2 1812 // - the TGeoManager
1813 // ---
1814 // Returns:
1815 // - the container TGeoBBox (return value)
1816 // - the size of the container (reference variables)
1817 //
297369a1 1818
592651e2 1819 // sizes of the added volumes, which are filled by passing them
1820 // to the volume creation methods
1821 Double_t kpLength, kpWidth, kpThick;
1822 Double_t alLength, alWidth, alThick;
297369a1 1823 // separation between left and right volumes
1824 Double_t separation = fgkmm * 1.42;
1825
1826 // create the two component volumes (each one will be replicated
1827 // twice) this gives also the size of their virtual container
1828 // boxes (just a reference, not a volume)
1829 TGeoVolume *kVol = CreateGroundingFoilSingle(kTRUE, kpLength,
1830 kpWidth, kpThick, mgr);
1831 TGeoVolume *aVol = CreateGroundingFoilSingle(kFALSE, alLength,
1832 alWidth, alThick, mgr);
592651e2 1833 kVol->SetLineColor(kRed);
1834 aVol->SetLineColor(kGray);
1835
297369a1 1836 // kapton leads the total size of the foil (including spagcing
1837 // of 1.42 mm between them in the center)
592651e2 1838 Double_t length, width;
1839 length = 2.0 * kpLength + separation;
1840 width = kpWidth;
1841 thickness = kpThick + alThick;
1842
1843 // create the container
1844 TGeoMedium *vacuum = mgr->GetMedium("VACUUM");
297369a1 1845 TGeoVolume *container = mgr->MakeBox("GFOIL", vacuum, 0.5*thickness,
1846 0.5*width, 0.5*length);
592651e2 1847
1848 // create the common correction rotations
1849 TGeoRotation *rotCorr1 = new TGeoRotation(*gGeoIdentity);
1850 TGeoRotation *rotCorr2 = new TGeoRotation(*gGeoIdentity);
1851 rotCorr1->RotateY(-90.0);
1852 rotCorr2->RotateY( 90.0);
1853
297369a1 1854 // compute the translations to place the objects at the edges of
1855 // the volume the kapton foils are also shifted down, and the
1856 // aluminum foils are shifted up with respect to the thickness
1857 // direction
1858 TGeoTranslation *kTrans1 = new TGeoTranslation(0.5*(-thickness+kpThick),
1859 0.0,
1860 0.5*(length-kpLength));
1861 TGeoTranslation *kTrans2 = new TGeoTranslation(0.5*(-thickness+kpThick),
1862 0.0,
1863 0.5*(-length+kpLength));
1864 TGeoTranslation *aTrans1 = new TGeoTranslation(0.5*(thickness-alThick),
1865 0.0,
1866 0.5*(length-alLength)-0.02);
1867 TGeoTranslation *aTrans2 = new TGeoTranslation(0.5*(thickness-alThick),
1868 0.0,
1869 0.5*(-length+alLength)+0.02);
592651e2 1870
1871 // combine translations and rotations
1872 TGeoCombiTrans *kCombi1 = new TGeoCombiTrans(*kTrans1, *rotCorr1);
1873 TGeoCombiTrans *kCombi2 = new TGeoCombiTrans(*kTrans2, *rotCorr2);
1874 TGeoCombiTrans *aCombi1 = new TGeoCombiTrans(*aTrans1, *rotCorr1);
1875 TGeoCombiTrans *aCombi2 = new TGeoCombiTrans(*aTrans2, *rotCorr2);
1876
1877 // add to container
1878 container->AddNode(kVol, 0, kCombi1);
1879 container->AddNode(kVol, 1, kCombi2);
1880 container->AddNode(aVol, 0, aCombi1);
1881 container->AddNode(aVol, 1, aCombi2);
1882
1883 return container;
1884}
1885
1886//______________________________________________________________________
297369a1 1887TGeoVolume* AliITSv11GeometrySPD::CreateMCMBase(TGeoManager *geom) const{
592651e2 1888 // Creates the MCM basis volume.
1889 // It is a little bit more complicated because this is a plain base
297369a1 1890 // with a poly shape similar to the one of grounding foil but
1891 // there are also some chips glued to its base and covered with
1892 // a cave cap.
592651e2 1893 // ---
1894 // The complete MCM object is created as the sum of the following parts:
1895 // 1) a planar basis shaped according to the MCM typical shape
297369a1 1896 // 2) some boxes which represent the chips and devices mounted on
1897 // this base
592651e2 1898 // 3) a cave cap which covers the portion of MCM containing these chips
1899 // ---
297369a1 1900 // Due to the different widths of MCM, it is implemented in a
1901 // more complicated way:
1902 // - cap and chips will define a sub-volume of this structure,
1903 // which can be bounded by a complete box
592651e2 1904 // - base of MCM will be a separate volume
297369a1 1905 // - these two objects will need to be glued together into an
1906 // upper-level volume
592651e2 1907 // ---
1908 // This metod creates only the thin base (point 1 in the list)
1909 //
1910
1911 // medium
1912 TGeoMedium *medBase = geom->GetMedium("MCM BASE");
1913
1914 // parameterize the interesting sizes of MCM
297369a1 1915 // it is divided into 3 sectors which have different size in
1916 // X and Y and are connected by trapezoidal-based shapes,
1917 // where the oblique angle makes a 45 degrees angle with the
1918 // vertical, so that the X size and Y size of these "intermezzo"'s
1919 // is the same
592651e2 1920 // +--------------------------------+
1921 // | sect 2 |
1922 // | sect 1 --------------------+
1923 // +-----------/
1924 Double_t sizeZ = fgkmm * 0.35;
1925 Double_t sizeXtot = fgkmm * 105.6;
1926 Double_t sizeXsector[3] = {fgkmm * 28.4, fgkmm * 41.4, fgkmm * 28.8};
1927 Double_t sizeYsector[3] = {fgkmm * 15.0, fgkmm * 11.0, fgkmm * 8.0};
1928 Double_t sizeSep01 = fgkmm * 4.0, sizeSep12 = fgkmm * 3.0;
1929 Double_t sizeHole = fgkmm * 1.0;
1930 Double_t posHoleX = fgkmm * -0.5*sizeXtot + 26.7 + 0.5*sizeHole;
1931 Double_t posHoleY = fgkmm * -0.5*sizeYsector[0] + 0.5*sizeHole;
1932
1933 // define the shape of base volume as an XTRU with two identical faces
1934 // distantiated by the width of the itself
1935 Double_t x[8], y[8];
1936 x[0] = -0.5*sizeXtot;
1937 y[0] = 0.5*sizeYsector[0];
1938 x[1] = -x[0];
1939 y[1] = y[0];
1940 x[2] = x[1];
1941 y[2] = y[1] - sizeYsector[2];
1942 x[3] = x[2] - sizeXsector[2];
1943 y[3] = y[2];
1944 x[4] = x[3] - sizeSep12;
1945 y[4] = y[3] - sizeSep12;
1946 x[5] = x[4] - sizeXsector[1];
1947 y[5] = y[4];
1948 x[6] = x[5] - sizeSep01;
1949 y[6] = y[5] - sizeSep01;
1950 x[7] = x[0];
1951 y[7] = -y[0];
1952
1953 // create shape
1954 TGeoXtru *shPoly = new TGeoXtru(2);
1955 shPoly->SetName("SH_MCMBASE_POLY");
1956 shPoly->DefinePolygon(8, x, y);
1957 shPoly->DefineSection(0, -0.5*sizeZ, 0., 0., 1.0);
1958 shPoly->DefineSection(1, 0.5*sizeZ, 0., 0., 1.0);
1959
1960 // create small hole
1961 TGeoBBox *shHole = 0;
297369a1 1962 shHole = new TGeoBBox("SH_MCMBASE_HOLE", 0.5*sizeHole, 0.5*sizeHole,
1963 0.5*sizeZ+0.01);
1964 TGeoTranslation *transHole = new TGeoTranslation("TR_MCMBASE_HOLE",
1965 posHoleX, posHoleY, 0.0);
592651e2 1966 transHole->RegisterYourself();
1967
1968 // create shape intersection
297369a1 1969 TGeoCompositeShape *shBase = new TGeoCompositeShape("SH_MCMBASE",
1970 "SH_MCMBASE_POLY - SH_MCMBASE_HOLE:TR_MCMBASE_HOLE");
592651e2 1971
1972 // create volume
1973 TGeoVolume *volBase = new TGeoVolume("VOL_MCMBASE", shBase, medBase);
1974 volBase->SetLineColor(kRed);
1975
1976 return volBase;
1977}
592651e2 1978//______________________________________________________________________
297369a1 1979TGeoVolume* AliITSv11GeometrySPD::CreateMCMCoverBorder(TGeoManager *geom){
592651e2 1980 // Creates the MCM basis volume.
1981 // It is a little bit more complicated because this is a plain base
297369a1 1982 // with a poly shape similar to the one of grounding foil but there
1983 // are also some chips glued to its base and covered with a cave cap.
592651e2 1984 // ---
1985 // The complete MCM object is created as the sum of the following parts:
1986 // 1) a planar basis shaped according to the MCM typical shape
297369a1 1987 // 2) some boxes which represent the chips and devices mounted on
1988 // this base
592651e2 1989 // 3) a cave cap which covers the portion of MCM containing these chips
1990 // ---
297369a1 1991 // Due to the different widths of MCM, it is implemented in a more
1992 // complicated way:
1993 // - cap and chips will define a sub-volume of this structure,
1994 // which can be bounded by a complete box
592651e2 1995 // - base of MCM will be a separate volume
297369a1 1996 // - these two objects will need to be glued together into an
1997 // upper-level volume
592651e2 1998 // ---
297369a1 1999 // This metod creates the thicker cap and its contents (points 2-3
2000 // in the list). Since it covers only two of the three sectors of
2001 // the MCM base with different width
2002 // the computations and variables related to the largest sector
2003 // are removed, while
592651e2 2004 // the other are the same as the other part of the MCM.
2005 //
2006
2007 // media
2008 TGeoMedium *medCap = geom->GetMedium("MCM COVER");
2009
2010 // parameterize the interesting sizes of MCM
297369a1 2011 // it is divided into 3 sectors which have different size in
2012 // X and Y and are connected by trapezoidal-based shapes,
2013 // where the oblique angle makes a 45 degrees angle with the
2014 // vertical, so that the X size and Y size of these "intermezzo"'s
2015 // is the same
592651e2 2016 // +--------------------------------+
2017 // | sect 2 |
2018 // | sect 1 --------------------+
2019 // +-----------/
2020 Double_t sizeZ = fgkmm * 0.3;
2021 Double_t capHeight = fgkmm * 1.7 - sizeZ;
2022 Double_t sizeXtot = fgkmm * 73.2;
2023 Double_t sizeXsector[2] = {fgkmm * 41.4, fgkmm * 28.8};
2024 Double_t sizeYsector[2] = {fgkmm * 11.0, fgkmm * 8.0};
2025 Double_t sizeSep = fgkmm * 3.0;
2026
2027 // === PART 1: border ===
2028
2029 // define the shape of base volume as an XTRU with two identical faces
2030 // distantiated by the width of the itself
2031 Double_t x[6], y[6];
2032 x[0] = -0.5*sizeXtot;
2033 y[0] = 0.5*sizeYsector[0];
2034 x[1] = -x[0];
2035 y[1] = y[0];
2036 x[2] = x[1];
2037 y[2] = y[1] - sizeYsector[1];
2038 x[3] = x[2] - sizeXsector[1];
2039 y[3] = y[2];
2040 x[4] = x[3] - sizeSep;
2041 y[4] = y[3] - sizeSep;
2042 x[5] = x[0];
2043 y[5] = -y[0];
2044
2045 // create outer border shape with above coordinates
2046 TGeoXtru *capOut = new TGeoXtru(2);
2047 capOut->SetName("SH_MCMCAPOUT");
2048 capOut->DefinePolygon(6, x, y);
2049 capOut->DefineSection(0, -0.5*capHeight, 0., 0., 1.0);
2050 capOut->DefineSection(1, 0.5*capHeight, 0., 0., 1.0);
2051
2052 // the inner border is built similarly but subtracting the thickness
2053 Double_t angle = 45.0;
2054 Double_t cs = TMath::Cos( 0.5*(TMath::Pi() - angle*TMath::DegToRad()) );
2055 Double_t xin[6], yin[6];
2056 xin[0] = x[0] + sizeZ;
2057 yin[0] = y[0] - sizeZ;
2058 xin[1] = x[1] - sizeZ;
2059 yin[1] = yin[0];
2060 xin[2] = xin[1];
2061 yin[2] = y[2] + sizeZ;
2062 xin[3] = x[3] - sizeZ*cs;
2063 yin[3] = yin[2];
2064 xin[4] = xin[3] - sizeSep;
2065 yin[4] = y[4] + sizeZ;
2066 xin[5] = xin[0];
2067 yin[5] = yin[4];
2068
2069 // create inner border shape
2070 TGeoXtru *capIn = new TGeoXtru(2);
2071 capIn->SetName("SH_MCMCAPIN");
2072 capIn->DefinePolygon(6, xin, yin);
2073 capIn->DefineSection(0, -0.5*capHeight-0.01, 0., 0., 1.0);
2074 capIn->DefineSection(1, 0.5*capHeight+0.01, 0., 0., 1.0);
2075
2076 // compose shape
297369a1 2077 TGeoCompositeShape *shBorder = new TGeoCompositeShape("SH_MCMCAPBORDER",
2078 "SH_MCMCAPOUT-SH_MCMCAPIN");
592651e2 2079
2080 // create volume
297369a1 2081 TGeoVolume *volBorder = new TGeoVolume("VOL_MCMCAPBORDER", shBorder,
2082 medCap);
592651e2 2083 volBorder->SetLineColor(kGreen);
2084
2085 return volBorder;
2086}
592651e2 2087//______________________________________________________________________
297369a1 2088TGeoVolume* AliITSv11GeometrySPD::CreateMCMCoverTop(TGeoManager *geom){
592651e2 2089 // Creates the MCM basis volume.
2090 // It is a little bit more complicated because this is a plain base
297369a1 2091 // with a poly shape similar to the one of grounding foil but
2092 // there are also
592651e2 2093 // some chips glued to its base and covered with a cave cap.
2094 // ---
2095 // The complete MCM object is created as the sum of the following parts:
2096 // 1) a planar basis shaped according to the MCM typical shape
297369a1 2097 // 2) some boxes which represent the chips and devices mounted on
2098 // this base
592651e2 2099 // 3) a cave cap which covers the portion of MCM containing these chips
2100 // ---
297369a1 2101 // Due to the different widths of MCM, it is implemented in a
2102 // more complicated way:
2103 // - cap and chips will define a sub-volume of this structure,
2104 // which can be bounded by a complete box
592651e2 2105 // - base of MCM will be a separate volume
297369a1 2106 // - these two objects will need to be glued together into an
2107 // upper-level volume
592651e2 2108 // ---
297369a1 2109 // This metod creates the thicker cap and its contents (points
2110 // 2-3 in the list). Since it covers only two of the three
2111 // sectors of the MCM base with different width
2112 // the computations and variables related to the largest sector
2113 // are removed, while the other are the same as the other part
2114 // of the MCM.
592651e2 2115 //
297369a1 2116
592651e2 2117 // media
2118 TGeoMedium *medCap = geom->GetMedium("MCM COVER");
2119
2120 // parameterize the interesting sizes of MCM
297369a1 2121 // it is divided into 3 sectors which have different size in X
2122 // and Y and are connected by trapezoidal-based shapes, where
2123 // the oblique angle makes a 45 degrees angle with the vertical,
2124 // so that the X size and Y size of these "intermezzo"'s is the same
592651e2 2125 // +--------------------------------+
2126 // | sect 2 |
2127 // | sect 1 --------------------+
2128 // +-----------/
2129 Double_t sizeZ = fgkmm * 0.3;
2130 Double_t sizeXtot = fgkmm * 73.2;
2131 Double_t sizeXsector[2] = {fgkmm * 41.4, fgkmm * 28.8};
2132 Double_t sizeYsector[2] = {fgkmm * 11.0, fgkmm * 8.0};
2133 Double_t sizeSep = fgkmm * 3.0;
2134
2135 // === PART 1: border ===
2136
2137 // define the shape of base volume as an XTRU with two identical faces
2138 // distantiated by the width of the itself
2139 Double_t x[6], y[6];
2140 x[0] = -0.5*sizeXtot;
2141 y[0] = 0.5*sizeYsector[0];
2142 x[1] = -x[0];
2143 y[1] = y[0];
2144 x[2] = x[1];
2145 y[2] = y[1] - sizeYsector[1];
2146 x[3] = x[2] - sizeXsector[1];
2147 y[3] = y[2];
2148 x[4] = x[3] - sizeSep;
2149 y[4] = y[3] - sizeSep;
2150 x[5] = x[0];
2151 y[5] = -y[0];
2152
2153 // create outer border shape with above coordinates
2154 TGeoXtru *capOut = new TGeoXtru(2);
2155 capOut->SetName("SH_MCMCAPOUT");
2156 capOut->DefinePolygon(6, x, y);
2157 capOut->DefineSection(0, -0.5*sizeZ, 0., 0., 1.0);
2158 capOut->DefineSection(1, 0.5*sizeZ, 0., 0., 1.0);
2159
2160 // the inner border is built similarly but subtracting the thickness
2161 Double_t angle = 45.0;
2162 Double_t cs = TMath::Cos( 0.5*(TMath::Pi() - angle*TMath::DegToRad()) );
2163 Double_t xin[6], yin[6];
2164 xin[0] = x[0] + sizeZ;
2165 yin[0] = y[0] - sizeZ;
2166 xin[1] = x[1] - sizeZ;
2167 yin[1] = yin[0];
2168 xin[2] = xin[1];
2169 yin[2] = y[2] + sizeZ;
2170 xin[3] = x[3] - sizeZ*cs;
2171 yin[3] = yin[2];
2172 xin[4] = xin[3] - sizeSep;
2173 yin[4] = y[4] + sizeZ;
2174 xin[5] = xin[0];
2175 yin[5] = yin[4];
2176
2177 // coverage of upper part (equal to external border, but full)
2178 TGeoXtru *shCover = new TGeoXtru(2);
2179 shCover->SetName("SH_MCMCAPCOVER");
2180 shCover->DefinePolygon(6, x, y);
2181 shCover->DefineSection(0, -0.5*sizeZ, 0., 0., 1.0);
2182 shCover->DefineSection(1, 0.5*sizeZ, 0., 0., 1.0);
2183
2184 // create volume
297369a1 2185 TGeoVolume *volCover = new TGeoVolume("VOL_MCMCAPCOVER", shCover,
2186 medCap);
592651e2 2187 volCover->SetLineColor(kBlue);
2188
2189 return volCover;
2190}
592651e2 2191//______________________________________________________________________
297369a1 2192TGeoVolumeAssembly* AliITSv11GeometrySPD::CreateStave(Int_t layer,
2193 Double_t &fullThickness, TGeoManager *mgr){
2194 // Creates the complete stave as an assembly which contains all
2195 // the stuff defined in the "CreateStaveBase" method (which are
2196 // the thin part of the structure) and adds to this the thick
2197 // cover of the MCM and the Pixel bus. This is done as an
2198 // assembly to avoid the problem of a "ghost" overlap which occurs
2199 // when putting the stave on the carbon fiber sector, in the case
2200 // that we define it as a volume container.
592651e2 2201 // ---
2202 // Arguments:
2203 // - the layer where the stave has to be put (hard check on this)
2204 // - the geometry manager
2205 //
2206
2207 // ** CRITICAL CHECK **
2208 // layer number can be ONLY 1 or 2
297369a1 2209 if (layer != 1 && layer != 2)
2210 AliFatal("Required that layer number be 1 or 2");
592651e2 2211
2212 // sizes regarding the components
2213 Double_t baseWidth, baseHeight, baseThickness;
2214 Double_t mcmCapBorderThickness = fgkmm * 0.3;
2215 Double_t mcmCapThickness = fgkmm * 1.7 - mcmCapBorderThickness;
2216 Double_t mcmCapHeight = fgkmm * 11.0;
2217 Double_t mcmCapWidth = fgkmm * 73.2;
2218
2219 // create container
297369a1 2220 TGeoVolumeAssembly *container = new TGeoVolumeAssembly(
2221 Form("LAY%d_FULLSTAVE", layer));
592651e2 2222
2223 // create subvolumes
297369a1 2224 TGeoVolume *staveBase = CreateStaveBase(layer, baseWidth, baseHeight,
2225 baseThickness, mgr);
592651e2 2226 TGeoVolume *mcmCapBorder = CreateMCMCoverBorder(mgr);
2227 TGeoVolume *mcmCapTop = CreateMCMCoverTop(mgr);
297369a1 2228 // bus in z > 0
2229 TGeoVolumeAssembly *bus0 = CreatePixelBusAndExtensions(kTRUE, mgr);
2230 // bus in z < 0
2231 TGeoVolumeAssembly *bus1 = CreatePixelBusAndExtensions(kFALSE, mgr);
2232
2233 // the full width and height of the area which contains all
2234 // components corresponds to the one of the stave base built with
2235 // the "CreateStaveBase" method while the thickness must be
2236 // computed as the sum of this base + the cover
592651e2 2237 fullThickness = baseThickness + mcmCapThickness + mcmCapBorderThickness;
2238
2239 // 1 - MCM cover
2240
2241 // translations (in the X direction, MCM is at the same level as ladder)
2242 Double_t xBase = -0.5*fullThickness + 0.5*baseThickness;
2243 TGeoTranslation *trBase = new TGeoTranslation(xBase, 0.0, 0.0);
2244 Double_t xMCMCapB = xBase + 0.5*baseThickness + 0.5*mcmCapThickness;
297369a1 2245 Double_t xMCMCapT = xMCMCapB + 0.5*mcmCapThickness +
2246 0.5*mcmCapBorderThickness;
592651e2 2247 Double_t yMCMCap = 0.5*(baseHeight - mcmCapHeight);
2248 Double_t zMCMCap1 = 0.5*baseWidth - 0.5*mcmCapWidth;
2249 Double_t zMCMCap0 = -zMCMCap1;
2250 // correction rotations
2251 TGeoRotation *rotCorr0 = new TGeoRotation(*gGeoIdentity);
2252 TGeoRotation *rotCorr1 = new TGeoRotation(*gGeoIdentity);
2253 rotCorr0->RotateY( 90.0);
2254 rotCorr1->RotateY(-90.0);
297369a1 2255 TGeoCombiTrans *trMCMCapBorder0 = new TGeoCombiTrans(xMCMCapB,
2256 yMCMCap, zMCMCap0, rotCorr0);
2257 TGeoCombiTrans *trMCMCapBorder1 = new TGeoCombiTrans(xMCMCapB,
2258 yMCMCap, zMCMCap1, rotCorr1);
2259 TGeoCombiTrans *trMCMCapTop0 = new TGeoCombiTrans(xMCMCapT,
2260 yMCMCap, zMCMCap0, rotCorr0);
2261 TGeoCombiTrans *trMCMCapTop1 = new TGeoCombiTrans(xMCMCapT,
2262 yMCMCap, zMCMCap1, rotCorr1);
592651e2 2263 // add to container
2264 container->AddNode(staveBase, 0, trBase);
2265 container->AddNode(mcmCapBorder, 0, trMCMCapBorder0);
2266 container->AddNode(mcmCapBorder, 1, trMCMCapBorder1);
2267 container->AddNode(mcmCapTop, 0, trMCMCapTop0);
2268 container->AddNode(mcmCapTop, 1, trMCMCapTop1);
2269
2270 // 2 - Pixel Bus
2271
2272 // translations
297369a1 2273 // for the moment, a correction amount of 0.04 is required to
2274 // place correctly the object in X and another correction of
2275 // 0.015 in Z
592651e2 2276 Double_t busHeight = fgkmm * 13.8;
2277 Double_t xPixelBus = xBase + baseThickness + 0.04;
297369a1 2278 Double_t yPixelBus1 = 0.5*baseHeight - 0.5*busHeight +
2279 0.5*(baseHeight - busHeight);
592651e2 2280 Double_t zPixelBus0 = -0.25*baseWidth + 0.015 - 0.03;
2281 //Double_t zPixelBus0 = -0.5*(0.5*baseWidth - 0.04);
2282 Double_t zPixelBus1 = -zPixelBus0;
2283 // correction rotations
2284 TGeoRotation *rotCorrBus1 = new TGeoRotation(*gGeoIdentity);
2285 rotCorrBus1->RotateX(180.0);
297369a1 2286 //TGeoCombiTrans *trBus0 = new TGeoCombiTrans(xPixelBus, 0.0,
2287 // zPixelBus0, rotCorrBus);
2288 TGeoTranslation *trBus0 = new TGeoTranslation(xPixelBus, 0.0,
2289 zPixelBus0);
2290 //TGeoTranslation *trBus1 = new TGeoTranslation(xPixelBus, 0.0,
2291 // zPixelBus1);
2292 TGeoCombiTrans *trBus1 = new TGeoCombiTrans(xPixelBus, yPixelBus1,
2293 zPixelBus1, rotCorrBus1);
592651e2 2294
2295 // add to container
2296 container->AddNode(bus0, 0, trBus0);
2297 container->AddNode(bus1, 1, trBus1);
2298
2299 return container;
2300}
592651e2 2301//______________________________________________________________________
297369a1 2302TGeoVolumeAssembly* AliITSv11GeometrySPD::CreatePixelBusAndExtensions(
2303 Bool_t zpos, TGeoManager *mgr){
592651e2 2304 // Creates an assembly which contains the pixel bus and its extension
2305 // and the extension of the MCM.
2306 // By: Renaud Vernet
2307 // NOTE: to be defined its material and its extension in the outside direction
2308 //
2309
2310 // ==== constants =====
2311
2312 //get the media
2313 TGeoMedium *medPixelBus = mgr->GetMedium("PIXEL BUS") ;
2314 TGeoMedium *medPBExtender = mgr->GetMedium("PIXEL BUS EXTENDER") ;
2315 TGeoMedium *medMCMExtender = mgr->GetMedium("MCM EXTENDER") ;
2316
2317 //geometrical constants
59da35b6 2318 const Double_t kGroundingThickness = 0.07 * fgkmm ;
2319 const Double_t kGrounding2pixelBusDz = 0.625 * fgkmm ;
2320 const Double_t kPixelBusThickness = 0.28 * fgkmm ;
2321 const Double_t kGroundingWidthX = 170.501 * fgkmm ;
2322 const Double_t kPixelBusContactDx = 1.099 * fgkmm ;
2323 const Double_t kPixelBusWidthY = 13.8 * fgkmm ;
297369a1 2324 //design=20 deg.
2325 const Double_t kPixelBusContactPhi = 20.0 * TMath::DegToRad();
2326 //design=?? 70 deg. seems OK
2327 const Double_t kPbExtenderPsi = 70.0 * TMath::DegToRad();
59da35b6 2328 const Double_t kPbExtenderWidthY = 11.0 * fgkmm ;
2329 const Double_t kPbExtenderTopZ = 2.72 * fgkmm ;
2330 const Double_t kMcmThickness = 0.35 * fgkmm ;
2331 const Double_t kMcmExtenderThickness = 0.20 * fgkmm ;
2332 const Double_t kDeltaMcmMcmextender = 1.6 * fgkmm ;
2333 const Double_t kHalfStaveTotalLength = 247.64 * fgkmm ;
2334 const Double_t kDeltaYOrigin = 15.95/2.* fgkmm ;
2335 const Double_t kDeltaXOrigin = 1.1 * fgkmm ;
2336 const Double_t kDeltaZOrigin = kHalfStaveTotalLength / 2. ;
592651e2 2337
297369a1 2338 const Double_t kGrounding2pixelBusDz2 = kGrounding2pixelBusDz+
2339 kGroundingThickness/2. + kPixelBusThickness/2. ;
59da35b6 2340 const Double_t kPixelBusWidthX = kGroundingWidthX ;
297369a1 2341 const Double_t kPixelBusRaiseLength = (kPixelBusContactDx-
2342 kPixelBusThickness*TMath::Sin(kPixelBusContactPhi))/
2343 TMath::Cos(kPixelBusContactPhi) ;
2344 const Double_t kPbExtenderBaseZ = kGrounding2pixelBusDz2 +
2345 kPixelBusRaiseLength*TMath::Sin(kPixelBusContactPhi) +
2346 2*kPixelBusThickness*TMath::Sin(kPixelBusContactPhi)*
2347 TMath::Tan(kPixelBusContactPhi) ;
59da35b6 2348 const Double_t kPbExtenderDeltaZ = kPbExtenderTopZ-kPbExtenderBaseZ ;
297369a1 2349 const Double_t kPbExtenderEndPointX = 2*kDeltaZOrigin - kGroundingWidthX -
2350 2*kPixelBusThickness*TMath::Sin(kPixelBusContactPhi) ;
59da35b6 2351 const Double_t kMcmextenderEndPointX = kDeltaZOrigin - 48.2 * fgkmm ;
2352 const Double_t kMcmExtenderWidthY = kPbExtenderWidthY ;
592651e2 2353
2354 //===== end constants =====
2355
2356
59da35b6 2357 /*
592651e2 2358 // ----------------- CREATE THE PIXEL BUS --------------------------
2359 // At the end of the pixel bus, a small piece is added for the contact
2360 // with the pixel bus extender.
2361 // The whole piece is made with an extrusion, using 7 points
2362 //
2363 // 4
2364 // /\
2365 // 6 5 / \ 3
2366 // +-----------------------------+ /
2367 // | /
2368 // +-----------------------------+--+
2369 // 0 1 2
2370 //
2371 // The length of the pixel bus is defined (170.501mm) by the technical design
2372 // this length corresponds to distance [0-1] and [6-5]
2373
59da35b6 2374 */
592651e2 2375
2376 TGeoVolumeAssembly *pixelBus = new TGeoVolumeAssembly("PIXEL BUS");
2377
2378 // definition of the 7 points for the extrusion
2379 Double_t pixelBusXtruX[7] = {
59da35b6 2380 -kPixelBusWidthX/2. ,
2381 kPixelBusWidthX/2. ,
2382 kPixelBusWidthX/2. + kPixelBusThickness * TMath::Sin(kPixelBusContactPhi) ,
297369a1 2383 kPixelBusWidthX/2. + kPixelBusThickness * TMath::Sin(kPixelBusContactPhi) +
2384 kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) ,
2385 kPixelBusWidthX/2. + kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi),
59da35b6 2386 kPixelBusWidthX/2. ,
2387 -kPixelBusWidthX/2.
592651e2 2388 } ;
2389 Double_t pixelBusXtruY[7] = {
59da35b6 2390 -kPixelBusThickness/2. ,
2391 -kPixelBusThickness/2. ,
297369a1 2392 -kPixelBusThickness/2. + kPixelBusThickness *
2393 (1 - TMath::Cos(kPixelBusContactPhi)) ,
2394 -kPixelBusThickness/2. + kPixelBusThickness *
2395 (1 - TMath::Cos(kPixelBusContactPhi)) +
2396 kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) ,
2397 kPixelBusThickness/2. + kPixelBusRaiseLength *
2398 TMath::Sin(kPixelBusContactPhi) ,
59da35b6 2399 kPixelBusThickness/2. ,
2400 kPixelBusThickness/2.
592651e2 2401 } ;
2402
2403 // creation of the volume
2404 TGeoXtru *pixelBusXtru = new TGeoXtru(2);
297369a1 2405 TGeoVolume* pixelBusXtruVol = new TGeoVolume("pixelBusXtru",
2406 pixelBusXtru,medPixelBus) ;
592651e2 2407 pixelBusXtru->DefinePolygon(7,pixelBusXtruX,pixelBusXtruY);
59da35b6 2408 pixelBusXtru->DefineSection(0,-kPixelBusWidthY/2.);
2409 pixelBusXtru->DefineSection(1, kPixelBusWidthY/2.);
297369a1 2410 // --------------- END PIXEL BUS -------------------------------------
592651e2 2411
2412
297369a1 2413 // ------------------------- CREATE THE PIXEL BUS EXTENDER -----------
592651e2 2414 // The geometry of the extender is a bit complicated sinceit is constrained
2415 // to be in contact with the pixel bus.
2416 // It consists of an extrusion using 13 points as shows the scheme below :
297369a1 2417 //
2418 // 8 7 6
2419 // +---+---------------------+
2420 // / |
2421 // / |
2422 // / +---------------------+
2423 // / / 4 5
2424 // / /
2425 // 11 10 9 / /
2426 // +---+-----------+ /
2427 // / /
2428 // / /
2429 // / +-----------+---+
2430 // 12 + / 1 2 3
2431 // \ /
2432 // \ /
2433 // +
2434 // 0
592651e2 2435
2436 // ==== constants =====
59da35b6 2437 const Double_t kPbExtenderXtru3L = 1.5 * fgkmm ; //arbitrary ?
297369a1 2438 const Double_t kPbExtenderXtru4L = (kPbExtenderDeltaZ +
2439 kPixelBusThickness*(TMath::Cos(kPbExtenderPsi)-2))/
2440 TMath::Sin(kPbExtenderPsi) ;
592651e2 2441 //===== end constants =====
2442
2443 TGeoVolumeAssembly *pbExtender = new TGeoVolumeAssembly("PIXEL BUS EXTENDER");
2444
2445 Double_t pbExtenderXtruX[13] = {
2446 0,
59da35b6 2447 kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) ,
2448 kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) + kPbExtenderXtru3L ,
297369a1 2449 kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) +
2450 kPbExtenderXtru3L + kPixelBusThickness * TMath::Sin(kPbExtenderPsi) ,
2451 kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) +
2452 kPbExtenderXtru3L + kPixelBusThickness *
2453 TMath::Sin(kPbExtenderPsi) + kPbExtenderXtru4L *
2454 TMath::Cos(kPbExtenderPsi) ,
59da35b6 2455 kPbExtenderEndPointX ,
2456 kPbExtenderEndPointX ,
297369a1 2457 kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) +
2458 kPbExtenderXtru3L + kPixelBusThickness * TMath::Sin(kPbExtenderPsi)+
2459 kPbExtenderXtru4L * TMath::Cos(kPbExtenderPsi) ,
2460 kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) +
2461 kPbExtenderXtru3L + kPixelBusThickness * TMath::Sin(kPbExtenderPsi)+
2462 kPbExtenderXtru4L * TMath::Cos(kPbExtenderPsi) - kPixelBusThickness*
2463 TMath::Sin(kPbExtenderPsi),
59da35b6 2464 kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) + kPbExtenderXtru3L ,
2465 kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) ,
297369a1 2466 kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) -
2467 kPixelBusThickness*TMath::Sin(kPixelBusContactPhi) ,
59da35b6 2468 -kPixelBusThickness * TMath::Sin(kPixelBusContactPhi)
592651e2 2469 } ;
2470 Double_t pbExtenderXtruY[13] = {
2471 0,
59da35b6 2472 kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) ,
2473 kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) ,
297369a1 2474 kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) +
2475 kPixelBusThickness * (1-TMath::Cos(kPbExtenderPsi)) ,
2476 kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) +
2477 kPixelBusThickness * (1-TMath::Cos(kPbExtenderPsi)) +
2478 kPbExtenderXtru4L * TMath::Sin(kPbExtenderPsi) ,
2479 kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) +
2480 kPixelBusThickness * (1-TMath::Cos(kPbExtenderPsi)) +
2481 kPbExtenderXtru4L * TMath::Sin(kPbExtenderPsi) ,
2482 kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) +
2483 kPixelBusThickness * (1-TMath::Cos(kPbExtenderPsi)) +
2484 kPbExtenderXtru4L * TMath::Sin(kPbExtenderPsi) +
2485 kPixelBusThickness ,
2486 kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) +
2487 kPixelBusThickness * (1-TMath::Cos(kPbExtenderPsi)) +
2488 kPbExtenderXtru4L * TMath::Sin(kPbExtenderPsi) +
2489 kPixelBusThickness ,
2490 kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) +
2491 kPixelBusThickness + kPbExtenderXtru4L *
2492 TMath::Sin(kPbExtenderPsi),
2493 kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi)+kPixelBusThickness ,
2494 kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi)+kPixelBusThickness ,
2495 kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi)+kPixelBusThickness*
2496 TMath::Cos(kPixelBusContactPhi) ,
59da35b6 2497 kPixelBusThickness * TMath::Cos(kPixelBusContactPhi)
592651e2 2498 } ;
2499
2500 // creation of the volume
2501 TGeoXtru *pbExtenderXtru = new TGeoXtru(2);
297369a1 2502 TGeoVolume *pbExtenderXtruVol = new TGeoVolume("pbExtenderXtru",
2503 pbExtenderXtru,medPBExtender) ;
592651e2 2504 pbExtenderXtru->DefinePolygon(13,pbExtenderXtruX,pbExtenderXtruY);
59da35b6 2505 pbExtenderXtru->DefineSection(0,-kPbExtenderWidthY/2.);
2506 pbExtenderXtru->DefineSection(1, kPbExtenderWidthY/2.);
297369a1 2507 // -------------- END PIXEL BUS EXTENDER -----------------------------
592651e2 2508
2509
297369a1 2510 // ------------------ CREATE THE MCM EXTENDER -------------------
592651e2 2511 //
2512 // The MCM extender is located betwen the MCM and the Pixel Bus Extender
2513 // It consists of an extrusion using 10 points as shows the scheme below :
297369a1 2514 //
2515 // 7 6 5
2516 // +---+---------------------+
2517 // / |
2518 // / |
2519 // / +---------------------+
2520 // / / 3 4
2521 // / /
2522 // 9 8 / /
2523 // +-----------+ /
2524 // | /
2525 // | /
2526 // +-----------+---+
2527 // 0 1 2
592651e2 2528
2529 //constants
59da35b6 2530 const Double_t kMcmExtenderXtru3L = 1.5 * fgkmm ;
592651e2 2531 //end constants
2532
2533 TGeoVolumeAssembly *mcmExtender = new TGeoVolumeAssembly("MCM EXTENDER");
2534 Double_t mcmExtenderXtruX[10] = {
2535 0 ,
59da35b6 2536 kMcmExtenderXtru3L ,
2537 kMcmExtenderXtru3L + kMcmExtenderThickness * TMath::Sin(kPbExtenderPsi) ,
297369a1 2538 kMcmExtenderXtru3L + kMcmExtenderThickness * TMath::Sin(kPbExtenderPsi) +
2539 kDeltaMcmMcmextender / TMath::Tan(kPbExtenderPsi) ,
59da35b6 2540 kMcmextenderEndPointX ,
2541 kMcmextenderEndPointX ,
297369a1 2542 kMcmExtenderXtru3L + kMcmExtenderThickness * TMath::Sin(kPbExtenderPsi) +
2543 kDeltaMcmMcmextender / TMath::Tan(kPbExtenderPsi) ,
59da35b6 2544 kMcmExtenderXtru3L + kDeltaMcmMcmextender / TMath::Tan(kPbExtenderPsi) ,
2545 kMcmExtenderXtru3L ,
592651e2 2546 0
2547 } ;
2548
2549 Double_t mcmExtenderXtruY[10] = {
2550 0 ,
2551 0 ,
297369a1 2552 kMcmExtenderThickness*(1.-TMath::Cos(kPbExtenderPsi)),
2553 kMcmExtenderThickness*(1.-TMath::Cos(kPbExtenderPsi))+kDeltaMcmMcmextender,
2554 kMcmExtenderThickness*(1.-TMath::Cos(kPbExtenderPsi))+kDeltaMcmMcmextender,
2555 kMcmExtenderThickness*(2.-TMath::Cos(kPbExtenderPsi))+kDeltaMcmMcmextender,
2556 kMcmExtenderThickness*(2.-TMath::Cos(kPbExtenderPsi))+kDeltaMcmMcmextender,
59da35b6 2557 kMcmExtenderThickness + kDeltaMcmMcmextender ,
2558 kMcmExtenderThickness ,
2559 kMcmExtenderThickness ,
592651e2 2560 } ;
2561
2562 // creation of the volume
2563 TGeoXtru *mcmExtenderXtru = new TGeoXtru(2);
297369a1 2564 TGeoVolume *mcmExtenderXtruVol = new TGeoVolume("mcmExtenderXtru",
2565 mcmExtenderXtru,medMCMExtender) ;
592651e2 2566 mcmExtenderXtru->DefinePolygon(10,mcmExtenderXtruX,mcmExtenderXtruY);
59da35b6 2567 mcmExtenderXtru->DefineSection(0,-kMcmExtenderWidthY/2.);
2568 mcmExtenderXtru->DefineSection(1, kMcmExtenderWidthY/2.);
592651e2 2569
2570
297369a1 2571 //-------------- DEFINITION OF GEOMETRICAL TRANSFORMATIONS ---------
592651e2 2572 TGeoRotation * commonRot = new TGeoRotation("commonRot",0,90,0);
2573 commonRot->MultiplyBy(new TGeoRotation("rot",-90,0,0)) ;
297369a1 2574 TGeoTranslation * pixelBusTrans = new TGeoTranslation(kPixelBusThickness/2.
2575 - kDeltaXOrigin + 0.52*fgkmm ,
2576 -kPixelBusWidthY/2.+ kDeltaYOrigin ,
2577 -kGroundingWidthX/2.+ kDeltaZOrigin) ;
592651e2 2578 TGeoRotation * pixelBusRot = new TGeoRotation(*commonRot);
2579 TGeoTranslation * pbExtenderTrans = new TGeoTranslation(*pixelBusTrans) ;
2580 TGeoRotation * pbExtenderRot = new TGeoRotation(*pixelBusRot) ;
297369a1 2581 pbExtenderTrans->SetDz(*(pbExtenderTrans->GetTranslation()+2)-
2582 kPixelBusWidthX/2.-2.*kPixelBusThickness*
2583 TMath::Sin(kPixelBusContactPhi)) ;
592651e2 2584 if (!zpos) {
297369a1 2585 pbExtenderTrans->SetDy(*(pbExtenderTrans->GetTranslation()+1) -
2586 (kPixelBusWidthY - kPbExtenderWidthY)/2.);
2587 }else {
2588 pbExtenderTrans->SetDy(*(pbExtenderTrans->GetTranslation()+1) +
2589 (kPixelBusWidthY - kPbExtenderWidthY)/2.);
2590 } // end if !zpos
2591 pbExtenderTrans->SetDx(*(pbExtenderTrans->GetTranslation()) +
2592 kPixelBusThickness/2 + 2*kPixelBusThickness*
2593 TMath::Sin(kPixelBusContactPhi)*
2594 TMath::Tan(kPixelBusContactPhi)) ;
2595 TGeoTranslation * mcmExtenderTrans = new TGeoTranslation(0.12*fgkmm +
2596 kMcmThickness - kDeltaXOrigin,
2597 pbExtenderTrans->GetTranslation()[1],-4.82);
592651e2 2598 TGeoRotation * mcmExtenderRot = new TGeoRotation(*pbExtenderRot);
592651e2 2599
2600 //ADD NODES TO ASSEMBLIES
2601 pixelBus ->AddNode((TGeoVolume*)pixelBusXtruVol,0);
2602 pbExtender ->AddNode((TGeoVolume*)pbExtenderXtruVol,0);
2603 mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtruVol,0);
2604// mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtru3Vol,0);
2605// mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtru3PrimVol,1);
2606// mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtru4Vol,2);
2607// mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtru4PrimVol,3);
2608// mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtru5Vol,4);
2609
2610
2611 //CREATE FINAL VOLUME ASSEMBLY AND ROTATE IT
2612 TGeoVolumeAssembly *assembly = new TGeoVolumeAssembly("EXTENDERS");
297369a1 2613 assembly->AddNode((TGeoVolume*)pixelBus ,0,
2614 new TGeoCombiTrans(*pixelBusTrans,*pixelBusRot));
2615 assembly->AddNode((TGeoVolume*)pbExtender ,0,
2616 new TGeoCombiTrans(*pbExtenderTrans,*pbExtenderRot));
2617 assembly->AddNode((TGeoVolume*)mcmExtender ,0,
2618 new TGeoCombiTrans(*mcmExtenderTrans,*mcmExtenderRot));
2619 assembly->SetTransparency(50);
592651e2 2620 return assembly ;
2621}
592651e2 2622//______________________________________________________________________
297369a1 2623TGeoVolume* AliITSv11GeometrySPD::CreateStaveBase(Int_t layer,
2624 Double_t &fullWidth, Double_t &fullHeight, Double_t &fullThickness,
2625 TGeoManager *mgr){
592651e2 2626 // Creates a box which contains the followin parts of the whole stave:
2627 // - the two layers of grounding foil
2628 // - the ladders
2629 // - the thin base of the MCM (except its thick cover)
2630 // - the pixel bus
2631 // ---
2632 // Since it is required by detector numbering conventions,
2633 // it is required as argument the layer which owns this stave.
2634 // This number will be used to define the name of the ladder volume,
2635 // which must be different for layer1 and layer2 objects.
2636 // ---
2637 // Arguments:
2638 // - layer number (will be checked to be 1 or 2)
2639 // - geometry manager
2640 // ---
2641 // Returns:
2642 // - a TGeoBBox volume containing all this stuff
297369a1 2643 // - the size of the container box are stored in the
2644 // reference-passed variables
592651e2 2645 //
592651e2 2646 // sizes of all objects to be inserted
2647 // these values are used to compute the total volume of the container
2648 // and to compute parametrically the position of each piece, instead
297369a1 2649 // of putting hard-coded number (this helps in eventually modifying
2650 // everything)
592651e2 2651 Double_t mcmThickness = fgkmm * 0.35;
2652 Double_t grndThickness = fgkmm * 0.07; // = 0.05 + 0.02
2653 Double_t sepThickness = fgkmm * 0.05;
2654
2655 Double_t ladderWidth = fgkmm * 70.72;
2656 Double_t mcmWidth = fgkmm * 105.60;
2657 Double_t sepLaddersWidth = fgkmm * 0.20;
2658 Double_t sepMCMWidth = fgkmm * 0.30;
297369a1 2659 // separations between central ladders in the two half-staves
2660 Double_t sepLaddersCtr = fgkmm * 0.40;
592651e2 2661
2662 Double_t mcmHeight = fgkmm * 15.00;
2663
2664 // compute the size of the container
297369a1 2665 fullWidth = 2.0*sepLaddersCtr + 4.0*ladderWidth +
2666 2.0*sepMCMWidth + 2.0*sepLaddersWidth + 2.0*mcmWidth;
592651e2 2667 fullHeight = fgkmm * 15.95;
2668 fullThickness = grndThickness + sepThickness + mcmThickness;
2669
2670 // create the container
297369a1 2671 TGeoVolume *container = mgr->MakeBox(Form("LAY%d_STAVE", layer),
2672 mgr->GetMedium("VACUUM"), 0.5*fullThickness,
2673 0.5*fullHeight, 0.5*fullWidth);
592651e2 2674
2675 // fill the container going from bottom to top
2676 // with respect to the thickness direction
2677
2678 // 1 - Grounding foil
2679 // volume
2680 TGeoVolume *grndVol = CreateGroundingFoil(grndThickness);
2681 // translation
2682 Double_t xGrnd = -0.5*fullThickness + 0.5*grndThickness;
2683 TGeoTranslation *grndTrans = new TGeoTranslation(xGrnd, 0.0, 0.0);
2684 // add to container
2685 container->AddNode(grndVol, 1, grndTrans);
2686
2687 // 2 - Ladders
2688 // volume (will be replicated 4 times)
2689 Double_t ladderLength, ladderThickness;
297369a1 2690 TGeoVolume *ladder = CreateLadder(layer, ladderLength, ladderWidth,
2691 ladderThickness, mgr);
592651e2 2692 // translations (in thickness direction, the MCM thickness is used)
297369a1 2693 // layers are sorted going from the one at largest Z to the one
2694 // at smallest Z:
592651e2 2695 // -|Zmax| ------> |Zmax|
2696 // 0 1 2 3
297369a1 2697 // but it is more comfortable to start defining their Z position
2698 // from center
2699 Double_t xLad = xGrnd + 0.5*grndThickness + 0.5*mcmThickness +
2700 sepThickness;
592651e2 2701 Double_t zLad1 = -0.5*ladderWidth - sepLaddersCtr;
2702 Double_t zLad0 = zLad1 - ladderWidth - sepLaddersWidth;
2703 Double_t zLad2 = -zLad1;
2704 Double_t zLad3 = -zLad0;
297369a1 2705 // rotLad->RotateZ(180.0);
2706 TGeoRotation *rotLad = new TGeoRotation(*gGeoIdentity);
592651e2 2707 TGeoCombiTrans *trLad0 = new TGeoCombiTrans(xLad, 0.0, zLad0, rotLad);
2708 TGeoCombiTrans *trLad1 = new TGeoCombiTrans(xLad, 0.0, zLad1, rotLad);
2709 TGeoCombiTrans *trLad2 = new TGeoCombiTrans(xLad, 0.0, zLad2, rotLad);
2710 TGeoCombiTrans *trLad3 = new TGeoCombiTrans(xLad, 0.0, zLad3, rotLad);
2711 // add to container
2712 container->AddNode(ladder, 0, trLad0);
2713 container->AddNode(ladder, 1, trLad1);
2714 container->AddNode(ladder, 2, trLad2);
2715 container->AddNode(ladder, 3, trLad3);
2716
297369a1 2717 // 3 - MCM (only the base, the cover is added as a separate
2718 // volume in a more global 'stave' assembly volume (will be
2719 // replicated twice)
592651e2 2720 TGeoVolume *mcm = CreateMCMBase(mgr);
297369a1 2721 // translations (in the X direction, MCM is at the same
2722 // level as ladder) the two copies of the MCM are placed at
2723 // the same distance from the center, on both sides and their
2724 // sorting is the same as ladders' one (MCM0 is at Z < 0,
2725 // MCM1 at Z > 0);
592651e2 2726 Double_t xMCM = xLad;
2727 Double_t yMCM = 0.5*(fullHeight - mcmHeight);
2728 Double_t zMCM1 = zLad3 + 0.5*ladderWidth + 0.5*mcmWidth + sepMCMWidth;
2729 Double_t zMCM0 = -zMCM1;
2730 // create the common correction rotations
2731 TGeoRotation *rotCorr0 = new TGeoRotation(*gGeoIdentity);
2732 TGeoRotation *rotCorr1 = new TGeoRotation(*gGeoIdentity);
2733 rotCorr0->RotateY( 90.0);
2734 rotCorr1->RotateY(-90.0);
297369a1 2735 TGeoCombiTrans *trMCM0 = new TGeoCombiTrans(xMCM,yMCM,zMCM0,rotCorr0);
2736 TGeoCombiTrans *trMCM1 = new TGeoCombiTrans(xMCM,yMCM,zMCM1,rotCorr1);
592651e2 2737 // add to container
2738 container->AddNode(mcm, 0, trMCM0);
2739 container->AddNode(mcm, 1, trMCM1);
2740
2741 return container;
2742}
592651e2 2743//______________________________________________________________________
297369a1 2744void AliITSv11GeometrySPD::StavesInSector(TGeoVolume *moth, TGeoManager *mgr){
592651e2 2745 // Unification of essentially two methods:
2746 // - the one which creates the sector structure
2747 // - the one which returns the complete stave
2748 // ---
2749 // For compatibility, this method requires the same arguments
2750 // asked by "CarbonFiberSector" method, which is recalled here.
2751 // Like this cited method, this one does not return any value,
2752 // but it inserts in the mother volume (argument 'moth') all the stuff
2753 // which composes the complete SPD sector.
2754 // ---
2755 // Arguments: see description of "CarbonFiberSector" method.
2756 //
2757
2758 // This service class is useful to this method only
2759 // to store in a meaningful way the data about the
2760 // rounded corners of the support, and some computations
2761 // which could turn out to be useful for stave placement
2762 // 'left' and 'right' (L/R) here are considered looking the support
2763 // from the positive Z side.
2764 // The sign of the radius is used to know what kind of tangent
2765 // must be found for the two circles which describe the rounded angles.
2766 class clsSupportPlane {
2767 public:
297369a1 2768 // curvature center and radius (with sign) of left corner
2769 Double_t xL, yL, rL, sL;
2770 // curvature center and radius (with sign) of right corner
2771 Double_t xR, yR, rR, sR;
2772 // shift from the innermost position (where the stave edge is
2773 // in the point where the rounded corner begins
2774 Double_t shift;
592651e2 2775
297369a1 2776 // Constructor with arguments which allow to set
2777 // directly everything since the values are given in
2778 // millimiters from drawings, they must be converted to cm
592651e2 2779 clsSupportPlane
2780 (Double_t xLin, Double_t yLin, Double_t rLin, Double_t sLin,
297369a1 2781 Double_t xRin, Double_t yRin, Double_t rRin, Double_t sRin,
2782 Double_t shiftin) :
2783 xL(xLin), yL(yLin), rL(rLin), sL(sLin), xR(xRin), yR(yRin),
2784 rR(rRin), sR(sRin), shift(shiftin) {
592651e2 2785 xL *= fgkmm;
2786 yL *= fgkmm;
2787 rL *= fgkmm;
2788 xR *= fgkmm;
2789 yR *= fgkmm;
2790 rR *= fgkmm;
2791 shift *= fgkmm;
297369a1 2792 } // end group.
592651e2 2793
297369a1 2794 // Computation of the line tangent to both circles
2795 // defined here which is taken above or below the center
2796 // according to the radius sign. This method returns:
2797 // - the mid-popint of the segment between the two
2798 // points where the tangent touches the two circles,
592651e2 2799 // - the inclination of this segment
2800 // - the half-length of this segment
297369a1 2801 Double_t TangentSegment(Double_t &midX, Double_t &midY,
2802 Double_t &phi){
2803 // compute the straight line which is tangent to
2804 // the two circles and extract its inclination
2805 // 'phi' w.r. to X axis
592651e2 2806 Double_t dx = xL - xR;
2807 Double_t dy = yL - yR;
2808 Double_t R = rL*sL + rR*sR;
2809 Double_t delta = dy*dy + dx*dx - R*R;
297369a1 2810 Double_t tan05phi = (-dy+TMath::Sqrt(delta))/(R - dx);
592651e2 2811 phi = 2.0 * TMath::ATan(tan05phi);
297369a1 2812 // compute the points where this line touchs the
2813 // two circles
592651e2 2814 Double_t leftX = xL + sL*rL*TMath::Cos(phi);
2815 Double_t leftY = yL + sL*rL*TMath::Sin(phi);
2816 Double_t rightX = xR + sR*rR*TMath::Cos(phi);
2817 Double_t rightY = yR + sR*rR*TMath::Sin(phi);
2818 // compute the mid point
2819 midX = 0.5 * (leftX + rightX);
2820 midY = 0.5 * (leftY + rightY);
2821 // compute angular coefficient for the line joining
2822 // the two points found using the above method
2823 dx = rightX - leftX;
2824 dy = rightY - leftY;
2825 phi = TMath::ATan2(dy, dx);
2826 // compute the half-length of this segment
297369a1 2827 Double_t len = 0.5*TMath::Sqrt((rightX-leftX)*
2828 (rightX-leftX) + (rightY-leftY)*
2829 (rightY-leftY));
59da35b6 2830 //MM cout << 2.0*len << endl;
592651e2 2831 return len;
297369a1 2832 } // end function
2833 }; // end class
592651e2 2834 // instantiate this class for each layer1 and layer2 corners
2835 clsSupportPlane *plane[6] = {0, 0, 0, 0, 0, 0};
2836
2837 // layer 2
297369a1 2838 plane[0] = new clsSupportPlane( 10.830, 16.858, 0.60, 1., 19.544,
2839 10.961, 0.8, 1., 1.816);
2840 plane[1] = new clsSupportPlane(- 0.733, 17.486, 0.60, 1., 11.581,
2841 13.371, 0.6, -1., -0.610);
2842 plane[2] = new clsSupportPlane(-12.252, 16.298, 0.60, 1., 0.562,
2843 14.107, 0.6, -1., -0.610);
2844 plane[3] = new clsSupportPlane(-22.276, 12.948, 0.85, 1., -10.445,
2845 13.162, 0.6, -1., -0.610);
592651e2 2846 // layer 1
297369a1 2847 plane[4] = new clsSupportPlane(- 3.123, -14.618, 0.50, 1., 11.280,
2848 -14.473, 0.9, -1., -0.691);
2849 plane[5] = new clsSupportPlane(-13.187, -19.964, 0.50, -1., - 3.833,
2850 -17.805, 0.6, -1., 1.300);
592651e2 2851 // put the sector in the container
2852 //CarbonFiberSector(moth, xAAtubeCenter0, yAAtubeCenter0, mgr);
2853
2854 // create stave volume
2855 Double_t staveHeight = 1.595, staveThickness;
297369a1 2856 TGeoVolume *stave1 = CreateStave(1, staveThickness,mgr);
2857 TGeoVolume *stave2 = CreateStave(2, staveThickness,mgr);
592651e2 2858
2859 // compute positions and rotation angles
2860 Double_t xm, ym, halfPlaneHeight, heightDiff, position, phi, xPos, yPos;
2861 for (Int_t i = 0; i < 6; i++) {
297369a1 2862 //
2863 // This functioninserted here for test. Added By Bjorn Nilsen
2864 // August 29 2007.
2865 Double_t x0,y0,x1,y1; // should be move out of loop
2866 Bool_t lreturn;
2867 lreturn = GetSectorMountingPoints(i,x0,y0,x1,y1,mgr);
2868 //
592651e2 2869 // recall the geometry computations defined for the classe
2870 halfPlaneHeight = plane[i]->TangentSegment(xm, ym, phi);
2871 // compute the difference between plane and stave heights
2872 heightDiff = halfPlaneHeight - 0.5*staveHeight;
2873 // It is necessary to shift the stave by at least
2874 // an amount equal to this difference
2875 // to avoid overlaps.
2876 // Moreover, some more shift is done for building reasons,
2877 // and it depends on the single plane (data-member 'shift')
2878 position = heightDiff + plane[i]->shift;
2879 // taking into account this shift plus another in the direction
2880 // normal to the support plane, due to the stave thickness,
297369a1 2881 // the final position of the stave is computed in a temporary
2882 // reference frame where the mid-point of the support plane
2883 // is in the origin
592651e2 2884 if (i < 4) {
297369a1 2885 ParallelPosition(0.5*staveThickness, position, phi,
2886 xPos, yPos);
2887 }else if (i == 4) {
2888 ParallelPosition(-0.5*staveThickness, -position, phi,
2889 xPos, yPos);
2890 }else {
2891 ParallelPosition(-0.5*staveThickness, -position, phi,
2892 xPos, yPos);
592651e2 2893 }
2894 // then we go into the true reference frame
2895 xPos += xm;
2896 yPos += ym;
2897 /*
2898 // TEMP
297369a1 2899 TGeoVolume *tubeTemp1 = mgr->MakeTube("tubeTemp1", NULL,
2900 0.0, 0.01, 50.0);
592651e2 2901 TGeoTranslation *trTemp1 = new TGeoTranslation(xm, ym, 0.0);
2902 tubeTemp1->SetLineColor(kRed);
2903 moth->AddNode(tubeTemp1, i + 1, trTemp1);
297369a1 2904 TGeoVolume *tubeTemp2 = mgr->MakeTube("tubeTemp2", NULL,
2905 0.0, 0.01, 50.0);
592651e2 2906 TGeoTranslation *trTemp2 = new TGeoTranslation(xPos, yPos, 0.0);
2907 tubeTemp2->SetLineColor(kBlue);
2908 moth->AddNode(tubeTemp2, i + 1, trTemp2);
2909 // END TEMP
2910 */
2911 // using the parameters found here, compute the
2912 // translation and rotation of this stave:
2913 TGeoRotation *rot = new TGeoRotation(*gGeoIdentity);
2914 if (i >= 4) rot->RotateY(180.0);
2915 rot->RotateZ(90.0 + phi * TMath::RadToDeg());
297369a1 2916 TGeoCombiTrans *trans = new TGeoCombiTrans(xPos,yPos,0.0,rot);
592651e2 2917 if (i < 4) {
2918 moth->AddNode(stave2, i, trans);
297369a1 2919 }else {
592651e2 2920 moth->AddNode(stave1, i - 4, trans);
297369a1 2921 } // end if i<4
2922 } // for i
592651e2 2923}
592651e2 2924//______________________________________________________________________
297369a1 2925void AliITSv11GeometrySPD::ParallelPosition(Double_t dist1, Double_t dist2,
2926 Double_t phi, Double_t &x, Double_t &y){
592651e2 2927 // Performs the following steps:
297369a1 2928 // 1 - finds a straight line parallel to the one passing through
2929 // the origin and with angle 'phi' with X axis (phi in RADIANS);
2930 // 2 - finds another line parallel to the previous one, with a
2931 // distance 'dist1' from it
2932 // 3 - takes a reference point in the second line in the
2933 // intersection between the normal to both lines passing
2934 // through the origin
2935 // 4 - finds a point whith has distance 'dist2' from this
2936 // reference, in the second line (point 2)
592651e2 2937 // ----
297369a1 2938 // According to the signs given to dist1 and dist2, the point
2939 // is found in different position w.r. to the origin
2940
592651e2 2941 // compute the point
2942 Double_t cs = TMath::Cos(phi);
2943 Double_t sn = TMath::Sin(phi);
2944
2945 x = dist2*cs - dist1*sn;
2946 y = dist1*cs + dist2*sn;
2947}
297369a1 2948//----------------------------------------------------------------------
2949Bool_t AliITSv11GeometrySPD::Make2DcrossSections(TPolyLine &a0,TPolyLine &a1,
2950 TPolyLine &b0,TPolyLine &b1,TPolyMarker &p)const{
2951 // Fill the objects with the points representing
2952 // a0 the outer carbon fiber SPD sector shape Cross Section A
2953 // a1 the inner carbon fiber SPD sector shape Cross Section A
2954 // b0 the outer carbon fiber SPD sector shape Cross Section B
2955 // b1 the inner carbon fiber SPD sector shape Cross Section B
2956 //
2957 // Inputs:
2958 // TPolyLine &a0 The outer carbon fiber SPD sector shape
2959 // TPolyLine &a1 The Inner carbon fiber SPD sector shape
2960 // TPolyLine &b0 The outer carbon fiber SPD sector shape
2961 // TPolyLine &b1 The Inner carbon fiber SPD sector shape
2962 // TPolyMarker &p The points where the ladders are to be placed
2963 // Outputs:
2964 // TPolyLine &a0 The shape filled with the points
2965 // TPolyLine &a1 The shape filled with the points
2966 // TPolyLine &b0 The shape filled with the points
2967 // TPolyLine &b1 The shape filled with the points
2968 // TPolyMarker &p The filled array of points
2969 // Return:
2970 // An error flag.
2971 Int_t n0,n1,i;
2972 Double_t x,y;
2973 TGeoVolume *a0V,*a1V,*b0V,*b1V;
2974 TGeoXtru *a0S,*a1S,*b0S,*b1S;
2975 TGeoManager *mgr = gGeoManager;
2976
2977 a0V = mgr->GetVolume(fSPDsectorShapeName.Data());
2978 a0S = dynamic_cast<TGeoXtru*>(a0V->GetShape());
2979 n0 = a0S->GetNvert();
2980 a0.SetPolyLine(n0+1);
2981 //for(i=0;i<fSPDsectorPoints0.GetSize();i++)
2982 // printf("%d %d %d\n",i,fSPDsectorPoints0[i],fSPDsectorPoints1[i]);
2983 for(i=0;i<n0;i++){
2984 x = a0S->GetX(i);
2985 y = a0S->GetY(i);
2986 //printf("%d %g %g\n",i,x,y);
2987 a0.SetPoint(i,x,y);
2988 if(i==0) a0.SetPoint(n0,x,y);
2989 } // end for i
2990 a1V = mgr->GetVolume("ITSSPDCarbonFiberSupportSectorAirA1");
2991 a1S = dynamic_cast<TGeoXtru*>(a1V->GetShape());
2992 n1 = a1S->GetNvert();
2993 a1.SetPolyLine(n1+1);
2994 for(i=0;i<n1;i++){
2995 x = a1S->GetX(i);
2996 y = a1S->GetY(i);
2997 a1.SetPoint(i,x,y);
2998 if(i==0) a1.SetPoint(n1,x,y);
2999 } // end for i
3000 // Cross Section B
3001 b0V = mgr->GetVolume("ITSSPDCarbonFiberSupportSectorEndB0");
3002 b0S = dynamic_cast<TGeoXtru*>(b0V->GetShape());
3003 n0 = b0S->GetNvert();
3004 b0.SetPolyLine(n0+1);
3005 for(i=0;i<n0;i++){
3006 x = b0S->GetX(i);
3007 y = b0S->GetY(i);
3008 b0.SetPoint(i,x,y);
3009 if(i==0) b0.SetPoint(n0,x,y);
3010 } // end for i
3011 b1V = mgr->GetVolume("ITSSPDCarbonFiberSupportSectorEndAirB1");
3012 b1S = dynamic_cast<TGeoXtru*>(b1V->GetShape());
3013 n1 = b1S->GetNvert();
3014 b1.SetPolyLine(n1+1);
3015 for(i=0;i<n1;i++){
3016 x = b1S->GetX(i);
3017 y = b1S->GetY(i);
3018 b1.SetPoint(i,x,y);
3019 if(i==0) b1.SetPoint(n1,x,y);
3020 } // end for i
3021 //
3022 Double_t x0,y0,x1,y1;
3023 p.SetPolyMarker(2*fSPDsectorPoints0.GetSize());
3024 for(i=0;i<fSPDsectorPoints0.GetSize();i++){
3025 GetSectorMountingPoints(i,x0,y0,x1,y1);
3026 p.SetPoint(2*i,x0,y0);
3027 p.SetPoint(2*i+1,x1,y1);
3028 } // end for i
3029 return kTRUE;
3030}
592651e2 3031