Event merging for ZDC
[u/mrichter/AliRoot.git] / ZDC / AliZDC.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.24  2001/09/26 16:03:41  coppedis
19 Merging implemented
20
21 Revision 1.23  2001/05/15 13:44:57  coppedis
22 Changes in AddHit method
23
24 Revision 1.22  2001/05/14 09:53:32  coppedis
25 Adding functions ZMin and ZMax
26
27 Revision 1.21  2001/04/20 10:05:02  coppedis
28 Minor changes
29
30 Revision 1.20  2001/03/26 13:39:20  coppedis
31 Comment prints
32
33 Revision 1.19  2001/03/26 09:10:23  coppedis
34 Corrected bug in constructor (fIshunt has to be =1)
35
36 Revision 1.18  2001/03/20 08:21:55  coppedis
37 ZDC needs PIPE, ABSO, DIPO and SHIL
38
39 Revision 1.17  2001/03/16 16:18:03  coppedis
40 Correction for superposition of ZDC volumes with MUON arm one
41
42 Revision 1.16  2001/03/15 16:01:11  coppedis
43 Code review
44
45 Revision 1.15  2001/01/26 19:56:27  hristov
46 Major upgrade of AliRoot code
47
48 Revision 1.14  2000/12/12 13:17:01  coppedis
49 Minor corrections suggested by P. Hristov
50
51 Revision 1.12  2000/12/01 08:19:01  coppedis
52 Adding a message error if ZDC is constructed without DIPO
53
54 Revision 1.11  2000/11/30 17:21:03  coppedis
55 Introduce hit array fStHits reset only at the end of the event (for digitization)
56
57 Revision 1.10  2000/11/22 11:32:58  coppedis
58 Major code revision
59
60 Revision 1.9  2000/10/02 21:28:20  fca
61 Removal of useless dependecies via forward declarations
62
63 Revision 1.8  2000/07/10 13:58:01  fca
64 New version of ZDC from E.Scomparin & C.Oppedisano
65
66 Revision 1.7  2000/01/19 17:17:40  fca
67
68 Revision 1.6  1999/09/29 09:24:35  fca
69 Introduction of the Copyright and cvs Log
70
71 */
72
73 ///////////////////////////////////////////////////////////////////////////////
74 //                                                                           //
75 //                      Zero Degree Calorimeter                              //
76 //           This class contains the basic functions for the ZDCs;           //
77 //            functions specific to one particular geometry are              //
78 //                      contained in the derived classes                     //
79 //                                                                           //
80 ///////////////////////////////////////////////////////////////////////////////
81
82 #include <stdlib.h>
83 #include <iostream.h>
84
85 // --- ROOT system
86 #include <TBRIK.h>
87 #include <TNode.h>
88 #include <TGeometry.h>
89 #include <TFile.h>
90 #include <TTree.h>
91
92 // --- AliRoot header files
93 #include "AliZDC.h"
94 #include "AliZDCHit.h"
95 #include "AliZDCMergedHit.h"
96 #include "AliZDCDigit.h"
97 #include "AliZDCMerger.h"
98 #include "AliDetector.h"
99 #include "AliCallf77.h"
100 #include "AliConst.h"
101 #include "AliMC.h"
102 #include "AliRun.h"
103 #include "AliHeader.h"
104
105  
106 ClassImp(AliZDC)
107  
108 //_____________________________________________________________________________
109 AliZDC::AliZDC()
110 {
111   //
112   // Default constructor for the Zero Degree Calorimeter base class
113   //
114   
115   fIshunt   = 1;
116   fNoShower = 0;
117   fMerger   = 0;
118
119   fHits     = 0;
120   fNhits    = 0;
121
122   fDigits   = 0;
123   fNdigits  = 0;
124   
125 }
126  
127 //_____________________________________________________________________________
128 AliZDC::AliZDC(const char *name, const char *title)
129   : AliDetector(name,title)
130 {
131   //
132   // Standard constructor for the Zero Degree Calorimeter base class
133   //
134
135   fIshunt   = 1;
136   fNoShower = 0;
137   fMerger   = 0;
138
139   // Allocate the hits array  
140   fHits   = new TClonesArray("AliZDCHit",1000);
141   gAlice->AddHitList(fHits);
142   // Allocate the merged hits array  
143   fMergedHits = new TClonesArray("AliZDCMergedHit",1000);
144
145   // Allocate the digits array  
146   fDigits = new TClonesArray("AliZDCDigit",1000);
147   
148
149 }
150 //____________________________________________________________________________ 
151 AliZDC::~AliZDC()
152 {
153   //
154   // ZDC destructor
155   //
156
157   fIshunt   = 0;
158   
159   if(fMerger) delete fMerger;
160
161 //  if(fHits){
162 //    fHits->Delete();
163 //    delete fHits;
164 //  }
165
166 //  if(fDigits){
167 //    fDigits->Delete();
168 //    delete fDigits;
169 //  }
170
171 }
172 //_____________________________________________________________________________
173 void AliZDC::AddHit(Int_t track, Int_t *vol, Float_t *hits)
174 {
175   //
176   //            Add a ZDC hit to the hit list.
177   // -> We make use of 2 array of hits:
178   // [1]  fHits (the usual one) that contains hits for each PRIMARY
179   // [2]  fStHits that contains hits for each EVENT and is used to
180   //      obtain digits at the end of each event
181   //
182   
183   static Float_t primKinEn, xImpact, yImpact, sFlag;
184
185   AliZDCHit *newquad, *curprimquad;
186   newquad = new AliZDCHit(fIshunt, track, vol, hits);
187   TClonesArray &lhits = *fHits;
188   
189   if(fNhits==0){
190       // First hit -> setting flag for primary or secondary particle
191       Int_t primary = gAlice->GetPrimary(track);     
192       if(track != primary){
193         newquad->fSFlag = 1;  // SECONDARY particle entering the ZDC
194       }
195       else if(track == primary){
196         newquad->fSFlag = 0;  // PRIMARY particle entering the ZDC
197       }  
198 //      fNPrimaryHits += 1;
199       sFlag     = newquad->fSFlag;
200       primKinEn = newquad->fPrimKinEn;
201       xImpact   = newquad->fXImpact;
202       yImpact   = newquad->fYImpact;
203    }
204    else{       
205       newquad->fPrimKinEn = primKinEn;
206       newquad->fXImpact = xImpact;
207       newquad->fYImpact = yImpact;
208       newquad->fSFlag   = sFlag;
209    }
210  
211   Int_t j;
212   for(j=0; j<fNhits; j++){
213     // If hits are equal (same track, same volume), sum them.
214      curprimquad = (AliZDCHit*) lhits[j];
215      if(*curprimquad == *newquad){
216         *curprimquad = *curprimquad+*newquad;
217         delete newquad;
218         return;
219      } 
220   }
221
222     //Otherwise create a new hit
223     new(lhits[fNhits]) AliZDCHit(newquad);
224     fNhits++;
225     
226     delete newquad;
227 }
228
229 //_____________________________________________________________________________
230 void  AliZDC::AddDigit(Int_t *sect, Int_t digit)
231 {
232 //
233   AliZDCDigit *newdigit;
234   newdigit = new AliZDCDigit(sect, digit);
235
236 //  AliZDCDigit *curdigit;
237 //  TClonesArray &ldigits = *fDigits;
238 //
239 //  Int_t j;
240 //  for(j=0; j<fNdigits; j++){
241 //     curdigit = (AliZDCDigit*) ldigits[j];
242 //     if(*curdigit == *newdigit){
243 //      *curdigit = *curdigit+*newdigit;
244 //      delete newdigit;
245 //      return;
246 //     } 
247 //  } 
248 //
249   
250 //  printf("\n  AddDigit -> sector[0] = %d, sector[1] = %d, digit = %d",
251 //         sect[0], sect[1], digit);
252   new((*fDigits)[fNdigits]) AliZDCDigit(*newdigit);
253   fNdigits++;
254   delete newdigit;
255 }
256       
257 //_____________________________________________________________________________
258 void AliZDC::BuildGeometry()
259 {
260   //
261   // Build the ROOT TNode geometry for event display 
262   // in the Zero Degree Calorimeter
263   // This routine is dummy for the moment
264   //
265
266   TNode *node, *top;
267   TBRIK *brik;
268   const int kColorZDC  = kBlue;
269   
270   //
271   top=gAlice->GetGeometry()->GetNode("alice");
272   
273   // ZDC
274     brik = new TBRIK("S_ZDC","ZDC box","void",300,300,5);
275     top->cd();
276     node = new TNode("ZDC","ZDC","S_ZDC",0,0,600,"");
277     node->SetLineColor(kColorZDC);
278     fNodes->Add(node);
279 }
280
281 //_____________________________________________________________________________
282 Int_t AliZDC::DistancetoPrimitive(Int_t , Int_t )
283 {
284   //
285   // Distance from the mouse to the Zero Degree Calorimeter
286   // Dummy routine
287   //
288   return 9999;
289 }
290
291 //____________________________________________________________________________
292 Float_t AliZDC::ZMin(void) const
293 {
294   // Minimum dimension of the ZDC module in z
295   return 11600.;
296 }
297
298 //____________________________________________________________________________
299 Float_t AliZDC::ZMax(void) const
300 {
301   // Maximum dimension of the ZDC module in z
302   return  11750.;
303 }
304   
305
306 //_____________________________________________________________________________
307  void AliZDC::MakeBranch(Option_t *opt, const char *file)
308 {
309   //
310   // Create Tree branches for the ZDC
311   //
312
313   char branchname[10];
314   sprintf(branchname,"%s",GetName());
315   
316   AliDetector::MakeBranch(opt);
317
318   const char *cS = strstr(opt,"S");
319
320   if (gAlice->TreeS() && cS) {
321     if(fMergedHits!=0) fMergedHits->Clear();
322     else fMergedHits = new TClonesArray ("AliZDCMergedHit",1000);
323     MakeBranchInTree(gAlice->TreeS(), 
324                      branchname, &fMergedHits, fBufferSize, file) ;
325     printf("* AliZDC::MakeBranch    * Making Branch %s for SDigits\n\n",branchname);
326   }
327
328     
329   const char *cD = strstr(opt,"D");
330
331   if (gAlice->TreeD() && cD) {
332     if(fDigits!=0) fDigits->Clear();
333     else fDigits = new TClonesArray ("AliZDCDigit",1000);
334     MakeBranchInTree(gAlice->TreeD(), 
335                      branchname, &fDigits, fBufferSize, file) ;
336     printf("* AliZDC::MakeBranch    * Making Branch %s for Digits\n\n",branchname);
337   }
338
339   
340   const char *cR = strstr(opt,"R");
341
342   if (gAlice->TreeR() && cR) {
343     MakeBranchInTree(gAlice->TreeR(), 
344                      branchname, &fRecPoints, fBufferSize, file) ;
345     printf("* AliZDC::MakeBranch    * Making Branch %s for RecPoints\n\n",branchname);   }
346           
347 }
348
349 //_____________________________________________________________________________
350  void AliZDC::MakeBranchInTreeSD(TTree *treeSD, const char *file)
351 {
352   // MakeBranchInTree
353   const Int_t kBufferSize = 4000;
354   char  branchname[20];
355   sprintf(branchname,"%s",GetName());
356   MakeBranchInTree(treeSD, branchname, &fMergedHits, kBufferSize, file) ;
357   printf("* AliZDC::MakeBranch    * Making Branch %s for SDigits\n\n",branchname);
358
359 }
360 //_____________________________________________________________________________
361  void AliZDC::MakeBranchInTreeD(TTree *treeD, const char *file)
362 {
363   // MakeBranchInTree
364   const Int_t kBufferSize = 4000;
365   char  branchname[20];
366   sprintf(branchname,"%s",GetName());
367   MakeBranchInTree(treeD, branchname, &fDigits, kBufferSize, file) ;
368   printf("* AliZDC::MakeBranch    * Making Branch %s for Digits\n\n",branchname);
369
370 }
371 //_____________________________________________________________________________
372 void AliZDC::Hits2SDigits()
373 {
374   printf("\n    Entering AliZDC::SDigits2Digits()\n");
375   
376   //----------------------------------------------------------------
377   if(!fMerger){ 
378     printf("\n  ZDC digitization (without merging)\n");
379
380     AliZDCMergedHit *MHit;
381     Int_t j, sector[2];
382     Float_t MHits[7];
383     fNMergedhits = 0;
384
385     TTree *treeH = gAlice->TreeH();
386     Int_t ntracks = (Int_t) treeH->GetEntries();
387     gAlice->ResetHits();
388   
389     // Tracks loop
390     for(Int_t itrack=0; itrack<ntracks; itrack++){
391        treeH->GetEvent(itrack);
392        for(AliZDCHit* zdcHit=(AliZDCHit*)this->FirstHit(-1); zdcHit;
393                       zdcHit = (AliZDCHit*)this->NextHit()){ 
394                       
395            for(j=0; j<2; j++) sector[j] = zdcHit->GetVolume(j);
396            MHits[0] = zdcHit->GetPrimKinEn();
397            MHits[1] = zdcHit->GetXImpact();
398            MHits[2] = zdcHit->GetYImpact();
399            MHits[3] = zdcHit->GetSFlag();
400            MHits[4] = zdcHit->GetLightPMQ();
401            MHits[5] = zdcHit->GetLightPMC();
402            MHits[6] = zdcHit->GetEnergy();
403        }//Hits loop
404        
405           MHit = new AliZDCMergedHit(sector, MHits);
406           new((*fMergedHits)[fNMergedhits]) AliZDCMergedHit(*MHit);       
407           TClonesArray &sdigits = *fMergedHits;
408           new (sdigits[fNMergedhits]) AliZDCMergedHit(*MHit);
409           fNMergedhits++;
410           delete MHit;
411     }
412     printf("\n  ### Filling SDigits tree\n");
413     gAlice->TreeS()->Fill();
414     gAlice->TreeS()->Write(0,TObject::kOverwrite);  
415     gAlice->TreeS()->Reset();  
416   }
417   //----------------------------------------------------------------
418   else if(fMerger){
419     printf("\n         ZDC merging and digitization\n");
420     // ### Initialise merging
421     fMerger -> InitMerging();
422
423     TFile *bgrFile  = fMerger->BgrFile();
424     bgrFile->cd();
425     // SDigits tree
426     Int_t fNEvBgr = fMerger->EvNum();
427     char treeSDBgrName[20];
428     sprintf(treeSDBgrName,"TreeS%d",fNEvBgr);
429     fTreeSD = (TTree*)gDirectory->Get(treeSDBgrName); // TreeH
430     if(!fTreeSD){
431       printf("\n ERROR -> Can't find TreeS%d in background file\n",fNEvBgr);
432     }    
433     // Branch address
434     TBranch *branchSD;
435     char branchSDname[20];
436     sprintf(branchSDname,"%s",GetName());
437     if(fTreeSD && fMergedHits){
438 //      printf("\n      fTreeSD!=0 && fMergedHits!=0\n");
439       branchSD = fTreeSD->GetBranch(branchSDname);
440       if(branchSD) branchSD->SetAddress(&fMergedHits);
441     }
442     if(!branchSD) MakeBranchInTreeSD(fTreeSD);
443
444     // ### Get TCA of MergedHits from AliZDCMerger
445     fMergedHits  = fMerger->MergedHits();
446     fNMergedhits = fMerger->GetNMhits();
447     printf("\n         fNMergedhits (from AliZDCMerger) = %d\n", fNMergedhits);   
448     AliZDCMergedHit *MHit;
449     TClonesArray &sdigits = *fMergedHits;
450     Int_t imhit;
451     //Merged Hits loop
452     for(imhit=0; imhit<fNMergedhits; imhit++){
453        MHit = (AliZDCMergedHit*) fMergedHits->UncheckedAt(imhit);
454        new (sdigits[imhit]) AliZDCMergedHit(*MHit);
455     }
456
457 //    printf("\n ### Filling SDigits tree\n");
458     bgrFile->cd();
459     fTreeSD->Fill();
460     fTreeSD->Write(0,TObject::kOverwrite);
461   }
462   
463 }
464
465 //_____________________________________________________________________________
466 void AliZDC::SDigits2Digits()
467 {
468   printf("\n    Entering AliZDC::SDigits2Digits()\n");
469   if(!fMerger){ // Only digitization
470     printf("\n        ZDC digitization (without merging) \n");
471     fMerger = new AliZDCMerger();    
472     fMerger->Digitize(fNMergedhits, fMergedHits);
473
474     char hname[30];
475     sprintf(hname,"TreeD%d",gAlice->GetHeader()->GetEvent());
476     gAlice->TreeD()->Fill();
477     gAlice->TreeD()->Write(0,TObject::kOverwrite);
478     gAlice->TreeD()->Reset();  
479   }
480   else if(fMerger){     // Merging and digitization
481     printf("\n        ZDC merging and digitization\n");
482     fMerger->Digitize(fNMergedhits, fMergedHits);
483
484     TFile *bgrFile = fMerger->BgrFile();
485     bgrFile->cd();
486     // Digits tree
487     Int_t fNEvBgr = fMerger->EvNum();
488     char treeDBgrName[20];
489     sprintf(treeDBgrName,"TreeD%d",fNEvBgr);
490     fTreeMD = (TTree*)gDirectory->Get(treeDBgrName); // TreeH
491     if(!fTreeMD){
492       printf("\n ERROR -> Can't find TreeD%d in background file\n",fNEvBgr);
493     }    
494     // Branch address
495     TBranch *branchD;
496     char branchDname[20];
497     sprintf(branchDname,"%s",GetName());
498     if(fTreeMD && fDigits){
499       printf("\n        fTreeMD!=0 && fDigits!=0\n");
500       branchD = fTreeMD->GetBranch(branchDname);
501       if(branchD) branchD->SetAddress(&fDigits);
502     }
503     if(!branchD) MakeBranchInTreeD(fTreeMD);
504     
505 //    printf("\n ### Filling Digits tree\n");
506     fTreeMD->Fill();
507     fTreeMD->Write(0,TObject::kOverwrite);
508   }
509   
510   
511 }
512 //_____________________________________________________________________________
513 void AliZDC::Hits2Digits()
514 {
515     gAlice->Hits2SDigits();
516     gAlice->SDigits2Digits();
517 }
518
519 //_____________________________________________________________________________
520 void AliZDC::Digits2Reco()
521 {
522     
523 }
524
525  
526 //_____________________________________________________________________________
527 void   AliZDC::SetMerger(AliZDCMerger* merger)
528 {
529 // Set pointer to merger 
530     fMerger = merger;
531 }
532
533 //_____________________________________________________________________________
534 AliZDCMerger*  AliZDC::Merger()
535 {
536 // Return pointer to merger
537     return fMerger;
538 }
539