//-----------------------------------------------------------------------------
#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"
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) {
/// 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];
}
///////////////////////////////////////////////////////////////////////
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;
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;
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
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++) {
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() {
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 */
}
}
+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)
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;
/// 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];
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
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);
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("");
}
/// 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)
// [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);
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;
}
// [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;
// 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];
// 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];
}
// //_________________________________________________________________________
+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;
+}
class AliAlignObjParams;
class TGeoManager;
class TGeoHMatrix;
+class AliITSAlignMilleModule;
// number of used objects
#define ITSMILLE_NDETELEM 2198
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);
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);
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
--- /dev/null
+/************************************************************************** \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
--- /dev/null
+#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
// 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+;
AliITSOnlineSDDCMN.cxx \
AliITSPreprocessorSSD.cxx \
AliITSAlignMille.cxx \
+ AliITSAlignMilleModule.cxx \
AliITSQAChecker.cxx \
AliITSResidualsAnalysis.cxx \
AliITSQADataMakerRec.cxx \