LCOV - code coverage report
Current view: top level - PHOS/PHOSbase - AliPHOSModuleMisalignment.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 145 0.7 %
Date: 2016-06-14 17:26:59 Functions: 1 23 4.3 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
       3             :  *                                                                        *
       4             :  * Author: The ALICE Off-line Project.                                    *
       5             :  * Contributors are mentioned in the code where appropriate.              *
       6             :  *                                                                        *
       7             :  * Permission to use, copy, modify and distribute this software and its   *
       8             :  * documentation strictly for non-commercial purposes is hereby granted   *
       9             :  * without fee, provided that the above copyright notice appears in all   *
      10             :  * copies and that both the copyright notice and this permission notice   *
      11             :  * appear in the supporting documentation. The authors make no claims     *
      12             :  * about the suitability of this software for any purpose. It is          *
      13             :  * provided "as is" without express or implied warranty.                  *
      14             :  **************************************************************************/
      15             : 
      16             : /* $Id: $ */
      17             : 
      18             : #include <stdexcept>
      19             : #include <iostream>
      20             : 
      21             : #include <TGeoMatrix.h>
      22             : #include <TObjArray.h>
      23             : #include <TString.h>
      24             : #include <TError.h>
      25             : #include <TMath.h>
      26             : 
      27             : #include "AliSurveyPoint.h"
      28             : 
      29             : #include "AliPHOSModuleMisalignment.h"
      30             : #include "AliPHOSGeometry.h"
      31             : 
      32          22 : ClassImp(AliPHOSModuleMisalignment)
      33             : 
      34             : namespace {
      35             : 
      36             :   /*
      37             :     Tiny vector/matrix utility stuff. Operates on doubles directly.
      38             :     Instead of points and vectors I use arrays of doubles with size 3.
      39             :     To make this explicit - I use references to arrays.
      40             :   */
      41             :   
      42             :   //___________________________________________________________________
      43             :   void Vector(const Double_t (&p1)[3], const Double_t (&p2)[3], Double_t (&v)[3])
      44             :   {
      45           0 :     for(UInt_t i = 0; i < 3; ++i)
      46           0 :       v[i] = p2[i] - p1[i];
      47           0 :   }
      48             :   
      49             : #if 0
      50             :   //___________________________________________________________________
      51             :   void MultVector(Double_t (&v)[3], Double_t m)
      52             :   {
      53             :     v[0] *= m;
      54             :     v[1] *= m;
      55             :     v[2] *= m;
      56             :   }
      57             : #endif
      58             :   
      59             :   /*
      60             :     Using points name0, name1, name2 find two orthogonal vectors.
      61             :   */
      62             :   //___________________________________________________________________
      63             :   void FindVectors(const Double_t (&pts)[3][3], Double_t (&v)[3][3])
      64             :   {
      65           0 :     Vector(pts[0], pts[2], v[0]);
      66             :     //v[1] will be cross-product (v[2] x v[0]).
      67           0 :     Vector(pts[0], pts[1], v[2]);
      68           0 :   }
      69             :   
      70             :   //___________________________________________________________________
      71             :   Double_t Length(const Double_t (&v)[3])
      72             :   {
      73           0 :     return TMath::Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
      74             :   }
      75             :   
      76             : #if 0
      77             :   //___________________________________________________________________
      78             :   Double_t Distance(const Double_t (&p1)[3], const Double_t (&p2)[3])
      79             :   {
      80             :     return TMath::Sqrt((p2[0] - p1[0]) * (p2[0] - p1[0]) +
      81             :                        (p2[1] - p1[1]) * (p2[1] - p1[1]) +
      82             :                        (p2[2] - p1[2]) * (p2[2] - p1[2]));
      83             :   }
      84             :   
      85             :   //______________________________________________________________________________
      86             : #endif
      87             :   void CrossProduct(const Double_t (&v1)[3], const Double_t (&v2)[3], Double_t (&v3)[3])
      88             :   {
      89           0 :     v3[0] = v1[1] * v2[2] - v2[1] * v1[2];
      90           0 :     v3[1] = v1[2] * v2[0] - v2[2] * v1[0];
      91           0 :     v3[2] = v1[0] * v2[1] - v2[0] * v1[1];
      92           0 :   }
      93             :   
      94             :   //___________________________________________________________________
      95             :   void Normalize(Double_t (&v)[3])
      96             :   {
      97           0 :     const Double_t len = Length(v);
      98           0 :     if(len < 1E-10)//Threshold?
      99           0 :       throw std::runtime_error("Zero len vector");
     100           0 :     v[0] /= len;
     101           0 :     v[1] /= len;
     102           0 :     v[2] /= len;
     103           0 :   }
     104             :   
     105             :   //______________________________________________________________________________
     106             :   void Normalize(Double_t (&v)[3][3])
     107             :   {
     108           0 :     for(UInt_t i = 0; i < 3; ++i)
     109           0 :       Normalize(v[i]);
     110           0 :   }
     111             :   
     112             :   
     113             :   //___________________________________________________________________
     114             :   void FindRotation(const Double_t (&u)[3][3], const Double_t (&v)[3][3], Double_t (&r)[9])
     115             :   {
     116             :     //I have orthogonal vectors and very nice rotation matrix.
     117             :     //V = R * U, R = V * U ^ t
     118           0 :     r[0] = v[0][0] * u[0][0] + v[1][0] * u[1][0] + v[2][0] * u[2][0];
     119           0 :     r[1] = v[0][0] * u[0][1] + v[1][0] * u[1][1] + v[2][0] * u[2][1];
     120           0 :     r[2] = v[0][0] * u[0][2] + v[1][0] * u[1][2] + v[2][0] * u[2][2];
     121             :     
     122           0 :     r[3] = v[0][1] * u[0][0] + v[1][1] * u[1][0] + v[2][1] * u[2][0];
     123           0 :     r[4] = v[0][1] * u[0][1] + v[1][1] * u[1][1] + v[2][1] * u[2][1];
     124           0 :     r[5] = v[0][1] * u[0][2] + v[1][1] * u[1][2] + v[2][1] * u[2][2];
     125             :     
     126           0 :     r[6] = v[0][2] * u[0][0] + v[1][2] * u[1][0] + v[2][2] * u[2][0];
     127           0 :     r[7] = v[0][2] * u[0][1] + v[1][2] * u[1][1] + v[2][2] * u[2][1];
     128           0 :     r[8] = v[0][2] * u[0][2] + v[1][2] * u[1][2] + v[2][2] * u[2][2];
     129           0 :   }
     130             :   
     131             :   //___________________________________________________________________
     132             :   void Rotate(const Double_t (&r)[9], const Double_t (&u)[3], Double_t (&v)[3])
     133             :   {
     134           0 :     v[0] = r[0] * u[0] + r[1] * u[1] + r[2] * u[2];
     135           0 :     v[1] = r[3] * u[0] + r[4] * u[1] + r[5] * u[2];
     136           0 :     v[2] = r[6] * u[0] + r[7] * u[1] + r[8] * u[2];
     137           0 :   }
     138             :   
     139             :   //___________________________________________________________________
     140             :   void Rotate(const Double_t (&r)[9], const Double_t (&u)[3][3], Double_t (&v)[3][3])
     141             :   {
     142           0 :     for(UInt_t i = 0; i < 3; ++i)
     143           0 :       Rotate(r, u[i], v[i]);
     144           0 :   }
     145             :   
     146             :   /*
     147             :     PrintVector, PrintMatrix, Translate are used in "debug" mode only.
     148             :   */
     149             :   //___________________________________________________________________
     150             :   void PrintVector(const Double_t (&v)[3])
     151             :   {
     152           0 :     std::cout<<v[0]<<' '<<v[1]<<' '<<v[2]<<std::endl;
     153           0 :   }
     154             :   
     155             :   //___________________________________________________________________
     156             :   void PrintMatrix(const Double_t (&u)[3][3])
     157             :   {
     158           0 :     for(UInt_t i = 0; i < 3; ++i)
     159           0 :       PrintVector(u[i]);
     160           0 :   }
     161             :   
     162             :   //___________________________________________________________________
     163             :   void Translate(const Double_t (&t)[3], const Double_t (&u)[3], Double_t (&v)[3])
     164             :   {
     165           0 :     for(UInt_t i = 0; i < 3; ++i)
     166           0 :       v[i] = u[i] + t[i];
     167           0 :   }
     168             :   
     169             :   //___________________________________________________________________
     170             :   void Translate(const Double_t (&t)[3], const Double_t (&u)[3][3], Double_t (&v)[3][3])
     171             :   {
     172           0 :     for(UInt_t i = 0; i < 3; ++i)
     173           0 :       Translate(t, u[i], v[i]);
     174           0 :   }
     175             :   
     176             : }
     177             : 
     178             : //______________________________________________________________________________
     179             : AliPHOSModuleMisalignment::
     180             : AliPHOSModuleMisalignment(const AliPHOSGeometry & geom, Bool_t debug)
     181           0 :                             : fDebug(debug),
     182           0 :                               fAngles(),
     183           0 :                               fCenters(),
     184           0 :                               fModule(),
     185           0 :                               fU(),
     186           0 :                               fV()
     187           0 : {
     188             :   //Ctor.
     189             :   //Extract ideal module transformations from AliPHOSGeometry.
     190             : 
     191             :   //Angles.
     192           0 :   for (UInt_t module = 0; module < kModules; ++module)
     193           0 :     for (UInt_t axis = 0; axis < 3; ++axis)
     194           0 :       for (UInt_t angle = 0; angle < 2; ++angle)
     195           0 :         fAngles[module][axis][angle] = geom.GetModuleAngle(module, axis, angle);
     196             :   //Translations.
     197           0 :   for (UInt_t module = 0; module < kModules; ++module)
     198           0 :     for (UInt_t axis = 0; axis < 3; ++axis)
     199           0 :       fCenters[module][axis] = geom.GetModuleCenter(module, axis);
     200             :   //Points, will be rotated/translated using module angle/center.
     201           0 :   fModule[0][0] = -geom.GetNPhi() / 2. * geom.GetCellStep() + geom.GetCellStep() / 2.;
     202           0 :   fModule[0][1] = -geom.GetNZ()   / 2. * geom.GetCellStep() + geom.GetCellStep() / 2.;
     203           0 :   fModule[0][2] = -22.61;//This number is hardcoded, AliPHOSGeometry does not have it,
     204             :                          //only 460. but this is result of transformation applied already.
     205           0 :   fModule[1][0] = fModule[0][0];
     206           0 :   fModule[1][1] = -fModule[0][1] - geom.GetCellStep();
     207           0 :   fModule[1][2] = -22.61;
     208             : 
     209           0 :   fModule[2][0] = -fModule[0][0] - 7 * geom.GetCellStep();
     210           0 :   fModule[2][1] = fModule[0][1];
     211           0 :   fModule[2][2] = -22.61;
     212           0 : }
     213             : 
     214             : //______________________________________________________________________________
     215             : AliPHOSModuleMisalignment::~AliPHOSModuleMisalignment()
     216           0 : {
     217           0 : }
     218             : 
     219             : //______________________________________________________________________________
     220             : void AliPHOSModuleMisalignment::
     221             : DeltaTransformation(UInt_t module, const TObjArray * points, 
     222             :                     const TString & name0, const TString & name1, 
     223             :                     const TString & name2, TGeoHMatrix * delta)
     224             : {
     225             :   //Find delta transformation to misalign module. Global transformation.
     226           0 :   const AliSurveyPoint * pt0 = static_cast<AliSurveyPoint *>(points->FindObject(name0));
     227           0 :   const AliSurveyPoint * pt1 = static_cast<AliSurveyPoint *>(points->FindObject(name1));
     228           0 :   const AliSurveyPoint * pt2 = static_cast<AliSurveyPoint *>(points->FindObject(name2));
     229             : 
     230           0 :   if (!pt0 || !pt1 || !pt2) {
     231           0 :     Warning("AliPHOSModuleData::DeltaTransformation",
     232             :             "One of points not found in TObjArray");
     233           0 :     return;
     234             :   }
     235             : 
     236             :   //Transform fModule using angle and translation for module number "module".
     237             :   //fU.
     238           0 :   FindIdealModule(module);
     239             :   //Extract coordinates from survey.
     240             :   //fV.
     241           0 :   FindRealModule(pt0, pt1, pt2);
     242             :   //Find delta, using ideal module (fU) and survey data (fV).
     243           0 :   FindDelta(delta);
     244           0 : }
     245             : 
     246             : //______________________________________________________________________________
     247             : void AliPHOSModuleMisalignment::FindIdealModule(UInt_t module)
     248             : {
     249             :   //Ideal module described by fU.
     250           0 :   TGeoHMatrix matrix;
     251             :   //Rotation.
     252           0 :   const TGeoRotation r("", 
     253           0 :                        fAngles[module][0][0], fAngles[module][0][1], 
     254           0 :                        fAngles[module][1][0], fAngles[module][1][1], 
     255           0 :                        fAngles[module][2][0], fAngles[module][2][1]);
     256           0 :   matrix.SetRotation(r.GetRotationMatrix());
     257             :   //Translation.
     258           0 :   matrix.SetDx(fCenters[module][0]);
     259           0 :   matrix.SetDy(fCenters[module][1]);
     260           0 :   matrix.SetDz(fCenters[module][2]);
     261             :   //Find ideal module's points.
     262           0 :   matrix.LocalToMaster(fModule[0], fU[0]);
     263           0 :   matrix.LocalToMaster(fModule[1], fU[1]);
     264           0 :   matrix.LocalToMaster(fModule[2], fU[2]);
     265           0 : }
     266             : 
     267             : //______________________________________________________________________________
     268             : void AliPHOSModuleMisalignment::FindRealModule(const AliSurveyPoint * pt0, 
     269             :                                                const AliSurveyPoint * pt1,
     270             :                                                const AliSurveyPoint * pt2)
     271             : {
     272             :   //Real module - fV.
     273             :   //Survey is in millimeters.
     274             :   //AliPHOSGeometry is in centimeters.
     275             :   const Double_t scale = 0.1;
     276             : 
     277           0 :   fV[0][0] = pt0->GetX() * scale;
     278           0 :   fV[0][1] = pt0->GetY() * scale;
     279           0 :   fV[0][2] = pt0->GetZ() * scale;
     280             : 
     281           0 :   fV[1][0] = pt1->GetX() * scale;
     282           0 :   fV[1][1] = pt1->GetY() * scale;
     283           0 :   fV[1][2] = pt1->GetZ() * scale;
     284             : 
     285           0 :   fV[2][0] = pt2->GetX() * scale;
     286           0 :   fV[2][1] = pt2->GetY() * scale;
     287           0 :   fV[2][2] = pt2->GetZ() * scale;
     288           0 : }
     289             : 
     290             : //______________________________________________________________________________
     291             : void AliPHOSModuleMisalignment::FindDelta(TGeoHMatrix * delta)const
     292             : {
     293             :   //Find rotation and translation wich can
     294             :   //convert fU into fV (ideal module points into points from survey).
     295           0 :   Double_t u[3][3] = {};
     296           0 :   FindVectors(fU, u);                 
     297             :   //Find cross product u2 x u0 and save it in u[2].
     298           0 :   CrossProduct(u[2], u[0], u[1]);
     299             :   /*
     300             :   const Double_t lenXideal = Length(u[0]);
     301             :   const Double_t lenZideal = Length(u[2]);
     302             :   */
     303           0 :   Double_t v[3][3] = {};
     304           0 :   FindVectors(fV, v);                 
     305             :   //Find cross product (v2 x v0) and save it in v[2].
     306           0 :   CrossProduct(v[2], v[0], v[1]);
     307             :   /*
     308             :   const Double_t lenXreal = Length(v[0]);
     309             :   const Double_t lenZreal = Length(v[2]);
     310             :   */
     311             :   //Now, find rotation matrix.
     312             :   //1. Normalize vectors in u and v.
     313             :   try {
     314           0 :     Normalize(u);
     315           0 :     Normalize(v);
     316           0 :   } catch (const std::exception & e) {
     317             :     //One of lengths is zero (in principle, impossible, just to be neat).
     318           0 :     Error("AliPHOSModuleMisalignment::FindDelta", 
     319             :           "\tone of vectors from ideal or real\n\tpoints have zero size\n"
     320             :           "\tzero misalignment will be created");
     321             :     return;
     322           0 :   }
     323             : 
     324             :   //2. Rotation matrix.
     325           0 :   Double_t r[9] = {};
     326           0 :   FindRotation(u, v, r);
     327           0 :   delta->SetRotation(r);
     328             :   
     329             : #if 1
     330             : 
     331             :   //3. Now, rotate fU and look, what translation I have to add.
     332           0 :   Double_t idealRotated[3] = {};
     333           0 :   Rotate(r, fU[0], idealRotated);
     334             : 
     335           0 :   delta->SetDx(fV[0][0] - idealRotated[0]);
     336           0 :   delta->SetDy(fV[0][1] - idealRotated[1]);
     337           0 :   delta->SetDz(fV[0][2] - idealRotated[2]);
     338             : 
     339           0 :   if (fDebug) {
     340           0 :     const Double_t shifts[3] = 
     341           0 :     {fV[0][0] - idealRotated[0], 
     342           0 :      fV[0][1] - idealRotated[1], 
     343           0 :      fV[0][2] - idealRotated[2]};
     344             : 
     345           0 :     Double_t test1[3][3] = {};
     346           0 :     Rotate(r, fU, test1);
     347           0 :     Double_t test2[3][3] = {};
     348           0 :     Translate(shifts, test1, test2);
     349           0 :     std::cout<<"ideal:\n";
     350           0 :     PrintMatrix(fU);
     351           0 :     std::cout<<"misaligned:\n";
     352           0 :     PrintMatrix(test2);
     353           0 :     std::cout<<"real:\n";
     354           0 :     PrintMatrix(fV);
     355           0 :   }
     356             : 
     357             : #endif
     358             : 
     359             : #if 0
     360             :   //3. Now, rotate fU and look, what translation I have to add.
     361             :   Double_t idealRotated[3][3] = {};
     362             :   Rotate(r, fU, idealRotated);
     363             :   //Because of measurement errors, distances 
     364             :   //between points has errors. I can try to split
     365             :   //this difference (and make "final errors" smaller).
     366             :   Double_t zShift[3] = {};
     367             :   Vector(fV[0], fV[1], zShift);
     368             :   Normalize(zShift);
     369             :   
     370             :   Double_t xShift[3] = {};
     371             :   Vector(fV[0], fV[2], xShift);
     372             :   Normalize(xShift);
     373             : 
     374             :   MultVector(zShift, 0.5 * (lenZreal - lenZideal));
     375             :   MultVector(xShift, 0.5 * (lenXreal - lenXideal));
     376             : 
     377             :   Double_t pt1[3] = {};
     378             :   Translate(zShift, fV[0], pt1);
     379             :   Double_t pt2[3] = {};
     380             :   Translate(xShift, pt1, pt2);
     381             : 
     382             :   Double_t shifts[] = {pt2[0] - idealRotated[0][0],
     383             :                        pt2[1] - idealRotated[0][1],
     384             :                        pt2[2] - idealRotated[0][2]};
     385             : 
     386             :   delta->SetDx(shifts[0]);
     387             :   delta->SetDy(shifts[1]);
     388             :   delta->SetDz(shifts[2]);
     389             : 
     390             :   if (fDebug) {
     391             :     Double_t idealTr[3][3] = {};
     392             :     Translate(shifts, idealRotated, idealTr);
     393             : 
     394             :     std::cout<<"misaligned:\n";
     395             :     PrintMatrix(idealTr);
     396             :     std::cout<<"ideal1 "<<Distance(idealTr[0], idealTr[1])<<std::endl;
     397             :     std::cout<<"ideal2 "<<Distance(idealTr[0], idealTr[2])<<std::endl;
     398             :     std::cout<<"real:\n";
     399             :     PrintMatrix(fV);
     400             :     std::cout<<"real1 "<<Distance(fV[0], fV[1])<<std::endl;
     401             :     std::cout<<"real2 "<<Distance(fV[0], fV[2])<<std::endl;
     402             :   }
     403             : #endif
     404           0 : }

Generated by: LCOV version 1.11