]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/UPGRADE/AliITSvUpgrade.cxx
Brought layer numbering to consistent scheme: the layer number
[u/mrichter/AliRoot.git] / ITS / UPGRADE / AliITSvUpgrade.cxx
1 /**************************************************************************
2  * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16
17 /* $Id: AliITSvUpgrade.cxx */
18
19
20 //========================================================================
21 //
22 //        Geometry for the Upgrade of the Inner Tracking System
23 //
24 // Mario Sitta (sitta@to.infn.it)
25 //
26 //========================================================================
27
28
29
30 // $Log: AliITSvUpgrade.cxx,v $
31
32 #include <TClonesArray.h>
33 #include <TGeoGlobalMagField.h>
34 #include <TGeoManager.h>
35 #include <TGeoMatrix.h>
36 #include <TGeoPhysicalNode.h>
37 #include <TGeoVolume.h>
38 #include <TGeoXtru.h>
39 #include <TLorentzVector.h>
40 #include <TString.h>
41 #include <TVirtualMC.h>
42
43 #include "AliITSUpg.h"
44 #include "AliITSDetTypeSim.h"
45 #include "AliITShit.h"
46 #include "AliLog.h"
47 #include "AliMC.h"
48 #include "AliMagF.h"
49 #include "AliRun.h"
50 #include "AliTrackReference.h"
51 #include "AliITSInitGeometryUpg.h"
52 #include "AliITSv11Geometry.h"
53 #include "AliITSv11GeometryUpgrade.h"
54 #include "AliITSv11GeomBeamPipe.h"
55 #include "AliITSvUpgrade.h"
56 #include "AliGeomManager.h"
57
58 const Double_t AliITSvUpgrade::fgkBeamPipeHalfZLen = 400;
59
60
61 ClassImp(AliITSvUpgrade)
62
63 //______________________________________________________________________
64 AliITSvUpgrade::AliITSvUpgrade():
65   fMajorVersion(IsVersion()),
66   fMinorVersion(-1),
67   fNumberOfLayers(0),
68   fLayTurbo(0),
69   fLayRadii(0),
70   fLayZLength(0),
71   fLaddPerLay(0),
72   fModPerLadd(0),
73   fLadThick(0),
74   fLadWidth(0),
75   fLadTilt(0),
76   fDetThick(0),
77   fBeamPipe(0),
78   fBeamPipeRmin(0),
79   fBeamPipeRmax(0),
80   fBeamPipeZlen(0),
81   fInitGeom((AliITSVersion_t)fMajorVersion,fMinorVersion),
82   fUpGeom(0),
83   fBPGeom(0)
84  {
85     //    Standard default constructor
86     // Inputs:
87     //   none.
88     // Outputs:
89     //   none.
90     // Return:
91     //   none.
92 }
93
94 //______________________________________________________________________
95 AliITSvUpgrade::AliITSvUpgrade(const char *title):
96   AliITSUpg("ITS", title),
97   fMajorVersion(IsVersion()),
98   fMinorVersion(-1),
99   fNumberOfLayers(0),
100   fLayTurbo(0),
101   fLayRadii(0),
102   fLayZLength(0),
103   fLaddPerLay(0),
104   fModPerLadd(0),
105   fLadThick(0),
106   fLadWidth(0),
107   fLadTilt(0),
108   fDetThick(0),
109   fBeamPipe(0),
110   fBeamPipeRmin(0),
111   fBeamPipeRmax(0),
112   fBeamPipeZlen(0),
113   fInitGeom((AliITSVersion_t)fMajorVersion,fMinorVersion),
114   fUpGeom(0),
115   fBPGeom(0)
116 {
117     //    Standard constructor for the Upgrade geometry.
118     // Inputs:
119     //   const char * title  Arbitrary title
120     // Outputs:
121     //   none.
122     // Return:
123     //   none.
124
125   fIdN = 6;
126   fIdName = new TString[fIdN];
127
128   fIdName[0] = "ITS1";
129   fIdName[1] = "ITS2";
130   fIdName[2] = "ITS3";
131   fIdName[3] = "ITS4";
132   fIdName[4] = "ITS5";
133   fIdName[5] = "ITS6";
134
135   fIdSens    = new Int_t[fIdN];
136   for(Int_t i=0; i<fIdN; i++) fIdSens[i] = 0;
137
138   fLayTurbo   = new Bool_t[fIdN];
139   fLayRadii   = new Double_t[fIdN];
140   fLayZLength = new Double_t[fIdN];
141   fLaddPerLay = new Int_t[fIdN];
142   fModPerLadd = new Int_t[fIdN];
143   fLadThick   = new Double_t[fIdN];
144   fLadWidth   = new Double_t[fIdN];
145   fLadTilt    = new Double_t[fIdN];
146   fDetThick   = new Double_t[fIdN];
147
148   fUpGeom = new AliITSv11GeometryUpgrade*[fIdN];
149
150   if (fNumberOfLayers > 0)  // if not, we'll Fatal-ize in CreateGeometry
151     for (Int_t j=0; j<fNumberOfLayers; j++) {
152       fLayRadii[j] = 0.;
153       fLayZLength[j] = 0.;
154       fLaddPerLay[j] = 0;
155       fModPerLadd[j] = 0;
156       fLadWidth[j] = 0.;
157       fDetThick[j] = 0.;
158       fUpGeom[j] = 0;
159     }
160     
161 }
162
163 //______________________________________________________________________
164 AliITSvUpgrade::AliITSvUpgrade(const char *name, const char *title,
165                                const Int_t nlay):
166   AliITSUpg("ITS", title),
167   fMajorVersion(IsVersion()),
168   fMinorVersion(1),
169   fNumberOfLayers(nlay),
170   fLayTurbo(0),
171   fLayRadii(0),
172   fLayZLength(0),
173   fLaddPerLay(0),
174   fModPerLadd(0),
175   fLadThick(0),
176   fLadWidth(0),
177   fLadTilt(0),
178   fDetThick(0),
179   fBeamPipe(0),
180   fBeamPipeRmin(0),
181   fBeamPipeRmax(0),
182   fBeamPipeZlen(0),
183   fInitGeom((AliITSVersion_t)fMajorVersion,fMinorVersion),
184   fUpGeom(0),
185   fBPGeom(0)
186 {
187     //    Standard constructor for the Upgrade geometry.
188     // Inputs:
189     //   const char * name   Ignored, set to "ITS"
190     //   const char * title  Arbitrary title
191     //   const Int_t nlay    Number of layers
192     // Outputs:
193     //   none.
194     // Return:
195     //   none.
196   
197   fIdN = nlay;
198   fIdName = new TString[fIdN];
199
200   for (Int_t j=0; j<fIdN; j++)
201     fIdName[j].Form("ITSupgSensor%d",j+1); // See AliITSv11GeometryUpgrade
202
203   (void) name; // removes warning message
204
205   fIdSens    = new Int_t[fIdN];
206   for(Int_t i=0; i<fIdN; i++) fIdSens[i] = 0;
207
208   fLayTurbo   = new Bool_t[fIdN];
209   fLayRadii   = new Double_t[fIdN];
210   fLayZLength = new Double_t[fIdN];
211   fLaddPerLay = new Int_t[fIdN];
212   fModPerLadd = new Int_t[fIdN];
213   fLadThick   = new Double_t[fIdN];
214   fLadWidth   = new Double_t[fIdN];
215   fLadTilt    = new Double_t[fIdN];
216   fDetThick   = new Double_t[fIdN];
217
218   fUpGeom = new AliITSv11GeometryUpgrade*[fIdN];
219   
220   if (fNumberOfLayers > 0)  // if not, we'll Fatal-ize in CreateGeometry
221     for (Int_t j=0; j<fNumberOfLayers; j++) {
222       fLayRadii[j] = 0.;
223       fLayZLength[j] = 0.;
224       fLaddPerLay[j] = 0;
225       fModPerLadd[j] = 0;
226       fLadWidth[j] = 0.;
227       fDetThick[j] = 0.;
228       fUpGeom[j] = 0;
229     }
230     
231 }
232
233 //______________________________________________________________________
234 AliITSvUpgrade::~AliITSvUpgrade() {
235     //    Standard destructor
236     // Inputs:
237     //   none.
238     // Outputs:
239     //   none.
240     // Return:
241     //   none.
242   delete [] fLayTurbo;
243   delete [] fLayRadii;
244   delete [] fLayZLength;
245   delete [] fLaddPerLay;
246   delete [] fModPerLadd;
247   delete [] fLadThick;
248   delete [] fLadWidth;
249   delete [] fLadTilt;
250   delete [] fDetThick;
251   delete [] fUpGeom;
252
253 }
254
255 //______________________________________________________________________
256 void AliITSvUpgrade::SetT2Lmatrix(Int_t uid, Double_t yShift, 
257                                   Bool_t yFlip, Bool_t yRot180) const {
258
259   //
260   // Creates the TGeo Local to Tracking transformation matrix
261   // and sends it to the corresponding TGeoPNEntry 
262   //
263   // This function is used in AddAlignableVolumes()
264
265   TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntryByUID(uid);
266   TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
267
268   Double_t *gtrans = globMatrix->GetTranslation(), rotMatrix[9];
269   memcpy(&rotMatrix[0], globMatrix->GetRotationMatrix(), 9*sizeof(Double_t));
270   Double_t al = TMath::ATan2(rotMatrix[1],rotMatrix[0]);
271   if (yRot180) {
272     al = TMath::ATan2(rotMatrix[1],-rotMatrix[0]);
273   }
274   Double_t xShift = gtrans[0]*TMath::Cos(al)+gtrans[1]*TMath::Sin(al);
275   Double_t zShift = -gtrans[2];
276
277   TGeoHMatrix *matLtoT = new TGeoHMatrix;
278   matLtoT->SetDx( xShift ); // translation
279   matLtoT->SetDy( yShift );
280   matLtoT->SetDz( zShift );
281   rotMatrix[0]= 0;  rotMatrix[1]= 1;  rotMatrix[2]= 0; // + rotation
282   rotMatrix[3]= 1;  rotMatrix[4]= 0;  rotMatrix[5]= 0;
283   rotMatrix[6]= 0;  rotMatrix[7]= 0;  rotMatrix[8]=-1;
284   if (yFlip) rotMatrix[3] = -1;  // flipping in y  (for SPD1)
285   if (yFlip) rotMatrix[1] = -1;  // flipping in y  (for SPD1)
286
287   if (yRot180) { // rotation of pi around the axis perpendicular to the wafer
288     if (yFlip) matLtoT->SetDx( -xShift ); // flipping in y  (for SPD1)
289     matLtoT->SetDy( -yShift );
290     matLtoT->SetDz( -zShift );
291     rotMatrix[8]=1;
292     rotMatrix[3] = -1;
293     if (yFlip) rotMatrix[3] = 1;  // flipping in y  (for SPD1)
294   }
295
296   TGeoRotation rot;
297   rot.SetMatrix(rotMatrix);
298   matLtoT->MultiplyLeft(&rot);
299   TGeoHMatrix *matTtoL = new TGeoHMatrix(matLtoT->Inverse());
300   delete matLtoT;
301   alignableEntry->SetMatrix(matTtoL);
302 }
303
304 //______________________________________________________________________
305 void AliITSvUpgrade::AddAlignableVolumes() const{
306   // Creates entries for alignable volumes associating the symbolic volume
307   // name with the corresponding volume path.
308   // 
309   // Records in the alignable entries the transformation matrices converting
310   // TGeo local coordinates (in the RS of alignable volumes) to the tracking
311   // system
312   // For this, this function has to run before the misalignment because we
313   // are using the ideal positions in the AliITSgeom object.
314   // Inputs:
315   //   none.
316   // Outputs:
317   //   none.
318   // Return:
319   //   none.
320
321   AliInfo("Add ITS alignable volumes");
322
323   if (!gGeoManager) {
324     AliFatal("TGeoManager doesn't exist !");
325     return;
326   }
327   // RS: to be checked with MS
328   if( !gGeoManager->SetAlignableEntry("ITS","ALIC_1/ITSV_2") )
329     AliFatal(Form("Unable to set alignable entry ! %s :: %s","ITS","ALIC_1/ITSV_2"));    
330   //
331   TString pth,snm;
332   for (int lr=0; lr<fNumberOfLayers; lr++) {
333     //
334     pth = Form("ALIC_1/ITSV_2/ITSupgLayer%d_1",lr+1);
335     snm = Form("ITS/LrUpg%d",lr+1);
336     //printf("SetAlignable: %s %s\n",snm.Data(),pth.Data());
337     gGeoManager->SetAlignableEntry(snm.Data(),pth.Data());
338     int modNum = 0;
339     //
340     for (int ld=0; ld<fLaddPerLay[lr]; ld++) {
341       //
342       TString pthL = Form("%s/ITSupgLadder%d_%d",pth.Data(),lr+1,ld+1);
343       TString snmL = Form("%s/LaddUpg%d",snm.Data(),ld+1);
344       //printf("SetAlignable: %s %s\n",snmL.Data(),pthL.Data());
345       gGeoManager->SetAlignableEntry(snmL.Data(),pthL.Data());
346       //
347       for (int md=0; md<fModPerLadd[lr]; md++) {
348         //
349         TString pthM = Form("%s/ITSupgModule%d_%d",pthL.Data(),lr+1,md+1);
350         TString snmM = Form("%s/ModUpg%d",snmL.Data(),md+1);
351         //
352         int modUID = AliGeomManager::LayerToVolUID(lr+1,modNum++);
353         //
354         //printf("SetAlignable (UID=%d, ModNum=%d): %s %s\n",modUID,modNum-1,snmM.Data(),pthM.Data());
355         gGeoManager->SetAlignableEntry(snmM.Data(),pthM.Data(),modUID);
356         //
357         double yshift = -(fUpGeom[lr]->GetSensorThick()-fUpGeom[lr]->GetLadderThick())/2;
358         SetT2Lmatrix(modUID,yshift, kTRUE,kTRUE); // RS: do we need here special matrix, ask MS
359         //
360       }
361     }
362   }
363   //
364 }
365
366 //______________________________________________________________________
367 void AliITSvUpgrade::AddBeamPipe(const Double_t rmin, const Double_t rmax,
368                                  const Double_t halfzlen) {
369
370   // Define the parameters for the beam pipe
371   if (fBeamPipe)
372     AliWarning("Redefining beam pipe parameters");
373
374   if (rmin <= 0) {
375     AliError(Form("Beam pipe min radius (%f) wrong",rmin));
376     return;
377   } else
378     fBeamPipeRmin = rmin;
379
380   if (rmax <= 0) {
381     AliError(Form("Beam pipe max radius (%f) wrong",rmax));
382     return;
383   } else
384     fBeamPipeRmax = rmax;
385
386   if (halfzlen < 0) {
387     AliError(Form("Beam pipe half Zlength (%f) wrong",halfzlen));
388     return;
389   } else {
390     if (halfzlen == 0) // Use default value
391       fBeamPipeZlen = fgkBeamPipeHalfZLen;
392     else
393       fBeamPipeZlen = halfzlen;
394   }
395
396   fBeamPipe = kTRUE;
397 }
398
399 //______________________________________________________________________
400 void AliITSvUpgrade::CreateGeometry() {
401
402   // Create the geometry and insert it in the mother volume ITSV
403
404
405   TGeoManager *geoManager = gGeoManager;
406
407   TGeoVolume *vALIC = geoManager->GetVolume("ALIC");
408
409   new TGeoVolumeAssembly("ITSV");
410   TGeoVolume *vITSV = geoManager->GetVolume("ITSV");
411   vALIC->AddNode(vITSV, 2, 0);  // Copy number is 2 to cheat AliGeoManager::CheckSymNamesLUT
412
413   //
414   const Char_t *cvsDate="$Date: 2011-03-11 18:17:13 +0100 (Fri, 11 Mar 2011) $";
415   const Char_t *cvsRevision="$Revision: 48336 $";
416   const Int_t kLength=100;
417   Char_t vstrng[kLength];
418   if(fInitGeom.WriteVersionString(vstrng,kLength,(AliITSVersion_t)IsVersion(),
419                              fMinorVersion,cvsDate,cvsRevision)) {
420     vITSV->SetTitle(vstrng);
421   }
422
423   // Check that we have all needed parameters
424   if (fNumberOfLayers <= 0)
425     AliFatal(Form("Wrong number of layers (%d)",fNumberOfLayers));
426
427   for (Int_t j=0; j<fNumberOfLayers; j++) {
428     if (fLayRadii[j] <= 0)
429       AliFatal(Form("Wrong layer radius for layer %d (%f)",j,fLayRadii[j]));
430     if (fLayZLength[j] <= 0)
431       AliFatal(Form("Wrong layer length for layer %d (%f)",j,fLayZLength[j]));
432     if (fLaddPerLay[j] <= 0)
433       AliFatal(Form("Wrong number of ladders for layer %d (%d)",j,
434                     fLaddPerLay[j]));
435     if (fModPerLadd[j] <= 0)
436       AliFatal(Form("Wrong number of modules for layer %d (%d)",j,
437                     fModPerLadd[j]));
438     if (fLadThick[j] < 0)
439       AliFatal(Form("Wrong ladder thickness for layer %d (%f)",j,
440                     fLadThick[j]));
441     if (fLayTurbo[j] && fLadWidth[j] <= 0)
442       AliFatal(Form("Wrong ladder width for layer %d (%f)",j,
443                     fLadWidth[j]));
444     if (fDetThick[j] < 0)
445       AliFatal(Form("Wrong module thickness for layer %d (%f)",j,
446                     fDetThick[j]));
447
448     if (j > 0) {
449       if (fLayRadii[j] <= fLayRadii[j-1])
450         AliError(Form("Layer %d radius (%f) is smaller than layer %d radius (%f)",
451                       j,fLayRadii[j],j-1,fLayRadii[j-1]));
452       if (fLayZLength[j] <= fLayZLength[j-1])
453         AliWarning(Form("Layer %d length (%f) is smaller than layer %d length (%f)",
454                       j,fLayZLength[j],j-1,fLayZLength[j-1]));
455     } // if (j > 0)
456
457     if (fLadThick[j] == 0)
458       AliInfo(Form("Ladder thickness for layer %d not set, using default",j));
459
460     if (fDetThick[j] == 0)
461       AliInfo(Form("Module thickness for layer %d not set, using default",j));
462
463   } // for (Int_t j=0; j<fNumberOfLayers; j++)
464
465   // Now create the actual geometry
466   for (Int_t j=0; j<fNumberOfLayers; j++) {
467     if (fLayTurbo[j]) {
468       fUpGeom[j] = new AliITSv11GeometryUpgrade(j+1,kTRUE,kFALSE);
469       fUpGeom[j]->SetLadderWidth(fLadWidth[j]);
470       fUpGeom[j]->SetLadderTilt(fLadTilt[j]);
471     }
472     else
473       fUpGeom[j] = new AliITSv11GeometryUpgrade(j+1,kFALSE);
474     fUpGeom[j]->SetRadius(fLayRadii[j]);
475     fUpGeom[j]->SetZLength(fLayZLength[j]);
476     fUpGeom[j]->SetNLadders(fLaddPerLay[j]);
477     fUpGeom[j]->SetNModules(fModPerLadd[j]);
478     if (fLadThick[j] != 0) fUpGeom[j]->SetLadderThick(fLadThick[j]);
479     if (fDetThick[j] != 0) fUpGeom[j]->SetSensorThick(fDetThick[j]);
480     fUpGeom[j]->CreateLayer(vITSV);
481   }
482
483   // Finally add the beam pipe
484   if (fBeamPipe) {
485     fBPGeom = new AliITSv11GeomBeamPipe(fBeamPipeRmin, fBeamPipeRmax,
486                                         fBeamPipeZlen, kFALSE);
487     fBPGeom->CreateBeamPipe(vALIC); // We put the BP in the ALIC volume
488   }
489
490 }
491
492 //______________________________________________________________________
493 void AliITSvUpgrade::CreateMaterials(){
494     // Create ITS materials
495     //     This function defines the default materials used in the Geant
496     // Monte Carlo simulations for the geometries AliITSv1, AliITSv3,
497     // AliITSv11Hybrid.
498     // In general it is automatically replaced by
499     // the CreateMaterials routine defined in AliITSv?. Should the function
500     // CreateMaterials not exist for the geometry version you are using this
501     // one is used. See the definition found in AliITSv5 or the other routine
502     // for a complete definition.
503     // Inputs:
504     //   none.
505     // Outputs:
506     //   none.
507     // Return:
508     //   none.
509
510     Int_t   ifield = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ();
511     Float_t fieldm = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max();
512
513     Float_t tmaxfd = 0.1; // 1.0; // Degree
514     Float_t stemax = 1.0; // cm
515     Float_t deemax = 0.1; // 30.0; // Fraction of particle's energy 0<deemax<=1
516     Float_t epsil  = 1.0E-4; // 1.0; // cm
517     Float_t stmin  = 0.0; // cm "Default value used"
518
519     Float_t tmaxfdSi = 0.1; // .10000E+01; // Degree
520     Float_t stemaxSi = 0.0075; //  .10000E+01; // cm
521     Float_t deemaxSi = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
522     Float_t epsilSi  = 1.0E-4;// .10000E+01;
523     Float_t stminSi  = 0.0; // cm "Default value used"
524
525     Float_t tmaxfdAir = 0.1; // .10000E+01; // Degree
526     Float_t stemaxAir = .10000E+01; // cm
527     Float_t deemaxAir = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
528     Float_t epsilAir  = 1.0E-4;// .10000E+01;
529     Float_t stminAir  = 0.0; // cm "Default value used"
530
531     // AIR
532     Float_t aAir[4]={12.0107,14.0067,15.9994,39.948};
533     Float_t zAir[4]={6.,7.,8.,18.};
534     Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};
535     Float_t dAir = 1.20479E-3;
536
537
538     AliMaterial(1,"SI$",0.28086E+02,0.14000E+02,0.23300E+01,0.93600E+01,0.99900E+03);
539     AliMedium(1,"SI$",1,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
540
541     AliMixture(5,"AIR$",aAir,zAir,dAir,4,wAir);
542     AliMedium(5,"AIR$",5,0,ifield,fieldm,tmaxfdAir,stemaxAir,deemaxAir,epsilAir,stminAir);
543
544     AliMaterial(8,"BERILLIUM$",9.01, 4., 1.848, 35.3, 36.7);// From AliPIPEv3
545     AliMedium(8,"BERILLIUM$",8,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
546
547 }
548
549 //______________________________________________________________________
550 void AliITSvUpgrade::DefineLayer(const Int_t nlay, const Double_t r,
551                                  const Double_t zlen, const Int_t nladd,
552                                  const Int_t nmod, const Double_t lthick,
553                                  const Double_t dthick){
554     //     Sets the layer parameters
555     // Inputs:
556     //          nlay    layer number
557     //          r       layer radius
558     //          zlen    layer length
559     //          nladd   number of ladders
560     //          nmod    number of modules per ladder
561     //          lthick  ladder thickness (if omitted, defaults to 0)
562     //          dthick  detector thickness (if omitted, defaults to 0)
563     // Outputs:
564     //   none.
565     // Return:
566     //   none.
567
568     if (nlay >= fNumberOfLayers || nlay < 0) {
569       AliError(Form("Wrong layer number (%d)",nlay));
570       return;
571     }
572
573     fLayTurbo[nlay] = kFALSE;
574     fLayRadii[nlay] = r;
575     fLayZLength[nlay] = zlen;
576     fLaddPerLay[nlay] = nladd;
577     fModPerLadd[nlay] = nmod;
578     fLadThick[nlay] = lthick;
579     fDetThick[nlay] = dthick;
580 }
581
582 //______________________________________________________________________
583 void AliITSvUpgrade::DefineLayerTurbo(const Int_t nlay, const Double_t r,
584                                       const Double_t zlen, const Int_t nladd,
585                                       const Int_t nmod, const Double_t width,
586                                       const Double_t tilt,
587                                       const Double_t lthick,
588                                       const Double_t dthick){
589     //     Sets the layer parameters for a "turbo" layer
590     //     (i.e. a layer whose ladders overlap in phi)
591     // Inputs:
592     //          nlay    layer number
593     //          r       layer radius
594     //          zlen    layer length
595     //          nladd   number of ladders
596     //          nmod    number of modules per ladder
597     //          width   layer width
598     //          tilt    layer tilt angle (degrees)
599     //          lthick  ladder thickness (if omitted, defaults to 0)
600     //          dthick  detector thickness (if omitted, defaults to 0)
601     // Outputs:
602     //   none.
603     // Return:
604     //   none.
605
606     if (nlay >= fNumberOfLayers || nlay < 0) {
607       AliError(Form("Wrong layer number (%d)",nlay));
608       return;
609     }
610
611     fLayTurbo[nlay] = kTRUE;
612     fLayRadii[nlay] = r;
613     fLayZLength[nlay] = zlen;
614     fLaddPerLay[nlay] = nladd;
615     fModPerLadd[nlay] = nmod;
616     fLadThick[nlay] = lthick;
617     fLadWidth[nlay] = width;
618     fLadTilt[nlay] = tilt;
619     fDetThick[nlay] = dthick;
620 }
621
622 //______________________________________________________________________
623 void AliITSvUpgrade::GetBeamPipeParameters(Double_t &rmin, Double_t &rmax,
624                                            Double_t &hzlen){
625     //     Gets the beam pipe parameters
626     // Inputs:
627     //   none.
628     // Outputs:
629     //          rmin    min radius
630     //          rmax    max radius
631     //          hzlen   half Z length
632     // Return:
633     //   none.
634
635     rmin  = fBeamPipeRmin;
636     rmax  = fBeamPipeRmax;
637     hzlen = fBeamPipeZlen;
638
639 }
640
641 //______________________________________________________________________
642 void AliITSvUpgrade::GetLayerParameters(const Int_t nlay,
643                                         Double_t &r, Double_t &zlen,
644                                         Int_t &nladd, Int_t &nmod,
645                                         Double_t &width, Double_t &tilt,
646                                         Double_t &lthick, Double_t &dthick){
647     //     Gets the layer parameters
648     // Inputs:
649     //          nlay    layer number
650     // Outputs:
651     //          r       layer radius
652     //          zlen    layer length
653     //          nladd   number of ladders
654     //          nmod    number of modules per ladder
655     //          width   ladder width
656     //          tilt    ladder tilt angle
657     //          lthick  ladder thickness
658     //          dthick  detector thickness
659     // Return:
660     //   none.
661
662     if (nlay >= fNumberOfLayers || nlay < 0) {
663       AliError(Form("Wrong layer number (%d)",nlay));
664       return;
665     }
666
667     r = fLayRadii[nlay];
668     zlen = fLayZLength[nlay];
669     nladd = fLaddPerLay[nlay];
670     nmod = fModPerLadd[nlay];
671     width = fLadWidth[nlay];
672     tilt = fLadTilt[nlay];
673     lthick = fLadThick[nlay];
674     dthick = fDetThick[nlay];
675 }
676
677 //______________________________________________________________________
678 void AliITSvUpgrade::Init(){
679     //     Initialise the ITS after it has been created.
680     // Inputs:
681     //   none.
682     // Outputs:
683     //   none.
684     // Return:
685     //   none.
686
687     AliDebug(1,Form("Init: Major version %d Minor version %d",fMajorVersion,
688                  fMinorVersion));
689     UpdateInternalGeometry();
690     AliITSUpg::Init();
691
692 }
693
694 //______________________________________________________________________
695 Bool_t AliITSvUpgrade::IsLayerTurbo(const Int_t nlay){
696     //     Returns true if the layer is a "turbo" layer
697     // Inputs:
698     //          nlay    layer number
699     // Outputs:
700     //   none.
701     // Return:
702     //          kTRUE if the layer is a turbo layer
703
704     if ( nlay < 0 || nlay > fNumberOfLayers ) {
705       AliError(Form("Wrong layer number %d",nlay));
706       return kFALSE;
707     } else
708       return fUpGeom[nlay]->IsTurbo();
709
710 }
711
712 //______________________________________________________________________
713 void AliITSvUpgrade::SetDefaults(){
714     // sets the default segmentation, response, digit and raw cluster classes
715     // Inputs:
716     //   none.
717     // Outputs:
718     //   none.
719     // Return:
720     //   none.
721
722     if(!fDetTypeSim){
723         Warning("SetDefaults","Error fDetTypeSim not defined");
724         return;
725     }
726
727     fDetTypeSim->SetDefaults();
728
729     return;
730 }
731
732 //______________________________________________________________________
733 void AliITSvUpgrade::StepManager(){
734     //    Called for every step in the ITS, then calles the AliITShit class
735     // creator with the information to be recoreded about that hit.
736     //     The value of the macro ALIITSPRINTGEOM if set to 1 will allow the
737     // printing of information to a file which can be used to create a .det
738     // file read in by the routine CreateGeometry(). If set to 0 or any other
739     // value except 1, the default behavior, then no such file is created nor
740     // it the extra variables and the like used in the printing allocated.
741     // Inputs:
742     //   none.
743     // Outputs:
744     //   none.
745     // Return:
746     //   none.
747   static TLorentzVector positionRS;
748   gMC->TrackPosition(positionRS);
749     if(!(this->IsActive())) return;
750     if(!(gMC->TrackCharge())) return;
751
752     Int_t copy, lay = 0;
753     Int_t id = gMC->CurrentVolID(copy);
754
755     Bool_t notSens = kFALSE;
756     while ((lay<fIdN)  && (notSens = id != fIdSens[lay])) ++lay;
757     //printf("R: %.1f | Lay: %d  NotSens: %d\n",positionRS.Pt(), lay, notSens);
758            
759     if (notSens) return;
760
761     if(gMC->IsTrackExiting()) {
762         AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kITS);
763     } // if Outer ITS mother Volume
764
765     static TLorentzVector position, momentum; // Saves on calls to construtors
766     static AliITShit hit;// Saves on calls to constructors
767
768     TClonesArray &lhits = *(Hits());
769     Int_t   cpn0, cpn1, mod, status = 0;
770     //
771     // Track status
772     if(gMC->IsTrackInside())      status +=  1;
773     if(gMC->IsTrackEntering())    status +=  2;
774     if(gMC->IsTrackExiting())     status +=  4;
775     if(gMC->IsTrackOut())         status +=  8;
776     if(gMC->IsTrackDisappeared()) status += 16;
777     if(gMC->IsTrackStop())        status += 32;
778     if(gMC->IsTrackAlive())       status += 64;
779
780     //
781     // retrieve the indices with the volume path
782     //
783     if (lay < 0 || lay >= fIdN) {
784       AliError(Form("Invalid value: lay=%d. Not an ITS sensitive volume",lay));
785       return; // not an ITS sensitive volume.
786     } else {
787       copy = 1;
788       gMC->CurrentVolOffID(1,cpn1);
789       gMC->CurrentVolOffID(2,cpn0);
790     } //
791
792     fInitGeom.DecodeDetector(mod,lay+1,cpn0,cpn1,copy);
793     // We should not need to pass by the switch !
794     // This is time consuming...
795     // therefore DecodeDetectorv11Upgrade(...) shouldn't be private !
796     // and we should be able to use instead :
797     //fInitGeom.DecodeDetectorv11Upgrade(mod,lay+1,cpn0,cpn1,copy);
798
799     //
800     // Fill hit structure.
801     //
802     hit.SetModule(mod);
803     hit.SetTrack(gAlice->GetMCApp()->GetCurrentTrackNumber());
804     gMC->TrackPosition(position);
805     gMC->TrackMomentum(momentum);
806     hit.SetPosition(position);
807     hit.SetTime(gMC->TrackTime());
808     hit.SetMomentum(momentum);
809     hit.SetStatus(status);
810     hit.SetEdep(gMC->Edep());
811     hit.SetShunt(GetIshunt());
812     if(gMC->IsTrackEntering()){
813         hit.SetStartPosition(position);
814         hit.SetStartTime(gMC->TrackTime());
815         hit.SetStartStatus(status);
816         return; // don't save entering hit.
817     } // end if IsEntering
818     // Fill hit structure with this new hit.
819     //Info("StepManager","Calling Copy Constructor");
820     new(lhits[fNhits++]) AliITShit(hit); // Use Copy Construtor.
821     // Save old position... for next hit.
822     hit.SetStartPosition(position);
823     hit.SetStartTime(gMC->TrackTime());
824     hit.SetStartStatus(status);
825
826     return;
827 }
828