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 AliLoader * richLoader = Rich()->GetLoader();
92 AliRunLoader * runLoader = richLoader->GetRunLoader();
94 if (richLoader->TreeH() == 0x0) richLoader->LoadHits();
95 if (richLoader->TreeR() == 0x0) richLoader->LoadRecPoints();
96 if (richLoader->TreeD() == 0x0) richLoader->LoadDigits();
97 if (runLoader->TreeE() == 0x0) runLoader->LoadHeader();
98 if (runLoader->TreeK() == 0x0) runLoader->LoadKinematics();
100 richLoader->TreeR()->GetEntry(0);
102 Float_t clusX[7][500],clusY[7][500];
103 Int_t clusQ[7][500],clusMul[7][500];
106 for (Int_t ich=0;ich<7;ich++) {
107 nClusters[ich] = Rich()->Clusters(ich+1)->GetEntries();
108 for(Int_t k=0;k<nClusters[ich];k++) {
109 AliRICHcluster *pCluster = (AliRICHcluster *)Rich()->Clusters(ich+1)->At(k);
110 clusX[ich][k] = pCluster->X();
111 clusY[ich][k] = pCluster->Y();
112 clusQ[ich][k] = pCluster->Q();
113 clusMul[ich][k] = pCluster->Size();
114 // pCluster->Print();
118 Int_t nPrimaries = (Int_t)richLoader->TreeH()->GetEntries();
120 cout << " N. primaries " << nPrimaries << endl;
122 for(Int_t i=0;i<nPrimaries;i++){
124 richLoader->TreeH()->GetEntry(i);
126 // Rich()->Hits()->Print();
131 for(Int_t j=0;j<Rich()->Hits()->GetEntries();j++) {
133 pHit = (AliRICHhit*)Rich()->Hits()->At(j);
134 if(pHit->GetTrack() < nPrimaries) break;
138 cout << " iPrim " << iPrim << " pHit " << pHit << endl;
144 TParticle *pParticle = runLoader->Stack()->Particle(pHit->GetTrack());
145 Float_t pmod = pParticle->P();
146 Float_t pt = pParticle->Pt();
147 Float_t trackEta = pParticle->Eta();
148 Int_t q = (Int_t)TMath::Sign(1.,pParticle->GetPDG()->Charge());
150 // pParticle->Print();
152 cout << " pmod " << pmod << " pt " << pt << " Eta " << trackEta << " charge " << q << endl;
154 SetTrackMomentum(pmod);
156 SetTrackEta(trackEta);
159 TVector3 pLocal(0,0,0);//?????
161 TVector2 primLocal =Rich()->C(pHit->C())->Glob2Loc(pHit->InX3());
163 // Float_t pmodFreo = pLocal.Mag();
164 Float_t trackTheta = pLocal.Theta();
165 Float_t trackPhi = pLocal.Phi();
167 // cout << " trackTheta " << trackTheta << " trackPhi " << trackPhi << endl;
169 SetTrackTheta(trackTheta);
170 SetTrackPhi(trackPhi);
173 Float_t minDist = 999.;
175 // cout << " n Clusters " << nClusters[pHit->Chamber()-1] << " for chamber n. " << pHit->Chamber() << endl;
177 for(Int_t j=0;j<nClusters[pHit->Chamber()-1];j++)
179 Float_t diffx = primLocal.X() - clusX[pHit->Chamber()-1][j];
180 Float_t diffy = primLocal.Y() - clusY[pHit->Chamber()-1][j];
183 Float_t diff = sqrt(diffx*diffx + diffy*diffy);
193 Float_t diffx = primLocal.X() - clusX[pHit->Chamber()-1][maxInd];
194 Float_t diffy = primLocal.Y() - clusY[pHit->Chamber()-1][maxInd];
196 cout << " diffx " << diffx << " diffy " << diffy << endl;
202 Float_t shiftX = 0;//primLocal.X()/primLocal.Z()*(fRadiatorWidth+fQuartzWidth+fGapWidth) + primLocal.X(); ?????
203 Float_t shiftY = 0;//primLocal.Y()/primLocal.Z()*(fRadiatorWidth+fQuartzWidth+fGapWidth) + primLocal.Y(); ?????
208 Float_t *pclusX = &clusX[pHit->Chamber()-1][0];
209 Float_t *pclusY = &clusY[pHit->Chamber()-1][0];
211 SetCandidatePhotonX(pclusX);
212 SetCandidatePhotonY(pclusY);
213 SetCandidatePhotonsNumber(nClusters[pHit->Chamber()-1]);
215 Int_t qch = clusQ[pHit->Chamber()-1][maxInd];
218 if(minDist < 3.0 && qch > 120 && maxInd !=0)
224 Float_t xrndm = fXmin + (fXmax-fXmin)*gRandom->Rndm(280964);
225 Float_t yrndm = fYmin + (fYmax-fYmin)*gRandom->Rndm(280964);
233 trackThetaStored = GetTrackTheta();
234 trackPhiStored = GetTrackPhi();
235 thetaCerenkovStored = GetThetaCerenkov();
236 houghPhotonsStored = GetHoughPhotons();
238 Int_t diffNPhotons = 999;
240 Float_t diffTrackTheta = 999.;
241 Float_t diffTrackPhi = 999.;
243 while(fIsMINIMIZER && GetHoughPhotons() > 2
245 && diffTrackTheta > 0.0001
249 Int_t houghPhotonsBefore = GetHoughPhotons();
251 Float_t trackThetaBefore = GetTrackTheta();
252 Float_t trackPhiBefore = GetTrackPhi();
258 diffNPhotons = TMath::Abs(houghPhotonsBefore - GetHoughPhotons());
260 Float_t trackThetaAfter = GetTrackTheta();
261 Float_t trackPhiAfter = GetTrackPhi();
263 diffTrackTheta = TMath::Abs(trackThetaAfter - trackThetaBefore);
264 diffTrackPhi = TMath::Abs(trackPhiAfter - trackPhiBefore);
267 cout << " houghPhotonsBefore " << houghPhotonsBefore
268 << " GetHoughPhotons() " << GetHoughPhotons();
273 SetFittedThetaCerenkov(GetThetaCerenkov());
274 SetFittedHoughPhotons(GetHoughPhotons());
276 SetTrackTheta(trackThetaStored);
277 SetTrackPhi(trackPhiStored);
278 SetThetaCerenkov(thetaCerenkovStored);
279 SetHoughPhotons(houghPhotonsStored);
285 if(fIsDISPLAY) DrawEvent(1);
291 if(fIsDISPLAY) fDisplay->Print("display.ps");
292 }//StartProcessEvent()
293 //__________________________________________________________________________________________________
294 void AliRICHRecon::EndProcessEvent()
296 // function called at the end of the event loop
301 //__________________________________________________________________________________________________
302 void AliRICHRecon::PatRec()
304 //pattern recognition method based on Hough transform
307 Float_t trackTheta = GetTrackTheta();
308 Float_t trackPhi = GetTrackPhi();
309 Float_t pmod = GetTrackMomentum();
310 Int_t iMipIndex = GetMipIndex();
312 Bool_t kPatRec = kFALSE;
314 Int_t candidatePhotons = 0;
316 Float_t shiftX = GetShiftX();
317 Float_t shiftY = GetShiftY();
319 Float_t* candidatePhotonX = GetCandidatePhotonX();
320 Float_t* candidatePhotonY = GetCandidatePhotonY();
322 Int_t candidatePhotonsNumber = GetCandidatePhotonsNumber();
324 if(fDebug) cout << " n " << candidatePhotonsNumber << endl;
326 SetThetaCerenkov(999.);
328 SetHoughPhotonsNorm(0);
331 for (Int_t j=0; j < candidatePhotonsNumber; j++)
340 if (j == iMipIndex) continue;
343 if(candidatePhotonX[j] < -64.) continue; /* avoid artificial clusters from edge uesd by Yale.... */
345 Float_t xtoentr = candidatePhotonX[j] - shiftX;
346 Float_t ytoentr = candidatePhotonY[j] - shiftY;
348 // Float_t chargehit = fHits_charge[j];
349 // if(chargehit > 150) continue;
351 SetEntranceX(xtoentr);
352 SetEntranceY(ytoentr);
356 Int_t photonStatus = PhotonInBand();
360 cout << " Photon n. " << j << " Status " << photonStatus << " accepted " << endl;
361 cout << " CandidatePhotonX[j] " << candidatePhotonX[j] << " CandidatePhotonY[j] " << candidatePhotonY[j] << endl;
364 if(photonStatus == 0) continue;
368 FindThetaPhotonCerenkov();
370 Float_t thetaPhotonCerenkov = GetThetaPhotonCerenkov();
372 if(fDebug) cout << " theta photon " << thetaPhotonCerenkov << endl;
374 SetPhotonEta(thetaPhotonCerenkov);
381 if(candidatePhotons >= 1) kPatRec = kTRUE;
385 SetThetaCerenkov(999.);
388 SetPhotonsNumber(candidatePhotonsNumber);
395 Int_t nPhotonHough = GetHoughPhotons();
399 SetThetaCerenkov(999.);
400 SetHoughPhotonsNorm(0.);
404 if(fIsWEIGHT) FindWeightThetaCerenkov();
406 Float_t thetaCerenkov = GetThetaCerenkov();
408 SetThetaOfRing(thetaCerenkov);
409 FindAreaAndPortionOfRing();
411 Float_t nPhotonHoughNorm = ((Float_t)nPhotonHough)/GetPortionOfRing();
412 SetHoughPhotonsNorm(nPhotonHoughNorm);
414 // Calculate the area where the photon are accepted...
416 Float_t thetaInternal = thetaCerenkov - 0.5*fWindowWidth;
417 SetThetaOfRing(thetaInternal);
418 FindAreaAndPortionOfRing();
419 Float_t internalArea = GetAreaOfRing();
421 Float_t thetaExternal = thetaCerenkov + 0.5*fWindowWidth;
422 SetThetaOfRing(thetaExternal);
423 FindAreaAndPortionOfRing();
424 Float_t externalArea = GetAreaOfRing();
426 Float_t houghArea = externalArea - internalArea;
428 SetHoughArea(houghArea);
432 cout << " ----- SUMMARY OF RECONSTRUCTION ----- " << endl;
433 cout << " Rings found " << fNrings << " with thetac " << thetaCerenkov << endl;
436 cout << " Nphotons " << GetPhotonsNumber()
437 << " Hough " << nPhotonHough
438 << " norm " << nPhotonHoughNorm << endl;
440 cout << " In PatRec:p " << pmod << " theta " << trackTheta << " phi " << trackPhi << endl;
441 cout << " ------------------------------------- " << endl;
444 Int_t nPhotons = GetPhotonsNumber();
450 for (Int_t j=0; j < nPhotons;j++)
454 Float_t eta = GetPhotonEta();
458 if(GetPhotonFlag() == 2)
471 xmean /=(Float_t)nev;
472 x2mean /=(Float_t)nev;
478 Float_t vRMS = sqrt(x2mean - xmean*xmean);
482 if(fDebug) cout << " RMS " << vRMS << endl;
486 void AliRICHRecon::FindEmissionPoint()
488 //estimate the emission point in radiator
490 // Find emission point
492 Float_t absorbtionLenght=7.83*fRadiatorWidth; //absorption length in the freon (cm)
493 // 7.83 = -1/ln(T0) where
494 // T0->Trasmission freon at 180nm = 0.88 (Eph=6.85eV)
495 Float_t photonLenght, photonLenghtMin, photonLenghtMax;
497 photonLenght=exp(-fRadiatorWidth/(absorbtionLenght*cos(fCerenkovAnglePad)));
498 photonLenghtMin=fRadiatorWidth*photonLenght/(1.-photonLenght);
499 photonLenghtMax=absorbtionLenght*cos(fCerenkovAnglePad);
500 Float_t emissionPoint = fRadiatorWidth + photonLenghtMin - photonLenghtMax;
502 SetEmissionPoint(emissionPoint);
506 Int_t AliRICHRecon::PhotonInBand()
508 //search band fro photon candidates
510 // Float_t massOfParticle;
516 Float_t xtoentr = GetEntranceX();
517 Float_t ytoentr = GetEntranceY();
522 Float_t phpad = GetPhiPoint();
524 // Float_t pmod = GetTrackMomentum();
525 // Float_t trackTheta = GetTrackTheta();
526 // Float_t trackPhi = GetTrackPhi();
529 SetPhotonEnergy(5.6);
530 SetEmissionPoint(fRadiatorWidth -0.0001);
531 SetMassHypotesis(0.93828);
534 SetFreonRefractiveIndex();
536 beta = GetBetaOfParticle();
537 nfreon = GetFreonRefractiveIndex();
539 thetacer = Cerenkovangle(nfreon,beta);
543 if(fDebug) cout << " thetacer in photoninband min " << thetacer << endl;
545 FindThetaAtQuartz(thetacer);
547 if(thetacer == 999. || GetThetaAtQuartz() == 999.)
550 SetXInnerRing(-999.);
551 SetYInnerRing(-999.);
552 SetRadiusInnerRing(-999.);
556 SetThetaPhotonInDRS(GetThetaAtQuartz());
557 SetPhiPhotonInDRS(phpad);
559 innerRadius = FromEmissionToCathode();
560 if(innerRadius == 999.) innerRadius = -999.;
562 SetXInnerRing(GetXPointOnCathode());
563 SetYInnerRing(GetYPointOnCathode());
564 SetRadiusInnerRing(innerRadius);
568 SetPhotonEnergy(7.7);
569 SetEmissionPoint(0.);
570 // SetMassHypotesis(0.139567);
571 SetMassHypotesis(0.);
574 SetFreonRefractiveIndex();
576 beta = GetBetaOfParticle();
577 nfreon = GetFreonRefractiveIndex();
579 thetacer = Cerenkovangle(nfreon,beta);
583 if(fDebug) cout << " thetacer in photoninband max " << thetacer << endl;
585 FindThetaAtQuartz(thetacer);
587 if(thetacer == 999. || GetThetaAtQuartz() == 999.)
592 SetRadiusOuterRing(999.);
596 SetThetaPhotonInDRS(GetThetaAtQuartz());
597 SetPhiPhotonInDRS(phpad);
599 outerRadius = FromEmissionToCathode();
600 // cout << " outerRadius " << outerRadius << endl;
601 SetXOuterRing(GetXPointOnCathode());
602 SetYOuterRing(GetYPointOnCathode());
603 SetRadiusOuterRing(outerRadius);
606 Float_t padradius = sqrt(TMath::Power(xtoentr,2)+TMath::Power(ytoentr,2));
608 if(fDebug) printf(" rmin %f r %f rmax %f \n",innerRadius,padradius,outerRadius);
610 if(padradius>=innerRadius && padradius<=outerRadius) return 1;
614 void AliRICHRecon::FindThetaAtQuartz(Float_t thetaCerenkov)
616 //find the theta at the quartz plate
618 if(thetaCerenkov == 999.)
620 SetThetaAtQuartz(999.);
624 Float_t thetaAtQuartz = 999.;
626 Float_t trackTheta = GetTrackTheta();
628 if(trackTheta == 0) {
630 if(fDebug) cout << " Theta sol unique " << thetaCerenkov << endl;
632 thetaAtQuartz = thetaCerenkov;
633 SetThetaAtQuartz(thetaAtQuartz);
637 Float_t trackPhi = GetTrackPhi();
638 Float_t phiPoint = GetPhiPoint();
640 Double_t den = TMath::Sin((Double_t)trackTheta)
641 *TMath::Cos((Double_t)trackPhi)
642 *TMath::Cos((Double_t)phiPoint) +
643 TMath::Sin((Double_t)trackTheta)
644 *TMath::Sin((Double_t)trackPhi)
645 *TMath::Sin((Double_t)phiPoint);
646 Double_t b = TMath::Cos((Double_t)trackTheta)/den;
647 Double_t c = -TMath::Cos((Double_t)thetaCerenkov)/den;
649 Double_t underSqrt = 1 + b*b - c*c;
653 cout << " trackTheta " << trackTheta << endl;
654 cout << " TrackPhi " << trackPhi << endl;
655 cout << " PhiPoint " << phiPoint << endl;
656 cout << " ThetaCerenkov " << thetaCerenkov << endl;
657 cout << " den b c " << den << " b " << b << " c " << c << endl;
661 if(fDebug) cout << " sqrt negative !!!!" << underSqrt << endl;
662 SetThetaAtQuartz(999.);
666 Double_t sol1 = (1+TMath::Sqrt(underSqrt))/(b-c);
667 Double_t sol2 = (1-TMath::Sqrt(underSqrt))/(b-c);
669 Double_t thetaSol1 = 2*TMath::ATan(sol1);
670 Double_t thetaSol2 = 2*TMath::ATan(sol2);
672 if(fDebug) cout << " Theta sol 1 " << thetaSol1
673 << " Theta sol 2 " << thetaSol2 << endl;
675 if(thetaSol1>0 && thetaSol1 < TMath::Pi()) thetaAtQuartz = (Float_t)thetaSol1;
676 if(thetaSol2>0 && thetaSol2 < TMath::Pi()) thetaAtQuartz = (Float_t)thetaSol2;
678 SetThetaAtQuartz(thetaAtQuartz);
681 void AliRICHRecon::FindThetaPhotonCerenkov()
683 //find theta cerenkov of ring
685 Float_t thetaCerMin = 0.;
686 Float_t thetaCerMax = 0.75;
687 Float_t thetaCerMean;
689 Float_t radiusMin, radiusMax, radiusMean;
690 Int_t nIteration = 0;
692 const Float_t kTollerance = 0.05;
694 // Float_t pmod = GetTrackMomentum();
695 // Float_t trackTheta = GetTrackTheta();
696 // Float_t trackPhi = GetTrackPhi();
698 Float_t phiPoint = GetPhiPoint();
700 SetPhotonEnergy(6.85);
701 SetEmissionPoint(fRadiatorWidth/2);
703 Float_t xPoint = GetEntranceX();
704 Float_t yPoint = GetEntranceY();
705 Float_t distPoint = sqrt(xPoint*xPoint + yPoint*yPoint);
707 if(fDebug) cout << " DistPoint " << distPoint << endl;
709 // Star minimization...
713 FindThetaAtQuartz(thetaCerMin);
715 if(GetThetaAtQuartz() == 999.)
721 SetThetaPhotonInDRS(GetThetaAtQuartz());
722 SetPhiPhotonInDRS(phiPoint);
724 radiusMin = FromEmissionToCathode();
729 FindThetaAtQuartz(thetaCerMax);
730 if(GetThetaAtQuartz() == 999.)
736 SetThetaPhotonInDRS(GetThetaAtQuartz());
737 SetPhiPhotonInDRS(phiPoint);
739 radiusMax = FromEmissionToCathode();
743 thetaCerMean = (thetaCerMax + thetaCerMin)/2;
745 FindThetaAtQuartz(thetaCerMean);
746 if(GetThetaAtQuartz() == 999.)
752 SetThetaPhotonInDRS(GetThetaAtQuartz());
753 SetPhiPhotonInDRS(phiPoint);
755 radiusMean = FromEmissionToCathode();
758 if(fDebug) cout << " r1 " << radiusMin << " rmean "
759 << radiusMean << " r2 " << radiusMax << endl;
761 while (TMath::Abs(radiusMean-distPoint) > kTollerance)
764 if((radiusMin-distPoint)*(radiusMean-distPoint) < 0) thetaCerMax = thetaCerMean;
765 if((radiusMin-distPoint)*(radiusMean-distPoint) > 0) {
767 thetaCerMin = thetaCerMean;
769 FindThetaAtQuartz(thetaCerMin);
770 SetThetaPhotonInDRS(GetThetaAtQuartz());
771 SetPhiPhotonInDRS(phiPoint);
773 radiusMin =FromEmissionToCathode();
776 thetaCerMean = (thetaCerMax + thetaCerMin)/2;
778 FindThetaAtQuartz(thetaCerMean);
779 SetThetaPhotonInDRS(GetThetaAtQuartz());
780 SetPhiPhotonInDRS(phiPoint);
782 radiusMean = FromEmissionToCathode();
786 if(fDebug) printf(" max iterations in FindPhotonCerenkov\n");
787 SetThetaPhotonCerenkov(999.);
792 SetThetaPhotonCerenkov(thetaCerMean);
796 void AliRICHRecon::FindAreaAndPortionOfRing()
798 //find fraction of the ring accepted by the RICH
800 Float_t xPoint[NPointsOfRing], yPoint[NPointsOfRing];
802 // Float_t xtoentr = GetEntranceX();
803 // Float_t ytoentr = GetEntranceY();
804 Float_t shiftX = GetShiftX();
805 Float_t shiftY = GetShiftY();
807 Float_t xemiss = GetXCoordOfEmission();
808 Float_t yemiss = GetYCoordOfEmission();
810 Float_t x0 = xemiss + shiftX;
811 Float_t y0 = yemiss + shiftY;
813 // Float_t pmod = GetTrackMomentum();
814 // Float_t trackTheta = GetTrackTheta();
815 // Float_t trackPhi = GetTrackPhi();
817 SetPhotonEnergy(6.85);
818 SetFreonRefractiveIndex();
820 SetEmissionPoint(fRadiatorWidth/2.);
822 Float_t theta = GetThetaOfRing();
825 Int_t nPsiAccepted = 0;
828 for(Int_t i=0;i<NPointsOfRing-1;i++)
831 Float_t psi = 2*TMath::Pi()*i/NPointsOfRing;
833 SetThetaPhotonInTRS(theta);
834 SetPhiPhotonInTRS(psi);
835 FindPhotonAnglesInDRS();
837 Float_t radius = FromEmissionToCathode();
838 if (radius == 999.) continue;
842 Float_t xPointRing = GetXPointOnCathode() + shiftX;
843 Float_t yPointRing = GetYPointOnCathode() + shiftY;
845 SetDetectorWhereX(xPointRing);
846 SetDetectorWhereY(yPointRing);
848 Int_t zone = CheckDetectorAcceptance();
853 FindIntersectionWithDetector();
854 xPoint[nPoints] = GetIntersectionX();
855 yPoint[nPoints] = GetIntersectionY();
859 xPoint[nPoints] = xPointRing;
860 yPoint[nPoints] = yPointRing;
868 xPoint[nPoints] = xPoint[0];
869 yPoint[nPoints] = yPoint[0];
875 for (Int_t i = 0; i < nPoints; i++)
877 area += TMath::Abs((xPoint[i]-x0)*(yPoint[i+1]-y0) - (xPoint[i+1]-x0)*(yPoint[i]-y0));
882 Float_t portionOfRing = ((Float_t)nPsiAccepted)/((Float_t)(nPsiTotal));
886 SetPortionOfRing(portionOfRing);
889 void AliRICHRecon::FindIntersectionWithDetector()
891 // find ring intersection with CsI edges
893 Float_t xIntersect, yIntersect;
894 Float_t x1, x2, y1, y2;
896 Float_t shiftX = GetShiftX();
897 Float_t shiftY = GetShiftY();
899 Float_t xPoint = GetXPointOnCathode() + shiftX;
900 Float_t yPoint = GetYPointOnCathode() + shiftY;
902 Float_t xemiss = GetXCoordOfEmission();
903 Float_t yemiss = GetYCoordOfEmission();
905 Float_t phi = GetPhiPhotonInDRS();
906 Float_t m = tan(phi);
908 Float_t x0 = xemiss + shiftX;
909 Float_t y0 = yemiss + shiftY;
933 yIntersect = m*(xIntersect - x0) + y0;
934 if (yIntersect >= fYmin && yIntersect <= fYmax && xIntersect >= x1 && xIntersect <= x2)
936 SetIntersectionX(xIntersect);
937 SetIntersectionY(yIntersect);
942 yIntersect = m*(xIntersect - x0) + y0;
943 if (yIntersect >= fYmin && yIntersect <= fYmax && xIntersect >= x1 && xIntersect <= x2)
945 SetIntersectionX(xIntersect);
946 SetIntersectionY(yIntersect);
951 xIntersect = (yIntersect - y0)/m + x0;
952 if (xIntersect >= fXmin && xIntersect <= fXmax && yIntersect >= y1 && yIntersect <= y2)
954 SetIntersectionX(xIntersect);
955 SetIntersectionY(yIntersect);
960 xIntersect = (yIntersect - y0)/m + x0;
961 if (xIntersect >= fXmin && xIntersect <= fXmax && yIntersect >= y1 && yIntersect <= y2)
963 SetIntersectionX(xIntersect);
964 SetIntersectionY(yIntersect);
968 cout << " sono fuori!!!!!!" << endl;
971 //__________________________________________________________________________________________________
972 Int_t AliRICHRecon::CheckDetectorAcceptance() const
974 // check for the acceptance
976 // crosses X -2.6 2.6 cm
979 Float_t xcoord = GetDetectorWhereX();
980 Float_t ycoord = GetDetectorWhereY();
984 if(ycoord > fYmax) return 2;
985 if(ycoord > fYmin && ycoord < fYmax) return 3;
986 if(ycoord < fYmin) return 4;
990 if(ycoord > fYmax) return 8;
991 if(ycoord > fYmin && ycoord < fYmax) return 7;
992 if(ycoord < fYmin) return 6;
994 if(xcoord > fXmin && xcoord < fXmax)
996 if(ycoord > fYmax) return 1;
997 if(ycoord > fYmin && ycoord < fYmax) return 0;
998 if(ycoord < fYmin) return 5;
1002 //__________________________________________________________________________________________________
1003 Float_t AliRICHRecon::PhotonPositionOnCathode()
1005 // find the photon position on the CsI
1006 // Float_t massOfParticle;
1011 SetPhotonEnergy(6.85);
1012 SetEmissionPoint(fRadiatorWidth/2.);
1013 SetMassHypotesis(0.139567);
1015 SetBetaOfParticle();
1016 SetFreonRefractiveIndex();
1018 beta = GetBetaOfParticle();
1019 nfreon = GetFreonRefractiveIndex();
1022 Float_t radius = FromEmissionToCathode();
1023 if (radius == 999.) return 999.;
1028 void AliRICHRecon::FindPhotonAnglesInDRS()
1030 // Setup the rotation matrix of the track...
1037 Float_t trackTheta = GetTrackTheta();
1038 Float_t trackPhi = GetTrackPhi();
1040 mtheta.RotateY(trackTheta);
1041 mphi.RotateZ(trackPhi);
1043 mrot = mphi * mtheta;
1044 // minv = mrot.Inverse();
1046 TVector3 photonInRadiator(1,1,1);
1048 Float_t thetaCerenkov = GetThetaPhotonInTRS();
1049 Float_t phiCerenkov = GetPhiPhotonInTRS();
1051 photonInRadiator.SetTheta(thetaCerenkov);
1052 photonInRadiator.SetPhi(phiCerenkov);
1053 photonInRadiator = mrot * photonInRadiator;
1054 Float_t theta = photonInRadiator.Theta();
1055 Float_t phi = photonInRadiator.Phi();
1056 SetThetaPhotonInDRS(theta);
1057 SetPhiPhotonInDRS(phi);
1061 Float_t AliRICHRecon::FromEmissionToCathode()
1063 // trace from emission point to cathode
1065 Float_t nfreon, nquartz, ngas;
1067 SetFreonRefractiveIndex();
1068 SetQuartzRefractiveIndex();
1069 SetGasRefractiveIndex();
1071 nfreon = GetFreonRefractiveIndex();
1072 nquartz = GetQuartzRefractiveIndex();
1073 ngas = GetGasRefractiveIndex();
1075 Float_t trackTheta = GetTrackTheta();
1076 Float_t trackPhi = GetTrackPhi();
1077 Float_t lengthOfEmissionPoint = GetEmissionPoint();
1079 Float_t theta = GetThetaPhotonInDRS();
1080 Float_t phi = GetPhiPhotonInDRS();
1082 // cout << " Theta " << Theta << " Phi " << Phi << endl;
1084 Float_t xemiss = lengthOfEmissionPoint*tan(trackTheta)*cos(trackPhi);
1085 Float_t yemiss = lengthOfEmissionPoint*tan(trackTheta)*sin(trackPhi);
1087 SetXCoordOfEmission(xemiss);
1088 SetYCoordOfEmission(yemiss);
1090 Float_t thetaquar = SnellAngle(nfreon, nquartz, theta);
1092 if(thetaquar == 999.)
1094 SetXPointOnCathode(999.);
1095 SetYPointOnCathode(999.);
1099 Float_t thetagap = SnellAngle( nquartz, ngas, thetaquar);
1101 if(thetagap == 999.)
1103 SetXPointOnCathode(999.);
1104 SetYPointOnCathode(999.);
1108 Float_t xw = (fRadiatorWidth - lengthOfEmissionPoint)*cos(phi)*tan(theta);
1109 Float_t xq = fQuartzWidth*cos(phi)*tan(thetaquar);
1110 Float_t xg = fGapWidth*cos(phi)*tan(thetagap);
1111 Float_t yw = (fRadiatorWidth - lengthOfEmissionPoint)*sin(phi)*tan(theta);
1112 Float_t yq = fQuartzWidth*sin(phi)*tan(thetaquar);
1113 Float_t yg = fGapWidth*sin(phi)*tan(thetagap);
1116 Float_t xtot = xemiss + xw + xq + xg;
1117 Float_t ytot = yemiss + yw + yq + yg;
1119 SetXPointOnCathode(xtot);
1120 SetYPointOnCathode(ytot);
1123 Float_t distanceFromEntrance = sqrt(TMath::Power(fPhotonLimitX,2)
1124 +TMath::Power(fPhotonLimitY,2));
1126 return distanceFromEntrance;
1131 void AliRICHRecon::FindPhiPoint()
1133 //find phi of generated point
1135 Float_t xtoentr = GetEntranceX();
1136 Float_t ytoentr = GetEntranceY();
1138 Float_t trackTheta = GetTrackTheta();
1139 Float_t trackPhi = GetTrackPhi();
1141 Float_t emissionPoint = GetEmissionPoint();
1143 Float_t argY = ytoentr - emissionPoint*tan(trackTheta)*sin(trackPhi);
1144 Float_t argX = xtoentr - emissionPoint*tan(trackTheta)*cos(trackPhi);
1145 Float_t phipad = atan2(argY,argX);
1147 SetPhiPoint(phipad);
1151 Float_t AliRICHRecon::Cerenkovangle(Float_t n, Float_t beta)
1153 // cerenkov angle from n and beta
1155 // Compute the cerenkov angle
1161 // cout << " warning in Cerenkoangle !!!!!! " << endl;
1165 thetacer = acos (1./(n*beta));
1169 Float_t AliRICHRecon::SnellAngle(Float_t n1, Float_t n2, Float_t theta1)
1173 // Compute the Snell angle
1175 Float_t sinrefractangle;
1176 Float_t refractangle;
1178 sinrefractangle = (n1/n2)*sin(theta1);
1180 if(sinrefractangle>1.) {
1181 // cout << " PROBLEMS IN SNELL ANGLE !!!!! " << endl;
1182 refractangle = 999.;
1183 return refractangle;
1186 refractangle = asin(sinrefractangle);
1187 return refractangle;
1191 void AliRICHRecon::HoughResponse()
1195 // Implement Hough response pat. rec. method
1202 int i, j, k, nCorrBand;
1203 float hcs[750],hcsw[750];
1204 float angle, weight;
1205 float lowerlimit,upperlimit;
1211 float etaPeakPos = -1;
1213 Int_t etaPeakCount = -1;
1215 Float_t thetaCerenkov = 0.;
1217 nBin = (int)(0.5+fThetaMax/(fDTheta));
1218 nCorrBand = (int)(0.5+ fWindowWidth/(2 * fDTheta));
1220 memset ((void *)hcs, 0, fThetaBin*sizeof(float));
1221 memset ((void *)hcsw, 0, fThetaBin*sizeof(float));
1223 Int_t nPhotons = GetPhotonsNumber();
1225 Int_t weightFlag = 0;
1227 for (k=0; k< nPhotons; k++) {
1231 angle = GetPhotonEta();
1233 if(angle == -999.) continue;
1235 if (angle>=fThetaMin && angle<= fThetaMax)
1239 bin = (int)(0.5+angle/(fDTheta));
1241 bin1= bin-nCorrBand;
1242 bin2= bin+nCorrBand;
1244 // calculate weights
1248 lowerlimit = ((Float_t)bin1)*fDTheta + 0.5*fDTheta;
1249 SetThetaOfRing(lowerlimit);
1250 FindAreaAndPortionOfRing();
1251 Float_t area1 = GetAreaOfRing();
1253 upperlimit = ((Float_t)bin2)*fDTheta + 0.5*fDTheta;
1254 SetThetaOfRing(upperlimit);
1255 FindAreaAndPortionOfRing();
1256 Float_t area2 = GetAreaOfRing();
1258 // cout << "lowerlimit" << lowerlimit << "upperlimit " << upperlimit << endl;
1259 Float_t diffarea = area2 - area1;
1263 weight = 1./(area2-area1);
1271 // cout <<" low "<< lowerlimit << " up " << upperlimit <<
1272 // " area1 " << area1 << " area2 " << area2 << " weight " << weight << endl;
1280 SetPhotonWeight(weight);
1282 // cout << "weight..." << weight << endl;
1286 if (bin2>nBin) bin2=nBin;
1288 for (j=bin1; j<bin2; j++)
1304 // cout << " probems with weight...normal procedure adopted " << endl;
1307 HoughFiltering(hCSspace);
1309 for (bin=0; bin <nBin; bin++) {
1310 angle = (bin+0.5) * (fDTheta);
1311 if (hCSspace[bin] && hCSspace[bin] > etaPeakPos) {
1313 etaPeakPos = hCSspace[bin];
1317 if (hCSspace[bin] == etaPeakPos) {
1318 etaPeak[++etaPeakCount] = angle;
1323 for (i=0; i<etaPeakCount+1; i++) {
1324 thetaCerenkov += etaPeak[i];
1326 if (etaPeakCount>=0) {
1327 thetaCerenkov /= etaPeakCount+1;
1328 fThetaPeakPos = etaPeakPos;
1331 SetThetaCerenkov(thetaCerenkov);
1335 void AliRICHRecon::HoughFiltering(float hcs[])
1342 float k[5] = {0.05, 0.25, 0.4, 0.25, 0.05};
1347 nBin = (int)(1+fThetaMax/fDTheta);
1348 sizeHCS = fThetaBin*sizeof(float);
1350 memset ((void *)hcsFilt, 0, sizeHCS);
1352 for (nx = 0; nx < nBin; nx++) {
1353 for (i = 0; i < 5; i++) {
1355 if (nxDx> -1 && nxDx<nBin)
1356 hcsFilt[nx] += hcs[nxDx] * k[i];
1360 for (nx = 0; nx < nBin; nx++) {
1361 hcs[nx] = hcsFilt[nx];
1365 void AliRICHRecon::FindWeightThetaCerenkov()
1367 // manage with weight for photons
1370 Float_t weightThetaCerenkov = 0.;
1372 Int_t nPhotons = GetPhotonsNumber();
1373 for(Int_t i=0;i<nPhotons;i++)
1377 if(GetPhotonFlag() == 2)
1379 Float_t photonEta = GetPhotonEta();
1380 Float_t photonWeight = GetPhotonWeight();
1381 weightThetaCerenkov += photonEta*photonWeight;
1382 wei += photonWeight;
1388 weightThetaCerenkov /= wei;
1392 weightThetaCerenkov = 0.;
1395 SetThetaCerenkov(weightThetaCerenkov);
1397 cout << " thetac weighted -> " << weightThetaCerenkov << endl;
1401 void AliRICHRecon::FlagPhotons()
1405 Int_t nPhotonHough = 0;
1407 Float_t thetaCerenkov = GetThetaCerenkov();
1408 if(fDebug) cout << " fThetaCerenkov " << thetaCerenkov << endl;
1410 Float_t thetaDist= thetaCerenkov - fThetaMin;
1411 Int_t steps = (Int_t)(thetaDist / fDTheta);
1413 Float_t tmin = fThetaMin + (Float_t)(steps - 1)*fDTheta;
1414 Float_t tmax = fThetaMin + (Float_t)(steps)*fDTheta;
1415 Float_t tavg = 0.5*(tmin+tmax);
1417 tmin = tavg - 0.5*fWindowWidth;
1418 tmax = tavg + 0.5*fWindowWidth;
1420 if(fDebug) cout << " tmin " << tmin << " tmax " << tmax << endl;
1421 if(fDebug) cout << " thetac " << thetaCerenkov << endl;
1423 // Int_t candidatePhotonsNumber = GetCandidatePhotonsNumber();
1425 Int_t nPhotons = GetPhotonsNumber();
1427 // for(Int_t i=0;i<candidatePhotonsNumber;i++)
1429 for(Int_t i=0;i<nPhotons;i++)
1433 Float_t photonEta = GetPhotonEta();
1435 if(photonEta == -999.) continue;
1437 if(photonEta >= tmin && photonEta <= tmax)
1443 SetHoughPhotons(nPhotonHough);
1446 void AliRICHRecon::DrawEvent(Int_t flag) const
1448 // draw event with rings
1450 flag=1; // dummy to be removed...
1453 Float_t AliRICHRecon::FindMassOfParticle()
1455 // find mass of the particle from theta cerenkov
1457 Float_t pmod = GetTrackMomentum();
1459 SetPhotonEnergy(6.85);
1460 SetFreonRefractiveIndex();
1462 Float_t thetaCerenkov = GetThetaCerenkov();
1463 FindBetaFromTheta(thetaCerenkov);
1465 Double_t beta = (Double_t)(GetBetaOfParticle());
1466 Double_t den = 1. - beta*beta;
1467 if(den<=0.) return 999.;
1469 Double_t gamma = 1./TMath::Sqrt(den);
1471 Float_t mass = pmod/(beta*(Float_t)gamma);
1477 void AliRICHRecon::FillHistograms()
1479 // fill histograms..
1481 Float_t fittedTrackTheta, fittedTrackPhi;
1483 Float_t thetaCerenkov = GetThetaCerenkov();
1484 if(thetaCerenkov == 999.) return;
1486 Float_t vertZ = GetEventVertexZ();
1488 Float_t trackTheta = GetTrackTheta();
1489 Float_t trackPhi = GetTrackPhi();
1490 Float_t pmod = GetTrackMomentum();
1491 Float_t pt = GetTrackPt();
1492 Float_t trackEta = GetTrackEta();
1493 Int_t q = GetTrackCharge();
1494 Float_t tPCLastZ = GetTrackTPCLastZ();
1495 Float_t minDist = GetMinDist();
1497 fittedTrackTheta = GetFittedTrackTheta();
1498 fittedTrackPhi = GetFittedTrackPhi();
1499 Int_t fittednPhotonHough = GetFittedHoughPhotons();
1503 cout << " p " << pmod << " ThetaC " << thetaCerenkov
1504 << " rings " << fNrings << endl;
1507 Int_t nPhotonHough = GetHoughPhotons();
1508 // Float_t nPhotonHoughNorm = GetHoughPhotonsNorm();
1509 Float_t inRing = GetPortionOfRing();
1511 Float_t massOfParticle = FindMassOfParticle();
1513 Float_t houghArea = GetHoughArea();
1514 Float_t multiplicity = GetEventMultiplicity();
1525 var[6] = trackTheta;
1527 var[8] = fittedTrackTheta;
1528 var[9] = fittedTrackPhi;
1530 var[11] = thetaCerenkov;
1531 var[12] = (Float_t)nPhotonHough;
1532 var[13] = (Float_t)fittednPhotonHough;
1534 var[15] = massOfParticle;
1535 var[16] = houghArea;
1536 var[17] = multiplicity;
1543 fittedTrackTheta = GetFittedTrackTheta();
1544 fittedTrackPhi = GetFittedTrackPhi();
1548 if(thetaCerenkov > 0.505 && thetaCerenkov < 0.605) {
1549 SetPhotonEnergy(6.85);
1550 SetFreonRefractiveIndex();
1553 Int_t nPhotons = GetPhotonsNumber();
1555 for (Int_t j=0; j < nPhotons;j++)
1558 //__________________________________________________________________________________________________
1559 void AliRICHRecon::Minimization()
1561 // minimization to find the best theta and phi of the track
1566 static Double_t vstart[2];
1567 static Double_t lower[2], upper[2];
1568 static Double_t step[2]={0.001,0.001};
1570 Double_t trackThetaNew,trackPhiNew;
1572 Double_t eps, b1, b2;
1575 gAliRICHminuit = new TMinuit(2);
1576 gAliRICHminuit->SetObjectFit((TObject *)this);
1577 gAliRICHminuit->SetFCN(fcnrecon);
1578 gAliRICHminuit->mninit(5,10,7);
1580 vstart[0] = (Double_t)GetTrackTheta();
1581 vstart[1] = (Double_t)GetTrackPhi();
1583 lower[0] = vstart[0] - 0.03;
1584 if(lower[0] < 0) lower[0] = 0.;
1585 upper[0] = vstart[0] + 0.03;
1586 lower[1] = vstart[1] - 0.03;
1587 upper[1] = vstart[1] + 0.03;
1590 gAliRICHminuit->mnparm(0,"theta",vstart[0],step[0],lower[0],upper[0],ierflag);
1591 gAliRICHminuit->mnparm(1," phi ",vstart[1],step[1],lower[1],upper[1],ierflag);
1595 // gAliRICHminuit->FixParameter(0);
1597 gAliRICHminuit->SetPrintLevel(-1);
1598 // gAliRICHminuit->mnexcm("SET PRI",&arglist, 1, ierflag);
1599 gAliRICHminuit->mnexcm("SET NOGR",&arglist, 1, ierflag);
1600 gAliRICHminuit->mnexcm("SET NOW",&arglist, 1, ierflag);
1602 gAliRICHminuit->mnexcm("SET ERR", &arglist, 1,ierflg);
1605 // gAliRICHminuit->mnscan();
1607 // gAliRICHminuit->mnexcm("SIMPLEX",&arglist, 0, ierflag);
1608 gAliRICHminuit->mnexcm("MIGRAD",&arglist, 0, ierflag);
1609 gAliRICHminuit->mnexcm("EXIT" ,&arglist, 0, ierflag);
1611 gAliRICHminuit->mnpout(0,chname, trackThetaNew, eps , b1, b2, ierflg);
1612 gAliRICHminuit->mnpout(1,chname, trackPhiNew, eps , b1, b2, ierflg);
1614 //values after the fit...
1615 SetFittedTrackTheta((Float_t)trackThetaNew);
1616 SetFittedTrackPhi((Float_t)trackPhiNew);
1618 delete gAliRICHminuit;
1622 void AliRICHRecon::EstimationOfTheta()
1628 Float_t shiftX = GetShiftX();
1629 Float_t shiftY = GetShiftY();
1631 Float_t *candidatePhotonX = GetCandidatePhotonX();
1632 Float_t *candidatePhotonY = GetCandidatePhotonY();
1634 Int_t nPhotonsCandidates = GetCandidatePhotonsNumber();
1636 // cout << "MINIM: Nphotons " << nPhotonsCandidates << endl;
1638 for (Int_t j=0; j < nPhotonsCandidates; j++)
1643 if(!GetPhotonFlag()) continue;
1645 Float_t xtoentr = candidatePhotonX[j] - shiftX;
1646 Float_t ytoentr = candidatePhotonY[j] - shiftY;
1648 SetEntranceX(xtoentr);
1649 SetEntranceY(ytoentr);
1653 FindThetaPhotonCerenkov();
1655 Float_t thetaPhotonCerenkov = GetThetaPhotonCerenkov();
1657 // cout << " ACCEPTED!!! " << thetaPhotonCerenkov << endl;
1659 SetPhotonEta(thetaPhotonCerenkov);
1666 Float_t x2mean = 0.;
1669 for (Int_t j=0; j < nPhotonsCandidates;j++)
1673 Float_t eta = GetPhotonEta();
1677 if(GetPhotonFlag() == 2)
1688 xmean /=(Float_t)nev;
1689 x2mean /=(Float_t)nev;
1695 Float_t vRMS = sqrt(x2mean - xmean*xmean);
1697 // cout << " RMS " << vRMS;
1699 SetEstimationOfTheta(xmean);
1700 SetEstimationOfThetaRMS(vRMS);
1703 void fcnrecon(Int_t& /*npar*/, Double_t* /*gin*/, Double_t &f, Double_t *par, Int_t)
1705 // function to be minimized
1706 AliRICHRecon *gMyRecon = (AliRICHRecon*)gAliRICHminuit->GetObjectFit();
1708 Float_t p0 = (Float_t)par[0];
1709 Float_t p1 = (Float_t)par[1];
1711 gMyRecon->SetTrackTheta(p0);
1712 gMyRecon->SetTrackPhi(p1);
1714 gMyRecon->EstimationOfTheta();
1715 Float_t vRMS = gMyRecon->GetEstimationOfThetaRMS();
1717 Int_t houghPhotons = gMyRecon->GetHoughPhotons();
1720 f = (Double_t)(1000*vRMS/(Float_t)houghPhotons);
1722 // if(fDebug) cout << " f " << f
1723 // << " theta " << par[0] << " phi " << par[1]
1724 // << " HoughPhotons " << houghPhotons << endl;
1726 // if(fDebug&&iflag == 3)
1728 // cout << " --- end convergence...summary --- " << endl;
1729 // cout << " theta " << par[0] << endl;
1730 // cout << " phi " << par[1] << endl;
1734 void AliRICHRecon::Waiting()
1737 if(!fIsDISPLAY) return;
1738 cout << " Press any key to continue...";
1740 // gSystem->ProcessEvents();