EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CbmRichHitProducer.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file CbmRichHitProducer.cxx
1 
7 #include "CbmRichHitProducer.h"
8 
9 #include "CbmRichPoint.h"
10 #include "CbmRichHit.h"
11 #include "CbmGeoRichPar.h"
12 
13 #include "FairRootManager.h"
14 #include "CbmMCTrack.h"
15 #include "FairRunAna.h"
16 #include "FairRuntimeDb.h"
17 #include "FairBaseParSet.h"
18 #include "FairGeoVolume.h"
19 #include "FairGeoTransform.h"
20 #include "FairGeoVector.h"
21 #include "FairGeoMedium.h"
22 #include "FairGeoNode.h"
23 
24 #include "TVector3.h"
25 #include "TRandom.h"
26 #include "TFormula.h"
27 #include "TString.h"
28 #include "TClonesArray.h"
29 
30 #include <iostream>
31 
32 using std::cout;
33 using std::endl;
34 
36  FairTask("CbmRichHitProducer"),
37  fRichPoints(NULL),
38  fRichHits(NULL),
39  //fMcTracks(NULL),
40  fNHits(0),
41  fNDoubleHits(0),
42 
43  fNRefrac(0.),
44  fDetection(0),
45  fNEvents(0),
46 
47  fDetX(0.),
48  fDetY(0.),
49  fDetZ(0.),
50  fDetZ_org(0.),
51  fDetWidthX(0.),
52  fDetWidthY(0.),
53 
54  fSensNodes(NULL),
55  fPassNodes(NULL),
56  fPar(NULL),
57 
58  fPhotomulRadius(0.0),
59  fPhotomulDist(0.),
60  fDetType(4),
61  fNofNoiseHits(220),
62  fCollectionEfficiency(1.),
63  fSigmaMirror(0.06),
64 
65  fTheta(0.),
66  fPhi(0.),
67 
68  fCrossTalkHitProb(0.02),
69  fNofCrossTalkHits(0)
70 {
71 
72 }
73 
75 {
77  manager->Write();
78 }
79 
81 {
82  // Get Base Container
84  FairRuntimeDb* rtdb=ana->GetRuntimeDb();
85  fPar = (CbmGeoRichPar*)(rtdb->getContainer("CbmGeoRichPar"));
86  // fPar1=(FairBaseParSet*)(rtdb->getContainer("FairBaseParSet"));
87  // fPar->print();
88 // fPar->setStatic(); // setting the parameters on static mode: <explanation>
89 }
90 
92 {
94 
97  //fSensNodes->ls();
98 
99  // get detector position:
100  FairGeoNode *det= dynamic_cast<FairGeoNode*> (fSensNodes->FindObject("rich1d#1"));
101  if (NULL == det) cout << " -I no RICH Geo Node found !!!!! " << endl;
102  //det->Dump();
103  //det->print();
104  FairGeoTransform* detTr=det->getLabTransform(); // detector position in labsystem
105  FairGeoVector detPosLab=detTr->getTranslation(); // ... in cm
106  FairGeoTransform detCen=det->getCenterPosition(); // center in Detector system
107  FairGeoVector detPosCen=detCen.getTranslation();
108  fDetZ = detPosLab.Z() + detPosCen.Z(); // z coordinate of photodetector (Labsystem, cm)
109  fDetY = detPosLab.Y() + detPosCen.Y(); // y coordinate of photodetector (Labsystem, cm)
110  fDetX = detPosLab.X() + detPosCen.X(); // x coordinate of photodetector (Labsystem, cm)
111 
112  TArrayD *fdetA=det->getParameters(); // get other geometry parameters: width in x, width in y, thickness
113  fDetWidthX = fdetA->At(0);
114  fDetWidthY = fdetA->At(1);
115  for(Int_t i = 0; i < fdetA->GetSize(); i++) cout << "Array detector " << fdetA->At(i)<< endl;
116  FairGeoRotation fdetR=detTr->getRotMatrix();
117  // detector might be rotated by theta around x-axis:
118  if (fVerbose) {
119  cout << "Rotation matrix of photodetector " << endl;
120  for(Int_t i = 0; i < 9; i++) cout << "Rot(" << i << ") = " << fdetR(i) << endl;
121  }
122 
123  // possible tilting around x-axis (theta) and y-axis (phi)
124  // fdetR(0) = cos(phi)
125  // fdetR(1) = 0
126  // fdetR(2) = -sin(phi)
127  // fdetR(3) = -sin(theta)sin(phi)
128  // fdetR(4) = cos(theta)
129  // fdetR(5) = -sin(theta)cos(phi)
130  // fdetR(6) = cos(theta)sin(phi)
131  // fdetR(7) = sin(theta)
132  // fdetR(8) = cos(theta)cos(phi)
133 
134 
135  fTheta = TMath::ASin(fdetR(7)); // tilting angle around x-axis
136  fPhi = -1.*TMath::ASin(fdetR(2)); // tilting angle around y-axis
137 
138  if (fVerbose) cout << "Rich Photodetector was tilted around x by " << fTheta*180./TMath::Pi() << " degrees" << endl;
139  if (fVerbose) cout << "Rich Photodetector was tilted around y by " << fPhi*180./TMath::Pi() << " degrees" << endl;
140 
141  // get refractive index of gas
142  FairGeoNode *gas= dynamic_cast<FairGeoNode*> (fPassNodes->FindObject("rich1gas1"));
143  if (NULL == gas) cout << " -I no RICH Geo Node found !!!!! " << endl;
144  FairGeoMedium* med = gas->getMedium();
145  // med->Dump();
146 
147  Int_t npckov = med->getNpckov();
148  Double_t* cerpar;
149  cerpar=new Double_t[4];
150  if (fVerbose) cout << "Number of optical parameters for Cherenkov " << npckov << endl;
151  med->getCerenkovPar(0,cerpar);
152 
153 // for(Int_t i=0;i<4;i++) {
154 // if (i==0) cout << " photon energy " << cerpar[0] << endl;
155 // if (i==1) cout << " absorption lenght" << cerpar[1] << endl;
156 // if (i==2) cout << " detection efficiency " << cerpar[2] << endl;
157 // if (i==3) cout << " refractive index (n-1)*10000 " << (cerpar[3]-1.)*10000. << endl;
158 // }
159 
160  fNRefrac = cerpar[3];
161  delete cerpar;
162  if (fVerbose) cout << " refractive index for lowest photon energies (n-1)*10000 " << (fNRefrac-1.0)*10000.0 << endl;
163 
164  // transform nominal detector position (for tilted photodetector), x>0, y>0:
165  Double_t fDetY_org, fDetX_org;
166  fDetZ_org = fDetZ;
167  fDetY_org = fDetY;
168  fDetX_org = fDetX;
169  fDetX = fDetX_org*TMath::Cos(fPhi)+fDetZ_org*TMath::Sin(fPhi);
170  fDetY = -fDetX_org*TMath::Sin(fTheta)*TMath::Sin(fPhi) + fDetY_org*TMath::Cos(fTheta) + fDetZ_org*TMath::Sin(fTheta)*TMath::Cos(fPhi);
171  fDetZ = -fDetX_org*TMath::Cos(fTheta)*TMath::Sin(fPhi) - fDetY_org*TMath::Sin(fTheta) + fDetZ_org*TMath::Cos(fTheta)*TMath::Cos(fPhi);
172 
173  if (fVerbose > 0) {
174  cout << "---------------------- RICH Hit Producer ---------------------------------------" << endl;
175  cout << " detector position in (x,y,z) [cm]: " << fDetX << " " << fDetY_org << " " << fDetZ_org << endl;
176  cout << " tilted detector position in (x,y,z) [cm]: " << fDetX << " " << fDetY << " " << fDetZ << endl;
177  cout << " detector size in x and y [cm]: " << fDetWidthX << " " << fDetWidthY << endl;
178  if (fDetType==0)
179  cout << " ideal detector " << endl;
180  if (fDetType==1)
181  cout << " detector type: Protvino PMT with PMT radius = " << fPhotomulRadius << " cm, distance between PMTs = " << fPhotomulDist << " cm" << endl;
182  if (fDetType==3)
183  cout << " detector type: CSI with pad size = " << fPhotomulRadius << " cm, distance between panels = " << fPhotomulDist << " cm" << endl;
184  if (fDetType==2 || fDetType == 4 || fDetType == 5 || fDetType == 6)
185  cout << " detector type: Hamamatsu H8500 with pad size = " << fPhotomulRadius << " cm, distance between elements = " << fPhotomulDist << " cm" << endl;
186  cout << " number of noise hits (to be reduced by geometrical efficiency) " << fNofNoiseHits << endl;
187  cout << "--------------------------------------------------------------------------------" << endl;
188  }
189 
190  //------------- example for getting more parameters from the data base: -------------------
191 /*
192  // 1) get and print medium
193  FairGeoMedium* med = det->getMedium();
194  med->Dump();
195 
196  // 2) retrieve relevant parameter
197  // Shape
198  Int_t npoints = det->getNumPoints();
199  Double_t para[npoints][3];
200  TString shapeName = det->getShape();
201  for (Int_t i=0;i<npoints;i++) {
202  for (Int_t j=0;j<3; j++){
203  para[i][j] = det->getVolParameter(i,j);
204  cout << "i: " << i << "j: " << j << "par: " << para[i][j] << endl;
205  }
206  }
207 
208  // 3) Lab Transform
209  FairGeoTransform* transf = det->getLabTransform();
210  FairGeoRotation rot = transf->getRotMatrix();
211  FairGeoVector trans = transf->getTransVector();
212 
213  Double_t rotp[9];
214  cout << " Lab rotation : " << endl;
215  for (Int_t i=0; i<9; i++) {
216  rotp[i] = rot(i);
217  cout << " i: " << i << " val: " << rotp[i] ;
218  }
219  cout << endl;
220  cout << " Lab translation : " << endl;
221  cout << " tX: " << trans.X() << " tY: " << trans.Y() << " tZ: " << trans.Z() << endl;
222 */
223 
224  fRichPoints = (TClonesArray*)fManager->GetObject("RichPoint");
225  if (NULL == fRichPoints) { Fatal("CbmRichHitProducer::Init","No RichPoint array!"); }
226 
227  //fMcTracks = (TClonesArray *)fManager->GetObject("MCTrack");
228  //if (NULL == fMcTracks) { Fatal("CbmRichHitProducer::Init","No MCTrack array!"); }
229 
230  fRichHits = new TClonesArray("CbmRichHit");
231  fManager->Register("RichHit","RICH", fRichHits, kTRUE);
232 
233  // Set photodetector parameters according to its type
234  if (fDetType == 0){
235  fPhotomulRadius = 0.;
236  fPhotomulDist = 0.;
237  }
238  if (fDetType == 2 || fDetType == 4 || fDetType == 5 || fDetType == 6) {
239  fPhotomulRadius = 0.6125;
240  fPhotomulDist = 0.2;
241  // fCrossTalkHitProb = 0.02;
242  }
243  if (fDetType == 3) {
244  fPhotomulRadius = 0.8;
245  fPhotomulDist = 0.5;
246  }
247 
248  return kSUCCESS;
249 }
250 
252  Option_t* option)
253 {
254  Int_t RichDetID = 0;
255 
256  fNEvents++;
257  cout << "-I- CbmRichHitProducer, event no " << fNEvents << endl;
258 
259  // Set photodetector quantum efficiency
260  Double_t lambda_min,lambda_max,lambda_step;
261  Double_t efficiency[100];
262  SetPhotoDetPar(fDetType,lambda_min,lambda_max,lambda_step,efficiency);
263 
264  fRichHits->Clear();
265  fNHits = 0;
266  fNDoubleHits = 0;
267 
268  //printf("%d RICH point(s) & %d track(s)\n", fRichPoints->GetEntries(), fMcTracks->GetEntriesFast());
269  for(Int_t j = 0; j < fRichPoints->GetEntries(); j++){
270  CbmRichPoint* pt = (CbmRichPoint*) fRichPoints->At(j);
271 
272  TVector3 posPoint;
273  pt->Position(posPoint);
274  TVector3 detPoint;
275  TiltPoint(&posPoint, &detPoint, fPhi, fTheta, fDetZ_org);
276 
277  if (fVerbose > 1) cout << " position in Labsystem " << posPoint.X() << " " << posPoint.Y() << " " << posPoint.Z() << endl;
278  if (fVerbose > 1) cout << " tilted position in Labsystem " << detPoint.X() << " " << detPoint.Y() << " " << detPoint.Z() << endl;
279 
280  //Int_t trackID = pt->GetTrackID();
281  //CbmMCTrack* p = (CbmMCTrack*) fMcTracks->At(trackID);
282  //Int_t gcode = TMath::Abs(p->GetPdgCode());
283  Int_t gcode = pt->fPDG;
284 
285  if ((fVerbose) && ((detPoint.Z() < (fDetZ-0.25)) || (detPoint.Z() > (fDetZ+0.25)))) {
286  cout << " z-position not at " << fDetZ << " but " << detPoint.Z() << endl;
287  }
288 
289  // hit position as a center of PMT
290  Double_t xHit, yHit;
291  Int_t pmtID;
292  Double_t sigma0 = 0.;
293  Double_t sigma = 0.19; // sigma (cm) for additional smearing of HitPosition due to WLS film
294 
295  // FindRichHitPosition
296  if (fDetType == 0) {
297  xHit = detPoint.X();
298  yHit = detPoint.Y();
299  pmtID = j;
300  }
301  if (fDetType == 1) FindRichHitPositionSinglePMT(detPoint.X(),detPoint.Y(),xHit,yHit,pmtID);
302  if (fDetType == 2 || fDetType == 4 || fDetType == 5 || fDetType == 6) FindRichHitPositionMAPMT(sigma0,detPoint.X(),detPoint.Y(),xHit,yHit,pmtID);
303  if (fDetType == 3) FindRichHitPositionCsI(detPoint.X(),detPoint.Y(),xHit,yHit,pmtID);
304 
305  //Double_t zHit = detPoint.Z();
306  Double_t zHit = fDetZ; // fix z-position to nominal value: either tilted (fDetZ = zDet) or untilted (fDetZ_org)
307  //TVector3 posHit(xHit,yHit,zHit);
308 
309  //error of hit position at the moment nothing better than +-tube_radius
310  TVector3 posHitErr(fPhotomulRadius,fPhotomulRadius,0.);
311 
312  // add Hit: Hit assigned only if xHit and yHit != 0
313  if (xHit != 0.0 && yHit != 0.0) {
314  if (fDetType == 1) {
315  if (fVerbose)
316  if (TMath::Sqrt((detPoint.X()-xHit)*(detPoint.X()-xHit)+(detPoint.Y()-yHit)*(detPoint.Y()-yHit)) > (fPhotomulRadius+fPhotomulDist)*1.5)
317  cout << "-E- RichHitProducer: wrongly assigned Hits (distance point-hit too large)!" << endl;
318  }
319  if (fDetType == 2 || fDetType == 3 || fDetType == 4 || fDetType == 6) {
320  if (fVerbose)
321  if (TMath::Abs(detPoint.X()-xHit) > fPhotomulRadius || TMath::Abs(detPoint.Y()-yHit) > fPhotomulRadius*1.5)
322  cout << "-E- RichHitProducer: wrongly assigned Hits (distance point-hit too large)! " <<
323  detPoint.X() << " " << xHit << " " << detPoint.Y() << " " << yHit << endl;
324  }
325  if (fDetType == 5) { // fDetType 5: additional smearing with RMS=3mm due to WLS film
326  if (fVerbose)
327  if (TMath::Abs(detPoint.X()-xHit) > fPhotomulRadius+1.5 || TMath::Abs(detPoint.Y()-yHit) > fPhotomulRadius*1.5)
328  cout << "-E- RichHitProducer: wrongly assigned Hits ? (distance point-hit too large)! " <<
329  detPoint.X() << " " << xHit << " " << detPoint.Y() << " " << yHit << endl;
330  }
331 
332  if (gcode == 50000050) {
333  // for photons weight with efficiency of PMT
334  TVector3 mom;
335  pt->Momentum(mom);
336  Double_t etot = sqrt(mom.Px()*mom.Px() + mom.Py()*mom.Py() + mom.Pz()*mom.Pz());
337  Double_t lambda=c/fNRefrac*h/e/etot;// wavelength in nm
338  fDetection=0;
339  if (lambda >= lambda_min && lambda < lambda_max) {
340  Int_t ilambda=(Int_t)((lambda-lambda_min)/lambda_step);
341  Double_t rand = gRandom->Rndm();
342  fDetection = 0;
343  if (fDetType == 5 && lambda < 300.) {// smear Hit position for lambda < 300 nm (WLS film!)
344  FindRichHitPositionMAPMT(sigma,detPoint.X(),detPoint.Y(),xHit,yHit,pmtID);
345  }
346  if (efficiency[ilambda]*fCollectionEfficiency > rand ) fDetection = 1;
347  } // min <= lambda < max
348  }// if photon
349 
350  // detection efficiency for hadrons crossing the PMT-cathodes?
351  // else if (gcode == 211) detection = 1; //pi+-
352  // else if (gcode == 321) detection = 1; //K+-
353  // else if (gcode == 2212) detection = 1; //p+-
354  else { // if not photon
355  // worst case: assume that all charged particles crossing
356  // the PMTplane leave Cherenkov light in the PMTglass which will be detected
357  fDetection=1;
358  }
359 
360  TVector3 posHit(xHit,yHit,zHit);
361 
362  if (fDetection == 1){
363  Int_t address = pt->GetDetectorID();
364  if (RichDetID == 0) RichDetID = address;
365  if (RichDetID != address)
366  cout << "-E- RichDetID changed from " << RichDetID << " to " << address << endl;
367  Double_t ampl = GetAmplitude();
368  AddHit(posHit,posHitErr,address,pmtID,ampl,j);
369 
370  AddCrossTalkHits(posHit.X(), posHit.Y(), j, RichDetID);
371  } // photon detected?
372  } // xHit and yHit != 0
373 
374  if (fVerbose > 2) {
375  cout << " iHit, Point-x, Point-y, Hit-x, Hiy-y, detected, PMT? " << j << " "
376  << posPoint.X() << " " << posPoint.Y() << " " << xHit << " "
377  << yHit << " " << fDetection << " " << pmtID << endl;
378  }
379  } // loop over RICH points
380 
381  // add noise hits
382  for(Int_t j = 0; j < fNofNoiseHits; j++) {
383  Double_t rand = gRandom->Rndm();
384  Double_t xRand = (fDetX-fDetZ_org*TMath::Sin(fPhi))-fDetWidthX + rand*2.*fDetWidthX;
385  rand = gRandom->Rndm();
386  if (rand < 0.5 ) xRand = -1.*xRand;
387  rand = gRandom->Rndm();
388  Double_t yRand = fDetY-fDetWidthY + rand*2.*fDetWidthY;
389  rand = gRandom->Rndm();
390  if (rand < 0.5 ) yRand = -1.*yRand;
391 
392  Double_t xHit, yHit;
393  Int_t pmtID;
394 
395  //FindRichHitPosition
396  if (fDetType == 0) {
397  xHit = xRand;
398  yHit = yRand;
399  pmtID = -j;
400  }
401  if (fDetType == 1) FindRichHitPositionSinglePMT(xRand,yRand,xHit,yHit,pmtID);
402  if (fDetType == 2 || fDetType == 4 || fDetType == 5 || fDetType == 6) FindRichHitPositionMAPMT(0,xRand,yRand,xHit,yHit,pmtID);
403  if (fDetType == 3) FindRichHitPositionCsI(xRand,yRand,xHit,yHit,pmtID);
404 
405  // add Hit
406  if (xHit!=0.0 && yHit!=0.0) {
407  Double_t zHit = fDetZ;
408  TVector3 posHit(xHit,yHit,zHit);
409  Double_t ampl = GetAmplitude();
410 
411  //error of hit position
412  //at the moment nothing better than +-tube_radius
413  TVector3 posHitErr(fPhotomulRadius,fPhotomulRadius,0.);
414 
415  AddHit(posHit,posHitErr,RichDetID,pmtID,ampl,-1);
416  }
417  }
418 
419  cout << "Nof hits: "<< fRichHits->GetEntries()<< endl;
420  cout << "Fraction of double hits: "<<(Double_t)(fNDoubleHits)/(Double_t)(fNHits) << endl;
421  cout << "Nof crosstalk hits: " << (Double_t) fNofCrossTalkHits / fNEvents << endl;
422 }
423 
425  TVector3 *inPos,
426  TVector3 *outPos,
427  Double_t phi,
428  Double_t theta,
429  Double_t detZOrig,
430  Bool_t noTilting)
431 {
432  if (noTilting == false){
433  Double_t xDet,yDet,zDet;
434 
435  if (inPos->X() > 0 && inPos->Y() > 0) {
436  xDet = inPos->X()*TMath::Cos(phi) + inPos->Z()*TMath::Sin(phi) - detZOrig*TMath::Sin(phi);
437  yDet = -inPos->X()*TMath::Sin(theta)*TMath::Sin(phi) + inPos->Y()*TMath::Cos(theta) + inPos->Z()*TMath::Sin(theta)*TMath::Cos(phi);
438  zDet = -inPos->X()*TMath::Cos(theta)*TMath::Sin(phi) - inPos->Y()*TMath::Sin(theta) + inPos->Z()*TMath::Cos(theta)*TMath::Cos(phi);
439  }
440  if (inPos->X() > 0 && inPos->Y() < 0) {
441  xDet = inPos->X()*TMath::Cos(phi) + inPos->Z()*TMath::Sin(phi) - detZOrig*TMath::Sin(phi);
442  yDet = inPos->X()*TMath::Sin(theta)*TMath::Sin(phi) + inPos->Y()*TMath::Cos(theta) - inPos->Z()*TMath::Sin(theta)*TMath::Cos(phi);
443  zDet = -inPos->X()*TMath::Cos(theta)*TMath::Sin(phi) + inPos->Y()*TMath::Sin(theta) + inPos->Z()*TMath::Cos(theta)*TMath::Cos(phi);
444  }
445  if (inPos->X() < 0 && inPos->Y() < 0) {
446  xDet = inPos->X()*TMath::Cos(phi) - inPos->Z()*TMath::Sin(phi) + detZOrig*TMath::Sin(phi);
447  yDet = -inPos->X()*TMath::Sin(theta)*TMath::Sin(phi) + inPos->Y()*TMath::Cos(theta) - inPos->Z()*TMath::Sin(theta)*TMath::Cos(phi);
448  zDet = inPos->X()*TMath::Cos(theta)*TMath::Sin(phi) + inPos->Y()*TMath::Sin(theta) + inPos->Z()*TMath::Cos(theta)*TMath::Cos(phi);
449  }
450  if (inPos->X() < 0 && inPos->Y() > 0) {
451  xDet = inPos->X()*TMath::Cos(phi) - inPos->Z()*TMath::Sin(phi) + detZOrig*TMath::Sin(phi);
452  yDet = inPos->X()*TMath::Sin(theta)*TMath::Sin(phi) + inPos->Y()*TMath::Cos(theta) + inPos->Z()*TMath::Sin(theta)*TMath::Cos(phi);
453  zDet = inPos->X()*TMath::Cos(theta)*TMath::Sin(phi) - inPos->Y()*TMath::Sin(theta) + inPos->Z()*TMath::Cos(theta)*TMath::Cos(phi);
454  }
455  outPos->SetXYZ(xDet,yDet,zDet);
456  } else {
457  outPos->SetXYZ(inPos->X(), inPos->Y(), inPos->Z());
458  }
459 }
460 
461 
463  TVector3 &posHit,
464  TVector3 &posHitErr,
465  Int_t address,
466  Int_t pmtID,
467  Double_t ampl,
468  Int_t index)
469 {
470  // Add this hit to existing one, if in the same PMT,
471  // otherwise create a new one.
472  Bool_t hitMerged = kFALSE;
473  CbmRichHit *hit;
474  // Check if there was any hit in the same PMT
475  for (Int_t iHit = 0; iHit < fNHits; iHit++) {
476  hit = (CbmRichHit*) fRichHits->At(iHit);
477  if (pmtID == hit->GetPmtId() && address==hit->GetAddress()) {
478  hit->SetNPhotons(hit->GetNPhotons()+1);
479  hit->SetAmplitude(GetAmplitude()+ampl);
480  hitMerged = kTRUE;
481  fNDoubleHits++;
482  break;
483  }
484  }
485 
486  // If no hits found in this PMT, add a new one
487  if (!hitMerged) {
488  new((*fRichHits)[fNHits]) CbmRichHit();
489  hit = (CbmRichHit*)fRichHits->At(fNHits);
490  hit->SetPosition(posHit);
491  hit->SetPositionError(posHitErr);
492  hit->SetAddress(address);
493  hit->SetPmtId(pmtID);
494  hit->SetNPhotons(1);
495  hit->SetAmplitude(GetAmplitude());
496  hit->SetRefId(index);
497  fNHits++;
498  }
499 }
500 
502  Double_t x,
503  Double_t y,
504  Int_t pointInd,
505  Int_t RichDetID)
506 {
507  // only for MAMPT
508  if (fDetType != 2 && fDetType != 4 && fDetType != 5 && fDetType != 6) return;
509 
510  Double_t xHit = 0.0, yHit = 0.0;
511  Int_t pmtID = -1;
512 
513  Double_t r = fPhotomulRadius;
514 
515  // closest neighbors
516  Double_t rand = gRandom->Rndm();
517  if (rand < fCrossTalkHitProb && xHit == 0.0 && yHit == 0.0 && pmtID == -1)
518  FindRichHitPositionMAPMT(0., x + r, y, xHit, yHit, pmtID);
519 
520  rand = gRandom->Rndm();
521  if (rand < fCrossTalkHitProb && xHit == 0.0 && yHit == 0.0 && pmtID == -1)
522  FindRichHitPositionMAPMT(0., x - r, y, xHit, yHit, pmtID);
523 
524  rand = gRandom->Rndm();
525  if (rand < fCrossTalkHitProb && xHit == 0.0 && yHit == 0.0 && pmtID == -1)
526  FindRichHitPositionMAPMT(0., x, y + r, xHit, yHit, pmtID);
527 
528  rand = gRandom->Rndm();
529  if (rand < fCrossTalkHitProb && xHit == 0.0 && yHit == 0.0 && pmtID == -1)
530  FindRichHitPositionMAPMT(0., x, y - r, xHit, yHit, pmtID);
531 
532  // diagonal neighbors
533  rand = gRandom->Rndm();
534  if (rand < fCrossTalkHitProb / 4. && xHit == 0.0 && yHit == 0.0 && pmtID == -1)
535  FindRichHitPositionMAPMT(0., x + r, y + r, xHit, yHit, pmtID);
536 
537  rand = gRandom->Rndm();
538  if (rand < fCrossTalkHitProb / 4. && xHit == 0.0 && yHit == 0.0 && pmtID == -1)
539  FindRichHitPositionMAPMT(0., x - r, y - r, xHit, yHit, pmtID);
540 
541  rand = gRandom->Rndm();
542  if (rand < fCrossTalkHitProb / 4. && xHit == 0.0 && yHit == 0.0 && pmtID == -1)
543  FindRichHitPositionMAPMT(0., x - r, y + r, xHit, yHit, pmtID);
544 
545  rand = gRandom->Rndm();
546  if (rand < fCrossTalkHitProb / 4.&& xHit == 0.0 && yHit == 0.0 && pmtID == -1)
547  FindRichHitPositionMAPMT(0., x + r, y - r, xHit, yHit, pmtID);
548 
549 
550  if (xHit != 0.0 && yHit != 0.0) {
551  Double_t zHit = fDetZ;
552  TVector3 posHit(xHit,yHit,zHit);
553  Double_t ampl = GetAmplitude();
554  TVector3 posHitErr(fPhotomulRadius,fPhotomulRadius,0.);
555 
556  AddHit(posHit, posHitErr, RichDetID, pmtID, ampl, pointInd);
558  }
559 }
560 
562 {
563  fRichHits->Clear();
564 }
565 
567  Int_t det_type,
568  Double_t& fLambdaMin,
569  Double_t& fLambdaMax,
570  Double_t& fLambdaStep,
571  Double_t fEfficiency[])
572 {
573  // gives parameters for a chosen photodetector type
574  if (fVerbose > 0) cout << "SetPhotoDetPar routine called for PMT type " << fDetType << endl;
575 
576  if (det_type == 1){
577  // PMT efficiencies for Protvino-type PMT
578  // corresponding range in lambda: (100nm)120nm - 700nm in steps of 20nm
579 
580  fLambdaMin = 120.;
581  fLambdaMax = 700.;
582  fLambdaStep = 20.;
583 
584  fEfficiency[0] = 0.216;
585  fEfficiency[1] = 0.216;
586  fEfficiency[2] = 0.216;
587  fEfficiency[3] = 0.216;
588  fEfficiency[4] = 0.216;
589  fEfficiency[5] = 0.216;
590  fEfficiency[6] = 0.216;
591  fEfficiency[7] = 0.216;
592  fEfficiency[8] = 0.216;
593  fEfficiency[9] = 0.216;
594  fEfficiency[10] = 0.216;
595  fEfficiency[11] = 0.227;
596  fEfficiency[12] = 0.23;
597  fEfficiency[13] = 0.227;
598  fEfficiency[14] = 0.216;
599  fEfficiency[15] = 0.2;
600  fEfficiency[16] = 0.176;
601  fEfficiency[17] = 0.15;
602  fEfficiency[18] = 0.138;
603  fEfficiency[19] = 0.1;
604  fEfficiency[20] = 0.082;
605  fEfficiency[21] = 0.06;
606  fEfficiency[22] = 0.044;
607  fEfficiency[23] = 0.032;
608  fEfficiency[24] = 0.022;
609  fEfficiency[25] = 0.015;
610  fEfficiency[26] = 0.01;
611  fEfficiency[27] = 0.006;
612  fEfficiency[28] = 0.004;
613 
614  fLambdaMin = 100.;
615  fLambdaMax = 700.;
616  fLambdaStep = 20.;
617 
618 // fEfficiency[0] = 0.216;
619 // fEfficiency[1] = 0.216;
620 // fEfficiency[2] = 0.216;
621 // fEfficiency[3] = 0.216;
622 // fEfficiency[4] = 0.216;
623 // fEfficiency[5] = 0.216;
624 // fEfficiency[6] = 0.216;
625 // fEfficiency[7] = 0.216;
626 // fEfficiency[8] = 0.216;
627 // fEfficiency[9] = 0.216;
628 // fEfficiency[10] = 0.216;
629 // fEfficiency[11] = 0.216;
630 // fEfficiency[12] = 0.227;
631 // fEfficiency[13] = 0.23;
632 // fEfficiency[14] = 0.227;
633 // fEfficiency[15] = 0.216;
634 // fEfficiency[16] = 0.2;
635 // fEfficiency[17] = 0.176;
636 // fEfficiency[18] = 0.15;
637 // fEfficiency[19] = 0.138;
638 // fEfficiency[20] = 0.1;
639 // fEfficiency[21] = 0.082;
640 // fEfficiency[22] = 0.06;
641 // fEfficiency[23] = 0.044;
642 // fEfficiency[24] = 0.032;
643 // fEfficiency[25] = 0.022;
644 // fEfficiency[26] = 0.015;
645 // fEfficiency[27] = 0.01;
646 // fEfficiency[28] = 0.006;
647 // fEfficiency[29] = 0.004;
648  } else if (det_type == 3){
649  // quantum efficiency for CsI photocathode
650  // approximately read off from fig.3 in NIM A 433 (1999) 201 (HADES)
651 
652  fLambdaMin = 130.;
653  fLambdaMax = 210.;
654  fLambdaStep = 10.;
655 
656  fEfficiency[0] = 0.45;
657  fEfficiency[1] = 0.4;
658  fEfficiency[2] = 0.35;
659  fEfficiency[3] = 0.32;
660  fEfficiency[4] = 0.25;
661  fEfficiency[5] = 0.2;
662  fEfficiency[6] = 0.1;
663  fEfficiency[7] = 0.03;
664 
665  } else if (det_type == 2){
666  // PMT efficiencies for Hamamatsu H8500
667  // (Flat type Multianode Photomultiplier)
668  // corresponding range in lambda: 260nm - 740nm in steps of 20nm
669 
670  fLambdaMin = 260.;
671  fLambdaMax = 740.;
672  fLambdaStep = 20.;
673 
674  fEfficiency[0] = 0.06;
675  fEfficiency[1] = 0.12;
676  fEfficiency[2] = 0.2;
677  fEfficiency[3] = 0.22;
678  fEfficiency[4] = 0.22;
679  fEfficiency[5] = 0.22;
680  fEfficiency[6] = 0.21;
681  fEfficiency[7] = 0.2;
682  fEfficiency[8] = 0.18;
683  fEfficiency[9] = 0.16;
684  fEfficiency[10] = 0.14;
685  fEfficiency[11] = 0.11;
686  fEfficiency[12] = 0.1;
687  fEfficiency[13] = 0.06;
688  fEfficiency[14] = 0.047;
689  fEfficiency[15] = 0.03;
690  fEfficiency[16] = 0.021;
691  fEfficiency[17] = 0.012;
692  fEfficiency[18] = 0.006;
693  fEfficiency[19] = 0.0023;
694  fEfficiency[20] = 0.0008;
695  fEfficiency[21] = 0.00022;
696  fEfficiency[22] = 0.00007;
697  fEfficiency[23] = 0.00002;
698 
699  } else if (det_type == 4){
700  // PMT efficiencies for Hamamatsu H8500-03
701  // (Flat type Multianode Photomultiplier with UV window)
702  // corresponding range in lambda: 200nm - 640nm in steps of 20nm
703 
704  fLambdaMin = 200.;
705  fLambdaMax = 640.;
706  fLambdaStep = 20.;
707 
708  fEfficiency[0] = 0.095;
709  fEfficiency[1] = 0.13;
710  fEfficiency[2] = 0.16;
711  fEfficiency[3] = 0.2;
712  fEfficiency[4] = 0.23;
713  fEfficiency[5] = 0.24;
714  fEfficiency[6] = 0.25;
715  fEfficiency[7] = 0.25;
716  fEfficiency[8] = 0.24;
717  fEfficiency[9] = 0.24;
718  fEfficiency[10] = 0.23;
719  fEfficiency[11] = 0.22;
720  fEfficiency[12] = 0.2;
721  fEfficiency[13] = 0.16;
722  fEfficiency[14] = 0.14;
723  fEfficiency[15] = 0.1;
724  fEfficiency[16] = 0.065;
725  fEfficiency[17] = 0.045;
726  fEfficiency[18] = 0.02;
727  fEfficiency[19] = 0.017;
728  fEfficiency[20] = 0.007;
729  fEfficiency[21] = 0.0033;
730  } else if (det_type == 5){
731  // PMT efficiencies for Hamamatsu H8500 + WLS film
732  // (Flat type Multianode Photomultiplier with UV window)
733  // corresponding range in lambda: 150nm - 650nm in steps of 20nm
734 
735  fLambdaMin = 160.;
736  fLambdaMax = 640.;
737  fLambdaStep = 20.;
738 
739  fEfficiency[0] = 0.1;
740  fEfficiency[1] = 0.2;
741  fEfficiency[2] = 0.2;
742  fEfficiency[3] = 0.2;
743  fEfficiency[4] = 0.2;
744  fEfficiency[5] = 0.2;
745  fEfficiency[6] = 0.23;
746  fEfficiency[7] = 0.24;
747  fEfficiency[8] = 0.25;
748  fEfficiency[9] = 0.25;
749  fEfficiency[10] = 0.24;
750  fEfficiency[11] = 0.24;
751  fEfficiency[12] = 0.23;
752  fEfficiency[13] = 0.22;
753  fEfficiency[14] = 0.2;
754  fEfficiency[15] = 0.16;
755  fEfficiency[16] = 0.14;
756  fEfficiency[17] = 0.1;
757  fEfficiency[18] = 0.065;
758  fEfficiency[19] = 0.045;
759  fEfficiency[20] = 0.02;
760  fEfficiency[21] = 0.017;
761  fEfficiency[22] = 0.007;
762  fEfficiency[23] = 0.0033;
763  } else if (det_type == 6) {
764  //QE measured at Wuppertal University (BUW), spring 2011
765  // H8500C-03 (BA + UV glass)
770  fLambdaMin = 160.;
771  fLambdaMax = 700.;
772  fLambdaStep = 10.;
773 
774  fEfficiency[0] = 0.0272;
775  fEfficiency[1] = 0.0443;
776  fEfficiency[2] = 0.06;
777  fEfficiency[3] = 0.08;
778  fEfficiency[4] = 0.0945;
779  fEfficiency[5] = 0.1061;
780  fEfficiency[6] = 0.1265;
781  fEfficiency[7] = 0.1482;
782  fEfficiency[8] = 0.1668;
783  fEfficiency[9] = 0.1887;
784  fEfficiency[10] = 0.2093;
785  fEfficiency[11] = 0.2134;
786  fEfficiency[12] = 0.2303;
787  fEfficiency[13] = 0.2482;
788  fEfficiency[14] = 0.2601;
789  fEfficiency[15] = 0.2659;
790  fEfficiency[16] = 0.2702;
791  fEfficiency[17] = 0.283;
792  fEfficiency[18] = 0.2863;
793  fEfficiency[19] = 0.2863;
794  fEfficiency[20] = 0.2884;
795  fEfficiency[21] = 0.286;
796  fEfficiency[22] = 0.2811;
797  fEfficiency[23] = 0.2802;
798  fEfficiency[24] = 0.272;
799  fEfficiency[25] = 0.2638;
800  fEfficiency[26] = 0.2562;
801  fEfficiency[27] = 0.2472;
802  fEfficiency[28] = 0.2368;
803  fEfficiency[29] = 0.2218;
804  fEfficiency[30] = 0.2032;
805  fEfficiency[31] = 0.186;
806  fEfficiency[32] = 0.1735;
807  fEfficiency[33] = 0.1661;
808  fEfficiency[34] = 0.1483;
809  fEfficiency[35] = 0.121;
810  fEfficiency[36] = 0.0959;
811  fEfficiency[37] = 0.0782;
812  fEfficiency[38] = 0.0647;
813  fEfficiency[39] = 0.0538;
814  fEfficiency[40] = 0.0372;
815  fEfficiency[41] = 0.0296;
816  fEfficiency[42] = 0.0237;
817  fEfficiency[43] = 0.0176;
818  fEfficiency[44] = 0.0123;
819  fEfficiency[45] = 0.0083;
820  fEfficiency[46] = 0.005;
821  fEfficiency[47] = 0.003;
822  fEfficiency[48] = 0.0017;
823  fEfficiency[49] = 0.0008;
824  fEfficiency[50] = 0.0006;
825  fEfficiency[51] = 0.0003;
826  fEfficiency[52] = 0.0003;
827  fEfficiency[53] = 0.0002;
828  fEfficiency[54] = 0.0001;
829 
830 
831  } else if (det_type == 0){
832 
833  // ideal detector
834 
835  fLambdaMin = 100.;
836  fLambdaMax = 700.;
837  fLambdaStep = 600.;
838 
839  fEfficiency[0] = 1.;
840  } else {
841  cout << "ERROR: photodetector type not specified" << endl;
842 
843  fLambdaMin = 100.;
844  fLambdaMax = 100.;
845  fLambdaStep = 100.;
846 
847  fEfficiency[0] = 0.;
848  }
849 }
850 
852  Double_t xPoint,
853  Double_t yPoint,
854  Double_t& xHit,
855  Double_t& yHit,
856  Int_t & pmtID)
857 {
858  // calculate Hits for Protvino type of PMT (single PMTs with circle surface, hexagonal packing):
859  // hexagonal packing of round phototubes with radius fPhotomulRadius,
860  // distance between phototubes 2*fPhotomulDist -> effective radius is
861  // (fPhotomulRadius+fPhotomulDist) assuming that the gap is covered by Al funnels
862 
863  xHit = 0.;
864  yHit = 0.;
865 
866  // Transformation of global (x,y) coordinates to local coordinates in photodetector plane (u,v)
867  // the center of (u,v) CS is in the lower left corner of each photodetector
868  // u is parrallel to x, v tilted by 30degree (alpha = 30 degree)
869 
870  Double_t uPoint, vPoint;
871  Double_t uPMT, vPMT;
872  Double_t alpha = TMath::Pi()/6.;
873  Double_t distance;
874 
875  // smear points due to light scattering in mirror
876  xPoint = xPoint + gRandom->Gaus(0,fSigmaMirror);
877  yPoint = yPoint + gRandom->Gaus(0,fSigmaMirror);
878 
879  uPoint = 2.*fDetWidthX - (fPhotomulRadius+fPhotomulDist) + xPoint;
880  if (yPoint > 0)
881  vPoint = (- fDetY + fDetWidthY - (fPhotomulRadius+fPhotomulDist) + yPoint)/ TMath::Cos(alpha);
882  if (yPoint < 0)
883  vPoint = (fDetY + fDetWidthY - (fPhotomulRadius+fPhotomulDist) + yPoint)/ TMath::Cos(alpha);
884 
885  // Calculate Position of nearest PMT
886  uPMT = (fPhotomulRadius+fPhotomulDist)*((Int_t)(uPoint/(fPhotomulRadius+fPhotomulDist)+0.999));
887  vPMT = (fPhotomulRadius+fPhotomulDist)*((Int_t)(vPoint/(fPhotomulRadius+fPhotomulDist)+0.999));
888 
889  // Calculate distance between PMT and Point
890  distance = TMath::Sqrt((uPMT-uPoint)*(uPMT-uPoint)+(vPMT-vPoint)*(vPMT-vPoint)*TMath::Cos(alpha)*TMath::Cos(alpha));
891 
892  // if distance < (fPhotomulRadius+fPhotomulDist)
893  // ==> retransform to global (x,y) and store Hit (center of PMT)
894  if (distance <= (fPhotomulRadius+fPhotomulDist)){
895  xHit = uPMT - 2.*fDetWidthX + (fPhotomulRadius+fPhotomulDist);
896  if (yPoint > 0)
897  yHit = vPMT*TMath::Cos(alpha) + fDetY - fDetWidthY + (fPhotomulRadius+fPhotomulDist);
898  if (yPoint < 0)
899  yHit = vPMT*TMath::Cos(alpha) - fDetY - fDetWidthY + (fPhotomulRadius+fPhotomulDist);
900 
901  pmtID = (Int_t)(uPMT/(fPhotomulRadius+fPhotomulDist))*100000+(Int_t)(vPMT/(fPhotomulRadius+fPhotomulDist));
902  if (yPoint<0.) pmtID = -1*pmtID;
903  }// if hit
904 }
905 
907  Double_t sigma,
908  Double_t xPoint,
909  Double_t yPoint,
910  Double_t& xHit,
911  Double_t& yHit,
912  Int_t & pmtID)
913 {
914  // calculate Hits for MAPMT (Hamamatsu H8500, 8x8 MAPMT):
915  // dimensions:
916  // length = 52mm x 52mm, active area = 49mm x 49mm
917  // pixel (mean size) = 6.125mm x 6.125mm
918  // assume some spacing between single units of s=1mm
919  // ==> use as effective values fPhotomulRadius = 6.125mm = 0.6125cm
920  // fPhotomulDist = 0.5mm + 1.5mm = 2mm = 0.2cm
921  //
922  // sigma (cm) : add WLS film --> hits smeared with sigma
923 
924  xHit = 0.;
925  yHit = 0.;
926 
927  Int_t nPixel = 8;
928  Double_t length = (Double_t)(nPixel)*fPhotomulRadius + 2 * fPhotomulDist;//effective size
929 
930  // Transformation of global (x,y) coordinates to local coordinates in photodetector plane (u,v)
931  // the center of (u,v) CS is in the lower left corner of each photodetector
932  Double_t uPoint, vPoint;
933  Double_t uPMT, vPMT, uPMTs, vPMTs;
934 
935  // smear points due to light scattering in mirror
936  xPoint = xPoint + gRandom->Gaus(0, fSigmaMirror);
937  yPoint = yPoint + gRandom->Gaus(0, fSigmaMirror);
938 
939  // smear Point if photon is converted via WLS film:
940  if (sigma > 0.) {
941  xPoint = xPoint + gRandom->Gaus(0,sigma);
942  yPoint = yPoint + gRandom->Gaus(0,sigma);
943  }
944 
945  uPoint = 2.*fDetWidthX + xPoint;
946  if (yPoint > 0)
947  vPoint = - fDetY + fDetWidthY + yPoint;
948  if (yPoint < 0)
949  vPoint = fDetY + fDetWidthY + yPoint;
950 
951  // calculate lower left corner of effective area of MAPMT unit which has been hit
952  uPMT = length*(Int_t)(uPoint/length)+fPhotomulDist;
953  vPMT = length*(Int_t)(vPoint/length)+fPhotomulDist;
954 
955  // reject points not lying in the effective area of the MAPMT units:
956  if ((TMath::Abs((uPMT+(Double_t)(nPixel)/2.*fPhotomulRadius)-uPoint) < ((Double_t)(nPixel)/2.*fPhotomulRadius)) &&
957  (TMath::Abs((vPMT+(Double_t)(nPixel)/2.*fPhotomulRadius)-vPoint) < ((Double_t)(nPixel)/2.*fPhotomulRadius))) {
958 
959  // check that uPoint > uPMT and vPoint > vPMT
960  if (uPoint < uPMT) cout << " -E- HitProducer: calculation of MAPMT unit (u) " << uPoint << " " << uPMT << endl;
961  if (vPoint < vPMT) cout << " -E- HitProducer: calculation of MAPMT unit (v) " << vPoint << " " << vPMT << endl;
962 
963  // calculate center of PMT cell hit in this MAPMT unit -> Hit
964  uPMTs = fPhotomulRadius*(Int_t)((uPoint-uPMT)/fPhotomulRadius)+fPhotomulRadius/2. + uPMT;
965  vPMTs = fPhotomulRadius*(Int_t)((vPoint-vPMT)/fPhotomulRadius)+fPhotomulRadius/2. + vPMT;
966 
967  // ==> retransform to global (x,y) and store Hit
968  xHit = uPMTs - 2.*fDetWidthX;
969  if (yPoint > 0) yHit = vPMTs + fDetY - fDetWidthY;
970  if (yPoint < 0) yHit = vPMTs - fDetY - fDetWidthY;
971 
972  pmtID = ((Int_t)(uPoint/length)*100 + (Int_t)((uPoint-uPMT)/fPhotomulRadius))*100000
973  + ((Int_t)(vPoint/length)*100 + (Int_t)((vPoint-vPMT)/fPhotomulRadius));
974 
975  if (yPoint<0.) pmtID = -1*pmtID;
976 
977  }// point in effective area ?
978 
979  if (fVerbose > 3) cout << "FindHitPos_MAPMT: " << xPoint << " " << yPoint << " " << xHit << " " << yHit << endl;
980 }
981 
983  Double_t xPoint,
984  Double_t yPoint,
985  Double_t& xHit,
986  Double_t& yHit,
987  Int_t & pmtID)
988 {
989  // calculate Hits for CsI
990  // dimensions (assume 3 panels of 1.4m x 1.067 m) per plane):
991  // height = (fDetWidthY - 2* fPhotomulDist) * 2
992  // length = (2.*fDetWidthX - 2* fPhotomulDist) * 2 / 3
993  // pixels (mean size) = 8mm x 8mm (similar to ALICE)
994  // integrate spacing between single panels into fPhotomulDist (= eff. distance between active areas)
995  // fPhotomulDist = 0.5cm
996  // fPhotomulRadius = 0.8cm
997 
998  xHit = 0.;
999  yHit = 0.;
1000  Double_t xlength = 2.*fDetWidthX * 2. / 3.;
1001  Double_t ylength = fDetWidthY * 2.;
1002 
1003  // Transformation of global (x,y) coordinates to local coordinates in photodetector plane (u,v)
1004  // the center of (u,v) CS is in the lower left corner of each photodetector
1005 
1006  Double_t uPoint, vPoint;
1007  Double_t uPMT, vPMT, uPMTs, vPMTs;
1008 
1009  // smear points due to light scattering in mirror
1010  xPoint = xPoint + gRandom->Gaus(0,fSigmaMirror);
1011  yPoint = yPoint + gRandom->Gaus(0,fSigmaMirror);
1012 
1013  uPoint = 2.*fDetWidthX + xPoint;
1014  if (yPoint > 0) vPoint = - fDetY + fDetWidthY + yPoint;
1015  if (yPoint < 0) vPoint = fDetY + fDetWidthY + yPoint;
1016 
1017  // calculate lower left corner of effective area of panel which has been hit
1018  uPMT = xlength*(Int_t)(uPoint/xlength)+fPhotomulDist;
1019  vPMT = ylength*(Int_t)(vPoint/ylength)+fPhotomulDist;
1020 
1021  // reject points not lying in the effective area of the panels:
1022  if ((TMath::Abs(uPMT+(xlength/2.-fPhotomulDist)-uPoint) < (xlength/2.-fPhotomulDist)) &&
1023  (TMath::Abs(vPMT+(ylength/2.-fPhotomulDist)-vPoint) < (ylength/2.-fPhotomulDist))) {
1024 
1025  // check that uPoint > uPMT and vPoint > vPMT
1026  if (uPoint < uPMT) cout << " -E- HitProducer: calculation of CsI unit (u) " << uPoint << " " << uPMT << endl;
1027  if (vPoint < vPMT) cout << " -E- HitProducer: calculation of CsI unit (v) " << vPoint << " " << vPMT << endl;
1028 
1029  // calculate center of PMT cell hit in this MAPMT unit -> Hit
1030  uPMTs = fPhotomulRadius*(Int_t)((uPoint-uPMT)/fPhotomulRadius)+fPhotomulRadius/2. + uPMT;
1031  vPMTs = fPhotomulRadius*(Int_t)((vPoint-vPMT)/fPhotomulRadius)+fPhotomulRadius/2. + vPMT;
1032 
1033  // ==> retransform to global (x,y) and store Hit
1034  xHit = uPMTs - 2.*fDetWidthX;
1035  if (yPoint > 0) yHit = vPMTs + fDetY - fDetWidthY;
1036  if (yPoint < 0) yHit = vPMTs - fDetY - fDetWidthY;
1037 
1038  pmtID = ((Int_t)(uPoint/xlength)*1000 + (Int_t)((uPoint-uPMT)/fPhotomulRadius))*100000
1039  + ((Int_t)(vPoint/ylength)*1000 + (Int_t)((vPoint-vPMT)/fPhotomulRadius));
1040 
1041  if (yPoint<0.) pmtID = -1*pmtID;
1042  } // point in effective area?
1043 }
1044 
1046  Double_t x)
1047 {
1048  // Spectrum of the PMT response to one photo-electron
1049  // after S.Sadovsky, 9 Sep 2004
1050  const Float_t kn=1.85;
1051  const Float_t kb=1.75;
1052  return TMath::Power(x*kb/kn,kn) * TMath::Exp(-(kb*x-kn));
1053 }
1054 
1056 {
1057  // Generate randomly PMT amplitude according to probability density
1058  // provided by OnePhotonAmplitude(x)
1059 
1060  const Double_t xMin=0;
1061  const Double_t xMax=6;
1062  Double_t ampl;
1063  while (kTRUE)
1064  if (gRandom->Rndm() < OnePhotonAmplitude(ampl = gRandom->Uniform(xMin,xMax))) break;
1065 
1066  return ampl;
1067 }
1068