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