9275f6167358a1eef426d3f0fd5c7c557f27ee60
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALSurvey.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 /* $Id: $ */
17
18 // Objects of this class read txt file with survey data
19 // and convert the data into AliAlignObjParams of alignable EMCAL volumes.
20 // AliEMCALSurvey inherits TObject only to use AliLog "functions".
21 //
22 // Dummy functions originally written before EMCAL installation and
23 // survey are kept for backward compatibility, but now they are not
24 // used.
25 //
26 // Surveyed points on the EMCAL support rails were used with the CATIA
27 // 3D graphics program to determine the positions of the bottom
28 // corners of the active area for each supermodule.  These numbers are
29 // read in from file and converted to position of the center and roll, 
30 // pitch, yaw angles of each installed SM.
31 //
32 // J.L. Klay - Cal Poly
33 // 21-May-2010
34 //
35
36 #include <fstream>
37
38 #include <TClonesArray.h>
39 #include <TGeoManager.h>
40 #include <TString.h>
41 #include <TMath.h>
42
43 #include "AliSurveyObj.h"
44 #include "AliSurveyPoint.h"
45
46 #include "AliAlignObjParams.h"
47 #include "AliEMCALGeometry.h"
48 #include "AliEMCALSurvey.h"
49 #include "AliLog.h"
50
51 ClassImp(AliEMCALSurvey)
52
53 //____________________________________________________________________________
54 AliEMCALSurvey::AliEMCALSurvey()
55  : fNSuperModule(0),
56    fSuperModuleData(0),
57    fDataType(kSurvey)
58 {
59   //Default constructor.
60 }
61
62 namespace {
63
64   //Coordinates for each SM described in survey reports
65
66   struct AliEMCALSuperModuleCoords {
67     Double_t fX1; //x coordinate of the center of supermodule
68     Double_t fY1; //y coordinate of the center of supermodule
69     Double_t fZ1; //z coordinate of the center of supermodule
70     Double_t fPsi;   //yaw (psi) of supermodule
71     Double_t fTheta; //pitch (theta) of supermodule
72     Double_t fPhi;  //roll angle (phi) of supermodule
73
74   };
75
76 }
77
78 //____________________________________________________________________________
79 AliEMCALSurvey::AliEMCALSurvey(const TString &txtFileName,const SurveyDataType_t type)
80   : fNSuperModule(0),
81     fSuperModuleData(0),
82     fDataType(type)
83 {
84   //Get the geometry object and then attempt to
85   //read survey data from a file, depending on which
86   //method (kSurvey or kDummy) is selected.
87   
88   const AliEMCALGeometry *geom = AliEMCALGeometry::GetInstance();
89   if (!geom) {
90     AliError("Cannot obtain AliEMCALGeometry instance.");
91     return;
92   }
93   
94   fNSuperModule = geom->GetNumberOfSuperModules();
95   
96   if(fDataType == kSurvey) {
97     
98     AliSurveyObj *s1 = new AliSurveyObj();
99     s1->FillFromLocalFile(txtFileName);
100     TObjArray* points = s1->GetData();
101     InitSuperModuleData(points);
102     
103   } else {
104     
105     //Use a dummy file that stores x,y,z of the center of each SM
106     //useful for testing...
107     std::ifstream inputFile(txtFileName.Data());
108     if (!inputFile) {
109       AliError(("Cannot open the survey file " + txtFileName).Data());
110       return;
111     }
112     
113     Int_t dummyInt = 0;
114     Double_t *xReal     = new Double_t[fNSuperModule];
115     Double_t *yReal     = new Double_t[fNSuperModule];
116     Double_t *zReal     = new Double_t[fNSuperModule];
117     Double_t *psiReal   = new Double_t[fNSuperModule];
118     Double_t *thetaReal = new Double_t[fNSuperModule];
119     Double_t *phiReal   = new Double_t[fNSuperModule];
120     //init the arrays
121     memset(xReal,     0,sizeof(Int_t)*fNSuperModule);
122     memset(yReal,     0,sizeof(Int_t)*fNSuperModule);
123     memset(zReal,     0,sizeof(Int_t)*fNSuperModule);
124     memset(psiReal,   0,sizeof(Int_t)*fNSuperModule);
125     memset(thetaReal, 0,sizeof(Int_t)*fNSuperModule);
126     memset(phiReal,   0,sizeof(Int_t)*fNSuperModule);
127     
128     
129     for (Int_t i = 0; i < fNSuperModule; ++i) {
130       if (!inputFile) {
131         AliError("Error while reading input file.");
132         delete [] xReal;
133         delete [] yReal;
134         delete [] zReal;
135         delete [] psiReal;
136         delete [] thetaReal;
137         delete [] phiReal;
138         return;
139       }
140       inputFile>>dummyInt>>xReal[i]>>yReal[i]>>zReal[i]>>psiReal[i]>>thetaReal[i]>>phiReal[i];
141     }
142     
143     InitSuperModuleData(xReal, yReal, zReal, psiReal, thetaReal, phiReal);
144     
145     delete [] xReal;
146     delete [] yReal;
147     delete [] zReal;
148     delete [] psiReal;
149     delete [] thetaReal;
150     delete [] phiReal;
151     
152   } //kDummy way of doing it
153   
154 }
155
156 //____________________________________________________________________________
157 AliEMCALSurvey::~AliEMCALSurvey()
158 {
159   //destructor
160   delete [] fSuperModuleData;
161 }
162
163 //____________________________________________________________________________
164 void AliEMCALSurvey::CreateAliAlignObjParams(TClonesArray &array)
165 {
166   //Create AliAlignObjParams.
167   const AliEMCALGeometry * geom = AliEMCALGeometry::GetInstance();
168   if (!geom) {
169     AliError("Cannot obtain AliEMCALGeometry instance.");
170     return;
171   }
172
173   if (!gGeoManager) {
174     AliWarning("Cannot create local transformations for supermodules - gGeoManager does not exist.");
175     AliInfo("Null shifts and rotations will be created instead.");
176     return CreateNullObjects(array, geom);
177   }
178
179   Int_t arrayInd = array.GetEntries(), iIndex = 0;
180   AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
181   UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,iIndex);
182   AliAlignObjParams* myobj = 0x0;
183
184   for (Int_t smodnum = 0; smodnum < geom->GetNumberOfSuperModules(); ++smodnum) {
185     TString smodName(TString::Format("EMCAL/FullSupermodule%d", smodnum+1));
186     if(geom->GetKey110DEG() && smodnum >= 10) {
187       smodName = "EMCAL/HalfSupermodule";
188       smodName += (smodnum-10+1);
189     }    
190     AliEMCALSuperModuleDelta t(GetSuperModuleTransformation(smodnum));
191
192     ///////////////////////////////
193     // JLK 13-July-2010
194     //
195     // VERY IMPORTANT!!!!
196     //
197     // All numbers were calculated in ALICE global c.s., which means
198     // that the last argument in the creation of AliAlignObjParams
199     // MUST BE set to true
200     //////////////////////////////
201     new(array[arrayInd])
202       AliAlignObjParams(
203                         smodName.Data(), volid, 
204                         t.fXShift, t.fYShift, t.fZShift, 
205                         -t.fPsi, -t.fTheta, -t.fPhi, 
206                         true
207                         );
208     ++arrayInd;
209     myobj = (AliAlignObjParams*)array.UncheckedAt(smodnum);
210     printf("==== AliAlignObjParams for SM %d ====\n",smodnum);
211     myobj->Print("");
212
213   }
214
215 }
216
217 //____________________________________________________________________________
218 void AliEMCALSurvey::CreateNullObjects(TClonesArray &array, const AliEMCALGeometry *geom)const
219 {
220   //Create null shifts and rotations.
221   Int_t arrayInd = array.GetEntries(), iIndex = 0;
222   AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
223   UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,iIndex);
224
225   for (Int_t smodnum = 0; smodnum < geom->GetNumberOfSuperModules(); ++smodnum) {
226     TString smodName(TString::Format("EMCAL/FullSupermodule%d", smodnum+1));
227     if(geom->GetKey110DEG() && smodnum >= 10) {
228       smodName = "EMCAL/HalfSupermodule";
229       smodName += (smodnum-10+1);
230     }
231     new(array[arrayInd]) AliAlignObjParams(smodName.Data(), volid, 0., 0., 0., 0., 0., 0., true);
232     ++arrayInd;
233   }
234 }
235
236 //____________________________________________________________________________
237 AliEMCALSurvey::AliEMCALSuperModuleDelta AliEMCALSurvey::GetSuperModuleTransformation(Int_t supModIndex)const
238 {
239   //Supermodule transformation.
240   AliEMCALSuperModuleDelta t = {0., 0., 0., 0., 0., 0.};
241   if (!fSuperModuleData)
242     return t;
243
244   return fSuperModuleData[supModIndex];
245 }
246
247 //____________________________________________________________________________
248 void AliEMCALSurvey::InitSuperModuleData(const TObjArray *svypts)
249 {
250   //This method uses the data points from the EMCAL survey and CATIA program to
251   //create the alignment matrices.  Only valid for (installed)
252   //SM, others will have null objects
253   
254   /*--------------------------------------
255    The bottom edges of the strip modules
256    define the active area of the EMCAL, but
257    in software we have a box to hold them which
258    is longer than that.  We need to convert
259    info about the position of the corners of the
260    bottom of the active area to the center of
261    the software box that contains the strip
262    modules.
263    
264    View from beam axis up to EMCAL
265    Ai                Ci
266    
267    0,1         0,0 1,0          1,1
268    xxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx
269    x   x             x x              x   x
270    x   x    % *      x x      * %     x   x
271    x   x             x x              x   x
272    xxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx
273    1,1         1,0 0,0          0,1
274    <--> = added length                 <--> = added length
275    
276    * represents the center of the active area
277    % represents the center of the full box (with added length)
278    
279    View from side of topmost SM
280    
281    Ai                Ci
282    
283    0,1         0,0 1,0          1,1
284    xxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx
285    x   x    % *      x x      % *     x   x
286    xxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx
287    1,1         1,0 0,0          0,1
288    <--> = added length                 <--> = added length
289    
290    * represents the center of the active area
291    % represents the center of the full box (with added length)
292    
293    -------------------------------------*/
294   
295   AliEMCALGeometry *geom = AliEMCALGeometry::GetInstance();
296   //Center of supermodules
297   Float_t *pars = geom->GetSuperModulesPars();
298   Double_t rpos = (geom->GetEnvelop(0) + geom->GetEnvelop(1))/2.;
299   Double_t phi=0, phiRad=0, xpos=0, ypos=0, zpos=0;
300   
301   AliEMCALSuperModuleCoords *idealSM = new AliEMCALSuperModuleCoords[fNSuperModule];
302   for (Int_t smodnum = 0; smodnum < geom->GetNumberOfSuperModules(); ++smodnum) {
303     AliEMCALSuperModuleCoords &smc = idealSM[smodnum];
304     phiRad = geom->GetPhiCenterOfSM(smodnum); //comes in radians
305     phi = phiRad*180./TMath::Pi(); //need degrees for AliAlignObjParams
306     xpos = rpos * TMath::Cos(phiRad);
307     ypos = rpos * TMath::Sin(phiRad);
308     zpos = pars[2];
309     if(geom->GetKey110DEG() && smodnum >= 10) {
310       xpos += (pars[1]/2. * TMath::Sin(phiRad));
311       ypos -= (pars[1]/2. * TMath::Cos(phiRad));
312     }
313     smc.fX1 = xpos;
314     smc.fY1 = ypos;
315     smc.fPhi = phi; //degrees
316     smc.fTheta = 0.; //degrees
317     smc.fPsi = 0.; //degrees
318     if(smodnum%2==0) {
319       smc.fZ1 = zpos;
320     } else {
321       smc.fZ1 = -zpos;
322     }
323     printf("<SM %d> IDEAL x,y,z positions: %.2f,%.2f,%.2f, IDEAL phi,theta,psi angles: %.2f,%.2f,%.2f\n",smodnum,smc.fX1,smc.fY1,smc.fZ1,smc.fPhi,smc.fTheta,smc.fPsi);
324     
325   }
326   
327   //Real coordinates of center and rotation angles need to be computed
328   //from the survey/CATIA points
329   const Int_t buffersize = 255;
330   char substr[buffersize];
331   AliEMCALSuperModuleCoords *realSM = new AliEMCALSuperModuleCoords[fNSuperModule];
332   for (Int_t smodnum = 0; smodnum < geom->GetNumberOfSuperModules(); ++smodnum) {
333     AliEMCALSuperModuleCoords &smc = realSM[smodnum];
334     Double_t zLength = pars[2]*2.; //length of SM in z from software
335     Double_t halfHeight = pars[0]; //half the height of the SM in y direction
336     Double_t halfWidth = pars[1];
337
338     printf("AliEMCALGeometry says zlength = %.2f, halfheight = %.2f, halfwidth = %.2f\n",zLength,halfHeight,halfWidth);
339     
340     snprintf(substr,buffersize,"4096%d",smodnum);
341     //retrieve components of four face points and determine average position of center
342     //in x,y,z
343     
344     std::vector<Double_t> xval;
345     std::vector<Double_t> yval;
346     std::vector<Double_t> zval;
347     
348     for(Int_t i = 0; i < svypts->GetEntries(); i++) {
349       AliSurveyPoint* pt = (AliSurveyPoint*)svypts->At(i);
350       TString ptname = pt->GetPointName();
351       if(ptname.Contains(substr)) {
352         //Note: order of values is 00, 01, 10, 11
353         xval.push_back(pt->GetX()*100.); //convert m to cm
354         yval.push_back(pt->GetY()*100.); 
355         zval.push_back(pt->GetZ()*100.); 
356       }
357     }
358     
359     //compute center of active area of each SM on bottome face from survey points
360     Double_t activeX = ((xval[0] + (xval[2] - xval[0])/2.)        //x00 and x10
361                         +(xval[1] + (xval[3] - xval[1])/2.) ) /2.; //x01 and x11
362     
363         Double_t activeY = ((yval[0] + (yval[2] - yval[0])/2.)
364                         +(yval[1] + (yval[3] - yval[1])/2.) ) /2.;
365         
366         Double_t activeZ = ((zval[0] + (zval[2] - zval[0])/2.)
367                         +(zval[1] + (zval[3] - zval[1])/2.) ) /2.;
368     
369     printf("Bottom Center of active area of SM %s: %.2f, %.2f, %.2f\n",substr,activeX,activeY,activeZ);
370     
371     //compute angles for each SM
372     //rotation about each axis
373     //phi = angle in x-y plane
374     
375     Double_t realphi = 0.;
376     //Note: this is phi wrt y axis.  To get phi wrt to x, add pi/2
377     if(smodnum%2 == 0) {
378       realphi = (TMath::ATan((yval[2] - yval[0])/(xval[2] - xval[0])) 
379                  +TMath::ATan((yval[3] - yval[1])/(xval[3] - xval[1])) )/2.;
380     } else {
381       realphi = (TMath::ATan((yval[0] - yval[2])/(xval[0] - xval[2]))
382                  +TMath::ATan((yval[1] - yval[3])/(xval[1] - xval[3])) )/2.;
383     }
384     
385     //NOTE: Psi angle is always zero because the two z values being
386     //subtracted are exactly the same, but just in case that could change...
387     //psi = angle in x-z plane
388     Double_t realpsi = (TMath::ATan((zval[0] - zval[2])/(xval[2] - xval[0]))
389                         +TMath::ATan((zval[1] - zval[3])/(xval[3] - xval[1])) )/2.;
390     
391     //theta = angle in y-z plane
392     Double_t realtheta = TMath::Pi()/2. 
393     + (TMath::ATan((zval[2] - zval[3])/(yval[3] - yval[2]))
394        +TMath::ATan((zval[0] - zval[1])/(yval[1] - yval[0])) )/2.;
395         
396     printf("Old edge of %s 01: %.2f, %.2f, %.2f\n",substr,xval[1],yval[1],zval[1]);
397     printf("Old edge of %s 11: %.2f, %.2f, %.2f\n",substr,xval[3],yval[3],zval[3]);
398     printf("Real theta angle (degrees) = %.2f\n",realtheta*TMath::RadToDeg());
399
400     //Now calculate the center of the box in z with length added to the 01
401     //and 11 corners, corrected by the theta angle
402     Double_t activeLength = TMath::Abs(((zval[1] - zval[0]) + (zval[3] - zval[2]))/2.);
403     printf("ACTIVE LENGTH = %.2f\n",activeLength);
404     if(smodnum%2 == 0) {
405       yval[1] += (zLength - activeLength)*sin(realtheta);
406       yval[3] += (zLength - activeLength)*sin(realtheta);
407       zval[1] += (zLength - activeLength)*cos(realtheta);
408       zval[3] += (zLength - activeLength)*cos(realtheta);
409     } else {
410       yval[1] -= (zLength - activeLength)*sin(realtheta);
411       yval[3] -= (zLength - activeLength)*sin(realtheta);
412       zval[1] -= (zLength - activeLength)*cos(realtheta);
413       zval[3] -= (zLength - activeLength)*cos(realtheta);
414     }
415     
416     printf("New extended edge of %s 01: %.2f, %.2f, %.2f\n",substr,xval[1],yval[1],zval[1]);            
417     printf("New extended edge of %s 11: %.2f, %.2f, %.2f\n",substr,xval[3],yval[3],zval[3]);
418     
419     //Compute the center of the bottom of the box in x,y,z
420     Double_t realX = activeX;    
421     Double_t realY = ((yval[0] + (yval[2] - yval[0])/2.)
422                       +(yval[1] + (yval[3] - yval[1])/2.) ) /2.;    
423     Double_t realZ = ((zval[0] + (zval[2] - zval[0])/2.)
424                       +(zval[1] + (zval[3] - zval[1])/2.) ) /2.;
425     
426     
427     printf("Bottom Center of SM %s Box: %.2f, %.2f, %.2f\n",substr,realX,realY,realZ);
428     
429     //correct the SM centers so that we have the center of the box in
430     //x,y using the phi,theta angles                   
431     realX += halfHeight*TMath::Cos(TMath::Pi()/2+realphi);
432     realY += halfHeight*(TMath::Sin(TMath::Pi()/2+realphi) + TMath::Sin(realtheta));
433     realZ += halfHeight*TMath::Cos(TMath::Pi()/2-realtheta);
434     
435     printf("Rotation angles of SM %s (phi,psi,theta) in degrees: %.4f, %.4f, %.4f\n",substr,realphi*TMath::RadToDeg(),realpsi*TMath::RadToDeg(),realtheta*TMath::RadToDeg());
436     printf("Middle of SM %s: %.2f, %.2f, %.2f\n\n",substr,realX,realY,realZ);
437     
438     smc.fX1 = realX;
439     smc.fY1 = realY;
440     smc.fZ1 = realZ;
441     
442     smc.fPhi = 90. + realphi*TMath::RadToDeg();
443     smc.fTheta = 0. + realtheta*TMath::RadToDeg();
444     smc.fPsi = 0. + realpsi*TMath::RadToDeg();
445     
446   }//loop over supermodules
447
448   //Now take average values for A and C side SMs (0&1,2&3) and set
449   //their values to be equal to that average
450   for (Int_t i = 0; i < fNSuperModule; i++) {
451     if(i%2==0) {
452       AliEMCALSuperModuleCoords &realA = realSM[i];
453       AliEMCALSuperModuleCoords &realC = realSM[i+1];
454       Double_t avgx = (realA.fX1 + realC.fX1)/2.;
455       Double_t avgy = (realA.fY1 + realC.fY1)/2.;
456       Double_t avgphi = (realA.fPhi + realC.fPhi)/2.;
457       Double_t avgtheta = (realA.fTheta + realC.fTheta)/2.;
458       Double_t avgpsi = (realA.fPsi + realC.fPsi)/2.;
459       printf("AVERAGE VALUES: %.2f,%.2f,%.2f,%.2f,%.2f\n",avgx,avgy,avgphi,avgtheta,avgpsi);
460       
461       realA.fX1 = avgx;         realC.fX1 = avgx;
462       realA.fY1 = avgy;         realC.fY1 = avgy;
463       realA.fPhi = avgphi;      realC.fPhi = avgphi;
464       realA.fTheta = avgtheta;  realC.fTheta = avgtheta;
465       realA.fPsi = avgpsi;      realC.fPhi = avgphi;
466     }
467   }
468
469   fSuperModuleData = new AliEMCALSuperModuleDelta[fNSuperModule];
470   
471   for (Int_t i = 0; i < fNSuperModule; ++i) {
472     const AliEMCALSuperModuleCoords &real = realSM[i];
473     const AliEMCALSuperModuleCoords &ideal = idealSM[i];
474     AliEMCALSuperModuleDelta &t = fSuperModuleData[i];
475     t.fXShift = real.fX1 - ideal.fX1;
476     t.fYShift = real.fY1 - ideal.fY1;
477     t.fZShift = real.fZ1 - ideal.fZ1;
478     t.fPhi = real.fPhi - ideal.fPhi;
479     t.fTheta = real.fTheta - ideal.fTheta;
480     t.fPsi = real.fPsi - ideal.fPsi;
481
482     printf("===================== SM %d =======================\n",i);
483     printf("real x (%.2f) - ideal x (%.2f) = shift in x (%.2f)\n",real.fX1,ideal.fX1,t.fXShift);
484     printf("real y (%.2f) - ideal y (%.2f) = shift in y (%.2f)\n",real.fY1,ideal.fY1,t.fYShift);
485     printf("real z (%.2f) - ideal z (%.2f) = shift in z (%.2f)\n",real.fZ1,ideal.fZ1,t.fZShift);
486     printf("real theta (%.2f) - ideal theta (%.2f) = shift in theta %.2f\n",real.fTheta,ideal.fTheta,t.fTheta);
487     printf("real psi (%.2f) - ideal psi (%.2f) = shift in psi %.2f\n",real.fPsi,ideal.fPsi,t.fPsi);
488     printf("real phi (%.2f) - ideal phi (%.2f) = shift in phi %.2f\n",real.fPhi,ideal.fPhi,t.fPhi);
489     printf("===================================================\n");    
490   }
491   
492   delete [] realSM;
493   delete [] idealSM;
494 }
495
496
497 //____________________________________________________________________________
498 void AliEMCALSurvey::InitSuperModuleData(const Double_t *xReal, const Double_t *yReal, 
499                                          const Double_t *zReal, const Double_t *psiReal,
500                                          const Double_t *thetaReal, const Double_t *phiReal)
501 {
502   ///////////////////////////////////////
503   //Dummy method just takes the inputted values and applies them
504   //
505   //Useful for testing small changes
506   //////////////////////////////////////
507   AliEMCALGeometry *geom = AliEMCALGeometry::GetInstance();
508   //Center of supermodules
509   Float_t *pars = geom->GetSuperModulesPars();
510   Double_t rpos = (geom->GetEnvelop(0) + geom->GetEnvelop(1))/2.;
511   Double_t phi=0, phiRad=0, xpos=0, ypos=0, zpos=0;
512
513   zpos = pars[2];
514
515   AliEMCALSuperModuleCoords *idealSM = new AliEMCALSuperModuleCoords[fNSuperModule];
516   for (Int_t smodnum = 0; smodnum < geom->GetNumberOfSuperModules(); ++smodnum) {
517     AliEMCALSuperModuleCoords &smc = idealSM[smodnum];
518     phiRad = geom->GetPhiCenterOfSM(smodnum); //comes in radians
519     phi = phiRad*180./TMath::Pi(); //need degrees for AliAlignObjParams
520     xpos = rpos * TMath::Cos(phiRad);
521     ypos = rpos * TMath::Sin(phiRad);
522     if(geom->GetKey110DEG() && smodnum >= 10) {
523       xpos += (pars[1]/2. * TMath::Sin(phiRad));
524       ypos -= (pars[1]/2. * TMath::Cos(phiRad));
525     }
526     smc.fX1 = xpos;
527     smc.fY1 = ypos;
528
529     smc.fPhi = phi; //degrees
530     smc.fTheta = 0.; //degrees
531     smc.fPsi = 0.; //degrees
532
533     if(smodnum%2==0) {
534       smc.fZ1 = zpos;
535     } else {
536       smc.fZ1 = -zpos;
537     }
538
539   }
540
541   AliEMCALSuperModuleCoords *realSM = new AliEMCALSuperModuleCoords[fNSuperModule];
542   for (Int_t smodnum = 0; smodnum < geom->GetNumberOfSuperModules(); ++smodnum) {
543     AliEMCALSuperModuleCoords &smc = realSM[smodnum];
544     smc.fX1    = xReal[smodnum];  
545     smc.fY1    = yReal[smodnum];  
546     smc.fZ1    = zReal[smodnum];  
547     smc.fTheta = thetaReal[smodnum];
548     smc.fPsi   = psiReal[smodnum];
549     smc.fPhi   = phiReal[smodnum];
550   }
551   
552   fSuperModuleData = new AliEMCALSuperModuleDelta[fNSuperModule];
553   
554   for (Int_t i = 0; i < fNSuperModule; ++i) {
555     const AliEMCALSuperModuleCoords &real = realSM[i];
556     const AliEMCALSuperModuleCoords &ideal = idealSM[i];
557     AliEMCALSuperModuleDelta &t = fSuperModuleData[i];
558     t.fTheta = real.fTheta - ideal.fTheta;
559     t.fPsi = 0.;
560     t.fPhi = real.fPhi - ideal.fPhi;
561     t.fXShift = real.fX1 - ideal.fX1;
562     t.fYShift = real.fY1 - ideal.fY1;
563     t.fZShift = real.fZ1 - ideal.fZ1;
564
565     printf("===================== SM %d =======================\n",i);
566     printf("real x (%.2f) - ideal x (%.2f) = shift in x (%.2f)\n",real.fX1,ideal.fX1,t.fXShift);
567     printf("real y (%.2f) - ideal y (%.2f) = shift in y (%.2f)\n",real.fY1,ideal.fY1,t.fYShift);
568     printf("real z (%.2f) - ideal z (%.2f) = shift in z (%.2f)\n",real.fZ1,ideal.fZ1,t.fZShift);
569     printf("real theta (%.2f) - ideal theta (%.2f) = shift in theta %.2f\n",real.fTheta,ideal.fTheta,t.fTheta);
570     printf("real psi (%.2f) - ideal psi (%.2f) = shift in psi %.2f\n",real.fPsi,ideal.fPsi,t.fPsi);
571     printf("real phi (%.2f) - ideal phi (%.2f) = shift in phi %.2f\n",real.fPhi,ideal.fPhi,t.fPhi);
572     printf("===================================================\n");    
573   }
574
575   delete [] realSM;
576   delete [] idealSM;
577 }
578