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