Line data Source code
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 42 : ClassImp(AliEMCALSurvey)
53 :
54 : //____________________________________________________________________________
55 0 : AliEMCALSurvey::AliEMCALSurvey()
56 0 : : fNSuperModule(0),
57 0 : fSuperModuleData(0),
58 0 : fDataType(kSurvey)
59 0 : {
60 : //Default constructor.
61 0 : }
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 0 : AliEMCALSurvey::AliEMCALSurvey(const TString &txtFileName,const SurveyDataType_t type)
81 0 : : fNSuperModule(0),
82 0 : fSuperModuleData(0),
83 0 : fDataType(type)
84 0 : {
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 0 : const AliEMCALGeometry *geom = AliEMCALGeometry::GetInstance();
90 0 : if (!geom) {
91 0 : AliError("Cannot obtain AliEMCALGeometry instance.");
92 0 : return;
93 : }
94 :
95 0 : fNSuperModule = geom->GetNumberOfSuperModules();
96 :
97 0 : if(fDataType == kSurvey) {
98 :
99 0 : AliSurveyObj *s1 = new AliSurveyObj();
100 0 : s1->FillFromLocalFile(txtFileName);
101 0 : TObjArray* points = s1->GetData();
102 0 : InitSuperModuleData(points);
103 :
104 0 : } else {
105 :
106 : //Use a dummy file that stores x,y,z of the center of each SM
107 : //useful for testing...
108 0 : std::ifstream inputFile(txtFileName.Data());
109 0 : if (!inputFile) {
110 0 : AliError(("Cannot open the survey file " + txtFileName).Data());
111 0 : return;
112 : }
113 :
114 0 : Int_t dummyInt = 0;
115 0 : Double_t *xReal = new Double_t[fNSuperModule];
116 0 : Double_t *yReal = new Double_t[fNSuperModule];
117 0 : Double_t *zReal = new Double_t[fNSuperModule];
118 0 : Double_t *psiReal = new Double_t[fNSuperModule];
119 0 : Double_t *thetaReal = new Double_t[fNSuperModule];
120 0 : Double_t *phiReal = new Double_t[fNSuperModule];
121 : //init the arrays
122 0 : memset(xReal, 0,sizeof(Int_t)*fNSuperModule);
123 0 : memset(yReal, 0,sizeof(Int_t)*fNSuperModule);
124 0 : memset(zReal, 0,sizeof(Int_t)*fNSuperModule);
125 0 : memset(psiReal, 0,sizeof(Int_t)*fNSuperModule);
126 0 : memset(thetaReal, 0,sizeof(Int_t)*fNSuperModule);
127 0 : memset(phiReal, 0,sizeof(Int_t)*fNSuperModule);
128 :
129 :
130 0 : for (Int_t i = 0; i < fNSuperModule; ++i) {
131 0 : if (!inputFile) {
132 0 : AliError("Error while reading input file.");
133 0 : delete [] xReal;
134 0 : delete [] yReal;
135 0 : delete [] zReal;
136 0 : delete [] psiReal;
137 0 : delete [] thetaReal;
138 0 : delete [] phiReal;
139 0 : return;
140 : }
141 0 : inputFile>>dummyInt>>xReal[i]>>yReal[i]>>zReal[i]>>psiReal[i]>>thetaReal[i]>>phiReal[i];
142 : }
143 :
144 0 : InitSuperModuleData(xReal, yReal, zReal, psiReal, thetaReal, phiReal);
145 :
146 0 : delete [] xReal;
147 0 : delete [] yReal;
148 0 : delete [] zReal;
149 0 : delete [] psiReal;
150 0 : delete [] thetaReal;
151 0 : delete [] phiReal;
152 :
153 0 : } //kDummy way of doing it
154 :
155 0 : }
156 :
157 : //____________________________________________________________________________
158 : AliEMCALSurvey::~AliEMCALSurvey()
159 0 : {
160 : //destructor
161 0 : delete [] fSuperModuleData;
162 0 : }
163 :
164 : //____________________________________________________________________________
165 : void AliEMCALSurvey::CreateAliAlignObjParams(TClonesArray &array)
166 : {
167 : //Create AliAlignObjParams.
168 0 : const AliEMCALGeometry * geom = AliEMCALGeometry::GetInstance();
169 0 : if (!geom) {
170 0 : AliError("Cannot obtain AliEMCALGeometry instance.");
171 0 : return;
172 : }
173 :
174 0 : if (!gGeoManager) {
175 0 : AliWarning("Cannot create local transformations for supermodules - gGeoManager does not exist.");
176 0 : AliInfo("Null shifts and rotations will be created instead.");
177 0 : return CreateNullObjects(array, geom);
178 : }
179 :
180 0 : Int_t arrayInd = array.GetEntries(), iIndex = 0;
181 : AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
182 0 : UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,iIndex);
183 : AliAlignObjParams* myobj = 0x0;
184 :
185 0 : TString SMName;
186 : Int_t tmpType = -1;
187 : Int_t SMOrder = 0;
188 :
189 0 : for (Int_t smodnum = 0; smodnum < geom->GetNumberOfSuperModules(); ++smodnum) {
190 0 : if(geom->GetSMType(smodnum) == AliEMCALGeometry::kEMCAL_Standard ) SMName = "FullSupermodule";
191 0 : else if(geom->GetSMType(smodnum) == AliEMCALGeometry::kEMCAL_Half ) SMName = "HalfSupermodule";
192 0 : else if(geom->GetSMType(smodnum) == AliEMCALGeometry::kEMCAL_3rd ) SMName = "OneThrdSupermodule";
193 0 : else if( geom->GetSMType(smodnum) == AliEMCALGeometry::kDCAL_Standard ) SMName = "DCALSupermodule";
194 0 : else if( geom->GetSMType(smodnum) == AliEMCALGeometry::kDCAL_Ext ) SMName = "DCALExtensionSM";
195 0 : else AliError("Unkown SM Type!!");
196 :
197 0 : if(geom->GetSMType(smodnum) == tmpType) {
198 0 : SMOrder++;
199 0 : } else {
200 0 : tmpType = geom->GetSMType(smodnum);
201 : SMOrder = 1;
202 : }
203 :
204 0 : TString smodName(TString::Format("EMCAL/%s%d", SMName.Data(), SMOrder));
205 0 : 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 0 : new(array[arrayInd])
217 0 : AliAlignObjParams(
218 0 : smodName.Data(), volid,
219 0 : t.fXShift, t.fYShift, t.fZShift,
220 0 : -t.fPsi, -t.fTheta, -t.fPhi,
221 : true
222 : );
223 0 : ++arrayInd;
224 0 : myobj = (AliAlignObjParams*)array.UncheckedAt(smodnum);
225 0 : printf("==== AliAlignObjParams for SM %d ====\n",smodnum);
226 0 : myobj->Print("");
227 :
228 0 : }
229 :
230 0 : }
231 :
232 : //____________________________________________________________________________
233 : void AliEMCALSurvey::CreateNullObjects(TClonesArray &array, const AliEMCALGeometry *geom)const
234 : {
235 : //Create null shifts and rotations.
236 0 : Int_t arrayInd = array.GetEntries(), iIndex = 0;
237 : AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
238 0 : UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,iIndex);
239 :
240 0 : TString SMName;
241 : Int_t tmpType = -1;
242 : Int_t SMOrder = 0;
243 :
244 0 : for (Int_t smodnum = 0; smodnum < geom->GetNumberOfSuperModules(); ++smodnum) {
245 0 : if(geom->GetSMType(smodnum) == AliEMCALGeometry::kEMCAL_Standard ) SMName = "FullSupermodule";
246 0 : else if(geom->GetSMType(smodnum) == AliEMCALGeometry::kEMCAL_Half ) SMName = "HalfSupermodule";
247 0 : else if(geom->GetSMType(smodnum) == AliEMCALGeometry::kEMCAL_3rd ) SMName = "OneThrdSupermodule";
248 0 : else if( geom->GetSMType(smodnum) == AliEMCALGeometry::kDCAL_Standard ) SMName = "DCALSupermodule";
249 0 : else if( geom->GetSMType(smodnum) == AliEMCALGeometry::kDCAL_Ext ) SMName = "DCALExtensionSM";
250 0 : else AliError("Unkown SM Type!!");
251 :
252 0 : if(geom->GetSMType(smodnum) == tmpType) {
253 0 : SMOrder++;
254 0 : } else {
255 0 : tmpType = geom->GetSMType(smodnum);
256 : SMOrder = 1;
257 : }
258 0 : TString smodName(TString::Format("EMCAL/%s%d", SMName.Data(), SMOrder));
259 :
260 0 : new(array[arrayInd]) AliAlignObjParams(smodName.Data(), volid, 0., 0., 0., 0., 0., 0., true);
261 0 : ++arrayInd;
262 0 : }
263 0 : }
264 :
265 : //____________________________________________________________________________
266 : AliEMCALSurvey::AliEMCALSuperModuleDelta AliEMCALSurvey::GetSuperModuleTransformation(Int_t supModIndex)const
267 : {
268 : //Supermodule transformation.
269 0 : AliEMCALSuperModuleDelta t = {0., 0., 0., 0., 0., 0.};
270 0 : if (!fSuperModuleData)
271 0 : return t;
272 :
273 0 : return fSuperModuleData[supModIndex];
274 0 : }
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 0 : AliEMCALGeometry *geom = AliEMCALGeometry::GetInstance();
325 : //Center of supermodules
326 0 : Float_t pars[] = {geom->GetSuperModulesPar(0),geom->GetSuperModulesPar(1),geom->GetSuperModulesPar(2)};
327 0 : Double_t rpos = (geom->GetEnvelop(0) + geom->GetEnvelop(1))/2.;
328 0 : Float_t fInnerEdge = geom->GetDCALInnerEdge();
329 : Double_t phi=0, phiRad=0, xpos=0, ypos=0, zpos=0;
330 :
331 0 : AliEMCALSuperModuleCoords *idealSM = new AliEMCALSuperModuleCoords[fNSuperModule];
332 0 : for (Int_t smodnum = 0; smodnum < geom->GetNumberOfSuperModules(); ++smodnum) {
333 0 : AliEMCALSuperModuleCoords &smc = idealSM[smodnum];
334 0 : phiRad = geom->GetPhiCenterOfSMSec(smodnum); //comes in radians
335 0 : phi = phiRad*180./TMath::Pi(); //need degrees for AliAlignObjParams
336 0 : xpos = rpos * TMath::Cos(phiRad);
337 0 : ypos = rpos * TMath::Sin(phiRad);
338 0 : zpos = pars[2];
339 0 : if( geom->GetSMType(smodnum) == AliEMCALGeometry::kEMCAL_Half
340 0 : || geom->GetSMType(smodnum) == AliEMCALGeometry::kEMCAL_3rd
341 0 : || geom->GetSMType(smodnum) == AliEMCALGeometry::kDCAL_Ext ) {
342 0 : xpos += (pars[1]/2. * TMath::Sin(phiRad));
343 0 : ypos -= (pars[1]/2. * TMath::Cos(phiRad));
344 0 : } else if( geom->GetSMType(smodnum) == AliEMCALGeometry::kDCAL_Standard) {
345 0 : zpos = pars[2] + fInnerEdge/2.;
346 0 : }
347 :
348 0 : smc.fX1 = xpos;
349 0 : smc.fY1 = ypos;
350 0 : smc.fPhi = phi; //degrees
351 0 : smc.fTheta = 0.; //degrees
352 0 : smc.fPsi = 0.; //degrees
353 0 : if(smodnum%2==0) {
354 0 : smc.fZ1 = zpos;
355 0 : } else {
356 0 : smc.fZ1 = -zpos;
357 : }
358 0 : 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 0 : char substr[buffersize];
366 0 : AliEMCALSuperModuleCoords *realSM = new AliEMCALSuperModuleCoords[fNSuperModule];
367 0 : for (Int_t smodnum = 0; smodnum < geom->GetNumberOfSuperModules(); ++smodnum) {
368 0 : AliEMCALSuperModuleCoords &smc = realSM[smodnum];
369 0 : Double_t zLength = pars[2]*2.; //length of SM in z from software
370 0 : Double_t halfHeight = pars[0]; //half the height of the SM in y direction
371 0 : Double_t halfWidth = pars[1];
372 :
373 0 : printf("AliEMCALGeometry says zlength = %.2f, halfheight = %.2f, halfwidth = %.2f\n",zLength,halfHeight,halfWidth);
374 :
375 0 : 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 0 : std::vector<Double_t> xval;
380 0 : std::vector<Double_t> yval;
381 0 : std::vector<Double_t> zval;
382 :
383 0 : for(Int_t i = 0; i < svypts->GetEntries(); i++) {
384 0 : AliSurveyPoint* pt = (AliSurveyPoint*)svypts->At(i);
385 0 : TString ptname = pt->GetPointName();
386 0 : if(ptname.Contains(substr)) {
387 : //Note: order of values is 00, 01, 10, 11
388 0 : xval.push_back(pt->GetX()*100.); //convert m to cm
389 0 : yval.push_back(pt->GetY()*100.);
390 0 : zval.push_back(pt->GetZ()*100.);
391 : }
392 0 : }
393 :
394 : //compute center of active area of each SM on bottome face from survey points
395 0 : Double_t activeX = ((xval[0] + (xval[2] - xval[0])/2.) //x00 and x10
396 0 : +(xval[1] + (xval[3] - xval[1])/2.) ) /2.; //x01 and x11
397 :
398 0 : Double_t activeY = ((yval[0] + (yval[2] - yval[0])/2.)
399 0 : +(yval[1] + (yval[3] - yval[1])/2.) ) /2.;
400 :
401 0 : Double_t activeZ = ((zval[0] + (zval[2] - zval[0])/2.)
402 0 : +(zval[1] + (zval[3] - zval[1])/2.) ) /2.;
403 :
404 0 : 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 0 : if(smodnum%2 == 0) {
413 0 : realphi = (TMath::ATan((yval[2] - yval[0])/(xval[2] - xval[0]))
414 0 : +TMath::ATan((yval[3] - yval[1])/(xval[3] - xval[1])) )/2.;
415 0 : } else {
416 0 : realphi = (TMath::ATan((yval[0] - yval[2])/(xval[0] - xval[2]))
417 0 : +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 0 : Double_t realpsi = (TMath::ATan((zval[0] - zval[2])/(xval[2] - xval[0]))
424 0 : +TMath::ATan((zval[1] - zval[3])/(xval[3] - xval[1])) )/2.;
425 :
426 : //theta = angle in y-z plane
427 0 : Double_t realtheta = TMath::Pi()/2.
428 0 : + (TMath::ATan((zval[2] - zval[3])/(yval[3] - yval[2]))
429 0 : +TMath::ATan((zval[0] - zval[1])/(yval[1] - yval[0])) )/2.;
430 :
431 0 : printf("Old edge of %s 01: %.2f, %.2f, %.2f\n",substr,xval[1],yval[1],zval[1]);
432 0 : printf("Old edge of %s 11: %.2f, %.2f, %.2f\n",substr,xval[3],yval[3],zval[3]);
433 0 : 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 0 : Double_t activeLength = TMath::Abs(((zval[1] - zval[0]) + (zval[3] - zval[2]))/2.);
438 0 : printf("ACTIVE LENGTH = %.2f\n",activeLength);
439 0 : if(smodnum%2 == 0) {
440 0 : yval[1] += (zLength - activeLength)*sin(realtheta);
441 0 : yval[3] += (zLength - activeLength)*sin(realtheta);
442 0 : zval[1] += (zLength - activeLength)*cos(realtheta);
443 0 : zval[3] += (zLength - activeLength)*cos(realtheta);
444 0 : } else {
445 0 : yval[1] -= (zLength - activeLength)*sin(realtheta);
446 0 : yval[3] -= (zLength - activeLength)*sin(realtheta);
447 0 : zval[1] -= (zLength - activeLength)*cos(realtheta);
448 0 : zval[3] -= (zLength - activeLength)*cos(realtheta);
449 : }
450 :
451 0 : printf("New extended edge of %s 01: %.2f, %.2f, %.2f\n",substr,xval[1],yval[1],zval[1]);
452 0 : 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 0 : Double_t realY = ((yval[0] + (yval[2] - yval[0])/2.)
457 0 : +(yval[1] + (yval[3] - yval[1])/2.) ) /2.;
458 0 : Double_t realZ = ((zval[0] + (zval[2] - zval[0])/2.)
459 0 : +(zval[1] + (zval[3] - zval[1])/2.) ) /2.;
460 :
461 :
462 0 : 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 0 : realX += halfHeight*TMath::Cos(TMath::Pi()/2+realphi);
467 0 : realY += halfHeight*(TMath::Sin(TMath::Pi()/2+realphi) + TMath::Sin(realtheta));
468 0 : realZ += halfHeight*TMath::Cos(TMath::Pi()/2-realtheta);
469 :
470 0 : 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 0 : printf("Middle of SM %s: %.2f, %.2f, %.2f\n\n",substr,realX,realY,realZ);
472 :
473 0 : smc.fX1 = realX;
474 0 : smc.fY1 = realY;
475 0 : smc.fZ1 = realZ;
476 :
477 0 : smc.fPhi = 90. + realphi*TMath::RadToDeg();
478 0 : smc.fTheta = 0. + realtheta*TMath::RadToDeg();
479 0 : smc.fPsi = 0. + realpsi*TMath::RadToDeg();
480 :
481 0 : }//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 0 : for (Int_t i = 0; i < fNSuperModule; i++) {
486 0 : if(i%2==0) {
487 0 : AliEMCALSuperModuleCoords &realA = realSM[i];
488 0 : AliEMCALSuperModuleCoords &realC = realSM[i+1];
489 0 : Double_t avgx = (realA.fX1 + realC.fX1)/2.;
490 0 : Double_t avgy = (realA.fY1 + realC.fY1)/2.;
491 0 : Double_t avgphi = (realA.fPhi + realC.fPhi)/2.;
492 0 : Double_t avgtheta = (realA.fTheta + realC.fTheta)/2.;
493 0 : Double_t avgpsi = (realA.fPsi + realC.fPsi)/2.;
494 0 : printf("AVERAGE VALUES: %.2f,%.2f,%.2f,%.2f,%.2f\n",avgx,avgy,avgphi,avgtheta,avgpsi);
495 :
496 0 : realA.fX1 = avgx; realC.fX1 = avgx;
497 0 : realA.fY1 = avgy; realC.fY1 = avgy;
498 0 : realA.fPhi = avgphi; realC.fPhi = avgphi;
499 0 : realA.fTheta = avgtheta; realC.fTheta = avgtheta;
500 0 : realA.fPsi = avgpsi; realC.fPhi = avgphi;
501 0 : }
502 : }
503 :
504 0 : fSuperModuleData = new AliEMCALSuperModuleDelta[fNSuperModule];
505 :
506 0 : for (Int_t i = 0; i < fNSuperModule; ++i) {
507 0 : const AliEMCALSuperModuleCoords &real = realSM[i];
508 0 : const AliEMCALSuperModuleCoords &ideal = idealSM[i];
509 0 : AliEMCALSuperModuleDelta &t = fSuperModuleData[i];
510 0 : t.fXShift = real.fX1 - ideal.fX1;
511 0 : t.fYShift = real.fY1 - ideal.fY1;
512 0 : t.fZShift = real.fZ1 - ideal.fZ1;
513 0 : t.fPhi = real.fPhi - ideal.fPhi;
514 0 : t.fTheta = real.fTheta - ideal.fTheta;
515 0 : t.fPsi = real.fPsi - ideal.fPsi;
516 :
517 0 : printf("===================== SM %d =======================\n",i);
518 0 : printf("real x (%.2f) - ideal x (%.2f) = shift in x (%.2f)\n",real.fX1,ideal.fX1,t.fXShift);
519 0 : printf("real y (%.2f) - ideal y (%.2f) = shift in y (%.2f)\n",real.fY1,ideal.fY1,t.fYShift);
520 0 : printf("real z (%.2f) - ideal z (%.2f) = shift in z (%.2f)\n",real.fZ1,ideal.fZ1,t.fZShift);
521 0 : printf("real theta (%.2f) - ideal theta (%.2f) = shift in theta %.2f\n",real.fTheta,ideal.fTheta,t.fTheta);
522 0 : printf("real psi (%.2f) - ideal psi (%.2f) = shift in psi %.2f\n",real.fPsi,ideal.fPsi,t.fPsi);
523 0 : printf("real phi (%.2f) - ideal phi (%.2f) = shift in phi %.2f\n",real.fPhi,ideal.fPhi,t.fPhi);
524 0 : printf("===================================================\n");
525 : }
526 :
527 0 : delete [] realSM;
528 0 : delete [] idealSM;
529 0 : }
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 0 : AliEMCALGeometry *geom = AliEMCALGeometry::GetInstance();
543 : //Center of supermodules
544 0 : Float_t pars[] = {geom->GetSuperModulesPar(0),geom->GetSuperModulesPar(1),geom->GetSuperModulesPar(2)};
545 0 : Double_t rpos = (geom->GetEnvelop(0) + geom->GetEnvelop(1))/2.;
546 0 : Float_t fInnerEdge = geom->GetDCALInnerEdge();
547 : Double_t phi=0, phiRad=0, xpos=0, ypos=0, zpos=0;
548 :
549 0 : zpos = pars[2];
550 :
551 0 : AliEMCALSuperModuleCoords *idealSM = new AliEMCALSuperModuleCoords[fNSuperModule];
552 0 : for (Int_t smodnum = 0; smodnum < geom->GetNumberOfSuperModules(); ++smodnum) {
553 0 : AliEMCALSuperModuleCoords &smc = idealSM[smodnum];
554 0 : phiRad = geom->GetPhiCenterOfSMSec(smodnum); //comes in radians
555 0 : phi = phiRad*180./TMath::Pi(); //need degrees for AliAlignObjParams
556 0 : xpos = rpos * TMath::Cos(phiRad);
557 0 : ypos = rpos * TMath::Sin(phiRad);
558 :
559 0 : if( geom->GetSMType(smodnum) == AliEMCALGeometry::kEMCAL_Half
560 0 : || geom->GetSMType(smodnum) == AliEMCALGeometry::kEMCAL_3rd
561 0 : || geom->GetSMType(smodnum) == AliEMCALGeometry::kDCAL_Ext ) {
562 0 : xpos += (pars[1]/2. * TMath::Sin(phiRad));
563 0 : ypos -= (pars[1]/2. * TMath::Cos(phiRad));
564 0 : } else if( geom->GetSMType(smodnum) == AliEMCALGeometry::kDCAL_Standard) {
565 0 : zpos = pars[2] + fInnerEdge/2.;
566 0 : }
567 :
568 0 : smc.fX1 = xpos;
569 0 : smc.fY1 = ypos;
570 :
571 0 : smc.fPhi = phi; //degrees
572 0 : smc.fTheta = 0.; //degrees
573 0 : smc.fPsi = 0.; //degrees
574 :
575 0 : if(smodnum%2==0) {
576 0 : smc.fZ1 = zpos;
577 0 : } else {
578 0 : smc.fZ1 = -zpos;
579 : }
580 :
581 : }
582 :
583 0 : AliEMCALSuperModuleCoords *realSM = new AliEMCALSuperModuleCoords[fNSuperModule];
584 0 : for (Int_t smodnum = 0; smodnum < geom->GetNumberOfSuperModules(); ++smodnum) {
585 0 : AliEMCALSuperModuleCoords &smc = realSM[smodnum];
586 0 : smc.fX1 = xReal[smodnum];
587 0 : smc.fY1 = yReal[smodnum];
588 0 : smc.fZ1 = zReal[smodnum];
589 0 : smc.fTheta = thetaReal[smodnum];
590 0 : smc.fPsi = psiReal[smodnum];
591 0 : smc.fPhi = phiReal[smodnum];
592 : }
593 :
594 0 : fSuperModuleData = new AliEMCALSuperModuleDelta[fNSuperModule];
595 :
596 0 : for (Int_t i = 0; i < fNSuperModule; ++i) {
597 0 : const AliEMCALSuperModuleCoords &real = realSM[i];
598 0 : const AliEMCALSuperModuleCoords &ideal = idealSM[i];
599 0 : AliEMCALSuperModuleDelta &t = fSuperModuleData[i];
600 0 : t.fTheta = real.fTheta - ideal.fTheta;
601 0 : t.fPsi = 0.;
602 0 : t.fPhi = real.fPhi - ideal.fPhi;
603 0 : t.fXShift = real.fX1 - ideal.fX1;
604 0 : t.fYShift = real.fY1 - ideal.fY1;
605 0 : t.fZShift = real.fZ1 - ideal.fZ1;
606 :
607 0 : printf("===================== SM %d =======================\n",i);
608 0 : printf("real x (%.2f) - ideal x (%.2f) = shift in x (%.2f)\n",real.fX1,ideal.fX1,t.fXShift);
609 0 : printf("real y (%.2f) - ideal y (%.2f) = shift in y (%.2f)\n",real.fY1,ideal.fY1,t.fYShift);
610 0 : printf("real z (%.2f) - ideal z (%.2f) = shift in z (%.2f)\n",real.fZ1,ideal.fZ1,t.fZShift);
611 0 : printf("real theta (%.2f) - ideal theta (%.2f) = shift in theta %.2f\n",real.fTheta,ideal.fTheta,t.fTheta);
612 0 : printf("real psi (%.2f) - ideal psi (%.2f) = shift in psi %.2f\n",real.fPsi,ideal.fPsi,t.fPsi);
613 0 : printf("real phi (%.2f) - ideal phi (%.2f) = shift in phi %.2f\n",real.fPhi,ideal.fPhi,t.fPhi);
614 0 : printf("===================================================\n");
615 : }
616 :
617 0 : delete [] realSM;
618 0 : delete [] idealSM;
619 0 : }
620 :
|