]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONDigitizer.cxx
Logging of Debug, Info and Error Messages follwing AliRoot Standard http://aliweb...
[u/mrichter/AliRoot.git] / MUON / AliMUONDigitizer.cxx
CommitLineData
28752ff4 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
88cb7938 16/* $Id$ */
ba030c0e 17
cf286af7 18#include "AliRun.h"
19#include "AliRunDigitizer.h"
88cb7938 20#include "AliRunLoader.h"
88cb7938 21
22#include "AliMUONDigitizer.h"
23#include "AliMUONConstants.h"
24#include "AliMUONChamber.h"
25#include "AliMUONHitMapA1.h"
28752ff4 26#include "AliMUON.h"
30178c30 27#include "AliMUONLoader.h"
116cbefd 28#include "AliMUONChamber.h"
29#include "AliMUONConstants.h"
116cbefd 30#include "AliMUONDigitizer.h"
28752ff4 31#include "AliMUONTransientDigit.h"
30178c30 32#include "AliMUONHitMapA1.h"
ce3e25a8 33#include "AliMUONTriggerDecision.h"
8c343c7c 34#include "AliLog.h"
30178c30 35
cf286af7 36
37/////////////////////////////////////////////////////////////////////////////////////
38//
39// AliMUONDigitizer should be base abstract class of all digitisers in the MUON
40// module. It implements the common functionality of looping over input streams
41// filling the fTDList and writing the fTDList to the output stream.
42// Inheriting digitizers need to override certain methods to choose and initialize
43// the correct input and output trees, apply the correct detector response if any
44// and implement how the transient digits are generated from the input stream.
45//
46/////////////////////////////////////////////////////////////////////////////////////
28752ff4 47
48ClassImp(AliMUONDigitizer)
49
50//___________________________________________
cf286af7 51AliMUONDigitizer::AliMUONDigitizer() :
52 AliDigitizer(),
53 fHitMap(0),
54 fTDList(0),
55 fTDCounter(0),
56 fMask(0),
57 fSignal(0),
58 fDebug(0)
28752ff4 59{
cf286af7 60// Default constructor.
61// Initializes all pointers to NULL.
62
30178c30 63 fRunLoader = NULL;
64 fGime = NULL;
65 fMUON = NULL;
66 fMUONData = NULL;
ce3e25a8 67 fTrigDec = NULL;
cf286af7 68};
28752ff4 69
70//___________________________________________
cf286af7 71AliMUONDigitizer::AliMUONDigitizer(AliRunDigitizer* manager) :
72 AliDigitizer(manager),
73 fHitMap(0),
74 fTDList(0),
75 fTDCounter(0),
76 fMask(0),
77 fSignal(0),
78 fDebug(0)
28752ff4 79{
cf286af7 80// Constructor which should be used rather than the default constructor.
81// Initializes all pointers to NULL.
82
30178c30 83 fRunLoader = NULL;
84 fGime = NULL;
85 fMUON = NULL;
86 fMUONData = NULL;
ce3e25a8 87 fTrigDec = NULL;
cf286af7 88};
28752ff4 89
11ca64ac 90//___________________________________________
91AliMUONDigitizer::AliMUONDigitizer(const AliMUONDigitizer& rhs)
92 : AliDigitizer(rhs)
93{
94// Protected copy constructor
95
8c343c7c 96 AliFatal("Not implemented.");
11ca64ac 97}
98
8789635b 99//___________________________________________
100AliMUONDigitizer::~AliMUONDigitizer()
101{
102// Destructor
ce3e25a8 103 if (fMUONData)
104 delete fMUONData;
105
106 if (fTrigDec)
107 delete fTrigDec;
8789635b 108}
109
11ca64ac 110//-------------------------------------------------------------------
111AliMUONDigitizer&
112AliMUONDigitizer::operator=(const AliMUONDigitizer& rhs)
113{
114// Protected assignement operator
115
116 if (this == &rhs) return *this;
117
8c343c7c 118 AliFatal("Not implemented.");
11ca64ac 119
120 return *this;
121}
122
28752ff4 123//------------------------------------------------------------------------
cf286af7 124Bool_t AliMUONDigitizer::Init()
28752ff4 125{
cf286af7 126// Does nothing.
127 return kTRUE;
28752ff4 128}
129
130//------------------------------------------------------------------------
cf286af7 131void AliMUONDigitizer::Exec(Option_t* option)
28752ff4 132{
cf286af7 133// The main work loop starts here.
134// The digitization process is broken up into two steps:
135// 1) Loop over input streams and create transient digits from the input.
136// Done in GenerateTransientDigits()
137// 2) Loop over the generated transient digits and write them to the output
138// stream. Done in CreateDigits()
139
8c343c7c 140 AliDebug(1, "Running digitiser.");
cf286af7 141 ParseOptions(option);
142
143 if (fManager->GetNinputs() == 0)
144 {
8c343c7c 145 AliWarning("No inputs set, nothing to do.");
cf286af7 146 return;
147 };
148
ce3e25a8 149 if (!FetchLoaders(fManager->GetInputFolderName(0), fRunLoader, fGime) ) return;
30178c30 150 if (! FetchGlobalPointers(fRunLoader) ) return;
ce3e25a8 151 if (! FetchTriggerPointer(fGime) ) return;
cf286af7 152
153 InitArrays();
154
8c343c7c 155 AliDebug(2, Form("Event Number is %d.", fManager->GetOutputEventNr()));
cf286af7 156
157 // Loop over files to merge and to digitize
158 fSignal = kTRUE;
159 for (Int_t inputFile = 0; inputFile < fManager->GetNinputs(); inputFile++)
160 {
161 fMask = fManager->GetMask(inputFile);
8c343c7c 162 AliDebug(2, Form("Digitising folder %d, with fMask = %d: %s", inputFile, fMask,
163 (const char*)fManager->GetInputFolderName(inputFile)));
cf286af7 164
165 if (inputFile != 0)
166 // If this is the first file then we already have the loaders loaded.
30178c30 167 if (! FetchLoaders(fManager->GetInputFolderName(inputFile), fRunLoader, fGime) )
cf286af7 168 continue;
169 else
170 // If this is not the first file then it is assumed to be background.
171 fSignal = kFALSE;
172
30178c30 173 if (! InitInputData(fGime) ) continue;
cf286af7 174 GenerateTransientDigits();
30178c30 175 CleanupInputData(fGime);
cf286af7 176 };
177
30178c30 178 Bool_t ok = FetchLoaders(fManager->GetOutputFolderName(), fRunLoader, fGime);
179 if (ok) ok = InitOutputData(fGime);
cf286af7 180 if (ok) CreateDigits();
ce3e25a8 181 if (ok) CreateTrigger();
30178c30 182 if (ok) CleanupOutputData(fGime);
cf286af7 183
184 CleanupArrays();
ce3e25a8 185 CleanupTriggerArrays();
cf286af7 186};
187
188//--------------------------------------------------------------------------
189void AliMUONDigitizer::AddOrUpdateTransientDigit(AliMUONTransientDigit* mTD)
190{
191// Checks to see if the transient digit exists in the corresponding fHitMap.
192// If it does then the digit is updated otherwise it is added.
193
194 if (ExistTransientDigit(mTD))
195 {
196 UpdateTransientDigit(mTD);
197 delete mTD; // The new digit can be deleted because it was not added.
198 }
199 else
200 AddTransientDigit(mTD);
201};
28752ff4 202
203//------------------------------------------------------------------------
cf286af7 204void AliMUONDigitizer::UpdateTransientDigit(AliMUONTransientDigit* mTD)
28752ff4 205{
cf286af7 206// Update the transient digit that is already in the fTDList by adding the new
207// transient digits charges and track lists to the existing one.
208
8c343c7c 209 AliDebug(4,Form( "Updating transient digit 0x%X", (void*)mTD));
cf286af7 210 // Choosing the maping of the cathode plane of the chamber:
211 Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
212 AliMUONTransientDigit *pdigit =
213 static_cast<AliMUONTransientDigit*>( fHitMap[iNchCpl]->GetHit(mTD->PadX(),mTD->PadY()) );
214
215 // update charge
216 pdigit->AddSignal( mTD->Signal() );
217 pdigit->AddPhysicsSignal( mTD->Physics() );
218
219 // update list of tracks
220 Int_t ntracks = mTD->GetNTracks();
221 if (ntracks > kMAXTRACKS) // Truncate the number of tracks to kMAXTRACKS if we have to.
222 {
8c343c7c 223 AliDebug(1,Form(
224 "TransientDigit returned the number of tracks to be %d, which is bigger than kMAXTRACKS.",
225 ntracks));
226 AliDebug(1,Form( "Reseting the number of tracks to be %d.", kMAXTRACKS));
cf286af7 227 ntracks = kMAXTRACKS;
228 };
229
230 for (Int_t i = 0; i < ntracks; i++)
231 {
232 pdigit->UpdateTrackList( mTD->GetTrack(i), mTD->GetCharge(i) );
233 };
234};
28752ff4 235
236//------------------------------------------------------------------------
cf286af7 237void AliMUONDigitizer::AddTransientDigit(AliMUONTransientDigit* mTD)
28752ff4 238{
cf286af7 239// Adds the transient digit to the fTDList and sets the appropriate entry
240// in the fHitMap arrays.
241
8c343c7c 242 AliDebug(4,Form( "Adding transient digit 0x%X", (void*)mTD));
cf286af7 243 // Choosing the maping of the cathode plane of the chamber:
244 Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
245 fTDList->AddAtAndExpand(mTD, fTDCounter);
246 fHitMap[iNchCpl]->SetHit( mTD->PadX(), mTD->PadY(), fTDCounter);
247 fTDCounter++;
248};
28752ff4 249
250//------------------------------------------------------------------------
cf286af7 251Bool_t AliMUONDigitizer::ExistTransientDigit(AliMUONTransientDigit* mTD)
28752ff4 252{
cf286af7 253// Checks if the transient digit already exists on the corresponding fHitMap.
254// i.e. is there a transient digit on the same chamber, cathode and pad position
255// as mTD. If yes then kTRUE is returned else kFASLE is returned.
256
257 // Choosing the maping of the cathode plane of the chamber:
258 Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
259 return( fHitMap[iNchCpl]->TestHit(mTD->PadX(), mTD->PadY()) );
260};
28752ff4 261
cf286af7 262//-----------------------------------------------------------------------
263void AliMUONDigitizer::CreateDigits()
264{
265// Loops over the fTDList for each cathode, gets the correct signal for the
266// digit and adds the new digit to the output stream.
267
8c343c7c 268 AliDebug(2, "Creating digits...");
cf286af7 269 for (Int_t icat = 0; icat < 2; icat++)
270 {
271 //
272 // Filling Digit List
273 Int_t nentries = fTDList->GetEntriesFast();
274 for (Int_t nent = 0; nent < nentries; nent++)
275 {
276 AliMUONTransientDigit* td = (AliMUONTransientDigit*)fTDList->At(nent);
277 if (td == NULL) continue;
278
279 // Must be the same cathode, otherwise we will fill a mixture
280 // of digits from both cathodes.
281 if (icat != td->Cathode() - 1) continue;
282
8c343c7c 283 AliDebug(3,Form( "Creating digit from transient digit 0x%X", (void*)td));
cf286af7 284
285 Int_t q = GetSignalFrom(td);
286 if (q > 0) AddDigit(td, q);
287 };
288 FillOutputData();
289 };
290};
28752ff4 291
292//------------------------------------------------------------------------
30178c30 293void AliMUONDigitizer::AddDigit(AliMUONTransientDigit* td, Int_t responseCharge)
28752ff4 294{
cf286af7 295// Prepares the digits, track and charge arrays in preparation for a call to
296// AddDigit(Int_t, Int_t[kMAXTRACKS], Int_t[kMAXTRACKS], Int_t[6])
297// This method is called by CreateDigits() whenever a new digit needs to be added
298// to the output stream trees.
30178c30 299// The responseCharge value is used as the Signal of the new digit.
cf286af7 300// The OnWriteTransientDigit method is also called just before the adding the
301// digit to allow inheriting digitizers to be able to do some specific processing
302// at this point.
303
304 Int_t tracks[kMAXTRACKS];
305 Int_t charges[kMAXTRACKS];
306 Int_t digits[6];
88cb7938 307
cf286af7 308 digits[0] = td->PadX();
309 digits[1] = td->PadY();
310 digits[2] = td->Cathode() - 1;
30178c30 311 digits[3] = responseCharge;
cf286af7 312 digits[4] = td->Physics();
313 digits[5] = td->Hit();
314
315 Int_t nptracks = td->GetNTracks();
316 if (nptracks > kMAXTRACKS)
317 {
8c343c7c 318 AliDebug(1, Form(
319 "TransientDigit returned the number of tracks to be %d, which is bigger than kMAXTRACKS.",
320 nptracks));
321 AliDebug(1, Form("Reseting the number of tracks to be %d.", kMAXTRACKS));
cf286af7 322 nptracks = kMAXTRACKS;
323 };
324
325 for (Int_t i = 0; i < nptracks; i++)
326 {
327 tracks[i] = td->GetTrack(i);
328 charges[i] = td->GetCharge(i);
329 };
330
331 // Sort list of tracks according to charge
332 SortTracks(tracks,charges,nptracks);
333
334 if (nptracks < kMAXTRACKS )
335 {
336 for (Int_t i = nptracks; i < kMAXTRACKS; i++)
337 {
338 tracks[i] = -1;
339 charges[i] = 0;
340 };
341 };
342
8c343c7c 343 AliDebug(4,Form( "Adding digit with charge %d.", responseCharge));
cf286af7 344
345 OnWriteTransientDigit(td);
346 AddDigit(td->Chamber(), tracks, charges, digits);
ce3e25a8 347 AddDigitTrigger(td->Chamber(), tracks, charges, digits);
cf286af7 348};
28752ff4 349
cf286af7 350//------------------------------------------------------------------------
351void AliMUONDigitizer::OnCreateTransientDigit(AliMUONTransientDigit* /*digit*/, TObject* /*source_object*/)
352{
353 // Does nothing.
354 //
355 // This is derived by Digitisers that want to trace which digits were made from
356 // which hits.
357};
28752ff4 358
b8278504 359//------------------------------------------------------------------------
cf286af7 360void AliMUONDigitizer::OnWriteTransientDigit(AliMUONTransientDigit* /*digit*/)
28752ff4 361{
cf286af7 362 // Does nothing.
363 //
364 // This is derived by Digitisers that want to trace which digits were made from
365 // which hits.
366};
367
368//------------------------------------------------------------------------
369Bool_t AliMUONDigitizer::FetchLoaders(const char* foldername, AliRunLoader*& runloader, AliMUONLoader*& muonloader)
370{
371// Fetches the run loader from the current folder, specified by 'foldername'.
372// The muon loader is then loaded from the fetched run loader.
373// kTRUE is returned if no error occurred otherwise kFALSE is returned.
374
8c343c7c 375 AliDebug(3, Form("Fetching run loader and muon loader from folder: %s", foldername));
cf286af7 376
377 runloader = AliRunLoader::GetRunLoader(foldername);
378 if (runloader == NULL)
379 {
8c343c7c 380 AliError(Form("RunLoader not found in folder: %s", foldername));
cf286af7 381 return kFALSE;
382 }
383 muonloader = (AliMUONLoader*) runloader->GetLoader("MUONLoader");
384 if (muonloader == NULL)
385 {
8c343c7c 386 AliError(Form("MUONLoader not found in folder: %s", foldername));
cf286af7 387 return kFALSE;
388 }
389 return kTRUE;
ce3e25a8 390
cf286af7 391};
392
393//------------------------------------------------------------------------
394Bool_t AliMUONDigitizer::FetchGlobalPointers(AliRunLoader* runloader)
395{
396// Fetches the AliRun object into the global gAlice pointer from the specified
397// run loader. The AliRun object is loaded into memory using the run loader if
398// not yet loaded. The MUON module object is then loaded from gAlice and
399// AliMUONData fetched from the MUON module.
400// kTRUE is returned if no error occurred otherwise kFALSE is returned.
401
8c343c7c 402 AliDebug(3, Form("Fetching gAlice, MUON module and AliMUONData from runloader 0x%X.",
cf286af7 403 (void*)runloader
8c343c7c 404 ));
cf286af7 405
406 if (runloader->GetAliRun() == NULL) runloader->LoadgAlice();
407 gAlice = runloader->GetAliRun();
408 if (gAlice == NULL)
409 {
8c343c7c 410 AliError(Form("Could not find the AliRun object in runloader 0x%X.", (void*)runloader));
cf286af7 411 return kFALSE;
412 };
30178c30 413 fMUON = (AliMUON*) gAlice->GetDetector("MUON");
414 if (fMUON == NULL)
cf286af7 415 {
8c343c7c 416 AliError(Form("Could not find the MUON module in runloader 0x%X.", (void*)runloader));
cf286af7 417 return kFALSE;
418 };
88646004 419
420 AliMUONLoader *muonloader = (AliMUONLoader*) runloader->GetLoader("MUONLoader");
421 if (muonloader == NULL)
422 {
8c343c7c 423 AliError( "MUONLoader not found ");
88646004 424 return kFALSE;
425 }
426
427
a20e540f 428 if (fMUONData == NULL) fMUONData = new AliMUONData(muonloader,"MUON","MUON");
30178c30 429 if (fMUONData == NULL)
cf286af7 430 {
8c343c7c 431 AliError(Form("Could not find AliMUONData object in runloader 0x%X.", (void*)runloader));
cf286af7 432 return kFALSE;
433 };
ce3e25a8 434
cf286af7 435 return kTRUE;
28752ff4 436}
ce3e25a8 437//-----------------------------------------------------------------------
438Bool_t AliMUONDigitizer::FetchTriggerPointer(AliMUONLoader* loader)
439{
440 if (fMUONData == NULL) {
8c343c7c 441 AliError("MUONData not found");
ce3e25a8 442 return kFALSE;
443 }
444
445 if (fTrigDec == NULL)
446 fTrigDec = new AliMUONTriggerDecision(loader,0,fMUONData);
447
448 return kTRUE;
449}
cf286af7 450//------------------------------------------------------------------------
451void AliMUONDigitizer::ParseOptions(Option_t* options)
452{
453// Called by the Exec method. ParseOptions should parse the option string given to the Exec method.
454//
455// The following options are defined:
456// "debug" - Sets the debug level to 99, which will show all debug messages.
457// "deb" - Same as "debug", implemented for backward comparability.
458//
459// If an invalid option is specified it is simply ignored.
460
461 TString optionString = options;
462 if (optionString.Data() == "debug" ||
463 optionString.Data() == "deb" // maintained for compatability.
464 )
465 {
8c343c7c 466 AliInfo("Called with option \"debug\".");
cf286af7 467 SetDebug(99);
468 };
469};
470
471//------------------------------------------------------------------------
472void AliMUONDigitizer::InitArrays()
473{
474// Creates a new fTDList object.
475// Also creates an array of 2 * chamber_number AliMUONHitMapA1 objects
476// in the fHitMaps array. Each one is set to a chamber and cathode
477// specific segmentation model.
478//
479// Note: the fTDList and fHitMap arrays must be NULL before calling this method.
480
8c343c7c 481 AliDebug(2, "Initialising internal arrays.");
482 AliDebug(4, "Creating transient digits list.");
cf286af7 483 fTDList = new TObjArray;
484
485 // Array of pointer of the AliMUONHitMapA1:
486 // two HitMaps per chamber, or one HitMap per cahtode plane
487 fHitMap = new AliMUONHitMapA1* [2*AliMUONConstants::NCh()];
488
489 // Loop over chambers for the definition AliMUONHitMap
490 for (Int_t i = 0; i < AliMUONConstants::NCh(); i++)
491 {
8c343c7c 492 AliDebug(4,Form( "Creating hit map for chamber %d, cathode 1.", i+1));
30178c30 493 AliMUONChamber* chamber = &(fMUON->Chamber(i));
cf286af7 494 AliSegmentation* c1Segmentation = chamber->SegmentationModel(1); // Cathode plane 1
495 fHitMap[i] = new AliMUONHitMapA1(c1Segmentation, fTDList);
8c343c7c 496 AliDebug(4,Form( "Creating hit map for chamber %d, cathode 2.", i+1));
cf286af7 497 AliSegmentation* c2Segmentation = chamber->SegmentationModel(2); // Cathode plane 2
498 fHitMap[i+AliMUONConstants::NCh()] = new AliMUONHitMapA1(c2Segmentation, fTDList);
499 };
500};
501
502//------------------------------------------------------------------------
503void AliMUONDigitizer::CleanupArrays()
504{
505// The arrays fTDList and fHitMap are deleted and the pointers set to NULL.
506
8c343c7c 507 AliDebug(2, "Deleting internal arrays.");
cf286af7 508 for(Int_t i = 0; i < 2*AliMUONConstants::NCh(); i++)
509 {
8c343c7c 510 AliDebug(4,Form( "Deleting hit map for chamber %d, cathode %d.",
511 i%AliMUONConstants::NCh()+1, i/AliMUONConstants::NCh()+1));
cf286af7 512 delete fHitMap[i];
513 };
514 delete [] fHitMap;
515 fHitMap = NULL;
516
8c343c7c 517 AliDebug(4, "Deleting transient digits list.");
cf286af7 518 fTDList->Delete();
519 delete fTDList;
520 fTDList = NULL;
ce3e25a8 521
cf286af7 522};
523
524//------------------------------------------------------------------------
30178c30 525void AliMUONDigitizer::SortTracks(Int_t *tracks, Int_t *charges, Int_t ntr) const
cf286af7 526{
527//
528// Sort the list of tracks contributing to a given digit
529// Only the 3 most significant tracks are actually sorted
530//
531
532 if (ntr <= 1) return;
533
534 //
535 // Loop over signals, only 3 times
536 //
537
538 Int_t qmax;
539 Int_t jmax;
540 Int_t idx[3] = {-2,-2,-2};
541 Int_t jch[3] = {-2,-2,-2};
542 Int_t jtr[3] = {-2,-2,-2};
543 Int_t i, j, imax;
544
545 if (ntr < 3) imax = ntr;
546 else imax=3;
547
548 for(i = 0; i < imax; i++)
549 {
550 qmax=0;
551 jmax=0;
552
553 for(j = 0; j < ntr; j++)
554 {
555 if ( (i == 1 && j == idx[i-1]) ||
556 (i == 2 && (j == idx[i-1] || j == idx[i-2]))
557 )
558 continue;
559
560 if(charges[j] > qmax)
561 {
562 qmax = charges[j];
563 jmax = j;
564 }
565 }
566
567 if(qmax > 0)
568 {
569 idx[i] = jmax;
570 jch[i] = charges[jmax];
571 jtr[i] = tracks[jmax];
572 }
573
574 }
575
576 for(i = 0; i < 3; i++)
577 {
578 if (jtr[i] == -2)
579 {
580 charges[i] = 0;
581 tracks[i] = 0;
582 }
583 else
584 {
585 charges[i] = jch[i];
586 tracks[i] = jtr[i];
587 }
588 }
589};