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 //////////////////////////////////////////////////////////////////////////
20 // RICH class to perfom pattern recognition based on Hough transfrom //
21 // for single chamber //
22 //////////////////////////////////////////////////////////////////////////
24 #include "AliRICHRecon.h" //class header
26 #include <TRotation.h>
30 #include "AliRICHCluster.h" //ThetaCerenkov()
31 #include "AliRICHParam.h"
32 #include "AliRICHHelix.h" //ThetaCerenkov()
35 #define NPointsOfRing 201
37 //__________________________________________________________________________________________________
38 AliRICHRecon::AliRICHRecon():
39 TTask ("RichRec","RichPat"),
41 fParam(AliRICHParam::Instance()),
43 fPhotonIndex(0), // should we use -1?
44 fFittedHoughPhotons(0),
66 fLengthEmissionPoint(0),
69 fDistanceFromCluster(999),
70 fCerenkovAnglePad(999),
71 fThetaPhotonCerenkov(0),
78 fMassHypotesis(0.139567),
84 fCandidatePhotonX(0x0),
85 fCandidatePhotonY(0x0),
88 fFittedThetaCerenkov(0),
92 fIsBACKGROUND(kFALSE),
98 fWeightThetaCerenkov(0),
102 for (Int_t i=0; i<3000; i++) {
105 fPhotonEta[i] = -999;
106 fPhotonWeight[i] = 0.0;
109 fWeightPhotons[i] = 0;
112 //__________________________________________________________________________________________________
113 Double_t AliRICHRecon::ThetaCerenkov(AliRICHHelix *pHelix,TClonesArray *pClusters,Int_t &nphot)
115 // Pattern recognition method based on Hough transform
116 // Return theta Cerenkov for a given track and list of clusters which are set in ctor
117 // Remeber that list of clusters must contain more then 1 cluster. This considiration implies that normally we have 1 mip cluster and few photon clusters per track.
119 // Returns: Track theta ckov in rad, nphot is the number of photon candidates accepted for reconstruction track theta ckov
120 SetTrackTheta(pHelix->Ploc().Theta()); SetTrackPhi(pHelix->Ploc().Phi());
121 SetShiftX(pHelix->PosRad().X()); SetShiftY(pHelix->PosRad().Y());
122 fClusters = pClusters;
123 if(pClusters->GetEntries()>200) fIsWEIGHT = kTRUE; // offset to take into account bkg in reconstruction
124 else fIsWEIGHT = kFALSE;
128 SetThetaCerenkov(-1);
131 // Photon Flag: Flag = 0 initial set; Flag = 1 good candidate (charge compatible with photon); Flag = 2 photon used for the ring;
134 for (Int_t iClu=0; iClu<fClusters->GetEntriesFast();iClu++){//clusters loop
135 if(iClu == nphot) continue; // do not consider MIP cluster as a photon candidate
136 SetPhotonIndex(iClu);
140 AliRICHCluster *pClu=(AliRICHCluster*)fClusters->UncheckedAt(iClu); //get pointer to current cluster
141 if(pClu->Q()>AliRICHParam::QthMIP()) continue; //avoid MIP clusters from bkg
142 SetEntranceX(pClu->X() - GetShiftX()); SetEntranceY(pClu->Y() - GetShiftY()); //cluster position with respect to track intersection
145 FindThetaPhotonCerenkov();
146 Float_t thetaPhotonCerenkov = GetThetaPhotonCerenkov();
147 AliDebug(1,Form("Track Theta=%5.2f deg, Phi=%5.2f deg Photon clus=%2i ThetaCkov=%5.2f rad",GetTrackTheta()*TMath::RadToDeg(),GetTrackPhi()*TMath::RadToDeg()
148 ,iClu,thetaPhotonCerenkov ));
149 SetPhotonEta(thetaPhotonCerenkov);
152 SetPhotonsNumber(fClusters->GetEntries());
154 if((nphot=FlagPhotons(HoughResponse()))<1) return -11; //flag photons according to individual theta ckov with respect to most probable track theta ckov
157 // Float_t thetaCerenkov = GetThetaCerenkov();
158 // SetThetaOfRing(thetaCerenkov);
159 // FindAreaAndPortionOfRing();
161 // Float_t nPhotonHoughNorm = ((Float_t)nPhotonHough)/GetPortionOfRing();
162 // SetHoughPhotonsNorm(nPhotonHoughNorm);
164 // Calculate the area where the photon are accepted...
166 Float_t thetaInternal = thetaCerenkov - 0.5*fWindowWidth;
167 SetThetaOfRing(thetaInternal);
168 FindAreaAndPortionOfRing();
169 Float_t internalArea = GetAreaOfRing();
171 Float_t thetaExternal = thetaCerenkov + 0.5*fWindowWidth;
172 SetThetaOfRing(thetaExternal);
173 FindAreaAndPortionOfRing();
174 Float_t externalArea = GetAreaOfRing();
176 Float_t houghArea = externalArea - internalArea;
178 SetHoughArea(houghArea);
181 return GetThetaCerenkov();
183 //__________________________________________________________________________________________________
184 Int_t AliRICHRecon::PhotonInBand()
186 // Define valid band for photon candidates. For that photons with ThetaMin and ThetaMax are traced up to photcathode
192 Float_t xtoentr = GetEntranceX();
193 Float_t ytoentr = GetEntranceY();
198 Float_t phpad = GetPhiPoint();
202 SetEmissionPoint(AliRICHParam::RadThick() -0.0001);
204 nfreon = fParam->IdxC6F14(fParam->EckovMin());
207 AliDebug(1,Form("thetacer in photoninband min %f",thetacer));
209 FindThetaAtQuartz(thetacer);
211 if(thetacer == 999. || GetThetaAtQuartz() == 999.) {
213 SetXInnerRing(-999.);
214 SetYInnerRing(-999.);
215 SetRadiusInnerRing(-999.);
219 SetThetaPhotonInDRS(GetThetaAtQuartz());
220 SetPhiPhotonInDRS(phpad);
222 innerRadius = FromEmissionToCathode();
223 if(innerRadius == 999.) innerRadius = -999.;
225 SetXInnerRing(GetXPointOnCathode());
226 SetYInnerRing(GetYPointOnCathode());
227 SetRadiusInnerRing(innerRadius);
231 SetEmissionPoint(0.);
232 // SetMassHypotesis(0.139567);
234 nfreon = fParam->IdxC6F14(fParam->EckovMax());
236 thetacer = Cerenkovangle(nfreon,1);
240 AliDebug(1,Form("thetacer in photoninband max %f",thetacer));
242 FindThetaAtQuartz(thetacer);
244 if(thetacer == 999. || GetThetaAtQuartz() == 999.)
249 SetRadiusOuterRing(999.);
253 SetThetaPhotonInDRS(GetThetaAtQuartz());
254 SetPhiPhotonInDRS(phpad);
256 outerRadius = FromEmissionToCathode();
257 // cout << " outerRadius " << outerRadius << endl;
258 SetXOuterRing(GetXPointOnCathode());
259 SetYOuterRing(GetYPointOnCathode());
260 SetRadiusOuterRing(outerRadius);
263 Float_t padradius = sqrt(TMath::Power(xtoentr,2)+TMath::Power(ytoentr,2));
265 AliDebug(1,Form("rmin %f r %f rmax %f",innerRadius,padradius,outerRadius));
267 if(padradius>=innerRadius && padradius<=outerRadius) return 1;
270 //__________________________________________________________________________________________________
271 void AliRICHRecon::FindThetaAtQuartz(Float_t thetaCerenkov)
273 // find the theta at the quartz plate
275 if(thetaCerenkov == 999.) { SetThetaAtQuartz(999.); return; }
277 Float_t thetaAtQuartz = 999.;
279 Float_t trackTheta = GetTrackTheta();
281 if(trackTheta == 0) {
282 thetaAtQuartz = thetaCerenkov;
283 SetThetaAtQuartz(thetaAtQuartz);
287 Float_t trackPhi = GetTrackPhi();
288 Float_t phiPoint = GetPhiPoint();
290 Double_t den = TMath::Sin((Double_t)trackTheta)*TMath::Cos((Double_t)trackPhi)*TMath::Cos((Double_t)phiPoint) +
291 TMath::Sin((Double_t)trackTheta)*TMath::Sin((Double_t)trackPhi)*TMath::Sin((Double_t)phiPoint);
292 Double_t b = TMath::Cos((Double_t)trackTheta)/den;
293 Double_t c = -TMath::Cos((Double_t)thetaCerenkov)/den;
295 Double_t underSqrt = 1 + b*b - c*c;
298 SetThetaAtQuartz(999.);
302 Double_t sol1 = (1+TMath::Sqrt(underSqrt))/(b-c);
303 Double_t sol2 = (1-TMath::Sqrt(underSqrt))/(b-c);
305 Double_t thetaSol1 = 2*TMath::ATan(sol1);
306 Double_t thetaSol2 = 2*TMath::ATan(sol2);
308 if(thetaSol1>0 && thetaSol1 < TMath::Pi()) thetaAtQuartz = (Float_t)thetaSol1;
309 if(thetaSol2>0 && thetaSol2 < TMath::Pi()) thetaAtQuartz = (Float_t)thetaSol2;
311 // AliDebug(1,Form(" Theta @ quartz window %f ",thetaAtQuartz));
313 SetThetaAtQuartz(thetaAtQuartz);
315 //__________________________________________________________________________________________________
316 void AliRICHRecon::FindThetaPhotonCerenkov()
318 //find theta cerenkov of ring
320 Float_t thetaCerMin = 0.;
321 Float_t thetaCerMax = 0.75;
322 Float_t thetaCerMean;
324 Float_t radiusMin, radiusMax, radiusMean;
325 Int_t nIteration = 0;
327 const Float_t kTollerance = 0.05;
330 Float_t phiPoint = GetPhiPoint();
332 SetEmissionPoint(AliRICHParam::RadThick()/2);
334 Float_t xPoint = GetEntranceX();
335 Float_t yPoint = GetEntranceY();
336 Float_t distPoint = TMath::Sqrt(xPoint*xPoint + yPoint*yPoint);
338 // AliDebug(1,Form(" DistPoint %f ",distPoint));
340 // Star minimization...
344 FindThetaAtQuartz(thetaCerMin);
346 if(GetThetaAtQuartz() == 999.)
352 SetThetaPhotonInDRS(GetThetaAtQuartz());
353 SetPhiPhotonInDRS(phiPoint);
355 radiusMin = FromEmissionToCathode();
360 FindThetaAtQuartz(thetaCerMax);
361 if(GetThetaAtQuartz() == 999.)
367 SetThetaPhotonInDRS(GetThetaAtQuartz());
368 SetPhiPhotonInDRS(phiPoint);
370 radiusMax = FromEmissionToCathode();
374 thetaCerMean = (thetaCerMax + thetaCerMin)/2;
376 FindThetaAtQuartz(thetaCerMean);
377 if(GetThetaAtQuartz() == 999.)
383 SetThetaPhotonInDRS(GetThetaAtQuartz());
384 SetPhiPhotonInDRS(phiPoint);
386 radiusMean = FromEmissionToCathode();
389 // AliDebug(1,Form(" r1 %f rmean %f r2 %f",radiusMin,radiusMean,radiusMax));
391 while (TMath::Abs(radiusMean-distPoint) > kTollerance)
394 if((radiusMin-distPoint)*(radiusMean-distPoint) < 0) thetaCerMax = thetaCerMean;
395 if((radiusMin-distPoint)*(radiusMean-distPoint) > 0) {
397 thetaCerMin = thetaCerMean;
399 FindThetaAtQuartz(thetaCerMin);
400 SetThetaPhotonInDRS(GetThetaAtQuartz());
401 SetPhiPhotonInDRS(phiPoint);
403 radiusMin =FromEmissionToCathode();
406 thetaCerMean = (thetaCerMax + thetaCerMin)/2;
408 FindThetaAtQuartz(thetaCerMean);
409 SetThetaPhotonInDRS(GetThetaAtQuartz());
410 SetPhiPhotonInDRS(phiPoint);
412 radiusMean = FromEmissionToCathode();
416 // AliDebug(1,Form(" max iterations in FindPhotonCerenkov ",nIteration));
417 SetThetaPhotonCerenkov(999.);
422 // AliDebug(1,Form(" distpoint %f radius %f ",distPoint,radiusMean));
423 SetThetaPhotonCerenkov(thetaCerMean);
426 //__________________________________________________________________________________________________
427 void AliRICHRecon::FindAreaAndPortionOfRing()
429 //find fraction of the ring accepted by the RICH
431 Float_t xPoint[NPointsOfRing], yPoint[NPointsOfRing];
433 // Float_t xtoentr = GetEntranceX();
434 // Float_t ytoentr = GetEntranceY();
435 Float_t shiftX = GetShiftX();
436 Float_t shiftY = GetShiftY();
438 Float_t xemiss = GetXCoordOfEmission();
439 Float_t yemiss = GetYCoordOfEmission();
441 Float_t x0 = xemiss + shiftX;
442 Float_t y0 = yemiss + shiftY;
446 SetEmissionPoint(AliRICHParam::RadThick()/2.);
448 Float_t theta = GetThetaOfRing();
451 Int_t nPsiAccepted = 0;
454 for(Int_t i=0;i<NPointsOfRing-1;i++){
455 Float_t psi = 2*TMath::Pi()*i/NPointsOfRing;
457 SetThetaPhotonInTRS(theta);
458 SetPhiPhotonInTRS(psi);
459 FindPhotonAnglesInDRS();
461 Float_t radius = FromEmissionToCathode();
462 if (radius == 999.) continue;
466 Float_t xPointRing = GetXPointOnCathode() + shiftX;
467 Float_t yPointRing = GetYPointOnCathode() + shiftY;
469 SetDetectorWhereX(xPointRing);
470 SetDetectorWhereY(yPointRing);
472 Int_t zone = CheckDetectorAcceptance();
474 AliDebug(1,Form("acceptance to detector zone -> %d",zone));
477 FindIntersectionWithDetector();
478 xPoint[nPoints] = GetIntersectionX(); yPoint[nPoints] = GetIntersectionY();
480 xPoint[nPoints] = xPointRing; yPoint[nPoints] = yPointRing;
486 xPoint[nPoints] = xPoint[0]; yPoint[nPoints] = yPoint[0];
492 for (Int_t i = 0; i < nPoints; i++)
494 area += TMath::Abs((xPoint[i]-x0)*(yPoint[i+1]-y0) - (xPoint[i+1]-x0)*(yPoint[i]-y0));
499 Float_t portionOfRing = 0;
501 portionOfRing = ((Float_t)nPsiAccepted)/((Float_t)(nPsiTotal));
505 SetPortionOfRing(portionOfRing);
506 }//FindAreaAndPortionOfRing()
507 //__________________________________________________________________________________________________
508 void AliRICHRecon::FindIntersectionWithDetector()
510 // find ring intersection with CsI edges
512 Float_t xIntersect, yIntersect;
513 Float_t x1, x2, y1, y2;
515 Float_t shiftX = GetShiftX();
516 Float_t shiftY = GetShiftY();
518 Float_t xPoint = GetXPointOnCathode() + shiftX;
519 Float_t yPoint = GetYPointOnCathode() + shiftY;
521 Float_t xemiss = GetXCoordOfEmission();
522 Float_t yemiss = GetYCoordOfEmission();
524 Float_t phi = GetPhiPhotonInDRS();
525 Float_t m = tan(phi);
527 Float_t x0 = xemiss + shiftX;
528 Float_t y0 = yemiss + shiftY;
551 xIntersect = AliRICHParam::PcSizeX();
552 yIntersect = m*(xIntersect - x0) + y0;
553 if (yIntersect >= 0 && yIntersect <= AliRICHParam::PcSizeY() && xIntersect >= x1 && xIntersect <= x2)
555 SetIntersectionX(xIntersect);
556 SetIntersectionY(yIntersect);
561 yIntersect = m*(xIntersect - x0) + y0;
562 if (yIntersect >= 0 && yIntersect <= AliRICHParam::PcSizeY() && xIntersect >= x1 && xIntersect <= x2)
564 SetIntersectionX(xIntersect);
565 SetIntersectionY(yIntersect);
569 yIntersect = AliRICHParam::PcSizeY();
570 xIntersect = (yIntersect - y0)/m + x0;
571 if (xIntersect >= 0 && xIntersect <= AliRICHParam::PcSizeX() && yIntersect >= y1 && yIntersect <= y2)
573 SetIntersectionX(xIntersect);
574 SetIntersectionY(yIntersect);
579 xIntersect = (yIntersect - y0)/m + x0;
580 if (xIntersect >= 0 && xIntersect <= AliRICHParam::PcSizeX() && yIntersect >= y1 && yIntersect <= y2)
582 SetIntersectionX(xIntersect);
583 SetIntersectionY(yIntersect);
588 //__________________________________________________________________________________________________
589 Int_t AliRICHRecon::CheckDetectorAcceptance() const
591 // check for the acceptance
593 // crosses X -2.6 2.6 cm
596 Float_t xcoord = GetDetectorWhereX();
597 Float_t ycoord = GetDetectorWhereY();
599 if(xcoord > AliRICHParam::PcSizeX())
601 if(ycoord > AliRICHParam::PcSizeY()) return 2;
602 if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 3;
603 if(ycoord < 0) return 4;
607 if(ycoord > AliRICHParam::PcSizeY()) return 8;
608 if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 7;
609 if(ycoord < 0) return 6;
611 if(xcoord > 0 && xcoord < AliRICHParam::PcSizeX())
613 if(ycoord > AliRICHParam::PcSizeY()) return 1;
614 if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 0;
615 if(ycoord < 0) return 5;
619 //__________________________________________________________________________________________________
620 void AliRICHRecon::FindPhotonAnglesInDRS()
622 // Setup the rotation matrix of the track...
629 Float_t trackTheta = GetTrackTheta();
630 Float_t trackPhi = GetTrackPhi();
632 mtheta.RotateY(trackTheta);
633 mphi.RotateZ(trackPhi);
635 mrot = mphi * mtheta;
636 // minv = mrot.Inverse();
638 TVector3 photonInRadiator(1,1,1);
640 Float_t thetaCerenkov = GetThetaPhotonInTRS();
641 Float_t phiCerenkov = GetPhiPhotonInTRS();
643 photonInRadiator.SetTheta(thetaCerenkov);
644 photonInRadiator.SetPhi(phiCerenkov);
645 photonInRadiator = mrot * photonInRadiator;
646 Float_t theta = photonInRadiator.Theta();
647 Float_t phi = photonInRadiator.Phi();
648 SetThetaPhotonInDRS(theta);
649 SetPhiPhotonInDRS(phi);
652 //__________________________________________________________________________________________________
653 Float_t AliRICHRecon::FromEmissionToCathode()
655 // Trace current photon from emission point somewhere in radiator to photocathode
659 Float_t nfreon, nquartz, ngas;
663 nfreon = fParam->IdxC6F14(fParam->EckovMean());
664 nquartz = fParam->IdxSiO2(fParam->EckovMean());
665 ngas = fParam->IdxCH4(fParam->EckovMean());
667 Float_t trackTheta = GetTrackTheta();
668 Float_t trackPhi = GetTrackPhi();
669 Float_t lengthOfEmissionPoint = GetEmissionPoint();
671 Float_t theta = GetThetaPhotonInDRS();
672 Float_t phi = GetPhiPhotonInDRS();
674 Float_t xemiss = lengthOfEmissionPoint*tan(trackTheta)*cos(trackPhi);
675 Float_t yemiss = lengthOfEmissionPoint*tan(trackTheta)*sin(trackPhi);
677 SetXCoordOfEmission(xemiss);
678 SetYCoordOfEmission(yemiss);
680 Float_t thetaquar = SnellAngle(nfreon, nquartz, theta);
682 if(thetaquar == 999.)
684 SetXPointOnCathode(999.);
685 SetYPointOnCathode(999.);
689 Float_t thetagap = SnellAngle( nquartz, ngas, thetaquar);
693 SetXPointOnCathode(999.);
694 SetYPointOnCathode(999.);
698 Float_t xw = (AliRICHParam::RadThick() - lengthOfEmissionPoint)*cos(phi)*tan(theta);
699 Float_t xq = AliRICHParam::WinThick()*cos(phi)*tan(thetaquar);
700 Float_t xg = AliRICHParam::Pc2Win()*cos(phi)*tan(thetagap);
701 Float_t yw = (AliRICHParam::RadThick() - lengthOfEmissionPoint)*sin(phi)*tan(theta);
702 Float_t yq = AliRICHParam::WinThick()*sin(phi)*tan(thetaquar);
703 Float_t yg = AliRICHParam::Pc2Win()*sin(phi)*tan(thetagap);
706 Float_t xtot = xemiss + xw + xq + xg;
707 Float_t ytot = yemiss + yw + yq + yg;
709 SetXPointOnCathode(xtot);
710 SetYPointOnCathode(ytot);
713 Float_t distanceFromEntrance = TMath::Sqrt(TMath::Power(fPhotonLimitX,2)+TMath::Power(fPhotonLimitY,2));
715 return distanceFromEntrance;
718 //__________________________________________________________________________________________________
719 void AliRICHRecon::FindPhiPoint()
721 //find phi of generated point
723 Float_t xtoentr = GetEntranceX();
724 Float_t ytoentr = GetEntranceY();
726 Float_t trackTheta = GetTrackTheta();
727 Float_t trackPhi = GetTrackPhi();
729 Float_t emissionPoint = GetEmissionPoint();
731 Float_t argY = ytoentr - emissionPoint*tan(trackTheta)*sin(trackPhi);
732 Float_t argX = xtoentr - emissionPoint*tan(trackTheta)*cos(trackPhi);
733 Float_t phi = atan2(argY,argX);
738 //__________________________________________________________________________________________________
739 Float_t AliRICHRecon::Cerenkovangle(Float_t n, Float_t beta)
741 // cerenkov angle from n and beta
743 // Compute the cerenkov angle
749 // cout << " warning in Cerenkoangle !!!!!! " << endl;
753 thetacer = acos (1./(n*beta));
756 //__________________________________________________________________________________________________
757 Float_t AliRICHRecon::SnellAngle(Float_t n1, Float_t n2, Float_t theta1)
761 // Compute the Snell angle
763 Float_t sinrefractangle;
764 Float_t refractangle;
766 sinrefractangle = (n1/n2)*sin(theta1);
768 if(sinrefractangle>1.) {
769 // cout << " PROBLEMS IN SNELL ANGLE !!!!! " << endl;
774 refractangle = asin(sinrefractangle);
777 //__________________________________________________________________________________________________
778 Double_t AliRICHRecon::HoughResponse()
783 Int_t nChannels = (Int_t)(fThetaMax/fDTheta+0.5);
784 TH1F *phots = new TH1F("phots" ,"phots" ,nChannels,0,fThetaMax);
785 TH1F *photsw = new TH1F("photsw" ,"photsw" ,nChannels,0,fThetaMax);
786 TH1F *resultw = new TH1F("resultw","resultw",nChannels,0,fThetaMax);
787 Int_t nBin = (Int_t)(fThetaMax/fDTheta);
788 Int_t nCorrBand = (Int_t)(fWindowWidth/(2*fDTheta));
789 AliDebug(1,Form("Ring reconstruction for track with theta %f",GetTrackTheta()*TMath::RadToDeg()));
790 for (Int_t kPhot=0; kPhot< GetPhotonsNumber(); kPhot++){
791 SetPhotonIndex(kPhot);
792 Double_t angle = GetPhotonEta();
793 if(angle<0||angle>fThetaMax) continue;
795 Int_t bin = (Int_t)(0.5+angle/(fDTheta));
798 Double_t lowerlimit = ((Float_t)bin)*fDTheta - 0.5*fDTheta;
799 SetThetaOfRing(lowerlimit);
800 FindAreaAndPortionOfRing();
801 Float_t area1 = GetAreaOfRing();
802 Double_t upperlimit = ((Float_t)bin)*fDTheta + 0.5*fDTheta;
803 SetThetaOfRing(upperlimit);
804 FindAreaAndPortionOfRing();
805 Float_t area2 = GetAreaOfRing();
806 AliDebug(1,Form("lowerlimit %f area %f ; upperlimit %f area %f",lowerlimit,area1,upperlimit,area2));
807 Float_t diffarea = area2 - area1;
808 if(diffarea>0){weight = 1./(area2-area1);}else{weight = 1.;}
810 AliDebug(1,Form("Calculated weight %f",weight));
811 photsw->Fill(angle,weight);
812 SetPhotonWeight(weight);
814 for (Int_t i=1; i<=nBin;i++){
815 Int_t bin1= i-nCorrBand;
816 Int_t bin2= i+nCorrBand;
818 if(bin2>nBin)bin2=nBin;
819 Double_t sumPhots=phots->Integral(bin1,bin2);
820 if(sumPhots<fMinNumPhots) continue; // cut on minimum n. of photons per ring
821 Double_t sumPhotsw=photsw->Integral(bin1,bin2);
822 resultw->Fill((Float_t)((i+0.5)*fDTheta),sumPhotsw);
824 // evaluate the "BEST" theta ckov as the maximum value of histogramm
825 Float_t *pVec = resultw->GetArray();
826 Int_t locMax = TMath::LocMax(nBin,pVec);
827 phots->Delete();photsw->Delete();resultw->Delete(); // Reset and delete objects
829 return (Double_t)(locMax*fDTheta+0.5*fDTheta); //final most probable track theta ckov
831 //__________________________________________________________________________________________________
832 void AliRICHRecon::FindThetaCerenkov()
834 // Loops on all Ckov candidates and estimates the best Theta Ckov for a ring formed by those candidates. Also estimates an error for that Theat Ckov
835 // collecting errors for all single Ckov candidates thetas. (Assuming they are independent)
840 Float_t weightThetaCerenkov = 0.;
842 Double_t etaMin=9999.,etaMax=0.;
843 Double_t sigma2 = 0; //to collect error squared for this ring
845 for(Int_t i=0;i<GetPhotonsNumber();i++){
847 if(GetPhotonFlag() == 2){
848 Float_t photonEta = GetPhotonEta();
849 if(photonEta<etaMin) etaMin=photonEta;
850 if(photonEta>etaMax) etaMax=photonEta;
851 Float_t photonWeight = GetPhotonWeight();
852 weightThetaCerenkov += photonEta*photonWeight;
854 //here comes sigma of the reconstructed ring
856 //Double_t phiref=(GetPhiPoint()-GetTrackPhi());
857 if(GetPhotonEta()<=0) continue;//?????????????????Flag photos = 2 may imply CkovEta = 0??????????????
858 //??????????? Look at SetPhoton Flag method
859 Double_t phiref=GetTrackPhi();
861 Double_t beta = 1./(TMath::Cos(GetPhotonEta())*fParam->IdxC6F14(AliRICHParam::EckovMean()));
862 sigma2 += 1./AliRICHParam::SigmaSinglePhotonFormula(GetPhotonEta(),GetPhiPoint(),GetTrackTheta(),phiref,beta);
866 if(sigma2>0) SetRingSigma2(1./sigma2);
867 else SetRingSigma2(1e10);
869 if(wei != 0.) weightThetaCerenkov /= wei; else weightThetaCerenkov = 0.;
870 SetThetaCerenkov(weightThetaCerenkov);
872 // estimate of the n. of bkg photons
873 SetThetaOfRing(etaMin); FindAreaAndPortionOfRing(); Double_t internalArea = GetAreaOfRing();
874 SetThetaOfRing(etaMax); FindAreaAndPortionOfRing(); Double_t externalArea = GetAreaOfRing();
876 Double_t effArea = (AliRICHParam::PcSizeX()-AliRICHParam::DeadZone())*(AliRICHParam::PcSizeY()-2*AliRICHParam::DeadZone());
877 Double_t nPhotBKG = (externalArea-internalArea)/effArea*fClusters->GetEntries();
878 if(nPhotBKG<0) nPhotBKG=0; //just protection from funny angles...
879 SetPhotBKG(nPhotBKG);
881 AliDebug(1,Form(" thetac weighted -> %f",weightThetaCerenkov));
883 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
884 Int_t AliRICHRecon::FlagPhotons(Double_t thetaCkovHough)
886 // flag photon candidates if their individual theta ckov inside the window around theta ckov of Hough transform
887 // Arguments: thetaCkovHough- value of most probable theta ckov for track as returned by HoughResponse()
888 // Returns: number of photon candidates happened to be inside the window
890 Int_t steps = (Int_t)((thetaCkovHough - fThetaMin)/ fDTheta); //how many times we need to have fDTheta to fill the distance betwee fThetaMin and thetaCkovHough
892 Float_t tmin = fThetaMin + (Float_t)(steps - 1)*fDTheta;
893 Float_t tmax = fThetaMin + (Float_t)(steps)*fDTheta;
894 Float_t tavg = 0.5*(tmin+tmax);
896 tmin = tavg - 0.5*fWindowWidth; tmax = tavg + 0.5*fWindowWidth;
898 Int_t iInsideCnt = 0; //count photons which theta inside prdefined window
899 for(Int_t i=0;i<GetPhotonsNumber();i++){//photon candidates loop
900 SetPhotonIndex(i); Float_t photonEta = GetPhotonEta();
901 if(photonEta == -999.) continue;
902 if(photonEta >= tmin && photonEta <= tmax) {