]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONMerger.cxx
AliMUONMerger prototype to be called by the merge manager.
[u/mrichter/AliRoot.git] / MUON / AliMUONMerger.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2000, 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 */
19
20 #include <TTree.h> 
21 #include <TVector.h>
22 #include <TObjArray.h>
23 #include <TFile.h>
24 #include <TDirectory.h>
25
26
27 // #include "AliMerger.h"
28 // #include "AliMergable.h"
29 #include "AliMUONMerger.h"
30 #include "AliMUONConstants.h"
31 #include "AliMUONChamber.h"
32 #include "AliHitMap.h"
33 #include "AliMUONHitMapA1.h"
34 #include "AliMUON.h"
35 #include "AliMUONHit.h"
36 #include "AliMUONPadHit.h"
37 #include "AliMUONDigit.h"
38 #include "AliMUONTransientDigit.h"
39 #include "AliRun.h"
40 #include "AliPDG.h"
41
42 ClassImp(AliMUONMerger)
43
44 //___________________________________________
45 AliMUONMerger::AliMUONMerger()
46 {
47 // Default constructor    
48     fEvNrSig = 0;
49     fEvNrBgr = 0;
50     fMerge   = kDigitize;
51     fFnBgr   = 0;
52     fHitMap  = 0;
53     fList    = 0;
54     fTrH1    = 0;
55     fHitsBgr = 0;
56     fPadHitsBgr = 0;
57     fHitMap     = 0;
58     fList       = 0;
59     fTrList     = 0;
60     fAddress    = 0; 
61 }
62
63 //------------------------------------------------------------------------
64 AliMUONMerger::~AliMUONMerger()
65 {
66 // Destructor
67     if (fTrH1)       delete fTrH1;
68     if (fHitsBgr)    delete fHitsBgr;
69     if (fPadHitsBgr) delete fPadHitsBgr;
70     if (fHitMap)     delete fHitMap;
71     if (fList)       delete fList;
72     if (fTrList)     delete fTrList;
73     if (fAddress)    delete fAddress; 
74 }
75
76 //------------------------------------------------------------------------
77 Bool_t AliMUONMerger::Exists(const AliMUONPadHit *mergable)
78 {
79     AliMUONPadHit *padhit = (AliMUONPadHit*) mergable;
80     return (fHitMap[fNch]->TestHit(padhit->PadX(),padhit->PadY()));
81 }
82
83 //------------------------------------------------------------------------
84 void AliMUONMerger::Update(AliMUONPadHit *mergable)
85 {
86     AliMUONPadHit *padhit = (AliMUONPadHit*) mergable;    
87     AliMUONTransientDigit* pdigit;
88     Int_t ipx      = padhit->PadX();        // pad number on X
89     Int_t ipy      = padhit->PadY();        // pad number on Y
90     Int_t iqpad    = Int_t(padhit->QPad()); // charge per pad
91
92     pdigit = (AliMUONTransientDigit*) fHitMap[fNch]->GetHit(ipx, ipy);
93     // update charge
94     //
95     (*pdigit).AddSignal(iqpad);
96     (*pdigit).AddPhysicsSignal(iqpad);          
97     // update list of tracks
98     //
99     TObjArray* fTrList = (TObjArray*)pdigit->TrackList();
100     Int_t lastEntry = fTrList->GetLast();
101     TVector *pTrack = (TVector*)fTrList->At(lastEntry);
102     TVector &ptrk   = *pTrack;
103     TVector &trinfo = *((TVector*) (*fAddress)[fCountadr-1]);
104     Int_t lastTrack = Int_t(ptrk(0));
105
106     if (trinfo(0) != kBgTag) {
107         if (lastTrack == fTrack) {
108             Int_t lastCharge = Int_t(ptrk(1));
109             lastCharge += iqpad;
110             fTrList->RemoveAt(lastEntry);
111             trinfo(1) = lastCharge;
112             fTrList->AddAt(&trinfo,lastEntry);
113         } else {
114             fTrList->Add(&trinfo);
115         }
116     } else {
117         if (lastTrack != -1) fTrList->Add(&trinfo);
118     }
119 }
120
121 //------------------------------------------------------------------------
122 void AliMUONMerger::CreateNew(AliMUONPadHit *mergable)
123 {
124     AliMUONPadHit *padhit = (AliMUONPadHit*) mergable;    
125     AliMUONTransientDigit* pdigit;
126
127     Int_t ipx      = padhit->PadX();       // pad number on X
128     Int_t ipy      = padhit->PadY();       // pad number on Y
129     fList->AddAtAndExpand(
130         new AliMUONTransientDigit(fNch,fDigits),fCounter);
131     fHitMap[fNch]->SetHit(ipx, ipy, fCounter);
132     fCounter++;
133     pdigit = (AliMUONTransientDigit*)fList->At(fList->GetLast());
134     // list of tracks
135     TObjArray *fTrList = (TObjArray*)pdigit->TrackList();
136     TVector &trinfo    = *((TVector*) (*fAddress)[fCountadr-1]);
137     fTrList->Add(&trinfo);
138 }
139
140
141 //------------------------------------------------------------------------
142 void AliMUONMerger::Init()
143 {
144 // Initialisation
145     
146     if (fMerge) fBgrFile = InitBgr();
147 }
148
149
150
151 //------------------------------------------------------------------------
152 TFile* AliMUONMerger::InitBgr()
153 {
154 // Initialise background event
155     TFile *file = new TFile(fFnBgr);
156 // add error checking later
157     printf("\n AliMUONMerger has opened %s file with background event \n", fFnBgr);
158     fHitsBgr     = new TClonesArray("AliMUONHit",1000);
159     fPadHitsBgr  = new TClonesArray("AliMUONPadHit",1000);
160     return file;
161 }
162
163 //------------------------------------------------------------------------
164 void AliMUONMerger::Digitise()
165 {
166
167     // keep galice.root for signal and name differently the file for 
168     // background when add! otherwise the track info for signal will be lost !
169   
170     AliMUONChamber*   iChamber;
171     AliSegmentation*  segmentation;
172
173     fList = new TObjArray;
174     if(!fAddress) fAddress = new TClonesArray("TVector",10000);
175
176     AliMUON *pMUON  = (AliMUON *) gAlice->GetModule("MUON");
177     fHitMap= new AliHitMap* [AliMUONConstants::NCh()];
178     for (Int_t i = 0; i < AliMUONConstants::NCh(); i++) {fHitMap[i] = 0;}
179     if (fMerge ) {
180         fBgrFile->cd();
181         fBgrFile->ls();
182         //
183         // Get Hits Tree header from file
184         if(fHitsBgr) fHitsBgr->Clear();
185         if(fPadHitsBgr) fPadHitsBgr->Clear();
186         if(fTrH1) delete fTrH1;
187         fTrH1 = 0;
188         
189         char treeName[20];
190         sprintf(treeName,"TreeH%d",fEvNrBgr);
191         fTrH1 = (TTree*)gDirectory->Get(treeName);
192         if (!fTrH1) {
193             printf("ERROR: cannot find Hits Tree for event:%d\n",fEvNrBgr);
194         }
195         //
196         // Set branch addresses
197         TBranch *branch;
198         char branchname[20];
199         sprintf(branchname,"%s",pMUON->GetName());
200         if (fTrH1 && fHitsBgr) {
201             branch = fTrH1->GetBranch(branchname);
202             if (branch) branch->SetAddress(&fHitsBgr);
203         }
204         if (fTrH1 && fPadHitsBgr) {
205             branch = fTrH1->GetBranch("MUONCluster");
206             if (branch) branch->SetAddress(&fPadHitsBgr);
207         }
208     }
209     //
210     // loop over cathodes
211     //
212     AliHitMap* hm;
213     fCountadr = 0;
214     for (int icat = 0; icat < 2; icat++) { 
215         fCounter = 0;
216         Int_t * nmuon = new Int_t [AliMUONConstants::NCh()];
217         for (Int_t i = 0; i < AliMUONConstants::NCh(); i++) {
218             iChamber = &(pMUON->Chamber(i));
219             if (iChamber->Nsec() == 1 && icat == 1) {
220                 continue;
221             } else {
222                 segmentation = iChamber->SegmentationModel(icat+1);
223             }
224             fHitMap[i] = new AliMUONHitMapA1(segmentation, fList);
225             nmuon[i] = 0;
226         }
227
228 //
229 //   Loop over tracks
230 //
231
232         TTree *treeH  = gAlice->TreeH();
233         Int_t ntracks = (Int_t) treeH->GetEntries();
234         Int_t jj;
235
236         Float_t ** xhit = new Float_t * [AliMUONConstants::NCh()];
237         for (jj = 0; jj < AliMUONConstants::NCh(); jj++) xhit[jj] = new Float_t[2];
238         Float_t ** yhit = new Float_t * [AliMUONConstants::NCh()];
239         for (jj = 0; jj < AliMUONConstants::NCh(); jj++) yhit[jj] = new Float_t[2];
240
241         for (fTrack = 0; fTrack < ntracks; fTrack++) {
242             gAlice->ResetHits();
243             treeH->GetEvent(fTrack);
244 //
245 //   Loop over hits
246             for(AliMUONHit* mHit = (AliMUONHit*)pMUON->FirstHit(-1); 
247                 mHit;
248                 mHit = (AliMUONHit*)pMUON->NextHit()) 
249             {
250                 fNch = mHit->Chamber()-1;  // chamber number
251                 if (fNch > AliMUONConstants::NCh()-1) continue;
252                 iChamber = &(pMUON->Chamber(fNch));
253                 /*
254                 if (fMerge) {
255                     if (mHit->Particle() == kMuonPlus || 
256                         mHit->Particle() == kMuonMinus) {
257                         xhit[fNch][nmuon[fNch]] = mHit->X();
258                         yhit[fNch][nmuon[fNch]] = mHit->Y();
259                         nmuon[fNch]++;
260                         if (nmuon[fNch] > 2) printf("MUON: nmuon %d\n",nmuon[fNch]);
261                     }
262                 }
263                 */
264                 
265 //
266 // Loop over pad hits
267                 for (AliMUONPadHit* mPad =
268                          (AliMUONPadHit*)pMUON->FirstPad(mHit,pMUON->PadHits());
269                      mPad;
270                      mPad = (AliMUONPadHit*)pMUON->NextPad(pMUON->PadHits()))
271                 {
272                     Int_t cathode  = mPad->Cathode();      // cathode number
273                     Int_t ipx      = mPad->PadX();         // pad number on X
274                     Int_t ipy      = mPad->PadY();         // pad number on Y
275                     Int_t iqpad    = Int_t(mPad->QPad());  // charge per pad
276                     if (cathode != (icat+1)) continue;
277
278                     segmentation = iChamber->SegmentationModel(cathode);
279
280                     new((*fAddress)[fCountadr++]) TVector(2);
281
282                     TVector &trinfo = *((TVector*) (*fAddress)[fCountadr-1]);
283                     trinfo(0) = (Float_t)fTrack;
284                     trinfo(1) = (Float_t)iqpad;
285
286                     fDigits[0] = ipx;
287                     fDigits[1] = ipy;
288                     fDigits[2] = icat;
289                     fDigits[3] = iqpad;
290                     fDigits[4] = iqpad;
291                     if (mHit->Particle() == kMuonPlus ||
292                         mHit->Particle() == kMuonMinus) {
293                         fDigits[5] = mPad->HitNumber();
294                     } else fDigits[5] = -1;
295
296                     // build the list of fired pads and update the info
297
298                     if (!Exists(mPad)) {
299                         CreateNew(mPad);
300                     } else {
301                         Update(mPad);
302                     } //  end if pdigit
303                 } //end loop over clusters
304             } // hit loop
305         } // track loop
306
307         // open the file with background
308        
309         if (fMerge) {
310             ntracks = (Int_t)fTrH1->GetEntries();
311 //
312 //   Loop over tracks
313 //
314             for (fTrack = 0; fTrack < ntracks; fTrack++) {
315
316                 if (fHitsBgr)       fHitsBgr->Clear();
317                 if (fPadHitsBgr)    fPadHitsBgr->Clear();
318
319                 fTrH1->GetEvent(fTrack);
320 //
321 //   Loop over hits
322                 AliMUONHit* mHit;
323                 for(int i = 0; i < fHitsBgr->GetEntriesFast(); ++i) 
324                 {       
325                     mHit   = (AliMUONHit*) (*fHitsBgr)[i];
326                     fNch   = mHit->Chamber()-1;  // chamber number
327                     iChamber = &(pMUON->Chamber(fNch));
328                     Float_t xbgr = mHit->X();
329                     Float_t ybgr = mHit->Y();
330                     Bool_t cond  = kFALSE;
331                     /*
332                     for (Int_t imuon = 0; imuon < nmuon[fNch]; imuon++) {
333                         Float_t dist = (xbgr-xhit[fNch][imuon])*(xbgr-xhit[fNch][imuon])
334                             +(ybgr-yhit[fNch][imuon])*(ybgr-yhit[fNch][imuon]);
335                         if (dist < 100.) cond = kTRUE;
336                     }
337                     */
338                     cond  = kTRUE;
339 //
340 // Loop over pad hits
341                     for (AliMUONPadHit* mPad =
342                              (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHitsBgr);
343                          mPad;
344                          mPad = (AliMUONPadHit*)pMUON->NextPad(fPadHitsBgr))
345                     {
346                         Int_t cathode  = mPad->Cathode();     // cathode number
347                         Int_t ipx      = mPad->PadX();        // pad number on X
348                         Int_t ipy      = mPad->PadY();        // pad number on Y
349                         Int_t iqpad    = Int_t(mPad->QPad()); // charge per pad
350
351                         if (cathode != (icat+1)) continue;
352                         new((*fAddress)[fCountadr++]) TVector(2);
353                         TVector &trinfo = *((TVector*) (*fAddress)[fCountadr-1]);
354                         trinfo(0) = kBgTag;  // tag background
355                         trinfo(1) = kBgTag;
356                         
357                         fDigits[0] = ipx;
358                         fDigits[1] = ipy;
359                         fDigits[2] = icat;
360                         fDigits[3] = iqpad;
361                         fDigits[4] = 0;
362                         fDigits[5] = -1;
363                         
364                         // build the list of fired pads and update the info
365                         if (!Exists(mPad)) {
366                             CreateNew(mPad);
367                         } else {
368                             Update(mPad);
369                         } //  end if !Exists
370                     } //end loop over clusters
371                 } // hit loop
372             } // track loop
373
374             TTree *fAli = gAlice->TreeK();
375             TFile *file = NULL;
376             
377             if (fAli) file = fAli->GetCurrentFile();
378             file->cd();
379         } // if fMerge
380         delete [] xhit;
381         delete [] yhit;
382
383         Int_t tracks[10];
384         Int_t charges[10];
385         Int_t nentries = fList->GetEntriesFast();
386         
387         for (Int_t nent = 0; nent < nentries; nent++) {
388             AliMUONTransientDigit *address = (AliMUONTransientDigit*)fList->At(nent);
389             if (address == 0) continue; 
390             Int_t ich = address->Chamber();
391             Int_t   q = address->Signal(); 
392             iChamber = &(pMUON->Chamber(ich));
393 //
394 //  Digit Response (noise, threshold, saturation, ...)
395             AliMUONResponse * response = iChamber->ResponseModel();
396             q = response->DigitResponse(q);
397             
398             if (!q) continue;
399             
400             fDigits[0] = address->PadX();
401             fDigits[1] = address->PadY();
402             fDigits[2] = address->Cathode();
403             fDigits[3] = q;
404             fDigits[4] = address->Physics();
405             fDigits[5] = address->Hit();
406             
407             TObjArray* fTrList = (TObjArray*)address->TrackList();
408             Int_t nptracks = fTrList->GetEntriesFast();
409
410             // this was changed to accomodate the real number of tracks
411
412             if (nptracks > 10) {
413                 printf("\n Attention - nptracks > 10 %d \n", nptracks);
414                 nptracks = 10;
415             }
416             if (nptracks > 2) {
417                 printf("Attention - nptracks > 2  %d \n",nptracks);
418                 printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,fDigits[0],fDigits[1],q);
419             }
420             for (Int_t tr = 0; tr < nptracks; tr++) {
421                 TVector *ppP = (TVector*)fTrList->At(tr);
422                 if(!ppP ) printf("ppP - %p\n",ppP);
423                 TVector &pp  = *ppP;
424                 tracks[tr]   = Int_t(pp(0));
425                 charges[tr]  = Int_t(pp(1));
426             }      //end loop over list of tracks for one pad
427             // Sort list of tracks according to charge
428             if (nptracks > 1) {
429                 pMUON->SortTracks(tracks,charges,nptracks);
430             }
431             if (nptracks < 10 ) {
432                 for (Int_t i = nptracks; i < 10; i++) {
433                     tracks[i]  = 0;
434                     charges[i] = 0;
435                 }
436             }
437             
438             // fill digits
439             pMUON->AddDigits(ich,tracks,charges,fDigits);
440             // delete fTrList;
441         }
442         gAlice->TreeD()->Fill();
443         pMUON->ResetDigits();
444         fList->Delete();
445
446         
447         for(Int_t ii = 0; ii < AliMUONConstants::NCh(); ++ii) {
448             if (fHitMap[ii]) {
449                 hm=fHitMap[ii];
450                 delete hm;
451                 fHitMap[ii] = 0;
452             }
453         }
454         delete [] nmuon;    
455     } //end loop over cathodes
456     delete [] fHitMap;
457     char hname[30];
458     sprintf(hname,"TreeD%d",fEvNrSig);
459     gAlice->TreeD()->Write(hname);
460     // reset tree
461     gAlice->TreeD()->Reset();
462     delete fList;
463     
464     if (fAddress)    fAddress->Delete();
465     if (fHitsBgr)    fHitsBgr->Delete();
466     if (fPadHitsBgr) fPadHitsBgr->Delete();
467     // gObjectTable->Print();
468 }
469
470
471
472
473