]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - ITS/AliITSAlignMilleModule.cxx
add the possibility to process the event stat file
[u/mrichter/AliRoot.git] / ITS / AliITSAlignMilleModule.cxx
index e1ffb8dc89483a34ee93388ea966b81282591583..9afc86152f10ada3fb9389e5c312107556470abd 100644 (file)
-/************************************************************************** \r
- * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. * \r
- *                                                                        * \r
- * Author: The ALICE Off-line Project.                                    * \r
- * Contributors are mentioned in the code where appropriate.              * \r
- *                                                                        * \r
- * Permission to use, copy, modify and distribute this software and its   * \r
- * documentation strictly for non-commercial purposes is hereby granted   * \r
- * without fee, provided that the above copyright notice appears in all   * \r
- * copies and that both the copyright notice and this permission notice   * \r
- * appear in the supporting documentation. The authors make no claims     * \r
- * about the suitability of this software for any purpose. It is          * \r
- * provided "as is" without express or implied warranty.                  * \r
- **************************************************************************/ \r
\r
-/* $Id$    */ \r
-//----------------------------------------------------------------------------- \r
-/// \class AliITSAlignMilleModule\r
-/// Alignment class for the ALICE ITS detector \r
-/// \r
-/// This class is used by AliITSAlignMille to build custom supermodules    \r
-/// made of ITS sensitive modules. These supermodules are then aligned\r
-/// \r
-/// Custom supermodules must have VolumeID > 14335\r
-///\r
-/// \author M. Lunardon  \r
-//----------------------------------------------------------------------------- \r
\r
-#include <TGeoManager.h> \r
-#include <TGeoMatrix.h> \r
\r
-#include "AliITSAlignMilleModule.h" \r
-#include "AliITSgeomTGeo.h" \r
-#include "AliGeomManager.h" \r
-#include "AliAlignObjParams.h" \r
-#include "AliLog.h" \r
\r
-/// \cond CLASSIMP \r
-ClassImp(AliITSAlignMilleModule) \r
-/// \endcond \r
-    \r
-//-------------------------------------------------------------\r
-AliITSAlignMilleModule::AliITSAlignMilleModule() : TNamed(), \r
-  fNSensVol(0), \r
-  fIndex(-1),  \r
-  fVolumeID(0),  \r
-  fMatrix(NULL),\r
-  fSensVolMatrix(NULL),\r
-  fSensVolModifMatrix(NULL),\r
-  fTempAlignObj(NULL)\r
-{ \r
-  /// void constructor  \r
-  fMatrix = new TGeoHMatrix; \r
-  fSensVolMatrix = new TGeoHMatrix; \r
-  fSensVolModifMatrix = new TGeoHMatrix; \r
-  fTempAlignObj=new AliAlignObjParams;\r
-} \r
-//-------------------------------------------------------------\r
-AliITSAlignMilleModule::AliITSAlignMilleModule(Int_t index, UShort_t volid, char* symname, TGeoHMatrix *m, Int_t nsv, UShort_t *volidsv) : TNamed(), \r
-  fNSensVol(0), \r
-  fIndex(-1),  \r
-  fVolumeID(0),  \r
-  fMatrix(NULL),\r
-  fSensVolMatrix(NULL),\r
-  fSensVolModifMatrix(NULL),\r
-  fTempAlignObj(NULL)\r
-{ \r
-  /// void constructor  \r
-  fMatrix = new TGeoHMatrix; \r
-  fSensVolMatrix = new TGeoHMatrix; \r
-  fSensVolModifMatrix = new TGeoHMatrix; \r
-  fTempAlignObj=new AliAlignObjParams;\r
-  if (Set(index,volid,symname,m,nsv,volidsv)) {\r
-    AliInfo("Error in AliITSAlignMilleModule::Set() - initializing void supermodule...");\r
-  }\r
-} \r
-//-------------------------------------------------------------\r
-AliITSAlignMilleModule::AliITSAlignMilleModule(UShort_t volid) : TNamed(), \r
-  fNSensVol(0), \r
-  fIndex(-1),  \r
-  fVolumeID(0),  \r
-  fMatrix(NULL),\r
-  fSensVolMatrix(NULL),\r
-  fSensVolModifMatrix(NULL),\r
-  fTempAlignObj(NULL)\r
-{ \r
-  /// simple constructor building a supermodule from a single sensitive volume \r
-  fMatrix = new TGeoHMatrix; \r
-  fSensVolMatrix = new TGeoHMatrix; \r
-  fSensVolModifMatrix = new TGeoHMatrix;   \r
-  // temporary align object, just use the rotation...\r
-  fTempAlignObj=new AliAlignObjParams;\r
-\r
-  fIndex = GetIndexFromVolumeID(volid);  \r
-  if (fIndex>=0 && gGeoManager) { // good sensitive module and geometry loaded\r
-    SetName(AliGeomManager::SymName(volid));\r
-    fVolumeID = volid;\r
-    AddSensitiveVolume(volid);\r
-    if (SensVolMatrix(volid, fMatrix))\r
-       AliInfo("Matrix not defined");\r
-  }\r
-  else {\r
-    AliInfo("Wrong VolumeID or Geometry not loaded - initializing void supermodule...");\r
-  }\r
-} \r
-//-------------------------------------------------------------\r
-AliITSAlignMilleModule::~AliITSAlignMilleModule() { \r
-  /// Destructor \r
-  delete fMatrix; \r
-  delete fSensVolMatrix; \r
-  delete fSensVolModifMatrix; \r
-  delete fTempAlignObj;\r
-} \r
-//-------------------------------------------------------------\r
-Int_t AliITSAlignMilleModule::Set(Int_t index, UShort_t volid, char* symname, TGeoHMatrix *m, Int_t nsv, UShort_t *volidsv) \r
-{\r
-  // initialize a custom supermodule\r
-  // index, volid, symname and matrix must be given\r
-  // if (volidsv) add nsv sensitive volumes to the supermodules\r
-  // return 0 if success\r
-\r
-  if (index<2198) {\r
-    AliInfo("Index must be >= 2198");\r
-    return -1;\r
-  }\r
-  if (volid<14336) {\r
-    AliInfo("VolumeID must be >= 14336");\r
-    return -2;\r
-  }\r
-  \r
-  if (!symname) return -3;\r
-  for (Int_t i=0; i<2198; i++) {\r
-    if (!strcmp(symname,AliITSgeomTGeo::GetSymName(i))) {\r
-      AliInfo("Symname already used by a Sensitive Volume");\r
-      return -3;\r
-    }\r
-  }\r
-  \r
-  if (!m) return -4;\r
-\r
-  // can initialize needed stuffs\r
-  fIndex = index;\r
-  fVolumeID = volid;\r
-  SetName(symname);\r
-  (*fMatrix) = (*m);\r
-\r
-  // add sensitive volumes\r
-  for (Int_t i=0; i<nsv; i++) AddSensitiveVolume(volidsv[i]);\r
-\r
-  return 0;\r
-}\r
-//-------------------------------------------------------------\r
-Int_t AliITSAlignMilleModule::GetIndexFromVolumeID(UShort_t voluid) {\r
-  /// index from volume ID\r
-  AliGeomManager::ELayerID lay = AliGeomManager::VolUIDToLayer(voluid);\r
-  if (lay<1|| lay>6) return -1;\r
-  Int_t idx=Int_t(voluid)-2048*lay;\r
-  if (idx>=AliGeomManager::LayerSize(lay)) return -1;\r
-  for (Int_t ilay=1; ilay<lay; ilay++) \r
-    idx += AliGeomManager::LayerSize(ilay);\r
-  return idx;\r
-}\r
-//-------------------------------------------------------------\r
-void AliITSAlignMilleModule::AddSensitiveVolume(UShort_t voluid)\r
-{\r
-  /// add a sensitive volume to this supermodule\r
-  if (GetIndexFromVolumeID(voluid)<0) return; // bad volid\r
-  fSensVolVolumeID[fNSensVol] = voluid;\r
-  fSensVolIndex[fNSensVol] = GetIndexFromVolumeID(voluid);\r
-  fNSensVol++;\r
-}\r
-//-------------------------------------------------------------\r
-Bool_t AliITSAlignMilleModule::IsIn(UShort_t voluid) \r
-{\r
-  /// check if voluid is defined\r
-  if (!voluid) return kFALSE; // only positive voluid are accepted\r
-  for (Int_t i=0; i<fNSensVol; i++) {\r
-    if (fSensVolVolumeID[i]==voluid) return kTRUE;\r
-  }\r
-  return kFALSE;\r
-}\r
-//-------------------------------------------------------------\r
-TGeoHMatrix *AliITSAlignMilleModule::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, Double_t *deltalocal)\r
-{\r
-  // modify the original TGeoHMatrix of the sensitive module 'voluid' according\r
-  // with a delta transform. applied to the supermodule matrix\r
-  // return NULL if error\r
-\r
-  if (!IsIn(voluid)) return NULL;\r
-  if (!gGeoManager) return NULL;\r
-\r
-  // prepare the TGeoHMatrix\r
-  Double_t tr[3],ang[3];\r
-  tr[0]=deltalocal[0]; // in centimeter\r
-  tr[1]=deltalocal[1]; \r
-  tr[2]=deltalocal[2];\r
-  ang[0]=deltalocal[3]; // psi   (X)  in deg\r
-  ang[1]=deltalocal[4]; // theta (Y)\r
-  ang[2]=deltalocal[5]; // phi   (Z)\r
-\r
-  // reset align object (may not be needed...)\r
-  fTempAlignObj->SetTranslation(0,0,0);\r
-  fTempAlignObj->SetRotation(0,0,0);\r
-\r
-  fTempAlignObj->SetRotation(ang[0],ang[1],ang[2]);\r
-  fTempAlignObj->SetTranslation(tr[0],tr[1],tr[2]);\r
-  AliDebug(3,Form("Delta angles: psi=%f  theta=%f   phi=%f",ang[0],ang[1],ang[2]));\r
-  TGeoHMatrix hm;\r
-  fTempAlignObj->GetMatrix(hm);\r
-  //printf("\n0: delta matrix\n");hm.Print();\r
-\r
-  // 1) start setting fSensVolModif = fSensVol\r
-  if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;\r
-  //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();\r
-\r
-  // 2) set fSensVolModif = SensVolRel\r
-  fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
-  //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();\r
\r
-  // 3) multiply left by delta\r
-  fSensVolModifMatrix->MultiplyLeft( &hm );\r
-  //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();\r
-  \r
-  // 4) multiply left by fMatrix\r
-  fSensVolModifMatrix->MultiplyLeft( fMatrix );\r
-  //printf("\n4: modif=finale\n");fSensVolModifMatrix->Print();\r
-\r
-  return fSensVolModifMatrix;\r
-}\r
-//-------------------------------------------------------------\r
-AliAlignObjParams *AliITSAlignMilleModule::GetSensitiveVolumeMisalignment(UShort_t voluid, Double_t *deltalocal)\r
-{\r
-  // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'\r
-  // of the mother volume. The misalignment is returned as AliAlignObjParams object\r
-\r
-  if (!IsIn(voluid)) return NULL;\r
-  if (!gGeoManager) return NULL;\r
-  \r
-  // prepare the TGeoHMatrix\r
-  Double_t tr[3],ang[3];\r
-  tr[0]=deltalocal[0]; // in centimeter\r
-  tr[1]=deltalocal[1]; \r
-  tr[2]=deltalocal[2];\r
-  ang[0]=deltalocal[3]; // psi   (X)  in deg\r
-  ang[1]=deltalocal[4]; // theta (Y)\r
-  ang[2]=deltalocal[5]; // phi   (Z)\r
-\r
-  // reset align object (may not be needed...)\r
-  fTempAlignObj->SetTranslation(0,0,0);\r
-  fTempAlignObj->SetRotation(0,0,0);\r
-\r
-  fTempAlignObj->SetRotation(ang[0],ang[1],ang[2]);\r
-  fTempAlignObj->SetTranslation(tr[0],tr[1],tr[2]);\r
-  AliDebug(3,Form("Delta angles: psi=%f  theta=%f   phi=%f",ang[0],ang[1],ang[2]));\r
-  \r
-  return GetSensitiveVolumeMisalignment(voluid,fTempAlignObj);\r
-}\r
-//-------------------------------------------------------------\r
-AliAlignObjParams *AliITSAlignMilleModule::GetSensitiveVolumeMisalignment(UShort_t voluid, AliAlignObjParams *a)\r
-{\r
-  // return the misalignment of the sens. vol. 'voluid' corresponding with \r
-  // a misalignment 'a' in the mother volume\r
-  // return NULL if error\r
-\r
-  // Gsv = Gg * Gg-1 * Gsv   -> Lsv,g = Gg-1 * Gsv\r
-  // G'sv = Gg * Dg * Lsv,g === Gsv * Dsv\r
-  // Gg * Dg * Gg-1 * Gsv = Gsv * Gsv-1 * Gg * Dg * Gg-1 * Gsv\r
-  //\r
-  // => Dsv = (Gsv-1 * Gg * Dg * Gg-1 * Gsv)\r
-  //\r
-\r
-  if (!IsIn(voluid)) return NULL;\r
-  if (!gGeoManager) return NULL;\r
-\r
-  //a->Print("");\r
-\r
-  // prepare the Delta matrix Dg\r
-  TGeoHMatrix dg;\r
-  a->GetMatrix(dg);\r
-  //dg.Print();\r
-\r
-  // 1) start setting fSensVolModif = Gsv\r
-  if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;\r
-  //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();\r
-\r
-  // 2) set fSensVolModif = Gg-1 * Gsv\r
-  fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
-  //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();\r
\r
-  // 3) set fSensVolModif = Dg * Gg-1 * Gsv\r
-  fSensVolModifMatrix->MultiplyLeft( &dg );\r
-  //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();\r
-  \r
-  // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv\r
-  fSensVolModifMatrix->MultiplyLeft( fMatrix );\r
-  //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();\r
-\r
-  // 5) set fSensVolModif = Gsv-1 * Gg * Dg * Gg-1 * Gsv\r
-  if (SensVolMatrix(voluid, &dg)) return NULL;\r
-  fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );\r
-  //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();\r
-\r
-  // reset align object (may not be needed...)\r
-  fTempAlignObj->SetTranslation(0,0,0);\r
-  fTempAlignObj->SetRotation(0,0,0);\r
-\r
-  if (!fTempAlignObj->SetMatrix(*fSensVolModifMatrix)) return NULL;\r
-  fTempAlignObj->SetVolUID(voluid);\r
-  fTempAlignObj->SetSymName(AliGeomManager::SymName(voluid));\r
-  \r
-  //fTempAlignObj->Print("");\r
-\r
-  return fTempAlignObj;\r
-}\r
-//-------------------------------------------------------------\r
-TGeoHMatrix *AliITSAlignMilleModule::GetSensitiveVolumeMatrix(UShort_t voluid)\r
-{\r
-  // return TGeoHMatrix of the sens.vol. 'voluid' in the current geometry\r
-  if (SensVolMatrix(voluid,fSensVolMatrix)) return NULL;\r
-  return fSensVolMatrix;\r
-}\r
-//-------------------------------------------------------------\r
-TGeoHMatrix *AliITSAlignMilleModule::GetSensitiveVolumeOrigGlobalMatrix(UShort_t voluid)\r
-{\r
-  // return original ideal position (from AliGeomManager::GetOrigGlobalMatrix())\r
-  if (SensVolOrigGlobalMatrix(voluid,fSensVolMatrix)) return NULL;\r
-  return fSensVolMatrix;\r
-}\r
-//-------------------------------------------------------------\r
-Int_t AliITSAlignMilleModule::SensVolMatrix(UShort_t volid, TGeoHMatrix *m) \r
-{\r
-  // set matrix for sensitive modules (SPD corrected)\r
-  // return 0 if success\r
-  Double_t rot[9];\r
-  Int_t idx=GetIndexFromVolumeID(volid);\r
-  if (idx<0) return -1;\r
-  if (!AliITSgeomTGeo::GetRotation(idx,rot)) return -2;\r
-  m->SetRotation(rot);\r
-  Double_t oLoc[3]={0,0,0};\r
-  Double_t oGlo[3]={0,0,0};\r
-  if (!AliITSgeomTGeo::LocalToGlobal(idx,oLoc,oGlo)) return -3;\r
-  m->SetTranslation(oGlo);\r
-  return 0;\r
-}\r
-//-------------------------------------------------------------\r
-Int_t AliITSAlignMilleModule::SensVolOrigGlobalMatrix(UShort_t volid, TGeoHMatrix *m) \r
-{\r
-  // set original global matrix for sensitive modules (SPD corrected)\r
-  // return 0 if success\r
-  Int_t idx=GetIndexFromVolumeID(volid);\r
-  if (idx<0) return -1;\r
-  TGeoHMatrix mo;\r
-  if (!AliGeomManager::GetOrigGlobalMatrix(AliGeomManager::SymName(volid),mo));\r
-  (*m)=mo;\r
-\r
-  // SPD y-shift by 81 mu\r
-  Double_t oLoc[3]={0.0,0.0081,0.0};\r
-  Double_t oGlo[3]={0,0,0};\r
-  m->LocalToMaster(oLoc,oGlo);\r
-  m->SetTranslation(oGlo);\r
-  return 0;\r
-}\r
-//-------------------------------------------------------------\r
-UShort_t AliITSAlignMilleModule::GetVolumeIDFromSymname(const Char_t *symname) {\r
-  /// volume ID from symname\r
-  if (!symname) return 0;\r
-\r
-  for (UShort_t voluid=2000; voluid<13300; voluid++) {\r
-    Int_t modId;\r
-    AliGeomManager::ELayerID layerId = AliGeomManager::VolUIDToLayer(voluid,modId);\r
-    if (layerId>0 && layerId<7 && modId>=0 && modId<AliGeomManager::LayerSize(layerId)) {\r
-      if (!strcmp(symname,AliGeomManager::SymName(layerId,modId))) return voluid;\r
-    }\r
-  }\r
-\r
-  return 0;\r
-}\r
-\r
-UShort_t AliITSAlignMilleModule::GetVolumeIDFromIndex(Int_t index) {\r
-  /// volume ID from index\r
-  if (index<0 || index>2197) return 0;\r
-  return GetVolumeIDFromSymname(AliITSgeomTGeo::GetSymName(index));\r
-}\r
-//-------------------------------------------------------------\r
-void AliITSAlignMilleModule::Print(Option_t*) const \r
-{\r
-  ///\r
-  printf("*** ITS SuperModule for AliITSAlignMille ***\n");\r
-  printf("symname  : %s\n",GetName());\r
-  printf("volumeID : %d\n",fVolumeID);\r
-  printf("index    : %d\n",fIndex);\r
-  fMatrix->Print();\r
-  printf("number of sensitive modules : %d\n",fNSensVol);\r
-  for (Int_t i=0; i<fNSensVol; i++) printf("   voluid[%d] = %d\n",i,fSensVolVolumeID[i]);\r
-}\r
-//_____________________________________________________________________________\r
-AliITSAlignMilleModule::AliITSAlignMilleModule(const AliITSAlignMilleModule &m) :\r
-  TNamed(m),\r
-  fNSensVol(m.fNSensVol),\r
-  fIndex(m.fIndex),\r
-  fVolumeID(m.fVolumeID),\r
-  fMatrix(new TGeoHMatrix(*m.GetMatrix())),\r
-  fSensVolMatrix(new TGeoHMatrix),\r
-  fSensVolModifMatrix(new TGeoHMatrix),\r
-  fTempAlignObj(new AliAlignObjParams)\r
-{\r
-  // Copy constructor\r
-  for (int i=0; i<fNSensVol; i++) {\r
-    fSensVolIndex[i]=m.fSensVolIndex[i];\r
-    fSensVolVolumeID[i]=m.fSensVolVolumeID[i];\r
-  }\r
-}\r
-//_____________________________________________________________________________\r
-AliITSAlignMilleModule& AliITSAlignMilleModule::operator=(const AliITSAlignMilleModule &m)  \r
-{\r
-  // operator =\r
-  //\r
-  if(this==&m) return *this;\r
-  ((TNamed *)this)->operator=(m);\r
-  \r
-  fNSensVol=m.fNSensVol;\r
-  fIndex=m.fIndex;\r
-  fVolumeID=m.fVolumeID;\r
-  delete fMatrix;\r
-  fMatrix=new TGeoHMatrix(*m.GetMatrix());\r
-  for (int i=0; i<fNSensVol; i++) {\r
-    fSensVolIndex[i]=m.fSensVolIndex[i];\r
-    fSensVolVolumeID[i]=m.fSensVolVolumeID[i];\r
-  }\r
-  return *this;\r
-}\r
-\r
-//_____________________________________________________________________________\r
-\r
-\r
+/************************************************************************** 
+ * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. * 
+ *                                                                        * 
+ * Author: The ALICE Off-line Project.                                    * 
+ * Contributors are mentioned in the code where appropriate.              * 
+ *                                                                        * 
+ * Permission to use, copy, modify and distribute this software and its   * 
+ * documentation strictly for non-commercial purposes is hereby granted   * 
+ * without fee, provided that the above copyright notice appears in all   * 
+ * copies and that both the copyright notice and this permission notice   * 
+ * appear in the supporting documentation. The authors make no claims     * 
+ * about the suitability of this software for any purpose. It is          * 
+ * provided "as is" without express or implied warranty.                  * 
+ **************************************************************************/ 
+/* $Id$    */ 
+//----------------------------------------------------------------------------- 
+/// \class AliITSAlignMilleModule
+/// Alignment class for the ALICE ITS detector 
+/// 
+/// This class is used by AliITSAlignMille to build custom supermodules    
+/// made of ITS sensitive modules. These supermodules are then aligned
+/// 
+/// Custom supermodules must have VolumeID > 14335
+///
+/// \author M. Lunardon  
+//----------------------------------------------------------------------------- 
+#include <TGeoManager.h> 
+//#include <TGeoMatrix.h> 
+#include "AliITSAlignMilleModule.h" 
+#include "AliITSgeomTGeo.h" 
+#include "AliGeomManager.h" 
+#include "AliAlignObjParams.h" 
+#include "AliLog.h" 
+/// \cond CLASSIMP 
+ClassImp(AliITSAlignMilleModule) 
+/// \endcond 
+    
+//-------------------------------------------------------------
+AliITSAlignMilleModule::AliITSAlignMilleModule() : TNamed(), 
+  fNSensVol(0), 
+  fIndex(-1),  
+  fVolumeID(0),  
+  fMatrix(NULL),
+  fSensVolMatrix(NULL),
+  fSensVolModifMatrix(NULL),
+  fTempAlignObj(NULL)
+{ 
+  /// void constructor  
+  fMatrix = new TGeoHMatrix; 
+  fSensVolMatrix = new TGeoHMatrix; 
+  fSensVolModifMatrix = new TGeoHMatrix; 
+  fTempAlignObj=new AliAlignObjParams;
+  for(Int_t k=0; k<fgkSensModules; k++){
+    fSensVolIndex[k] = 0;
+    fSensVolVolumeID[k] = 0;
+  }
+} 
+//-------------------------------------------------------------
+AliITSAlignMilleModule::AliITSAlignMilleModule(Int_t index, UShort_t volid, char* symname, const TGeoHMatrix *m, Int_t nsv, const UShort_t *volidsv) : TNamed(), 
+  fNSensVol(0), 
+  fIndex(-1),  
+  fVolumeID(0),  
+  fMatrix(NULL),
+  fSensVolMatrix(NULL),
+  fSensVolModifMatrix(NULL),
+  fTempAlignObj(NULL)
+{ 
+  /// void constructor  
+  fMatrix = new TGeoHMatrix; 
+  fSensVolMatrix = new TGeoHMatrix; 
+  fSensVolModifMatrix = new TGeoHMatrix; 
+  fTempAlignObj=new AliAlignObjParams;
+  if (Set(index,volid,symname,m,nsv,volidsv)) {
+    AliInfo("Error in AliITSAlignMilleModule::Set() - initializing void supermodule...");
+
+  }
+  for(Int_t k=0; k<fgkSensModules; k++){
+    fSensVolIndex[k] = 0;
+    fSensVolVolumeID[k] = 0;
+  }
+}
+//-------------------------------------------------------------
+AliITSAlignMilleModule::AliITSAlignMilleModule(UShort_t volid) : TNamed(), 
+  fNSensVol(0), 
+  fIndex(-1),  
+  fVolumeID(0),  
+  fMatrix(NULL),
+  fSensVolMatrix(NULL),
+  fSensVolModifMatrix(NULL),
+  fTempAlignObj(NULL)
+{ 
+  /// simple constructor building a supermodule from a single sensitive volume 
+  fMatrix = new TGeoHMatrix; 
+  fSensVolMatrix = new TGeoHMatrix; 
+  fSensVolModifMatrix = new TGeoHMatrix;   
+  // temporary align object, just use the rotation...
+  fTempAlignObj=new AliAlignObjParams;
+
+  fIndex = GetIndexFromVolumeID(volid);  
+  if (fIndex>=0 && gGeoManager) { // good sensitive module and geometry loaded
+    SetName(AliGeomManager::SymName(volid));
+    fVolumeID = volid;
+    AddSensitiveVolume(volid);
+    if (SensVolMatrix(volid, fMatrix))
+       AliInfo("Matrix not defined");
+  }
+  else {
+    AliInfo("Wrong VolumeID or Geometry not loaded - initializing void supermodule...");
+  for(Int_t k=0; k<fgkSensModules; k++){
+    fSensVolIndex[k] = 0;
+    fSensVolVolumeID[k] = 0;
+  }
+  }
+} 
+//-------------------------------------------------------------
+AliITSAlignMilleModule::~AliITSAlignMilleModule() { 
+  /// Destructor 
+  delete fMatrix; 
+  delete fSensVolMatrix; 
+  delete fSensVolModifMatrix; 
+  delete fTempAlignObj;
+} 
+//-------------------------------------------------------------
+Int_t AliITSAlignMilleModule::Set(Int_t index, UShort_t volid, char* symname, const TGeoHMatrix * const m, Int_t nsv, const UShort_t *volidsv) 
+{
+  // initialize a custom supermodule
+  // index, volid, symname and matrix must be given
+  // if (volidsv) add nsv sensitive volumes to the supermodules
+  // return 0 if success
+
+  if (index<2198) {
+    AliInfo("Index must be >= 2198");
+    return -1;
+  }
+  if (volid<14336) {
+    AliInfo("VolumeID must be >= 14336");
+    return -2;
+  }
+  
+  if (!symname) return -3;
+  for (Int_t i=0; i<2198; i++) {
+    if (!strcmp(symname,AliITSgeomTGeo::GetSymName(i))) {
+      AliInfo("Symname already used by a Sensitive Volume");
+      return -3;
+    }
+  }
+  
+  if (!m) return -4;
+
+  // can initialize needed stuffs
+  fIndex = index;
+  fVolumeID = volid;
+  SetName(symname);
+  (*fMatrix) = (*m);
+
+  // add sensitive volumes
+  for (Int_t i=0; i<nsv; i++) AddSensitiveVolume(volidsv[i]);
+
+  return 0;
+}
+//-------------------------------------------------------------
+Int_t AliITSAlignMilleModule::GetIndexFromVolumeID(UShort_t voluid) {
+  /// index from volume ID
+  AliGeomManager::ELayerID lay = AliGeomManager::VolUIDToLayer(voluid);
+  if (lay<1|| lay>6) return -1;
+  Int_t idx=Int_t(voluid)-2048*lay;
+  if (idx>=AliGeomManager::LayerSize(lay)) return -1;
+  for (Int_t ilay=1; ilay<lay; ilay++) 
+    idx += AliGeomManager::LayerSize(ilay);
+  return idx;
+}
+//-------------------------------------------------------------
+void AliITSAlignMilleModule::AddSensitiveVolume(UShort_t voluid)
+{
+  /// add a sensitive volume to this supermodule
+  if (GetIndexFromVolumeID(voluid)<0) return; // bad volid
+  fSensVolVolumeID[fNSensVol] = voluid;
+  fSensVolIndex[fNSensVol] = GetIndexFromVolumeID(voluid);
+  fNSensVol++;
+}
+//-------------------------------------------------------------
+Bool_t AliITSAlignMilleModule::IsIn(UShort_t voluid) const 
+{
+  /// check if voluid is defined
+  if (!voluid) return kFALSE; // only positive voluid are accepted
+  for (Int_t i=0; i<fNSensVol; i++) {
+    if (fSensVolVolumeID[i]==voluid) return kTRUE;
+  }
+  return kFALSE;
+}
+//-------------------------------------------------------------
+TGeoHMatrix *AliITSAlignMilleModule::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, const Double_t * const deltalocal)
+{
+  // modify the original TGeoHMatrix of the sensitive module 'voluid' according
+  // with a delta transform. applied to the supermodule matrix
+  // return NULL if error
+
+  if (!IsIn(voluid)) return NULL;
+  if (!gGeoManager) return NULL;
+
+  // prepare the TGeoHMatrix
+  Double_t tr[3],ang[3];
+  tr[0]=deltalocal[0]; // in centimeter
+  tr[1]=deltalocal[1]; 
+  tr[2]=deltalocal[2];
+  ang[0]=deltalocal[3]; // psi   (X)  in deg
+  ang[1]=deltalocal[4]; // theta (Y)
+  ang[2]=deltalocal[5]; // phi   (Z)
+
+  // reset align object (may not be needed...)
+  fTempAlignObj->SetVolUID(0);
+  fTempAlignObj->SetSymName("");
+  fTempAlignObj->SetRotation(ang[0],ang[1],ang[2]);
+  fTempAlignObj->SetTranslation(tr[0],tr[1],tr[2]);
+  AliDebug(3,Form("Delta angles: psi=%f  theta=%f   phi=%f",ang[0],ang[1],ang[2]));
+  TGeoHMatrix hm;
+  fTempAlignObj->GetMatrix(hm);
+  //printf("\n0: delta matrix\n");hm.Print();
+
+  // 1) start setting fSensVolModif = fSensVol
+  if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
+  //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
+
+  // 2) set fSensVolModif = SensVolRel
+  fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
+  //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
+  // 3) multiply left by delta
+  fSensVolModifMatrix->MultiplyLeft( &hm );
+  //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
+  
+  // 4) multiply left by fMatrix
+  fSensVolModifMatrix->MultiplyLeft( fMatrix );
+  //printf("\n4: modif=finale\n");fSensVolModifMatrix->Print();
+
+  return fSensVolModifMatrix;
+}
+//-------------------------------------------------------------
+AliAlignObjParams *AliITSAlignMilleModule::GetSensitiveVolumeMisalignment(UShort_t voluid, const Double_t * const deltalocal)
+{
+  // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
+  // of the mother volume. The misalignment is returned as AliAlignObjParams object
+
+  if (!IsIn(voluid)) return NULL;
+  if (!gGeoManager) return NULL;
+  
+  // prepare the TGeoHMatrix
+  Double_t tr[3],ang[3];
+  tr[0]=deltalocal[0]; // in centimeter
+  tr[1]=deltalocal[1]; 
+  tr[2]=deltalocal[2];
+  ang[0]=deltalocal[3]; // psi   (X)  in deg
+  ang[1]=deltalocal[4]; // theta (Y)
+  ang[2]=deltalocal[5]; // phi   (Z)
+
+  // reset align object (may not be needed...)
+  fTempAlignObj->SetVolUID(0);
+  fTempAlignObj->SetSymName("");
+  fTempAlignObj->SetRotation(ang[0],ang[1],ang[2]);
+  fTempAlignObj->SetTranslation(tr[0],tr[1],tr[2]);
+  AliDebug(3,Form("Delta angles: psi=%f  theta=%f   phi=%f",ang[0],ang[1],ang[2]));
+  
+  return GetSensitiveVolumeMisalignment(voluid,fTempAlignObj);
+}
+//-------------------------------------------------------------
+AliAlignObjParams *AliITSAlignMilleModule::GetSensitiveVolumeMisalignment(UShort_t voluid, const AliAlignObjParams *a)
+{
+  // return the misalignment of the sens. vol. 'voluid' corresponding with 
+  // a misalignment 'a' in the mother volume
+  // return NULL if error
+
+  // Gsv = Gg * Gg-1 * Gsv   -> Lsv,g = Gg-1 * Gsv
+  // G'sv = Gg * Dg * Lsv,g === Gsv * Dsv
+  // Gg * Dg * Gg-1 * Gsv = Gsv * Gsv-1 * Gg * Dg * Gg-1 * Gsv
+  //
+  // => Dsv = (Gsv-1 * Gg * Dg * Gg-1 * Gsv)
+  //
+
+  if (!IsIn(voluid)) return NULL;
+  if (!gGeoManager) return NULL;
+
+  //a->Print("");
+
+  // prepare the Delta matrix Dg
+  TGeoHMatrix dg;
+  a->GetMatrix(dg);
+  //dg.Print();
+
+  // 1) start setting fSensVolModif = Gsv
+  if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
+  //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
+
+  // 2) set fSensVolModif = Gg-1 * Gsv
+  fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
+  //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
+  // 3) set fSensVolModif = Dg * Gg-1 * Gsv
+  fSensVolModifMatrix->MultiplyLeft( &dg );
+  //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
+  
+  // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv
+  fSensVolModifMatrix->MultiplyLeft( fMatrix );
+  //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();
+
+  // 5) set fSensVolModif = Gsv-1 * Gg * Dg * Gg-1 * Gsv
+  if (SensVolMatrix(voluid, &dg)) return NULL;
+  fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );
+  //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();
+
+  // 6) mo' fSensVolModif dovrebbe essere la Dsv(loc) t.c. G'sv = Gsv*Dsv(loc)
+  // per trasformarla in Dsv(loc rispetto al Gsv0, non modificato) dovrebbe essere:
+  // Dsv(loc) -> Dpre * Dsv(loc) * Dpre-1
+  //TGeoHMatrix dpre; // dpre = Gsv0-1*Gsv
+  //if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;
+  //if (SensVolMatrix(voluid, &dpre)) return NULL;
+  //dpre.MultiplyLeft( &dg.Inverse() );
+  //fSensVolModifMatrix->Multiply( &dpre.Inverse() );
+  //fSensVolModifMatrix->MultiplyLeft( &dpre );
+  // direi che NON FUNZIONA!!!!
+
+  // reset align object (may not be needed...)
+  fTempAlignObj->SetVolUID(0);
+  fTempAlignObj->SetSymName("");
+  fTempAlignObj->SetTranslation(0,0,0);
+  fTempAlignObj->SetRotation(0,0,0);
+
+  // correction for SPD y-shift
+  if (voluid>=2048 && voluid<4256) {
+    TGeoHMatrix deltay;
+    double dy[3]={0.,0.0081,0.};
+    deltay.SetTranslation(dy);
+    fSensVolModifMatrix->MultiplyLeft( &deltay );
+    fSensVolModifMatrix->Multiply( &deltay.Inverse() );
+  }
+  
+  if (!fTempAlignObj->SetMatrix(*fSensVolModifMatrix)) return NULL;
+  fTempAlignObj->SetVolUID(voluid);
+  fTempAlignObj->SetSymName(AliGeomManager::SymName(voluid));
+  
+  //fTempAlignObj->Print("");
+
+  return fTempAlignObj;
+}
+//-------------------------------------------------------------
+
+
+//-------------------------------------------------------------
+AliAlignObjParams *AliITSAlignMilleModule::GetSensitiveVolumeTotalMisalignment(UShort_t voluid, const Double_t * const deltalocal)
+{
+  // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
+  // of the mother volume. The misalignment is returned as AliAlignObjParams object including
+  // the (evenctual) prealignment => no merging needed
+
+  if (!IsIn(voluid)) return NULL;
+  if (!gGeoManager) return NULL;
+  
+  // prepare the TGeoHMatrix
+  Double_t tr[3],ang[3];
+  tr[0]=deltalocal[0]; // in centimeter
+  tr[1]=deltalocal[1]; 
+  tr[2]=deltalocal[2];
+  ang[0]=deltalocal[3]; // psi   (X)  in deg
+  ang[1]=deltalocal[4]; // theta (Y)
+  ang[2]=deltalocal[5]; // phi   (Z)
+
+  // reset align object (may not be needed...)
+  fTempAlignObj->SetVolUID(0);
+  fTempAlignObj->SetSymName("");
+  fTempAlignObj->SetRotation(ang[0],ang[1],ang[2]);
+  fTempAlignObj->SetTranslation(tr[0],tr[1],tr[2]);
+  AliDebug(3,Form("Delta angles: psi=%f  theta=%f   phi=%f",ang[0],ang[1],ang[2]));
+
+  // Gsv = Gg * Gg-1 * Gsv   -> Lsv,g = Gg-1 * Gsv
+  // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv 
+  //
+  // => Dsv = (G0sv-1 * Gg * Dg * Gg-1 * GMsv)  //
+  //
+
+  // prepare the Delta matrix Dg
+  TGeoHMatrix dg;
+  fTempAlignObj->GetMatrix(dg);
+  //dg.Print();
+
+  // 1) start setting fSensVolModif = Gsv
+  if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
+  //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
+
+  // 2) set fSensVolModif = Gg-1 * Gsv
+  fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
+  //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
+  // 3) set fSensVolModif = Dg * Gg-1 * Gsv
+  fSensVolModifMatrix->MultiplyLeft( &dg );
+  //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
+  
+  // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv
+  fSensVolModifMatrix->MultiplyLeft( fMatrix );
+  //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();
+
+  // 5) set fSensVolModif = G0sv-1 * Gg * Dg * Gg-1 * Gsv
+  // qui usa l'orig anziche' la prealigned...
+  if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;
+  fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );
+  //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();
+
+  // reset align object (may not be needed...)
+  fTempAlignObj->SetVolUID(0);
+  fTempAlignObj->SetSymName("");
+  fTempAlignObj->SetTranslation(0,0,0);
+  fTempAlignObj->SetRotation(0,0,0);
+
+  // correction for SPD y-shift
+  if (voluid>=2048 && voluid<4256) {
+    TGeoHMatrix deltay;
+    double dy[3]={0.,0.0081,0.};
+    deltay.SetTranslation(dy);
+    fSensVolModifMatrix->MultiplyLeft( &deltay );
+    fSensVolModifMatrix->Multiply( &deltay.Inverse() );
+  }
+  if (!fTempAlignObj->SetMatrix(*fSensVolModifMatrix)) return NULL;
+  fTempAlignObj->SetVolUID(voluid);
+  fTempAlignObj->SetSymName(AliGeomManager::SymName(voluid));
+
+  
+  //fTempAlignObj->Print("");
+
+  return fTempAlignObj;
+}
+//-------------------------------------------------------------
+
+// //-------------------------------------------------------------
+// AliAlignObjParams *AliITSAlignMilleModule::GetSensitiveVolumeTotalMisalignment(UShort_t voluid, Double_t *deltalocal)
+// {
+//   // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
+//   // of the mother volume. The misalignment is returned as AliAlignObjParams object including
+//   // the (evenctual) prealignment => no merging needed
+
+//   if (!IsIn(voluid)) return NULL;
+//   if (!gGeoManager) return NULL;
+  
+//   // prepare the TGeoHMatrix
+//   Double_t tr[3],ang[3];
+//   tr[0]=deltalocal[0]; // in centimeter
+//   tr[1]=deltalocal[1]; 
+//   tr[2]=deltalocal[2];
+//   ang[0]=deltalocal[3]; // psi   (X)  in deg
+//   ang[1]=deltalocal[4]; // theta (Y)
+//   ang[2]=deltalocal[5]; // phi   (Z)
+
+//   // reset align object (may not be needed...)
+//   fTempAlignObj->SetVolUID(0);
+//   fTempAlignObj->SetSymName("");
+//   fTempAlignObj->SetRotation(ang[0],ang[1],ang[2]);
+//   fTempAlignObj->SetTranslation(tr[0],tr[1],tr[2]);
+//   AliDebug(3,Form("Delta angles: psi=%f  theta=%f   phi=%f",ang[0],ang[1],ang[2]));
+
+//   // Gsv = Gg * Gg-1 * Gsv   -> Lsv,g = Gg-1 * Gsv
+//   // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv 
+//   //
+//   // => Dsv = (G0sv-1 * Gg * Dg * Gg-1 * GMsv)  //
+//   //
+
+//   // prepare the Delta matrix Dg
+//   TGeoHMatrix dg;
+//   fTempAlignObj->GetMatrix(dg);
+//   //dg.Print();
+
+//   // 1) start setting fSensVolModif = Gsv
+//   if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
+//   //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
+
+//   // 2) set dg = Gg * Dg * Gg-1 
+//   dg.Multiply( &fMatrix->Inverse() );
+//   dg.MultiplyLeft( fMatrix );
+//   // 3) set dg = Gsv-1 * dg * Gsv locale nel sistema del SV preallineato
+//   dg.Multiply( fSensVolModifMatrix );
+//   dg.MultiplyLeft( &fSensVolModifMatrix->Inverse() );
+
+//   // calcola la deltaPre
+//   TGeoHMatrix hp;
+//   if (SensVolOrigGlobalMatrix(voluid, &hp)) return NULL;
+//   fSensVolModifMatrix->MultiplyLeft( &hp.Inverse() );
+
+//   // mo' fSensVolModifMatrix e' la deltapre ideale
+//   // col dg diventa la deltatot ideale
+//   fSensVolModifMatrix->Multiply( &dg );
+//   //fSensVolModifMatrix->MultiplyLeft( &dg );
+  
+//   // reset align object (may not be needed...)
+//   fTempAlignObj->SetVolUID(0);
+//   fTempAlignObj->SetSymName("");
+//   fTempAlignObj->SetTranslation(0,0,0);
+//   fTempAlignObj->SetRotation(0,0,0);
+
+//   // correction for SPD y-shift
+//   if (voluid>=2048 && voluid<4256) {
+//     TGeoHMatrix deltay;
+//     double dy[3]={0.,0.0081,0.};
+//     deltay.SetTranslation(dy);
+//     fSensVolModifMatrix->MultiplyLeft( &deltay );
+//     fSensVolModifMatrix->Multiply( &deltay.Inverse() );
+//   }
+//   if (!fTempAlignObj->SetMatrix(*fSensVolModifMatrix)) return NULL;
+//   fTempAlignObj->SetVolUID(voluid);
+//   fTempAlignObj->SetSymName(AliGeomManager::SymName(voluid));
+
+  
+//   //fTempAlignObj->Print("");
+
+//   return fTempAlignObj;
+// }
+// //-------------------------------------------------------------
+
+
+//-------------------------------------------------------------
+AliAlignObjParams *AliITSAlignMilleModule::GetSensitiveVolumeGlobalMisalignment(UShort_t voluid, const Double_t * const deltalocal)
+{
+  // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
+  // of the mother volume. The misalignment is returned as AliAlignObjParams object
+
+  if (!IsIn(voluid)) return NULL;
+  if (!gGeoManager) return NULL;
+  
+  // prepare the TGeoHMatrix
+  Double_t tr[3],ang[3];
+  tr[0]=deltalocal[0]; // in centimeter
+  tr[1]=deltalocal[1]; 
+  tr[2]=deltalocal[2];
+  ang[0]=deltalocal[3]; // psi   (X)  in deg
+  ang[1]=deltalocal[4]; // theta (Y)
+  ang[2]=deltalocal[5]; // phi   (Z)
+
+  // reset align object (may not be needed...)
+  fTempAlignObj->SetTranslation(0,0,0);
+  fTempAlignObj->SetRotation(0,0,0);
+
+  fTempAlignObj->SetRotation(ang[0],ang[1],ang[2]);
+  fTempAlignObj->SetTranslation(tr[0],tr[1],tr[2]);
+  AliDebug(3,Form("Delta angles: psi=%f  theta=%f   phi=%f",ang[0],ang[1],ang[2]));
+
+  // Gsv = Gg * Gg-1 * Gsv   -> Lsv,g = Gg-1 * Gsv
+  // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv 
+  //
+  // => DGsv = (Gg * Dg * Gg-1)
+  //
+
+  // prepare the Delta matrix Dg
+  TGeoHMatrix dg;
+  fTempAlignObj->GetMatrix(dg);
+  //dg.Print();
+
+  dg.MultiplyLeft( fMatrix );
+  dg.Multiply( &fMatrix->Inverse() );
+
+  // reset align object (may not be needed...)
+  fTempAlignObj->SetTranslation(0,0,0);
+  fTempAlignObj->SetRotation(0,0,0);
+
+  fTempAlignObj->SetVolUID(voluid);
+  fTempAlignObj->SetSymName(AliGeomManager::SymName(voluid));
+
+  if (!fTempAlignObj->SetMatrix(dg)) return NULL;
+  
+  //fTempAlignObj->Print("");
+
+  return fTempAlignObj;
+}
+//-------------------------------------------------------------
+
+TGeoHMatrix *AliITSAlignMilleModule::GetSensitiveVolumeMatrix(UShort_t voluid)
+{
+  // return TGeoHMatrix of the sens.vol. 'voluid' in the current geometry
+  if (SensVolMatrix(voluid,fSensVolMatrix)) return NULL;
+  return fSensVolMatrix;
+}
+//-------------------------------------------------------------
+TGeoHMatrix *AliITSAlignMilleModule::GetSensitiveVolumeOrigGlobalMatrix(UShort_t voluid)
+{
+  // return original ideal position (from AliGeomManager::GetOrigGlobalMatrix())
+  if (SensVolOrigGlobalMatrix(voluid,fSensVolMatrix)) return NULL;
+  return fSensVolMatrix;
+}
+//-------------------------------------------------------------
+Int_t AliITSAlignMilleModule::SensVolMatrix(UShort_t volid, TGeoHMatrix *m) 
+{
+  // set matrix for sensitive modules (SPD corrected)
+  // return 0 if success
+  Double_t rot[9];
+  Int_t idx=GetIndexFromVolumeID(volid);
+  if (idx<0) return -1;
+  if (!AliITSgeomTGeo::GetRotation(idx,rot)) return -2;
+  m->SetRotation(rot);
+  Double_t oLoc[3]={0,0,0};
+  Double_t oGlo[3]={0,0,0};
+  if (!AliITSgeomTGeo::LocalToGlobal(idx,oLoc,oGlo)) return -3;
+  m->SetTranslation(oGlo);
+  return 0;
+}
+//-------------------------------------------------------------
+Int_t AliITSAlignMilleModule::SensVolOrigGlobalMatrix(UShort_t volid, TGeoHMatrix *m) 
+{
+  // set original global matrix for sensitive modules (SPD corrected)
+  // return 0 if success
+  Int_t idx=GetIndexFromVolumeID(volid);
+  if (idx<0) return -1;
+  TGeoHMatrix mo;
+  if (!AliGeomManager::GetOrigGlobalMatrix(AliGeomManager::SymName(volid),mo)) return -1;
+
+  (*m)=mo;
+
+  // SPD y-shift by 81 mu
+  if (volid<5000) { 
+    Double_t oLoc[3]={0.0,0.0081,0.0};
+    Double_t oGlo[3]={0,0,0};
+    m->LocalToMaster(oLoc,oGlo);
+    m->SetTranslation(oGlo);
+  }
+  return 0;
+}
+//-------------------------------------------------------------
+UShort_t AliITSAlignMilleModule::GetVolumeIDFromSymname(const Char_t *symname) {
+  /// volume ID from symname
+  if (!symname) return 0;
+
+  for (UShort_t voluid=2000; voluid<13300; voluid++) {
+    Int_t modId;
+    AliGeomManager::ELayerID layerId = AliGeomManager::VolUIDToLayer(voluid,modId);
+    if (layerId>0 && layerId<7 && modId>=0 && modId<AliGeomManager::LayerSize(layerId)) {
+      if (!strcmp(symname,AliGeomManager::SymName(layerId,modId))) return voluid;
+    }
+  }
+
+  return 0;
+}
+
+UShort_t AliITSAlignMilleModule::GetVolumeIDFromIndex(Int_t index) {
+  /// volume ID from index
+  if (index<0 || index>2197) return 0;
+  return GetVolumeIDFromSymname(AliITSgeomTGeo::GetSymName(index));
+}
+//-------------------------------------------------------------
+void AliITSAlignMilleModule::Print(Option_t*) const 
+{
+  ///
+  printf("*** ITS SuperModule for AliITSAlignMille ***\n");
+  printf("symname  : %s\n",GetName());
+  printf("volumeID : %d\n",fVolumeID);
+  printf("index    : %d\n",fIndex);
+  fMatrix->Print();
+  printf("number of sensitive modules : %d\n",fNSensVol);
+  for (Int_t i=0; i<fNSensVol; i++) printf("   voluid[%d] = %d\n",i,fSensVolVolumeID[i]);
+}
+//_____________________________________________________________________________
+AliITSAlignMilleModule::AliITSAlignMilleModule(const AliITSAlignMilleModule &m) :
+  TNamed(m),
+  fNSensVol(m.fNSensVol),
+  fIndex(m.fIndex),
+  fVolumeID(m.fVolumeID),
+  fMatrix(new TGeoHMatrix(*m.GetMatrix())),
+  fSensVolMatrix(new TGeoHMatrix),
+  fSensVolModifMatrix(new TGeoHMatrix),
+  fTempAlignObj(new AliAlignObjParams)
+{
+  // Copy constructor
+  for(Int_t k=0; k<fgkSensModules; k++){
+    fSensVolIndex[k] = 0;
+    fSensVolVolumeID[k] = 0;
+  }
+  for (int i=0; i<fNSensVol; i++) {
+    fSensVolIndex[i]=m.fSensVolIndex[i];
+    fSensVolVolumeID[i]=m.fSensVolVolumeID[i];
+  }
+}
+//_____________________________________________________________________________
+AliITSAlignMilleModule& AliITSAlignMilleModule::operator=(const AliITSAlignMilleModule &m)  
+{
+  // operator =
+  //
+  if(this==&m) return *this;
+  ((TNamed *)this)->operator=(m);
+  
+  fNSensVol=m.fNSensVol;
+  fIndex=m.fIndex;
+  fVolumeID=m.fVolumeID;
+  delete fMatrix;
+  fMatrix=new TGeoHMatrix(*m.GetMatrix());
+  for (int i=0; i<fNSensVol; i++) {
+    fSensVolIndex[i]=m.fSensVolIndex[i];
+    fSensVolVolumeID[i]=m.fSensVolVolumeID[i];
+  }
+  return *this;
+}
+
+//_____________________________________________________________________________
+
+