1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 //////////////////////////////////////////////////////////////////////////
18 // AliHMPIDReconHTA //
20 // HMPID class to perfom pattern recognition based on Hough transfrom //
21 // for single chamber //
22 //////////////////////////////////////////////////////////////////////////
24 #include "AliHMPIDReconHTA.h"//class header
25 #include "AliHMPIDCluster.h" //CkovHiddenTrk()
26 #include "AliHMPIDRecon.h" //FunMinPhot()
27 #include <TFile.h> //Database()
28 #include <TMinuit.h> //FitFree()
29 #include <TClonesArray.h> //CkovHiddenTrk()
30 #include <AliESDtrack.h> //CkovHiddenTrk()
31 #include <TH2F.h> //InitDatabase()
32 #include <TGraph.h> //ShapeModel()
33 #include <TSpline.h> //ShapeModel()
34 #include <TCanvas.h> //ShapeModel()
35 #include "TStopwatch.h" //
37 Int_t AliHMPIDReconHTA::fgDB[500][150]={{75000*0}};
38 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
39 AliHMPIDReconHTA::AliHMPIDReconHTA():
40 TNamed("RichRec","RichPat"),
61 fParam(AliHMPIDParam::Instance())
66 fParam->SetRefIdx(fParam->MeanIdxRad()); // initialization of ref index to a default one
69 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
70 AliHMPIDReconHTA::~AliHMPIDReconHTA()
74 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
75 void AliHMPIDReconHTA::InitVars(Int_t n)
80 fXClu = new Double_t[n];
81 fYClu = new Double_t[n];
82 fPhiPhot = new Double_t[n];
83 fThetaPhot = new Double_t[n];
84 fClCk = new Bool_t[n];
85 for(Int_t i=0;i<n;i++) fClCk[i] = kTRUE;
88 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
89 void AliHMPIDReconHTA::DeleteVars()const
94 if(fXClu) delete [] fXClu;
95 if(fYClu) delete [] fYClu;
96 if(fPhiPhot) delete [] fPhiPhot;
97 if(fThetaPhot) delete [] fThetaPhot;
98 if(fClCk) delete [] fClCk;
100 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
101 Bool_t AliHMPIDReconHTA::CkovHiddenTrk(AliESDtrack *pTrk,TClonesArray *pCluLst,Int_t index, Double_t nmean)
103 // Pattern recognition method without any infos from tracking:HTA (Hidden Track Algorithm)...
104 // The method finds in the chmuber the cluster with the highest charge
105 // compatibile with a MIP, then the strategy is applied
106 // Arguments: pTrk - pointer to ESD track
107 // pCluLs - list of clusters for a given chamber
108 // pNmean - pointer to ref. index
109 // pQthre - pointer to qthre
110 // Returns: - 0=ok,1=not fitted
112 AliHMPIDParam *pParam = AliHMPIDParam::Instance();
114 if(!CluPreFilter(pCluLst)) return kFALSE;
119 fNClu = pCluLst->GetEntriesFast();
121 for (Int_t iClu=0;iClu<fNClu;iClu++){ //clusters loop
122 AliHMPIDCluster *pClu=(AliHMPIDCluster*)pCluLst->UncheckedAt(iClu); //get pointer to current cluster
123 fXClu[iClu] = pClu->X();fYClu[iClu] = pClu->Y(); //store x,y for fitting procedure
124 fClCk[iClu] = kTRUE; //all cluster are accepted at this stage to be reconstructed
131 sizeClu = pClu->Size();
133 fClCk[index] = kFALSE;
135 AliDebug(1,Form(" MIP n. %i x %f y %f Q %f",iClu,pClu->X(),pClu->Y(),pClu->Q()));
139 pParam->SetRefIdx(nmean);
142 Float_t xra,yra,th,ph; pTrk->GetHMPIDtrk(xra,yra,th,ph);
143 AliDebug(1,Form(" simulated phiTRK %6.2f thetaTRK %6.2f",ph*TMath::RadToDeg(),th*TMath::RadToDeg()));
146 if(!DoRecHiddenTrk()) {
147 pTrk->SetHMPIDsignal(pParam->kNoPhotAccept);
149 } //Do track and ring reconstruction,if problems returns 1
150 AliDebug(1,Form(" fitted phi %6.2f ",fPhTrkFit*TMath::RadToDeg()));
152 pTrk->SetHMPIDtrk(fRadX,fRadY,fThTrkFit,fPhTrkFit); //store track intersection info
153 pTrk->SetHMPIDmip(fMipX,fMipY,(Int_t)fMipQ,NCluFit()); //store mip info + n. phots of the ring
154 pTrk->SetHMPIDcluIdx(nCh,fIdxMip+1000*sizeClu); //set cham number, index of cluster + cluster size
155 pTrk->SetHMPIDsignal(fCkovFit); //find best Theta ckov for ring i.e. track
156 pTrk->SetHMPIDchi2(fCkovSig2); //errors squared
157 AliDebug(1,Form(" n clusters tot %i fitted to ring %i",fNClu,NCluFit()));
158 for(Int_t i=0;i<fNClu;i++) {
159 AliDebug(1,Form(" n.%3i ThetaCer %8.3f PhiCer %8.3f check %i",i,fThetaPhot[i],fPhiPhot[i],fClCk[i]));
161 AliDebug(1,Form("CkovHiddenTrk: thetaC %f th %f ph %f",fCkovFit,fThTrkFit*TMath::RadToDeg(),fPhTrkFit*TMath::RadToDeg()));
166 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
167 Bool_t AliHMPIDReconHTA::DoRecHiddenTrk()
169 // Pattern recognition method without any infos from tracking...
170 // First a preclustering filter to avoid part of the noise
171 // Then only ellipsed-rings are fitted (no possibility,
172 // for the moment, to reconstruct very inclined tracks)
173 // Finally a fitting with (th,ph) free, starting by very close values
174 // previously evaluated.
177 Double_t thTrkRec,phiTrkRec,thetaCRec;
179 if(!FindShape(thTrkRec,phiTrkRec,thetaCRec)) {
180 AliDebug(1,Form(" FindShape failed...!"));
183 AliDebug(1,Form(" FindShape accepted...!"));
185 if(!FitRing(thTrkRec,phiTrkRec)) {
186 AliDebug(1,Form(" FitRing failed...!"));
189 AliDebug(1,Form(" FitRing accepted...!"));
191 if(!UniformDistrib()) {
192 AliDebug(1,Form(" UniformDistrib failed...!"));
195 AliDebug(1,Form(" UniformDistrib accepted...!"));
199 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
200 Bool_t AliHMPIDReconHTA::CluPreFilter(TClonesArray *pCluLst)
202 // Pre-filter of bkg clusters
203 // Arguments: pSluLst - List of the clusters for a given chamber
204 // Returns: status - TRUE if filtering leaves enough photons, FALSE if not
206 Int_t nClusTot = pCluLst->GetEntriesFast();
207 if(nClusTot<4||nClusTot>100) {
214 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
215 Bool_t AliHMPIDReconHTA::FindShape(Double_t &thTrkRec,Double_t &phiTrkRec,Double_t &thetaCRec)
217 // Finds the estimates for phi and theta of the track and the ThetaCerenkov
218 // by using a database of the shapes of the rings
220 // Returns: thTrkRec - estimate of theta track
221 // phiTrkRec - estimate of phi track
222 // thetaCRec - estimate of ThetaCerenkov
223 // status - TRUE if a good solution is found, FALSE if not
225 Double_t phiphot[1000];
231 if(fNClu>1000) return kFALSE; // too many clusters....
233 // Sort in phi angle...
234 for(Int_t i=0;i<fNClu;i++) {
236 AliDebug(1,Form(" n.%3i xMIP %8.3f yMIP %8.3f check %i",i,fMipX,fMipY,fClCk[i]));
241 phiphot[i] = (TMath::ATan2(fMipY-fYClu[i],fMipX-fXClu[i])+TMath::Pi())*TMath::RadToDeg();
242 dist[i]=TMath::Sqrt((fMipX-fXClu[i])*(fMipX-fXClu[i])+(fMipY-fYClu[i])*(fMipY-fYClu[i]));
243 AliDebug(1,Form(" n.%3i phiphot %8.3f dist %8.3f check %i",i,phiphot[i],dist[i],fClCk[i]));
246 TMath::Sort(fNClu,phiphot,indphi,kFALSE);
248 // Purify with a truncated mean;
252 for(Int_t i=0;i<fNClu;i++) {
253 if(!fClCk[indphi[i]]) continue; // Check if a good photon candidate or not
254 dMean +=dist[indphi[i]];
255 dMean2+=dist[indphi[i]]*dist[indphi[i]];
260 dMean /=(Double_t)np;
261 dMean2 /=(Double_t)np;}
262 Double_t rms = TMath::Sqrt(dMean2 - dMean*dMean);
264 for(Int_t i=0;i<fNClu;i++) {
265 if(!fClCk[indphi[i]]) continue; // Check if a good photon candidate or not
266 if(TMath::Abs(dMean-dist[indphi[i]]) > 1.5*rms) {
267 fClCk[indphi[i]] = kFALSE;
272 AliDebug(1,"Purification of photons...");
274 // purify vectors for good photon candidates
277 Double_t *phiphotP = new Double_t[fNClu+1];
278 Double_t *distP = new Double_t[fNClu+1];
279 for(Int_t i=0;i<fNClu;i++) {
280 AliDebug(1,Form(" n. %3i phiphot %8.3f dist %8.3f check %i",i,phiphot[indphi[i]],dist[indphi[i]],fClCk[indphi[i]]));
281 if(!fClCk[indphi[i]]) continue; // Check if a good photon candidate or not
282 phiphotP[npeff] = phiphot[indphi[i]];
283 distP[npeff] = dist[indphi[i]];
288 AliDebug(1,Form("FindShape failed: no enough photons = %i...",npeff));
297 if(!ShapeModel(npeff,phiphotP,distP,xA,xB,phiTrkRec)) {AliDebug(1,Form("ShapeModel failed ")); return kFALSE;}
299 // if(xA > 50 || xB > 15) {AliDebug(1,Form("xA and xB failed out of range")); return kFALSE;}
304 if(xA > xB) { //geometrically not possible, try to recover on a mean values...
306 FindBinDB(xA,xA,binxDB,binyDB);
307 if(binxDB<0 || binyDB<0) {AliDebug(1,Form("bin < 0 ! failed ")); return kFALSE;}
308 Int_t compactDB1 = CompactDB(binxDB,binyDB);
309 FindBinDB(xB,xB,binxDB,binyDB);
310 if(binxDB<0 || binyDB<0) {AliDebug(1,Form("bin < 0 ! failed ")); return kFALSE;}
311 Int_t compactDB2 = CompactDB(binxDB,binyDB);
312 Double_t thetaCRec1 = (Double_t)(compactDB1%1000);
313 Double_t thetaCRec2 = (Double_t)(compactDB2%1000);
314 Double_t thTrkRec1 = (Double_t)(compactDB1/1000);
315 Double_t thTrkRec2 = (Double_t)(compactDB2/1000);
316 thetaCRec = 0.5*(thetaCRec1+thetaCRec2);
317 thTrkRec = 0.5*( thTrkRec1+ thTrkRec2);
321 FindBinDB(xA,xB,binxDB,binyDB);
322 if(binxDB<0 || binyDB<0) {AliDebug(1,Form("bin < 0 ! failed ")); return kFALSE;}
324 compactDB = CompactDB(binxDB,binyDB);
326 if(compactDB<0) {AliDebug(1,Form("compact< 0! failed ")); return kFALSE;}
329 thetaCRec = (Double_t)(compactDB%1000);
330 thTrkRec = (Double_t)(compactDB/1000);
334 AliDebug(1,Form(" CompactDB %i thTrkRec %8.3f thetaCRec %8.3f ",compactDB,thTrkRec,thetaCRec));
336 phiTrkRec *= TMath::DegToRad();
337 thTrkRec *= TMath::DegToRad();
338 thetaCRec *= TMath::DegToRad();
347 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
348 Bool_t AliHMPIDReconHTA::ShapeModel(Int_t np,Double_t *phiphot,Double_t *dist,Double_t &xA,Double_t &xB,Double_t &phiStart)
350 // Find a Spline curve to define dist. vs. phi angle
351 // in order to estimate the phi of the track
352 // Arguments: np - # points corresponding to # photon candidates
353 // dist - distance of each photon from MIP
354 // phiphot - phi of the photon in the DRS
355 // Returns: xA - min. distance from MIP
356 // xB - dist. from mip perpedicular to the major axis
357 // phiStart- estimate of the track phi
359 TGraph *phigr = new TGraph(np,phiphot,dist);
360 phiStart = FindSimmPhi();
362 Double_t phiStart1 = phiStart;
363 if(phiStart1 > 360) phiStart1 -= 360;
364 Double_t phiStart2 = phiStart+90;
365 if(phiStart2 > 360) phiStart2 -= 360;
366 xA = phigr->Eval(phiStart1);
367 xB = phigr->Eval(phiStart2);
369 AliDebug(1,Form("phiStart %f phiStart1 %f phiStart2 %f ",phiStart,phiStart1,phiStart2));
370 AliDebug(1,Form("xA %f xB %f",xA,xB));
373 if(phiStart>360) phiStart-=360;
377 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
378 Double_t AliHMPIDReconHTA::VertParab(Double_t x1,Double_t y1,Double_t x2, Double_t y2, Double_t x3, Double_t y3)const
380 // It uses parabola from 3 points to evaluate the x-coord of the parab
381 // Arguments: xi,yi - points
382 // Returns: x-coord of the vertex
384 Double_t a = ((x1-x3)*(y1-y2)-(x1-x2)*(y1-y3))/((x1*x1-x2*x2)*(x1-x3)-(x1*x1-x3*x3)*(x1-x2));
385 Double_t b = (y1-y2 - a*(x1*x1-x2*x2))/(x1-x2);
386 // Double_t c = y1 - a*x1*x1-b*x1;
389 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
390 Bool_t AliHMPIDReconHTA::FitRing(Double_t thTrkRec,Double_t phiTrkRec)
392 Double_t th = thTrkRec;
393 Double_t ph = phiTrkRec;
403 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
404 Bool_t AliHMPIDReconHTA::FitFree(Double_t thTrkRec,Double_t phiTrkRec)
406 // Fit performed by minimizing RMS/sqrt(n) of the
407 // photons reconstructed. First phi is fixed and theta
408 // is fouond, then (th,ph) of the track
409 // as free parameters
410 // Arguments: PhiRec phi of the track
413 TMinuit *pMinuit = new TMinuit(2);
415 gMinuit->SetObjectFit((TObject*)this); gMinuit->SetFCN(AliHMPIDReconHTA::FunMinPhot); //set fit function
416 Double_t aArg=-1,parStep,parLow,parHigh; Int_t iErrFlg; //tmp vars for TMinuit
421 pMinuit->mnexcm("SET PRI",&aArg,1,iErrFlg); //suspend all printout from TMinuit
422 pMinuit->mnexcm("SET NOW",&aArg,0,iErrFlg);
424 if(thTrkRec==0) thTrkRec = 3.*TMath::DegToRad(); // not to start from the edge...
426 AliDebug(1,Form(" Minimization STARTED with phiTRK %6.2f thetaTRK %6.2f",phiTrkRec,thTrkRec));
428 pMinuit->mnparm(0," thTrk ",thTrkRec ,parStep=0.01,parLow=0,parHigh=TMath::PiOver4(),iErrFlg);
429 pMinuit->mnparm(1," phiTrk ",phiTrkRec,parStep=0.01,parLow=0,parHigh=TMath::TwoPi(),iErrFlg);
431 pMinuit->FixParameter(1);
432 pMinuit->mnexcm("SIMPLEX" ,&aArg,0,iErrFlg);
433 pMinuit->mnexcm("MIGRAD" ,&aArg,0,iErrFlg);
435 pMinuit->mnexcm("MIGRAD" ,&aArg,0,iErrFlg);
437 pMinuit->mnpout(0,sName,th,d1,d2,d3,iErrFlg);
438 pMinuit->mnpout(1,sName,ph,d1,d2,d3,iErrFlg);
442 par[0] = th;par[1] = ph;
443 pMinuit->Eval(2,grad,f,par,3);
448 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
449 void AliHMPIDReconHTA::FunMinPhot(Int_t &/* */,Double_t* /* */,Double_t &f,Double_t *par,Int_t iflag)
451 // Minimization function to find best track and thetaC parameters
452 // Arguments: f = function value to minimize
453 // par = list of parameter to find
454 // iflag = flag status. See Minuit instructions
457 // Note: it is necessary to call an instance of AlihMPIDParam. Not possible to use fParam
458 // because of the static instantiation of the function in Minuit
460 AliHMPIDParam *pParam=AliHMPIDParam::Instance();
461 AliHMPIDReconHTA *pRecHTA=(AliHMPIDReconHTA*)gMinuit->GetObjectFit();
463 Double_t sizeCh = 0.5*pParam->RadThick()+pParam->WinThick()+pParam->GapThick();
464 Double_t thTrk = par[0];
465 Double_t phTrk = par[1];
466 Double_t xrad = pRecHTA->MipX() - sizeCh*TMath::Tan(thTrk)*TMath::Cos(phTrk);
467 Double_t yrad = pRecHTA->MipY() - sizeCh*TMath::Tan(thTrk)*TMath::Sin(phTrk);
468 pRecHTA->SetRadXY(xrad,yrad);
469 pRec.SetTrack(xrad,yrad,thTrk,phTrk);
471 Double_t meanCkov =0;
472 Double_t meanCkov2=0;
473 Double_t thetaCer,phiCer;
475 Int_t nClTot=pRecHTA->NClu();
477 for(Int_t i=0;i<nClTot;i++) {
479 if(pRecHTA->IdxMip() == i) {
480 pRecHTA->SetPhotAngles(i,999.,999.);
484 if(!(pRecHTA->ClCk(i))) continue;
486 Bool_t status = pRec.FindPhotCkov(pRecHTA->XClu(i),pRecHTA->YClu(i),thetaCer,phiCer);
488 pRecHTA->SetPhotAngles(i,999.,999.);
491 pRecHTA->SetPhotAngles(i,thetaCer,phiCer);
492 meanCkov += thetaCer;
493 meanCkov2 += thetaCer*thetaCer;
497 if(nClAcc==0) {f=999;return;}
498 meanCkov /=(Double_t)nClAcc;
499 meanCkov2 /=(Double_t)nClAcc;
500 Double_t rms = TMath::Sqrt(TMath::Abs(meanCkov2 - meanCkov*meanCkov));
501 f = rms/TMath::Sqrt((Double_t)nClAcc);
504 Int_t nClAccStep1 = nClAcc;
506 Double_t meanCkov1=0;
507 Double_t meanCkov3=0;
508 for(Int_t i=0;i<nClTot;i++) {
510 if(!(pRecHTA->ClCk(i))) continue;
511 thetaCer = pRecHTA->PhotTheta(i);
512 if(TMath::Abs(thetaCer-meanCkov)<2*rms) {
513 meanCkov1 += thetaCer;
514 meanCkov3 += thetaCer*thetaCer;
516 } else pRecHTA->SetClCk(i,kFALSE);
520 pRecHTA->SetFitStatus(kFALSE);
521 pRecHTA->SetCkovFit(meanCkov);
522 pRecHTA->SetCkovSig2(rms*rms);
523 pRecHTA->SetNCluFit(nClAccStep1);
528 Double_t rms2 = (meanCkov3 - meanCkov*meanCkov*nClAcc)/nClAcc;
530 // get a logger instance
532 //AliLog::GetRootLogger();
534 if(nClAcc!=nClAccStep1) pRecHTA->SetFitStatus(kTRUE); else pRecHTA->SetFitStatus(kFALSE);
536 pRecHTA->SetCkovFit(meanCkov1);
537 pRecHTA->SetCkovSig2(rms2);
538 pRecHTA->SetNCluFit(nClAcc);
541 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
542 void AliHMPIDReconHTA::InitDatabase()
544 // Construction a database of ring shapes on fly
547 // N.B. fgDB is the distance with x-min from MIP
548 // y-dist from the ring of the MIP perpendicular to major axis
549 // The content is the packed info of track theta and thetaC in degrees
552 // TFile *pout = new TFile("./database.root","recreate");
554 static Bool_t isDone = kFALSE;
566 AliInfo(Form("database HTA is being built.Please, wait..."));
568 Double_t x[3]={0,0,0},y[3];
572 if(!fParam) fParam=AliHMPIDParam::Instance();
573 Double_t thetaMax = TMath::ACos(1./fParam->MeanIdxRad());
574 Double_t thTrkMax = 1./TMath::ASin(fParam->MeanIdxRad());
584 for(Int_t i=0;i<nstepx;i++) { //loop on thetaC
585 for(Int_t j=0;j<nstepy;j++) { //loop on theta particle
586 Double_t thetaC = thetaMax/nstepx*((Double_t)i+0.5);
587 Double_t thTrk = thTrkMax/nstepy*((Double_t)j+0.5);
591 Double_t sizeCh = 0.5*fParam->RadThick()+fParam->WinThick()+fParam->GapThick();
592 Double_t xmip = xrad + sizeCh*TMath::Tan(thTrk)*TMath::Cos(phTrk);
593 Double_t ymip = yrad + sizeCh*TMath::Tan(thTrk)*TMath::Sin(phTrk);
595 Double_t dist1,dist2;
597 //first point at phi=0
599 rec.SetTrack(xrad,yrad,thTrk,phTrk);
601 pos=rec.TracePhot(thetaC,0);
604 dist1 = 0; //open ring...only the distance btw mip and point at 180 will be considered
606 x[0] = pos.X(); y[0] = pos.Y();
607 dist1 = TMath::Sqrt((x[0]-xmip)*(x[0]-xmip)+(y[0]-ymip)*(y[0]-ymip));
610 //second point at phi=180
612 rec.SetTrack(xrad,yrad,thTrk,phTrk);
613 pos=rec.TracePhot(thetaC,TMath::Pi());
615 if(pos.X()==-999) {AliDebug(1,Form("it should not happens!Bye"));return;}
616 x[1] = pos.X(); y[1] = pos.Y();
617 if((x[1]-xmip)*(x[0]-xmip)>0) continue; // to avoid circles out mips (for very low ThetaC)
618 dist2 = TMath::Sqrt((x[1]-xmip)*(x[1]-xmip)+(y[1]-ymip)*(y[1]-ymip));
620 // Double_t distA = dist1+dist2;
621 Double_t distA = dist2; // only the minimum: problem of acceptance
623 //second point at phi=90
625 rec.SetTrack(xrad,yrad,thTrk,phTrk);
626 pos=rec.TracePhot(thetaC,TMath::PiOver2());
628 if(pos.X()==-999) continue;
629 x[2] = pos.X(); y[2] = pos.Y();
630 Double_t distB = TMath::Sqrt((x[2]-xmip)*(x[2]-xmip)+(y[2]-ymip)*(y[2]-ymip));
631 // compact the infos...
632 Int_t compact = (Int_t)(thetaC*TMath::RadToDeg())+1000*(Int_t)(thTrk*TMath::RadToDeg());
634 FindBinDB(distA,distB,binxDB,binyDB);
635 if(fgDB[binxDB][binyDB]==0) fgDB[binxDB][binyDB] = compact;
643 Double_t nSecs = timer.CpuTime();
644 AliInfo(Form("database HTA successfully open in %3.1f sec.(CPU). Reconstruction is started.",nSecs));
652 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
653 void AliHMPIDReconHTA::FillZeroChan()const
655 //If fills eventually channel without entries
656 //inthe histo "database" jyst interpolating the neighboring cells
657 // Arguments: histogram pointer of the database
660 const Int_t nxDB = 500;
661 const Int_t nyDB = 150;
663 for(Int_t i = 0;i<nxDB;i++) {
664 for(Int_t j = 0;j<nyDB;j++) {
665 if(fgDB[i][j] == 0) {
667 Int_t nXmin = i-1; Int_t nXmax=i+1;
668 Int_t nYmin = j-1; Int_t nYmax=j+1;
672 for(Int_t ix=nXmin;ix<=nXmax;ix++) {
673 if(ix<0||ix>=nxDB) continue;
674 for(Int_t iy=nYmin;iy<=nYmax;iy++) {
675 if(iy<0||iy>=nyDB) continue;
676 meanC += (Int_t)(fgDB[ix][iy]%1000);
677 meanTrk+= (Int_t)(fgDB[ix][iy]/1000);
680 meanC/=nc; meanTrk/=nc;
681 Int_t compact = (Int_t)meanC+1000*(Int_t)meanTrk;
682 if(compact>0)fgDB[i][j] = compact;
688 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
689 Int_t AliHMPIDReconHTA::r2(Double_t *coef, Double_t &x1, Double_t &x2)
693 // Arguments: coef 2 1 0: ax^2+bx+c=0
694 // Returns: n. of solutions
701 Double_t delta = b*b-4*a*c;
702 if(delta<0) {return 0;}
712 x1 = (-b+TMath::Sqrt(delta))/(2*a);
713 x2 = (-b-TMath::Sqrt(delta))/(2*a);
716 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
718 Double_t AliHMPIDReconHTA::FindSimmPhi()
720 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
721 // Reconstruction of phiTRK angle with two methods (in switching)
723 // - least square method (for closed rings)
724 // - by minimum distance mip-photon (for open rings)
726 Float_t coeff1ord=0; Float_t coeff2ord=0; Float_t coeff0ord=0;
727 Float_t xrotsumm =0; Float_t yrotsumm =0; Float_t xx =0;
728 Float_t yy =0; Float_t xy =0;
734 Double_t distMin = 999.;
736 for(Int_t i=0;i<fNClu;i++) {
737 if(!fClCk[i]) continue;
739 xrotsumm+=fXClu[i]; // summ xi
740 yrotsumm+=fYClu[i]; // summ yi
741 xx+=fXClu[i]*fXClu[i]; // summ xixi
742 yy+=fYClu[i]*fYClu[i]; // summ yiyi
743 xy+=fXClu[i]*fYClu[i]; // summ yixi
744 Double_t dist2= (fXClu[i]-fMipX)*(fXClu[i]-fMipX)+(fYClu[i]-fMipY)*(fYClu[i]-fMipY);
752 Double_t AngM = TMath::ATan2(ymin-fMipY,(xmin-fMipX))*TMath::RadToDeg();
753 if (AngM<0) AngM+=360;
755 AliDebug(1,Form(" Simple angle prediction with MIN phi = %f",AngM));
757 //_____calc. met min quadr using effective distance _________________________________________________
760 coeff2ord = xy-xrotsumm*yrotsumm/np;
761 coeff1ord = yrotsumm*yrotsumm/np - xrotsumm*xrotsumm/np - yy + xx;
763 coeff0ord = -coeff2ord;
765 AliDebug(1,Form(" a = %f b = %f c = %f",coeff2ord,coeff1ord,coeff0ord));
767 Double_t m1=0, m2=0; Double_t n1=0, n2=0;
769 Double_t coeff[3]={coeff0ord,coeff1ord,coeff2ord};
774 n1=(yrotsumm-m1*xrotsumm)/np;
775 n2=(yrotsumm-m2*xrotsumm)/np;}
776 // 2 solutions.................
778 // negative angles solved...
780 Double_t d1 =(1/(m1*m1+1))*(yy+m1*m1*xx+np*n1*n1-2*m1*xy-2*n1*yrotsumm+2*m1*n1*xrotsumm);
781 Double_t d2 =(1/(m2*m2+1))*(yy+m2*m2*xx+np*n2*n2-2*m2*xy-2*n2*yrotsumm+2*m2*n2*xrotsumm);
783 AliDebug(1,Form(" predicted distance d1 %f for angle %6.2f d2 %f for angle %6.2f",d1,TMath::ATan(m1)*TMath::RadToDeg(),
784 d2,TMath::ATan(m2)*TMath::RadToDeg()));
786 if(d1 > d2) mMin = m2; else mMin = m1;
790 if(ymin < fMipY && xmin > fMipX) {phiTrk = TMath::ATan(mMin)*TMath::RadToDeg()+180;}
791 if(ymin > fMipY && xmin < fMipX) {phiTrk = TMath::ATan(mMin)*TMath::RadToDeg()+360;}
792 if(ymin > fMipY && xmin > fMipX) {phiTrk = TMath::ATan(mMin)*TMath::RadToDeg()+180;}
793 if(ymin < fMipY && xmin < fMipX) {phiTrk = TMath::ATan(mMin)*TMath::RadToDeg();}
794 if(ymin == fMipY && xmin > fMipX) {phiTrk = TMath::ATan(mMin)*TMath::RadToDeg()+180;}
795 if(ymin == fMipY && xmin < fMipX) {phiTrk = TMath::ATan(mMin)*TMath::RadToDeg();}
796 if(ymin < fMipY && xmin == fMipX) {phiTrk = 90;}
797 if(ymin > fMipY && xmin == fMipX) {phiTrk = 270;}
799 // ------------------------- choose the best-----------------------
802 if( AngM-40 <= phiTrk && AngM+40 >= phiTrk) return phiTrk; else return AngM;
804 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
805 void AliHMPIDReconHTA::FindBinDB(Double_t x,Double_t y,Int_t &binX,Int_t &binY)
807 const Int_t nxDB = 500;
808 const Int_t nyDB = 150;
809 const Double_t xlowDB = 0;
810 const Double_t xhigDB = 50;
811 const Double_t ylowDB = 0;
812 const Double_t yhigDB = 30;
816 if(x<xlowDB && x>xhigDB &&
817 y<ylowDB && y>yhigDB) return;
818 binX = Int_t((x-xlowDB)/(xhigDB-xlowDB)*nxDB);
819 binY = Int_t((y-ylowDB)/(yhigDB-ylowDB)*nyDB);
820 if(binX>=nxDB || binY>=nyDB) {
826 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
827 Bool_t AliHMPIDReconHTA::UniformDistrib()
829 AliHMPIDParam *pParam=AliHMPIDParam::Instance();
832 Double_t sizeCh = 0.5*pParam->RadThick()+pParam->WinThick()+pParam->GapThick();
833 Double_t xrad = MipX() - sizeCh*TMath::Tan(fThTrkFit)*TMath::Cos(fPhTrkFit);
834 Double_t yrad = MipY() - sizeCh*TMath::Tan(fThTrkFit)*TMath::Sin(fPhTrkFit);
836 pRec.SetTrack(xrad,yrad,fThTrkFit,fPhTrkFit);
839 Int_t nPhotPerBin = 4;
840 for(Int_t i=0;i<fNClu;i++) {
841 if(!ClCk(i)) continue;
845 Int_t nPhiBins = npeff/nPhotPerBin+1;
846 if(nPhiBins<=1) nPhiBins = 2;
849 iPhiBin = new Double_t[nPhiBins];
851 for(Int_t i=0;i<nPhiBins;i++) iPhiBin[i] =0;
853 for(Int_t i=0;i<fNClu;i++) {
854 if(!ClCk(i)) continue;
855 Double_t phiCer = PhotPhi(i);
857 Double_t PhiProva = phiCer*TMath::RadToDeg();
858 if(PhiProva<0) PhiProva+= 360;
859 Int_t index = (Int_t)((Float_t)nPhiBins*PhiProva/360.);
864 for(Int_t i=0;i<nPhiBins;i++) {
865 Double_t theo = (Double_t)npeff/(Double_t)nPhiBins;
866 if(theo==0) continue;
867 chi2+= (iPhiBin[i] - theo)*(iPhiBin[i] - theo)/theo;
872 Double_t prob = TMath::Prob(chi2, nPhiBins-1);
873 AliDebug(1,Form(" Probability for uniform distrib: %6f.3 %s",prob,(prob<0.05) ? "rejected" : "accepted"));
874 if(prob<0.05) return kFALSE;
878 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++