]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONPedestalEventGenerator.cxx
Attempt to fix Coverity defect 14695
[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
24dbd5dd 20#include "AliCodeTimer.h"
21#include "AliDAQ.h"
ea199e33 22#include "AliHeader.h"
23#include "AliLog.h"
24#include "AliMUONCalibrationData.h"
ea199e33 25#include "AliMUONRawWriter.h"
26#include "AliMUONVCalibParam.h"
42825ed9 27#include "AliMUONVDigit.h"
24dbd5dd 28#include "AliMUONVDigitStore.h"
42825ed9 29#include "AliMUONVStore.h"
30#include "AliMpCathodType.h"
31#include "AliMpConstants.h"
32#include "AliMpDEStore.h"
33#include "AliMpDetElement.h"
42825ed9 34#include "AliMpPlaneType.h"
24dbd5dd 35#include "AliRawDataHeaderSim.h"
ea199e33 36#include "AliRunLoader.h"
42825ed9 37#include <TClonesArray.h>
38#include <TMath.h>
39#include <TROOT.h>
40#include <TRandom.h>
41#include <TStopwatch.h>
42#include <TSystem.h>
ea199e33 43
b785c4bd 44#include <cstdio>
45
3d1463c8 46//-----------------------------------------------------------------------------
ea199e33 47/// \class AliMUONPedestalEventGenerator
48///
49/// Generate simulated pedestal events for MUON TRK, to be able to e.g. test
50/// online calibration routines.
51///
52/// The pedestals themselves are taken from the CDB. What we get from the CDB
53/// is, per channel, the mean and the sigma of the pedestal. We then use
54/// those informations to randomly get the pedestals for each channel, for
55/// each event (picking in a gaus(mean,sigma)).
56///
57/// Output can be just digits, or digits + raw (ddl), or digits + raw (ddl)
58/// + raw (date files, one per LDC), depending of ctor and MakeDDL() method.
59///
60/// \author L. Aphecetche
3d1463c8 61//-----------------------------------------------------------------------------
ea199e33 62
63/// \cond CLASSIMP
64ClassImp(AliMUONPedestalEventGenerator)
65/// \endcond
66
67Int_t AliMUONPedestalEventGenerator::fgCounter(0);
68
42825ed9 69//std::streambuf* RedirectTo(std::ostream& what, std::ostream& to)
70//{
71// std::streambuf* old = what.rdbuf();
72//
73// std::streambuf* psbuf = to.rdbuf();
74// what.rdbuf(psbuf);
75//
76// return old;
77//}
78
ea199e33 79//_____________________________________________________________________________
80AliMUONPedestalEventGenerator::AliMUONPedestalEventGenerator(Int_t runNumber,
81 Int_t nevents,
82 const char* filename)
83: TTask("AliMUONPedestalEventGenerator","Generate fake pedestal events"),
ea199e33 84fCalibrationData(new AliMUONCalibrationData(runNumber)),
85fDateFileName(filename),
86fGAliceFileName("galice.root"),
42825ed9 87fMakeDDL(kTRUE),
88fLoader(0x0),
89fPedestals(fCalibrationData->Pedestals()),
42825ed9 90fDigitStore(0x0),
91fRawWriter(0x0)
ea199e33 92{
93 /// Will generate pedestals according to (mean,sigma)s found in CDB
94 /// for run runNumber.
95 /// Will generate nevents events
96 /// If filename is != "", it will be the basename of the output LDC files
97 ///
98 if (!gSystem->IsAbsoluteFileName(fGAliceFileName))
99 {
100 char* absFileName = gSystem->ConcatFileName(gSystem->WorkingDirectory(),
101 fGAliceFileName);
102 fGAliceFileName = absFileName;
103 delete[] absFileName;
104 }
105
106 AliRunLoader* runLoader = LoadRun("recreate");
ea199e33 107 if (!runLoader)
108 {
109 AliError("Could not create RunLoader");
110 return;
111 }
112
e6fb429f 113 runLoader->SetNumberOfEventsPerFile(nevents);
114
ea199e33 115 // Initialize event headers.
116 runLoader->MakeTree("E");
42825ed9 117
ea199e33 118 for ( Int_t iEvent = 0; iEvent < nevents; ++iEvent )
119 {
120 runLoader->SetEventNumber(iEvent);
121 runLoader->GetHeader()->Reset(runNumber,iEvent);
122 runLoader->TreeE()->Fill();
123 }
124 runLoader->WriteHeader("OVERWRITE");
125 runLoader->CdGAFile();
126 runLoader->Write(0, TObject::kOverwrite);
127
ea199e33 128 delete runLoader;
42825ed9 129 fLoader = 0x0;
ea199e33 130}
131
132
133//_____________________________________________________________________________
134AliMUONPedestalEventGenerator::~AliMUONPedestalEventGenerator()
135{
136 /// dtor
ea199e33 137 delete fCalibrationData;
138 AliInfo(Form("make a digit counter %d",fgCounter));
42825ed9 139 delete fDigitStore;
140 delete fRawWriter;
ea199e33 141}
142
143//_____________________________________________________________________________
144Bool_t
145AliMUONPedestalEventGenerator::ConvertRawFilesToDate()
146{
147 /// convert raw data DDL files to DATE files with the program "dateStream".
148 /// we make one file per LDC
149
99c136e1 150 AliCodeTimerAuto("",0)
42825ed9 151
152 AliInfo("Converting raw to date");
153
ea199e33 154 const Int_t kIDet = AliDAQ::DetectorID("MUONTRK");
155
6c870207 156 const Int_t kNLDCs = 5;//TMath::CeilNint(AliDAQ::NumberOfLdcs(kIDet));
ea199e33 157
158 char* path = gSystem->Which(gSystem->Getenv("PATH"), "dateStream");
159 if (!path)
160 {
161 AliError("the program dateStream was not found");
162 return kFALSE;
163 }
164
165 delete[] path;
166
167 AliRunLoader* runLoader = LoadRun("read");
168 if (!runLoader) return kFALSE;
169
170 AliInfo(Form("converting raw data DDL files to DATE files %s", fDateFileName.Data()));
171 FILE** pipe = new FILE*[kNLDCs];
172
173 for ( Int_t iFile = 0; iFile < kNLDCs; ++iFile)
174 {
175 char command[256];
176 // Note the option -s. It is used in order to avoid
177 // the generation of SOR/EOR events.
b785c4bd 178 snprintf(command, 256, "dateStream -c -D -o %s.LDC%d -# %d -C",
ea199e33 179 fDateFileName.Data(), iFile, runLoader->GetNumberOfEvents());
180 pipe[iFile] = gSystem->OpenPipe(command, "w");
181 }
182
183 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); ++iEvent)
184 {
185 Float_t ldc = 0;
186 Int_t prevLDC = -1;
187
188 for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls(kIDet); ++iDDL)
189 {
190 Int_t ddlID = AliDAQ::DdlID(kIDet,iDDL);
191 Int_t ldcID = Int_t(ldc + 0.0001);
192 ldc += AliDAQ::NumberOfLdcs(kIDet) / AliDAQ::NumberOfDdls(kIDet);
193
194 char rawFileName[256];
b785c4bd 195 snprintf(rawFileName, 256, "raw%d/%s",
ea199e33 196 iEvent, AliDAQ::DdlFileName(kIDet,iDDL));
197
198 // check existence and size of raw data file
199 FILE* file = fopen(rawFileName, "rb");
200 if (!file) continue;
201 fseek(file, 0, SEEK_END);
202 unsigned long size = ftell(file);
203 fclose(file);
204 if (!size) continue;
205
206 if (ldcID != prevLDC) {
207 fprintf(pipe[ldcID], " LDC Id %d\n", ldcID);
208 prevLDC = ldcID;
209 }
210 fprintf(pipe[ldcID], " Equipment Id %d Payload %s\n", ddlID, rawFileName);
211 }
212 }
213
214 Int_t result(0);
215
216 for ( Int_t iFile = 0; iFile < kNLDCs; ++iFile)
217 {
218 result += gSystem->ClosePipe(pipe[iFile]);
219 }
220
4332f0d4 221 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); ++iEvent)
222 {
223 char command[256];
b785c4bd 224 snprintf(command, 256, "rm -r raw%d", iEvent);
4332f0d4 225 gSystem->Exec(command);
226 }
227
ea199e33 228 delete [] pipe;
229 delete runLoader;
42825ed9 230 fLoader=0x0;
ea199e33 231 return (result == 0);
232}
233
42825ed9 234//_____________________________________________________________________________
235AliMUONVDigitStore*
236AliMUONPedestalEventGenerator::DigitStore()
237{
238/// Return digt container; create it if it does not exist
239
4332f0d4 240 if (!fDigitStore) fDigitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV2R");
42825ed9 241 return fDigitStore;
242}
243
ea199e33 244//_____________________________________________________________________________
245void
246AliMUONPedestalEventGenerator::Exec(Option_t*)
247{
248 /// Main steering method
249
99c136e1 250 AliCodeTimerAuto("",0)
42825ed9 251
252 if (!fPedestals)
253 {
254 AliError("No pedestal store. Cannot proceed.");
255 return;
256 }
257
258 AliRunLoader* runLoader = LoadRun("update");
ea199e33 259
42825ed9 260 Int_t nevents = runLoader->GetNumberOfEvents();
261
262 for ( Int_t i = 0; i < nevents ; ++i )
ea199e33 263 {
ea199e33 264 runLoader->GetEvent(i);
ea199e33 265
42825ed9 266 fLoader->MakeDigitsContainer();
267 TTree* treeD = fLoader->TreeD();
268 if (!treeD)
ea199e33 269 {
42825ed9 270 AliError(Form("Could not get TreeD for event %d",i));
271 continue;
ea199e33 272 }
ea199e33 273
42825ed9 274 DigitStore()->Connect(*treeD);
275
276 GenerateDigits(*(DigitStore()));
277
ea199e33 278 // Fill the output treeD
42825ed9 279 treeD->Fill();
ea199e33 280
281 // Write to the output tree(D).
282 // Please note that as GlobalTrigger, LocalTrigger and Digits are in the same
283 // tree (=TreeD) in different branches, this WriteDigits in fact writes all of
284 // the 3 branches.
42825ed9 285
134d2964 286 AliCodeTimerStart("WriteDigits")
42825ed9 287 fLoader->WriteDigits("OVERWRITE");
134d2964 288 AliCodeTimerStop("WriteDigits")
ea199e33 289
42825ed9 290 fLoader->UnloadDigits();
ea199e33 291
42825ed9 292 if ( fMakeDDL )
293 {
dd0be8a7 294 AliCodeTimerAuto("Digits2Raw",1);
42825ed9 295 Digits2Raw(i);
296 }
ea199e33 297 }
42825ed9 298
ea199e33 299 runLoader->WriteRunLoader("OVERWRITE");
ea199e33 300 delete runLoader;
42825ed9 301 fLoader = 0x0;
302
ea199e33 303 // Finally, if instructed to do so, convert DDL files to DATE file(s)
304 if ( fMakeDDL && fDateFileName.Length() > 0 )
305 {
70d92702 306 AliCodeTimerAuto("ConvertRawFilesToDate",1)
ea199e33 307 Bool_t dateOutput = ConvertRawFilesToDate();
ea199e33 308 if (!dateOutput)
309 {
9ee1d6ff 310 AliError("DATE output failed. Exiting.");
ea199e33 311 return;
312 }
313 }
ea199e33 314}
315
316//_____________________________________________________________________________
317void
42825ed9 318AliMUONPedestalEventGenerator::Digits2Raw(Int_t event)
ea199e33 319{
320 /// Converts digits (from MUON.Digits.root file) to Raw DDL ascii files.
321
99c136e1 322 AliCodeTimerAuto("",0)
ea199e33 323
24dbd5dd 324 if (!fRawWriter)
325 {
326 AliRawDataHeaderSim header;
327 fRawWriter = new AliMUONRawWriter;
328 fRawWriter->SetHeader(header);
329 }
ea199e33 330
331 // Generate RAW data from the digits
332 // Be carefull to create&change to the correct directory first...
42825ed9 333
ea199e33 334 TString baseDir = gSystem->WorkingDirectory();
42825ed9 335
336 char dirName[256];
b785c4bd 337 snprintf(dirName, 256, "raw%d", event);
42825ed9 338 gSystem->MakeDirectory(dirName);
339 if (!gSystem->ChangeDirectory(dirName))
ea199e33 340 {
42825ed9 341 AliError(Form("couldn't change to directory %s", dirName));
342 return;
ea199e33 343 }
344
42825ed9 345 fRawWriter->Digits2Raw(DigitStore(),0);
ea199e33 346
42825ed9 347 gSystem->ChangeDirectory(baseDir);
ea199e33 348}
349
350//_____________________________________________________________________________
351void
42825ed9 352AliMUONPedestalEventGenerator::GenerateDigits(AliMUONVDigitStore& digitStore)
ea199e33 353{
354 /// Generate digits (where ADC is set to pedestal value) for all MUON TRK
355 /// and for 1 event.
356
99c136e1 357 AliCodeTimerAuto("",0)
42825ed9 358
359 digitStore.Clear();
360
ea199e33 361 Int_t ngenerated(0);
42825ed9 362 Int_t nmanus(0);
363 TIter next(fPedestals->CreateIterator());
364 AliMUONVCalibParam* pedestals;
ea199e33 365
42825ed9 366 while ( ( pedestals = static_cast<AliMUONVCalibParam*>(next())) )
ea199e33 367 {
42825ed9 368 Int_t detElemId = pedestals->ID0();
369 Int_t manuId = pedestals->ID1();
ea199e33 370
42825ed9 371 AliMpDetElement* de = AliMpDEStore::Instance()->GetDetElement(detElemId);
372 AliMp::PlaneType planeType = AliMp::kBendingPlane;
373 if ( manuId & AliMpConstants::ManuMask(AliMp::kNonBendingPlane) )
ea199e33 374 {
42825ed9 375 planeType = AliMp::kNonBendingPlane;
ea199e33 376 }
42825ed9 377 AliMp::CathodType cathode = de->GetCathodType(planeType);
378
379 ++nmanus;
380
ea199e33 381 for ( Int_t manuChannel = 0; manuChannel < pedestals->Size(); ++manuChannel )
382 {
383 Float_t mean = pedestals->ValueAsFloat(manuChannel,0);
384 if (mean == AliMUONVCalibParam::InvalidFloatValue())
385 {
386 // This is a poor's man way of knowing if that channel really exists.
387 // Better and safer way (but much slower too) would be to check pad existence
168e9c4d 388 // using AliMpVSegmentation::PadByLocation(manuId,manuChannel)
ea199e33 389 continue;
390 }
4332f0d4 391 else if ( mean < 1 || mean > 4095 )
392 {
393 AliFatal(Form("Got an invalid mean pedestal value for DE %d Manu %d"
394 " channel %d : mean = %e",detElemId,manuId,manuChannel,
395 mean));
396 }
ea199e33 397 else
398 {
399 Float_t sigma = pedestals->ValueAsFloat(manuChannel,1);
42825ed9 400
4332f0d4 401 if ( sigma < 0 )
402 {
403 AliWarning(Form("Got a negative sigma pedestal value for DE %d Manu %d"
404 " channel %d : sigma = %e, will use Abs()=%e",
405 detElemId,manuId,manuChannel,
406 sigma,-sigma));
407 sigma = -sigma;
408 }
409
42825ed9 410 AliMUONVDigit* d = digitStore.Add(detElemId,manuId,manuChannel,
411 cathode,
412 AliMUONVDigitStore::kIgnore);
413
4332f0d4 414 Float_t ped = -1;
415 while ( ped <= 0 )
416 {
417 ped = gRandom->Gaus(mean,sigma);
418 }
42825ed9 419 Int_t pedADC = TMath::FloorNint(ped);
420
421 d->SetADC(pedADC);
422 d->SetCharge(ped);
ea199e33 423 // we do not set the remaining parts of the digit, as in principle
424 // this is all we need : manuId, manuChannel and ADC, as far as
425 // real data is concerned.
ea199e33 426 ++fgCounter;
427 ++ngenerated;
428 }
429 }
430 }
42825ed9 431 AliDebug(1,Form("ngenerated=%d nmanus=%d",ngenerated,nmanus));
ea199e33 432}
433
434//_____________________________________________________________________________
435AliRunLoader*
436AliMUONPedestalEventGenerator::LoadRun(const char* mode)
437{
438 /// Get access to AliRunLoader object
33c3c91a 439 while (AliRunLoader::Instance())
ea199e33 440 {
33c3c91a 441 AliDebug(1,Form("Deleting AliRunLoader %p",AliRunLoader::Instance()));
442 delete AliRunLoader::Instance();
ea199e33 443 }
444
445 AliRunLoader* runLoader =
446 AliRunLoader::Open(fGAliceFileName,AliConfig::GetDefaultEventFolderName(),
447 mode);
42825ed9 448
ea199e33 449 AliDebug(1,Form("AliRunLoader(%s)=%p",mode,runLoader));
42825ed9 450
ea199e33 451 if (!runLoader)
452 {
453 AliError("No run loader found in file galice.root");
fc2293be 454 return 0x0;
ea199e33 455 }
42825ed9 456
457 TString smode(mode);
458 smode.ToUpper();
459
460 if (smode.Contains("RECREATE"))
461 {
462 AliInfo("Creating folder structure");
463 AliConfig::Instance()
464 ->CreateDetectorFolders(runLoader->GetEventFolder(),
465 "MUON", "MUON");
466 fLoader = new AliLoader("MUON",runLoader->GetEventFolder());
467 runLoader->AddLoader(fLoader);
468 }
469
470 fLoader = static_cast<AliLoader*>(runLoader->GetDetectorLoader("MUON"));
471
ea199e33 472 return runLoader;
473}