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(38217945);
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,const char* distrib) {
68 // misalignment by symname
70 Double_t vx=0.,vy=0.,vz=0.,vpsi=0.,vtheta=0.,vphi=0.;
72 TString sdistrib(distrib);
74 if(sdistrib==TString("gaussian")) {
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);
81 }else if(sdistrib==TString("uniform")){
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);
88 }else if(sdistrib==TString("fixed")){
96 AliFatal(Form("Invalid string \"%s\" specifying the misalignment type for the volume \"%s\""));
99 new(fAlobj[fInd]) AliAlignObjParams(name,0,vx,vy,vz,vpsi,vtheta,vphi,kFALSE);
101 AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
102 itsalobj->ApplyToGeometry();
110 //________________________________________________________________________
111 Int_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) {
114 // misalignment at the level of ladders/modules
116 lay+=1; // layers are numbered from 1 to 6 in AliGeomManager
118 printf("LAYER %d MODULES %d\n",lay,AliGeomManager::LayerSize(lay));
120 for (Int_t iModule = 0; iModule < AliGeomManager::LayerSize(lay); iModule++) {
122 Double_t vx,vy,vz,vpsi,vtheta,vphi;
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);
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);
140 UShort_t volid = AliGeomManager::LayerToVolUID(lay,iModule);
141 const char *symname = AliGeomManager::SymName(volid);
143 new(fAlobj[fInd]) AliAlignObjParams(symname,volid,vx,vy,vz,vpsi,vtheta,vphi,kFALSE);
144 AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
145 itsalobj->ApplyToGeometry();
152 //________________________________________________________________________
153 Int_t AliITSMisalignMaker::AddAlignObj(Int_t lay,Int_t ladd,Double_t dx,Double_t dy,Double_t dz,
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,
159 // misalignment at the level of half-staves/ladders (ladd=-1 means that all ladders are scanned)
161 Double_t vx,vy,vz,vpsi,vtheta,vphi;
162 Double_t tr[3],rot[3];
164 Int_t laddMin = ladd;
165 Int_t laddMax = laddMin+1;
168 laddMax = fgkNLadders[lay];
171 for (Int_t iLadd=laddMin; iLadd<laddMax; iLadd++) {
175 for (Int_t iHalfStave=0; iHalfStave<nHS; iHalfStave++) {
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);
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);
193 TString name(GetHalfStaveLadderSymbName(lay,iLadd,iHalfStave));
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
199 // then, apply layer-level misalignment (only for SDD and SSD)
205 rot[1] += thetaShift;
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
210 AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
211 itsalobj->ApplyToGeometry();
220 //________________________________________________________________________
221 Int_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) {
227 // misalignment at the level of SPD sectors and half-barrels
230 if ((sectMin<1) || (sectMax>10)) return kFALSE;
231 Double_t vx,vy,vz,vpsi,vtheta,vphi;
232 Double_t tr[3],rot[3];
234 for (Int_t iSect = sectMin-1; iSect<sectMax; iSect++) {
236 // first, apply sector level misalignment
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);
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);
253 TString name(GetSymbName(0));
258 AliAlignObjParams aaop(name.Data(),0,vx,vy,vz,vpsi,vtheta,vphi,kFALSE); // set them as local
259 aaop.GetPars(tr,rot); // global
261 // then, apply half-barrel level misalignment
266 rot[1] += thetaShift;
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
271 AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
272 itsalobj->ApplyToGeometry();
278 //________________________________________________________________________
279 Double_t AliITSMisalignMaker::GaussCut(Double_t mean,Double_t sigma,Double_t absMax) {
281 // random from gaussian with cut on tails
283 Double_t val = fRnd.Gaus(mean,sigma);
284 while (TMath::Abs(val-mean)>absMax)
285 val = fRnd.Gaus(mean,sigma);
289 //________________________________________________________________________
290 const char* AliITSMisalignMaker::GetSymbName(Int_t layer) const {
292 // be careful : SPD0 and SPD1 are not physically separated
297 case 1: name = fStrSPD; name += layer; break;
299 case 3: name = fStrSDD; name += layer; break;
301 case 5: name = fStrSSD; name += layer; break;
302 default: AliFatal("Wrong layer index");
307 //________________________________________________________________________
308 const char* AliITSMisalignMaker::GetSymbName(Int_t layer, Int_t ladder, Int_t det) const {
310 // symname from layer, ladder, detector
312 TString symname(GetHalfStaveLadderSymbName(layer,ladder,det));
318 AliError("Invalid layer!");
322 return symname.Data();
325 //________________________________________________________________________
326 const char* AliITSMisalignMaker::GetSymbName(Int_t layer,Int_t ladd) const {
328 // Get logical names at the level of staves / ladders
330 TString name(GetSymbName(layer));
331 if (layer==0) { // SPD1
336 int stave = ladd-sector*2;
340 else if (layer==1) { // SPD2
345 int stave = ladd-sector*4;
349 else if (layer>=2 && layer<=5) { // SDD and SSD
354 AliFatal("Wrong layer index");
359 //________________________________________________________________________
360 const char* AliITSMisalignMaker::GetHalfStaveLadderSymbName(Int_t layer,Int_t ladd,Int_t halfStave) const {
362 // Get logical names at the level of half-staves (SPD) or ladders (SDD and SSD)
364 TString name(GetSymbName(layer));
365 if (layer==0) { // SPD1
370 int stave = ladd-sector*2;
373 name += fStrHalfStave;
376 else if (layer==1) { // SPD2
381 int stave = ladd-sector*4;
384 name += fStrHalfStave;
387 else if (layer>=2 && layer<=5) { // SDD and SSD
392 AliFatal("Wrong layer index");
397 //________________________________________________________________________
398 const char* AliITSMisalignMaker::GetParentSymName(const char* symname) {
400 // symnane of parent volume
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,'/');
407 if(!parent.CountChar('/')) AliErrorClass("Not a valid symbolic name");
410 GetLayerAndLevel(symname,layer,level);
411 if(level==1) return "ITS";
413 parent.Remove(parent.Last('/'));
415 if((layer==0 || layer==1) && level==2){
416 parent.Remove(parent.Last('/'));
420 return parent.Data();
423 //________________________________________________________________________
424 Bool_t AliITSMisalignMaker::GetLayerAndLevel(const char* symname, Int_t &layer, Int_t &level) {
426 // given the symbolic name set layer and level
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);
437 if(strSym.BeginsWith(basename[i])) break;
441 AliErrorClass(Form("%s is not a valid symbolic name for an ITS alignable volume",strSym.Data()));
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
455 if(strSym.Contains("Stave")) level=2;
456 if(strSym.Contains("Ladder")) level=3;
462 if(strSym.Contains("Sensor")) level=2;
468 //________________________________________________________________________
469 Int_t AliITSMisalignMaker::GetNSisters(const char* symname) {
471 // number of volumes on same 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"));
482 //________________________________________________________________________
483 Int_t AliITSMisalignMaker::GetNDaughters(const char* symname) {
485 // number of daughter volumes
488 if(!GetLayerAndLevel(symname,layer,level)) return -1;
491 for(Int_t lay=0; lay<6; lay++) nLadders += GetNLadders(lay);
494 if(level==1) return GetNDetectors(layer);
496 AliWarningClass(Form("Volume %s is a sensitive volume and has no alignable dauthers",symname));
499 AliErrorClass(Form("Invalid layer and level"));
504 //________________________________________________________________________
505 TString AliITSMisalignMaker::GetSymbName(Int_t layer,Int_t ladd,Int_t mod) const {
507 // Get logical names at the level of SPD ladders / SDD and SSD modules
509 Int_t halfStave = mod/2;
510 TString name = GetHalfStaveLadderSymbName(layer,ladd,halfStave);
512 if (layer<2) { // SPD
516 else if (layer>=2 && layer<=5) { // SDD and SSD
521 AliFatal("Wrong layer index");