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 **************************************************************************/
18 Revision 1.28 2000/10/17 20:50:57 jbarbosa
19 Inversed digtise by particle type (now, only the selected particle type is not digitsed).
20 Corrected several geometry minor bugs.
21 Added new parameter (opaque quartz thickness).
23 Revision 1.27 2000/10/11 10:33:55 jbarbosa
24 Corrected bug introduced by earlier revisions (CerenkovData array cannot be reset to zero on wach call of StepManager)
26 Revision 1.26 2000/10/03 21:44:08 morsch
27 Use AliSegmentation and AliHit abstract base classes.
29 Revision 1.25 2000/10/02 21:28:12 fca
30 Removal of useless dependecies via forward declarations
32 Revision 1.24 2000/10/02 15:43:17 jbarbosa
33 Fixed forward declarations.
34 Fixed honeycomb density.
35 Fixed cerenkov storing.
38 Revision 1.23 2000/09/13 10:42:14 hristov
39 Minor corrections for HP, DEC and Sun; strings.h included
41 Revision 1.22 2000/09/12 18:11:13 fca
42 zero hits area before using
44 Revision 1.21 2000/07/21 10:21:07 morsch
45 fNrawch = 0; and fNrechits = 0; in the default constructor.
47 Revision 1.20 2000/07/10 15:28:39 fca
48 Correction of the inheritance scheme
50 Revision 1.19 2000/06/30 16:29:51 dibari
51 Added kDebugLevel variable to control output size on demand
53 Revision 1.18 2000/06/12 15:15:46 jbarbosa
56 Revision 1.17 2000/06/09 14:58:37 jbarbosa
57 New digitisation per particle type
59 Revision 1.16 2000/04/19 12:55:43 morsch
60 Newly structured and updated version (JB, AM)
65 ////////////////////////////////////////////////
66 // Manager and hits classes for set:RICH //
67 ////////////////////////////////////////////////
75 #include <TObjArray.h>
78 #include <TParticle.h>
79 #include <TGeometry.h>
86 #include "AliSegmentation.h"
87 #include "AliRICHHit.h"
88 #include "AliRICHCerenkov.h"
89 #include "AliRICHPadHit.h"
90 #include "AliRICHDigit.h"
91 #include "AliRICHTransientDigit.h"
92 #include "AliRICHRawCluster.h"
93 #include "AliRICHRecHit.h"
94 #include "AliRICHHitMapA1.h"
95 #include "AliRICHClusterFinder.h"
101 #include "AliPoints.h"
102 #include "AliCallf77.h"
106 // Static variables for the pad-hit iterator routines
107 static Int_t sMaxIterPad=0;
108 static Int_t sCurIterPad=0;
109 static TClonesArray *fClusters2;
110 static TClonesArray *fHits2;
115 //___________________________________________
118 // Default constructor for RICH manager class
127 for (Int_t i=0; i<7; i++)
135 //___________________________________________
136 AliRICH::AliRICH(const char *name, const char *title)
137 : AliDetector(name,title)
141 <img src="gif/alirich.gif">
145 fHits = new TClonesArray("AliRICHHit",1000 );
146 gAlice->AddHitList(fHits);
147 fPadHits = new TClonesArray("AliRICHPadHit",100000);
148 fCerenkovs = new TClonesArray("AliRICHCerenkov",1000);
149 gAlice->AddHitList(fCerenkovs);
150 //gAlice->AddHitList(fHits);
155 //fNdch = new Int_t[kNCH];
157 fDchambers = new TObjArray(kNCH);
159 fRecHits = new TObjArray(kNCH);
163 for (i=0; i<kNCH ;i++) {
164 (*fDchambers)[i] = new TClonesArray("AliRICHDigit",10000);
168 //fNrawch = new Int_t[kNCH];
170 fRawClusters = new TObjArray(kNCH);
171 //printf("Created fRwClusters with adress:%p",fRawClusters);
173 for (i=0; i<kNCH ;i++) {
174 (*fRawClusters)[i] = new TClonesArray("AliRICHRawCluster",10000);
178 //fNrechits = new Int_t[kNCH];
180 for (i=0; i<kNCH ;i++) {
181 (*fRecHits)[i] = new TClonesArray("AliRICHRecHit",1000);
183 //printf("Created fRecHits with adress:%p",fRecHits);
186 SetMarkerColor(kRed);
189 AliRICH::AliRICH(const AliRICH& RICH)
195 //___________________________________________
199 // Destructor of RICH manager class
207 //___________________________________________
208 void AliRICH::AddHit(Int_t track, Int_t *vol, Float_t *hits)
212 // Adds a hit to the Hits list
215 TClonesArray &lhits = *fHits;
216 new(lhits[fNhits++]) AliRICHHit(fIshunt,track,vol,hits);
218 //_____________________________________________________________________________
219 void AliRICH::AddCerenkov(Int_t track, Int_t *vol, Float_t *cerenkovs)
223 // Adds a RICH cerenkov hit to the Cerenkov Hits list
226 TClonesArray &lcerenkovs = *fCerenkovs;
227 new(lcerenkovs[fNcerenkovs++]) AliRICHCerenkov(fIshunt,track,vol,cerenkovs);
228 //printf ("Done for Cerenkov %d\n\n\n\n",fNcerenkovs);
230 //___________________________________________
231 void AliRICH::AddPadHit(Int_t *clhits)
235 // Add a RICH pad hit to the list
238 TClonesArray &lPadHits = *fPadHits;
239 new(lPadHits[fNPadHits++]) AliRICHPadHit(clhits);
241 //_____________________________________________________________________________
242 void AliRICH::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
246 // Add a RICH digit to the list
249 TClonesArray &ldigits = *((TClonesArray*)(*fDchambers)[id]);
250 new(ldigits[fNdch[id]++]) AliRICHDigit(tracks,charges,digits);
253 //_____________________________________________________________________________
254 void AliRICH::AddRawCluster(Int_t id, const AliRICHRawCluster& c)
257 // Add a RICH digit to the list
260 TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]);
261 new(lrawcl[fNrawch[id]++]) AliRICHRawCluster(c);
264 //_____________________________________________________________________________
265 void AliRICH::AddRecHit(Int_t id, Float_t *rechit, Float_t *photons, Int_t *padsx, Int_t* padsy)
269 // Add a RICH reconstructed hit to the list
272 TClonesArray &lrec = *((TClonesArray*)(*fRecHits)[id]);
273 new(lrec[fNrechits[id]++]) AliRICHRecHit(id,rechit,photons,padsx,padsy);
276 //___________________________________________
277 void AliRICH::BuildGeometry()
282 // Builds a TNode geometry for event display
286 const int kColorRICH = kGreen;
288 top=gAlice->GetGeometry()->GetNode("alice");
291 new TBRIK("S_RICH","S_RICH","void",71.09999,11.5,73.15);
294 Float_t pos1[3]={0,471.8999,165.2599};
295 //Chamber(0).SetChamberTransform(pos1[0],pos1[1],pos1[2],
296 new TRotMatrix("rot993","rot993",90,0,70.69,90,19.30999,-90);
297 node = new TNode("RICH1","RICH1","S_RICH",pos1[0],pos1[1],pos1[2],"rot993");
300 node->SetLineColor(kColorRICH);
304 Float_t pos2[3]={171,470,0};
305 //Chamber(1).SetChamberTransform(pos2[0],pos2[1],pos2[2],
306 new TRotMatrix("rot994","rot994",90,-20,90,70,0,0);
307 node = new TNode("RICH2","RICH2","S_RICH",pos2[0],pos2[1],pos2[2],"rot994");
310 node->SetLineColor(kColorRICH);
313 Float_t pos3[3]={0,500,0};
314 //Chamber(2).SetChamberTransform(pos3[0],pos3[1],pos3[2],
315 new TRotMatrix("rot995","rot995",90,0,90,90,0,0);
316 node = new TNode("RICH3","RICH3","S_RICH",pos3[0],pos3[1],pos3[2],"rot995");
319 node->SetLineColor(kColorRICH);
322 Float_t pos4[3]={-171,470,0};
323 //Chamber(3).SetChamberTransform(pos4[0],pos4[1],pos4[2],
324 new TRotMatrix("rot996","rot996",90,20,90,110,0,0);
325 node = new TNode("RICH4","RICH4","S_RICH",pos4[0],pos4[1],pos4[2],"rot996");
328 node->SetLineColor(kColorRICH);
331 Float_t pos5[3]={161.3999,443.3999,-165.3};
332 //Chamber(4).SetChamberTransform(pos5[0],pos5[1],pos5[2],
333 new TRotMatrix("rot997","rot997",90,340,108.1999,70,18.2,70);
334 node = new TNode("RICH5","RICH5","S_RICH",pos5[0],pos5[1],pos5[2],"rot997");
336 node->SetLineColor(kColorRICH);
339 Float_t pos6[3]={0., 471.9, -165.3,};
340 //Chamber(5).SetChamberTransform(pos6[0],pos6[1],pos6[2],
341 new TRotMatrix("rot998","rot998",90,0,109.3099,90,19.30999,90);
342 node = new TNode("RICH6","RICH6","S_RICH",pos6[0],pos6[1],pos6[2],"rot998");
345 node->SetLineColor(kColorRICH);
348 Float_t pos7[3]={-161.399,443.3999,-165.3};
349 //Chamber(6).SetChamberTransform(pos7[0],pos7[1],pos7[2],
350 new TRotMatrix("rot999","rot999",90,20,108.1999,110,18.2,110);
351 node = new TNode("RICH7","RICH7","S_RICH",pos7[0],pos7[1],pos7[2],"rot999");
352 node->SetLineColor(kColorRICH);
357 //___________________________________________
358 void AliRICH::CreateGeometry()
361 // Create the geometry for RICH version 1
363 // Modified by: N. Colonna (INFN - BARI, Nicola.Colonna@ba.infn.it)
364 // R.A. Fini (INFN - BARI, Rosanna.Fini@ba.infn.it)
365 // R.A. Loconsole (Bari University, loco@riscom.ba.infn.it)
369 <img src="picts/AliRICHv1.gif">
374 <img src="picts/AliRICHv1Tree.gif">
378 AliRICH *pRICH = (AliRICH *) gAlice->GetDetector("RICH");
379 AliSegmentation* segmentation;
380 AliRICHGeometry* geometry;
381 AliRICHChamber* iChamber;
383 iChamber = &(pRICH->Chamber(0));
384 segmentation=iChamber->GetSegmentationModel(0);
385 geometry=iChamber->GetGeometryModel();
388 distance = geometry->GetFreonThickness()/2 + geometry->GetQuartzThickness() + geometry->GetGapThickness();
389 geometry->SetRadiatorToPads(distance);
391 //Opaque quartz thickness
392 Float_t oqua_thickness = .4;
394 Int_t *idtmed = fIdtmed->GetArray()-999;
401 // --- Define the RICH detector
402 // External aluminium box
404 par[1] = 11.5; //Original Settings
409 gMC->Gsvolu("RICH", "BOX ", idtmed[1009], par, 3);
411 // Sensitive part of the whole RICH
413 par[1] = 11.5; //Original Settings
418 gMC->Gsvolu("SRIC", "BOX ", idtmed[1000], par, 3);
422 par[1] = .188; //Original Settings
427 gMC->Gsvolu("HONE", "BOX ", idtmed[1001], par, 3);
431 par[1] = .025; //Original Settings
436 gMC->Gsvolu("ALUM", "BOX ", idtmed[1009], par, 3);
439 par[0] = geometry->GetQuartzWidth()/2;
440 par[1] = geometry->GetQuartzThickness()/2;
441 par[2] = geometry->GetQuartzLength()/2;
443 par[1] = .25; //Original Settings
445 /*par[0] = geometry->GetQuartzWidth()/2;
446 par[1] = geometry->GetQuartzThickness()/2;
447 par[2] = geometry->GetQuartzLength()/2;*/
448 //printf("\n\n\n\n\n\n\n\\n\n\n\n Gap Thickness: %f %f %f\n\n\n\n\n\n\n\n\n\n\n\n\n\n",par[0],par[1],par[2]);
449 gMC->Gsvolu("QUAR", "BOX ", idtmed[1002], par, 3);
451 // Spacers (cylinders)
454 par[2] = geometry->GetFreonThickness()/2;
455 gMC->Gsvolu("SPAC", "TUBE", idtmed[1002], par, 3);
459 par[1] = .2; //Original Settings
464 gMC->Gsvolu("OQUA", "BOX ", idtmed[1007], par, 3);
466 // Frame of opaque quartz
467 par[0] = geometry->GetOuterFreonWidth()/2;
469 par[1] = geometry->GetFreonThickness()/2;
470 par[2] = geometry->GetOuterFreonLength()/2;
473 par[1] = .5; //Original Settings
478 gMC->Gsvolu("OQF1", "BOX ", idtmed[1007], par, 3);
480 par[0] = geometry->GetInnerFreonWidth()/2 + oqua_thickness;
481 par[1] = geometry->GetFreonThickness()/2;
482 par[2] = geometry->GetInnerFreonLength()/2 + oqua_thickness;
483 gMC->Gsvolu("OQF2", "BOX ", idtmed[1007], par, 3);
485 // Little bar of opaque quartz
487 par[1] = geometry->GetQuartzThickness()/2;
488 //par[2] = geometry->GetInnerFreonLength()/2 - 2.4;
489 par[2] = geometry->GetInnerFreonLength()/2;
492 par[1] = .25; //Original Settings
497 gMC->Gsvolu("BARR", "BOX ", idtmed[1007], par, 3);
500 par[0] = geometry->GetOuterFreonWidth()/2;
501 par[1] = geometry->GetFreonThickness()/2;
502 par[2] = geometry->GetOuterFreonLength()/2;
504 par[1] = .5; //Original Settings
509 gMC->Gsvolu("FRE1", "BOX ", idtmed[1003], par, 3);
511 par[0] = geometry->GetInnerFreonWidth()/2;
512 par[1] = geometry->GetFreonThickness()/2;
513 par[2] = geometry->GetInnerFreonLength()/2;
514 gMC->Gsvolu("FRE2", "BOX ", idtmed[1003], par, 3);
518 par[1] = geometry->GetGapThickness()/2;
519 //printf("\n\n\n\n\n\n\n\\n\n\n\n Gap Thickness: %f\n\n\n\n\n\n\n\n\n\n\n\n\n\n",par[1]);
521 gMC->Gsvolu("META", "BOX ", idtmed[1004], par, 3);
525 par[1] = geometry->GetProximityGapThickness()/2;
526 //printf("\n\n\n\n\n\n\n\\n\n\n\n Gap Thickness: %f\n\n\n\n\n\n\n\n\n\n\n\n\n\n",par[1]);
528 gMC->Gsvolu("GAP ", "BOX ", idtmed[1008], par, 3);
534 gMC->Gsvolu("CSI ", "BOX ", idtmed[1005], par, 3);
540 gMC->Gsvolu("GRID", "TUBE", idtmed[1006], par, 3);
542 // --- Places the detectors defined with GSVOLU
543 // Place material inside RICH
544 gMC->Gspos("SRIC", 1, "RICH", 0., 0., 0., 0, "ONLY");
546 gMC->Gspos("ALUM", 1, "SRIC", 0., 1.276 - geometry->GetGapThickness()/2 - geometry->GetQuartzThickness() - geometry->GetFreonThickness()- .4 -.05 - .376 -.025, 0., 0, "ONLY");
547 gMC->Gspos("HONE", 1, "SRIC", 0., 1.276- geometry->GetGapThickness()/2 - geometry->GetQuartzThickness() - geometry->GetFreonThickness()- .4 -.05 - .188, 0., 0, "ONLY");
548 gMC->Gspos("ALUM", 2, "SRIC", 0., 1.276 - geometry->GetGapThickness()/2 - geometry->GetQuartzThickness() - geometry->GetFreonThickness()- .4 - .025, 0., 0, "ONLY");
549 gMC->Gspos("OQUA", 1, "SRIC", 0., 1.276 - geometry->GetGapThickness()/2 - geometry->GetQuartzThickness() - geometry->GetFreonThickness()- .2, 0., 0, "ONLY");
551 AliMatrix(idrotm[1019], 0., 0., 90., 0., 90., 90.);
553 Int_t nspacers = (Int_t)(TMath::Abs(geometry->GetInnerFreonLength()/14.4));
554 //printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n Spacers:%d\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",nspacers);
556 //printf("Nspacers: %d", nspacers);
558 //for (i = 1; i <= 9; ++i) {
559 //zs = (5 - i) * 14.4; //Original settings
560 for (i = 0; i < nspacers; i++) {
561 zs = (TMath::Abs(nspacers/2) - i) * 14.4;
562 gMC->Gspos("SPAC", i, "FRE1", 6.7, 0., zs, idrotm[1019], "ONLY"); //Original settings
563 //gMC->Gspos("SPAC", i, "FRE1", zs, 0., 6.7, idrotm[1019], "ONLY");
565 //for (i = 10; i <= 18; ++i) {
566 //zs = (14 - i) * 14.4; //Original settings
567 for (i = nspacers; i < nspacers*2; ++i) {
568 zs = (nspacers + TMath::Abs(nspacers/2) - i) * 14.4;
569 gMC->Gspos("SPAC", i, "FRE1", -6.7, 0., zs, idrotm[1019], "ONLY"); //Original settings
570 //gMC->Gspos("SPAC", i, "FRE1", zs, 0., -6.7, idrotm[1019], "ONLY");
573 //for (i = 1; i <= 9; ++i) {
574 //zs = (5 - i) * 14.4; //Original settings
575 for (i = 0; i < nspacers; i++) {
576 zs = (TMath::Abs(nspacers/2) - i) * 14.4;
577 gMC->Gspos("SPAC", i, "FRE2", 6.7, 0., zs, idrotm[1019], "ONLY"); //Original settings
578 //gMC->Gspos("SPAC", i, "FRE2", zs, 0., 6.7, idrotm[1019], "ONLY");
580 //for (i = 10; i <= 18; ++i) {
581 //zs = (5 - i) * 14.4; //Original settings
582 for (i = nspacers; i < nspacers*2; ++i) {
583 zs = (nspacers + TMath::Abs(nspacers/2) - i) * 14.4;
584 gMC->Gspos("SPAC", i, "FRE2", -6.7, 0., zs, idrotm[1019], "ONLY"); //Original settings
585 //gMC->Gspos("SPAC", i, "FRE2", zs, 0., -6.7, idrotm[1019], "ONLY");
588 /*gMC->Gspos("FRE1", 1, "OQF1", 0., 0., 0., 0, "ONLY");
589 gMC->Gspos("FRE2", 1, "OQF2", 0., 0., 0., 0, "ONLY");
590 gMC->Gspos("OQF1", 1, "SRIC", 31.3, -4.724, 41.3, 0, "ONLY");
591 gMC->Gspos("OQF2", 2, "SRIC", 0., -4.724, 0., 0, "ONLY");
592 gMC->Gspos("OQF1", 3, "SRIC", -31.3, -4.724, -41.3, 0, "ONLY");
593 gMC->Gspos("BARR", 1, "QUAR", -21.65, 0., 0., 0, "ONLY"); //Original settings
594 gMC->Gspos("BARR", 2, "QUAR", 21.65, 0., 0., 0, "ONLY"); //Original settings
595 gMC->Gspos("QUAR", 1, "SRIC", 0., -3.974, 0., 0, "ONLY");
596 gMC->Gspos("GAP ", 1, "META", 0., 4.8, 0., 0, "ONLY");
597 gMC->Gspos("META", 1, "SRIC", 0., 1.276, 0., 0, "ONLY");
598 gMC->Gspos("CSI ", 1, "SRIC", 0., 6.526, 0., 0, "ONLY");*/
601 gMC->Gspos("FRE1", 1, "OQF1", 0., 0., 0., 0, "ONLY");
602 gMC->Gspos("FRE2", 1, "OQF2", 0., 0., 0., 0, "ONLY");
603 gMC->Gspos("OQF1", 1, "SRIC", geometry->GetOuterFreonWidth()/2 + geometry->GetInnerFreonWidth()/2 + 2*oqua_thickness, 1.276 - geometry->GetGapThickness()/2- geometry->GetQuartzThickness() -geometry->GetFreonThickness()/2, 0., 0, "ONLY"); //Original settings (31.3)
604 gMC->Gspos("OQF2", 2, "SRIC", 0., 1.276 - geometry->GetGapThickness()/2 - geometry->GetQuartzThickness() - geometry->GetFreonThickness()/2, 0., 0, "ONLY"); //Original settings
605 gMC->Gspos("OQF1", 3, "SRIC", - (geometry->GetOuterFreonWidth()/2 + geometry->GetInnerFreonWidth()/2) - 2*oqua_thickness, 1.276 - geometry->GetGapThickness()/2 - geometry->GetQuartzThickness() - geometry->GetFreonThickness()/2, 0., 0, "ONLY"); //Original settings (-31.3)
606 gMC->Gspos("BARR", 1, "QUAR", - geometry->GetInnerFreonWidth()/2 - oqua_thickness, 0., 0., 0, "ONLY"); //Original settings (-21.65)
607 gMC->Gspos("BARR", 2, "QUAR", geometry->GetInnerFreonWidth()/2 + oqua_thickness, 0., 0., 0, "ONLY"); //Original settings (21.65)
608 gMC->Gspos("QUAR", 1, "SRIC", 0., 1.276 - geometry->GetGapThickness()/2 - geometry->GetQuartzThickness()/2, 0., 0, "ONLY");
609 gMC->Gspos("GAP ", 1, "META", 0., geometry->GetGapThickness()/2 - geometry->GetProximityGapThickness()/2 - 0.0001, 0., 0, "ONLY");
610 gMC->Gspos("META", 1, "SRIC", 0., 1.276, 0., 0, "ONLY");
611 gMC->Gspos("CSI ", 1, "SRIC", 0., 1.276 + geometry->GetGapThickness()/2 + .25, 0., 0, "ONLY");
613 //printf("Position of the gap: %f to %f\n", 1.276 + geometry->GetGapThickness()/2 - geometry->GetProximityGapThickness()/2 - .2, 1.276 + geometry->GetGapThickness()/2 - geometry->GetProximityGapThickness()/2 + .2);
615 // Place RICH inside ALICE apparatus
617 AliMatrix(idrotm[1000], 90., 0., 70.69, 90., 19.31, -90.);
618 AliMatrix(idrotm[1001], 90., -20., 90., 70., 0., 0.);
619 AliMatrix(idrotm[1002], 90., 0., 90., 90., 0., 0.);
620 AliMatrix(idrotm[1003], 90., 20., 90., 110., 0., 0.);
621 AliMatrix(idrotm[1004], 90., 340., 108.2, 70., 18.2, 70.);
622 AliMatrix(idrotm[1005], 90., 0., 109.31, 90., 19.31, 90.);
623 AliMatrix(idrotm[1006], 90., 20., 108.2, 110., 18.2, 110.);
625 gMC->Gspos("RICH", 1, "ALIC", 0., 471.9, 165.26, idrotm[1000], "ONLY");
626 gMC->Gspos("RICH", 2, "ALIC", 171., 470., 0., idrotm[1001], "ONLY");
627 gMC->Gspos("RICH", 3, "ALIC", 0., 500., 0., idrotm[1002], "ONLY");
628 gMC->Gspos("RICH", 4, "ALIC", -171., 470., 0., idrotm[1003], "ONLY");
629 gMC->Gspos("RICH", 5, "ALIC", 161.4, 443.4, -165.3, idrotm[1004], "ONLY");
630 gMC->Gspos("RICH", 6, "ALIC", 0., 471.9, -165.3, idrotm[1005], "ONLY");
631 gMC->Gspos("RICH", 7, "ALIC", -161.4, 443.4, -165.3, idrotm[1006], "ONLY");
636 //___________________________________________
637 void AliRICH::CreateMaterials()
640 // *** DEFINITION OF AVAILABLE RICH MATERIALS ***
641 // ORIGIN : NICK VAN EIJNDHOVEN
642 // Modified by: N. Colonna (INFN - BARI, Nicola.Colonna@ba.infn.it)
643 // R.A. Fini (INFN - BARI, Rosanna.Fini@ba.infn.it)
644 // R.A. Loconsole (Bari University, loco@riscom.ba.infn.it)
646 Int_t isxfld = gAlice->Field()->Integ();
647 Float_t sxmgmx = gAlice->Field()->Max();
650 /************************************Antonnelo's Values (14-vectors)*****************************************/
652 Float_t ppckov[14] = { 5.63e-9,5.77e-9,5.9e-9,6.05e-9,6.2e-9,6.36e-9,6.52e-9,
653 6.7e-9,6.88e-9,7.08e-9,7.3e-9,7.51e-9,7.74e-9,8e-9 };
654 Float_t rIndexQuarz[14] = { 1.528309,1.533333,
655 1.538243,1.544223,1.550568,1.55777,
656 1.565463,1.574765,1.584831,1.597027,
657 1.611858,1.6277,1.6472,1.6724 };
658 Float_t rIndexOpaqueQuarz[14] = { 1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1. };
659 Float_t rIndexMethane[14] = { 1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1. };
660 Float_t rIndexGrid[14] = { 1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1. };
661 Float_t abscoFreon[14] = { 179.0987,179.0987,
662 179.0987,179.0987,179.0987,142.92,56.65,13.95,10.43,7.07,2.03,.5773,.33496,0. };
663 //Float_t abscoFreon[14] = { 1e-5,1e-5,1e-5,1e-5,1e-5,1e-5,1e-5,1e-5,1e-5,
664 // 1e-5,1e-5,1e-5,1e-5,1e-5 };
665 Float_t abscoQuarz[14] = { 64.035,39.98,35.665,31.262,27.527,22.815,21.04,17.52,
666 14.177,9.282,4.0925,1.149,.3627,.10857 };
667 Float_t abscoOpaqueQuarz[14] = { 1e-5,1e-5,1e-5,1e-5,1e-5,1e-5,1e-5,1e-5,1e-5,
668 1e-5,1e-5,1e-5,1e-5,1e-5 };
669 Float_t abscoCsI[14] = { 1e-4,1e-4,1e-4,1e-4,1e-4,1e-4,1e-4,1e-4,1e-4,1e-4,
670 1e-4,1e-4,1e-4,1e-4 };
671 Float_t abscoMethane[14] = { 1e6,1e6,1e6,1e6,1e6,1e6,1e6,1e6,1e6,1e6,1e6,
673 Float_t abscoGrid[14] = { 1e-4,1e-4,1e-4,1e-4,1e-4,1e-4,1e-4,1e-4,1e-4,1e-4,
674 1e-4,1e-4,1e-4,1e-4 };
675 Float_t efficAll[14] = { 1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1. };
676 Float_t efficCsI[14] = { 6e-4,.005,.0075,.01125,.045,.117,.135,.16575,
677 .17425,.1785,.1836,.1904,.1938,.221 };
678 Float_t efficGrid[14] = { 1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1. };
682 /**********************************End of Antonnelo's Values**********************************/
684 /**********************************Values from rich_media.f (31-vectors)**********************************/
687 //Photons energy intervals
691 ppckov[i] = (Float_t(i)*0.1+5.5)*1e-9;
692 //printf ("Energy intervals: %e\n",ppckov[i]);
696 //Refraction index for quarz
697 Float_t rIndexQuarz[26];
704 Float_t ene=ppckov[i]*1e9;
705 Float_t a=f1/(e1*e1 - ene*ene);
706 Float_t b=f2/(e2*e2 - ene*ene);
707 rIndexQuarz[i] = TMath::Sqrt(1. + a + b );
708 //printf ("rIndexQuarz: %e\n",rIndexQuarz[i]);
711 //Refraction index for opaque quarz, methane and grid
712 Float_t rIndexOpaqueQuarz[26];
713 Float_t rIndexMethane[26];
714 Float_t rIndexGrid[26];
717 rIndexOpaqueQuarz[i]=1;
718 rIndexMethane[i]=1.000444;
720 //printf ("rIndexOpaqueQuarz , etc: %e, %e, %e\n",rIndexOpaqueQuarz[i], rIndexMethane[i], rIndexGrid[i]=1);
723 //Absorption index for freon
724 Float_t abscoFreon[26] = {179.0987, 179.0987, 179.0987, 179.0987, 179.0987, 179.0987, 179.0987, 179.0987,
725 179.0987, 142.9206, 56.64957, 25.58622, 13.95293, 12.03905, 10.42953, 8.804196,
726 7.069031, 4.461292, 2.028366, 1.293013, .577267, .40746, .334964, 0., 0., 0.};
728 //Absorption index for quarz
729 /*Float_t Qzt [21] = {.0,.0,.005,.04,.35,.647,.769,.808,.829,.844,.853,.858,.869,.887,.903,.902,.902,
730 .906,.907,.907,.907};
731 Float_t Wavl2[] = {150.,155.,160.0,165.0,170.0,175.0,180.0,185.0,190.0,195.0,200.0,205.0,210.0,
732 215.0,220.0,225.0,230.0,235.0,240.0,245.0,250.0};
733 Float_t abscoQuarz[31];
734 for (Int_t i=0;i<31;i++)
736 Float_t Xlam = 1237.79 / (ppckov[i]*1e9);
737 if (Xlam <= 160) abscoQuarz[i] = 0;
738 if (Xlam > 250) abscoQuarz[i] = 1;
741 for (Int_t j=0;j<21;j++)
743 //printf ("Passed\n");
744 if (Xlam > Wavl2[j] && Xlam < Wavl2[j+1])
746 Float_t Dabs = (Qzt[j+1] - Qzt[j])/(Wavl2[j+1] - Wavl2[j]);
747 Float_t Abso = Qzt[j] + Dabs*(Xlam - Wavl2[j]);
748 abscoQuarz[i] = -5.0/(TMath::Log(Abso));
752 printf ("abscoQuarz: %e abscoFreon: %e for energy: %e\n",abscoQuarz[i],abscoFreon[i],ppckov[i]);
755 /*Float_t abscoQuarz[31] = {49.64211, 48.41296, 47.46989, 46.50492, 45.13682, 44.47883, 43.1929 , 41.30922, 40.5943 ,
756 39.82956, 38.98623, 38.6247 , 38.43448, 37.41084, 36.22575, 33.74852, 30.73901, 24.25086,
757 17.94531, 11.88753, 5.99128, 3.83503, 2.36661, 1.53155, 1.30582, 1.08574, .8779708,
758 .675275, 0., 0., 0.};
760 for (Int_t i=0;i<31;i++)
762 abscoQuarz[i] = abscoQuarz[i]/10;
765 Float_t abscoQuarz [26] = {105.8, 65.52, 48.58, 42.85, 35.79, 31.262, 28.598, 27.527, 25.007, 22.815, 21.004,
766 19.266, 17.525, 15.878, 14.177, 11.719, 9.282, 6.62, 4.0925, 2.601, 1.149, .667, .3627,
767 .192, .1497, .10857};
769 //Absorption index for methane
770 Float_t abscoMethane[26];
773 abscoMethane[i]=AbsoCH4(ppckov[i]*1e9);
774 //printf("abscoMethane: %e for energy: %e\n", abscoMethane[i],ppckov[i]*1e9);
777 //Absorption index for opaque quarz, csi and grid, efficiency for all and grid
778 Float_t abscoOpaqueQuarz[26];
779 Float_t abscoCsI[26];
780 Float_t abscoGrid[26];
781 Float_t efficAll[26];
782 Float_t efficGrid[26];
785 abscoOpaqueQuarz[i]=1e-5;
790 //printf ("All must be 1: %e, %e, %e, %e, %e\n",abscoOpaqueQuarz[i],abscoCsI[i],abscoGrid[i],efficAll[i],efficGrid[i]);
795 Float_t efficCsI[26] = {0.000199999995, 0.000600000028, 0.000699999975, 0.00499999989, 0.00749999983, 0.010125,
796 0.0242999997, 0.0405000001, 0.0688500032, 0.105299994, 0.121500008, 0.141749993, 0.157949999,
797 0.162, 0.166050002, 0.167669997, 0.174299985, 0.176789999, 0.179279998, 0.182599992, 0.18592,
798 0.187579989, 0.189239994, 0.190899998, 0.207499996, 0.215799987};
802 //FRESNEL LOSS CORRECTION FOR PERPENDICULAR INCIDENCE AND
803 //UNPOLARIZED PHOTONS
807 efficCsI[i] = efficCsI[i]/(1.-Fresnel(ppckov[i]*1e9,1.,0));
808 //printf ("Fresnel result: %e for energy: %e\n",Fresnel(ppckov[i]*1e9,1.,0),ppckov[i]*1e9);
811 /*******************************************End of rich_media.f***************************************/
818 Float_t afre[2], agri, amet[2], aqua[2], ahon, zfre[2], zgri, zhon,
822 Int_t nlmatmet, nlmatqua;
823 Float_t wmatquao[2], rIndexFreon[26];
824 Float_t aquao[2], epsil, stmin, zquao[2];
826 Float_t radlal, densal, tmaxfd, deemax, stemax;
827 Float_t aal, zal, radlgri, densfre, radlhon, densgri, denshon,densqua, densmet, wmatfre[2], wmatmet[2], wmatqua[2];
829 Int_t *idtmed = fIdtmed->GetArray()-999;
831 TGeant3 *geant3 = (TGeant3*) gMC;
833 // --- Photon energy (GeV)
834 // --- Refraction indexes
835 for (i = 0; i < 26; ++i) {
836 rIndexFreon[i] = ppckov[i] * .0172 * 1e9 + 1.177;
837 //rIndexFreon[i] = 1;
838 //printf ("rIndexFreon: %e \n efficCsI: %e for energy: %e\n",rIndexFreon[i], efficCsI[i], ppckov[i]);
841 // --- Detection efficiencies (quantum efficiency for CsI)
842 // --- Define parameters for honeycomb.
843 // Used carbon of equivalent rad. lenght
850 // --- Parameters to include in GSMIXT, relative to Quarz (SiO2)
861 // --- Parameters to include in GSMIXT, relative to opaque Quarz (SiO2)
872 // --- Parameters to include in GSMIXT, relative to Freon (C6F14)
883 // --- Parameters to include in GSMIXT, relative to methane (CH4)
894 // --- Parameters to include in GSMIXT, relative to anode grid (Cu)
901 // --- Parameters to include in GSMATE related to aluminium sheet
908 AliMaterial(1, "Air $", 14.61, 7.3, .001205, 30420., 67500);
909 AliMaterial(6, "HON", ahon, zhon, denshon, radlhon, 0);
910 AliMaterial(16, "CSI", ahon, zhon, denshon, radlhon, 0);
911 AliMixture(20, "QUA", aqua, zqua, densqua, nlmatqua, wmatqua);
912 AliMixture(21, "QUAO", aquao, zquao, densquao, nlmatquao, wmatquao);
913 AliMixture(30, "FRE", afre, zfre, densfre, nlmatfre, wmatfre);
914 AliMixture(40, "MET", amet, zmet, densmet, nlmatmet, wmatmet);
915 AliMixture(41, "METG", amet, zmet, densmet, nlmatmet, wmatmet);
916 AliMaterial(11, "GRI", agri, zgri, densgri, radlgri, 0);
917 AliMaterial(50, "ALUM", aal, zal, densal, radlal, 0);
925 AliMedium(1, "DEFAULT MEDIUM AIR$", 1, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
926 AliMedium(2, "HONEYCOMB$", 6, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
927 AliMedium(3, "QUARZO$", 20, 1, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
928 AliMedium(4, "FREON$", 30, 1, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
929 AliMedium(5, "METANO$", 40, 1, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
930 AliMedium(6, "CSI$", 16, 1, isxfld, sxmgmx,tmaxfd, stemax, deemax, epsil, stmin);
931 AliMedium(7, "GRIGLIA$", 11, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
932 AliMedium(8, "QUARZOO$", 21, 1, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
933 AliMedium(9, "GAP$", 41, 1, isxfld, sxmgmx,tmaxfd, .1, -deemax, epsil, -stmin);
934 AliMedium(10, "ALUMINUM$", 50, 1, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
937 geant3->Gsckov(idtmed[1000], 26, ppckov, abscoMethane, efficAll, rIndexMethane);
938 geant3->Gsckov(idtmed[1001], 26, ppckov, abscoMethane, efficAll, rIndexMethane);
939 geant3->Gsckov(idtmed[1002], 26, ppckov, abscoQuarz, efficAll,rIndexQuarz);
940 geant3->Gsckov(idtmed[1003], 26, ppckov, abscoFreon, efficAll,rIndexFreon);
941 geant3->Gsckov(idtmed[1004], 26, ppckov, abscoMethane, efficAll, rIndexMethane);
942 geant3->Gsckov(idtmed[1005], 26, ppckov, abscoCsI, efficCsI, rIndexMethane);
943 geant3->Gsckov(idtmed[1006], 26, ppckov, abscoGrid, efficGrid, rIndexGrid);
944 geant3->Gsckov(idtmed[1007], 26, ppckov, abscoOpaqueQuarz, efficAll, rIndexOpaqueQuarz);
945 geant3->Gsckov(idtmed[1008], 26, ppckov, abscoMethane, efficAll, rIndexMethane);
946 geant3->Gsckov(idtmed[1009], 26, ppckov, abscoGrid, efficGrid, rIndexGrid);
949 //___________________________________________
951 Float_t AliRICH::Fresnel(Float_t ene,Float_t pdoti, Bool_t pola)
954 //ENE(EV), PDOTI=COS(INC.ANG.), PDOTR=COS(POL.PLANE ROT.ANG.)
956 Float_t en[36] = {5.0,5.1,5.2,5.3,5.4,5.5,5.6,5.7,5.8,5.9,6.0,6.1,6.2,
957 6.3,6.4,6.5,6.6,6.7,6.8,6.9,7.0,7.1,7.2,7.3,7.4,7.5,7.6,7.7,
958 7.8,7.9,8.0,8.1,8.2,8.3,8.4,8.5};
961 Float_t csin[36] = {2.14,2.21,2.33,2.48,2.76,2.97,2.99,2.59,2.81,3.05,
962 2.86,2.53,2.55,2.66,2.79,2.96,3.18,3.05,2.84,2.81,2.38,2.11,
963 2.01,2.13,2.39,2.73,3.08,3.15,2.95,2.73,2.56,2.41,2.12,1.95,
966 Float_t csik[36] = {0.,0.,0.,0.,0.,0.196,0.408,0.208,0.118,0.49,0.784,0.543,
967 0.424,0.404,0.371,0.514,0.922,1.102,1.139,1.376,1.461,1.253,0.878,
968 0.69,0.612,0.649,0.824,1.347,1.571,1.678,1.763,1.857,1.824,1.824,
971 Int_t j=Int_t(xe*10)-49;
972 Float_t cn=csin[j]+((csin[j+1]-csin[j])/0.1)*(xe-en[j]);
973 Float_t ck=csik[j]+((csik[j+1]-csik[j])/0.1)*(xe-en[j]);
975 //FORMULAE FROM HANDBOOK OF OPTICS, 33.23 OR
976 //W.R. HUNTER, J.O.S.A. 54 (1964),15 , J.O.S.A. 55(1965),1197
978 Float_t sinin=TMath::Sqrt(1-pdoti*pdoti);
979 Float_t tanin=sinin/pdoti;
981 Float_t c1=cn*cn-ck*ck-sinin*sinin;
982 Float_t c2=4*cn*cn*ck*ck;
983 Float_t aO=TMath::Sqrt(0.5*(TMath::Sqrt(c1*c1+c2)+c1));
984 Float_t b2=0.5*(TMath::Sqrt(c1*c1+c2)-c1);
986 Float_t rs=((aO-pdoti)*(aO-pdoti)+b2)/((aO+pdoti)*(aO+pdoti)+b2);
987 Float_t rp=rs*((aO-sinin*tanin)*(aO-sinin*tanin)+b2)/((aO+sinin*tanin)*(aO+sinin*tanin)+b2);
990 //CORRECTION FACTOR FOR SURFACE ROUGHNESS
991 //B.J. STAGG APPLIED OPTICS, 30(1991),4113
994 Float_t lamb=1240/ene;
997 Float_t rO=TMath::Exp(-(4*TMath::Pi()*pdoti*sigraf/lamb)*(4*TMath::Pi()*pdoti*sigraf/lamb));
1001 Float_t pdotr=0.8; //DEGREE OF POLARIZATION : 1->P , -1->S
1002 fresn=0.5*(rp*(1+pdotr)+rs*(1-pdotr));
1011 //__________________________________________
1012 Float_t AliRICH::AbsoCH4(Float_t x)
1015 //KLOSCH,SCH4(9),WL(9),EM(9),ALENGTH(31)
1016 Float_t sch4[9] = {.12,.16,.23,.38,.86,2.8,7.9,28.,80.}; //MB X 10^22
1017 //Float_t wl[9] = {153.,152.,151.,150.,149.,148.,147.,146.,145};
1018 Float_t em[9] = {8.1,8.158,8.212,8.267,8.322,8.378,8.435,8.493,8.55};
1019 const Float_t kLosch=2.686763E19; // LOSCHMIDT NUMBER IN CM-3
1020 const Float_t kIgas1=100, kIgas2=0, kOxy=10., kWater=5., kPressure=750.,kTemperature=283.;
1021 Float_t pn=kPressure/760.;
1022 Float_t tn=kTemperature/273.16;
1025 // ------- METHANE CROSS SECTION -----------------
1026 // ASTROPH. J. 214, L47 (1978)
1032 if(x>=7.75 && x<=8.1)
1034 Float_t c0=-1.655279e-1;
1035 Float_t c1=6.307392e-2;
1036 Float_t c2=-8.011441e-3;
1037 Float_t c3=3.392126e-4;
1038 sm=(c0+c1*x+c2*x*x+c3*x*x*x)*1.e-18;
1044 while (x<=em[j] && x>=em[j+1])
1047 Float_t a=(sch4[j+1]-sch4[j])/(em[j+1]-em[j]);
1048 sm=(sch4[j]+a*(x-em[j]))*1e-22;
1052 Float_t dm=(kIgas1/100.)*(1.-((kOxy+kWater)/1.e6))*kLosch*pn/tn;
1053 Float_t abslm=1./sm/dm;
1055 // ------- ISOBUTHANE CROSS SECTION --------------
1056 // i-C4H10 (ai) abs. length from curves in
1057 // Lu-McDonald paper for BARI RICH workshop .
1058 // -----------------------------------------------------------
1067 if(x>=7.25 && x<7.375)
1073 Float_t si = 1./(ai*kLosch*273.16/293.); // ISOB. CRO.SEC.IN CM2
1074 Float_t di=(kIgas2/100.)*(1.-((kOxy+kWater)/1.e6))*kLosch*pn/tn;
1079 // ---------------------------------------------------------
1081 // transmission of O2
1083 // y= path in cm, x=energy in eV
1084 // so= cross section for UV absorption in cm2
1085 // do= O2 molecular density in cm-3
1086 // ---------------------------------------------------------
1094 so=3.392709e-13 * TMath::Exp(2.864104 *x);
1100 so=2.910039e-34 * TMath::Exp(10.3337*x);
1107 Float_t a0=-73770.76;
1108 Float_t a1=46190.69;
1109 Float_t a2=-11475.44;
1110 Float_t a3=1412.611;
1111 Float_t a4=-86.07027;
1112 Float_t a5=2.074234;
1113 so= a0+(a1*x)+(a2*x*x)+(a3*x*x*x)+(a4*x*x*x*x)+(a5*x*x*x*x*x);
1117 Float_t dox=(kOxy/1e6)*kLosch*pn/tn;
1122 // ---------------------------------------------------------
1124 // transmission of H2O
1126 // y= path in cm, x=energy in eV
1127 // sw= cross section for UV absorption in cm2
1128 // dw= H2O molecular density in cm-3
1129 // ---------------------------------------------------------
1133 Float_t b0=29231.65;
1134 Float_t b1=-15807.74;
1135 Float_t b2=3192.926;
1136 Float_t b3=-285.4809;
1137 Float_t b4=9.533944;
1141 Float_t sw= b0+(b1*x)+(b2*x*x)+(b3*x*x*x)+(b4*x*x*x*x);
1143 Float_t dw=(kWater/1e6)*kLosch*pn/tn;
1149 // ---------------------------------------------------------
1151 Float_t alength=1./(1./abslm+1./absli+1./abslo+1./abslw);
1157 //___________________________________________
1158 Int_t AliRICH::DistancetoPrimitive(Int_t , Int_t )
1166 //___________________________________________
1167 void AliRICH::MakeBranch(Option_t* option)
1169 // Create Tree branches for the RICH.
1171 const Int_t kBufferSize = 4000;
1172 char branchname[20];
1175 AliDetector::MakeBranch(option);
1176 sprintf(branchname,"%sCerenkov",GetName());
1177 if (fCerenkovs && gAlice->TreeH()) {
1178 gAlice->TreeH()->Branch(branchname,&fCerenkovs, kBufferSize);
1179 printf("Making Branch %s for Cerenkov Hits\n",branchname);
1182 sprintf(branchname,"%sPadHits",GetName());
1183 if (fPadHits && gAlice->TreeH()) {
1184 gAlice->TreeH()->Branch(branchname,&fPadHits, kBufferSize);
1185 printf("Making Branch %s for PadHits\n",branchname);
1188 // one branch for digits per chamber
1191 for (i=0; i<kNCH ;i++) {
1192 sprintf(branchname,"%sDigits%d",GetName(),i+1);
1194 if (fDchambers && gAlice->TreeD()) {
1195 gAlice->TreeD()->Branch(branchname,&((*fDchambers)[i]), kBufferSize);
1196 printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
1200 // one branch for raw clusters per chamber
1201 for (i=0; i<kNCH ;i++) {
1202 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
1204 if (fRawClusters && gAlice->TreeR()) {
1205 gAlice->TreeR()->Branch(branchname,&((*fRawClusters)[i]), kBufferSize);
1206 printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1);
1210 // one branch for rec hits per chamber
1211 for (i=0; i<kNCH ;i++) {
1212 sprintf(branchname,"%sRecHits%d",GetName(),i+1);
1214 if (fRecHits && gAlice->TreeR()) {
1215 gAlice->TreeR()->Branch(branchname,&((*fRecHits)[i]), kBufferSize);
1216 printf("Making Branch %s for rec. hits in chamber %d\n",branchname,i+1);
1221 //___________________________________________
1222 void AliRICH::SetTreeAddress()
1224 // Set branch address for the Hits and Digits Tree.
1225 char branchname[20];
1228 AliDetector::SetTreeAddress();
1231 TTree *treeH = gAlice->TreeH();
1232 TTree *treeD = gAlice->TreeD();
1233 TTree *treeR = gAlice->TreeR();
1237 branch = treeH->GetBranch("RICHPadHits");
1238 if (branch) branch->SetAddress(&fPadHits);
1241 branch = treeH->GetBranch("RICHCerenkov");
1242 if (branch) branch->SetAddress(&fCerenkovs);
1247 for (int i=0; i<kNCH; i++) {
1248 sprintf(branchname,"%sDigits%d",GetName(),i+1);
1250 branch = treeD->GetBranch(branchname);
1251 if (branch) branch->SetAddress(&((*fDchambers)[i]));
1256 for (i=0; i<kNCH; i++) {
1257 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
1259 branch = treeR->GetBranch(branchname);
1260 if (branch) branch->SetAddress(&((*fRawClusters)[i]));
1264 for (i=0; i<kNCH; i++) {
1265 sprintf(branchname,"%sRecHits%d",GetName(),i+1);
1267 branch = treeR->GetBranch(branchname);
1268 if (branch) branch->SetAddress(&((*fRecHits)[i]));
1274 //___________________________________________
1275 void AliRICH::ResetHits()
1277 // Reset number of clusters and the cluster array for this detector
1278 AliDetector::ResetHits();
1281 if (fPadHits) fPadHits->Clear();
1282 if (fCerenkovs) fCerenkovs->Clear();
1286 //____________________________________________
1287 void AliRICH::ResetDigits()
1290 // Reset number of digits and the digits array for this detector
1292 for ( int i=0;i<kNCH;i++ ) {
1293 if ((*fDchambers)[i]) (*fDchambers)[i]->Clear();
1294 if (fNdch) fNdch[i]=0;
1298 //____________________________________________
1299 void AliRICH::ResetRawClusters()
1302 // Reset number of raw clusters and the raw clust array for this detector
1304 for ( int i=0;i<kNCH;i++ ) {
1305 if ((*fRawClusters)[i]) ((TClonesArray*)(*fRawClusters)[i])->Clear();
1306 if (fNrawch) fNrawch[i]=0;
1310 //____________________________________________
1311 void AliRICH::ResetRecHits()
1314 // Reset number of raw clusters and the raw clust array for this detector
1317 for ( int i=0;i<kNCH;i++ ) {
1318 if ((*fRecHits)[i]) ((TClonesArray*)(*fRecHits)[i])->Clear();
1319 if (fNrechits) fNrechits[i]=0;
1323 //___________________________________________
1324 void AliRICH::SetGeometryModel(Int_t id, AliRICHGeometry *geometry)
1328 // Setter for the RICH geometry model
1332 ((AliRICHChamber*) (*fChambers)[id])->GeometryModel(geometry);
1335 //___________________________________________
1336 void AliRICH::SetSegmentationModel(Int_t id, AliSegmentation *segmentation)
1340 // Setter for the RICH segmentation model
1343 ((AliRICHChamber*) (*fChambers)[id])->SetSegmentationModel(segmentation);
1346 //___________________________________________
1347 void AliRICH::SetResponseModel(Int_t id, AliRICHResponse *response)
1351 // Setter for the RICH response model
1354 ((AliRICHChamber*) (*fChambers)[id])->ResponseModel(response);
1357 void AliRICH::SetReconstructionModel(Int_t id, AliRICHClusterFinder *reconst)
1361 // Setter for the RICH reconstruction model (clusters)
1364 ((AliRICHChamber*) (*fChambers)[id])->SetReconstructionModel(reconst);
1367 void AliRICH::SetNsec(Int_t id, Int_t nsec)
1371 // Sets the number of padplanes
1374 ((AliRICHChamber*) (*fChambers)[id])->SetNsec(nsec);
1378 //___________________________________________
1379 void AliRICH::StepManager()
1382 // Full Step Manager
1386 static Int_t vol[2];
1388 static Float_t hits[18];
1389 static Float_t ckovData[19];
1390 TLorentzVector position;
1391 TLorentzVector momentum;
1394 Float_t localPos[3];
1395 Float_t localMom[4];
1396 Float_t localTheta,localPhi;
1398 Float_t destep, step;
1401 Float_t coscerenkov;
1402 static Float_t eloss, xhit, yhit, tlength;
1403 const Float_t kBig=1.e10;
1405 TClonesArray &lhits = *fHits;
1406 TGeant3 *geant3 = (TGeant3*) gMC;
1407 TParticle *current = (TParticle*)(*gAlice->Particles())[gAlice->CurrentTrack()];
1409 //if (current->Energy()>1)
1412 // Only gas gap inside chamber
1413 // Tag chambers and record hits when track enters
1416 id=gMC->CurrentVolID(copy);
1417 Float_t cherenkovLoss=0;
1418 //gAlice->KeepTrack(gAlice->CurrentTrack());
1420 gMC->TrackPosition(position);
1424 //bzero((char *)ckovData,sizeof(ckovData)*19);
1425 ckovData[1] = pos[0]; // X-position for hit
1426 ckovData[2] = pos[1]; // Y-position for hit
1427 ckovData[3] = pos[2]; // Z-position for hit
1428 //ckovData[11] = gAlice->CurrentTrack();
1430 //printf("\n+++++++++++\nTrack: %d\n++++++++++++\n",gAlice->CurrentTrack());
1432 //AliRICH *RICH = (AliRICH *) gAlice->GetDetector("RICH");
1434 /********************Store production parameters for Cerenkov photons************************/
1435 //is it a Cerenkov photon?
1436 if (gMC->TrackPid() == 50000050) {
1438 //if (gMC->VolId("GAP ")==gMC->CurrentVolID(copy))
1440 Float_t ckovEnergy = current->Energy();
1441 //energy interval for tracking
1442 if (ckovEnergy > 5.6e-09 && ckovEnergy < 7.8e-09 )
1443 //if (ckovEnergy > 0)
1445 if (gMC->IsTrackEntering()){ //is track entering?
1446 //printf("Track entered (1)\n");
1447 if (gMC->VolId("FRE1")==gMC->CurrentVolID(copy) || gMC->VolId("FRE2")==gMC->CurrentVolID(copy))
1449 if (geant3->Gctrak()->nstep<1){ //is it the first step?
1450 //printf("I'm in!\n");
1451 Int_t mother = current->GetFirstMother();
1453 //printf("Second Mother:%d\n",current->GetSecondMother());
1455 ckovData[10] = mother;
1456 ckovData[11] = gAlice->CurrentTrack();
1457 ckovData[12] = 1; //Media where photon was produced 1->Freon, 2->Quarz
1458 //printf("Produced in FREO\n");
1461 //printf("Index: %d\n",fCkovNumber);
1462 } //first step question
1465 if (geant3->Gctrak()->nstep<1){ //is it first step?
1466 if (gMC->VolId("QUAR")==gMC->CurrentVolID(copy)) //is it in quarz?
1469 //printf("Produced in QUAR\n");
1471 } //first step question
1473 //printf("Before %d\n",fFreonProd);
1474 } //track entering question
1476 if (ckovData[12] == 1) //was it produced in Freon?
1477 //if (fFreonProd == 1)
1479 if (gMC->IsTrackEntering()){ //is track entering?
1480 //printf("Track entered (2)\n");
1481 //printf("Current volume (should be META): %s\n",gMC->CurrentVolName());
1482 //printf("VolId: %d, CurrentVolID: %d\n",gMC->VolId("META"),gMC->CurrentVolID(copy));
1483 if (gMC->VolId("META")==gMC->CurrentVolID(copy)) //is it in gap?
1485 //printf("Got in META\n");
1486 gMC->TrackMomentum(momentum);
1491 // Z-position for hit
1494 /**************** Photons lost in second grid have to be calculated by hand************/
1496 Float_t cophi = TMath::Cos(TMath::ATan2(mom[0], mom[1]));
1497 Float_t t = (1. - .025 / cophi) * (1. - .05 / cophi);
1499 //printf("grid calculation:%f\n",t);
1501 geant3->StopTrack();
1503 AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
1504 //printf("Added One (1)!\n");
1505 //printf("Lost one in grid\n");
1507 /**********************************************************************************/
1510 //printf("Current volume (should be CSI) (1): %s\n",gMC->CurrentVolName());
1511 //printf("VolId: %d, CurrentVolID: %d\n",gMC->VolId("CSI "),gMC->CurrentVolID(copy));
1512 if (gMC->VolId("CSI ")==gMC->CurrentVolID(copy)) //is it in csi?
1514 //printf("Got in CSI\n");
1515 gMC->TrackMomentum(momentum);
1521 /********* Photons lost by Fresnel reflection have to be calculated by hand********/
1522 /***********************Cerenkov phtons (always polarised)*************************/
1524 Float_t cophi = TMath::Cos(TMath::ATan2(mom[0], mom[1]));
1525 Float_t t = Fresnel(ckovEnergy*1e9,cophi,1);
1528 geant3->StopTrack();
1530 AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
1531 //printf("Added One (2)!\n");
1532 //printf("Lost by Fresnel\n");
1534 /**********************************************************************************/
1539 /********************Evaluation of losses************************/
1540 /******************still in the old fashion**********************/
1542 Int_t i1 = geant3->Gctrak()->nmec; //number of physics mechanisms acting on the particle
1543 for (Int_t i = 0; i < i1; ++i) {
1545 if (geant3->Gctrak()->lmec[i] == 106) { //was it reflected
1547 if (gMC->VolId("FRE1")==gMC->CurrentVolID(copy) || gMC->VolId("FRE2")==gMC->CurrentVolID(copy))
1549 if (gMC->CurrentVolID(copy) == gMC->VolId("QUAR"))
1551 //geant3->StopTrack();
1552 //AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
1553 } //reflection question
1556 else if (geant3->Gctrak()->lmec[i] == 101) { //was it absorbed?
1557 //printf("Got in absorption\n");
1559 if (gMC->VolId("FRE1")==gMC->CurrentVolID(copy) || gMC->VolId("FRE2")==gMC->CurrentVolID(copy))
1561 if (gMC->CurrentVolID(copy) == gMC->VolId("QUAR"))
1563 if (gMC->CurrentVolID(copy) == gMC->VolId("META"))
1565 if (gMC->CurrentVolID(copy) == gMC->VolId("GAP "))
1568 if (gMC->CurrentVolID(copy) == gMC->VolId("SRIC"))
1572 if (gMC->CurrentVolID(copy) == gMC->VolId("CSI ")) {
1575 geant3->StopTrack();
1576 AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
1577 //printf("Added One (3)!\n");
1578 //printf("Added cerenkov %d\n",fCkovNumber);
1579 } //absorption question
1582 // Photon goes out of tracking scope
1583 else if (geant3->Gctrak()->lmec[i] == 30) { //is it below energy treshold?
1585 geant3->StopTrack();
1586 AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
1587 //printf("Added One (4)!\n");
1588 } // energy treshold question
1589 } //number of mechanisms cycle
1590 /**********************End of evaluation************************/
1591 } //freon production question
1592 } //energy interval question
1593 //}//inside the proximity gap question
1594 } //cerenkov photon question
1596 /**************************************End of Production Parameters Storing*********************/
1599 /*******************************Treat photons that hit the CsI (Ckovs and Feedbacks)************/
1601 if (gMC->TrackPid() == 50000050 || gMC->TrackPid() == 50000051) {
1602 //printf("Cerenkov\n");
1603 if (gMC->VolId("CSI ")==gMC->CurrentVolID(copy))
1605 //printf("Current volume (should be CSI) (2): %s\n",gMC->CurrentVolName());
1606 //printf("VolId: %d, CurrentVolID: %d\n",gMC->VolId("CSI "),gMC->CurrentVolID(copy));
1607 //printf("Got in CSI\n");
1608 if (gMC->Edep() > 0.){
1609 gMC->TrackPosition(position);
1610 gMC->TrackMomentum(momentum);
1618 Double_t tc = mom[0]*mom[0]+mom[1]*mom[1];
1619 Double_t rt = TMath::Sqrt(tc);
1620 theta = Float_t(TMath::ATan2(rt,Double_t(mom[2])))*kRaddeg;
1621 phi = Float_t(TMath::ATan2(Double_t(mom[1]),Double_t(mom[0])))*kRaddeg;
1622 gMC->Gmtod(pos,localPos,1);
1623 gMC->Gmtod(mom,localMom,2);
1625 gMC->CurrentVolOffID(2,copy);
1629 //Int_t sector=((AliRICHChamber*) (*fChambers)[idvol])
1630 //->Sector(localPos[0], localPos[2]);
1631 //printf("Sector:%d\n",sector);
1633 /*if (gMC->TrackPid() == 50000051){
1635 printf("Feedbacks:%d\n",fFeedbacks);
1638 ((AliRICHChamber*) (*fChambers)[idvol])
1639 ->SigGenInit(localPos[0], localPos[2], localPos[1]);
1641 ckovData[0] = gMC->TrackPid(); // particle type
1642 ckovData[1] = pos[0]; // X-position for hit
1643 ckovData[2] = pos[1]; // Y-position for hit
1644 ckovData[3] = pos[2]; // Z-position for hit
1645 ckovData[4] = theta; // theta angle of incidence
1646 ckovData[5] = phi; // phi angle of incidence
1647 ckovData[8] = (Float_t) fNPadHits; // first padhit
1648 ckovData[9] = -1; // last pad hit
1649 ckovData[13] = 4; // photon was detected
1650 ckovData[14] = mom[0];
1651 ckovData[15] = mom[1];
1652 ckovData[16] = mom[2];
1654 destep = gMC->Edep();
1655 gMC->SetMaxStep(kBig);
1656 cherenkovLoss += destep;
1657 ckovData[7]=cherenkovLoss;
1659 nPads = MakePadHits(localPos[0],localPos[2],cherenkovLoss,idvol,kCerenkov);
1660 if (fNPadHits > (Int_t)ckovData[8]) {
1661 ckovData[8]= ckovData[8]+1;
1662 ckovData[9]= (Float_t) fNPadHits;
1665 ckovData[17] = nPads;
1666 //printf("nPads:%d",nPads);
1668 //TClonesArray *Hits = RICH->Hits();
1669 AliRICHHit *mipHit = (AliRICHHit*) (fHits->UncheckedAt(0));
1672 mom[0] = current->Px();
1673 mom[1] = current->Py();
1674 mom[2] = current->Pz();
1675 Float_t mipPx = mipHit->fMomX;
1676 Float_t mipPy = mipHit->fMomY;
1677 Float_t mipPz = mipHit->fMomZ;
1679 Float_t r = mom[0]*mom[0] + mom[1]*mom[1] + mom[2]*mom[2];
1680 Float_t rt = TMath::Sqrt(r);
1681 Float_t mipR = mipPx*mipPx + mipPy*mipPy + mipPz*mipPz;
1682 Float_t mipRt = TMath::Sqrt(mipR);
1685 coscerenkov = (mom[0]*mipPx + mom[1]*mipPy + mom[2]*mipPz)/(rt*mipRt);
1691 Float_t cherenkov = TMath::ACos(coscerenkov);
1692 ckovData[18]=cherenkov;
1696 AddHit(gAlice->CurrentTrack(),vol,ckovData);
1697 AddCerenkov(gAlice->CurrentTrack(),vol,ckovData);
1698 //printf("Added One (5)!\n");
1705 /***********************************************End of photon hits*********************************************/
1708 /**********************************************Charged particles treatment*************************************/
1710 else if (gMC->TrackCharge())
1714 /*if (gMC->IsTrackEntering())
1716 hits[13]=20;//is track entering?
1718 if (gMC->VolId("FRE1")==gMC->CurrentVolID(copy) || gMC->VolId("FRE2")==gMC->CurrentVolID(copy))
1723 if (gMC->VolId("GAP ")== gMC->CurrentVolID(copy)) {
1724 // Get current particle id (ipart), track position (pos) and momentum (mom)
1726 gMC->CurrentVolOffID(3,copy);
1730 //Int_t sector=((AliRICHChamber*) (*fChambers)[idvol])
1731 //->Sector(localPos[0], localPos[2]);
1732 //printf("Sector:%d\n",sector);
1734 gMC->TrackPosition(position);
1735 gMC->TrackMomentum(momentum);
1743 gMC->Gmtod(pos,localPos,1);
1744 gMC->Gmtod(mom,localMom,2);
1746 ipart = gMC->TrackPid();
1748 // momentum loss and steplength in last step
1749 destep = gMC->Edep();
1750 step = gMC->TrackStep();
1753 // record hits when track enters ...
1754 if( gMC->IsTrackEntering()) {
1755 // gMC->SetMaxStep(fMaxStepGas);
1756 Double_t tc = mom[0]*mom[0]+mom[1]*mom[1];
1757 Double_t rt = TMath::Sqrt(tc);
1758 theta = Float_t(TMath::ATan2(rt,Double_t(mom[2])))*kRaddeg;
1759 phi = Float_t(TMath::ATan2(Double_t(mom[1]),Double_t(mom[0])))*kRaddeg;
1762 Double_t localTc = localMom[0]*localMom[0]+localMom[2]*localMom[2];
1763 Double_t localRt = TMath::Sqrt(localTc);
1764 localTheta = Float_t(TMath::ATan2(localRt,Double_t(localMom[1])))*kRaddeg;
1765 localPhi = Float_t(TMath::ATan2(Double_t(localMom[2]),Double_t(localMom[0])))*kRaddeg;
1767 hits[0] = Float_t(ipart); // particle type
1768 hits[1] = localPos[0]; // X-position for hit
1769 hits[2] = localPos[1]; // Y-position for hit
1770 hits[3] = localPos[2]; // Z-position for hit
1771 hits[4] = localTheta; // theta angle of incidence
1772 hits[5] = localPhi; // phi angle of incidence
1773 hits[8] = (Float_t) fNPadHits; // first padhit
1774 hits[9] = -1; // last pad hit
1775 hits[13] = fFreonProd; // did id hit the freon?
1784 Chamber(idvol).LocaltoGlobal(localPos,hits+1);
1787 //To make chamber coordinates x-y had to pass localPos[0], localPos[2]
1790 // Only if not trigger chamber
1793 // Initialize hit position (cursor) in the segmentation model
1794 ((AliRICHChamber*) (*fChambers)[idvol])
1795 ->SigGenInit(localPos[0], localPos[2], localPos[1]);
1800 // Calculate the charge induced on a pad (disintegration) in case
1802 // Mip left chamber ...
1803 if( gMC->IsTrackExiting() || gMC->IsTrackStop() || gMC->IsTrackDisappeared()){
1804 gMC->SetMaxStep(kBig);
1809 // Only if not trigger chamber
1813 if(gMC->TrackPid() == kNeutron)
1814 printf("\n\n\n\n\n Neutron Making Pad Hit!!! \n\n\n\n");
1815 nPads = MakePadHits(xhit,yhit,eloss,idvol,kMip);
1817 //printf("nPads:%d",nPads);
1823 if (fNPadHits > (Int_t)hits[8]) {
1825 hits[9]= (Float_t) fNPadHits;
1829 new(lhits[fNhits++]) AliRICHHit(fIshunt,gAlice->CurrentTrack(),vol,hits);
1832 // Check additional signal generation conditions
1833 // defined by the segmentation
1834 // model (boundary crossing conditions)
1836 (((AliRICHChamber*) (*fChambers)[idvol])
1837 ->SigGenCond(localPos[0], localPos[2], localPos[1]))
1839 ((AliRICHChamber*) (*fChambers)[idvol])
1840 ->SigGenInit(localPos[0], localPos[2], localPos[1]);
1843 if(gMC->TrackPid() == kNeutron)
1844 printf("\n\n\n\n\n Neutron Making Pad Hit!!! \n\n\n\n");
1845 nPads = MakePadHits(xhit,yhit,eloss,idvol,kMip);
1847 //printf("Npads:%d",NPads);
1854 // nothing special happened, add up energy loss
1861 /*************************************************End of MIP treatment**************************************/
1865 void AliRICH::FindClusters(Int_t nev,Int_t lastEntry)
1869 // Loop on chambers and on cathode planes
1871 for (Int_t icat=1;icat<2;icat++) {
1872 gAlice->ResetDigits();
1873 gAlice->TreeD()->GetEvent(1); // spurious +1 ...
1874 for (Int_t ich=0;ich<kNCH;ich++) {
1875 AliRICHChamber* iChamber=(AliRICHChamber*) (*fChambers)[ich];
1876 TClonesArray *pRICHdigits = this->DigitsAddress(ich);
1877 if (pRICHdigits == 0)
1880 // Get ready the current chamber stuff
1882 AliRICHResponse* response = iChamber->GetResponseModel();
1883 AliSegmentation* seg = iChamber->GetSegmentationModel();
1884 AliRICHClusterFinder* rec = iChamber->GetReconstructionModel();
1886 rec->SetSegmentation(seg);
1887 rec->SetResponse(response);
1888 rec->SetDigits(pRICHdigits);
1889 rec->SetChamber(ich);
1890 if (nev==0) rec->CalibrateCOG();
1891 rec->FindRawClusters();
1894 fRch=RawClustAddress(ich);
1898 gAlice->TreeR()->Fill();
1900 for (int i=0;i<kNCH;i++) {
1901 fRch=RawClustAddress(i);
1902 int nraw=fRch->GetEntriesFast();
1903 printf ("Chamber %d, raw clusters %d\n",i,nraw);
1911 sprintf(hname,"TreeR%d",nev);
1912 gAlice->TreeR()->Write(hname,kOverwrite,0);
1913 gAlice->TreeR()->Reset();
1915 //gObjectTable->Print();
1919 //______________________________________________________________________________
1920 void AliRICH::Streamer(TBuffer &R__b)
1922 // Stream an object of class AliRICH.
1923 AliRICHChamber *iChamber;
1924 AliSegmentation *segmentation;
1925 AliRICHResponse *response;
1926 TClonesArray *digitsaddress;
1927 TClonesArray *rawcladdress;
1928 TClonesArray *rechitaddress;
1930 if (R__b.IsReading()) {
1931 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1932 AliDetector::Streamer(R__b);
1934 R__b >> fPadHits; // diff
1935 R__b >> fNcerenkovs;
1936 R__b >> fCerenkovs; // diff
1938 R__b >> fRawClusters;
1939 R__b >> fRecHits; //diff
1940 R__b >> fDebugLevel; //diff
1941 R__b.ReadStaticArray(fNdch);
1942 R__b.ReadStaticArray(fNrawch);
1943 R__b.ReadStaticArray(fNrechits);
1946 // Stream chamber related information
1947 for (Int_t i =0; i<kNCH; i++) {
1948 iChamber=(AliRICHChamber*) (*fChambers)[i];
1949 iChamber->Streamer(R__b);
1950 segmentation=iChamber->GetSegmentationModel();
1951 segmentation->Streamer(R__b);
1952 response=iChamber->GetResponseModel();
1953 response->Streamer(R__b);
1954 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1955 rawcladdress->Streamer(R__b);
1956 rechitaddress=(TClonesArray*) (*fRecHits)[i];
1957 rechitaddress->Streamer(R__b);
1958 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1959 digitsaddress->Streamer(R__b);
1961 R__b >> fDebugLevel;
1962 R__b >> fCkovNumber;
1969 R__b >> fLostAquarz;
1977 R__b >> fLostFresnel;
1980 R__b.WriteVersion(AliRICH::IsA());
1981 AliDetector::Streamer(R__b);
1983 R__b << fPadHits; // diff
1984 R__b << fNcerenkovs;
1985 R__b << fCerenkovs; // diff
1987 R__b << fRawClusters;
1988 R__b << fRecHits; //diff
1989 R__b << fDebugLevel; //diff
1990 R__b.WriteArray(fNdch, kNCH);
1991 R__b.WriteArray(fNrawch, kNCH);
1992 R__b.WriteArray(fNrechits, kNCH);
1995 // Stream chamber related information
1996 for (Int_t i =0; i<kNCH; i++) {
1997 iChamber=(AliRICHChamber*) (*fChambers)[i];
1998 iChamber->Streamer(R__b);
1999 segmentation=iChamber->GetSegmentationModel();
2000 segmentation->Streamer(R__b);
2001 response=iChamber->GetResponseModel();
2002 response->Streamer(R__b);
2003 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
2004 rawcladdress->Streamer(R__b);
2005 rechitaddress=(TClonesArray*) (*fRecHits)[i];
2006 rechitaddress->Streamer(R__b);
2007 digitsaddress=(TClonesArray*) (*fDchambers)[i];
2008 digitsaddress->Streamer(R__b);
2010 R__b << fDebugLevel;
2011 R__b << fCkovNumber;
2018 R__b << fLostAquarz;
2026 R__b << fLostFresnel;
2029 AliRICHPadHit* AliRICH::FirstPad(AliRICHHit* hit,TClonesArray *clusters )
2032 // Initialise the pad iterator
2033 // Return the address of the first padhit for hit
2034 TClonesArray *theClusters = clusters;
2035 Int_t nclust = theClusters->GetEntriesFast();
2036 if (nclust && hit->fPHlast > 0) {
2037 sMaxIterPad=Int_t(hit->fPHlast);
2038 sCurIterPad=Int_t(hit->fPHfirst);
2039 return (AliRICHPadHit*) clusters->UncheckedAt(sCurIterPad-1);
2046 AliRICHPadHit* AliRICH::NextPad(TClonesArray *clusters)
2049 // Iterates over pads
2052 if (sCurIterPad <= sMaxIterPad) {
2053 return (AliRICHPadHit*) clusters->UncheckedAt(sCurIterPad-1);
2060 void AliRICH::Digitise(Int_t nev, Int_t flag, Option_t *option,Text_t *filename)
2062 // keep galice.root for signal and name differently the file for
2063 // background when add! otherwise the track info for signal will be lost !
2065 static Bool_t first=kTRUE;
2066 static TFile *pFile;
2067 char *addBackground = strstr(option,"Add");
2070 FILE* points; //these will be the digits...
2072 points=fopen("points.dat","w");
2074 AliRICHChamber* iChamber;
2075 AliSegmentation* segmentation;
2080 TObjArray *list=new TObjArray;
2081 static TClonesArray *pAddress=0;
2082 if(!pAddress) pAddress=new TClonesArray("TVector",1000);
2085 AliRICH *pRICH = (AliRICH *) gAlice->GetDetector("RICH");
2086 AliHitMap* pHitMap[10];
2088 for (i=0; i<10; i++) {pHitMap[i]=0;}
2089 if (addBackground ) {
2092 cout<<"filename"<<fFileName<<endl;
2093 pFile=new TFile(fFileName);
2094 cout<<"I have opened "<<fFileName<<" file "<<endl;
2095 fHits2 = new TClonesArray("AliRICHHit",1000 );
2096 fClusters2 = new TClonesArray("AliRICHPadHit",10000);
2100 // Get Hits Tree header from file
2101 if(fHits2) fHits2->Clear();
2102 if(fClusters2) fClusters2->Clear();
2103 if(TrH1) delete TrH1;
2107 sprintf(treeName,"TreeH%d",nev);
2108 TrH1 = (TTree*)gDirectory->Get(treeName);
2110 printf("ERROR: cannot find Hits Tree for event:%d\n",nev);
2112 // Set branch addresses
2114 char branchname[20];
2115 sprintf(branchname,"%s",GetName());
2116 if (TrH1 && fHits2) {
2117 branch = TrH1->GetBranch(branchname);
2118 if (branch) branch->SetAddress(&fHits2);
2120 if (TrH1 && fClusters2) {
2121 branch = TrH1->GetBranch("RICHCluster");
2122 if (branch) branch->SetAddress(&fClusters2);
2129 for (i =0; i<kNCH; i++) {
2130 iChamber=(AliRICHChamber*) (*fChambers)[i];
2131 segmentation=iChamber->GetSegmentationModel(1);
2132 pHitMap[i] = new AliRICHHitMapA1(segmentation, list);
2138 TTree *treeH = gAlice->TreeH();
2139 Int_t ntracks =(Int_t) treeH->GetEntries();
2140 for (Int_t track=0; track<ntracks; track++) {
2141 gAlice->ResetHits();
2142 treeH->GetEvent(track);
2145 for(AliRICHHit* mHit=(AliRICHHit*)pRICH->FirstHit(-1);
2147 mHit=(AliRICHHit*)pRICH->NextHit())
2150 Int_t nch = mHit->fChamber-1; // chamber number
2151 Int_t index = mHit->Track();
2152 if (nch >kNCH) continue;
2153 iChamber = &(pRICH->Chamber(nch));
2155 TParticle *current = (TParticle*)(*gAlice->Particles())[index];
2157 if (current->GetPdgCode() >= 50000050)
2159 TParticle *motherofcurrent = (TParticle*)(*gAlice->Particles())[current->GetFirstMother()];
2160 particle = motherofcurrent->GetPdgCode();
2164 particle = current->GetPdgCode();
2168 //printf("Flag:%d\n",flag);
2169 //printf("Track:%d\n",track);
2170 //printf("Particle:%d\n",particle);
2175 if(TMath::Abs(particle)==211 || TMath::Abs(particle)==111)
2179 if(TMath::Abs(particle)==321 || TMath::Abs(particle)==130 || TMath::Abs(particle)==310
2180 || TMath::Abs(particle)==311)
2183 if (flag == 3 && TMath::Abs(particle)==2212)
2186 if (flag == 4 && TMath::Abs(particle)==13)
2189 if (flag == 5 && TMath::Abs(particle)==11)
2192 if (flag == 6 && TMath::Abs(particle)==2112)
2196 //printf ("Particle: %d, Flag: %d, Digitise: %d\n",particle,flag,digitise);
2203 // Loop over pad hits
2204 for (AliRICHPadHit* mPad=
2205 (AliRICHPadHit*)pRICH->FirstPad(mHit,fPadHits);
2207 mPad=(AliRICHPadHit*)pRICH->NextPad(fPadHits))
2209 Int_t cathode = mPad->fCathode; // cathode number
2210 Int_t ipx = mPad->fPadX; // pad number on X
2211 Int_t ipy = mPad->fPadY; // pad number on Y
2212 Int_t iqpad = mPad->fQpad; // charge per pad
2215 //printf("X:%d, Y:%d, Q:%d\n",ipx,ipy,iqpad);
2217 Float_t thex, they, thez;
2218 segmentation=iChamber->GetSegmentationModel(cathode);
2219 segmentation->GetPadC(ipx,ipy,thex,they,thez);
2220 new((*pAddress)[countadr++]) TVector(2);
2221 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
2222 trinfo(0)=(Float_t)track;
2223 trinfo(1)=(Float_t)iqpad;
2229 AliRICHTransientDigit* pdigit;
2230 // build the list of fired pads and update the info
2231 if (!pHitMap[nch]->TestHit(ipx, ipy)) {
2232 list->AddAtAndExpand(new AliRICHTransientDigit(nch,digits),counter);
2233 pHitMap[nch]->SetHit(ipx, ipy, counter);
2235 pdigit=(AliRICHTransientDigit*)list->At(list->GetLast());
2237 TObjArray *trlist=(TObjArray*)pdigit->TrackList();
2238 trlist->Add(&trinfo);
2240 pdigit=(AliRICHTransientDigit*) pHitMap[nch]->GetHit(ipx, ipy);
2242 (*pdigit).fSignal+=iqpad;
2243 // update list of tracks
2244 TObjArray* trlist=(TObjArray*)pdigit->TrackList();
2245 Int_t lastEntry=trlist->GetLast();
2246 TVector *ptrkP=(TVector*)trlist->At(lastEntry);
2247 TVector &ptrk=*ptrkP;
2248 Int_t lastTrack=Int_t(ptrk(0));
2249 Int_t lastCharge=Int_t(ptrk(1));
2250 if (lastTrack==track) {
2252 trlist->RemoveAt(lastEntry);
2253 trinfo(0)=lastTrack;
2254 trinfo(1)=lastCharge;
2255 trlist->AddAt(&trinfo,lastEntry);
2257 trlist->Add(&trinfo);
2259 // check the track list
2260 Int_t nptracks=trlist->GetEntriesFast();
2262 printf("Attention - tracks: %d (>2)\n",nptracks);
2263 //printf("cat,nch,ix,iy %d %d %d %d \n",icat+1,nch,ipx,ipy);
2264 for (Int_t tr=0;tr<nptracks;tr++) {
2265 TVector *pptrkP=(TVector*)trlist->At(tr);
2266 TVector &pptrk=*pptrkP;
2267 trk[tr]=Int_t(pptrk(0));
2268 chtrk[tr]=Int_t(pptrk(1));
2270 } // end if nptracks
2272 } //end loop over clusters
2273 }// track type condition
2277 // open the file with background
2279 if (addBackground ) {
2280 ntracks =(Int_t)TrH1->GetEntries();
2281 //printf("background - icat,ntracks1 %d %d\n",icat,ntracks);
2282 //printf("background - Start loop over tracks \n");
2286 for (Int_t trak=0; trak<ntracks; trak++) {
2287 if (fHits2) fHits2->Clear();
2288 if (fClusters2) fClusters2->Clear();
2289 TrH1->GetEvent(trak);
2293 for(int j=0;j<fHits2->GetEntriesFast();++j)
2295 mHit=(AliRICHHit*) (*fHits2)[j];
2296 Int_t nch = mHit->fChamber-1; // chamber number
2297 if (nch >6) continue;
2298 iChamber = &(pRICH->Chamber(nch));
2299 Int_t rmin = (Int_t)iChamber->RInner();
2300 Int_t rmax = (Int_t)iChamber->ROuter();
2302 // Loop over pad hits
2303 for (AliRICHPadHit* mPad=
2304 (AliRICHPadHit*)pRICH->FirstPad(mHit,fClusters2);
2306 mPad=(AliRICHPadHit*)pRICH->NextPad(fClusters2))
2308 Int_t cathode = mPad->fCathode; // cathode number
2309 Int_t ipx = mPad->fPadX; // pad number on X
2310 Int_t ipy = mPad->fPadY; // pad number on Y
2311 Int_t iqpad = mPad->fQpad; // charge per pad
2313 Float_t thex, they, thez;
2314 segmentation=iChamber->GetSegmentationModel(cathode);
2315 segmentation->GetPadC(ipx,ipy,thex,they,thez);
2316 Float_t rpad=TMath::Sqrt(thex*thex+they*they);
2317 if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
2318 new((*pAddress)[countadr++]) TVector(2);
2319 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
2320 trinfo(0)=-1; // tag background
2325 if (trak <4 && nch==0)
2326 printf("bgr - pHitMap[nch]->TestHit(ipx, ipy),trak %d %d\n",
2327 pHitMap[nch]->TestHit(ipx, ipy),trak);
2328 AliRICHTransientDigit* pdigit;
2329 // build the list of fired pads and update the info
2330 if (!pHitMap[nch]->TestHit(ipx, ipy)) {
2331 list->AddAtAndExpand(new AliRICHTransientDigit(nch,digits),counter);
2333 pHitMap[nch]->SetHit(ipx, ipy, counter);
2335 printf("bgr new elem in list - counter %d\n",counter);
2337 pdigit=(AliRICHTransientDigit*)list->At(list->GetLast());
2339 TObjArray *trlist=(TObjArray*)pdigit->TrackList();
2340 trlist->Add(&trinfo);
2342 pdigit=(AliRICHTransientDigit*) pHitMap[nch]->GetHit(ipx, ipy);
2344 (*pdigit).fSignal+=iqpad;
2345 // update list of tracks
2346 TObjArray* trlist=(TObjArray*)pdigit->TrackList();
2347 Int_t lastEntry=trlist->GetLast();
2348 TVector *ptrkP=(TVector*)trlist->At(lastEntry);
2349 TVector &ptrk=*ptrkP;
2350 Int_t lastTrack=Int_t(ptrk(0));
2351 if (lastTrack==-1) {
2354 trlist->Add(&trinfo);
2356 // check the track list
2357 Int_t nptracks=trlist->GetEntriesFast();
2359 for (Int_t tr=0;tr<nptracks;tr++) {
2360 TVector *pptrkP=(TVector*)trlist->At(tr);
2361 TVector &pptrk=*pptrkP;
2362 trk[tr]=Int_t(pptrk(0));
2363 chtrk[tr]=Int_t(pptrk(1));
2365 } // end if nptracks
2367 } //end loop over clusters
2370 TTree *fAli=gAlice->TreeK();
2371 if (fAli) pFile =fAli->GetCurrentFile();
2377 //cout<<"Start filling digits \n "<<endl;
2378 Int_t nentries=list->GetEntriesFast();
2379 //printf(" \n \n nentries %d \n",nentries);
2381 // start filling the digits
2383 for (Int_t nent=0;nent<nentries;nent++) {
2384 AliRICHTransientDigit *address=(AliRICHTransientDigit*)list->At(nent);
2385 if (address==0) continue;
2387 Int_t ich=address->fChamber;
2388 Int_t q=address->fSignal;
2389 iChamber=(AliRICHChamber*) (*fChambers)[ich];
2390 AliRICHResponse * response=iChamber->GetResponseModel();
2391 Int_t adcmax= (Int_t) response->MaxAdc();
2394 // add white noise and do zero-suppression and signal truncation (new electronics,old electronics gaus 1.2,0.2)
2395 //printf("Treshold: %d\n",iChamber->fTresh->GetHitIndex(address->fPadX,address->fPadY));
2396 Int_t pedestal = iChamber->fTresh->GetHitIndex(address->fPadX,address->fPadY);
2398 //printf("Pedestal:%d\n",pedestal);
2400 Float_t treshold = (pedestal + 4*2.2);
2402 Float_t meanNoise = gRandom->Gaus(2.2, 0.3);
2403 Float_t noise = gRandom->Gaus(0, meanNoise);
2404 q+=(Int_t)(noise + pedestal);
2405 //q+=(Int_t)(noise);
2406 // magic number to be parametrised !!!
2413 if ( q >= adcmax) q=adcmax;
2414 digits[0]=address->fPadX;
2415 digits[1]=address->fPadY;
2418 TObjArray* trlist=(TObjArray*)address->TrackList();
2419 Int_t nptracks=trlist->GetEntriesFast();
2421 // this was changed to accomodate the real number of tracks
2422 if (nptracks > 10) {
2423 cout<<"Attention - tracks > 10 "<<nptracks<<endl;
2427 printf("Attention - tracks > 2 %d \n",nptracks);
2428 //printf("cat,ich,ix,iy,q %d %d %d %d %d \n",
2429 //icat,ich,digits[0],digits[1],q);
2431 for (Int_t tr=0;tr<nptracks;tr++) {
2432 TVector *ppP=(TVector*)trlist->At(tr);
2434 tracks[tr]=Int_t(pp(0));
2435 charges[tr]=Int_t(pp(1));
2436 } //end loop over list of tracks for one pad
2437 if (nptracks < 10 ) {
2438 for (Int_t t=nptracks; t<10; t++) {
2445 fprintf(points,"%4d, %4d, %4d\n",digits[0],digits[1],digits[2]);
2448 pRICH->AddDigits(ich,tracks,charges,digits);
2450 gAlice->TreeD()->Fill();
2453 for(Int_t ii=0;ii<kNCH;++ii) {
2461 //TTree *TD=gAlice->TreeD();
2462 //Stat_t ndig=TD->GetEntries();
2463 //cout<<"number of digits "<<ndig<<endl;
2465 for (int k=0;k<kNCH;k++) {
2466 fDch= pRICH->DigitsAddress(k);
2467 int ndigit=fDch->GetEntriesFast();
2468 printf ("Chamber %d digits %d \n",k,ndigit);
2470 pRICH->ResetDigits();
2472 sprintf(hname,"TreeD%d",nev);
2473 gAlice->TreeD()->Write(hname,kOverwrite,0);
2476 // gAlice->TreeD()->Reset();
2479 // gObjectTable->Print();
2482 AliRICH& AliRICH::operator=(const AliRICH& rhs)
2484 // Assignment operator
2489 Int_t AliRICH::MakePadHits(Float_t xhit,Float_t yhit,Float_t eloss, Int_t idvol, ResponseType res)
2492 // Calls the charge disintegration method of the current chamber and adds
2493 // the simulated cluster to the root treee
2496 Float_t newclust[6][500];
2500 // Integrated pulse height on chamber
2504 ((AliRICHChamber*) (*fChambers)[idvol])->DisIntegration(eloss, xhit, yhit, nnew, newclust, res);
2509 for (Int_t i=0; i<nnew; i++) {
2510 if (Int_t(newclust[3][i]) > 0) {
2513 clhits[1] = Int_t(newclust[5][i]);
2515 clhits[2] = Int_t(newclust[0][i]);
2517 clhits[3] = Int_t(newclust[1][i]);
2519 clhits[4] = Int_t(newclust[2][i]);
2521 clhits[5] = Int_t(newclust[3][i]);
2522 // Pad: chamber sector
2523 clhits[6] = Int_t(newclust[4][i]);