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