//-----------------------------------------------------------------------------
/// \class AliITSAlignMille
-/// Alignment class fro the ALICE ITS detector
+/// Alignment class for the ALICE ITS detector
///
/// ITS specific alignment class which interface to AliMillepede.
/// For each track ProcessTrack calculates the local and global derivatives
#include "AliTrackPointArray.h"
#include "AliAlignObjParams.h"
#include "AliLog.h"
-#include "TSystem.h" // come si fa?
+#include "TSystem.h"
+#include "AliTrackFitterRieman.h"
/// \cond CLASSIMP
ClassImp(AliITSAlignMille)
fResCutInitial(100.),
fResCut(100.),
fNGlobal(ITSMILLE_NDETELEM*ITSMILLE_NPARCH),
- fNLocal(ITSMILLE_NLOCAL),
+ fNLocal(4),
fNStdDev(ITSMILLE_NSTDEV),
fIsMilleInit(kFALSE),
fParSigTranslations(0.0100),
fTrack(NULL),
fCluster(),
fGlobalDerivatives(NULL),
+ fSigmaXfactor(1.0),
+ fSigmaZfactor(1.0),
fTempAlignObj(NULL),
fDerivativeXLoc(0),
fDerivativeZLoc(0),
- fDeltaPar(0),
fMinNPtsPerTrack(3),
fInitTrackParamsMeth(1),
+ fProcessedPoints(NULL),
+ fTotBadLocEqPoints(0),
+ fRieman(NULL),
+ fRequirePoints(kFALSE),
+ fTempExcludedModule(-1),
fGeometryFileName("geometry.root"),
fPreAlignmentFileName(""),
fGeoManager(0),
fUseLocalShifts(kTRUE),
fUseSuperModules(kFALSE),
fUsePreAlignment(kFALSE),
+ fUseSortedTracks(kTRUE),
+ fBOn(kFALSE),
+ fBField(0.0),
fNSuperModules(0),
- fCurrentModuleHMatrix(NULL)
+ fCurrentModuleHMatrix(NULL),
+ fIsConfigured(kFALSE),
+ fBug(0)
{
/// main constructor that takes input from configuration file
fMillepede = new AliMillepede();
fGlobalDerivatives = new Double_t[fNGlobal];
- //fTempHMat = new TGeoHMatrix;
- //fCurrentModuleHMatrix = new TGeoHMatrix;
-
+
+ for (Int_t i=0; i<ITSMILLE_NDETELEM*2; i++) {
+ fPreAlignQF[i]=-1;
+ fSensVolSigmaXfactor[i]=1.0;
+ fSensVolSigmaZfactor[i]=1.0;
+ }
+
+ for (Int_t i=0; i<6; i++) {
+ fNReqLayUp[i]=0;
+ fNReqLayDown[i]=0;
+ fNReqLay[i]=0;
+ }
+ for (Int_t i=0; i<3; i++) {
+ fNReqDetUp[i]=0;
+ fNReqDetDown[i]=0;
+ fNReqDet[i]=0;
+ }
+
Int_t lc=LoadConfig(configFilename);
if (lc) {
AliInfo(Form("Error %d loading configuration from %s",lc,configFilename));
}
else {
+ fIsConfigured=kTRUE;
if (initmille && fNGlobal<20000) {
AliInfo(Form("Initializing Millepede with %d gpar, %d lpar and %d stddev ...",fNGlobal, fNLocal, fNStdDev));
Init(fNGlobal, fNLocal, fNStdDev);
}
}
- fDeltaPar=0.0; // not used at the moment - to be checked later...
-
+ if (fNModules) {
+ fProcessedPoints=new Int_t[fNModules];
+ for (Int_t ipp=0; ipp<fNModules; ipp++) fProcessedPoints[ipp]=0;
+ }
}
AliITSAlignMille::~AliITSAlignMille() {
/// Destructor
if (fMillepede) delete fMillepede;
delete [] fGlobalDerivatives;
- //delete fCurrentModuleHMatrix;
- //delete fTempHMat;
for (int i=0; i<fNModules; i++) delete fMilleModule[i];
for (int i=0; i<fNSuperModules; i++) delete fSuperModule[i];
+ if (fNModules) delete [] fProcessedPoints;
+ if (fRieman) delete fRieman;
}
///////////////////////////////////////////////////////////////////////
-
Int_t AliITSAlignMille::LoadConfig(const Char_t *cfile) {
/// return 0 if success
/// 1 if error in module index or voluid
Char_t st[200],st2[200];
Char_t tmp[100];
Int_t idx,itx,ity,itz,ith,ips,iph;
- Float_t f1;
+ Float_t f1,f2;
UShort_t voluid;
Int_t nmod=0;
if (LoadSuperModuleFile(st2)) return -1;
}
+ if (strstr(st,"SET_B_FIELD")) {
+ sscanf(st,"%s %f",tmp,&f1);
+ if (f1>0) {
+ fBField = f1;
+ fBOn = kTRUE;
+ fNLocal = 5; // helices
+ fRieman = new AliTrackFitterRieman();
+ }
+ else {
+ fBField = 0.0;
+ fBOn = kFALSE;
+ fNLocal = 4;
+ }
+ }
+
if (strstr(st,"SET_PARSIG_TRA")) {
sscanf(st,"%s %f",tmp,&f1);
fParSigTranslations=f1;
fResCut=f1;
}
+ if (strstr(st,"SET_LOCALSIGMAFACTOR")) {
+ sscanf(st,"%s %f %f",tmp,&f1,&f2);
+ if (f1>0 && f2>0) {
+ fSigmaXfactor=f1;
+ fSigmaZfactor=f2;
+ }
+ }
+
if (strstr(st,"SET_STARTFAC")) {
sscanf(st,"%s %f",tmp,&f1);
fStartFac=f1;
}
+ if (strstr(st,"REQUIRE_POINT")) {
+ // syntax: REQUIRE_POINT where ndet updw nreqpts
+ // where = LAYER or DETECTOR
+ // ndet = detector number: 1-6 for LAYER and 1-3 for DETECTOR (SPD=1, SDD=2, SSD=3)
+ // updw = 1 for Y>0, -1 for Y<0, 0 if not specified
+ // nreqpts = minimum number of points of that type
+ sscanf(st,"%s %s %d %d %d",tmp,st2,&itx,&ity,&itz);
+ itx--;
+ if (strstr(st2,"LAYER")) {
+ if (itx<0 || itx>5) return -7;
+ if (ity>0) fNReqLayUp[itx]=itz;
+ else if (ity<0) fNReqLayDown[itx]=itz;
+ else fNReqLay[itx]=itz;
+ fRequirePoints=kTRUE;
+ }
+ else if (strstr(st2,"DETECTOR")) { // DETECTOR
+ if (itx<0 || itx>2) return -7;
+ if (ity>0) fNReqDetUp[itx]=itz;
+ else if (ity<0) fNReqDetDown[itx]=itz;
+ else fNReqDet[itx]=itz;
+ fRequirePoints=kTRUE;
+ }
+ }
+
+
if (strstr(st,"SET_LOCAL_SHIFTS")) { // only enabled mode...
fUseLocalShifts = kTRUE;
}
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);
+ f1=0; f2=0;
+ sscanf(st,"%s %d %d %d %d %d %d %d %f %f",tmp,&idx,&itx,&ity,&itz,&iph,&ith,&ips,&f1,&f2);
+ if (idx<0 || idx>2197) return 1; // bad index
voluid=GetModuleVolumeID(idx);
if (!voluid || voluid>14300) return 1; // bad index
fModuleIndex[nmod]=idx;
fFreeParam[nmod][4]=ith;
fFreeParam[nmod][5]=ips;
fMilleModule[nmod] = new AliITSAlignMilleModule(voluid);
+ if (f1>0) fSensVolSigmaXfactor[idx]=f1;
+ if (f2>0) fSensVolSigmaZfactor[idx]=f2;
nmod++;
}
if (strstr(st,"MODULE_VOLUID")) {
- sscanf(st,"%s %d %d %d %d %d %d %d",tmp,&idx,&itx,&ity,&itz,&iph,&ith,&ips);
+ f1=0; f2=0;
+ sscanf(st,"%s %d %d %d %d %d %d %d %f %f",tmp,&idx,&itx,&ity,&itz,&iph,&ith,&ips,&f1,&f2);
voluid=UShort_t(idx);
if (voluid>14335 && fUseSuperModules) { // custom supermodule
int ism=-1;
fFreeParam[nmod][4]=ith;
fFreeParam[nmod][5]=ips;
fMilleModule[nmod] = new AliITSAlignMilleModule(*fSuperModule[ism]);
- nmod++;
+ if (f1>0) {
+ for (int kk=0; kk<fMilleModule[nmod]->GetNSensitiveVolumes(); kk++) {
+ idx=AliITSAlignMilleModule::GetIndexFromVolumeID(fMilleModule[nmod]->GetSensitiveVolumeVolumeID()[kk]);
+ if (idx>=0) fSensVolSigmaXfactor[idx]=f1;
+ }
+ }
+ if (f2>0) {
+ for (int kk=0; kk<fMilleModule[nmod]->GetNSensitiveVolumes(); kk++) {
+ idx=AliITSAlignMilleModule::GetIndexFromVolumeID(fMilleModule[nmod]->GetSensitiveVolumeVolumeID()[kk]);
+ if (idx>=0) fSensVolSigmaZfactor[idx]=f2;
+ }
+ } nmod++;
}
else { // sensitive volume
idx=GetModuleIndex(voluid);
fFreeParam[nmod][4]=ith;
fFreeParam[nmod][5]=ips;
fMilleModule[nmod] = new AliITSAlignMilleModule(voluid);
+ if (f1>0) fSensVolSigmaXfactor[idx]=f1;
+ if (f2>0) fSensVolSigmaZfactor[idx]=f2;
nmod++;
}
}
return 0;
}
+void AliITSAlignMille::SetRequiredPoint(Char_t* where, Int_t ndet, Int_t updw, Int_t nreqpts)
+{
+ // set minimum number of points in specific detector or layer
+ // where = LAYER or DETECTOR
+ // ndet = detector number: 1-6 for LAYER and 1-3 for DETECTOR (SPD=1, SDD=2, SSD=3)
+ // updw = 1 for Y>0, -1 for Y<0, 0 if not specified
+ // nreqpts = minimum number of points of that type
+ ndet--;
+ if (strstr(where,"LAYER")) {
+ if (ndet<0 || ndet>5) return;
+ if (updw>0) fNReqLayUp[ndet]=nreqpts;
+ else if (updw<0) fNReqLayDown[ndet]=nreqpts;
+ else fNReqLay[ndet]=nreqpts;
+ fRequirePoints=kTRUE;
+ }
+ else if (strstr(where,"DETECTOR")) {
+ if (ndet<0 || ndet>2) return;
+ if (updw>0) fNReqDetUp[ndet]=nreqpts;
+ else if (updw<0) fNReqDetDown[ndet]=nreqpts;
+ else fNReqDet[ndet]=nreqpts;
+ fRequirePoints=kTRUE;
+ }
+}
+
Int_t AliITSAlignMille::GetModuleIndex(const Char_t *symname) {
/// index from symname
if (!symname) return -1;
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;
}
for (Int_t j=0; j<ITSMILLE_NPARCH; j++) {
if (!fFreeParam[i][j]) FixParameter(i*ITSMILLE_NPARCH+j,0.0);
else {
- // pepopepo: da sistemare il settaggio delle sigma...
+ // pepopepo: da verificare il settaggio delle sigma, ma forse va bene...
Double_t parsig=0;
if (j<3) parsig=fParSigTranslations; // translations (0.0100 cm)
else parsig=fParSigRotations; // rotations (1/10 deg)
for (int ix=0; ix<nprea; ix++) {
AliAlignObjParams *preo=(AliAlignObjParams*) prea->UncheckedAt(ix);
+ Int_t index=AliITSAlignMilleModule::GetIndexFromVolumeID(preo->GetVolUID());
+ if (index>=0) {
+ fPreAlignQF[index] = (int) preo->GetUniqueID();
+ //printf("index=%d QF=%d\n",index,preo->GetUniqueID());
+ }
if (!preo->ApplyToGeometry()) return -4;
}
pref->Close();
return 0;
}
+Int_t AliITSAlignMille::GetPreAlignmentQualityFactor(Int_t index) {
+ /// works for sensitive volumes
+ if (!fUsePreAlignment || index<0 || index>2197) return -1;
+ return fPreAlignQF[index];
+}
+
+AliTrackPointArray *AliITSAlignMille::PrepareTrack(AliTrackPointArray *atp) {
+ /// create a new AliTrackPointArray keeping only defined modules
+ /// move points according to a given prealignment, if any
+ /// sort alitrackpoints w.r.t. global Y direction, if selected
+
+ AliTrackPointArray *atps=NULL;
+ Int_t idx[20];
+ Int_t npts=atp->GetNPoints();
+
+ /// checks if AliTrackPoints belong to defined modules
+ Int_t ngoodpts=0;
+ Int_t intidx[20];
+
+ for (int j=0; j<npts; j++) {
+ intidx[j] = IsContained(atp->GetVolumeID()[j]);
+ if (intidx[j]>=0) ngoodpts++;
+ }
+ AliDebug(3,Form("Number of points in defined modules: %d",ngoodpts));
+
+ // reject track if not enough points are left
+ if (ngoodpts<fMinNPtsPerTrack) {
+ AliInfo("Track with not enough points!");
+ return NULL;
+ }
+
+ AliTrackPoint p;
+ // check points in specific places
+ if (fRequirePoints) {
+ Int_t nlayup[6],nlaydown[6],nlay[6];
+ Int_t ndetup[3],ndetdown[3],ndet[3];
+ for (Int_t j=0; j<6; j++) {nlayup[j]=0; nlaydown[j]=0; nlay[j]=0;}
+ for (Int_t j=0; j<3; j++) {ndetup[j]=0; ndetdown[j]=0; ndet[j]=0;}
+
+ for (int i=0; i<npts; i++) {
+ // skip not defined points
+ if (intidx[i]<0) continue;
+ Float_t xx=atp->GetX()[i];
+ Float_t yy=atp->GetY()[i];
+ Float_t r=TMath::Sqrt(xx*xx + yy*yy);
+ int lay=-1;
+ if (r<5) lay=0;
+ else if (r>5 && r<10) lay=1;
+ else if (r>10 && r<18) lay=2;
+ else if (r>18 && r<30) lay=3;
+ else if (r>30 && r<40) lay=4;
+ else if (r>40) lay=5;
+ if (lay<0) continue;
+ int det=lay/2;
+ //printf("Point %d - x=%f y=%f R=%f lay=%d det=%d\n",i,xx,yy,r,lay,det);
+
+ if (yy>=0.0) { // UP point
+ nlayup[lay]++;
+ nlay[lay]++;
+ ndetup[det]++;
+ ndet[det]++;
+ }
+ else {
+ nlaydown[lay]++;
+ nlay[lay]++;
+ ndetdown[det]++;
+ ndet[det]++;
+ }
+ }
+
+ // checks minimum values
+ Bool_t isok=kTRUE;
+ for (Int_t j=0; j<6; j++) {
+ if (nlayup[j]<fNReqLayUp[j]) isok=kFALSE;
+ if (nlaydown[j]<fNReqLayDown[j]) isok=kFALSE;
+ if (nlay[j]<fNReqLay[j]) isok=kFALSE;
+ }
+ for (Int_t j=0; j<3; j++) {
+ if (ndetup[j]<fNReqDetUp[j]) isok=kFALSE;
+ if (ndetdown[j]<fNReqDetDown[j]) isok=kFALSE;
+ if (ndet[j]<fNReqDet[j]) isok=kFALSE;
+ }
+ if (!isok) {
+ AliInfo("Track does not meet all location point requirements!");
+ return NULL;
+ }
+ }
+
+ // build a new track with (sorted) (prealigned) good points
+ atps=new AliTrackPointArray(ngoodpts);
+
+ for (int i=0; i<npts; i++) idx[i]=i;
+ // sort track if required
+ if (fUseSortedTracks) TMath::Sort(npts,atp->GetY(),idx); // sort descending...
+
+ Int_t npto=0;
+ for (int i=0; i<npts; i++) {
+ // skip not defined points
+ if (intidx[idx[i]]<0) continue;
+ atp->GetPoint(p,idx[i]);
+
+ // prealign point if required
+ // get IDEAL matrix
+ TGeoHMatrix *svOrigMatrix = fMilleModule[intidx[idx[i]]]->GetSensitiveVolumeOrigGlobalMatrix(p.GetVolumeID());
+ // get back real local coordinates: use OriginalGlobalMatrix because AliTrackPoints were written
+ // with idel geometry
+ Double_t pg[3],pl[3];
+ pg[0]=p.GetX();
+ pg[1]=p.GetY();
+ pg[2]=p.GetZ();
+ AliDebug(3,Form("Global coordinates of measured point : X=%f Y=%f Z=%f \n",pg[0],pg[1],pg[2]));
+ svOrigMatrix->MasterToLocal(pg,pl);
+
+ AliDebug(3,Form("Local coordinates of measured point : X=%f Y=%f Z=%f \n",pl[0],pl[1],pl[2]));
+
+ // update covariance matrix
+ TGeoHMatrix hcov;
+ Double_t hcovel[9];
+ hcovel[0]=double(p.GetCov()[0]);
+ hcovel[1]=double(p.GetCov()[1]);
+ hcovel[2]=double(p.GetCov()[2]);
+ hcovel[3]=double(p.GetCov()[1]);
+ hcovel[4]=double(p.GetCov()[3]);
+ hcovel[5]=double(p.GetCov()[4]);
+ hcovel[6]=double(p.GetCov()[2]);
+ hcovel[7]=double(p.GetCov()[4]);
+ hcovel[8]=double(p.GetCov()[5]);
+ hcov.SetRotation(hcovel);
+ // now rotate in local system
+ hcov.Multiply(svOrigMatrix);
+ hcov.MultiplyLeft(&svOrigMatrix->Inverse());
+ // now hcov is LOCAL COVARIANCE MATRIX
+
+
+ // pepopepo
+ if (fBug==1) {
+ // correzione bug LAYER 5 SSD temporanea..
+ int ssdidx=AliITSAlignMilleModule::GetIndexFromVolumeID(p.GetVolumeID());
+ if (ssdidx>=500 && ssdidx<1248) {
+ int ladder=(ssdidx-500)%22;
+ if (ladder==18) p.SetVolumeID(AliITSAlignMilleModule::GetVolumeIDFromIndex(ssdidx+1));
+ if (ladder==19) p.SetVolumeID(AliITSAlignMilleModule::GetVolumeIDFromIndex(ssdidx-1));
+ }
+ }
+
+ /// get (evenctually prealigned) matrix of sens. vol.
+ TGeoHMatrix *svMatrix = fMilleModule[intidx[idx[i]]]->GetSensitiveVolumeMatrix(p.GetVolumeID());
+ // modify global coordinates according with pre-aligment
+ svMatrix->LocalToMaster(pl,pg);
+ // now rotate in local system
+ hcov.Multiply(&svMatrix->Inverse());
+ hcov.MultiplyLeft(svMatrix);
+ // hcov is back in GLOBAL RF
+ Float_t pcov[6];
+ pcov[0]=hcov.GetRotationMatrix()[0];
+ pcov[1]=hcov.GetRotationMatrix()[1];
+ pcov[2]=hcov.GetRotationMatrix()[2];
+ pcov[3]=hcov.GetRotationMatrix()[4];
+ pcov[4]=hcov.GetRotationMatrix()[5];
+ pcov[5]=hcov.GetRotationMatrix()[8];
+
+ p.SetXYZ(pg[0],pg[1],pg[2],pcov);
+ AliDebug(3,Form("New global coordinates of measured point : X=%f Y=%f Z=%f \n",pg[0],pg[1],pg[2]));
+ atps->AddPoint(npto,&p);
+ AliDebug(2,Form("Adding point[%d] = ( %f , %f , %f ) volid = %d",npto,atps->GetX()[npto],atps->GetY()[npto],atps->GetZ()[npto],atps->GetVolumeID()[npto] ));
+
+ npto++;
+ }
+
+ return atps;
+}
+
+
+
+AliTrackPointArray *AliITSAlignMille::SortTrack(AliTrackPointArray *atp) {
+ /// sort alitrackpoints w.r.t. global Y direction
+ AliTrackPointArray *atps=NULL;
+ Int_t idx[20];
+ Int_t npts=atp->GetNPoints();
+ AliTrackPoint p;
+ atps=new AliTrackPointArray(npts);
+
+ TMath::Sort(npts,atp->GetY(),idx);
+
+ for (int i=0; i<npts; i++) {
+ atp->GetPoint(p,idx[i]);
+ atps->AddPoint(i,&p);
+ AliDebug(2,Form("Point[%d] = ( %f , %f , %f ) volid = %d",i,atps->GetX()[i],atps->GetY()[i],atps->GetZ()[i],atps->GetVolumeID()[i] ));
+ }
+ return atps;
+}
+
+
Int_t AliITSAlignMille::InitModuleParams() {
/// initialize geometry parameters for a given detector
/// for current cluster (fCluster)
/// fGlobalInitParam[] is set as:
/// [tx,ty,tz,psi,theta,phi]
- /// (old was [tx,ty,tz,theta,psi,phi] ROOT's angles...)
- /// *** At the moment: using Raffalele's angles definition ***
///
- /// Num of Dets: ITSMILLE_NDETELEM = fgNDetElem
- /// Num of Par : ITSMILLE_NPARCH = fgNParCh
/// return 0 if success
if (!fGeoManager) {
// set the internal index (index in module list)
UShort_t voluid=fCluster.GetVolumeID();
Int_t k=fNModules-1;
- while (k>=0 && !(fMilleModule[k]->IsIn(voluid)) ) k--; // new
+ while (k>=0 && !(fMilleModule[k]->IsIn(voluid)) ) k--;
if (k<0) return -3;
fCurrentModuleInternalIndex=k; // the internal index of the SUPERMODULE
fModuleInitParam[3] = 0.0; // psi (X)
fModuleInitParam[4] = 0.0; // theta (Y)
fModuleInitParam[5] = 0.0; // phi (Z)
-
- /// 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);
-// 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
+ /// get (evenctually prealigned) matrix of sens. vol.
+ TGeoHMatrix *svMatrix = fMilleModule[fCurrentModuleInternalIndex]->GetSensitiveVolumeMatrix(voluid);
+
fMeasGlo[0] = fCluster.GetX();
fMeasGlo[1] = fCluster.GetY();
- fMeasGlo[2] = fCluster.GetZ();
- svOrigMatrix->MasterToLocal(fMeasGlo,fMeasLoc);
- //svMatrix->MasterToLocal(fMeasGlo,fMeasLoc);
+ fMeasGlo[2] = fCluster.GetZ();
+ 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[0]=double(fCluster.GetCov()[0]);
hcovel[1]=double(fCluster.GetCov()[1]);
- hcovel[2]=double(fCluster.GetCov()[3]);
+ hcovel[2]=double(fCluster.GetCov()[2]);
hcovel[3]=double(fCluster.GetCov()[1]);
- hcovel[4]=double(fCluster.GetCov()[2]);
+ hcovel[4]=double(fCluster.GetCov()[3]);
hcovel[5]=double(fCluster.GetCov()[4]);
- hcovel[6]=double(fCluster.GetCov()[3]);
+ hcovel[6]=double(fCluster.GetCov()[2]);
hcovel[7]=double(fCluster.GetCov()[4]);
hcovel[8]=double(fCluster.GetCov()[5]);
hcov.SetRotation(hcovel);
// now rotate in local system
- hcov.MultiplyLeft(&svMatrix->Inverse());
hcov.Multiply(svMatrix);
+ hcov.MultiplyLeft(&svMatrix->Inverse());
- // per i ruotati c'e' delle sigmaY che compaiono... prob
- // e' un problema di troncamento
+ // set local sigmas
fSigmaLoc[0] = TMath::Sqrt(TMath::Abs(hcov.GetRotationMatrix()[0]));
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
+ // 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] ));
+ // multiply local sigmas by global factor
+ fSigmaLoc[0] *= fSigmaXfactor;
+ fSigmaLoc[2] *= fSigmaZfactor;
+
+ // multiply local sigmas by individual factor
+ fSigmaLoc[0] *= fSensVolSigmaXfactor[index];
+ fSigmaLoc[2] *= fSensVolSigmaZfactor[index];
+
+ AliDebug(2,Form("Setting StDev from CovMat : fSigmaLocX=%g fSigmaLocY=%g fSigmaLocZ=%g \n",fSigmaLoc[0] ,fSigmaLoc[1] ,fSigmaLoc[2] ));
return 0;
}
return;
}
UShort_t voluid=GetModuleVolumeID(index);
- //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);
+ AliInfo(Form("module %d not defined\n",index));
}
void AliITSAlignMille::SetCurrentSensitiveModule(Int_t index) {
}
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);
+ AliInfo(Form("module %d not defined\n",index));
}
void AliITSAlignMille::Print(Option_t*) const
{
- ///
+ /// print infos
printf("*** AliMillepede for ITS ***\n");
printf(" number of defined super modules: %d\n",fNModules);
else
printf(" prealignment not used\n");
+ if (fBOn)
+ printf(" B Field set to %f T - using Riemann's helices\n",fBField);
+ else
+ printf(" B Field OFF - using straight lines \n");
+
if (fUseLocalShifts)
printf(" Alignment shifts will be computed in LOCAL RS\n");
else
printf(" Alignment shifts will be computed in GLOBAL RS\n");
+
+ if (fRequirePoints) printf(" Required points in tracks:\n");
+ for (Int_t i=0; i<6; i++) {
+ if (fNReqLayUp[i]>0) printf(" Layer %d : %d points with Y>0\n",i+1,fNReqLayUp[i]);
+ if (fNReqLayDown[i]>0) printf(" Layer %d : %d points with Y<0\n",i+1,fNReqLayDown[i]);
+ if (fNReqLay[i]>0) printf(" Layer %d : %d points \n",i+1,fNReqLay[i]);
+ }
+ for (Int_t i=0; i<3; i++) {
+ if (fNReqDetUp[i]>0) printf(" Detector %d : %d points with Y>0\n",i+1,fNReqDetUp[i]);
+ if (fNReqDetDown[i]>0) printf(" Detector %d : %d points with Y<0\n",i+1,fNReqDetDown[i]);
+ if (fNReqDet[i]>0) printf(" Detector %d : %d points \n",i+1,fNReqDet[i]);
+ }
- printf(" Millepede configuration parameters:\n");
- printf(" init parsig for translations : %.4f\n",fParSigTranslations);
- printf(" init parsig for rotations : %.4f\n",fParSigRotations);
- printf(" init value for chi2 cut : %.4f\n",fStartFac);
- printf(" first iteration cut value : %.4f\n",fResCutInitial);
- printf(" other iterations cut value : %.4f\n",fResCut);
- printf(" number of stddev for chi2 cut : %d\n",fNStdDev);
+ printf("\n Millepede configuration parameters:\n");
+ printf(" init parsig for translations : %.4f\n",fParSigTranslations);
+ printf(" init parsig for rotations : %.4f\n",fParSigRotations);
+ printf(" init value for chi2 cut : %.4f\n",fStartFac);
+ printf(" first iteration cut value : %.4f\n",fResCutInitial);
+ printf(" other iterations cut value : %.4f\n",fResCut);
+ printf(" number of stddev for chi2 cut : %d\n",fNStdDev);
+ printf(" mult. fact. for local sigmas : %.4f %.4f\n",fSigmaXfactor, fSigmaZfactor);
printf("List of defined modules:\n");
printf(" intidx\tindex\tvoluid\tname\n");
fMilleModule[k]->Print("");
}
+Bool_t AliITSAlignMille::InitRiemanFit() {
+ // Initialize Riemann Fitter for current track
+ // return kFALSE if error
+
+ if (!fBOn) return kFALSE;
+
+ Int_t npts=0;
+ AliTrackPoint ap;
+ npts = fTrack->GetNPoints();
+ AliDebug(3,Form("Fitting track with %d points",npts));
+
+ fRieman->Reset();
+ fRieman->SetTrackPointArray(fTrack);
+
+ TArrayI ai(npts);
+ for (Int_t ipt=0; ipt<npts; ipt++) ai[ipt]=fTrack->GetVolumeID()[ipt];
+
+ // fit track with 5 params in his own tracking-rotated reference system
+ // xc = -p[1]/p[0];
+ // yc = 1/p[0];
+ // R = sqrt( x0*x0 + y0*y0 - y0*p[2]);
+ if (!fRieman->Fit(&ai,NULL,(AliGeomManager::ELayerID)1,(AliGeomManager::ELayerID)6)) {
+ return kFALSE;
+ }
+
+ for (int i=0; i<5; i++)
+ fLocalInitParam[i] = fRieman->GetParam()[i];
+
+ return kTRUE;
+}
+
void AliITSAlignMille::InitTrackParams(int meth) {
/// initialize local parameters with different methods
// test #1: linear fit in x(y) and z(y)
npts = fTrack->GetNPoints();
+ AliDebug(3,Form("*** initializing track with %d points ***",npts));
f1=new TF1("f1","[0]+x*[1]",-50,50);
// test #1: linear fit in x(y) and z(y)
npts = fTrack->GetNPoints();
+ AliDebug(3,Form("*** initializing track with %d points ***",npts));
+
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];
+ sigmay[isig]=ap.GetCov()[3];
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]);
+
+ if (fTempExcludedModule>=0 && fTempExcludedModule==AliITSAlignMilleModule::GetIndexFromVolumeID(ap.GetVolumeID())) {
+ sigmax[isig] *= 1000.;
+ sigmay[isig] *= 1000.;
+ sigmaz[isig] *= 1000.;
+ fTempExcludedModule=-1;
+ }
}
f1=new TF1("f1","[0]+x*[1]",-50,50);
ngoodpts++;
}
}
- // pepo da controllare...
+
if (ngoodpts<fMinNPtsPerTrack) return 0;
return ngoodpts;
}
Int_t npts = track->GetNPoints();
- AliDebug(2,Form("\n*** Processing track with %d points ***\n",npts));
- fTrack = track;
-
- // checks if there are enough good points
- if (!CheckCurrentTrack()) {
- AliInfo("Track with not enough good points - will not be used...");
- return -1;
- }
+ AliDebug(2,Form("*** Input track with %d points ***",npts));
- // set 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
- InitTrackParams(fInitTrackParamsMeth);
+ // preprocessing of the input track: keep only points in defined volumes,
+ // move points if prealignment is set, sort by Yglo if required
+
+ fTrack=PrepareTrack(track);
+ if (!fTrack) return -1;
+ npts = fTrack->GetNPoints();
+ AliDebug(2,Form("*** Processing prepared track with %d points ***",npts));
+
+ if (!fBOn) { // straight lines
+ // set 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
+ InitTrackParams(fInitTrackParamsMeth);
+ }
+ else {
+ // local parms (fLocalInitParam[]) are the Riemann Fitter params
+ if (!InitRiemanFit()) {
+ AliInfo("Riemann fit failed! skipping this track...");
+ delete fTrack;
+ fTrack=NULL;
+ return -5;
+ }
+ }
+
+ Int_t nloceq=0;
+ MilleData *md = new MilleData[npts];
+
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()));
+ AliDebug(2,Form("\n--- processing point %d --- \n",ipt));
// 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(" Preprocessed Point = ( %f , %f , %f ) \n",fCluster.GetX(),fCluster.GetY(),fCluster.GetZ()));
+ AliDebug(2,Form(" Preprocessed Point = ( %f , %f , %f ) \n",fCluster.GetX(),fCluster.GetY(),fCluster.GetZ()));
+
+ if (!AddLocalEquation(md[nloceq])) {
+ nloceq++;
+ fProcessedPoints[fCurrentModuleInternalIndex]++;
+ }
+ else {
+ fTotBadLocEqPoints++;
+ }
- if (SetLocalEquations()) return -1;
-
} // end loop over points
+ delete fTrack;
+ fTrack=NULL;
+
+ // not enough good points!
+ if (nloceq<fMinNPtsPerTrack) {
+ delete [] md;
+ return -1;
+ }
+
+ // finally send local equations to millepede
+ SetLocalEquations(md,nloceq);
+
+ delete [] md;
+
return 0;
}
Int_t AliITSAlignMille::CalcIntersectionPoint(Double_t *lpar, Double_t *gpar) {
- /// calculate track intersection point in local coordinates
- /// according with a given set of parameters (local(4) and global(6))
+ /// calculate intersection point of track with current module in local coordinates
+ /// according with a given set of parameters (local(4/5) and global(6))
/// and fill fPintLoc/Glo
- /// local are: pgx0, pgz0, ugx0, ugz0
+ /// local are: pgx0, pgz0, ugx, ugz OR riemann fitters pars
/// global are: tx,ty,tz,psi,theta,phi (Raff's delta angles in deg.)
/// return 0 if success
- AliDebug(3,Form("lpar = %g %g %g %g \ngpar= %g %g %g %g %g %g\n",lpar[0],lpar[1],lpar[2],lpar[3],gpar[0],gpar[1],gpar[2],gpar[3],gpar[4],gpar[5]));
-
- // vector of initial straight line direction in glob. coord
- // ATTENZIONE: forse va rinormalizzato tutto...
- Double_t v0g[3];
- //Double_t
- v0g[0]=lpar[2];
- v0g[1]=1.0;
- v0g[2]=lpar[3];
+ AliDebug(3,Form("lpar = %g %g %g %g %g\ngpar= %g %g %g %g %g %g\n",lpar[0],lpar[1],lpar[2],lpar[3],lpar[4],gpar[0],gpar[1],gpar[2],gpar[3],gpar[4],gpar[5]));
+ AliDebug(3,Form("deltalpar = %g %g %g %g %g\n",lpar[0]-fLocalInitParam[0],lpar[1]-fLocalInitParam[1],lpar[2]-fLocalInitParam[2],lpar[3]-fLocalInitParam[3],lpar[4]-fLocalInitParam[4]));
- // intercept in yg=0 plane in glob coord
- Double_t p0g[3];
- p0g[0]=lpar[0];
- p0g[1]=0.0;
- p0g[2]=lpar[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);
-// // 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);
+ // prepare the TGeoHMatrix
TGeoHMatrix *fTempHMat = fMilleModule[fCurrentModuleInternalIndex]->GetSensitiveVolumeModifiedMatrix(fCluster.GetVolumeID(),gpar);
if (!fTempHMat) return -1;
-
+
+ Double_t v0g[3]; // vector with straight line direction in global coord.
+ Double_t p0g[3]; // point of the straight line (glo)
+
+ if (fBOn) { // B FIELD!
+ AliTrackPoint prf;
+ for (int ip=0; ip<5; ip++)
+ fRieman->SetParam(ip,lpar[ip]);
+
+ if (!fRieman->GetPCA(fCluster,prf)) {
+ AliInfo(Form("error in GetPCA for point %d",fCluster.GetVolumeID()));
+ return -3;
+ }
+ // now determine straight line passing tangent to fit curve at prf
+ // ugx = dX/dY_glo = DeltaX/DeltaY_glo
+ // mo' P1=(X,Y,Z)_glo_prf
+ // => (x,y,Z)_trk_prf ruotando di alpha...
+ Double_t alpha=fRieman->GetAlpha();
+ Double_t x1g = prf.GetX();
+ Double_t y1g = prf.GetY();
+ Double_t z1g = prf.GetZ();
+ Double_t x1t = x1g*TMath::Cos(alpha) + y1g*TMath::Sin(alpha);
+ Double_t y1t = -x1g*TMath::Sin(alpha) + y1g*TMath::Cos(alpha);
+ Double_t z1t = z1g;
+
+ Double_t x2t = x1t+1.0;
+ Double_t y2t = y1t+fRieman->GetDYat(x1t);
+ Double_t z2t = z1t+fRieman->GetDZat(x1t);
+ Double_t x2g = x2t*TMath::Cos(alpha) - y2t*TMath::Sin(alpha);
+ Double_t y2g = x2t*TMath::Sin(alpha) + y2t*TMath::Cos(alpha);
+ Double_t z2g = z2t;
+
+ AliDebug(3,Form("Riemann frame: fAlpha = %f = %f ",alpha,alpha*180./TMath::Pi()));
+ AliDebug(3,Form(" prf_glo=( %f , %f , %f ) prf_rf=( %f , %f , %f )\n", x1g,y1g,z1g, x1t,y1t,z1t));
+ AliDebug(3,Form(" mov_glo=( %f , %f , %f ) rf=( %f , %f , %f )\n",x2g,y2g,z2g, x2t,y2t,z2t));
+
+ if (TMath::Abs(y2g-y1g)<1e-15) {
+ AliInfo("DeltaY=0! Cannot proceed...");
+ return -1;
+ }
+ // ugx,1,ugz
+ v0g[0] = (x2g-x1g)/(y2g-y1g);
+ v0g[1]=1.0;
+ v0g[2] = (z2g-z1g)/(y2g-y1g);
+
+ // point: just keep prf
+ p0g[0]=x1g;
+ p0g[1]=y1g;
+ p0g[2]=z1g;
+ }
+ else { // staight line
+ // vector of initial straight line direction in glob. coord
+ v0g[0]=lpar[2];
+ v0g[1]=1.0;
+ v0g[2]=lpar[3];
+
+ // intercept in yg=0 plane in glob coord
+ p0g[0]=lpar[0];
+ p0g[1]=0.0;
+ p0g[2]=lpar[1];
+ }
+ AliDebug(3,Form("Line vector: ( %f , %f , %f ) point:( %f , %f , %f )\n",v0g[0],v0g[1],v0g[2],p0g[0],p0g[1],p0g[2]));
+
// same in local coord.
Double_t p0l[3],v0l[3];
fTempHMat->MasterToLocalVect(v0g,v0l);
fTempHMat->MasterToLocal(p0g,p0l);
-
+
if (TMath::Abs(v0l[1])<1e-15) {
AliInfo("Track Y direction in local frame is zero! Cannot proceed...");
return -1;
// global intersection point
fTempHMat->LocalToMaster(fPintLoc,fPintGlo);
AliDebug(3,Form("Intesect. point: L( %f , %f , %f ) G( %f , %f , %f )\n",fPintLoc[0],fPintLoc[1],fPintLoc[2],fPintGlo[0],fPintGlo[1],fPintGlo[2]));
-
+
return 0;
}
Int_t AliITSAlignMille::CalcDerivatives(Int_t paridx, Bool_t islpar) {
/// calculate numerically (ROOT's style) the derivatives for
/// local X intersection and local Z intersection
- /// parlist: local (islpar=kTRUE) pgx0, pgz0, ugx0, ugz0
+ /// parlist: local (islpar=kTRUE) pgx0, pgz0, ugx0, ugz0 OR riemann's params
/// global (islpar=kFALSE) tx, ty, tz, psi, theta, phi (Raf's angles in deg)
/// return 0 if success
for (Int_t i=0; i<ITSMILLE_NLOCAL; i++) lpar[i]=fLocalInitParam[i];
for (Int_t i=0; i<ITSMILLE_NPARCH; i++) gpar[i]=fModuleInitParam[i];
- // pepopepo
// trial with fixed dpar...
Double_t dpar=0.0;
- if (islpar) {
+
+ if (islpar) { // track parameters
//dpar=fLocalInitParam[paridx]*0.001;
// set minimum dpar
- if (paridx<2) dpar=1.0e-4; // translations
- else dpar=1.0e-6; // direction
+ if (!fBOn) {
+ if (paridx<2) dpar=1.0e-4; // translations
+ else dpar=1.0e-6; // direction
+ }
+ else { // B Field
+ // pepo: proviamo con 1/1000, poi evenctually 1/100...
+ Double_t dfrac=0.01;
+ switch(paridx) {
+ case 0:
+ // RMS cosmics: 1e-4
+ dpar = TMath::Max(1.0e-6,TMath::Abs(fLocalInitParam[paridx]*dfrac));
+ break;
+ case 1:
+ // RMS cosmics: 0.2
+ dpar = TMath::Max(0.002,TMath::Abs(fLocalInitParam[paridx]*dfrac));
+ break;
+ case 2:
+ // RMS cosmics: 9
+ dpar = TMath::Max(0.09,TMath::Abs(fLocalInitParam[paridx]*dfrac));
+ break;
+ case 3:
+ // RMS cosmics: 7
+ dpar = TMath::Max(0.07,TMath::Abs(fLocalInitParam[paridx]*dfrac));
+ break;
+ case 4:
+ // RMS cosmics: 0.3
+ dpar = TMath::Max(0.003,TMath::Abs(fLocalInitParam[paridx]*dfrac));
+ break;
+ }
+ }
}
- else {
+ else { // alignment global parameters
//dpar=fModuleInitParam[paridx]*0.001;
if (paridx<3) dpar=1.0e-4; // translations
else dpar=1.0e-2; // angles
}
- AliDebug(3,Form("\n+++ automatic dpar=%g\n",dpar));
- if (fDeltaPar) dpar=fDeltaPar;
- AliDebug(3,Form("+++ using dpar=%g\n\n",dpar));
+
+ AliDebug(3,Form("+++ using dpar=%g",dpar));
// calculate derivative ROOT's like:
// using f(x+h),f(x-h),f(x+h/2),f(x-h2)...
return 0;
}
-Int_t AliITSAlignMille::SetLocalEquations() {
- /// Define local equation for current track and cluster in x coor.
+
+Int_t AliITSAlignMille::AddLocalEquation(MilleData &m) {
+ /// Define local equation for current cluster in X and Z coor.
+ /// and store them to memory
/// return 0 if success
// store first interaction point
- CalcIntersectionPoint(fLocalInitParam, fModuleInitParam);
+ if (CalcIntersectionPoint(fLocalInitParam, fModuleInitParam)) return -4;
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];
- for (Int_t i=0; i<ITSMILLE_NLOCAL; i++) {
+ for (Int_t i=0; i<fNLocal; i++) {
if (CalcDerivatives(i,kTRUE)) return -1;
dXdL[i]=fDerivativeXLoc;
dZdL[i]=fDerivativeZLoc;
}
AliDebug(2,Form("\n***************\n"));
- for (Int_t i=0; i<ITSMILLE_NLOCAL; i++)
+ for (Int_t i=0; i<fNLocal; i++)
AliDebug(2,Form("Local parameter %d - dXdpar = %g - dZdpar = %g\n",i,dXdL[i],dZdL[i]));
for (Int_t i=0; i<ITSMILLE_NPARCH; i++)
AliDebug(2,Form("Global parameter %d - dXdpar = %g - dZdpar = %g\n",i,dXdG[i],dZdG[i]));
AliDebug(2,Form("\n***************\n"));
-
- AliDebug(2,Form("setting local equation X with fMeas=%.6f and fSigma=%.6f",(fMeasLoc[0]-fPintLoc0[0]), fSigmaLoc[0]));
+ // check if at least 1 local and 1 global derivs. are not null
+ Double_t nonzero=0.0;
+ for (Int_t i=0; i<fNLocal; i++) nonzero += TMath::Abs(dXdL[i]);
+ if (nonzero==0.0) {
+ AliInfo("Aborting local equations for this point beacuse of zero local X derivatives!");
+ return -2;
+ }
+ nonzero=0.0;
+ for (Int_t i=0; i<ITSMILLE_NPARCH; i++) nonzero += TMath::Abs(dXdG[i]);
+ if (nonzero==0.0) {
+ AliInfo("Aborting local equations for this point beacuse of zero global X derivatives!");
+ return -2;
+ }
+ nonzero=0.0;
+ for (Int_t i=0; i<fNLocal; i++) nonzero += TMath::Abs(dZdL[i]);
+ if (nonzero==0.0) {
+ AliInfo("Aborting local equations for this point beacuse of zero local Z derivatives!");
+ return -2;
+ }
+ nonzero=0.0;
+ for (Int_t i=0; i<ITSMILLE_NPARCH; i++) nonzero += TMath::Abs(dZdG[i]);
+ if (nonzero==0.0) {
+ AliInfo("Aborting local equations for this point beacuse of zero global Z derivatives!");
+ return -2;
+ }
+
+ // ok, can copy to m
+
+ AliDebug(2,Form("Adding local equation X with fMeas=%.6f and fSigma=%.6f",(fMeasLoc[0]-fPintLoc0[0]), fSigmaLoc[0]));
// set equation for Xloc coordinate
- for (Int_t i=0; i<ITSMILLE_NLOCAL; i++)
- SetLocalDerivative(i,dXdL[i]);
- for (Int_t i=0; i<ITSMILLE_NPARCH; i++)
- SetGlobalDerivative(fCurrentModuleInternalIndex*ITSMILLE_NPARCH+i,dXdG[i]);
- fMillepede->SetLocalEquation(fGlobalDerivatives, fLocalDerivatives, (fMeasLoc[0]-fPintLoc0[0]), fSigmaLoc[0]);
+ for (Int_t i=0; i<fNLocal; i++) {
+ m.idxlocX[i]=i;
+ m.derlocX[i]=dXdL[i];
+ }
+ for (Int_t i=0; i<ITSMILLE_NPARCH; i++) {
+ m.idxgloX[i]=fCurrentModuleInternalIndex*ITSMILLE_NPARCH+i;
+ m.dergloX[i]=dXdG[i];
+ }
+ m.measX = fMeasLoc[0]-fPintLoc0[0];
+ m.sigmaX = fSigmaLoc[0];
-
- AliDebug(2,Form("setting local equation Z with fMeas=%.6f and fSigma=%.6f",(fMeasLoc[2]-fPintLoc0[2]), fSigmaLoc[2]));
+ AliDebug(2,Form("Adding local equation Z with fMeas=%.6f and fSigma=%.6f",(fMeasLoc[2]-fPintLoc0[2]), fSigmaLoc[2]));
// set equation for Zloc coordinate
- for (Int_t i=0; i<ITSMILLE_NLOCAL; i++)
- SetLocalDerivative(i,dZdL[i]);
- for (Int_t i=0; i<ITSMILLE_NPARCH; i++)
- SetGlobalDerivative(fCurrentModuleInternalIndex*ITSMILLE_NPARCH+i,dZdG[i]);
- fMillepede->SetLocalEquation(fGlobalDerivatives, fLocalDerivatives, (fMeasLoc[2]-fPintLoc0[2]), fSigmaLoc[2]);
-
+ for (Int_t i=0; i<fNLocal; i++) {
+ m.idxlocZ[i]=i;
+ m.derlocZ[i]=dZdL[i];
+ }
+ for (Int_t i=0; i<ITSMILLE_NPARCH; i++) {
+ m.idxgloZ[i]=fCurrentModuleInternalIndex*ITSMILLE_NPARCH+i;
+ m.dergloZ[i]=dZdG[i];
+ }
+ m.measZ = fMeasLoc[2]-fPintLoc0[2];
+ m.sigmaZ = fSigmaLoc[2];
+
return 0;
}
+void AliITSAlignMille::SetLocalEquations(MilleData *m, Int_t neq) {
+ /// Set local equations with data stored in m
+ /// return 0 if success
+
+ for (Int_t j=0; j<neq; j++) {
+
+ AliDebug(2,Form("setting local equation X with fMeas=%.6f and fSigma=%.6f",m[j].measX, m[j].sigmaX));
+ // set equation for Xloc coordinate
+ for (Int_t i=0; i<fNLocal; i++)
+ SetLocalDerivative( m[j].idxlocX[i], m[j].derlocX[i] );
+
+ for (Int_t i=0; i<ITSMILLE_NPARCH; i++)
+ SetGlobalDerivative( m[j].idxgloX[i], m[j].dergloX[i] );
+
+ fMillepede->SetLocalEquation(fGlobalDerivatives, fLocalDerivatives, m[j].measX, m[j].sigmaX);
+
+
+ AliDebug(2,Form("setting local equation Z with fMeas=%.6f and fSigma=%.6f",m[j].measZ, m[j].sigmaZ));
+ // set equation for Zloc coordinate
+ for (Int_t i=0; i<fNLocal; i++)
+ SetLocalDerivative( m[j].idxlocZ[i], m[j].derlocZ[i] );
+
+ for (Int_t i=0; i<ITSMILLE_NPARCH; i++)
+ SetGlobalDerivative( m[j].idxgloZ[i], m[j].dergloZ[i] );
+
+ fMillepede->SetLocalEquation(fGlobalDerivatives, fLocalDerivatives, m[j].measZ, m[j].sigmaZ);
+ }
+}
+
+
void AliITSAlignMille::LocalFit(Int_t iTrack, Double_t *lTrackParam, Int_t lSingleFit) {
/// Call local fit for this track
if (!fIsMilleInit) {
#include <TString.h>
#include <TObject.h>
+#include <TArray.h>
#include "AliTrackPointArray.h"
class AliMillepede;
class TGeoManager;
class TGeoHMatrix;
class AliITSAlignMilleModule;
+class AliTrackFitterRieman;
// number of used objects
#define ITSMILLE_NDETELEM 2198
#define ITSMILLE_NPARCH 6
-#define ITSMILLE_NLOCAL 4
+#define ITSMILLE_NLOCAL 5
#define ITSMILLE_NSTDEV 3
+
+struct MilleData {
+ /// structure to store data for 2 LocalEquations (X and Z)
+ Double_t measX;
+ Double_t sigmaX;
+ Int_t idxlocX[ITSMILLE_NLOCAL];
+ Double_t derlocX[ITSMILLE_NLOCAL];
+ Int_t idxgloX[ITSMILLE_NPARCH];
+ Double_t dergloX[ITSMILLE_NPARCH];
+
+ Double_t measZ;
+ Double_t sigmaZ;
+ Int_t idxlocZ[ITSMILLE_NLOCAL];
+ Double_t derlocZ[ITSMILLE_NLOCAL];
+ Int_t idxgloZ[ITSMILLE_NPARCH];
+ Double_t dergloZ[ITSMILLE_NPARCH];
+};
+
class AliITSAlignMille:public TObject
{
-
public:
AliITSAlignMille(const Char_t *configFilename="AliITSAlignMille.conf", Bool_t initmille=kTRUE);
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);
const Char_t* GetPreAlignmentFileName() {return fPreAlignmentFileName.Data();}
void PrintCurrentModuleInfo();
void Print(Option_t*) const;
+ Bool_t IsConfigured() const {return fIsConfigured;}
+ void SetRequiredPoint(Char_t* where, Int_t ndet, Int_t updw, Int_t nreqpts);
// fitting methods
void SetMinNPtsPerTrack(Int_t pts=3) {fMinNPtsPerTrack=pts;}
Int_t ProcessTrack(AliTrackPointArray *track);
+ AliTrackPointArray *PrepareTrack(AliTrackPointArray *track); // build a new AliTrackPointArray with selected conditions
void InitTrackParams(int meth=1);
+ Bool_t InitRiemanFit();
+ AliTrackFitterRieman *GetRiemanFitter() const {return fRieman;}
Int_t InitModuleParams();
Int_t CheckCurrentTrack();
Bool_t CheckVolumeID(UShort_t voluid) const; // checks voluid for sensitive volumes
Double_t* GetLocalIntersectionPoint() {return fPintLoc;}
Double_t* GetGlobalIntersectionPoint() {return fPintGlo;}
void SetInitTrackParamsMeth(Int_t meth=1) {fInitTrackParamsMeth=meth;}
+ AliTrackPointArray *SortTrack(AliTrackPointArray *atp);
+ void SetTemporaryExcludedModule(Int_t index) {fTempExcludedModule=index;}
// millepede methods
void FixParameter(Int_t param, Double_t value);
void GlobalFit(Double_t *parameters,Double_t *errors,Double_t *pulls);
void PrintGlobalParameters();
Double_t GetParError(Int_t iPar);
- Int_t SetLocalEquations();
+ Int_t AddLocalEquation(MilleData &m);
+ void SetLocalEquations(MilleData *m, Int_t neq);
// fitting stuffs
AliTrackPointArray *GetCurrentTrack() {return fTrack;}
AliTrackPoint *GetCurrentCluster() {return &fCluster;}
+ void SetCurrentTrack(AliTrackPointArray *atp) {fTrack=atp;}
+ void SetCurrentCluster(AliTrackPoint &atp) {fCluster=atp;}
// geometry stuffs
- Int_t GetNModules() const {return fNModules;}
- Int_t GetCurrentModuleIndex() const {return fCurrentModuleIndex;}
+ Int_t GetNModules() const {return fNModules;}
+ Int_t GetCurrentModuleIndex() const {return fCurrentModuleIndex;}
TGeoHMatrix *GetCurrentModuleHMatrix() {return fCurrentModuleHMatrix;}
- Double_t *GetCurrentModuleTranslation() {return fCurrentModuleTranslation;}
- Int_t GetCurrentModuleInternalIndex() const {return fCurrentModuleInternalIndex;}
- Int_t *GetModuleIndexArray() {return fModuleIndex;}
+ Double_t *GetCurrentModuleTranslation() {return fCurrentModuleTranslation;}
+ Int_t GetCurrentModuleInternalIndex() const {return fCurrentModuleInternalIndex;}
+ Int_t *GetModuleIndexArray() {return fModuleIndex;}
+ Int_t *GetProcessedPoints() {return fProcessedPoints;}
+ Int_t GetTotBadLocEqPoints() const {return fTotBadLocEqPoints;}
AliITSAlignMilleModule *GetMilleModule(UShort_t voluid); // get pointer to the defined supermodule
AliITSAlignMilleModule *GetCurrentModule();
- UShort_t *GetModuleVolumeIDArray() {return fModuleVolumeID;}
-
+ UShort_t *GetModuleVolumeIDArray() {return fModuleVolumeID;}
+
+ // debug stuffs
+ Double_t *GetMeasLoc() { return fMeasLoc;}
+ Double_t *GetSigmaLoc() { return fSigmaLoc;}
+ Double_t GetBField() const {return fBField;}
+ Double_t *GetLocalInitParam() {return fLocalInitParam;}
+ Double_t GetLocalDX() const {return fDerivativeXLoc;}
+ Double_t GetLocalDZ() const {return fDerivativeZLoc;}
+ Double_t GetParSigTranslations() const {return fParSigTranslations;}
+ Double_t GetParSigRotations() const {return fParSigRotations;}
+ Int_t GetPreAlignmentQualityFactor(Int_t index); // if not prealign. return -1
+ void SetBug(Int_t bug) {fBug=bug;} // 1:SSD inversion sens.18-19
+
private:
// configuration methods
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; ///
+ Double_t fSigmaXfactor; ///
+ Double_t fSigmaZfactor; ///
AliAlignObjParams *fTempAlignObj; ///
Double_t fDerivativeXLoc; // localX deriv.
Double_t fDerivativeZLoc; // localZ deriv.
- Double_t fDeltaPar; ///
Int_t fMinNPtsPerTrack; ///
Int_t fInitTrackParamsMeth; ///
+ Int_t *fProcessedPoints; /// array of statistics of used points per module
+ Int_t fTotBadLocEqPoints; /// total number of reject points because of bad EqLoc
+ AliTrackFitterRieman *fRieman; /// riemann fitter for helices
+ Bool_t fRequirePoints; // required points in specific layers
+ Int_t fNReqLayUp[6]; /// number of points required in layer[n] with Y>0
+ Int_t fNReqLayDown[6]; /// number of points required in layer[n] with Y<0
+ Int_t fNReqLay[6]; /// number of points required in layer[n]
+ Int_t fNReqDetUp[3]; /// number of points required in Detector[n] with Y>0
+ Int_t fNReqDetDown[3]; /// number of points required in Detector[n] with Y<0
+ Int_t fNReqDet[3]; /// number of points required in Detector[n]
+ Int_t fTempExcludedModule; /// single module temporary excluded from initial fit
// geometry stuffs
TString fGeometryFileName; ///
Bool_t fUseLocalShifts; ///
Bool_t fUseSuperModules; ///
Bool_t fUsePreAlignment; ///
+ Bool_t fUseSortedTracks; /// default is kTRUE
+ Bool_t fBOn; /// magentic field ON
+ Double_t fBField; /// value of magnetic field
Int_t fNSuperModules; /// number of custom supermodules in SM file
TGeoHMatrix *fCurrentModuleHMatrix; /// SuperModule matrix
+ Bool_t fIsConfigured; ///
+ Int_t fPreAlignQF[ITSMILLE_NDETELEM*2]; ///
+ Double_t fSensVolSigmaXfactor[ITSMILLE_NDETELEM*2]; ///
+ Double_t fSensVolSigmaZfactor[ITSMILLE_NDETELEM*2]; ///
+ Int_t fBug; /// tag for temporary bug correction
AliITSAlignMilleModule *fMilleModule[ITSMILLE_NDETELEM*2]; /// array of super modules to be aligned
-/************************************************************************** \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) const \r
-{\r
- /// check if voluid is defined\r
- if (!voluid) return kFALSE; // only positive voluid are accepted\r
- for (Int_t i=0; i<fNSensVol; i++) {\r
- if (fSensVolVolumeID[i]==voluid) return kTRUE;\r
- }\r
- return kFALSE;\r
-}\r
-//-------------------------------------------------------------\r
-TGeoHMatrix *AliITSAlignMilleModule::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, Double_t *deltalocal)\r
-{\r
- // modify the original TGeoHMatrix of the sensitive module 'voluid' according\r
- // with a delta transform. applied to the supermodule matrix\r
- // return NULL if error\r
-\r
- if (!IsIn(voluid)) return NULL;\r
- if (!gGeoManager) return NULL;\r
-\r
- // prepare the TGeoHMatrix\r
- Double_t tr[3],ang[3];\r
- tr[0]=deltalocal[0]; // in centimeter\r
- tr[1]=deltalocal[1]; \r
- tr[2]=deltalocal[2];\r
- ang[0]=deltalocal[3]; // psi (X) in deg\r
- ang[1]=deltalocal[4]; // theta (Y)\r
- ang[2]=deltalocal[5]; // phi (Z)\r
-\r
- // reset align object (may not be needed...)\r
- fTempAlignObj->SetTranslation(0,0,0);\r
- fTempAlignObj->SetRotation(0,0,0);\r
-\r
- fTempAlignObj->SetRotation(ang[0],ang[1],ang[2]);\r
- fTempAlignObj->SetTranslation(tr[0],tr[1],tr[2]);\r
- AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r
- TGeoHMatrix hm;\r
- fTempAlignObj->GetMatrix(hm);\r
- //printf("\n0: delta matrix\n");hm.Print();\r
-\r
- // 1) start setting fSensVolModif = fSensVol\r
- if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;\r
- //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();\r
-\r
- // 2) set fSensVolModif = SensVolRel\r
- fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
- //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();\r
- \r
- // 3) multiply left by delta\r
- fSensVolModifMatrix->MultiplyLeft( &hm );\r
- //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();\r
- \r
- // 4) multiply left by fMatrix\r
- fSensVolModifMatrix->MultiplyLeft( fMatrix );\r
- //printf("\n4: modif=finale\n");fSensVolModifMatrix->Print();\r
-\r
- return fSensVolModifMatrix;\r
-}\r
-//-------------------------------------------------------------\r
-AliAlignObjParams *AliITSAlignMilleModule::GetSensitiveVolumeMisalignment(UShort_t voluid, Double_t *deltalocal)\r
-{\r
- // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'\r
- // of the mother volume. The misalignment is returned as AliAlignObjParams object\r
-\r
- if (!IsIn(voluid)) return NULL;\r
- if (!gGeoManager) return NULL;\r
- \r
- // prepare the TGeoHMatrix\r
- Double_t tr[3],ang[3];\r
- tr[0]=deltalocal[0]; // in centimeter\r
- tr[1]=deltalocal[1]; \r
- tr[2]=deltalocal[2];\r
- ang[0]=deltalocal[3]; // psi (X) in deg\r
- ang[1]=deltalocal[4]; // theta (Y)\r
- ang[2]=deltalocal[5]; // phi (Z)\r
-\r
- // reset align object (may not be needed...)\r
- fTempAlignObj->SetTranslation(0,0,0);\r
- fTempAlignObj->SetRotation(0,0,0);\r
-\r
- fTempAlignObj->SetRotation(ang[0],ang[1],ang[2]);\r
- fTempAlignObj->SetTranslation(tr[0],tr[1],tr[2]);\r
- AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r
- \r
- return GetSensitiveVolumeMisalignment(voluid,fTempAlignObj);\r
-}\r
-//-------------------------------------------------------------\r
-AliAlignObjParams *AliITSAlignMilleModule::GetSensitiveVolumeMisalignment(UShort_t voluid, AliAlignObjParams *a)\r
-{\r
- // return the misalignment of the sens. vol. 'voluid' corresponding with \r
- // a misalignment 'a' in the mother volume\r
- // return NULL if error\r
-\r
- // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv\r
- // G'sv = Gg * Dg * Lsv,g === Gsv * Dsv\r
- // Gg * Dg * Gg-1 * Gsv = Gsv * Gsv-1 * Gg * Dg * Gg-1 * Gsv\r
- //\r
- // => Dsv = (Gsv-1 * Gg * Dg * Gg-1 * Gsv)\r
- //\r
-\r
- if (!IsIn(voluid)) return NULL;\r
- if (!gGeoManager) return NULL;\r
-\r
- //a->Print("");\r
-\r
- // prepare the Delta matrix Dg\r
- TGeoHMatrix dg;\r
- a->GetMatrix(dg);\r
- //dg.Print();\r
-\r
- // 1) start setting fSensVolModif = Gsv\r
- if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;\r
- //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();\r
-\r
- // 2) set fSensVolModif = Gg-1 * Gsv\r
- fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
- //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();\r
- \r
- // 3) set fSensVolModif = Dg * Gg-1 * Gsv\r
- fSensVolModifMatrix->MultiplyLeft( &dg );\r
- //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();\r
- \r
- // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv\r
- fSensVolModifMatrix->MultiplyLeft( fMatrix );\r
- //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();\r
-\r
- // 5) set fSensVolModif = Gsv-1 * Gg * Dg * Gg-1 * Gsv\r
- if (SensVolMatrix(voluid, &dg)) return NULL;\r
- fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );\r
- //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();\r
-\r
- // reset align object (may not be needed...)\r
- fTempAlignObj->SetTranslation(0,0,0);\r
- fTempAlignObj->SetRotation(0,0,0);\r
-\r
- if (!fTempAlignObj->SetMatrix(*fSensVolModifMatrix)) return NULL;\r
- fTempAlignObj->SetVolUID(voluid);\r
- fTempAlignObj->SetSymName(AliGeomManager::SymName(voluid));\r
- \r
- //fTempAlignObj->Print("");\r
-\r
- return fTempAlignObj;\r
-}\r
-//-------------------------------------------------------------\r
-TGeoHMatrix *AliITSAlignMilleModule::GetSensitiveVolumeMatrix(UShort_t voluid)\r
-{\r
- // return TGeoHMatrix of the sens.vol. 'voluid' in the current geometry\r
- if (SensVolMatrix(voluid,fSensVolMatrix)) return NULL;\r
- return fSensVolMatrix;\r
-}\r
-//-------------------------------------------------------------\r
-TGeoHMatrix *AliITSAlignMilleModule::GetSensitiveVolumeOrigGlobalMatrix(UShort_t voluid)\r
-{\r
- // return original ideal position (from AliGeomManager::GetOrigGlobalMatrix())\r
- if (SensVolOrigGlobalMatrix(voluid,fSensVolMatrix)) return NULL;\r
- return fSensVolMatrix;\r
-}\r
-//-------------------------------------------------------------\r
-Int_t AliITSAlignMilleModule::SensVolMatrix(UShort_t volid, TGeoHMatrix *m) \r
-{\r
- // set matrix for sensitive modules (SPD corrected)\r
- // return 0 if success\r
- Double_t rot[9];\r
- Int_t idx=GetIndexFromVolumeID(volid);\r
- if (idx<0) return -1;\r
- if (!AliITSgeomTGeo::GetRotation(idx,rot)) return -2;\r
- m->SetRotation(rot);\r
- Double_t oLoc[3]={0,0,0};\r
- Double_t oGlo[3]={0,0,0};\r
- if (!AliITSgeomTGeo::LocalToGlobal(idx,oLoc,oGlo)) return -3;\r
- m->SetTranslation(oGlo);\r
- return 0;\r
-}\r
-//-------------------------------------------------------------\r
-Int_t AliITSAlignMilleModule::SensVolOrigGlobalMatrix(UShort_t volid, TGeoHMatrix *m) \r
-{\r
- // set original global matrix for sensitive modules (SPD corrected)\r
- // return 0 if success\r
- Int_t idx=GetIndexFromVolumeID(volid);\r
- if (idx<0) return -1;\r
- TGeoHMatrix mo;\r
- if (!AliGeomManager::GetOrigGlobalMatrix(AliGeomManager::SymName(volid),mo));\r
- (*m)=mo;\r
-\r
- // SPD y-shift by 81 mu\r
- Double_t oLoc[3]={0.0,0.0081,0.0};\r
- Double_t oGlo[3]={0,0,0};\r
- m->LocalToMaster(oLoc,oGlo);\r
- m->SetTranslation(oGlo);\r
- return 0;\r
-}\r
-//-------------------------------------------------------------\r
-UShort_t AliITSAlignMilleModule::GetVolumeIDFromSymname(const Char_t *symname) {\r
- /// volume ID from symname\r
- if (!symname) return 0;\r
-\r
- for (UShort_t voluid=2000; voluid<13300; voluid++) {\r
- Int_t modId;\r
- AliGeomManager::ELayerID layerId = AliGeomManager::VolUIDToLayer(voluid,modId);\r
- if (layerId>0 && layerId<7 && modId>=0 && modId<AliGeomManager::LayerSize(layerId)) {\r
- if (!strcmp(symname,AliGeomManager::SymName(layerId,modId))) return voluid;\r
- }\r
- }\r
-\r
- return 0;\r
-}\r
-\r
-UShort_t AliITSAlignMilleModule::GetVolumeIDFromIndex(Int_t index) {\r
- /// volume ID from index\r
- if (index<0 || index>2197) return 0;\r
- return GetVolumeIDFromSymname(AliITSgeomTGeo::GetSymName(index));\r
-}\r
-//-------------------------------------------------------------\r
-void AliITSAlignMilleModule::Print(Option_t*) const \r
-{\r
- ///\r
- printf("*** ITS SuperModule for AliITSAlignMille ***\n");\r
- printf("symname : %s\n",GetName());\r
- printf("volumeID : %d\n",fVolumeID);\r
- printf("index : %d\n",fIndex);\r
- fMatrix->Print();\r
- printf("number of sensitive modules : %d\n",fNSensVol);\r
- for (Int_t i=0; i<fNSensVol; i++) printf(" voluid[%d] = %d\n",i,fSensVolVolumeID[i]);\r
-}\r
-//_____________________________________________________________________________\r
-AliITSAlignMilleModule::AliITSAlignMilleModule(const AliITSAlignMilleModule &m) :\r
- TNamed(m),\r
- fNSensVol(m.fNSensVol),\r
- fIndex(m.fIndex),\r
- fVolumeID(m.fVolumeID),\r
- fMatrix(new TGeoHMatrix(*m.GetMatrix())),\r
- fSensVolMatrix(new TGeoHMatrix),\r
- fSensVolModifMatrix(new TGeoHMatrix),\r
- fTempAlignObj(new AliAlignObjParams)\r
-{\r
- // Copy constructor\r
- for (int i=0; i<fNSensVol; i++) {\r
- fSensVolIndex[i]=m.fSensVolIndex[i];\r
- fSensVolVolumeID[i]=m.fSensVolVolumeID[i];\r
- }\r
-}\r
-//_____________________________________________________________________________\r
-AliITSAlignMilleModule& AliITSAlignMilleModule::operator=(const AliITSAlignMilleModule &m) \r
-{\r
- // operator =\r
- //\r
- if(this==&m) return *this;\r
- ((TNamed *)this)->operator=(m);\r
- \r
- fNSensVol=m.fNSensVol;\r
- fIndex=m.fIndex;\r
- fVolumeID=m.fVolumeID;\r
- delete fMatrix;\r
- fMatrix=new TGeoHMatrix(*m.GetMatrix());\r
- for (int i=0; i<fNSensVol; i++) {\r
- fSensVolIndex[i]=m.fSensVolIndex[i];\r
- fSensVolVolumeID[i]=m.fSensVolVolumeID[i];\r
- }\r
- return *this;\r
-}\r
-\r
-//_____________________________________________________________________________\r
-\r
-\r
+/**************************************************************************
+ * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Id$ */
+//-----------------------------------------------------------------------------
+/// \class AliITSAlignMilleModule
+/// Alignment class for the ALICE ITS detector
+///
+/// This class is used by AliITSAlignMille to build custom supermodules
+/// made of ITS sensitive modules. These supermodules are then aligned
+///
+/// Custom supermodules must have VolumeID > 14335
+///
+/// \author M. Lunardon
+//-----------------------------------------------------------------------------
+
+#include <TGeoManager.h>
+#include <TGeoMatrix.h>
+
+#include "AliITSAlignMilleModule.h"
+#include "AliITSgeomTGeo.h"
+#include "AliGeomManager.h"
+#include "AliAlignObjParams.h"
+#include "AliLog.h"
+
+/// \cond CLASSIMP
+ClassImp(AliITSAlignMilleModule)
+/// \endcond
+
+//-------------------------------------------------------------
+AliITSAlignMilleModule::AliITSAlignMilleModule() : TNamed(),
+ fNSensVol(0),
+ fIndex(-1),
+ fVolumeID(0),
+ fMatrix(NULL),
+ fSensVolMatrix(NULL),
+ fSensVolModifMatrix(NULL),
+ fTempAlignObj(NULL)
+{
+ /// void constructor
+ fMatrix = new TGeoHMatrix;
+ fSensVolMatrix = new TGeoHMatrix;
+ fSensVolModifMatrix = new TGeoHMatrix;
+ fTempAlignObj=new AliAlignObjParams;
+}
+//-------------------------------------------------------------
+AliITSAlignMilleModule::AliITSAlignMilleModule(Int_t index, UShort_t volid, char* symname, TGeoHMatrix *m, Int_t nsv, UShort_t *volidsv) : TNamed(),
+ fNSensVol(0),
+ fIndex(-1),
+ fVolumeID(0),
+ fMatrix(NULL),
+ fSensVolMatrix(NULL),
+ fSensVolModifMatrix(NULL),
+ fTempAlignObj(NULL)
+{
+ /// void constructor
+ fMatrix = new TGeoHMatrix;
+ fSensVolMatrix = new TGeoHMatrix;
+ fSensVolModifMatrix = new TGeoHMatrix;
+ fTempAlignObj=new AliAlignObjParams;
+ if (Set(index,volid,symname,m,nsv,volidsv)) {
+ AliInfo("Error in AliITSAlignMilleModule::Set() - initializing void supermodule...");
+ }
+}
+//-------------------------------------------------------------
+AliITSAlignMilleModule::AliITSAlignMilleModule(UShort_t volid) : TNamed(),
+ fNSensVol(0),
+ fIndex(-1),
+ fVolumeID(0),
+ fMatrix(NULL),
+ fSensVolMatrix(NULL),
+ fSensVolModifMatrix(NULL),
+ fTempAlignObj(NULL)
+{
+ /// simple constructor building a supermodule from a single sensitive volume
+ fMatrix = new TGeoHMatrix;
+ fSensVolMatrix = new TGeoHMatrix;
+ fSensVolModifMatrix = new TGeoHMatrix;
+ // temporary align object, just use the rotation...
+ fTempAlignObj=new AliAlignObjParams;
+
+ fIndex = GetIndexFromVolumeID(volid);
+ if (fIndex>=0 && gGeoManager) { // good sensitive module and geometry loaded
+ SetName(AliGeomManager::SymName(volid));
+ fVolumeID = volid;
+ AddSensitiveVolume(volid);
+ if (SensVolMatrix(volid, fMatrix))
+ AliInfo("Matrix not defined");
+ }
+ else {
+ AliInfo("Wrong VolumeID or Geometry not loaded - initializing void supermodule...");
+ }
+}
+//-------------------------------------------------------------
+AliITSAlignMilleModule::~AliITSAlignMilleModule() {
+ /// Destructor
+ delete fMatrix;
+ delete fSensVolMatrix;
+ delete fSensVolModifMatrix;
+ delete fTempAlignObj;
+}
+//-------------------------------------------------------------
+Int_t AliITSAlignMilleModule::Set(Int_t index, UShort_t volid, char* symname, TGeoHMatrix *m, Int_t nsv, UShort_t *volidsv)
+{
+ // initialize a custom supermodule
+ // index, volid, symname and matrix must be given
+ // if (volidsv) add nsv sensitive volumes to the supermodules
+ // return 0 if success
+
+ if (index<2198) {
+ AliInfo("Index must be >= 2198");
+ return -1;
+ }
+ if (volid<14336) {
+ AliInfo("VolumeID must be >= 14336");
+ return -2;
+ }
+
+ if (!symname) return -3;
+ for (Int_t i=0; i<2198; i++) {
+ if (!strcmp(symname,AliITSgeomTGeo::GetSymName(i))) {
+ AliInfo("Symname already used by a Sensitive Volume");
+ return -3;
+ }
+ }
+
+ if (!m) return -4;
+
+ // can initialize needed stuffs
+ fIndex = index;
+ fVolumeID = volid;
+ SetName(symname);
+ (*fMatrix) = (*m);
+
+ // add sensitive volumes
+ for (Int_t i=0; i<nsv; i++) AddSensitiveVolume(volidsv[i]);
+
+ return 0;
+}
+//-------------------------------------------------------------
+Int_t AliITSAlignMilleModule::GetIndexFromVolumeID(UShort_t voluid) {
+ /// index from volume ID
+ AliGeomManager::ELayerID lay = AliGeomManager::VolUIDToLayer(voluid);
+ if (lay<1|| lay>6) return -1;
+ Int_t idx=Int_t(voluid)-2048*lay;
+ if (idx>=AliGeomManager::LayerSize(lay)) return -1;
+ for (Int_t ilay=1; ilay<lay; ilay++)
+ idx += AliGeomManager::LayerSize(ilay);
+ return idx;
+}
+//-------------------------------------------------------------
+void AliITSAlignMilleModule::AddSensitiveVolume(UShort_t voluid)
+{
+ /// add a sensitive volume to this supermodule
+ if (GetIndexFromVolumeID(voluid)<0) return; // bad volid
+ fSensVolVolumeID[fNSensVol] = voluid;
+ fSensVolIndex[fNSensVol] = GetIndexFromVolumeID(voluid);
+ fNSensVol++;
+}
+//-------------------------------------------------------------
+Bool_t AliITSAlignMilleModule::IsIn(UShort_t voluid) const
+{
+ /// check if voluid is defined
+ if (!voluid) return kFALSE; // only positive voluid are accepted
+ for (Int_t i=0; i<fNSensVol; i++) {
+ if (fSensVolVolumeID[i]==voluid) return kTRUE;
+ }
+ return kFALSE;
+}
+//-------------------------------------------------------------
+TGeoHMatrix *AliITSAlignMilleModule::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, Double_t *deltalocal)
+{
+ // modify the original TGeoHMatrix of the sensitive module 'voluid' according
+ // with a delta transform. applied to the supermodule matrix
+ // return NULL if error
+
+ if (!IsIn(voluid)) return NULL;
+ if (!gGeoManager) return NULL;
+
+ // prepare the TGeoHMatrix
+ Double_t tr[3],ang[3];
+ tr[0]=deltalocal[0]; // in centimeter
+ tr[1]=deltalocal[1];
+ tr[2]=deltalocal[2];
+ ang[0]=deltalocal[3]; // psi (X) in deg
+ ang[1]=deltalocal[4]; // theta (Y)
+ ang[2]=deltalocal[5]; // phi (Z)
+
+ // reset align object (may not be needed...)
+ fTempAlignObj->SetTranslation(0,0,0);
+ fTempAlignObj->SetRotation(0,0,0);
+
+ fTempAlignObj->SetRotation(ang[0],ang[1],ang[2]);
+ fTempAlignObj->SetTranslation(tr[0],tr[1],tr[2]);
+ AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
+ TGeoHMatrix hm;
+ fTempAlignObj->GetMatrix(hm);
+ //printf("\n0: delta matrix\n");hm.Print();
+
+ // 1) start setting fSensVolModif = fSensVol
+ if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
+ //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
+
+ // 2) set fSensVolModif = SensVolRel
+ fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
+ //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
+
+ // 3) multiply left by delta
+ fSensVolModifMatrix->MultiplyLeft( &hm );
+ //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
+
+ // 4) multiply left by fMatrix
+ fSensVolModifMatrix->MultiplyLeft( fMatrix );
+ //printf("\n4: modif=finale\n");fSensVolModifMatrix->Print();
+
+ return fSensVolModifMatrix;
+}
+//-------------------------------------------------------------
+AliAlignObjParams *AliITSAlignMilleModule::GetSensitiveVolumeMisalignment(UShort_t voluid, Double_t *deltalocal)
+{
+ // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
+ // of the mother volume. The misalignment is returned as AliAlignObjParams object
+
+ if (!IsIn(voluid)) return NULL;
+ if (!gGeoManager) return NULL;
+
+ // prepare the TGeoHMatrix
+ Double_t tr[3],ang[3];
+ tr[0]=deltalocal[0]; // in centimeter
+ tr[1]=deltalocal[1];
+ tr[2]=deltalocal[2];
+ ang[0]=deltalocal[3]; // psi (X) in deg
+ ang[1]=deltalocal[4]; // theta (Y)
+ ang[2]=deltalocal[5]; // phi (Z)
+
+ // reset align object (may not be needed...)
+ fTempAlignObj->SetTranslation(0,0,0);
+ fTempAlignObj->SetRotation(0,0,0);
+
+ fTempAlignObj->SetRotation(ang[0],ang[1],ang[2]);
+ fTempAlignObj->SetTranslation(tr[0],tr[1],tr[2]);
+ AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
+
+ return GetSensitiveVolumeMisalignment(voluid,fTempAlignObj);
+}
+//-------------------------------------------------------------
+AliAlignObjParams *AliITSAlignMilleModule::GetSensitiveVolumeMisalignment(UShort_t voluid, AliAlignObjParams *a)
+{
+ // return the misalignment of the sens. vol. 'voluid' corresponding with
+ // a misalignment 'a' in the mother volume
+ // return NULL if error
+
+ // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv
+ // G'sv = Gg * Dg * Lsv,g === Gsv * Dsv
+ // Gg * Dg * Gg-1 * Gsv = Gsv * Gsv-1 * Gg * Dg * Gg-1 * Gsv
+ //
+ // => Dsv = (Gsv-1 * Gg * Dg * Gg-1 * Gsv)
+ //
+
+ if (!IsIn(voluid)) return NULL;
+ if (!gGeoManager) return NULL;
+
+ //a->Print("");
+
+ // prepare the Delta matrix Dg
+ TGeoHMatrix dg;
+ a->GetMatrix(dg);
+ //dg.Print();
+
+ // 1) start setting fSensVolModif = Gsv
+ if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
+ //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
+
+ // 2) set fSensVolModif = Gg-1 * Gsv
+ fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
+ //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
+
+ // 3) set fSensVolModif = Dg * Gg-1 * Gsv
+ fSensVolModifMatrix->MultiplyLeft( &dg );
+ //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
+
+ // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv
+ fSensVolModifMatrix->MultiplyLeft( fMatrix );
+ //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();
+
+ // 5) set fSensVolModif = Gsv-1 * Gg * Dg * Gg-1 * Gsv
+ if (SensVolMatrix(voluid, &dg)) return NULL;
+ fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );
+ //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();
+
+ // reset align object (may not be needed...)
+ fTempAlignObj->SetTranslation(0,0,0);
+ fTempAlignObj->SetRotation(0,0,0);
+
+ if (!fTempAlignObj->SetMatrix(*fSensVolModifMatrix)) return NULL;
+ fTempAlignObj->SetVolUID(voluid);
+ fTempAlignObj->SetSymName(AliGeomManager::SymName(voluid));
+
+ //fTempAlignObj->Print("");
+
+ return fTempAlignObj;
+}
+//-------------------------------------------------------------
+TGeoHMatrix *AliITSAlignMilleModule::GetSensitiveVolumeMatrix(UShort_t voluid)
+{
+ // return TGeoHMatrix of the sens.vol. 'voluid' in the current geometry
+ if (SensVolMatrix(voluid,fSensVolMatrix)) return NULL;
+ return fSensVolMatrix;
+}
+//-------------------------------------------------------------
+TGeoHMatrix *AliITSAlignMilleModule::GetSensitiveVolumeOrigGlobalMatrix(UShort_t voluid)
+{
+ // return original ideal position (from AliGeomManager::GetOrigGlobalMatrix())
+ if (SensVolOrigGlobalMatrix(voluid,fSensVolMatrix)) return NULL;
+ return fSensVolMatrix;
+}
+//-------------------------------------------------------------
+Int_t AliITSAlignMilleModule::SensVolMatrix(UShort_t volid, TGeoHMatrix *m)
+{
+ // set matrix for sensitive modules (SPD corrected)
+ // return 0 if success
+ Double_t rot[9];
+ Int_t idx=GetIndexFromVolumeID(volid);
+ if (idx<0) return -1;
+ if (!AliITSgeomTGeo::GetRotation(idx,rot)) return -2;
+ m->SetRotation(rot);
+ Double_t oLoc[3]={0,0,0};
+ Double_t oGlo[3]={0,0,0};
+ if (!AliITSgeomTGeo::LocalToGlobal(idx,oLoc,oGlo)) return -3;
+ m->SetTranslation(oGlo);
+ return 0;
+}
+//-------------------------------------------------------------
+Int_t AliITSAlignMilleModule::SensVolOrigGlobalMatrix(UShort_t volid, TGeoHMatrix *m)
+{
+ // set original global matrix for sensitive modules (SPD corrected)
+ // return 0 if success
+ Int_t idx=GetIndexFromVolumeID(volid);
+ if (idx<0) return -1;
+ TGeoHMatrix mo;
+ if (!AliGeomManager::GetOrigGlobalMatrix(AliGeomManager::SymName(volid),mo));
+ (*m)=mo;
+
+ // SPD y-shift by 81 mu
+ if (volid<5000) {
+ Double_t oLoc[3]={0.0,0.0081,0.0};
+ Double_t oGlo[3]={0,0,0};
+ m->LocalToMaster(oLoc,oGlo);
+ m->SetTranslation(oGlo);
+ }
+ return 0;
+}
+//-------------------------------------------------------------
+UShort_t AliITSAlignMilleModule::GetVolumeIDFromSymname(const Char_t *symname) {
+ /// volume ID from symname
+ if (!symname) return 0;
+
+ for (UShort_t voluid=2000; voluid<13300; voluid++) {
+ Int_t modId;
+ AliGeomManager::ELayerID layerId = AliGeomManager::VolUIDToLayer(voluid,modId);
+ if (layerId>0 && layerId<7 && modId>=0 && modId<AliGeomManager::LayerSize(layerId)) {
+ if (!strcmp(symname,AliGeomManager::SymName(layerId,modId))) return voluid;
+ }
+ }
+
+ return 0;
+}
+
+UShort_t AliITSAlignMilleModule::GetVolumeIDFromIndex(Int_t index) {
+ /// volume ID from index
+ if (index<0 || index>2197) return 0;
+ return GetVolumeIDFromSymname(AliITSgeomTGeo::GetSymName(index));
+}
+//-------------------------------------------------------------
+void AliITSAlignMilleModule::Print(Option_t*) const
+{
+ ///
+ printf("*** ITS SuperModule for AliITSAlignMille ***\n");
+ printf("symname : %s\n",GetName());
+ printf("volumeID : %d\n",fVolumeID);
+ printf("index : %d\n",fIndex);
+ fMatrix->Print();
+ printf("number of sensitive modules : %d\n",fNSensVol);
+ for (Int_t i=0; i<fNSensVol; i++) printf(" voluid[%d] = %d\n",i,fSensVolVolumeID[i]);
+}
+//_____________________________________________________________________________
+AliITSAlignMilleModule::AliITSAlignMilleModule(const AliITSAlignMilleModule &m) :
+ TNamed(m),
+ fNSensVol(m.fNSensVol),
+ fIndex(m.fIndex),
+ fVolumeID(m.fVolumeID),
+ fMatrix(new TGeoHMatrix(*m.GetMatrix())),
+ fSensVolMatrix(new TGeoHMatrix),
+ fSensVolModifMatrix(new TGeoHMatrix),
+ fTempAlignObj(new AliAlignObjParams)
+{
+ // Copy constructor
+ for (int i=0; i<fNSensVol; i++) {
+ fSensVolIndex[i]=m.fSensVolIndex[i];
+ fSensVolVolumeID[i]=m.fSensVolVolumeID[i];
+ }
+}
+//_____________________________________________________________________________
+AliITSAlignMilleModule& AliITSAlignMilleModule::operator=(const AliITSAlignMilleModule &m)
+{
+ // operator =
+ //
+ if(this==&m) return *this;
+ ((TNamed *)this)->operator=(m);
+
+ fNSensVol=m.fNSensVol;
+ fIndex=m.fIndex;
+ fVolumeID=m.fVolumeID;
+ delete fMatrix;
+ fMatrix=new TGeoHMatrix(*m.GetMatrix());
+ for (int i=0; i<fNSensVol; i++) {
+ fSensVolIndex[i]=m.fSensVolIndex[i];
+ fSensVolVolumeID[i]=m.fSensVolVolumeID[i];
+ }
+ return *this;
+}
+
+//_____________________________________________________________________________
+
+
-#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) const;\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
+#ifndef ALIITSALIGNMILLEMODULE_H
+#define ALIITSALIGNMILLEMODULE_H
+/* Copyright(c) 2007-2009 , ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/// \ingroup rec
+/// \class AliITSAlignMilleModule
+/// \brief Class for alignment of ITS
+//
+// Authors: Marcello Lunardon
+
+/* $Id$ */
+//#include <TString.h>
+//#include <TObject.h>
+#include <TNamed.h>
+
+#define ITSMILLE_NSENSVOL 2198
+
+class AliAlignObjParams;
+class TGeoHMatrix;
+
+class AliITSAlignMilleModule : public TNamed
+{
+public:
+ AliITSAlignMilleModule();
+ AliITSAlignMilleModule(UShort_t volid); // basic single volume constructor
+ AliITSAlignMilleModule(Int_t index, UShort_t volid, char* symname, TGeoHMatrix *m, Int_t nsv=0, UShort_t *volidsv=NULL); // general constructor
+
+ AliITSAlignMilleModule(const AliITSAlignMilleModule& rhs); // copy constructor
+ AliITSAlignMilleModule& operator=(const AliITSAlignMilleModule& rhs);
+
+ virtual ~AliITSAlignMilleModule();
+
+ // geometry methods
+ Int_t GetIndex() const {return fIndex;}
+ UShort_t GetVolumeID() const {return fVolumeID;}
+ Int_t GetNSensitiveVolumes() const {return fNSensVol;}
+ TGeoHMatrix *GetMatrix() const {return fMatrix;}
+ UShort_t *GetSensitiveVolumeVolumeID() {return fSensVolVolumeID;}
+
+ 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
+
+ // util
+ static Int_t GetIndexFromVolumeID(UShort_t volid);
+ static UShort_t GetVolumeIDFromSymname(const Char_t *symname);
+ static UShort_t GetVolumeIDFromIndex(Int_t index);
+
+ // methods
+ Bool_t IsIn(UShort_t volid) const;
+ TGeoHMatrix *GetSensitiveVolumeMatrix(UShort_t voluid);
+ TGeoHMatrix *GetSensitiveVolumeOrigGlobalMatrix(UShort_t voluid);
+ TGeoHMatrix *GetSensitiveVolumeModifiedMatrix(UShort_t voluid, Double_t *deltalocal);
+ AliAlignObjParams *GetSensitiveVolumeMisalignment(UShort_t voluid, AliAlignObjParams *a);
+ AliAlignObjParams *GetSensitiveVolumeMisalignment(UShort_t voluid, Double_t *deltalocal);
+ void Print(Option_t*) const;
+
+protected:
+ Int_t SensVolMatrix(UShort_t volid, TGeoHMatrix *m);
+ Int_t SensVolOrigGlobalMatrix(UShort_t volid, TGeoHMatrix *m);
+ void AddSensitiveVolume(UShort_t volid);
+
+private:
+ Int_t fNSensVol; ///
+ Int_t fIndex; ///
+ UShort_t fVolumeID; ///
+ // il symname e' il nome del TNamed...
+ Int_t fSensVolIndex[ITSMILLE_NSENSVOL]; ///
+ UShort_t fSensVolVolumeID[ITSMILLE_NSENSVOL]; ///
+ TGeoHMatrix *fMatrix; /// ideal TGeoHMatrix of the supermodule
+ TGeoHMatrix *fSensVolMatrix; ///
+ TGeoHMatrix *fSensVolModifMatrix; ///
+ AliAlignObjParams *fTempAlignObj; ///
+
+ ClassDef(AliITSAlignMilleModule, 0)
+
+};
+
+#endif
-#if !defined(__CINT__) || defined(__MAKECINT__)\r
-#include <Riostream.h>\r
-#include <TChain.h>\r
-#include <TClonesArray.h>\r
-#include <TFile.h>\r
-#include <TMath.h>\r
-#include <TStopwatch.h>\r
-#include "AliAlignObjParams.h"\r
-#include "AliTrackPointArray.h"\r
-#include "AliITSAlignMille.h"\r
-#endif\r
-//********************************************************************\r
-// Example to run ITS alignment using Millepede\r
-//\r
-// Read tracks from AliTrackPoints.N.root and fill Millepede.\r
-// Millepede configuration is taken from AliITSAlignMille.conf\r
-// Results are written as AliAlignObjParams in outfile.\r
-//\r
-// Origin: M. Lunardon\r
-//********************************************************************\r
-\r
-Bool_t SelectLayers(AliTrackPointArray *tpa, int *nreqpts_lay) {\r
- // selection on layers\r
- int npts=tpa->GetNPoints();\r
- int nlay[6]; \r
- for (int jj=0;jj<6;jj++) nlay[jj]=0;\r
- for (int ip=0; ip<npts; ip++) {\r
- int lay=-1;\r
- float r=TMath::Sqrt(tpa->GetX()[ip]*tpa->GetX()[ip] + tpa->GetY()[ip]*tpa->GetY()[ip]);\r
- if (r<5) lay=1;\r
- else if (r>5 && r<10) lay=2;\r
- else if (r>10 && r<18) lay=3;\r
- else if (r>18 && r<30) lay=4;\r
- else if (r>30 && r<40) lay=5;\r
- else if (r>40) lay=6;\r
- if (lay<0) continue;\r
- nlay[lay-1]++;\r
- }\r
- Bool_t isgood=1;\r
- for (int jj=0; jj<6; jj++) {\r
- if (nlay[jj]<nreqpts_lay[jj]) isgood=0;\r
- }\r
- return isgood;\r
-}\r
-//////////////////////////////////////\r
-\r
-int ITSAlignMille(int fromev=1, int toev=200, int maxentries=-1, char *outfile="ITSAlignMille.root") {\r
-\r
- // Read tracks from AliTrackPoints.N.root and fill Millepede.\r
- // Millepede results are written as AliAlignObjParams in outfile.\r
- \r
- int nreqpts=6;\r
- int nreqpts_lay[6]={0,0,0,0,0,0};\r
-\r
- TFile *fout=new TFile(outfile,"recreate");\r
- if (!fout->IsOpen()) {\r
- printf("\nCannot open output file!\n");\r
- return -1;\r
- }\r
-\r
- TChain *chain=new TChain("spTree"); \r
- char dir[100]="AliTrackPoints";\r
- char st[200];\r
- \r
- for (int iev=fromev; iev<=toev; iev++) {\r
- sprintf(st,"%s/AliTrackPoints.%d.root",dir,iev);\r
- chain->Add(st);\r
- }\r
- \r
- int nentries=chain->GetEntries();\r
- printf("There are %d entries in chain\n",nentries);\r
- \r
- if (maxentries>0 && maxentries<nentries) nentries=maxentries;\r
- \r
- AliTrackPointArray *tpa = 0;\r
- chain->SetBranchAddress("SP", &tpa);\r
-\r
- ////////////////////////////////////////////\r
- \r
- AliITSAlignMille *alig = new AliITSAlignMille("AliITSAlignMille.conf");\r
-\r
- Int_t nmod=alig->GetNModules();\r
-\r
- Double_t *parameters = new Double_t[nmod*6];\r
- Double_t *errors = new Double_t[nmod*6];\r
- Double_t *pulls = new Double_t[nmod*6];\r
-\r
- for(Int_t k=0;k<nmod*6;k++) {\r
- parameters[k]=0.;\r
- errors[k]=0.;\r
- pulls[k]=0.;\r
- }\r
-\r
- Double_t trackParams[8] = {0.,0.,0.,0.,0.,0.,0.,0.};\r
- alig->InitGlobalParameters(parameters);\r
- alig->Print();\r
-\r
- ////////////////////////////////////////////////////////////////////\r
-\r
- TStopwatch stimer;\r
- stimer.Start();\r
-\r
- int iTrackOk=0; // number of good passed track\r
- // loop on spTree entries\r
- // one entry = one track\r
- for (int i=0; i<nentries; i++) {\r
- chain->GetEvent(i);\r
- //////////////////////////////////////////////////////\r
- // track preselection \r
- int npts=tpa->GetNPoints();\r
- if (npts<nreqpts) continue;\r
- if (!SelectLayers(tpa,nreqpts_lay)) continue;\r
- //////////////////////////////////////////////////////\r
-\r
- if (!alig->ProcessTrack(tpa)) {\r
- if (!(iTrackOk%500)) \r
- printf("Calling LocalFit n. %d\n",iTrackOk);\r
- alig->LocalFit(iTrackOk++,trackParams,0);\r
- }\r
- }\r
- printf("\nMillepede fed with %d tracks\n\n",iTrackOk);\r
- \r
- alig->GlobalFit(parameters,errors,pulls);\r
- \r
- cout << "Done with GlobalFit " << endl;\r
- \r
- ////////////////////////////////////////////////////////////\r
- // output\r
- \r
-\r
- TClonesArray *array = new TClonesArray("AliAlignObjParams",4000);\r
- TClonesArray &alobj = *array;\r
-\r
- // first object: ITS\r
- new(alobj[0]) AliAlignObjParams("ITS", 0, 0., 0., 0., 0., 0., 0., kTRUE);\r
- \r
- UShort_t volid;\r
- const Char_t *symname;\r
- Double_t dx,dy,dz,dpsi,dtheta,dphi;\r
- Double_t corr[21];\r
-\r
- // all ITS modules\r
- for (int idx=0; idx<2198; idx++) {\r
- volid=alig->GetModuleVolumeID(idx);\r
- symname = AliGeomManager::SymName(volid);\r
- for (int jj=0;jj<21;jj++) corr[jj]=0.0;\r
-\r
- if (alig->CheckVolumeID(volid)) { // defined modules\r
- alig->SetCurrentModule(idx);\r
- int iidx=alig->GetCurrentModuleInternalIndex();\r
- dx = parameters[iidx*6+0]; corr[0] = errors[iidx*6+0]*errors[iidx*6+0];\r
- dy = parameters[iidx*6+1]; corr[2] = errors[iidx*6+1]*errors[iidx*6+1];\r
- dz = parameters[iidx*6+2]; corr[5] = errors[iidx*6+2]*errors[iidx*6+2];\r
- dpsi = parameters[iidx*6+3]; corr[9] = errors[iidx*6+3]*errors[iidx*6+3];\r
- dtheta= parameters[iidx*6+4]; corr[14]= errors[iidx*6+4]*errors[iidx*6+4];\r
- dphi = parameters[iidx*6+5]; corr[20]= errors[iidx*6+5]*errors[iidx*6+5];\r
- }\r
- else { // other modules\r
- dx=0.0; dy=0.0; dz=0.0; dpsi=0.0; dtheta=0.0; dphi=0.0;\r
- }\r
- \r
- new(alobj[idx+1]) AliAlignObjParams(symname, volid, dx, dy, dz, dpsi, dtheta, dphi, kFALSE);\r
- AliAlignObjParams* alo = (AliAlignObjParams*) array->UncheckedAt(idx+1);\r
- alo->SetCorrMatrix(corr);\r
- }\r
- \r
- fout->WriteObject(array,"ITSAlignObjs","kSingleKey");\r
- fout->Close();\r
-\r
- stimer.Stop();\r
- stimer.Print();\r
- \r
- return 0;\r
-}\r
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include <Riostream.h>
+#include <TChain.h>
+#include <TClonesArray.h>
+#include <TFile.h>
+#include <TMath.h>
+#include <TStopwatch.h>
+#include "AliAlignObjParams.h"
+#include "AliTrackPointArray.h"
+#include "AliITSAlignMille.h"
+#endif
+
+//********************************************************************
+// Example to run ITS alignment using Millepede
+//
+// Read tracks from AliTrackPoints.N.root and fill Millepede.
+// Millepede configuration is taken from AliITSAlignMille.conf
+// Results are written as AliAlignObjParams in outfile.
+//
+// Origin: M. Lunardon
+//********************************************************************
+
+
+int ITSAlignMille(int fromev=1, int toev=1, int fromentry=0, int nentries=-1, char *outfile="ITSAlignMille.root", char *confile="AliITSAlignMille.conf",int nreqpts=3) {
+
+ //AliLog::SetGlobalLogLevel(6);
+
+ TFile *fout=new TFile(outfile,"recreate");
+ if (!fout->IsOpen()) {
+ printf("\nCannot open output file!\n");
+ return -1;
+ }
+
+ TChain *chain=new TChain("spTree");
+ char dir[100]="AliTrackPoints";
+ char st[200];
+
+ for (int iev=fromev; iev<=toev; iev++) {
+ sprintf(st,"%s/AliTrackPoints.%d.root",dir,iev);
+ chain->Add(st);
+ }
+
+ int toentry=chain->GetEntries();
+ printf("There are %d entries in chain\n",toentry);
+
+ if (nentries>0 && nentries<(toentry-fromentry)) toentry=fromentry+nentries;
+
+ AliTrackPointArray *tpa = 0;
+ chain->SetBranchAddress("SP", &tpa);
+
+ ////////////////////////////////////////////
+
+ AliITSAlignMille *alig = new AliITSAlignMille(confile);
+ if (!alig->IsConfigured()) return -3;
+
+ Int_t nmod=alig->GetNModules();
+ alig->SetMinNPtsPerTrack(nreqpts);
+
+ // require 4 points in SPD (one per layer, up and down)
+ if (nreqpts>3) {
+ alig->SetRequiredPoint("LAYER",1,1,1);
+ alig->SetRequiredPoint("LAYER",1,-1,1);
+ alig->SetRequiredPoint("LAYER",2,1,1);
+ alig->SetRequiredPoint("LAYER",2,-1,1);
+ }
+
+ // correction for SSD bug (1) : inverisione sensor 18 e 19
+ // alig->SetBug(1);
+
+ Double_t *parameters = new Double_t[nmod*6];
+ Double_t *errors = new Double_t[nmod*6];
+ Double_t *pulls = new Double_t[nmod*6];
+
+ for(Int_t k=0;k<nmod*6;k++) {
+ parameters[k]=0.;
+ errors[k]=0.;
+ pulls[k]=0.;
+ }
+
+ // need array with size fNLocal*2
+ Double_t trackParams[10] = {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
+ alig->InitGlobalParameters(parameters);
+ alig->Print();
+
+ Double_t sigmatra=alig->GetParSigTranslations();
+ Double_t sigmarot=alig->GetParSigRotations();
+ ////////////////////////////////////////////////////////////////////
+
+ TStopwatch stimer;
+ stimer.Start();
+
+ /////////////////////
+
+ int iTrackOk=0; // number of good passed track
+ // loop on spTree entries
+ // one entry = one track
+ for (int i=fromentry; i<toentry; i++) {
+
+ chain->GetEvent(i);
+ if (!alig->ProcessTrack(tpa)) {
+ if (!(iTrackOk%500))
+ printf("Calling LocalFit n. %d\n",iTrackOk);
+ alig->LocalFit(iTrackOk++,trackParams,0);
+ }
+ }
+ printf("\nMillepede fed with %d tracks\n",iTrackOk);
+ printf("Total number of rejected points because of bad EqLoc : %d\n\n",alig->GetTotBadLocEqPoints());
+
+ stimer.Print();
+ stimer.Continue();
+
+ // make global fit
+ alig->GlobalFit(parameters,errors,pulls);
+
+ cout << "Done with GlobalFit " << endl;
+
+ ////////////////////////////////////////////////////////////
+ // output
+
+ printf("\nProcessed points statistics:\n");
+ Int_t maxstat=0;
+
+ printf("\nOutput values and point statistics:\n\n");
+ for (int i=0; i<nmod; i++) {
+ Int_t statm=alig->GetProcessedPoints()[i];
+ if (statm>maxstat) maxstat=statm;
+ printf("index: %-4d stat: %-7d pars: %f %f %f %f %f %f\n",alig->GetModuleIndexArray()[i], statm,
+ parameters[i*6+0],
+ parameters[i*6+1],
+ parameters[i*6+2],
+ parameters[i*6+3],
+ parameters[i*6+4],
+ parameters[i*6+5]);
+
+ }
+ FILE *pf=fopen("ITSAlignMille.out","w");
+ if (pf) {
+ fprintf(pf,"# param dx dy dz dpsi dtheta dphi\n");
+ for (int i=0; i<nmod; i++) {
+ fprintf(pf," %-5d %-10f %-10f %-10f %-10f %-10f %-10f\n",i,
+ parameters[i*6+0],
+ parameters[i*6+1],
+ parameters[i*6+2],
+ parameters[i*6+3],
+ parameters[i*6+4],
+ parameters[i*6+5]);
+
+ }
+ fclose(pf);
+ }
+
+ printf("Max statistics = %d\n",maxstat);
+ if (maxstat<1) {
+ printf("No points for alignment! quitting now...\n");
+ return -1;
+ }
+
+ TClonesArray *array = new TClonesArray("AliAlignObjParams",4000);
+ TClonesArray &alobj = *array;
+
+ // first object: ITS
+ new(alobj[0]) AliAlignObjParams("ITS", 0, 0., 0., 0., 0., 0., 0., kTRUE);
+
+ UShort_t volid;
+ Char_t *symname;
+ Double_t dx,dy,dz,dpsi,dtheta,dphi;
+ Double_t corr[21];
+ Double_t deltalocal[6];
+ Double_t t[3],r[3];
+
+ AliAlignObjParams *tmpa=NULL;
+
+ // quality factor: 0 = NOT ALIGNED or OFF
+ // N = ALIGNED with statistics = N
+ UInt_t QF;
+
+ // all ITS sensitive modules
+ for (int idx=0; idx<2198; idx++) {
+ volid=AliITSAlignMilleModule::GetVolumeIDFromIndex(idx);
+ symname = AliGeomManager::SymName(volid);
+ // default null misalignment
+ for (int jj=0;jj<21;jj++) corr[jj]=0.0;
+ for (int jj=0;jj<3;jj++) {t[jj]=0.0;r[jj]=0.0;}
+ QF=0;
+
+ if (alig->IsContained(volid)>=0) { // defined modules or inside a supermodule
+ alig->SetCurrentModule(idx); // set the supermodule that contains idx
+ int iidx=alig->GetCurrentModuleInternalIndex();
+
+ // check if all 6 parameters have been evaluated by millepede
+ Bool_t isoff=0;
+ Double_t parsig=0;
+ for (int kk=0; kk<6; kk++) {
+ parsig=sigmatra;
+ if (kk>2) parsig=sigmarot;
+ if (pulls[iidx*6+kk]==0.0 && errors[iidx*6+kk]==parsig) isoff=1;
+ }
+
+ // check if module was fixed
+ Bool_t isfixed=1;
+ for (int kk=0; kk<6; kk++) {
+ if (parameters[iidx*6+kk]!=0.0 || pulls[iidx*6+kk]!=0.0 || errors[iidx*6+kk]!=0.0) isfixed=0;
+ }
+
+ if (!isoff && !isfixed) { // OK, has been evaluated
+ deltalocal[0] = parameters[iidx*6+0];
+ deltalocal[1] = parameters[iidx*6+1];
+ deltalocal[2] = parameters[iidx*6+2];
+ deltalocal[3] = parameters[iidx*6+3];
+ deltalocal[4] = parameters[iidx*6+4];
+ deltalocal[5] = parameters[iidx*6+5];
+ tmpa = alig->GetCurrentModule()->GetSensitiveVolumeMisalignment(volid,deltalocal);
+ if (!tmpa) {
+ printf("error transforming millepede parameters for module %d\n",idx);
+ continue;
+ }
+ tmpa->GetPars(t,r);
+ // at the moment sigma of supermodule is given to sensitive modules. to be fixed...
+ corr[0] = errors[iidx*6+0]*errors[iidx*6+0];
+ corr[2] = errors[iidx*6+1]*errors[iidx*6+1];
+ corr[5] = errors[iidx*6+2]*errors[iidx*6+2];
+ corr[9] = errors[iidx*6+3]*errors[iidx*6+3];
+ corr[14]= errors[iidx*6+4]*errors[iidx*6+4];
+ corr[20]= errors[iidx*6+5]*errors[iidx*6+5];
+ Int_t statm=alig->GetProcessedPoints()[iidx];
+ QF=statm;
+ }
+ else {
+ if (isoff) {
+ printf("Module %d is OFF!\n",idx);
+ QF=0;
+ }
+ if (isfixed) {
+ printf("Module %d was FIXED!\n",idx);
+ if (alig->GetPreAlignmentQualityFactor(idx)>0)
+ QF=alig->GetPreAlignmentQualityFactor(idx);
+ else
+ QF=0;
+ }
+ }
+
+ }
+
+ new(alobj[idx+1]) AliAlignObjParams(symname,volid,t[0],t[1],t[2],r[0],r[1],r[2],kFALSE);
+ AliAlignObjParams* alo = (AliAlignObjParams*) array->UncheckedAt(idx+1);
+ alo->SetCorrMatrix(corr);
+ alo->SetUniqueID(QF);
+ }
+
+ fout->WriteObject(array,"ITSAlignObjs","kSingleKey");
+ fout->Close();
+
+ stimer.Stop();
+ stimer.Print();
+
+ return 0;
+}
--- /dev/null
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include <TError.h>
+#include <TFile.h>
+#include <TGeoManager.h>
+#include <TMath.h>
+#include <TString.h>
+#include <TSystem.h>
+#include "AliCDBPath.h"
+#include "AliCDBEntry.h"
+#include "AliCDBManager.h"
+#include "AliCDBStorage.h"
+#include "AliGeomManager.h"
+#include "AliITSMisalignMaker.h"
+#endif
+void MakeITSMilleSuperModules(char *geomfile="geometry.root") {
+//========================================================================
+//
+// Macro for building supermodules for ITS alignment
+//
+// Main author: M. Lunardon
+//
+//========================================================================
+
+ const char* macroname = "MakeITSMilleSuperModules.C";
+
+ if (!geomfile) { // look for default geometry
+ // Activate CDB storage and load geometry from CDB
+ AliCDBManager* cdb = AliCDBManager::Instance();
+ if(!cdb->IsDefaultStorageSet()) cdb->SetDefaultStorage("local://$ALICE_ROOT");
+ cdb->SetRun(0);
+
+ AliCDBStorage* storage = NULL;
+
+ TString compare("kTRUE");
+ if(gSystem->Getenv("TOCDB") == compare.Data()){
+ TString Storage = gSystem->Getenv("STORAGE");
+ if(!Storage.BeginsWith("local://") && !Storage.BeginsWith("alien://")) {
+ Error(macroname,"STORAGE variable set to %s is not valid. Exiting\n",Storage.Data());
+ return;
+ }
+ storage = cdb->GetStorage(Storage.Data());
+ if(!storage){
+ Error(macroname,"Unable to open storage %s\n",Storage.Data());
+ return;
+ }
+ AliCDBPath path("GRP","Geometry","Data");
+ AliCDBEntry *entry = storage->Get(path.GetPath(),cdb->GetRun());
+ if(!entry) Fatal(macroname,"Could not get the specified CDB entry!");
+ entry->SetOwner(0);
+ TGeoManager* geom = (TGeoManager*) entry->GetObject();
+ AliGeomManager::SetGeometry(geom);
+ }else{
+ AliGeomManager::LoadGeometry("geometry.root"); //load geom from default CDB storage
+ }
+ }
+ else
+ AliGeomManager::LoadGeometry(geomfile); //load geom from file
+ //////////////////////////////////////////////////////////////////
+
+ TClonesArray *array = new TClonesArray("AliAlignObjParams",2000);
+ TClonesArray &alobj = *array;
+ Int_t j = 0;
+
+ // custom ITS supermodules are stored as AliAlignObjParams as follow:
+ // symname, volid = SMsymname, SMvolid
+ // matrix = TGeoHMatrix of the SM in the global c.s.
+ // symname: the list of sensitive volumes, starting with "ITSMilleModuleList:"
+ // keyword, is appended to the symname
+ // example: "ITSMilleModuleList: N1 N2 N3-N4 ..."
+ // where N is a ITS sensitive volume INDEX (0-2197)
+
+ Char_t symname[4096];
+ UShort_t volid;
+ Char_t modlist[4096];
+ Double_t t[3]; // global translation
+ Double_t r[9]; // global rotation
+ TGeoHMatrix m;
+
+ // virtual volids start at layer 7
+ volid=14336;
+
+ // LAYERS: volids 14336 to 14341
+ strcpy(modlist,"ITSMilleModuleList: 0-79");
+ sprintf(symname,"%s %s","ITS/SPD0",modlist);
+ m.Clear(); // global frame
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+
+ strcpy(modlist,"ITSMilleModuleList: 80-239");
+ sprintf(symname,"%s %s","ITS/SPD1",modlist);
+ m.Clear(); // global frame
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+
+ strcpy(modlist,"ITSMilleModuleList: 240-323");
+ sprintf(symname,"%s %s","ITS/SDD2",modlist);
+ m.Clear(); // global frame
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+
+ strcpy(modlist,"ITSMilleModuleList: 324-499");
+ sprintf(symname,"%s %s","ITS/SDD3",modlist);
+ m.Clear(); // global frame
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+
+ strcpy(modlist,"ITSMilleModuleList: 500-1247");
+ sprintf(symname,"%s %s","ITS/SSD4",modlist);
+ m.Clear(); // global frame
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+
+ strcpy(modlist,"ITSMilleModuleList: 1248-2197");
+ sprintf(symname,"%s %s","ITS/SSD5",modlist);
+ m.Clear(); // global frame
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+
+ // SPD BARREL: volid 14342
+ strcpy(modlist,"ITSMilleModuleList: 0-239");
+ sprintf(symname,"%s %s","ITS/SPD/Barrel",modlist);
+ m.Clear(); // global frame
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+
+ // SPD HALF BARREL: volids 14343-14344
+ strcpy(modlist,"ITSMilleModuleList: 0-39 80-159");
+ sprintf(symname,"%s %s","ITS/SPD/HalfBarrel0",modlist); // up
+ m.Clear(); // global frame
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+
+ strcpy(modlist,"ITSMilleModuleList: 40-79 160-239");
+ sprintf(symname,"%s %s","ITS/SPD/HalfBarrel1",modlist); // down
+ m.Clear(); // global frame
+ //m.RotateZ(180.);
+ //m.RotateY(180.); // just negY->posY
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+
+ // SPD sectors: volids 14345 to 14354
+ for (int is=0; is<10; is++) {
+ // sect 0: 0-7 80-95
+ // sect 1: 8-15 96-111
+ // ...
+ sprintf(modlist,"ITSMilleModuleList: %d-%d %d-%d",is*8,is*8+7,is*16+80,is*16+80+15);
+ sprintf(symname,"ITS/SPD0/Sector%d",is);
+ if (AliGeomManager::GetMatrix(symname))
+ m=(*AliGeomManager::GetMatrix(symname));
+ else {
+ Error(macroname,"cannot find matrix for SPD sector\n");
+ return;
+ }
+ sprintf(symname,"%s%d %s","ITS/SPD0/Sector",is,modlist);
+
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+ }
+
+ // SPD staves: volids 14355 to 14414
+ for (int is=0; is<60; is++) {
+ // Stave0: 0-3
+// // ...
+ sprintf(modlist," ITSMilleModuleList: %d-%d",is*4,is*4+3);
+ strcpy(symname,AliITSgeomTGeo::GetSymName(is*4));
+ char *clad=strstr(symname,"Ladder");
+ if (clad) *(clad-1) = NULL;
+ else {
+ Error(macroname,"cannot find 'Ladder' in symname\n");
+ return;
+ }
+ //printf("Symname=%s\n",symname);
+ if (AliGeomManager::GetMatrix(symname))
+ m=(*AliGeomManager::GetMatrix(symname));
+ else {
+ Error(macroname,"cannot find matrix for SPD stave\n");
+ return;
+ }
+
+ clad=strstr(symname,"HalfStave");
+ if (clad) *(clad-1) = NULL;
+ else {
+ Error(macroname,"cannot find 'HalfStave' in symname\n");
+ return;
+ }
+ strcat(symname,modlist);
+
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+ }
+
+
+ // SPD HALF staves: volids 14415 to 14534
+ for (int is=0; is<120; is++) {
+ // HalfStave0: 0-1
+// // ...
+ sprintf(modlist," ITSMilleModuleList: %d-%d ",is*2,is*2+1);
+ strcpy(symname,AliITSgeomTGeo::GetSymName(is*2));
+ char *clad=strstr(symname,"Ladder");
+ if (clad) *(clad-1) = NULL;
+ else {
+ Error(macroname,"cannot find 'Ladder' in symname\n");
+ return;
+ }
+ if (AliGeomManager::GetMatrix(symname))
+ m=(*AliGeomManager::GetMatrix(symname));
+ else {
+ Error(macroname,"cannot find matrix for SPD half-stave\n");
+ return;
+ }
+ strcat(symname,modlist);
+
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+ }
+
+ // SPD HALF-HALF BARREL UP/DOWN FORWARD/BACKWARD (Y>0 and Z>0): volids 14535 to 14538
+ strcpy(modlist,"ITSMilleModuleList: ");
+ for (int ii=0; ii<40; ii++) {
+ int ij=ii/2;
+ if (!(ij%2)) sprintf(modlist,"%s %d",modlist,ii);
+ }
+ for (int ii=80; ii<160; ii++) {
+ int ij=ii/2;
+ if (!(ij%2)) sprintf(modlist,"%s %d",modlist,ii);
+ }
+ sprintf(symname,"%s %s","ITS/SPD/HalfBarrel0fw",modlist); // up/fw
+ m.Clear(); // global frame
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+ //-----
+ strcpy(modlist,"ITSMilleModuleList: ");
+ for (int ii=0; ii<40; ii++) {
+ int ij=ii/2;
+ if ((ij%2)) sprintf(modlist,"%s %d",modlist,ii);
+ }
+ for (int ii=80; ii<160; ii++) {
+ int ij=ii/2;
+ if ((ij%2)) sprintf(modlist,"%s %d",modlist,ii);
+ }
+ sprintf(symname,"%s %s","ITS/SPD/HalfBarrel0bw",modlist); // up/bw
+ m.Clear(); // global frame
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+ //-----
+ strcpy(modlist,"ITSMilleModuleList: ");
+ for (int ii=40; ii<80; ii++) {
+ int ij=ii/2;
+ if (!(ij%2)) sprintf(modlist,"%s %d",modlist,ii);
+ }
+ for (int ii=160; ii<240; ii++) {
+ int ij=ii/2;
+ if (!(ij%2)) sprintf(modlist,"%s %d",modlist,ii);
+ }
+ sprintf(symname,"%s %s","ITS/SPD/HalfBarrel1fw",modlist); // down/fw
+ m.Clear(); // global frame
+ //m.RotateZ(180.);
+ //m.RotateY(180.); // just negY->posY
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+ //-----
+ strcpy(modlist,"ITSMilleModuleList: ");
+ for (int ii=40; ii<80; ii++) {
+ int ij=ii/2;
+ if ((ij%2)) sprintf(modlist,"%s %d",modlist,ii);
+ }
+ for (int ii=160; ii<240; ii++) {
+ int ij=ii/2;
+ if ((ij%2)) sprintf(modlist,"%s %d",modlist,ii);
+ }
+ sprintf(symname,"%s %s","ITS/SPD/HalfBarrel1bw",modlist); // down/bw
+ m.Clear(); // global frame
+ //m.RotateZ(180.);
+ //m.RotateY(180.); // just negY->posY
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+ //-----
+
+ // SDD
+ // start at volid=15000
+ // - SDD2: 14 ladders da 6 elementi
+ // - SDD3: 22 ladders da 8 elementi
+ volid=15000;
+
+ // SDD2 Ladders: volids 15000 to 15013
+ for (int is=0; is<14; is++) {
+ // Ladder: 0-5
+ // // ...
+ sprintf(modlist," ITSMilleModuleList: %d-%d ",240+is*6,240+is*6+5);
+ strcpy(symname,AliITSgeomTGeo::GetSymName(240+is*6));
+ char *clad=strstr(symname,"Sensor");
+ if (clad) *(clad-1) = NULL;
+ else {
+ Error(macroname,"cannot find 'Sensor' in symname\n");
+ return;
+ }
+ if (AliGeomManager::GetMatrix(symname))
+ m=(*AliGeomManager::GetMatrix(symname));
+ else {
+ Error(macroname,"cannot find matrix for SDD ladder\n");
+ return;
+ }
+ strcat(symname,modlist);
+
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+ }
+
+ // SDD3 Ladders: volids 15014 to 15035
+ for (int is=0; is<22; is++) {
+ // Ladder: 0-7
+ // // ...
+ sprintf(modlist," ITSMilleModuleList: %d-%d ",324+is*8,324+is*8+7);
+ strcpy(symname,AliITSgeomTGeo::GetSymName(324+is*8));
+ char *clad=strstr(symname,"Sensor");
+ if (clad) *(clad-1) = NULL;
+ else {
+ Error(macroname,"cannot find 'Sensor' in symname\n");
+ return;
+ }
+ if (AliGeomManager::GetMatrix(symname))
+ m=(*AliGeomManager::GetMatrix(symname));
+ else {
+ Error(macroname,"cannot find matrix for SDD ladder\n");
+ return;
+ }
+ strcat(symname,modlist);
+
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+ }
+
+ //----------
+
+ // SSD
+ // start at volid=16000
+ // - SSD4: 34 ladders da 22 elementi
+ // - SSD5: 38 ladders da 25 elementi
+ volid=16000;
+
+ // SSD4 Ladders: volids 16000 to 16033
+ for (int is=0; is<34; is++) {
+ // Ladder: 0-5
+ // // ...
+ sprintf(modlist," ITSMilleModuleList: %d-%d ",500+is*22,500+is*22+21);
+ strcpy(symname,AliITSgeomTGeo::GetSymName(500+is*22));
+ char *clad=strstr(symname,"Sensor");
+ if (clad) *(clad-1) = NULL;
+ else {
+ Error(macroname,"cannot find 'Sensor' in symname\n");
+ return;
+ }
+ if (AliGeomManager::GetMatrix(symname))
+ m=(*AliGeomManager::GetMatrix(symname));
+ else {
+ Error(macroname,"cannot find matrix for SSD ladder\n");
+ return;
+ }
+ strcat(symname,modlist);
+
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+ }
+
+ // SSD5 Ladders: volids 16034 to 16071
+ for (int is=0; is<38; is++) {
+ // Ladder: 0-7
+ // // ...
+ sprintf(modlist," ITSMilleModuleList: %d-%d ",1248+is*25,1248+is*25+24);
+ strcpy(symname,AliITSgeomTGeo::GetSymName(1248+is*25));
+ char *clad=strstr(symname,"Sensor");
+ if (clad) *(clad-1) = NULL;
+ else {
+ Error(macroname,"cannot find 'Sensor' in symname\n");
+ return;
+ }
+ if (AliGeomManager::GetMatrix(symname))
+ m=(*AliGeomManager::GetMatrix(symname));
+ else {
+ Error(macroname,"cannot find matrix for SDD ladder\n");
+ return;
+ }
+ strcat(symname,modlist);
+
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+ }
+
+ // SSD BARREL: volid 16072
+ strcpy(modlist,"ITSMilleModuleList: 500-2197");
+ sprintf(symname,"%s %s","ITS/SSD/Barrel",modlist);
+ m.Clear(); // global frame
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+
+
+ // SSD HALF BARREL: volids 16073-16074
+ // SSD HALF BARREL UP: volid 16073
+ strcpy(modlist,"ITSMilleModuleList: 500-873 1248-1722");
+ sprintf(symname,"%s %s","ITS/SSD/HalfBarrel0",modlist); // up
+ m.Clear(); // global frame
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+
+ // SSD HALF BARREL DOWN: volid 16074
+ strcpy(modlist,"ITSMilleModuleList: 874-1246 1723-2197");
+ sprintf(symname,"%s %s","ITS/SSD/HalfBarrel1",modlist); // down
+ m.Clear(); // global frame
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+
+
+ //----------
+ // SSD HALF-LADDERS
+ // - SSD4: 34x2=68 halfladders da 12+10 elementi
+ // - SSD5: 38x2=76 halfladders da 12+13 elementi
+
+ // SSD4 Ladders: volids 16075 to 16142
+ for (int is=0; is<34; is++) {
+ // Ladder: 0-33
+ // first half
+ sprintf(modlist," ITSMilleModuleList: %d-%d ",500+is*22,500+is*22+11);
+ strcpy(symname,AliITSgeomTGeo::GetSymName(500+is*22));
+ char *clad=strstr(symname,"Sensor");
+ if (clad) *(clad-1) = NULL;
+ else {
+ Error(macroname,"cannot find 'Sensor' in symname\n");
+ return;
+ }
+ if (AliGeomManager::GetMatrix(symname))
+ m=(*AliGeomManager::GetMatrix(symname));
+ else {
+ Error(macroname,"cannot find matrix for SSD ladder\n");
+ return;
+ }
+ strcat(symname,"Half0");
+ strcat(symname,modlist);
+
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+
+ // second half
+ sprintf(modlist," ITSMilleModuleList: %d-%d ",500+is*22+12,500+is*22+21);
+ strcpy(symname,AliITSgeomTGeo::GetSymName(500+is*22));
+ char *clad=strstr(symname,"Sensor");
+ if (clad) *(clad-1) = NULL;
+ else {
+ Error(macroname,"cannot find 'Sensor' in symname\n");
+ return;
+ }
+ if (AliGeomManager::GetMatrix(symname))
+ m=(*AliGeomManager::GetMatrix(symname));
+ else {
+ Error(macroname,"cannot find matrix for SSD ladder\n");
+ return;
+ }
+ strcat(symname,"Half1");
+ strcat(symname,modlist);
+
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+
+ }
+
+ // SSD5 Ladders: volids 16143 to 16218
+ for (int is=0; is<38; is++) {
+ // first half
+ sprintf(modlist," ITSMilleModuleList: %d-%d ",1248+is*25,1248+is*25+11);
+ strcpy(symname,AliITSgeomTGeo::GetSymName(1248+is*25));
+ char *clad=strstr(symname,"Sensor");
+ if (clad) *(clad-1) = NULL;
+ else {
+ Error(macroname,"cannot find 'Sensor' in symname\n");
+ return;
+ }
+ if (AliGeomManager::GetMatrix(symname))
+ m=(*AliGeomManager::GetMatrix(symname));
+ else {
+ Error(macroname,"cannot find matrix for SDD ladder\n");
+ return;
+ }
+ strcat(symname,"Half0");
+ strcat(symname,modlist);
+
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+
+ // second half
+ sprintf(modlist," ITSMilleModuleList: %d-%d ",1248+is*25+12,1248+is*25+24);
+ strcpy(symname,AliITSgeomTGeo::GetSymName(1248+is*25));
+ char *clad=strstr(symname,"Sensor");
+ if (clad) *(clad-1) = NULL;
+ else {
+ Error(macroname,"cannot find 'Sensor' in symname\n");
+ return;
+ }
+ if (AliGeomManager::GetMatrix(symname))
+ m=(*AliGeomManager::GetMatrix(symname));
+ else {
+ Error(macroname,"cannot find matrix for SDD ladder\n");
+ return;
+ }
+ strcat(symname,"Half1");
+ strcat(symname,modlist);
+
+ new(alobj[j]) AliAlignObjParams(symname, volid, m, kTRUE);
+ *(strstr(symname,"ITSMilleModuleList"))=NULL ;printf("added module %s with volid %d \n",symname,volid);
+ j++; volid++;
+ }
+
+
+ //////////////////////////////////////////////////////////////////
+ if( TString(gSystem->Getenv("TOCDB")) != TString("kTRUE") ){
+ // save on file
+ const char* filename = "ITSMilleSuperModules.root";
+ TFile f(filename,"RECREATE");
+ if(!f){
+ Error(macroname,"cannot open file for output\n");
+ return;
+ }
+ Info(macroname,"Saving ITS SuperModules as AliAlignObjs to the file %s", filename);
+ f.cd();
+ f.WriteObject(array,"ITSMilleSuperModules","kSingleKey");
+ f.Close();
+ }else{
+ // save in CDB storage
+ TString Storage = gSystem->Getenv("STORAGE");
+ if(!Storage.BeginsWith("local://") && !Storage.BeginsWith("alien://")) {
+ Error(macroname,"STORAGE variable set to %s is not valid. Exiting\n",Storage.Data());
+ return;
+ }
+ Info(macroname,"Saving ITS SuperModules in CDB storage %s",
+ Storage.Data());
+ AliCDBManager* cdb = AliCDBManager::Instance();
+ AliCDBStorage* storage = cdb->GetStorage(Storage.Data());
+ if(!storage){
+ Error(macroname,"Unable to open storage %s\n",Storage.Data());
+ return;
+ }
+ AliCDBMetaData *md= new AliCDBMetaData();
+ md->SetResponsible("Marcello Lunardon");
+ md->SetComment("ITS super modules for ITS alignment with Millepede");
+ md->SetAliRootVersion(gSystem->Getenv("ARVERSION"));
+ AliCDBId id("ITS/Align/Data",0,AliCDBRunRange::Infinity());
+ storage->Put(array,id, md);
+ }
+
+ array->Delete();
+ return;
+}