1 /**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * All rights reserved. *
6 * Artur Szostak <artursz@iafrica.com> *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
18 /// \file MUONTimeRawStreamTrigger.C
19 /// \brief Macro for checking the timing (speed) performace of the two different trigger decoders.
21 /// \author Artur Szostak <artursz@iafrica.com>
23 /// This macro is used to check the timing (speed) performance of the existing
24 /// offline decoder for the trigger DDLs and also for the new high performance
25 /// decoder. It can be invoked as follows:
28 /// .L $ALICE_ROOT/MUON/MUONTimeRawStreamTrigger.C+
29 /// MUONTimeRawStreamTrigger(filename, maxEvent);
31 /// where \em filename is the name of a file containing the raw data, or alternatively
32 /// the directory containing rawX (X being an integer) paths with the raw DDL
33 /// data. The \em maxEvent value is the maximum event to process (default set to
34 /// 1000). Thus the macro will time the algorithm for all events in the range
35 /// [0 .. maxEvent-1].
38 #if !defined(__CINT__) || defined(__MAKECINT__)
40 #include "AliCodeTimer.h"
43 #include "AliMUONRawStreamTrigger.h"
44 #include "AliMUONRawStreamTriggerHP.h"
45 #include "AliMUONDarcHeader.h"
46 #include "AliMUONRegHeader.h"
47 #include "AliMUONLocalStruct.h"
48 #include "AliMUONDDLTrigger.h"
51 #include "AliRawReader.h"
52 #include "AliRawReaderMemory.h"
53 #include "AliRawDataHeader.h"
55 #include "TStopwatch.h"
57 #include "Riostream.h"
62 // Linked list node for buffer structures.
72 // local structure information to store
73 struct AliLocalStructInfo
87 UInt_t LoadFiles(AliBufferInfo*& list, TString fileName = "./", Int_t maxEvent = 1000)
89 /// Reads in the DDL files into memory buffers as a linked list.
91 AliRawReader* rawReader = AliRawReader::Create(fileName.Data());
93 if (rawReader == NULL)
95 cerr << "ERROR: Could not create AliRawReader." << endl;
103 while (rawReader->NextEvent())
105 if (iEvent++ >= maxEvent) break;
107 rawReader->Select("MUONTRG", 0, 1);
108 while (rawReader->ReadHeader())
110 AliBufferInfo* info = new AliBufferInfo;
113 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
118 info->fEquipId = rawReader->GetEquipmentId();
119 info->fBufferSize = rawReader->GetDataSize() + sizeof(AliRawDataHeader);
120 info->fBuffer = new UChar_t[info->fBufferSize];
121 if (info->fBuffer == NULL)
123 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
130 memcpy(info->fBuffer, rawReader->GetDataHeader(), sizeof(AliRawDataHeader));
132 // Now copy the payload.
133 if (! rawReader->ReadNext(
134 info->fBuffer + sizeof(AliRawDataHeader),
135 info->fBufferSize - sizeof(AliRawDataHeader)
139 cerr << "ERROR: Failed to read from AliRawReader." << endl;
150 UInt_t CountMaxStructs(AliBufferInfo* list)
152 /// Counts the maximum number of local structures possible
155 AliBufferInfo* current = list;
156 while (current != NULL)
158 total += current->fBufferSize / 5;
159 current = current->fNext;
165 void ReleaseBuffers(AliBufferInfo* list)
167 /// Deletes the memory allocated for the linked list of buffers.
169 AliBufferInfo* current = list;
170 while (current != NULL)
172 AliBufferInfo* tmp = current;
173 current = current->fNext;
174 delete [] tmp->fBuffer;
180 Double_t TimeUsingOldDecoder(AliBufferInfo* list, AliLocalStructInfo* buffer, UInt_t maxBufferSize)
182 /// Perform a timing using the old decoder.
184 AliRawReaderMemory rawReader;
185 AliMUONRawStreamTrigger rawStream(&rawReader);
186 rawReader.NextEvent();
192 AliBufferInfo* current = list;
193 while (current != NULL)
195 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
196 rawReader.SetEquipmentID(current->fEquipId);
204 while ( rawStream.Next(buffer[i].fId, buffer[i].fDec, buffer[i].fTrigY,
205 buffer[i].fYPos, buffer[i].fSXDev, buffer[i].fXDev,
206 buffer[i].fXPos, buffer[i].fTriggerY, buffer[i].fTriggerX,
207 fXPattern, fYPattern)
210 if (i < maxBufferSize-1) i++;
213 current = current->fNext;
216 return timer.RealTime();
220 Double_t TimeUsingNewDecoder(AliBufferInfo* list, AliLocalStructInfo* buffer, UInt_t maxBufferSize)
222 /// Perform a timing using the new decoder.
224 AliRawReaderMemory rawReader;
225 AliMUONRawStreamTriggerHP rawStream(&rawReader);
226 rawReader.NextEvent();
232 AliBufferInfo* current = list;
233 while (current != NULL)
235 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
236 rawReader.SetEquipmentID(current->fEquipId);
241 const AliMUONRawStreamTriggerHP::AliLocalStruct* local = NULL;
242 while ( (local = rawStream.Next()) != NULL )
244 if (i < maxBufferSize)
246 buffer[i].fId = local->GetId();
247 buffer[i].fDec = local->GetDec();
248 buffer[i].fTrigY = local->GetTrigY();
249 buffer[i].fYPos = local->GetYPos();
250 buffer[i].fSXDev = local->GetSXDev();
251 buffer[i].fXDev = local->GetXDev();
252 buffer[i].fXPos = local->GetXPos();
253 buffer[i].fTriggerY = local->GetTriggerY();
254 buffer[i].fTriggerX = local->GetTriggerX();
259 current = current->fNext;
262 return timer.RealTime();
266 Double_t TimeUsingNewDecoderOldInterface(AliBufferInfo* list, AliLocalStructInfo* buffer, UInt_t maxBufferSize)
268 /// Perform a timing using the new decoder but the old Next() method
269 /// as the interface.
271 AliRawReaderMemory rawReader;
272 AliMUONRawStreamTriggerHP rawStream(&rawReader);
273 rawReader.NextEvent();
279 AliBufferInfo* current = list;
280 while (current != NULL)
282 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
283 rawReader.SetEquipmentID(current->fEquipId);
291 while ( rawStream.Next(buffer[i].fId, buffer[i].fDec, buffer[i].fTrigY,
292 buffer[i].fYPos, buffer[i].fSXDev, buffer[i].fXDev,
293 buffer[i].fXPos, buffer[i].fTriggerY, buffer[i].fTriggerX,
294 fXPattern, fYPattern)
297 if (i < maxBufferSize-1) i++;
300 current = current->fNext;
303 return timer.RealTime();
307 void Loop(const char* filename, Bool_t newDecoder)
309 AliCodeTimerAutoGeneral(Form("Loop %s",(newDecoder ? "NEW":"OLD")),);
311 AliRawReader* reader = AliRawReader::Create(filename);
313 AliMUONVRawStreamTrigger* stream;
317 stream = new AliMUONRawStreamTriggerHP(reader);
321 stream = new AliMUONRawStreamTrigger(reader);
336 while ( reader->NextEvent() )
340 while ( stream->Next(id, dec, trigY, yPos, sXDev, xDev, xPos,
341 triggerY, triggerX, xPattern, yPattern) )
352 void MUONTimeRawStreamTriggerDumb(TString fileName)
354 AliCodeTimer::Instance()->Reset();
356 // first check we can open the stream
357 AliRawReader* reader = AliRawReader::Create(fileName.Data());
360 cerr << "Cannot create reader from " << fileName.Data() << endl;
365 // now start the timing per se
367 Loop(fileName,kFALSE);
369 Loop(fileName,kTRUE);
371 AliCodeTimer::Instance()->Print();
375 void MUONTimeRawStreamTrigger(TString fileName = "./", Int_t maxEvent = 1000)
377 /// Performs a timing of old and new decoders and reports this.
379 AliBufferInfo* list = NULL;
380 UInt_t bufferCount = LoadFiles(list, fileName, maxEvent);
381 if (bufferCount == 0)
383 cerr << "ERROR: No DDL files found or read in." << endl;
387 UInt_t maxBufferSize = CountMaxStructs(list);
388 AliLocalStructInfo* buffer = new AliLocalStructInfo[maxBufferSize];
391 ReleaseBuffers(list);
392 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
395 Double_t oldTimes[100];
396 for (Int_t i = 0; i < 100; i++)
398 cout << "Timing old decoder: timing iteration " << i+1 << " of 100" << endl;
399 oldTimes[i] = TimeUsingOldDecoder(list, buffer, maxBufferSize);
401 Double_t newTimes[100];
402 for (Int_t i = 0; i < 100; i++)
404 cout << "Timing new decoder: timing iteration " << i+1 << " of 100" << endl;
405 newTimes[i] = TimeUsingNewDecoder(list, buffer, maxBufferSize);
407 Double_t newTimes2[100];
408 for (Int_t i = 0; i < 100; i++)
410 cout << "Timing new decoder with old interface: timing iteration " << i+1 << " of 100" << endl;
411 newTimes2[i] = TimeUsingNewDecoderOldInterface(list, buffer, maxBufferSize);
414 ReleaseBuffers(list);
417 Double_t oldTime = TMath::Mean(100, oldTimes) / Double_t(bufferCount);
418 Double_t oldTimeErr = TMath::RMS(100, oldTimes) / Double_t(bufferCount);
419 Double_t newTime = TMath::Mean(100, newTimes) / Double_t(bufferCount);
420 Double_t newTimeErr = TMath::RMS(100, newTimes) / Double_t(bufferCount);
421 Double_t newTime2 = TMath::Mean(100, newTimes2) / Double_t(bufferCount);
422 Double_t newTime2Err = TMath::RMS(100, newTimes2) / Double_t(bufferCount);
424 cout << "Average processing time per DDL for:" << endl;
425 cout << " Old decoder = " << oldTime*1e6 << " +/- " << oldTimeErr*1e6/TMath::Sqrt(100) << " micro seconds" << endl;
426 cout << " New decoder = " << newTime*1e6 << " +/- " << newTimeErr*1e6/TMath::Sqrt(100) << " micro seconds" << endl;
427 cout << "New decoder with old interface = " << newTime2*1e6 << " +/- " << newTime2Err*1e6/TMath::Sqrt(100) << " micro seconds" << endl;