]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RICH/AliRICH.cxx
Introduce TLorentzVector in AliMC::GetSecondary. Thanks to I.Hrivnacova
[u/mrichter/AliRoot.git] / RICH / AliRICH.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /*
17 $Log$
18 Revision 1.12  1999/09/29 09:24:29  fca
19 Introduction of the Copyright and cvs Log
20
21 */
22
23 ////////////////////////////////////////////////
24 //  Manager and hits classes for set:RICH     //
25 ////////////////////////////////////////////////
26
27 #include <TBRIK.h>
28 #include <TTUBE.h>
29 #include <TNode.h> 
30 #include <TRandom.h> 
31 #include <TObject.h>
32 #include <TVector.h>
33 #include <TObjArray.h>
34
35 #include "AliRICH.h"
36 #include "AliRICHHitMap.h"
37 #include "AliRun.h"
38 #include "AliMC.h"
39 #include "iostream.h"
40 #include "AliCallf77.h" 
41
42 // Static variables for the pad-hit iterator routines
43 static Int_t sMaxIterPad=0;
44 static Int_t sCurIterPad=0;
45 static TClonesArray *fClusters2;
46 static TClonesArray *fHits2;
47  
48 ClassImp(AliRICH)
49     
50 //___________________________________________
51 AliRICH::AliRICH()
52 {
53     fIshunt     = 0;
54     fHits       = 0;
55     fClusters   = 0;
56     fNclusters  = 0;
57     fDchambers  = 0;
58     fRecClusters= 0;
59     fCerenkovs  = 0;
60     fNdch       = 0;
61 }
62
63 //___________________________________________
64 AliRICH::AliRICH(const char *name, const char *title)
65     : AliDetector(name,title)
66 {
67 //Begin_Html
68 /*
69   <img src="gif/alirich.gif">
70 */
71 //End_Html
72     
73     fHits       = new TClonesArray("AliRICHhit",1000  );
74     fClusters   = new TClonesArray("AliRICHcluster",10000);
75     fCerenkovs  = new TClonesArray("AliRICHCerenkov",20000);
76     fNclusters  =  0;
77     fIshunt     =  0;
78     
79     fNdch      = new Int_t[7];
80     
81     fDchambers = new TObjArray(7);
82     
83     Int_t i;
84    
85     for (i=0; i<7 ;i++) {
86         (*fDchambers)[i] = new TClonesArray("AliRICHdigit",10000); 
87         fNdch[i]=0;
88     }
89     
90     fRecClusters=new TObjArray(7);
91     for (i=0; i<7;i++)
92         (*fRecClusters)[i] = new TObjArray(1000);
93     
94 //   
95 // Transport angular cut
96     fAccCut=0;
97     fAccMin=2;
98     fAccMax=9;
99     
100     SetMarkerColor(kRed);
101 }
102
103 //___________________________________________
104 AliRICH::~AliRICH()
105 {
106     fIshunt  = 0;
107     delete fHits;
108     delete fClusters;
109     delete fCerenkovs;
110     for (Int_t i=0;i<7;i++) 
111         delete (*fRecClusters)[i];
112     delete fRecClusters;
113     
114 }
115
116 //___________________________________________
117 void AliRICH::AddHit(Int_t track, Int_t *vol, Float_t *hits)
118 {
119     TClonesArray &lhits = *fHits;
120     new(lhits[fNhits++]) AliRICHhit(fIshunt,track,vol,hits);
121 }
122 //_____________________________________________________________________________
123 void AliRICH::AddCerenkov(Int_t track, Int_t *vol, Float_t *cerenkovs)
124 {
125     TClonesArray &lcerenkovs = *fCerenkovs;
126     new(lcerenkovs[fNcerenkovs++]) AliRICHCerenkov(fIshunt,track,vol,cerenkovs);
127 }
128 //___________________________________________
129 void AliRICH::AddCluster(Int_t *clhits)
130 {
131     TClonesArray &lclusters = *fClusters;
132     new(lclusters[fNclusters++]) AliRICHcluster(clhits);
133 }
134 //_____________________________________________________________________________
135 void AliRICH::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
136 {
137     //
138     // Add a RICH digit to the list
139     //
140
141     TClonesArray &ldigits = *((TClonesArray*)(*fDchambers)[id]);
142     new(ldigits[fNdch[id]++]) AliRICHdigit(tracks,charges,digits);
143 }
144
145
146 //_____________________________________________________________________________
147 void AliRICH::AddRecCluster(Int_t iCh, Int_t iCat, AliRICHRecCluster* Cluster)
148 {
149     //
150     // Add a RICH reconstructed cluster to the list
151     //
152     TObjArray* ClusterList = RecClusters(iCh,iCat);
153     ClusterList->Add(Cluster);
154 }
155
156
157
158 //___________________________________________
159 void AliRICH::BuildGeometry()
160     
161 {
162     //
163     // Builds a TNode geometry for event display
164     //
165     TNode *Node, *Top;
166     
167     const int kColorRICH = kGreen;
168     //
169     Top=gAlice->GetGeometry()->GetNode("alice");
170     
171     
172     new TBRIK("S_RICH","S_RICH","void",71.09999,11.5,73.15);
173     
174     Top->cd();
175     Float_t pos1[3]={0,471.8999,165.2599};
176     Chamber(0).SetChamberTransform(pos1[0],pos1[1],pos1[2],new TRotMatrix("rot993","rot993",90,0,70.69,90,19.30999,-90));
177     Node = new TNode("RICH1","RICH1","S_RICH",pos1[0],pos1[1],pos1[2],"rot993");
178     
179
180     Node->SetLineColor(kColorRICH);
181     fNodes->Add(Node);
182     Top->cd();
183     
184     Float_t pos2[3]={171,470,0};
185     Chamber(1).SetChamberTransform(pos2[0],pos2[1],pos2[2],new TRotMatrix("rot994","rot994",90,-20,90,70,0,0));
186     Node = new TNode("RICH2","RICH2","S_RICH",pos2[0],pos2[1],pos2[2],"rot994");
187     
188     
189     Node->SetLineColor(kColorRICH);
190     fNodes->Add(Node);
191     Top->cd();
192     Float_t pos3[3]={0,500,0};
193     Chamber(2).SetChamberTransform(pos3[0],pos3[1],pos3[2],new TRotMatrix("rot995","rot995",90,0,90,90,0,0));
194     Node = new TNode("RICH3","RICH3","S_RICH",pos3[0],pos3[1],pos3[2],"rot995");
195     
196
197     Node->SetLineColor(kColorRICH);
198     fNodes->Add(Node);
199     Top->cd();
200     Float_t pos4[3]={-171,470,0};
201     Chamber(3).SetChamberTransform(pos4[0],pos4[1],pos4[2], new TRotMatrix("rot996","rot996",90,20,90,110,0,0));  
202     Node = new TNode("RICH4","RICH4","S_RICH",pos4[0],pos4[1],pos4[2],"rot996");
203     
204
205     Node->SetLineColor(kColorRICH);
206     fNodes->Add(Node);
207     Top->cd();
208     Float_t pos5[3]={161.3999,443.3999,-165.3};
209     Chamber(4).SetChamberTransform(pos5[0],pos5[1],pos5[2],new TRotMatrix("rot997","rot997",90,340,108.1999,70,18.2,70));
210     Node = new TNode("RICH5","RICH5","S_RICH",pos5[0],pos5[1],pos5[2],"rot997");
211     
212     Node->SetLineColor(kColorRICH);
213     fNodes->Add(Node);
214     Top->cd();
215     Float_t pos6[3]={0., 471.9, -165.3,};
216     Chamber(5).SetChamberTransform(pos6[0],pos6[1],pos6[2],new TRotMatrix("rot998","rot998",90,0,109.3099,90,19.30999,90));
217     Node = new TNode("RICH6","RICH6","S_RICH",pos6[0],pos6[1],pos6[2],"rot998");
218     
219     
220     Node->SetLineColor(kColorRICH);
221     fNodes->Add(Node);
222     Top->cd();
223     Float_t pos7[3]={-161.399,443.3999,-165.3};
224     Chamber(6).SetChamberTransform(pos7[0],pos7[1],pos7[2],new TRotMatrix("rot999","rot999",90,20,108.1999,110,18.2,110));
225     Node = new TNode("RICH7","RICH7","S_RICH",pos7[0],pos7[1],pos7[2],"rot999");
226     Node->SetLineColor(kColorRICH);
227     fNodes->Add(Node); 
228     
229 }
230
231 //___________________________________________
232 Int_t AliRICH::DistancetoPrimitive(Int_t , Int_t )
233 {
234     return 9999;
235 }
236
237 //___________________________________________
238 void AliRICH::MakeBranch(Option_t* option)
239 {
240     // Create Tree branches for the RICH.
241     
242     const Int_t buffersize = 4000;
243     char branchname[20];
244     
245     
246     AliDetector::MakeBranch(option);
247     sprintf(branchname,"%sCerenkov",GetName());
248     if (fCerenkovs   && gAlice->TreeH()) {
249         gAlice->TreeH()->Branch(branchname,&fCerenkovs, buffersize);
250         printf("Making Branch %s for Cerenkov Hits\n",branchname);
251     }
252     
253     sprintf(branchname,"%sCluster",GetName());
254     if (fClusters   && gAlice->TreeH()) {
255         gAlice->TreeH()->Branch(branchname,&fClusters, buffersize);
256         printf("Making Branch %s for clusters\n",branchname);
257     }
258     
259 // one branch for digits per chamber
260     Int_t i;
261     
262     for (i=0; i<7 ;i++) {
263         sprintf(branchname,"%sDigits%d",GetName(),i+1);
264         
265         if (fDchambers   && gAlice->TreeD()) {
266             gAlice->TreeD()->Branch(branchname,&((*fDchambers)[i]), buffersize);
267             printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
268         }       
269     }
270 // one branch for rec clusters
271     for (i=0; i<7; i++) {
272         sprintf(branchname,"%sRecClus%d",GetName(),i+1);
273         if (fRecClusters   && gAlice->TreeD()) {
274             gAlice->TreeR()
275                 ->Branch(branchname,"TObjArray", 
276                          &((*fRecClusters)[i]), buffersize,0);
277             printf("Making Branch %s for clusters in chamber %d\n",
278                    branchname,i+1);
279         }
280     }
281 }
282
283 //___________________________________________
284 void AliRICH::SetTreeAddress()
285 {
286     // Set branch address for the Hits and Digits Tree.
287     char branchname[20];
288     AliDetector::SetTreeAddress();
289     
290     TBranch *branch;
291     TTree *treeH = gAlice->TreeH();
292     TTree *treeD = gAlice->TreeD();
293     
294     if (treeH) {
295         if (fClusters) {
296             branch = treeH->GetBranch("RICHCluster");
297             if (branch) branch->SetAddress(&fClusters);
298         }
299         if (fCerenkovs) {
300             branch = treeH->GetBranch("RICHCerenkov");
301             if (branch) branch->SetAddress(&fCerenkovs);
302         }
303         
304     }
305     
306     if (treeD) {
307         for (int i=0; i<7; i++) {
308             sprintf(branchname,"%sDigits%d",GetName(),i+1);
309             if (fDchambers) {
310                 branch = treeD->GetBranch(branchname);
311                 if (branch) branch->SetAddress(&((*fDchambers)[i]));
312             }
313         }
314     }
315 }
316 //___________________________________________
317 void AliRICH::ResetHits()
318 {
319     // Reset number of clusters and the cluster array for this detector
320     AliDetector::ResetHits();
321     fNclusters = 0;
322     if (fClusters) fClusters->Clear();
323     if (fCerenkovs) fCerenkovs->Clear();
324 }
325
326 //____________________________________________
327 void AliRICH::ResetDigits()
328 {
329     //
330     // Reset number of digits and the digits array for this detector
331     //
332     for ( int i=0;i<7;i++ ) {
333         if ((*fDchambers)[i])   (*fDchambers)[i]->Clear();
334         if (fNdch)  fNdch[i]=0;
335     }
336 }
337 //____________________________________________
338 void AliRICH::ResetRecClusters()
339 {
340     //
341     // Reset the rec clusters
342     //
343     for ( int i=0;i<7;i++ ) {
344         if ((*fRecClusters)[i])   (*fRecClusters)[i]->Clear();
345     }
346 }
347 //___________________________________________
348
349 void AliRICH::SetPADSIZ(Int_t id, Int_t isec, Float_t p1, Float_t p2)
350 {
351     Int_t i=2*(id-1);
352     ((AliRICHchamber*) (*fChambers)[i])  ->SetPADSIZ(isec,p1,p2);
353     ((AliRICHchamber*) (*fChambers)[i+1])->SetPADSIZ(isec,p1,p2);
354 }
355
356 //___________________________________________
357 void AliRICH::SetMUCHSP(Int_t id, Float_t p1)
358 {
359     Int_t i=2*(id-1);
360     ((AliRICHchamber*) (*fChambers)[i])->SetMUCHSP(p1);
361     ((AliRICHchamber*) (*fChambers)[i+1])->SetMUCHSP(p1);
362 }
363
364 //___________________________________________
365 void AliRICH::SetMUSIGM(Int_t id, Float_t p1, Float_t p2)
366 {
367     Int_t i=2*(id-1);
368     ((AliRICHchamber*) (*fChambers)[i])->SetMUSIGM(p1,p2);
369     ((AliRICHchamber*) (*fChambers)[i+1])->SetMUSIGM(p1,p2);
370 }
371
372 //___________________________________________
373 void AliRICH::SetRSIGM(Int_t id, Float_t p1)
374 {
375     Int_t i=2*(id-1);
376     ((AliRICHchamber*) (*fChambers)[i])->SetRSIGM(p1);
377     ((AliRICHchamber*) (*fChambers)[i+1])->SetRSIGM(p1);
378 }
379
380 //___________________________________________
381 void AliRICH::SetMAXADC(Int_t id, Float_t p1)
382 {
383     Int_t i=2*(id-1);
384     ((AliRICHchamber*) (*fChambers)[i])->SetMAXADC(p1);
385     ((AliRICHchamber*) (*fChambers)[i+1])->SetMAXADC(p1);
386 }
387
388 //___________________________________________
389 void AliRICH::SetSMAXAR(Float_t p1)
390 {
391     fMaxStepGas=p1;
392 }
393
394 //___________________________________________
395 void AliRICH::SetSMAXAL(Float_t p1)
396 {
397     fMaxStepAlu=p1;
398 }
399
400 //___________________________________________
401 void AliRICH::SetDMAXAR(Float_t p1)
402 {
403     fMaxDestepGas=p1;
404 }
405
406 //___________________________________________
407 void AliRICH::SetDMAXAL(Float_t p1)
408 {
409     fMaxDestepAlu=p1;
410 }
411 //___________________________________________
412 void AliRICH::SetRICHACC(Bool_t acc, Float_t angmin, Float_t angmax)
413 {
414     fAccCut=acc;
415     fAccMin=angmin;
416     fAccMax=angmax;
417 }
418 //___________________________________________
419 void   AliRICH::SetSegmentationModel(Int_t id, Int_t isec, AliRICHsegmentation *segmentation)
420 {
421     ((AliRICHchamber*) (*fChambers)[id])->SegmentationModel(isec, segmentation);
422
423 }
424 //___________________________________________
425 void   AliRICH::SetResponseModel(Int_t id, Response_t res,  AliRICHresponse *response)
426 {
427     ((AliRICHchamber*) (*fChambers)[id])->ResponseModel(res, response);
428 }
429
430 void   AliRICH::SetNsec(Int_t id, Int_t nsec)
431 {
432     ((AliRICHchamber*) (*fChambers)[id])->SetNsec(nsec);
433 }
434
435
436 //___________________________________________
437
438 void AliRICH::StepManager()
439 {
440     printf("Dummy version of RICH step -- it should never happen!!\n");
441     const Float_t kRaddeg = 180/TMath::Pi();
442     Int_t nsec, ipart;
443     TLorentzVector x, p;
444     Float_t pt, th0, th1;
445     char proc[5];
446     if(fAccCut) {
447         if((nsec=gMC->NSecondaries())>0) {
448             gMC->ProdProcess(proc);
449             if((gMC->TrackPid()==113 || gMC->TrackPid()==114) && !strcmp(proc,"DCAY")) {
450                 
451                 // Check angular acceptance
452                 //* --- and have muons from resonance decays in the wanted window --- 
453                 if(nsec != 2) {
454                     printf(" AliRICH::StepManager: Strange resonance Decay into %d particles\n",nsec);
455                     gMC->StopEvent();
456                 } else {
457                     gMC->GetSecondary(0,ipart,x,p);
458                     pt  = TMath::Sqrt(p[0]*p[0]+p[1]*p[1]);
459                     th0 = TMath::ATan2(pt,p[2])*kRaddeg;
460                     gMC->GetSecondary(1,ipart,x,p);
461                     pt  = TMath::Sqrt(p[0]*p[0]+p[1]*p[1]);
462                     th1 = TMath::ATan2(pt,p[2])*kRaddeg;
463                     if(!(fAccMin < th0 && th0 < fAccMax) ||
464                        !(fAccMin < th1 && th1 < fAccMax)) 
465                         gMC->StopEvent();
466                 }
467             }
468         }
469     }
470 }
471 void AliRICH::ReconstructClusters()
472 {
473 //
474 // Initialize the necessary correspondance table
475 //
476     static const Int_t kMaxNPadx = 600;
477     static const Int_t kMaxNPady = 600;
478     Int_t elem[kMaxNPadx*2][kMaxNPady*2];
479 //
480 // Loop on chambers and on cathode planes
481 //
482     for (Int_t ich=0;ich<7;ich++)
483         for (Int_t icat=0;icat<1;icat++) {
484             //
485             // Get ready the current chamber stuff
486             //
487             
488             printf ("Olarilole");
489             AliRICHchamber*  iChamber= &(this->Chamber(ich));
490             AliRICHsegmentation*  segmentation = 
491                 iChamber->GetSegmentationModel(icat+1);
492             if (!segmentation) 
493                 continue;
494             TClonesArray *RICHdigits  = this->DigitsAddress(ich);
495             if (RICHdigits == 0) 
496                 continue;
497             cout << "Npx " << segmentation->Npx() 
498                  << " Npy " << segmentation->Npy() << endl;
499             //      
500             // Ready the digits
501             //  
502             gAlice->ResetDigits();
503             gAlice->TreeD()->GetEvent(icat+1); // spurious +1 ...
504             Int_t ndigits = RICHdigits->GetEntriesFast();
505             if (ndigits == 0) 
506                 continue;
507             printf("Found %d digits for cathode %d in chamber %d \n",
508                    ndigits,icat,ich+1);
509             AliRICHdigit  *mdig;
510             AliRICHRecCluster *Cluster;
511             //
512             // Build the correspondance table
513             //
514             memset(elem,0,sizeof(Int_t)*kMaxNPadx*kMaxNPady*4);
515             Int_t digit;
516             for (digit=0; digit<ndigits; digit++) 
517             {
518                 mdig    = (AliRICHdigit*)RICHdigits->UncheckedAt(digit);
519                 elem[kMaxNPadx+mdig->fPadX][kMaxNPady+mdig->fPadY] = digit+1;
520                 // because default is 0
521             }
522             //
523             // Declare some useful variables
524             //
525             Int_t Xlist[10];
526             Int_t Ylist[10];
527             Int_t Nlist;
528             Int_t nclust=0;
529             //
530             // loop over digits
531             //
532             for (digit=0;digit<ndigits;digit++) {
533                 mdig    = (AliRICHdigit*)RICHdigits->UncheckedAt(digit);
534                 //
535                 // if digit still available, start clustering
536                 //
537                 if (elem[kMaxNPadx+mdig->fPadX][kMaxNPady+mdig->fPadY]) {
538                     Cluster = new AliRICHRecCluster(digit, ich, icat);
539                     elem[kMaxNPadx+mdig->fPadX][kMaxNPady+mdig->fPadY]=0;
540                     //
541                     // loop over the current list of digits 
542                     // and look for neighbours
543                     //
544                     for(Int_t clusDigit=Cluster->FirstDigitIndex();
545                         clusDigit!=Cluster->InvalidDigitIndex();
546                         clusDigit=Cluster->NextDigitIndex()) {
547                         AliRICHdigit* pDigit=(AliRICHdigit*)RICHdigits
548                             ->UncheckedAt(clusDigit);
549                         segmentation->Neighbours(pDigit->fPadX,pDigit->fPadY, 
550                                                  &Nlist, Xlist, Ylist);
551                         for (Int_t Ilist=0;Ilist<Nlist;Ilist++) {
552                             if (elem[kMaxNPadx+Xlist[Ilist]][kMaxNPady
553                                                             +Ylist[Ilist]]) {
554                                 //
555                                 // Add the digit at the end and reset the table
556                                 //
557                                 Cluster->AddDigit(elem[kMaxNPadx+Xlist[Ilist]][kMaxNPady+Ylist[Ilist]]-1);
558                                 elem[kMaxNPadx+Xlist[Ilist]][kMaxNPady
559                                                             +Ylist[Ilist]] =0;
560                             } // if elem
561                         } // for Ilist
562                     } // for pDigit
563                     //
564                     // Store the cluster (good time to do Cluster polishing)
565                     //
566                     segmentation->FitXY(Cluster,RICHdigits);
567                     nclust ++;
568                     AddRecCluster(ich,icat,Cluster);
569                 }
570             }
571             printf("===> %d Clusters\n",nclust); 
572         } // for icat
573 }
574
575
576 //______________________________________________________________________________
577 void AliRICH::Streamer(TBuffer &R__b)
578 {
579     // Stream an object of class AliRICH.
580     AliRICHchamber       *iChamber;
581     AliRICHsegmentation  *segmentation;
582     AliRICHresponse      *response;
583     TClonesArray         *digitsaddress;
584       
585     if (R__b.IsReading()) {
586         Version_t R__v = R__b.ReadVersion(); if (R__v) { }
587         AliDetector::Streamer(R__b);
588         R__b >> fNclusters;
589         R__b >> fClusters; // diff
590         R__b >> fDchambers;
591         R__b.ReadArray(fNdch);
592         //
593         R__b >> fAccCut;
594         R__b >> fAccMin;
595         R__b >> fAccMax; 
596         //   
597         R__b >> fChambers;
598 // Stream chamber related information
599         for (Int_t i =0; i<7; i++) {
600             iChamber=(AliRICHchamber*) (*fChambers)[i];
601             iChamber->Streamer(R__b);
602             if (iChamber->Nsec()==1) {
603                 segmentation=iChamber->GetSegmentationModel(1);
604                 segmentation->Streamer(R__b);
605             } else {
606                 segmentation=iChamber->GetSegmentationModel(1);
607                 segmentation->Streamer(R__b);
608                 segmentation=iChamber->GetSegmentationModel(2);
609                 segmentation->Streamer(R__b);
610             }
611             response=iChamber->GetResponseModel(mip);
612             response->Streamer(R__b);     
613             response=iChamber->GetResponseModel(cerenkov);
614             response->Streamer(R__b);     
615             
616             digitsaddress=(TClonesArray*) (*fDchambers)[i];
617             digitsaddress->Streamer(R__b);
618         }
619       
620     } else {
621         R__b.WriteVersion(AliRICH::IsA());
622         AliDetector::Streamer(R__b);
623         R__b << fNclusters;
624         R__b << fClusters; // diff
625         R__b << fDchambers;
626         R__b.WriteArray(fNdch, 7);
627         //
628         R__b << fAccCut;
629         R__b << fAccMin;
630         R__b << fAccMax; 
631         //   
632         R__b << fChambers;
633 //  Stream chamber related information
634         for (Int_t i =0; i<7; i++) {
635             iChamber=(AliRICHchamber*) (*fChambers)[i];
636             iChamber->Streamer(R__b);
637             if (iChamber->Nsec()==1) {
638                 segmentation=iChamber->GetSegmentationModel(1);
639                 segmentation->Streamer(R__b);
640             } else {
641                 segmentation=iChamber->GetSegmentationModel(1);
642                 segmentation->Streamer(R__b);
643                 segmentation=iChamber->GetSegmentationModel(2);
644                 segmentation->Streamer(R__b);
645             }
646             response=iChamber->GetResponseModel(mip);
647             response->Streamer(R__b);
648             response=iChamber->GetResponseModel(cerenkov);
649             response->Streamer(R__b);
650             
651             digitsaddress=(TClonesArray*) (*fDchambers)[i];
652             digitsaddress->Streamer(R__b);
653         }
654     }
655 }
656 AliRICHcluster* AliRICH::FirstPad(AliRICHhit*  hit,TClonesArray *clusters ) 
657 {
658 //
659     // Initialise the pad iterator
660     // Return the address of the first padhit for hit
661     TClonesArray *theClusters = clusters;
662     Int_t nclust = theClusters->GetEntriesFast();
663     if (nclust && hit->fPHlast > 0) {
664         sMaxIterPad=hit->fPHlast;
665         sCurIterPad=hit->fPHfirst;
666         return (AliRICHcluster*) clusters->UncheckedAt(sCurIterPad-1);
667     } else {
668         return 0;
669     }
670     
671 }
672
673 AliRICHcluster* AliRICH::NextPad(TClonesArray *clusters) 
674 {
675     sCurIterPad++;
676     if (sCurIterPad <= sMaxIterPad) {
677         return (AliRICHcluster*) clusters->UncheckedAt(sCurIterPad-1);
678     } else {
679         return 0;
680     }
681 }
682
683 ClassImp(AliRICHcluster)
684     
685 //___________________________________________
686 AliRICHcluster::AliRICHcluster(Int_t *clhits)
687 {
688     fHitNumber=clhits[0];
689     fCathode=clhits[1];
690     fQ=clhits[2];
691     fPadX=clhits[3];
692     fPadY=clhits[4];
693     fQpad=clhits[5];
694     fRSec=clhits[6];
695 }
696 ClassImp(AliRICHdigit)
697 //_____________________________________________________________________________
698 AliRICHdigit::AliRICHdigit(Int_t *digits)
699 {
700     //
701     // Creates a RICH digit object to be updated
702     //
703     fPadX        = digits[0];
704     fPadY        = digits[1];
705     fSignal      = digits[2];
706     
707 }
708 //_____________________________________________________________________________
709 AliRICHdigit::AliRICHdigit(Int_t *tracks, Int_t *charges, Int_t *digits)
710 {
711     //
712     // Creates a RICH digit object
713     //
714     fPadX        = digits[0];
715     fPadY        = digits[1];
716     fSignal      = digits[2];
717     for(Int_t i=0; i<10; i++) {
718         fTcharges[i]  = charges[i];
719         fTracks[i]    = tracks[i];
720     }
721 }
722
723 ClassImp(AliRICHlist)
724     
725 //____________________________________________________________________________
726 AliRICHlist::AliRICHlist(Int_t ich, Int_t *digits): 
727     AliRICHdigit(digits)
728 {
729     //
730     // Creates a RICH digit list object
731     //
732     
733     fChamber = ich;
734     fTrackList   = new TObjArray;
735     
736 }
737 //_____________________________________________________________________________
738
739
740 ClassImp(AliRICHhit)
741     
742 //___________________________________________
743 AliRICHhit::AliRICHhit(Int_t shunt, Int_t track, Int_t *vol, Float_t *hits):
744     AliHit(shunt, track)
745 {
746     fChamber=vol[0];
747     fParticle=hits[0];
748     fX=hits[1];
749     fY=hits[2];
750     fZ=hits[3];
751     fTheta=hits[4];
752     fPhi=hits[5];
753     fTlength=hits[6];
754     fEloss=hits[7];
755     fPHfirst=(Int_t) hits[8];
756     fPHlast=(Int_t) hits[9];
757 }
758 ClassImp(AliRICHreccluster)
759
760 ClassImp(AliRICHCerenkov)
761 //___________________________________________
762 AliRICHCerenkov::AliRICHCerenkov(Int_t shunt, Int_t track, Int_t *vol, Float_t *hits):
763     AliHit(shunt, track)
764 {
765     fChamber=vol[0];
766     fX=hits[1];
767     fY=hits[2];
768     fZ=hits[3];
769     fTheta=hits[4];
770     fPhi=hits[5];
771     fTlength=hits[6];
772     fPHfirst=(Int_t) hits[8];
773     fPHlast=(Int_t) hits[9];
774 }
775
776 ClassImp(AliRICHRecCluster)
777     
778 //_____________________________________________________________________
779 AliRICHRecCluster::AliRICHRecCluster()
780 {
781     fDigits=0;
782     fNdigit=-1;
783 }
784
785 AliRICHRecCluster::AliRICHRecCluster(Int_t FirstDigit,Int_t Ichamber, Int_t Icathod)
786 {
787     fX = 0.;
788     fY = 0.;
789     fDigits = new TArrayI(10);
790     fNdigit=0;
791     AddDigit(FirstDigit);
792     fChamber=Ichamber;
793     fCathod=Icathod;
794 }
795
796 void AliRICHRecCluster::AddDigit(Int_t Digit)
797 {
798     if (fNdigit==fDigits->GetSize()) {
799         //enlarge the list by hand!
800         Int_t *array= new Int_t[fNdigit*2];
801         for(Int_t i=0;i<fNdigit;i++)
802             array[i] = fDigits->At(i);
803         fDigits->Adopt(fNdigit*2,array);
804     }
805     fDigits->AddAt(Digit,fNdigit);
806     fNdigit++;
807 }
808
809
810 AliRICHRecCluster::~AliRICHRecCluster()
811 {
812     if (fDigits)
813         delete fDigits;
814 }
815
816 Int_t AliRICHRecCluster::FirstDigitIndex()
817 {
818     fCurrentDigit=0;
819     return fDigits->At(fCurrentDigit);
820 }
821
822 Int_t AliRICHRecCluster::NextDigitIndex()
823 {
824     fCurrentDigit++;
825     if (fCurrentDigit<fNdigit)
826         return fDigits->At(fCurrentDigit);
827     else 
828         return InvalidDigitIndex();
829 }
830
831 Int_t AliRICHRecCluster::NDigits()
832 {
833     return fNdigit;
834 }
835
836 void AliRICHRecCluster::Finish()
837 {
838     // In order to reconstruct coordinates, one has to
839     // get back to the digits which is not trivial here,
840     // because we don't know where digits are stored!
841     // Center Of Gravity, or other method should be
842     // a property of AliRICH class!
843 }
844
845
846
847 void AliRICH::Digitise(Int_t nev,Option_t *option,Text_t *filename)
848 {
849     // keep galice.root for signal and name differently the file for 
850     // background when add! otherwise the track info for signal will be lost !
851     
852     static Bool_t first=kTRUE;
853     static TTree *TH1;
854     static TFile *File;
855     Int_t i;
856     char *Add = strstr(option,"Add");
857
858     AliRICHchamber*  iChamber;
859     AliRICHsegmentation*  segmentation;
860
861     
862     Int_t trk[50];
863     Int_t chtrk[50];  
864     TObjArray *list=new TObjArray;
865     Int_t digits[3]; 
866     
867     AliRICH *RICH  = (AliRICH *) gAlice->GetDetector("RICH");
868     AliRICHHitMap* HitMap[10];
869     for (i=0; i<10; i++) {HitMap[i]=0;}
870     if (Add ) {
871         if(first) {
872             fFileName=filename;
873             cout<<"filename"<<fFileName<<endl;
874             File=new TFile(fFileName);
875             cout<<"I have opened "<<fFileName<<" file "<<endl;
876             fHits2     = new TClonesArray("AliRICHhit",1000  );
877             fClusters2 = new TClonesArray("AliRICHcluster",10000);
878             first=kFALSE;
879         }
880         File->cd();
881         File->ls();
882         // Get Hits Tree header from file
883         if(fHits2) fHits2->Clear();
884         if(fClusters2) fClusters2->Clear();
885         if(TH1) delete TH1;
886         TH1=0;
887         //
888         char treeName[20];
889         sprintf(treeName,"TreeH%d",nev);
890         TH1 = (TTree*)gDirectory->Get(treeName);
891         if (!TH1) {
892             printf("ERROR: cannot find Hits Tree for event:%d\n",nev);
893         }
894         // Set branch addresses
895         TBranch *branch;
896         char branchname[20];
897         sprintf(branchname,"%s",GetName());
898         if (TH1 && fHits2) {
899             branch = TH1->GetBranch(branchname);
900             if (branch) branch->SetAddress(&fHits2);
901         }
902         if (TH1 && fClusters2) {
903             branch = TH1->GetBranch("RICHCluster");
904             if (branch) branch->SetAddress(&fClusters2);
905         }
906     }
907     //
908     // loop over cathodes
909     //
910     AliRICHHitMap* hm;
911     
912     for (int icat=0; icat<1; icat++) { 
913         for (i=0; i<7; i++) {
914             if (HitMap[i]) {
915                 hm=HitMap[i];
916                 delete hm;
917                 HitMap[i]=0;
918             }
919         }
920         Int_t counter=0;
921         for (i =0; i<7; i++) {
922             iChamber=(AliRICHchamber*) (*fChambers)[i];
923             if (iChamber->Nsec()==1 && icat==1) {
924                 continue;
925             } else {
926                 segmentation=iChamber->GetSegmentationModel(icat+1);
927             }
928             HitMap[i] = new AliRICHHitMapA1(segmentation, list);
929         }
930         printf("Start loop over tracks \n");     
931 //
932 //   Loop over tracks
933 //
934
935         TTree *TH = gAlice->TreeH();
936         Int_t ntracks =(Int_t) TH->GetEntries();
937         for (Int_t track=0; track<ntracks; track++) {
938             gAlice->ResetHits();
939             TH->GetEvent(track);
940 //
941 //   Loop over hits
942             for(AliRICHhit* mHit=(AliRICHhit*)RICH->FirstHit(-1); 
943                 mHit;
944                 mHit=(AliRICHhit*)RICH->NextHit()) 
945             {
946                 Int_t   nch   = mHit->fChamber-1;  // chamber number
947                 if (nch >7) continue;
948                 iChamber = &(RICH->Chamber(nch));
949                                 
950 //
951 // Loop over pad hits
952                 for (AliRICHcluster* mPad=
953                          (AliRICHcluster*)RICH->FirstPad(mHit,fClusters);
954                      mPad;
955                      mPad=(AliRICHcluster*)RICH->NextPad(fClusters))
956                 {
957                     Int_t cathode  = mPad->fCathode;    // cathode number
958                     Int_t ipx      = mPad->fPadX;       // pad number on X
959                     Int_t ipy      = mPad->fPadY;       // pad number on Y
960                     Int_t iqpad    = mPad->fQpad;       // charge per pad
961 //
962 //
963                     
964                     if (cathode != (icat+1)) continue;
965                     // fill the info array
966                     Float_t thex, they;
967                     segmentation=iChamber->GetSegmentationModel(cathode);
968                     segmentation->GetPadCxy(ipx,ipy,thex,they);
969                     TVector *trinfo_p= new TVector(2);
970                     TVector &trinfo = *trinfo_p;
971                     trinfo(0)=(Float_t)track;
972                     trinfo(1)=(Float_t)iqpad;
973                     
974                     digits[0]=ipx;
975                     digits[1]=ipy;
976                     digits[2]=iqpad;
977                     
978                     AliRICHlist* pdigit;
979                     // build the list of fired pads and update the info
980                     if (!HitMap[nch]->TestHit(ipx, ipy)) {
981                         list->AddAtAndExpand(
982                             new AliRICHlist(nch,digits),counter);
983                         HitMap[nch]->SetHit(ipx, ipy, counter);
984                         counter++;
985                         pdigit=(AliRICHlist*)list->At(list->GetLast());
986                         // list of tracks
987                         TObjArray *trlist=(TObjArray*)pdigit->TrackList();
988                         trlist->Add(&trinfo);
989                     } else {
990                         pdigit=(AliRICHlist*) HitMap[nch]->GetHit(ipx, ipy);
991                         // update charge
992                         (*pdigit).fSignal+=iqpad;
993                         // update list of tracks
994                         TObjArray* trlist=(TObjArray*)pdigit->TrackList();
995                         Int_t last_entry=trlist->GetLast();
996                         TVector *ptrk_p=(TVector*)trlist->At(last_entry);
997                         TVector &ptrk=*ptrk_p;
998                         Int_t last_track=Int_t(ptrk(0));
999                         Int_t last_charge=Int_t(ptrk(1));
1000                         if (last_track==track) {
1001                             last_charge+=iqpad;
1002                             trlist->RemoveAt(last_entry);
1003                             trinfo(0)=last_track;
1004                             trinfo(1)=last_charge;
1005                             trlist->AddAt(&trinfo,last_entry);
1006                         } else {
1007                             trlist->Add(&trinfo);
1008                         }
1009                         // check the track list
1010                         Int_t nptracks=trlist->GetEntriesFast();
1011                         if (nptracks > 2) {
1012                             printf("Attention - nptracks > 2  %d \n",nptracks);
1013                             printf("cat,nch,ix,iy %d %d %d %d  \n",icat+1,nch,ipx,ipy);
1014                             for (Int_t tr=0;tr<nptracks;tr++) {
1015                                 TVector *pptrk_p=(TVector*)trlist->At(tr);
1016                                 TVector &pptrk=*pptrk_p;
1017                                 trk[tr]=Int_t(pptrk(0));
1018                                 chtrk[tr]=Int_t(pptrk(1));
1019                             }
1020                         } // end if nptracks
1021                     } //  end if pdigit
1022                 } //end loop over clusters
1023             } // hit loop
1024         } // track loop
1025         
1026         Int_t nentr1=list->GetEntriesFast();
1027         printf(" \n counter, nentr1 %d %d\n",counter,nentr1);
1028         
1029         // open the file with background
1030         
1031         if (Add ) {
1032             ntracks =(Int_t)TH1->GetEntries();
1033             printf("background - icat,ntracks1  %d %d\n",icat,ntracks);
1034             printf("background - Start loop over tracks \n");     
1035 //
1036 //   Loop over tracks
1037 //
1038             for (Int_t trak=0; trak<ntracks; trak++) {
1039
1040                 if (fHits2)       fHits2->Clear();
1041                 if (fClusters2)   fClusters2->Clear();
1042                 
1043                 TH1->GetEvent(trak);
1044 //
1045 //   Loop over hits
1046                 AliRICHhit* mHit;
1047                 for(int j=0;j<fHits2->GetEntriesFast();++j) 
1048                 {
1049                     mHit=(AliRICHhit*) (*fHits2)[j];
1050                     Int_t   nch   = mHit->fChamber-1;  // chamber number
1051                     if (nch >9) continue;
1052                     iChamber = &(RICH->Chamber(nch));
1053                     Int_t rmin = (Int_t)iChamber->RInner();
1054                     Int_t rmax = (Int_t)iChamber->ROuter();
1055 //
1056 // Loop over pad hits
1057                     for (AliRICHcluster* mPad=
1058                              (AliRICHcluster*)RICH->FirstPad(mHit,fClusters2);
1059                          mPad;
1060                          mPad=(AliRICHcluster*)RICH->NextPad(fClusters2))
1061                     {
1062                         Int_t cathode  = mPad->fCathode;    // cathode number
1063                         Int_t ipx      = mPad->fPadX;       // pad number on X
1064                         Int_t ipy      = mPad->fPadY;       // pad number on Y
1065                         Int_t iqpad    = mPad->fQpad;       // charge per pad
1066                         if (trak==3 && nch==0 && icat==0) printf("bgr - trak,iqpad,ipx,ipy %d %d %d %d\n",trak,iqpad,ipx,ipy);
1067 //
1068 //
1069                         if (cathode != (icat+1)) continue;
1070                         // fill the info array
1071                         Float_t thex, they;
1072                         segmentation=iChamber->GetSegmentationModel(cathode);
1073                         segmentation->GetPadCxy(ipx,ipy,thex,they);
1074                         Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1075                         if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1076                         
1077                         TVector *trinfo_p;
1078                         trinfo_p = new TVector(2);
1079                         TVector &trinfo = *trinfo_p;
1080                         trinfo(0)=-1;  // tag background
1081                         trinfo(1)=-1;
1082                         
1083                         digits[0]=ipx;
1084                         digits[1]=ipy;
1085                         digits[2]=iqpad;
1086
1087                         
1088                         if (trak <4 && icat==0 && nch==0)
1089                             printf("bgr - HitMap[nch]->TestHit(ipx, ipy),trak %d %d\n",
1090                                    HitMap[nch]->TestHit(ipx, ipy),trak);
1091                         AliRICHlist* pdigit;
1092                         // build the list of fired pads and update the info
1093                         if (!HitMap[nch]->TestHit(ipx, ipy)) {
1094                             list->AddAtAndExpand(new AliRICHlist(nch,digits),counter);
1095                             
1096                             HitMap[nch]->SetHit(ipx, ipy, counter);
1097                             counter++;
1098                             printf("bgr new elem in list - counter %d\n",counter);
1099                             
1100                             pdigit=(AliRICHlist*)list->At(list->GetLast());
1101                             // list of tracks
1102                             TObjArray *trlist=(TObjArray*)pdigit->TrackList();
1103                             trlist->Add(&trinfo);
1104                         } else {
1105                             pdigit=(AliRICHlist*) HitMap[nch]->GetHit(ipx, ipy);
1106                             // update charge
1107                             (*pdigit).fSignal+=iqpad;
1108                             // update list of tracks
1109                             TObjArray* trlist=(TObjArray*)pdigit->TrackList();
1110                             Int_t last_entry=trlist->GetLast();
1111                             TVector *ptrk_p=(TVector*)trlist->At(last_entry);
1112                             TVector &ptrk=*ptrk_p;
1113                             Int_t last_track=Int_t(ptrk(0));
1114                             if (last_track==-1) {
1115                                 continue;
1116                             } else {
1117                                 trlist->Add(&trinfo);
1118                             }
1119                             // check the track list
1120                             Int_t nptracks=trlist->GetEntriesFast();
1121                             if (nptracks > 0) {
1122                                 for (Int_t tr=0;tr<nptracks;tr++) {
1123                                     TVector *pptrk_p=(TVector*)trlist->At(tr);
1124                                     TVector &pptrk=*pptrk_p;
1125                                     trk[tr]=Int_t(pptrk(0));
1126                                     chtrk[tr]=Int_t(pptrk(1));
1127                                 }
1128                             } // end if nptracks
1129                         } //  end if pdigit
1130                     } //end loop over clusters
1131                 } // hit loop
1132             } // track loop
1133             Int_t nentr2=list->GetEntriesFast();
1134             printf(" \n counter2, nentr2 %d %d \n",counter,nentr2);
1135             TTree *fAli=gAlice->TreeK();
1136             if (fAli) File =fAli->GetCurrentFile();
1137             File->cd();
1138         } // if Add     
1139         
1140         Int_t tracks[10];
1141         Int_t charges[10];
1142         cout<<"start filling digits \n "<<endl;
1143         Int_t nentries=list->GetEntriesFast();
1144         printf(" \n \n nentries %d \n",nentries);
1145
1146         // start filling the digits
1147         
1148         for (Int_t nent=0;nent<nentries;nent++) {
1149             AliRICHlist *address=(AliRICHlist*)list->At(nent);
1150             if (address==0) continue; 
1151             Int_t ich=address->fChamber;
1152             Int_t q=address->fSignal; 
1153             iChamber=(AliRICHchamber*) (*fChambers)[ich];
1154             // add white noise and do zero-suppression and signal truncation
1155             Float_t MeanNoise = gRandom->Gaus(1, 0.2);
1156             Float_t ZeroSupp=5*MeanNoise;
1157             Float_t Noise     = gRandom->Gaus(0, MeanNoise);
1158             q+=(Int_t)Noise; 
1159             if ( q <= ZeroSupp) continue;
1160             digits[0]=address->fPadX;
1161             digits[1]=address->fPadY;
1162             digits[2]=q;
1163             
1164             TObjArray* trlist=(TObjArray*)address->TrackList();
1165             Int_t nptracks=trlist->GetEntriesFast();
1166             
1167             // this was changed to accomodate the real number of tracks
1168             if (nptracks > 10) {
1169                 cout<<"Attention - nptracks > 10 "<<nptracks<<endl;
1170                 nptracks=10;
1171             }
1172             if (nptracks > 2) {
1173                 printf("Attention - nptracks > 2  %d \n",nptracks);
1174                 printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[1],q);
1175             }
1176             for (Int_t tr=0;tr<nptracks;tr++) {
1177                 TVector *pp_p=(TVector*)trlist->At(tr);
1178                 TVector &pp  =*pp_p;
1179                 tracks[tr]=Int_t(pp(0));
1180                 charges[tr]=Int_t(pp(1));
1181             }      //end loop over list of tracks for one pad
1182             if (nptracks < 10 ) {
1183                 for (Int_t t=nptracks; t<10; t++) {
1184                     tracks[t]=0;
1185                     charges[t]=0;
1186                 }
1187             }
1188             // fill digits
1189             RICH->AddDigits(ich,tracks,charges,digits);
1190             
1191             delete address;
1192         }
1193         cout<<"I'm out of the loops for digitisation"<<endl;
1194         gAlice->TreeD()->Fill();
1195         TTree *TD=gAlice->TreeD();
1196         Stat_t ndig=TD->GetEntries();
1197         cout<<"number of digits  "<<ndig<<endl;
1198         TClonesArray *fDch;
1199         for (int k=0;k<7;k++) {
1200             fDch= RICH->DigitsAddress(k);
1201             int ndigit=fDch->GetEntriesFast();
1202             printf (" k, ndigits %d %d \n",k,ndigit);
1203         }
1204         RICH->ResetDigits();
1205         
1206         list->Clear();
1207         
1208     } //end loop over cathodes
1209     char hname[30];
1210     sprintf(hname,"TreeD%d",nev);
1211     gAlice->TreeD()->Write(hname);
1212 }
1213
1214
1215
1216
1217
1218
1219
1220
1221