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