]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ITS/AliITSMisalignMaker.cxx
Adding possibility to use custom Gain map for dEdx calculation (Marian)
[u/mrichter/AliRoot.git] / ITS / AliITSMisalignMaker.cxx
CommitLineData
3b61c716 1/**************************************************************************
2 * Copyright(c) 1998-2007, 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
b5cec7b2 16/* $Id$ */
3b61c716 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 <TRandom3.h>
30#include <TClonesArray.h>
5c978c5e 31#include <TClass.h>
3b61c716 32
33
34#include "AliLog.h"
35#include "AliAlignObjParams.h"
36#include "AliITSMisalignMaker.h"
37
38
39ClassImp(AliITSMisalignMaker)
40
41const Int_t AliITSMisalignMaker::fgkNLadders[AliITSMisalignMaker::kNLayers] = {20,40,14,22,34,38};
42const Int_t AliITSMisalignMaker::fgkNDetectors[AliITSMisalignMaker::kNLayers] = {4,4,6,8,22,25};
43
44
45//________________________________________________________________________
46AliITSMisalignMaker::AliITSMisalignMaker():
47 fRnd(),
48 fInd(0),
49 fAlobj(TClonesArray("AliAlignObjParams",4000)),
50 fStrSPD("ITS/SPD"),
51 fStrSDD("ITS/SDD"),
52 fStrSSD("ITS/SSD"),
53 fStrStave("/Stave"),
54 fStrHalfStave("/HalfStave"),
55 fStrLadder("/Ladder"),
56 fStrSector("/Sector"),
57 fStrSensor("/Sensor")
58{
5c978c5e 59 //
60 // defaul constructor
61 //
3b61c716 62 fRnd.SetSeed(23472341);
63}
64//________________________________________________________________________
65Int_t AliITSMisalignMaker::AddAlignObj(char* name,Double_t dx,Double_t dy,Double_t dz,
66 Double_t dpsi,Double_t dtheta,Double_t dphi,Bool_t unif) {
5c978c5e 67 //
68 // misalignment by symname
69 //
3b61c716 70 Double_t vx,vy,vz,vpsi,vtheta,vphi;
71
72 if(!unif) {
73 vx = GaussCut(0,dx/3.,dx); // mean, sigma, max absolute value
74 vy = GaussCut(0,dy/3.,dy);
75 vz = GaussCut(0,dz/3.,dz);
76 vpsi = GaussCut(0,dpsi/3., dpsi );
77 vtheta = GaussCut(0,dtheta/3.,dtheta);
78 vphi = GaussCut(0,dphi/3., dphi);
79 } else {
80 vx = fRnd.Uniform(-dx,dx);
81 vy = fRnd.Uniform(-dy,dy);
82 vz = fRnd.Uniform(-dz,dz);
83 vpsi = fRnd.Uniform(-dpsi,dpsi);
84 vtheta = fRnd.Uniform(-dtheta,dtheta);
85 vphi = fRnd.Uniform(-dphi,dphi);
86 }
87
88 new(fAlobj[fInd]) AliAlignObjParams(name,0,vx,vy,vz,vpsi,vtheta,vphi,kFALSE);
89
5c978c5e 90 AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
91 itsalobj->ApplyToGeometry();
3b61c716 92
93 fInd++;
94
95 return kTRUE;
96}
97
98
99//________________________________________________________________________
100Int_t AliITSMisalignMaker::AddAlignObj(Int_t lay,Double_t dx,Double_t dy,Double_t dz,
101 Double_t dpsi,Double_t dtheta,Double_t dphi,Bool_t unif) {
5c978c5e 102 //
3b61c716 103 // misalignment at the level of ladders/modules
5c978c5e 104 //
b5cec7b2 105 lay+=1; // layers are numbered from 1 to 6 in AliGeomManager
3b61c716 106
b5cec7b2 107 printf("LAYER %d MODULES %d\n",lay,AliGeomManager::LayerSize(lay));
3b61c716 108
b5cec7b2 109 for (Int_t iModule = 0; iModule < AliGeomManager::LayerSize(lay); iModule++) {
3b61c716 110
b5cec7b2 111 Double_t vx,vy,vz,vpsi,vtheta,vphi;
112
113 if(!unif) {
114 vx = GaussCut(0,dx/3.,dx); // mean, sigma, max absolute value
115 vy = GaussCut(0,dy/3.,dy);
116 vz = GaussCut(0,dz/3.,dz);
117 vpsi = GaussCut(0,dpsi/3., dpsi );
118 vtheta = GaussCut(0,dtheta/3.,dtheta);
119 vphi = GaussCut(0,dphi/3., dphi);
120 } else {
121 vx = fRnd.Uniform(-dx,dx);
122 vy = fRnd.Uniform(-dy,dy);
123 vz = fRnd.Uniform(-dz,dz);
124 vpsi = fRnd.Uniform(-dpsi,dpsi);
125 vtheta = fRnd.Uniform(-dtheta,dtheta);
126 vphi = fRnd.Uniform(-dphi,dphi);
3b61c716 127 }
b5cec7b2 128
129 UShort_t volid = AliGeomManager::LayerToVolUID(lay,iModule);
130 const char *symname = AliGeomManager::SymName(volid);
131
132 new(fAlobj[fInd]) AliAlignObjParams(symname,volid,vx,vy,vz,vpsi,vtheta,vphi,kFALSE);
5c978c5e 133 AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
134 itsalobj->ApplyToGeometry();
b5cec7b2 135 fInd++;
3b61c716 136 }
137
138 return kTRUE;
139}
140
3b61c716 141//________________________________________________________________________
142Int_t AliITSMisalignMaker::AddAlignObj(Int_t lay,Int_t ladd,Double_t dx,Double_t dy,Double_t dz,
5c978c5e 143 Double_t dpsi,Double_t dtheta,Double_t dphi,
144 Double_t xShift,Double_t yShift,Double_t zShift,
145 Double_t psiShift,Double_t thetaShift,Double_t phiShift,
146 Bool_t unif) {
147 //
3b61c716 148 // misalignment at the level of half-staves/ladders (ladd=-1 means that all ladders are scanned)
5c978c5e 149 //
3b61c716 150 Double_t vx,vy,vz,vpsi,vtheta,vphi;
5c978c5e 151 Double_t tr[3],rot[3];
3b61c716 152
153 Int_t laddMin = ladd;
154 Int_t laddMax = laddMin+1;
155 if (ladd<0) {
156 laddMin = 0;
157 laddMax = fgkNLadders[lay];
158 }
159
160 for (Int_t iLadd=laddMin; iLadd<laddMax; iLadd++) {
161
162 Int_t nHS = 1;
163 if (lay<2) nHS = 2;
164 for (Int_t iHalfStave=0; iHalfStave<nHS; iHalfStave++) {
165
166 if(!unif) {
167 vx = GaussCut(0,dx/3.,dx); // mean, sigma, max absolute value
168 vy = GaussCut(0,dy/3.,dy);
169 vz = GaussCut(0,dz/3.,dz);
170 vpsi = GaussCut(0,dpsi/3., dpsi );
171 vtheta = GaussCut(0,dtheta/3.,dtheta);
172 vphi = GaussCut(0,dphi/3., dphi);
173 } else {
174 vx = fRnd.Uniform(-dx,dx);
175 vy = fRnd.Uniform(-dy,dy);
176 vz = fRnd.Uniform(-dz,dz);
177 vpsi = fRnd.Uniform(-dpsi,dpsi);
178 vtheta = fRnd.Uniform(-dtheta,dtheta);
179 vphi = fRnd.Uniform(-dphi,dphi);
180 }
181
5c978c5e 182 TString name(GetHalfStaveLadderSymbName(lay,iLadd,iHalfStave));
183
184 // first apply half-stave / ladder level misalignment
185 AliAlignObjParams aaop(name.Data(),0,vx,vy,vz,vpsi,vtheta,vphi,kFALSE); // set them as local
186 aaop.GetPars(tr,rot); // global
187
188 // then, apply layer-level misalignment (only for SDD and SSD)
189 if(lay>1) {
190 tr[0] += xShift;
191 tr[1] += yShift;
192 tr[2] += zShift;
193 rot[0] += psiShift;
194 rot[1] += thetaShift;
195 rot[2] += phiShift;
196 }
197 new(fAlobj[fInd]) AliAlignObjParams(name.Data(),0,tr[0],tr[1],tr[2],rot[0],rot[1],rot[2],kTRUE); // set them as global
198
199 AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
200 itsalobj->ApplyToGeometry();
3b61c716 201 fInd++;
202 }
203 }
204
205 return kTRUE;
206}
207
208
209//________________________________________________________________________
210Int_t AliITSMisalignMaker::AddSectorAlignObj(Int_t sectMin,Int_t sectMax,
211 Double_t dx,Double_t dy,Double_t dz,
212 Double_t dpsi,Double_t dtheta,Double_t dphi,
213 Double_t xShift,Double_t yShift,Double_t zShift,
214 Double_t psiShift,Double_t thetaShift,Double_t phiShift,Bool_t unif) {
5c978c5e 215 //
3b61c716 216 // misalignment at the level of SPD sectors and half-barrels
5c978c5e 217 //
218
3b61c716 219 if ((sectMin<1) || (sectMax>10)) return kFALSE;
220 Double_t vx,vy,vz,vpsi,vtheta,vphi;
221 Double_t tr[3],rot[3];
222
223 for (Int_t iSect = sectMin-1; iSect<sectMax; iSect++) {
224
225 // first, apply sector level misalignment
226 if(!unif) {
227 vx = GaussCut(0,dx/3.,dx); // mean, sigma, max absolute value
228 vy = GaussCut(0,dy/3.,dy);
229 vz = GaussCut(0,dz/3.,dz);
230 vpsi = GaussCut(0,dpsi/3., dpsi );
231 vtheta = GaussCut(0,dtheta/3.,dtheta);
232 vphi = GaussCut(0,dphi/3., dphi);
233 } else {
234 vx = fRnd.Uniform(-dx,dx);
235 vy = fRnd.Uniform(-dy,dy);
236 vz = fRnd.Uniform(-dz,dz);
237 vpsi = fRnd.Uniform(-dpsi,dpsi);
238 vtheta = fRnd.Uniform(-dtheta,dtheta);
239 vphi = fRnd.Uniform(-dphi,dphi);
240 }
241
5c978c5e 242 TString name(GetSymbName(0));
3b61c716 243 name += fStrSector;
244 name += iSect;
245
246
247 AliAlignObjParams aaop(name.Data(),0,vx,vy,vz,vpsi,vtheta,vphi,kFALSE); // set them as local
248 aaop.GetPars(tr,rot); // global
249
250 // then, apply half-barrel level misalignment
251 tr[0] += xShift;
252 tr[1] += yShift;
253 tr[2] += zShift;
254 rot[0] += psiShift;
255 rot[1] += thetaShift;
256 rot[2] += phiShift;
257
258 new(fAlobj[fInd]) AliAlignObjParams(name.Data(),0,tr[0],tr[1],tr[2],rot[0],rot[1],rot[2],kTRUE); // set them as global
259
5c978c5e 260 AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
261 itsalobj->ApplyToGeometry();
3b61c716 262 fInd++;
263 }
264 return kTRUE;
265}
266
267//________________________________________________________________________
268Double_t AliITSMisalignMaker::GaussCut(Double_t mean,Double_t sigma,Double_t absMax) {
5c978c5e 269 //
270 // random from gaussian with cut on tails
271 //
3b61c716 272 Double_t val = fRnd.Gaus(mean,sigma);
8dd124ba 273 while (TMath::Abs(val-mean)>absMax)
3b61c716 274 val = fRnd.Gaus(mean,sigma);
275 return val;
276}
277
278//________________________________________________________________________
5c978c5e 279const char* AliITSMisalignMaker::GetSymbName(Int_t layer) const {
280 //
3b61c716 281 // be careful : SPD0 and SPD1 are not physically separated
5c978c5e 282 //
3b61c716 283 TString name;
284 switch (layer) {
285 case 0:
286 case 1: name = fStrSPD; name += layer; break;
287 case 2:
288 case 3: name = fStrSDD; name += layer; break;
289 case 4:
290 case 5: name = fStrSSD; name += layer; break;
291 default: AliFatal("Wrong layer index");
292 }
5c978c5e 293 return name.Data();
3b61c716 294}
295
296//________________________________________________________________________
5c978c5e 297const char* AliITSMisalignMaker::GetSymbName(Int_t layer, Int_t ladder, Int_t det) const {
298 //
299 // symname from layer, ladder, detector
300 //
301 TString symname(GetHalfStaveLadderSymbName(layer,ladder,det));
302 if(layer<=2){
303 symname+="Ladder";
304 }else if(layer<=6){
305 symname+="Sensor";
306 }else{
307 AliError("Invalid layer!");
308 return 0;
309 }
310 symname+=det;
311 return symname.Data();
312}
3b61c716 313
5c978c5e 314//________________________________________________________________________
315const char* AliITSMisalignMaker::GetSymbName(Int_t layer,Int_t ladd) const {
316 //
317 // Get logical names at the level of staves / ladders
318 //
319 TString name(GetSymbName(layer));
3b61c716 320 if (layer==0) { // SPD1
321
322 int sector = ladd/2;
323 name += fStrSector;
324 name += sector;
325 int stave = ladd-sector*2;
326 name += fStrStave;
327 name += stave;
3b61c716 328 }
329 else if (layer==1) { // SPD2
330
331 int sector = ladd/4;
332 name += fStrSector;
333 name += sector;
334 int stave = ladd-sector*4;
335 name += fStrStave;
336 name += stave;
3b61c716 337 }
338 else if (layer>=2 && layer<=5) { // SDD and SSD
339 name += fStrLadder;
340 name += ladd;
5c978c5e 341 }
3b61c716 342 else {
343 AliFatal("Wrong layer index");
344 }
5c978c5e 345 return name.Data();
3b61c716 346}
347
348//________________________________________________________________________
5c978c5e 349const char* AliITSMisalignMaker::GetHalfStaveLadderSymbName(Int_t layer,Int_t ladd,Int_t halfStave) const {
350 //
351 // Get logical names at the level of half-staves (SPD) or ladders (SDD and SSD)
352 //
353 TString name(GetSymbName(layer));
3b61c716 354 if (layer==0) { // SPD1
355
356 int sector = ladd/2;
357 name += fStrSector;
358 name += sector;
359 int stave = ladd-sector*2;
360 name += fStrStave;
361 name += stave;
5c978c5e 362 name += fStrHalfStave;
363 name += halfStave;
3b61c716 364 }
365 else if (layer==1) { // SPD2
366
367 int sector = ladd/4;
368 name += fStrSector;
369 name += sector;
370 int stave = ladd-sector*4;
371 name += fStrStave;
372 name += stave;
5c978c5e 373 name += fStrHalfStave;
374 name += halfStave;
3b61c716 375 }
376 else if (layer>=2 && layer<=5) { // SDD and SSD
377 name += fStrLadder;
378 name += ladd;
5c978c5e 379 }
3b61c716 380 else {
381 AliFatal("Wrong layer index");
382 }
5c978c5e 383 return name.Data();
384}
385
386//________________________________________________________________________
387const char* AliITSMisalignMaker::GetParentSymName(const char* symname) {
388 //
389 // symnane of parent volume
390 //
391 TString parent(symname);
392 // Give the symname of
393 if(parent.BeginsWith('/')) parent.Remove(TString::kLeading,'/');
394 if(parent.EndsWith("/")) parent.Remove(TString::kTrailing,'/');
395
396 if(!parent.CountChar('/')) AliErrorClass("Not a valid symbolic name");
397
398 Int_t layer,level;
399 GetLayerAndLevel(symname,layer,level);
400 if(level==1) return "ITS";
401
402 parent.Remove(parent.Last('/'));
403
404 if((layer==0 || layer==1) && level==2){
405 parent.Remove(parent.Last('/'));
406 parent[7]='0';
407 }
408
409 return parent.Data();
410}
411
412//________________________________________________________________________
413Bool_t AliITSMisalignMaker::GetLayerAndLevel(const char* symname, Int_t &layer, Int_t &level) {
414 //
415 // given the symbolic name set layer and level
416 //
417 const char* basename[6] = {"ITS/SPD0/Sector","ITS/SPD1/Sector","ITS/SDD2/Ladder","ITS/SDD3/Ladder","ITS/SSD4/Ladder","ITS/SSD5/Ladder"};
418 TString strSym(symname);
419 if(strSym=="ITS"){
420 level=0;
421 layer=-1;
422 return kTRUE;
423 }
424 Int_t i;
425 for(i=0; i<6; i++){
426 if(strSym.BeginsWith(basename[i])) break;
427 }
428
429 if(i>=6){
430 AliErrorClass(Form("%s is not a valid symbolic name for an ITS alignable volume",strSym.Data()));
431 return kFALSE;
432 }
433
434 layer=i;
435 //The part above could be replaced by just
436 // TString seventh = strSym[7];
437 // layer = seventh.Atoi();
438 // if we don't need to check the validity of the symname
439
440 level=1;
441 switch(layer){
442 case 0:
443 case 1:
444 if(strSym.Contains("Stave")) level=2;
445 if(strSym.Contains("Ladder")) level=3;
446 break;
447 case 2:
448 case 3:
449 case 4:
450 case 5:
451 if(strSym.Contains("Sensor")) level=2;
452 }
453
454 return kTRUE;
455}
456
457//________________________________________________________________________
458Int_t AliITSMisalignMaker::GetNSisters(const char* symname) {
459 //
460 // number of volumes on same level
461 //
462 Int_t layer,level;
463 if(!GetLayerAndLevel(symname,layer,level)) return -1;
464 if(level==0) return -1;
465 if(level==1) return GetNLadders(layer);
466 if(level==2) return GetNDetectors(layer);
467 AliErrorClass(Form("Invalid layer and level"));
468 return -1;
3b61c716 469}
5c978c5e 470
471//________________________________________________________________________
472Int_t AliITSMisalignMaker::GetNDaughters(const char* symname) {
473 //
474 // number of daughter volumes
475 //
476 Int_t layer,level;
477 if(!GetLayerAndLevel(symname,layer,level)) return -1;
478 if(level==0) {
479 Int_t nLadders = 0;
480 for(Int_t lay=0; lay<6; lay++) nLadders += GetNLadders(lay);
481 return nLadders;
482 }
483 if(level==1) return GetNDetectors(layer);
484 if(level==2){
485 AliWarningClass(Form("Volume %s is a sensitive volume and has no alignable dauthers",symname));
486 return -1;
487 }
488 AliErrorClass(Form("Invalid layer and level"));
489 return -1;
490}
491
b5cec7b2 492/*
3b61c716 493//________________________________________________________________________
494TString AliITSMisalignMaker::GetSymbName(Int_t layer,Int_t ladd,Int_t mod) const {
495
496 // Get logical names at the level of SPD ladders / SDD and SSD modules
497
498 Int_t halfStave = mod/2;
499 TString name = GetHalfStaveLadderSymbName(layer,ladd,halfStave);
500
501 if (layer<2) { // SPD
502 name += fStrLadder;
503 name += mod;
504 }
505 else if (layer>=2 && layer<=5) { // SDD and SSD
506 name += fStrSensor;
507 name += mod;
508 }
509 else {
510 AliFatal("Wrong layer index");
511 }
512 return name;
513}
b5cec7b2 514*/
5c978c5e 515