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