]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONPedestalEventGenerator.cxx
No more misaligned_geometry
[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
ea199e33 20#include "AliHeader.h"
21#include "AliLog.h"
22#include "AliMUONCalibrationData.h"
42825ed9 23#include "AliMUONDigitStoreV1.h"
ea199e33 24#include "AliMUONRawWriter.h"
134d2964 25#include "AliCodeTimer.h"
ea199e33 26#include "AliMUONVCalibParam.h"
42825ed9 27#include "AliMUONVDigit.h"
28#include "AliMUONVStore.h"
29#include "AliMpCathodType.h"
30#include "AliMpConstants.h"
31#include "AliMpDEStore.h"
32#include "AliMpDetElement.h"
ea199e33 33#include "AliMpIntPair.h"
42825ed9 34#include "AliMpPlaneType.h"
ea199e33 35#include "AliRunLoader.h"
42825ed9 36#include <TClonesArray.h>
37#include <TMath.h>
38#include <TROOT.h>
39#include <TRandom.h>
40#include <TStopwatch.h>
41#include <TSystem.h>
42#include "AliDAQ.h"
ea199e33 43
44///
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
59///
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
134d2964 149 AliCodeTimerAuto("")
42825ed9 150
151 AliInfo("Converting raw to date");
152
ea199e33 153 const Int_t kIDet = AliDAQ::DetectorID("MUONTRK");
154
155 const Int_t kNLDCs = TMath::CeilNint(AliDAQ::NumberOfLdcs(kIDet));
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.
177 sprintf(command, "dateStream -s -D -o %s.LDC%d -# %d -C",
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
220 delete [] pipe;
221 delete runLoader;
42825ed9 222 fLoader=0x0;
ea199e33 223 return (result == 0);
224}
225
42825ed9 226//_____________________________________________________________________________
227AliMUONVDigitStore*
228AliMUONPedestalEventGenerator::DigitStore()
229{
230/// Return digt container; create it if it does not exist
231
232 if (!fDigitStore) fDigitStore = new AliMUONDigitStoreV1;
233 return fDigitStore;
234}
235
ea199e33 236//_____________________________________________________________________________
237void
238AliMUONPedestalEventGenerator::Exec(Option_t*)
239{
240 /// Main steering method
241
134d2964 242 AliCodeTimerAuto("")
42825ed9 243
244 if (!fPedestals)
245 {
246 AliError("No pedestal store. Cannot proceed.");
247 return;
248 }
249
250 AliRunLoader* runLoader = LoadRun("update");
ea199e33 251
42825ed9 252 Int_t nevents = runLoader->GetNumberOfEvents();
253
254 for ( Int_t i = 0; i < nevents ; ++i )
ea199e33 255 {
ea199e33 256 runLoader->GetEvent(i);
ea199e33 257
42825ed9 258 fLoader->MakeDigitsContainer();
259 TTree* treeD = fLoader->TreeD();
260 if (!treeD)
ea199e33 261 {
42825ed9 262 AliError(Form("Could not get TreeD for event %d",i));
263 continue;
ea199e33 264 }
ea199e33 265
42825ed9 266 DigitStore()->Connect(*treeD);
267
268 GenerateDigits(*(DigitStore()));
269
ea199e33 270 // Fill the output treeD
42825ed9 271 treeD->Fill();
ea199e33 272
273 // Write to the output tree(D).
274 // Please note that as GlobalTrigger, LocalTrigger and Digits are in the same
275 // tree (=TreeD) in different branches, this WriteDigits in fact writes all of
276 // the 3 branches.
42825ed9 277
134d2964 278 AliCodeTimerStart("WriteDigits")
42825ed9 279 fLoader->WriteDigits("OVERWRITE");
134d2964 280 AliCodeTimerStop("WriteDigits")
ea199e33 281
42825ed9 282 fLoader->UnloadDigits();
ea199e33 283
42825ed9 284 if ( fMakeDDL )
285 {
286 Digits2Raw(i);
287 }
288
289// gROOT->ProcessLine(Form("gObjectTable->Print(); > generate.txt.%d",i));
ea199e33 290 }
42825ed9 291
ea199e33 292 runLoader->WriteRunLoader("OVERWRITE");
ea199e33 293 delete runLoader;
42825ed9 294 fLoader = 0x0;
295
ea199e33 296 // Finally, if instructed to do so, convert DDL files to DATE file(s)
297 if ( fMakeDDL && fDateFileName.Length() > 0 )
298 {
ea199e33 299 Bool_t dateOutput = ConvertRawFilesToDate();
ea199e33 300 if (!dateOutput)
301 {
302 AliError("DATE output failed. Aborting.");
303 return;
304 }
305 }
ea199e33 306}
307
308//_____________________________________________________________________________
309void
42825ed9 310AliMUONPedestalEventGenerator::Digits2Raw(Int_t event)
ea199e33 311{
312 /// Converts digits (from MUON.Digits.root file) to Raw DDL ascii files.
313
134d2964 314 AliCodeTimerAuto("")
ea199e33 315
42825ed9 316 if (!fRawWriter) fRawWriter = new AliMUONRawWriter;
ea199e33 317
318 // Generate RAW data from the digits
319 // Be carefull to create&change to the correct directory first...
42825ed9 320
ea199e33 321 TString baseDir = gSystem->WorkingDirectory();
42825ed9 322
323 char dirName[256];
324 sprintf(dirName, "raw%d", event);
325 gSystem->MakeDirectory(dirName);
326 if (!gSystem->ChangeDirectory(dirName))
ea199e33 327 {
42825ed9 328 AliError(Form("couldn't change to directory %s", dirName));
329 return;
ea199e33 330 }
331
42825ed9 332 fRawWriter->Digits2Raw(DigitStore(),0);
ea199e33 333
42825ed9 334 gSystem->ChangeDirectory(baseDir);
ea199e33 335}
336
337//_____________________________________________________________________________
338void
42825ed9 339AliMUONPedestalEventGenerator::GenerateDigits(AliMUONVDigitStore& digitStore)
ea199e33 340{
341 /// Generate digits (where ADC is set to pedestal value) for all MUON TRK
342 /// and for 1 event.
343
134d2964 344 AliCodeTimerAuto("")
42825ed9 345
346 digitStore.Clear();
347
ea199e33 348 Int_t ngenerated(0);
42825ed9 349 Int_t nmanus(0);
350 TIter next(fPedestals->CreateIterator());
351 AliMUONVCalibParam* pedestals;
ea199e33 352
42825ed9 353 while ( ( pedestals = static_cast<AliMUONVCalibParam*>(next())) )
ea199e33 354 {
42825ed9 355 Int_t detElemId = pedestals->ID0();
356 Int_t manuId = pedestals->ID1();
ea199e33 357
42825ed9 358 AliMpDetElement* de = AliMpDEStore::Instance()->GetDetElement(detElemId);
359 AliMp::PlaneType planeType = AliMp::kBendingPlane;
360 if ( manuId & AliMpConstants::ManuMask(AliMp::kNonBendingPlane) )
ea199e33 361 {
42825ed9 362 planeType = AliMp::kNonBendingPlane;
ea199e33 363 }
42825ed9 364 AliMp::CathodType cathode = de->GetCathodType(planeType);
365
366 ++nmanus;
367
ea199e33 368 for ( Int_t manuChannel = 0; manuChannel < pedestals->Size(); ++manuChannel )
369 {
370 Float_t mean = pedestals->ValueAsFloat(manuChannel,0);
371 if (mean == AliMUONVCalibParam::InvalidFloatValue())
372 {
373 // This is a poor's man way of knowing if that channel really exists.
374 // Better and safer way (but much slower too) would be to check pad existence
375 // using AliMpVSegmentation::PadByLocation(AliMpIntPair(manuId,manuChannel))
376 continue;
377 }
378 else
379 {
380 Float_t sigma = pedestals->ValueAsFloat(manuChannel,1);
42825ed9 381
382
383 AliMUONVDigit* d = digitStore.Add(detElemId,manuId,manuChannel,
384 cathode,
385 AliMUONVDigitStore::kIgnore);
386
ea199e33 387 Float_t ped = gRandom->Gaus(mean,sigma);
42825ed9 388 Int_t pedADC = TMath::FloorNint(ped);
389
390 d->SetADC(pedADC);
391 d->SetCharge(ped);
ea199e33 392 // we do not set the remaining parts of the digit, as in principle
393 // this is all we need : manuId, manuChannel and ADC, as far as
394 // real data is concerned.
ea199e33 395 ++fgCounter;
396 ++ngenerated;
397 }
398 }
399 }
42825ed9 400 AliDebug(1,Form("ngenerated=%d nmanus=%d",ngenerated,nmanus));
ea199e33 401}
402
403//_____________________________________________________________________________
404AliRunLoader*
405AliMUONPedestalEventGenerator::LoadRun(const char* mode)
406{
407 /// Get access to AliRunLoader object
408 while (AliRunLoader::GetRunLoader())
409 {
410 AliDebug(1,Form("Deleting AliRunLoader %p",AliRunLoader::GetRunLoader()));
411 delete AliRunLoader::GetRunLoader();
412 }
413
414 AliRunLoader* runLoader =
415 AliRunLoader::Open(fGAliceFileName,AliConfig::GetDefaultEventFolderName(),
416 mode);
42825ed9 417
ea199e33 418 AliDebug(1,Form("AliRunLoader(%s)=%p",mode,runLoader));
42825ed9 419
ea199e33 420 if (!runLoader)
421 {
422 AliError("No run loader found in file galice.root");
423 }
42825ed9 424
425 TString smode(mode);
426 smode.ToUpper();
427
428 if (smode.Contains("RECREATE"))
429 {
430 AliInfo("Creating folder structure");
431 AliConfig::Instance()
432 ->CreateDetectorFolders(runLoader->GetEventFolder(),
433 "MUON", "MUON");
434 fLoader = new AliLoader("MUON",runLoader->GetEventFolder());
435 runLoader->AddLoader(fLoader);
436 }
437
438 fLoader = static_cast<AliLoader*>(runLoader->GetDetectorLoader("MUON"));
439
ea199e33 440 return runLoader;
441}