1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
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".
22 // Dummy functions originally written before EMCAL installation and
23 // survey are kept for backward compatibility, but now they are not
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.
32 // J.L. Klay - Cal Poly
33 // Adapted for DCAL by M.L. Wang CCNU & Subatech Oct-19-2012
39 #include <TClonesArray.h>
40 #include <TGeoManager.h>
44 #include "AliSurveyObj.h"
45 #include "AliSurveyPoint.h"
47 #include "AliAlignObjParams.h"
48 #include "AliEMCALGeometry.h"
49 #include "AliEMCALSurvey.h"
52 ClassImp(AliEMCALSurvey)
54 //____________________________________________________________________________
55 AliEMCALSurvey::AliEMCALSurvey()
60 //Default constructor.
65 //Coordinates for each SM described in survey reports
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
79 //____________________________________________________________________________
80 AliEMCALSurvey::AliEMCALSurvey(const TString &txtFileName,const SurveyDataType_t type)
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.
89 const AliEMCALGeometry *geom = AliEMCALGeometry::GetInstance();
91 AliError("Cannot obtain AliEMCALGeometry instance.");
95 fNSuperModule = geom->GetNumberOfSuperModules();
97 if(fDataType == kSurvey) {
99 AliSurveyObj *s1 = new AliSurveyObj();
100 s1->FillFromLocalFile(txtFileName);
101 TObjArray* points = s1->GetData();
102 InitSuperModuleData(points);
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());
110 AliError(("Cannot open the survey file " + txtFileName).Data());
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];
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);
130 for (Int_t i = 0; i < fNSuperModule; ++i) {
132 AliError("Error while reading input file.");
141 inputFile>>dummyInt>>xReal[i]>>yReal[i]>>zReal[i]>>psiReal[i]>>thetaReal[i]>>phiReal[i];
144 InitSuperModuleData(xReal, yReal, zReal, psiReal, thetaReal, phiReal);
153 } //kDummy way of doing it
157 //____________________________________________________________________________
158 AliEMCALSurvey::~AliEMCALSurvey()
161 delete [] fSuperModuleData;
164 //____________________________________________________________________________
165 void AliEMCALSurvey::CreateAliAlignObjParams(TClonesArray &array)
167 //Create AliAlignObjParams.
168 const AliEMCALGeometry * geom = AliEMCALGeometry::GetInstance();
170 AliError("Cannot obtain AliEMCALGeometry instance.");
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);
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;
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!!");
197 if(geom->GetSMType(smodnum) == tmpType) {
200 tmpType = geom->GetSMType(smodnum);
204 TString smodName(TString::Format("EMCAL/%s%d", SMName.Data(), SMOrder));
205 AliEMCALSuperModuleDelta t(GetSuperModuleTransformation(smodnum));
207 ///////////////////////////////
210 // VERY IMPORTANT!!!!
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 //////////////////////////////
218 smodName.Data(), volid,
219 t.fXShift, t.fYShift, t.fZShift,
220 -t.fPsi, -t.fTheta, -t.fPhi,
224 myobj = (AliAlignObjParams*)array.UncheckedAt(smodnum);
225 printf("==== AliAlignObjParams for SM %d ====\n",smodnum);
232 //____________________________________________________________________________
233 void AliEMCALSurvey::CreateNullObjects(TClonesArray &array, const AliEMCALGeometry *geom)const
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);
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!!");
252 if(geom->GetSMType(smodnum) == tmpType) {
255 tmpType = geom->GetSMType(smodnum);
258 TString smodName(TString::Format("EMCAL/%s%d", SMName.Data(), SMOrder));
260 new(array[arrayInd]) AliAlignObjParams(smodName.Data(), volid, 0., 0., 0., 0., 0., 0., true);
265 //____________________________________________________________________________
266 AliEMCALSurvey::AliEMCALSuperModuleDelta AliEMCALSurvey::GetSuperModuleTransformation(Int_t supModIndex)const
268 //Supermodule transformation.
269 AliEMCALSuperModuleDelta t = {0., 0., 0., 0., 0., 0.};
270 if (!fSuperModuleData)
273 return fSuperModuleData[supModIndex];
276 //____________________________________________________________________________
277 void AliEMCALSurvey::InitSuperModuleData(const TObjArray *svypts)
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
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
293 View from beam axis up to EMCAL
297 xxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx
301 xxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx
303 <--> = added length <--> = added length
305 * represents the center of the active area
306 % represents the center of the full box (with added length)
308 View from side of topmost SM
313 xxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx
315 xxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx
317 <--> = added length <--> = added length
319 * represents the center of the active area
320 % represents the center of the full box (with added length)
322 -------------------------------------*/
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;
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);
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.;
350 smc.fPhi = phi; //degrees
351 smc.fTheta = 0.; //degrees
352 smc.fPsi = 0.; //degrees
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);
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];
373 printf("AliEMCALGeometry says zlength = %.2f, halfheight = %.2f, halfwidth = %.2f\n",zLength,halfHeight,halfWidth);
375 snprintf(substr,buffersize,"4096%d",smodnum);
376 //retrieve components of four face points and determine average position of center
379 std::vector<Double_t> xval;
380 std::vector<Double_t> yval;
381 std::vector<Double_t> zval;
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.);
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
398 Double_t activeY = ((yval[0] + (yval[2] - yval[0])/2.)
399 +(yval[1] + (yval[3] - yval[1])/2.) ) /2.;
401 Double_t activeZ = ((zval[0] + (zval[2] - zval[0])/2.)
402 +(zval[1] + (zval[3] - zval[1])/2.) ) /2.;
404 printf("Bottom Center of active area of SM %s: %.2f, %.2f, %.2f\n",substr,activeX,activeY,activeZ);
406 //compute angles for each SM
407 //rotation about each axis
408 //phi = angle in x-y plane
410 Double_t realphi = 0.;
411 //Note: this is phi wrt y axis. To get phi wrt to x, add pi/2
413 realphi = (TMath::ATan((yval[2] - yval[0])/(xval[2] - xval[0]))
414 +TMath::ATan((yval[3] - yval[1])/(xval[3] - xval[1])) )/2.;
416 realphi = (TMath::ATan((yval[0] - yval[2])/(xval[0] - xval[2]))
417 +TMath::ATan((yval[1] - yval[3])/(xval[1] - xval[3])) )/2.;
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.;
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.;
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());
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);
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);
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);
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]);
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.;
462 printf("Bottom Center of SM %s Box: %.2f, %.2f, %.2f\n",substr,realX,realY,realZ);
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);
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);
477 smc.fPhi = 90. + realphi*TMath::RadToDeg();
478 smc.fTheta = 0. + realtheta*TMath::RadToDeg();
479 smc.fPsi = 0. + realpsi*TMath::RadToDeg();
481 }//loop over supermodules
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++) {
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);
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;
504 fSuperModuleData = new AliEMCALSuperModuleDelta[fNSuperModule];
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;
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");
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)
537 ///////////////////////////////////////
538 //Dummy method just takes the inputted values and applies them
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;
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);
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.;
571 smc.fPhi = phi; //degrees
572 smc.fTheta = 0.; //degrees
573 smc.fPsi = 0.; //degrees
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];
594 fSuperModuleData = new AliEMCALSuperModuleDelta[fNSuperModule];
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;
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;
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");