]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSMisalignMaker.cxx
bug fixed
[u/mrichter/AliRoot.git] / ITS / AliITSMisalignMaker.cxx
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
16 /* $Id$  */
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>
31 #include <TClass.h>
32
33
34 #include "AliLog.h"
35 #include "AliAlignObjParams.h"
36 #include "AliITSMisalignMaker.h"
37
38
39 ClassImp(AliITSMisalignMaker)
40   
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};
43
44
45 //________________________________________________________________________
46 AliITSMisalignMaker::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 {
59   //
60   // defaul constructor
61   //
62   fRnd.SetSeed(38217945);
63 }
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) {
67   //
68   // misalignment by symname
69   //
70   Double_t vx=0.,vy=0.,vz=0.,vpsi=0.,vtheta=0.,vphi=0.;
71
72   TString sdistrib(distrib);
73
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")){
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\""));
97   }
98
99   new(fAlobj[fInd]) AliAlignObjParams(name,0,vx,vy,vz,vpsi,vtheta,vphi,kFALSE);
100
101   AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
102   itsalobj->ApplyToGeometry();
103
104   fInd++;
105
106   return kTRUE;
107 }
108
109
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) {
113   //
114   // misalignment at the level of ladders/modules
115   //
116   lay+=1; // layers are numbered from 1 to 6 in AliGeomManager
117
118   printf("LAYER %d  MODULES %d\n",lay,AliGeomManager::LayerSize(lay));
119
120   for (Int_t iModule = 0; iModule < AliGeomManager::LayerSize(lay); iModule++) {
121
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);
138     }
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);
144     AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
145     itsalobj->ApplyToGeometry();
146     fInd++; 
147   }
148
149   return kTRUE;
150 }
151
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,
157                                        Bool_t unif) {
158   //
159   // misalignment at the level of half-staves/ladders (ladd=-1 means that all ladders are scanned)
160   //
161   Double_t vx,vy,vz,vpsi,vtheta,vphi;
162   Double_t tr[3],rot[3];  
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
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();
212       fInd++;
213     }
214   }
215   
216   return kTRUE;
217 }
218
219
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) {
226   //
227   // misalignment at the level of SPD sectors and half-barrels
228   // 
229
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
253     TString name(GetSymbName(0));
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
271     AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
272     itsalobj->ApplyToGeometry();
273     fInd++;
274   }
275   return kTRUE;
276 }
277
278 //________________________________________________________________________
279 Double_t AliITSMisalignMaker::GaussCut(Double_t mean,Double_t sigma,Double_t absMax) {
280   //
281   // random from gaussian with cut on tails
282   //
283   Double_t val = fRnd.Gaus(mean,sigma);
284   while (TMath::Abs(val-mean)>absMax)
285     val = fRnd.Gaus(mean,sigma);
286   return val;
287 }
288
289 //________________________________________________________________________
290 const char* AliITSMisalignMaker::GetSymbName(Int_t layer) const {
291   //
292   // be careful : SPD0 and SPD1 are not physically separated 
293   //
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   }
304   return name.Data();
305 }
306
307 //________________________________________________________________________
308 const 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 }
324
325 //________________________________________________________________________
326 const 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));
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;
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;
348   }
349   else if (layer>=2 && layer<=5) { // SDD and SSD
350     name += fStrLadder;
351     name += ladd;
352   }
353   else {
354     AliFatal("Wrong layer index");
355   }
356   return name.Data();
357 }
358
359 //________________________________________________________________________
360 const 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));
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;
373     name += fStrHalfStave;
374     name += halfStave;
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;
384     name += fStrHalfStave;
385     name += halfStave;
386   }
387   else if (layer>=2 && layer<=5) { // SDD and SSD
388     name += fStrLadder;
389     name += ladd;
390   } 
391   else {
392     AliFatal("Wrong layer index");
393   }
394   return name.Data();
395 }
396
397 //________________________________________________________________________
398 const 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 //________________________________________________________________________
424 Bool_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 //________________________________________________________________________
469 Int_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;
480 }
481
482 //________________________________________________________________________
483 Int_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
503 /*
504 //________________________________________________________________________
505 TString 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 }
525 */
526