1 /**************************************************************************
2 * Copyright(c) 1998-1999, 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 #include "AliMUONDigitizerV3.h"
21 #include "AliMUONCalibrationData.h"
22 #include "AliMUONChamber.h"
23 #include "AliMUONConstants.h"
24 #include "AliMUONData.h"
25 #include "AliMUONDigit.h"
26 #include "AliMUONTriggerDecisionV1.h"
27 //#include "AliMUONTriggerElectronics.h"
28 #include "AliMUONCalibParam.h"
29 #include "AliMpDEManager.h"
30 #include "AliMpStationType.h"
32 #include "AliRunDigitizer.h"
33 #include "AliRunLoader.h"
34 #include "Riostream.h"
38 ClassImp(AliMUONDigitizerV3)
40 //_____________________________________________________________________________
41 AliMUONDigitizerV3::AliMUONDigitizerV3(AliRunDigitizer* manager,
42 ETriggerCodeVersion triggerCodeVersion)
43 : AliDigitizer(manager),
46 fIsInitialized(kFALSE),
48 fCalibrationData(0x0),
49 fTriggerProcessor(0x0),
50 fTriggerCodeVersion(triggerCodeVersion)
52 AliDebug(1,Form("AliRunDigitizer=%p",fManager));
55 //_____________________________________________________________________________
56 AliMUONDigitizerV3::~AliMUONDigitizerV3()
60 delete fCalibrationData;
61 delete fTriggerProcessor;
64 //_____________________________________________________________________________
66 AliMUONDigitizerV3::ApplyResponseToDigit(AliMUONDigit& digit)
68 // For trigger digits, simply sets the digit's charge to 0 or 1.
70 // For tracking digits, starting from an ideal digit's charge, we :
72 // - add some noise (thus leading to a realistic charge)
73 // - divide by a gain (thus decalibrating the digit)
74 // - add a pedestal (thus decalibrating the digit)
75 // - sets the signal to zero if below ZeroSuppression() level (thus simulating
79 Int_t detElemId = digit.DetElemId();
80 AliMpStationType stationType = AliMpDEManager::GetStationType(detElemId);
81 if ( stationType == kStationTrigger )
83 if ( digit.Signal() > 0 )
94 // The following is for tracking digits only.
96 Int_t manuId = digit.ManuId();
97 Int_t manuChannel = digit.ManuChannel();
99 AliMUONCalibParam* pedestal = fCalibrationData->Pedestal(detElemId,manuId,manuChannel);
102 AliFatal(Form("Could not get pedestal for DE=%d manuId=%d manuChannel=%d",
103 detElemId,manuId,manuChannel));
105 Float_t adc_noise = gRandom->Gaus(0.0,pedestal->Sigma());
107 AliMUONCalibParam* gain = fCalibrationData->Gain(detElemId,manuId,manuChannel);
110 AliFatal(Form("Could not get gain for DE=%d manuId=%d manuChannel=%d",
111 detElemId,manuId,manuChannel));
114 Float_t signal_noise = adc_noise*gain->Mean();
116 Float_t signal = digit.Signal() + signal_noise;
119 if ( signal > fSaturation )
122 digit.Saturated(kTRUE);
126 if ( gain->Mean() < 1E-6 )
128 AliFatal(Form("Got a too small gain %e for DE=%d manuId=%d manuChannel=%d",
129 gain->Mean(),detElemId,manuId,manuChannel));
131 adc = TMath::Nint( signal / gain->Mean() + pedestal->Mean() );
133 if ( adc <= pedestal->Mean() + 3.0*pedestal->Sigma() )
138 digit.SetPhysicsSignal(TMath::Nint(signal));
139 digit.SetSignal(adc);
143 //_____________________________________________________________________________
145 AliMUONDigitizerV3::ApplyResponse()
147 for ( Int_t ich = 0; ich < AliMUONConstants::NCh(); ++ich )
149 TClonesArray* digits = fOutputData->Digits(ich);
150 Int_t n = digits->GetEntriesFast();
151 for ( Int_t i = 0; i < n; ++i )
153 AliMUONDigit* d = static_cast<AliMUONDigit*>(digits->UncheckedAt(i));
154 ApplyResponseToDigit(*d);
155 if ( d->Signal() <= 0 )
162 for ( Int_t ich = 0; ich < AliMUONConstants::NCh(); ++ich )
164 fOutputData->Digits(ich)->Compress();
168 //_____________________________________________________________________________
170 AliMUONDigitizerV3::AddOrUpdateDigit(TClonesArray& array,
171 const AliMUONDigit& digit)
173 Int_t ix = FindDigitIndex(array,digit);
177 AliMUONDigit* d = static_cast<AliMUONDigit*>(array.UncheckedAt(ix));
178 Bool_t ok = MergeDigits(digit,*d);
181 AliError("Digits are not mergeable !");
185 new(array[ix]) AliMUONDigit(*d);
190 ix = array.GetLast() + 1;
191 new(array[ix]) AliMUONDigit(digit);
196 //_____________________________________________________________________________
198 AliMUONDigitizerV3::Exec(Option_t*)
200 AliDebug(1, "Running digitizer.");
202 if ( fManager->GetNinputs() == 0 )
204 AliWarning("No input set. Nothing to do.");
208 if ( !fIsInitialized )
210 AliError("Not initialized. Cannot perform the work. Sorry");
214 Int_t nInputFiles = fManager->GetNinputs();
216 if ( fOutputData->TreeD() == 0x0 )
218 AliDebug(1,"Calling MakeDigitsContainer");
219 fOutputData->GetLoader()->MakeDigitsContainer();
221 fOutputData->MakeBranch("D,GLT");
222 fOutputData->SetTreeAddress("D,GLT");
224 // Loop over all the input files, and merge the sdigits found in those
226 for ( Int_t iFile = 0; iFile < nInputFiles; ++iFile )
228 AliMUONData* inputData = GetDataAccess(fManager->GetInputFolderName(iFile));
231 AliFatal(Form("Could not get access to input file #%d",iFile));
233 AliDebug(1,Form("inputData=%p",inputData));
234 //FIXME: what about the fMask ???
235 inputData->GetLoader()->LoadSDigits("READ");
236 TTree* treeS = inputData->GetLoader()->TreeS();
237 AliDebug(1,Form("TreeS=%p",treeS));
238 inputData->SetTreeAddress("S");
239 inputData->GetSDigits();
240 MergeWithSDigits(*fOutputData,*inputData);
241 inputData->ResetSDigits();
242 inputData->GetLoader()->UnloadSDigits();
246 // At this point, we do have digit arrays (one per chamber) which contains
247 // the merging of all the sdigits of the input file(s).
248 // We now massage them to apply the detector response, i.e. this
249 // is here that we do the "digitization" work.
255 // We generate the global and local trigger decisions.
256 fTriggerProcessor->ExecuteTask();
258 // Fill the output treeD
259 fOutputData->Fill("D,GLT");
261 // Write to the output tree(D).
262 // Please note that as GlobalTrigger, LocalTrigger and Digits are in the same
263 // tree (=TreeD) in different branches, this WriteDigits in fact writes all of
265 fOutputData->GetLoader()->WriteDigits("OVERWRITE");
267 // Finally, we clean up after ourselves.
268 fOutputData->ResetDigits();
269 fOutputData->ResetTrigger();
270 fOutputData->GetLoader()->UnloadDigits();
273 //_____________________________________________________________________________
275 AliMUONDigitizerV3::FindDigitIndex(TClonesArray& array, const AliMUONDigit& digit)
277 // FIXME: this is of course not the best implementation you can think of.
278 // Reconsider the use of hit/digit map...
279 Int_t n = array.GetEntriesFast();
280 for ( Int_t i = 0; i < n; ++i )
282 AliMUONDigit* d = static_cast<AliMUONDigit*>(array.UncheckedAt(i));
283 if ( d->DetElemId() == digit.DetElemId() &&
284 d->PadX() == digit.PadX() &&
285 d->PadY() == digit.PadY() &&
286 d->Cathode() == digit.Cathode() )
294 //_____________________________________________________________________________
296 AliMUONDigitizerV3::GetDataAccess(const TString& folderName)
298 AliDebug(1,Form("Getting access to folder %s",folderName.Data()));
299 AliRunLoader* runLoader = AliRunLoader::GetRunLoader(folderName);
302 AliError(Form("Could not get RunLoader from folder %s",folderName.Data()));
305 AliLoader* loader = static_cast<AliLoader*>(runLoader->GetLoader("MUONLoader"));
308 AliError(Form("Could not get MuonLoader from folder %s",folderName.Data()));
311 AliMUONData* data = new AliMUONData(loader,"MUON","MUONDataForDigitOutput");
312 AliDebug(1,Form("AliMUONData=%p loader=%p",data,loader));
316 //_____________________________________________________________________________
318 AliMUONDigitizerV3::Init()
322 if ( fIsInitialized )
324 AliError("Object already initialized.");
330 AliError("fManager is null !");
334 fOutputData = GetDataAccess(fManager->GetOutputFolderName());
337 AliError("Can not perform digitization. I'm sorry");
340 AliDebug(1,Form("fOutputData=%p",fOutputData));
342 AliRunLoader* runLoader = fOutputData->GetLoader()->GetRunLoader();
343 AliRun* galice = runLoader->GetAliRun();
344 Int_t runnumber = galice->GetRunNumber();
346 fCalibrationData = new AliMUONCalibrationData(runnumber);
348 switch (fTriggerCodeVersion)
350 case kTriggerDecision:
351 fTriggerProcessor = new AliMUONTriggerDecisionV1(fOutputData);
353 case kTriggerElectronics:
354 AliFatal("Implement me!");
355 // fTrigger = new AliMUONTriggerElectronics(fOutputData);
358 AliFatal("Unknown trigger processor type");
362 fIsInitialized = kTRUE;
366 //_____________________________________________________________________________
368 AliMUONDigitizerV3::MergeDigits(const AliMUONDigit& src, AliMUONDigit& srcAndDest)
370 AliDebug(1,"Merging the following digits:");
371 StdoutToAliDebug(1,src.Print(););
372 StdoutToAliDebug(1,srcAndDest.Print(););
374 Bool_t check = ( src.DetElemId() == srcAndDest.DetElemId() &&
375 src.PadX() == srcAndDest.PadX() &&
376 src.PadY() == srcAndDest.PadY() &&
377 src.Cathode() == srcAndDest.Cathode() );
384 srcAndDest.AddSignal(src.Signal());
385 srcAndDest.AddPhysicsSignal(src.Physics());
386 StdoutToAliDebug(1,cout << "result:"; srcAndDest.Print(););
390 //_____________________________________________________________________________
392 AliMUONDigitizerV3::MergeWithSDigits(AliMUONData& outputData,
393 const AliMUONData& inputData)
397 for ( Int_t ich = 0; ich < AliMUONConstants::NCh(); ++ich )
399 TClonesArray* iDigits = inputData.SDigits(ich);
400 TClonesArray* oDigits = outputData.Digits(ich);
403 AliError(Form("Could not get sdigits for ich=%d",ich));
406 Int_t nSDigits = iDigits->GetEntriesFast();
407 for ( Int_t k = 0; k < nSDigits; ++k )
409 AliMUONDigit* sdigit = static_cast<AliMUONDigit*>(iDigits->UncheckedAt(k));
410 // FIXME: Merging logic should go here.
411 // For testing, only put the digit in the output.
414 AliError(Form("Could not get sdigit for ich=%d and k=%d",ich,k));
418 AddOrUpdateDigit(*oDigits,*sdigit);
424 //------------------------------------------------------------------------
425 //void AliMUONDigitizerv2::FillTriggerOutput()
427 // // Derived to fill TreeD and resets the trigger array in fMUONData.
429 // AliDebug(3,"Filling trees with trigger.");
430 // fMUONData->Fill("GLT");
431 // fMUONData->ResetTrigger();
434 //------------------------------------------------------------------------
435 //void AliMUONDigitizerv2::CreateTrigger()
437 // fMUONData->MakeBranch("GLT");
438 // fMUONData->SetTreeAddress("GLT");
439 // fTrigDec->Digits2Trigger();
440 // FillTriggerOutput();