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>
46 //-----------------------------------------------------------------------------
47 /// \class AliMUONPedestalEventGenerator
49 /// Generate simulated pedestal events for MUON TRK, to be able to e.g. test
50 /// online calibration routines.
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)).
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.
60 /// \author L. Aphecetche
61 //-----------------------------------------------------------------------------
64 ClassImp(AliMUONPedestalEventGenerator)
67 Int_t AliMUONPedestalEventGenerator::fgCounter(0);
69 //std::streambuf* RedirectTo(std::ostream& what, std::ostream& to)
71 // std::streambuf* old = what.rdbuf();
73 // std::streambuf* psbuf = to.rdbuf();
79 //_____________________________________________________________________________
80 AliMUONPedestalEventGenerator::AliMUONPedestalEventGenerator(Int_t runNumber,
83 : TTask("AliMUONPedestalEventGenerator","Generate fake pedestal events"),
84 fCalibrationData(new AliMUONCalibrationData(runNumber)),
85 fDateFileName(filename),
86 fGAliceFileName("galice.root"),
89 fPedestals(fCalibrationData->Pedestals()),
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
98 if (!gSystem->IsAbsoluteFileName(fGAliceFileName))
100 char* absFileName = gSystem->ConcatFileName(gSystem->WorkingDirectory(),
102 fGAliceFileName = absFileName;
103 delete[] absFileName;
106 AliRunLoader* runLoader = LoadRun("recreate");
109 AliError("Could not create RunLoader");
113 runLoader->SetNumberOfEventsPerFile(nevents);
115 // Initialize event headers.
116 runLoader->MakeTree("E");
118 for ( Int_t iEvent = 0; iEvent < nevents; ++iEvent )
120 runLoader->SetEventNumber(iEvent);
121 runLoader->GetHeader()->Reset(runNumber,iEvent);
122 runLoader->TreeE()->Fill();
124 runLoader->WriteHeader("OVERWRITE");
125 runLoader->CdGAFile();
126 runLoader->Write(0, TObject::kOverwrite);
133 //_____________________________________________________________________________
134 AliMUONPedestalEventGenerator::~AliMUONPedestalEventGenerator()
137 delete fCalibrationData;
138 AliInfo(Form("make a digit counter %d",fgCounter));
143 //_____________________________________________________________________________
145 AliMUONPedestalEventGenerator::ConvertRawFilesToDate()
147 /// convert raw data DDL files to DATE files with the program "dateStream".
148 /// we make one file per LDC
150 AliCodeTimerAuto("",0)
152 AliInfo("Converting raw to date");
154 const Int_t kIDet = AliDAQ::DetectorID("MUONTRK");
156 const Int_t kNLDCs = 5;//TMath::CeilNint(AliDAQ::NumberOfLdcs(kIDet));
158 char* path = gSystem->Which(gSystem->Getenv("PATH"), "dateStream");
161 AliError("the program dateStream was not found");
167 AliRunLoader* runLoader = LoadRun("read");
168 if (!runLoader) return kFALSE;
170 AliInfo(Form("converting raw data DDL files to DATE files %s", fDateFileName.Data()));
171 FILE** pipe = new FILE*[kNLDCs];
173 for ( Int_t iFile = 0; iFile < kNLDCs; ++iFile)
176 // Note the option -s. It is used in order to avoid
177 // the generation of SOR/EOR events.
178 snprintf(command, 256, "dateStream -c -D -o %s.LDC%d -# %d -C",
179 fDateFileName.Data(), iFile, runLoader->GetNumberOfEvents());
180 pipe[iFile] = gSystem->OpenPipe(command, "w");
183 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); ++iEvent)
188 for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls(kIDet); ++iDDL)
190 Int_t ddlID = AliDAQ::DdlID(kIDet,iDDL);
191 Int_t ldcID = Int_t(ldc + 0.0001);
192 ldc += AliDAQ::NumberOfLdcs(kIDet) / AliDAQ::NumberOfDdls(kIDet);
194 char rawFileName[256];
195 snprintf(rawFileName, 256, "raw%d/%s",
196 iEvent, AliDAQ::DdlFileName(kIDet,iDDL));
198 // check existence and size of raw data file
199 FILE* file = fopen(rawFileName, "rb");
201 fseek(file, 0, SEEK_END);
202 unsigned long size = ftell(file);
206 if (ldcID != prevLDC) {
207 fprintf(pipe[ldcID], " LDC Id %d\n", ldcID);
210 fprintf(pipe[ldcID], " Equipment Id %d Payload %s\n", ddlID, rawFileName);
216 for ( Int_t iFile = 0; iFile < kNLDCs; ++iFile)
218 result += gSystem->ClosePipe(pipe[iFile]);
221 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); ++iEvent)
224 snprintf(command, 256, "rm -r raw%d", iEvent);
225 gSystem->Exec(command);
231 return (result == 0);
234 //_____________________________________________________________________________
236 AliMUONPedestalEventGenerator::DigitStore()
238 /// Return digt container; create it if it does not exist
240 if (!fDigitStore) fDigitStore = AliMUONVDigitStore::Create("AliMUONDigitStoreV2R");
244 //_____________________________________________________________________________
246 AliMUONPedestalEventGenerator::Exec(Option_t*)
248 /// Main steering method
250 AliCodeTimerAuto("",0)
254 AliError("No pedestal store. Cannot proceed.");
258 AliRunLoader* runLoader = LoadRun("update");
260 Int_t nevents = runLoader->GetNumberOfEvents();
262 for ( Int_t i = 0; i < nevents ; ++i )
264 runLoader->GetEvent(i);
266 fLoader->MakeDigitsContainer();
267 TTree* treeD = fLoader->TreeD();
270 AliError(Form("Could not get TreeD for event %d",i));
274 DigitStore()->Connect(*treeD);
276 GenerateDigits(*(DigitStore()));
278 // Fill the output treeD
281 // Write to the output tree(D).
282 // Please note that as GlobalTrigger, LocalTrigger and Digits are in the same
283 // tree (=TreeD) in different branches, this WriteDigits in fact writes all of
286 AliCodeTimerStart("WriteDigits")
287 fLoader->WriteDigits("OVERWRITE");
288 AliCodeTimerStop("WriteDigits")
290 fLoader->UnloadDigits();
294 AliCodeTimerAuto("Digits2Raw",1);
299 runLoader->WriteRunLoader("OVERWRITE");
303 // Finally, if instructed to do so, convert DDL files to DATE file(s)
304 if ( fMakeDDL && fDateFileName.Length() > 0 )
306 AliCodeTimerAuto("ConvertRawFilesToDate",1)
307 Bool_t dateOutput = ConvertRawFilesToDate();
310 AliError("DATE output failed. Exiting.");
316 //_____________________________________________________________________________
318 AliMUONPedestalEventGenerator::Digits2Raw(Int_t event)
320 /// Converts digits (from MUON.Digits.root file) to Raw DDL ascii files.
322 AliCodeTimerAuto("",0)
326 AliRawDataHeaderSim header;
327 fRawWriter = new AliMUONRawWriter;
328 fRawWriter->SetHeader(header);
331 // Generate RAW data from the digits
332 // Be carefull to create&change to the correct directory first...
334 TString baseDir = gSystem->WorkingDirectory();
337 snprintf(dirName, 256, "raw%d", event);
338 gSystem->MakeDirectory(dirName);
339 if (!gSystem->ChangeDirectory(dirName))
341 AliError(Form("couldn't change to directory %s", dirName));
345 fRawWriter->Digits2Raw(DigitStore(),0);
347 gSystem->ChangeDirectory(baseDir);
350 //_____________________________________________________________________________
352 AliMUONPedestalEventGenerator::GenerateDigits(AliMUONVDigitStore& digitStore)
354 /// Generate digits (where ADC is set to pedestal value) for all MUON TRK
357 AliCodeTimerAuto("",0)
363 TIter next(fPedestals->CreateIterator());
364 AliMUONVCalibParam* pedestals;
366 while ( ( pedestals = static_cast<AliMUONVCalibParam*>(next())) )
368 Int_t detElemId = pedestals->ID0();
369 Int_t manuId = pedestals->ID1();
371 AliMpDetElement* de = AliMpDEStore::Instance()->GetDetElement(detElemId);
372 AliMp::PlaneType planeType = AliMp::kBendingPlane;
373 if ( manuId & AliMpConstants::ManuMask(AliMp::kNonBendingPlane) )
375 planeType = AliMp::kNonBendingPlane;
377 AliMp::CathodType cathode = de->GetCathodType(planeType);
381 for ( Int_t manuChannel = 0; manuChannel < pedestals->Size(); ++manuChannel )
383 Float_t mean = pedestals->ValueAsFloat(manuChannel,0);
384 if (mean == AliMUONVCalibParam::InvalidFloatValue())
386 // This is a poor's man way of knowing if that channel really exists.
387 // Better and safer way (but much slower too) would be to check pad existence
388 // using AliMpVSegmentation::PadByLocation(manuId,manuChannel)
391 else if ( mean < 1 || mean > 4095 )
393 AliFatal(Form("Got an invalid mean pedestal value for DE %d Manu %d"
394 " channel %d : mean = %e",detElemId,manuId,manuChannel,
399 Float_t sigma = pedestals->ValueAsFloat(manuChannel,1);
403 AliWarning(Form("Got a negative sigma pedestal value for DE %d Manu %d"
404 " channel %d : sigma = %e, will use Abs()=%e",
405 detElemId,manuId,manuChannel,
410 AliMUONVDigit* d = digitStore.Add(detElemId,manuId,manuChannel,
412 AliMUONVDigitStore::kIgnore);
417 ped = gRandom->Gaus(mean,sigma);
419 Int_t pedADC = TMath::FloorNint(ped);
423 // we do not set the remaining parts of the digit, as in principle
424 // this is all we need : manuId, manuChannel and ADC, as far as
425 // real data is concerned.
431 AliDebug(1,Form("ngenerated=%d nmanus=%d",ngenerated,nmanus));
434 //_____________________________________________________________________________
436 AliMUONPedestalEventGenerator::LoadRun(const char* mode)
438 /// Get access to AliRunLoader object
439 while (AliRunLoader::Instance())
441 AliDebug(1,Form("Deleting AliRunLoader %p",AliRunLoader::Instance()));
442 delete AliRunLoader::Instance();
445 AliRunLoader* runLoader =
446 AliRunLoader::Open(fGAliceFileName,AliConfig::GetDefaultEventFolderName(),
449 AliDebug(1,Form("AliRunLoader(%s)=%p",mode,runLoader));
453 AliError("No run loader found in file galice.root");
460 if (smode.Contains("RECREATE"))
462 AliInfo("Creating folder structure");
463 AliConfig::Instance()
464 ->CreateDetectorFolders(runLoader->GetEventFolder(),
466 fLoader = new AliLoader("MUON",runLoader->GetEventFolder());
467 runLoader->AddLoader(fLoader);
470 fLoader = static_cast<AliLoader*>(runLoader->GetDetectorLoader("MUON"));