AliROOT classes are at least TObject objects
[u/mrichter/AliRoot.git] / TOF / AliTOFAlignment.cxx
CommitLineData
b33ed6c7 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. *
0e46b9ae 14***************************************************************************/
15
16/*
b33ed6c7 17$Log$
24cd30eb 18Revision 1.19 2007/10/02 09:46:08 arcelli
19add methods to retrieve real survey data, and make some analysis (by B. Guerzoni)
20
90dbf5fb 21Revision 1.17 2007/06/06 16:26:46 arcelli
22remove fall-back call to local CDB storage
23
03705065 24Revision 1.16 2007/05/15 16:25:44 cvetan
25Moving the alignment-related static methods from AliAlignObj to the new geometry steering class AliGeomManager (macro from Raffaele)
26
ae079791 27Revision 1.15 2007/05/03 09:25:10 decaro
28Coding convention: RN13 violation -> suppression
29
cbf167bd 30Revision 1.14 2007/04/18 14:49:54 arcelli
31Some code cleanup, added more debug info
32
99a365f3 33Revision 1.13 2007/04/17 16:38:36 arcelli
34Include Methods to derive TOF AlignObjs from Survey Data
35
5398b994 36Revision 1.12 2007/02/28 18:09:23 arcelli
37Add protection against failed retrieval of the CDB cal object
38
1b20c168 39Revision 1.11 2006/09/19 14:31:26 cvetan
40Bugfixes and clean-up of alignment object classes. Introduction of so called symbolic names used to identify the alignable volumes (Raffaele and Cvetan)
41
b760c02e 42Revision 1.10 2006/08/22 13:26:05 arcelli
43removal of effective c++ warnings (C.Zampolli)
44
655e379f 45Revision 1.9 2006/08/10 14:46:54 decaro
46TOF raw data format: updated version
47
d0eb8f39 48Revision 1.8 2006/05/04 19:41:42 hristov
49Possibility for partial TOF geometry (S.Arcelli)
50
06e24a91 51Revision 1.7 2006/04/27 13:13:29 hristov
52Moving the destructor to the implementation file
53
e78d8265 54Revision 1.6 2006/04/20 22:30:49 hristov
55Coding conventions (Annalisa)
56
0e46b9ae 57Revision 1.5 2006/04/16 22:29:05 hristov
58Coding conventions (Annalisa)
59
7aeeaf38 60Revision 1.4 2006/04/05 08:35:38 hristov
61Coding conventions (S.Arcelli, C.Zampolli)
62
340693af 63Revision 1.3 2006/03/31 13:49:07 arcelli
64Removing some junk printout
65
0120b1d1 66Revision 1.2 2006/03/31 11:26:30 arcelli
67 changing CDB Ids according to standard convention
68
28dd10b6 69Revision 1.1 2006/03/28 14:54:48 arcelli
70class for TOF alignment
71
b33ed6c7 72author: Silvia Arcelli, arcelli@bo.infn.it
73*/
74
0e46b9ae 75/////////////////////////////////////////////////////////
76// //
77// Class for alignment procedure //
78// //
79// //
80// //
81/////////////////////////////////////////////////////////
82
b33ed6c7 83#include <Rtypes.h>
0e46b9ae 84
5398b994 85#include "TMath.h"
86#include "TFile.h"
0e46b9ae 87#include "TRandom.h"
0e46b9ae 88
b33ed6c7 89#include "AliLog.h"
b33ed6c7 90#include "AliAlignObj.h"
90dbf5fb 91#include "AliAlignObjParams.h"
5398b994 92#include "AliAlignObjMatrix.h"
b33ed6c7 93#include "AliCDBManager.h"
94#include "AliCDBMetaData.h"
b33ed6c7 95#include "AliCDBId.h"
96#include "AliCDBEntry.h"
0e46b9ae 97#include "AliTOFAlignment.h"
a1523f55 98#include "AliSurveyObj.h"
99#include "AliSurveyPoint.h"
100#include "TObjString.h"
b33ed6c7 101ClassImp(AliTOFAlignment)
a1523f55 102
5398b994 103const Double_t AliTOFAlignment::fgkRorigTOF = 384.5; // Mean Radius of the TOF ext. volume, cm
a1523f55 104const Double_t AliTOFAlignment::fgkX1BTOF = 124.5; //x1 size of BTOF
105const Double_t AliTOFAlignment::fgkX2BTOF = 134.7262; //x2 size of BTOF
106const Double_t AliTOFAlignment::fgkYBTOF = 747.2; //y size of BTOF
107const Double_t AliTOFAlignment::fgkZBTOF = 29.0; //z size of BTOF
108const Double_t AliTOFAlignment::fgkXFM = 38.0; //x pos of FM in BTOF, cm
109const Double_t AliTOFAlignment::fgkYFM = 457.3; //y pos of FM in BTOF, cm
110const Double_t AliTOFAlignment::fgkZFM = 11.2; //z pos of FM in BTOF, cm
b33ed6c7 111
112//_____________________________________________________________________________
655e379f 113AliTOFAlignment::AliTOFAlignment():
114 TTask("AliTOFAlignment",""),
115 fNTOFAlignObj(0),
5398b994 116 fTOFmgr(0x0),
655e379f 117 fTOFAlignObjArray(0x0)
118 {
5398b994 119 //AliTOFalignment main Ctor
a1523f55 120 for(Int_t i=0; i<18;i++)
121 for(Int_t j=0; j<5; j++)
122 fNFMforSM[i][j]=0;
123 for(Int_t i=0; i<72; i++)
124 for (Int_t j=0; j<6; j++)
125 fCombFMData[i][j]=0;
b33ed6c7 126}
127//_____________________________________________________________________________
655e379f 128AliTOFAlignment::AliTOFAlignment(const AliTOFAlignment &t):
129 TTask("AliTOFAlignment",""),
130 fNTOFAlignObj(0),
5398b994 131 fTOFmgr(0x0),
655e379f 132 fTOFAlignObjArray(0x0)
133{
b33ed6c7 134 //AliTOFAlignment copy Ctor
135
136 fNTOFAlignObj=t.fNTOFAlignObj;
137 fTOFAlignObjArray=t.fTOFAlignObjArray;
5398b994 138 //AliTOFalignment main Ctor
a1523f55 139 for(Int_t i=0; i<18;i++)
140 for(Int_t j=0; j<5; j++)
141 fNFMforSM[i][j]=t.fNFMforSM[i][j];
142 for(Int_t i=0; i<72; i++)
143 for (Int_t j=0; j<6; j++)
144 fCombFMData[i][j]=t.fCombFMData[i][j];
b33ed6c7 145}
b33ed6c7 146//_____________________________________________________________________________
7aeeaf38 147AliTOFAlignment& AliTOFAlignment::operator=(const AliTOFAlignment &t){
148 //AliTOFAlignment assignment operator
149
150 this->fNTOFAlignObj=t.fNTOFAlignObj;
5398b994 151 this->fTOFmgr=t.fTOFmgr;
7aeeaf38 152 this->fTOFAlignObjArray=t.fTOFAlignObjArray;
153 return *this;
154
155}
7aeeaf38 156//_____________________________________________________________________________
99a365f3 157AliTOFAlignment::~AliTOFAlignment() {
158 delete fTOFAlignObjArray;
159 delete fTOFmgr;
160}
e78d8265 161
162//_____________________________________________________________________________
340693af 163void AliTOFAlignment::Smear( Float_t *tr, Float_t *rot)
164{
165 //Introduce Random Offset/Tilts
b33ed6c7 166 fTOFAlignObjArray = new TObjArray(kMaxAlignObj);
167 Float_t dx, dy, dz; // shifts
168 Float_t dpsi, dtheta, dphi; // angular displacements
169 TRandom *rnd = new TRandom(1567);
06e24a91 170
171 Int_t nSMTOF = 18;
ae079791 172 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
28dd10b6 173 UShort_t iIndex=0; //dummy volume index
ae079791 174 // AliGeomManager::ELayerID iLayer = AliGeomManager::kTOF;
28dd10b6 175 // Int_t iIndex=1; //dummy volume index
ae079791 176 UShort_t dvoluid = AliGeomManager::LayerToVolUID(iLayer,iIndex); //dummy volume identity
b33ed6c7 177 Int_t i;
06e24a91 178 for (i = 0; i<nSMTOF ; i++) {
179 Char_t path[100];
180 sprintf(path,"/ALIC_1/B077_1/BSEGMO%i_1/BTOF%i_1",i,i);
181
182 dx = (rnd->Gaus(0.,1.))*tr[0];
183 dy = (rnd->Gaus(0.,1.))*tr[1];
184 dz = (rnd->Gaus(0.,1.))*tr[2];
185 dpsi = rot[0];
186 dtheta = rot[1];
187 dphi = rot[2];
90dbf5fb 188 AliAlignObjParams *o =new AliAlignObjParams(path, dvoluid, dx, dy, dz, dpsi, dtheta, dphi, kTRUE);
b33ed6c7 189 fTOFAlignObjArray->Add(o);
190 }
191
b33ed6c7 192 fNTOFAlignObj=fTOFAlignObjArray->GetEntries();
193 AliInfo(Form("Number of Alignable Volumes: %d",fNTOFAlignObj));
194 delete rnd;
195}
196
197//_____________________________________________________________________________
340693af 198void AliTOFAlignment::Align( Float_t *tr, Float_t *rot)
199{
200 //Introduce Offset/Tilts
b33ed6c7 201
202 fTOFAlignObjArray = new TObjArray(kMaxAlignObj);
203 Float_t dx, dy, dz; // shifts
204 Float_t dpsi, dtheta, dphi; // angular displacements
b33ed6c7 205
206
06e24a91 207 Int_t nSMTOF = 18;
ae079791 208 AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
28dd10b6 209 UShort_t iIndex=0; //dummy volume index
ae079791 210 UShort_t dvoluid = AliGeomManager::LayerToVolUID(iLayer,iIndex); //dummy volume identity
b33ed6c7 211 Int_t i;
06e24a91 212 for (i = 0; i<nSMTOF ; i++) {
213
214 Char_t path[100];
215 sprintf(path,"/ALIC_1/B077_1/BSEGMO%i_1/BTOF%i_1",i,i);
216 dx = tr[0];
217 dy = tr[1];
218 dz = tr[2];
219 dpsi = rot[0];
220 dtheta = rot[1];
221 dphi = rot[2];
b33ed6c7 222
90dbf5fb 223 AliAlignObjParams *o =new AliAlignObjParams(path, dvoluid, dx, dy, dz, dpsi, dtheta, dphi, kTRUE);
b33ed6c7 224 fTOFAlignObjArray->Add(o);
225 }
226 fNTOFAlignObj=fTOFAlignObjArray->GetEntries();
227 AliInfo(Form("Number of Alignable Volumes: %d",fNTOFAlignObj));
228}
229//_____________________________________________________________________________
340693af 230void AliTOFAlignment::WriteParOnCDB(Char_t *sel, Int_t minrun, Int_t maxrun)
231{
232 //Write Align Par on CDB
b33ed6c7 233 AliCDBManager *man = AliCDBManager::Instance();
b33ed6c7 234 Char_t *sel1 = "AlignPar" ;
235 Char_t out[100];
236 sprintf(out,"%s/%s",sel,sel1);
237 AliCDBId idTOFAlign(out,minrun,maxrun);
238 AliCDBMetaData *mdTOFAlign = new AliCDBMetaData();
239 mdTOFAlign->SetResponsible("TOF");
240 AliInfo(Form("Number of Alignable Volumes: %d",fNTOFAlignObj));
241 man->Put(fTOFAlignObjArray,idTOFAlign,mdTOFAlign);
242}
243//_____________________________________________________________________________
340693af 244void AliTOFAlignment::ReadParFromCDB(Char_t *sel, Int_t nrun)
245{
246 //Read Align Par from CDB
b33ed6c7 247 AliCDBManager *man = AliCDBManager::Instance();
b33ed6c7 248 Char_t *sel1 = "AlignPar" ;
249 Char_t out[100];
250 sprintf(out,"%s/%s",sel,sel1);
251 AliCDBEntry *entry = man->Get(out,nrun);
1b20c168 252 if (!entry) {
253 AliError(Form("Failed to get entry: %s",out));
254 return;
255 }
b33ed6c7 256 fTOFAlignObjArray=(TObjArray*)entry->GetObject();
257 fNTOFAlignObj=fTOFAlignObjArray->GetEntries();
258 AliInfo(Form("Number of Alignable Volumes from CDB: %d",fNTOFAlignObj));
259
260}
261//_____________________________________________________________________________
340693af 262void AliTOFAlignment::WriteSimParOnCDB(Char_t *sel, Int_t minrun, Int_t maxrun)
263{
264 //Write Sim Align Par on CDB
b33ed6c7 265 AliCDBManager *man = AliCDBManager::Instance();
b33ed6c7 266 Char_t *sel1 = "AlignSimPar" ;
267 Char_t out[100];
268 sprintf(out,"%s/%s",sel,sel1);
269 AliCDBId idTOFAlign(out,minrun,maxrun);
270 AliCDBMetaData *mdTOFAlign = new AliCDBMetaData();
271 mdTOFAlign->SetResponsible("TOF");
272 AliInfo(Form("Number of Alignable Volumes: %d",fNTOFAlignObj));
273 man->Put(fTOFAlignObjArray,idTOFAlign,mdTOFAlign);
274}
275//_____________________________________________________________________________
276void AliTOFAlignment::ReadSimParFromCDB(Char_t *sel, Int_t nrun){
340693af 277 //Read Sim Align Par from CDB
b33ed6c7 278 AliCDBManager *man = AliCDBManager::Instance();
b33ed6c7 279 Char_t *sel1 = "AlignSimPar" ;
280 Char_t out[100];
281 sprintf(out,"%s/%s",sel,sel1);
282 AliCDBEntry *entry = man->Get(out,nrun);
283 fTOFAlignObjArray=(TObjArray*)entry->GetObject();
284 fNTOFAlignObj=fTOFAlignObjArray->GetEntries();
285 AliInfo(Form("Number of Alignable Volumes from CDB: %d",fNTOFAlignObj));
286
287}
28dd10b6 288//_____________________________________________________________________________
340693af 289void AliTOFAlignment::WriteOnCDBforDC()
290{
291 //Write Align Par on CDB for DC06
28dd10b6 292 AliCDBManager *man = AliCDBManager::Instance();
28dd10b6 293 AliCDBId idTOFAlign("TOF/Align/Data",0,0);
294 AliCDBMetaData *mdTOFAlign = new AliCDBMetaData();
295 mdTOFAlign->SetComment("Alignment objects for ideal geometry, i.e. applying them to TGeo has to leave geometry unchanged");
296 mdTOFAlign->SetResponsible("TOF");
297 AliInfo(Form("Number of Alignable Volumes: %d",fNTOFAlignObj));
298 man->Put(fTOFAlignObjArray,idTOFAlign,mdTOFAlign);
299}
300//_____________________________________________________________________________
340693af 301void AliTOFAlignment::ReadFromCDBforDC()
302{
303 //Read Sim Align Par from CDB for DC06
28dd10b6 304 AliCDBManager *man = AliCDBManager::Instance();
28dd10b6 305 AliCDBEntry *entry = man->Get("TOF/Align/Data",0);
306 fTOFAlignObjArray=(TObjArray*)entry->GetObject();
307 fNTOFAlignObj=fTOFAlignObjArray->GetEntries();
308 AliInfo(Form("Number of Alignable Volumes from CDB: %d",fNTOFAlignObj));
309
310}
a1523f55 311
5398b994 312//_____________________________________________________________________________
313void AliTOFAlignment::BuildGeomForSurvey()
314{
315
99a365f3 316 //Generates the ideal TOF structure with four Fiducial Marks in each
317 //supermodule (two on each z side) in their expected position.
a1523f55 318 //Make BTOF
5398b994 319
320 fTOFmgr = new TGeoManager("Geom","survey to alignment for TOF");
321 TGeoMedium *medium = 0;
322 TGeoVolume *top = fTOFmgr->MakeBox("TOP",medium,1000,1000,1000);
323 fTOFmgr->SetTopVolume(top);
324 // make shape components:
a1523f55 325 // This is the BTOF containing the FTOA
326 TGeoTrd1 *strd1 = new TGeoTrd1(fgkX1BTOF*0.5,fgkX2BTOF*0.5, fgkYBTOF*0.5,fgkZBTOF*0.5);
327 TGeoVolume* trd1[18];
5398b994 328
329 // Now four fiducial marks on SM, expressed in local coordinates
a1523f55 330 // They are positioned at x=+/- 38 cm, y=+/- 457.3 cm, z=11.2 cm
331
5398b994 332 TGeoBBox *fmbox = new TGeoBBox(1,1,1);
333 TGeoVolume* fm = new TGeoVolume("FM",fmbox);
a1523f55 334 fm->SetLineColor(2);
335
5398b994 336
a1523f55 337 TGeoTranslation* mAtr = new TGeoTranslation("mAtr",-fgkXFM, -fgkYFM ,fgkZFM);
338 TGeoTranslation* mBtr = new TGeoTranslation("mBtr",fgkXFM, -fgkYFM ,fgkZFM );
339 TGeoTranslation* mCtr = new TGeoTranslation("mCtr",fgkXFM, fgkYFM ,fgkZFM );
340 TGeoTranslation* mDtr = new TGeoTranslation("mDtr",-fgkXFM, fgkYFM ,fgkZFM );
5398b994 341
342 // position all this stuff in the global ALICE frame
343
344 char name[16];
345 Double_t smX = 0.;
346 Double_t smY = 0.;
347 Double_t smZ = 0.;
348 Float_t smR = fgkRorigTOF;
5398b994 349 for (Int_t iSM = 0; iSM < 18; iSM++) {
350 Int_t mod = iSM + 13;
351 if (mod > 17) mod -= 18;
352 sprintf(name, "BTOF%d",mod);
a1523f55 353 trd1[iSM] = new TGeoVolume(name,strd1);
5398b994 354 Float_t phi = iSM * 20.;
a1523f55 355 Float_t phi2 = 270 + phi;
356 if (phi2 >= 360.) phi2 -= 360.;
5398b994 357 smX = TMath::Sin(phi*TMath::Pi()/180.)*smR;
358 smY = -TMath::Cos(phi*TMath::Pi()/180.)*smR;
a1523f55 359 smZ = 0.;
360 TGeoRotation* bTOFRot = new TGeoRotation("bTOFRot",phi,90,0.);
361 TGeoCombiTrans trans = *(new TGeoCombiTrans(smX,smY,smZ, bTOFRot));
5398b994 362 TGeoMatrix* id = new TGeoHMatrix();
363 TGeoHMatrix transMat = *id * trans;
364 TGeoHMatrix *smTrans = new TGeoHMatrix(transMat);
a1523f55 365
366 trd1[iSM]->AddNode(fm,1,mAtr); //place FM in BTOF
367 trd1[iSM]->AddNode(fm,2,mBtr);
368 trd1[iSM]->AddNode(fm,3,mCtr);
369 trd1[iSM]->AddNode(fm,4,mDtr);
370 top->AddNode(trd1[iSM],1,smTrans); //place BTOF_iSM in ALICE
371 trd1[iSM]->SetVisDaughters();
372 trd1[iSM]->SetLineColor(iSM); //black
373
5398b994 374 }
375
376 fTOFmgr->CloseGeometry();
377 fTOFmgr->GetTopVolume()->Draw();
378 fTOFmgr->SetVisOption(0);
379 fTOFmgr->SetVisLevel(6);
380
a1523f55 381 // Now Store the "Ideal" Global Matrices (local to global) for later use
382
5398b994 383 for (Int_t iSM = 0; iSM < 18; iSM++) {
384
385 sprintf(name, "TOP_1/BTOF%d_1", iSM);
99a365f3 386 printf("\n\n***************** TOF SuperModule: %s ****************** \n",name);
5398b994 387 TGeoPhysicalNode* pn3 = fTOFmgr->MakePhysicalNode(name);
a1523f55 388 fTOFMatrixId[iSM] = pn3->GetMatrix(); //save "ideal" global matrix
99a365f3 389 printf("\n\n*************** The Ideal Matrix in GRS *****************\n");
5398b994 390 fTOFMatrixId[iSM]->Print();
391
392 }
393}
a1523f55 394
5398b994 395//_____________________________________________________________________________
a1523f55 396void AliTOFAlignment::InsertMisAlignment(Float_t *mis)
5398b994 397{
398 // Now Apply the Displacements and store the misaligned FM positions...
a1523f55 399 //
400 //
5398b994 401
a1523f55 402 Double_t lA[3]={-fgkXFM, -fgkYFM ,fgkZFM};
403 Double_t lB[3]={fgkXFM, -fgkYFM ,fgkZFM};
404 Double_t lC[3]={fgkXFM, fgkYFM ,fgkZFM};
405 Double_t lD[3]={-fgkXFM, fgkYFM ,fgkZFM};
5398b994 406
407 for(Int_t iSM=0;iSM<18;iSM++){
a1523f55 408 char name[16];
409 sprintf(name, "TOP_1/BTOF%d_1", iSM);
410 fTOFmgr->cd(name);
411 printf("\n\n******Misaligning TOF SuperModule ************** %s \n",name);
5398b994 412
a1523f55 413 // ************* get ideal global matrix *******************
5398b994 414 TGeoHMatrix g3 = *fTOFmgr->GetCurrentMatrix();
a1523f55 415 AliInfo(Form("This is the ideal global trasformation of SM %i",iSM));
416 g3.Print(); // g3 is the local(BTOF) to global (ALICE) matrix and is the same of fTOFMatrixId
417 TGeoNode* n3 = fTOFmgr->GetCurrentNode();
5398b994 418 TGeoMatrix* l3 = n3->GetMatrix();
a1523f55 419
420 Double_t gA[3], gB[3], gC[3], gD[3]; // ideal global FM point coord.
cbf167bd 421 g3.LocalToMaster(lA,gA);
422 g3.LocalToMaster(lB,gB);
423 g3.LocalToMaster(lC,gC);
424 g3.LocalToMaster(lD,gD);
a1523f55 425
426 // We apply a delta transformation to the surveyed vol to represent
427 // its real position, given below by ng3 nl3, which differs from its
428 // ideal position saved above in g3 and l3
429
430 //we have to express the displacements as regards the old local RS (non misaligned BTOF)
431 Double_t dx = mis[0]; // shift along x
432 Double_t dy = mis[1]; // shift along y
433 Double_t dz = mis[2]; // shift along z
434 Double_t dphi = mis[3]; // rot around z
435 Double_t dtheta = mis[4]; // rot around x'
436 Double_t dpsi = mis[5]; // rot around z''
5398b994 437
438 TGeoRotation* rrot = new TGeoRotation("rot",dphi,dtheta,dpsi);
439 TGeoCombiTrans localdelta = *(new TGeoCombiTrans(dx,dy,dz, rrot));
a1523f55 440 AliInfo(Form("This is the local delta trasformation for SM %i \n",iSM));
441 localdelta.Print();
5398b994 442 TGeoHMatrix nlocal = *l3 * localdelta;
a1523f55 443 TGeoHMatrix* nl3 = new TGeoHMatrix(nlocal); // new matrix, representing real position (from new local mis RS to the global one)
444
5398b994 445 TGeoPhysicalNode* pn3 = fTOFmgr->MakePhysicalNode(name);
5398b994 446
a1523f55 447 pn3->Align(nl3);
5398b994 448
449 TGeoHMatrix* ng3 = pn3->GetMatrix(); //"real" global matrix, what survey sees
99a365f3 450 printf("\n\n************* The Misaligned Matrix in GRS **************\n");
5398b994 451 ng3->Print();
a1523f55 452 Double_t ngA[3], ngB[3], ngC[3], ngD[3];// real FM point coord., global RS
cbf167bd 453 ng3->LocalToMaster(lA,ngA);
454 ng3->LocalToMaster(lB,ngB);
455 ng3->LocalToMaster(lC,ngC);
456 ng3->LocalToMaster(lD,ngD);
5398b994 457
a1523f55 458 for(Int_t coord=0;coord<3;coord++){
459 fCombFMData[iSM*4][2*coord]=ngA[coord];
460 fCombFMData[iSM*4][2*coord+1]=1;
461 fCombFMData[iSM*4+1][2*coord]=ngB[coord];
462 fCombFMData[iSM*4+1][2*coord+1]=1;
463 fCombFMData[iSM*4+2][2*coord]=ngC[coord];
464 fCombFMData[iSM*4+2][2*coord+1]=1;
465 fCombFMData[iSM*4+3][2*coord]=ngD[coord];
466 fCombFMData[iSM*4+3][2*coord+1]=1;
467 }
468 }
469
470}
471
472//____________________________________________________________________________
473void AliTOFAlignment::WriteCombData(const Char_t *nomefile, Int_t option)
474{
475 // 1 for simulated data; 0 for data from survey file
476 // write combined data on a file
477 //
478
479 FILE *data;
480 /* Open file in text mode: */
481 if( (data = fopen( nomefile, "w+t" )) != NULL ){
482 if (option==1){
483 fprintf( data, "simulated data\n" );} else {
484 fprintf( data, "survey data\n" );}
485 if (option==1){
486 fprintf( data, "data from InsertMisAlignmentBTOF method\n");}
487 else {fprintf( data, "real survey data from text file (coordinate in global RS)\n");}
488 fprintf( data, "Point Name,XPH,YPH,ZPH,PrecisionX(mm),PrecisionY(mm),PrecisionZ(mm)\n");
489 fprintf( data, "> Data:\n");
490 for(Int_t i=0;i<72;i++){
491 if (fCombFMData[i][0]!=0){
492 fprintf( data, "SM%02iFM%i %f %f %f M Y %f %f %f\n", (i-i%4)/4, i%4, fCombFMData[i][0],fCombFMData[i][2],fCombFMData[i][4],fCombFMData[i][1]*10,fCombFMData[i][3]*10,fCombFMData[i][5]*10);
493 }
5398b994 494 }
a1523f55 495 fclose( data );
496 }
497 else{
498 printf( "Problem opening the file\n" );
5398b994 499 }
a1523f55 500
501 return;
502}
503
504//____________________________________________________________________________
505void AliTOFAlignment::WriteSimSurveyData(const Char_t *nomefile)
506{
507 // write sim data in standard format
508 //
509 //
510
511 FILE *data;
512 /* Open file in text mode: */
513 if( (data = fopen( nomefile, "w+t" )) != NULL )
514 {
515 fprintf( data, "> Title:\n" );
516 fprintf( data, "simulated data\n" );
517 fprintf( data, "> Date:\n" );
518 fprintf( data, "24.09.2007\n" );
519 fprintf( data, "> Subdetector:\n" );
520 fprintf( data, "TOF\n" );
521 fprintf( data, "> Report URL:\n" );
522 fprintf( data, "https://edms.cern.ch/document/835615\n" );
523 fprintf( data, "> Version:\n" );
524 fprintf( data, "1\n");
525 fprintf( data, "> General Observations:\n");
526 fprintf( data, "data from InsertMisAlignmentBTOF method\n");
527 fprintf( data, "> Coordinate System:\n");
528 fprintf( data, "\\ALICEPH\n");
529 fprintf( data, "> Units:\n");
530 fprintf( data, "cm\n");
531 fprintf( data, "> Nr Columns:\n");
532 fprintf( data, "9\n");
533 fprintf( data, "> Column Names:\n");
534 fprintf( data, "Point Name,XPH,YPH,ZPH,Point Type,Target Used,PrecisionX(mm),PrecisionY(mm),PrecisionZ(mm)\n");
535 fprintf( data, "> Data:\n");
536 for(Int_t i=0;i<72;i++)
537 if (fCombFMData[i][0]!=0)
538 fprintf( data, "SM%02iFM%i %f %f %f M Y %f %f %f\n", (i-i%4)/4, i%4, fCombFMData[i][0],fCombFMData[i][2],fCombFMData[i][4],fCombFMData[i][1],fCombFMData[i][3],fCombFMData[i][5]);
539
540 fclose( data );
541 }
542 else
543 printf( "Problem opening the file\n" );
544}
545
546//____________________________________________________________________________
547void AliTOFAlignment::MakeDefData(const Int_t nf,TString namefiles[])
548{
549 //this method combines survey data from different files (namefiles[])
550 //
551 //
552
553 Float_t data[72][6][100];
554 for (Int_t i=0;i<72;i++)
555 for (Int_t j=0; j<6; j++)
556 for(Int_t k=0; k<100; k++)
557 data[i][j][k]=0;
558 Int_t nfm=0;
559 Int_t nsm=0;
560 Long64_t totdata[72]={0};
24cd30eb 561
a1523f55 562 for (Int_t i=0;i<nf; i++)
563 {
24cd30eb 564 AliSurveyObj *so = new AliSurveyObj();
a1523f55 565 const Char_t *nome=namefiles[i];
566 so->FillFromLocalFile(nome);
567 TObjArray *points = so->GetData();
568 Int_t nSurveyPoint=points->GetEntries();
569 for(Int_t i=0;i<nSurveyPoint;i++){
570 const char* pointName= ((AliSurveyPoint *) points->At(i))->GetPointName().Data();
571 nfm=atoi(&pointName[6]);
572 nsm=atoi(&pointName[2]);
573 data[nsm*4+nfm][0][totdata[nsm*4+nfm]]=((AliSurveyPoint *) points->At(i))->GetX();
574 data[nsm*4+nfm][2][totdata[nsm*4+nfm]]=((AliSurveyPoint *) points->At(i))->GetY();
575 data[nsm*4+nfm][4][totdata[nsm*4+nfm]]=((AliSurveyPoint *) points->At(i))->GetZ();
576 data[nsm*4+nfm][1][totdata[nsm*4+nfm]]=((AliSurveyPoint *) points->At(i))->GetPrecisionX();
577 data[nsm*4+nfm][3][totdata[nsm*4+nfm]]=((AliSurveyPoint *) points->At(i))->GetPrecisionY();
578 data[nsm*4+nfm][5][totdata[nsm*4+nfm]]=((AliSurveyPoint *) points->At(i))->GetPrecisionZ();
579 totdata[nsm*4+nfm]=totdata[nsm*4+nfm]+1;
580 }
24cd30eb 581 delete so;
a1523f55 582 }
583
24cd30eb 584
a1523f55 585
586 for(Int_t i=0; i<72 ;i++){
587 Float_t numx=0, numy=0,numz=0, comodox=0, comodoy=0, comodoz=0,denx=0, deny=0, denz=0;
588 if(totdata[i]!=0){
589 for(Int_t j=0; j<totdata[i]; j++){
590 comodox=1/(data[i][1][j]/10*data[i][1][j]/10);//precision in mm, position in cm
591 numx=numx+data[i][0][j]*comodox;
592 denx=denx+comodox;
593 comodoy=1/(data[i][3][j]/10*data[i][3][j]/10);
594 numy=numy+data[i][2][j]*comodoy;
595 deny=deny+comodoy;
596 comodoz=1/(data[i][5][j]/10*data[i][5][j]/10);
597 numz=numz+data[i][4][j]*comodoz;
598 denz=denz+comodoz;
599 }
600 fCombFMData[i][1]=TMath::Sqrt(1/denx); //error for x position
601 fCombFMData[i][3]=TMath::Sqrt(1/deny); //error for y position
602 fCombFMData[i][5]=TMath::Sqrt(1/denz); //error for z position
603 fCombFMData[i][0]=numx/denx; //combined survey data for x position of FM
604 fCombFMData[i][2]=numy/deny; //combined survey data for y position of FM
605 fCombFMData[i][4]=numz/denz; //combined survey data for z position of FM
606 } else continue;
607 }
608
609 for(Int_t i=0;i<72;i++)
610 if (fCombFMData[i][0]!=0){
611 fNFMforSM[(i-i%4)/4][i%4]=1;
612 fNFMforSM[(i-i%4)/4][4]=fNFMforSM[(i-i%4)/4][4]+1;
613 }
5398b994 614}
615
616//_____________________________________________________________________________
a1523f55 617void AliTOFAlignment::ReadSurveyDataAndAlign(){
618 //
619 // read the survey data and, if we know the positions of at least 3 FM
620 //for a SM, call the right Alignement procedure
621
622 fTOFAlignObjArray = new TObjArray(kMaxAlignObj);
623
624 Float_t deltaFM0=0, deltaFM1=0, deltaFM2=0, deltaFM3=0;
625
626 for(Int_t i=0; i<18; i++){
627 switch(fNFMforSM[i][4]){
628 case 0:
629 printf("we don't know the position of any FM of SM %i\n",i);
630 break;
631 case 1:
632 printf("we know the position of only one FM for SM %i\n",i);
633
634 break;
635 case 2:
636 printf("we know the position of only 2 FM for SM %i\n",i);
637
638 break;
639 case 3:
640 if (fNFMforSM[i][0]==1 && fNFMforSM[i][1]==1 && fNFMforSM[i][2]==1){
641 printf("we know the position of FM A B C for SM %i\n",i);
642 AliTOFAlignment::AlignFromSurveyABC(i);};
643
644
645 if (fNFMforSM[i][0]==1 && fNFMforSM[i][1]==1 && fNFMforSM[i][3]==1){
646 printf("we know the position of FM A B D for SM %i\n",i);
647 AliTOFAlignment::AlignFromSurveyABD(i);};
648
649
650 if (fNFMforSM[i][0]==1 && fNFMforSM[i][2]==1 && fNFMforSM[i][3]==1){
651 printf("we know the position of FM A C D for SM %i\n",i);
652 AliTOFAlignment::AlignFromSurveyACD(i);};
653
654
655 if (fNFMforSM[i][1]==1 && fNFMforSM[i][2]==1 && fNFMforSM[i][3]==1){
656 printf("we know the position of FM B C D for SM %i\n",i);
657 AliTOFAlignment::AlignFromSurveyBCD(i);};
658
659
660 break;
661 case 4:
662 printf("we know the position of all the 4 FM for SM %i\n",i);
663 //check the precision of the measurement
664
665 deltaFM0=fCombFMData[i*4][1]/TMath::Abs(fCombFMData[i*4][0])+fCombFMData[i*4][3]/TMath::Abs(fCombFMData[i*4][2])+fCombFMData[i*4][5]/TMath::Abs(fCombFMData[i*4][4]);
666 deltaFM1=fCombFMData[i*4+1][1]/TMath::Abs(fCombFMData[i*4+1][0])+fCombFMData[i*4+1][3]/TMath::Abs(fCombFMData[i*4+1][2])+fCombFMData[i*4+1][5]/TMath::Abs(fCombFMData[i*4+1][4]);
667 deltaFM2=fCombFMData[i*4+2][1]/TMath::Abs(fCombFMData[i*4+2][0])+fCombFMData[i*4+2][3]/TMath::Abs(fCombFMData[i*4+2][2])+fCombFMData[i*4+2][5]/TMath::Abs(fCombFMData[i*4+2][4]);
668 deltaFM3=fCombFMData[i*4+3][1]/TMath::Abs(fCombFMData[i*4+3][0])+fCombFMData[i*4+3][3]/TMath::Abs(fCombFMData[i*4+3][2])+fCombFMData[i*4+3][5]/TMath::Abs(fCombFMData[i*4+3][4]);
669
670 //to AlignFromSurvey we use the 3 FM whose positions are known with greatest precision
671 if(deltaFM0>=deltaFM1 && deltaFM0>=deltaFM2 && deltaFM0>=deltaFM3){
672 printf("to Align we use FM B,C,D");
673 AliTOFAlignment::AlignFromSurveyBCD(i);} else
674 if(deltaFM1>=deltaFM0 && deltaFM1>=deltaFM2 && deltaFM1>=deltaFM3){
675 printf("to Align we use FM A,C,D");
676 AliTOFAlignment::AlignFromSurveyACD(i);} else
677 if(deltaFM2>=deltaFM0 && deltaFM2>=deltaFM1 && deltaFM2>=deltaFM3){
678 printf("to Align we use FM A,B,D");
679 AliTOFAlignment::AlignFromSurveyABD(i);} else{
680 printf("to Align we use FM A,B,C");
681 AliTOFAlignment::AlignFromSurveyABC(i);}
682
683 break;
684 }
685
686 }
687
688 // saving TOF AligObjs from survey on a file, for the moment..
689 fNTOFAlignObj=fTOFAlignObjArray->GetEntries();
690 AliInfo(Form("Number of Alignable Volumes: %d",fNTOFAlignObj));
691 TFile f("TOFAlignFromSurvey.root","RECREATE");
692 f.cd();
693 f.WriteObject(fTOFAlignObjArray,"TOFAlignObjs","kSingleKey");
694 f.Close();
24cd30eb 695
a1523f55 696
697}
698
699//_____________________________________________________________________________
700void AliTOFAlignment::AlignFromSurveyABC(Int_t iSM)
5398b994 701{
a1523f55 702
99a365f3 703 //From Survey data, derive the needed transformations to get the
5398b994 704 //Alignment Objects.
705 //Again, highly "inspired" to Raffaele's example...
a1523f55 706 //we use FM A,B,C
707
708 Double_t ngA[3], ngB[3], ngC[3]; // real FM point coord., global RS
709 // Get the 'realistic' input from the Survey Matrix
710 for(Int_t coord=0;coord<3;coord++){
711 ngA[coord]= fCombFMData[iSM*4][coord*2];
712 ngB[coord]= fCombFMData[iSM*4+1][coord*2];
713 ngC[coord]= fCombFMData[iSM*4+2][coord*2];
714 }
99a365f3 715
716 printf("\n\n******Survey analysis for TOF SuperModule ************** %i \n",iSM);
717
a1523f55 718 // From the real fiducial marks coordinates derive back the
5398b994 719 // new global position of the surveyed volume
720 //*** What follows is the actual survey-to-alignment procedure
721
722 Double_t ab[3], bc[3], n[3];
723 Double_t plane[4], s=1.;
724
725 // first vector on the plane of the fiducial marks
726 for(Int_t i=0;i<3;i++){
727 ab[i] = (ngB[i] - ngA[i]);
728 }
729
730 // second vector on the plane of the fiducial marks
731 for(Int_t i=0;i<3;i++){
732 bc[i] = (ngC[i] - ngB[i]);
733 }
734
735 // vector normal to the plane of the fiducial marks obtained
736 // as cross product of the two vectors on the plane d0^d1
737 n[0] = (ab[1] * bc[2] - ab[2] * bc[1]);
738 n[1] = (ab[2] * bc[0] - ab[0] * bc[2]);
739 n[2] = (ab[0] * bc[1] - ab[1] * bc[0]);
740
741 Double_t sizen = TMath::Sqrt( n[0]*n[0] + n[1]*n[1] + n[2]*n[2] );
742 if(sizen>1.e-8){
743 s = Double_t(1.)/sizen ; //normalization factor
744 }else{
745 AliInfo("Problem in normalizing the vector");
746 }
747
748 // plane expressed in the hessian normal form, see:
749 // http://mathworld.wolfram.com/HessianNormalForm.html
750 // the first three are the coordinates of the orthonormal vector
751 // the fourth coordinate is equal to the distance from the origin
752
753 for(Int_t i=0;i<3;i++){
754 plane[i] = n[i] * s;
755 }
756 plane[3] = ( plane[0] * ngA[0] + plane[1] * ngA[1] + plane[2] * ngA[2] );
757
758 // The center of the square with fiducial marks as corners
759 // as the middle point of one diagonal - md
760 // Used below to get the center - orig - of the surveyed box
761
762 Double_t orig[3], md[3];
763 for(Int_t i=0;i<3;i++){
764 md[i] = (ngA[i] + ngC[i]) * 0.5;
765 }
766
767 // The center of the box, gives the global translation
5398b994 768 for(Int_t i=0;i<3;i++){
a1523f55 769 orig[i] = md[i] - plane[i]*fgkZFM;
5398b994 770 }
771
772 // get local directions needed to write the global rotation matrix
773 // for the surveyed volume by normalising vectors ab and bc
5398b994 774 Double_t sx = TMath::Sqrt(ab[0]*ab[0] + ab[1]*ab[1] + ab[2]*ab[2]);
a1523f55 775
776
5398b994 777 if(sx>1.e-8){
778 for(Int_t i=0;i<3;i++){
779 ab[i] /= sx;
780 }
781 }
782 Double_t sy = TMath::Sqrt(bc[0]*bc[0] + bc[1]*bc[1] + bc[2]*bc[2]);
783 if(sy>1.e-8){
784 for(Int_t i=0;i<3;i++){
785 bc[i] /= sy;
786 }
787 }
a1523f55 788 Double_t rot[9] = {ab[0],bc[0],plane[0],ab[1],bc[1],plane[1],ab[2],bc[2],plane[2]}; // the rotation matrix
789 // the Aligned matrix for the current TOF SM in the Global RS, as derived from Survey
790 TGeoHMatrix ng;
791 ng.SetTranslation(orig);
792 ng.SetRotation(rot);
793 printf("\n\n**** The Misaligned Matrix in GRS, as from Survey data ***\n");
794 ng.Print();
99a365f3 795
a1523f55 796 // Calculate the delta transformation wrt Ideal geometry
797 // (Should be gdelta.rot ==I and gdelta.tr=0 if no misalignment is applied.)
798
799 printf("\n\n**** The ideal matrix ***\n");
800 fTOFMatrixId[iSM]->Print();
801
802 TGeoHMatrix gdelta =fTOFMatrixId[iSM]->Inverse();
803 printf("\n\n**** The inverse of the ideal matrix ***\n");
804 gdelta.Print();
805
806 gdelta.MultiplyLeft(&ng);
807 printf("\n\n**** The Delta Matrix in GRS, as from Survey data ***\n");
808 gdelta.Print(); //this is the global delta trasformation
809
810 // Now Write the Alignment Objects....
811 Int_t index=0; //let all SM modules have index=0
812 AliGeomManager::ELayerID layer = AliGeomManager::kInvalidLayer;
813 UShort_t dvoluid = AliGeomManager::LayerToVolUID(layer,index); //dummy vol id
814 TString symname(Form("TOF/sm%02d",iSM));
815 AliAlignObjMatrix* o = new AliAlignObjMatrix(symname.Data(),dvoluid,gdelta,kTRUE);
816 fTOFAlignObjArray->Add(o);
817
818 }
819
820
821//_____________________________________________________________________________
822void AliTOFAlignment::AlignFromSurveyABD(Int_t iSM)
823{
824
825 //From Survey data, derive the needed transformations to get the
826 //Alignment Objects.
827 //Again, highly "inspired" to Raffaele's example...
828 //we use FM A,B,D
829
830 Double_t ngA[3], ngB[3], ngD[3];// real FM point coord., global RS
831
832 // Get the 'realistic' input from the Survey Matrix
833 for(Int_t coord=0;coord<3;coord++){
834 ngA[coord]= fCombFMData[iSM*4][coord*2];
835 ngB[coord]= fCombFMData[iSM*4+1][coord*2];
836 ngD[coord]= fCombFMData[iSM*4+3][coord*2];
837 }
838
839 printf("\n\n******Survey analysis for TOF SuperModule ************** %i \n",iSM);
840
841 // From the new fiducial marks coordinates derive back the
842 // new global position of the surveyed volume
843 //*** What follows is the actual survey-to-alignment procedure
844
845 Double_t ab[3], ad[3], n[3];
846 Double_t plane[4], s=1.;
847
848 // first vector on the plane of the fiducial marks
849 for(Int_t i=0;i<3;i++){
850 ab[i] = (ngB[i] - ngA[i]);
851 }
852
853 // second vector on the plane of the fiducial marks
854 for(Int_t i=0;i<3;i++){
855 ad[i] = (ngD[i] - ngA[i]);
856 }
857
858 // vector normal to the plane of the fiducial marks obtained
859 // as cross product of the two vectors on the plane d0^d1
860 n[0] = (ab[1] * ad[2] - ab[2] * ad[1]);
861 n[1] = (ab[2] * ad[0] - ab[0] * ad[2]);
862 n[2] = (ab[0] * ad[1] - ab[1] * ad[0]);
863
864 Double_t sizen = TMath::Sqrt( n[0]*n[0] + n[1]*n[1] + n[2]*n[2] );
865 if(sizen>1.e-8){
866 s = Double_t(1.)/sizen ; //normalization factor
867 }else{
868 AliInfo("Problem in normalizing the vector");
869 }
870
871 // plane expressed in the hessian normal form, see:
872 // http://mathworld.wolfram.com/HessianNormalForm.html
873 // the first three are the coordinates of the orthonormal vector
874 // the fourth coordinate is equal to the distance from the origin
875
876 for(Int_t i=0;i<3;i++){
877 plane[i] = n[i] * s;
878 }
879 plane[3] = ( plane[0] * ngA[0] + plane[1] * ngA[1] + plane[2] * ngA[2] );
880
881 // The center of the square with fiducial marks as corners
882 // as the middle point of one diagonal - md
883 // Used below to get the center - orig - of the surveyed box
884
885 Double_t orig[3], md[3];
886 for(Int_t i=0;i<3;i++){
887 md[i] = (ngB[i] + ngD[i]) * 0.5;
888 }
889
890 // The center of the box, gives the global translation
891 for(Int_t i=0;i<3;i++){
892 orig[i] = md[i] - plane[i]*fgkZFM;
893 }
894
895 // get local directions needed to write the global rotation matrix
896 // for the surveyed volume by normalising vectors ab and bc
897 Double_t sx = TMath::Sqrt(ab[0]*ab[0] + ab[1]*ab[1] + ab[2]*ab[2]);
898 if(sx>1.e-8){
899 for(Int_t i=0;i<3;i++){
900 ab[i] /= sx;
901 }
902 }
903 Double_t sy = TMath::Sqrt(ad[0]*ad[0] + ad[1]*ad[1] + ad[2]*ad[2]);
904 if(sy>1.e-8){
905 for(Int_t i=0;i<3;i++){
906 ad[i] /= sy;
907 }
908 }
909 Double_t rot[9] = {ab[0],ad[0],plane[0],ab[1],ad[1],plane[1],ab[2],ad[2],plane[2]};
910 // the Aligned matrix for the current TOF SM in the Global RS, as derived from Survey:
911 TGeoHMatrix ng;
5398b994 912 ng.SetTranslation(orig);
913 ng.SetRotation(rot);
99a365f3 914 printf("\n\n**** The Misaligned Matrix in GRS, as from Survey data ***\n");
a1523f55 915 ng.Print();
99a365f3 916
917 // Calculate the delta transformation wrt Ideal geometry
918 // (Should be gdelta.rot ==I and gdelta.tr=0 if no misalignment is applied.)
a1523f55 919
920 printf("\n\n**** The ideal matrix ***\n");
921 fTOFMatrixId[iSM]->Print();
922
5398b994 923 TGeoHMatrix gdelta =fTOFMatrixId[iSM]->Inverse();
99a365f3 924 printf("\n\n**** The inverse of the ideal matrix ***\n");
a1523f55 925 gdelta.Print();
926
5398b994 927 gdelta.MultiplyLeft(&ng);
99a365f3 928 printf("\n\n**** The Delta Matrix in GRS, as from Survey data ***\n");
a1523f55 929 gdelta.Print(); //global delta trasformation
99a365f3 930
931 // Now Write the Alignment Objects....
a1523f55 932 Int_t index=0; //let all SM modules have index=0
933 AliGeomManager::ELayerID layer = AliGeomManager::kInvalidLayer;
934 UShort_t dvoluid = AliGeomManager::LayerToVolUID(layer,index); //dummy vol id
99a365f3 935 TString symname(Form("TOF/sm%02d",iSM));
936 AliAlignObjMatrix* o = new AliAlignObjMatrix(symname.Data(),dvoluid,gdelta,kTRUE);
937 fTOFAlignObjArray->Add(o);
a1523f55 938
5398b994 939 }
a1523f55 940//_____________________________________________________________________________
941void AliTOFAlignment::AlignFromSurveyACD(Int_t iSM)
942{
943 //From Survey data, derive the needed transformations to get the
944 //Alignment Objects.
945 //Again, highly "inspired" to Raffaele's example...
946 //we use FM A,C,D
947
948
949 Double_t ngA[3], ngC[3], ngD[3];// real FM point coord., global RS
950
951 // Get the 'realistic' input from the Survey Matrix
952 for(Int_t coord=0;coord<3;coord++){
953 ngA[coord]= fCombFMData[iSM*4][coord*2];
954 ngC[coord]= fCombFMData[iSM*4+2][coord*2];
955 ngD[coord]= fCombFMData[iSM*4+3][coord*2];
956 }
957
958 printf("\n\n******Survey analysis for TOF SuperModule ************** %i \n",iSM);
959
960 // From the new fiducial marks coordinates derive back the
961 // new global position of the surveyed volume
962 //*** What follows is the actual survey-to-alignment procedure
963
964 Double_t cd[3], ad[3], n[3];
965 Double_t plane[4], s=1.;
966
967 // first vector on the plane of the fiducial marks
968 for(Int_t i=0;i<3;i++){
969 cd[i] = (ngC[i] - ngD[i]);
970 }
971
972 // second vector on the plane of the fiducial marks
973 for(Int_t i=0;i<3;i++){
974 ad[i] = (ngD[i] - ngA[i]);
975 }
976
977 // vector normal to the plane of the fiducial marks obtained
978 // as cross product of the two vectors on the plane d0^d1
979 n[0] = (ad[1] * cd[2] - ad[2] * cd[1]);
980 n[1] = (ad[2] * cd[0] - ad[0] * cd[2]);
981 n[2] = (ad[0] * cd[1] - ad[1] * cd[0]);
982
983 Double_t sizen = TMath::Sqrt( n[0]*n[0] + n[1]*n[1] + n[2]*n[2] );
984 if(sizen>1.e-8){
985 s = Double_t(1.)/sizen ; //normalization factor
986 }else{
987 AliInfo("Problem in normalizing the vector");
988 }
989
990 // plane expressed in the hessian normal form, see:
991 // http://mathworld.wolfram.com/HessianNormalForm.html
992 // the first three are the coordinates of the orthonormal vector
993 // the fourth coordinate is equal to the distance from the origin
994
995 for(Int_t i=0;i<3;i++){
996 plane[i] = n[i] * s;
997 }
998 plane[3] = ( plane[0] * ngA[0] + plane[1] * ngA[1] + plane[2] * ngA[2] );
999
1000 // The center of the square with fiducial marks as corners
1001 // as the middle point of one diagonal - md
1002 // Used below to get the center - orig - of the surveyed box
1003
1004 Double_t orig[3], md[3];
1005 for(Int_t i=0;i<3;i++){
1006 md[i] = (ngA[i] + ngC[i]) * 0.5;
1007 }
1008
1009 // The center of the box, gives the global translation
1010 for(Int_t i=0;i<3;i++){
1011 orig[i] = md[i] + plane[i]*fgkZFM;
1012 }
1013
1014 // get local directions needed to write the global rotation matrix
1015 // for the surveyed volume by normalising vectors ab and bc
1016 Double_t sx = TMath::Sqrt(ad[0]*ad[0] + ad[1]*ad[1] + ad[2]*ad[2]);
1017 if(sx>1.e-8){
1018 for(Int_t i=0;i<3;i++){
1019 ad[i] /= sx;
1020 }
1021 }
1022 Double_t sy = TMath::Sqrt(cd[0]*cd[0] + cd[1]*cd[1] + cd[2]*cd[2]);
1023 if(sy>1.e-8){
1024 for(Int_t i=0;i<3;i++){
1025 cd[i] /= sy;
1026 }
1027 }
1028 Double_t rot[9] = {cd[0],ad[0],-plane[0],cd[1],ad[1],-plane[1],cd[2],ad[2],-plane[2]};
1029 // the Aligned matrix for the current TOF SM in the Global RS, as derived from Survey:
1030 TGeoHMatrix ng;
1031 ng.SetTranslation(orig);
1032 ng.SetRotation(rot);
1033 printf("\n\n**** The Misaligned Matrix in GRS, as from Survey data ***\n");
1034 ng.Print();
1035
1036 // Calculate the delta transformation wrt Ideal geometry
1037 // (Should be gdelta.rot ==I and gdelta.tr=0 if no misalignment is applied.)
1038
1039 printf("\n\n**** The ideal matrix ***\n");
1040 fTOFMatrixId[iSM]->Print();
1041
1042 TGeoHMatrix gdelta =fTOFMatrixId[iSM]->Inverse();
1043 printf("\n\n**** The inverse of the ideal matrix ***\n");
1044 gdelta.Print();
1045
1046 gdelta.MultiplyLeft(&ng);
1047 printf("\n\n**** The Delta Matrix in GRS, as from Survey data ***\n");
1048 gdelta.Print(); //global delta trasformation
1049
1050 // Now Write the Alignment Objects....
1051 Int_t index=0; //let all SM modules have index=0
1052 AliGeomManager::ELayerID layer = AliGeomManager::kInvalidLayer;
1053 UShort_t dvoluid = AliGeomManager::LayerToVolUID(layer,index); //dummy vol id
1054 TString symname(Form("TOF/sm%02d",iSM));
1055 AliAlignObjMatrix* o = new AliAlignObjMatrix(symname.Data(),dvoluid,gdelta,kTRUE);
1056 fTOFAlignObjArray->Add(o);
1057 }
1058
1059//___________________________________________________________________________
1060void AliTOFAlignment::AlignFromSurveyBCD(Int_t iSM)
1061{
1062 //From Survey data, derive the needed transformations to get the
1063 //Alignment Objects.
1064 //Again, highly "inspired" to Raffaele's example...
1065 //we use FM B,C,D
1066
1067 Double_t ngB[3], ngC[3], ngD[3];// real FM point coord., global RS
1068
1069
1070 // Get the 'realistic' input from the Survey Matrix
1071 for(Int_t coord=0;coord<3;coord++){
1072 ngB[coord]= fCombFMData[iSM*4+1][coord*2];
1073 ngC[coord]= fCombFMData[iSM*4+2][coord*2];
1074 ngD[coord]= fCombFMData[iSM*4+3][coord*2];
1075 }
1076
1077 printf("\n\n******Survey analysis for TOF SuperModule ************** %i \n",iSM);
1078
1079 // From the new fiducial marks coordinates derive back the
1080 // new global position of the surveyed volume
1081 //*** What follows is the actual survey-to-alignment procedure
1082
1083 Double_t cd[3], bc[3], n[3];
1084 Double_t plane[4], s=1.;
1085
1086 // first vector on the plane of the fiducial marks
1087 for(Int_t i=0;i<3;i++){
1088 cd[i] = (ngC[i] - ngD[i]);
1089 }
1090
1091 // second vector on the plane of the fiducial marks
1092 for(Int_t i=0;i<3;i++){
1093 bc[i] = (ngC[i] - ngB[i]);
1094 }
1095
1096 // vector normal to the plane of the fiducial marks obtained
1097 // as cross product of the two vectors on the plane d0^d1
1098 n[0] = (bc[1] * cd[2] - bc[2] * cd[1]);
1099 n[1] = (bc[2] * cd[0] - bc[0] * cd[2]);
1100 n[2] = (bc[0] * cd[1] - bc[1] * cd[0]);
1101
1102 Double_t sizen = TMath::Sqrt( n[0]*n[0] + n[1]*n[1] + n[2]*n[2] );
1103 if(sizen>1.e-8){
1104 s = Double_t(1.)/sizen ; //normalization factor
1105 }else{
1106 AliInfo("Problem in normalizing the vector");
1107 }
1108
1109 // plane expressed in the hessian normal form, see:
1110 // http://mathworld.wolfram.com/HessianNormalForm.html
1111 // the first three are the coordinates of the orthonormal vector
1112 // the fourth coordinate is equal to the distance from the origin
1113
1114 for(Int_t i=0;i<3;i++){
1115 plane[i] = n[i] * s;
1116 }
1117 plane[3] = ( plane[0] * ngB[0] + plane[1] * ngB[1] + plane[2] * ngB[2] );
1118
1119 // The center of the square with fiducial marks as corners
1120 // as the middle point of one diagonal - md
1121 // Used below to get the center - orig - of the surveyed box
1122
1123 Double_t orig[3], md[3];
1124 for(Int_t i=0;i<3;i++){
1125 md[i] = (ngB[i] + ngD[i]) * 0.5;
1126 }
1127
1128 // The center of the box, gives the global translation
1129 for(Int_t i=0;i<3;i++){
1130 orig[i] = md[i] + plane[i]*fgkZFM;
1131 }
1132
1133 // get local directions needed to write the global rotation matrix
1134 // for the surveyed volume by normalising vectors ab and bc
1135 Double_t sx = TMath::Sqrt(cd[0]*cd[0] + cd[1]*cd[1] + cd[2]*cd[2]);
1136 if(sx>1.e-8){
1137 for(Int_t i=0;i<3;i++){
1138 cd[i] /= sx;
1139 }
1140 }
1141 Double_t sy = TMath::Sqrt(bc[0]*bc[0] + bc[1]*bc[1] + bc[2]*bc[2]);
1142 if(sy>1.e-8){
1143 for(Int_t i=0;i<3;i++){
1144 bc[i] /= sy;
1145 }
1146 }
1147 Double_t rot[9] = {cd[0],bc[0],-plane[0],cd[1],bc[1],-plane[1],cd[2],bc[2],-plane[2]};
1148 // the Aligned matrix for the current TOF SM in the Global RS, as derived from Survey:
1149 TGeoHMatrix ng;
1150 ng.SetTranslation(orig);
1151 ng.SetRotation(rot);
1152 printf("\n\n**** The Misaligned Matrix in GRS, as from Survey data ***\n");
1153 ng.Print();
1154
1155 // Calculate the delta transformation wrt Ideal geometry
1156 // (Should be gdelta.rot ==I and gdelta.tr=0 if no misalignment is applied.)
1157
1158 printf("\n\n**** The ideal matrix ***\n");
1159 fTOFMatrixId[iSM]->Print();
1160
1161 TGeoHMatrix gdelta =fTOFMatrixId[iSM]->Inverse();
1162 printf("\n\n**** The inverse of the ideal matrix ***\n");
1163 gdelta.Print();
1164
1165 gdelta.MultiplyLeft(&ng);
1166 printf("\n\n**** The Delta Matrix in GRS, as from Survey data ***\n");
1167 gdelta.Print(); //global delta trasformation
1168
1169 // Now Write the Alignment Objects....
1170 Int_t index=0; //let all SM modules have index=0
1171 AliGeomManager::ELayerID layer = AliGeomManager::kInvalidLayer;
1172 UShort_t dvoluid = AliGeomManager::LayerToVolUID(layer,index); //dummy vol id
1173 TString symname(Form("TOF/sm%02d",iSM));
1174 AliAlignObjMatrix* o = new AliAlignObjMatrix(symname.Data(),dvoluid,gdelta,kTRUE);
1175 fTOFAlignObjArray->Add(o);
1176 }
1177
1178