1 /**************************************************************************
2 * Copyright(c) 1998-2007, 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 //========================================================================
30 #include <TClonesArray.h>
35 #include "AliAlignObjParams.h"
36 #include "AliITSMisalignMaker.h"
39 ClassImp(AliITSMisalignMaker)
41 const Int_t AliITSMisalignMaker::fgkNLadders[AliITSMisalignMaker::kNLayers] = {20,40,14,22,34,38};
42 const Int_t AliITSMisalignMaker::fgkNDetectors[AliITSMisalignMaker::kNLayers] = {4,4,6,8,22,25};
45 //________________________________________________________________________
46 AliITSMisalignMaker::AliITSMisalignMaker():
49 fAlobj(TClonesArray("AliAlignObjParams",4000)),
54 fStrHalfStave("/HalfStave"),
55 fStrLadder("/Ladder"),
56 fStrSector("/Sector"),
62 fRnd.SetSeed(23472341);
64 //________________________________________________________________________
65 Int_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) {
68 // misalignment by symname
70 Double_t vx,vy,vz,vpsi,vtheta,vphi;
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);
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);
88 new(fAlobj[fInd]) AliAlignObjParams(name,0,vx,vy,vz,vpsi,vtheta,vphi,kFALSE);
90 AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
91 itsalobj->ApplyToGeometry();
99 //________________________________________________________________________
100 Int_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) {
103 // misalignment at the level of ladders/modules
105 lay+=1; // layers are numbered from 1 to 6 in AliGeomManager
107 printf("LAYER %d MODULES %d\n",lay,AliGeomManager::LayerSize(lay));
109 for (Int_t iModule = 0; iModule < AliGeomManager::LayerSize(lay); iModule++) {
111 Double_t vx,vy,vz,vpsi,vtheta,vphi;
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);
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);
129 UShort_t volid = AliGeomManager::LayerToVolUID(lay,iModule);
130 const char *symname = AliGeomManager::SymName(volid);
132 new(fAlobj[fInd]) AliAlignObjParams(symname,volid,vx,vy,vz,vpsi,vtheta,vphi,kFALSE);
133 AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
134 itsalobj->ApplyToGeometry();
141 //________________________________________________________________________
142 Int_t AliITSMisalignMaker::AddAlignObj(Int_t lay,Int_t ladd,Double_t dx,Double_t dy,Double_t dz,
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,
148 // misalignment at the level of half-staves/ladders (ladd=-1 means that all ladders are scanned)
150 Double_t vx,vy,vz,vpsi,vtheta,vphi;
151 Double_t tr[3],rot[3];
153 Int_t laddMin = ladd;
154 Int_t laddMax = laddMin+1;
157 laddMax = fgkNLadders[lay];
160 for (Int_t iLadd=laddMin; iLadd<laddMax; iLadd++) {
164 for (Int_t iHalfStave=0; iHalfStave<nHS; iHalfStave++) {
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);
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);
182 TString name(GetHalfStaveLadderSymbName(lay,iLadd,iHalfStave));
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
188 // then, apply layer-level misalignment (only for SDD and SSD)
194 rot[1] += thetaShift;
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
199 AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
200 itsalobj->ApplyToGeometry();
209 //________________________________________________________________________
210 Int_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) {
216 // misalignment at the level of SPD sectors and half-barrels
219 if ((sectMin<1) || (sectMax>10)) return kFALSE;
220 Double_t vx,vy,vz,vpsi,vtheta,vphi;
221 Double_t tr[3],rot[3];
223 for (Int_t iSect = sectMin-1; iSect<sectMax; iSect++) {
225 // first, apply sector level misalignment
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);
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);
242 TString name(GetSymbName(0));
247 AliAlignObjParams aaop(name.Data(),0,vx,vy,vz,vpsi,vtheta,vphi,kFALSE); // set them as local
248 aaop.GetPars(tr,rot); // global
250 // then, apply half-barrel level misalignment
255 rot[1] += thetaShift;
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
260 AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
261 itsalobj->ApplyToGeometry();
267 //________________________________________________________________________
268 Double_t AliITSMisalignMaker::GaussCut(Double_t mean,Double_t sigma,Double_t absMax) {
270 // random from gaussian with cut on tails
272 Double_t val = fRnd.Gaus(mean,sigma);
273 while (TMath::Abs(val-mean)>absMax)
274 val = fRnd.Gaus(mean,sigma);
278 //________________________________________________________________________
279 const char* AliITSMisalignMaker::GetSymbName(Int_t layer) const {
281 // be careful : SPD0 and SPD1 are not physically separated
286 case 1: name = fStrSPD; name += layer; break;
288 case 3: name = fStrSDD; name += layer; break;
290 case 5: name = fStrSSD; name += layer; break;
291 default: AliFatal("Wrong layer index");
296 //________________________________________________________________________
297 const char* AliITSMisalignMaker::GetSymbName(Int_t layer, Int_t ladder, Int_t det) const {
299 // symname from layer, ladder, detector
301 TString symname(GetHalfStaveLadderSymbName(layer,ladder,det));
307 AliError("Invalid layer!");
311 return symname.Data();
314 //________________________________________________________________________
315 const char* AliITSMisalignMaker::GetSymbName(Int_t layer,Int_t ladd) const {
317 // Get logical names at the level of staves / ladders
319 TString name(GetSymbName(layer));
320 if (layer==0) { // SPD1
325 int stave = ladd-sector*2;
329 else if (layer==1) { // SPD2
334 int stave = ladd-sector*4;
338 else if (layer>=2 && layer<=5) { // SDD and SSD
343 AliFatal("Wrong layer index");
348 //________________________________________________________________________
349 const char* AliITSMisalignMaker::GetHalfStaveLadderSymbName(Int_t layer,Int_t ladd,Int_t halfStave) const {
351 // Get logical names at the level of half-staves (SPD) or ladders (SDD and SSD)
353 TString name(GetSymbName(layer));
354 if (layer==0) { // SPD1
359 int stave = ladd-sector*2;
362 name += fStrHalfStave;
365 else if (layer==1) { // SPD2
370 int stave = ladd-sector*4;
373 name += fStrHalfStave;
376 else if (layer>=2 && layer<=5) { // SDD and SSD
381 AliFatal("Wrong layer index");
386 //________________________________________________________________________
387 const char* AliITSMisalignMaker::GetParentSymName(const char* symname) {
389 // symnane of parent volume
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,'/');
396 if(!parent.CountChar('/')) AliErrorClass("Not a valid symbolic name");
399 GetLayerAndLevel(symname,layer,level);
400 if(level==1) return "ITS";
402 parent.Remove(parent.Last('/'));
404 if((layer==0 || layer==1) && level==2){
405 parent.Remove(parent.Last('/'));
409 return parent.Data();
412 //________________________________________________________________________
413 Bool_t AliITSMisalignMaker::GetLayerAndLevel(const char* symname, Int_t &layer, Int_t &level) {
415 // given the symbolic name set layer and level
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);
426 if(strSym.BeginsWith(basename[i])) break;
430 AliErrorClass(Form("%s is not a valid symbolic name for an ITS alignable volume",strSym.Data()));
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
444 if(strSym.Contains("Stave")) level=2;
445 if(strSym.Contains("Ladder")) level=3;
451 if(strSym.Contains("Sensor")) level=2;
457 //________________________________________________________________________
458 Int_t AliITSMisalignMaker::GetNSisters(const char* symname) {
460 // number of volumes on same 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"));
471 //________________________________________________________________________
472 Int_t AliITSMisalignMaker::GetNDaughters(const char* symname) {
474 // number of daughter volumes
477 if(!GetLayerAndLevel(symname,layer,level)) return -1;
480 for(Int_t lay=0; lay<6; lay++) nLadders += GetNLadders(lay);
483 if(level==1) return GetNDetectors(layer);
485 AliWarningClass(Form("Volume %s is a sensitive volume and has no alignable dauthers",symname));
488 AliErrorClass(Form("Invalid layer and level"));
493 //________________________________________________________________________
494 TString AliITSMisalignMaker::GetSymbName(Int_t layer,Int_t ladd,Int_t mod) const {
496 // Get logical names at the level of SPD ladders / SDD and SSD modules
498 Int_t halfStave = mod/2;
499 TString name = GetHalfStaveLadderSymbName(layer,ladd,halfStave);
501 if (layer<2) { // SPD
505 else if (layer>=2 && layer<=5) { // SDD and SSD
510 AliFatal("Wrong layer index");