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) performance of the tracker decoder.
21 /// \author Artur Szostak <artursz@iafrica.com>
23 /// This macro is used to check the timing (speed) performance of the
24 /// decoder for the tracker DDLs. It can be invoked as follows:
27 /// .L $ALICE_ROOT/MUON/MUONTimeRawStreamTracker.C+
28 /// MUONTimeRawStreamTracker(filename, maxEvent);
30 /// where \em filename is the name of a file containing the raw data, or alternatively
31 /// the directory containing rawX (X being an integer) paths with the raw DDL
32 /// data. The \em maxEvent value is the maximum event to process (default set to
33 /// 1000). Thus the macro will time the algorithm for all events in the range
34 /// [0 .. maxEvent-1].
37 #if !defined(__CINT__) || defined(__MAKECINT__)
39 #include "AliCodeTimer.h"
42 #include "AliMUONRawStreamTrackerHP.h"
43 #include "AliMUONDspHeader.h"
44 #include "AliMUONBlockHeader.h"
45 #include "AliMUONBusStruct.h"
46 #include "AliMUONDDLTracker.h"
49 #include "AliRawReader.h"
50 #include "AliRawReaderMemory.h"
51 #include "AliRawDataHeader.h"
53 #include "TStopwatch.h"
55 #include "Riostream.h"
60 // Linked list node for buffer structures.
70 // Digit information to store
79 UInt_t LoadFiles(AliBufferInfo*& list, TString fileName = "./", Int_t maxEvent = 1000)
81 /// Reads in the DDL files into memory buffers as a linked list.
83 AliRawReader* rawReader = AliRawReader::Create(fileName.Data());
85 if (rawReader == NULL)
87 cerr << "ERROR: Could not create AliRawReader." << endl;
95 while (rawReader->NextEvent())
97 if (iEvent++ >= maxEvent) break;
99 rawReader->Select("MUONTRK", 0, 19);
100 while (rawReader->ReadHeader())
102 AliBufferInfo* info = new AliBufferInfo;
105 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
110 info->fEquipId = rawReader->GetEquipmentId();
111 info->fBufferSize = rawReader->GetDataSize() + sizeof(AliRawDataHeader);
112 info->fBuffer = new UChar_t[info->fBufferSize];
113 if (info->fBuffer == NULL)
115 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
122 memcpy(info->fBuffer, rawReader->GetDataHeader(), sizeof(AliRawDataHeader));
124 // Now copy the payload.
125 if (! rawReader->ReadNext(
126 info->fBuffer + sizeof(AliRawDataHeader),
127 info->fBufferSize - sizeof(AliRawDataHeader)
131 cerr << "ERROR: Failed to read from AliRawReader." << endl;
142 UInt_t CountMaxDigits(AliBufferInfo* list)
144 /// Counts the maximum number of digits possible in all the buffers.
147 AliBufferInfo* current = list;
148 while (current != NULL)
150 total += current->fBufferSize;
151 current = current->fNext;
157 void ReleaseBuffers(AliBufferInfo* list)
159 /// Deletes the memory allocated for the linked list of buffers.
161 AliBufferInfo* current = list;
162 while (current != NULL)
164 AliBufferInfo* tmp = current;
165 current = current->fNext;
166 delete [] tmp->fBuffer;
172 Double_t TimeDecoderBusPatchIteration(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize)
174 /// Perform a timing using the new decoder using the "next bus patch" iteration
176 AliRawReaderMemory rawReader;
177 AliMUONRawStreamTrackerHP rawStream(&rawReader);
178 rawReader.NextEvent();
184 AliBufferInfo* current = list;
185 while (current != NULL)
187 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
188 rawReader.SetEquipmentID(current->fEquipId);
191 UShort_t manuId, adc;
196 const AliMUONRawStreamTrackerHP::AliBusPatch* buspatch = NULL;
197 while ((buspatch = rawStream.Next()) != NULL)
199 for (UInt_t j = 0; j < buspatch->GetDataCount(); j++)
201 buspatch->GetData(j, manuId, manuChannel, adc);
202 if (i < maxBufferSize)
204 buffer[i].fManuId = manuId;
205 buffer[i].fAdc = adc;
206 buffer[i].fChannelId = manuChannel;
212 current = current->fNext;
215 return timer.RealTime();
219 Double_t TimeDecoderChannelIteration(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize, Bool_t skipParityErrors)
221 /// Perform a timing using the "next channel" iteration
223 AliRawReaderMemory rawReader;
224 AliMUONRawStreamTrackerHP rawStream(&rawReader);
225 rawReader.NextEvent();
231 AliBufferInfo* current = list;
232 while (current != NULL)
234 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
235 rawReader.SetEquipmentID(current->fEquipId);
239 UShort_t manuId, adc;
244 while ( rawStream.Next(busPatch,manuId,manuChannel,adc,skipParityErrors) )
246 if (i < maxBufferSize)
248 buffer[i].fManuId = manuId;
249 buffer[i].fAdc = adc;
250 buffer[i].fChannelId = manuChannel;
255 current = current->fNext;
258 return timer.RealTime();
261 void MUONTimeRawStreamTrackerDumb(TString fileName)
263 AliCodeTimer::Instance()->Reset();
265 // first check we can open the stream
266 AliRawReader* reader = AliRawReader::Create(fileName.Data());
269 cerr << "Cannot create reader from " << fileName.Data() << endl;
273 AliMUONRawStreamTrackerHP stream(reader);
276 UShort_t manuId, adc;
279 while ( reader->NextEvent() )
283 while ( stream.Next(busPatch,manuId,manuChannel,adc) )
289 AliCodeTimer::Instance()->Print();
293 void MUONTimeRawStreamTracker(TString fileName = "./", Int_t maxEvent = 1000)
295 /// Performs a timing of decoder
297 AliBufferInfo* list = NULL;
298 UInt_t bufferCount = LoadFiles(list, fileName, maxEvent);
299 if (bufferCount == 0)
301 cerr << "ERROR: No DDL files found or read in." << endl;
305 UInt_t maxBufferSize = CountMaxDigits(list);
306 AliDigitInfo* buffer = new AliDigitInfo[maxBufferSize];
309 ReleaseBuffers(list);
310 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
313 Double_t bpTimes[100];
314 for (Int_t i = 0; i < 100; i++)
316 cout << "Timing decoder: bus patch iteration " << i+1 << " of 100" << endl;
317 bpTimes[i] = TimeDecoderBusPatchIteration(list, buffer, maxBufferSize);
319 Double_t channelTimes[100];
320 for (Int_t i = 0; i < 100; i++)
322 cout << "Timing decoder: channel iteration w/ parity check" << i+1 << " of 100" << endl;
323 channelTimes[i] = TimeDecoderChannelIteration(list, buffer, maxBufferSize,kTRUE);
325 Double_t channelTimes2[100];
326 for (Int_t i = 0; i < 100; i++)
328 cout << "Timing decoder: channel iteration w/o parity check" << i+1 << " of 100" << endl;
329 channelTimes2[i] = TimeDecoderChannelIteration(list, buffer, maxBufferSize,kFALSE);
332 ReleaseBuffers(list);
335 Double_t bpTime = TMath::Mean(100, bpTimes) / Double_t(bufferCount);
336 Double_t bpTimeErr = TMath::RMS(100, bpTimes) / Double_t(bufferCount);
337 Double_t channelTime = TMath::Mean(100, channelTimes) / Double_t(bufferCount);
338 Double_t channelTimeErr = TMath::RMS(100, channelTimes) / Double_t(bufferCount);
339 Double_t channelTime2 = TMath::Mean(100, channelTimes2) / Double_t(bufferCount);
340 Double_t channelTime2Err = TMath::RMS(100, channelTimes2) / Double_t(bufferCount);
342 cout << "Average processing time per DDL for:" << endl;
343 cout << " bus patch iteration = " << bpTime*1e6 << " +/- " << bpTimeErr*1e6/TMath::Sqrt(100) << " micro seconds" << endl;
344 cout << " channel iteration with parity check = " << channelTime*1e6 << " +/- " << channelTimeErr*1e6/TMath::Sqrt(100) << " micro seconds" << endl;
345 cout << " channel iteration without parity check = " << channelTime2*1e6 << " +/- " << channelTime2Err*1e6/TMath::Sqrt(100) << " micro seconds" << endl;