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__)
41 #include "AliMUONRawStreamTracker.h"
42 #include "AliMUONRawStreamTrackerHP.h"
43 #include "AliMUONDspHeader.h"
44 #include "AliMUONBlockHeader.h"
45 #include "AliMUONBusStruct.h"
46 #include "AliMUONDDLTracker.h"
49 #include "AliRawReaderDate.h"
50 #include "AliRawReaderFile.h"
51 #include "AliRawReaderRoot.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 = NULL;
87 // check extention to choose the rawdata file format
88 if (fileName.EndsWith("/"))
90 rawReader = new AliRawReaderFile(fileName); // DDL files
92 else if (fileName.EndsWith(".root"))
94 rawReader = new AliRawReaderRoot(fileName);
96 else if (!fileName.IsNull())
98 rawReader = new AliRawReaderDate(fileName); // DATE file
101 if (rawReader == NULL)
103 cerr << "ERROR: Could not create AliRawReader." << endl;
111 while (rawReader->NextEvent())
113 if (iEvent++ >= maxEvent) break;
115 rawReader->Select("MUONTRK", 0, 19);
116 while (rawReader->ReadHeader())
118 AliBufferInfo* info = new AliBufferInfo;
121 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
126 info->fEquipId = rawReader->GetEquipmentId();
127 info->fBufferSize = rawReader->GetDataSize() + sizeof(AliRawDataHeader);
128 info->fBuffer = new UChar_t[info->fBufferSize];
129 if (info->fBuffer == NULL)
131 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
138 memcpy(info->fBuffer, rawReader->GetDataHeader(), sizeof(AliRawDataHeader));
140 // Now copy the payload.
141 if (! rawReader->ReadNext(
142 info->fBuffer + sizeof(AliRawDataHeader),
143 info->fBufferSize - sizeof(AliRawDataHeader)
147 cerr << "ERROR: Failed to read from AliRawReader." << endl;
158 UInt_t CountMaxDigits(AliBufferInfo* list)
160 /// Deletes the memory allocated for the linked list of buffers.
163 AliBufferInfo* current = list;
164 while (current != NULL)
166 total += current->fBufferSize;
167 current = current->fNext;
173 void ReleaseBuffers(AliBufferInfo* list)
175 /// Deletes the memory allocated for the linked list of buffers.
177 AliBufferInfo* current = list;
178 while (current != NULL)
180 AliBufferInfo* tmp = current;
181 current = current->fNext;
182 delete [] tmp->fBuffer;
188 Double_t TimeUsingOldDecoder(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize)
190 /// Perform a timing using the old decoder.
192 AliRawReaderMemory rawReader;
193 AliMUONRawStreamTracker rawStream(&rawReader);
199 AliBufferInfo* current = list;
200 while (current != NULL)
202 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
203 rawReader.SetEquipmentID(current->fEquipId);
207 UShort_t manuId, adc;
212 while ( rawStream.Next(busPatch,manuId,manuChannel,adc) )
214 if (i < maxBufferSize)
216 buffer->fManuId = manuId;
218 buffer->fChannelId = manuChannel;
223 current = current->fNext;
226 return timer.RealTime();
230 Double_t TimeUsingNewDecoder(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize)
232 /// Perform a timing using the new decoder.
234 AliRawReaderMemory rawReader;
235 AliMUONRawStreamTrackerHP rawStream(&rawReader);
241 AliBufferInfo* current = list;
242 while (current != NULL)
244 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
245 rawReader.SetEquipmentID(current->fEquipId);
248 UShort_t manuId, adc;
253 const AliMUONRawStreamTrackerHP::AliBusPatch* buspatch = NULL;
254 while ((buspatch = rawStream.Next()) != NULL)
256 for (UInt_t j = 0; j < buspatch->GetDataCount(); j++)
258 buspatch->GetData(j, manuId, manuChannel, adc);
259 if (i < maxBufferSize)
261 buffer->fManuId = manuId;
263 buffer->fChannelId = manuChannel;
269 current = current->fNext;
272 return timer.RealTime();
276 Double_t TimeUsingNewDecoderOldInterface(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize)
278 /// Perform a timing using the new decoder but the old Next() method
279 /// as the interface.
281 AliRawReaderMemory rawReader;
282 AliMUONRawStreamTrackerHP rawStream(&rawReader);
288 AliBufferInfo* current = list;
289 while (current != NULL)
291 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
292 rawReader.SetEquipmentID(current->fEquipId);
296 UShort_t manuId, adc;
301 while ( rawStream.Next(busPatch,manuId,manuChannel,adc) )
303 if (i < maxBufferSize)
305 buffer->fManuId = manuId;
307 buffer->fChannelId = manuChannel;
312 current = current->fNext;
315 return timer.RealTime();
319 void MUONTimeRawStreamTracker(TString fileName = "./", Int_t maxEvent = 1000)
321 /// Performs a timing of old and new decoders and reports this.
323 AliBufferInfo* list = NULL;
324 UInt_t bufferCount = LoadFiles(list, fileName, maxEvent);
325 if (bufferCount == 0)
327 cerr << "ERROR: No DDL files found or read in." << endl;
331 UInt_t maxBufferSize = CountMaxDigits(list);
332 AliDigitInfo* buffer = new AliDigitInfo[maxBufferSize];
335 ReleaseBuffers(list);
336 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
339 Double_t oldTimes[100];
340 for (Int_t i = 0; i < 100; i++)
342 cout << "Timing old decoder: timing iteration " << i+1 << " of 100" << endl;
343 oldTimes[i] = TimeUsingOldDecoder(list, buffer, maxBufferSize);
345 Double_t newTimes[100];
346 for (Int_t i = 0; i < 100; i++)
348 cout << "Timing new decoder: timing iteration " << i+1 << " of 100" << endl;
349 newTimes[i] = TimeUsingNewDecoder(list, buffer, maxBufferSize);
351 Double_t newTimes2[100];
352 for (Int_t i = 0; i < 100; i++)
354 cout << "Timing new decoder with old interface: timing iteration " << i+1 << " of 100" << endl;
355 newTimes2[i] = TimeUsingNewDecoderOldInterface(list, buffer, maxBufferSize);
358 ReleaseBuffers(list);
361 Double_t oldTime = TMath::Mean(100, oldTimes) / Double_t(bufferCount);
362 Double_t oldTimeErr = TMath::RMS(100, oldTimes) / Double_t(bufferCount);
363 Double_t newTime = TMath::Mean(100, newTimes) / Double_t(bufferCount);
364 Double_t newTimeErr = TMath::RMS(100, newTimes) / Double_t(bufferCount);
365 Double_t newTime2 = TMath::Mean(100, newTimes2) / Double_t(bufferCount);
366 Double_t newTime2Err = TMath::RMS(100, newTimes2) / Double_t(bufferCount);
368 cout << "Average processing time per DDL for:" << endl;
369 cout << " Old decoder = " << oldTime*1e6 << " +/- " << oldTimeErr*1e6/TMath::Sqrt(100) << " micro seconds" << endl;
370 cout << " New decoder = " << newTime*1e6 << " +/- " << newTimeErr*1e6/TMath::Sqrt(100) << " micro seconds" << endl;
371 cout << "New decoder with old interface = " << newTime2*1e6 << " +/- " << newTime2Err*1e6/TMath::Sqrt(100) << " micro seconds" << endl;