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 //
22 //////////////////////////////////////////////////////////////////////////
26 #include "AliRICHRecon.h"
27 #include "AliRICHParam.h"
28 #include "AliRICHChamber.h"
29 #include <AliLoader.h>
32 #include <Riostream.h>
33 #include <TParticle.h>
40 #include <TRotation.h>
44 #define NPointsOfRing 201
46 TMinuit *gAliRICHminuit ;
48 void fcnrecon(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag);
49 //__________________________________________________________________________________________________
50 AliRICHRecon::AliRICHRecon(const char*name, const char*title)
54 fThetaBin=750; fThetaMin = 0.0; fThetaMax = 0.75;
55 fDTheta = 0.001; fWindowWidth = 0.060;
56 fNpadX = AliRICHParam::NpadsY();
57 fNpadY = AliRICHParam::NpadsX();
58 fPadSizeX = AliRICHParam::PadSizeY();
59 fPadSizeY = AliRICHParam::PadSizeX();
60 fRadiatorWidth = AliRICHParam::FreonThickness();
61 fQuartzWidth = AliRICHParam::QuartzThickness();
62 fGapWidth = AliRICHParam::RadiatorToPads();
63 fXmin = -AliRICHParam::PcSizeY()/2.;
64 fXmax = AliRICHParam::PcSizeY()/2.;
65 fYmin = -AliRICHParam::PcSizeX()/2.;
66 fYmax = AliRICHParam::PcSizeX()/2.;
67 fRich = (AliRICH*)gAlice->GetDetector("RICH");
68 fOutFile=new TFile("Anal.root","RECREATE","My Analysis histos");
69 if(fIsDISPLAY) fDisplay = new TCanvas("Display","RICH Display",0,0,1200,750);
70 fNtuple=new TNtuple("hn","ntuple",
71 "Run:Trig:VertZ:Pmod:Pt:Eta:TrackTheta:TrackPhi:TrackThetaFit:TrackPhiFit:Charge::NPhotons:NPhotonsFit:InRing:MassOfParticle:HoughArea:Multiplicity:TPCLastZ");
73 //__________________________________________________________________________________________________
74 void AliRICHRecon::StartProcessEvent()
76 //start to process for pattern recognition
78 Float_t trackThetaStored = 0;
79 Float_t trackPhiStored = 0;
80 Float_t thetaCerenkovStored = 0;
81 Int_t houghPhotonsStored = 0;
83 SetFreonScaleFactor(0.994);
91 Rich()->GetLoader()->LoadHits();
92 Rich()->GetLoader()->LoadRecPoints();
93 Rich()->GetLoader()->LoadDigits();
94 gAlice->GetRunLoader()->LoadHeader();
95 gAlice->GetRunLoader()->LoadKinematics();
97 Rich()->GetLoader()->TreeR()->GetEntry(0);
99 Float_t clusX[7][500],clusY[7][500];
100 Int_t clusQ[7][500],clusMul[7][500];
103 for (Int_t ich=0;ich<7;ich++) {
104 nClusters[ich] = Rich()->Clusters(ich+1)->GetEntries();
105 for(Int_t k=0;k<nClusters[ich];k++) {
106 AliRICHcluster *pCluster = (AliRICHcluster *)Rich()->Clusters(ich+1)->At(k);
107 clusX[ich][k] = pCluster->X();
108 clusY[ich][k] = pCluster->Y();
109 clusQ[ich][k] = pCluster->Q();
110 clusMul[ich][k] = pCluster->Size();
111 // pCluster->Print();
115 Int_t nPrimaries = (Int_t)Rich()->GetLoader()->TreeH()->GetEntries();
117 cout << " N. primaries " << nPrimaries << endl;
119 for(Int_t i=0;i<nPrimaries;i++){
121 Rich()->GetLoader()->TreeH()->GetEntry(i);
123 // Rich()->Hits()->Print();
128 for(Int_t j=0;j<Rich()->Hits()->GetEntries();j++) {
130 pHit = (AliRICHhit*)Rich()->Hits()->At(j);
131 if(pHit->GetTrack() < nPrimaries) break;
135 cout << " iPrim " << iPrim << " pHit " << pHit << endl;
141 TParticle *pParticle = gAlice->GetRunLoader()->Stack()->Particle(pHit->GetTrack());
142 Float_t pmod = pParticle->P();
143 Float_t pt = pParticle->Pt();
144 Float_t trackEta = pParticle->Eta();
145 Int_t q = (Int_t)TMath::Sign(1.,pParticle->GetPDG()->Charge());
147 // pParticle->Print();
149 cout << " pmod " << pmod << " pt " << pt << " Eta " << trackEta << " charge " << q << endl;
151 SetTrackMomentum(pmod);
153 SetTrackEta(trackEta);
156 TVector3 pLocal(0,0,0);//?????
158 TVector2 primLocal =Rich()->C(pHit->C())->Glob2Loc(pHit->InX3());
160 // Float_t pmodFreo = pLocal.Mag();
161 Float_t trackTheta = pLocal.Theta();
162 Float_t trackPhi = pLocal.Phi();
164 // cout << " trackTheta " << trackTheta << " trackPhi " << trackPhi << endl;
166 SetTrackTheta(trackTheta);
167 SetTrackPhi(trackPhi);
170 Float_t minDist = 999.;
172 // cout << " n Clusters " << nClusters[pHit->Chamber()-1] << " for chamber n. " << pHit->Chamber() << endl;
174 for(Int_t j=0;j<nClusters[pHit->Chamber()-1];j++)
176 Float_t diffx = primLocal.X() - clusX[pHit->Chamber()-1][j];
177 Float_t diffy = primLocal.Y() - clusY[pHit->Chamber()-1][j];
180 Float_t diff = sqrt(diffx*diffx + diffy*diffy);
190 Float_t diffx = primLocal.X() - clusX[pHit->Chamber()-1][maxInd];
191 Float_t diffy = primLocal.Y() - clusY[pHit->Chamber()-1][maxInd];
193 cout << " diffx " << diffx << " diffy " << diffy << endl;
199 Float_t shiftX = 0;//primLocal.X()/primLocal.Z()*(fRadiatorWidth+fQuartzWidth+fGapWidth) + primLocal.X(); ?????
200 Float_t shiftY = 0;//primLocal.Y()/primLocal.Z()*(fRadiatorWidth+fQuartzWidth+fGapWidth) + primLocal.Y(); ?????
205 Float_t *pclusX = &clusX[pHit->Chamber()-1][0];
206 Float_t *pclusY = &clusY[pHit->Chamber()-1][0];
208 SetCandidatePhotonX(pclusX);
209 SetCandidatePhotonY(pclusY);
210 SetCandidatePhotonsNumber(nClusters[pHit->Chamber()-1]);
212 Int_t qch = clusQ[pHit->Chamber()-1][maxInd];
215 if(minDist < 3.0 && qch > 120 && maxInd !=0)
221 Float_t xrndm = fXmin + (fXmax-fXmin)*gRandom->Rndm(280964);
222 Float_t yrndm = fYmin + (fYmax-fYmin)*gRandom->Rndm(280964);
230 trackThetaStored = GetTrackTheta();
231 trackPhiStored = GetTrackPhi();
232 thetaCerenkovStored = GetThetaCerenkov();
233 houghPhotonsStored = GetHoughPhotons();
235 Int_t diffNPhotons = 999;
237 Float_t diffTrackTheta = 999.;
238 Float_t diffTrackPhi = 999.;
240 while(fIsMINIMIZER && GetHoughPhotons() > 2
242 && diffTrackTheta > 0.0001
246 Int_t houghPhotonsBefore = GetHoughPhotons();
248 Float_t trackThetaBefore = GetTrackTheta();
249 Float_t trackPhiBefore = GetTrackPhi();
255 diffNPhotons = TMath::Abs(houghPhotonsBefore - GetHoughPhotons());
257 Float_t trackThetaAfter = GetTrackTheta();
258 Float_t trackPhiAfter = GetTrackPhi();
260 diffTrackTheta = TMath::Abs(trackThetaAfter - trackThetaBefore);
261 diffTrackPhi = TMath::Abs(trackPhiAfter - trackPhiBefore);
264 cout << " houghPhotonsBefore " << houghPhotonsBefore
265 << " GetHoughPhotons() " << GetHoughPhotons();
270 SetFittedThetaCerenkov(GetThetaCerenkov());
271 SetFittedHoughPhotons(GetHoughPhotons());
273 SetTrackTheta(trackThetaStored);
274 SetTrackPhi(trackPhiStored);
275 SetThetaCerenkov(thetaCerenkovStored);
276 SetHoughPhotons(houghPhotonsStored);
282 if(fIsDISPLAY) DrawEvent(1);
288 if(fIsDISPLAY) fDisplay->Print("display.ps");
289 }//StartProcessEvent()
290 //__________________________________________________________________________________________________
291 void AliRICHRecon::EndProcessEvent()
293 // function called at the end of the event loop
298 //__________________________________________________________________________________________________
299 void AliRICHRecon::PatRec()
301 //pattern recognition method based on Hough transform
304 Float_t trackTheta = GetTrackTheta();
305 Float_t trackPhi = GetTrackPhi();
306 Float_t pmod = GetTrackMomentum();
307 Int_t iMipIndex = GetMipIndex();
309 Bool_t kPatRec = kFALSE;
311 Int_t candidatePhotons = 0;
313 Float_t shiftX = GetShiftX();
314 Float_t shiftY = GetShiftY();
316 Float_t* candidatePhotonX = GetCandidatePhotonX();
317 Float_t* candidatePhotonY = GetCandidatePhotonY();
319 Int_t candidatePhotonsNumber = GetCandidatePhotonsNumber();
321 if(fDebug) cout << " n " << candidatePhotonsNumber << endl;
323 SetThetaCerenkov(999.);
325 SetHoughPhotonsNorm(0);
328 for (Int_t j=0; j < candidatePhotonsNumber; j++)
337 if (j == iMipIndex) continue;
340 if(candidatePhotonX[j] < -64.) continue; /* avoid artificial clusters from edge uesd by Yale.... */
342 Float_t xtoentr = candidatePhotonX[j] - shiftX;
343 Float_t ytoentr = candidatePhotonY[j] - shiftY;
345 // Float_t chargehit = fHits_charge[j];
346 // if(chargehit > 150) continue;
348 SetEntranceX(xtoentr);
349 SetEntranceY(ytoentr);
353 Int_t photonStatus = PhotonInBand();
357 cout << " Photon n. " << j << " Status " << photonStatus << " accepted " << endl;
358 cout << " CandidatePhotonX[j] " << candidatePhotonX[j] << " CandidatePhotonY[j] " << candidatePhotonY[j] << endl;
361 if(photonStatus == 0) continue;
365 FindThetaPhotonCerenkov();
367 Float_t thetaPhotonCerenkov = GetThetaPhotonCerenkov();
369 if(fDebug) cout << " theta photon " << thetaPhotonCerenkov << endl;
371 SetPhotonEta(thetaPhotonCerenkov);
378 if(candidatePhotons >= 1) kPatRec = kTRUE;
382 SetThetaCerenkov(999.);
385 SetPhotonsNumber(candidatePhotonsNumber);
392 Int_t nPhotonHough = GetHoughPhotons();
396 SetThetaCerenkov(999.);
397 SetHoughPhotonsNorm(0.);
401 if(fIsWEIGHT) FindWeightThetaCerenkov();
403 Float_t thetaCerenkov = GetThetaCerenkov();
405 SetThetaOfRing(thetaCerenkov);
406 FindAreaAndPortionOfRing();
408 Float_t nPhotonHoughNorm = ((Float_t)nPhotonHough)/GetPortionOfRing();
409 SetHoughPhotonsNorm(nPhotonHoughNorm);
411 // Calculate the area where the photon are accepted...
413 Float_t thetaInternal = thetaCerenkov - 0.5*fWindowWidth;
414 SetThetaOfRing(thetaInternal);
415 FindAreaAndPortionOfRing();
416 Float_t internalArea = GetAreaOfRing();
418 Float_t thetaExternal = thetaCerenkov + 0.5*fWindowWidth;
419 SetThetaOfRing(thetaExternal);
420 FindAreaAndPortionOfRing();
421 Float_t externalArea = GetAreaOfRing();
423 Float_t houghArea = externalArea - internalArea;
425 SetHoughArea(houghArea);
429 cout << " ----- SUMMARY OF RECONSTRUCTION ----- " << endl;
430 cout << " Rings found " << fNrings << " with thetac " << thetaCerenkov << endl;
433 cout << " Nphotons " << GetPhotonsNumber()
434 << " Hough " << nPhotonHough
435 << " norm " << nPhotonHoughNorm << endl;
437 cout << " In PatRec:p " << pmod << " theta " << trackTheta << " phi " << trackPhi << endl;
438 cout << " ------------------------------------- " << endl;
441 Int_t nPhotons = GetPhotonsNumber();
447 for (Int_t j=0; j < nPhotons;j++)
451 Float_t eta = GetPhotonEta();
455 if(GetPhotonFlag() == 2)
468 xmean /=(Float_t)nev;
469 x2mean /=(Float_t)nev;
475 Float_t vRMS = sqrt(x2mean - xmean*xmean);
479 if(fDebug) cout << " RMS " << vRMS << endl;
483 void AliRICHRecon::FindEmissionPoint()
485 //estimate the emission point in radiator
487 // Find emission point
489 Float_t absorbtionLenght=7.83*fRadiatorWidth; //absorption length in the freon (cm)
490 // 7.83 = -1/ln(T0) where
491 // T0->Trasmission freon at 180nm = 0.88 (Eph=6.85eV)
492 Float_t photonLenght, photonLenghtMin, photonLenghtMax;
494 photonLenght=exp(-fRadiatorWidth/(absorbtionLenght*cos(fCerenkovAnglePad)));
495 photonLenghtMin=fRadiatorWidth*photonLenght/(1.-photonLenght);
496 photonLenghtMax=absorbtionLenght*cos(fCerenkovAnglePad);
497 Float_t emissionPoint = fRadiatorWidth + photonLenghtMin - photonLenghtMax;
499 SetEmissionPoint(emissionPoint);
503 Int_t AliRICHRecon::PhotonInBand()
505 //search band fro photon candidates
507 // Float_t massOfParticle;
513 Float_t xtoentr = GetEntranceX();
514 Float_t ytoentr = GetEntranceY();
519 Float_t phpad = GetPhiPoint();
521 // Float_t pmod = GetTrackMomentum();
522 // Float_t trackTheta = GetTrackTheta();
523 // Float_t trackPhi = GetTrackPhi();
526 SetPhotonEnergy(5.6);
527 SetEmissionPoint(fRadiatorWidth -0.0001);
528 SetMassHypotesis(0.93828);
531 SetFreonRefractiveIndex();
533 beta = GetBetaOfParticle();
534 nfreon = GetFreonRefractiveIndex();
536 thetacer = Cerenkovangle(nfreon,beta);
540 if(fDebug) cout << " thetacer in photoninband min " << thetacer << endl;
542 FindThetaAtQuartz(thetacer);
544 if(thetacer == 999. || GetThetaAtQuartz() == 999.)
547 SetXInnerRing(-999.);
548 SetYInnerRing(-999.);
549 SetRadiusInnerRing(-999.);
553 SetThetaPhotonInDRS(GetThetaAtQuartz());
554 SetPhiPhotonInDRS(phpad);
556 innerRadius = FromEmissionToCathode();
557 if(innerRadius == 999.) innerRadius = -999.;
559 SetXInnerRing(GetXPointOnCathode());
560 SetYInnerRing(GetYPointOnCathode());
561 SetRadiusInnerRing(innerRadius);
565 SetPhotonEnergy(7.7);
566 SetEmissionPoint(0.);
567 // SetMassHypotesis(0.139567);
568 SetMassHypotesis(0.);
571 SetFreonRefractiveIndex();
573 beta = GetBetaOfParticle();
574 nfreon = GetFreonRefractiveIndex();
576 thetacer = Cerenkovangle(nfreon,beta);
580 if(fDebug) cout << " thetacer in photoninband max " << thetacer << endl;
582 FindThetaAtQuartz(thetacer);
584 if(thetacer == 999. || GetThetaAtQuartz() == 999.)
589 SetRadiusOuterRing(999.);
593 SetThetaPhotonInDRS(GetThetaAtQuartz());
594 SetPhiPhotonInDRS(phpad);
596 outerRadius = FromEmissionToCathode();
597 // cout << " outerRadius " << outerRadius << endl;
598 SetXOuterRing(GetXPointOnCathode());
599 SetYOuterRing(GetYPointOnCathode());
600 SetRadiusOuterRing(outerRadius);
603 Float_t padradius = sqrt(TMath::Power(xtoentr,2)+TMath::Power(ytoentr,2));
605 if(fDebug) printf(" rmin %f r %f rmax %f \n",innerRadius,padradius,outerRadius);
607 if(padradius>=innerRadius && padradius<=outerRadius) return 1;
611 void AliRICHRecon::FindThetaAtQuartz(Float_t thetaCerenkov)
613 //find the theta at the quartz plate
615 if(thetaCerenkov == 999.)
617 SetThetaAtQuartz(999.);
621 Float_t thetaAtQuartz = 999.;
623 Float_t trackTheta = GetTrackTheta();
625 if(trackTheta == 0) {
627 if(fDebug) cout << " Theta sol unique " << thetaCerenkov << endl;
629 thetaAtQuartz = thetaCerenkov;
630 SetThetaAtQuartz(thetaAtQuartz);
634 Float_t trackPhi = GetTrackPhi();
635 Float_t phiPoint = GetPhiPoint();
637 Double_t den = TMath::Sin((Double_t)trackTheta)
638 *TMath::Cos((Double_t)trackPhi)
639 *TMath::Cos((Double_t)phiPoint) +
640 TMath::Sin((Double_t)trackTheta)
641 *TMath::Sin((Double_t)trackPhi)
642 *TMath::Sin((Double_t)phiPoint);
643 Double_t b = TMath::Cos((Double_t)trackTheta)/den;
644 Double_t c = -TMath::Cos((Double_t)thetaCerenkov)/den;
646 Double_t underSqrt = 1 + b*b - c*c;
650 cout << " trackTheta " << trackTheta << endl;
651 cout << " TrackPhi " << trackPhi << endl;
652 cout << " PhiPoint " << phiPoint << endl;
653 cout << " ThetaCerenkov " << thetaCerenkov << endl;
654 cout << " den b c " << den << " b " << b << " c " << c << endl;
658 if(fDebug) cout << " sqrt negative !!!!" << underSqrt << endl;
659 SetThetaAtQuartz(999.);
663 Double_t sol1 = (1+TMath::Sqrt(underSqrt))/(b-c);
664 Double_t sol2 = (1-TMath::Sqrt(underSqrt))/(b-c);
666 Double_t thetaSol1 = 2*TMath::ATan(sol1);
667 Double_t thetaSol2 = 2*TMath::ATan(sol2);
669 if(fDebug) cout << " Theta sol 1 " << thetaSol1
670 << " Theta sol 2 " << thetaSol2 << endl;
672 if(thetaSol1>0 && thetaSol1 < TMath::Pi()) thetaAtQuartz = (Float_t)thetaSol1;
673 if(thetaSol2>0 && thetaSol2 < TMath::Pi()) thetaAtQuartz = (Float_t)thetaSol2;
675 SetThetaAtQuartz(thetaAtQuartz);
678 void AliRICHRecon::FindThetaPhotonCerenkov()
680 //find theta cerenkov of ring
682 Float_t thetaCerMin = 0.;
683 Float_t thetaCerMax = 0.75;
684 Float_t thetaCerMean;
686 Float_t radiusMin, radiusMax, radiusMean;
687 Int_t nIteration = 0;
689 const Float_t kTollerance = 0.05;
691 // Float_t pmod = GetTrackMomentum();
692 // Float_t trackTheta = GetTrackTheta();
693 // Float_t trackPhi = GetTrackPhi();
695 Float_t phiPoint = GetPhiPoint();
697 SetPhotonEnergy(6.85);
698 SetEmissionPoint(fRadiatorWidth/2);
700 Float_t xPoint = GetEntranceX();
701 Float_t yPoint = GetEntranceY();
702 Float_t distPoint = sqrt(xPoint*xPoint + yPoint*yPoint);
704 if(fDebug) cout << " DistPoint " << distPoint << endl;
706 // Star minimization...
710 FindThetaAtQuartz(thetaCerMin);
712 if(GetThetaAtQuartz() == 999.)
718 SetThetaPhotonInDRS(GetThetaAtQuartz());
719 SetPhiPhotonInDRS(phiPoint);
721 radiusMin = FromEmissionToCathode();
726 FindThetaAtQuartz(thetaCerMax);
727 if(GetThetaAtQuartz() == 999.)
733 SetThetaPhotonInDRS(GetThetaAtQuartz());
734 SetPhiPhotonInDRS(phiPoint);
736 radiusMax = FromEmissionToCathode();
740 thetaCerMean = (thetaCerMax + thetaCerMin)/2;
742 FindThetaAtQuartz(thetaCerMean);
743 if(GetThetaAtQuartz() == 999.)
749 SetThetaPhotonInDRS(GetThetaAtQuartz());
750 SetPhiPhotonInDRS(phiPoint);
752 radiusMean = FromEmissionToCathode();
755 if(fDebug) cout << " r1 " << radiusMin << " rmean "
756 << radiusMean << " r2 " << radiusMax << endl;
758 while (TMath::Abs(radiusMean-distPoint) > kTollerance)
761 if((radiusMin-distPoint)*(radiusMean-distPoint) < 0) thetaCerMax = thetaCerMean;
762 if((radiusMin-distPoint)*(radiusMean-distPoint) > 0) {
764 thetaCerMin = thetaCerMean;
766 FindThetaAtQuartz(thetaCerMin);
767 SetThetaPhotonInDRS(GetThetaAtQuartz());
768 SetPhiPhotonInDRS(phiPoint);
770 radiusMin =FromEmissionToCathode();
773 thetaCerMean = (thetaCerMax + thetaCerMin)/2;
775 FindThetaAtQuartz(thetaCerMean);
776 SetThetaPhotonInDRS(GetThetaAtQuartz());
777 SetPhiPhotonInDRS(phiPoint);
779 radiusMean = FromEmissionToCathode();
783 if(fDebug) printf(" max iterations in FindPhotonCerenkov\n");
784 SetThetaPhotonCerenkov(999.);
789 SetThetaPhotonCerenkov(thetaCerMean);
793 void AliRICHRecon::FindAreaAndPortionOfRing()
795 //find fraction of the ring accepted by the RICH
797 Float_t xPoint[NPointsOfRing], yPoint[NPointsOfRing];
799 // Float_t xtoentr = GetEntranceX();
800 // Float_t ytoentr = GetEntranceY();
801 Float_t shiftX = GetShiftX();
802 Float_t shiftY = GetShiftY();
804 Float_t xemiss = GetXCoordOfEmission();
805 Float_t yemiss = GetYCoordOfEmission();
807 Float_t x0 = xemiss + shiftX;
808 Float_t y0 = yemiss + shiftY;
810 // Float_t pmod = GetTrackMomentum();
811 // Float_t trackTheta = GetTrackTheta();
812 // Float_t trackPhi = GetTrackPhi();
814 SetPhotonEnergy(6.85);
815 SetFreonRefractiveIndex();
817 SetEmissionPoint(fRadiatorWidth/2.);
819 Float_t theta = GetThetaOfRing();
822 Int_t nPsiAccepted = 0;
825 for(Int_t i=0;i<NPointsOfRing-1;i++)
828 Float_t psi = 2*TMath::Pi()*i/NPointsOfRing;
830 SetThetaPhotonInTRS(theta);
831 SetPhiPhotonInTRS(psi);
832 FindPhotonAnglesInDRS();
834 Float_t radius = FromEmissionToCathode();
835 if (radius == 999.) continue;
839 Float_t xPointRing = GetXPointOnCathode() + shiftX;
840 Float_t yPointRing = GetYPointOnCathode() + shiftY;
842 SetDetectorWhereX(xPointRing);
843 SetDetectorWhereY(yPointRing);
845 Int_t zone = CheckDetectorAcceptance();
850 FindIntersectionWithDetector();
851 xPoint[nPoints] = GetIntersectionX();
852 yPoint[nPoints] = GetIntersectionY();
856 xPoint[nPoints] = xPointRing;
857 yPoint[nPoints] = yPointRing;
865 xPoint[nPoints] = xPoint[0];
866 yPoint[nPoints] = yPoint[0];
872 for (Int_t i = 0; i < nPoints; i++)
874 area += TMath::Abs((xPoint[i]-x0)*(yPoint[i+1]-y0) - (xPoint[i+1]-x0)*(yPoint[i]-y0));
879 Float_t portionOfRing = ((Float_t)nPsiAccepted)/((Float_t)(nPsiTotal));
883 SetPortionOfRing(portionOfRing);
886 void AliRICHRecon::FindIntersectionWithDetector()
888 // find ring intersection with CsI edges
890 Float_t xIntersect, yIntersect;
891 Float_t x1, x2, y1, y2;
893 Float_t shiftX = GetShiftX();
894 Float_t shiftY = GetShiftY();
896 Float_t xPoint = GetXPointOnCathode() + shiftX;
897 Float_t yPoint = GetYPointOnCathode() + shiftY;
899 Float_t xemiss = GetXCoordOfEmission();
900 Float_t yemiss = GetYCoordOfEmission();
902 Float_t phi = GetPhiPhotonInDRS();
903 Float_t m = tan(phi);
905 Float_t x0 = xemiss + shiftX;
906 Float_t y0 = yemiss + shiftY;
930 yIntersect = m*(xIntersect - x0) + y0;
931 if (yIntersect >= fYmin && yIntersect <= fYmax && xIntersect >= x1 && xIntersect <= x2)
933 SetIntersectionX(xIntersect);
934 SetIntersectionY(yIntersect);
939 yIntersect = m*(xIntersect - x0) + y0;
940 if (yIntersect >= fYmin && yIntersect <= fYmax && xIntersect >= x1 && xIntersect <= x2)
942 SetIntersectionX(xIntersect);
943 SetIntersectionY(yIntersect);
948 xIntersect = (yIntersect - y0)/m + x0;
949 if (xIntersect >= fXmin && xIntersect <= fXmax && yIntersect >= y1 && yIntersect <= y2)
951 SetIntersectionX(xIntersect);
952 SetIntersectionY(yIntersect);
957 xIntersect = (yIntersect - y0)/m + x0;
958 if (xIntersect >= fXmin && xIntersect <= fXmax && yIntersect >= y1 && yIntersect <= y2)
960 SetIntersectionX(xIntersect);
961 SetIntersectionY(yIntersect);
965 cout << " sono fuori!!!!!!" << endl;
968 //__________________________________________________________________________________________________
969 Int_t AliRICHRecon::CheckDetectorAcceptance() const
971 // check for the acceptance
973 // crosses X -2.6 2.6 cm
976 Float_t xcoord = GetDetectorWhereX();
977 Float_t ycoord = GetDetectorWhereY();
981 if(ycoord > fYmax) return 2;
982 if(ycoord > fYmin && ycoord < fYmax) return 3;
983 if(ycoord < fYmin) return 4;
987 if(ycoord > fYmax) return 8;
988 if(ycoord > fYmin && ycoord < fYmax) return 7;
989 if(ycoord < fYmin) return 6;
991 if(xcoord > fXmin && xcoord < fXmax)
993 if(ycoord > fYmax) return 1;
994 if(ycoord > fYmin && ycoord < fYmax) return 0;
995 if(ycoord < fYmin) return 5;
999 //__________________________________________________________________________________________________
1000 Float_t AliRICHRecon::PhotonPositionOnCathode()
1002 // find the photon position on the CsI
1003 // Float_t massOfParticle;
1008 SetPhotonEnergy(6.85);
1009 SetEmissionPoint(fRadiatorWidth/2.);
1010 SetMassHypotesis(0.139567);
1012 SetBetaOfParticle();
1013 SetFreonRefractiveIndex();
1015 beta = GetBetaOfParticle();
1016 nfreon = GetFreonRefractiveIndex();
1019 Float_t radius = FromEmissionToCathode();
1020 if (radius == 999.) return 999.;
1025 void AliRICHRecon::FindPhotonAnglesInDRS()
1027 // Setup the rotation matrix of the track...
1034 Float_t trackTheta = GetTrackTheta();
1035 Float_t trackPhi = GetTrackPhi();
1037 mtheta.RotateY(trackTheta);
1038 mphi.RotateZ(trackPhi);
1040 mrot = mphi * mtheta;
1041 // minv = mrot.Inverse();
1043 TVector3 photonInRadiator(1,1,1);
1045 Float_t thetaCerenkov = GetThetaPhotonInTRS();
1046 Float_t phiCerenkov = GetPhiPhotonInTRS();
1048 photonInRadiator.SetTheta(thetaCerenkov);
1049 photonInRadiator.SetPhi(phiCerenkov);
1050 photonInRadiator = mrot * photonInRadiator;
1051 Float_t theta = photonInRadiator.Theta();
1052 Float_t phi = photonInRadiator.Phi();
1053 SetThetaPhotonInDRS(theta);
1054 SetPhiPhotonInDRS(phi);
1058 Float_t AliRICHRecon::FromEmissionToCathode()
1060 // trace from emission point to cathode
1062 Float_t nfreon, nquartz, ngas;
1064 SetFreonRefractiveIndex();
1065 SetQuartzRefractiveIndex();
1066 SetGasRefractiveIndex();
1068 nfreon = GetFreonRefractiveIndex();
1069 nquartz = GetQuartzRefractiveIndex();
1070 ngas = GetGasRefractiveIndex();
1072 Float_t trackTheta = GetTrackTheta();
1073 Float_t trackPhi = GetTrackPhi();
1074 Float_t lengthOfEmissionPoint = GetEmissionPoint();
1076 Float_t theta = GetThetaPhotonInDRS();
1077 Float_t phi = GetPhiPhotonInDRS();
1079 // cout << " Theta " << Theta << " Phi " << Phi << endl;
1081 Float_t xemiss = lengthOfEmissionPoint*tan(trackTheta)*cos(trackPhi);
1082 Float_t yemiss = lengthOfEmissionPoint*tan(trackTheta)*sin(trackPhi);
1084 SetXCoordOfEmission(xemiss);
1085 SetYCoordOfEmission(yemiss);
1087 Float_t thetaquar = SnellAngle(nfreon, nquartz, theta);
1089 if(thetaquar == 999.)
1091 SetXPointOnCathode(999.);
1092 SetYPointOnCathode(999.);
1096 Float_t thetagap = SnellAngle( nquartz, ngas, thetaquar);
1098 if(thetagap == 999.)
1100 SetXPointOnCathode(999.);
1101 SetYPointOnCathode(999.);
1105 Float_t xw = (fRadiatorWidth - lengthOfEmissionPoint)*cos(phi)*tan(theta);
1106 Float_t xq = fQuartzWidth*cos(phi)*tan(thetaquar);
1107 Float_t xg = fGapWidth*cos(phi)*tan(thetagap);
1108 Float_t yw = (fRadiatorWidth - lengthOfEmissionPoint)*sin(phi)*tan(theta);
1109 Float_t yq = fQuartzWidth*sin(phi)*tan(thetaquar);
1110 Float_t yg = fGapWidth*sin(phi)*tan(thetagap);
1113 Float_t xtot = xemiss + xw + xq + xg;
1114 Float_t ytot = yemiss + yw + yq + yg;
1116 SetXPointOnCathode(xtot);
1117 SetYPointOnCathode(ytot);
1120 Float_t distanceFromEntrance = sqrt(TMath::Power(fPhotonLimitX,2)
1121 +TMath::Power(fPhotonLimitY,2));
1123 return distanceFromEntrance;
1128 void AliRICHRecon::FindPhiPoint()
1130 //find phi of generated point
1132 Float_t xtoentr = GetEntranceX();
1133 Float_t ytoentr = GetEntranceY();
1135 Float_t trackTheta = GetTrackTheta();
1136 Float_t trackPhi = GetTrackPhi();
1138 Float_t emissionPoint = GetEmissionPoint();
1140 Float_t argY = ytoentr - emissionPoint*tan(trackTheta)*sin(trackPhi);
1141 Float_t argX = xtoentr - emissionPoint*tan(trackTheta)*cos(trackPhi);
1142 Float_t phipad = atan2(argY,argX);
1144 SetPhiPoint(phipad);
1148 Float_t AliRICHRecon::Cerenkovangle(Float_t n, Float_t beta)
1150 // cerenkov angle from n and beta
1152 // Compute the cerenkov angle
1158 // cout << " warning in Cerenkoangle !!!!!! " << endl;
1162 thetacer = acos (1./(n*beta));
1166 Float_t AliRICHRecon::SnellAngle(Float_t n1, Float_t n2, Float_t theta1)
1170 // Compute the Snell angle
1172 Float_t sinrefractangle;
1173 Float_t refractangle;
1175 sinrefractangle = (n1/n2)*sin(theta1);
1177 if(sinrefractangle>1.) {
1178 // cout << " PROBLEMS IN SNELL ANGLE !!!!! " << endl;
1179 refractangle = 999.;
1180 return refractangle;
1183 refractangle = asin(sinrefractangle);
1184 return refractangle;
1188 void AliRICHRecon::HoughResponse()
1192 // Implement Hough response pat. rec. method
1199 int i, j, k, nCorrBand;
1200 float hcs[750],hcsw[750];
1201 float angle, weight;
1202 float lowerlimit,upperlimit;
1208 float etaPeakPos = -1;
1210 Int_t etaPeakCount = -1;
1212 Float_t thetaCerenkov = 0.;
1214 nBin = (int)(0.5+fThetaMax/(fDTheta));
1215 nCorrBand = (int)(0.5+ fWindowWidth/(2 * fDTheta));
1217 memset ((void *)hcs, 0, fThetaBin*sizeof(float));
1218 memset ((void *)hcsw, 0, fThetaBin*sizeof(float));
1220 Int_t nPhotons = GetPhotonsNumber();
1222 Int_t weightFlag = 0;
1224 for (k=0; k< nPhotons; k++) {
1228 angle = GetPhotonEta();
1230 if(angle == -999.) continue;
1232 if (angle>=fThetaMin && angle<= fThetaMax)
1236 bin = (int)(0.5+angle/(fDTheta));
1238 bin1= bin-nCorrBand;
1239 bin2= bin+nCorrBand;
1241 // calculate weights
1245 lowerlimit = ((Float_t)bin1)*fDTheta + 0.5*fDTheta;
1246 SetThetaOfRing(lowerlimit);
1247 FindAreaAndPortionOfRing();
1248 Float_t area1 = GetAreaOfRing();
1250 upperlimit = ((Float_t)bin2)*fDTheta + 0.5*fDTheta;
1251 SetThetaOfRing(upperlimit);
1252 FindAreaAndPortionOfRing();
1253 Float_t area2 = GetAreaOfRing();
1255 // cout << "lowerlimit" << lowerlimit << "upperlimit " << upperlimit << endl;
1256 Float_t diffarea = area2 - area1;
1260 weight = 1./(area2-area1);
1268 // cout <<" low "<< lowerlimit << " up " << upperlimit <<
1269 // " area1 " << area1 << " area2 " << area2 << " weight " << weight << endl;
1277 SetPhotonWeight(weight);
1279 // cout << "weight..." << weight << endl;
1283 if (bin2>nBin) bin2=nBin;
1285 for (j=bin1; j<bin2; j++)
1301 // cout << " probems with weight...normal procedure adopted " << endl;
1304 HoughFiltering(hCSspace);
1306 for (bin=0; bin <nBin; bin++) {
1307 angle = (bin+0.5) * (fDTheta);
1308 if (hCSspace[bin] && hCSspace[bin] > etaPeakPos) {
1310 etaPeakPos = hCSspace[bin];
1314 if (hCSspace[bin] == etaPeakPos) {
1315 etaPeak[++etaPeakCount] = angle;
1320 for (i=0; i<etaPeakCount+1; i++) {
1321 thetaCerenkov += etaPeak[i];
1323 if (etaPeakCount>=0) {
1324 thetaCerenkov /= etaPeakCount+1;
1325 fThetaPeakPos = etaPeakPos;
1328 SetThetaCerenkov(thetaCerenkov);
1332 void AliRICHRecon::HoughFiltering(float hcs[])
1339 float k[5] = {0.05, 0.25, 0.4, 0.25, 0.05};
1344 nBin = (int)(1+fThetaMax/fDTheta);
1345 sizeHCS = fThetaBin*sizeof(float);
1347 memset ((void *)hcsFilt, 0, sizeHCS);
1349 for (nx = 0; nx < nBin; nx++) {
1350 for (i = 0; i < 5; i++) {
1352 if (nxDx> -1 && nxDx<nBin)
1353 hcsFilt[nx] += hcs[nxDx] * k[i];
1357 for (nx = 0; nx < nBin; nx++) {
1358 hcs[nx] = hcsFilt[nx];
1362 void AliRICHRecon::FindWeightThetaCerenkov()
1364 // manage with weight for photons
1367 Float_t weightThetaCerenkov = 0.;
1369 Int_t nPhotons = GetPhotonsNumber();
1370 for(Int_t i=0;i<nPhotons;i++)
1374 if(GetPhotonFlag() == 2)
1376 Float_t photonEta = GetPhotonEta();
1377 Float_t photonWeight = GetPhotonWeight();
1378 weightThetaCerenkov += photonEta*photonWeight;
1379 wei += photonWeight;
1385 weightThetaCerenkov /= wei;
1389 weightThetaCerenkov = 0.;
1392 SetThetaCerenkov(weightThetaCerenkov);
1394 cout << " thetac weighted -> " << weightThetaCerenkov << endl;
1398 void AliRICHRecon::FlagPhotons()
1402 Int_t nPhotonHough = 0;
1404 Float_t thetaCerenkov = GetThetaCerenkov();
1405 if(fDebug) cout << " fThetaCerenkov " << thetaCerenkov << endl;
1407 Float_t thetaDist= thetaCerenkov - fThetaMin;
1408 Int_t steps = (Int_t)(thetaDist / fDTheta);
1410 Float_t tmin = fThetaMin + (Float_t)(steps - 1)*fDTheta;
1411 Float_t tmax = fThetaMin + (Float_t)(steps)*fDTheta;
1412 Float_t tavg = 0.5*(tmin+tmax);
1414 tmin = tavg - 0.5*fWindowWidth;
1415 tmax = tavg + 0.5*fWindowWidth;
1417 if(fDebug) cout << " tmin " << tmin << " tmax " << tmax << endl;
1418 if(fDebug) cout << " thetac " << thetaCerenkov << endl;
1420 // Int_t candidatePhotonsNumber = GetCandidatePhotonsNumber();
1422 Int_t nPhotons = GetPhotonsNumber();
1424 // for(Int_t i=0;i<candidatePhotonsNumber;i++)
1426 for(Int_t i=0;i<nPhotons;i++)
1430 Float_t photonEta = GetPhotonEta();
1432 if(photonEta == -999.) continue;
1434 if(photonEta >= tmin && photonEta <= tmax)
1440 SetHoughPhotons(nPhotonHough);
1443 void AliRICHRecon::DrawEvent(Int_t flag) const
1445 // draw event with rings
1447 flag=1; // dummy to be removed...
1450 Float_t AliRICHRecon::FindMassOfParticle()
1452 // find mass of the particle from theta cerenkov
1454 Float_t pmod = GetTrackMomentum();
1456 SetPhotonEnergy(6.85);
1457 SetFreonRefractiveIndex();
1459 Float_t thetaCerenkov = GetThetaCerenkov();
1460 FindBetaFromTheta(thetaCerenkov);
1462 Double_t beta = (Double_t)(GetBetaOfParticle());
1463 Double_t den = 1. - beta*beta;
1464 if(den<=0.) return 999.;
1466 Double_t gamma = 1./TMath::Sqrt(den);
1468 Float_t mass = pmod/(beta*(Float_t)gamma);
1474 void AliRICHRecon::FillHistograms()
1476 // fill histograms..
1478 Float_t fittedTrackTheta, fittedTrackPhi;
1480 Float_t thetaCerenkov = GetThetaCerenkov();
1481 if(thetaCerenkov == 999.) return;
1483 Float_t vertZ = GetEventVertexZ();
1485 Float_t trackTheta = GetTrackTheta();
1486 Float_t trackPhi = GetTrackPhi();
1487 Float_t pmod = GetTrackMomentum();
1488 Float_t pt = GetTrackPt();
1489 Float_t trackEta = GetTrackEta();
1490 Int_t q = GetTrackCharge();
1491 Float_t tPCLastZ = GetTrackTPCLastZ();
1492 Float_t minDist = GetMinDist();
1494 fittedTrackTheta = GetFittedTrackTheta();
1495 fittedTrackPhi = GetFittedTrackPhi();
1496 Int_t fittednPhotonHough = GetFittedHoughPhotons();
1500 cout << " p " << pmod << " ThetaC " << thetaCerenkov
1501 << " rings " << fNrings << endl;
1504 Int_t nPhotonHough = GetHoughPhotons();
1505 // Float_t nPhotonHoughNorm = GetHoughPhotonsNorm();
1506 Float_t inRing = GetPortionOfRing();
1508 Float_t massOfParticle = FindMassOfParticle();
1510 Float_t houghArea = GetHoughArea();
1511 Float_t multiplicity = GetEventMultiplicity();
1522 var[6] = trackTheta;
1524 var[8] = fittedTrackTheta;
1525 var[9] = fittedTrackPhi;
1527 var[11] = thetaCerenkov;
1528 var[12] = (Float_t)nPhotonHough;
1529 var[13] = (Float_t)fittednPhotonHough;
1531 var[15] = massOfParticle;
1532 var[16] = houghArea;
1533 var[17] = multiplicity;
1540 fittedTrackTheta = GetFittedTrackTheta();
1541 fittedTrackPhi = GetFittedTrackPhi();
1545 if(thetaCerenkov > 0.505 && thetaCerenkov < 0.605) {
1546 SetPhotonEnergy(6.85);
1547 SetFreonRefractiveIndex();
1550 Int_t nPhotons = GetPhotonsNumber();
1552 for (Int_t j=0; j < nPhotons;j++)
1555 //__________________________________________________________________________________________________
1556 void AliRICHRecon::Minimization()
1558 // minimization to find the best theta and phi of the track
1563 static Double_t vstart[2];
1564 static Double_t lower[2], upper[2];
1565 static Double_t step[2]={0.001,0.001};
1567 Double_t trackThetaNew,trackPhiNew;
1569 Double_t eps, b1, b2;
1572 gAliRICHminuit = new TMinuit(2);
1573 gAliRICHminuit->SetObjectFit((TObject *)this);
1574 gAliRICHminuit->SetFCN(fcnrecon);
1575 gAliRICHminuit->mninit(5,10,7);
1577 vstart[0] = (Double_t)GetTrackTheta();
1578 vstart[1] = (Double_t)GetTrackPhi();
1580 lower[0] = vstart[0] - 0.03;
1581 if(lower[0] < 0) lower[0] = 0.;
1582 upper[0] = vstart[0] + 0.03;
1583 lower[1] = vstart[1] - 0.03;
1584 upper[1] = vstart[1] + 0.03;
1587 gAliRICHminuit->mnparm(0,"theta",vstart[0],step[0],lower[0],upper[0],ierflag);
1588 gAliRICHminuit->mnparm(1," phi ",vstart[1],step[1],lower[1],upper[1],ierflag);
1592 // gAliRICHminuit->FixParameter(0);
1594 gAliRICHminuit->SetPrintLevel(-1);
1595 // gAliRICHminuit->mnexcm("SET PRI",&arglist, 1, ierflag);
1596 gAliRICHminuit->mnexcm("SET NOGR",&arglist, 1, ierflag);
1597 gAliRICHminuit->mnexcm("SET NOW",&arglist, 1, ierflag);
1599 gAliRICHminuit->mnexcm("SET ERR", &arglist, 1,ierflg);
1602 // gAliRICHminuit->mnscan();
1604 // gAliRICHminuit->mnexcm("SIMPLEX",&arglist, 0, ierflag);
1605 gAliRICHminuit->mnexcm("MIGRAD",&arglist, 0, ierflag);
1606 gAliRICHminuit->mnexcm("EXIT" ,&arglist, 0, ierflag);
1608 gAliRICHminuit->mnpout(0,chname, trackThetaNew, eps , b1, b2, ierflg);
1609 gAliRICHminuit->mnpout(1,chname, trackPhiNew, eps , b1, b2, ierflg);
1611 //values after the fit...
1612 SetFittedTrackTheta((Float_t)trackThetaNew);
1613 SetFittedTrackPhi((Float_t)trackPhiNew);
1615 delete gAliRICHminuit;
1619 void AliRICHRecon::EstimationOfTheta()
1625 Float_t shiftX = GetShiftX();
1626 Float_t shiftY = GetShiftY();
1628 Float_t *candidatePhotonX = GetCandidatePhotonX();
1629 Float_t *candidatePhotonY = GetCandidatePhotonY();
1631 Int_t nPhotonsCandidates = GetCandidatePhotonsNumber();
1633 // cout << "MINIM: Nphotons " << nPhotonsCandidates << endl;
1635 for (Int_t j=0; j < nPhotonsCandidates; j++)
1640 if(!GetPhotonFlag()) continue;
1642 Float_t xtoentr = candidatePhotonX[j] - shiftX;
1643 Float_t ytoentr = candidatePhotonY[j] - shiftY;
1645 SetEntranceX(xtoentr);
1646 SetEntranceY(ytoentr);
1650 FindThetaPhotonCerenkov();
1652 Float_t thetaPhotonCerenkov = GetThetaPhotonCerenkov();
1654 // cout << " ACCEPTED!!! " << thetaPhotonCerenkov << endl;
1656 SetPhotonEta(thetaPhotonCerenkov);
1663 Float_t x2mean = 0.;
1666 for (Int_t j=0; j < nPhotonsCandidates;j++)
1670 Float_t eta = GetPhotonEta();
1674 if(GetPhotonFlag() == 2)
1685 xmean /=(Float_t)nev;
1686 x2mean /=(Float_t)nev;
1692 Float_t vRMS = sqrt(x2mean - xmean*xmean);
1694 // cout << " RMS " << vRMS;
1696 SetEstimationOfTheta(xmean);
1697 SetEstimationOfThetaRMS(vRMS);
1700 void fcnrecon(Int_t& /*npar*/, Double_t* /*gin*/, Double_t &f, Double_t *par, Int_t)
1702 // function to be minimized
1703 AliRICHRecon *gMyRecon = (AliRICHRecon*)gAliRICHminuit->GetObjectFit();
1705 Float_t p0 = (Float_t)par[0];
1706 Float_t p1 = (Float_t)par[1];
1708 gMyRecon->SetTrackTheta(p0);
1709 gMyRecon->SetTrackPhi(p1);
1711 gMyRecon->EstimationOfTheta();
1712 Float_t vRMS = gMyRecon->GetEstimationOfThetaRMS();
1714 Int_t houghPhotons = gMyRecon->GetHoughPhotons();
1717 f = (Double_t)(1000*vRMS/(Float_t)houghPhotons);
1719 // if(fDebug) cout << " f " << f
1720 // << " theta " << par[0] << " phi " << par[1]
1721 // << " HoughPhotons " << houghPhotons << endl;
1723 // if(fDebug&&iflag == 3)
1725 // cout << " --- end convergence...summary --- " << endl;
1726 // cout << " theta " << par[0] << endl;
1727 // cout << " phi " << par[1] << endl;
1731 void AliRICHRecon::Waiting()
1734 if(!fIsDISPLAY) return;
1735 cout << " Press any key to continue...";
1737 // gSystem->ProcessEvents();