]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TOF/AliTOFAlignment.cxx
delete the AliSurvey objs after use
[u/mrichter/AliRoot.git] / TOF / AliTOFAlignment.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14 ***************************************************************************/
15
16 /*
17 $Log$
18 Revision 1.19  2007/10/02 09:46:08  arcelli
19 add methods to retrieve real survey data, and make some analysis (by B. Guerzoni)
20
21 Revision 1.17  2007/06/06 16:26:46  arcelli
22 remove fall-back call to local CDB storage
23
24 Revision 1.16  2007/05/15 16:25:44  cvetan
25 Moving the alignment-related static methods from AliAlignObj to the new geometry steering class AliGeomManager (macro from Raffaele)
26
27 Revision 1.15  2007/05/03 09:25:10  decaro
28 Coding convention: RN13 violation -> suppression
29
30 Revision 1.14  2007/04/18 14:49:54  arcelli
31 Some code cleanup, added more debug info
32
33 Revision 1.13  2007/04/17 16:38:36  arcelli
34 Include Methods to derive TOF AlignObjs from Survey Data
35
36 Revision 1.12  2007/02/28 18:09:23  arcelli
37 Add protection against failed retrieval of the CDB cal object
38
39 Revision 1.11  2006/09/19 14:31:26  cvetan
40 Bugfixes and clean-up of alignment object classes. Introduction of so called symbolic names used to identify the alignable volumes (Raffaele and Cvetan)
41
42 Revision 1.10  2006/08/22 13:26:05  arcelli
43 removal of effective c++ warnings (C.Zampolli)
44
45 Revision 1.9  2006/08/10 14:46:54  decaro
46 TOF raw data format: updated version
47
48 Revision 1.8  2006/05/04 19:41:42  hristov
49 Possibility for partial TOF geometry (S.Arcelli)
50
51 Revision 1.7  2006/04/27 13:13:29  hristov
52 Moving the destructor to the implementation file
53
54 Revision 1.6  2006/04/20 22:30:49  hristov
55 Coding conventions (Annalisa)
56
57 Revision 1.5  2006/04/16 22:29:05  hristov
58 Coding conventions (Annalisa)
59
60 Revision 1.4  2006/04/05 08:35:38  hristov
61 Coding conventions (S.Arcelli, C.Zampolli)
62
63 Revision 1.3  2006/03/31 13:49:07  arcelli
64 Removing some junk printout
65
66 Revision 1.2  2006/03/31 11:26:30  arcelli
67  changing CDB Ids according to standard convention
68
69 Revision 1.1  2006/03/28 14:54:48  arcelli
70 class for TOF alignment
71
72 author: Silvia Arcelli, arcelli@bo.infn.it
73 */  
74
75 /////////////////////////////////////////////////////////
76 //                                                     //
77 //            Class for alignment procedure            //
78 //                                                     //
79 //                                                     //
80 //                                                     //
81 /////////////////////////////////////////////////////////
82
83 #include <Rtypes.h>
84
85 #include "TMath.h"
86 #include "TFile.h"
87 #include "TRandom.h"
88
89 #include "AliLog.h"
90 #include "AliAlignObj.h"
91 #include "AliAlignObjParams.h"
92 #include "AliAlignObjMatrix.h"
93 #include "AliCDBManager.h"
94 #include "AliCDBMetaData.h"
95 #include "AliCDBId.h"
96 #include "AliCDBEntry.h"
97 #include "AliTOFAlignment.h"
98 #include "AliSurveyObj.h"
99 #include "AliSurveyPoint.h"
100 #include "TObjString.h"
101 ClassImp(AliTOFAlignment)
102
103 const Double_t AliTOFAlignment::fgkRorigTOF  = 384.5; // Mean Radius of the TOF ext. volume, cm
104 const Double_t AliTOFAlignment::fgkX1BTOF = 124.5;    //x1 size of BTOF
105 const Double_t AliTOFAlignment::fgkX2BTOF = 134.7262; //x2 size of BTOF
106 const Double_t AliTOFAlignment::fgkYBTOF = 747.2;     //y size of BTOF
107 const Double_t AliTOFAlignment::fgkZBTOF = 29.0;      //z size of BTOF
108 const Double_t AliTOFAlignment::fgkXFM = 38.0;     //x pos of FM in BTOF, cm 
109 const Double_t AliTOFAlignment::fgkYFM = 457.3;    //y pos of FM in BTOF, cm
110 const Double_t AliTOFAlignment::fgkZFM = 11.2;     //z pos of FM in BTOF, cm
111
112 //_____________________________________________________________________________
113 AliTOFAlignment::AliTOFAlignment():
114   TTask("AliTOFAlignment",""),
115   fNTOFAlignObj(0),
116   fTOFmgr(0x0),
117   fTOFAlignObjArray(0x0)
118  { 
119    //AliTOFalignment main Ctor
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;
126 }
127 //_____________________________________________________________________________
128 AliTOFAlignment::AliTOFAlignment(const AliTOFAlignment &t):
129   TTask("AliTOFAlignment",""),
130   fNTOFAlignObj(0),
131   fTOFmgr(0x0),
132   fTOFAlignObjArray(0x0)
133
134   //AliTOFAlignment copy Ctor
135
136   fNTOFAlignObj=t.fNTOFAlignObj;
137   fTOFAlignObjArray=t.fTOFAlignObjArray;
138   //AliTOFalignment main Ctor
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]; 
145 }
146 //_____________________________________________________________________________
147 AliTOFAlignment& AliTOFAlignment::operator=(const AliTOFAlignment &t){ 
148   //AliTOFAlignment assignment operator
149
150   this->fNTOFAlignObj=t.fNTOFAlignObj;
151   this->fTOFmgr=t.fTOFmgr;
152   this->fTOFAlignObjArray=t.fTOFAlignObjArray;
153   return *this;
154
155 }
156 //_____________________________________________________________________________
157 AliTOFAlignment::~AliTOFAlignment() {
158   delete fTOFAlignObjArray;
159   delete fTOFmgr;
160 }
161
162 //_____________________________________________________________________________
163 void AliTOFAlignment::Smear( Float_t *tr, Float_t *rot)
164 {
165   //Introduce Random Offset/Tilts
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);
170  
171   Int_t nSMTOF = 18;
172   AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
173   UShort_t iIndex=0; //dummy volume index
174   //  AliGeomManager::ELayerID iLayer = AliGeomManager::kTOF;
175   //  Int_t iIndex=1; //dummy volume index
176   UShort_t dvoluid = AliGeomManager::LayerToVolUID(iLayer,iIndex); //dummy volume identity 
177   Int_t i;
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];
188     AliAlignObjParams *o =new AliAlignObjParams(path, dvoluid, dx, dy, dz, dpsi, dtheta, dphi, kTRUE);
189     fTOFAlignObjArray->Add(o);
190   }
191
192   fNTOFAlignObj=fTOFAlignObjArray->GetEntries();
193   AliInfo(Form("Number of Alignable Volumes: %d",fNTOFAlignObj));
194   delete rnd;
195 }
196
197 //_____________________________________________________________________________
198 void AliTOFAlignment::Align( Float_t *tr, Float_t *rot)
199 {
200   //Introduce Offset/Tilts
201
202   fTOFAlignObjArray = new TObjArray(kMaxAlignObj);
203   Float_t dx, dy, dz;  // shifts
204   Float_t dpsi, dtheta, dphi; // angular displacements
205
206
207   Int_t nSMTOF = 18;
208   AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer;
209   UShort_t iIndex=0; //dummy volume index
210   UShort_t dvoluid = AliGeomManager::LayerToVolUID(iLayer,iIndex); //dummy volume identity 
211   Int_t i;
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];
222     
223     AliAlignObjParams *o =new AliAlignObjParams(path, dvoluid, dx, dy, dz, dpsi, dtheta, dphi, kTRUE);
224     fTOFAlignObjArray->Add(o);
225   }
226   fNTOFAlignObj=fTOFAlignObjArray->GetEntries();
227   AliInfo(Form("Number of Alignable Volumes: %d",fNTOFAlignObj));
228 }
229 //_____________________________________________________________________________
230 void AliTOFAlignment::WriteParOnCDB(Char_t *sel, Int_t minrun, Int_t maxrun)
231 {
232   //Write Align Par on CDB
233   AliCDBManager *man = AliCDBManager::Instance();
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 //_____________________________________________________________________________
244 void AliTOFAlignment::ReadParFromCDB(Char_t *sel, Int_t nrun)
245 {
246   //Read Align Par from CDB
247   AliCDBManager *man = AliCDBManager::Instance();
248   Char_t *sel1 = "AlignPar" ;
249   Char_t  out[100];
250   sprintf(out,"%s/%s",sel,sel1); 
251   AliCDBEntry *entry = man->Get(out,nrun);
252   if (!entry) { 
253     AliError(Form("Failed to get entry: %s",out));
254     return; 
255   }
256   fTOFAlignObjArray=(TObjArray*)entry->GetObject();
257   fNTOFAlignObj=fTOFAlignObjArray->GetEntries();
258   AliInfo(Form("Number of Alignable Volumes from CDB: %d",fNTOFAlignObj));
259
260 }
261 //_____________________________________________________________________________
262 void AliTOFAlignment::WriteSimParOnCDB(Char_t *sel, Int_t minrun, Int_t maxrun)
263 {
264   //Write Sim Align Par on CDB
265   AliCDBManager *man = AliCDBManager::Instance();
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 //_____________________________________________________________________________
276 void AliTOFAlignment::ReadSimParFromCDB(Char_t *sel, Int_t nrun){
277   //Read Sim Align Par from CDB
278   AliCDBManager *man = AliCDBManager::Instance();
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 }
288 //_____________________________________________________________________________
289 void AliTOFAlignment::WriteOnCDBforDC()
290 {
291   //Write Align Par on CDB for DC06
292   AliCDBManager *man = AliCDBManager::Instance();
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 //_____________________________________________________________________________
301 void AliTOFAlignment::ReadFromCDBforDC()
302 {
303   //Read Sim Align Par from CDB for DC06
304   AliCDBManager *man = AliCDBManager::Instance();
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 }
311
312 //_____________________________________________________________________________
313 void AliTOFAlignment::BuildGeomForSurvey()
314 {
315
316   //Generates the ideal TOF structure with four Fiducial Marks in each 
317   //supermodule (two on each z side) in their expected position. 
318   //Make BTOF
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:  
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];
328
329   // Now four fiducial marks on SM, expressed in local coordinates
330   // They are positioned at x=+/- 38 cm, y=+/- 457.3 cm, z=11.2 cm
331   
332   TGeoBBox *fmbox  = new TGeoBBox(1,1,1);
333   TGeoVolume* fm = new TGeoVolume("FM",fmbox);
334   fm->SetLineColor(2);
335   
336
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 );
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;
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);
353     trd1[iSM] = new TGeoVolume(name,strd1);
354     Float_t phi  = iSM * 20.;
355     Float_t phi2 = 270 + phi;
356     if (phi2 >= 360.) phi2 -= 360.;
357     smX =  TMath::Sin(phi*TMath::Pi()/180.)*smR;
358     smY = -TMath::Cos(phi*TMath::Pi()/180.)*smR;
359     smZ = 0.;  
360     TGeoRotation* bTOFRot = new TGeoRotation("bTOFRot",phi,90,0.);
361     TGeoCombiTrans trans = *(new TGeoCombiTrans(smX,smY,smZ, bTOFRot));
362     TGeoMatrix* id = new TGeoHMatrix();
363     TGeoHMatrix  transMat = *id * trans;
364     TGeoHMatrix  *smTrans = new TGeoHMatrix(transMat);
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     
374   }  
375
376   fTOFmgr->CloseGeometry();
377   fTOFmgr->GetTopVolume()->Draw();
378   fTOFmgr->SetVisOption(0);
379   fTOFmgr->SetVisLevel(6);
380
381   // Now Store the "Ideal"  Global Matrices (local to global) for later use
382   
383   for (Int_t iSM = 0; iSM < 18; iSM++) {
384
385     sprintf(name, "TOP_1/BTOF%d_1", iSM);
386     printf("\n\n*****************  TOF SuperModule:  %s ****************** \n",name);
387     TGeoPhysicalNode* pn3 = fTOFmgr->MakePhysicalNode(name);
388     fTOFMatrixId[iSM] = pn3->GetMatrix(); //save "ideal" global matrix
389     printf("\n\n***************  The Ideal Matrix in GRS *****************\n");
390     fTOFMatrixId[iSM]->Print();
391
392   }
393 }
394
395 //_____________________________________________________________________________
396 void AliTOFAlignment::InsertMisAlignment(Float_t *mis)
397 {
398   // Now Apply the Displacements and store the misaligned FM positions...
399   //
400   //
401
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};
406
407   for(Int_t iSM=0;iSM<18;iSM++){
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);
412
413     // ************* get ideal global matrix *******************
414     TGeoHMatrix g3 = *fTOFmgr->GetCurrentMatrix(); 
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(); 
418     TGeoMatrix* l3 = n3->GetMatrix(); 
419     
420     Double_t gA[3], gB[3], gC[3], gD[3]; // ideal global FM point coord.
421     g3.LocalToMaster(lA,gA);
422     g3.LocalToMaster(lB,gB);
423     g3.LocalToMaster(lC,gC);
424     g3.LocalToMaster(lD,gD);
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''
437
438     TGeoRotation* rrot = new TGeoRotation("rot",dphi,dtheta,dpsi);
439     TGeoCombiTrans localdelta = *(new TGeoCombiTrans(dx,dy,dz, rrot));
440     AliInfo(Form("This is the local delta trasformation for SM %i \n",iSM));
441     localdelta.Print();
442     TGeoHMatrix nlocal = *l3 * localdelta;
443     TGeoHMatrix* nl3 = new TGeoHMatrix(nlocal); // new matrix, representing real position (from new local mis RS to the global one)
444    
445     TGeoPhysicalNode* pn3 = fTOFmgr->MakePhysicalNode(name);
446
447     pn3->Align(nl3);   
448     
449     TGeoHMatrix* ng3 = pn3->GetMatrix(); //"real" global matrix, what survey sees 
450     printf("\n\n*************  The Misaligned Matrix in GRS **************\n");
451     ng3->Print();
452     Double_t ngA[3], ngB[3], ngC[3], ngD[3];// real FM point coord., global RS 
453     ng3->LocalToMaster(lA,ngA);
454     ng3->LocalToMaster(lB,ngB);
455     ng3->LocalToMaster(lC,ngC);
456     ng3->LocalToMaster(lD,ngD);    
457
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 //____________________________________________________________________________
473 void 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       }
494     }
495     fclose( data );
496    }
497   else{
498     printf(  "Problem opening the file\n" );
499   }
500   
501   return;  
502 }
503
504 //____________________________________________________________________________
505 void 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 //____________________________________________________________________________
547 void 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};
561
562   for (Int_t i=0;i<nf; i++)
563     {
564       AliSurveyObj *so = new AliSurveyObj();
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       } 
581       delete so;
582     }
583
584   
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     }
614 }
615
616 //_____________________________________________________________________________
617 void 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();
695   
696
697 }
698
699 //_____________________________________________________________________________
700 void AliTOFAlignment::AlignFromSurveyABC(Int_t iSM)
701 {
702
703   //From Survey data, derive the needed transformations to get the 
704   //Alignment Objects. 
705   //Again, highly "inspired" to Raffaele's example... 
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       }
715
716     printf("\n\n******Survey analysis for TOF SuperModule ************** %i \n",iSM);
717
718     // From the real fiducial marks coordinates derive back the
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
768     for(Int_t i=0;i<3;i++){
769       orig[i] = md[i] - plane[i]*fgkZFM;
770     }
771     
772     // get local directions needed to write the global rotation matrix
773     // for the surveyed volume by normalising vectors ab and bc
774     Double_t sx = TMath::Sqrt(ab[0]*ab[0] + ab[1]*ab[1] + ab[2]*ab[2]);
775
776
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     }
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();    
795
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 //_____________________________________________________________________________
822 void 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;              
912     ng.SetTranslation(orig);
913     ng.SetRotation(rot);
914     printf("\n\n**** The Misaligned Matrix in GRS, as from Survey data ***\n");
915     ng.Print();    
916
917     // Calculate the delta transformation wrt Ideal geometry
918     // (Should be gdelta.rot ==I and gdelta.tr=0 if no misalignment is applied.)
919     
920     printf("\n\n**** The ideal matrix ***\n"); 
921     fTOFMatrixId[iSM]->Print();   
922     
923     TGeoHMatrix gdelta =fTOFMatrixId[iSM]->Inverse();
924     printf("\n\n**** The inverse of the ideal matrix ***\n");
925     gdelta.Print();
926  
927     gdelta.MultiplyLeft(&ng);
928     printf("\n\n**** The Delta Matrix in GRS, as from Survey data ***\n");
929     gdelta.Print();  //global delta trasformation
930     
931     // Now Write the Alignment Objects....
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 
935     TString symname(Form("TOF/sm%02d",iSM));
936     AliAlignObjMatrix* o = new AliAlignObjMatrix(symname.Data(),dvoluid,gdelta,kTRUE);
937     fTOFAlignObjArray->Add(o);
938
939   }
940 //_____________________________________________________________________________
941 void 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 //___________________________________________________________________________
1060 void 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