LCOV - code coverage report
Current view: top level - ITS/ITSrec - AliITSAlignMille2Module.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 661 0.2 %
Date: 2016-06-14 17:26:59 Functions: 1 52 1.9 %

          Line data    Source code
       1             : /************************************************************************** 
       2             :  * Copyright(c) 2007-2009, 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             : /// \class AliITSAlignMille2Module
      19             : /// Alignment class for the ALICE ITS detector 
      20             : /// 
      21             : /// This class is used by AliITSAlignMille to build custom supermodules    
      22             : /// made of ITS sensitive modules. These supermodules are then aligned
      23             : /// 
      24             : /// Custom supermodules must have VolumeID > 14335
      25             : ///
      26             : /// \author M. Lunardon  
      27             : //----------------------------------------------------------------------------- 
      28             :  
      29             : #include <TGeoManager.h> 
      30             : #include <TGeoMatrix.h> 
      31             :  
      32             : #include "AliITSAlignMille2Module.h" 
      33             : #include "AliITSgeomTGeo.h" 
      34             : #include "AliGeomManager.h" 
      35             : #include "AliAlignObjParams.h" 
      36             : #include "AliLog.h" 
      37             : #include "AliITSAlignMille2.h"
      38             :  
      39             : /// \cond CLASSIMP 
      40         116 : ClassImp(AliITSAlignMille2Module) 
      41             : /// \endcond 
      42             : 
      43             : #define CORHW_
      44             : 
      45             : 
      46             : const Float_t AliITSAlignMille2Module::fgkDummyConstraint = 1e-2;//1.E3;
      47             :     
      48             : //-------------------------------------------------------------
      49             : AliITSAlignMille2Module::AliITSAlignMille2Module() : 
      50           0 :   TNamed(), 
      51           0 :   fNSensVol(0), 
      52           0 :   fIndex(-1),  
      53           0 :   fDetType(-1),
      54           0 :   fVolumeID(0),
      55           0 :   fNParTot(0),
      56           0 :   fNParFree(0),
      57           0 :   fParOffs(0),
      58           0 :   fNProcPoints(0),
      59           0 :   fParVals(0),
      60           0 :   fParErrs(0),
      61           0 :   fParCstr(0),
      62           0 :   fSensVolIndex(0),
      63           0 :   fSensVolVolumeID(0),
      64           0 :   fMatrix(NULL),
      65           0 :   fSensVolMatrix(NULL),
      66           0 :   fSensVolModifMatrix(NULL),
      67           0 :   fParent(NULL),
      68           0 :   fChildren(0)
      69           0 : { 
      70             :   /// void constructor  
      71           0 :   fMatrix = new TGeoHMatrix; 
      72           0 :   fSensVolMatrix = new TGeoHMatrix; 
      73           0 :   fSensVolModifMatrix = new TGeoHMatrix; 
      74           0 :   fSensVolIndex.Set(1);
      75           0 :   fSensVolVolumeID.Set(1);
      76           0 :   fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;
      77           0 : } 
      78             : 
      79             : //-------------------------------------------------------------
      80             : AliITSAlignMille2Module::AliITSAlignMille2Module(Int_t index, UShort_t volid, const char* symname,
      81             :                                                  const TGeoHMatrix *m, Int_t nsv, const UShort_t *volidsv) : 
      82           0 :   TNamed(), 
      83           0 :   fNSensVol(0), 
      84           0 :   fIndex(-1),  
      85           0 :   fDetType(-1),  
      86           0 :   fVolumeID(0),
      87           0 :   fNParTot(0),
      88           0 :   fNParFree(0),
      89           0 :   fParOffs(kMaxParGeom),
      90           0 :   fNProcPoints(0),
      91           0 :   fParVals(0),
      92           0 :   fParErrs(0),
      93           0 :   fParCstr(0),
      94           0 :   fSensVolIndex(0),
      95           0 :   fSensVolVolumeID(0),  
      96           0 :   fMatrix(NULL),
      97           0 :   fSensVolMatrix(NULL),
      98           0 :   fSensVolModifMatrix(NULL),
      99           0 :   fParent(NULL),
     100           0 :   fChildren(0)
     101           0 : { 
     102             :   /// void constructor  
     103           0 :   fMatrix = new TGeoHMatrix; 
     104           0 :   fSensVolMatrix = new TGeoHMatrix; 
     105           0 :   fSensVolModifMatrix = new TGeoHMatrix; 
     106           0 :   fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;
     107           0 :   for (int i=kMaxParGeom;i--;) fParOffs[i] = -1;
     108           0 :   if (Set(index,volid,symname,m,nsv,volidsv)) {
     109           0 :     AliInfo("Error in AliITSAlignMille2Module::Set() - initializing void supermodule...");
     110             :   }
     111           0 :   AssignDetType();
     112           0 : } 
     113             : 
     114             : //-------------------------------------------------------------
     115             : AliITSAlignMille2Module::AliITSAlignMille2Module(UShort_t volid) : 
     116           0 :   TNamed(), 
     117           0 :   fNSensVol(0), 
     118           0 :   fIndex(-1),    
     119           0 :   fDetType(-1),
     120           0 :   fVolumeID(0),
     121           0 :   fNParTot(0),
     122           0 :   fNParFree(0),
     123           0 :   fParOffs(kMaxParGeom),
     124           0 :   fNProcPoints(0),
     125           0 :   fParVals(0),
     126           0 :   fParErrs(0),
     127           0 :   fParCstr(0),  
     128           0 :   fSensVolIndex(0),
     129           0 :   fSensVolVolumeID(0),
     130           0 :   fMatrix(NULL),
     131           0 :   fSensVolMatrix(NULL),
     132           0 :   fSensVolModifMatrix(NULL),
     133           0 :   fParent(NULL),
     134           0 :   fChildren(0)
     135           0 : { 
     136             :   /// simple constructor building a supermodule from a single sensitive volume 
     137           0 :   fMatrix = new TGeoHMatrix; 
     138           0 :   fSensVolMatrix = new TGeoHMatrix; 
     139           0 :   fSensVolModifMatrix = new TGeoHMatrix;   
     140             :   // temporary align object, just use the rotation...
     141           0 :   fSensVolIndex.Set(1);
     142           0 :   fSensVolVolumeID.Set(1);
     143           0 :   fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;
     144           0 :   for (int i=kMaxParGeom;i--;) fParOffs[i] = -1;
     145             :   //
     146           0 :   fIndex = GetIndexFromVolumeID(volid);  
     147           0 :   if (fIndex>=0 && gGeoManager) { // good sensitive module and geometry loaded
     148           0 :     SetName(AliGeomManager::SymName(volid));
     149           0 :     fVolumeID = volid;
     150           0 :     AddSensitiveVolume(volid);
     151           0 :     SetSensorsProvided(kTRUE);
     152           0 :     if (SensVolMatrix(volid, fMatrix))
     153           0 :        AliInfo("Matrix not defined");
     154             :   }
     155             :   else {
     156           0 :     AliInfo("Wrong VolumeID or Geometry not loaded - initializing void supermodule...");
     157             :   }
     158           0 :   AssignDetType();
     159           0 : } 
     160             : 
     161             : 
     162             : //_____________________________________________________________________________
     163             : AliITSAlignMille2Module::AliITSAlignMille2Module(const AliITSAlignMille2Module &m) :
     164           0 :   TNamed(m),
     165           0 :   fNSensVol(m.fNSensVol),
     166           0 :   fIndex(m.fIndex),  
     167           0 :   fDetType(m.fDetType),
     168           0 :   fVolumeID(m.fVolumeID),
     169           0 :   fNParTot(m.fNParTot),
     170           0 :   fNParFree(m.fNParFree),
     171           0 :   fParOffs(m.fNParTot),
     172           0 :   fNProcPoints(0),
     173           0 :   fParVals(0),
     174           0 :   fParErrs(0),
     175           0 :   fParCstr(0),  
     176           0 :   fSensVolIndex(m.fSensVolIndex),
     177           0 :   fSensVolVolumeID(m.fSensVolVolumeID),
     178           0 :   fMatrix(new TGeoHMatrix(*m.GetMatrix())),
     179           0 :   fSensVolMatrix(new TGeoHMatrix),
     180           0 :   fSensVolModifMatrix(new TGeoHMatrix),
     181           0 :   fParent(m.fParent),
     182           0 :   fChildren(0)
     183           0 : {
     184             :   // Copy constructor
     185           0 :   fSensVolIndex = m.fSensVolIndex;
     186           0 :   fSensVolVolumeID = m.fSensVolVolumeID;
     187           0 :   for (int i=m.fNParTot;i--;) fParOffs[i] = m.fParOffs[i];
     188           0 :   for (int i=3;i--;) fSigmaFactor[i] = m.fSigmaFactor[i];
     189           0 :   if (fNParTot) {
     190           0 :     fParVals = new Float_t[fNParTot];
     191           0 :     fParErrs = new Float_t[fNParTot];
     192           0 :     fParCstr = new Float_t[fNParTot];
     193           0 :     for (int i=fNParTot;i--;) {
     194           0 :       fParVals[i] = m.fParVals[i];
     195           0 :       fParErrs[i] = m.fParErrs[i];
     196           0 :       fParCstr[i] = m.fParCstr[i];
     197             :     }
     198           0 :   }
     199           0 : }
     200             : 
     201             : //_____________________________________________________________________________
     202             : AliITSAlignMille2Module& AliITSAlignMille2Module::operator=(const AliITSAlignMille2Module &m)  
     203             : {
     204             :   // operator =
     205             :   //
     206           0 :   if(this==&m) return *this;
     207           0 :   this->TNamed::operator=(m);
     208             :   //
     209           0 :   fNSensVol=m.fNSensVol;
     210           0 :   fIndex=m.fIndex;
     211           0 :   fDetType = m.fDetType;
     212           0 :   fVolumeID=m.fVolumeID;
     213           0 :   fNParTot  = m.fNParTot;
     214           0 :   fNParFree = m.fNParFree; 
     215           0 :   fNProcPoints = m.fNProcPoints; 
     216           0 :   delete[] fParVals; fParVals = 0;
     217           0 :   delete[] fParErrs; fParErrs = 0;
     218           0 :   delete[] fParCstr; fParCstr = 0;
     219             :   //
     220           0 :   if (fNParTot) {
     221           0 :     fParVals = new Float_t[fNParTot];
     222           0 :     fParErrs = new Float_t[fNParTot];
     223           0 :     fParCstr = new Float_t[fNParTot];
     224           0 :     for (int i=m.GetNParTot();i--;) {
     225           0 :       fParVals[i] = m.fParVals[i];
     226           0 :       fParErrs[i] = m.fParErrs[i];
     227           0 :       fParCstr[i] = m.fParCstr[i];
     228             :     }
     229           0 :   }
     230             :   //
     231           0 :   fParOffs.Set(fNParTot);
     232           0 :   for (int i=0;i<fNParTot;i++) fParOffs[i] = m.fParOffs[i];
     233           0 :   for (int i=0;i<3;i++) fSigmaFactor[i] = m.fSigmaFactor[i];
     234           0 :   if (fMatrix) delete fMatrix;
     235           0 :   fMatrix=new TGeoHMatrix(*m.GetMatrix());
     236           0 :   if(fSensVolMatrix) delete fSensVolMatrix;
     237           0 :   fSensVolMatrix = new TGeoHMatrix(*m.fSensVolMatrix);
     238           0 :   if(fSensVolModifMatrix) delete fSensVolModifMatrix;
     239           0 :   fSensVolModifMatrix = new TGeoHMatrix(*m.fSensVolModifMatrix);
     240           0 :   fSensVolIndex = m.fSensVolIndex;
     241           0 :   fSensVolVolumeID = m.fSensVolVolumeID;
     242           0 :   fParent = m.fParent;
     243           0 :   fChildren.Clear();
     244           0 :   for (int i=0;i<m.GetNChildren();i++) fChildren.Add(m.GetChild(i));
     245           0 :   return *this;
     246           0 : }
     247             : 
     248             : 
     249             : //-------------------------------------------------------------
     250           0 : AliITSAlignMille2Module::~AliITSAlignMille2Module() { 
     251             :   /// Destructor 
     252           0 :   delete fMatrix; 
     253           0 :   delete fSensVolMatrix; 
     254           0 :   delete fSensVolModifMatrix; 
     255           0 :   delete[] fParVals;
     256           0 :   delete[] fParErrs;
     257           0 :   delete[] fParCstr;
     258           0 :   fChildren.Clear();
     259           0 : } 
     260             : 
     261             : //-------------------------------------------------------------
     262             : Int_t AliITSAlignMille2Module::Set(Int_t index, UShort_t volid, const char* symname, 
     263             :                                    const TGeoHMatrix *m, Int_t nsv, const UShort_t *volidsv) 
     264             : {
     265             :   // initialize a custom supermodule
     266             :   // index, volid, symname and matrix must be given
     267             :   // if (volidsv) add nsv sensitive volumes to the supermodules
     268             :   // return 0 if success
     269             : 
     270           0 :   if (index<2198) {
     271           0 :     AliInfo("Index must be >= 2198");
     272           0 :     return -1;
     273             :   }
     274           0 :   if (volid<14336) {
     275           0 :     AliInfo("VolumeID must be >= 14336");
     276           0 :     return -2;
     277             :   }
     278             :   
     279           0 :   if (!symname) return -3;
     280           0 :   for (Int_t i=0; i<2198; i++) {
     281           0 :     if (!strcmp(symname,AliITSgeomTGeo::GetSymName(i))) {
     282           0 :       AliInfo("Symname already used by a Sensitive Volume");
     283           0 :       return -3;
     284             :     }
     285             :   }
     286             :   
     287           0 :   if (!m) return -4;
     288             : 
     289             :   // can initialize needed stuffs
     290           0 :   fIndex = index;
     291           0 :   fVolumeID = volid;
     292           0 :   SetName(symname);
     293             :   //
     294           0 :   (*fMatrix) = (*m);
     295             :   //
     296           0 :   fSensVolIndex.Set(nsv);
     297           0 :   fSensVolVolumeID.Set(nsv);
     298             :   // add sensitive volumes
     299           0 :   for (Int_t i=0; i<nsv; i++) AddSensitiveVolume(volidsv[i]);
     300             : 
     301           0 :   return 0;
     302           0 : }
     303             : 
     304             : //-------------------------------------------------------------
     305             : void AliITSAlignMille2Module::SetFreeDOF(Int_t dof,Double_t cstr)
     306             : {
     307           0 :   if (AliITSAlignMille2::IsZero(cstr)) fParCstr[dof] = 0;  // fixed parameter
     308           0 :   else if (cstr>0)                     fParCstr[dof] = fgkDummyConstraint+1.; // the parameter is free and unconstrained
     309           0 :   else                                 fParCstr[dof] = -cstr;                 // the parameter is free but constrained
     310           0 : }
     311             : 
     312             : //-------------------------------------------------------------
     313             : Bool_t AliITSAlignMille2Module::IsSensor(UShort_t voluid) 
     314             : {
     315             :   // Does this volid correspond to sensor ?
     316           0 :   AliGeomManager::ELayerID layId = AliGeomManager::VolUIDToLayerSafe(voluid);
     317           0 :   if (layId>0 && layId<7) {
     318           0 :     Int_t mId = Int_t(voluid & 0x7ff);
     319           0 :     if( mId>=0 && mId<AliGeomManager::LayerSize(layId)) return kTRUE;
     320           0 :   }
     321           0 :   return kFALSE;
     322           0 : }
     323             : 
     324             : //-------------------------------------------------------------
     325             : Int_t AliITSAlignMille2Module::GetIndexFromVolumeID(UShort_t voluid) {
     326             :   /// index from volume ID
     327           0 :   AliGeomManager::ELayerID lay = AliGeomManager::VolUIDToLayer(voluid);
     328           0 :   if (lay<1|| lay>6) return -1;
     329           0 :   Int_t idx=Int_t(voluid)-2048*lay;
     330           0 :   if (idx>=AliGeomManager::LayerSize(lay)) return -1;
     331           0 :   for (Int_t ilay=1; ilay<lay; ilay++) 
     332           0 :     idx += AliGeomManager::LayerSize(ilay);
     333           0 :   return idx;
     334           0 : }
     335             : 
     336             : //-------------------------------------------------------------
     337             : void AliITSAlignMille2Module::AddSensitiveVolume(UShort_t voluid)
     338             : {
     339             :   /// add a sensitive volume to this supermodule
     340           0 :   if (GetIndexFromVolumeID(voluid)<0) return; // bad volid
     341             :   //
     342             :   // in principle, the correct size of fSensVol... arrays was set outside but check anyway
     343           0 :   if (fSensVolVolumeID.GetSize()<fNSensVol+1) {
     344           0 :     fSensVolVolumeID.Set(fNSensVol+1);
     345           0 :     fSensVolIndex.Set(fNSensVol+1);
     346           0 :   }
     347             :   //
     348           0 :   fSensVolVolumeID[fNSensVol] = Short_t(voluid);
     349           0 :   fSensVolIndex[fNSensVol] = GetIndexFromVolumeID(voluid);
     350           0 :   fNSensVol++;
     351           0 : }
     352             : 
     353             : //-------------------------------------------------------------
     354             : void AliITSAlignMille2Module::DelSensitiveVolume(Int_t at)
     355             : {
     356             :   // Suppress sensor at position "at"
     357             :   // in fact we are swapping with the last valid one 
     358           0 :   int lastValid = --fNSensVol;
     359           0 :   int tmpv = fSensVolIndex[at];
     360           0 :   fSensVolIndex[at] = fSensVolIndex[lastValid];
     361           0 :   tmpv = fSensVolVolumeID[at];
     362           0 :   fSensVolVolumeID[at] = fSensVolVolumeID[lastValid];
     363           0 :   fSensVolVolumeID[lastValid] = tmpv;
     364             :   //
     365           0 : }
     366             : 
     367             : //-------------------------------------------------------------
     368             : Bool_t AliITSAlignMille2Module::IsIn(UShort_t voluid) const 
     369             : {
     370             :   /// check if voluid is defined
     371           0 :   if (!voluid) return kFALSE; // only positive voluid are accepted
     372           0 :   for (Int_t i=0; i<fNSensVol; i++) if (UShort_t(fSensVolVolumeID[i])==voluid) return kTRUE;
     373           0 :   return kFALSE;
     374           0 : }
     375             : 
     376             : //-------------------------------------------------------------
     377             : Bool_t AliITSAlignMille2Module::BelongsTo(AliITSAlignMille2Module* parent) const
     378             : {
     379             :   /// check if parent contains the sensors of this volume
     380           0 :   if (fNSensVol<1 || fNSensVol>=parent->GetNSensitiveVolumes()) return kFALSE;
     381           0 :   return parent->IsIn( fSensVolVolumeID[0] );
     382           0 : }
     383             : 
     384             : //-------------------------------------------------------------
     385             : TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, const Double_t *delta,Bool_t local)
     386             : {
     387             :   // modify the original TGeoHMatrix of the sensitive module 'voluid' according
     388             :   // with a delta transform. applied to the supermodule matrix
     389             :   // return NULL if error
     390             : 
     391           0 :   if (!IsIn(voluid)) return NULL;
     392           0 :   if (!gGeoManager)  return NULL;
     393             : 
     394             :   // prepare the TGeoHMatrix
     395             :   Double_t tr[3],ang[3];
     396           0 :   tr[0]=delta[0]; // in centimeter
     397           0 :   tr[1]=delta[1]; 
     398           0 :   tr[2]=delta[2];
     399           0 :   ang[0]=delta[3]; // psi   (X)  in deg
     400           0 :   ang[1]=delta[4]; // theta (Y)
     401           0 :   ang[2]=delta[5]; // phi   (Z)
     402             :   //
     403           0 :   static AliAlignObjParams tempAlignObj;
     404           0 :   tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
     405           0 :   tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
     406           0 :   AliDebug(3,Form("Delta angles: psi=%f  theta=%f   phi=%f",ang[0],ang[1],ang[2]));
     407           0 :   TGeoHMatrix hm;
     408           0 :   tempAlignObj.GetMatrix(hm);
     409             :   //printf("\n0: delta matrix\n");hm.Print();
     410             : 
     411             :   // 1) start setting fSensVolModif = fSensVol
     412           0 :   if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
     413             :   //
     414           0 :   if (local) {
     415             :     // 2) set fSensVolModif = SensVolRel
     416           0 :     fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
     417             :     // 3) multiply left by delta
     418           0 :     fSensVolModifMatrix->MultiplyLeft( &hm );
     419             :     // 4) multiply left by fMatrix
     420           0 :     fSensVolModifMatrix->MultiplyLeft( fMatrix );
     421             :   }
     422           0 :   else fSensVolModifMatrix->MultiplyLeft( &hm );
     423             :   //
     424           0 :   return fSensVolModifMatrix;
     425           0 : }
     426             : 
     427             : //-------------------------------------------------------------
     428             : AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, const Double_t *deltalocal)
     429             : {
     430             :   // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
     431             :   // of the mother volume. The misalignment is returned as AliAlignObjParams object
     432             : 
     433           0 :   if (!IsIn(voluid)) return NULL;
     434           0 :   if (!gGeoManager) return NULL;
     435             :   
     436             :   // prepare the TGeoHMatrix
     437             :   Double_t tr[3],ang[3];
     438           0 :   tr[0]=deltalocal[0]; // in centimeter
     439           0 :   tr[1]=deltalocal[1]; 
     440           0 :   tr[2]=deltalocal[2];
     441           0 :   ang[0]=deltalocal[3]; // psi   (X)  in deg
     442           0 :   ang[1]=deltalocal[4]; // theta (Y)
     443           0 :   ang[2]=deltalocal[5]; // phi   (Z)
     444             :   //
     445           0 :   static AliAlignObjParams tempAlignObj;
     446           0 :   tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
     447           0 :   tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
     448           0 :   AliDebug(3,Form("Delta angles: psi=%f  theta=%f   phi=%f",ang[0],ang[1],ang[2]));
     449             :   //
     450           0 :   return GetSensitiveVolumeMisalignment(voluid,&tempAlignObj);
     451           0 : }
     452             : 
     453             : //-------------------------------------------------------------
     454             : AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, const AliAlignObjParams *a)
     455             : {
     456             :   // return the misalignment of the sens. vol. 'voluid' corresponding with 
     457             :   // a misalignment 'a' in the mother volume
     458             :   // return NULL if error
     459             : 
     460             :   // Gsv = Gg * Gg-1 * Gsv   -> Lsv,g = Gg-1 * Gsv
     461             :   // G'sv = Gg * Dg * Lsv,g === Gsv * Dsv
     462             :   // Gg * Dg * Gg-1 * Gsv = Gsv * Gsv-1 * Gg * Dg * Gg-1 * Gsv
     463             :   //
     464             :   // => Dsv = (Gsv-1 * Gg * Dg * Gg-1 * Gsv)
     465             :   //
     466             : 
     467           0 :   if (!IsIn(voluid)) return NULL;
     468           0 :   if (!gGeoManager) return NULL;
     469             : 
     470             :   //a->Print("");
     471             : 
     472             :   // prepare the Delta matrix Dg
     473           0 :   TGeoHMatrix dg;
     474           0 :   a->GetMatrix(dg);
     475             :   //dg.Print();
     476             : 
     477             :   // 1) start setting fSensVolModif = Gsv
     478           0 :   if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
     479             :   //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
     480             : 
     481             :   // 2) set fSensVolModif = Gg-1 * Gsv
     482           0 :   fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
     483             :   //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
     484             :  
     485             :   // 3) set fSensVolModif = Dg * Gg-1 * Gsv
     486           0 :   fSensVolModifMatrix->MultiplyLeft( &dg );
     487             :   //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
     488             :   
     489             :   // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv
     490           0 :   fSensVolModifMatrix->MultiplyLeft( fMatrix );
     491             :   //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();
     492             : 
     493             :   // 5) set fSensVolModif = Gsv-1 * Gg * Dg * Gg-1 * Gsv
     494           0 :   if (SensVolMatrix(voluid, &dg)) return NULL;
     495           0 :   fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );
     496             :   //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();
     497             :   //
     498             :   // >> RS
     499             :  // 6) mo' fSensVolModif dovrebbe essere la Dsv(loc) t.c. G'sv = Gsv*Dsv(loc)
     500             :   // per trasformarla in Dsv(loc rispetto al Gsv0, non modificato) dovrebbe essere:
     501             :   // Dsv(loc) -> Dpre * Dsv(loc) * Dpre-1
     502             :   //TGeoHMatrix dpre; // dpre = Gsv0-1*Gsv
     503             :   //if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;
     504             :   //if (SensVolMatrix(voluid, &dpre)) return NULL;
     505             :   //dpre.MultiplyLeft( &dg.Inverse() );
     506             :   //fSensVolModifMatrix->Multiply( &dpre.Inverse() );
     507             :   //fSensVolModifMatrix->MultiplyLeft( &dpre );
     508             :   // direi che NON FUNZIONA!!!!  
     509             : 
     510             :   // << RS
     511             : 
     512             :   // reset align object (may not be needed...)
     513           0 :   static AliAlignObjParams tempAlignObj;
     514           0 :   tempAlignObj.SetVolUID(0);
     515           0 :   tempAlignObj.SetSymName("");
     516           0 :   tempAlignObj.SetTranslation(0,0,0);
     517           0 :   tempAlignObj.SetRotation(0,0,0);
     518             :   //
     519             :   // >> RS
     520             : #ifdef CORHW_
     521             :   // correction for SPD y-shift
     522           0 :   if (voluid>=2048 && voluid<4256) {
     523           0 :     TGeoHMatrix deltay;
     524           0 :     double dy[3]={0.,0.0081,0.};
     525           0 :     deltay.SetTranslation(dy);
     526           0 :     fSensVolModifMatrix->MultiplyLeft( &deltay );
     527           0 :     fSensVolModifMatrix->Multiply( &deltay.Inverse() );
     528           0 :   }
     529             : #endif
     530             :   // << RS
     531           0 :   if (!tempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;
     532           0 :   tempAlignObj.SetVolUID(voluid);
     533           0 :   tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
     534             :   //
     535           0 :   return &tempAlignObj;
     536           0 : }
     537             : 
     538             : // >> RS
     539             : //-------------------------------------------------------------
     540             : AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeTotalMisalignment(UShort_t voluid, const Double_t *deltalocal)
     541             : {
     542             :   // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
     543             :   // of the mother volume. The misalignment is returned as AliAlignObjParams object including
     544             :   // the (evenctual) prealignment => no merging needed
     545             : 
     546           0 :   if (!IsIn(voluid)) return NULL;
     547           0 :   if (!gGeoManager) return NULL;
     548             :   
     549             :   // prepare the TGeoHMatrix
     550             :   Double_t tr[3],ang[3];
     551           0 :   tr[0]=deltalocal[0]; // in centimeter
     552           0 :   tr[1]=deltalocal[1]; 
     553           0 :   tr[2]=deltalocal[2];
     554           0 :   ang[0]=deltalocal[3]; // psi   (X)  in deg
     555           0 :   ang[1]=deltalocal[4]; // theta (Y)
     556           0 :   ang[2]=deltalocal[5]; // phi   (Z)
     557             : 
     558             :   // reset align object (may not be needed...)
     559           0 :   static AliAlignObjParams tempAlignObj;
     560           0 :   tempAlignObj.SetVolUID(0);
     561           0 :   tempAlignObj.SetSymName("");
     562           0 :   tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
     563           0 :   tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
     564           0 :   AliDebug(3,Form("Delta angles: psi=%f  theta=%f   phi=%f",ang[0],ang[1],ang[2]));
     565             : 
     566             :   // Gsv = Gg * Gg-1 * Gsv   -> Lsv,g = Gg-1 * Gsv
     567             :   // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv 
     568             :   //
     569             :   // => Dsv = (G0sv-1 * Gg * Dg * Gg-1 * GMsv)  //
     570             :   //
     571             : 
     572             :   // prepare the Delta matrix Dg
     573           0 :   TGeoHMatrix dg;
     574           0 :   tempAlignObj.GetMatrix(dg);
     575             :   //dg.Print();
     576             : 
     577             :   // 1) start setting fSensVolModif = Gsv
     578           0 :   if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
     579             :   //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
     580             : 
     581             :   // 2) set fSensVolModif = Gg-1 * Gsv
     582           0 :   fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
     583             :   //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
     584             :  
     585             :   // 3) set fSensVolModif = Dg * Gg-1 * Gsv
     586           0 :   fSensVolModifMatrix->MultiplyLeft( &dg );
     587             :   //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
     588             :   
     589             :   // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv
     590           0 :   fSensVolModifMatrix->MultiplyLeft( fMatrix );
     591             :   //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();
     592             : 
     593             :   // 5) set fSensVolModif = G0sv-1 * Gg * Dg * Gg-1 * Gsv
     594             :   // qui usa l'orig anziche' la prealigned...
     595           0 :   if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;
     596           0 :   fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );
     597             :   //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();
     598             : 
     599             :   // reset align object (may not be needed...)
     600           0 :   tempAlignObj.SetVolUID(0);
     601           0 :   tempAlignObj.SetSymName("");
     602           0 :   tempAlignObj.SetTranslation(0,0,0);
     603           0 :   tempAlignObj.SetRotation(0,0,0);
     604             : 
     605             : #ifdef CORHW_
     606             :   // correction for SPD y-shift
     607           0 :   if (voluid>=2048 && voluid<4256) {
     608           0 :     TGeoHMatrix deltay;
     609           0 :     double dy[3]={0.,0.0081,0.};
     610           0 :     deltay.SetTranslation(dy);
     611           0 :     fSensVolModifMatrix->MultiplyLeft( &deltay );
     612           0 :     fSensVolModifMatrix->Multiply( &deltay.Inverse() );
     613           0 :   }
     614             : #endif
     615           0 :   if (!tempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;
     616           0 :   tempAlignObj.SetVolUID(voluid);
     617           0 :   tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
     618             : 
     619             :   
     620             :   //tempAlignObj.Print("");
     621             : 
     622           0 :   return &tempAlignObj;
     623           0 : }
     624             : //-------------------------------------------------------------
     625             : 
     626             : //-------------------------------------------------------------
     627             : AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeGlobalMisalignment(UShort_t voluid, const Double_t *deltalocal)
     628             : {
     629             :   // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
     630             :   // of the mother volume. The misalignment is returned as AliAlignObjParams object
     631             : 
     632           0 :   if (!IsIn(voluid)) return NULL;
     633           0 :   if (!gGeoManager) return NULL;
     634             :   
     635             :   // prepare the TGeoHMatrix
     636             :   Double_t tr[3],ang[3];
     637           0 :   tr[0]=deltalocal[0]; // in centimeter
     638           0 :   tr[1]=deltalocal[1]; 
     639           0 :   tr[2]=deltalocal[2];
     640           0 :   ang[0]=deltalocal[3]; // psi   (X)  in deg
     641           0 :   ang[1]=deltalocal[4]; // theta (Y)
     642           0 :   ang[2]=deltalocal[5]; // phi   (Z)
     643             : 
     644             :   // reset align object (may not be needed...)
     645           0 :   static AliAlignObjParams tempAlignObj;
     646           0 :   tempAlignObj.SetTranslation(0,0,0);
     647           0 :   tempAlignObj.SetRotation(0,0,0);
     648             : 
     649           0 :   tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);
     650           0 :   tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);
     651           0 :   AliDebug(3,Form("Delta angles: psi=%f  theta=%f   phi=%f",ang[0],ang[1],ang[2]));
     652             : 
     653             :   // Gsv = Gg * Gg-1 * Gsv   -> Lsv,g = Gg-1 * Gsv
     654             :   // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv 
     655             :   //
     656             :   // => DGsv = (Gg * Dg * Gg-1)
     657             :   //
     658             : 
     659             :   // prepare the Delta matrix Dg
     660           0 :   TGeoHMatrix dg;
     661           0 :   tempAlignObj.GetMatrix(dg);
     662             :   //dg.Print();
     663             : 
     664           0 :   dg.MultiplyLeft( fMatrix );
     665           0 :   dg.Multiply( &fMatrix->Inverse() );
     666             : 
     667             :   // reset align object (may not be needed...)
     668           0 :   tempAlignObj.SetTranslation(0,0,0);
     669           0 :   tempAlignObj.SetRotation(0,0,0);
     670             : 
     671           0 :   tempAlignObj.SetVolUID(voluid);
     672           0 :   tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));
     673             : 
     674           0 :   if (!tempAlignObj.SetMatrix(dg)) return NULL;
     675             :   
     676             :   //tempAlignObj.Print("");
     677             : 
     678           0 :   return &tempAlignObj;
     679           0 : }
     680             : // << RS
     681             : 
     682             : //-------------------------------------------------------------
     683             : TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeMatrix(UShort_t voluid)
     684             : {
     685             :   // return TGeoHMatrix of the sens.vol. 'voluid' in the current geometry
     686           0 :   if (SensVolMatrix(voluid,fSensVolMatrix)) return NULL;
     687           0 :   return fSensVolMatrix;
     688           0 : }
     689             : 
     690             : //-------------------------------------------------------------
     691             : TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeOrigGlobalMatrix(UShort_t voluid)
     692             : {
     693             :   // return original ideal position (from AliGeomManager::GetOrigGlobalMatrix())
     694           0 :   if (SensVolOrigGlobalMatrix(voluid,fSensVolMatrix)) return NULL;
     695           0 :   return fSensVolMatrix;
     696           0 : }
     697             : //-------------------------------------------------------------
     698             : Int_t AliITSAlignMille2Module::SensVolMatrix(UShort_t volid, TGeoHMatrix *m) 
     699             : {
     700             :   // set matrix for sensitive modules (SPD corrected)
     701             :   // return 0 if success
     702           0 :   Double_t rot[9];
     703           0 :   Int_t idx=GetIndexFromVolumeID(volid);
     704           0 :   if (idx<0) return -1;
     705           0 :   if (!AliITSgeomTGeo::GetRotation(idx,rot)) return -2;
     706           0 :   m->SetRotation(rot);
     707           0 :   Double_t oLoc[3]={0,0,0};
     708           0 :   Double_t oGlo[3]={0,0,0};
     709           0 :   if (!AliITSgeomTGeo::LocalToGlobal(idx,oLoc,oGlo)) return -3;
     710           0 :   m->SetTranslation(oGlo);
     711           0 :   return 0;
     712           0 : }
     713             : 
     714             : //-------------------------------------------------------------
     715             : Int_t AliITSAlignMille2Module::SensVolOrigGlobalMatrix(UShort_t volid, TGeoHMatrix *m) 
     716             : {
     717             :   // set original global matrix for sensitive modules (SPD corrected)
     718             :   // return 0 if success
     719           0 :   Int_t idx=GetIndexFromVolumeID(volid);
     720           0 :   if (idx<0) return -1;
     721           0 :   TGeoHMatrix mo;
     722           0 :   if (!AliGeomManager::GetOrigGlobalMatrix(AliGeomManager::SymName(volid),mo)) return -1;
     723           0 :   (*m)=mo;
     724             :   //
     725             : #ifdef CORHW_
     726             :   // SPD y-shift by 81 mu
     727           0 :   if (volid<5000) { 
     728           0 :     Double_t oLoc[3]={0.0,0.0081,0.0};
     729           0 :     Double_t oGlo[3]={0,0,0};
     730           0 :     m->LocalToMaster(oLoc,oGlo);
     731           0 :     m->SetTranslation(oGlo);
     732           0 :   }
     733             : #endif
     734           0 :   return 0;
     735           0 : }
     736             : 
     737             : //-------------------------------------------------------------
     738             : UShort_t AliITSAlignMille2Module::GetVolumeIDFromSymname(const Char_t *symname) {
     739             :   /// volume ID from symname
     740           0 :   if (!symname) return 0;
     741             : 
     742           0 :   for (UShort_t voluid=2000; voluid<13300; voluid++) {
     743           0 :     Int_t modId;
     744           0 :     AliGeomManager::ELayerID layerId = AliGeomManager::VolUIDToLayer(voluid,modId);
     745           0 :     if (layerId>0 && layerId<7 && modId>=0 && modId<AliGeomManager::LayerSize(layerId)) {
     746           0 :       if (!strcmp(symname,AliGeomManager::SymName(layerId,modId))) return voluid;
     747             :     }
     748           0 :   }
     749             : 
     750           0 :   return 0;
     751           0 : }
     752             : 
     753             : //-------------------------------------------------------------
     754             : UShort_t AliITSAlignMille2Module::GetVolumeIDFromIndex(Int_t index) {
     755             :   /// volume ID from index
     756           0 :   if (index<0 || index>2197) return 0;
     757           0 :   return GetVolumeIDFromSymname(AliITSgeomTGeo::GetSymName(index));
     758           0 : }
     759             : 
     760             : //-------------------------------------------------------------
     761             : void AliITSAlignMille2Module::Print(Option_t*) const 
     762             : {
     763             :   // print data
     764             :   //
     765           0 :   const char* typeName[] = {"SPD","SDD","SSD"};
     766           0 :   printf("*** ITS SuperModule for AliITSAlignMille ***\n");
     767           0 :   printf("symname  : %s (type: %s)\n",GetName(),fDetType<0 ? "N/A":typeName[fDetType]);
     768           0 :   printf("parent   : %s | %d children\n",fParent ? fParent->GetName() : "N/A",GetNChildren());
     769           0 :   printf("volumeID : %4d  | index : %4d | Geom.Params are %s\n",fVolumeID,fIndex,
     770           0 :          GeomParamsGlobal() ? "Global":"Local");
     771           0 :   printf("Factors  : X=%.2f Y=%.2f Z=%.2f\n"
     772             :          "DOF: %cTx:%5d| %cTy:%5d| %cTz:%5d| %cPsi:%5d| %cTheta:%5d| %cPhi:%5d|",
     773           0 :          fSigmaFactor[0],fSigmaFactor[1],fSigmaFactor[2],
     774           0 :          IsFreeDOF(kDOFTX) ? '+':'-',GetParOffset(kDOFTX),IsFreeDOF(kDOFTY) ? '+':'-',GetParOffset(kDOFTY),
     775           0 :          IsFreeDOF(kDOFTZ) ? '+':'-',GetParOffset(kDOFTZ),IsFreeDOF(kDOFPS) ? '+':'-',GetParOffset(kDOFPS),
     776           0 :          IsFreeDOF(kDOFTH) ? '+':'-',GetParOffset(kDOFTH),IsFreeDOF(kDOFPH) ? '+':'-',GetParOffset(kDOFPH));
     777           0 :   if (IsSDD()) {
     778           0 :     printf("%cT0:%5d| %cDVl:%5d| %cDVr:%5d|",IsFreeDOF(kDOFT0)?'+':'-',GetParOffset(kDOFT0),
     779           0 :            IsFreeDOF(kDOFDVL)?'+':'-',GetParOffset(kDOFDVL),IsFreeDOF(kDOFDVR)?'+':'-',GetParOffset(kDOFDVR));
     780           0 :     if (IsVDriftLRSame()) printf("(dVL=dVR)");
     781             :   }
     782           0 :   printf("\n");
     783           0 :   fMatrix->Print();
     784           0 :   printf("%4d Sensitive volumes | %6d Processed Points\n",fNSensVol,fNProcPoints);
     785           0 :   for (Int_t i=0; i<fNSensVol; i++) printf("   voluid[%d] = %d\n",i,UShort_t(fSensVolVolumeID[i]));
     786           0 : }
     787             : 
     788             : //-------------------------------------------------------------
     789             : Bool_t AliITSAlignMille2Module::IsAlignable() const
     790             : {
     791             :   // it it alignable?
     792           0 :   TGeoManager* geoManager = AliGeomManager::GetGeometry();
     793           0 :   if (!geoManager) {
     794           0 :     AliInfo("Couldn't initialize geometry");
     795           0 :     return kFALSE;
     796             :   }
     797           0 :   return geoManager->GetAlignableEntry(GetName())!=0;
     798           0 : }
     799             : 
     800             : //-------------------------------------------------------------
     801             : void AliITSAlignMille2Module::GetLocalMatrix(TGeoHMatrix &mat) const
     802             : {
     803             :   // return the local matrix for transformation to its parent
     804           0 :   mat = *fMatrix;
     805           0 :   if (fParent) mat.MultiplyLeft( &fParent->GetMatrix()->Inverse() );
     806           0 : }
     807             : 
     808             : //-------------------------------------------------------------
     809             : void AliITSAlignMille2Module::AssignDetType()
     810             : {
     811             :   // assign the detector type
     812           0 :   TString tp = GetName();
     813           0 :   if      (tp.Contains("SPD",TString::kIgnoreCase)) fDetType = kSPD;
     814           0 :   else if (tp.Contains("SDD",TString::kIgnoreCase)) fDetType = kSDD;
     815           0 :   else if (tp.Contains("SSD",TString::kIgnoreCase)) fDetType = kSSD;
     816           0 :   else fDetType = -1;
     817           0 :   fNParTot = IsSDD() ? kMaxParTot:kMaxParGeom;
     818           0 :   fNParFree = 0;
     819           0 :   fParVals = new Float_t[fNParTot];
     820           0 :   fParErrs = new Float_t[fNParTot];  
     821           0 :   fParCstr = new Float_t[fNParTot];  
     822           0 :   if (fParOffs.GetSize()<fNParTot) fParOffs.Set(fNParTot);
     823           0 :   for (int i=fNParTot;i--;) {
     824           0 :     fParVals[i] = fParErrs[i] = 0.; 
     825           0 :     fParCstr[i] = 0.;
     826           0 :     fParOffs[i] = -1;
     827             :   }
     828           0 : }
     829             : 
     830             : //-------------------------------------------------------------
     831             : void AliITSAlignMille2Module::EvaluateDOF()
     832             : {
     833             :   // count d.o.f.
     834           0 :   fNParFree = 0;
     835           0 :   for (int i=fNParTot;i--;) if (IsFreeDOF(i)) fNParFree++;
     836           0 : }
     837             : 
     838             : //-------------------------------------------------------------
     839             : void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,Double_t *t, Double_t *r)
     840             : {
     841             :   // return global parameters of the sensor volid
     842           0 :   for (int i=3;i--;) t[i] = r[i] = 0.;
     843           0 :   if (SensVolMatrix(volid,fSensVolMatrix)) return;  
     844           0 :   AliAlignObjParams tempAlignObj;
     845           0 :   tempAlignObj.SetMatrix(*fSensVolMatrix);
     846           0 :   tempAlignObj.GetPars(t,r);
     847           0 : }
     848             : 
     849             : //-------------------------------------------------------------
     850             : void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,Double_t *t, Double_t *r)
     851             : {
     852             :   // return parameters of the sensor volid in the current module
     853           0 :   for (int i=3;i--;) t[i] = r[i] = 0.;
     854           0 :   if (SensVolMatrix(volid,fSensVolMatrix)) return;  
     855           0 :   fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );
     856           0 :   AliAlignObjParams tempAlignObj;  
     857           0 :   tempAlignObj.SetMatrix(*fSensVolMatrix);
     858           0 :   tempAlignObj.GetPars(t,r);
     859           0 : }
     860             : 
     861             : //-------------------------------------------------------------
     862             : void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,const Double_t* loct, const Double_t* locr,Double_t *t, Double_t *r)
     863             : {
     864             :   // return global parameters of the sensor volid modified by the localDelta params
     865           0 :   for (int i=3;i--;) t[i] = r[i] = 0.;
     866           0 :   if (SensVolMatrix(volid,fSensVolMatrix)) return;  
     867           0 :   AliAlignObjParams tempAlignObj;
     868           0 :   tempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
     869           0 :   tempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
     870             :   //
     871           0 :   tempAlignObj.GetMatrix(*fSensVolModifMatrix);      // obtain local delta
     872           0 :   fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta
     873           0 :   tempAlignObj.SetMatrix(*fSensVolModifMatrix);
     874           0 :   tempAlignObj.GetPars(t,r);                         // obtain global params
     875           0 : }
     876             : 
     877             : //-------------------------------------------------------------
     878             : void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,const Double_t* loct,const Double_t* locr,Double_t *t, Double_t *r)
     879             : {
     880             :   // return parameters of the sensor volid (modified by the localDelta params) in the current volume
     881           0 :   for (int i=3;i--;) t[i] = r[i] = 0.;
     882           0 :   if (SensVolMatrix(volid,fSensVolMatrix)) return;  
     883           0 :   AliAlignObjParams tempAlignObj;
     884           0 :   tempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
     885           0 :   tempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
     886             :   //
     887           0 :   tempAlignObj.GetMatrix(*fSensVolModifMatrix);      // obtain local delta
     888           0 :   fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta
     889           0 :   fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() ); // obtain delta in current volume
     890           0 :   tempAlignObj.SetMatrix(*fSensVolModifMatrix);
     891           0 :   tempAlignObj.GetPars(t,r);                         // obtain params
     892           0 : }
     893             : 
     894             : //-------------------------------------------------------------
     895             : void AliITSAlignMille2Module::SetParVals(Double_t *vl,Int_t npar)
     896             : {
     897             :   // set parameters
     898           0 :   for (int i=TMath::Min(npar,(Int_t)fNParTot);i--;) fParVals[i] = vl[i];
     899           0 : }
     900             : 
     901             : //-------------------------------------------------------------
     902             : void AliITSAlignMille2Module::GetGeomParamsGlo(Double_t *pars)
     903             : {
     904             :   // recompute parameters from local to global frame
     905             :   //
     906             :   // is there anything to do?
     907           0 :   if (GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}
     908             :   //
     909             :   // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)
     910             :   // as for the current module. Since in the mp2 the modules are stored from parents to children,
     911             :   // it is safe to call this method in loop staring from the lowest level child, i.e. from the end
     912             :   // of the modules array.
     913             :   //
     914             :   // DeltaGlobal = (ModifParents)*DeltaLocal*(ModifParents)^-1 
     915             :   //
     916           0 :   *fSensVolMatrix = *fMatrix;   // current global matrix
     917           0 :   AliAlignObjParams tempAlignObj;
     918           0 :   AliITSAlignMille2Module* parent = GetParent();
     919           0 :   while (parent) {
     920           0 :     if (parent->GeomParamsGlobal()) {
     921           0 :       AliError("Cannot convert params to Global when the parents are already Global\n");
     922           0 :       for (int i=kMaxParGeom;i--;) pars[i] = 0;
     923           0 :       return;
     924             :     }
     925           0 :     fSensVolMatrix->MultiplyLeft( &parent->GetMatrix()->Inverse() ); // Local Matrix
     926           0 :     Float_t *parpar = parent->GetParVals();
     927           0 :     tempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);
     928           0 :     tempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);
     929           0 :     tempAlignObj.GetMatrix(*fSensVolModifMatrix);
     930           0 :     fSensVolMatrix->MultiplyLeft(fSensVolModifMatrix);
     931           0 :     fSensVolMatrix->MultiplyLeft(parent->GetMatrix());  // global matrix after parents modifications
     932           0 :     parent = parent->GetParent();
     933             :   }
     934             :   //
     935           0 :   tempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);
     936           0 :   tempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);
     937           0 :   tempAlignObj.GetMatrix(*fSensVolModifMatrix);  // local delta matrix
     938           0 :   fSensVolModifMatrix->Multiply( &fSensVolMatrix->Inverse() );
     939           0 :   fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix );
     940           0 :   tempAlignObj.SetMatrix( *fSensVolModifMatrix );  // global delta matrix
     941           0 :   tempAlignObj.GetPars(pars,pars+3);
     942             :   //
     943           0 : }
     944             : 
     945             : //-------------------------------------------------------------
     946             : void AliITSAlignMille2Module::GetGeomParamsLoc(Double_t *pars)
     947             : {
     948             :   // recompute parameters from global to local frame
     949             :   //
     950             :   // is there anything to do?
     951           0 :   if (!GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}
     952             :   //
     953             :   // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)
     954             :   // as for the current module. Since in the mp2 the modules are stored from parents to children,
     955             :   // it is safe to call this method in loop staring from the lowest level child, i.e. from the end
     956             :   // of the modules array.
     957             :   //
     958             :   //  DeltaLocal = (DeltaParents*GlobalMat)^-1*DeltaGlobal*(DeltaParents*GlobalMat)
     959             :   //
     960           0 :   AliITSAlignMille2Module* parent = GetParent();
     961           0 :   AliAlignObjParams tempAlignObj;
     962           0 :   tempAlignObj.SetTranslation(0.,0.,0.);
     963           0 :   tempAlignObj.SetRotation(0.,0.,0.);
     964           0 :   tempAlignObj.GetMatrix(*fSensVolMatrix); // get no-shift matrix
     965             :   //
     966           0 :   while (parent) { // accumulate the product of parents global modifications
     967           0 :     if (!parent->GeomParamsGlobal()) {
     968           0 :       AliError("Cannot convert params to Local when the parents are already Local\n");
     969           0 :       for (int i=kMaxParGeom;i--;) pars[i] = 0;
     970           0 :       return;
     971             :     }
     972           0 :     Float_t *parpar = parent->GetParVals();
     973           0 :     tempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);
     974           0 :     tempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);
     975           0 :     tempAlignObj.GetMatrix(*fSensVolModifMatrix);
     976           0 :     fSensVolMatrix->Multiply(fSensVolModifMatrix); 
     977           0 :     parent = parent->GetParent();
     978             :   }
     979             :   // global matrix after parents modifications
     980           0 :   fSensVolMatrix->Multiply(fMatrix);
     981             :   //
     982           0 :   tempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);
     983           0 :   tempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);
     984           0 :   tempAlignObj.GetMatrix(*fSensVolModifMatrix);  // global delta matrix
     985           0 :   fSensVolModifMatrix->MultiplyLeft( &fSensVolMatrix->Inverse() );
     986           0 :   fSensVolModifMatrix->Multiply( fSensVolMatrix );
     987           0 :   tempAlignObj.SetMatrix( *fSensVolModifMatrix );  // local delta matrix
     988           0 :   tempAlignObj.GetPars(pars,pars+3);
     989             :   //
     990           0 : }
     991             : 
     992             : 
     993             : //-------------------------------------------------------------
     994             : void AliITSAlignMille2Module::CalcDerivDPosDPar(Int_t sensVol,const Double_t* pl, Double_t *deriv)
     995             : {
     996             :   // calculate jacobian of the global position vs Parameters (dPos/dParam) 
     997             :   // for the point in the sensor sensVol
     998             :   const double kDel = 0.01;
     999           0 :   double pos0[3],pos1[3],pos2[3],pos3[3];
    1000           0 :   double delta[kMaxParGeom];
    1001             :   //
    1002           0 :   for (int ip=kMaxParGeom;ip--;) delta[ip] = 0;
    1003             :   //
    1004           0 :   for (int ip=kMaxParGeom;ip--;) {
    1005             :     //
    1006           0 :     delta[ip] -= kDel;
    1007           0 :     GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos0);    
    1008           0 :     delta[ip] += kDel/2;
    1009           0 :     GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos1);    
    1010           0 :     delta[ip] += kDel;
    1011           0 :     GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos2);    
    1012           0 :     delta[ip] += kDel/2;
    1013           0 :     GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos3);    
    1014             :     //
    1015           0 :     delta[ip] = 0;
    1016           0 :     double *curd = deriv + ip*3;
    1017           0 :     for (int i=3;i--;) curd[i] = (8.*(pos2[i]-pos1[i]) - (pos3[i]-pos0[i]))/6./kDel;
    1018             :   }
    1019             :   //
    1020           0 : }
    1021             : 
    1022             : //-------------------------------------------------------------
    1023             : void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t idx,Double_t *deriv)
    1024             : {
    1025             :   // calculate derivative of global params vs local param idx:  deriv[j] = dParGlo[j]/dParLoc[idx]
    1026           0 :   Double_t lpar[kMaxParGeom];
    1027           0 :   for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
    1028             :   //  using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
    1029           0 :   Double_t par1[kMaxParGeom]; // f(x-h)
    1030           0 :   Double_t par2[kMaxParGeom]; // f(x-h/2)
    1031           0 :   Double_t par3[kMaxParGeom]; // f(x+h/2)
    1032           0 :   Double_t par4[kMaxParGeom]; // f(x+h)
    1033             :   //
    1034             :   const Double_t dpar = 1e-3;
    1035             :   //
    1036             :   // first values
    1037           0 :   lpar[idx] -= dpar;
    1038           0 :   GetGlobalParams(lpar,lpar+3, par1,par1+3);
    1039             :   //
    1040             :   // second values
    1041           0 :   lpar[idx] += dpar/2;
    1042           0 :   GetGlobalParams(lpar,lpar+3, par2,par2+3);
    1043             :   //
    1044             :   // third values
    1045           0 :   lpar[idx] += dpar;
    1046           0 :   GetGlobalParams(lpar,lpar+3, par3,par3+3);
    1047             :   //
    1048             :   // fourth values
    1049           0 :   lpar[idx] += dpar/2;
    1050           0 :   GetGlobalParams(lpar,lpar+3, par4,par4+3);
    1051             :   //
    1052             :   Double_t h2 = 1./(2.*dpar);
    1053           0 :   for (int i=kMaxParGeom;i--;) {
    1054           0 :     Double_t d0 = par4[i]-par1[i];
    1055           0 :     Double_t d2 = 2.*(par3[i]-par2[i]);
    1056           0 :     deriv[i] = h2*(4*d2 - d0)/3.;
    1057           0 :     if (TMath::Abs(deriv[i]) < 1.0e-9) deriv[i] = 0.0;
    1058             :   }
    1059             :   //
    1060           0 : }
    1061             : 
    1062             : //-------------------------------------------------------------
    1063             : void AliITSAlignMille2Module::CalcDerivLocGlo(Double_t *deriv)
    1064             : {
    1065             :   // calculate derivative of local params vs global params:  deriv[i][j] = dParLoc[i]/dParGlo[j]
    1066           0 :   Double_t gpar[kMaxParGeom];
    1067           0 :   for (int i=kMaxParGeom;i--;) gpar[i] = 0.;
    1068             :   //  using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
    1069           0 :   Double_t par1[kMaxParGeom]; // f(x-h)
    1070           0 :   Double_t par2[kMaxParGeom]; // f(x-h/2)
    1071           0 :   Double_t par3[kMaxParGeom]; // f(x+h/2)
    1072           0 :   Double_t par4[kMaxParGeom]; // f(x+h)
    1073             :   //
    1074             :   const Double_t dpar = 1e-3;
    1075             :   //
    1076           0 :   for (int ig=kMaxParGeom;ig--;) {
    1077             :     // first values
    1078           0 :     gpar[ig] -= dpar;
    1079           0 :     GetLocalParams(gpar,gpar+3, par1,par1+3);
    1080             :     //
    1081             :     // second values
    1082           0 :     gpar[ig] += dpar/2;
    1083           0 :     GetLocalParams(gpar,gpar+3, par2,par2+3);
    1084             :     //
    1085             :     // third values
    1086           0 :     gpar[ig] += dpar;
    1087           0 :     GetLocalParams(gpar,gpar+3, par3,par3+3);
    1088             :     //
    1089             :     // fourth values
    1090           0 :     gpar[ig] += dpar/2;
    1091           0 :     GetLocalParams(gpar,gpar+3, par4,par4+3);
    1092             :     //
    1093             :     Double_t h2 = 1./(2.*dpar);
    1094           0 :     for (int i=kMaxParGeom;i--;) {
    1095           0 :       Double_t d0 = par4[i]-par1[i];
    1096           0 :       Double_t d2 = 2.*(par3[i]-par2[i]);
    1097           0 :       int idig = i*kMaxParGeom + ig;
    1098           0 :       deriv[idig] = h2*(4*d2 - d0)/3.;
    1099           0 :       if (TMath::Abs(deriv[idig]) < 1.0e-9) deriv[idig] = 0.0;
    1100             :     }
    1101             :   }
    1102             :   //
    1103           0 : }
    1104             : 
    1105             : //________________________________________________________________________________________________________
    1106             : void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t sensVol,Int_t paridx,Double_t* derivative)
    1107             : {
    1108             :   /// calculate numerically the derivatives of global params vs local param paridx for sensor sensVol: dPglob/dPloc_paridx
    1109             :   //
    1110           0 :   Double_t lpar[kMaxParGeom];
    1111           0 :   for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
    1112             :   //  using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
    1113           0 :   Double_t par1[kMaxParGeom]; // f(x-h)
    1114           0 :   Double_t par2[kMaxParGeom]; // f(x-h/2)
    1115           0 :   Double_t par3[kMaxParGeom]; // f(x+h/2)
    1116           0 :   Double_t par4[kMaxParGeom]; // f(x+h)
    1117             :   //
    1118             :   const Double_t dpar = 1e-3;
    1119             :   //
    1120             :   // first values
    1121           0 :   lpar[paridx] -= dpar;
    1122           0 :   GetSensVolGlobalParams(sensVol,lpar,lpar+3, par1,par1+3);
    1123             :   //
    1124             :   // second values
    1125           0 :   lpar[paridx] += dpar/2;
    1126           0 :   GetSensVolGlobalParams(sensVol,lpar,lpar+3, par2,par2+3);
    1127             :   //
    1128             :   // third values
    1129           0 :   lpar[paridx] += dpar;
    1130           0 :   GetSensVolGlobalParams(sensVol,lpar,lpar+3, par3,par3+3);
    1131             :   //
    1132             :   // fourth values
    1133           0 :   lpar[paridx] += dpar/2;
    1134           0 :   GetSensVolGlobalParams(sensVol,lpar,lpar+3, par4,par4+3);
    1135             :   //
    1136             :   Double_t h2 = 1./(2.*dpar);
    1137           0 :   for (int i=kMaxParGeom;i--;) {
    1138           0 :     Double_t d0 = par4[i]-par1[i];
    1139           0 :     Double_t d2 = 2.*(par3[i]-par2[i]);
    1140           0 :     derivative[i] = h2*(4*d2 - d0)/3.;
    1141           0 :     if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;
    1142             :   }
    1143             :   //
    1144           0 : }
    1145             : 
    1146             : //________________________________________________________________________________________________________
    1147             : void AliITSAlignMille2Module::CalcDerivCurLoc(Int_t sensVol,Int_t paridx,Double_t* derivative)  
    1148             : {
    1149             :   /// calculate numerically the derivatives of sensor params in the current volume vs sensor local param paridx
    1150             :   //
    1151           0 :   Double_t lpar[kMaxParGeom];
    1152           0 :   for (int i=kMaxParGeom;i--;) lpar[i] = 0.;
    1153             :   //  using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
    1154           0 :   Double_t par1[kMaxParGeom]; // f(x-h)
    1155           0 :   Double_t par2[kMaxParGeom]; // f(x-h/2)
    1156           0 :   Double_t par3[kMaxParGeom]; // f(x+h/2)
    1157           0 :   Double_t par4[kMaxParGeom]; // f(x+h)
    1158             :   //
    1159             :   const Double_t dpar = 1e-3;
    1160             :   //
    1161             :   // first values
    1162           0 :   lpar[paridx] -= dpar;
    1163           0 :   GetSensVolLocalParams(sensVol,lpar,lpar+3, par1,par1+3);
    1164             :   //
    1165             :   // second values
    1166           0 :   lpar[paridx] += dpar/2;
    1167           0 :   GetSensVolLocalParams(sensVol,lpar,lpar+3, par2,par2+3);
    1168             :   //
    1169             :   // third values
    1170           0 :   lpar[paridx] += dpar;
    1171           0 :   GetSensVolLocalParams(sensVol,lpar,lpar+3, par3,par3+3);
    1172             :   //
    1173             :   // fourth values
    1174           0 :   lpar[paridx] += dpar/2;
    1175           0 :   GetSensVolLocalParams(sensVol,lpar,lpar+3, par4,par4+3);
    1176             :   //
    1177             :   Double_t h2 = 1./(2.*dpar);
    1178           0 :   for (int i=kMaxParGeom;i--;) {
    1179           0 :     Double_t d0 = par4[i]-par1[i];
    1180           0 :     Double_t d2 = 2.*(par3[i]-par2[i]);
    1181           0 :     derivative[i] = h2*(4*d2 - d0)/3.;
    1182           0 :     if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;
    1183             :   }
    1184             :   //
    1185           0 : }
    1186             : 
    1187             : 
    1188             : //-------------------------------------------------------------
    1189             : void AliITSAlignMille2Module::GetGlobalParams(Double_t *t, Double_t *r) const
    1190             : {
    1191             :   // global parameters of the module
    1192           0 :   AliAlignObjParams tempAlignObj;
    1193           0 :   tempAlignObj.SetMatrix( *fMatrix );
    1194           0 :   tempAlignObj.GetPars(t,r);
    1195           0 : }
    1196             : 
    1197             : //-------------------------------------------------------------
    1198             : void AliITSAlignMille2Module::GetGlobalParams(const Double_t* loct, const Double_t* locr, Double_t *t, Double_t *r)
    1199             : {
    1200             :   // global parameters of the module after the modification by local loct,locr
    1201           0 :   AliAlignObjParams tempAlignObj;
    1202           0 :   tempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);
    1203           0 :   tempAlignObj.SetRotation(locr[0],locr[1],locr[2]);
    1204           0 :   tempAlignObj.GetMatrix(*fSensVolModifMatrix);  
    1205           0 :   *fSensVolMatrix = *fMatrix;
    1206           0 :   fSensVolMatrix->Multiply(fSensVolModifMatrix);
    1207           0 :   tempAlignObj.SetMatrix(*fSensVolMatrix);
    1208           0 :   tempAlignObj.GetPars(t,r);
    1209           0 : }
    1210             : 
    1211             : //-------------------------------------------------------------
    1212             : void AliITSAlignMille2Module::GetLocalParams(const Double_t* glot, const Double_t* glor, Double_t *t, Double_t *r)
    1213             : {
    1214             :   // obtain local delta parameters from global delta params
    1215           0 :   AliAlignObjParams tempAlignObj;
    1216           0 :   tempAlignObj.SetTranslation(glot[0],glot[1],glot[2]);
    1217           0 :   tempAlignObj.SetRotation(glor[0],glor[1],glor[2]);
    1218           0 :   tempAlignObj.GetMatrix(*fSensVolMatrix);  
    1219           0 :   fSensVolMatrix->Multiply( fMatrix );
    1220           0 :   fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );
    1221           0 :   tempAlignObj.SetMatrix(*fSensVolMatrix);
    1222           0 :   tempAlignObj.GetPars(t,r);
    1223           0 : }

Generated by: LCOV version 1.11