]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Update for hierarchcal alignment (M. Lunardon)
authormasera <masera@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 9 Apr 2008 20:50:08 +0000 (20:50 +0000)
committermasera <masera@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 9 Apr 2008 20:50:08 +0000 (20:50 +0000)
ITS/AliITSAlignMille.cxx
ITS/AliITSAlignMille.h
ITS/AliITSAlignMilleModule.cxx [new file with mode: 0644]
ITS/AliITSAlignMilleModule.h [new file with mode: 0644]
ITS/ITSrecLinkDef.h
ITS/libITSrec.pkg

index 88c8cac0c632ede7559477ef4c7b16a6fb554b9e..18ec77473d2ac81700bd0c6a8fa7336b60113bf2 100644 (file)
 //-----------------------------------------------------------------------------
 
 #include <TF1.h>
+#include <TFile.h>
+#include <TClonesArray.h>
 #include <TGraph.h>
 #include <TGeoMatrix.h>
 #include <TMath.h>
+#include <TGraphErrors.h>
 
+#include "AliITSAlignMilleModule.h"
 #include "AliITSAlignMille.h"
 #include "AliITSgeomTGeo.h"
 #include "AliGeomManager.h"
@@ -63,26 +67,31 @@ AliITSAlignMille::AliITSAlignMille(const Char_t *configFilename, Bool_t initmill
     fTrack(NULL),
     fCluster(),
     fGlobalDerivatives(NULL),
-    fTempHMat(NULL),
     fTempAlignObj(NULL),
     fDerivativeXLoc(0),
     fDerivativeZLoc(0),
     fDeltaPar(0),
     fMinNPtsPerTrack(3),
+    fInitTrackParamsMeth(1),
     fGeometryFileName("geometry.root"),
+    fPreAlignmentFileName(""),
     fGeoManager(0),
     fCurrentModuleIndex(0),
     fCurrentModuleInternalIndex(0),
+    fCurrentSensVolIndex(0),
     fNModules(0),
     fUseLocalShifts(kTRUE),
+    fUseSuperModules(kFALSE),
+    fUsePreAlignment(kFALSE),
+    fNSuperModules(0),
     fCurrentModuleHMatrix(NULL)
 {
   /// main constructor that takes input from configuration file
   
   fMillepede = new AliMillepede();
   fGlobalDerivatives = new Double_t[fNGlobal];
-  fTempHMat = new TGeoHMatrix;
-  fCurrentModuleHMatrix = new TGeoHMatrix;
+  //fTempHMat = new TGeoHMatrix;
+  //fCurrentModuleHMatrix = new TGeoHMatrix;
   
   Int_t lc=LoadConfig(configFilename);
   if (lc) {
@@ -108,8 +117,10 @@ AliITSAlignMille::~AliITSAlignMille() {
   /// Destructor
   if (fMillepede) delete fMillepede;
   delete [] fGlobalDerivatives;
-  delete fCurrentModuleHMatrix;
-  delete fTempHMat;
+  //delete fCurrentModuleHMatrix;
+  //delete fTempHMat;
+  for (int i=0; i<fNModules; i++) delete fMilleModule[i];
+  for (int i=0; i<fNSuperModules; i++) delete fSuperModule[i];
 }
 
 ///////////////////////////////////////////////////////////////////////
@@ -145,6 +156,29 @@ Int_t AliITSAlignMille::LoadConfig(const Char_t *cfile) {
       InitGeometry();
     }
 
+    if (strstr(st,"PREALIGNMENT_FILE")) {
+      sscanf(st,"%s %s",tmp,st2);
+      if (gSystem->AccessPathName(st2)) {
+       AliInfo("*** WARNING! *** prealignment file not found! ");
+       return -1;
+      }  
+      fPreAlignmentFileName=st2;
+      itx=ApplyToGeometry();
+      if (itx) {
+       AliInfo(Form("*** WARNING! *** error %d reading prealignment file! ",itx));
+       return -6;
+      }
+    }
+
+    if (strstr(st,"SUPERMODULE_FILE")) {
+      sscanf(st,"%s %s",tmp,st2);
+      if (gSystem->AccessPathName(st2)) {
+       AliInfo("*** WARNING! *** supermodule file not found! ");
+       return -1;
+      }  
+      if (LoadSuperModuleFile(st2)) return -1;
+    }
+
     if (strstr(st,"SET_PARSIG_TRA")) {
       sscanf(st,"%s %f",tmp,&f1);
       fParSigTranslations=f1;
@@ -179,10 +213,10 @@ Int_t AliITSAlignMille::LoadConfig(const Char_t *cfile) {
       fUseLocalShifts = kTRUE;
     }
 
-    if (strstr(st,"MODULE_INDEX")) {
+    if (strstr(st,"MODULE_INDEX")) { // works only for sensitive modules
       sscanf(st,"%s %d %d %d %d %d %d %d",tmp,&idx,&itx,&ity,&itz,&iph,&ith,&ips);
       voluid=GetModuleVolumeID(idx);
-      if (!voluid) return 1; // bad index
+      if (!voluid || voluid>14300) return 1; // bad index
       fModuleIndex[nmod]=idx;
       fModuleVolumeID[nmod]=voluid;
       fFreeParam[nmod][0]=itx;
@@ -191,12 +225,46 @@ Int_t AliITSAlignMille::LoadConfig(const Char_t *cfile) {
       fFreeParam[nmod][3]=iph;
       fFreeParam[nmod][4]=ith;
       fFreeParam[nmod][5]=ips;
+      fMilleModule[nmod] = new AliITSAlignMilleModule(voluid);
       nmod++;
     }
    
     if (strstr(st,"MODULE_VOLUID")) {
-      // to be implemented
+      sscanf(st,"%s %d %d %d %d %d %d %d",tmp,&idx,&itx,&ity,&itz,&iph,&ith,&ips);
+      voluid=UShort_t(idx);
+      if (voluid>14335 && fUseSuperModules) { // custom supermodule
+       int ism=-1;
+       for (int j=0; j<fNSuperModules; j++) {
+         if (voluid==fSuperModule[j]->GetVolumeID()) ism=j;
+       }
+       if (ism<0) return -1; // bad volid
+       fModuleIndex[nmod]=fSuperModule[ism]->GetIndex();
+       fModuleVolumeID[nmod]=voluid;
+       fFreeParam[nmod][0]=itx;
+       fFreeParam[nmod][1]=ity;
+       fFreeParam[nmod][2]=itz;
+       fFreeParam[nmod][3]=iph;
+       fFreeParam[nmod][4]=ith;
+       fFreeParam[nmod][5]=ips;
+       fMilleModule[nmod] = new AliITSAlignMilleModule(*fSuperModule[ism]);
+       nmod++;
+      }
+      else { // sensitive volume
+       idx=GetModuleIndex(voluid);
+       if (idx<0 || idx>2197) return 1; // bad index
+       fModuleIndex[nmod]=idx;
+       fModuleVolumeID[nmod]=voluid;
+       fFreeParam[nmod][0]=itx;
+       fFreeParam[nmod][1]=ity;
+       fFreeParam[nmod][2]=itz;
+       fFreeParam[nmod][3]=iph;
+       fFreeParam[nmod][4]=ith;
+       fFreeParam[nmod][5]=ips;
+       fMilleModule[nmod] = new AliITSAlignMilleModule(voluid);
+       nmod++;
+      }
     }
+    //----------
 
   } // end while
 
@@ -229,6 +297,7 @@ Int_t AliITSAlignMille::GetModuleIndex(UShort_t voluid) {
 
 UShort_t AliITSAlignMille::GetModuleVolumeID(const Char_t *symname) {
   /// volume ID from symname
+  /// works for sensitive volumes only
   if (!symname) return 0;
 
   for (UShort_t voluid=2000; voluid<13300; voluid++) {
@@ -244,8 +313,15 @@ UShort_t AliITSAlignMille::GetModuleVolumeID(const Char_t *symname) {
 
 UShort_t AliITSAlignMille::GetModuleVolumeID(Int_t index) {
   /// volume ID from index
-  if (index<0 || index>2197) return 0;
-  return GetModuleVolumeID(AliITSgeomTGeo::GetSymName(index));
+  if (index<0) return 0;
+  if (index<2198)
+    return GetModuleVolumeID(AliITSgeomTGeo::GetSymName(index));
+  else {
+    for (int i=0; i<fNSuperModules; i++) {
+      if (fSuperModule[i]->GetIndex()==index) return fSuperModule[i]->GetVolumeID();
+    }
+  }
+  return 0;
 }
 
 void AliITSAlignMille::InitGeometry() {
@@ -257,7 +333,8 @@ void AliITSAlignMille::InitGeometry() {
     return;
   }
   // temporary align object, just use the rotation...
-  fTempAlignObj=new AliAlignObjParams(AliITSgeomTGeo::GetSymName(7),2055,0,0,0,0,0,0,kFALSE);
+  //fTempAlignObj=new AliAlignObjParams(AliITSgeomTGeo::GetSymName(7),2055,0,0,0,0,0,0,kFALSE);
+  fTempAlignObj=new AliAlignObjParams;
 }
 
 void AliITSAlignMille::Init(Int_t nGlobal,  /* number of global paramers */
@@ -330,6 +407,27 @@ void AliITSAlignMille::ResetLocalEquation()
   }
 }
 
+Int_t AliITSAlignMille::ApplyToGeometry() {
+  /// apply starting realignment to ideal geometry
+  if (!fGeoManager) return -1; 
+  TFile *pref = new TFile(fPreAlignmentFileName.Data());
+  if (!pref->IsOpen()) return -2;
+  TClonesArray *prea=(TClonesArray*)pref->Get("ITSAlignObjs");
+  if (!prea) return -3;  
+  Int_t nprea=prea->GetEntriesFast();
+  AliInfo(Form("Array of input misalignments with %d entries",nprea));
+
+  for (int ix=0; ix<nprea; ix++) {
+    AliAlignObjParams *preo=(AliAlignObjParams*) prea->UncheckedAt(ix);
+    if (!preo->ApplyToGeometry()) return -4;
+  }
+  pref->Close();
+  delete pref;
+
+  fUsePreAlignment = kTRUE;
+  return 0;
+}
+
 Int_t AliITSAlignMille::InitModuleParams() {
   /// initialize geometry parameters for a given detector
   /// for current cluster (fCluster)
@@ -347,17 +445,21 @@ Int_t AliITSAlignMille::InitModuleParams() {
     return -1;
   }
 
+  // now 'voluid' is the volumeID of a SENSITIVE VOLUME (coming from a cluster)
+
   // set the internal index (index in module list)
   UShort_t voluid=fCluster.GetVolumeID();
   Int_t k=fNModules-1;
-  while (k>=0 && !(voluid==fModuleVolumeID[k]) ) k--;  
+  while (k>=0 && !(fMilleModule[k]->IsIn(voluid)) ) k--;  // new
   if (k<0) return -3;    
-  fCurrentModuleInternalIndex=k;
+  fCurrentModuleInternalIndex=k; // the internal index of the SUPERMODULE
+
+  fCurrentModuleIndex=fMilleModule[k]->GetIndex(); // index of the SUPERMODULE
 
   // set the index
-  Int_t index = GetModuleIndex(AliGeomManager::SymName(voluid));
+  Int_t index = GetModuleIndex(voluid);
   if (index<0) return -2;
-  fCurrentModuleIndex = index;
+  fCurrentSensVolIndex = index; // the index of the SENSITIVE VOLUME
 
   fModuleInitParam[0] = 0.0;
   fModuleInitParam[1] = 0.0;
@@ -368,19 +470,37 @@ Int_t AliITSAlignMille::InitModuleParams() {
 
   /// get global (corrected) matrix  
   //  if (!AliITSgeomTGeo::GetOrigMatrix(index,*fCurrentModuleHMatrix)) return -3;
-  Double_t rott[9];
-  if (!AliITSgeomTGeo::GetRotation(index,rott)) return -3;
-  fCurrentModuleHMatrix->SetRotation(rott);
-  Double_t oLoc[3]={0,0,0};
-  if (!AliITSgeomTGeo::LocalToGlobal(index,oLoc,fCurrentModuleTranslation)) return -4;
-  fCurrentModuleHMatrix->SetTranslation(fCurrentModuleTranslation);
+//   Double_t rott[9];
+//   if (!AliITSgeomTGeo::GetRotation(index,rott)) return -3;
+//   fCurrentModuleHMatrix->SetRotation(rott);
+//   Double_t oLoc[3]={0,0,0};
+//   if (!AliITSgeomTGeo::LocalToGlobal(index,oLoc,fCurrentModuleTranslation)) return -4;
+//   fCurrentModuleHMatrix->SetTranslation(fCurrentModuleTranslation);
+  
+// new
+  fCurrentModuleHMatrix = fMilleModule[fCurrentModuleInternalIndex]->GetMatrix();
+
+  for (int ii=0; ii<3; ii++)
+    fCurrentModuleTranslation[ii]=fCurrentModuleHMatrix->GetTranslation()[ii];
+
+  TGeoHMatrix *svOrigMatrix = fMilleModule[fCurrentModuleInternalIndex]->GetSensitiveVolumeOrigGlobalMatrix(voluid);
 
   /// get back local coordinates
   fMeasGlo[0] = fCluster.GetX();
   fMeasGlo[1] = fCluster.GetY();
   fMeasGlo[2] = fCluster.GetZ();
-  fCurrentModuleHMatrix->MasterToLocal(fMeasGlo,fMeasLoc);
+  svOrigMatrix->MasterToLocal(fMeasGlo,fMeasLoc);
+  //svMatrix->MasterToLocal(fMeasGlo,fMeasLoc);
+  AliDebug(2,Form("Local coordinates of measured point : X=%f  Y=%f  Z=%f \n",fMeasLoc[0] ,fMeasLoc[1] ,fMeasLoc[2] ));
+
+  TGeoHMatrix *svMatrix = fMilleModule[fCurrentModuleInternalIndex]->GetSensitiveVolumeMatrix(voluid);
+  
+  // modify global coordinates according with pre-aligment
+  svMatrix->LocalToMaster(fMeasLoc,fMeasGlo);
+  fCluster.SetXYZ(fMeasGlo[0],fMeasGlo[1] ,fMeasGlo[2]);
+  AliDebug(2,Form("New global coordinates of measured point : X=%f  Y=%f  Z=%f \n",fMeasGlo[0] ,fMeasGlo[1] ,fMeasGlo[2] ));
 
+  // mettere il new GetLocalSigma...
   // set stdev from cluster
   TGeoHMatrix hcov;
   Double_t hcovel[9];
@@ -395,8 +515,8 @@ Int_t AliITSAlignMille::InitModuleParams() {
   hcovel[8]=double(fCluster.GetCov()[5]);
   hcov.SetRotation(hcovel);
   // now rotate in local system
-  hcov.MultiplyLeft(&fCurrentModuleHMatrix->Inverse());
-  hcov.Multiply(fCurrentModuleHMatrix);
+  hcov.MultiplyLeft(&svMatrix->Inverse());
+  hcov.Multiply(svMatrix);
 
   // per i ruotati c'e' delle sigmaY che compaiono... prob
   // e' un problema di troncamento
@@ -404,33 +524,82 @@ Int_t AliITSAlignMille::InitModuleParams() {
   fSigmaLoc[1] = TMath::Sqrt(TMath::Abs(hcov.GetRotationMatrix()[4]));
   fSigmaLoc[2] = TMath::Sqrt(TMath::Abs(hcov.GetRotationMatrix()[8]));
 
+  // set minimum value for SigmaLoc to 10 micron
+  if (fSigmaLoc[0]<0.0010) fSigmaLoc[0]=0.0010;
+  if (fSigmaLoc[2]<0.0010) fSigmaLoc[2]=0.0010;
+
     AliDebug(2,Form("Setting StDev from CovMat : fSigmaLocX=%f  fSigmaLocY=%f fSigmaLocZ=%f \n",fSigmaLoc[0] ,fSigmaLoc[1] ,fSigmaLoc[2] ));
    
   return 0;
 }
 
 void AliITSAlignMille::SetCurrentModule(Int_t index) {
-  ///
+  /// set as current the SuperModule that contains the 'index' sens.vol.
+  if (index<0 || index>2197) {
+    AliInfo("index does not correspond to a sensitive volume!");
+    return;
+  }
   UShort_t voluid=GetModuleVolumeID(index);
-  if (voluid) {
+  //Int_t k=IsDefined(voluid);
+  Int_t k=IsContained(voluid);
+  if (k>=0){
+    //if (voluid<14336) 
+    fCluster.SetVolumeID(voluid);
+    //else {
+    //fCluster.SetVolumeID(fMilleModule[k]->GetSensitiveVolumeVolumeID()[0]);
+    //printf("current module is a supermodule: fCluster set to first sensitive volume of the supermodule\n");
+    //}
+    fCluster.SetXYZ(0,0,0);
+    InitModuleParams();
+  }
+  else
+    printf("module %d not defined\n",index);    
+}
+
+void AliITSAlignMille::SetCurrentSensitiveModule(Int_t index) {
+  /// set as current the SuperModule that contains the 'index' sens.vol.
+  if (index<0 || index>2197) {
+    AliInfo("index does not correspond to a sensitive volume!");
+    return;
+  }
+  UShort_t voluid=AliITSAlignMilleModule::GetVolumeIDFromIndex(index);
+  Int_t k=IsDefined(voluid);
+  //printf("---> voluid=%d   k=%d\n",voluid,k);
+  if (k>=0){
     fCluster.SetVolumeID(voluid);
     fCluster.SetXYZ(0,0,0);
     InitModuleParams();
   }
+  else
+    printf("module %d not defined\n",index);    
 }
 
-void AliITSAlignMille::Print(Option_t* /* opt */) const {
+void AliITSAlignMille::Print(Option_t*) const 
+{
   ///
   printf("*** AliMillepede for ITS ***\n");
-  printf("    number of defined modules: %d\n",fNModules);
+  printf("    number of defined super modules: %d\n",fNModules);
+  
   if (fGeoManager)
     printf("    geometry loaded from %s\n",fGeometryFileName.Data());
   else
     printf("    geometry not loaded\n");
+  
+  if (fUseSuperModules) 
+    printf("    using custom supermodules ( %d defined )\n",fNSuperModules);
+  else
+    printf("    custom supermodules not used\n");    
+
+  if (fUsePreAlignment) 
+    printf("    using prealignment from %s \n",fPreAlignmentFileName.Data());
+  else
+    printf("    prealignment not used\n");    
+
   if (fUseLocalShifts) 
     printf("    Alignment shifts will be computed in LOCAL RS\n");
   else
     printf("    Alignment shifts will be computed in GLOBAL RS\n");    
+  
   printf("    Millepede configuration parameters:\n");
   printf("       init parsig for translations  : %.4f\n",fParSigTranslations);
   printf("       init parsig for rotations     : %.4f\n",fParSigRotations);
@@ -440,19 +609,33 @@ void AliITSAlignMille::Print(Option_t* /* opt */) const {
   printf("       number of stddev for chi2 cut : %d\n",fNStdDev);
 
   printf("List of defined modules:\n");
-  printf("  intidx\tindex\tvoluid\tsymname\n");
+  printf("  intidx\tindex\tvoluid\tname\n");
   for (int i=0; i<fNModules; i++)
-    printf("  %d\t%d\t%d\t%s\n",i,fModuleIndex[i],fModuleVolumeID[i],AliITSgeomTGeo::GetSymName(fModuleIndex[i]));
+    printf("  %d\t%d\t%d\t%s\n",i,fModuleIndex[i],fModuleVolumeID[i],fMilleModule[i]->GetName());
+   
 }
 
-void AliITSAlignMille::PrintCurrentModuleInfo() {
+AliITSAlignMilleModule  *AliITSAlignMille::GetMilleModule(UShort_t voluid) 
+{
+  // return pointer to a define supermodule
+  // return NULL if error
+  Int_t i=IsDefined(voluid);
+  if (i<0) return NULL;
+  return fMilleModule[i];
+}
+
+AliITSAlignMilleModule  *AliITSAlignMille::GetCurrentModule() 
+{
+  if (fNModules) return fMilleModule[fCurrentModuleInternalIndex];
+  return NULL;
+}
+
+void AliITSAlignMille::PrintCurrentModuleInfo() 
+{
   ///
-  if (fCurrentModuleIndex<0 || fCurrentModuleIndex>2197) return;
-  UShort_t voluid=fModuleVolumeID[fCurrentModuleInternalIndex];
-  printf("Current module: index=%d   voluid=%d\n",fCurrentModuleIndex,voluid);
-  printf("                symname:%s\n",AliGeomManager::SymName(voluid));
-  printf("  TGeoHMatrix: \n");
-  fCurrentModuleHMatrix->Print();
+  Int_t k=fCurrentModuleInternalIndex;
+  if (k<0 || k>=fNModules) return;
+  fMilleModule[k]->Print("");
 }
 
 
@@ -460,6 +643,13 @@ void AliITSAlignMille::InitTrackParams(int meth) {
   /// initialize local parameters with different methods
   /// for current track (fTrack)
   
+  Int_t npts=0;
+  TF1 *f1=NULL;
+  TGraph *g=NULL;
+  Float_t sigmax[20],sigmay[20],sigmaz[20];
+  AliTrackPoint ap;
+  TGraphErrors *ge=NULL;
+
   switch (meth) {
   case 1:   // simple linear interpolation
     // get local starting parameters (to be substituted by ESD track parms)
@@ -470,11 +660,11 @@ void AliITSAlignMille::InitTrackParams(int meth) {
     //      [3] = pz/py
     
     // test #1: linear fit in x(y) and z(y)
-    Int_t npts = fTrack->GetNPoints();
+    npts = fTrack->GetNPoints();
 
-    TF1 *f1=new TF1("f1","[0]+x*[1]",-50,50);
+    f1=new TF1("f1","[0]+x*[1]",-50,50);
 
-    TGraph *g=new TGraph(npts,fTrack->GetY(),fTrack->GetX());
+    g=new TGraph(npts,fTrack->GetY(),fTrack->GetX());
     g->Fit(f1,"RNQ");
     fLocalInitParam[0] = f1->GetParameter(0);
     fLocalInitParam[2] = f1->GetParameter(1);
@@ -490,15 +680,80 @@ void AliITSAlignMille::InitTrackParams(int meth) {
     delete f1;
 
     break;
+    
+  case 2:   // simple linear interpolation weighted using sigmas
+    // get local starting parameters (to be substituted by ESD track parms)
+    // local parms (fLocalInitParam[]) are:
+    //      [0] = global x coord. of straight line intersection at y=0 plane
+    //      [1] = global z coord. of straight line intersection at y=0 plane
+    //      [2] = px/py  
+    //      [3] = pz/py
+    
+    // test #1: linear fit in x(y) and z(y)
+    npts = fTrack->GetNPoints();
+    for (Int_t isig=0; isig<npts; isig++) {
+      fTrack->GetPoint(ap,isig);
+      sigmax[isig]=ap.GetCov()[0]; 
+      if (sigmax[isig]<1.0e-07) sigmax[isig]=1.0e-07; // minimum sigma=3 mu
+      sigmax[isig]=TMath::Sqrt(sigmax[isig]);
+
+      sigmay[isig]=ap.GetCov()[2]; 
+      if (sigmay[isig]<1.0e-07) sigmay[isig]=1.0e-07; // minimum sigma=3 mu
+      sigmay[isig]=TMath::Sqrt(sigmay[isig]);
+
+      sigmaz[isig]=ap.GetCov()[5]; 
+      if (sigmaz[isig]<1.0e-07) sigmaz[isig]=1.0e-07; // minimum sigma=3 mu
+      sigmaz[isig]=TMath::Sqrt(sigmaz[isig]);      
+    }
+
+    f1=new TF1("f1","[0]+x*[1]",-50,50);
+
+    ge=new TGraphErrors(npts,fTrack->GetY(),fTrack->GetX(),sigmay,sigmax);
+    ge->Fit(f1,"RNQ");
+    fLocalInitParam[0] = f1->GetParameter(0);
+    fLocalInitParam[2] = f1->GetParameter(1);
+    AliDebug(2,Form("X = p0gx + ugx*Y : p0gx = %f +- %f    ugx = %f +- %f\n",fLocalInitParam[0],f1->GetParError(0),fLocalInitParam[2],f1->GetParError(1)));
+    delete ge; ge=NULL;
+    
+    ge=new TGraphErrors(npts,fTrack->GetY(),fTrack->GetZ(),sigmay,sigmaz);
+    ge->Fit(f1,"RNQ");
+    fLocalInitParam[1] = f1->GetParameter(0);
+    fLocalInitParam[3] = f1->GetParameter(1);
+    AliDebug(2,Form("Z = p0gz + ugz*Y : p0gz=%f  ugz=%f\n",fLocalInitParam[1],fLocalInitParam[3]));
+    delete ge;
+    delete f1;
+    
+    break;
+    
   }
+}
 
+Int_t AliITSAlignMille::IsDefined(UShort_t voluid) const
+{
+  // checks if supermodule 'voluid' is defined and return the internal index
+  // return -1 if error
+  Int_t k=fNModules-1;
+  while (k>=0 && !(voluid==fModuleVolumeID[k]) ) k--;  
+  if (k<0) return -1; 
+  return k;
+}
+
+Int_t AliITSAlignMille::IsContained(UShort_t voluid) const
+{
+  // checks if the sensitive module 'voluid' is contained inside a supermodule and return the internal index of the last identified supermodule
+  // return -1 if error
+  if (AliITSAlignMilleModule::GetIndexFromVolumeID(voluid)<0) return -1;
+  Int_t k=fNModules-1;
+  while (k>=0 && !(fMilleModule[k]->IsIn(voluid)) ) k--;  
+  if (k<0) return -1; 
+  return k;
 }
+
 Bool_t AliITSAlignMille::CheckVolumeID(UShort_t voluid) const 
 {
-  ///
+  /// check if a sensitive volume is contained inside one of the defined supermodules
   Int_t k=fNModules-1;
-  while (k>=0 && !(voluid==fModuleVolumeID[k]) ) k--;  
-  //printf("selected element with voluid=%d : %d\n",voluid,k);
+  while (k>=0 && !(fMilleModule[k]->IsIn(voluid)) ) k--;  
   if (k>=0) return kTRUE;
   return kFALSE;
 }
@@ -549,18 +804,19 @@ Int_t AliITSAlignMille::ProcessTrack(AliTrackPointArray *track) {
   //      [1] = global z coord. of straight line intersection at y=0 plane
   //      [2] = px/py  
   //      [3] = pz/py
-  InitTrackParams(1);  
+  InitTrackParams(fInitTrackParamsMeth);  
 
   for (Int_t ipt=0; ipt<npts; ipt++) {
     fTrack->GetPoint(fCluster,ipt);
     if (!CheckVolumeID(fCluster.GetVolumeID())) continue;
+    AliDebug(2,Form("  Original Point = ( %f , %f , %f )   volid=%d\n",fCluster.GetX(),fCluster.GetY(),fCluster.GetZ(),fCluster.GetVolumeID()));
 
     // set geometry parameters for the the current module
     AliDebug(2,Form("\n--- processing point %d --- \n",ipt));    
     if (InitModuleParams()) continue;
 
     AliDebug(2,Form("    VolID=%d  Index=%d  InternalIdx=%d  symname=%s\n", track->GetVolumeID()[ipt], fCurrentModuleIndex ,fCurrentModuleInternalIndex, AliGeomManager::SymName(track->GetVolumeID()[ipt]) ));
-    AliDebug(2,Form("    Point = ( %f , %f , %f ) \n",track->GetX()[ipt],track->GetY()[ipt],track->GetZ()[ipt]));
+    AliDebug(2,Form("  Preprocessed Point = ( %f , %f , %f ) \n",fCluster.GetX(),fCluster.GetY(),fCluster.GetZ()));
     
     if (SetLocalEquations()) return -1;    
 
@@ -595,35 +851,37 @@ Int_t AliITSAlignMille::CalcIntersectionPoint(Double_t *lpar, Double_t *gpar) {
 
 
   // prepare the TGeoHMatrix
-  Double_t tr[3],ang[3];
-  //Double_t rad2deg=180./TMath::Pi();
-  if (fUseLocalShifts) { // just Delta matrix
-    tr[0]=gpar[0]; 
-    tr[1]=gpar[1]; 
-    tr[2]=gpar[2];
-    ang[0]=gpar[3]; // psi   (X)
-    ang[1]=gpar[4]; // theta (Y)
-    ang[2]=gpar[5]; // phi   (Z)
-  }
-  else { // total matrix with shifted parameter
-    AliInfo("global shifts not implemented yet!");
-    return -1;
-  }
-
-  //printf("fTempRot = 0x%x  - ang = %g %g %g \n",fTempRot,gpar[5]*rad2deg,gpar[3]*rad2deg,gpar[4]*rad2deg);
-
-  fTempAlignObj->SetRotation(ang[0],ang[1],ang[2]);
-  AliDebug(3,Form("Delta angles: psi=%f  theta=%f   phi=%f",ang[0],ang[1],ang[2]));
-  TGeoHMatrix hm;
-  fTempAlignObj->GetMatrix(hm);
-  fTempHMat->SetRotation(hm.GetRotationMatrix());
-  fTempHMat->SetTranslation(tr);
+//   Double_t tr[3],ang[3];
+//   //Double_t rad2deg=180./TMath::Pi();
+//   if (fUseLocalShifts) { // just Delta matrix
+//     tr[0]=gpar[0]; 
+//     tr[1]=gpar[1]; 
+//     tr[2]=gpar[2];
+//     ang[0]=gpar[3]; // psi   (X)
+//     ang[1]=gpar[4]; // theta (Y)
+//     ang[2]=gpar[5]; // phi   (Z)
+//   }
+//   else { // total matrix with shifted parameter
+//     AliInfo("global shifts not implemented yet!");
+//     return -1;
+//   }
+
+//   //printf("fTempRot = 0x%x  - ang = %g %g %g \n",fTempRot,gpar[5]*rad2deg,gpar[3]*rad2deg,gpar[4]*rad2deg);
+
+//   fTempAlignObj->SetRotation(ang[0],ang[1],ang[2]);
+//   AliDebug(3,Form("Delta angles: psi=%f  theta=%f   phi=%f",ang[0],ang[1],ang[2]));
+//   TGeoHMatrix hm;
+//   fTempAlignObj->GetMatrix(hm);
+//   fTempHMat->SetRotation(hm.GetRotationMatrix());
+//   fTempHMat->SetTranslation(tr);
   
-  // in this case the gpar[] array contains only shifts
-  // and fInitModuleParam[] are set to 0
-  // fCurrentModuleHMatrix is then modified as fCurrentHM*fTempHM
-  if (fUseLocalShifts) 
-    fTempHMat->MultiplyLeft(fCurrentModuleHMatrix);
+//   // in this case the gpar[] array contains only shifts
+//   // and fInitModuleParam[] are set to 0
+//   // fCurrentModuleHMatrix is then modified as fCurrentHM*fTempHM
+//   if (fUseLocalShifts) 
+//     fTempHMat->MultiplyLeft(fCurrentModuleHMatrix);
+  TGeoHMatrix *fTempHMat = fMilleModule[fCurrentModuleInternalIndex]->GetSensitiveVolumeModifiedMatrix(fCluster.GetVolumeID(),gpar);
+  if (!fTempHMat) return -1;
 
   // same in local coord.
   Double_t p0l[3],v0l[3];
@@ -734,6 +992,7 @@ Int_t AliITSAlignMille::SetLocalEquations() {
   // store first interaction point
   CalcIntersectionPoint(fLocalInitParam, fModuleInitParam);  
   for (Int_t i=0; i<3; i++) fPintLoc0[i]=fPintLoc[i];
+  AliDebug(2,Form("Intesect. point: L( %f , %f , %f )",fPintLoc[0],fPintLoc[1],fPintLoc[2]));
   
   // calculate local derivatives numerically
   Double_t dXdL[ITSMILLE_NLOCAL],dZdL[ITSMILLE_NLOCAL];
@@ -822,4 +1081,94 @@ void AliITSAlignMille::PrintGlobalParameters() {
 }
 
 // //_________________________________________________________________________
+Int_t AliITSAlignMille::LoadSuperModuleFile(const Char_t *sfile)
+{ 
+  // load definitions of supermodules from a root file
+  // return 0 if success
+
+  TFile *smf=TFile::Open(sfile);
+  if (!smf->IsOpen()) {
+    AliInfo(Form("Cannot open supermodule file %s",sfile));
+    return -1;
+  }
+
+  TClonesArray *sma=(TClonesArray*)smf->Get("ITSMilleSuperModules");
+  if (!sma) {
+    AliInfo(Form("Cannot find ITSMilleSuperModules array in file"));
+    return -2;  
+  }  
+  Int_t nsma=sma->GetEntriesFast();
+  AliInfo(Form("Array of SuperModules with %d entries\n",nsma));
+  
+  Char_t st[250];
+  char symname[150];
+  UShort_t volid;
+  TGeoHMatrix m;
+
+  for (Int_t i=0; i<nsma; i++) {
+    AliAlignObjParams *a = (AliAlignObjParams*)sma->UncheckedAt(i);
+    volid=a->GetVolUID();
+    strcpy(st,a->GetSymName());
+    a->GetMatrix(m);
+
+    sscanf(st,"%s",symname);
+    // decode module list
+    char *stp=strstr(st,"ModuleList:");
+    if (!stp) return -3;
+    stp += 11;
+    int idx[2200];
+    char spp[200]; int jp=0;
+    char cl[20];
+    strcpy(st,stp);
+    int l=strlen(st);
+    int j=0;
+    int n=0;
+
+    while (j<=l) {
+      if (st[j]==9 || st[j]==32 || st[j]==10 || st[j]==0) {
+       spp[jp]=0;
+       jp=0;
+       if (strlen(spp)) {
+         int k=strcspn(spp,"-");
+         if (k<int(strlen(spp))) { // c'e' il -
+           strcpy(cl,&(spp[k+1]));
+           spp[k]=0;
+           int ifrom=atoi(spp); int ito=atoi(cl);
+           for (int b=ifrom; b<=ito; b++) {
+             idx[n]=b;
+             n++;
+           }
+         }
+         else { // numerillo singolo
+           idx[n]=atoi(spp);
+           n++;
+         }
+       }
+      }
+      else {
+       spp[jp]=st[j];
+       jp++;
+      }
+      j++;
+    }
+    UShort_t volidsv[2198];
+    for (j=0;j<n;j++) {
+      volidsv[j]=AliITSAlignMilleModule::GetVolumeIDFromIndex(idx[j]);
+      if (!volidsv[j]) {
+       AliInfo(Form("Index %d not valid (range 0->2197)",idx[j]));
+       return -5;
+      }
+    }
+    Int_t smindex=int(2198+volid-14336); // virtual index
+    fSuperModule[fNSuperModules]=new AliITSAlignMilleModule(smindex,volid,symname,&m,n,volidsv);
+
+    //-------------
+    fNSuperModules++;
+  }
+
+  smf->Close();
+
+  fUseSuperModules=1;
+  return 0;
+}
 
index 3303f00d6bc139bdfda21e19ad91573fbe93fb66..a64fe526256fc226a4a0cb84145b625c29a71368 100644 (file)
@@ -20,6 +20,7 @@ class AliMillepede;
 class AliAlignObjParams;
 class TGeoManager;
 class TGeoHMatrix;
+class AliITSAlignMilleModule;
 
 // number of used objects
 #define ITSMILLE_NDETELEM    2198
@@ -35,31 +36,35 @@ public:
   virtual ~AliITSAlignMille();
   
   // geometry methods 
-  Int_t     GetModuleIndex(const Char_t *symname);
+  Int_t  GetModuleIndex(const Char_t *symname);
   Int_t     GetModuleIndex(UShort_t voluid);
   UShort_t  GetModuleVolumeID(const Char_t *symname);
   UShort_t  GetModuleVolumeID(Int_t index);
-  void      SetCurrentModule(Int_t index);
+  void      SetCurrentModule(Int_t index); 
+  void      SetCurrentSensitiveModule(Int_t index); // set as current the SENSITIVE module with index 'index'
 
   // configuration methods
   void      SetGeometryFileName(const Char_t* filename="geometry.root") 
     { fGeometryFileName = filename; }
   const Char_t* GetGeometryFileName() {return fGeometryFileName.Data();}
+  const Char_t* GetPreAlignmentFileName() {return fPreAlignmentFileName.Data();}
   void      PrintCurrentModuleInfo();
-  virtual void Print(Option_t* /* opt */) const;
+  void      Print(Option_t*) const;
   
   // fitting methods
   void      SetMinNPtsPerTrack(Int_t pts=3) {fMinNPtsPerTrack=pts;}
-  //Bool_t    CheckTrack(AliTrackPointArray *track);
   Int_t     ProcessTrack(AliTrackPointArray *track);
   void      InitTrackParams(int meth=1);
   Int_t     InitModuleParams();
   Int_t     CheckCurrentTrack();
-  Bool_t    CheckVolumeID(UShort_t voluid) const ;
+  Bool_t    CheckVolumeID(UShort_t voluid) const; // checks voluid for sensitive volumes
+  Int_t     IsDefined(UShort_t voluid) const;
+  Int_t     IsContained(UShort_t voluid) const;
   Int_t     CalcIntersectionPoint(Double_t *lpar, Double_t *gpar);
   Int_t     CalcDerivatives(Int_t paridx, Bool_t islpar);
   Double_t* GetLocalIntersectionPoint() {return fPintLoc;}
   Double_t* GetGlobalIntersectionPoint() {return fPintGlo;}
+  void      SetInitTrackParamsMeth(Int_t meth=1) {fInitTrackParamsMeth=meth;}
 
   // millepede methods
   void      FixParameter(Int_t param, Double_t value);
@@ -86,14 +91,18 @@ public:
   Double_t    *GetCurrentModuleTranslation() {return fCurrentModuleTranslation;}
   Int_t  GetCurrentModuleInternalIndex() const {return fCurrentModuleInternalIndex;}
   Int_t       *GetModuleIndexArray() {return fModuleIndex;}
+  AliITSAlignMilleModule  *GetMilleModule(UShort_t voluid); // get pointer to the defined supermodule
+  AliITSAlignMilleModule  *GetCurrentModule();
   UShort_t    *GetModuleVolumeIDArray() {return fModuleVolumeID;}
   
  private:
 
   // configuration methods
   Int_t     LoadConfig(const Char_t *cfile="AliITSAlignMille.conf");
+  Int_t     LoadSuperModuleFile(const Char_t *cfile="ITSMilleSuperModules.root");
   void      ResetLocalEquation();
   void      InitGeometry();
+  Int_t     ApplyToGeometry();
 
   // millepede methods
   void      Init(Int_t nGlobal, Int_t nLocal, Int_t nStdDev);
@@ -126,30 +135,42 @@ public:
   Double_t      fMeasLoc[3]; // current point local coordinates (the original ones)
   Double_t      fMeasGlo[3]; // current point glob. coord (AliTrackPoint)
   Double_t      fSigmaLoc[3]; // stdev current point
-  TGeoHMatrix  *fTempHMat; ///
+  //TGeoHMatrix  *fTempHMat; ///
   AliAlignObjParams *fTempAlignObj; ///
   Double_t      fDerivativeXLoc; // localX deriv.
   Double_t      fDerivativeZLoc; // localZ deriv.
   Double_t      fDeltaPar; ///
   Int_t         fMinNPtsPerTrack; ///
-  
+  Int_t         fInitTrackParamsMeth; ///
+
   // geometry stuffs
   TString       fGeometryFileName;  ///
+  TString       fPreAlignmentFileName;  ///
   TGeoManager  *fGeoManager;        ///
-  Int_t         fCurrentModuleIndex;   ///
-  Int_t         fCurrentModuleInternalIndex;  ///
+  Int_t         fCurrentModuleIndex;   /// SuperModule index
+  Int_t         fCurrentModuleInternalIndex;  /// SuperModule internal index
+  Int_t         fCurrentSensVolIndex;   /// Current point (sens. vol.) index
   Double_t      fCurrentModuleTranslation[3]; ///
   Int_t         fNModules;  /// number of defined modules from config file
-  Int_t         fModuleIndex[ITSMILLE_NDETELEM]; ///
-  UShort_t      fModuleVolumeID[ITSMILLE_NDETELEM];  ///
-  Bool_t        fFreeParam[ITSMILLE_NDETELEM][ITSMILLE_NPARCH];  ///
+  Int_t         fModuleIndex[ITSMILLE_NDETELEM*2]; ///
+  UShort_t      fModuleVolumeID[ITSMILLE_NDETELEM*2];  ///
+  Bool_t        fFreeParam[ITSMILLE_NDETELEM*2][ITSMILLE_NPARCH];  ///
   Bool_t        fUseLocalShifts; /// 
-  TGeoHMatrix  *fCurrentModuleHMatrix; /// 
+  Bool_t        fUseSuperModules; /// 
+  Bool_t        fUsePreAlignment; /// 
+  Int_t         fNSuperModules; /// number of custom supermodules in SM file
+  TGeoHMatrix  *fCurrentModuleHMatrix; /// SuperModule matrix
+
+  AliITSAlignMilleModule *fMilleModule[ITSMILLE_NDETELEM*2]; /// array of super modules to be aligned
+
+  AliITSAlignMilleModule *fSuperModule[ITSMILLE_NDETELEM*2]; /// array of super modules defined in supermodule file
 
   AliITSAlignMille(const AliITSAlignMille& rhs);
   AliITSAlignMille& operator=(const AliITSAlignMille& rhs);
 
 
-ClassDef(AliITSAlignMille, 0)};
+  ClassDef(AliITSAlignMille, 0)
+
+};
 
 #endif
diff --git a/ITS/AliITSAlignMilleModule.cxx b/ITS/AliITSAlignMilleModule.cxx
new file mode 100644 (file)
index 0000000..e1ffb8d
--- /dev/null
@@ -0,0 +1,435 @@
+/************************************************************************** \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
diff --git a/ITS/AliITSAlignMilleModule.h b/ITS/AliITSAlignMilleModule.h
new file mode 100644 (file)
index 0000000..c0e3b97
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef ALIITSALIGNMILLEMODULE_H\r
+#define ALIITSALIGNMILLEMODULE_H \r
+/* Copyright(c) 2007-2009 , ALICE Experiment at CERN, All rights reserved. * \r
+ * See cxx source for full Copyright notice                               */  \r
\r
+/// \ingroup rec \r
+/// \class AliITSAlignMilleModule \r
+/// \brief Class for alignment of ITS \r
+// \r
+// Authors: Marcello Lunardon \r
+\r
+/* $Id$  */ \r
+#include <TString.h> \r
+#include <TObject.h> \r
+#include <TNamed.h> \r
+\r
+#define ITSMILLE_NSENSVOL    2198\r
+\r
+class AliAlignObjParams; \r
+class TGeoHMatrix; \r
+\r
+class AliITSAlignMilleModule : public TNamed \r
+{ \r
+public: \r
+  AliITSAlignMilleModule(); \r
+  AliITSAlignMilleModule(UShort_t volid); // basic single volume constructor\r
+  AliITSAlignMilleModule(Int_t index, UShort_t volid, char* symname, TGeoHMatrix *m, Int_t nsv=0, UShort_t *volidsv=NULL); // general constructor\r
+\r
+  AliITSAlignMilleModule(const AliITSAlignMilleModule& rhs); // copy constructor\r
+  AliITSAlignMilleModule& operator=(const AliITSAlignMilleModule& rhs);  \r
+    \r
+  virtual ~AliITSAlignMilleModule(); \r
+   \r
+  // geometry methods  \r
+  Int_t     GetIndex() const {return fIndex;} \r
+  UShort_t  GetVolumeID() const {return fVolumeID;}  \r
+  Int_t     GetNSensitiveVolumes() const {return fNSensVol;} \r
+  TGeoHMatrix *GetMatrix() const {return fMatrix;} \r
+  UShort_t *GetSensitiveVolumeVolumeID() {return fSensVolVolumeID;}\r
+\r
+  Int_t     Set(Int_t index, UShort_t volid, char* symname, TGeoHMatrix *m, Int_t nsv=0, UShort_t *volidsv=NULL); // initialize a super module\r
+  \r
+  // util\r
+  static Int_t GetIndexFromVolumeID(UShort_t volid);\r
+  static UShort_t GetVolumeIDFromSymname(const Char_t *symname);\r
+  static UShort_t GetVolumeIDFromIndex(Int_t index);\r
+\r
+  // methods\r
+  Bool_t    IsIn(UShort_t volid);\r
+  TGeoHMatrix *GetSensitiveVolumeMatrix(UShort_t voluid);\r
+  TGeoHMatrix *GetSensitiveVolumeOrigGlobalMatrix(UShort_t voluid);\r
+  TGeoHMatrix *GetSensitiveVolumeModifiedMatrix(UShort_t voluid, Double_t *deltalocal); \r
+  AliAlignObjParams *GetSensitiveVolumeMisalignment(UShort_t voluid, AliAlignObjParams *a); \r
+  AliAlignObjParams *GetSensitiveVolumeMisalignment(UShort_t voluid, Double_t *deltalocal); \r
+  void      Print(Option_t*) const; \r
+\r
+protected:\r
+  Int_t     SensVolMatrix(UShort_t volid, TGeoHMatrix *m); \r
+  Int_t     SensVolOrigGlobalMatrix(UShort_t volid, TGeoHMatrix *m); \r
+  void      AddSensitiveVolume(UShort_t volid);\r
+\r
+private:\r
+  Int_t          fNSensVol; ///\r
+  Int_t          fIndex; ///\r
+  UShort_t       fVolumeID; ///\r
+  // il symname e' il nome del TNamed...\r
+  Int_t          fSensVolIndex[ITSMILLE_NSENSVOL]; ///\r
+  UShort_t       fSensVolVolumeID[ITSMILLE_NSENSVOL]; ///\r
+  TGeoHMatrix   *fMatrix; /// ideal TGeoHMatrix of the supermodule\r
+  TGeoHMatrix   *fSensVolMatrix; ///\r
+  TGeoHMatrix   *fSensVolModifMatrix; ///\r
+  AliAlignObjParams *fTempAlignObj; ///\r
+       \r
+  ClassDef(AliITSAlignMilleModule, 0)\r
+\r
+}; \r
+\r
+#endif \r
index 2b4393d5a91ef87d0c9eabf55de6d150de2a5633..49db3ab791d7a5182063af775de4a2bf8797d791 100644 (file)
 
 // Classes for alignment
 #pragma link C++ class AliITSAlignMille+;
+#pragma link C++ class AliITSAlignMilleModule+;
 #pragma link C++ class AliITSResidualsAnalysis+;
 // Classes for QA
 #pragma link C++ class AliITSQAChecker+;
index 2e1b40bb3b8b4ea2e378d3cec2491bb79a672ffd..bd79a962655b737ca512a6f4209a228de9165fea 100644 (file)
@@ -82,6 +82,7 @@ SRCS =        AliITSDetTypeRec.cxx \
                 AliITSOnlineSDDCMN.cxx \
                AliITSPreprocessorSSD.cxx \
                AliITSAlignMille.cxx \
+               AliITSAlignMilleModule.cxx \
                AliITSQAChecker.cxx \
                AliITSResidualsAnalysis.cxx \
                AliITSQADataMakerRec.cxx \