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