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