1 /**************************************************************************
2 * Copyright(c) 1998-2000, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 Revision 1.4 2001/03/20 13:36:11 egangler
19 TFile memory leak and "too many files open" problem solved (?):
20 the backgroud file is open only once forever, and not once for each event.
22 Revision 1.3 2001/03/05 23:57:44 morsch
23 Writing of digit tree moved to macro.
25 Revision 1.2 2001/03/05 08:40:25 morsch
26 Method SortTracks(..) imported from AliMUON.
28 Revision 1.1 2001/02/02 14:11:53 morsch
29 AliMUONMerger prototype to be called by the merge manager.
35 #include <TObjArray.h>
37 #include <TDirectory.h>
40 // #include "AliMerger.h"
41 // #include "AliMergable.h"
42 #include "AliMUONMerger.h"
43 #include "AliMUONConstants.h"
44 #include "AliMUONChamber.h"
45 #include "AliHitMap.h"
46 #include "AliMUONHitMapA1.h"
48 #include "AliMUONHit.h"
49 #include "AliMUONPadHit.h"
50 #include "AliMUONDigit.h"
51 #include "AliMUONTransientDigit.h"
55 ClassImp(AliMUONMerger)
57 //___________________________________________
58 AliMUONMerger::AliMUONMerger()
60 // Default constructor
75 //------------------------------------------------------------------------
76 AliMUONMerger::~AliMUONMerger()
79 if (fTrH1) delete fTrH1;
80 if (fHitsBgr) delete fHitsBgr;
81 if (fPadHitsBgr) delete fPadHitsBgr;
82 if (fHitMap) delete fHitMap;
83 if (fList) delete fList;
84 if (fBgrFile) delete fBgrFile;
87 //------------------------------------------------------------------------
88 Bool_t AliMUONMerger::Exists(const AliMUONPadHit *mergable)
90 AliMUONPadHit *padhit = (AliMUONPadHit*) mergable;
91 return (fHitMap[fNch]->TestHit(padhit->PadX(),padhit->PadY()));
94 //------------------------------------------------------------------------
95 void AliMUONMerger::Update(AliMUONPadHit *padhit)
97 AliMUONTransientDigit *pdigit =
98 static_cast<AliMUONTransientDigit*>(
99 fHitMap[fNch]->GetHit(padhit->PadX(),padhit->PadY()));
103 Int_t iqpad = padhit->QPad(); // charge per pad
104 pdigit->AddSignal(iqpad);
105 pdigit->AddPhysicsSignal(iqpad);
107 // update list of tracks
117 pdigit->UpdateTrackList(track,charge);
120 //------------------------------------------------------------------------
121 void AliMUONMerger::CreateNew(AliMUONPadHit *padhit)
123 fList->AddAtAndExpand(
124 new AliMUONTransientDigit(fNch,fDigits),fCounter);
125 fHitMap[fNch]->SetHit(padhit->PadX(),padhit->PadY(),fCounter);
126 AliMUONTransientDigit* pdigit =
127 (AliMUONTransientDigit*)fList->At(fList->GetLast());
132 charge = padhit->QPad();
137 pdigit->AddToTrackList(track,charge);
142 //------------------------------------------------------------------------
143 void AliMUONMerger::Init()
146 // open only once the background file !!
147 if (fMerge && !fBgrFile) fBgrFile = InitBgr();
152 //------------------------------------------------------------------------
153 TFile* AliMUONMerger::InitBgr()
155 // Initialise background event
156 TFile *file = new TFile(fFnBgr);
157 // add error checking later
158 printf("\n AliMUONMerger has opened %s file with background event \n", fFnBgr);
159 fHitsBgr = new TClonesArray("AliMUONHit",1000);
160 fPadHitsBgr = new TClonesArray("AliMUONPadHit",1000);
164 //------------------------------------------------------------------------
165 void AliMUONMerger::Digitise()
168 // keep galice.root for signal and name differently the file for
169 // background when add! otherwise the track info for signal will be lost !
171 AliMUONChamber* iChamber;
172 AliSegmentation* segmentation;
174 fList = new TObjArray;
176 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
177 fHitMap= new AliHitMap* [AliMUONConstants::NCh()];
181 // Get Hits Tree header from file
182 //if(fHitsBgr) fHitsBgr->Clear(); // Useless because line 327
183 //if(fPadHitsBgr) fPadHitsBgr->Clear(); // Useless because line 328
184 if(fTrH1) delete fTrH1;
188 sprintf(treeName,"TreeH%d",fEvNrBgr);
189 fTrH1 = (TTree*)gDirectory->Get(treeName);
191 printf("ERROR: cannot find Hits Tree for event:%d\n",fEvNrBgr);
194 // Set branch addresses
197 sprintf(branchname,"%s",pMUON->GetName());
198 if (fTrH1 && fHitsBgr) {
199 branch = fTrH1->GetBranch(branchname);
200 if (branch) branch->SetAddress(&fHitsBgr);
202 if (fTrH1 && fPadHitsBgr) {
203 branch = fTrH1->GetBranch("MUONCluster");
204 if (branch) branch->SetAddress(&fPadHitsBgr);
208 // loop over cathodes
212 for (int icat = 0; icat < 2; icat++) {
214 Int_t * nmuon = new Int_t [AliMUONConstants::NCh()];
215 for (Int_t i = 0; i < AliMUONConstants::NCh(); i++) {
216 iChamber = &(pMUON->Chamber(i));
217 if (iChamber->Nsec() == 1 && icat == 1) {
220 segmentation = iChamber->SegmentationModel(icat+1);
222 fHitMap[i] = new AliMUONHitMapA1(segmentation, fList);
230 TTree *treeH = gAlice->TreeH();
231 Int_t ntracks = (Int_t) treeH->GetEntries();
233 for (fTrack = 0; fTrack < ntracks; fTrack++) {
235 treeH->GetEvent(fTrack);
238 for(AliMUONHit* mHit = (AliMUONHit*)pMUON->FirstHit(-1);
240 mHit = (AliMUONHit*)pMUON->NextHit())
242 fNch = mHit->Chamber()-1; // chamber number
243 if (fNch > AliMUONConstants::NCh()-1) continue;
244 iChamber = &(pMUON->Chamber(fNch));
247 // Loop over pad hits
248 for (AliMUONPadHit* mPad =
249 (AliMUONPadHit*)pMUON->FirstPad(mHit,pMUON->PadHits());
251 mPad = (AliMUONPadHit*)pMUON->NextPad(pMUON->PadHits()))
253 Int_t cathode = mPad->Cathode(); // cathode number
254 Int_t ipx = mPad->PadX(); // pad number on X
255 Int_t ipy = mPad->PadY(); // pad number on Y
256 Int_t iqpad = Int_t(mPad->QPad()); // charge per pad
257 if (cathode != (icat+1)) continue;
259 segmentation = iChamber->SegmentationModel(cathode);
266 if (mHit->Particle() == kMuonPlus ||
267 mHit->Particle() == kMuonMinus) {
268 fDigits[5] = mPad->HitNumber();
269 } else fDigits[5] = -1;
271 // build the list of fired pads and update the info
278 } //end loop over clusters
282 // open the file with background
286 ntracks = (Int_t)fTrH1->GetEntries();
290 for (fTrack = 0; fTrack < ntracks; fTrack++) {
292 if (fHitsBgr) fHitsBgr->Clear();
293 if (fPadHitsBgr) fPadHitsBgr->Clear();
295 fTrH1->GetEvent(fTrack);
299 for(int i = 0; i < fHitsBgr->GetEntriesFast(); ++i)
301 mHit = (AliMUONHit*) (*fHitsBgr)[i];
302 fNch = mHit->Chamber()-1; // chamber number
303 iChamber = &(pMUON->Chamber(fNch));
305 // Loop over pad hits
306 for (AliMUONPadHit* mPad =
307 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHitsBgr);
309 mPad = (AliMUONPadHit*)pMUON->NextPad(fPadHitsBgr))
311 Int_t cathode = mPad->Cathode(); // cathode number
312 Int_t ipx = mPad->PadX(); // pad number on X
313 Int_t ipy = mPad->PadY(); // pad number on Y
314 Int_t iqpad = Int_t(mPad->QPad()); // charge per pad
316 if (cathode != (icat+1)) continue;
324 // build the list of fired pads and update the info
330 } //end loop over clusters
334 TTree *fAli = gAlice->TreeK();
337 if (fAli) file = fAli->GetCurrentFile();
341 Int_t tracks[kMAXTRACKS];
342 Int_t charges[kMAXTRACKS];
343 Int_t nentries = fList->GetEntriesFast();
345 for (Int_t nent = 0; nent < nentries; nent++) {
346 AliMUONTransientDigit *address = (AliMUONTransientDigit*)fList->At(nent);
347 if (address == 0) continue;
348 Int_t ich = address->Chamber();
349 Int_t q = address->Signal();
350 iChamber = &(pMUON->Chamber(ich));
352 // Digit Response (noise, threshold, saturation, ...)
353 AliMUONResponse * response = iChamber->ResponseModel();
354 q = response->DigitResponse(q);
358 fDigits[0] = address->PadX();
359 fDigits[1] = address->PadY();
360 fDigits[2] = address->Cathode();
362 fDigits[4] = address->Physics();
363 fDigits[5] = address->Hit();
365 Int_t nptracks = address->GetNTracks();
367 if (nptracks > kMAXTRACKS) {
368 printf("\n Attention - nptracks > kMAXTRACKS %d \n", nptracks);
369 nptracks = kMAXTRACKS;
372 printf("Attention - nptracks > 2 %d \n",nptracks);
373 printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,fDigits[0],fDigits[1],q);
375 for (Int_t tr = 0; tr < nptracks; tr++) {
376 tracks[tr] = address->GetTrack(tr);
377 charges[tr] = address->GetCharge(tr);
378 } //end loop over list of tracks for one pad
379 // Sort list of tracks according to charge
381 SortTracks(tracks,charges,nptracks);
383 if (nptracks < kMAXTRACKS ) {
384 for (Int_t i = nptracks; i < kMAXTRACKS; i++) {
391 pMUON->AddDigits(ich,tracks,charges,fDigits);
393 gAlice->TreeD()->Fill();
394 pMUON->ResetDigits();
398 for(Int_t ii = 0; ii < AliMUONConstants::NCh(); ++ii) {
406 } //end loop over cathodes
410 // no need to delete ... and it makes a crash also
411 // if (fHitsBgr) fHitsBgr->Delete();
412 // if (fPadHitsBgr) fPadHitsBgr->Delete();
413 // gObjectTable->Print();
418 void AliMUONMerger::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr)
421 // Sort the list of tracks contributing to a given digit
422 // Only the 3 most significant tracks are acctually sorted
426 // Loop over signals, only 3 times
431 Int_t idx[3] = {-2,-2,-2};
432 Int_t jch[3] = {-2,-2,-2};
433 Int_t jtr[3] = {-2,-2,-2};
444 if((i == 1 && j == idx[i-1])
445 ||(i == 2 && (j == idx[i-1] || j == idx[i-2]))) continue;
447 if(charges[j] > qmax) {
455 jch[i]=charges[jmax];