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