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