1 /**************************************************************************
2 * Copyright(c) 2007-2010, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 //========================================================================
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.
24 // Main author: L. Gaudichet
25 // Contact: andrea.dainese@lnl.infn.it
27 //========================================================================
29 #include <TClonesArray.h>
32 #include <TGeoManager.h>
34 #include "AliAlignObjParams.h"
35 #include "AliITSMisAligner.h"
36 #include "AliITSSurveyToAlign.h"
37 #include "AliMathBase.h"
39 ClassImp(AliITSMisAligner)
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};
44 const Double_t kRadToDeg = 180./TMath::Pi();
46 //________________________________________________________________________
47 AliITSMisAligner::AliITSMisAligner():
56 fStrHalfStave("/HalfStave"),
57 fStrLadder("/Ladder"),
58 fStrSector("/Sector"),
59 fStrSensor("/Sensor"),
60 fUnifSPDSector(kFALSE),
62 fUnifSDDLadder(kFALSE),
63 fUnifSSDLadder(kFALSE),
64 fUnifSPDLadder(kFALSE),
65 fUnifSDDModule(kFALSE),
66 fUnifSSDModule(kFALSE)
71 fRnd.SetSeed(38217945);
72 fAlignObjArray = new TClonesArray("AliAlignObjParams",4000);
73 for(Int_t ii=0; ii<6; ii++)
89 fSPDLadderShiftT[ii]=0.;
90 fSPDLadderShiftB[ii]=0.;
91 fSDDLadderShift1[ii]=0.;
92 fSDDLadderShift2[ii]=0.;
93 fSSDLadderShift1[ii]=0.;
94 fSSDLadderShift2[ii]=0.;
98 //________________________________________________________________________
99 AliITSMisAligner::AliITSMisAligner(const AliITSMisAligner &mAligner):
102 fAlignObjArray(mAligner.fAlignObjArray),
107 fStrHalfStave("/HalfStave"),
108 fStrLadder("/Ladder"),
109 fStrSector("/Sector"),
110 fStrSensor("/Sensor"),
111 fUnifSPDSector(kFALSE),
113 fUnifSDDLadder(kFALSE),
114 fUnifSSDLadder(kFALSE),
115 fUnifSPDLadder(kFALSE),
116 fUnifSDDModule(kFALSE),
117 fUnifSSDModule(kFALSE)
124 //________________________________________________________________________
125 AliITSMisAligner &AliITSMisAligner::operator= (const AliITSMisAligner &mAligner)
128 // assignment operator
130 fRnd = mAligner.fRnd,
132 fAlignObjArray = mAligner.fAlignObjArray;
136 fStrStave = "/Stave";
137 fStrHalfStave = "/HalfStave";
138 fStrLadder = "/Ladder";
139 fStrSector = "/Sector";
140 fStrSensor = "/Sensor";
141 fUnifSPDSector = mAligner.fUnifSPDSector;
143 fUnifSDDLadder = kFALSE;
144 fUnifSSDLadder = kFALSE;
145 fUnifSPDLadder = kFALSE;
146 fUnifSDDModule = kFALSE;
147 fUnifSSDModule = kFALSE;
151 //_______________________________________________________________________________________
152 TClonesArray* AliITSMisAligner::MakeAlObjsArray() {
153 // Make the array of alignment objects, depending on the misalignment scenario (Zero, Residual, Full)
156 // Setting default values for ideal, residual or full misalignment
157 SetWholeITSMisAlignment();
158 SetSPDMisAlignment();
159 SetSDDMisAlignment();
160 SetSSDMisAlignment();
162 // Get array of alignment objects from survey (based on which we build later the SSD objects)
163 AliITSSurveyToAlign* s2a = new AliITSSurveyToAlign();
165 TClonesArray* surveyArray = dynamic_cast<TClonesArray*> (s2a->GetAlignObjsArray());
167 Printf("SSD survey array was not build! Probably you missed to connect to alien");
170 Printf("survey array contains %d entries", surveyArray->GetEntriesFast());
172 //(AliGeomManager::GetGeometry())->UnlockGeometry();
174 AddAlignObj("ITS",fWholeITS[0],fWholeITS[1],fWholeITS[2],fWholeITS[3],fWholeITS[4],fWholeITS[5],"fixed");
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);
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
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
195 for(Int_t ii=0; ii<surveyArray->GetEntriesFast(); ii++)
197 AliAlignObjParams* aop = dynamic_cast<AliAlignObjParams*> (surveyArray->UncheckedAt(ii));
199 // Printf("Unexpected missing object at %d!", ii);
202 TString sName(aop->GetSymName());
204 // First we shift all SSD ladders by the same quantity to reproduce a barrel shift
205 ShiftAlignObj(*aop,fSSDBarrel[0],fSSDBarrel[1],fSSDBarrel[2],fSSDBarrel[3],fSSDBarrel[4],fSSDBarrel[5]);
206 if(sName.Contains("SSD4") && !sName.Contains("Sensor")){
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 new((*fAlignObjArray)[fInd++]) AliAlignObjParams(*aop);
210 }else if(sName.Contains("SSD5") && !sName.Contains("Sensor")){
211 SmearAlignObj(*aop,fSSDLadder[0],fSSDLadder[1],fSSDLadder[2],fSSDLadder[3],fSSDLadder[4],fSSDLadder[5]);
212 new((*fAlignObjArray)[fInd++]) AliAlignObjParams(*aop);
214 aop->ApplyToGeometry();
217 //=****************************************
218 // misalignment at the level of ladders (SPD)/modules (SDD,SSD) :
219 //=****************************************
220 AddAlignObj(0,fSPDLadder[0],fSPDLadder[1],fSPDLadder[2],fSPDLadder[3],fSPDLadder[4],fSPDLadder[5],fUnifSPDLadder);// all SPD1 ladders
221 AddAlignObj(1,fSPDLadder[0],fSPDLadder[1],fSPDLadder[2],fSPDLadder[3],fSPDLadder[4],fSPDLadder[5],fUnifSPDLadder);// all SPD2 ladders
223 AddAlignObj(2,fSDDModule[0],fSDDModule[1],fSDDModule[2],fSDDModule[3],fSDDModule[4],fSDDModule[5],fUnifSDDModule);// all SDD1 modules
224 AddAlignObj(3,fSDDModule[0],fSDDModule[1],fSDDModule[2],fSDDModule[3],fSDDModule[4],fSDDModule[5],fUnifSDDModule);// all SDD2 modules
227 for(Int_t ii=0; ii<surveyArray->GetEntriesFast(); ii++)
229 AliAlignObjParams* aop = dynamic_cast<AliAlignObjParams*> (surveyArray->UncheckedAt(ii));
230 TString sName(aop->GetSymName());
231 if(sName.Contains("SSD") && sName.Contains("Sensor"))
233 SmearAlignObj(*aop,fSSDModule[0],fSSDModule[1],fSSDModule[2],fSSDModule[3],fSSDModule[4],fSSDModule[5]);
234 new((*fAlignObjArray)[fInd++]) AliAlignObjParams(*aop);
238 return fAlignObjArray;
241 //_______________________________________________________________________________________
242 void AliITSMisAligner::ShiftAlignObj(AliAlignObjParams &alObj, Double_t dx, Double_t dy, Double_t dz, Double_t dpsi, Double_t dtheta, Double_t dphi)
245 // Shift the parameters of the alignment object passed as first argument by the quantities defined by the arguments
247 Double_t shifts[3]; Double_t angles[3];
248 alObj.GetPars(shifts, angles);
249 alObj.SetPars(shifts[0]+dx, shifts[1]+dy, shifts[2]+dz, angles[0]+dpsi, angles[1]+dtheta, angles[2]+dphi);
252 //_______________________________________________________________________________________
253 void AliITSMisAligner::SmearAlignObj(AliAlignObjParams &alObj, Double_t sx, Double_t sy, Double_t sz, Double_t spsi, Double_t stheta, Double_t sphi)
256 // Smear the parameters of the alignment object passed as first argument in the range defined by the subsequent arguments
258 Double_t shifts[3]; Double_t angles[3];
259 alObj.GetLocalPars(shifts, angles);
260 Double_t x = AliMathBase::TruncatedGaus(shifts[0], sx, 3.*sx);
261 Double_t y = AliMathBase::TruncatedGaus(shifts[1], sy, 3.*sy);
262 Double_t z = AliMathBase::TruncatedGaus(shifts[2], sz, 3.*sz);
263 Double_t psi = AliMathBase::TruncatedGaus(angles[0], spsi, 3.*spsi);
264 Double_t theta = AliMathBase::TruncatedGaus(angles[1], stheta, 3.*stheta);
265 Double_t phi = AliMathBase::TruncatedGaus(angles[2], sphi, 3.*sphi);
266 alObj.SetLocalPars(x, y, z, psi, theta, phi);
269 //_______________________________________________________________________________________
270 void AliITSMisAligner::SetWholeITSMisAlignment()
272 // Set misalignment for the whole ITS for the standar scenarios (zero, residual, full)
273 // To make custom misalignments set directly the misalignments at each level (methods "SetS?D*Pars")
275 if(TString(GetMisalType())=="ideal")
277 // overall ITS misalignment according to survey as reported by Werner Riegler (18/07/2008)
278 SetWholeITSPars(-0.12, -0.07, 0.29, 0., 0.03, 0.04);
279 }else if(TString(GetMisalType())=="residual"){
280 // overall ITS misalignment according to survey as reported by Werner Riegler (18/07/2008)
281 // no smearing added (would clash with vertex constraint)
282 SetWholeITSPars(-0.12, -0.07, 0.29, 0., 0.03, 0.04);
283 }else if(TString(GetMisalType())=="full"){
284 // overall ITS misalignment according to survey as reported by Werner Riegler (18/07/2008) plus smearing
285 Double_t sigmatrW = 0.01;
286 Double_t sigmarotW = 0.006;
287 SetWholeITSPars(AliMathBase::TruncatedGaus(-0.12,sigmatrW,3.*sigmatrW),
288 AliMathBase::TruncatedGaus(-0.07,sigmatrW,3.*sigmatrW),
289 AliMathBase::TruncatedGaus(0.29,sigmatrW,3.*sigmatrW),
290 AliMathBase::TruncatedGaus(0.,sigmarotW,3.*sigmarotW),
291 AliMathBase::TruncatedGaus(0.03,sigmarotW,3.*sigmarotW),
292 AliMathBase::TruncatedGaus(0.04,sigmarotW,3.*sigmarotW));
296 //_______________________________________________________________________________________
297 void AliITSMisAligner::SetSPDMisAlignment()
299 // Set misalignment for SPD alignable volumes for the standar scenarios (zero, residual, full)
300 // To make custom misalignments set directly the misalignments at each level (methods "SetSPD*Pars")
302 if(TString(GetMisalType())=="ideal")
304 // misalignment for SPD at all levels equal to zero (identical transformations)
305 SetSPDBarrelSigmas(0., 0., 0., 0., 0., 0.);
306 SetSPDHBSigmas(0., 0., 0., 0., 0., 0.);
307 SetSPDSectorSigmas(0., 0., 0., 0., 0., 0.);
308 SetSPDHSSigmas(0., 0., 0., 0., 0., 0.);
309 SetSPDLadderSigmas(0., 0., 0., 0., 0., 0.);
310 }else if(TString(GetMisalType())=="residual"){
311 // misalignment at the level of SPD barrel and half-barrels left to zero
312 SetSPDBarrelSigmas(0., 0., 0., 0., 0., 0.);
313 SetSPDHBSigmas(0., 0., 0., 0., 0., 0.);
315 // misalignment at the level of SPD sectors (source: A.Pepato)
316 SetSPDSectorSigmas( 0.0050/5., // 50 micron (~tangetial, i.e. rphi)
317 0.0100/5., // 100 micron (~radial)
318 0.0100/5., // 100 micron
319 0.0100/30.*kRadToDeg/5., // so as to have 100 micron difference at the two extremes
320 0.0100/30.*kRadToDeg/5., // so as to have 100 micron difference at the two extremes
321 0.0050/1.5*kRadToDeg/5.); // so as to have 50 micron difference at the two extremes
322 fUnifSPDSector=kFALSE;
324 // misalignment at the level of half-staves (SPD) (source: S.Moretto)
325 SetSPDHSSigmas( 0.0100/4., // 100 micron
326 0.0020/4., // 20 micron
327 0.0020/4., // 20 micron
328 0.0020/7.*kRadToDeg/4., // so as to have 20 micron difference at the two extremes
329 0.0050/7.*kRadToDeg/4., // so as to have 50 micron difference at the two extremes
330 0.0050/0.7*kRadToDeg/4.);// so as to have 50 micron difference at the two extremes
333 // misalignment at the level of ladders (SPD) (source: R.Santoro)
334 SetSPDLadderSigmas( 0.0010/5., // 10 micron
335 0.0050/5., // 50 micron
336 0.0010/5., // 10 micron
337 0.0001*kRadToDeg/5., // 0.1 mrad
338 0.0001*kRadToDeg/5., // 0.1 mrad
339 0.0001*kRadToDeg/5.);// 0.1 mrad
340 fUnifSPDLadder=kFALSE;
342 }else if(TString(GetMisalType())=="full"){
343 // misalignment at the level of SPD barrel (source: A.Pepato)
344 SetSPDBarrelSigmas( 0.1000, // 1 mm (very pessimistic)
345 0.1000, // 1 mm (very pessimistic)
346 0.1000, // 1 mm (very pessimistic)
347 0.0500/30.*kRadToDeg, // so as to have 500 micron difference at the two extremes
348 0.0500/30.*kRadToDeg, // so as to have 500 micron difference at the two extremes
349 0.0500/7.*kRadToDeg); // so as to have 500 micron difference at the two extremes
351 // misalignment at the level of SPD half-barrels (source: A.Pepato)
352 SetSPDHBSigmas( 0.0200, // 200 micron
353 0.0200, // 200 micron
354 0.0200, // 200 micron
355 0.0100/30.*kRadToDeg, // so as to have 100 micron difference at the two extremes
356 0.0100/30.*kRadToDeg, // so as to have 100 micron difference at the two extremes
357 0.0100/7.*kRadToDeg); // so as to have 100 micron difference at the two extremes
359 // misalignment at the level of SPD sectors (source: A.Pepato)
360 SetSPDSectorSigmas( 0.0050, // 50 micron (~tangetial, i.e. rphi)
361 0.0100, // 100 micron (~radial)
362 0.0100, // 100 micron
363 0.0100/30.*kRadToDeg, // so as to have 100 micron difference at the two extremes
364 0.0100/30.*kRadToDeg, // so as to have 100 micron difference at the two extremes
365 0.0050/1.5*kRadToDeg); // so as to have 50 micron difference at the two extremes
366 fUnifSPDSector=kTRUE;
368 // misalignment at the level of half-staves (SPD) (source: S.Moretto)
369 SetSPDHSSigmas( 0.0100, // 100 micron // normal to plane
372 0.0020/7.*kRadToDeg, // so as to have 20 micron difference at the two extremes
373 0.0050/7.*kRadToDeg, // so as to have 50 micron difference at the two extremes
374 0.0050/0.7*kRadToDeg); // so as to have 50 micron difference at the two extremes
377 // misalignment at the level of ladders (SPD) (source: R.Santoro)
378 SetSPDLadderSigmas( 0.0010, // 10 micron
381 0.0001*kRadToDeg, // 0.1 mrad
382 0.0001*kRadToDeg, // 0.1 mrad
383 0.0001*kRadToDeg); // 0.1 mrad
384 fUnifSPDLadder=kTRUE;
387 // misalignment at the level of SPD barrel, half-barrels, and at the level
389 Double_t shBtop[6], shBbot[6]; //top and bottom barrel shifts
390 for(Int_t ii=0; ii<6; ii++){
391 shBtop[ii] = AliMathBase::TruncatedGaus(0.,fSPDBarrel[ii]/3,fSPDBarrel[ii]);
392 shBbot[ii] = shBtop[ii];
395 for(Int_t ii=0; ii<6; ii++){
396 shBtop[ii] += AliMathBase::TruncatedGaus(0.,fSPDHB[ii]/3,fSPDHB[ii]);
397 shBbot[ii] += AliMathBase::TruncatedGaus(0.,fSPDHB[ii]/3,fSPDHB[ii]);
399 SetSPDLadderShiftT(shBtop);
400 SetSPDLadderShiftB(shBbot);
404 //_______________________________________________________________________________________
405 void AliITSMisAligner::SetSDDMisAlignment()
407 // Set misalignment for SDD alignable volumes for the standar scenarios (zero, residual, full)
408 // To make custom misalignments set directly the misalignments at each level (methods "SetSDD*Pars")
410 if(TString(GetMisalType())=="ideal")
412 // misalignment for SDD at all levels equal to zero
413 SetSDDLayerSigmas(0., 0., 0., 0., 0., 0.);
414 SetSDDBarrelSigmas(0., 0., 0., 0., 0., 0.);
415 SetSDDLadderSigmas(0., 0., 0., 0., 0., 0.);
416 SetSDDModuleSigmas(0., 0., 0., 0., 0., 0.);
417 }else if(TString(GetMisalType())=="residual"){
418 // misalignment at the level of SDD and SSD layers(source: B.Giraudo)
419 SetSDDLayerSigmas(0., 0., 0., 0., 0., 0.);
420 SetSDDBarrelSigmas(0., 0., 0., 0., 0., 0.);
422 // misalignment at the level of half-staves (SPD) (source: S.Moretto)
423 SetSDDLadderSigmas( 0.0005, // 5 micron
429 fUnifSDDLadder=kFALSE;
431 // misalignment at the level of SDD modules(source: L.Gaudichet)
432 SetSDDModuleSigmas( 0.0045/5., // 45 micron
433 0.0045/5., // 45 micron
434 0.0105/5., // 105 micron
438 fUnifSDDModule=kFALSE;
440 }else if(TString(GetMisalType())=="full"){
441 // misalignment at the level of SDD layers(source: B.Giraudo)
442 SetSDDBarrelSigmas( 0.0020, // 20 micron
445 0.0020/52.*kRadToDeg, // so as to have 20 micron difference at the two extremes
446 0.0020/52.*kRadToDeg, // so as to have 20 micron difference at the two extremes
447 0.0020/20.*kRadToDeg); // so as to have 20 micron difference at the two extremes
449 SetSDDLayerSigmas( 0.0010, // 10 micron
452 0.0010/52.*kRadToDeg, // so as to have 10 micron difference at the two extremes
453 0.0010/52.*kRadToDeg, // so as to have 10 micron difference at the two extremes
454 0.0010/20.*kRadToDeg); // so as to have 10 micron difference at the two extremes
456 // misalignment at the level of SDD ladders
457 SetSDDLadderSigmas( 0.0005, // 5 micron
463 fUnifSDDLadder=kTRUE;
465 // misalignment at the level of SDD modules (source: L.Gaudichet)
466 SetSDDModuleSigmas( 0.0045, // 45 micron
468 0.0105, // 105 micron
472 fUnifSDDModule=kTRUE;
475 fSDDLadderShift1[0] = GetUnif(-fSDDBarrel[0],fSDDBarrel[0]);
476 fSDDLadderShift1[1] = GetUnif(-fSDDBarrel[1],fSDDBarrel[1]);
477 fSDDLadderShift1[2] = GetUnif(-fSDDBarrel[2],fSDDBarrel[2]);
478 fSDDLadderShift1[3] = GetUnif(-fSDDBarrel[3],fSDDBarrel[3]);
479 fSDDLadderShift1[4] = GetUnif(-fSDDBarrel[4],fSDDBarrel[4]);
480 fSDDLadderShift1[5] = GetUnif(-fSDDBarrel[5],fSDDBarrel[5]);
482 for(Int_t ii=0; ii<6; ii++)
483 fSDDLadderShift2[ii] = fSDDLadderShift1[ii];
486 fSDDLadderShift1[0] += GetUnif(-fSDDLayer[0],fSDDLayer[0]);
487 fSDDLadderShift1[1] += GetUnif(-fSDDLayer[1],fSDDLayer[1]);
488 fSDDLadderShift1[2] += GetUnif(-fSDDLayer[2],fSDDLayer[2]);
489 fSDDLadderShift1[3] += GetUnif(-fSDDLayer[3],fSDDLayer[3]);
490 fSDDLadderShift1[4] += GetUnif(-fSDDLayer[4],fSDDLayer[4]);
491 fSDDLadderShift1[5] += GetUnif(-fSDDLayer[5],fSDDLayer[5]);
494 fSDDLadderShift2[0] += GetUnif(-fSDDLayer[0],fSDDLayer[0]);
495 fSDDLadderShift2[1] += GetUnif(-fSDDLayer[1],fSDDLayer[1]);
496 fSDDLadderShift2[2] += GetUnif(-fSDDLayer[2],fSDDLayer[2]);
497 fSDDLadderShift2[3] += GetUnif(-fSDDLayer[3],fSDDLayer[3]);
498 fSDDLadderShift2[4] += GetUnif(-fSDDLayer[4],fSDDLayer[4]);
499 fSDDLadderShift2[5] += GetUnif(-fSDDLayer[5],fSDDLayer[5]);
503 //_______________________________________________________________________________________
504 void AliITSMisAligner::SetSSDMisAlignment()
506 // Set misalignment for SSD alignable volumes for the standar scenarios (zero, residual, full)
507 // To make custom misalignments set directly the misalignments at each level (methods "SetSSD*Pars")
509 if(TString(GetMisalType())=="ideal"){
511 // zero misalignment at the level of SSD barrel
512 SetSSDBarrelPars(0.,0.,0.,0.,0.,0.);
513 // zero misalignment at the level of SSD ladders
514 SetSSDLadderSigmas(0.,0.,0.,0.,0.,0.);
515 // zero misalignment at the level of SSD modules
516 SetSSDModuleSigmas(0.,0.,0.,0.,0.,0.);
518 }else if(TString(GetMisalType())=="residual"){
520 // zero misalignment at the level of SSD barrel
521 SetSSDBarrelPars(0.,0.,0.,0.,0.,0.);
522 // misalignment at the level of SSD ladders (source: M. Van Leeuwen)
523 // values set so that overall maximum displacement (combined effect of shift and rotation
524 // of the ladder) for any point of the ladder cannot exceed 10um in x, 100 um in y, 50um in z
525 SetSSDLadderSigmas( 0.0005, // 5 microns
526 0.0033, // 33 microns
527 0.0050, // 50 microns
528 0.000067*kRadToDeg, // 0.067 mrads
529 0.00001*kRadToDeg, // 0.01 mrads
530 0.001*kRadToDeg); // 1 mrad
531 fUnifSSDLadder=kTRUE;
533 // misalignment at the level of SSD modules (source: M. Van Leeuwen)
534 // values set so that overall maximum displacement (combined effect of shift and rotation
535 // of the ladder) for any point of the module cannot exceed 5um in x, 10 um in y, 5um in z
536 SetSSDModuleSigmas( 0.00025, // 2.5 microns
537 0.00034, // 3.4 microns
539 0.00017*kRadToDeg, // 0.17 mrads
540 0.000125*kRadToDeg, // 0.125 mrads
541 0.0001*kRadToDeg); // 0.1 mrads
542 fUnifSSDModule=kTRUE;
544 }else if(TString(GetMisalType())=="full"){
545 // misalignment at the level of SSD layers (source: B. Giraudo)
546 SetSSDBarrelPars( GetUnif(-0.0020,0.0020), // 20 micron
547 GetUnif(-0.0020,0.0020), // 20 micron
548 GetUnif(-0.0020,0.0020), // 20 micron
549 GetUnif(-0.0020/90.*kRadToDeg,0.0020), // so as to have 20 micron difference at the two extremes
550 GetUnif(-0.0020/90.*kRadToDeg,0.0020), // so as to have 20 micron difference at the two extremes
551 GetUnif(-0.0020/40.*kRadToDeg,0.0020)); // so as to have 20 micron difference at the two extremes
553 // misalignment at the level of SSD ladders (source: M. Van Leeuwen)
554 // values set so that overall maximum displacement (combined effect of shift and rotation
555 // of the ladder) for any point of the ladder cannot exceed 20um in x, 100 um in y, 50um in z
556 SetSSDLadderSigmas( 0.0010, // 10 microns
557 0.0033, // 33 microns
558 0.0050, // 50 microns
559 0.000067*kRadToDeg, // 0.067 mrads
560 0.00002*kRadToDeg, // 0.02 mrads
561 0.001*kRadToDeg); // 1 mrad
562 fUnifSSDLadder=kTRUE;
564 // misalignment at the level of SSD modules (source: M. Van Leeuwen)
565 // values set so that overall maximum displacement (combined effect of shift and rotation
566 // of the ladder) for any point of the module cannot exceed 5um in x, 10 um in y, 5um in z
567 SetSSDModuleSigmas( 0.00025, // 2.5 microns
568 0.00034, // 3.4 microns
570 0.00017*kRadToDeg, // 0.17 mrads
571 0.000125*kRadToDeg, // 0.125 mrads
572 0.0001*kRadToDeg); // 0.1 mrads
573 fUnifSSDModule=kTRUE;
577 fSSDLadderShift1[0] = GetUnif(-fSSDBarrel[0],fSSDBarrel[0]);
578 fSSDLadderShift1[1] = GetUnif(-fSSDBarrel[1],fSSDBarrel[1]);
579 fSSDLadderShift1[2] = GetUnif(-fSSDBarrel[2],fSSDBarrel[2]);
580 fSSDLadderShift1[3] = GetUnif(-fSSDBarrel[3],fSSDBarrel[3]);
581 fSSDLadderShift1[4] = GetUnif(-fSSDBarrel[4],fSSDBarrel[4]);
582 fSSDLadderShift1[5] = GetUnif(-fSSDBarrel[5],fSSDBarrel[5]);
585 for(Int_t ii=0; ii<6; ii++)
586 fSSDLadderShift2[ii] = fSSDLadderShift1[ii];
589 fSSDLadderShift1[0] += GetUnif(-fSSDLayer[0],fSSDLayer[0]);
590 fSSDLadderShift1[1] += GetUnif(-fSSDLayer[1],fSSDLayer[1]);
591 fSSDLadderShift1[2] += GetUnif(-fSSDLayer[2],fSSDLayer[2]);
592 fSSDLadderShift1[3] += GetUnif(-fSSDLayer[3],fSSDLayer[3]);
593 fSSDLadderShift1[4] += GetUnif(-fSSDLayer[4],fSSDLayer[4]);
594 fSSDLadderShift1[5] += GetUnif(-fSSDLayer[5],fSSDLayer[5]);
597 fSSDLadderShift2[0] += GetUnif(-fSSDLayer[0],fSSDLayer[0]);
598 fSSDLadderShift2[1] += GetUnif(-fSSDLayer[1],fSSDLayer[1]);
599 fSSDLadderShift2[2] += GetUnif(-fSSDLayer[2],fSSDLayer[2]);
600 fSSDLadderShift2[3] += GetUnif(-fSSDLayer[3],fSSDLayer[3]);
601 fSSDLadderShift2[4] += GetUnif(-fSSDLayer[4],fSSDLayer[4]);
602 fSSDLadderShift2[5] += GetUnif(-fSSDLayer[5],fSSDLayer[5]);
607 //_______________________________________________________________________________________
608 AliCDBMetaData* AliITSMisAligner::GetCDBMetaData() const {
609 // Returns the AliCDBMetaData to be associated with AliCDBEntry which will contain
610 // the array of alignment objects for ITS misalignment
611 // Presently "responsible" and "comment" are filled.
613 AliCDBMetaData* md = new AliCDBMetaData();
614 md->SetResponsible("Andrea Dainese");
616 if(TString(GetMisalType())=="ideal")
617 md->SetComment("Alignment objects for ITS ideal misalignment");
618 if(TString(GetMisalType())=="residual")
619 md->SetComment("Alignment objects for ITS residual misalignment");
620 if(TString(GetMisalType())=="full")
621 md->SetComment("Alignment objects for ITS full misalignment");
625 //________________________________________________________________________
626 Bool_t AliITSMisAligner::AddAlignObj(char* name,Double_t dx,Double_t dy,Double_t dz,
627 Double_t dpsi,Double_t dtheta,Double_t dphi,const char* distrib) {
629 // misalignment by symname
631 Double_t vx=0.,vy=0.,vz=0.,vpsi=0.,vtheta=0.,vphi=0.;
633 TString sdistrib(distrib);
635 if(sdistrib==TString("gaussian")) {
636 vx = AliMathBase::TruncatedGaus(0.,dx/3.,dx); // mean, sigma, max absolute value
637 vy = AliMathBase::TruncatedGaus(0.,dy/3.,dy);
638 vz = AliMathBase::TruncatedGaus(0.,dz/3.,dz);
639 vpsi = AliMathBase::TruncatedGaus(0.,dpsi/3., dpsi );
640 vtheta = AliMathBase::TruncatedGaus(0.,dtheta/3.,dtheta);
641 vphi = AliMathBase::TruncatedGaus(0.,dphi/3., dphi);
642 }else if(sdistrib==TString("uniform")){
643 vx = fRnd.Uniform(-dx,dx);
644 vy = fRnd.Uniform(-dy,dy);
645 vz = fRnd.Uniform(-dz,dz);
646 vpsi = fRnd.Uniform(-dpsi,dpsi);
647 vtheta = fRnd.Uniform(-dtheta,dtheta);
648 vphi = fRnd.Uniform(-dphi,dphi);
649 }else if(sdistrib==TString("fixed")){
657 AliFatal(Form("Invalid string \"%s\" specifying the misalignment type for the volume \"%s\""));
660 new((*fAlignObjArray)[fInd]) AliAlignObjParams(name,0,vx,vy,vz,vpsi,vtheta,vphi,kFALSE);
662 AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlignObjArray->UncheckedAt(fInd);
663 itsalobj->ApplyToGeometry();
671 //________________________________________________________________________
672 Bool_t AliITSMisAligner::AddAlignObj(Int_t lay,Double_t dx,Double_t dy,Double_t dz,
673 Double_t dpsi,Double_t dtheta,Double_t dphi,Bool_t unif) {
675 // misalignment at the level of sensitive alignable volumes (SPD ladders/ SDD,SSD modules)
676 // done for all ladders/modules of the given layer
678 lay+=1; // layers are numbered from 1 to 6 in AliGeomManager
680 printf("LAYER %d MODULES %d\n",lay,AliGeomManager::LayerSize(lay));
682 for (Int_t iModule = 0; iModule < AliGeomManager::LayerSize(lay); iModule++) {
684 Double_t vx,vy,vz,vpsi,vtheta,vphi;
687 vx = AliMathBase::TruncatedGaus(0.,dx/3.,dx); // mean, sigma, max absolute value
688 vy = AliMathBase::TruncatedGaus(0.,dy/3.,dy);
689 vz = AliMathBase::TruncatedGaus(0.,dz/3.,dz);
690 vpsi = AliMathBase::TruncatedGaus(0.,dpsi/3.,dpsi);
691 vtheta = AliMathBase::TruncatedGaus(0.,dtheta/3.,dtheta);
692 vphi = AliMathBase::TruncatedGaus(0.,dphi/3.,dphi);
694 vx = fRnd.Uniform(-dx,dx);
695 vy = fRnd.Uniform(-dy,dy);
696 vz = fRnd.Uniform(-dz,dz);
697 vpsi = fRnd.Uniform(-dpsi,dpsi);
698 vtheta = fRnd.Uniform(-dtheta,dtheta);
699 vphi = fRnd.Uniform(-dphi,dphi);
702 UShort_t volid = AliGeomManager::LayerToVolUID(lay,iModule);
703 const char *symname = AliGeomManager::SymName(volid);
705 new((*fAlignObjArray)[fInd]) AliAlignObjParams(symname,volid,vx,vy,vz,vpsi,vtheta,vphi,kFALSE);
712 //________________________________________________________________________
713 Bool_t AliITSMisAligner::AddAlignObj(Int_t lay,Int_t ladd,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,
719 // misalignment at the level of half-staves/ladders (ladd=-1 means that all ladders are scanned)
721 Double_t vx,vy,vz,vpsi,vtheta,vphi;
722 Double_t tr[3],rot[3];
724 Int_t laddMin = ladd;
725 Int_t laddMax = laddMin+1;
728 laddMax = fgkNLadders[lay];
731 for (Int_t iLadd=laddMin; iLadd<laddMax; iLadd++) {
735 for (Int_t iHalfStave=0; iHalfStave<nHS; iHalfStave++) {
738 vx = AliMathBase::TruncatedGaus(0.,dx/3.,dx); // mean, sigma, max absolute value
739 vy = AliMathBase::TruncatedGaus(0.,dy/3.,dy);
740 vz = AliMathBase::TruncatedGaus(0.,dz/3.,dz);
741 vpsi = AliMathBase::TruncatedGaus(0.,dpsi/3.,dpsi);
742 vtheta = AliMathBase::TruncatedGaus(0.,dtheta/3.,dtheta);
743 vphi = AliMathBase::TruncatedGaus(0.,dphi/3.,dphi);
745 vx = fRnd.Uniform(-dx,dx);
746 vy = fRnd.Uniform(-dy,dy);
747 vz = fRnd.Uniform(-dz,dz);
748 vpsi = fRnd.Uniform(-dpsi,dpsi);
749 vtheta = fRnd.Uniform(-dtheta,dtheta);
750 vphi = fRnd.Uniform(-dphi,dphi);
753 TString name(GetHalfStaveLadderSymbName(lay,iLadd,iHalfStave));
755 // first apply half-stave / ladder level misalignment
756 AliAlignObjParams aaop(name.Data(),0,vx,vy,vz,vpsi,vtheta,vphi,kFALSE); // set them as local
757 aaop.GetPars(tr,rot); // global
759 // then, apply layer-level misalignment (only for SDD and SSD)
765 rot[1] += thetaShift;
768 new((*fAlignObjArray)[fInd]) AliAlignObjParams(name.Data(),0,tr[0],tr[1],tr[2],rot[0],rot[1],rot[2],kTRUE); // set them as global
770 AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlignObjArray->UncheckedAt(fInd);
771 itsalobj->ApplyToGeometry();
780 //________________________________________________________________________
781 Bool_t AliITSMisAligner::AddSectorAlignObj(Int_t sectMin,Int_t sectMax,
782 Double_t dx,Double_t dy,Double_t dz,
783 Double_t dpsi,Double_t dtheta,Double_t dphi,
784 Double_t xShift,Double_t yShift,Double_t zShift,
785 Double_t psiShift,Double_t thetaShift,Double_t phiShift,Bool_t unif) {
787 // misalignment at the level of SPD sectors and half-barrels
790 if ((sectMin<1) || (sectMax>10)) return kFALSE;
791 Double_t vx,vy,vz,vpsi,vtheta,vphi;
792 Double_t tr[3],rot[3];
794 for (Int_t iSect = sectMin-1; iSect<sectMax; iSect++) {
796 // first, apply sector level misalignment
798 vx = AliMathBase::TruncatedGaus(0.,dx/3.,dx); // mean, sigma, max absolute value
799 vy = AliMathBase::TruncatedGaus(0.,dy/3.,dy);
800 vz = AliMathBase::TruncatedGaus(0.,dz/3.,dz);
801 vpsi = AliMathBase::TruncatedGaus(0.,dpsi/3.,dpsi);
802 vtheta = AliMathBase::TruncatedGaus(0.,dtheta/3.,dtheta);
803 vphi = AliMathBase::TruncatedGaus(0.,dphi/3.,dphi);
805 vx = fRnd.Uniform(-dx,dx);
806 vy = fRnd.Uniform(-dy,dy);
807 vz = fRnd.Uniform(-dz,dz);
808 vpsi = fRnd.Uniform(-dpsi,dpsi);
809 vtheta = fRnd.Uniform(-dtheta,dtheta);
810 vphi = fRnd.Uniform(-dphi,dphi);
813 TString name(GetSymbName(0));
818 AliAlignObjParams aaop(name.Data(),0,vx,vy,vz,vpsi,vtheta,vphi,kFALSE); // set them as local
819 aaop.GetPars(tr,rot); // global
821 // then, apply half-barrel level misalignment
826 rot[1] += thetaShift;
829 new((*fAlignObjArray)[fInd]) AliAlignObjParams(name.Data(),0,tr[0],tr[1],tr[2],rot[0],rot[1],rot[2],kTRUE); // set them as global
831 AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlignObjArray->UncheckedAt(fInd);
832 itsalobj->ApplyToGeometry();
838 //________________________________________________________________________
839 const char* AliITSMisAligner::GetSymbName(Int_t layer) const {
841 // be careful : SPD0 and SPD1 are not physically separated
846 case 1: name = fStrSPD; name += layer; break;
848 case 3: name = fStrSDD; name += layer; break;
850 case 5: name = fStrSSD; name += layer; break;
851 default: AliFatal("Wrong layer index");
856 //________________________________________________________________________
857 const char* AliITSMisAligner::GetSymbName(Int_t layer, Int_t ladder, Int_t det) const {
859 // symname from layer, ladder, detector
861 TString symname(GetHalfStaveLadderSymbName(layer,ladder,det));
867 AliError("Invalid layer!");
871 return symname.Data();
874 //________________________________________________________________________
875 const char* AliITSMisAligner::GetSymbName(Int_t layer,Int_t ladd) const {
877 // Get logical names at the level of staves / ladders
879 TString name(GetSymbName(layer));
880 if (layer==0) { // SPD1
885 int stave = ladd-sector*2;
889 else if (layer==1) { // SPD2
894 int stave = ladd-sector*4;
898 else if (layer>=2 && layer<=5) { // SDD and SSD
903 AliFatal("Wrong layer index");
908 //________________________________________________________________________
909 const char* AliITSMisAligner::GetHalfStaveLadderSymbName(Int_t layer,Int_t ladd,Int_t halfStave) const {
911 // Get logical names at the level of half-staves (SPD) or ladders (SDD and SSD)
913 TString name(GetSymbName(layer));
914 if (layer==0) { // SPD1
919 int stave = ladd-sector*2;
922 name += fStrHalfStave;
925 else if (layer==1) { // SPD2
930 int stave = ladd-sector*4;
933 name += fStrHalfStave;
936 else if (layer>=2 && layer<=5) { // SDD and SSD
941 AliFatal("Wrong layer index");
946 //________________________________________________________________________
947 const char* AliITSMisAligner::GetParentSymName(const char* symname) {
949 // symnane of parent volume
951 TString parent(symname);
952 // Give the symname of
953 if(parent.BeginsWith('/')) parent.Remove(TString::kLeading,'/');
954 if(parent.EndsWith("/")) parent.Remove(TString::kTrailing,'/');
956 if(!parent.CountChar('/')) AliErrorClass("Not a valid symbolic name");
959 GetLayerAndLevel(symname,layer,level);
960 if(level==1) return "ITS";
962 parent.Remove(parent.Last('/'));
964 if((layer==0 || layer==1) && level==2){
965 parent.Remove(parent.Last('/'));
969 return parent.Data();
972 //________________________________________________________________________
973 Bool_t AliITSMisAligner::GetLayerAndLevel(const char* symname, Int_t &layer, Int_t &level) {
975 // given the symbolic name set layer and level
977 const char* basename[6] = {"ITS/SPD0/Sector","ITS/SPD1/Sector","ITS/SDD2/Ladder","ITS/SDD3/Ladder","ITS/SSD4/Ladder","ITS/SSD5/Ladder"};
978 TString strSym(symname);
986 if(strSym.BeginsWith(basename[i])) break;
990 AliErrorClass(Form("%s is not a valid symbolic name for an ITS alignable volume",strSym.Data()));
995 //The part above could be replaced by just
996 // TString seventh = strSym[7];
997 // layer = seventh.Atoi();
998 // if we don't need to check the validity of the symname
1004 if(strSym.Contains("Stave")) level=2;
1005 if(strSym.Contains("Ladder")) level=3;
1011 if(strSym.Contains("Sensor")) level=2;
1017 //________________________________________________________________________
1018 Int_t AliITSMisAligner::GetNSisters(const char* symname) {
1020 // number of volumes on same level
1023 if(!GetLayerAndLevel(symname,layer,level)) return -1;
1024 if(level==0) return -1;
1025 if(level==1) return GetNLadders(layer);
1026 if(level==2) return GetNDetectors(layer);
1027 AliErrorClass(Form("Invalid layer and level"));
1031 //________________________________________________________________________
1032 Int_t AliITSMisAligner::GetNDaughters(const char* symname) {
1034 // number of daughter volumes
1037 if(!GetLayerAndLevel(symname,layer,level)) return -1;
1040 for(Int_t lay=0; lay<6; lay++) nLadders += GetNLadders(lay);
1043 if(level==1) return GetNDetectors(layer);
1045 AliWarningClass(Form("Volume %s is a sensitive volume and has no alignable dauthers",symname));
1048 AliErrorClass(Form("Invalid layer and level"));
1053 //________________________________________________________________________
1054 TString AliITSMisAligner::GetSymbName(Int_t layer,Int_t ladd,Int_t mod) const {
1056 // Get logical names at the level of SPD ladders / SDD and SSD modules
1058 Int_t halfStave = mod/2;
1059 TString name = GetHalfStaveLadderSymbName(layer,ladd,halfStave);
1061 if (layer<2) { // SPD
1065 else if (layer>=2 && layer<=5) { // SDD and SSD
1070 AliFatal("Wrong layer index");