]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONPedestalEventGenerator.cxx
- Adding option for ownership of sector
[u/mrichter/AliRoot.git] / MUON / AliMUONPedestalEventGenerator.cxx
CommitLineData
ea199e33 1/**************************************************************************
2* Copyright(c) 1998-1999, 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
16// $Id$
17
18#include "AliMUONPedestalEventGenerator.h"
19
20#include "AliDAQ.h"
21#include "AliHeader.h"
22#include "AliLog.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"
31
32#include "TClonesArray.h"
33#include "TRandom.h"
34#include "TStopwatch.h"
35#include "TSystem.h"
36#include "TMath.h"
37
38///
39/// \class AliMUONPedestalEventGenerator
40///
41/// Generate simulated pedestal events for MUON TRK, to be able to e.g. test
42/// online calibration routines.
43///
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)).
48///
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.
51///
52/// \author L. Aphecetche
53///
54
55/// \cond CLASSIMP
56ClassImp(AliMUONPedestalEventGenerator)
57/// \endcond
58
59Int_t AliMUONPedestalEventGenerator::fgCounter(0);
60
61//_____________________________________________________________________________
62AliMUONPedestalEventGenerator::AliMUONPedestalEventGenerator(Int_t runNumber,
63 Int_t nevents,
64 const char* filename)
65: TTask("AliMUONPedestalEventGenerator","Generate fake pedestal events"),
66fManuList(AliMpManuList::ManuList()),
67fCalibrationData(new AliMUONCalibrationData(runNumber)),
68fDateFileName(filename),
69fGAliceFileName("galice.root"),
70fMakeDDL(kTRUE)
71{
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
76 ///
77 if (!gSystem->IsAbsoluteFileName(fGAliceFileName))
78 {
79 char* absFileName = gSystem->ConcatFileName(gSystem->WorkingDirectory(),
80 fGAliceFileName);
81 fGAliceFileName = absFileName;
82 delete[] absFileName;
83 }
84
85 AliRunLoader* runLoader = LoadRun("recreate");
86
87 runLoader->SetNumberOfEventsPerFile(nevents);
88
89 if (!runLoader)
90 {
91 AliError("Could not create RunLoader");
92 return;
93 }
94
95 AliConfig::Instance()
96 ->CreateDetectorFolders(runLoader->GetEventFolder(),
97 "MUON", "MUON");
98
99 AliLoader* loader = new AliLoader("MUON",runLoader->GetEventFolder());
100
101 runLoader->AddLoader(loader);
102
103 // Initialize event headers.
104 runLoader->MakeTree("E");
105 for ( Int_t iEvent = 0; iEvent < nevents; ++iEvent )
106 {
107 runLoader->SetEventNumber(iEvent);
108 runLoader->GetHeader()->Reset(runNumber,iEvent);
109 runLoader->TreeE()->Fill();
110 }
111 runLoader->WriteHeader("OVERWRITE");
112 runLoader->CdGAFile();
113 runLoader->Write(0, TObject::kOverwrite);
114
115 assert(runLoader->GetNumberOfEvents()==nevents);
116 assert(runLoader->GetHeader()->GetRun()==runNumber);
117
118 delete runLoader;
119}
120
121
122//_____________________________________________________________________________
123AliMUONPedestalEventGenerator::~AliMUONPedestalEventGenerator()
124{
125 /// dtor
126 delete fManuList;
127 delete fCalibrationData;
128 AliInfo(Form("make a digit counter %d",fgCounter));
129}
130
131//_____________________________________________________________________________
132Bool_t
133AliMUONPedestalEventGenerator::ConvertRawFilesToDate()
134{
135 /// convert raw data DDL files to DATE files with the program "dateStream".
136 /// we make one file per LDC
137
138 const Int_t kIDet = AliDAQ::DetectorID("MUONTRK");
139
140 const Int_t kNLDCs = TMath::CeilNint(AliDAQ::NumberOfLdcs(kIDet));
141
142 char* path = gSystem->Which(gSystem->Getenv("PATH"), "dateStream");
143 if (!path)
144 {
145 AliError("the program dateStream was not found");
146 return kFALSE;
147 }
148
149 delete[] path;
150
151 AliRunLoader* runLoader = LoadRun("read");
152 if (!runLoader) return kFALSE;
153
154 AliInfo(Form("converting raw data DDL files to DATE files %s", fDateFileName.Data()));
155 FILE** pipe = new FILE*[kNLDCs];
156
157 for ( Int_t iFile = 0; iFile < kNLDCs; ++iFile)
158 {
159 char command[256];
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");
165 }
166
167 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); ++iEvent)
168 {
169 Float_t ldc = 0;
170 Int_t prevLDC = -1;
171
172 for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls(kIDet); ++iDDL)
173 {
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);
177
178 char rawFileName[256];
179 sprintf(rawFileName, "raw%d/%s",
180 iEvent, AliDAQ::DdlFileName(kIDet,iDDL));
181
182 // check existence and size of raw data file
183 FILE* file = fopen(rawFileName, "rb");
184 if (!file) continue;
185 fseek(file, 0, SEEK_END);
186 unsigned long size = ftell(file);
187 fclose(file);
188 if (!size) continue;
189
190 if (ldcID != prevLDC) {
191 fprintf(pipe[ldcID], " LDC Id %d\n", ldcID);
192 prevLDC = ldcID;
193 }
194 fprintf(pipe[ldcID], " Equipment Id %d Payload %s\n", ddlID, rawFileName);
195 }
196 }
197
198 Int_t result(0);
199
200 for ( Int_t iFile = 0; iFile < kNLDCs; ++iFile)
201 {
202 result += gSystem->ClosePipe(pipe[iFile]);
203 }
204
205 delete [] pipe;
206 delete runLoader;
207 return (result == 0);
208}
209
210//_____________________________________________________________________________
211void
212AliMUONPedestalEventGenerator::Exec(Option_t*)
213{
214 /// Main steering method
215
216 TStopwatch timer;
217 timer.Start(kTRUE);
218
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();
235 TStopwatch getTimer;
236
237 getTimer.Start(kTRUE);
238 AliMUONData* data = GetDataAccess("update");
239 AliRunLoader* runLoader = data->GetLoader()->GetRunLoader();
240 getTimer.Stop();
241
242 for ( Int_t i = 0; i < runLoader->GetNumberOfEvents(); ++i )
243 {
244 getEventTimer.Start(kFALSE);
245 runLoader->GetEvent(i);
246 getEventTimer.Stop();
247
248 branchTimer.Start(kFALSE);
249 if ( data->TreeD() == 0x0 )
250 {
251 AliDebug(1,"Calling MakeDigitsContainer");
252 data->GetLoader()->MakeDigitsContainer();
253 }
254 data->MakeBranch("D,GLT");
255 data->SetTreeAddress("D,GLT");
256 branchTimer.Stop();
257
258 generateDigitsTimer.Start(kFALSE);
259 GenerateDigits(data);
260 generateDigitsTimer.Stop();
261
262 fillTimer.Start(kTRUE);
263 // Fill the output treeD
264 data->Fill("D,GLT");
265 fillTimer.Stop();
266
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
270 // the 3 branches.
271
272 writeTimer.Start(kFALSE);
273 data->GetLoader()->WriteDigits("OVERWRITE");
274 writeTimer.Stop();
275
276 // Finally, we clean up after ourselves.
277 resetTimer.Start(kTRUE);
278 data->ResetDigits();
279 data->ResetTrigger();
280 data->GetLoader()->UnloadDigits();
281 resetTimer.Stop();
282 }
283
284 TStopwatch endTimer;
285 endTimer.Start(kTRUE);
286 runLoader->WriteRunLoader("OVERWRITE");
287 delete data;
288 delete runLoader;
289 endTimer.Stop();
290
291 if ( fMakeDDL )
292 {
293 // Now convert the digits.root file(s) to DDL files
294 digits2RawTimer.Start(kFALSE);
295 Digits2Raw();
296 digits2RawTimer.Stop();
297 }
298
299 // Finally, if instructed to do so, convert DDL files to DATE file(s)
300 if ( fMakeDDL && fDateFileName.Length() > 0 )
301 {
302 convertRawFilesToDateTimer.Start(kFALSE);
303 AliDebug(1,"Converting to DATE file(s)");
304
305 Bool_t dateOutput = ConvertRawFilesToDate();
306 convertRawFilesToDateTimer.Stop();
307 if (!dateOutput)
308 {
309 AliError("DATE output failed. Aborting.");
310 return;
311 }
312 }
313
314 AliInfo(Form("Execution time Exec : R:%.2fs C:%.2fs",
315 timer.RealTime(),timer.CpuTime()));
316
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()));
337}
338
339//_____________________________________________________________________________
340void
341AliMUONPedestalEventGenerator::Digits2Raw()
342{
343 /// Converts digits (from MUON.Digits.root file) to Raw DDL ascii files.
344
345 AliMUONData* data = GetDataAccess("read");
346 AliRunLoader* runLoader = data->GetLoader()->GetRunLoader();
347 AliDebug(1,Form("runLoader=%p",runLoader));
348
349 AliMUONRawWriter rawWriter(data);
350
351 // Generate RAW data from the digits
352 // Be carefull to create&change to the correct directory first...
353
354 TString baseDir = gSystem->WorkingDirectory();
355
356 for ( Int_t i = 0; i < runLoader->GetNumberOfEvents(); ++i )
357 {
358 runLoader->GetEvent(i);
359
360 AliDebug(1,Form("processing event %d", i));
361
362 char dirName[256];
363 sprintf(dirName, "raw%d", i);
364 gSystem->MakeDirectory(dirName);
365 if (!gSystem->ChangeDirectory(dirName))
366 {
367 AliError(Form("couldn't change to directory %s", dirName));
368 return;
369 }
370
371 rawWriter.Digits2Raw();
372
373 gSystem->ChangeDirectory(baseDir);
374 }
375
376 delete data;
377 delete runLoader;
378
379 AliDebug(1,Form("DDL files written successfully"));
380}
381
382//_____________________________________________________________________________
383void
384AliMUONPedestalEventGenerator::GenerateDigits(AliMUONData* data)
385{
386 /// Generate digits (where ADC is set to pedestal value) for all MUON TRK
387 /// and for 1 event.
388
389 TIter next(fManuList);
390 AliMpIntPair* p;
391 Int_t ngenerated(0);
392
393 while ( ( p = static_cast<AliMpIntPair*>(next())) )
394 {
395 Int_t detElemId = p->GetFirst();
396
397 Int_t chamber = detElemId/100-1;
398
399 TClonesArray* pdigits = data->Digits(chamber);
400 if (!pdigits)
401 {
402 AliError(Form("No digits for chamber %d",1));
403 continue;
404 }
405 TClonesArray& digits = *pdigits;
406
407 Int_t manuId = p->GetSecond();
408
409 AliMUONVCalibParam* pedestals = fCalibrationData->Pedestals(detElemId,manuId);
410 if (!pedestals)
411 {
412 AliError(Form("Could not find pedestals for (DE,MANU)=(%d,%d)",detElemId,
413 manuId));
414 return;
415 }
416 for ( Int_t manuChannel = 0; manuChannel < pedestals->Size(); ++manuChannel )
417 {
418 Float_t mean = pedestals->ValueAsFloat(manuChannel,0);
419 if (mean == AliMUONVCalibParam::InvalidFloatValue())
420 {
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))
424 continue;
425 }
426 else
427 {
428 Float_t sigma = pedestals->ValueAsFloat(manuChannel,1);
429 AliMUONDigit d;
430 Float_t ped = gRandom->Gaus(mean,sigma);
431 Int_t pedADC = TMath::FloorNint(ped);
432 d.SetElectronics(manuId, manuChannel);
433 d.SetADC(pedADC);
434 d.SetSignal(ped);
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);
440 ++fgCounter;
441 ++ngenerated;
442 }
443 }
444 }
445 AliDebug(1,Form("ngenerated=%d",ngenerated));
446}
447
448//_____________________________________________________________________________
449AliMUONData*
450AliMUONPedestalEventGenerator::GetDataAccess(const char* mode)
451{
452 /// Get the pointer to AliMUONData object
453 AliRunLoader* runLoader = LoadRun(mode);
454 if (!runLoader)
455 {
456 AliError("Could not get RunLoader");
457 return 0x0;
458 }
459 AliLoader* loader = static_cast<AliLoader*>(runLoader->GetLoader("MUONLoader"));
460 if (!loader)
461 {
462 AliError("Could not get MuonLoader");
463 return 0x0;
464 }
465
466 return new AliMUONData(loader,"MUON","MUONData");
467}
468
469//_____________________________________________________________________________
470AliRunLoader*
471AliMUONPedestalEventGenerator::LoadRun(const char* mode)
472{
473 /// Get access to AliRunLoader object
474 while (AliRunLoader::GetRunLoader())
475 {
476 AliDebug(1,Form("Deleting AliRunLoader %p",AliRunLoader::GetRunLoader()));
477 delete AliRunLoader::GetRunLoader();
478 }
479
480 AliRunLoader* runLoader =
481 AliRunLoader::Open(fGAliceFileName,AliConfig::GetDefaultEventFolderName(),
482 mode);
483
484 AliDebug(1,Form("AliRunLoader(%s)=%p",mode,runLoader));
485
486 if (!runLoader)
487 {
488 AliError("No run loader found in file galice.root");
489 }
490 return runLoader;
491}