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 "AliMpIntPair.h"
35 #include "AliMpPlaneType.h"
36 #include "AliRawDataHeaderSim.h"
37 #include "AliRunLoader.h"
38 #include <TClonesArray.h>
42 #include <TStopwatch.h>
45 //-----------------------------------------------------------------------------
46 /// \class AliMUONPedestalEventGenerator
48 /// Generate simulated pedestal events for MUON TRK, to be able to e.g. test
49 /// online calibration routines.
51 /// The pedestals themselves are taken from the CDB. What we get from the CDB
52 /// is, per channel, the mean and the sigma of the pedestal. We then use
53 /// those informations to randomly get the pedestals for each channel, for
54 /// each event (picking in a gaus(mean,sigma)).
56 /// Output can be just digits, or digits + raw (ddl), or digits + raw (ddl)
57 /// + raw (date files, one per LDC), depending of ctor and MakeDDL() method.
59 /// \author L. Aphecetche
60 //-----------------------------------------------------------------------------
63 ClassImp(AliMUONPedestalEventGenerator)
66 Int_t AliMUONPedestalEventGenerator::fgCounter(0);
68 //std::streambuf* RedirectTo(std::ostream& what, std::ostream& to)
70 // std::streambuf* old = what.rdbuf();
72 // std::streambuf* psbuf = to.rdbuf();
78 //_____________________________________________________________________________
79 AliMUONPedestalEventGenerator::AliMUONPedestalEventGenerator(Int_t runNumber,
82 : TTask("AliMUONPedestalEventGenerator","Generate fake pedestal events"),
83 fCalibrationData(new AliMUONCalibrationData(runNumber)),
84 fDateFileName(filename),
85 fGAliceFileName("galice.root"),
88 fPedestals(fCalibrationData->Pedestals()),
92 /// Will generate pedestals according to (mean,sigma)s found in CDB
93 /// for run runNumber.
94 /// Will generate nevents events
95 /// If filename is != "", it will be the basename of the output LDC files
97 if (!gSystem->IsAbsoluteFileName(fGAliceFileName))
99 char* absFileName = gSystem->ConcatFileName(gSystem->WorkingDirectory(),
101 fGAliceFileName = absFileName;
102 delete[] absFileName;
105 AliRunLoader* runLoader = LoadRun("recreate");
107 runLoader->SetNumberOfEventsPerFile(nevents);
111 AliError("Could not create RunLoader");
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
152 AliInfo("Converting raw to date");
154 const Int_t kIDet = AliDAQ::DetectorID("MUONTRK");
156 const Int_t kNLDCs = 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 sprintf(command, "dateStream -s -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 sprintf(rawFileName, "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 sprintf(command, "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
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");
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")
307 Bool_t dateOutput = ConvertRawFilesToDate();
310 AliError("DATE output failed. Aborting.");
316 //_____________________________________________________________________________
318 AliMUONPedestalEventGenerator::Digits2Raw(Int_t event)
320 /// Converts digits (from MUON.Digits.root file) to Raw DDL ascii files.
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 sprintf(dirName, "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
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(AliMpIntPair(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");
459 if (smode.Contains("RECREATE"))
461 AliInfo("Creating folder structure");
462 AliConfig::Instance()
463 ->CreateDetectorFolders(runLoader->GetEventFolder(),
465 fLoader = new AliLoader("MUON",runLoader->GetEventFolder());
466 runLoader->AddLoader(fLoader);
469 fLoader = static_cast<AliLoader*>(runLoader->GetDetectorLoader("MUON"));