]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RICH/AliRICHRecon.cxx
more clear variables
[u/mrichter/AliRoot.git] / RICH / AliRICHRecon.cxx
CommitLineData
5cb4dfc3 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
88dd9ad4 16//////////////////////////////////////////////////////////////////////////
17// //
18// AliRICHRecon //
19// //
20// RICH class to perfom pattern recognition based on Hough transfrom //
db910db9 21// for single chamber //
88dd9ad4 22//////////////////////////////////////////////////////////////////////////
23
db910db9 24#include "AliRICHRecon.h" //class header
5cb4dfc3 25#include <TMath.h>
5cb4dfc3 26#include <TRotation.h>
5cb4dfc3 27#include <TVector3.h>
910735ae 28#include <TH1F.h>
024a7e64 29
db910db9 30#include "AliRICHCluster.h" //ThetaCerenkov()
024a7e64 31#include "AliRICHParam.h"
db910db9 32#include "AliRICHHelix.h" //ThetaCerenkov()
998b831f 33#include <AliLog.h>
5cb4dfc3 34
35#define NPointsOfRing 201
36
b068561d 37//__________________________________________________________________________________________________
5c09947e 38AliRICHRecon::AliRICHRecon():
39 TTask ("RichRec","RichPat"),
40 fClusters(0x0),
41 fParam(AliRICHParam::Instance()),
42 fPhotonsNumber(0),
43 fPhotonIndex(0), // should we use -1?
44 fFittedHoughPhotons(0),
45 fMinNumPhots(3),
46 fTrackTheta(0),
47 fTrackPhi(0),
48 fMinDist(999),
49 fTrackBeta(0),
50 fXtoentr(999),
51 fYtoentr(999),
52 fThetaPhotonInTRS(0),
53 fPhiPhotonInTRS(0),
54 fThetaPhotonInDRS(0),
55 fPhiPhotonInDRS(0),
56 fThetaAtQuartz(0),
57 fXEmiss(-999),
58 fYEmiss(-999),
59 fXInner(-999),
60 fYInner(-999),
61 fXOuter(-999),
62 fYOuter(-999),
63 fInnerRadius(-999),
64 fOuterRadius(-999),
65 fEphot(0),
66 fLengthEmissionPoint(0),
67 fPhotonLimitX(999),
68 fPhotonLimitY(999),
69 fDistanceFromCluster(999),
70 fCerenkovAnglePad(999),
71 fThetaPhotonCerenkov(0),
72 fShiftX(0),
73 fShiftY(0),
74 fXcoord(999),
75 fYcoord(999),
76 fIntersectionX(999),
77 fIntersectionY(999),
78 fMassHypotesis(0.139567),
79 fThetaOfRing(0),
80 fAreaOfRing(0),
81 fPortionOfRing(0),
82 fHoughArea(0),
83 fHoughRMS(999),
84 fCandidatePhotonX(0x0),
85 fCandidatePhotonY(0x0),
86 fFittedTrackTheta(0),
87 fFittedTrackPhi(0),
88 fFittedThetaCerenkov(0),
89 fThetaMin(0.0),
90 fThetaMax(0.75),
91 fIsWEIGHT(kFALSE),
92 fIsBACKGROUND(kFALSE),
93 fDTheta(0.001),
94 fWindowWidth(0.045),
95 fNumEtaPhotons(0),
96 fnPhotBKG(0),
97 fThetaCerenkov(0),
98 fWeightThetaCerenkov(0),
99 fThetaPeakPos(0)
5cb4dfc3 100{
998b831f 101// main ctor
5c09947e 102 for (Int_t i=0; i<3000; i++) {
103 fPhotonFlag[i] = 0;
104 fPhiPoint[i] = -999;
105 fPhotonEta[i] = -999;
106 fPhotonWeight[i] = 0.0;
107 fEtaFlag[i] = 0;
108 fEtaPhotons[i] = 0;
109 fWeightPhotons[i] = 0;
110 }
5cb4dfc3 111}
b068561d 112//__________________________________________________________________________________________________
aad5d262 113Double_t AliRICHRecon::ThetaCerenkov(AliRICHHelix *pHelix,TClonesArray *pClusters,Int_t &nphot)
5cb4dfc3 114{
998b831f 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
db910db9 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.
118// Argume
aad5d262 119// Returns: Track theta ckov in rad, nphot is the number of photon candidates accepted for reconstruction track theta ckov
db910db9 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;
5cb4dfc3 125
5cb4dfc3 126
5cb4dfc3 127
db910db9 128 SetThetaCerenkov(-1);
5cb4dfc3 129
84093f6f 130 //
131 // Photon Flag: Flag = 0 initial set; Flag = 1 good candidate (charge compatible with photon); Flag = 2 photon used for the ring;
132 //
133
db910db9 134 for (Int_t iClu=0; iClu<fClusters->GetEntriesFast();iClu++){//clusters loop
aad5d262 135 if(iClu == nphot) continue; // do not consider MIP cluster as a photon candidate
db910db9 136 SetPhotonIndex(iClu);
998b831f 137 SetPhotonFlag(0);
138 SetPhotonEta(-999.);
139 SetPhotonWeight(0.);
db910db9 140 AliRICHCluster *pClu=(AliRICHCluster*)fClusters->UncheckedAt(iClu); //get pointer to current cluster
84093f6f 141 if(pClu->Q()>AliRICHParam::QthMIP()) continue; //avoid MIP clusters from bkg
db910db9 142 SetEntranceX(pClu->X() - GetShiftX()); SetEntranceY(pClu->Y() - GetShiftY()); //cluster position with respect to track intersection
998b831f 143 FindPhiPoint();
84093f6f 144 SetPhotonFlag(1);
998b831f 145 FindThetaPhotonCerenkov();
146 Float_t thetaPhotonCerenkov = GetThetaPhotonCerenkov();
db910db9 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 ));
998b831f 149 SetPhotonEta(thetaPhotonCerenkov);
998b831f 150 }//clusters loop
5cb4dfc3 151
db910db9 152 SetPhotonsNumber(fClusters->GetEntries());
998b831f 153
aad5d262 154 if((nphot=FlagPhotons(HoughResponse()))<1) return -11; //flag photons according to individual theta ckov with respect to most probable track theta ckov
5cb4dfc3 155
5cb4dfc3 156
101624cd 157// Float_t thetaCerenkov = GetThetaCerenkov();
158// SetThetaOfRing(thetaCerenkov);
998b831f 159// FindAreaAndPortionOfRing();
5cb4dfc3 160
998b831f 161// Float_t nPhotonHoughNorm = ((Float_t)nPhotonHough)/GetPortionOfRing();
162// SetHoughPhotonsNorm(nPhotonHoughNorm);
5cb4dfc3 163
164 // Calculate the area where the photon are accepted...
998b831f 165/*
88dd9ad4 166 Float_t thetaInternal = thetaCerenkov - 0.5*fWindowWidth;
167 SetThetaOfRing(thetaInternal);
5cb4dfc3 168 FindAreaAndPortionOfRing();
88dd9ad4 169 Float_t internalArea = GetAreaOfRing();
5cb4dfc3 170
88dd9ad4 171 Float_t thetaExternal = thetaCerenkov + 0.5*fWindowWidth;
172 SetThetaOfRing(thetaExternal);
5cb4dfc3 173 FindAreaAndPortionOfRing();
88dd9ad4 174 Float_t externalArea = GetAreaOfRing();
5cb4dfc3 175
88dd9ad4 176 Float_t houghArea = externalArea - internalArea;
5cb4dfc3 177
88dd9ad4 178 SetHoughArea(houghArea);
998b831f 179*/
db910db9 180 FindThetaCerenkov();
998b831f 181 return GetThetaCerenkov();
998b831f 182}//ThetaCerenkov()
183//__________________________________________________________________________________________________
5cb4dfc3 184Int_t AliRICHRecon::PhotonInBand()
185{
db910db9 186// Define valid band for photon candidates. For that photons with ThetaMin and ThetaMax are traced up to photcathode
5cb4dfc3 187
5cb4dfc3 188 Float_t nfreon;
189
190 Float_t thetacer;
191
88dd9ad4 192 Float_t xtoentr = GetEntranceX();
193 Float_t ytoentr = GetEntranceY();
5cb4dfc3 194
88dd9ad4 195 Float_t innerRadius;
196 Float_t outerRadius;
5cb4dfc3 197
198 Float_t phpad = GetPhiPoint();
199
5cb4dfc3 200
201 // inner radius //
db910db9 202 SetEmissionPoint(AliRICHParam::RadThick() -0.0001);
5cb4dfc3 203
db910db9 204 nfreon = fParam->IdxC6F14(fParam->EckovMin());
5cb4dfc3 205 thetacer = 0.;
206
998b831f 207 AliDebug(1,Form("thetacer in photoninband min %f",thetacer));
5cb4dfc3 208
209 FindThetaAtQuartz(thetacer);
210
db910db9 211 if(thetacer == 999. || GetThetaAtQuartz() == 999.) {
88dd9ad4 212 innerRadius = -999.;
5cb4dfc3 213 SetXInnerRing(-999.);
214 SetYInnerRing(-999.);
215 SetRadiusInnerRing(-999.);
216 }
217 else
218 {
219 SetThetaPhotonInDRS(GetThetaAtQuartz());
220 SetPhiPhotonInDRS(phpad);
221
88dd9ad4 222 innerRadius = FromEmissionToCathode();
223 if(innerRadius == 999.) innerRadius = -999.;
5cb4dfc3 224
225 SetXInnerRing(GetXPointOnCathode());
226 SetYInnerRing(GetYPointOnCathode());
88dd9ad4 227 SetRadiusInnerRing(innerRadius);
5cb4dfc3 228 }
229
230 // outer radius //
5cb4dfc3 231 SetEmissionPoint(0.);
232// SetMassHypotesis(0.139567);
5cb4dfc3 233
db910db9 234 nfreon = fParam->IdxC6F14(fParam->EckovMax());
5cb4dfc3 235
998b831f 236 thetacer = Cerenkovangle(nfreon,1);
5cb4dfc3 237
238 // thetacer = 0.75;
239
998b831f 240 AliDebug(1,Form("thetacer in photoninband max %f",thetacer));
5cb4dfc3 241
242 FindThetaAtQuartz(thetacer);
243
244 if(thetacer == 999. || GetThetaAtQuartz() == 999.)
245 {
88dd9ad4 246 outerRadius = 999.;
5cb4dfc3 247 SetXOuterRing(999.);
248 SetYOuterRing(999.);
249 SetRadiusOuterRing(999.);
250 }
251 else
252 {
253 SetThetaPhotonInDRS(GetThetaAtQuartz());
254 SetPhiPhotonInDRS(phpad);
255
88dd9ad4 256 outerRadius = FromEmissionToCathode();
257// cout << " outerRadius " << outerRadius << endl;
5cb4dfc3 258 SetXOuterRing(GetXPointOnCathode());
259 SetYOuterRing(GetYPointOnCathode());
88dd9ad4 260 SetRadiusOuterRing(outerRadius);
5cb4dfc3 261 }
262
88dd9ad4 263 Float_t padradius = sqrt(TMath::Power(xtoentr,2)+TMath::Power(ytoentr,2));
5cb4dfc3 264
998b831f 265 AliDebug(1,Form("rmin %f r %f rmax %f",innerRadius,padradius,outerRadius));
5cb4dfc3 266
88dd9ad4 267 if(padradius>=innerRadius && padradius<=outerRadius) return 1;
5cb4dfc3 268 return 0;
db910db9 269}//PhotonInBand()
101624cd 270//__________________________________________________________________________________________________
88dd9ad4 271void AliRICHRecon::FindThetaAtQuartz(Float_t thetaCerenkov)
5cb4dfc3 272{
db910db9 273// find the theta at the quartz plate
5cb4dfc3 274
db910db9 275 if(thetaCerenkov == 999.) { SetThetaAtQuartz(999.); return; }
5cb4dfc3 276
88dd9ad4 277 Float_t thetaAtQuartz = 999.;
5cb4dfc3 278
88dd9ad4 279 Float_t trackTheta = GetTrackTheta();
5cb4dfc3 280
88dd9ad4 281 if(trackTheta == 0) {
88dd9ad4 282 thetaAtQuartz = thetaCerenkov;
283 SetThetaAtQuartz(thetaAtQuartz);
5cb4dfc3 284 return;
285 }
286
88dd9ad4 287 Float_t trackPhi = GetTrackPhi();
288 Float_t phiPoint = GetPhiPoint();
5cb4dfc3 289
db910db9 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);
88dd9ad4 292 Double_t b = TMath::Cos((Double_t)trackTheta)/den;
293 Double_t c = -TMath::Cos((Double_t)thetaCerenkov)/den;
5cb4dfc3 294
88dd9ad4 295 Double_t underSqrt = 1 + b*b - c*c;
5cb4dfc3 296
88dd9ad4 297 if(underSqrt < 0) {
5cb4dfc3 298 SetThetaAtQuartz(999.);
299 return;
300 }
301
88dd9ad4 302 Double_t sol1 = (1+TMath::Sqrt(underSqrt))/(b-c);
303 Double_t sol2 = (1-TMath::Sqrt(underSqrt))/(b-c);
5cb4dfc3 304
88dd9ad4 305 Double_t thetaSol1 = 2*TMath::ATan(sol1);
306 Double_t thetaSol2 = 2*TMath::ATan(sol2);
5cb4dfc3 307
88dd9ad4 308 if(thetaSol1>0 && thetaSol1 < TMath::Pi()) thetaAtQuartz = (Float_t)thetaSol1;
309 if(thetaSol2>0 && thetaSol2 < TMath::Pi()) thetaAtQuartz = (Float_t)thetaSol2;
5cb4dfc3 310
998b831f 311// AliDebug(1,Form(" Theta @ quartz window %f ",thetaAtQuartz));
312
88dd9ad4 313 SetThetaAtQuartz(thetaAtQuartz);
5cb4dfc3 314}
101624cd 315//__________________________________________________________________________________________________
5cb4dfc3 316void AliRICHRecon::FindThetaPhotonCerenkov()
317{
88dd9ad4 318 //find theta cerenkov of ring
5cb4dfc3 319
88dd9ad4 320 Float_t thetaCerMin = 0.;
321 Float_t thetaCerMax = 0.75;
322 Float_t thetaCerMean;
5cb4dfc3 323
88dd9ad4 324 Float_t radiusMin, radiusMax, radiusMean;
5cb4dfc3 325 Int_t nIteration = 0;
326
88dd9ad4 327 const Float_t kTollerance = 0.05;
5cb4dfc3 328
5cb4dfc3 329
88dd9ad4 330 Float_t phiPoint = GetPhiPoint();
5cb4dfc3 331
db910db9 332 SetEmissionPoint(AliRICHParam::RadThick()/2);
5cb4dfc3 333
88dd9ad4 334 Float_t xPoint = GetEntranceX();
335 Float_t yPoint = GetEntranceY();
998b831f 336 Float_t distPoint = TMath::Sqrt(xPoint*xPoint + yPoint*yPoint);
5cb4dfc3 337
101624cd 338// AliDebug(1,Form(" DistPoint %f ",distPoint));
5cb4dfc3 339
340 // Star minimization...
341
342 // First value...
343
88dd9ad4 344 FindThetaAtQuartz(thetaCerMin);
5cb4dfc3 345
346 if(GetThetaAtQuartz() == 999.)
347 {
88dd9ad4 348 radiusMin = -999.;
5cb4dfc3 349 }
350 else
351 {
352 SetThetaPhotonInDRS(GetThetaAtQuartz());
88dd9ad4 353 SetPhiPhotonInDRS(phiPoint);
5cb4dfc3 354
88dd9ad4 355 radiusMin = FromEmissionToCathode();
5cb4dfc3 356 }
357
358 // Second value...
359
88dd9ad4 360 FindThetaAtQuartz(thetaCerMax);
5cb4dfc3 361 if(GetThetaAtQuartz() == 999.)
362 {
88dd9ad4 363 radiusMax = 999.;
5cb4dfc3 364 }
365 else
366 {
367 SetThetaPhotonInDRS(GetThetaAtQuartz());
88dd9ad4 368 SetPhiPhotonInDRS(phiPoint);
5cb4dfc3 369
88dd9ad4 370 radiusMax = FromEmissionToCathode();
5cb4dfc3 371 }
372 // Mean value...
373
88dd9ad4 374 thetaCerMean = (thetaCerMax + thetaCerMin)/2;
5cb4dfc3 375
88dd9ad4 376 FindThetaAtQuartz(thetaCerMean);
5cb4dfc3 377 if(GetThetaAtQuartz() == 999.)
378 {
88dd9ad4 379 radiusMean = 999.;
5cb4dfc3 380 }
381 else
382 {
383 SetThetaPhotonInDRS(GetThetaAtQuartz());
88dd9ad4 384 SetPhiPhotonInDRS(phiPoint);
5cb4dfc3 385
88dd9ad4 386 radiusMean = FromEmissionToCathode();
5cb4dfc3 387 }
388
101624cd 389// AliDebug(1,Form(" r1 %f rmean %f r2 %f",radiusMin,radiusMean,radiusMax));
5cb4dfc3 390
88dd9ad4 391 while (TMath::Abs(radiusMean-distPoint) > kTollerance)
5cb4dfc3 392 {
393
88dd9ad4 394 if((radiusMin-distPoint)*(radiusMean-distPoint) < 0) thetaCerMax = thetaCerMean;
395 if((radiusMin-distPoint)*(radiusMean-distPoint) > 0) {
5cb4dfc3 396
88dd9ad4 397 thetaCerMin = thetaCerMean;
5cb4dfc3 398
88dd9ad4 399 FindThetaAtQuartz(thetaCerMin);
5cb4dfc3 400 SetThetaPhotonInDRS(GetThetaAtQuartz());
88dd9ad4 401 SetPhiPhotonInDRS(phiPoint);
5cb4dfc3 402
88dd9ad4 403 radiusMin =FromEmissionToCathode();
5cb4dfc3 404 }
405
88dd9ad4 406 thetaCerMean = (thetaCerMax + thetaCerMin)/2;
5cb4dfc3 407
88dd9ad4 408 FindThetaAtQuartz(thetaCerMean);
5cb4dfc3 409 SetThetaPhotonInDRS(GetThetaAtQuartz());
88dd9ad4 410 SetPhiPhotonInDRS(phiPoint);
5cb4dfc3 411
88dd9ad4 412 radiusMean = FromEmissionToCathode();
5cb4dfc3 413
414 nIteration++;
415 if(nIteration>=50) {
d0831219 416// AliDebug(1,Form(" max iterations in FindPhotonCerenkov ",nIteration));
5cb4dfc3 417 SetThetaPhotonCerenkov(999.);
418 return;
419 }
420 }
421
101624cd 422// AliDebug(1,Form(" distpoint %f radius %f ",distPoint,radiusMean));
88dd9ad4 423 SetThetaPhotonCerenkov(thetaCerMean);
5cb4dfc3 424
425}
101624cd 426//__________________________________________________________________________________________________
5cb4dfc3 427void AliRICHRecon::FindAreaAndPortionOfRing()
428{
88dd9ad4 429 //find fraction of the ring accepted by the RICH
5cb4dfc3 430
88dd9ad4 431 Float_t xPoint[NPointsOfRing], yPoint[NPointsOfRing];
5cb4dfc3 432
88dd9ad4 433 // Float_t xtoentr = GetEntranceX();
434 // Float_t ytoentr = GetEntranceY();
435 Float_t shiftX = GetShiftX();
436 Float_t shiftY = GetShiftY();
5cb4dfc3 437
88dd9ad4 438 Float_t xemiss = GetXCoordOfEmission();
439 Float_t yemiss = GetYCoordOfEmission();
5cb4dfc3 440
88dd9ad4 441 Float_t x0 = xemiss + shiftX;
442 Float_t y0 = yemiss + shiftY;
5cb4dfc3 443
5cb4dfc3 444
5cb4dfc3 445
db910db9 446 SetEmissionPoint(AliRICHParam::RadThick()/2.);
5cb4dfc3 447
88dd9ad4 448 Float_t theta = GetThetaOfRing();
5cb4dfc3 449
450 Int_t nPoints = 0;
88dd9ad4 451 Int_t nPsiAccepted = 0;
452 Int_t nPsiTotal = 0;
5cb4dfc3 453
db910db9 454 for(Int_t i=0;i<NPointsOfRing-1;i++){
88dd9ad4 455 Float_t psi = 2*TMath::Pi()*i/NPointsOfRing;
5cb4dfc3 456
88dd9ad4 457 SetThetaPhotonInTRS(theta);
458 SetPhiPhotonInTRS(psi);
5cb4dfc3 459 FindPhotonAnglesInDRS();
460
88dd9ad4 461 Float_t radius = FromEmissionToCathode();
462 if (radius == 999.) continue;
5cb4dfc3 463
88dd9ad4 464 nPsiTotal++;
5cb4dfc3 465
88dd9ad4 466 Float_t xPointRing = GetXPointOnCathode() + shiftX;
467 Float_t yPointRing = GetYPointOnCathode() + shiftY;
5cb4dfc3 468
88dd9ad4 469 SetDetectorWhereX(xPointRing);
470 SetDetectorWhereY(yPointRing);
5cb4dfc3 471
88dd9ad4 472 Int_t zone = CheckDetectorAcceptance();
5cb4dfc3 473
910735ae 474 AliDebug(1,Form("acceptance to detector zone -> %d",zone));
5cb4dfc3 475
db910db9 476 if (zone != 0){
477 FindIntersectionWithDetector();
478 xPoint[nPoints] = GetIntersectionX(); yPoint[nPoints] = GetIntersectionY();
479 }else{
480 xPoint[nPoints] = xPointRing; yPoint[nPoints] = yPointRing;
481 nPsiAccepted++;
482 }
5cb4dfc3 483 nPoints++;
db910db9 484 }
5cb4dfc3 485
db910db9 486 xPoint[nPoints] = xPoint[0]; yPoint[nPoints] = yPoint[0];
5cb4dfc3 487
488 // find area...
489
88dd9ad4 490 Float_t area = 0;
5cb4dfc3 491
492 for (Int_t i = 0; i < nPoints; i++)
493 {
88dd9ad4 494 area += TMath::Abs((xPoint[i]-x0)*(yPoint[i+1]-y0) - (xPoint[i+1]-x0)*(yPoint[i]-y0));
5cb4dfc3 495 }
496
88dd9ad4 497 area *= 0.5;
5cb4dfc3 498
adcdf4dd 499 Float_t portionOfRing = 0;
500 if (nPsiTotal>0)
501 portionOfRing = ((Float_t)nPsiAccepted)/((Float_t)(nPsiTotal));
5cb4dfc3 502
5cb4dfc3 503
88dd9ad4 504 SetAreaOfRing(area);
505 SetPortionOfRing(portionOfRing);
db910db9 506}//FindAreaAndPortionOfRing()
101624cd 507//__________________________________________________________________________________________________
5cb4dfc3 508void AliRICHRecon::FindIntersectionWithDetector()
509{
88dd9ad4 510 // find ring intersection with CsI edges
5cb4dfc3 511
88dd9ad4 512 Float_t xIntersect, yIntersect;
5cb4dfc3 513 Float_t x1, x2, y1, y2;
514
88dd9ad4 515 Float_t shiftX = GetShiftX();
516 Float_t shiftY = GetShiftY();
5cb4dfc3 517
88dd9ad4 518 Float_t xPoint = GetXPointOnCathode() + shiftX;
519 Float_t yPoint = GetYPointOnCathode() + shiftY;
5cb4dfc3 520
88dd9ad4 521 Float_t xemiss = GetXCoordOfEmission();
522 Float_t yemiss = GetYCoordOfEmission();
5cb4dfc3 523
88dd9ad4 524 Float_t phi = GetPhiPhotonInDRS();
525 Float_t m = tan(phi);
5cb4dfc3 526
88dd9ad4 527 Float_t x0 = xemiss + shiftX;
528 Float_t y0 = yemiss + shiftY;
5cb4dfc3 529
88dd9ad4 530 if(xPoint > x0)
5cb4dfc3 531 {
532 x1 = x0;
88dd9ad4 533 x2 = xPoint;
5cb4dfc3 534 }
535 else
536 {
537 x2 = x0;
88dd9ad4 538 x1 = xPoint;
5cb4dfc3 539 }
88dd9ad4 540 if(yPoint > y0)
5cb4dfc3 541 {
542 y1 = y0;
88dd9ad4 543 y2 = yPoint;
5cb4dfc3 544 }
545 else
546 {
547 y2 = y0;
88dd9ad4 548 y1 = yPoint;
5cb4dfc3 549 }
550 //
db910db9 551 xIntersect = AliRICHParam::PcSizeX();
88dd9ad4 552 yIntersect = m*(xIntersect - x0) + y0;
db910db9 553 if (yIntersect >= 0 && yIntersect <= AliRICHParam::PcSizeY() && xIntersect >= x1 && xIntersect <= x2)
5cb4dfc3 554 {
88dd9ad4 555 SetIntersectionX(xIntersect);
556 SetIntersectionY(yIntersect);
5cb4dfc3 557 return;
558 }
559 //
db910db9 560 xIntersect = 0;
88dd9ad4 561 yIntersect = m*(xIntersect - x0) + y0;
db910db9 562 if (yIntersect >= 0 && yIntersect <= AliRICHParam::PcSizeY() && xIntersect >= x1 && xIntersect <= x2)
5cb4dfc3 563 {
88dd9ad4 564 SetIntersectionX(xIntersect);
565 SetIntersectionY(yIntersect);
5cb4dfc3 566 return;
567 }
568 //
db910db9 569 yIntersect = AliRICHParam::PcSizeY();
88dd9ad4 570 xIntersect = (yIntersect - y0)/m + x0;
db910db9 571 if (xIntersect >= 0 && xIntersect <= AliRICHParam::PcSizeX() && yIntersect >= y1 && yIntersect <= y2)
5cb4dfc3 572 {
88dd9ad4 573 SetIntersectionX(xIntersect);
574 SetIntersectionY(yIntersect);
5cb4dfc3 575 return;
576 }
577 //
db910db9 578 yIntersect = 0;
88dd9ad4 579 xIntersect = (yIntersect - y0)/m + x0;
db910db9 580 if (xIntersect >= 0 && xIntersect <= AliRICHParam::PcSizeX() && yIntersect >= y1 && yIntersect <= y2)
5cb4dfc3 581 {
88dd9ad4 582 SetIntersectionX(xIntersect);
583 SetIntersectionY(yIntersect);
5cb4dfc3 584 return;
585 }
5cb4dfc3 586}
db910db9 587
b068561d 588//__________________________________________________________________________________________________
88dd9ad4 589Int_t AliRICHRecon::CheckDetectorAcceptance() const
5cb4dfc3 590{
88dd9ad4 591 // check for the acceptance
5cb4dfc3 592
593 // crosses X -2.6 2.6 cm
594 // crosses Y -1 1 cm
595
88dd9ad4 596 Float_t xcoord = GetDetectorWhereX();
597 Float_t ycoord = GetDetectorWhereY();
5cb4dfc3 598
db910db9 599 if(xcoord > AliRICHParam::PcSizeX())
5cb4dfc3 600 {
db910db9 601 if(ycoord > AliRICHParam::PcSizeY()) return 2;
602 if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 3;
603 if(ycoord < 0) return 4;
5cb4dfc3 604 }
db910db9 605 if(xcoord < 0)
5cb4dfc3 606 {
db910db9 607 if(ycoord > AliRICHParam::PcSizeY()) return 8;
608 if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 7;
609 if(ycoord < 0) return 6;
5cb4dfc3 610 }
db910db9 611 if(xcoord > 0 && xcoord < AliRICHParam::PcSizeX())
5cb4dfc3 612 {
db910db9 613 if(ycoord > AliRICHParam::PcSizeY()) return 1;
614 if(ycoord > 0 && ycoord < AliRICHParam::PcSizeY()) return 0;
615 if(ycoord < 0) return 5;
5cb4dfc3 616 }
617 return 999;
618}
b068561d 619//__________________________________________________________________________________________________
5cb4dfc3 620void AliRICHRecon::FindPhotonAnglesInDRS()
621{
622 // Setup the rotation matrix of the track...
623
88dd9ad4 624 TRotation mtheta;
625 TRotation mphi;
626 TRotation minv;
627 TRotation mrot;
5cb4dfc3 628
88dd9ad4 629 Float_t trackTheta = GetTrackTheta();
630 Float_t trackPhi = GetTrackPhi();
5cb4dfc3 631
88dd9ad4 632 mtheta.RotateY(trackTheta);
633 mphi.RotateZ(trackPhi);
5cb4dfc3 634
88dd9ad4 635 mrot = mphi * mtheta;
636 // minv = mrot.Inverse();
5cb4dfc3 637
88dd9ad4 638 TVector3 photonInRadiator(1,1,1);
5cb4dfc3 639
88dd9ad4 640 Float_t thetaCerenkov = GetThetaPhotonInTRS();
641 Float_t phiCerenkov = GetPhiPhotonInTRS();
5cb4dfc3 642
88dd9ad4 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);
5cb4dfc3 650
651}
101624cd 652//__________________________________________________________________________________________________
5cb4dfc3 653Float_t AliRICHRecon::FromEmissionToCathode()
654{
db910db9 655// Trace current photon from emission point somewhere in radiator to photocathode
656// Arguments: none
657// Returns:
5cb4dfc3 658
659 Float_t nfreon, nquartz, ngas;
660
84093f6f 661 //fParam->Print();
5cb4dfc3 662
db910db9 663 nfreon = fParam->IdxC6F14(fParam->EckovMean());
664 nquartz = fParam->IdxSiO2(fParam->EckovMean());
665 ngas = fParam->IdxCH4(fParam->EckovMean());
5cb4dfc3 666
88dd9ad4 667 Float_t trackTheta = GetTrackTheta();
668 Float_t trackPhi = GetTrackPhi();
669 Float_t lengthOfEmissionPoint = GetEmissionPoint();
5cb4dfc3 670
88dd9ad4 671 Float_t theta = GetThetaPhotonInDRS();
672 Float_t phi = GetPhiPhotonInDRS();
5cb4dfc3 673
88dd9ad4 674 Float_t xemiss = lengthOfEmissionPoint*tan(trackTheta)*cos(trackPhi);
675 Float_t yemiss = lengthOfEmissionPoint*tan(trackTheta)*sin(trackPhi);
5cb4dfc3 676
88dd9ad4 677 SetXCoordOfEmission(xemiss);
678 SetYCoordOfEmission(yemiss);
5cb4dfc3 679
88dd9ad4 680 Float_t thetaquar = SnellAngle(nfreon, nquartz, theta);
5cb4dfc3 681
682 if(thetaquar == 999.)
683 {
684 SetXPointOnCathode(999.);
685 SetYPointOnCathode(999.);
686 return thetaquar;
687 }
688
689 Float_t thetagap = SnellAngle( nquartz, ngas, thetaquar);
690
691 if(thetagap == 999.)
692 {
693 SetXPointOnCathode(999.);
694 SetYPointOnCathode(999.);
695 return thetagap;
696 }
697
db910db9 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);
5cb4dfc3 704
5cb4dfc3 705
88dd9ad4 706 Float_t xtot = xemiss + xw + xq + xg;
707 Float_t ytot = yemiss + yw + yq + yg;
5cb4dfc3 708
709 SetXPointOnCathode(xtot);
710 SetYPointOnCathode(ytot);
711
5cb4dfc3 712
db910db9 713 Float_t distanceFromEntrance = TMath::Sqrt(TMath::Power(fPhotonLimitX,2)+TMath::Power(fPhotonLimitY,2));
5cb4dfc3 714
88dd9ad4 715 return distanceFromEntrance;
5cb4dfc3 716
717}
101624cd 718//__________________________________________________________________________________________________
5cb4dfc3 719void AliRICHRecon::FindPhiPoint()
720{
88dd9ad4 721 //find phi of generated point
5cb4dfc3 722
88dd9ad4 723 Float_t xtoentr = GetEntranceX();
724 Float_t ytoentr = GetEntranceY();
5cb4dfc3 725
88dd9ad4 726 Float_t trackTheta = GetTrackTheta();
727 Float_t trackPhi = GetTrackPhi();
5cb4dfc3 728
88dd9ad4 729 Float_t emissionPoint = GetEmissionPoint();
5cb4dfc3 730
88dd9ad4 731 Float_t argY = ytoentr - emissionPoint*tan(trackTheta)*sin(trackPhi);
732 Float_t argX = xtoentr - emissionPoint*tan(trackTheta)*cos(trackPhi);
101624cd 733 Float_t phi = atan2(argY,argX);
5cb4dfc3 734
998b831f 735 SetPhiPoint(phi);
5cb4dfc3 736
737}
101624cd 738//__________________________________________________________________________________________________
5cb4dfc3 739Float_t AliRICHRecon::Cerenkovangle(Float_t n, Float_t beta)
740{
88dd9ad4 741 // cerenkov angle from n and beta
5cb4dfc3 742
743// Compute the cerenkov angle
744
745 Float_t thetacer;
746
747 if((n*beta)<1.) {
748 thetacer = 999.;
749 // cout << " warning in Cerenkoangle !!!!!! " << endl;
750 return thetacer;
751 }
752
753 thetacer = acos (1./(n*beta));
754 return thetacer;
755}
101624cd 756//__________________________________________________________________________________________________
5cb4dfc3 757Float_t AliRICHRecon::SnellAngle(Float_t n1, Float_t n2, Float_t theta1)
88dd9ad4 758{
759 // Snell law
5cb4dfc3 760
761// Compute the Snell angle
762
763 Float_t sinrefractangle;
764 Float_t refractangle;
765
766 sinrefractangle = (n1/n2)*sin(theta1);
767
768 if(sinrefractangle>1.) {
769 // cout << " PROBLEMS IN SNELL ANGLE !!!!! " << endl;
770 refractangle = 999.;
771 return refractangle;
772 }
773
774 refractangle = asin(sinrefractangle);
775 return refractangle;
776}
101624cd 777//__________________________________________________________________________________________________
db910db9 778Double_t AliRICHRecon::HoughResponse()
88dd9ad4 779{
db910db9 780//
781//
782//
fab9e039 783 Int_t nChannels = (Int_t)(fThetaMax/fDTheta+0.5);
db910db9 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);
910735ae 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()));
db910db9 790 for (Int_t kPhot=0; kPhot< GetPhotonsNumber(); kPhot++){
910735ae 791 SetPhotonIndex(kPhot);
792 Double_t angle = GetPhotonEta();
fab9e039 793 if(angle<0||angle>fThetaMax) continue;
910735ae 794 phots->Fill(angle);
795 Int_t bin = (Int_t)(0.5+angle/(fDTheta));
796 Double_t weight=1.;
797 if(fIsWEIGHT){
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.;}
809 }
fab9e039 810 AliDebug(1,Form("Calculated weight %f",weight));
910735ae 811 photsw->Fill(angle,weight);
812 SetPhotonWeight(weight);
813 }
814 for (Int_t i=1; i<=nBin;i++){
815 Int_t bin1= i-nCorrBand;
816 Int_t bin2= i+nCorrBand;
817 if(bin1<1) bin1=1;
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);
fab9e039 822 resultw->Fill((Float_t)((i+0.5)*fDTheta),sumPhotsw);
db910db9 823 }
824// evaluate the "BEST" theta ckov as the maximum value of histogramm
910735ae 825 Float_t *pVec = resultw->GetArray();
826 Int_t locMax = TMath::LocMax(nBin,pVec);
db910db9 827 phots->Delete();photsw->Delete();resultw->Delete(); // Reset and delete objects
828
829 return (Double_t)(locMax*fDTheta+0.5*fDTheta); //final most probable track theta ckov
910735ae 830}//HoughResponse
101624cd 831//__________________________________________________________________________________________________
832void AliRICHRecon::FindThetaCerenkov()
5cb4dfc3 833{
84093f6f 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)
836// Arguments: none
837// Return: none
5cb4dfc3 838
839 Float_t wei = 0.;
88dd9ad4 840 Float_t weightThetaCerenkov = 0.;
5cb4dfc3 841
fab9e039 842 Double_t etaMin=9999.,etaMax=0.;
84093f6f 843 Double_t sigma2 = 0; //to collect error squared for this ring
844
db910db9 845 for(Int_t i=0;i<GetPhotonsNumber();i++){
846 SetPhotonIndex(i);
847 if(GetPhotonFlag() == 2){
84093f6f 848 Float_t photonEta = GetPhotonEta();
db910db9 849 if(photonEta<etaMin) etaMin=photonEta;
850 if(photonEta>etaMax) etaMax=photonEta;
84093f6f 851 Float_t photonWeight = GetPhotonWeight();
852 weightThetaCerenkov += photonEta*photonWeight;
853 wei += photonWeight;
854 //here comes sigma of the reconstructed ring
855
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();
860
861 Double_t beta = 1./(TMath::Cos(GetPhotonEta())*fParam->IdxC6F14(AliRICHParam::EckovMean()));
862 sigma2 += 1./AliRICHParam::SigmaSinglePhotonFormula(GetPhotonEta(),GetPhiPoint(),GetTrackTheta(),phiref,beta);
863 }
db910db9 864 }
84093f6f 865
866 if(sigma2>0) SetRingSigma2(1./sigma2);
867 else SetRingSigma2(1e10);
868
fab9e039 869 if(wei != 0.) weightThetaCerenkov /= wei; else weightThetaCerenkov = 0.;
88dd9ad4 870 SetThetaCerenkov(weightThetaCerenkov);
5cb4dfc3 871
fab9e039 872 // estimate of the n. of bkg photons
873 SetThetaOfRing(etaMin); FindAreaAndPortionOfRing(); Double_t internalArea = GetAreaOfRing();
874 SetThetaOfRing(etaMax); FindAreaAndPortionOfRing(); Double_t externalArea = GetAreaOfRing();
875
876 Double_t effArea = (AliRICHParam::PcSizeX()-AliRICHParam::DeadZone())*(AliRICHParam::PcSizeY()-2*AliRICHParam::DeadZone());
db910db9 877 Double_t nPhotBKG = (externalArea-internalArea)/effArea*fClusters->GetEntries();
fab9e039 878 if(nPhotBKG<0) nPhotBKG=0; //just protection from funny angles...
879 SetPhotBKG(nPhotBKG);
fab9e039 880
101624cd 881 AliDebug(1,Form(" thetac weighted -> %f",weightThetaCerenkov));
5cb4dfc3 882}
db910db9 883//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
884Int_t AliRICHRecon::FlagPhotons(Double_t thetaCkovHough)
5cb4dfc3 885{
db910db9 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
5cb4dfc3 889
db910db9 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
5cb4dfc3 891
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);
895
db910db9 896 tmin = tavg - 0.5*fWindowWidth; tmax = tavg + 0.5*fWindowWidth;
5cb4dfc3 897
db910db9 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;
84093f6f 902 if(photonEta >= tmin && photonEta <= tmax) {
903 SetPhotonFlag(2);
904 iInsideCnt++;
905 }
db910db9 906 }
907 return iInsideCnt;
908}//FlagPhotons