bug fixed
[u/mrichter/AliRoot.git] / MUON / AliMUONSurveyUtil.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, 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 //-----------------------------------------------------------------------------
17 /// \class AliMUONSurveyUtil
18 /// Singleton utility class for the survey processing of the ALICE DiMuon spectrometer 
19 /// 
20 /// This class contains various functions to calculate misalignement parameters
21 /// from survey data and designed positions of survey targets.
22 /// Macro also includes a method to get the new AliMUONGeometryTranformer.
23 /// 
24 /// \author Javier Castillo
25 //-----------------------------------------------------------------------------
26
27 #include <TClonesArray.h>
28 #include <TMath.h>
29 #include <TMatrixDSym.h>
30 #include <TString.h>
31
32 #include "AliAlignObjMatrix.h"
33
34 #include "AliMUONSurveyUtil.h"
35 #include "AliMUONGeometryTransformer.h"
36 #include "AliMUONGeometryModuleTransformer.h"
37 #include "AliMUONGeometryDetElement.h"
38 #include "AliMUONGeometryBuilder.h"
39 #include "AliMpExMap.h"
40 #include "AliMpExMapIterator.h"
41
42 /// \cond CLASSIMP
43 ClassImp(AliMUONSurveyUtil)
44 /// \endcond
45
46 int AliMUONSurveyUtil::fgNDetElemCh[10] = {4,4,4,4,18,18,26,26,26,26};
47 AliMUONSurveyUtil* AliMUONSurveyUtil::fgInstance(0x0);
48
49 AliMUONSurveyUtil::~AliMUONSurveyUtil(){
50   printf("WHAT AM I DOING HERE????????????????\n");
51   fgInstance = 0x0;
52 }
53
54 AliMUONSurveyUtil* AliMUONSurveyUtil::Instance() {
55   ///  Return its instance 
56   if (!fgInstance) 
57     fgInstance = new AliMUONSurveyUtil();
58   
59   return fgInstance;
60 }
61
62 Bool_t AliMUONSurveyUtil::MatrixToAngles(const Double_t *rot, Double_t *angles)
63 {
64   /// Calculates the Euler angles in "x y z" notation
65   /// using the rotation matrix
66   /// Returns false in case the rotation angles can not be
67
68   // extracted from the matrix
69   //
70   if(TMath::Abs(rot[0])<1e-7 || TMath::Abs(rot[8])<1e-7) {
71     printf("Failed to extract roll-pitch-yall angles!");
72     return kFALSE;
73   }
74   //   Double_t raddeg = TMath::RadToDeg();
75   angles[0]=TMath::ATan2(-rot[5],rot[8]);
76   angles[1]=TMath::ASin(rot[2]);
77   angles[2]=TMath::ATan2(-rot[1],rot[0]);
78   return kTRUE;
79 }
80
81 void AliMUONSurveyUtil::AnglesToMatrix(const Double_t *angles, Double_t *rot)
82 {
83   /// Calculates the rotation matrix using the 
84   /// Euler angles in "x y z" notation
85   ///
86   //  Double_t degrad = TMath::DegToRad();
87   Double_t degrad = 1.;
88   Double_t sinpsi = TMath::Sin(degrad*angles[0]);
89   Double_t cospsi = TMath::Cos(degrad*angles[0]);
90   Double_t sinthe = TMath::Sin(degrad*angles[1]);
91   Double_t costhe = TMath::Cos(degrad*angles[1]);
92   Double_t sinphi = TMath::Sin(degrad*angles[2]);
93   Double_t cosphi = TMath::Cos(degrad*angles[2]);
94
95   rot[0] =  costhe*cosphi;
96   rot[1] = -costhe*sinphi;
97   rot[2] =  sinthe;
98   rot[3] =  sinpsi*sinthe*cosphi + cospsi*sinphi;
99   rot[4] = -sinpsi*sinthe*sinphi + cospsi*cosphi;
100   rot[5] = -costhe*sinpsi;
101   rot[6] = -cospsi*sinthe*cosphi + sinpsi*sinphi;
102   rot[7] =  cospsi*sinthe*sinphi + sinpsi*cosphi;
103   rot[8] =  costhe*cospsi;
104 }
105
106 Double_t AliMUONSurveyUtil::XpCenter(const Double_t *x, const Double_t *par) const{
107   /// Returns center x position using x coord. of 2 button targets. + solution. 
108   Double_t lCos2Tht = TMath::Cos(2*par[6]);
109   Double_t lSinTht = TMath::Sin(par[6]);
110
111   Double_t inSqrt = TMath::Abs((par[0] - par[3])*(par[0] - par[3]) 
112                                -2*(x[0] -x[1])*(x[0] -x[1]) 
113                                +(par[1] - par[4] + par[2] - par[5])*(par[1] - par[4] - par[2] + par[5]) 
114                                +((par[0] - par[3])*(par[0] - par[3]) 
115                                  +(par[1] - par[4])*(par[1] - par[4]) 
116                                  +(par[2] - par[5])*(par[2] - par[5]))*lCos2Tht 
117                                +4*(x[0] - x[1])*(par[2] - par[5])*lSinTht);
118
119   if (inSqrt<0) return inSqrt*1e10;
120
121   Double_t xD = ((2*(par[0]*par[0]*x[1] 
122                      -par[0]*par[3]*(x[0] + x[1]) 
123                      +x[1]*par[1]*(par[1] - par[4]) 
124                      +x[0]*(par[3]*par[3] - par[1]*par[4] + par[4]*par[4])) 
125                   -2*(par[3]*par[3]*par[2] 
126                       +par[0]*par[0]*par[5] 
127                       -par[0]*par[3]*(par[2] + par[5]) 
128                       +(par[1] - par[4])*(-par[4]*par[2] +par[1]*par[5]))*lSinTht 
129                   +TMath::Sqrt(2)*(-par[3]*par[1] + par[0]*par[4])
130                   *TMath::Sqrt(inSqrt))
131                  /(2*((par[0] - par[3])*(par[0] - par[3]) + (par[1] - par[4])*(par[1] - par[4]))));
132
133   return xD;
134 }
135
136 Double_t AliMUONSurveyUtil::XnCenter(const Double_t *x, const Double_t *par) const{
137   /// Returns center x position using x coord. of 2 button targets. - solution. 
138   Double_t lCos2Tht = TMath::Cos(2*par[6]);
139   Double_t lSinTht = TMath::Sin(par[6]);
140
141   Double_t inSqrt = TMath::Abs((par[0] - par[3])*(par[0] - par[3]) 
142                                -2*(x[0] - x[1])*(x[0] - x[1]) 
143                                +(par[1] - par[4] + par[2] - par[5])*(par[1] - par[4] - par[2] + par[5]) 
144                                +((par[0] - par[3])*(par[0] - par[3]) 
145                                  +(par[1] - par[4])*(par[1] - par[4]) 
146                                  +(par[2] - par[5])*(par[2] - par[5]))*lCos2Tht
147                                +4*(x[0] - x[1])*(par[2] - par[5])*lSinTht);
148
149   if (inSqrt<0) return inSqrt*1e10;
150
151   Double_t xD = ((2*(par[0]*par[0]*x[1] 
152                      -par[0]*par[3]*(x[0] + x[1]) 
153                      +x[1]*par[1]*(par[1] - par[4]) 
154                      +x[0]*(par[3]*par[3] - par[1]*par[4] + par[4]*par[4])) 
155                   -2*(par[3]*par[3]*par[2] + par[0]*par[0]*par[5] 
156                       -par[0]*par[3]*(par[2] + par[5]) 
157                       +(par[1] - par[4])*(-par[4]*par[2] + par[1]*par[5]))*lSinTht 
158                   +TMath::Sqrt(2)*(par[3]*par[1] - par[0]*par[4])
159                   *TMath::Sqrt(inSqrt))
160                  /(2*((par[0] - par[3])*(par[0] - par[3]) + (par[1] - par[4])*(par[1] - par[4]))));
161
162   return xD;
163 }
164
165 Double_t AliMUONSurveyUtil::PhiXpn(const Double_t *x, const Double_t *par) const{
166   /// Returns phi rot. using x coord. of 2 button targets. +- solution. 
167   Double_t inSqrt = TMath::Abs(((par[0] - par[3])*(par[0] - par[3]) 
168                                 -2*(x[0] - x[1])*(x[0] - x[1]) 
169                                 +(par[1] - par[4] + par[2] - par[5])*(par[1] - par[4] - par[2] + par[5]) 
170                                 +(+(par[0] - par[3])*(par[0] - par[3]) 
171                                   +(par[1] - par[4])*(par[1] - par[4]) 
172                                   +(par[2] - par[5])*(par[2] - par[5]))*TMath::Cos(2*par[6]) 
173                                 +4*(x[0] - x[1])*(par[2] - par[5])*TMath::Sin(par[6])));
174
175   if (inSqrt<0) return inSqrt*1e10;
176   
177   Double_t phix = ((+2*(par[0] - par[3])*(x[0] - x[1]) 
178                     -2*(par[0] - par[3])*(par[2] - par[5])*TMath::Sin(par[6]) 
179                     +TMath::Sqrt(2)*(par[1] - par[4])
180                     *TMath::Sqrt(inSqrt))
181                    /(2*(+(par[0] - par[3])*(par[0] - par[3]) 
182                         +(par[1] - par[4])*(par[1] - par[4]))*TMath::Cos(par[6])));
183
184   phix = -TMath::ACos(phix);
185
186   return phix;
187 }
188
189 Double_t AliMUONSurveyUtil::PhiXpp(const Double_t *x, const Double_t *par) const{
190   /// Returns phi rot. using x coord. of 2 button targets. ++ solution. 
191   Double_t inSqrt = TMath::Abs(+(par[0] - par[3])*(par[0] - par[3]) 
192                                -2*(x[0] - x[1])*(x[0] - x[1]) 
193                                +(par[1] - par[4] + par[2] - par[5])*(par[1] - par[4] - par[2] + par[5]) 
194                                +(+(par[0] - par[3])*(par[0] - par[3]) 
195                                  +(par[1] - par[4])*(par[1] - par[4]) 
196                                  +(par[2] - par[5])*(par[2] - par[5]))*TMath::Cos(2*par[6]) 
197                                +4*(x[0] - x[1])*(par[2] - par[5])*TMath::Sin(par[6]));
198
199   if (inSqrt<0) return inSqrt*1e10;
200
201   Double_t phix = ((+2*(par[0] - par[3])*(x[0] - x[1]) 
202                     -2*(par[0] - par[3])*(par[2] - par[5])*TMath::Sin(par[6]) 
203                     +TMath::Sqrt(2)*(par[1] - par[4])
204                     *TMath::Sqrt(inSqrt))
205                    /(2*(+(par[0] - par[3])*(par[0] - par[3]) 
206                         +(par[1] - par[4])*(par[1] - par[4]))*TMath::Cos(par[6])));
207
208   phix = TMath::ACos(phix);
209
210   return phix;
211 }
212
213 Double_t AliMUONSurveyUtil::PhiXnn(const Double_t *x, const Double_t *par) const{
214   /// Returns phi rot. using x coord. of 2 button targets. -- solution. 
215   Double_t inSqrt = TMath::Abs(+(par[0] - par[3])*(par[0] - par[3]) 
216                                -2*(x[0] - x[1])*(x[0] - x[1]) 
217                                +(par[1] - par[4] + par[2] - par[5])*(par[1] - par[4] - par[2] + par[5]) 
218                                +(+(par[0] - par[3])*(par[0] - par[3]) 
219                                  +(par[1] - par[4])*(par[1] - par[4]) 
220                                  +(par[2] - par[5])*(par[2] - par[5]))*TMath::Cos(2*par[6]) 
221                                + 4*(x[0] - x[1])*(par[2] - par[5])*TMath::Sin(par[6]));
222
223   if (inSqrt<0) return inSqrt*1e10;
224   
225   Double_t phix = (+(+2*(par[0] - par[3])*(x[0] - x[1]) 
226                      -2*(par[0] - par[3])*(par[2] - par[5])*TMath::Sin(par[6]) 
227                      +TMath::Sqrt(2)*(-par[1] + par[4])
228                      *TMath::Sqrt(inSqrt))
229                    /(2*(+(par[0] - par[3])*(par[0] - par[3]) 
230                         +(par[1] - par[4])*(par[1] - par[4]))*TMath::Cos(par[6])));
231
232   phix = -TMath::ACos(phix);
233
234   return phix;
235 }
236
237 Double_t AliMUONSurveyUtil::PhiXnp(const Double_t *x, const Double_t *par) const{
238   /// Returns phi rot. using x coord. of 2 button targets. +- solution. 
239   Double_t inSqrt = TMath::Abs(+(par[0] - par[3])*(par[0] - par[3]) 
240                                -2*(x[0] - x[1])*(x[0] - x[1]) 
241                                +(par[1] - par[4] + par[2] - par[5])*(par[1] - par[4] - par[2] + par[5]) 
242                                +(+(par[0] - par[3])*(par[0] - par[3]) 
243                                  +(par[1] - par[4])*(par[1] - par[4]) 
244                                  +(par[2] - par[5])*(par[2] - par[5]))*TMath::Cos(2*par[6]) 
245                                +4*(x[0] - x[1])*(par[2] - par[5])*TMath::Sin(par[6]));
246
247   if (inSqrt<0) return inSqrt*1e10;
248
249   Double_t phix = (+(+2*(par[0] - par[3])*(x[0] - x[1]) 
250                      -2*(par[0] - par[3])*(par[2] - par[5])*TMath::Sin(par[6]) 
251                      +TMath::Sqrt(2)*(-par[1] + par[4])
252                      *TMath::Sqrt(inSqrt))
253                    /(2*(+(par[0] - par[3])*(par[0] - par[3]) 
254                         +(par[1] - par[4])*(par[1] - par[4]))*TMath::Cos(par[6])));
255
256   phix = TMath::ACos(phix);
257
258   return phix;
259 }
260
261 Double_t AliMUONSurveyUtil::YpCenter(const Double_t *x, const Double_t *par) const{
262   /// Returns center y position using y coord. of 2 button targets. + solution. 
263
264   // par : x1l, y1l, z1l, x2l, y2l, z2, lpsi, tht,
265   Double_t lCosPsi = TMath::Cos(par[6]);
266   Double_t lSinPsi = TMath::Sin(par[6]);
267   Double_t lCosTht = TMath::Cos(par[7]);
268   Double_t lSinTht = TMath::Sin(par[7]);
269
270   Double_t yD = ((1./((par[0] - par[3])*(par[0] - par[3]) + (par[1] - par[4])*(par[1] - par[4])))
271                  *(+par[3]*par[3]*x[0] 
272                    +par[0]*par[0]*x[1] 
273                    -par[0]*par[3]*(x[0] + x[1]) 
274                    +(par[1] - par[4])*(-x[0]*par[4] + par[1]*x[1]) 
275                    +(par[3]*par[3]*par[2] 
276                      +par[0]*par[0]*par[5] 
277                      -par[0]*par[3]*(par[2] + par[5]) 
278                      +(par[1] - par[4])*(-par[4]*par[2] + par[1]*par[5]))*lCosTht*lSinPsi 
279                    +(-par[3]*par[1] + par[0]*par[4])
280                    *TMath::Sqrt(-(x[0] - x[1] 
281                                   +(par[2] - par[5])*lCosTht*lSinPsi)
282                                 *(x[0] - x[1] 
283                                   +(par[2] - par[5])*lCosTht*lSinPsi) 
284                                 + ((par[0] - par[3])*(par[0] - par[3]) 
285                                    +(par[1] - par[4])*(par[1] - par[4]))*(lCosPsi*lCosPsi 
286                                                                           +lSinPsi*lSinPsi*lSinTht*lSinTht))));
287
288   return yD;  
289 }
290
291 Double_t AliMUONSurveyUtil::PhiYpn(const Double_t *x, const Double_t *par) const{
292   /// Returns phi rot. using y coord. of 2 button targets. +- solution. 
293
294   Double_t lCosPsi = TMath::Cos(par[6]);
295   Double_t lSinPsi = TMath::Sin(par[6]);
296   Double_t lCosTht = TMath::Cos(par[7]);
297   Double_t lSinTht = TMath::Sin(par[7]);
298
299   Double_t phiy = ((lCosPsi*((par[1] - par[4])*(x[0] - x[1]) 
300                              +(par[1] - par[4])*(par[2] - par[5])*lCosTht*lSinPsi 
301                              +(-par[0] + par[3])
302                              *TMath::Sqrt(-(x[0] - x[1] 
303                                             +(par[2] - par[5])*lCosTht*lSinPsi)
304                                           *(x[0] - x[1] 
305                                             +(par[2] - par[5])*lCosTht*lSinPsi) 
306                                           +(+(par[0] - par[3])*(par[0] - par[3]) 
307                                             +(par[1] - par[4])*(par[1] - par[4]))*(lCosPsi*lCosPsi
308                                                                                    +lSinPsi*lSinPsi*lSinTht*lSinTht))) 
309                     +lSinPsi*lSinTht*((par[0] - par[3])*(x[0] - x[1]) 
310                                       +(par[0] - par[3])*(par[2] - par[5])*lCosTht*lSinPsi 
311                                       +(par[1] - par[4])
312                                       *TMath::Sqrt(-(x[0] - x[1] 
313                                                      +(par[2] - par[5])*lCosTht*lSinPsi)
314                                                    *(x[0] - x[1] 
315                                                      +(par[2] - par[5])*lCosTht*lSinPsi) 
316                                                    + ((par[0] - par[3])*(par[0] - par[3]) 
317                                                       +(par[1] - par[4])*(par[1] - par[4]))*(lCosPsi*lCosPsi 
318                                                                                              +lSinPsi*lSinPsi*lSinTht*lSinTht))))
319                    /((+(par[0] - par[3])*(par[0] - par[3]) 
320                       +(par[1] - par[4])*(par[1] - par[4]))*(lCosPsi*lCosPsi 
321                                                              +lSinPsi*lSinPsi*lSinTht*lSinTht)));
322   
323   phiy = -TMath::ACos(phiy);
324
325
326   return phiy;
327 }
328
329 Double_t AliMUONSurveyUtil::PhiYpp(const Double_t *x, const Double_t *par) const{
330   /// Returns phi rot. using y coord. of 2 button targets. ++ solution. 
331
332   Double_t lCosPsi = TMath::Cos(par[6]);
333   Double_t lSinPsi = TMath::Sin(par[6]);
334   Double_t lCosTht = TMath::Cos(par[7]);
335   Double_t lSinTht = TMath::Sin(par[7]);
336
337   Double_t phiy = ((lCosPsi*((par[1] - par[4])*(x[0] - x[1]) 
338                              +(par[1] - par[4])*(par[2] - par[5])*lCosTht*lSinPsi 
339                              +(-par[0] + par[3])
340                              *TMath::Sqrt(-(x[0] - x[1] 
341                                             +(par[2] - par[5])*lCosTht*lSinPsi)
342                                           *(x[0] - x[1] 
343                                             +(par[2] - par[5])*lCosTht*lSinPsi) 
344                                           +((par[0] - par[3])*(par[0] - par[3]) 
345                                             +(par[1] - par[4])*(par[1] - par[4]))*(lCosPsi*lCosPsi 
346                                                                                    +lSinPsi*lSinPsi*lSinTht*lSinTht))) 
347                     +lSinPsi*lSinTht*((par[0] - par[3])*(x[0] - x[1]) 
348                                       +(par[0] - par[3])*(par[2] - par[5])*lCosTht*lSinPsi 
349                                       +(par[1] - par[4])*TMath::Sqrt(-(x[0] - x[1] 
350                                                                        +(par[2] - par[5])*lCosTht*lSinPsi)
351                                                                      *(x[0] - x[1] 
352                                                                        +(par[2] - par[5])*lCosTht*lSinPsi) 
353                                                                      +((par[0] - par[3])*(par[0] - par[3])
354                                                                        +(par[1] - par[4])*(par[1] - par[4]))*(lCosPsi*lCosPsi 
355                                                                                                               +lSinPsi*lSinPsi*lSinTht*lSinTht))))
356                    /(((par[0] - par[3])*(par[0] - par[3]) 
357                       +(par[1] - par[4])*(par[1] - par[4]))*(lCosPsi*lCosPsi 
358                                                              +lSinPsi*lSinPsi*lSinTht*lSinTht)));
359   
360   phiy = TMath::ACos(phiy);
361
362   return phiy;
363 }
364  
365 Double_t AliMUONSurveyUtil::YnCenter(const Double_t *x, const Double_t *par) const{
366   /// Returns center y position using y coord. of 2 button targets. - solution. 
367   Double_t lCosPsi = TMath::Cos(par[6]);
368   Double_t lSinPsi = TMath::Sin(par[6]);
369   Double_t lCosTht = TMath::Cos(par[7]);
370   Double_t lSinTht = TMath::Sin(par[7]);
371
372   Double_t yD = ((1./(+(par[0] - par[3])*(par[0] - par[3]) 
373                       +(par[1] - par[4])*(par[1] - par[4])))
374                  *(+par[3]*par[3]*x[0] 
375                    +par[0]*par[0]*x[1] 
376                    -par[0]*par[3]*(x[0] + x[1]) 
377                    +(par[1] - par[4])*(-x[0]*par[4] + par[1]*x[1]) 
378                    +(+par[3]*par[3]*par[2] 
379                      +par[0]*par[0]*par[5] 
380                      -par[0]*par[3]*(par[2] + par[5]) 
381                      +(par[1] - par[4])*(-par[4]*par[2] + par[1]*par[5]))*lCosTht*lSinPsi 
382                    +(par[3]*par[1] - par[0]*par[4])
383                    *TMath::Sqrt(-(+x[0] - x[1] 
384                                   +(par[2] - par[5])*lCosTht*lSinPsi)
385                                 *(x[0] - x[1] 
386                                   +(par[2] - par[5])*lCosTht*lSinPsi) 
387                                 +((par[0] - par[3])*(par[0] - par[3]) 
388                                   +(par[1] - par[4])*(par[1] - par[4]))*(+lCosPsi*lCosPsi 
389                                                                          +lSinPsi*lSinPsi*lSinTht*lSinTht))));
390   
391   return yD;  
392 }
393  
394
395 Double_t AliMUONSurveyUtil::PhiYnn(const Double_t *x, const Double_t *par) const{
396   /// Returns phi rot. using y coord. of 2 button targets. -- solution. 
397
398   Double_t lCosPsi = TMath::Cos(par[6]);
399   Double_t lSinPsi = TMath::Sin(par[6]);
400   Double_t lCosTht = TMath::Cos(par[7]);
401   Double_t lSinTht = TMath::Sin(par[7]);
402
403   Double_t phiy = ((lCosPsi*(+(par[1] - par[4])*(x[0] - x[1]) 
404                              +(par[1] - par[4])*(par[2] - par[5])*lCosTht*lSinPsi 
405                              +(par[0] - par[3])
406                              *TMath::Sqrt(-(x[0] - x[1] 
407                                             +(par[2] - par[5])*lCosTht*lSinPsi)
408                                           *(x[0] - x[1] 
409                                             +(par[2] - par[5])*lCosTht*lSinPsi) 
410                                           +(+(par[0] - par[3])*(par[0] - par[3]) 
411                                             +(par[1] - par[4])*(par[1] - par[4]))*(+lCosPsi*lCosPsi 
412                                                                                    +lSinPsi*lSinPsi*lSinTht*lSinTht))) 
413                     +lSinPsi*lSinTht*(+(par[0] - par[3])*(x[0] - x[1]) 
414                                       +(par[0] - par[3])*(par[2] - par[5])*lCosTht*lSinPsi 
415                                       +(-par[1] + par[4])
416                                       *TMath::Sqrt(-(x[0] - x[1] 
417                                                      +(par[2] - par[5])*lCosTht*lSinPsi)
418                                                    *(x[0] - x[1] 
419                                                      +(par[2] - par[5])*lCosTht*lSinPsi) 
420                                                    +(+(par[0] - par[3])*(par[0] - par[3]) 
421                                                      +(par[1] - par[4])*(par[1] - par[4]))*(+lCosPsi*lCosPsi 
422                                                                                             +lSinPsi*lSinPsi*lSinTht*lSinTht))))
423                    /((+(par[0] - par[3])*(par[0] - par[3]) 
424                       +(par[1] - par[4])*(par[1] - par[4]))*(+lCosPsi*lCosPsi 
425                                                              +lSinPsi*lSinPsi*lSinTht*lSinTht)));
426   
427   phiy = -TMath::ACos(phiy);
428   
429   return phiy;
430 }
431
432
433 Double_t AliMUONSurveyUtil::PhiYnp(const Double_t *x, const Double_t *par) const{
434   /// Returns phi rot. using y coord. of 2 button targets. -+ solution. 
435
436   Double_t lCosPsi = TMath::Cos(par[6]);
437   Double_t lSinPsi = TMath::Sin(par[6]);
438   Double_t lCosTht = TMath::Cos(par[7]);
439   Double_t lSinTht = TMath::Sin(par[7]);
440
441   Double_t phiy = ((lCosPsi*(+(par[1] - par[4])*(x[0] - x[1]) 
442                              +(par[1] - par[4])*(par[2] - par[5])*lCosTht*lSinPsi 
443                              +(par[0] - par[3])
444                              *TMath::Sqrt(-(x[0] - x[1] 
445                                             +(par[2] - par[5])*lCosTht*lSinPsi)
446                                           *(x[0] - x[1] 
447                                             +(par[2] - par[5])*lCosTht*lSinPsi) 
448                                           +((par[0] - par[3])*(par[0] - par[3]) 
449                                             +(par[1] - par[4])*(par[1] - par[4]))*(+lCosPsi*lCosPsi 
450                                                                                    +lSinPsi*lSinPsi*lSinTht*lSinTht))) 
451                     +lSinPsi*lSinTht*(+(par[0] - par[3])*(x[0] - x[1]) 
452                                       +(par[0] - par[3])*(par[2] - par[5])*lCosTht*lSinPsi 
453                                       +(-par[1] + par[4])
454                                       *TMath::Sqrt(-(x[0] - x[1] 
455                                                      +(par[2] - par[5])*lCosTht*lSinPsi)
456                                                    *(x[0] - x[1] 
457                                                      +(par[2] - par[5])*lCosTht*lSinPsi) 
458                                                    +((par[0] - par[3])*(par[0] - par[3]) 
459                                                      +(par[1] - par[4])*(par[1] - par[4]))*(+lCosPsi*lCosPsi 
460                                                                                             +lSinPsi*lSinPsi*lSinTht*lSinTht))))
461                    /((+(par[0] - par[3])*(par[0] - par[3])
462                       +(par[1] - par[4])*(par[1] - par[4]))*(+lCosPsi*lCosPsi 
463                                                              +lSinPsi*lSinPsi*lSinTht*lSinTht)));
464   
465   phiy = TMath::ACos(phiy);
466   
467   return phiy;
468 }
469
470 Double_t AliMUONSurveyUtil::ZnCenter(const Double_t *x, const Double_t *par) const{
471   /// Returns center z position using z coord. of 2 button targets. - solution. 
472
473   // par :  x1l, y1l, z1l, x2l, y2l, z2l, psi, tht
474   Double_t lCosPsi = TMath::Cos(par[6]);
475   Double_t lSinPsi = TMath::Sin(par[6]);
476   Double_t lCosTht = TMath::Cos(par[7]);
477   Double_t lSinTht = TMath::Sin(par[7]);
478
479   Double_t inSqrt = ((par[3]*par[1] - par[0]*par[4])*(par[3]*par[1] - par[0]*par[4])
480                      *((-(x[0] - x[1])*(x[0] - x[1]))
481                        +(((par[0] - par[3])*(par[0] - par[3])
482                           +(par[1] - par[4])*(par[1] - par[4])))*lSinPsi*lSinPsi
483                        +lCosPsi*((-(par[2] - par[5]))
484                                  *lCosTht*(-2*x[0]+2*x[1]
485                                            +(par[2] - par[5])*lCosPsi*lCosTht)
486                                  +((par[0] - par[3])*(par[0] - par[3])
487                                    +(par[1] - par[4])*(par[1] - par[4]))*lCosPsi*lSinTht*lSinTht)));
488
489   if (inSqrt<0) return inSqrt*1e10;
490
491   Double_t zD = ((1./((par[0] - par[3])*(par[0] - par[3]) 
492                       +(par[1] - par[4])*(par[1] - par[4])))
493                  *(-par[1]*par[4]*x[0] 
494                    +par[4]*par[4]*x[0] 
495                    +par[0]*par[0]*x[1] 
496                    +par[1]*par[1]*x[1] 
497                    -par[1]*par[4]*x[1] 
498                    -par[0]*par[3]*(x[0] + x[1]) 
499                    +par[3]*par[3]*x[0]
500                    +(+par[1]*par[4]*par[2] 
501                      -par[4]*par[4]*par[2] 
502                      -par[0]*par[0]*par[5] 
503                      -par[1]*par[1]*par[5] 
504                      +par[1]*par[4]*par[5] 
505                      +par[0]*par[3]*(par[2] + par[5])
506                      -par[3]*par[3]*par[2])*lCosPsi*lCosTht
507                    -TMath::Sqrt(inSqrt)));
508   
509   return zD;
510 }
511
512 Double_t AliMUONSurveyUtil::ZpCenter(const Double_t *x, const Double_t *par) const{
513   /// Returns center z position using z coord. of 2 button targets. + solution. 
514
515   // par :  x1l, y1l, z1l, x2l, y2l, z2l, psi, tht
516   Double_t lCosPsi = TMath::Cos(par[6]);
517   Double_t lSinPsi = TMath::Sin(par[6]);
518   Double_t lCosTht = TMath::Cos(par[7]);
519   Double_t lSinTht = TMath::Sin(par[7]);
520
521   Double_t inSqrt = ((par[3]*par[1] - par[0]*par[4])*(par[3]*par[1] - par[0]*par[4])
522                      *((-(x[0] - x[1])*(x[0] - x[1]))
523                        +(((par[0] - par[3])*(par[0] - par[3])
524                           +(par[1] - par[4])*(par[1] - par[4])))*lSinPsi*lSinPsi
525                        +lCosPsi*((-(par[2] - par[5]))
526                                  *lCosTht*(-2*x[0]+2*x[1]
527                                            +(par[2] - par[5])*lCosPsi*lCosTht)
528                                  +((par[0] - par[3])*(par[0] - par[3])
529                                    +(par[1] - par[4])*(par[1] - par[4]))*lCosPsi*lSinTht*lSinTht)));
530
531   if (inSqrt<0) return inSqrt*1e10;  
532
533   Double_t zD = ((1./((par[0] - par[3])*(par[0] - par[3]) 
534                       +(par[1] - par[4])*(par[1] - par[4])))
535                  *(-par[1]*par[4]*x[0] 
536                    +par[4]*par[4]*x[0] 
537                    +par[0]*par[0]*x[1] 
538                    +par[1]*par[1]*x[1] 
539                    -par[1]*par[4]*x[1] 
540                    -par[0]*par[3]*(x[0] + x[1]) 
541                    +par[3]*par[3]*x[0]
542                    +(+par[1]*par[4]*par[2] 
543                      -par[4]*par[4]*par[2] 
544                      -par[0]*par[0]*par[5] 
545                      -par[1]*par[1]*par[5] 
546                      +par[1]*par[4]*par[5] 
547                      +par[0]*par[3]*(par[2] + par[5])
548                      -par[3]*par[3]*par[2])*lCosPsi*lCosTht
549                    +TMath::Sqrt(inSqrt)));
550
551   return zD;
552 }
553
554 //______________________________________________________________________
555 AliMUONGeometryTransformer* AliMUONSurveyUtil::ReAlign(const AliMUONGeometryTransformer * transformer, 
556                                                        int rMod, int rNDetElems, int rDetElemPseudoIdToDetElem[], TGeoCombiTrans deltaDetElemTransf[], Bool_t verbose)
557 {
558   /////////////////////////////////////////////////////////////////////
559   ///   Takes the internal geometry module transformers, copies them
560   /// and gets the Detection Elements from them.
561   /// Takes misalignment parameters and applies these
562   /// to the local transform of the Detection Element
563   /// Obtains the global transform by multiplying the module transformer
564   /// transformation with the local transformation 
565   /// Applies the global transform to a new detection element
566   /// Adds the new detection element to a new module transformer
567   /// Adds the new module transformer to a new geometry transformer
568   /// Returns the new geometry transformer
569
570   Int_t iDetElemId = 0;
571   Int_t iDetElemPseudoId = 0;
572
573   AliMUONGeometryTransformer *newGeometryTransformer =
574     new AliMUONGeometryTransformer();
575   for (Int_t iMt = 0; iMt < transformer->GetNofModuleTransformers(); iMt++) {
576     // module transformers    
577     const AliMUONGeometryModuleTransformer *kModuleTransformer =
578       transformer->GetModuleTransformer(iMt, true);
579       
580     AliMUONGeometryModuleTransformer *newModuleTransformer =
581       new AliMUONGeometryModuleTransformer(iMt);
582     newGeometryTransformer->AddModuleTransformer(newModuleTransformer);
583     
584     TGeoCombiTrans moduleTransform =
585       TGeoCombiTrans(*kModuleTransformer->GetTransformation());
586     // New module transformation
587     TGeoCombiTrans *newModuleTransform;
588     if ((rMod<4 && iMt==rMod) || (rMod>=4 && (iMt==4+(rMod-4)*2||iMt==4+(rMod-4)*2+1))) {
589       newModuleTransform = new TGeoCombiTrans(moduleTransform*deltaDetElemTransf[rNDetElems]);
590     } else {
591       newModuleTransform = new TGeoCombiTrans(moduleTransform);
592     }
593     newModuleTransformer->SetTransformation(*newModuleTransform);
594     
595     // For the selected chamber add misalign module
596     if ((rMod<4 && iMt==rMod) || (rMod>=4 && (iMt==4+(rMod-4)*2||iMt==4+(rMod-4)*2+1))) {
597       // Get delta transformation: 
598       // Tdelta = Tnew * Told.inverse
599       TGeoHMatrix deltaModuleTransform = 
600         AliMUONGeometryBuilder::Multiply(*newModuleTransform, 
601                                          kModuleTransformer->GetTransformation()->Inverse());    
602       // Create module mis alignment matrix
603       newGeometryTransformer
604         ->AddMisAlignModule(kModuleTransformer->GetModuleId(), deltaModuleTransform);
605     }
606     
607     AliMpExMap *detElements = kModuleTransformer->GetDetElementStore();
608     
609     if (verbose)
610       printf("%i DEs in old GeometryStore  %i\n",detElements->GetSize(), iMt);
611     TGeoCombiTrans *deltaLocalTransform;
612     TIter next(detElements->CreateIterator());
613     AliMUONGeometryDetElement *detElement;
614     while ((detElement = static_cast<AliMUONGeometryDetElement*>(next()))){
615       /// make a new detection element
616       AliMUONGeometryDetElement *newDetElement =
617         new AliMUONGeometryDetElement(detElement->GetId(),
618                                       detElement->GetVolumePath());
619       TString lDetElemName(detElement->GetDEName());
620       lDetElemName.ReplaceAll("DE","");
621       iDetElemId = lDetElemName.Atoi();
622       iDetElemPseudoId = iDetElemId%100;
623       if ((rMod<4 && iMt==rMod) || (rMod>=4 && (iMt==4+(rMod-4)*2||iMt==4+(rMod-4)*2+1))) {
624         deltaLocalTransform = new TGeoCombiTrans(deltaDetElemTransf[rDetElemPseudoIdToDetElem[iDetElemPseudoId]]);       
625       } else {
626         deltaLocalTransform = new TGeoCombiTrans(*gGeoIdentity);
627       }
628       
629       // local transformation of this detection element.
630       TGeoCombiTrans localTransform
631         = TGeoCombiTrans(*detElement->GetLocalTransformation());
632       //      TGeoHMatrix newLocalMatrix = localTransform * (*deltaLocalTransform);
633       TGeoCombiTrans newLocalTransform 
634         = TGeoCombiTrans(localTransform * (*deltaLocalTransform));
635       newDetElement->SetLocalTransformation(newLocalTransform);   
636       // global transformation
637       TGeoHMatrix newGlobalTransform =
638         AliMUONGeometryBuilder::Multiply(*newModuleTransform,
639                                          newLocalTransform);
640       newDetElement->SetGlobalTransformation(newGlobalTransform);
641       
642       // add this det element to module
643       newModuleTransformer->GetDetElementStore()->Add(newDetElement->GetId(),
644                                                       newDetElement);
645       
646       // In the Alice Alignment Framework misalignment objects store
647       // global delta transformation
648       // Get detection "intermediate" global transformation
649       TGeoHMatrix newOldGlobalTransform = (*newModuleTransform) * localTransform;
650       // Get detection element global delta transformation: 
651       // Tdelta = Tnew * Told.inverse
652       TGeoHMatrix  deltaGlobalTransform
653         = AliMUONGeometryBuilder::Multiply(newGlobalTransform, 
654                                            newOldGlobalTransform.Inverse());
655       
656       // Create mis alignment matrix
657       newGeometryTransformer
658         ->AddMisAlignDetElement(detElement->GetId(), deltaGlobalTransform);
659     }
660       
661     if (verbose)
662       printf("Added module transformer %i to the transformer\n", iMt);
663     newGeometryTransformer->AddModuleTransformer(newModuleTransformer);
664   }
665   return newGeometryTransformer;
666 }
667
668 void AliMUONSurveyUtil::SetAlignmentResolution(const TClonesArray* misAlignArray, Int_t chId, Double_t chResX, Double_t chResY, Double_t deResX, Double_t deResY){
669   /// Sets the alignment resolution to the AliAlignObjMatrix correlation matrix
670
671   TMatrixDSym mChCorrMatrix(6);
672   mChCorrMatrix[0][0]=chResX*chResX;
673   mChCorrMatrix[1][1]=chResY*chResY;
674   //  mChCorrMatrix.Print();
675
676   TMatrixDSym mDECorrMatrix(6);
677   mDECorrMatrix[0][0]=deResX*deResX;
678   mDECorrMatrix[1][1]=deResY*deResY;
679   //  mDECorrMatrix.Print();
680
681   AliAlignObjMatrix *alignMat = 0x0;
682
683 //  Int_t modId = (chId<4)? chId : 4+(chId-4)*2;   
684   TString chName1;
685   TString chName2;
686   if (chId<4){
687     chName1 = Form("GM%d",chId);
688     chName2 = Form("GM%d",chId);
689   } else {
690     chName1 = Form("GM%d",4+(chId-4)*2);
691     chName2 = Form("GM%d",4+(chId-4)*2+1);
692   }
693   
694   for (int i=0; i<misAlignArray->GetEntries(); i++) {
695     alignMat = (AliAlignObjMatrix*)misAlignArray->At(i);
696     TString volName(alignMat->GetSymName());
697     if((volName.Contains(chName1)&&
698         volName.Last('/')<=volName.Index(chName1)+chName1.Length())||
699        (volName.Contains(chName2)&&
700         volName.Last('/')<=volName.Index(chName2)+chName2.Length())) {
701       volName.Remove(0,volName.Last('/')+1);
702       if (volName.Contains("GM")) {
703         //      alignMat->Print("NULL");
704         alignMat->SetCorrMatrix(mChCorrMatrix);
705       } else if (volName.Contains("DE")) {
706         //      alignMat->Print("NULL");
707         alignMat->SetCorrMatrix(mDECorrMatrix);
708       }
709     }
710   }
711 }