Adding some further mother volumes to speed-up the overlap checking and particle...
[u/mrichter/AliRoot.git] / ITS / AliITSMisAligner.cxx
1 /**************************************************************************
2  * Copyright(c) 2007-2010, 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 /* $Id$ */
17
18 //========================================================================
19 //
20 // This class is a helper, producing ITS aligmnent objects.
21 // It provides also some useful functions
22 // See the parameters of the misalignment at the end of this script.
23 //
24 // Main author: L. Gaudichet
25 // Contact: andrea.dainese@lnl.infn.it
26 //
27 //========================================================================
28
29 #include <TClonesArray.h>
30 #include <TMath.h>
31 #include <TClass.h>
32 #include <TGeoManager.h>
33 #include "AliLog.h"
34 #include "AliAlignObjParams.h"
35 #include "AliITSMisAligner.h"
36 #include "AliITSSurveyToAlign.h"
37 #include "AliMathBase.h"
38
39 ClassImp(AliITSMisAligner)
40   
41 const Int_t AliITSMisAligner::fgkNLadders[AliITSMisAligner::kNLayers] = {20,40,14,22,34,38};
42 const Int_t AliITSMisAligner::fgkNDetectors[AliITSMisAligner::kNLayers] = {4,4,6,8,22,25};
43
44 const Double_t kRadToDeg = 180./TMath::Pi();
45
46 //________________________________________________________________________
47 AliITSMisAligner::AliITSMisAligner():
48     AliMisAligner(),
49     fRnd(),
50     fInd(0),
51     fAlignObjArray(NULL),
52     fStrSPD("ITS/SPD"),
53     fStrSDD("ITS/SDD"),
54     fStrSSD("ITS/SSD"),
55     fStrStave("/Stave"),
56     fStrHalfStave("/HalfStave"),
57     fStrLadder("/Ladder"),
58     fStrSector("/Sector"),
59     fStrSensor("/Sensor"),
60     fUnifSPDSector(kFALSE),
61     fUnifSPDHS(kFALSE),
62     fUnifSDDLadder(kFALSE),
63     fUnifSSDLadder(kFALSE),
64     fUnifSPDLadder(kFALSE),
65     fUnifSDDModule(kFALSE),
66     fUnifSSDModule(kFALSE)
67 {
68     //
69     // defaul constructor
70     //
71     fRnd.SetSeed(38217945);
72     fAlignObjArray = new TClonesArray("AliAlignObjParams",4000);
73     for(Int_t ii=0; ii<6; ii++)
74     {
75         fWholeITS[ii]=0.;
76         fSPDSector[ii]=0.;
77         fSPDHB[ii]=0.;
78         fSPDBarrel[ii]=0.;
79         fSPDHS[ii]=0.;
80         fSPDLadder[ii]=0.;
81         fSDDLayer[ii]=0.;
82         fSDDBarrel[ii]=0.;
83         fSDDLadder[ii]=0.;
84         fSDDModule[ii]=0.;
85         fSSDBarrel[ii]=0.;
86         fSSDLayer[ii]=0.;
87         fSSDLadder[ii]=0.;
88         fSSDModule[ii]=0.;
89         fSPDLadderShiftT[ii]=0.;
90         fSPDLadderShiftB[ii]=0.;
91         fSDDLadderShift1[ii]=0.;
92         fSDDLadderShift2[ii]=0.;
93     }
94 }
95
96 //________________________________________________________________________
97 AliITSMisAligner::AliITSMisAligner(const AliITSMisAligner &mAligner):
98     fRnd(mAligner.fRnd),
99     fInd(0),
100     fAlignObjArray(mAligner.fAlignObjArray),
101     fStrSPD("ITS/SPD"),
102     fStrSDD("ITS/SDD"),
103     fStrSSD("ITS/SSD"),
104     fStrStave("/Stave"),
105     fStrHalfStave("/HalfStave"),
106     fStrLadder("/Ladder"),
107     fStrSector("/Sector"),
108     fStrSensor("/Sensor"),
109     fUnifSPDSector(kFALSE),
110     fUnifSPDHS(kFALSE),
111     fUnifSDDLadder(kFALSE),
112     fUnifSSDLadder(kFALSE),
113     fUnifSPDLadder(kFALSE),
114     fUnifSDDModule(kFALSE),
115     fUnifSSDModule(kFALSE)
116 {
117     //
118     // copy constructor
119     //
120 }
121
122 //________________________________________________________________________
123 AliITSMisAligner &AliITSMisAligner::operator= (const AliITSMisAligner &mAligner)
124 {
125     //
126     // assignment operator
127     //
128     fRnd = mAligner.fRnd;
129     fInd = 0;
130     fAlignObjArray = mAligner.fAlignObjArray;
131     fStrSPD = "ITS/SPD";
132     fStrSDD = "ITS/SDD";
133     fStrSSD = "ITS/SSD";
134     fStrStave = "/Stave";
135     fStrHalfStave = "/HalfStave";
136     fStrLadder = "/Ladder";
137     fStrSector = "/Sector";
138     fStrSensor = "/Sensor";
139     fUnifSPDSector = mAligner.fUnifSPDSector;
140     fUnifSPDHS = kFALSE;
141     fUnifSDDLadder = kFALSE;
142     fUnifSSDLadder = kFALSE;
143     fUnifSPDLadder = kFALSE;
144     fUnifSDDModule = kFALSE;
145     fUnifSSDModule = kFALSE;
146     return (*this);
147 }
148
149 //_______________________________________________________________________________________
150 TClonesArray* AliITSMisAligner::MakeAlObjsArray() {
151     // Make the array of alignment objects, depending on the misalignment scenario (Zero, Residual, Full)
152     //
153
154     // Setting default values for ideal, residual or full misalignment
155     SetWholeITSMisAlignment();
156     SetSPDMisAlignment();
157     SetSDDMisAlignment();
158     SetSSDMisAlignment(); 
159
160     // Get array of alignment objects from survey (based on which we build later the SSD objects)
161     AliITSSurveyToAlign* s2a = new AliITSSurveyToAlign();
162     s2a->Run();
163     TClonesArray* surveyArray = dynamic_cast<TClonesArray*> (s2a->GetAlignObjsArray());
164     if(!surveyArray){
165         Printf("SSD survey array was not build! Probably you missed to connect to alien");
166         return 0;
167     }else{
168         Printf("survey array contains %d entries", surveyArray->GetEntriesFast());
169     }
170
171     AddAlignObj("ITS",fWholeITS[0],fWholeITS[1],fWholeITS[2],fWholeITS[3],fWholeITS[4],fWholeITS[5],"fixed");
172
173     AddSectorAlignObj(1,5,fSPDSector[0],fSPDSector[1],fSPDSector[2],fSPDSector[3],fSPDSector[4],fSPDSector[5],
174             fSPDLadderShiftT[0],fSPDLadderShiftT[1],fSPDLadderShiftT[2],fSPDLadderShiftT[3],fSPDLadderShiftT[4],fSPDLadderShiftT[5],fUnifSPDSector);
175     AddSectorAlignObj(6,10,fSPDSector[0],fSPDSector[1],fSPDSector[2],fSPDSector[3],fSPDSector[4],fSPDSector[5],
176             fSPDLadderShiftB[0],fSPDLadderShiftB[1],fSPDLadderShiftB[2],fSPDLadderShiftB[3],fSPDLadderShiftB[4],fSPDLadderShiftB[5],fUnifSPDSector);
177
178     //=****************************************
179     // misalignment at the level of half-staves (SPD)/ladders (SDD,SSD) :
180     //=****************************************
181     AddAlignObj(0,-1,fSPDHS[0],fSPDHS[1],fSPDHS[2],fSPDHS[3],fSPDHS[4],fSPDHS[5],
182             0,0,0,0,0,0,fUnifSPDHS); // all SPD1 half-staves
183     AddAlignObj(1,-1,fSPDHS[0],fSPDHS[1],fSPDHS[2],fSPDHS[3],fSPDHS[4],fSPDHS[5],
184             0,0,0,0,0,0,fUnifSPDHS); // all SPD2 half-staves
185
186     AddAlignObj(2,-1,fSDDLadder[0],fSDDLadder[1],fSDDLadder[2],fSDDLadder[3],
187             fSDDLadder[4],fSDDLadder[5],fSDDLadderShift1[0],fSDDLadderShift1[1],fSDDLadderShift1[2],fSDDLadderShift1[3],fSDDLadderShift1[4],fSDDLadderShift1[5],fUnifSDDLadder); // all SDD1 ladders
188     AddAlignObj(3,-1,fSDDLadder[0],fSDDLadder[1],fSDDLadder[2],fSDDLadder[3],
189             fSDDLadder[4],fSDDLadder[5],fSDDLadderShift2[0],fSDDLadderShift2[1],fSDDLadderShift2[2],fSDDLadderShift2[3],fSDDLadderShift2[4],fSDDLadderShift2[5],fUnifSDDLadder); // all SDD2 ladders
190
191     // all SSD ladders as from survey, + shift and smearing in the "residual" and "full" case
192     for(Int_t ii=0; ii<surveyArray->GetEntriesFast(); ii++)
193     {
194         AliAlignObjParams* aop = dynamic_cast<AliAlignObjParams*> (surveyArray->UncheckedAt(ii));
195         TString sName(aop->GetSymName());
196
197         if(sName.Contains("SSD") && !sName.Contains("Sensor"))
198         {
199
200             if(!(TString(GetMisalType())=="ideal"))
201             {
202                 // First we shift all SSD ladders by the same quantity to reproduce a barrel shift
203                 ShiftAlignObj(*aop,fSSDBarrel[0],fSSDBarrel[1],fSSDBarrel[2],fSSDBarrel[3],fSSDBarrel[4],fSSDBarrel[5]);
204
205                 // Then we smear according to the sigmas given by the misalignment scenario
206                 if(sName.Contains("SSD4")){
207                     // we correct with the factor 1.13 for the fact that, in the inner SSD layer, z lever arm is 45.135cm instead of 51cm
208                     SmearAlignObj(*aop,fSSDLadder[0],fSSDLadder[1],fSSDLadder[2],fSSDLadder[3]*1.13,fSSDLadder[4]*1.13,fSSDLadder[5]);
209                 }else if(sName.Contains("SSD5")){
210                     SmearAlignObj(*aop,fSSDLadder[0],fSSDLadder[1],fSSDLadder[2],fSSDLadder[3],fSSDLadder[4],fSSDLadder[5]);
211                 }
212             }
213
214             new((*fAlignObjArray)[fInd++]) AliAlignObjParams(*aop);
215             aop->ApplyToGeometry(); // this we need to correctly build objects for SSD ladders below
216         }
217     }
218
219     //=****************************************
220     // misalignment at the level of ladders (SPD)/modules (SDD,SSD) :
221     //=****************************************
222     AddAlignObj(0,fSPDLadder[0],fSPDLadder[1],fSPDLadder[2],fSPDLadder[3],fSPDLadder[4],fSPDLadder[5],fUnifSPDLadder);// all SPD1 ladders
223     AddAlignObj(1,fSPDLadder[0],fSPDLadder[1],fSPDLadder[2],fSPDLadder[3],fSPDLadder[4],fSPDLadder[5],fUnifSPDLadder);// all SPD2 ladders
224
225     AddAlignObj(2,fSDDModule[0],fSDDModule[1],fSDDModule[2],fSDDModule[3],fSDDModule[4],fSDDModule[5],fUnifSDDModule);// all SDD1 modules
226     AddAlignObj(3,fSDDModule[0],fSDDModule[1],fSDDModule[2],fSDDModule[3],fSDDModule[4],fSDDModule[5],fUnifSDDModule);// all SDD2 modules
227
228     // all SSD modules
229     for(Int_t ii=0; ii<surveyArray->GetEntriesFast(); ii++)
230     {
231         AliAlignObjParams* aop = dynamic_cast<AliAlignObjParams*> (surveyArray->UncheckedAt(ii));
232         TString sName(aop->GetSymName());
233         if(sName.Contains("SSD") && sName.Contains("Sensor"))
234         {
235             if(!(TString(GetMisalType())=="ideal"))
236                 SmearAlignObj(*aop,fSSDModule[0],fSSDModule[1],fSSDModule[2],fSSDModule[3],fSSDModule[4],fSSDModule[5]);
237             new((*fAlignObjArray)[fInd++]) AliAlignObjParams(*aop);
238         }
239     }
240
241     return fAlignObjArray;
242 }
243
244 //_______________________________________________________________________________________
245 void AliITSMisAligner::ShiftAlignObj(AliAlignObjParams &alObj, Double_t dx, Double_t dy, Double_t dz, Double_t dpsi, Double_t dtheta, Double_t dphi)
246 {
247     // 
248     // Shift the parameters of the alignment object passed as first argument by the quantities defined by the arguments
249     //
250     Double_t shifts[3]; Double_t angles[3];
251     alObj.GetPars(shifts, angles);
252     alObj.SetPars(shifts[0]+dx, shifts[1]+dy, shifts[2]+dz, angles[0]+dpsi, angles[1]+dtheta, angles[2]+dphi);
253 }
254
255 //_______________________________________________________________________________________
256 void AliITSMisAligner::SmearAlignObj(AliAlignObjParams &alObj, Double_t sx, Double_t sy, Double_t sz, Double_t spsi, Double_t stheta, Double_t sphi)
257 {
258     // 
259     // Smear the parameters of the alignment object passed as first argument in the range defined by the subsequent arguments
260     //
261     Double_t shifts[3]; Double_t angles[3];
262     alObj.GetLocalPars(shifts, angles);
263     Double_t x = AliMathBase::TruncatedGaus(shifts[0], sx, 3.*sx);
264     Double_t y = AliMathBase::TruncatedGaus(shifts[1], sy, 3.*sy);
265     Double_t z = AliMathBase::TruncatedGaus(shifts[2], sz, 3.*sz);
266     Double_t psi = AliMathBase::TruncatedGaus(angles[0], spsi, 3.*spsi);
267     Double_t theta = AliMathBase::TruncatedGaus(angles[1], stheta, 3.*stheta);
268     Double_t phi = AliMathBase::TruncatedGaus(angles[2], sphi, 3.*sphi);
269     alObj.SetLocalPars(x, y, z, psi, theta, phi);
270 }
271
272 //_______________________________________________________________________________________
273 void AliITSMisAligner::SetWholeITSMisAlignment()
274 {
275     // Set misalignment for the whole ITS for the standar scenarios (zero, residual, full)
276     // To make custom misalignments set directly the misalignments at each level (methods "SetS?D*Pars")
277     //
278     if(TString(GetMisalType())=="ideal")
279     {
280         // overall ITS misalignment according to survey as reported by Werner Riegler (18/07/2008)
281         SetWholeITSPars(-0.12, -0.07, 0.29, 0., 0.03, 0.04);
282     }else if(TString(GetMisalType())=="residual"){
283         // overall ITS misalignment according to survey as reported by Werner Riegler (18/07/2008)
284         // no smearing added (would clash with vertex constraint)
285         SetWholeITSPars(-0.12, -0.07, 0.29, 0., 0.03, 0.04);
286     }else if(TString(GetMisalType())=="full"){
287         // overall ITS misalignment according to survey as reported by Werner Riegler (18/07/2008) plus smearing
288         Double_t sigmatrW = 0.01;
289         Double_t sigmarotW = 0.006;
290         SetWholeITSPars(AliMathBase::TruncatedGaus(-0.12,sigmatrW,3.*sigmatrW),
291                 AliMathBase::TruncatedGaus(-0.07,sigmatrW,3.*sigmatrW),
292                 AliMathBase::TruncatedGaus(0.29,sigmatrW,3.*sigmatrW),
293                 AliMathBase::TruncatedGaus(0.,sigmarotW,3.*sigmarotW),
294                 AliMathBase::TruncatedGaus(0.03,sigmarotW,3.*sigmarotW),
295                 AliMathBase::TruncatedGaus(0.04,sigmarotW,3.*sigmarotW));
296     }
297 }
298
299 //_______________________________________________________________________________________
300 void AliITSMisAligner::SetSPDMisAlignment()
301 {
302     // Set misalignment for SPD alignable volumes for the standar scenarios (zero, residual, full)
303     // To make custom misalignments set directly the misalignments at each level (methods "SetSPD*Pars")
304     //
305     if(TString(GetMisalType())=="ideal")
306     {
307         // misalignment for SPD at all levels equal to zero (identical transformations)
308         SetSPDBarrelSigmas(0., 0., 0., 0., 0., 0.); 
309         SetSPDHBSigmas(0., 0., 0., 0., 0., 0.); 
310         SetSPDSectorSigmas(0., 0., 0., 0., 0., 0.); 
311         SetSPDHSSigmas(0., 0., 0., 0., 0., 0.); 
312         SetSPDLadderSigmas(0., 0., 0., 0., 0., 0.); 
313     }else if(TString(GetMisalType())=="residual"){
314         // misalignment at the level of SPD barrel and half-barrels left to zero
315         SetSPDBarrelSigmas(0., 0., 0., 0., 0., 0.); 
316         SetSPDHBSigmas(0., 0., 0., 0., 0., 0.); 
317
318         // misalignment at the level of SPD sectors (source: A.Pepato)
319         SetSPDSectorSigmas( 0.0050/5., //  50 micron (~tangetial, i.e. rphi)
320                 0.0100/5., // 100 micron (~radial)
321                 0.0100/5., // 100 micron
322                 0.0100/30.*kRadToDeg/5., // so as to have 100 micron difference at the two extremes
323                 0.0100/30.*kRadToDeg/5., // so as to have 100 micron difference at the two extremes
324                 0.0050/1.5*kRadToDeg/5.); // so as to have 50 micron difference at the two extremes
325         fUnifSPDSector=kFALSE;
326
327         // misalignment at the level of half-staves (SPD) (source: S.Moretto)
328         SetSPDHSSigmas( 0.0100/4., // 100 micron
329                 0.0020/4., // 20 micron
330                 0.0020/4., // 20 micron
331                 0.0020/7.*kRadToDeg/4., // so as to have 20 micron difference at the two extremes
332                 0.0050/7.*kRadToDeg/4., // so as to have 50 micron difference at the two extremes
333                 0.0050/0.7*kRadToDeg/4.);// so as to have 50 micron difference at the two extremes
334         fUnifSPDHS=kFALSE;
335
336         // misalignment at the level of ladders (SPD) (source: R.Santoro)
337         SetSPDLadderSigmas( 0.0010/5., // 10 micron
338                 0.0050/5., // 50 micron
339                 0.0010/5., // 10 micron
340                 0.0001*kRadToDeg/5., // 0.1 mrad
341                 0.0001*kRadToDeg/5., // 0.1 mrad
342                 0.0001*kRadToDeg/5.);// 0.1 mrad
343         fUnifSPDLadder=kFALSE;
344
345     }else if(TString(GetMisalType())=="full"){
346         // misalignment at the level of SPD barrel (source: A.Pepato)
347         SetSPDBarrelSigmas( 0.1000, // 1 mm (very pessimistic)
348                 0.1000, // 1 mm (very pessimistic)
349                 0.1000, // 1 mm (very pessimistic)
350                 0.0500/30.*kRadToDeg, // so as to have 500 micron difference at the two extremes
351                 0.0500/30.*kRadToDeg, // so as to have 500 micron difference at the two extremes
352                 0.0500/7.*kRadToDeg); // so as to have 500 micron difference at the two extremes
353
354         // misalignment at the level of SPD half-barrels (source: A.Pepato)
355         SetSPDHBSigmas( 0.0200, // 200 micron
356                 0.0200, // 200 micron
357                 0.0200, // 200 micron
358                 0.0100/30.*kRadToDeg, // so as to have 100 micron difference at the two extremes
359                 0.0100/30.*kRadToDeg, // so as to have 100 micron difference at the two extremes
360                 0.0100/7.*kRadToDeg); // so as to have 100 micron difference at the two extremes
361
362         // misalignment at the level of SPD sectors (source: A.Pepato)
363         SetSPDSectorSigmas( 0.0050, //  50 micron (~tangetial, i.e. rphi)
364                 0.0100, // 100 micron (~radial)
365                 0.0100, // 100 micron
366                 0.0100/30.*kRadToDeg, // so as to have 100 micron difference at the two extremes
367                 0.0100/30.*kRadToDeg, // so as to have 100 micron difference at the two extremes
368                 0.0050/1.5*kRadToDeg); // so as to have 50 micron difference at the two extremes
369         fUnifSPDSector=kTRUE;
370
371         // misalignment at the level of half-staves (SPD) (source: S.Moretto)
372         SetSPDHSSigmas( 0.0100, // 100 micron // normal to plane
373                 0.0020, // 20 micron
374                 0.0020, // 20 micron
375                 0.0020/7.*kRadToDeg, // so as to have 20 micron difference at the two extremes
376                 0.0050/7.*kRadToDeg, // so as to have 50 micron difference at the two extremes
377                 0.0050/0.7*kRadToDeg); // so as to have 50 micron difference at the two extremes
378         fUnifSPDHS=kTRUE;
379
380         // misalignment at the level of ladders (SPD) (source: R.Santoro)
381         SetSPDLadderSigmas( 0.0010, // 10 micron
382                 0.0030, // 50 micron
383                 0.0010, // 10 micron
384                 0.0001*kRadToDeg, // 0.1 mrad
385                 0.0001*kRadToDeg, // 0.1 mrad
386                 0.0001*kRadToDeg); // 0.1 mrad
387         fUnifSPDLadder=kTRUE;
388
389
390         // misalignment at the level of SPD barrel, half-barrels, and at the level
391         // of SPD sectors
392         Double_t shBtop[6], shBbot[6]; //top and bottom barrel shifts
393         for(Int_t ii=0; ii<6; ii++){
394             shBtop[ii] = AliMathBase::TruncatedGaus(0.,fSPDBarrel[ii]/3,fSPDBarrel[ii]);
395             shBbot[ii] = shBtop[ii];
396         }
397
398         for(Int_t ii=0; ii<6; ii++){
399             shBtop[ii] += AliMathBase::TruncatedGaus(0.,fSPDHB[ii]/3,fSPDHB[ii]);
400             shBbot[ii] += AliMathBase::TruncatedGaus(0.,fSPDHB[ii]/3,fSPDHB[ii]);
401         }
402         SetSPDLadderShiftT(shBtop);
403         SetSPDLadderShiftB(shBbot);
404     }
405 }
406
407 //_______________________________________________________________________________________
408 void AliITSMisAligner::SetSDDMisAlignment() 
409 {
410     // Set misalignment for SDD alignable volumes for the standar scenarios (zero, residual, full)
411     // To make custom misalignments set directly the misalignments at each level (methods "SetSDD*Pars")
412     //
413     if(TString(GetMisalType())=="ideal")
414     {
415         // misalignment for SDD at all levels equal to zero
416         SetSDDLayerSigmas(0., 0., 0., 0., 0., 0.);
417         SetSDDBarrelSigmas(0., 0., 0., 0., 0., 0.);
418         SetSDDLadderSigmas(0., 0., 0., 0., 0., 0.);
419         SetSDDModuleSigmas(0., 0., 0., 0., 0., 0.);
420     }else if(TString(GetMisalType())=="residual"){
421         // misalignment at the level of SDD and SSD layers(source: B.Giraudo)
422         SetSDDLayerSigmas(0., 0., 0., 0., 0., 0.);
423         SetSDDBarrelSigmas(0., 0., 0., 0., 0., 0.);
424
425         // misalignment at the level of half-staves (SPD) (source: S.Moretto)
426         SetSDDLadderSigmas( 0.0005, // 5 micron
427                 0.0005, // 5 micron
428                 0.0005, // 5 micron
429                 0.00, //  ?
430                 0.00, //  ?
431                 0.00); //  ?
432         fUnifSDDLadder=kFALSE;
433
434         // misalignment at the level of SDD modules(source: L.Gaudichet)
435         SetSDDModuleSigmas( 0.0045/5., // 45 micron
436                 0.0045/5., // 45 micron
437                 0.0105/5., // 105 micron
438                 0.00, // ?
439                 0.00, //  ?
440                 0.00);//  ?
441         fUnifSDDModule=kFALSE;
442
443     }else if(TString(GetMisalType())=="full"){
444         // misalignment at the level of SDD layers(source: B.Giraudo)
445         SetSDDBarrelSigmas( 0.0020, // 20 micron
446                 0.0020, // 20 micron
447                 0.0020, // 20 micron
448                 0.0020/52.*kRadToDeg,  // so as to have 20 micron difference at the two extremes
449                 0.0020/52.*kRadToDeg,  // so as to have 20 micron difference at the two extremes
450                 0.0020/20.*kRadToDeg); // so as to have 20 micron difference at the two extremes
451
452         SetSDDLayerSigmas( 0.0010, // 10 micron
453                 0.0010, // 10 micron
454                 0.0010, // 10 micron
455                 0.0010/52.*kRadToDeg, // so as to have 10 micron difference at the two extremes
456                 0.0010/52.*kRadToDeg, // so as to have 10 micron difference at the two extremes
457                 0.0010/20.*kRadToDeg);  // so as to have 10 micron difference at the two extremes
458
459         // misalignment at the level of SDD ladders
460         SetSDDLadderSigmas( 0.0005, // 5 micron
461                 0.0005, // 5 micron
462                 0.0005, // 5 micron
463                 0.00, //  ?
464                 0.00, //  ?
465                 0.00);//  ?
466         fUnifSDDLadder=kTRUE;
467
468         // misalignment at the level of SDD modules (source: L.Gaudichet)
469         SetSDDModuleSigmas( 0.0045, // 45 micron
470                 0.0045, // 45 micron
471                 0.0105, // 105 micron
472                 0.00, // ?
473                 0.00, //  ?
474                 0.00);//  ?
475         fUnifSDDModule=kTRUE;
476     }
477
478     fSDDLadderShift1[0] = GetUnif(-fSDDBarrel[0],fSDDBarrel[0]);
479     fSDDLadderShift1[1] = GetUnif(-fSDDBarrel[1],fSDDBarrel[1]);
480     fSDDLadderShift1[2] = GetUnif(-fSDDBarrel[2],fSDDBarrel[2]);
481     fSDDLadderShift1[3] = GetUnif(-fSDDBarrel[3],fSDDBarrel[3]);
482     fSDDLadderShift1[4] = GetUnif(-fSDDBarrel[4],fSDDBarrel[4]);
483     fSDDLadderShift1[5] = GetUnif(-fSDDBarrel[5],fSDDBarrel[5]);
484
485     for(Int_t ii=0; ii<6; ii++)
486         fSDDLadderShift2[ii] = fSDDLadderShift1[ii];
487
488     //  layer SDD1
489     fSDDLadderShift1[0] += GetUnif(-fSDDLayer[0],fSDDLayer[0]);
490     fSDDLadderShift1[1] += GetUnif(-fSDDLayer[1],fSDDLayer[1]);
491     fSDDLadderShift1[2] += GetUnif(-fSDDLayer[2],fSDDLayer[2]);
492     fSDDLadderShift1[3] += GetUnif(-fSDDLayer[3],fSDDLayer[3]);
493     fSDDLadderShift1[4] += GetUnif(-fSDDLayer[4],fSDDLayer[4]);
494     fSDDLadderShift1[5] += GetUnif(-fSDDLayer[5],fSDDLayer[5]);
495
496     //  layer SDD2
497     fSDDLadderShift2[0] += GetUnif(-fSDDLayer[0],fSDDLayer[0]);
498     fSDDLadderShift2[1] += GetUnif(-fSDDLayer[1],fSDDLayer[1]);
499     fSDDLadderShift2[2] += GetUnif(-fSDDLayer[2],fSDDLayer[2]);
500     fSDDLadderShift2[3] += GetUnif(-fSDDLayer[3],fSDDLayer[3]);
501     fSDDLadderShift2[4] += GetUnif(-fSDDLayer[4],fSDDLayer[4]);
502     fSDDLadderShift2[5] += GetUnif(-fSDDLayer[5],fSDDLayer[5]);
503
504 }
505
506 //_______________________________________________________________________________________
507 void AliITSMisAligner::SetSSDMisAlignment() 
508 {
509     // Set misalignment for SSD alignable volumes for the standar scenarios (zero, residual, full)
510     // To make custom misalignments set directly the misalignments at each level (methods "SetSSD*Pars")
511     //
512     if(TString(GetMisalType())=="ideal"){
513
514         // zero misalignment at the level of SSD barrel
515         SetSSDBarrelPars(0.,0.,0.,0.,0.,0.);
516         // zero misalignment at the level of SSD ladders
517         SetSSDLadderSigmas(0.,0.,0.,0.,0.,0.);
518         // zero misalignment at the level of SSD modules
519         SetSSDModuleSigmas(0.,0.,0.,0.,0.,0.);
520
521     }else if(TString(GetMisalType())=="residual"){
522
523         // zero misalignment at the level of SSD barrel
524         SetSSDBarrelPars(0.,0.,0.,0.,0.,0.);
525         // misalignment at the level of SSD ladders (source: M. Van Leeuwen)
526         // values set so that overall maximum displacement (combined effect of shift and rotation
527         // of the ladder) for any point of the ladder cannot exceed 10um in x, 100 um in y, 50um in z
528         SetSSDLadderSigmas( 0.0005, // 5 microns
529                 0.0033, // 33 microns
530                 0.0050, // 50 microns
531                 0.000067*kRadToDeg, // 0.067 mrads
532                 0.00001*kRadToDeg, // 0.01 mrads
533                 0.001*kRadToDeg); // 1 mrad
534         fUnifSSDLadder=kTRUE;
535
536         // misalignment at the level of SSD modules (source: M. Van Leeuwen)
537         // values set so that overall maximum displacement (combined effect of shift and rotation
538         // of the ladder) for any point of the module cannot exceed 5um in x, 10 um in y, 5um in z
539         SetSSDModuleSigmas( 0.00025, // 2.5 microns
540                 0.00034, // 3.4 microns
541                 0.0005, // 5 microns
542                 0.00017*kRadToDeg, // 0.17 mrads
543                 0.000125*kRadToDeg, // 0.125 mrads
544                 0.0001*kRadToDeg); // 0.1 mrads
545         fUnifSSDModule=kTRUE;
546
547     }else if(TString(GetMisalType())=="full"){
548         // misalignment at the level of SSD layers (source: B. Giraudo)
549         SetSSDBarrelPars( GetUnif(-0.0020,0.0020), // 20 micron
550                 GetUnif(-0.0020,0.0020), // 20 micron
551                 GetUnif(-0.0020,0.0020), // 20 micron
552                 GetUnif(-0.0020/90.*kRadToDeg,0.0020), // so as to have 20 micron difference at the two extremes
553                 GetUnif(-0.0020/90.*kRadToDeg,0.0020), // so as to have 20 micron difference at the two extremes
554                 GetUnif(-0.0020/40.*kRadToDeg,0.0020));  // so as to have 20 micron difference at the two extremes
555
556         // misalignment at the level of SSD ladders (source: M. Van Leeuwen)
557         // values set so that overall maximum displacement (combined effect of shift and rotation
558         // of the ladder) for any point of the ladder cannot exceed 20um in x, 100 um in y, 50um in z
559         SetSSDLadderSigmas( 0.0010, // 10 microns
560                 0.0033, // 33 microns
561                 0.0050, // 50 microns
562                 0.000067*kRadToDeg, // 0.067 mrads
563                 0.00002*kRadToDeg, // 0.02 mrads
564                 0.001*kRadToDeg); // 1 mrad
565         fUnifSSDLadder=kTRUE;
566
567         // misalignment at the level of SSD modules (source: M. Van Leeuwen)
568         // values set so that overall maximum displacement (combined effect of shift and rotation
569         // of the ladder) for any point of the module cannot exceed 5um in x, 10 um in y, 5um in z
570         SetSSDModuleSigmas( 0.00025, // 2.5 microns
571                 0.00034, // 3.4 microns
572                 0.0005, // 5 microns
573                 0.00017*kRadToDeg, // 0.17 mrads
574                 0.000125*kRadToDeg, // 0.125 mrads
575                 0.0001*kRadToDeg); // 0.1 mrads
576         fUnifSSDModule=kTRUE;
577     }
578
579 }
580
581 //_______________________________________________________________________________________
582 AliCDBMetaData* AliITSMisAligner::GetCDBMetaData() const {
583     // Returns the AliCDBMetaData to be associated with AliCDBEntry which will contain
584     // the array of alignment objects for ITS misalignment
585     // Presently "responsible" and "comment" are filled.
586     //
587     AliCDBMetaData* md = new AliCDBMetaData();
588     md->SetResponsible("A. Dainese, M. Van Leeuwen, R. Grosso");
589
590     if(TString(GetMisalType())=="ideal")
591         md->SetComment(
592                 Form("Alignment objects for ITS ideal misalignment. It includes:"
593                     "\n                                 survey of whole ITS;"
594                     "\n                                 survey of SSD ladders and modules"));
595     if(TString(GetMisalType())=="residual")
596         md->SetComment(
597                 Form("Alignment objects for ITS residual misalignment. It includes:"
598                     "\n                                 survey of whole ITS;"
599                     "\n                                 survey of SSD ladders and modules"));
600     if(TString(GetMisalType())=="full")
601         md->SetComment(
602                 Form("Alignment objects for ITS full misalignment. It includes:"
603                     "\n                                 survey of whole ITS;"
604                     "\n                                 survey of SSD ladders and modules"));
605     return md;
606 }
607
608 //________________________________________________________________________
609 Bool_t AliITSMisAligner::AddAlignObj(char* name,Double_t dx,Double_t dy,Double_t dz,
610         Double_t dpsi,Double_t dtheta,Double_t dphi,const char* distrib) {
611     //
612     // misalignment by symname
613     //
614     Double_t vx=0.,vy=0.,vz=0.,vpsi=0.,vtheta=0.,vphi=0.;
615
616     TString sdistrib(distrib);
617
618     if(sdistrib==TString("gaussian")) {
619         vx = AliMathBase::TruncatedGaus(0.,dx/3.,dx); // mean, sigma, max absolute value 
620         vy = AliMathBase::TruncatedGaus(0.,dy/3.,dy);
621         vz = AliMathBase::TruncatedGaus(0.,dz/3.,dz);
622         vpsi   = AliMathBase::TruncatedGaus(0.,dpsi/3.,  dpsi );
623         vtheta = AliMathBase::TruncatedGaus(0.,dtheta/3.,dtheta);
624         vphi   = AliMathBase::TruncatedGaus(0.,dphi/3.,  dphi);
625     }else if(sdistrib==TString("uniform")){ 
626         vx = fRnd.Uniform(-dx,dx);
627         vy = fRnd.Uniform(-dy,dy);
628         vz = fRnd.Uniform(-dz,dz);
629         vpsi = fRnd.Uniform(-dpsi,dpsi);
630         vtheta = fRnd.Uniform(-dtheta,dtheta);
631         vphi = fRnd.Uniform(-dphi,dphi);
632     }else if(sdistrib==TString("fixed")){
633         vx=dx;
634         vy=dy;
635         vz=dz;
636         vpsi=dpsi;
637         vtheta=dtheta;
638         vphi=dphi;
639     }else{
640         AliFatal(Form("Invalid string \"%s\" specifying the misalignment type for the volume \"%s\""));
641     }
642
643     new((*fAlignObjArray)[fInd]) AliAlignObjParams(name,0,vx,vy,vz,vpsi,vtheta,vphi,kFALSE);
644
645     AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlignObjArray->UncheckedAt(fInd);
646     itsalobj->ApplyToGeometry();
647
648     fInd++;
649
650     return kTRUE;
651 }
652
653
654 //________________________________________________________________________
655 Bool_t AliITSMisAligner::AddAlignObj(Int_t lay,Double_t dx,Double_t dy,Double_t dz,
656         Double_t dpsi,Double_t dtheta,Double_t dphi,Bool_t unif) {
657     //
658     // misalignment at the level of sensitive alignable volumes (SPD ladders/ SDD,SSD modules)
659     // done for all ladders/modules of the given layer
660     //
661     lay+=1; // layers are numbered from 1 to 6 in AliGeomManager
662
663     printf("LAYER %d  MODULES %d\n",lay,AliGeomManager::LayerSize(lay));
664
665     for (Int_t iModule = 0; iModule < AliGeomManager::LayerSize(lay); iModule++) {
666
667         Double_t vx,vy,vz,vpsi,vtheta,vphi;
668
669         if(!unif) {
670             vx = AliMathBase::TruncatedGaus(0.,dx/3.,dx); // mean, sigma, max absolute value 
671             vy = AliMathBase::TruncatedGaus(0.,dy/3.,dy);
672             vz = AliMathBase::TruncatedGaus(0.,dz/3.,dz);
673             vpsi = AliMathBase::TruncatedGaus(0.,dpsi/3.,dpsi);
674             vtheta = AliMathBase::TruncatedGaus(0.,dtheta/3.,dtheta);
675             vphi = AliMathBase::TruncatedGaus(0.,dphi/3.,dphi);
676         } else {
677             vx = fRnd.Uniform(-dx,dx);
678             vy = fRnd.Uniform(-dy,dy);
679             vz = fRnd.Uniform(-dz,dz);
680             vpsi = fRnd.Uniform(-dpsi,dpsi);
681             vtheta = fRnd.Uniform(-dtheta,dtheta);
682             vphi = fRnd.Uniform(-dphi,dphi);
683         }
684
685         UShort_t volid = AliGeomManager::LayerToVolUID(lay,iModule);
686         const char *symname = AliGeomManager::SymName(volid);
687
688         new((*fAlignObjArray)[fInd]) AliAlignObjParams(symname,volid,vx,vy,vz,vpsi,vtheta,vphi,kFALSE);
689         fInd++; 
690     }
691
692     return kTRUE;
693 }
694
695 //________________________________________________________________________
696 Bool_t AliITSMisAligner::AddAlignObj(Int_t lay,Int_t ladd,Double_t dx,Double_t dy,Double_t dz,
697         Double_t dpsi,Double_t dtheta,Double_t dphi,
698         Double_t xShift,Double_t yShift,Double_t zShift,
699         Double_t psiShift,Double_t thetaShift,Double_t phiShift,
700         Bool_t unif) {
701     //
702     // misalignment at the level of half-staves/ladders (ladd=-1 means that all ladders are scanned)
703     //
704     Double_t vx,vy,vz,vpsi,vtheta,vphi;
705     Double_t tr[3],rot[3];  
706
707     Int_t laddMin = ladd;
708     Int_t laddMax = laddMin+1;
709     if (ladd<0) {
710         laddMin = 0;
711         laddMax = fgkNLadders[lay];
712     }
713
714     for (Int_t iLadd=laddMin; iLadd<laddMax; iLadd++) {
715
716         Int_t nHS = 1; 
717         if (lay<2) nHS = 2;
718         for (Int_t iHalfStave=0; iHalfStave<nHS; iHalfStave++) {
719
720             if(!unif) {
721                 vx = AliMathBase::TruncatedGaus(0.,dx/3.,dx); // mean, sigma, max absolute value 
722                 vy = AliMathBase::TruncatedGaus(0.,dy/3.,dy);
723                 vz = AliMathBase::TruncatedGaus(0.,dz/3.,dz);
724                 vpsi = AliMathBase::TruncatedGaus(0.,dpsi/3.,dpsi);
725                 vtheta = AliMathBase::TruncatedGaus(0.,dtheta/3.,dtheta);
726                 vphi = AliMathBase::TruncatedGaus(0.,dphi/3.,dphi);
727             } else {
728                 vx = fRnd.Uniform(-dx,dx);
729                 vy = fRnd.Uniform(-dy,dy);
730                 vz = fRnd.Uniform(-dz,dz);
731                 vpsi = fRnd.Uniform(-dpsi,dpsi);
732                 vtheta = fRnd.Uniform(-dtheta,dtheta);
733                 vphi = fRnd.Uniform(-dphi,dphi);
734             }
735
736             TString name(GetHalfStaveLadderSymbName(lay,iLadd,iHalfStave));
737
738             // first apply half-stave / ladder level misalignment
739             AliAlignObjParams aaop(name.Data(),0,vx,vy,vz,vpsi,vtheta,vphi,kFALSE); // set them as local
740             aaop.GetPars(tr,rot); // global
741
742             // then, apply layer-level misalignment (only for SDD and SSD)
743             if(lay>1) {
744                 tr[0] += xShift;
745                 tr[1] += yShift;
746                 tr[2] += zShift;
747                 rot[0] += psiShift;
748                 rot[1] += thetaShift;
749                 rot[2] += phiShift;
750             }
751             new((*fAlignObjArray)[fInd]) AliAlignObjParams(name.Data(),0,tr[0],tr[1],tr[2],rot[0],rot[1],rot[2],kTRUE); // set them as global
752
753             AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlignObjArray->UncheckedAt(fInd);
754             itsalobj->ApplyToGeometry();
755             fInd++;
756         }
757     }
758
759     return kTRUE;
760 }
761
762
763 //________________________________________________________________________
764 Bool_t AliITSMisAligner::AddSectorAlignObj(Int_t sectMin,Int_t sectMax,
765         Double_t dx,Double_t dy,Double_t dz,
766         Double_t dpsi,Double_t dtheta,Double_t dphi,
767         Double_t xShift,Double_t yShift,Double_t zShift,
768         Double_t psiShift,Double_t thetaShift,Double_t phiShift,Bool_t unif) {
769     //
770     // misalignment at the level of SPD sectors and half-barrels
771     // 
772
773     if ((sectMin<1) || (sectMax>10)) return kFALSE;
774     Double_t vx,vy,vz,vpsi,vtheta,vphi;
775     Double_t tr[3],rot[3];  
776
777     for (Int_t iSect = sectMin-1; iSect<sectMax; iSect++) {
778
779         // first, apply sector level misalignment    
780         if(!unif) {
781             vx = AliMathBase::TruncatedGaus(0.,dx/3.,dx); // mean, sigma, max absolute value 
782             vy = AliMathBase::TruncatedGaus(0.,dy/3.,dy);
783             vz = AliMathBase::TruncatedGaus(0.,dz/3.,dz);
784             vpsi = AliMathBase::TruncatedGaus(0.,dpsi/3.,dpsi);
785             vtheta = AliMathBase::TruncatedGaus(0.,dtheta/3.,dtheta);
786             vphi = AliMathBase::TruncatedGaus(0.,dphi/3.,dphi);
787         } else {
788             vx = fRnd.Uniform(-dx,dx);
789             vy = fRnd.Uniform(-dy,dy);
790             vz = fRnd.Uniform(-dz,dz);
791             vpsi = fRnd.Uniform(-dpsi,dpsi);
792             vtheta = fRnd.Uniform(-dtheta,dtheta);
793             vphi = fRnd.Uniform(-dphi,dphi);
794         }
795
796         TString name(GetSymbName(0));
797         name += fStrSector;
798         name += iSect;
799
800
801         AliAlignObjParams aaop(name.Data(),0,vx,vy,vz,vpsi,vtheta,vphi,kFALSE); // set them as local
802         aaop.GetPars(tr,rot); // global
803
804         // then, apply half-barrel level misalignment
805         tr[0] += xShift;
806         tr[1] += yShift;
807         tr[2] += zShift;
808         rot[0] += psiShift;
809         rot[1] += thetaShift;
810         rot[2] += phiShift;
811
812         new((*fAlignObjArray)[fInd]) AliAlignObjParams(name.Data(),0,tr[0],tr[1],tr[2],rot[0],rot[1],rot[2],kTRUE); // set them as global
813
814         AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlignObjArray->UncheckedAt(fInd);
815         itsalobj->ApplyToGeometry();
816         fInd++;
817     }
818     return kTRUE;
819 }
820
821 //________________________________________________________________________
822 const char* AliITSMisAligner::GetSymbName(Int_t layer) const {
823     //
824     // be careful : SPD0 and SPD1 are not physically separated 
825     //
826     TString name;
827     switch (layer) {
828         case 0:
829         case 1: name = fStrSPD; name += layer; break;
830         case 2:
831         case 3: name = fStrSDD; name += layer; break;
832         case 4:
833         case 5: name = fStrSSD; name += layer; break;
834         default: AliFatal("Wrong layer index");
835     }
836     return name.Data();
837 }
838
839 //________________________________________________________________________
840 const char* AliITSMisAligner::GetSymbName(Int_t layer, Int_t ladder, Int_t det) const {
841     //
842     // symname from layer, ladder, detector
843     //
844     TString symname(GetHalfStaveLadderSymbName(layer,ladder,det));
845     if(layer<=2){
846         symname+="Ladder";
847     }else if(layer<=6){
848         symname+="Sensor";
849     }else{
850         AliError("Invalid layer!");
851         return 0;
852     }
853     symname+=det;
854     return symname.Data();
855 }
856
857 //________________________________________________________________________
858 const char* AliITSMisAligner::GetSymbName(Int_t layer,Int_t ladd) const {
859     //
860     // Get logical names at the level of staves / ladders
861     //
862     TString name(GetSymbName(layer));
863     if (layer==0) { // SPD1
864
865         int sector = ladd/2;
866         name += fStrSector;
867         name += sector;
868         int stave = ladd-sector*2;
869         name += fStrStave;
870         name += stave;
871     }
872     else if (layer==1) { // SPD2
873
874         int sector = ladd/4;
875         name += fStrSector;
876         name += sector;
877         int stave = ladd-sector*4;
878         name += fStrStave;
879         name += stave;
880     }
881     else if (layer>=2 && layer<=5) { // SDD and SSD
882         name += fStrLadder;
883         name += ladd;
884     }
885     else {
886         AliFatal("Wrong layer index");
887     }
888     return name.Data();
889 }
890
891 //________________________________________________________________________
892 const char* AliITSMisAligner::GetHalfStaveLadderSymbName(Int_t layer,Int_t ladd,Int_t halfStave) const {
893     //
894     // Get logical names at the level of half-staves (SPD) or ladders (SDD and SSD)
895     //
896     TString name(GetSymbName(layer));
897     if (layer==0) { // SPD1
898
899         int sector = ladd/2;
900         name += fStrSector;
901         name += sector;
902         int stave = ladd-sector*2;
903         name += fStrStave;
904         name += stave;
905         name += fStrHalfStave;
906         name += halfStave;
907     }
908     else if (layer==1) { // SPD2
909
910         int sector = ladd/4;
911         name += fStrSector;
912         name += sector;
913         int stave = ladd-sector*4;
914         name += fStrStave;
915         name += stave;
916         name += fStrHalfStave;
917         name += halfStave;
918     }
919     else if (layer>=2 && layer<=5) { // SDD and SSD
920         name += fStrLadder;
921         name += ladd;
922     } 
923     else {
924         AliFatal("Wrong layer index");
925     }
926     return name.Data();
927 }
928
929 //________________________________________________________________________
930 const char* AliITSMisAligner::GetParentSymName(const char* symname) {
931     //
932     // symnane of parent volume
933     //
934     TString parent(symname);
935     // Give the symname of 
936     if(parent.BeginsWith('/')) parent.Remove(TString::kLeading,'/');
937     if(parent.EndsWith("/")) parent.Remove(TString::kTrailing,'/');
938
939     if(!parent.CountChar('/')) AliErrorClass("Not a valid symbolic name");
940
941     Int_t layer,level;
942     GetLayerAndLevel(symname,layer,level);
943     if(level==1) return "ITS";
944
945     parent.Remove(parent.Last('/'));
946
947     if((layer==0 || layer==1) && level==2){
948         parent.Remove(parent.Last('/'));
949         parent[7]='0';
950     }
951
952     return parent.Data(); 
953 }
954
955 //________________________________________________________________________
956 Bool_t AliITSMisAligner::GetLayerAndLevel(const char* symname, Int_t &layer, Int_t &level) {
957     //
958     // given the symbolic name set layer and level
959     //
960     const char* basename[6] = {"ITS/SPD0/Sector","ITS/SPD1/Sector","ITS/SDD2/Ladder","ITS/SDD3/Ladder","ITS/SSD4/Ladder","ITS/SSD5/Ladder"};
961     TString strSym(symname);
962     if(strSym=="ITS"){
963         level=0;
964         layer=-1;
965         return kTRUE;
966     }
967     Int_t i;
968     for(i=0; i<6; i++){
969         if(strSym.BeginsWith(basename[i])) break;
970     }
971
972     if(i>=6){
973         AliErrorClass(Form("%s is not a valid symbolic name for an ITS alignable volume",strSym.Data()));
974         return kFALSE;
975     }
976
977     layer=i;
978     //The part above could be replaced by just
979     // TString seventh = strSym[7];
980     // layer = seventh.Atoi();
981     // if we don't need to check the validity of the symname
982
983     level=1;
984     switch(layer){
985         case 0:
986         case 1:
987             if(strSym.Contains("Stave")) level=2;
988             if(strSym.Contains("Ladder")) level=3;
989             break;
990         case 2:
991         case 3:
992         case 4:
993         case 5:
994             if(strSym.Contains("Sensor")) level=2;
995     }
996
997     return kTRUE;
998 }
999
1000 //________________________________________________________________________
1001 Int_t AliITSMisAligner::GetNSisters(const char* symname) {
1002     //
1003     // number of volumes on same level
1004     //
1005     Int_t layer,level;
1006     if(!GetLayerAndLevel(symname,layer,level)) return -1;
1007     if(level==0) return -1;
1008     if(level==1) return GetNLadders(layer);
1009     if(level==2) return GetNDetectors(layer);
1010     AliErrorClass(Form("Invalid layer and level"));
1011     return -1;
1012 }
1013
1014 //________________________________________________________________________
1015 Int_t AliITSMisAligner::GetNDaughters(const char* symname) {
1016     //
1017     // number of daughter volumes
1018     // 
1019     Int_t layer,level;
1020     if(!GetLayerAndLevel(symname,layer,level)) return -1;
1021     if(level==0) {
1022         Int_t nLadders = 0;
1023         for(Int_t lay=0; lay<6; lay++) nLadders += GetNLadders(lay);
1024         return nLadders;
1025     }
1026     if(level==1) return GetNDetectors(layer);
1027     if(level==2){
1028         AliWarningClass(Form("Volume %s is a sensitive volume and has no alignable dauthers",symname));
1029         return -1;
1030     }
1031     AliErrorClass(Form("Invalid layer and level"));
1032     return -1;
1033 }
1034
1035 /*
1036 //________________________________________________________________________
1037 TString AliITSMisAligner::GetSymbName(Int_t layer,Int_t ladd,Int_t mod) const {
1038
1039 // Get logical names at the level of SPD ladders / SDD and SSD modules
1040
1041 Int_t halfStave = mod/2;
1042 TString name = GetHalfStaveLadderSymbName(layer,ladd,halfStave);
1043
1044 if (layer<2) { // SPD
1045 name += fStrLadder;
1046 name += mod;
1047
1048 else if (layer>=2 && layer<=5) { // SDD and SSD
1049 name += fStrSensor;
1050 name += mod;
1051 }
1052 else {
1053 AliFatal("Wrong layer index");
1054 }
1055 return name;
1056 }
1057 */