minor fix
[u/mrichter/AliRoot.git] / ITS / AliITSSurveyToAlign.cxx
1 /**************************************************************************
2  * Copyright(c) 2008-2010, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 //////////////////////////////////////////////////////////////////////////
19 //   Class to convert survey tables in alignment objects
20 //   for SSD and SDD
21 //   origin: Marco Van Leeuwen (m.vanleeuwen1@uu.nl)
22 //           Panos.Christakoglou (Panos.Christakoglou@cern.ch)
23 //           Martin Poghosyan (Martin.Poghosyan@to.infn.it)
24 //////////////////////////////////////////////////////////////////////////
25
26 #include "TGeoManager.h"
27 #include "TGeoPhysicalNode.h"
28 #include "TMatrixD.h"
29 #include "TMath.h"
30
31 #include "AliITSSurveyToAlign.h"
32 #include "AliSurveyPoint.h"
33 #include "AliAlignObjParams.h"
34 #include "AliGeomManager.h"
35
36 #include "AliLog.h"
37
38 #include "AliCDBManager.h"
39
40 #include "AliITSgeomTGeo.h"
41
42
43 //#include "dataSDDladder.h"
44 ClassImp(AliITSSurveyToAlign)
45
46 const Double_t AliITSSurveyToAlign::fgkLocR[6][3]={{ 3.24,0.21905,-2.4},
47                                                    { 3.58,0.21905, 0. },
48                                                    { 3.24,0.21905,+2.4},
49                                                    {-3.24,0.21905,+2.4},
50                                                    {-3.58,0.21905, 0. },
51                                                    {-3.24,0.21905,-2.4}};
52
53 const Double_t AliITSSurveyToAlign::fgkLocL[6][3]={{-3.24,0.21905, 2.4},
54                                                    {-3.58,0.21905, 0. },
55                                                    {-3.24,0.21905,-2.4},
56                                                    { 3.24,0.21905,-2.4},
57                                                    { 3.58,0.21905, 0. },
58                                                    { 3.24,0.21905, 2.4}};
59
60 const Double_t kRadToDeg = 180./TMath::Pi();
61
62 //________________________________________________________________________
63 AliITSSurveyToAlign::AliITSSurveyToAlign(Int_t run, Int_t repModSDD, Int_t repModVerSDD, Int_t repLadSDD, Int_t repLadVerSDD, Int_t repModSSD, Int_t repModVerSSD, Int_t repLaddSSD, Int_t repLaddVerSSD) :
64   AliSurveyToAlignObjs(),
65   fRun(run),
66   fSDDModuleRepNumber(repModSDD),
67   fSDDModuleRepVersion(repModVerSDD),
68   fSDDLadderRepNumber(repLadSDD),
69   fSDDLadderRepVersion(repLadVerSDD),
70   fSSDModuleRepNumber(repModSSD),
71   fSSDModuleRepVersion(repModVerSSD),
72   fSSDLadderRepNumber(repLaddSSD),
73   fSSDLadderRepVersion(repLaddVerSSD)
74  {
75    // Standard constructor
76   for(Int_t i=0; i<260; i++)
77     {
78       fuidSDDm[i]= 0;
79       fsymnameSDDm[i]=TString("");
80       fxSDDm[i]=0;
81       fySDDm[i]=0;
82       fzSDDm[i]=0;
83       fpsiSDDm[i]=0;
84       ftetSDDm[i]=0;
85       fphiSDDm[i]=0;
86       if(i>35) continue;
87       fuidSDDl[i]=0;
88       fsymnameSDDl[i]=TString("");
89       fxSDDl[i]=0;
90       fySDDl[i]=0;
91       fzSDDl[i]=0;
92       fpsiSDDl[i]=0;
93       ftetSDDl[i]=0;
94       fphiSDDl[i]=0;
95     }
96
97    //   ftypeSDDlad=0;
98   //
99   //  default constructor
100   //  Arguments are report numbers for survey data. 
101   //  The defaults point to reports from detector construction
102   // 
103 }
104
105 //_________________________________________________________________________
106 AliITSSurveyToAlign::AliITSSurveyToAlign(const AliITSSurveyToAlign &align) :
107   AliSurveyToAlignObjs(align),
108   fRun(align.fRun),
109   fSDDModuleRepNumber(align.fSDDModuleRepNumber),
110   fSDDModuleRepVersion(align.fSDDModuleRepVersion),
111   fSDDLadderRepNumber(align.fSDDLadderRepNumber),
112   fSDDLadderRepVersion(align.fSDDLadderRepVersion),
113   fSSDModuleRepNumber(align.fSSDModuleRepNumber),
114   fSSDModuleRepVersion(align.fSSDModuleRepVersion),
115   fSSDLadderRepNumber(align.fSSDLadderRepNumber),
116   fSSDLadderRepVersion(align.fSSDLadderRepVersion)
117 {
118   //
119   //  copy constructor 
120   //
121   for(Int_t i=0; i<260; i++)
122     {
123       fuidSDDm[i]= align.fuidSDDm[i];
124       fsymnameSDDm[i]=TString(align.fsymnameSDDm[i]);
125       fxSDDm[i]=align.fxSDDm[i];
126       fySDDm[i]=align.fySDDm[i];
127       fzSDDm[i]=align.fzSDDm[i];
128       fpsiSDDm[i]=align.fpsiSDDm[i];
129       ftetSDDm[i]=align.ftetSDDm[i];
130       fphiSDDm[i]=align.fphiSDDm[i];
131       if(i>35) continue;
132       fuidSDDl[i]=align.fuidSDDl[i];
133       fsymnameSDDl[i]=TString(align.fsymnameSDDl[i]);
134       fxSDDl[i]=align.fxSDDl[i];
135       fySDDl[i]=align.fySDDl[i];
136       fzSDDl[i]=align.fzSDDl[i];
137       fpsiSDDl[i]=align.fpsiSDDl[i];
138       ftetSDDl[i]=align.ftetSDDl[i];
139       fphiSDDl[i]=align.fphiSDDl[i];
140     }
141
142 }
143
144 //__________________________________________________________________________
145 AliITSSurveyToAlign & AliITSSurveyToAlign::operator =(const AliITSSurveyToAlign& align)  {
146   //
147   // assignment operator
148   //
149   this->~AliITSSurveyToAlign();
150   new(this) AliITSSurveyToAlign(align);
151   return *this;
152 }
153
154 //__________________________________________________________________________
155 AliITSSurveyToAlign::~AliITSSurveyToAlign() {
156   //
157   // destructor
158   //
159 }
160
161 //______________________________________________________________________
162 void AliITSSurveyToAlign::Run() { 
163   //
164   // Runs the full chain
165   // User should call StoreAlignObjToFile or StoreAlignObjToCDB afterwards to 
166   // store output (not included here to leave the choice between the two)
167   //
168
169   // Load ideal geometry from the OCDB
170   AliCDBManager *cdb = AliCDBManager::Instance();
171   cdb->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
172   cdb->SetRun(fRun);
173   AliGeomManager::LoadGeometry();
174
175   if(!CreateAlignObjs()) AliError("Construction of alignment objects from survey failed!");
176
177
178 //______________________________________________________________________
179 Bool_t AliITSSurveyToAlign::CreateAlignObjs() { 
180   // Fill the array of alignment objects with alignment objects
181   // from survey for all three subdetectors
182   //
183
184   //for SPD
185   CreateAlignObjDummySPD();
186
187   ///////////////////////////
188   // for SDD
189   if(!LoadSurveyFromAlienFile("ITS", fSDDModuleRepNumber, fSDDModuleRepVersion)){
190       AliError("Loading of alignment objects from survey for SDD modules failed!");
191       return kFALSE;
192   }
193   CreateAlignObjSDDModules();
194
195   if(!LoadSurveyFromAlienFile("ITS", fSDDLadderRepNumber, fSDDLadderRepVersion)){
196       AliError("Loading of alignment objects from survey for SDD ladder failed!");
197       return kFALSE;
198   }
199   CreateAlignObjSDDLadders();
200   if(!ApplyAlignObjSDD()) return kFALSE;
201
202
203   // for SSD ladders
204   if(!LoadSurveyFromAlienFile("ITS", fSSDLadderRepNumber, fSSDLadderRepVersion)){
205       AliError("Loading of alignment objects from survey for SSD ladders failed!");
206       return kFALSE;
207   }
208   CreateAlignObjSSDLadders();
209
210   // for SSD modules
211   if(!ApplyAlignObjSSDLadders()) return kFALSE; // needed to build correctly the objects for SSD modules
212   if(!LoadSurveyFromAlienFile("ITS", fSSDModuleRepNumber, fSSDModuleRepVersion)){
213       AliError("Loading of alignment objects from survey for SSD modules failed!");
214       return kFALSE;
215   }
216   CreateAlignObjSSDModules();
217
218   return kTRUE;
219 }
220
221 //______________________________________________________________________
222 void AliITSSurveyToAlign::CreateAlignObjDummySPD(){
223   // 
224   // Create alignObjs for SPD
225   //    For the moment, uses 0,0,0,0,0,0
226   //
227   for(Int_t imod = 0; imod < 240; imod++) {
228     Int_t ilayer = (imod < 80) ? AliGeomManager::kSPD1 : AliGeomManager::kSPD2;
229     Int_t imodule = (imod < 80) ? imod : imod - 80;
230
231     Int_t uid = AliGeomManager::LayerToVolUID(ilayer,imodule);
232     const Char_t *symname = AliGeomManager::SymName(uid);
233
234     new((*fAlignObjArray)[imod]) AliAlignObjParams(symname, uid, 0., 0., 0., 0., 0., 0., kTRUE);
235   }//module loop
236
237 }
238 Bool_t AliITSSurveyToAlign::ApplyAlignObjSDD()
239 {
240   // Apply alignment for SDD
241   Int_t applied=0;
242
243   for(Int_t iLadd=0; iLadd<36; iLadd++)
244     {
245       new((*fAlignObjArray)[240+iLadd]) AliAlignObjParams(fsymnameSDDl[iLadd].Data(), fuidSDDl[iLadd], 
246                                                fxSDDl[iLadd]  , fySDDl[iLadd]  , fzSDDl[iLadd]  , 
247                                                fpsiSDDl[iLadd], ftetSDDl[iLadd], fphiSDDl[iLadd], kFALSE);
248       //      new((*fAlignObjArray)[240+iLadd]) AliAlignObjParams(fsymnameSDDl[iLadd].Data(), fuidSDDl[iLadd], 
249       //                               fxSDDl[iLadd]  , fySDDl[iLadd]  , fzSDDl[iLadd]  , 
250       //                               0, 0, 0, kFALSE);
251
252       AliAlignObjParams* ap = dynamic_cast<AliAlignObjParams*> (fAlignObjArray->UncheckedAt(240+iLadd));
253       //      printf("%s  %f  %f  %f\n",fxSDDl[iLadd], fsymnameSDDl[iLadd].Data(), fySDDl[iLadd]  , fzSDDl[iLadd]);
254       //printf("%d  %f\n", iLadd, fzSDDl[iLadd]);
255
256       if(ap != 0 && fsymnameSDDl[iLadd].Contains("SDD") && fsymnameSDDl[iLadd].Contains("Ladder"))
257         {
258           //      printf("%d  %s  %d\n",240+iLadd, fsymnameSDDl[iLadd].Data(),fuidSDDl[iLadd] );
259
260           if(!ap->ApplyToGeometry()) return kFALSE;
261           applied++;
262         }
263       else
264         {
265           AliError("SDD Ladder array is not initialized correctly");
266           return kFALSE;
267         }
268     }
269
270   for(Int_t iMod=0; iMod<260; iMod++)
271     {
272       //           printf("%d s=%s  x= %f  y= %f  z= %f\n",240+36+iMod, fsymnameSDDm[iMod].Data(),fxSDDm[iMod], fySDDm[iMod], fzSDDm[iMod] );
273
274       new((*fAlignObjArray)[240+36+iMod]) AliAlignObjParams(fsymnameSDDm[iMod].Data(), fuidSDDm[iMod], 
275                                              fxSDDm[iMod]  , fySDDm[iMod]  , fzSDDm[iMod], 
276                                              fpsiSDDm[iMod], ftetSDDm[iMod], fphiSDDm[iMod], kFALSE);
277
278      
279           if(!fsymnameSDDm[iMod].Contains("SDD") || !fsymnameSDDm[iMod].Contains("Sensor"))
280             {
281           AliError("SDD Module array is not initialized correctly\n");
282           return kFALSE;
283             }
284
285     }
286
287   AliInfo(Form(" %d alignment objects for SDD ladders applied to geometry.",applied));
288   return kTRUE;
289 }
290
291 //______________________________________________________________________
292 void AliITSSurveyToAlign::CreateAlignObjSDDModules(){
293   //
294   // Create alignment objects for SDD
295   // Called by Run()
296   //
297   Int_t uid = 0;
298   const char* symname = 0;
299   AliSurveyPoint* pt = 0;
300  
301   Int_t iModuleIndex=240;
302   Int_t iModule0=0;
303   Int_t iLadder0=0;
304   Int_t iLayer0=3;
305   Int_t nModules=0;
306
307   if (fSurveyPoints == 0 || fSurveyPoints->GetEntries() == 0) {
308     AliWarning("SDD survey data are not available, using zero values");
309     CreateAlignObjDummySDDModules();
310     return;
311   }
312
313   for(Int_t imod = 1; imod < fSurveyPoints->GetEntries(); imod++) {
314     pt = (AliSurveyPoint*) fSurveyPoints->At(imod);
315     if(!pt) continue;
316
317     Int_t iLayer, iLadder, iModule, iPoint;
318     ReadPointNameSDD(pt->GetName(),iLayer, iLadder, iModule, iPoint);
319
320       Double_t x =pt->GetX();
321       Double_t y =pt->GetY();
322       Double_t z =pt->GetZ();
323       Double_t xE=pt->GetPrecisionX();
324       Double_t yE=pt->GetPrecisionY();
325       Double_t zE=pt->GetPrecisionZ();
326   
327          if(iLayer==3 && iLadder==2)
328         {
329           if(iPoint<3) iPoint+=3;
330           else if(iPoint>2) iPoint-=3;
331           iModule=TMath::Abs(iModule - 5);
332           x=500-x;
333           y*=-1;
334         }
335       
336
337       iModuleIndex = AliITSgeomTGeo::GetModuleIndex(iLayer0,iLadder0+1,iModule0+1);
338       Int_t iModuleIndex1 = AliITSgeomTGeo::GetModuleIndex(iLayer,iLadder+1,iModule+1);
339
340     if(iModuleIndex==iModuleIndex1)
341     {
342       fSDDmeP[iPoint][0]=x;
343       fSDDmeP[iPoint][1]=y;
344       fSDDmeP[iPoint][2]=z;
345       fSDDmeP[iPoint][3]=xE;
346       fSDDmeP[iPoint][4]=yE;
347       fSDDmeP[iPoint][5]=zE;
348       fSDDisMe[iPoint]=kTRUE;
349
350       if(iLayer==3) uid = AliGeomManager::LayerToVolUID(iLayer0,iModuleIndex-240);
351       if(iLayer==4) uid = AliGeomManager::LayerToVolUID(iLayer0,iModuleIndex-324);
352       symname = AliGeomManager::SymName(uid);
353       GetIdPosSDD(uid,iLayer0, iModule0, iPoint);
354       nModules++;
355
356
357       //      printf("%s\n",pt->GetName());
358       //      printf("Me: %7.4f  %7.4f  %7.4f\n", fSDDmeP[iPoint][0], fSDDmeP[iPoint][1], fSDDmeP[iPoint][2]);
359       //      printf("Id: %7.4f  %7.4f  %7.4f\n", fSDDidP[iPoint][0], fSDDidP[iPoint][1], fSDDidP[iPoint][2]);
360     }
361
362     //    cout << "Points red module " << imod << endl;
363     if((iModuleIndex!=iModuleIndex1)||(imod==(fSurveyPoints->GetEntries()-1)))
364     {
365       ConvertToRSofModulesAndRotSDD(iLayer0, iModule0);
366
367       Double_t tet = 0.;
368       Double_t psi = 0.;
369       Double_t phi = 0.;
370       Double_t x0  = 0.;
371       Double_t y0  = 0.;
372       Double_t z0  = 0.;
373
374       if(nModules==2) CalcShiftSDD(x0,y0,z0);
375       if(nModules>2)   CalcShiftRotSDD(tet, psi, phi, x0, y0, z0);
376       //          printf("%s  %d  %f  %f  %f  %f  %f  %f\n",symname, uid, x0/10., y0/10., z0/10., psi, tet, phi);
377       tet*=kRadToDeg;
378       psi*=kRadToDeg;
379       phi*=kRadToDeg;
380 //      cout << "Allocate alignobjparams " << imod << endl;
381 //      new((*fAlignObjArray)[iModuleIndex]) AliAlignObjParams(symname, uid, x0/10., y0/10., z0/10., psi, tet, phi, kFALSE);
382 //       printf("INDEX:   Module: %d\n",iModuleIndex);
383
384
385       fsymnameSDDm[iModuleIndex-240]=TString(symname);
386       fuidSDDm[iModuleIndex-240]=uid;
387       fxSDDm[iModuleIndex-240]=x0/10.;
388       fySDDm[iModuleIndex-240]=y0/10.;
389       fzSDDm[iModuleIndex-240]=z0/10.;
390       fpsiSDDm[iModuleIndex-240]=psi;
391       ftetSDDm[iModuleIndex-240]=tet;
392       fphiSDDm[iModuleIndex-240]=phi;
393       //      new((*fAlignObjArray)[36+iModuleIndex]) AliAlignObjParams(fsymnameSDDm[iModuleIndex-240].Data(), fuidSDDm[iModuleIndex-240], 
394       //                                             fxSDDm[iModuleIndex-240], fySDDm[iModuleIndex-240], fzSDDm[iModuleIndex-240], 
395       //                                             fpsiSDDm[iModuleIndex-240], ftetSDDm[iModuleIndex-240], fphiSDDm[iModuleIndex-240], kFALSE);
396       iModule0=iModule;
397       iLayer0=iLayer;
398       iLadder0=iLadder;
399       nModules=0;
400       //      iModuleIndex = AliITSgeomTGeo::GetModuleIndex(iLayer,iLadder+1,iModule+1);
401       for(Int_t i=0; i<6;i++) fSDDisMe[i]=kFALSE;
402       if(imod!=(fSurveyPoints->GetEntries()-1)) imod--;
403     }
404   }//module loop
405 //  printf("done\n");
406 }
407
408 //______________________________________________________________________
409 void AliITSSurveyToAlign::CreateAlignObjDummySDDModules(){
410   // 
411   // Create empty alignment objects
412   // Used when fSurveySDD == 0
413   //
414   for(Int_t imod = 0; imod < 260; imod++) {
415
416     Int_t ilayer = (imod < 84) ? AliGeomManager::kSDD1 : AliGeomManager::kSDD2;
417     Int_t imodule = (imod < 84) ? imod : imod - 84;
418
419     Int_t uid = AliGeomManager::LayerToVolUID(ilayer,imodule);
420     const Char_t *symname = AliGeomManager::SymName(uid);
421
422       fsymnameSDDm[imod]=TString(symname);
423       fuidSDDm[imod]=uid;
424       fxSDDm[imod]=0.;
425       fySDDm[imod]=0.;
426       fzSDDm[imod]=0.;
427       fpsiSDDm[imod]=0.;
428       ftetSDDm[imod]=0.;
429       fphiSDDm[imod]=0.;
430
431     //    new((*fAlignObjArray)[imod+36+240]) AliAlignObjParams(symname, uid, 0., 0., 0., 0., 0., 0., kTRUE);
432   }//module loop
433 }
434
435 //______________________________________________________________________
436 void AliITSSurveyToAlign::CreateAlignObjSSDModules(){
437   //
438   // Create alignment objects for SSD modules
439   // Objects for SSD ladders must be applied to geometry first
440   //
441   Double_t sx, sz;
442   const Float_t kMu2Cm = 1e-4;
443   const Float_t kSensLength = 7.464;
444   const Int_t kSSDMODULES = 1698;
445
446   if (fSurveyPoints == 0 || fSurveyPoints->GetEntries() == 0) {
447     AliWarning("SSD module survey data not available; using dummy values");
448     CreateAlignObjDummySSDModules();
449     return;
450   }
451
452   // First do module-by-module
453
454   for(Int_t imod = 500; imod < kSSDMODULES + 500; imod++) {
455     Int_t iLayer, iLadder, iLaddMod;
456     AliITSgeomTGeo::GetModuleId(imod,iLayer,iLadder,iLaddMod);  // returns 1-based numbers
457  
458     TString pname="ITS/SSD";
459     pname += iLayer-1;
460     pname += "/Ladder";
461     pname += iLadder-1;
462     pname += "/Sensor";
463     pname += iLaddMod-1;
464     AliSurveyPoint *pt1 = (AliSurveyPoint*) fSurveyPoints->FindObject(pname+"/Point0");
465     AliSurveyPoint *pt2 = (AliSurveyPoint*) fSurveyPoints->FindObject(pname+"/Point1");
466     if(!pt1 || !pt2) {
467       AliWarning(Form("No Survey points for iladd %d imod %d",iLadder,iLaddMod));
468       continue;
469     }
470
471     sx = 0.5*(pt1->GetX() + pt2->GetX()) * kMu2Cm;
472     sz = 0.5*(pt1->GetZ() + pt2->GetZ()) * kMu2Cm;
473
474     // Minus sign to change local coordinate convention 
475     Float_t theta = -(pt2->GetZ() - pt1->GetZ())*kMu2Cm/kSensLength;
476
477     theta *= kRadToDeg;
478     Int_t iLayMod = imod - 500;
479     if (iLayer == 6)
480       iLayMod -= 748;
481     Int_t uid = AliGeomManager::LayerToVolUID(iLayer,iLayMod);
482
483     const Char_t *symname = AliGeomManager::SymName(uid);
484     if (pname.CompareTo(symname) != 0)
485       AliWarning(Form("Mapping mismatch survey point %s volume name %s",pname.Data(),symname));
486     /*
487     if (imod >= 676 && imod <= 697) {
488       cout << "ilayer " << iLayer << " imod " << imod 
489            << " uid " << uid << " name " << symname 
490            << " survey shift " << sx << " " << 0 << " " << sz << endl
491            << " theta " << theta << endl;
492     }
493     */
494     new((*fAlignObjArray)[imod+36]) AliAlignObjParams(symname, uid, sx, 0, sz, 0., theta, 0., kFALSE);
495   } //module loop
496 }
497
498 //______________________________________________________________________
499 Bool_t AliITSSurveyToAlign::ApplyAlignObjSSDLadders(){
500   //
501   //   Apply alignment objects for SSD ladders to geometry, needed to correctly
502   //   build alignment objects for SSD modules
503   // 
504   Int_t applied=0;
505
506   for(Int_t jj=0; jj<fAlignObjArray->GetEntriesFast(); jj++)
507   {
508       AliAlignObjParams* ap = dynamic_cast<AliAlignObjParams*> (fAlignObjArray->UncheckedAt(jj));
509       if(ap) 
510       {
511           TString sName(ap->GetSymName());
512           if(sName.Contains("SSD") && sName.Contains("Ladder"))
513           {
514               if(!ap->ApplyToGeometry()) return kFALSE;
515               applied++;
516           }
517       }
518   }
519   AliInfo(Form(" %d alignment objects for SSD ladders applied to geometry.",applied));
520
521   return kTRUE;
522 }
523 //______________________________________________________________________
524 /*
525 Bool_t AliITSSurveyToAlign::ApplyAlignObjSDDLadders(){
526   //
527   //   Apply alignment objects for SDD ladders to geometry, needed to correctly
528   //   build alignment objects for SDD modules
529   // 
530   Int_t applied=0;
531
532   for(Int_t jj=0; jj<fAlignObjArray->GetEntriesFast(); jj++)
533   {
534       AliAlignObjParams* ap = dynamic_cast<AliAlignObjParams*> (fAlignObjArray->UncheckedAt(jj));
535       if(ap) 
536       {
537           TString sName(ap->GetSymName());
538 //        printf("%s\n",sName.Data());
539           if(sName.Contains("SDD") && sName.Contains("Ladder"))
540           {
541               if(!ap->ApplyToGeometry()) return kFALSE;
542               applied++;
543           }
544       }
545   }
546   AliInfo(Form(" %d alignment objects for SDD ladders applied to geometry.",applied));
547
548   return kTRUE;
549 }
550 */
551 //______________________________________________________________________
552 void AliITSSurveyToAlign::CreateAlignObjDummySDDLadders()
553 {
554   // 
555   // Create empty alignment objects
556   TString sddName = "ITS/SDD";
557   Int_t iLadd = 0;
558
559   for (Int_t ilayer =  0; ilayer <  2; ilayer ++)
560     {
561     Int_t nLadder = 14;              // layer SDD1
562     if (ilayer == 1)  nLadder = 22;  // layer SDD2
563     for (Int_t iLadder = 0; iLadder < nLadder; iLadder++) {
564       TString ladName = sddName;
565       ladName += (ilayer+2);      
566       ladName += "/Ladder";
567       ladName += iLadder;
568       fsymnameSDDl[iLadd]=TString(ladName);
569       fuidSDDl[iLadd]=0;
570       fxSDDl[iLadd]=0;
571       fySDDl[iLadd]=0;
572       fzSDDl[iLadd]=0;
573       fpsiSDDl[iLadd]=0;
574       ftetSDDl[iLadd]=0;
575       fphiSDDl[iLadd]=0;
576       iLadd++;
577     }  // Ladder loop
578   }  // Layer loop
579
580 }
581
582
583
584 void AliITSSurveyToAlign::CreateAlignObjSDDLadders(){
585   //
586   //   Alignment objects from survey for SDD ladders
587   // 
588   const Float_t kLaddLenz[2] ={500, 650};  // Layer 2,3: distance between mouting points along z (mm)
589   const Float_t kLaddLenx    = 28 ;        // Layer 2,3: distance between mouting points along x (mm)
590
591   TString sddName = "ITS/SDD";
592
593  TObjArray *ladderPoints = fSurveyPoints;  
594   if (ladderPoints == 0 || ladderPoints->GetEntries() == 0) {
595     AliWarning("No SDD Ladder alignment points found. Skipping");
596     return;
597   }
598   if (ladderPoints->GetEntries()!= 72) {
599     AliWarning(Form("Unexpected number of survey points %d, should be 72",ladderPoints->GetEntries())); 
600   }
601  
602
603 /*
604 TAlien::Connect("alien://");
605 gSystem->Load("libXMLParser.so");
606 .x loadlibs.C 
607
608 AliCDBManager *cdb = AliCDBManager::Instance();
609 cdb->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
610 cdb->SetRun(0);
611 AliGeomManager::LoadGeometry();
612 AliITSSurveyToAlign *a = new AliITSSurveyToAlign(); 
613
614 a->CreateAlignObjSDDLadders()                     
615 a->ApplyAlignObjSDDLadders();
616
617 a->LoadSurveyFromAlienFile("ITS", 845069, 1);
618 a->CreateAlignObjSDD();
619
620 a->CreateAlignObjs();
621 */
622
623   Int_t iLadd = 0;
624
625   for (Int_t ilayer =  0; ilayer <  2; ilayer ++)
626     {
627     Int_t nLadder = 14;              // layer SDD1
628     if (ilayer == 1)  nLadder = 22;  // layer SDD2
629
630     for (Int_t iLadder = 0; iLadder < nLadder; iLadder++) {
631       TString ladName = sddName;
632       ladName += (ilayer+2);      
633       ladName += "/Ladder";
634       ladName += iLadder;
635
636
637       /////////////////////////////////////////////////////////////////////////////
638       AliSurveyPoint *p24 =  (AliSurveyPoint*) ladderPoints->FindObject(ladName+"/RB24");
639       AliSurveyPoint *p26 =  (AliSurveyPoint*) ladderPoints->FindObject(ladName+"/RB26");
640       if (p24 == 0) {
641         AliWarning(Form("Cannot find RB24 side point for ladder %s",ladName.Data()));
642         continue;
643       }
644       if (p26 == 0) {
645         AliWarning(Form("Cannot find RB26 side point for ladder %s",ladName.Data()));
646         continue;
647       }
648
649       TString tmpStr;
650       tmpStr.Insert(0,p24->GetName(),3);
651       Int_t ladder = tmpStr.Atoi();
652       tmpStr="";
653       tmpStr.Insert(0,p26->GetName(),3);
654       if (tmpStr.Atoi() != ladder) 
655         AliError(Form("Survey data file error. Expect pairs of RB24, RB26 points. Got ladders %d %d",ladder,tmpStr.Atoi()));
656
657
658       Double_t x24, y24, z24;
659       Double_t x26, y26, z26;
660
661       x24=p24->GetX();
662       y24=p24->GetY();
663       z24=p24->GetZ();
664       x26=p26->GetX();
665       y26=p26->GetY();
666       z26=p26->GetZ();
667
668       // for top ladders: RS(local) = RS(global) + Y_shift 
669       // rot around z-axis
670       Double_t phi = 0;  // Not measured
671       // rot around y-axis
672       Double_t theta = 0;
673       // rot around x-axis
674       Double_t psi = 0;
675
676
677       psi=TMath::ATan((y26-y24)/(kLaddLenz[ilayer]+z24-z26));
678       Double_t tgtet0 = kLaddLenx/kLaddLenz[ilayer];
679       Double_t tgtet1 = (x24-x26+kLaddLenx)/(kLaddLenz[ilayer]+z24-z26);
680       theta=TMath::ATan((tgtet1-tgtet0)/(1+tgtet1*tgtet0));
681
682       Double_t x0=x24-theta*kLaddLenz[ilayer]/2;
683       Double_t y0=y24+psi*kLaddLenz[ilayer]/2;
684       Double_t z0=z24+theta*kLaddLenx/2;
685
686       theta*= kRadToDeg;
687       psi*= kRadToDeg;
688
689       // local delta transformation by passing 3 shifts (in centimeters) and 3 angles (expressed in degrees)    
690       //      new((*fAlignObjArray)[500+1698+144+iLadd]) AliAlignObjParams(ladName,0,drLoc[0],drLoc[1],drLoc[2],psi,theta,phi,kFALSE);
691       fsymnameSDDl[iLadd]=TString(ladName);
692       fuidSDDl[iLadd]=0;
693       fxSDDl[iLadd]=x0/10.;
694       fySDDl[iLadd]=y0/10.;
695       fzSDDl[iLadd]=z0/10.;
696       fpsiSDDl[iLadd]=psi;
697       ftetSDDl[iLadd]=theta;
698       fphiSDDl[iLadd]=phi;
699       //      new((*fAlignObjArray)[240+iLadd]) AliAlignObjParams(fsymnameSDDl[iLadd].Data(), fuidSDDl[iLadd], 
700       //                                               fxSDDl[iLadd]  , fySDDl[iLadd]  , fzSDDl[iLadd]  , 
701       //                                               fpsiSDDl[iLadd], ftetSDDl[iLadd], fphiSDDl[iLadd], kFALSE);
702       //       printf("INDEX:   Ladder: %d\n",iLadd);
703       iLadd++;
704     }  // Ladder loop
705   }  // Layer loop
706 }
707 ////////////////////////////////////////////////////////////////////////////////////////
708
709
710
711 //______________________________________________________________________
712 void AliITSSurveyToAlign::CreateAlignObjSSDLadders(){
713   //
714   //   Alignment objects from survey for SSD ladders (Torino data)
715   // 
716   const Float_t kLaddLen5 = 90.27;  // Layer 5: distance between mouting points
717   const Float_t kLaddLen6 = 102.0;  // Layer 6: distance between mouting points
718   const Float_t zLag = 2.927;         // Distance between V mounting point and Zloc = 0
719                                     // = half ladder length - nom z-position of ladder from gGeoManager
720   const Float_t kMu2Cm = 1e-4;
721
722   TString ssdName = "ITS/SSD";
723
724   TObjArray *ladderPoints = fSurveyPoints;  
725   if (ladderPoints == 0 || ladderPoints->GetEntries() == 0) {
726     AliWarning("No SSD Ladder alignment points found. Skipping");
727     return;
728   }
729   if (ladderPoints->GetEntries()!= 2*(34+38)) {
730     AliWarning(Form("Unexpected number of survey points %d, should be 144",ladderPoints->GetEntries())); 
731   }
732   Int_t iLadd = 0;
733   for (Int_t ilayer =  4; ilayer <=  5; ilayer ++) {
734     Int_t nLadder = 34; // layer 5
735     if (ilayer == 5)
736       nLadder = 38;     // layer 6
737
738     for (Int_t iLadder = 0; iLadder < nLadder; iLadder++) {
739       TString ladName = ssdName;
740       ladName += ilayer;
741       ladName += "/Ladder";
742       ladName += iLadder;
743
744       AliSurveyPoint *vPoint =  (AliSurveyPoint*) ladderPoints->FindObject(ladName+"/V");
745       AliSurveyPoint *qPoint =  (AliSurveyPoint*) ladderPoints->FindObject(ladName+"/Q");
746       if (vPoint == 0) {
747         AliWarning(Form("Cannot find V side point for ladder %s",ladName.Data()));
748         continue;
749       }
750       if (qPoint == 0) {
751         AliWarning(Form("Cannot find Q side point for ladder %s",ladName.Data()));
752         continue;
753       }
754
755       TString tmpStr;
756       tmpStr.Insert(0,vPoint->GetName(),3);
757       Int_t ladder = tmpStr.Atoi();
758       tmpStr="";
759       tmpStr.Insert(0,qPoint->GetName(),3);
760       if (tmpStr.Atoi() != ladder) 
761         AliError(Form("Survey data file error. Expect pairs of V,Q points. Got ladders %d %d",ladder,tmpStr.Atoi()));
762
763       // Note: file gives meas-nom in local offline coordinates, 
764       // ie. local z = - global z and local x = - global x (for ladder 508, i.e. top ladder)
765       Double_t dxLoc = vPoint->GetX() * kMu2Cm;
766       Double_t dyLoc = vPoint->GetY() * kMu2Cm;
767       Double_t dzLoc = vPoint->GetZ() * kMu2Cm;
768
769       // rot around z-axis
770       Double_t phi = 0;  // Not measured
771       // rot around y-axis
772       Double_t theta = 0;
773       Double_t psi = 0;
774
775       // Note: local psi = -global psi, psi = atan(-(y(z1) - y(z0)) / (z1-z0))  
776       // local theta = global theta = atan(dx/dz) 
777       // V side is A side is large global z 
778       // Q side is C side is large local z
779
780
781       if (ladder >= 600) {
782         theta = TMath::ATan((qPoint->GetX() - vPoint->GetX())*kMu2Cm/kLaddLen6);
783         psi = TMath::ATan((vPoint->GetY() - qPoint->GetY())*kMu2Cm/kLaddLen6);
784       }
785       else {
786         theta = TMath::ATan((qPoint->GetX() - vPoint->GetX())*kMu2Cm/kLaddLen5);
787         psi = TMath::ATan((vPoint->GetY() - qPoint->GetY())*kMu2Cm/kLaddLen5);
788       } 
789
790       // Move along ladder to local Z = 0 point
791       dxLoc += zLag*theta;
792       dyLoc -= zLag*psi;
793
794       // Convert to degrees
795       theta *= kRadToDeg;
796       psi *= kRadToDeg;
797       AliDebug(1,Form("ladname %f %f %f %f %f %f ",dxLoc,dyLoc,dzLoc,psi,theta,phi));  
798       
799       new((*fAlignObjArray)[500+36+1698+iLadd]) AliAlignObjParams(ladName,0,dxLoc,dyLoc,dzLoc,psi,theta,phi,kFALSE);
800
801       iLadd++;
802     }  // Ladder loop
803   }  // Layer loop
804 }
805 ////////////////////////////////////////////////////////////////////////////////////////
806
807 //______________________________________________________________________
808 void AliITSSurveyToAlign::CreateAlignObjDummySSDModules(){
809   // 
810   // Create empty alignment objects
811   // Used when fSurveySSD == 0
812   //
813   for(Int_t imod = 0; imod < 1698; imod++) {
814     Int_t ilayer = (imod < 748) ? AliGeomManager::kSSD1 : AliGeomManager::kSSD2;
815     Int_t imodule = (imod < 748) ? imod : imod - 748;
816
817     Int_t uid = AliGeomManager::LayerToVolUID(ilayer,imodule);
818     const Char_t *symname = AliGeomManager::SymName(uid);
819
820     new((*fAlignObjArray)[500+36+imod]) AliAlignObjParams(symname, uid, 0., 0., 0., 0., 0., 0., kTRUE);
821   }//module loop
822 }
823
824
825 //______________________________________________________________________
826 void AliITSSurveyToAlign::GetIdPosSDD(Int_t uid, Int_t layer, Int_t module, Int_t iPoint)
827 {
828   // 
829   //    Utility function used by CreateAlignObjSDD
830   // 
831   TGeoHMatrix gMod = *AliGeomManager::GetMatrix(uid); //global matrix of sensor
832   TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID(uid);
833   // TString ladderPath = AliGeomManager::SymName(uid);
834   TString ladderPath(pne->GetTitle());
835   if(ladderPath.EndsWith("/")) ladderPath.Remove(TString::kTrailing,'/');
836   ladderPath.Remove(ladderPath.Last('/'));
837   //  ladderPath.Remove(ladderPath.Last('/'));
838   gGeoManager->cd(ladderPath.Data());
839   TGeoHMatrix gLad = *gGeoManager->GetCurrentMatrix(); // global matrix of ladder
840
841
842   TGeoHMatrix rel = gMod; // to equal relative matrix ladder to sensor.
843   TGeoHMatrix invgLad = gLad.Inverse();
844   rel.MultiplyLeft(&invgLad);
845   TGeoRotation* rr = new TGeoRotation("rr",90,90,0,0,90,180);
846   TGeoCombiTrans* ct = 0;
847   if(layer==3) ct= new TGeoCombiTrans(25.,0.,0.,rr);
848   if(layer==4) ct= new TGeoCombiTrans(25.+7.5,0.,0.,rr);
849
850   rel.MultiplyLeft(ct);
851   
852   if((layer==3)&&(module<3)) rel.LocalToMaster(fgkLocR[iPoint],fSDDidP[iPoint]);
853   if((layer==3)&&(module>2)) rel.LocalToMaster(fgkLocL[iPoint],fSDDidP[iPoint]);
854   if((layer==4)&&(module<4)) rel.LocalToMaster(fgkLocR[iPoint],fSDDidP[iPoint]);
855   if((layer==4)&&(module>3)) rel.LocalToMaster(fgkLocL[iPoint],fSDDidP[iPoint]);
856
857   for(Int_t i=0; i<3; i++) fSDDidP[iPoint][i]*=10; 
858   fSDDidP[iPoint][2]-=0.5205;
859
860   //  if(ladderPath.Data(),"/ALIC_1/ITSV_1/ITSsddLayer3_1/ITSsddLadd_3");
861   //  if(ladderPath.Contains("ITSsddLayer3_1") && (ladderPath.Contains("ITSsddLadd_3")|| ladderPath.Contains("ITSsddLadd_10")))
862   //  {
863   ///ALIC_1/ITSV_1/ITSsddLayer4_1/ITSsddLadd_5
864   ///ALIC_1/ITSV_1/ITSsddLayer4_1/ITSsddLadd_16
865   //  gLad.Print();
866   //  printf("%s  : Module# %d  Point# %d\n",ladderPath.Data(), module, iPoint);
867
868   if((layer==3)&&(module<3)) rel.LocalToMaster(fgkLocR[1],fSDDidP[1]);
869   if((layer==3)&&(module>2)) rel.LocalToMaster(fgkLocL[1],fSDDidP[1]);
870   if((layer==4)&&(module<4)) rel.LocalToMaster(fgkLocR[1],fSDDidP[1]);
871   if((layer==4)&&(module>3)) rel.LocalToMaster(fgkLocL[1],fSDDidP[1]);
872   for(Int_t i=0; i<3; i++) fSDDidP[1][i]*=10;
873   fSDDidP[1][2]-=0.5205;
874
875   //  rel.LocalToMaster(fgkLocR[1],fSDDidP[1]);
876   //  printf("ID   {%f, %f, %f}\n", fSDDidP[iPoint][0],fSDDidP[iPoint][1],fSDDidP[iPoint][2]);
877   //  printf("Me   {%f, %f, %f}\n", fSDDmeP[iPoint][0],fSDDmeP[iPoint][1],fSDDmeP[iPoint][2]);
878   //  }
879 }
880
881 //______________________________________________________________________
882 void AliITSSurveyToAlign::ReadPointNameSDD(const char str[], Int_t &iLayer, Int_t &iLader, Int_t &iModul, Int_t &iPoint) const
883 {
884   // 
885   //    Utility function used by CreateAlignObjSDD
886   // 
887   iLayer=-1;
888   iLader=-1;
889   iModul=-1;
890   iPoint=-1;
891
892   if(str[7]=='2') iLayer=3;
893   if(str[7]=='3') iLayer=4;
894
895   if(str[15]=='0') iLader=0;
896   if(str[15]=='1') iLader=1;
897   if(str[15]=='2') iLader=2;
898   if(str[15]=='3') iLader=3;
899   if(str[15]=='4') iLader=4;
900   if(str[15]=='5') iLader=5;
901   if(str[15]=='6') iLader=6;
902   if(str[15]=='7') iLader=7;
903   if(str[15]=='8') iLader=8;
904   if(str[15]=='9') iLader=9;
905
906   Int_t ord=0;
907   if(str[16]=='0') {iLader=10*iLader+0; ord=1;}
908   if(str[16]=='1') {iLader=10*iLader+1; ord=1;}
909   if(str[16]=='2') {iLader=10*iLader+2; ord=1;}
910   if(str[16]=='3') {iLader=10*iLader+3; ord=1;}
911   if(str[16]=='4') {iLader=10*iLader+4; ord=1;}
912   if(str[16]=='5') {iLader=10*iLader+5; ord=1;}
913   if(str[16]=='6') {iLader=10*iLader+6; ord=1;}
914   if(str[16]=='7') {iLader=10*iLader+7; ord=1;}
915   if(str[16]=='8') {iLader=10*iLader+8; ord=1;}
916   if(str[16]=='9') {iLader=10*iLader+9; ord=1;}
917
918   /*
919   //tmp solution
920   Int_t module=-1;
921   if(str[23+ord]=='0') module=0;
922   if(str[23+ord]=='1') module=1;
923   if(str[23+ord]=='2') module=2;
924   if(str[23+ord]=='3') module=3;
925   if(str[23+ord]=='4') module=4;
926   if(str[23+ord]=='5') module=5;
927   if(str[23+ord]=='6') module=6;
928   if(str[23+ord]=='7') module=7;
929   if(str[23+ord]=='8') module=8;
930   if(str[23+ord]=='9') module=9;
931
932   if(iLayer==3)
933     {
934       if(module==0) iModul= 5;
935       if(module==1) iModul= 4;
936       if(module==2) iModul= 3;
937       if(module==3) iModul= 2;
938       if(module==4) iModul= 1;
939       if(module==5) iModul= 0;
940     }
941
942
943   if(iLayer==4)
944     {
945       if(module==0) iModul= 7;
946       if(module==1) iModul= 6;
947       if(module==2) iModul= 5;
948       if(module==3) iModul= 4;
949       if(module==4) iModul= 3;
950       if(module==5) iModul= 2;
951       if(module==6) iModul= 1;
952       if(module==7) iModul= 0;
953     }
954
955   if(module<0) {printf("ERROR MOULE\n"); iModul=0;}
956   */
957
958   if(str[23+ord]=='0') iModul=0;
959   if(str[23+ord]=='1') iModul=1;
960   if(str[23+ord]=='2') iModul=2;
961   if(str[23+ord]=='3') iModul=3;
962   if(str[23+ord]=='4') iModul=4;
963   if(str[23+ord]=='5') iModul=5;
964   if(str[23+ord]=='6') iModul=6;
965   if(str[23+ord]=='7') iModul=7;
966   if(str[23+ord]=='8') iModul=8;
967   if(str[23+ord]=='9') iModul=9;
968
969
970   if((str[25+ord]=='R')&&(str[26+ord]=='D')) iPoint=0;
971   if((str[25+ord]=='R')&&(str[26+ord]=='C')) iPoint=1;
972   if((str[25+ord]=='R')&&(str[26+ord]=='U')) iPoint=2;
973   if((str[25+ord]=='L')&&(str[26+ord]=='U')) iPoint=3;
974   if((str[25+ord]=='L')&&(str[26+ord]=='C')) iPoint=4;
975   if((str[25+ord]=='L')&&(str[26+ord]=='D')) iPoint=5;
976
977   return;
978 }
979
980
981 //______________________________________________________________________
982 void AliITSSurveyToAlign::ConvertToRSofModulesAndRotSDD(Int_t Layer, Int_t Module)
983 {
984   // 
985   //    Utility function used by CreateAlignObjSDD
986   // 
987
988   Double_t ymId;
989   Double_t zmId;
990
991   Double_t ymMe;
992   Double_t zmMe;
993   Double_t ymMeE;
994   Double_t zmMeE;
995
996   Double_t x0=fSDDidP[1][0];
997   Double_t z0=fSDDidP[1][2];//-0.5205;
998   //  Double_t z0=fSDDidP[1][2]-0.5;
999   //  printf("x0= %f   z0= %f \n",x0,z0);
1000   for(Int_t i=0; i<6; i++)
1001     {
1002       //      fSDDidP[i][2]-=0.5205;
1003       //      fSDDidP[i][2]-=0.5;
1004
1005       if(!fSDDisMe[i]) continue; 
1006
1007       //      printf("Me1_0: %d:  %f  %f  %f\n",i, fSDDmeP[i][0], fSDDmeP[i][1], fSDDmeP[i][2]);
1008       //      printf("Id1_0: %d:  %f  %f  %f\n",i, fSDDidP[i][0], fSDDidP[i][1], fSDDidP[i][2]);
1009
1010       fSDDidP[i][0]-=x0;
1011       fSDDidP[i][2]-=z0;
1012       fSDDmeP[i][0]-=x0;
1013       fSDDmeP[i][2]-=z0;
1014                                 
1015       ymId=fSDDidP[i][1];
1016       zmId=fSDDidP[i][2];
1017                         
1018       fSDDidP[i][2]=fSDDidP[i][0];
1019       fSDDidP[i][0]=ymId;
1020       fSDDidP[i][1]=zmId;
1021                         
1022       ymMe=fSDDmeP[i][1];
1023       zmMe=fSDDmeP[i][2];
1024                         
1025       ymMeE=fSDDmeP[i][4];
1026       zmMeE=fSDDmeP[i][5];
1027                         
1028       fSDDmeP[i][2]=fSDDmeP[i][0];
1029       fSDDmeP[i][0]=ymMe;
1030       fSDDmeP[i][1]=zmMe;
1031       fSDDmeP[i][5]=fSDDmeP[i][3];
1032       fSDDmeP[i][3]=ymMeE;
1033       fSDDmeP[i][4]=zmMeE;
1034                         
1035
1036       if(((Layer==3)&&(Module>2))||((Layer==4)&&(Module>3)))
1037         {
1038           fSDDidP[i][0]*=(-1);
1039           fSDDidP[i][2]*=(-1);
1040           fSDDmeP[i][0]*=(-1);
1041           fSDDmeP[i][2]*=(-1);
1042         }
1043       //      printf("Me1_1: %d:  %f  %f  %f\n",i, fSDDmeP[i][0], fSDDmeP[i][1], fSDDmeP[i][2] );
1044       //      printf("Id1_1: %d:  %f  %f  %f\n",i, fSDDidP[i][0], fSDDidP[i][1], fSDDidP[i][2]);
1045
1046     }   
1047 }
1048
1049
1050 //______________________________________________________________________
1051 void AliITSSurveyToAlign::CalcShiftSDD(Double_t &x0,Double_t &y0,Double_t &z0) const
1052 {
1053     // Calculates the 3 shifts for the present SDD module
1054     // and sets the three reference arguments
1055     //
1056   Double_t xId, yId, zId;
1057   Double_t xMe, yMe, zMe, sX2, sY2, sZ2;
1058   Double_t aX=0., bX=0.;
1059   Double_t aY=0., bY=0.;
1060   Double_t aZ=0., bZ=0.;
1061   for(Int_t iP1=0; iP1<6; iP1++)
1062     {
1063       if(!fSDDisMe[iP1]) continue;
1064       xId=fSDDidP[iP1][0];
1065       yId=fSDDidP[iP1][1];
1066       zId=fSDDidP[iP1][2];
1067       xMe=fSDDmeP[iP1][0];
1068       yMe=fSDDmeP[iP1][1];
1069       zMe=fSDDmeP[iP1][2];
1070       sX2 =fSDDmeP[iP1][3]*fSDDmeP[iP1][3];
1071       sY2 =fSDDmeP[iP1][4]*fSDDmeP[iP1][4];
1072       sZ2 =fSDDmeP[iP1][5]*fSDDmeP[iP1][5];
1073       aX+=(1./sX2);
1074       bX+=((xMe-xId)/sX2); 
1075       aY+=(1./sY2);
1076       bY+=((yMe-yId)/sY2); 
1077       aZ+=(1./sZ2);
1078       bZ+=((zMe-zId)/sZ2); 
1079     }
1080   Double_t x1 = bX/aX;
1081   Double_t x2 = bY/aY;
1082   Double_t x3 = bZ/aZ;
1083   x0=x1;
1084   y0=x2;
1085   z0=x3;
1086
1087 /*
1088   for(Int_t iP1=0; iP1<6; iP1++)
1089     {
1090       if(!fSDDisMe[iP1]) continue;
1091       printf("%d Me: %6.3f  %6.3f  %6.3f\n",iP1, fSDDmeP[iP1][0], fSDDmeP[iP1][1], fSDDmeP[iP1][2]);
1092       printf("%d Id: %6.3f  %6.3f  %6.3f\n",iP1, fSDDidP[iP1][0], fSDDidP[iP1][1], fSDDidP[iP1][2]);
1093     }
1094 */
1095
1096   return;
1097 }
1098
1099
1100 //______________________________________________________________________
1101 void AliITSSurveyToAlign::CalcShiftRotSDD(Double_t &tet,Double_t &psi,Double_t &phi,Double_t &x0,Double_t &y0,Double_t &z0)
1102 {
1103     // Calculates the 3 shifts and 3 euler angles for the present SDD module
1104     // and sets the six reference arguments
1105     //
1106   TMatrixD pC(6,6);
1107
1108   Double_t a[6][6];
1109   for(Int_t ii=0; ii<6; ii++){
1110       for(Int_t jj=0; jj<6; jj++){
1111           a[ii][jj]=0.;
1112       }
1113   }
1114
1115   Double_t c[6];
1116   for(Int_t ii=0; ii<6; ii++)
1117       c[ii]=0.;
1118
1119   Double_t xId, yId, zId;
1120   Double_t xMe, yMe, zMe, sX2, sY2, sZ2;
1121
1122   //  printf("\n");
1123
1124   for(Int_t iP1=0; iP1<6; iP1++)
1125     {
1126       if(!fSDDisMe[iP1]) continue;
1127
1128       //ideal x,y,z for fiducial mark iP1
1129       xId= fSDDidP[iP1][0];
1130       yId= fSDDidP[iP1][1];
1131       zId= fSDDidP[iP1][2];
1132
1133       //measured x,y,z for fiducial mark iP1
1134       xMe= fSDDmeP[iP1][0];
1135       yMe= fSDDmeP[iP1][1];
1136       zMe= fSDDmeP[iP1][2];
1137
1138       //      printf("Me1: %d:  %f  %f  %f\n",iP1, xMe, yMe, zMe );
1139       //      printf("MeE: %d:  %f  %f  %f\n",iP1, fSDDmeP[iP1][3], fSDDmeP[iP1][4], fSDDmeP[iP1][5] );
1140       //      printf("Id1: %d:  %f  %f  %f\n",iP1, xId, yId, zId );
1141       //      printf("Res: %d:  %f  %f  %f\n",iP1, xMe-xId, yMe-yId, zMe-zId );
1142
1143       //squared precisions of measured x,y,z for fiducial mark iP1
1144       sX2 = fSDDmeP[iP1][3]* fSDDmeP[iP1][3];
1145       sY2 = fSDDmeP[iP1][4]* fSDDmeP[iP1][4];
1146       sZ2 = fSDDmeP[iP1][5]* fSDDmeP[iP1][5];
1147
1148       a[0][0]+=(zId*zId/sX2+xId*xId/sZ2);
1149       //      printf("%f\n",a[0][0]);
1150       a[0][1]-=(zId*yId/sX2);
1151       a[0][2]-=(xId*yId/sZ2);
1152       a[0][3]-=(zId/sX2);
1153       a[0][4] =0.;
1154       a[0][5]+=(xId/sZ2);
1155       c[0]+=(xId*(zMe-zId)/sZ2-zId*(xMe-xId)/sX2); 
1156
1157       a[1][0]-=(yId*zId/sX2);
1158       a[1][1]+=(xId*xId/sY2+yId*yId/sX2);
1159       a[1][2]-=(xId*zId/sY2);
1160       a[1][3]+=(yId/sX2);
1161       a[1][4]-=(xId/sY2);
1162       a[1][5] =0.;
1163       c[1]+=(yId*(xMe-xId)/sX2-xId*(yMe-yId)/sY2); 
1164
1165       a[2][0]-=(yId*xId/sZ2);
1166       a[2][1]-=(xId*zId/sY2);
1167       a[2][2]+=(zId*zId/sY2+yId*yId/sZ2);
1168       a[2][3] =0.;
1169       a[2][4]+=(zId/sY2);
1170       a[2][5]-=(yId/sZ2);
1171       c[2]+=(zId*(yMe-yId)/sY2-yId*(zMe-zId)/sZ2); 
1172
1173       a[3][0]-=(zId/sX2);
1174       a[3][1]+=(yId/sX2);
1175       a[3][2] =0.;
1176       a[3][3]+=(1./sX2);
1177       a[3][4] =0.;
1178       a[3][5] =0.;
1179       c[3]+=((xMe-xId)/sX2); 
1180
1181       a[4][0] =0.;
1182       a[4][1]-=(xId/sY2);
1183       a[4][2]+=(zId/sY2);
1184       a[4][3] =0.;
1185       a[4][4]+=(1./sY2);
1186       a[4][5] =0.;
1187       c[4]+=((yMe-yId)/sY2); 
1188
1189       a[5][0]+=(xId/sZ2);
1190       a[5][1] =0.;
1191       a[5][2]-=(yId/sZ2);
1192       a[5][3] =0.;
1193       a[5][4] =0.;
1194       a[5][5]+=(1./sZ2);
1195       c[5]+=((zMe-zId)/sZ2); 
1196     }
1197
1198   ///////////////////////////////////////////////////////////////
1199
1200   pC.SetMatrixArray(&(a[0][0]));
1201   TMatrixD p1(pC);
1202   TMatrixD p2(pC);
1203   TMatrixD p3(pC);
1204   TMatrixD p4(pC);
1205   TMatrixD p5(pC);
1206   TMatrixD p6(pC);
1207
1208   for(Int_t raw=0; raw<6; raw++)
1209       p1[raw][0]=c[raw];
1210   for(Int_t raw=0; raw<6; raw++)
1211       p2[raw][1]=c[raw];
1212   for(Int_t raw=0; raw<6; raw++)
1213       p3[raw][2]=c[raw];
1214   for(Int_t raw=0; raw<6; raw++)
1215       p4[raw][3]=c[raw];
1216   for(Int_t raw=0; raw<6; raw++)
1217       p5[raw][4]=c[raw];
1218   for(Int_t raw=0; raw<6; raw++)
1219       p6[raw][5]=c[raw];
1220
1221   // cout << "calculating determinants" << endl;
1222   Double_t det0=pC.Determinant();
1223   Double_t x1 = p1.Determinant()/det0;
1224   Double_t x2 = p2.Determinant()/det0;
1225   Double_t x3 = p3.Determinant()/det0;
1226   Double_t x4 = p4.Determinant()/det0;
1227   Double_t x5 = p5.Determinant()/det0;
1228   Double_t x6 = p6.Determinant()/det0;
1229   //cout << "calculating determinants done" << endl;
1230   if (TMath::Abs(x1) < 1.e-10) {
1231     AliInfo("p1 singular ");
1232     p1.Print();
1233   }
1234   if (TMath::Abs(x2) < 1.e-10) {
1235     AliInfo("p2 singular ");
1236     p2.Print();
1237   }
1238   if (TMath::Abs(x3) < 1.e-10) {
1239     AliInfo("p3 singular ");
1240     p3.Print();
1241   }
1242   if (TMath::Abs(x4) < 1.e-10) {
1243     AliInfo("p4 singular ");
1244     p4.Print();
1245   }
1246   if (TMath::Abs(x5) < 1.e-10) {
1247     AliInfo("p5 singular ");
1248     p5.Print();
1249   }
1250   if (TMath::Abs(x6) < 1.e-10) {
1251     AliInfo("p6 singular ");
1252     p6.Print();
1253   }
1254
1255
1256   tet=x1;
1257   psi=x2;
1258   phi=x3;
1259   x0=x4;
1260   y0=x5;
1261   z0=x6;
1262
1263   //  for(Int_t i=0; i<6; i++)
1264     //  printf("%f  %f  %f  %f  %f  %f\n",a[i][0], a[i][1], a[i][2], a[i][3], a[i][4], a[i][5]);
1265
1266   //  pC.Print();
1267   //  p1.Print();
1268   //  p2.Print();
1269   //  p3.Print();
1270   //  p4.Print();
1271   //  p5.Print();
1272   //  p6.Print();
1273
1274
1275   //  printf("fit: %f  %f  %f  %f  %f  %f\n",x0, y0, z0, tet, psi, phi);
1276
1277   return;
1278 }