]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/MUONTimeRawStreamTracker.C
Updated the fast decoder to take into account the end of DDL
[u/mrichter/AliRoot.git] / MUON / MUONTimeRawStreamTracker.C
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
19 /// \brief Macro for checking the timing (speed) performace of the two different tracker decoders.
20 ///
21 /// \author Artur Szostak <artursz@iafrica.com>
22 ///
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:
26 /// 
27 ///  $ aliroot
28 /// .L $ALICE_ROOT/MUON/MUONTimeRawStreamTracker.C+
29 ///  MUONTimeRawStreamTracker(filename, maxEvent);
30 ///
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].
36 ///
37
38 #if !defined(__CINT__) || defined(__MAKECINT__)
39
40 // MUON includes
41 #include "AliMUONRawStreamTracker.h"
42 #include "AliMUONRawStreamTrackerHP.h"
43 #include "AliMUONDspHeader.h"
44 #include "AliMUONBlockHeader.h"
45 #include "AliMUONBusStruct.h"
46 #include "AliMUONDDLTracker.h"
47
48 // RAW includes
49 #include "AliRawReaderDate.h"
50 #include "AliRawReaderFile.h"
51 #include "AliRawReaderRoot.h"
52 #include "AliRawReaderMemory.h"
53 #include "AliRawDataHeader.h"
54
55 #include "TStopwatch.h"
56 #include "TMath.h"
57 #include "Riostream.h"
58
59 #endif
60
61
62 // Linked list node for buffer structures.
63 struct AliBufferInfo
64 {
65         AliBufferInfo* fNext;
66         Int_t fEquipId;
67         UInt_t fBufferSize;
68         UChar_t* fBuffer;
69 };
70
71
72 // Digit information to store
73 struct AliDigitInfo
74 {
75         UShort_t fManuId;
76         UShort_t fAdc;
77         UChar_t fChannelId;
78 };
79
80
81 UInt_t LoadFiles(AliBufferInfo*& list, TString fileName = "./", Int_t maxEvent = 1000)
82 {
83         /// Reads in the DDL files into memory buffers as a linked list.
84
85         AliRawReader* rawReader = NULL;
86   
87         // check extention to choose the rawdata file format
88         if (fileName.EndsWith("/"))
89         {
90                 rawReader = new AliRawReaderFile(fileName); // DDL files
91         }
92         else if (fileName.EndsWith(".root"))
93         {
94                 rawReader = new AliRawReaderRoot(fileName);
95         }
96         else if (!fileName.IsNull())
97         {
98                 rawReader = new AliRawReaderDate(fileName); // DATE file
99         }
100
101         if (rawReader == NULL)
102         {
103                 cerr << "ERROR: Could not create AliRawReader." << endl;
104                 delete rawReader;
105                 return 0;
106         }
107
108         UInt_t count = 0;
109         Int_t iEvent = 0;
110         list = NULL;
111         while (rawReader->NextEvent())
112         {
113                 if (iEvent++ >= maxEvent) break;
114
115                 rawReader->Select("MUONTRK", 0, 19);
116                 while (rawReader->ReadHeader())
117                 {
118                         AliBufferInfo* info = new AliBufferInfo;
119                         if (info == NULL)
120                         {
121                                 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
122                                 delete rawReader;
123                                 return count;
124                         }
125                         info->fNext = list;
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)
130                         {
131                                 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
132                                 delete rawReader;
133                                 return count;
134                         }
135                         list = info;
136                         
137                         // Copy the header.
138                         memcpy(info->fBuffer, rawReader->GetDataHeader(), sizeof(AliRawDataHeader));
139
140                         // Now copy the payload.
141                         if (! rawReader->ReadNext(
142                                                 info->fBuffer + sizeof(AliRawDataHeader),
143                                                 info->fBufferSize - sizeof(AliRawDataHeader)
144                                         )
145                            )
146                         {
147                                 cerr << "ERROR: Failed to read from AliRawReader." << endl;
148                         }
149                         count++;
150                 }
151         }
152
153         delete rawReader;
154         return count;
155 }
156
157
158 UInt_t CountMaxDigits(AliBufferInfo* list)
159 {
160         /// Deletes the memory allocated for the linked list of buffers.
161
162         UInt_t total = 0;
163         AliBufferInfo* current = list;
164         while (current != NULL)
165         {
166                 total += current->fBufferSize;
167                 current = current->fNext;
168         }
169         return total;
170 }
171
172
173 void ReleaseBuffers(AliBufferInfo* list)
174 {
175         /// Deletes the memory allocated for the linked list of buffers.
176
177         AliBufferInfo* current = list;
178         while (current != NULL)
179         {
180                 AliBufferInfo* tmp = current;
181                 current = current->fNext;
182                 delete [] tmp->fBuffer;
183                 delete tmp;
184         }
185 }
186
187
188 Double_t TimeUsingOldDecoder(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize)
189 {
190         /// Perform a timing using the old decoder.
191
192         AliRawReaderMemory rawReader;
193         AliMUONRawStreamTracker rawStream(&rawReader);
194         rawReader.NextEvent();
195
196         TStopwatch timer;
197         timer.Start(kTRUE);
198
199         UInt_t i = 0;
200         AliBufferInfo* current = list;
201         while (current != NULL)
202         {
203                 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
204                 rawReader.SetEquipmentID(current->fEquipId);
205                 rawReader.Reset();
206
207                 Int_t busPatch;
208                 UShort_t manuId, adc;
209                 UChar_t manuChannel;
210
211                 rawStream.First();
212
213                 while ( rawStream.Next(busPatch,manuId,manuChannel,adc) )
214                 {
215                         if (i < maxBufferSize)
216                         {
217                                 buffer->fManuId = manuId;
218                                 buffer->fAdc = adc;
219                                 buffer->fChannelId = manuChannel;
220                                 i++;
221                         }
222                 }
223
224                 current = current->fNext;
225         }
226
227         return timer.RealTime();
228 }
229
230
231 Double_t TimeUsingNewDecoder(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize)
232 {
233         /// Perform a timing using the new decoder.
234
235         AliRawReaderMemory rawReader;
236         AliMUONRawStreamTrackerHP rawStream(&rawReader);
237         rawReader.NextEvent();
238
239         TStopwatch timer;
240         timer.Start(kTRUE);
241
242         UInt_t i = 0;
243         AliBufferInfo* current = list;
244         while (current != NULL)
245         {
246                 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
247                 rawReader.SetEquipmentID(current->fEquipId);
248                 rawReader.Reset();
249
250                 UShort_t manuId, adc;
251                 UChar_t manuChannel;
252
253                 rawStream.First();
254
255                 const AliMUONRawStreamTrackerHP::AliBusPatch* buspatch = NULL;
256                 while ((buspatch = rawStream.Next()) != NULL)
257                 {
258                         for (UInt_t j = 0; j < buspatch->GetDataCount(); j++)
259                         {
260                                 buspatch->GetData(j, manuId, manuChannel, adc);
261                                 if (i < maxBufferSize)
262                                 {
263                                         buffer->fManuId = manuId;
264                                         buffer->fAdc = adc;
265                                         buffer->fChannelId = manuChannel;
266                                         i++;
267                                 }
268                         }
269                 }
270
271                 current = current->fNext;
272         }
273
274         return timer.RealTime();
275 }
276
277
278 Double_t TimeUsingNewDecoderOldInterface(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize)
279 {
280         /// Perform a timing using the new decoder but the old Next() method
281         /// as the interface.
282
283         AliRawReaderMemory rawReader;
284         AliMUONRawStreamTrackerHP rawStream(&rawReader);
285         rawReader.NextEvent();
286
287         TStopwatch timer;
288         timer.Start(kTRUE);
289
290         UInt_t i = 0;
291         AliBufferInfo* current = list;
292         while (current != NULL)
293         {
294                 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
295                 rawReader.SetEquipmentID(current->fEquipId);
296                 rawReader.Reset();
297
298                 Int_t busPatch;
299                 UShort_t manuId, adc;
300                 UChar_t manuChannel;
301
302                 rawStream.First();
303
304                 while ( rawStream.Next(busPatch,manuId,manuChannel,adc) )
305                 {
306                         if (i < maxBufferSize)
307                         {
308                                 buffer->fManuId = manuId;
309                                 buffer->fAdc = adc;
310                                 buffer->fChannelId = manuChannel;
311                                 i++;
312                         }
313                 }
314
315                 current = current->fNext;
316         }
317
318         return timer.RealTime();
319 }
320
321
322 void MUONTimeRawStreamTracker(TString fileName = "./", Int_t maxEvent = 1000)
323 {
324         /// Performs a timing of old and new decoders and reports this.
325
326         AliBufferInfo* list = NULL;
327         UInt_t bufferCount = LoadFiles(list, fileName, maxEvent);
328         if (bufferCount == 0)
329         {
330                 cerr << "ERROR: No DDL files found or read in." << endl;
331                 return;
332         }
333
334         UInt_t maxBufferSize = CountMaxDigits(list);
335         AliDigitInfo* buffer = new AliDigitInfo[maxBufferSize];
336         if (buffer == NULL)
337         {
338                 ReleaseBuffers(list);
339                 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
340                 return;
341         }
342         Double_t oldTimes[100];
343         for (Int_t i = 0; i < 100; i++)
344         {
345                 cout << "Timing old decoder: timing iteration " << i+1 << " of 100" << endl;
346                 oldTimes[i] = TimeUsingOldDecoder(list, buffer, maxBufferSize);
347         }
348         Double_t newTimes[100];
349         for (Int_t i = 0; i < 100; i++)
350         {
351                 cout << "Timing new decoder: timing iteration " << i+1 << " of 100" << endl;
352                 newTimes[i] = TimeUsingNewDecoder(list, buffer, maxBufferSize);
353         }
354         Double_t newTimes2[100];
355         for (Int_t i = 0; i < 100; i++)
356         {
357                 cout << "Timing new decoder with old interface: timing iteration " << i+1 << " of 100" << endl;
358                 newTimes2[i] = TimeUsingNewDecoderOldInterface(list, buffer, maxBufferSize);
359         }
360
361         ReleaseBuffers(list);
362         delete buffer;
363
364         Double_t oldTime = TMath::Mean(100, oldTimes) / Double_t(bufferCount);
365         Double_t oldTimeErr = TMath::RMS(100, oldTimes) / Double_t(bufferCount);
366         Double_t newTime = TMath::Mean(100, newTimes) / Double_t(bufferCount);
367         Double_t newTimeErr = TMath::RMS(100, newTimes) / Double_t(bufferCount);
368         Double_t newTime2 = TMath::Mean(100, newTimes2) / Double_t(bufferCount);
369         Double_t newTime2Err = TMath::RMS(100, newTimes2) / Double_t(bufferCount);
370
371         cout << "Average processing time per DDL for:" << endl;
372         cout << "                   Old decoder = " << oldTime*1e6 << " +/- " << oldTimeErr*1e6/TMath::Sqrt(100) << " micro seconds" << endl;
373         cout << "                   New decoder = " << newTime*1e6 << " +/- " << newTimeErr*1e6/TMath::Sqrt(100) << " micro seconds" << endl;
374         cout << "New decoder with old interface = " << newTime2*1e6 << " +/- " << newTime2Err*1e6/TMath::Sqrt(100) << " micro seconds" << endl;
375 }
376