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 "AliMUONPedestalEventGenerator.h"
21 #include "AliHeader.h"
23 #include "AliMUONCalibrationData.h"
24 #include "AliMUONData.h"
25 #include "AliMUONDigit.h"
26 #include "AliMUONRawWriter.h"
27 #include "AliMUONVCalibParam.h"
28 #include "AliMpIntPair.h"
29 #include "AliMpManuList.h"
30 #include "AliRunLoader.h"
32 #include "TClonesArray.h"
34 #include "TStopwatch.h"
39 /// \class AliMUONPedestalEventGenerator
41 /// Generate simulated pedestal events for MUON TRK, to be able to e.g. test
42 /// online calibration routines.
44 /// The pedestals themselves are taken from the CDB. What we get from the CDB
45 /// is, per channel, the mean and the sigma of the pedestal. We then use
46 /// those informations to randomly get the pedestals for each channel, for
47 /// each event (picking in a gaus(mean,sigma)).
49 /// Output can be just digits, or digits + raw (ddl), or digits + raw (ddl)
50 /// + raw (date files, one per LDC), depending of ctor and MakeDDL() method.
52 /// \author L. Aphecetche
56 ClassImp(AliMUONPedestalEventGenerator)
59 Int_t AliMUONPedestalEventGenerator::fgCounter(0);
61 //_____________________________________________________________________________
62 AliMUONPedestalEventGenerator::AliMUONPedestalEventGenerator(Int_t runNumber,
65 : TTask("AliMUONPedestalEventGenerator","Generate fake pedestal events"),
66 fManuList(AliMpManuList::ManuList()),
67 fCalibrationData(new AliMUONCalibrationData(runNumber)),
68 fDateFileName(filename),
69 fGAliceFileName("galice.root"),
72 /// Will generate pedestals according to (mean,sigma)s found in CDB
73 /// for run runNumber.
74 /// Will generate nevents events
75 /// If filename is != "", it will be the basename of the output LDC files
77 if (!gSystem->IsAbsoluteFileName(fGAliceFileName))
79 char* absFileName = gSystem->ConcatFileName(gSystem->WorkingDirectory(),
81 fGAliceFileName = absFileName;
85 AliRunLoader* runLoader = LoadRun("recreate");
87 runLoader->SetNumberOfEventsPerFile(nevents);
91 AliError("Could not create RunLoader");
96 ->CreateDetectorFolders(runLoader->GetEventFolder(),
99 AliLoader* loader = new AliLoader("MUON",runLoader->GetEventFolder());
101 runLoader->AddLoader(loader);
103 // Initialize event headers.
104 runLoader->MakeTree("E");
105 for ( Int_t iEvent = 0; iEvent < nevents; ++iEvent )
107 runLoader->SetEventNumber(iEvent);
108 runLoader->GetHeader()->Reset(runNumber,iEvent);
109 runLoader->TreeE()->Fill();
111 runLoader->WriteHeader("OVERWRITE");
112 runLoader->CdGAFile();
113 runLoader->Write(0, TObject::kOverwrite);
119 //_____________________________________________________________________________
120 AliMUONPedestalEventGenerator::~AliMUONPedestalEventGenerator()
124 delete fCalibrationData;
125 AliInfo(Form("make a digit counter %d",fgCounter));
128 //_____________________________________________________________________________
130 AliMUONPedestalEventGenerator::ConvertRawFilesToDate()
132 /// convert raw data DDL files to DATE files with the program "dateStream".
133 /// we make one file per LDC
135 const Int_t kIDet = AliDAQ::DetectorID("MUONTRK");
137 const Int_t kNLDCs = TMath::CeilNint(AliDAQ::NumberOfLdcs(kIDet));
139 char* path = gSystem->Which(gSystem->Getenv("PATH"), "dateStream");
142 AliError("the program dateStream was not found");
148 AliRunLoader* runLoader = LoadRun("read");
149 if (!runLoader) return kFALSE;
151 AliInfo(Form("converting raw data DDL files to DATE files %s", fDateFileName.Data()));
152 FILE** pipe = new FILE*[kNLDCs];
154 for ( Int_t iFile = 0; iFile < kNLDCs; ++iFile)
157 // Note the option -s. It is used in order to avoid
158 // the generation of SOR/EOR events.
159 sprintf(command, "dateStream -s -D -o %s.LDC%d -# %d -C",
160 fDateFileName.Data(), iFile, runLoader->GetNumberOfEvents());
161 pipe[iFile] = gSystem->OpenPipe(command, "w");
164 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); ++iEvent)
169 for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls(kIDet); ++iDDL)
171 Int_t ddlID = AliDAQ::DdlID(kIDet,iDDL);
172 Int_t ldcID = Int_t(ldc + 0.0001);
173 ldc += AliDAQ::NumberOfLdcs(kIDet) / AliDAQ::NumberOfDdls(kIDet);
175 char rawFileName[256];
176 sprintf(rawFileName, "raw%d/%s",
177 iEvent, AliDAQ::DdlFileName(kIDet,iDDL));
179 // check existence and size of raw data file
180 FILE* file = fopen(rawFileName, "rb");
182 fseek(file, 0, SEEK_END);
183 unsigned long size = ftell(file);
187 if (ldcID != prevLDC) {
188 fprintf(pipe[ldcID], " LDC Id %d\n", ldcID);
191 fprintf(pipe[ldcID], " Equipment Id %d Payload %s\n", ddlID, rawFileName);
197 for ( Int_t iFile = 0; iFile < kNLDCs; ++iFile)
199 result += gSystem->ClosePipe(pipe[iFile]);
204 return (result == 0);
207 //_____________________________________________________________________________
209 AliMUONPedestalEventGenerator::Exec(Option_t*)
211 /// Main steering method
216 TStopwatch writeTimer;
217 writeTimer.Start(kTRUE); writeTimer.Stop();
218 TStopwatch fillTimer;
219 fillTimer.Start(kTRUE); fillTimer.Stop();
220 TStopwatch resetTimer;
221 resetTimer.Start(kTRUE); resetTimer.Stop();
222 TStopwatch getEventTimer;
223 getEventTimer.Start(kTRUE); getEventTimer.Stop();
224 TStopwatch branchTimer;
225 branchTimer.Start(kTRUE); branchTimer.Stop();
226 TStopwatch generateDigitsTimer;
227 generateDigitsTimer.Start(kTRUE); generateDigitsTimer.Stop();
228 TStopwatch digits2RawTimer;
229 digits2RawTimer.Start(kTRUE); digits2RawTimer.Stop();
230 TStopwatch convertRawFilesToDateTimer;
231 convertRawFilesToDateTimer.Start(kTRUE); convertRawFilesToDateTimer.Stop();
234 getTimer.Start(kTRUE);
235 AliMUONData* data = GetDataAccess("update");
236 AliRunLoader* runLoader = data->GetLoader()->GetRunLoader();
239 for ( Int_t i = 0; i < runLoader->GetNumberOfEvents(); ++i )
241 getEventTimer.Start(kFALSE);
242 runLoader->GetEvent(i);
243 getEventTimer.Stop();
245 branchTimer.Start(kFALSE);
246 if ( data->TreeD() == 0x0 )
248 AliDebug(1,"Calling MakeDigitsContainer");
249 data->GetLoader()->MakeDigitsContainer();
251 data->MakeBranch("D,GLT");
252 data->SetTreeAddress("D,GLT");
255 generateDigitsTimer.Start(kFALSE);
256 GenerateDigits(data);
257 generateDigitsTimer.Stop();
259 fillTimer.Start(kTRUE);
260 // Fill the output treeD
264 // Write to the output tree(D).
265 // Please note that as GlobalTrigger, LocalTrigger and Digits are in the same
266 // tree (=TreeD) in different branches, this WriteDigits in fact writes all of
269 writeTimer.Start(kFALSE);
270 data->GetLoader()->WriteDigits("OVERWRITE");
273 // Finally, we clean up after ourselves.
274 resetTimer.Start(kTRUE);
276 data->ResetTrigger();
277 data->GetLoader()->UnloadDigits();
282 endTimer.Start(kTRUE);
283 runLoader->WriteRunLoader("OVERWRITE");
290 // Now convert the digits.root file(s) to DDL files
291 digits2RawTimer.Start(kFALSE);
293 digits2RawTimer.Stop();
296 // Finally, if instructed to do so, convert DDL files to DATE file(s)
297 if ( fMakeDDL && fDateFileName.Length() > 0 )
299 convertRawFilesToDateTimer.Start(kFALSE);
300 AliDebug(1,"Converting to DATE file(s)");
302 Bool_t dateOutput = ConvertRawFilesToDate();
303 convertRawFilesToDateTimer.Stop();
306 AliError("DATE output failed. Aborting.");
311 AliInfo(Form("Execution time Exec : R:%.2fs C:%.2fs",
312 timer.RealTime(),timer.CpuTime()));
314 AliInfo(Form(" Execution time branch : R:%.2fs C:%.2fs",
315 branchTimer.RealTime(),branchTimer.CpuTime()));
316 AliInfo(Form(" Execution time getEvent : R:%.2fs C:%.2fs",
317 getEventTimer.RealTime(),getEventTimer.CpuTime()));
318 AliInfo(Form(" Execution time fill digits : R:%.2fs C:%.2fs",
319 fillTimer.RealTime(),fillTimer.CpuTime()));
320 AliInfo(Form(" Execution time write digits : R:%.2fs C:%.2fs",
321 writeTimer.RealTime(),writeTimer.CpuTime()));
322 AliInfo(Form(" Execution time reset digits : R:%.2fs C:%.2fs",
323 resetTimer.RealTime(),resetTimer.CpuTime()));
324 AliInfo(Form(" Execution time for GenerateDigits : R:%.2fs C:%.2fs",
325 generateDigitsTimer.RealTime(),generateDigitsTimer.CpuTime()));
326 AliInfo(Form(" Execution time for Digits2Raw : R:%.2fs C:%.2fs",
327 digits2RawTimer.RealTime(),digits2RawTimer.CpuTime()));
328 AliInfo(Form(" Execution time for ConvertRawFilesToDate : R:%.2fs C:%.2fs",
329 convertRawFilesToDateTimer.RealTime(),convertRawFilesToDateTimer.CpuTime()));
330 AliInfo(Form(" Execution time for get : R:%.2fs C:%.2fs",
331 getTimer.RealTime(),getTimer.CpuTime()));
332 AliInfo(Form(" Execution time for end : R:%.2fs C:%.2fs",
333 endTimer.RealTime(),endTimer.CpuTime()));
336 //_____________________________________________________________________________
338 AliMUONPedestalEventGenerator::Digits2Raw()
340 /// Converts digits (from MUON.Digits.root file) to Raw DDL ascii files.
342 AliMUONData* data = GetDataAccess("read");
343 AliRunLoader* runLoader = data->GetLoader()->GetRunLoader();
344 AliDebug(1,Form("runLoader=%p",runLoader));
346 AliMUONRawWriter rawWriter(data);
348 // Generate RAW data from the digits
349 // Be carefull to create&change to the correct directory first...
351 TString baseDir = gSystem->WorkingDirectory();
353 for ( Int_t i = 0; i < runLoader->GetNumberOfEvents(); ++i )
355 runLoader->GetEvent(i);
357 AliDebug(1,Form("processing event %d", i));
360 sprintf(dirName, "raw%d", i);
361 gSystem->MakeDirectory(dirName);
362 if (!gSystem->ChangeDirectory(dirName))
364 AliError(Form("couldn't change to directory %s", dirName));
368 rawWriter.Digits2Raw();
370 gSystem->ChangeDirectory(baseDir);
376 AliDebug(1,Form("DDL files written successfully"));
379 //_____________________________________________________________________________
381 AliMUONPedestalEventGenerator::GenerateDigits(AliMUONData* data)
383 /// Generate digits (where ADC is set to pedestal value) for all MUON TRK
386 TIter next(fManuList);
390 while ( ( p = static_cast<AliMpIntPair*>(next())) )
392 Int_t detElemId = p->GetFirst();
394 Int_t chamber = detElemId/100-1;
396 TClonesArray* pdigits = data->Digits(chamber);
399 AliError(Form("No digits for chamber %d",1));
402 TClonesArray& digits = *pdigits;
404 Int_t manuId = p->GetSecond();
406 AliMUONVCalibParam* pedestals = fCalibrationData->Pedestals(detElemId,manuId);
409 AliError(Form("Could not find pedestals for (DE,MANU)=(%d,%d)",detElemId,
413 for ( Int_t manuChannel = 0; manuChannel < pedestals->Size(); ++manuChannel )
415 Float_t mean = pedestals->ValueAsFloat(manuChannel,0);
416 if (mean == AliMUONVCalibParam::InvalidFloatValue())
418 // This is a poor's man way of knowing if that channel really exists.
419 // Better and safer way (but much slower too) would be to check pad existence
420 // using AliMpVSegmentation::PadByLocation(AliMpIntPair(manuId,manuChannel))
425 Float_t sigma = pedestals->ValueAsFloat(manuChannel,1);
427 Float_t ped = gRandom->Gaus(mean,sigma);
428 Int_t pedADC = TMath::FloorNint(ped);
429 d.SetElectronics(manuId, manuChannel);
432 d.SetDetElemId(detElemId);
433 // we do not set the remaining parts of the digit, as in principle
434 // this is all we need : manuId, manuChannel and ADC, as far as
435 // real data is concerned.
436 new (digits[digits.GetLast()+1]) AliMUONDigit(d);
442 AliDebug(1,Form("ngenerated=%d",ngenerated));
445 //_____________________________________________________________________________
447 AliMUONPedestalEventGenerator::GetDataAccess(const char* mode)
449 /// Get the pointer to AliMUONData object
450 AliRunLoader* runLoader = LoadRun(mode);
453 AliError("Could not get RunLoader");
456 AliLoader* loader = static_cast<AliLoader*>(runLoader->GetLoader("MUONLoader"));
459 AliError("Could not get MuonLoader");
463 return new AliMUONData(loader,"MUON","MUONData");
466 //_____________________________________________________________________________
468 AliMUONPedestalEventGenerator::LoadRun(const char* mode)
470 /// Get access to AliRunLoader object
471 while (AliRunLoader::GetRunLoader())
473 AliDebug(1,Form("Deleting AliRunLoader %p",AliRunLoader::GetRunLoader()));
474 delete AliRunLoader::GetRunLoader();
477 AliRunLoader* runLoader =
478 AliRunLoader::Open(fGAliceFileName,AliConfig::GetDefaultEventFolderName(),
481 AliDebug(1,Form("AliRunLoader(%s)=%p",mode,runLoader));
485 AliError("No run loader found in file galice.root");