1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 #include "AliMUONPedestalEventGenerator.h"
20 #include "AliCodeTimer.h"
22 #include "AliHeader.h"
24 #include "AliMUONCalibrationData.h"
25 #include "AliMUONRawWriter.h"
26 #include "AliMUONVCalibParam.h"
27 #include "AliMUONVDigit.h"
28 #include "AliMUONVDigitStore.h"
29 #include "AliMUONVStore.h"
30 #include "AliMpCathodType.h"
31 #include "AliMpConstants.h"
32 #include "AliMpDEStore.h"
33 #include "AliMpDetElement.h"
34 #include "AliMpPlaneType.h"
35 #include "AliRawDataHeaderSim.h"
36 #include "AliRunLoader.h"
37 #include <TClonesArray.h>
41 #include <TStopwatch.h>
44 //-----------------------------------------------------------------------------
45 /// \class AliMUONPedestalEventGenerator
47 /// Generate simulated pedestal events for MUON TRK, to be able to e.g. test
48 /// online calibration routines.
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)).
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.
58 /// \author L. Aphecetche
59 //-----------------------------------------------------------------------------
62 ClassImp(AliMUONPedestalEventGenerator)
65 Int_t AliMUONPedestalEventGenerator::fgCounter(0);
67 //std::streambuf* RedirectTo(std::ostream& what, std::ostream& to)
69 // std::streambuf* old = what.rdbuf();
71 // std::streambuf* psbuf = to.rdbuf();
77 //_____________________________________________________________________________
78 AliMUONPedestalEventGenerator::AliMUONPedestalEventGenerator(Int_t runNumber,
81 : TTask("AliMUONPedestalEventGenerator","Generate fake pedestal events"),
82 fCalibrationData(new AliMUONCalibrationData(runNumber)),
83 fDateFileName(filename),
84 fGAliceFileName("galice.root"),
87 fPedestals(fCalibrationData->Pedestals()),
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
96 if (!gSystem->IsAbsoluteFileName(fGAliceFileName))
98 char* absFileName = gSystem->ConcatFileName(gSystem->WorkingDirectory(),
100 fGAliceFileName = absFileName;
101 delete[] absFileName;
104 AliRunLoader* runLoader = LoadRun("recreate");
106 runLoader->SetNumberOfEventsPerFile(nevents);
110 AliError("Could not create RunLoader");
114 // Initialize event headers.
115 runLoader->MakeTree("E");
117 for ( Int_t iEvent = 0; iEvent < nevents; ++iEvent )
119 runLoader->SetEventNumber(iEvent);
120 runLoader->GetHeader()->Reset(runNumber,iEvent);
121 runLoader->TreeE()->Fill();
123 runLoader->WriteHeader("OVERWRITE");
124 runLoader->CdGAFile();
125 runLoader->Write(0, TObject::kOverwrite);
132 //_____________________________________________________________________________
133 AliMUONPedestalEventGenerator::~AliMUONPedestalEventGenerator()
136 delete fCalibrationData;
137 AliInfo(Form("make a digit counter %d",fgCounter));
142 //_____________________________________________________________________________
144 AliMUONPedestalEventGenerator::ConvertRawFilesToDate()
146 /// convert raw data DDL files to DATE files with the program "dateStream".
147 /// we make one file per LDC
151 AliInfo("Converting raw to date");
153 const Int_t kIDet = AliDAQ::DetectorID("MUONTRK");
155 const Int_t kNLDCs = TMath::CeilNint(AliDAQ::NumberOfLdcs(kIDet));
157 char* path = gSystem->Which(gSystem->Getenv("PATH"), "dateStream");
160 AliError("the program dateStream was not found");
166 AliRunLoader* runLoader = LoadRun("read");
167 if (!runLoader) return kFALSE;
169 AliInfo(Form("converting raw data DDL files to DATE files %s", fDateFileName.Data()));
170 FILE** pipe = new FILE*[kNLDCs];
172 for ( Int_t iFile = 0; iFile < kNLDCs; ++iFile)
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");
182 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); ++iEvent)
187 for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls(kIDet); ++iDDL)
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);
193 char rawFileName[256];
194 sprintf(rawFileName, "raw%d/%s",
195 iEvent, AliDAQ::DdlFileName(kIDet,iDDL));
197 // check existence and size of raw data file
198 FILE* file = fopen(rawFileName, "rb");
200 fseek(file, 0, SEEK_END);
201 unsigned long size = ftell(file);
205 if (ldcID != prevLDC) {
206 fprintf(pipe[ldcID], " LDC Id %d\n", ldcID);
209 fprintf(pipe[ldcID], " Equipment Id %d Payload %s\n", ddlID, rawFileName);
215 for ( Int_t iFile = 0; iFile < kNLDCs; ++iFile)
217 result += gSystem->ClosePipe(pipe[iFile]);
220 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); ++iEvent)
223 sprintf(command, "rm -r raw%d", iEvent);
224 gSystem->Exec(command);
230 return (result == 0);
233 //_____________________________________________________________________________
235 AliMUONPedestalEventGenerator::DigitStore()
237 /// Return digt container; create it if it does not exist
239 if (!fDigitStore) fDigitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV2R");
243 //_____________________________________________________________________________
245 AliMUONPedestalEventGenerator::Exec(Option_t*)
247 /// Main steering method
253 AliError("No pedestal store. Cannot proceed.");
257 AliRunLoader* runLoader = LoadRun("update");
259 Int_t nevents = runLoader->GetNumberOfEvents();
261 for ( Int_t i = 0; i < nevents ; ++i )
263 runLoader->GetEvent(i);
265 fLoader->MakeDigitsContainer();
266 TTree* treeD = fLoader->TreeD();
269 AliError(Form("Could not get TreeD for event %d",i));
273 DigitStore()->Connect(*treeD);
275 GenerateDigits(*(DigitStore()));
277 // Fill the output treeD
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
285 AliCodeTimerStart("WriteDigits")
286 fLoader->WriteDigits("OVERWRITE");
287 AliCodeTimerStop("WriteDigits")
289 fLoader->UnloadDigits();
293 AliCodeTimerAuto("Digits2Raw");
298 runLoader->WriteRunLoader("OVERWRITE");
302 // Finally, if instructed to do so, convert DDL files to DATE file(s)
303 if ( fMakeDDL && fDateFileName.Length() > 0 )
305 AliCodeTimerAuto("ConvertRawFilesToDate")
306 Bool_t dateOutput = ConvertRawFilesToDate();
309 AliError("DATE output failed. Aborting.");
315 //_____________________________________________________________________________
317 AliMUONPedestalEventGenerator::Digits2Raw(Int_t event)
319 /// Converts digits (from MUON.Digits.root file) to Raw DDL ascii files.
325 AliRawDataHeaderSim header;
326 fRawWriter = new AliMUONRawWriter;
327 fRawWriter->SetHeader(header);
330 // Generate RAW data from the digits
331 // Be carefull to create&change to the correct directory first...
333 TString baseDir = gSystem->WorkingDirectory();
336 sprintf(dirName, "raw%d", event);
337 gSystem->MakeDirectory(dirName);
338 if (!gSystem->ChangeDirectory(dirName))
340 AliError(Form("couldn't change to directory %s", dirName));
344 fRawWriter->Digits2Raw(DigitStore(),0);
346 gSystem->ChangeDirectory(baseDir);
349 //_____________________________________________________________________________
351 AliMUONPedestalEventGenerator::GenerateDigits(AliMUONVDigitStore& digitStore)
353 /// Generate digits (where ADC is set to pedestal value) for all MUON TRK
362 TIter next(fPedestals->CreateIterator());
363 AliMUONVCalibParam* pedestals;
365 while ( ( pedestals = static_cast<AliMUONVCalibParam*>(next())) )
367 Int_t detElemId = pedestals->ID0();
368 Int_t manuId = pedestals->ID1();
370 AliMpDetElement* de = AliMpDEStore::Instance()->GetDetElement(detElemId);
371 AliMp::PlaneType planeType = AliMp::kBendingPlane;
372 if ( manuId & AliMpConstants::ManuMask(AliMp::kNonBendingPlane) )
374 planeType = AliMp::kNonBendingPlane;
376 AliMp::CathodType cathode = de->GetCathodType(planeType);
380 for ( Int_t manuChannel = 0; manuChannel < pedestals->Size(); ++manuChannel )
382 Float_t mean = pedestals->ValueAsFloat(manuChannel,0);
383 if (mean == AliMUONVCalibParam::InvalidFloatValue())
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
387 // using AliMpVSegmentation::PadByLocation(manuId,manuChannel)
390 else if ( mean < 1 || mean > 4095 )
392 AliFatal(Form("Got an invalid mean pedestal value for DE %d Manu %d"
393 " channel %d : mean = %e",detElemId,manuId,manuChannel,
398 Float_t sigma = pedestals->ValueAsFloat(manuChannel,1);
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,
409 AliMUONVDigit* d = digitStore.Add(detElemId,manuId,manuChannel,
411 AliMUONVDigitStore::kIgnore);
416 ped = gRandom->Gaus(mean,sigma);
418 Int_t pedADC = TMath::FloorNint(ped);
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.
430 AliDebug(1,Form("ngenerated=%d nmanus=%d",ngenerated,nmanus));
433 //_____________________________________________________________________________
435 AliMUONPedestalEventGenerator::LoadRun(const char* mode)
437 /// Get access to AliRunLoader object
438 while (AliRunLoader::Instance())
440 AliDebug(1,Form("Deleting AliRunLoader %p",AliRunLoader::Instance()));
441 delete AliRunLoader::Instance();
444 AliRunLoader* runLoader =
445 AliRunLoader::Open(fGAliceFileName,AliConfig::GetDefaultEventFolderName(),
448 AliDebug(1,Form("AliRunLoader(%s)=%p",mode,runLoader));
452 AliError("No run loader found in file galice.root");
458 if (smode.Contains("RECREATE"))
460 AliInfo("Creating folder structure");
461 AliConfig::Instance()
462 ->CreateDetectorFolders(runLoader->GetEventFolder(),
464 fLoader = new AliLoader("MUON",runLoader->GetEventFolder());
465 runLoader->AddLoader(fLoader);
468 fLoader = static_cast<AliLoader*>(runLoader->GetDetectorLoader("MUON"));