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 MUONTimeRawStreamTracker.C
19 /// \brief Macro for checking the timing (speed) performace of the two different tracker 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 tracker DDLs and also for the new high performance
25 /// decoder. It can be invoked as follows:
28 /// .L $ALICE_ROOT/MUON/MUONTimeRawStreamTracker.C+
29 /// MUONTimeRawStreamTracker(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 "AliMUONRawStreamTracker.h"
44 #include "AliMUONRawStreamTrackerHP.h"
45 #include "AliMUONDspHeader.h"
46 #include "AliMUONBlockHeader.h"
47 #include "AliMUONBusStruct.h"
48 #include "AliMUONDDLTracker.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 // Digit information to store
81 UInt_t LoadFiles(AliBufferInfo*& list, TString fileName = "./", Int_t maxEvent = 1000)
83 /// Reads in the DDL files into memory buffers as a linked list.
85 AliRawReader* rawReader = AliRawReader::Create(fileName.Data());
87 if (rawReader == NULL)
89 cerr << "ERROR: Could not create AliRawReader." << endl;
97 while (rawReader->NextEvent())
99 if (iEvent++ >= maxEvent) break;
101 rawReader->Select("MUONTRK", 0, 19);
102 while (rawReader->ReadHeader())
104 AliBufferInfo* info = new AliBufferInfo;
107 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
112 info->fEquipId = rawReader->GetEquipmentId();
113 info->fBufferSize = rawReader->GetDataSize() + sizeof(AliRawDataHeader);
114 info->fBuffer = new UChar_t[info->fBufferSize];
115 if (info->fBuffer == NULL)
117 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
124 memcpy(info->fBuffer, rawReader->GetDataHeader(), sizeof(AliRawDataHeader));
126 // Now copy the payload.
127 if (! rawReader->ReadNext(
128 info->fBuffer + sizeof(AliRawDataHeader),
129 info->fBufferSize - sizeof(AliRawDataHeader)
133 cerr << "ERROR: Failed to read from AliRawReader." << endl;
144 UInt_t CountMaxDigits(AliBufferInfo* list)
146 /// Counts the maximum number of digits possible in all the buffers.
149 AliBufferInfo* current = list;
150 while (current != NULL)
152 total += current->fBufferSize;
153 current = current->fNext;
159 void ReleaseBuffers(AliBufferInfo* list)
161 /// Deletes the memory allocated for the linked list of buffers.
163 AliBufferInfo* current = list;
164 while (current != NULL)
166 AliBufferInfo* tmp = current;
167 current = current->fNext;
168 delete [] tmp->fBuffer;
174 Double_t TimeUsingOldDecoder(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize)
176 /// Perform a timing using the old decoder.
178 AliRawReaderMemory rawReader;
179 AliMUONRawStreamTracker rawStream(&rawReader);
180 rawReader.NextEvent();
186 AliBufferInfo* current = list;
187 while (current != NULL)
189 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
190 rawReader.SetEquipmentID(current->fEquipId);
194 UShort_t manuId, adc;
199 while ( rawStream.Next(busPatch,manuId,manuChannel,adc) )
201 if (i < maxBufferSize)
203 buffer[i].fManuId = manuId;
204 buffer[i].fAdc = adc;
205 buffer[i].fChannelId = manuChannel;
210 current = current->fNext;
213 return timer.RealTime();
217 Double_t TimeUsingNewDecoder(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize)
219 /// Perform a timing using the new decoder.
221 AliRawReaderMemory rawReader;
222 AliMUONRawStreamTrackerHP rawStream(&rawReader);
223 rawReader.NextEvent();
229 AliBufferInfo* current = list;
230 while (current != NULL)
232 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
233 rawReader.SetEquipmentID(current->fEquipId);
236 UShort_t manuId, adc;
241 const AliMUONRawStreamTrackerHP::AliBusPatch* buspatch = NULL;
242 while ((buspatch = rawStream.Next()) != NULL)
244 for (UInt_t j = 0; j < buspatch->GetDataCount(); j++)
246 buspatch->GetData(j, manuId, manuChannel, adc);
247 if (i < maxBufferSize)
249 buffer[i].fManuId = manuId;
250 buffer[i].fAdc = adc;
251 buffer[i].fChannelId = manuChannel;
257 current = current->fNext;
260 return timer.RealTime();
264 Double_t TimeUsingNewDecoderOldInterface(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize)
266 /// Perform a timing using the new decoder but the old Next() method
267 /// as the interface.
269 AliRawReaderMemory rawReader;
270 AliMUONRawStreamTrackerHP rawStream(&rawReader);
271 rawReader.NextEvent();
277 AliBufferInfo* current = list;
278 while (current != NULL)
280 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
281 rawReader.SetEquipmentID(current->fEquipId);
285 UShort_t manuId, adc;
290 while ( rawStream.Next(busPatch,manuId,manuChannel,adc) )
292 if (i < maxBufferSize)
294 buffer[i].fManuId = manuId;
295 buffer[i].fAdc = adc;
296 buffer[i].fChannelId = manuChannel;
301 current = current->fNext;
304 return timer.RealTime();
308 void Loop(const char* filename, Bool_t newDecoder)
310 AliCodeTimerAutoGeneral(Form("Loop %s",(newDecoder ? "NEW":"OLD")));
312 AliRawReader* reader = AliRawReader::Create(filename);
314 AliMUONVRawStreamTracker* stream;
318 stream = new AliMUONRawStreamTrackerHP(reader);
322 stream = new AliMUONRawStreamTracker(reader);
326 UShort_t manuId, adc;
329 while ( reader->NextEvent() )
333 while ( stream->Next(busPatch,manuId,manuChannel,adc) )
344 void MUONTimeRawStreamTrackerDumb(TString fileName)
346 AliCodeTimer::Instance()->Reset();
348 // first check we can open the stream
349 AliRawReader* reader = AliRawReader::Create(fileName.Data());
352 cerr << "Cannot create reader from " << fileName.Data() << endl;
357 // now start the timing per se
359 Loop(fileName,kFALSE);
361 Loop(fileName,kTRUE);
363 AliCodeTimer::Instance()->Print();
367 void MUONTimeRawStreamTracker(TString fileName = "./", Int_t maxEvent = 1000)
369 /// Performs a timing of old and new decoders and reports this.
371 AliBufferInfo* list = NULL;
372 UInt_t bufferCount = LoadFiles(list, fileName, maxEvent);
373 if (bufferCount == 0)
375 cerr << "ERROR: No DDL files found or read in." << endl;
379 UInt_t maxBufferSize = CountMaxDigits(list);
380 AliDigitInfo* buffer = new AliDigitInfo[maxBufferSize];
383 ReleaseBuffers(list);
384 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
387 Double_t oldTimes[100];
388 for (Int_t i = 0; i < 100; i++)
390 cout << "Timing old decoder: timing iteration " << i+1 << " of 100" << endl;
391 oldTimes[i] = TimeUsingOldDecoder(list, buffer, maxBufferSize);
393 Double_t newTimes[100];
394 for (Int_t i = 0; i < 100; i++)
396 cout << "Timing new decoder: timing iteration " << i+1 << " of 100" << endl;
397 newTimes[i] = TimeUsingNewDecoder(list, buffer, maxBufferSize);
399 Double_t newTimes2[100];
400 for (Int_t i = 0; i < 100; i++)
402 cout << "Timing new decoder with old interface: timing iteration " << i+1 << " of 100" << endl;
403 newTimes2[i] = TimeUsingNewDecoderOldInterface(list, buffer, maxBufferSize);
406 ReleaseBuffers(list);
409 Double_t oldTime = TMath::Mean(100, oldTimes) / Double_t(bufferCount);
410 Double_t oldTimeErr = TMath::RMS(100, oldTimes) / Double_t(bufferCount);
411 Double_t newTime = TMath::Mean(100, newTimes) / Double_t(bufferCount);
412 Double_t newTimeErr = TMath::RMS(100, newTimes) / Double_t(bufferCount);
413 Double_t newTime2 = TMath::Mean(100, newTimes2) / Double_t(bufferCount);
414 Double_t newTime2Err = TMath::RMS(100, newTimes2) / Double_t(bufferCount);
416 cout << "Average processing time per DDL for:" << endl;
417 cout << " Old decoder = " << oldTime*1e6 << " +/- " << oldTimeErr*1e6/TMath::Sqrt(100) << " micro seconds" << endl;
418 cout << " New decoder = " << newTime*1e6 << " +/- " << newTimeErr*1e6/TMath::Sqrt(100) << " micro seconds" << endl;
419 cout << "New decoder with old interface = " << newTime2*1e6 << " +/- " << newTime2Err*1e6/TMath::Sqrt(100) << " micro seconds" << endl;