4 #include <TDirectory.h>
12 #include "AliMUONChamber.h"
13 #include "AliMUONConstants.h"
14 #include "AliMUONDigit.h"
15 #include "AliMUONDigitizerv1.h"
16 #include "AliMUONHit.h"
17 #include "AliMUONHitMapA1.h"
18 #include "AliMUONPadHit.h"
19 #include "AliMUONTransientDigit.h"
21 #include "AliRunDigitizer.h"
22 #include "AliRunLoader.h"
23 #include "AliLoader.h"
25 ClassImp(AliMUONDigitizerv1)
27 //___________________________________________
28 AliMUONDigitizerv1::AliMUONDigitizerv1() :AliDigitizer()
30 // Default ctor - don't use it
34 cerr<<"AliMUONDigitizerv1::AliMUONDigitizerv1"
35 <<"(AliRunDigitizer* manager) was processed"<<endl;
38 //___________________________________________
39 AliMUONDigitizerv1::AliMUONDigitizerv1(AliRunDigitizer* manager)
40 :AliDigitizer(manager)
42 // ctor which should be used
46 fHits = new TClonesArray("AliMUONHit",1000);
48 cerr<<"AliMUONDigitizerv1::AliMUONDigitizerv1"
49 <<"(AliRunDigitizer* manager) was processed"<<endl;
52 //------------------------------------------------------------------------
53 AliMUONDigitizerv1::~AliMUONDigitizerv1()
59 //------------------------------------------------------------------------
60 void AliMUONDigitizerv1::AddTransientDigit(AliMUONTransientDigit * mTD)
62 // Choosing the maping of the cathode plane of the chamber:
63 Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
64 fTDList->AddAtAndExpand(mTD, fTDCounter);
65 fHitMap[iNchCpl]->SetHit( mTD->PadX(), mTD->PadY(), fTDCounter);
69 //------------------------------------------------------------------------
70 Bool_t AliMUONDigitizerv1::ExistTransientDigit(AliMUONTransientDigit * mTD)
72 // Choosing the maping of the cathode plane of the chamber:
73 Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
74 return( fHitMap[iNchCpl]->TestHit(mTD->PadX(), mTD->PadY()) );
77 //------------------------------------------------------------------------
78 Bool_t AliMUONDigitizerv1::Init()
84 //------------------------------------------------------------------------
85 void AliMUONDigitizerv1::UpdateTransientDigit(Int_t track, AliMUONTransientDigit * mTD)
87 // Choosing the maping of the cathode plane of the chamber:
88 Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
89 AliMUONTransientDigit *pdigit =
90 static_cast<AliMUONTransientDigit*>(fHitMap[iNchCpl]->GetHit(mTD->PadX(),mTD->PadY()));
93 Int_t iqpad = mTD->Signal(); // charge per pad
94 pdigit->AddSignal(iqpad);
95 pdigit->AddPhysicsSignal(iqpad);
96 // update list of tracks
100 if (fSignal) charge = iqpad;
101 //else charge = kBgTag;
102 else charge = iqpad + fMask;
104 pdigit->UpdateTrackList(track,charge);
108 //--------------------------------------------------------------------------
109 void AliMUONDigitizerv1::MakeTransientDigit(Int_t track, Int_t iHit, AliMUONHit * mHit)
111 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
113 cerr<<"AliMUONDigitizerv1::Digitize Error:"
114 <<" module MUON not found in the input file"<<endl;
116 if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::MakeTransientDigit starts"<<endl;
117 Int_t ichamber = mHit->Chamber()-1;
118 AliMUONChamber & chamber = pMUON->Chamber(ichamber);
119 Float_t xhit = mHit->X();
120 Float_t yhit = mHit->Y();
121 Float_t zhit = mHit->Z();
122 Float_t eloss= mHit->Eloss();
123 Float_t tof = mHit->Age();
124 // Variables for chamber response from AliMUONChamber::DisIntegration
125 Float_t newdigit[6][500]; // Pad information
126 Int_t nnew=0; // Number of touched Pads per hit
130 // Calls the charge disintegration method of the current chamber
131 if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::MakeTransientDigit calling AliMUONChamber::DisIngtegration starts"<<endl;
132 chamber.DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newdigit);
133 // Creating a new TransientDigits from hit
134 for(Int_t iTD=0; iTD<nnew; iTD++) {
135 digits[0] = Int_t(newdigit[1][iTD]); // Padx of the Digit
136 digits[1] = Int_t(newdigit[2][iTD]); // Pady of the Digit
137 digits[2] = Int_t(newdigit[5][iTD]); // Cathode plane
138 digits[3] = Int_t(newdigit[3][iTD]); // Induced charge in the Pad
139 if (fSignal) digits[4] = Int_t(newdigit[3][iTD]);
141 digits[5] = iHit+fMask; // Hit number in the list
142 if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::MakeTransientDigit " <<
143 "PadX "<< digits[0] << " " <<
144 "PadY "<< digits[1] << " " <<
145 "Plane " << digits[2] << " " <<
146 "Charge " << digits[3] <<" " <<
147 "Hit " << digits[5] << endl;
151 if (fSignal) charge = digits[3];
152 //else charge = kBgTag;
153 else charge = digits[3] + fMask;
155 if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::MakeTransientDigit Creating AliMUONTransientDigit"<<endl;
156 AliMUONTransientDigit * mTD = new AliMUONTransientDigit(ichamber, digits);
157 mTD->AddToTrackList(track,charge);
158 if (!ExistTransientDigit(mTD)) {
159 AddTransientDigit(mTD);
160 if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::MakeTransientDigit Adding TransientDigit"<<endl;
163 if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::MakeTransientDigit updating TransientDigit"<<endl;
164 UpdateTransientDigit(track, mTD);
169 //-----------------------------------------------------------------------
170 void AliMUONDigitizerv1::Exec(Option_t* option)
172 TString optionString = option;
173 if (optionString.Data() == "deb") {
174 cout<<"AliMUONDigitizerv1::Exec: called with option deb "<<endl;
177 AliMUONChamber* chamber;
178 AliSegmentation* c1Segmentation; //Cathode plane c1 of the chamber
179 AliSegmentation* c2Segmentation; //Cathode place c2 of the chamber
181 if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::Digitize() starts"<<endl;
182 fTDList = new TObjArray;
184 //Loaders (We assume input0 to be the output too)
185 AliRunLoader * runloader; // Input loader
188 runloader = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(0));
189 if (runloader == 0x0) {
190 cerr<<"AliMUONDigitizerv1::Digitize() opening file "<<fManager->GetInputFileName(0,0)<<endl;
191 return; // RunDigitizer is not working.
193 gime = runloader->GetLoader("MUONLoader");
194 if (gime->TreeH()==0x0) {
195 Info("Digitize","TreeH is not loaded yet. Loading...");
196 gime->LoadHits("READ");
197 Info("Digitize","Now treeH is %#x. MUONLoader is %#x",gime->TreeH(),gime);
200 if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::Digitize() loaders"<<endl;
202 if (runloader->GetAliRun() == 0x0) runloader->LoadgAlice();
203 gAlice = runloader->GetAliRun();
205 // Getting Module MUON
206 AliMUON *pMUON = (AliMUON *) gAlice->GetDetector("MUON");
208 cerr<<"AliMUONDigitizerv1::Digitize Error:"
209 <<" module MUON not found in the input file"<<endl;
214 Int_t currentevent = fManager->GetOutputEventNr();
216 if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::Digitize() Event Number is "<<currentevent <<endl;
217 if ( (currentevent<10) ||
218 (Int_t(TMath::Log10(currentevent)) == TMath::Log10(currentevent) ) )
219 cout <<"ALiMUONDigitizerv1::Digitize() Event Number is "<< currentevent <<endl;
221 // Output file for digits
222 AliRunLoader * runloaderout = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
223 AliLoader * gimeout = runloaderout->GetLoader("MUONLoader");
224 // New branch per chamber for MUON digit in the tree of digits
225 if (gime->TreeD() == 0x0) gimeout->MakeDigitsContainer();
226 TTree* treeD = gimeout->TreeD();
227 pMUON->MakeBranchInTreeD(treeD);
229 // Array of pointer of the AliMUONHitMapA1:
230 // two HitMaps per chamber, or one HitMap per cahtode plane
231 fHitMap= new AliMUONHitMapA1* [2*AliMUONConstants::NCh()];
233 //Loop over chambers for the definition AliMUONHitMap
234 for (Int_t i=0; i<AliMUONConstants::NCh(); i++) {
235 chamber = &(pMUON->Chamber(i));
236 c1Segmentation = chamber->SegmentationModel(1); // Cathode plane 1
237 fHitMap[i] = new AliMUONHitMapA1(c1Segmentation, fTDList);
238 c2Segmentation = chamber->SegmentationModel(2); // Cathode plane 2
239 fHitMap[i+AliMUONConstants::NCh()] = new AliMUONHitMapA1(c2Segmentation, fTDList);
242 // Loop over files to merge and to digitize
244 for (Int_t inputFile=0; inputFile<fManager->GetNinputs(); inputFile++) {
245 if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::Digitize() Input File is "<<inputFile<<endl;
248 TBranch *branchHits = 0;
250 // Connect MUON Hit branch
251 if (inputFile > 0 ) {
253 runloader = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(inputFile));
254 if (runloader == 0x0) {
255 cerr<<"AliMUONDigitizerv1::Digitize() RunLoader for inputFile "<<inputFile<< " not found !!! "<<endl;
257 gime = runloader->GetLoader("MUONLoader");
258 if (gime->TreeH() == 0x0) gime->LoadHits("READ");
261 // Setting the address of fHits list
262 TTree *treeH = gime->TreeH();
264 Error("Digitize","Can not get TreeH from input %d",inputFile);
265 Info("Digitize","Now treeH is %#x. MUONLoader is %#x",gime->TreeH(),gime);
269 cerr<<"AliMUONDigitizerv1::Exec inputFile is "<<inputFile<<" "<<endl;
270 cerr<<"AliMUONDigitizerv1::Exec treeH, fHits "<<treeH<<" "<<fHits<<endl;
272 if (treeH && fHits) {
273 branchHits = treeH->GetBranch("MUON");
276 branchHits->SetAddress(&fHits);
279 Error("Exec","branch MUON was not found");
281 if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::Exec branchHits = "<<branchHits<<endl;
284 fMask = fManager->GetMask(inputFile);
288 Int_t ntracks = (Int_t) treeH->GetEntries();
289 for (itrack = 0; itrack < ntracks; itrack++) {
290 if (GetDebug()>2) cerr<<"AliMUONDigitizerv1::Exec itrack = "<<itrack<<endl;
292 treeH->GetEvent(itrack);
295 Int_t ihit, ichamber;
297 for(ihit = 0; ihit < fHits->GetEntriesFast(); ihit++) {
298 mHit = static_cast<AliMUONHit*>(fHits->At(ihit));
299 ichamber = mHit->Chamber()-1; // chamber number
300 if (ichamber > AliMUONConstants::NCh()-1) {
301 cerr<<"AliMUONDigitizer: ERROR: "
302 <<"fNch > AliMUONConstants::NCh()-1, fNch, NCh(): "
303 <<ichamber<<", "<< AliMUONConstants::NCh()<<endl;
306 chamber = &(pMUON->Chamber(ichamber));
308 //Dumping Hit content:
310 cerr<<"AliMuonDigitizerv1::Exec ihit, ichamber, x, y, z, eloss " <<
312 mHit->Chamber() << " " <<
316 mHit->Eloss() << " " << endl;
319 // Inititializing Correlation
320 chamber->ChargeCorrelationInit();
321 if (ichamber < AliMUONConstants::NTrackingCh()) {
323 // Initialize hit position (cursor) in the segmentation model
324 chamber->SigGenInit(mHit->X(), mHit->Y(), mHit->Z());
328 MakeTransientDigit(itrack, ihit, mHit);
332 if (GetDebug()>2) cerr<<"AliMUONDigitizer::Exec End of hits, track and file loops"<<endl;
336 for(icat=0; icat<2; icat++) {
338 // Filling Digit List
339 Int_t tracks[kMAXTRACKS];
340 Int_t charges[kMAXTRACKS];
341 Int_t nentries = fTDList->GetEntriesFast();
343 for (Int_t nent = 0; nent < nentries; nent++) {
344 AliMUONTransientDigit *address = (AliMUONTransientDigit*)fTDList->At(nent);
345 if (address == 0) continue;
346 Int_t ich = address->Chamber();
347 Int_t q = address->Signal();
348 chamber = &(pMUON->Chamber(ich));
350 // Digit Response (noise, threshold, saturation, ...)
351 AliMUONResponse * response = chamber->ResponseModel();
352 q = response->DigitResponse(q,address);
356 digits[0] = address->PadX();
357 digits[1] = address->PadY();
358 digits[2] = address->Cathode()-1;
360 digits[4] = address->Physics();
361 digits[5] = address->Hit();
363 Int_t nptracks = address->GetNTracks();
365 if (nptracks > kMAXTRACKS) {
367 cerr<<"AliMUONDigitizer:Exec nptracks > 10 "<<nptracks;
368 cerr<<"reset to max value "<<kMAXTRACKS<<endl;
370 nptracks = kMAXTRACKS;
372 if (nptracks > 2 && GetDebug() >2) {
373 cerr<<"AliMUONDigitizer::Exec nptracks > 2 "<<nptracks<<endl;
374 // printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[1],q);
376 for (Int_t tr = 0; tr < nptracks; tr++) {
377 tracks[tr] = address->GetTrack(tr);
378 charges[tr] = address->GetCharge(tr);
379 } //end loop over list of tracks for one pad
380 // Sort list of tracks according to charge
382 SortTracks(tracks,charges,nptracks);
384 if (nptracks < kMAXTRACKS ) {
385 for (Int_t i = nptracks; i < kMAXTRACKS; i++) {
392 if (GetDebug()>3) cerr<<"AliMUONDigitzerv1::Exex TransientDigit to Digit"<<endl;
393 if ( digits[2] == icat ) pMUON->AddDigits(ich,tracks,charges,digits);
395 // Filling list of digits per chamber for a given cathode.
397 pMUON->ResetDigits();
398 } // end loop cathode
401 for(Int_t ii = 0; ii < 2*AliMUONConstants::NCh(); ++ii) {
409 cerr<<"AliMUONDigitizer::Exec: writing the TreeD: "
410 <<treeD->GetName()<<endl;
412 gimeout->WriteDigits("OVERWRITE");
416 if (fHits) fHits->Clear();
419 //------------------------------------------------------------------------
420 void AliMUONDigitizerv1::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr)
423 // Sort the list of tracks contributing to a given digit
424 // Only the 3 most significant tracks are acctually sorted
428 // Loop over signals, only 3 times
433 Int_t idx[3] = {-2,-2,-2};
434 Int_t jch[3] = {-2,-2,-2};
435 Int_t jtr[3] = {-2,-2,-2};
446 if((i == 1 && j == idx[i-1])
447 ||(i == 2 && (j == idx[i-1] || j == idx[i-2]))) continue;
449 if(charges[j] > qmax) {
457 jch[i]=charges[jmax];