]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/MUONTimeRawStreamTracker.C
mixing example
[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 #include "AliCodeTimer.h"
41
42 // MUON includes
43 #include "AliMUONRawStreamTracker.h"
44 #include "AliMUONRawStreamTrackerHP.h"
45 #include "AliMUONDspHeader.h"
46 #include "AliMUONBlockHeader.h"
47 #include "AliMUONBusStruct.h"
48 #include "AliMUONDDLTracker.h"
49
50 // RAW includes
51 #include "AliRawReader.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 = AliRawReader::Create(fileName.Data()); 
86
87         if (rawReader == NULL)
88         {
89                 cerr << "ERROR: Could not create AliRawReader." << endl;
90                 delete rawReader;
91                 return 0;
92         }
93
94         UInt_t count = 0;
95         Int_t iEvent = 0;
96         list = NULL;
97         while (rawReader->NextEvent())
98         {
99                 if (iEvent++ >= maxEvent) break;
100
101                 rawReader->Select("MUONTRK", 0, 19);
102                 while (rawReader->ReadHeader())
103                 {
104                         AliBufferInfo* info = new AliBufferInfo;
105                         if (info == NULL)
106                         {
107                                 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
108                                 delete rawReader;
109                                 return count;
110                         }
111                         info->fNext = list;
112                         info->fEquipId = rawReader->GetEquipmentId();
113                         info->fBufferSize = rawReader->GetDataSize() + sizeof(AliRawDataHeader);
114                         info->fBuffer = new UChar_t[info->fBufferSize];
115                         if (info->fBuffer == NULL)
116                         {
117                                 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
118                                 delete rawReader;
119                                 return count;
120                         }
121                         list = info;
122                         
123                         // Copy the header.
124                         memcpy(info->fBuffer, rawReader->GetDataHeader(), sizeof(AliRawDataHeader));
125
126                         // Now copy the payload.
127                         if (! rawReader->ReadNext(
128                                                 info->fBuffer + sizeof(AliRawDataHeader),
129                                                 info->fBufferSize - sizeof(AliRawDataHeader)
130                                         )
131                            )
132                         {
133                                 cerr << "ERROR: Failed to read from AliRawReader." << endl;
134                         }
135                         count++;
136                 }
137         }
138
139         delete rawReader;
140         return count;
141 }
142
143
144 UInt_t CountMaxDigits(AliBufferInfo* list)
145 {
146         /// Counts the maximum number of digits possible in all the buffers.
147
148         UInt_t total = 0;
149         AliBufferInfo* current = list;
150         while (current != NULL)
151         {
152                 total += current->fBufferSize;
153                 current = current->fNext;
154         }
155         return total;
156 }
157
158
159 void ReleaseBuffers(AliBufferInfo* list)
160 {
161         /// Deletes the memory allocated for the linked list of buffers.
162
163         AliBufferInfo* current = list;
164         while (current != NULL)
165         {
166                 AliBufferInfo* tmp = current;
167                 current = current->fNext;
168                 delete [] tmp->fBuffer;
169                 delete tmp;
170         }
171 }
172
173
174 Double_t TimeUsingOldDecoder(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize)
175 {
176         /// Perform a timing using the old decoder.
177
178         AliRawReaderMemory rawReader;
179         AliMUONRawStreamTracker rawStream(&rawReader);
180         rawReader.NextEvent();
181
182         TStopwatch timer;
183         timer.Start(kTRUE);
184
185         UInt_t i = 0;
186         AliBufferInfo* current = list;
187         while (current != NULL)
188         {
189                 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
190                 rawReader.SetEquipmentID(current->fEquipId);
191                 rawReader.Reset();
192
193                 Int_t busPatch;
194                 UShort_t manuId, adc;
195                 UChar_t manuChannel;
196
197                 rawStream.First();
198
199                 while ( rawStream.Next(busPatch,manuId,manuChannel,adc) )
200                 {
201                         if (i < maxBufferSize)
202                         {
203                                 buffer[i].fManuId = manuId;
204                                 buffer[i].fAdc = adc;
205                                 buffer[i].fChannelId = manuChannel;
206                                 i++;
207                         }
208                 }
209
210                 current = current->fNext;
211         }
212
213         return timer.RealTime();
214 }
215
216
217 Double_t TimeUsingNewDecoder(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize)
218 {
219         /// Perform a timing using the new decoder.
220
221         AliRawReaderMemory rawReader;
222         AliMUONRawStreamTrackerHP rawStream(&rawReader);
223         rawReader.NextEvent();
224
225         TStopwatch timer;
226         timer.Start(kTRUE);
227
228         UInt_t i = 0;
229         AliBufferInfo* current = list;
230         while (current != NULL)
231         {
232                 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
233                 rawReader.SetEquipmentID(current->fEquipId);
234                 rawReader.Reset();
235
236                 UShort_t manuId, adc;
237                 UChar_t manuChannel;
238
239                 rawStream.First();
240
241                 const AliMUONRawStreamTrackerHP::AliBusPatch* buspatch = NULL;
242                 while ((buspatch = rawStream.Next()) != NULL)
243                 {
244                         for (UInt_t j = 0; j < buspatch->GetDataCount(); j++)
245                         {
246                                 buspatch->GetData(j, manuId, manuChannel, adc);
247                                 if (i < maxBufferSize)
248                                 {
249                                         buffer[i].fManuId = manuId;
250                                         buffer[i].fAdc = adc;
251                                         buffer[i].fChannelId = manuChannel;
252                                         i++;
253                                 }
254                         }
255                 }
256
257                 current = current->fNext;
258         }
259
260         return timer.RealTime();
261 }
262
263
264 Double_t TimeUsingNewDecoderOldInterface(AliBufferInfo* list, AliDigitInfo* buffer, UInt_t maxBufferSize)
265 {
266         /// Perform a timing using the new decoder but the old Next() method
267         /// as the interface.
268
269         AliRawReaderMemory rawReader;
270         AliMUONRawStreamTrackerHP rawStream(&rawReader);
271         rawReader.NextEvent();
272
273         TStopwatch timer;
274         timer.Start(kTRUE);
275
276         UInt_t i = 0;
277         AliBufferInfo* current = list;
278         while (current != NULL)
279         {
280                 rawReader.SetMemory(current->fBuffer, current->fBufferSize);
281                 rawReader.SetEquipmentID(current->fEquipId);
282                 rawReader.Reset();
283
284                 Int_t busPatch;
285                 UShort_t manuId, adc;
286                 UChar_t manuChannel;
287
288                 rawStream.First();
289
290                 while ( rawStream.Next(busPatch,manuId,manuChannel,adc) )
291                 {
292                         if (i < maxBufferSize)
293                         {
294                                 buffer[i].fManuId = manuId;
295                                 buffer[i].fAdc = adc;
296                                 buffer[i].fChannelId = manuChannel;
297                                 i++;
298                         }
299                 }
300
301                 current = current->fNext;
302         }
303
304         return timer.RealTime();
305 }
306
307
308 void Loop(const char* filename, Bool_t newDecoder)
309 {
310   AliCodeTimerAutoGeneral(Form("Loop %s",(newDecoder ? "NEW":"OLD")));
311   
312   AliRawReader* reader = AliRawReader::Create(filename);
313   
314   AliMUONVRawStreamTracker* stream;
315   
316   if ( newDecoder ) 
317   {
318     stream = new AliMUONRawStreamTrackerHP(reader);
319   }
320   else
321   {
322     stream = new AliMUONRawStreamTracker(reader);
323   }
324
325   Int_t busPatch;
326   UShort_t manuId, adc;
327   UChar_t manuChannel;
328   
329   while ( reader->NextEvent() ) 
330   {
331     stream->First();
332     
333     while ( stream->Next(busPatch,manuId,manuChannel,adc) ) 
334     {
335       adc *= 2;
336     }
337   }
338   
339   delete stream;
340   delete reader;
341 }
342
343
344 void MUONTimeRawStreamTrackerDumb(TString fileName)
345 {
346   AliCodeTimer::Instance()->Reset();
347   
348   // first check we can open the stream
349   AliRawReader* reader = AliRawReader::Create(fileName.Data());
350   if (!reader)
351   {
352     cerr << "Cannot create reader from " << fileName.Data() << endl;
353     return;
354   }
355   delete reader;
356   
357   // now start the timing per se
358   
359   Loop(fileName,kFALSE);
360   
361   Loop(fileName,kTRUE);
362   
363   AliCodeTimer::Instance()->Print();
364 }
365
366
367 void MUONTimeRawStreamTracker(TString fileName = "./", Int_t maxEvent = 1000)
368 {
369         /// Performs a timing of old and new decoders and reports this.
370
371         AliBufferInfo* list = NULL;
372         UInt_t bufferCount = LoadFiles(list, fileName, maxEvent);
373         if (bufferCount == 0)
374         {
375                 cerr << "ERROR: No DDL files found or read in." << endl;
376                 return;
377         }
378
379         UInt_t maxBufferSize = CountMaxDigits(list);
380         AliDigitInfo* buffer = new AliDigitInfo[maxBufferSize];
381         if (buffer == NULL)
382         {
383                 ReleaseBuffers(list);
384                 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
385                 return;
386         }
387         Double_t oldTimes[100];
388         for (Int_t i = 0; i < 100; i++)
389         {
390                 cout << "Timing old decoder: timing iteration " << i+1 << " of 100" << endl;
391                 oldTimes[i] = TimeUsingOldDecoder(list, buffer, maxBufferSize);
392         }
393         Double_t newTimes[100];
394         for (Int_t i = 0; i < 100; i++)
395         {
396                 cout << "Timing new decoder: timing iteration " << i+1 << " of 100" << endl;
397                 newTimes[i] = TimeUsingNewDecoder(list, buffer, maxBufferSize);
398         }
399         Double_t newTimes2[100];
400         for (Int_t i = 0; i < 100; i++)
401         {
402                 cout << "Timing new decoder with old interface: timing iteration " << i+1 << " of 100" << endl;
403                 newTimes2[i] = TimeUsingNewDecoderOldInterface(list, buffer, maxBufferSize);
404         }
405
406         ReleaseBuffers(list);
407         delete buffer;
408
409         Double_t oldTime = TMath::Mean(100, oldTimes) / Double_t(bufferCount);
410         Double_t oldTimeErr = TMath::RMS(100, oldTimes) / Double_t(bufferCount);
411         Double_t newTime = TMath::Mean(100, newTimes) / Double_t(bufferCount);
412         Double_t newTimeErr = TMath::RMS(100, newTimes) / Double_t(bufferCount);
413         Double_t newTime2 = TMath::Mean(100, newTimes2) / Double_t(bufferCount);
414         Double_t newTime2Err = TMath::RMS(100, newTimes2) / Double_t(bufferCount);
415
416         cout << "Average processing time per DDL for:" << endl;
417         cout << "                   Old decoder = " << oldTime*1e6 << " +/- " << oldTimeErr*1e6/TMath::Sqrt(100) << " micro seconds" << endl;
418         cout << "                   New decoder = " << newTime*1e6 << " +/- " << newTimeErr*1e6/TMath::Sqrt(100) << " micro seconds" << endl;
419         cout << "New decoder with old interface = " << newTime2*1e6 << " +/- " << newTime2Err*1e6/TMath::Sqrt(100) << " micro seconds" << endl;
420 }
421