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