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