]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ITS/AliITSMisAligner.cxx
Adding some further mother volumes to speed-up the overlap checking and particle...
[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):
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//________________________________________________________________________
123AliITSMisAligner &AliITSMisAligner::operator= (const AliITSMisAligner &mAligner)
124{
125 //
126 // assignment operator
127 //
f76750d6 128 fRnd = mAligner.fRnd;
edccc22d 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//_______________________________________________________________________________________
150TClonesArray* 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 }
edccc22d 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
f76750d6 191 // all SSD ladders as from survey, + shift and smearing in the "residual" and "full" case
edccc22d 192 for(Int_t ii=0; ii<surveyArray->GetEntriesFast(); ii++)
193 {
194 AliAlignObjParams* aop = dynamic_cast<AliAlignObjParams*> (surveyArray->UncheckedAt(ii));
edccc22d 195 TString sName(aop->GetSymName());
196
f76750d6 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
edccc22d 214 new((*fAlignObjArray)[fInd++]) AliAlignObjParams(*aop);
f76750d6 215 aop->ApplyToGeometry(); // this we need to correctly build objects for SSD ladders below
edccc22d 216 }
edccc22d 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 {
f76750d6 235 if(!(TString(GetMisalType())=="ideal"))
236 SmearAlignObj(*aop,fSSDModule[0],fSSDModule[1],fSSDModule[2],fSSDModule[3],fSSDModule[4],fSSDModule[5]);
edccc22d 237 new((*fAlignObjArray)[fInd++]) AliAlignObjParams(*aop);
238 }
239 }
240
241 return fAlignObjArray;
242}
243
244//_______________________________________________________________________________________
245void 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//_______________________________________________________________________________________
256void 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//_______________________________________________________________________________________
273void 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//_______________________________________________________________________________________
300void 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.);
f76750d6 317
edccc22d 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;
f76750d6 335
edccc22d 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;
f76750d6 379
edccc22d 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;
f76750d6 388
edccc22d 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//_______________________________________________________________________________________
408void 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.);
f76750d6 424
edccc22d 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
f76750d6 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]);
edccc22d 503
504}
f76750d6 505
edccc22d 506//_______________________________________________________________________________________
507void 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.);
f76750d6 520
edccc22d 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
f76750d6 555
edccc22d 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
edccc22d 579}
580
581//_______________________________________________________________________________________
582AliCDBMetaData* 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 //
f76750d6 587 AliCDBMetaData* md = new AliCDBMetaData();
588 md->SetResponsible("A. Dainese, M. Van Leeuwen, R. Grosso");
edccc22d 589
f76750d6 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;
edccc22d 606}
607
edccc22d 608//________________________________________________________________________
f76750d6 609Bool_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.;
edccc22d 615
f76750d6 616 TString sdistrib(distrib);
edccc22d 617
f76750d6 618 if(sdistrib==TString("gaussian")) {
edccc22d 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);
f76750d6 622 vpsi = AliMathBase::TruncatedGaus(0.,dpsi/3., dpsi );
edccc22d 623 vtheta = AliMathBase::TruncatedGaus(0.,dtheta/3.,dtheta);
f76750d6 624 vphi = AliMathBase::TruncatedGaus(0.,dphi/3., dphi);
625 }else if(sdistrib==TString("uniform")){
edccc22d 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);
f76750d6 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 }
edccc22d 642
f76750d6 643 new((*fAlignObjArray)[fInd]) AliAlignObjParams(name,0,vx,vy,vz,vpsi,vtheta,vphi,kFALSE);
edccc22d 644
f76750d6 645 AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlignObjArray->UncheckedAt(fInd);
646 itsalobj->ApplyToGeometry();
edccc22d 647
f76750d6 648 fInd++;
649
650 return kTRUE;
651}
652
653
654//________________________________________________________________________
655Bool_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 }
edccc22d 684
f76750d6 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++;
edccc22d 690 }
f76750d6 691
692 return kTRUE;
693}
694
695//________________________________________________________________________
696Bool_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;
edccc22d 760}
761
762
763//________________________________________________________________________
764Bool_t AliITSMisAligner::AddSectorAlignObj(Int_t sectMin,Int_t sectMax,
f76750d6 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 //
edccc22d 772
f76750d6 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 }
edccc22d 795
f76750d6 796 TString name(GetSymbName(0));
797 name += fStrSector;
798 name += iSect;
edccc22d 799
edccc22d 800
f76750d6 801 AliAlignObjParams aaop(name.Data(),0,vx,vy,vz,vpsi,vtheta,vphi,kFALSE); // set them as local
802 aaop.GetPars(tr,rot); // global
edccc22d 803
f76750d6 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;
edccc22d 811
f76750d6 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;
edccc22d 819}
820
821//________________________________________________________________________
822const char* AliITSMisAligner::GetSymbName(Int_t layer) const {
f76750d6 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();
edccc22d 837}
838
839//________________________________________________________________________
840const char* AliITSMisAligner::GetSymbName(Int_t layer, Int_t ladder, Int_t det) const {
f76750d6 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();
edccc22d 855}
856
857//________________________________________________________________________
858const char* AliITSMisAligner::GetSymbName(Int_t layer,Int_t ladd) const {
f76750d6 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();
edccc22d 889}
890
891//________________________________________________________________________
892const char* AliITSMisAligner::GetHalfStaveLadderSymbName(Int_t layer,Int_t ladd,Int_t halfStave) const {
f76750d6 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();
edccc22d 927}
928
929//________________________________________________________________________
930const char* AliITSMisAligner::GetParentSymName(const char* symname) {
f76750d6 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";
edccc22d 944
edccc22d 945 parent.Remove(parent.Last('/'));
f76750d6 946
947 if((layer==0 || layer==1) && level==2){
948 parent.Remove(parent.Last('/'));
949 parent[7]='0';
950 }
951
952 return parent.Data();
edccc22d 953}
954
955//________________________________________________________________________
956Bool_t AliITSMisAligner::GetLayerAndLevel(const char* symname, Int_t &layer, Int_t &level) {
f76750d6 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
edccc22d 997 return kTRUE;
edccc22d 998}
999
1000//________________________________________________________________________
1001Int_t AliITSMisAligner::GetNSisters(const char* symname) {
f76750d6 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;
edccc22d 1012}
1013
1014//________________________________________________________________________
1015Int_t AliITSMisAligner::GetNDaughters(const char* symname) {
f76750d6 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"));
edccc22d 1032 return -1;
edccc22d 1033}
1034
1035/*
1036//________________________________________________________________________
1037TString AliITSMisAligner::GetSymbName(Int_t layer,Int_t ladd,Int_t mod) const {
1038
f76750d6 1039// Get logical names at the level of SPD ladders / SDD and SSD modules
1040
1041Int_t halfStave = mod/2;
1042TString name = GetHalfStaveLadderSymbName(layer,ladd,halfStave);
1043
1044if (layer<2) { // SPD
1045name += fStrLadder;
1046name += mod;
1047}
1048else if (layer>=2 && layer<=5) { // SDD and SSD
1049name += fStrSensor;
1050name += mod;
1051}
1052else {
1053AliFatal("Wrong layer index");
1054}
1055return name;
edccc22d 1056}
1057*/