]>
Commit | Line | Data |
---|---|---|
1 | /************************************************************************** | |
2 | * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | /* $Id$ */ | |
17 | ||
18 | //----------------------------------------------------------------------------- | |
19 | /// \class AliITSAlignMille | |
20 | /// Alignment class fro the ALICE ITS detector | |
21 | /// | |
22 | /// ITS specific alignment class which interface to AliMillepede. | |
23 | /// For each track ProcessTrack calculates the local and global derivatives | |
24 | /// at each hit and fill the corresponding local equations. Provide methods for | |
25 | /// fixing or constraining detection elements for best results. | |
26 | /// | |
27 | /// \author M. Lunardon (thanks to J. Castillo) | |
28 | //----------------------------------------------------------------------------- | |
29 | ||
30 | #include <TF1.h> | |
31 | #include <TGraph.h> | |
32 | #include <TGeoMatrix.h> | |
33 | #include <TMath.h> | |
34 | ||
35 | #include "AliITSAlignMille.h" | |
36 | #include "AliITSgeomTGeo.h" | |
37 | #include "AliGeomManager.h" | |
38 | #include "AliMillepede.h" | |
39 | #include "AliTrackPointArray.h" | |
40 | #include "AliAlignObjParams.h" | |
41 | #include "AliLog.h" | |
42 | #include "TSystem.h" // come si fa? | |
43 | ||
44 | /// \cond CLASSIMP | |
45 | ClassImp(AliITSAlignMille) | |
46 | /// \endcond | |
47 | ||
48 | Int_t AliITSAlignMille::fgNDetElem = ITSMILLE_NDETELEM; | |
49 | Int_t AliITSAlignMille::fgNParCh = ITSMILLE_NPARCH; | |
50 | ||
51 | AliITSAlignMille::AliITSAlignMille(const Char_t *configFilename, Bool_t initmille) | |
52 | : TObject(), | |
53 | fMillepede(0), | |
54 | fStartFac(16.), | |
55 | fResCutInitial(100.), | |
56 | fResCut(100.), | |
57 | fNGlobal(ITSMILLE_NDETELEM*ITSMILLE_NPARCH), | |
58 | fNLocal(ITSMILLE_NLOCAL), | |
59 | fNStdDev(ITSMILLE_NSTDEV), | |
60 | fIsMilleInit(kFALSE), | |
61 | fParSigTranslations(0.0100), | |
62 | fParSigRotations(0.1), | |
63 | fTrack(NULL), | |
64 | fCluster(), | |
65 | fGlobalDerivatives(NULL), | |
66 | fTempHMat(NULL), | |
67 | fTempAlignObj(NULL), | |
68 | fDerivativeXLoc(0), | |
69 | fDerivativeZLoc(0), | |
70 | fDeltaPar(0), | |
71 | fMinNPtsPerTrack(3), | |
72 | fGeometryFileName("geometry.root"), | |
73 | fGeoManager(0), | |
74 | fCurrentModuleIndex(0), | |
75 | fCurrentModuleInternalIndex(0), | |
76 | fNModules(0), | |
77 | fUseLocalShifts(kTRUE), | |
78 | fCurrentModuleHMatrix(NULL) | |
79 | { | |
80 | /// main constructor that takes input from configuration file | |
81 | ||
82 | fMillepede = new AliMillepede(); | |
83 | fGlobalDerivatives = new Double_t[fNGlobal]; | |
84 | fTempHMat = new TGeoHMatrix; | |
85 | fCurrentModuleHMatrix = new TGeoHMatrix; | |
86 | ||
87 | Int_t lc=LoadConfig(configFilename); | |
88 | if (lc) { | |
89 | AliInfo(Form("Error %d loading configuration from %s",lc,configFilename)); | |
90 | } | |
91 | else { | |
92 | if (initmille && fNGlobal<20000) { | |
93 | AliInfo(Form("Initializing Millepede with %d gpar, %d lpar and %d stddev ...",fNGlobal, fNLocal, fNStdDev)); | |
94 | Init(fNGlobal, fNLocal, fNStdDev); | |
95 | ResetLocalEquation(); | |
96 | AliInfo("Parameters initialized to zero"); | |
97 | } | |
98 | else { | |
99 | AliInfo("Millepede has not been initialized ... "); | |
100 | } | |
101 | } | |
102 | ||
103 | fDeltaPar=0.0; // not used at the moment - to be checked later... | |
104 | ||
105 | } | |
106 | ||
107 | AliITSAlignMille::~AliITSAlignMille() { | |
108 | /// Destructor | |
109 | if (fMillepede) delete fMillepede; | |
110 | delete [] fGlobalDerivatives; | |
111 | delete fCurrentModuleHMatrix; | |
112 | delete fTempHMat; | |
113 | } | |
114 | ||
115 | /////////////////////////////////////////////////////////////////////// | |
116 | ||
117 | Int_t AliITSAlignMille::LoadConfig(const Char_t *cfile) { | |
118 | /// return 0 if success | |
119 | /// 1 if error in module index or voluid | |
120 | ||
121 | FILE *pfc=fopen(cfile,"r"); | |
122 | if (!pfc) return -1; | |
123 | ||
124 | Char_t st[200],st2[200]; | |
125 | Char_t tmp[100]; | |
126 | Int_t idx,itx,ity,itz,ith,ips,iph; | |
127 | Float_t f1; | |
128 | UShort_t voluid; | |
129 | Int_t nmod=0; | |
130 | ||
131 | while (fgets(st,200,pfc)) { | |
132 | ||
133 | // skip comments | |
134 | for (int i=0; i<int(strlen(st)); i++) { | |
135 | if (st[i]=='#') st[i]=0; | |
136 | } | |
137 | ||
138 | if (strstr(st,"GEOMETRY_FILE")) { | |
139 | sscanf(st,"%s %s",tmp,st2); | |
140 | if (gSystem->AccessPathName(st2)) { | |
141 | AliInfo("*** WARNING! *** geometry file not found! "); | |
142 | return -1; | |
143 | } | |
144 | fGeometryFileName=st2; | |
145 | InitGeometry(); | |
146 | } | |
147 | ||
148 | if (strstr(st,"SET_PARSIG_TRA")) { | |
149 | sscanf(st,"%s %f",tmp,&f1); | |
150 | fParSigTranslations=f1; | |
151 | } | |
152 | ||
153 | if (strstr(st,"SET_PARSIG_ROT")) { | |
154 | sscanf(st,"%s %f",tmp,&f1); | |
155 | fParSigRotations=f1; | |
156 | } | |
157 | ||
158 | if (strstr(st,"SET_NSTDDEV")) { | |
159 | sscanf(st,"%s %d",tmp,&idx); | |
160 | fNStdDev=idx; | |
161 | } | |
162 | ||
163 | if (strstr(st,"SET_RESCUT_INIT")) { | |
164 | sscanf(st,"%s %f",tmp,&f1); | |
165 | fResCutInitial=f1; | |
166 | } | |
167 | ||
168 | if (strstr(st,"SET_RESCUT_OTHER")) { | |
169 | sscanf(st,"%s %f",tmp,&f1); | |
170 | fResCut=f1; | |
171 | } | |
172 | ||
173 | if (strstr(st,"SET_STARTFAC")) { | |
174 | sscanf(st,"%s %f",tmp,&f1); | |
175 | fStartFac=f1; | |
176 | } | |
177 | ||
178 | if (strstr(st,"SET_LOCAL_SHIFTS")) { // only enabled mode... | |
179 | fUseLocalShifts = kTRUE; | |
180 | } | |
181 | ||
182 | if (strstr(st,"MODULE_INDEX")) { | |
183 | sscanf(st,"%s %d %d %d %d %d %d %d",tmp,&idx,&itx,&ity,&itz,&iph,&ith,&ips); | |
184 | voluid=GetModuleVolumeID(idx); | |
185 | if (!voluid) return 1; // bad index | |
186 | fModuleIndex[nmod]=idx; | |
187 | fModuleVolumeID[nmod]=voluid; | |
188 | fFreeParam[nmod][0]=itx; | |
189 | fFreeParam[nmod][1]=ity; | |
190 | fFreeParam[nmod][2]=itz; | |
191 | fFreeParam[nmod][3]=iph; | |
192 | fFreeParam[nmod][4]=ith; | |
193 | fFreeParam[nmod][5]=ips; | |
194 | nmod++; | |
195 | } | |
196 | ||
197 | if (strstr(st,"MODULE_VOLUID")) { | |
198 | // to be implemented | |
199 | } | |
200 | ||
201 | } // end while | |
202 | ||
203 | fNModules = nmod; | |
204 | fNGlobal = fNModules*fgNParCh; | |
205 | ||
206 | fclose(pfc); | |
207 | return 0; | |
208 | } | |
209 | ||
210 | Int_t AliITSAlignMille::GetModuleIndex(const Char_t *symname) { | |
211 | /// index from symname | |
212 | if (!symname) return -1; | |
213 | for (Int_t i=0; i<2198; i++) { | |
214 | if (!strcmp(symname,AliITSgeomTGeo::GetSymName(i))) return i; | |
215 | } | |
216 | return -1; | |
217 | } | |
218 | ||
219 | Int_t AliITSAlignMille::GetModuleIndex(UShort_t voluid) { | |
220 | /// index from volume ID | |
221 | AliGeomManager::ELayerID lay = AliGeomManager::VolUIDToLayer(voluid); | |
222 | if (lay<1|| lay>6) return -1; | |
223 | Int_t idx=Int_t(voluid)-2048*lay; | |
224 | if (idx>=AliGeomManager::LayerSize(lay)) return -1; | |
225 | for (Int_t ilay=1; ilay<lay; ilay++) | |
226 | idx += AliGeomManager::LayerSize(ilay); | |
227 | return idx; | |
228 | } | |
229 | ||
230 | UShort_t AliITSAlignMille::GetModuleVolumeID(const Char_t *symname) { | |
231 | /// volume ID from symname | |
232 | if (!symname) return 0; | |
233 | ||
234 | for (UShort_t voluid=2000; voluid<13300; voluid++) { | |
235 | Int_t modId; | |
236 | AliGeomManager::ELayerID layerId = AliGeomManager::VolUIDToLayer(voluid,modId); | |
237 | if (layerId>0 && layerId<7 && modId>=0 && modId<AliGeomManager::LayerSize(layerId)) { | |
238 | if (!strcmp(symname,AliGeomManager::SymName(layerId,modId))) return voluid; | |
239 | } | |
240 | } | |
241 | ||
242 | return 0; | |
243 | } | |
244 | ||
245 | UShort_t AliITSAlignMille::GetModuleVolumeID(Int_t index) { | |
246 | /// volume ID from index | |
247 | if (index<0 || index>2197) return 0; | |
248 | return GetModuleVolumeID(AliITSgeomTGeo::GetSymName(index)); | |
249 | } | |
250 | ||
251 | void AliITSAlignMille::InitGeometry() { | |
252 | /// initialize geometry | |
253 | AliGeomManager::LoadGeometry(fGeometryFileName.Data()); | |
254 | fGeoManager = AliGeomManager::GetGeometry(); | |
255 | if (!fGeoManager) { | |
256 | AliInfo("Couldn't initialize geometry"); | |
257 | return; | |
258 | } | |
259 | // temporary align object, just use the rotation... | |
260 | fTempAlignObj=new AliAlignObjParams(AliITSgeomTGeo::GetSymName(7),2055,0,0,0,0,0,0,kFALSE); | |
261 | } | |
262 | ||
263 | void AliITSAlignMille::Init(Int_t nGlobal, /* number of global paramers */ | |
264 | Int_t nLocal, /* number of local parameters */ | |
265 | Int_t nStdDev /* std dev cut */ ) | |
266 | { | |
267 | /// Initialization of AliMillepede. Fix parameters, define constraints ... | |
268 | fMillepede->InitMille(nGlobal,nLocal,nStdDev,fResCut,fResCutInitial); | |
269 | fIsMilleInit = kTRUE; | |
270 | ||
271 | /// Fix non free parameters | |
272 | for (Int_t i=0; i<fNModules; i++) { | |
273 | for (Int_t j=0; j<ITSMILLE_NPARCH; j++) { | |
274 | if (!fFreeParam[i][j]) FixParameter(i*ITSMILLE_NPARCH+j,0.0); | |
275 | else { | |
276 | // pepopepo: da sistemare il settaggio delle sigma... | |
277 | Double_t parsig=0; | |
278 | if (j<3) parsig=fParSigTranslations; // translations (0.0100 cm) | |
279 | else parsig=fParSigRotations; // rotations (1/10 deg) | |
280 | FixParameter(i*ITSMILLE_NPARCH+j,parsig); | |
281 | } | |
282 | } | |
283 | } | |
284 | ||
285 | ||
286 | // // Set iterations | |
287 | if (fStartFac>1) fMillepede->SetIterations(fStartFac); | |
288 | } | |
289 | ||
290 | ||
291 | void AliITSAlignMille::AddConstraint(Double_t *par, Double_t value) { | |
292 | /// Constrain equation defined by par to value | |
293 | if (!fIsMilleInit) { | |
294 | AliInfo("Millepede has not been initialized!"); | |
295 | return; | |
296 | } | |
297 | fMillepede->SetGlobalConstraint(par, value); | |
298 | AliInfo("Adding constraint"); | |
299 | } | |
300 | ||
301 | void AliITSAlignMille::InitGlobalParameters(Double_t *par) { | |
302 | /// Initialize global parameters with par array | |
303 | if (!fIsMilleInit) { | |
304 | AliInfo("Millepede has not been initialized!"); | |
305 | return; | |
306 | } | |
307 | fMillepede->SetGlobalParameters(par); | |
308 | AliInfo("Init Global Parameters"); | |
309 | } | |
310 | ||
311 | void AliITSAlignMille::FixParameter(Int_t iPar, Double_t value) { | |
312 | /// Parameter iPar is encourage to vary in [-value;value]. | |
313 | /// If value == 0, parameter is fixed | |
314 | if (!fIsMilleInit) { | |
315 | AliInfo("Millepede has not been initialized!"); | |
316 | return; | |
317 | } | |
318 | fMillepede->SetParSigma(iPar, value); | |
319 | if (value==0) AliInfo(Form("Parameter %i Fixed", iPar)); | |
320 | } | |
321 | ||
322 | void AliITSAlignMille::ResetLocalEquation() | |
323 | { | |
324 | /// Reset the derivative vectors | |
325 | for(int i=0; i<fNLocal; i++) { | |
326 | fLocalDerivatives[i] = 0.0; | |
327 | } | |
328 | for(int i=0; i<fNGlobal; i++) { | |
329 | fGlobalDerivatives[i] = 0.0; | |
330 | } | |
331 | } | |
332 | ||
333 | Int_t AliITSAlignMille::InitModuleParams() { | |
334 | /// initialize geometry parameters for a given detector | |
335 | /// for current cluster (fCluster) | |
336 | /// fGlobalInitParam[] is set as: | |
337 | /// [tx,ty,tz,psi,theta,phi] | |
338 | /// (old was [tx,ty,tz,theta,psi,phi] ROOT's angles...) | |
339 | /// *** At the moment: using Raffalele's angles definition *** | |
340 | /// | |
341 | /// Num of Dets: ITSMILLE_NDETELEM = fgNDetElem | |
342 | /// Num of Par : ITSMILLE_NPARCH = fgNParCh | |
343 | /// return 0 if success | |
344 | ||
345 | if (!fGeoManager) { | |
346 | AliInfo("ITS geometry not initialized!"); | |
347 | return -1; | |
348 | } | |
349 | ||
350 | // set the internal index (index in module list) | |
351 | UShort_t voluid=fCluster.GetVolumeID(); | |
352 | Int_t k=fNModules-1; | |
353 | while (k>=0 && !(voluid==fModuleVolumeID[k]) ) k--; | |
354 | if (k<0) return -3; | |
355 | fCurrentModuleInternalIndex=k; | |
356 | ||
357 | // set the index | |
358 | Int_t index = GetModuleIndex(AliGeomManager::SymName(voluid)); | |
359 | if (index<0) return -2; | |
360 | fCurrentModuleIndex = index; | |
361 | ||
362 | fModuleInitParam[0] = 0.0; | |
363 | fModuleInitParam[1] = 0.0; | |
364 | fModuleInitParam[2] = 0.0; | |
365 | fModuleInitParam[3] = 0.0; // psi (X) | |
366 | fModuleInitParam[4] = 0.0; // theta (Y) | |
367 | fModuleInitParam[5] = 0.0; // phi (Z) | |
368 | ||
369 | /// get global (corrected) matrix | |
370 | // if (!AliITSgeomTGeo::GetOrigMatrix(index,*fCurrentModuleHMatrix)) return -3; | |
371 | Double_t rott[9]; | |
372 | if (!AliITSgeomTGeo::GetRotation(index,rott)) return -3; | |
373 | fCurrentModuleHMatrix->SetRotation(rott); | |
374 | Double_t oLoc[3]={0,0,0}; | |
375 | if (!AliITSgeomTGeo::LocalToGlobal(index,oLoc,fCurrentModuleTranslation)) return -4; | |
376 | fCurrentModuleHMatrix->SetTranslation(fCurrentModuleTranslation); | |
377 | ||
378 | /// get back local coordinates | |
379 | fMeasGlo[0] = fCluster.GetX(); | |
380 | fMeasGlo[1] = fCluster.GetY(); | |
381 | fMeasGlo[2] = fCluster.GetZ(); | |
382 | fCurrentModuleHMatrix->MasterToLocal(fMeasGlo,fMeasLoc); | |
383 | ||
384 | // set stdev from cluster | |
385 | TGeoHMatrix hcov; | |
386 | Double_t hcovel[9]; | |
387 | hcovel[0]=double(fCluster.GetCov()[0]); | |
388 | hcovel[1]=double(fCluster.GetCov()[1]); | |
389 | hcovel[2]=double(fCluster.GetCov()[3]); | |
390 | hcovel[3]=double(fCluster.GetCov()[1]); | |
391 | hcovel[4]=double(fCluster.GetCov()[2]); | |
392 | hcovel[5]=double(fCluster.GetCov()[4]); | |
393 | hcovel[6]=double(fCluster.GetCov()[3]); | |
394 | hcovel[7]=double(fCluster.GetCov()[4]); | |
395 | hcovel[8]=double(fCluster.GetCov()[5]); | |
396 | hcov.SetRotation(hcovel); | |
397 | // now rotate in local system | |
398 | hcov.MultiplyLeft(&fCurrentModuleHMatrix->Inverse()); | |
399 | hcov.Multiply(fCurrentModuleHMatrix); | |
400 | ||
401 | // per i ruotati c'e' delle sigmaY che compaiono... prob | |
402 | // e' un problema di troncamento | |
403 | fSigmaLoc[0] = TMath::Sqrt(TMath::Abs(hcov.GetRotationMatrix()[0])); | |
404 | fSigmaLoc[1] = TMath::Sqrt(TMath::Abs(hcov.GetRotationMatrix()[4])); | |
405 | fSigmaLoc[2] = TMath::Sqrt(TMath::Abs(hcov.GetRotationMatrix()[8])); | |
406 | ||
407 | AliDebug(2,Form("Setting StDev from CovMat : fSigmaLocX=%f fSigmaLocY=%f fSigmaLocZ=%f \n",fSigmaLoc[0] ,fSigmaLoc[1] ,fSigmaLoc[2] )); | |
408 | ||
409 | return 0; | |
410 | } | |
411 | ||
412 | void AliITSAlignMille::SetCurrentModule(Int_t index) { | |
413 | /// | |
414 | UShort_t voluid=GetModuleVolumeID(index); | |
415 | if (voluid) { | |
416 | fCluster.SetVolumeID(voluid); | |
417 | fCluster.SetXYZ(0,0,0); | |
418 | InitModuleParams(); | |
419 | } | |
420 | } | |
421 | ||
422 | void AliITSAlignMille::Print(Option_t* /* opt */) const { | |
423 | /// | |
424 | printf("*** AliMillepede for ITS ***\n"); | |
425 | printf(" number of defined modules: %d\n",fNModules); | |
426 | if (fGeoManager) | |
427 | printf(" geometry loaded from %s\n",fGeometryFileName.Data()); | |
428 | else | |
429 | printf(" geometry not loaded\n"); | |
430 | if (fUseLocalShifts) | |
431 | printf(" Alignment shifts will be computed in LOCAL RS\n"); | |
432 | else | |
433 | printf(" Alignment shifts will be computed in GLOBAL RS\n"); | |
434 | printf(" Millepede configuration parameters:\n"); | |
435 | printf(" init parsig for translations : %.4f\n",fParSigTranslations); | |
436 | printf(" init parsig for rotations : %.4f\n",fParSigRotations); | |
437 | printf(" init value for chi2 cut : %.4f\n",fStartFac); | |
438 | printf(" first iteration cut value : %.4f\n",fResCutInitial); | |
439 | printf(" other iterations cut value : %.4f\n",fResCut); | |
440 | printf(" number of stddev for chi2 cut : %d\n",fNStdDev); | |
441 | ||
442 | printf("List of defined modules:\n"); | |
443 | printf(" intidx\tindex\tvoluid\tsymname\n"); | |
444 | for (int i=0; i<fNModules; i++) | |
445 | printf(" %d\t%d\t%d\t%s\n",i,fModuleIndex[i],fModuleVolumeID[i],AliITSgeomTGeo::GetSymName(fModuleIndex[i])); | |
446 | } | |
447 | ||
448 | void AliITSAlignMille::PrintCurrentModuleInfo() { | |
449 | /// | |
450 | if (fCurrentModuleIndex<0 || fCurrentModuleIndex>2197) return; | |
451 | UShort_t voluid=fModuleVolumeID[fCurrentModuleInternalIndex]; | |
452 | printf("Current module: index=%d voluid=%d\n",fCurrentModuleIndex,voluid); | |
453 | printf(" symname:%s\n",AliGeomManager::SymName(voluid)); | |
454 | printf(" TGeoHMatrix: \n"); | |
455 | fCurrentModuleHMatrix->Print(); | |
456 | } | |
457 | ||
458 | ||
459 | void AliITSAlignMille::InitTrackParams(int meth) { | |
460 | /// initialize local parameters with different methods | |
461 | /// for current track (fTrack) | |
462 | ||
463 | switch (meth) { | |
464 | case 1: // simple linear interpolation | |
465 | // get local starting parameters (to be substituted by ESD track parms) | |
466 | // local parms (fLocalInitParam[]) are: | |
467 | // [0] = global x coord. of straight line intersection at y=0 plane | |
468 | // [1] = global z coord. of straight line intersection at y=0 plane | |
469 | // [2] = px/py | |
470 | // [3] = pz/py | |
471 | ||
472 | // test #1: linear fit in x(y) and z(y) | |
473 | Int_t npts = fTrack->GetNPoints(); | |
474 | ||
475 | TF1 *f1=new TF1("f1","[0]+x*[1]",-50,50); | |
476 | ||
477 | TGraph *g=new TGraph(npts,fTrack->GetY(),fTrack->GetX()); | |
478 | g->Fit(f1,"RNQ"); | |
479 | fLocalInitParam[0] = f1->GetParameter(0); | |
480 | fLocalInitParam[2] = f1->GetParameter(1); | |
481 | AliDebug(2,Form("X = p0gx + ugx*Y : p0gx = %f +- %f ugx = %f +- %f\n",fLocalInitParam[0],f1->GetParError(0),fLocalInitParam[2],f1->GetParError(1))); | |
482 | delete g; g=NULL; | |
483 | ||
484 | g=new TGraph(npts,fTrack->GetY(),fTrack->GetZ()); | |
485 | g->Fit(f1,"RNQ"); | |
486 | fLocalInitParam[1] = f1->GetParameter(0); | |
487 | fLocalInitParam[3] = f1->GetParameter(1); | |
488 | AliDebug(2,Form("Z = p0gz + ugz*Y : p0gz=%f ugz=%f\n",fLocalInitParam[1],fLocalInitParam[3])); | |
489 | delete g; | |
490 | delete f1; | |
491 | ||
492 | break; | |
493 | } | |
494 | ||
495 | } | |
496 | Bool_t AliITSAlignMille::CheckVolumeID(UShort_t voluid) const | |
497 | { | |
498 | /// | |
499 | Int_t k=fNModules-1; | |
500 | while (k>=0 && !(voluid==fModuleVolumeID[k]) ) k--; | |
501 | //printf("selected element with voluid=%d : %d\n",voluid,k); | |
502 | if (k>=0) return kTRUE; | |
503 | return kFALSE; | |
504 | } | |
505 | ||
506 | Int_t AliITSAlignMille::CheckCurrentTrack() { | |
507 | /// checks if AliTrackPoints belongs to defined modules | |
508 | /// return number of good poins | |
509 | /// return 0 if not enough points | |
510 | ||
511 | Int_t npts = fTrack->GetNPoints(); | |
512 | Int_t ngoodpts=0; | |
513 | // debug points | |
514 | for (int j=0; j<npts; j++) { | |
515 | UShort_t voluid = fTrack->GetVolumeID()[j]; | |
516 | if (CheckVolumeID(voluid)) { | |
517 | ngoodpts++; | |
518 | } | |
519 | } | |
520 | // pepo da controllare... | |
521 | if (ngoodpts<fMinNPtsPerTrack) return 0; | |
522 | ||
523 | return ngoodpts; | |
524 | } | |
525 | ||
526 | Int_t AliITSAlignMille::ProcessTrack(AliTrackPointArray *track) { | |
527 | /// Process track; Loop over hits and set local equations | |
528 | /// here 'track' is a AliTrackPointArray | |
529 | /// return 0 if success; | |
530 | ||
531 | if (!fIsMilleInit) { | |
532 | AliInfo("Millepede has not been initialized!"); | |
533 | return -1; | |
534 | } | |
535 | ||
536 | Int_t npts = track->GetNPoints(); | |
537 | AliDebug(2,Form("\n*** Processing track with %d points ***\n",npts)); | |
538 | fTrack = track; | |
539 | ||
540 | // checks if there are enough good points | |
541 | if (!CheckCurrentTrack()) { | |
542 | AliInfo("Track with not enough good points - will not be used..."); | |
543 | return -1; | |
544 | } | |
545 | ||
546 | // set local starting parameters (to be substituted by ESD track parms) | |
547 | // local parms (fLocalInitParam[]) are: | |
548 | // [0] = global x coord. of straight line intersection at y=0 plane | |
549 | // [1] = global z coord. of straight line intersection at y=0 plane | |
550 | // [2] = px/py | |
551 | // [3] = pz/py | |
552 | InitTrackParams(1); | |
553 | ||
554 | for (Int_t ipt=0; ipt<npts; ipt++) { | |
555 | fTrack->GetPoint(fCluster,ipt); | |
556 | if (!CheckVolumeID(fCluster.GetVolumeID())) continue; | |
557 | ||
558 | // set geometry parameters for the the current module | |
559 | AliDebug(2,Form("\n--- processing point %d --- \n",ipt)); | |
560 | if (InitModuleParams()) continue; | |
561 | ||
562 | AliDebug(2,Form(" VolID=%d Index=%d InternalIdx=%d symname=%s\n", track->GetVolumeID()[ipt], fCurrentModuleIndex ,fCurrentModuleInternalIndex, AliGeomManager::SymName(track->GetVolumeID()[ipt]) )); | |
563 | AliDebug(2,Form(" Point = ( %f , %f , %f ) \n",track->GetX()[ipt],track->GetY()[ipt],track->GetZ()[ipt])); | |
564 | ||
565 | if (SetLocalEquations()) return -1; | |
566 | ||
567 | } // end loop over points | |
568 | ||
569 | return 0; | |
570 | } | |
571 | ||
572 | Int_t AliITSAlignMille::CalcIntersectionPoint(Double_t *lpar, Double_t *gpar) { | |
573 | /// calculate track intersection point in local coordinates | |
574 | /// according with a given set of parameters (local(4) and global(6)) | |
575 | /// and fill fPintLoc/Glo | |
576 | /// local are: pgx0, pgz0, ugx0, ugz0 | |
577 | /// global are: tx,ty,tz,psi,theta,phi (Raff's delta angles in deg.) | |
578 | /// return 0 if success | |
579 | ||
580 | 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])); | |
581 | ||
582 | // vector of initial straight line direction in glob. coord | |
583 | // ATTENZIONE: forse va rinormalizzato tutto... | |
584 | Double_t v0g[3]; | |
585 | //Double_t | |
586 | v0g[0]=lpar[2]; | |
587 | v0g[1]=1.0; | |
588 | v0g[2]=lpar[3]; | |
589 | ||
590 | // intercept in yg=0 plane in glob coord | |
591 | Double_t p0g[3]; | |
592 | p0g[0]=lpar[0]; | |
593 | p0g[1]=0.0; | |
594 | p0g[2]=lpar[1]; | |
595 | ||
596 | ||
597 | // prepare the TGeoHMatrix | |
598 | Double_t tr[3],ang[3]; | |
599 | //Double_t rad2deg=180./TMath::Pi(); | |
600 | if (fUseLocalShifts) { // just Delta matrix | |
601 | tr[0]=gpar[0]; | |
602 | tr[1]=gpar[1]; | |
603 | tr[2]=gpar[2]; | |
604 | ang[0]=gpar[3]; // psi (X) | |
605 | ang[1]=gpar[4]; // theta (Y) | |
606 | ang[2]=gpar[5]; // phi (Z) | |
607 | } | |
608 | else { // total matrix with shifted parameter | |
609 | AliInfo("global shifts not implemented yet!"); | |
610 | return -1; | |
611 | } | |
612 | ||
613 | //printf("fTempRot = 0x%x - ang = %g %g %g \n",fTempRot,gpar[5]*rad2deg,gpar[3]*rad2deg,gpar[4]*rad2deg); | |
614 | ||
615 | fTempAlignObj->SetRotation(ang[0],ang[1],ang[2]); | |
616 | AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2])); | |
617 | TGeoHMatrix hm; | |
618 | fTempAlignObj->GetMatrix(hm); | |
619 | fTempHMat->SetRotation(hm.GetRotationMatrix()); | |
620 | fTempHMat->SetTranslation(tr); | |
621 | ||
622 | // in this case the gpar[] array contains only shifts | |
623 | // and fInitModuleParam[] are set to 0 | |
624 | // fCurrentModuleHMatrix is then modified as fCurrentHM*fTempHM | |
625 | if (fUseLocalShifts) | |
626 | fTempHMat->MultiplyLeft(fCurrentModuleHMatrix); | |
627 | ||
628 | // same in local coord. | |
629 | Double_t p0l[3],v0l[3]; | |
630 | fTempHMat->MasterToLocalVect(v0g,v0l); | |
631 | fTempHMat->MasterToLocal(p0g,p0l); | |
632 | ||
633 | if (TMath::Abs(v0l[1])<1e-15) { | |
634 | AliInfo("Track Y direction in local frame is zero! Cannot proceed..."); | |
635 | return -1; | |
636 | } | |
637 | ||
638 | // local intersection point | |
639 | fPintLoc[0] = p0l[0] - (v0l[0]/v0l[1])*p0l[1]; | |
640 | fPintLoc[1] = 0; | |
641 | fPintLoc[2] = p0l[2] - (v0l[2]/v0l[1])*p0l[1]; | |
642 | ||
643 | // global intersection point | |
644 | fTempHMat->LocalToMaster(fPintLoc,fPintGlo); | |
645 | 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])); | |
646 | ||
647 | return 0; | |
648 | } | |
649 | ||
650 | Int_t AliITSAlignMille::CalcDerivatives(Int_t paridx, Bool_t islpar) { | |
651 | /// calculate numerically (ROOT's style) the derivatives for | |
652 | /// local X intersection and local Z intersection | |
653 | /// parlist: local (islpar=kTRUE) pgx0, pgz0, ugx0, ugz0 | |
654 | /// global (islpar=kFALSE) tx, ty, tz, psi, theta, phi (Raf's angles in deg) | |
655 | /// return 0 if success | |
656 | ||
657 | // copy initial parameters | |
658 | Double_t lpar[ITSMILLE_NLOCAL]; | |
659 | Double_t gpar[ITSMILLE_NPARCH]; | |
660 | for (Int_t i=0; i<ITSMILLE_NLOCAL; i++) lpar[i]=fLocalInitParam[i]; | |
661 | for (Int_t i=0; i<ITSMILLE_NPARCH; i++) gpar[i]=fModuleInitParam[i]; | |
662 | ||
663 | // pepopepo | |
664 | // trial with fixed dpar... | |
665 | Double_t dpar=0.0; | |
666 | if (islpar) { | |
667 | //dpar=fLocalInitParam[paridx]*0.001; | |
668 | // set minimum dpar | |
669 | if (paridx<2) dpar=1.0e-4; // translations | |
670 | else dpar=1.0e-6; // direction | |
671 | } | |
672 | else { | |
673 | //dpar=fModuleInitParam[paridx]*0.001; | |
674 | if (paridx<3) dpar=1.0e-4; // translations | |
675 | else dpar=1.0e-2; // angles | |
676 | } | |
677 | AliDebug(3,Form("\n+++ automatic dpar=%g\n",dpar)); | |
678 | if (fDeltaPar) dpar=fDeltaPar; | |
679 | AliDebug(3,Form("+++ using dpar=%g\n\n",dpar)); | |
680 | ||
681 | // calculate derivative ROOT's like: | |
682 | // using f(x+h),f(x-h),f(x+h/2),f(x-h2)... | |
683 | Double_t pintl1[3]; // f(x-h) | |
684 | Double_t pintl2[3]; // f(x-h/2) | |
685 | Double_t pintl3[3]; // f(x+h/2) | |
686 | Double_t pintl4[3]; // f(x+h) | |
687 | ||
688 | // first values | |
689 | if (islpar) lpar[paridx] -= dpar; | |
690 | else gpar[paridx] -= dpar; | |
691 | if (CalcIntersectionPoint(lpar, gpar)) return -2; | |
692 | for (Int_t i=0; i<3; i++) pintl1[i]=fPintLoc[i]; | |
693 | ||
694 | // second values | |
695 | if (islpar) lpar[paridx] += dpar/2; | |
696 | else gpar[paridx] += dpar/2; | |
697 | if (CalcIntersectionPoint(lpar, gpar)) return -2; | |
698 | for (Int_t i=0; i<3; i++) pintl2[i]=fPintLoc[i]; | |
699 | ||
700 | // third values | |
701 | if (islpar) lpar[paridx] += dpar; | |
702 | else gpar[paridx] += dpar; | |
703 | if (CalcIntersectionPoint(lpar, gpar)) return -2; | |
704 | for (Int_t i=0; i<3; i++) pintl3[i]=fPintLoc[i]; | |
705 | ||
706 | // fourth values | |
707 | if (islpar) lpar[paridx] += dpar/2; | |
708 | else gpar[paridx] += dpar/2; | |
709 | if (CalcIntersectionPoint(lpar, gpar)) return -2; | |
710 | for (Int_t i=0; i<3; i++) pintl4[i]=fPintLoc[i]; | |
711 | ||
712 | Double_t h2 = 1./(2.*dpar); | |
713 | Double_t d0 = pintl4[0]-pintl1[0]; | |
714 | Double_t d2 = 2.*(pintl3[0]-pintl2[0]); | |
715 | fDerivativeXLoc = h2*(4*d2 - d0)/3.; | |
716 | if (TMath::Abs(fDerivativeXLoc) < 1.0e-9) fDerivativeXLoc=0.0; | |
717 | ||
718 | d0 = pintl4[2]-pintl1[2]; | |
719 | d2 = 2.*(pintl3[2]-pintl2[2]); | |
720 | fDerivativeZLoc = h2*(4*d2 - d0)/3.; | |
721 | if (TMath::Abs(fDerivativeZLoc) < 1.0e-9) fDerivativeZLoc=0.0; | |
722 | ||
723 | AliDebug(3,Form("\n+++ derivatives +++ \n")); | |
724 | AliDebug(3,Form("+++ dXLoc/dpar = %g +++\n",fDerivativeXLoc)); | |
725 | AliDebug(3,Form("+++ dZLoc/dpar = %g +++\n\n",fDerivativeZLoc)); | |
726 | ||
727 | return 0; | |
728 | } | |
729 | ||
730 | Int_t AliITSAlignMille::SetLocalEquations() { | |
731 | /// Define local equation for current track and cluster in x coor. | |
732 | /// return 0 if success | |
733 | ||
734 | // store first interaction point | |
735 | CalcIntersectionPoint(fLocalInitParam, fModuleInitParam); | |
736 | for (Int_t i=0; i<3; i++) fPintLoc0[i]=fPintLoc[i]; | |
737 | ||
738 | // calculate local derivatives numerically | |
739 | Double_t dXdL[ITSMILLE_NLOCAL],dZdL[ITSMILLE_NLOCAL]; | |
740 | for (Int_t i=0; i<ITSMILLE_NLOCAL; i++) { | |
741 | if (CalcDerivatives(i,kTRUE)) return -1; | |
742 | dXdL[i]=fDerivativeXLoc; | |
743 | dZdL[i]=fDerivativeZLoc; | |
744 | } | |
745 | ||
746 | Double_t dXdG[ITSMILLE_NPARCH],dZdG[ITSMILLE_NPARCH]; | |
747 | for (Int_t i=0; i<ITSMILLE_NPARCH; i++) { | |
748 | if (CalcDerivatives(i,kFALSE)) return -1; | |
749 | dXdG[i]=fDerivativeXLoc; | |
750 | dZdG[i]=fDerivativeZLoc; | |
751 | } | |
752 | ||
753 | AliDebug(2,Form("\n***************\n")); | |
754 | for (Int_t i=0; i<ITSMILLE_NLOCAL; i++) | |
755 | AliDebug(2,Form("Local parameter %d - dXdpar = %g - dZdpar = %g\n",i,dXdL[i],dZdL[i])); | |
756 | for (Int_t i=0; i<ITSMILLE_NPARCH; i++) | |
757 | AliDebug(2,Form("Global parameter %d - dXdpar = %g - dZdpar = %g\n",i,dXdG[i],dZdG[i])); | |
758 | AliDebug(2,Form("\n***************\n")); | |
759 | ||
760 | ||
761 | AliDebug(2,Form("setting local equation X with fMeas=%.6f and fSigma=%.6f",(fMeasLoc[0]-fPintLoc0[0]), fSigmaLoc[0])); | |
762 | // set equation for Xloc coordinate | |
763 | for (Int_t i=0; i<ITSMILLE_NLOCAL; i++) | |
764 | SetLocalDerivative(i,dXdL[i]); | |
765 | for (Int_t i=0; i<ITSMILLE_NPARCH; i++) | |
766 | SetGlobalDerivative(fCurrentModuleInternalIndex*ITSMILLE_NPARCH+i,dXdG[i]); | |
767 | fMillepede->SetLocalEquation(fGlobalDerivatives, fLocalDerivatives, (fMeasLoc[0]-fPintLoc0[0]), fSigmaLoc[0]); | |
768 | ||
769 | ||
770 | AliDebug(2,Form("setting local equation Z with fMeas=%.6f and fSigma=%.6f",(fMeasLoc[2]-fPintLoc0[2]), fSigmaLoc[2])); | |
771 | // set equation for Zloc coordinate | |
772 | for (Int_t i=0; i<ITSMILLE_NLOCAL; i++) | |
773 | SetLocalDerivative(i,dZdL[i]); | |
774 | for (Int_t i=0; i<ITSMILLE_NPARCH; i++) | |
775 | SetGlobalDerivative(fCurrentModuleInternalIndex*ITSMILLE_NPARCH+i,dZdG[i]); | |
776 | fMillepede->SetLocalEquation(fGlobalDerivatives, fLocalDerivatives, (fMeasLoc[2]-fPintLoc0[2]), fSigmaLoc[2]); | |
777 | ||
778 | return 0; | |
779 | } | |
780 | ||
781 | ||
782 | void AliITSAlignMille::LocalFit(Int_t iTrack, Double_t *lTrackParam, Int_t lSingleFit) { | |
783 | /// Call local fit for this track | |
784 | if (!fIsMilleInit) { | |
785 | AliInfo("Millepede has not been initialized!"); | |
786 | return; | |
787 | } | |
788 | Int_t iRes = fMillepede->LocalFit(iTrack,lTrackParam,lSingleFit); | |
789 | AliDebug(2,Form("iRes = %d",iRes)); | |
790 | if (iRes && !lSingleFit) { | |
791 | fMillepede->SetNLocalEquations(fMillepede->GetNLocalEquations()+1); | |
792 | } | |
793 | } | |
794 | ||
795 | void AliITSAlignMille::GlobalFit(Double_t *parameters,Double_t *errors,Double_t *pulls) { | |
796 | /// Call global fit; Global parameters are stored in parameters | |
797 | if (!fIsMilleInit) { | |
798 | AliInfo("Millepede has not been initialized!"); | |
799 | return; | |
800 | } | |
801 | fMillepede->GlobalFit(parameters,errors,pulls); | |
802 | AliInfo("Done fitting global parameters!"); | |
803 | } | |
804 | ||
805 | Double_t AliITSAlignMille::GetParError(Int_t iPar) { | |
806 | /// Get error of parameter iPar | |
807 | if (!fIsMilleInit) { | |
808 | AliInfo("Millepede has not been initialized!"); | |
809 | return 0; | |
810 | } | |
811 | Double_t lErr = fMillepede->GetParError(iPar); | |
812 | return lErr; | |
813 | } | |
814 | ||
815 | void AliITSAlignMille::PrintGlobalParameters() { | |
816 | /// Print global parameters | |
817 | if (!fIsMilleInit) { | |
818 | AliInfo("Millepede has not been initialized!"); | |
819 | return; | |
820 | } | |
821 | fMillepede->PrintGlobalParameters(); | |
822 | } | |
823 | ||
824 | // //_________________________________________________________________________ | |
825 |