]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/MUONTimeRawStreamTracker.C
New raw-reader class which deals with events taken from shared memory via the DATE...
[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
195         TStopwatch timer;
196         timer.Start(kTRUE);
197
198         UInt_t i = 0;
199         AliBufferInfo* current = list;
200         while (current != NULL)
201         {
202                 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
203                 rawReader.SetEquipmentID(current->fEquipId);
204                 rawReader.Reset();
205
206                 Int_t busPatch;
207                 UShort_t manuId, adc;
208                 UChar_t manuChannel;
209
210                 rawStream.First();
211
212                 while ( rawStream.Next(busPatch,manuId,manuChannel,adc) )
213                 {
214                         if (i < maxBufferSize)
215                         {
216                                 buffer->fManuId = manuId;
217                                 buffer->fAdc = adc;
218                                 buffer->fChannelId = manuChannel;
219                                 i++;
220                         }
221                 }
222
223                 current = current->fNext;
224         }
225
226         return timer.RealTime();
227 }
228
229
230 Double_t TimeUsingNewDecoder(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize)
231 {
232         /// Perform a timing using the new decoder.
233
234         AliRawReaderMemory rawReader;
235         AliMUONRawStreamTrackerHP rawStream(&rawReader);
236
237         TStopwatch timer;
238         timer.Start(kTRUE);
239
240         UInt_t i = 0;
241         AliBufferInfo* current = list;
242         while (current != NULL)
243         {
244                 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
245                 rawReader.SetEquipmentID(current->fEquipId);
246                 rawReader.Reset();
247
248                 UShort_t manuId, adc;
249                 UChar_t manuChannel;
250
251                 rawStream.First();
252
253                 const AliMUONRawStreamTrackerHP::AliBusPatch* buspatch = NULL;
254                 while ((buspatch = rawStream.Next()) != NULL)
255                 {
256                         for (UInt_t j = 0; j < buspatch->GetDataCount(); j++)
257                         {
258                                 buspatch->GetData(j, manuId, manuChannel, adc);
259                                 if (i < maxBufferSize)
260                                 {
261                                         buffer->fManuId = manuId;
262                                         buffer->fAdc = adc;
263                                         buffer->fChannelId = manuChannel;
264                                         i++;
265                                 }
266                         }
267                 }
268
269                 current = current->fNext;
270         }
271
272         return timer.RealTime();
273 }
274
275
276 Double_t TimeUsingNewDecoderOldInterface(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize)
277 {
278         /// Perform a timing using the new decoder but the old Next() method
279         /// as the interface.
280
281         AliRawReaderMemory rawReader;
282         AliMUONRawStreamTrackerHP rawStream(&rawReader);
283
284         TStopwatch timer;
285         timer.Start(kTRUE);
286
287         UInt_t i = 0;
288         AliBufferInfo* current = list;
289         while (current != NULL)
290         {
291                 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
292                 rawReader.SetEquipmentID(current->fEquipId);
293                 rawReader.Reset();
294
295                 Int_t busPatch;
296                 UShort_t manuId, adc;
297                 UChar_t manuChannel;
298
299                 rawStream.First();
300
301                 while ( rawStream.Next(busPatch,manuId,manuChannel,adc) )
302                 {
303                         if (i < maxBufferSize)
304                         {
305                                 buffer->fManuId = manuId;
306                                 buffer->fAdc = adc;
307                                 buffer->fChannelId = manuChannel;
308                                 i++;
309                         }
310                 }
311
312                 current = current->fNext;
313         }
314
315         return timer.RealTime();
316 }
317
318
319 void MUONTimeRawStreamTracker(TString fileName = "./", Int_t maxEvent = 1000)
320 {
321         /// Performs a timing of old and new decoders and reports this.
322
323         AliBufferInfo* list = NULL;
324         UInt_t bufferCount = LoadFiles(list, fileName, maxEvent);
325         if (bufferCount == 0)
326         {
327                 cerr << "ERROR: No DDL files found or read in." << endl;
328                 return;
329         }
330
331         UInt_t maxBufferSize = CountMaxDigits(list);
332         AliDigitInfo* buffer = new AliDigitInfo[maxBufferSize];
333         if (buffer == NULL)
334         {
335                 ReleaseBuffers(list);
336                 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
337                 return;
338         }
339         Double_t oldTimes[100];
340         for (Int_t i = 0; i < 100; i++)
341         {
342                 cout << "Timing old decoder: timing iteration " << i+1 << " of 100" << endl;
343                 oldTimes[i] = TimeUsingOldDecoder(list, buffer, maxBufferSize);
344         }
345         Double_t newTimes[100];
346         for (Int_t i = 0; i < 100; i++)
347         {
348                 cout << "Timing new decoder: timing iteration " << i+1 << " of 100" << endl;
349                 newTimes[i] = TimeUsingNewDecoder(list, buffer, maxBufferSize);
350         }
351         Double_t newTimes2[100];
352         for (Int_t i = 0; i < 100; i++)
353         {
354                 cout << "Timing new decoder with old interface: timing iteration " << i+1 << " of 100" << endl;
355                 newTimes2[i] = TimeUsingNewDecoderOldInterface(list, buffer, maxBufferSize);
356         }
357
358         ReleaseBuffers(list);
359         delete buffer;
360
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);
367
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;
372 }
373