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);
115 assert(runLoader->GetNumberOfEvents()==nevents);
116 assert(runLoader->GetHeader()->GetRun()==runNumber);
122 //_____________________________________________________________________________
123 AliMUONPedestalEventGenerator::~AliMUONPedestalEventGenerator()
127 delete fCalibrationData;
128 AliInfo(Form("make a digit counter %d",fgCounter));
131 //_____________________________________________________________________________
133 AliMUONPedestalEventGenerator::ConvertRawFilesToDate()
135 /// convert raw data DDL files to DATE files with the program "dateStream".
136 /// we make one file per LDC
138 const Int_t kIDet = AliDAQ::DetectorID("MUONTRK");
140 const Int_t kNLDCs = TMath::CeilNint(AliDAQ::NumberOfLdcs(kIDet));
142 char* path = gSystem->Which(gSystem->Getenv("PATH"), "dateStream");
145 AliError("the program dateStream was not found");
151 AliRunLoader* runLoader = LoadRun("read");
152 if (!runLoader) return kFALSE;
154 AliInfo(Form("converting raw data DDL files to DATE files %s", fDateFileName.Data()));
155 FILE** pipe = new FILE*[kNLDCs];
157 for ( Int_t iFile = 0; iFile < kNLDCs; ++iFile)
160 // Note the option -s. It is used in order to avoid
161 // the generation of SOR/EOR events.
162 sprintf(command, "dateStream -s -D -o %s.LDC%d -# %d -C",
163 fDateFileName.Data(), iFile, runLoader->GetNumberOfEvents());
164 pipe[iFile] = gSystem->OpenPipe(command, "w");
167 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); ++iEvent)
172 for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls(kIDet); ++iDDL)
174 Int_t ddlID = AliDAQ::DdlID(kIDet,iDDL);
175 Int_t ldcID = Int_t(ldc + 0.0001);
176 ldc += AliDAQ::NumberOfLdcs(kIDet) / AliDAQ::NumberOfDdls(kIDet);
178 char rawFileName[256];
179 sprintf(rawFileName, "raw%d/%s",
180 iEvent, AliDAQ::DdlFileName(kIDet,iDDL));
182 // check existence and size of raw data file
183 FILE* file = fopen(rawFileName, "rb");
185 fseek(file, 0, SEEK_END);
186 unsigned long size = ftell(file);
190 if (ldcID != prevLDC) {
191 fprintf(pipe[ldcID], " LDC Id %d\n", ldcID);
194 fprintf(pipe[ldcID], " Equipment Id %d Payload %s\n", ddlID, rawFileName);
200 for ( Int_t iFile = 0; iFile < kNLDCs; ++iFile)
202 result += gSystem->ClosePipe(pipe[iFile]);
207 return (result == 0);
210 //_____________________________________________________________________________
212 AliMUONPedestalEventGenerator::Exec(Option_t*)
214 /// Main steering method
219 TStopwatch writeTimer;
220 writeTimer.Start(kTRUE); writeTimer.Stop();
221 TStopwatch fillTimer;
222 fillTimer.Start(kTRUE); fillTimer.Stop();
223 TStopwatch resetTimer;
224 resetTimer.Start(kTRUE); resetTimer.Stop();
225 TStopwatch getEventTimer;
226 getEventTimer.Start(kTRUE); getEventTimer.Stop();
227 TStopwatch branchTimer;
228 branchTimer.Start(kTRUE); branchTimer.Stop();
229 TStopwatch generateDigitsTimer;
230 generateDigitsTimer.Start(kTRUE); generateDigitsTimer.Stop();
231 TStopwatch digits2RawTimer;
232 digits2RawTimer.Start(kTRUE); digits2RawTimer.Stop();
233 TStopwatch convertRawFilesToDateTimer;
234 convertRawFilesToDateTimer.Start(kTRUE); convertRawFilesToDateTimer.Stop();
237 getTimer.Start(kTRUE);
238 AliMUONData* data = GetDataAccess("update");
239 AliRunLoader* runLoader = data->GetLoader()->GetRunLoader();
242 for ( Int_t i = 0; i < runLoader->GetNumberOfEvents(); ++i )
244 getEventTimer.Start(kFALSE);
245 runLoader->GetEvent(i);
246 getEventTimer.Stop();
248 branchTimer.Start(kFALSE);
249 if ( data->TreeD() == 0x0 )
251 AliDebug(1,"Calling MakeDigitsContainer");
252 data->GetLoader()->MakeDigitsContainer();
254 data->MakeBranch("D,GLT");
255 data->SetTreeAddress("D,GLT");
258 generateDigitsTimer.Start(kFALSE);
259 GenerateDigits(data);
260 generateDigitsTimer.Stop();
262 fillTimer.Start(kTRUE);
263 // Fill the output treeD
267 // Write to the output tree(D).
268 // Please note that as GlobalTrigger, LocalTrigger and Digits are in the same
269 // tree (=TreeD) in different branches, this WriteDigits in fact writes all of
272 writeTimer.Start(kFALSE);
273 data->GetLoader()->WriteDigits("OVERWRITE");
276 // Finally, we clean up after ourselves.
277 resetTimer.Start(kTRUE);
279 data->ResetTrigger();
280 data->GetLoader()->UnloadDigits();
285 endTimer.Start(kTRUE);
286 runLoader->WriteRunLoader("OVERWRITE");
293 // Now convert the digits.root file(s) to DDL files
294 digits2RawTimer.Start(kFALSE);
296 digits2RawTimer.Stop();
299 // Finally, if instructed to do so, convert DDL files to DATE file(s)
300 if ( fMakeDDL && fDateFileName.Length() > 0 )
302 convertRawFilesToDateTimer.Start(kFALSE);
303 AliDebug(1,"Converting to DATE file(s)");
305 Bool_t dateOutput = ConvertRawFilesToDate();
306 convertRawFilesToDateTimer.Stop();
309 AliError("DATE output failed. Aborting.");
314 AliInfo(Form("Execution time Exec : R:%.2fs C:%.2fs",
315 timer.RealTime(),timer.CpuTime()));
317 AliInfo(Form(" Execution time branch : R:%.2fs C:%.2fs",
318 branchTimer.RealTime(),branchTimer.CpuTime()));
319 AliInfo(Form(" Execution time getEvent : R:%.2fs C:%.2fs",
320 getEventTimer.RealTime(),getEventTimer.CpuTime()));
321 AliInfo(Form(" Execution time fill digits : R:%.2fs C:%.2fs",
322 fillTimer.RealTime(),fillTimer.CpuTime()));
323 AliInfo(Form(" Execution time write digits : R:%.2fs C:%.2fs",
324 writeTimer.RealTime(),writeTimer.CpuTime()));
325 AliInfo(Form(" Execution time reset digits : R:%.2fs C:%.2fs",
326 resetTimer.RealTime(),resetTimer.CpuTime()));
327 AliInfo(Form(" Execution time for GenerateDigits : R:%.2fs C:%.2fs",
328 generateDigitsTimer.RealTime(),generateDigitsTimer.CpuTime()));
329 AliInfo(Form(" Execution time for Digits2Raw : R:%.2fs C:%.2fs",
330 digits2RawTimer.RealTime(),digits2RawTimer.CpuTime()));
331 AliInfo(Form(" Execution time for ConvertRawFilesToDate : R:%.2fs C:%.2fs",
332 convertRawFilesToDateTimer.RealTime(),convertRawFilesToDateTimer.CpuTime()));
333 AliInfo(Form(" Execution time for get : R:%.2fs C:%.2fs",
334 getTimer.RealTime(),getTimer.CpuTime()));
335 AliInfo(Form(" Execution time for end : R:%.2fs C:%.2fs",
336 endTimer.RealTime(),endTimer.CpuTime()));
339 //_____________________________________________________________________________
341 AliMUONPedestalEventGenerator::Digits2Raw()
343 /// Converts digits (from MUON.Digits.root file) to Raw DDL ascii files.
345 AliMUONData* data = GetDataAccess("read");
346 AliRunLoader* runLoader = data->GetLoader()->GetRunLoader();
347 AliDebug(1,Form("runLoader=%p",runLoader));
349 AliMUONRawWriter rawWriter(data);
351 // Generate RAW data from the digits
352 // Be carefull to create&change to the correct directory first...
354 TString baseDir = gSystem->WorkingDirectory();
356 for ( Int_t i = 0; i < runLoader->GetNumberOfEvents(); ++i )
358 runLoader->GetEvent(i);
360 AliDebug(1,Form("processing event %d", i));
363 sprintf(dirName, "raw%d", i);
364 gSystem->MakeDirectory(dirName);
365 if (!gSystem->ChangeDirectory(dirName))
367 AliError(Form("couldn't change to directory %s", dirName));
371 rawWriter.Digits2Raw();
373 gSystem->ChangeDirectory(baseDir);
379 AliDebug(1,Form("DDL files written successfully"));
382 //_____________________________________________________________________________
384 AliMUONPedestalEventGenerator::GenerateDigits(AliMUONData* data)
386 /// Generate digits (where ADC is set to pedestal value) for all MUON TRK
389 TIter next(fManuList);
393 while ( ( p = static_cast<AliMpIntPair*>(next())) )
395 Int_t detElemId = p->GetFirst();
397 Int_t chamber = detElemId/100-1;
399 TClonesArray* pdigits = data->Digits(chamber);
402 AliError(Form("No digits for chamber %d",1));
405 TClonesArray& digits = *pdigits;
407 Int_t manuId = p->GetSecond();
409 AliMUONVCalibParam* pedestals = fCalibrationData->Pedestals(detElemId,manuId);
412 AliError(Form("Could not find pedestals for (DE,MANU)=(%d,%d)",detElemId,
416 for ( Int_t manuChannel = 0; manuChannel < pedestals->Size(); ++manuChannel )
418 Float_t mean = pedestals->ValueAsFloat(manuChannel,0);
419 if (mean == AliMUONVCalibParam::InvalidFloatValue())
421 // This is a poor's man way of knowing if that channel really exists.
422 // Better and safer way (but much slower too) would be to check pad existence
423 // using AliMpVSegmentation::PadByLocation(AliMpIntPair(manuId,manuChannel))
428 Float_t sigma = pedestals->ValueAsFloat(manuChannel,1);
430 Float_t ped = gRandom->Gaus(mean,sigma);
431 Int_t pedADC = TMath::FloorNint(ped);
432 d.SetElectronics(manuId, manuChannel);
435 d.SetDetElemId(detElemId);
436 // we do not set the remaining parts of the digit, as in principle
437 // this is all we need : manuId, manuChannel and ADC, as far as
438 // real data is concerned.
439 new (digits[digits.GetLast()+1]) AliMUONDigit(d);
445 AliDebug(1,Form("ngenerated=%d",ngenerated));
448 //_____________________________________________________________________________
450 AliMUONPedestalEventGenerator::GetDataAccess(const char* mode)
452 /// Get the pointer to AliMUONData object
453 AliRunLoader* runLoader = LoadRun(mode);
456 AliError("Could not get RunLoader");
459 AliLoader* loader = static_cast<AliLoader*>(runLoader->GetLoader("MUONLoader"));
462 AliError("Could not get MuonLoader");
466 return new AliMUONData(loader,"MUON","MUONData");
469 //_____________________________________________________________________________
471 AliMUONPedestalEventGenerator::LoadRun(const char* mode)
473 /// Get access to AliRunLoader object
474 while (AliRunLoader::GetRunLoader())
476 AliDebug(1,Form("Deleting AliRunLoader %p",AliRunLoader::GetRunLoader()));
477 delete AliRunLoader::GetRunLoader();
480 AliRunLoader* runLoader =
481 AliRunLoader::Open(fGAliceFileName,AliConfig::GetDefaultEventFolderName(),
484 AliDebug(1,Form("AliRunLoader(%s)=%p",mode,runLoader));
488 AliError("No run loader found in file galice.root");