]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSMisalignMaker.cxx
Just something left from v2...now clean
[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(23472341);
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,Bool_t unif) {
67   //
68   // misalignment by symname
69   //
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
90   AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
91   itsalobj->ApplyToGeometry();
92
93   fInd++;
94
95   return kTRUE;
96 }
97
98
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) {
102   //
103   // misalignment at the level of ladders/modules
104   //
105   lay+=1; // layers are numbered from 1 to 6 in AliGeomManager
106
107   printf("LAYER %d  MODULES %d\n",lay,AliGeomManager::LayerSize(lay));
108
109   for (Int_t iModule = 0; iModule < AliGeomManager::LayerSize(lay); iModule++) {
110
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);
127     }
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);
133     AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
134     itsalobj->ApplyToGeometry();
135     fInd++; 
136   }
137
138   return kTRUE;
139 }
140
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,
146                                        Bool_t unif) {
147   //
148   // misalignment at the level of half-staves/ladders (ladd=-1 means that all ladders are scanned)
149   //
150   Double_t vx,vy,vz,vpsi,vtheta,vphi;
151   Double_t tr[3],rot[3];  
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
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();
201       fInd++;
202     }
203   }
204   
205   return kTRUE;
206 }
207
208
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) {
215   //
216   // misalignment at the level of SPD sectors and half-barrels
217   // 
218
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
242     TString name(GetSymbName(0));
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
260     AliAlignObjParams* itsalobj = (AliAlignObjParams*) fAlobj.UncheckedAt(fInd);
261     itsalobj->ApplyToGeometry();
262     fInd++;
263   }
264   return kTRUE;
265 }
266
267 //________________________________________________________________________
268 Double_t AliITSMisalignMaker::GaussCut(Double_t mean,Double_t sigma,Double_t absMax) {
269   //
270   // random from gaussian with cut on tails
271   //
272   Double_t val = fRnd.Gaus(mean,sigma);
273   while (TMath::Abs(val-mean)>absMax)
274     val = fRnd.Gaus(mean,sigma);
275   return val;
276 }
277
278 //________________________________________________________________________
279 const char* AliITSMisalignMaker::GetSymbName(Int_t layer) const {
280   //
281   // be careful : SPD0 and SPD1 are not physically separated 
282   //
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   }
293   return name.Data();
294 }
295
296 //________________________________________________________________________
297 const 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 }
313
314 //________________________________________________________________________
315 const 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));
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;
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;
337   }
338   else if (layer>=2 && layer<=5) { // SDD and SSD
339     name += fStrLadder;
340     name += ladd;
341   }
342   else {
343     AliFatal("Wrong layer index");
344   }
345   return name.Data();
346 }
347
348 //________________________________________________________________________
349 const 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));
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;
362     name += fStrHalfStave;
363     name += halfStave;
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;
373     name += fStrHalfStave;
374     name += halfStave;
375   }
376   else if (layer>=2 && layer<=5) { // SDD and SSD
377     name += fStrLadder;
378     name += ladd;
379   } 
380   else {
381     AliFatal("Wrong layer index");
382   }
383   return name.Data();
384 }
385
386 //________________________________________________________________________
387 const 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 //________________________________________________________________________
413 Bool_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 //________________________________________________________________________
458 Int_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;
469 }
470
471 //________________________________________________________________________
472 Int_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
492 /*
493 //________________________________________________________________________
494 TString 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 }
514 */
515