new functionality and new class added
[u/mrichter/AliRoot.git] / MUON / MUONTimeRawStreamTracker.C
CommitLineData
d684c469 1/**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * All rights reserved. *
4 * *
5 * Primary Authors: *
6 * Artur Szostak <artursz@iafrica.com> *
7 * *
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 **************************************************************************/
16
17/// \ingroup macros
18/// \file MUONTimeRawStreamTracker.C
4f131d83 19/// \brief Macro for checking the timing (speed) performance of the tracker decoder.
d684c469 20///
21/// \author Artur Szostak <artursz@iafrica.com>
22///
4f131d83 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:
d684c469 25///
26/// $ aliroot
27/// .L $ALICE_ROOT/MUON/MUONTimeRawStreamTracker.C+
28/// MUONTimeRawStreamTracker(filename, maxEvent);
29///
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].
35///
36
37#if !defined(__CINT__) || defined(__MAKECINT__)
38
ce22afdc 39#include "AliCodeTimer.h"
40
d684c469 41// MUON includes
d684c469 42#include "AliMUONRawStreamTrackerHP.h"
43#include "AliMUONDspHeader.h"
44#include "AliMUONBlockHeader.h"
45#include "AliMUONBusStruct.h"
46#include "AliMUONDDLTracker.h"
47
48// RAW includes
ce22afdc 49#include "AliRawReader.h"
d684c469 50#include "AliRawReaderMemory.h"
51#include "AliRawDataHeader.h"
52
53#include "TStopwatch.h"
54#include "TMath.h"
55#include "Riostream.h"
56
57#endif
58
59
60// Linked list node for buffer structures.
61struct AliBufferInfo
62{
63 AliBufferInfo* fNext;
64 Int_t fEquipId;
65 UInt_t fBufferSize;
66 UChar_t* fBuffer;
67};
68
69
70// Digit information to store
71struct AliDigitInfo
72{
73 UShort_t fManuId;
74 UShort_t fAdc;
75 UChar_t fChannelId;
76};
77
78
79UInt_t LoadFiles(AliBufferInfo*& list, TString fileName = "./", Int_t maxEvent = 1000)
80{
81 /// Reads in the DDL files into memory buffers as a linked list.
82
ce22afdc 83 AliRawReader* rawReader = AliRawReader::Create(fileName.Data());
d684c469 84
85 if (rawReader == NULL)
86 {
87 cerr << "ERROR: Could not create AliRawReader." << endl;
88 delete rawReader;
89 return 0;
90 }
91
92 UInt_t count = 0;
93 Int_t iEvent = 0;
94 list = NULL;
95 while (rawReader->NextEvent())
96 {
97 if (iEvent++ >= maxEvent) break;
98
99 rawReader->Select("MUONTRK", 0, 19);
100 while (rawReader->ReadHeader())
101 {
102 AliBufferInfo* info = new AliBufferInfo;
103 if (info == NULL)
104 {
105 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
106 delete rawReader;
107 return count;
108 }
109 info->fNext = list;
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)
114 {
115 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
116 delete rawReader;
117 return count;
118 }
119 list = info;
120
121 // Copy the header.
122 memcpy(info->fBuffer, rawReader->GetDataHeader(), sizeof(AliRawDataHeader));
123
124 // Now copy the payload.
125 if (! rawReader->ReadNext(
126 info->fBuffer + sizeof(AliRawDataHeader),
127 info->fBufferSize - sizeof(AliRawDataHeader)
128 )
129 )
130 {
131 cerr << "ERROR: Failed to read from AliRawReader." << endl;
132 }
133 count++;
134 }
135 }
136
137 delete rawReader;
138 return count;
139}
140
141
142UInt_t CountMaxDigits(AliBufferInfo* list)
143{
1788245f 144 /// Counts the maximum number of digits possible in all the buffers.
d684c469 145
146 UInt_t total = 0;
147 AliBufferInfo* current = list;
148 while (current != NULL)
149 {
150 total += current->fBufferSize;
151 current = current->fNext;
152 }
153 return total;
154}
155
156
157void ReleaseBuffers(AliBufferInfo* list)
158{
159 /// Deletes the memory allocated for the linked list of buffers.
160
161 AliBufferInfo* current = list;
162 while (current != NULL)
163 {
164 AliBufferInfo* tmp = current;
165 current = current->fNext;
166 delete [] tmp->fBuffer;
167 delete tmp;
168 }
169}
170
171
4f131d83 172Double_t TimeDecoderBusPatchIteration(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize)
d684c469 173{
4f131d83 174 /// Perform a timing using the new decoder using the "next bus patch" iteration
d684c469 175
176 AliRawReaderMemory rawReader;
177 AliMUONRawStreamTrackerHP rawStream(&rawReader);
29b6be6a 178 rawReader.NextEvent();
d684c469 179
180 TStopwatch timer;
181 timer.Start(kTRUE);
182
183 UInt_t i = 0;
184 AliBufferInfo* current = list;
185 while (current != NULL)
186 {
187 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
188 rawReader.SetEquipmentID(current->fEquipId);
189 rawReader.Reset();
190
191 UShort_t manuId, adc;
192 UChar_t manuChannel;
193
194 rawStream.First();
195
196 const AliMUONRawStreamTrackerHP::AliBusPatch* buspatch = NULL;
197 while ((buspatch = rawStream.Next()) != NULL)
198 {
199 for (UInt_t j = 0; j < buspatch->GetDataCount(); j++)
200 {
201 buspatch->GetData(j, manuId, manuChannel, adc);
202 if (i < maxBufferSize)
203 {
1788245f 204 buffer[i].fManuId = manuId;
205 buffer[i].fAdc = adc;
206 buffer[i].fChannelId = manuChannel;
d684c469 207 i++;
208 }
209 }
210 }
211
212 current = current->fNext;
213 }
214
215 return timer.RealTime();
216}
217
218
4f131d83 219Double_t TimeDecoderChannelIteration(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize, Bool_t skipParityErrors)
d684c469 220{
4f131d83 221 /// Perform a timing using the "next channel" iteration
222
d684c469 223 AliRawReaderMemory rawReader;
224 AliMUONRawStreamTrackerHP rawStream(&rawReader);
29b6be6a 225 rawReader.NextEvent();
d684c469 226
227 TStopwatch timer;
228 timer.Start(kTRUE);
229
230 UInt_t i = 0;
231 AliBufferInfo* current = list;
232 while (current != NULL)
233 {
234 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
235 rawReader.SetEquipmentID(current->fEquipId);
236 rawReader.Reset();
237
238 Int_t busPatch;
239 UShort_t manuId, adc;
240 UChar_t manuChannel;
241
242 rawStream.First();
243
4f131d83 244 while ( rawStream.Next(busPatch,manuId,manuChannel,adc,skipParityErrors) )
d684c469 245 {
246 if (i < maxBufferSize)
247 {
1788245f 248 buffer[i].fManuId = manuId;
249 buffer[i].fAdc = adc;
250 buffer[i].fChannelId = manuChannel;
d684c469 251 i++;
252 }
253 }
254
255 current = current->fNext;
256 }
257
258 return timer.RealTime();
259}
260
4f131d83 261void MUONTimeRawStreamTrackerDumb(TString fileName)
ce22afdc 262{
4f131d83 263 AliCodeTimer::Instance()->Reset();
ce22afdc 264
4f131d83 265 // first check we can open the stream
266 AliRawReader* reader = AliRawReader::Create(fileName.Data());
267 if (!reader)
ce22afdc 268 {
4f131d83 269 cerr << "Cannot create reader from " << fileName.Data() << endl;
270 return;
ce22afdc 271 }
4f131d83 272
273 AliMUONRawStreamTrackerHP stream(reader);
274
ce22afdc 275 Int_t busPatch;
276 UShort_t manuId, adc;
277 UChar_t manuChannel;
278
279 while ( reader->NextEvent() )
280 {
4f131d83 281 stream.First();
ce22afdc 282
4f131d83 283 while ( stream.Next(busPatch,manuId,manuChannel,adc) )
ce22afdc 284 {
285 adc *= 2;
286 }
287 }
288
ce22afdc 289 AliCodeTimer::Instance()->Print();
290}
d684c469 291
1788245f 292
d684c469 293void MUONTimeRawStreamTracker(TString fileName = "./", Int_t maxEvent = 1000)
294{
4f131d83 295 /// Performs a timing of decoder
d684c469 296
297 AliBufferInfo* list = NULL;
298 UInt_t bufferCount = LoadFiles(list, fileName, maxEvent);
299 if (bufferCount == 0)
300 {
301 cerr << "ERROR: No DDL files found or read in." << endl;
302 return;
303 }
304
305 UInt_t maxBufferSize = CountMaxDigits(list);
306 AliDigitInfo* buffer = new AliDigitInfo[maxBufferSize];
307 if (buffer == NULL)
308 {
309 ReleaseBuffers(list);
310 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
311 return;
312 }
4f131d83 313 Double_t bpTimes[100];
d684c469 314 for (Int_t i = 0; i < 100; i++)
315 {
4f131d83 316 cout << "Timing decoder: bus patch iteration " << i+1 << " of 100" << endl;
317 bpTimes[i] = TimeDecoderBusPatchIteration(list, buffer, maxBufferSize);
d684c469 318 }
4f131d83 319 Double_t channelTimes[100];
d684c469 320 for (Int_t i = 0; i < 100; i++)
321 {
4f131d83 322 cout << "Timing decoder: channel iteration w/ parity check" << i+1 << " of 100" << endl;
323 channelTimes[i] = TimeDecoderChannelIteration(list, buffer, maxBufferSize,kTRUE);
d684c469 324 }
4f131d83 325 Double_t channelTimes2[100];
d684c469 326 for (Int_t i = 0; i < 100; i++)
327 {
4f131d83 328 cout << "Timing decoder: channel iteration w/o parity check" << i+1 << " of 100" << endl;
329 channelTimes2[i] = TimeDecoderChannelIteration(list, buffer, maxBufferSize,kFALSE);
d684c469 330 }
4f131d83 331
d684c469 332 ReleaseBuffers(list);
333 delete buffer;
334
4f131d83 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);
d684c469 341
342 cout << "Average processing time per DDL for:" << endl;
4f131d83 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;
d684c469 346}
347