]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/MUONTimeRawStreamTracker.C
e3366cea7846fa70212ec6a8760544fa560829ea
[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         /// Deletes the memory allocated for the linked list of 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->fManuId = manuId;
204                                 buffer->fAdc = adc;
205                                 buffer->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->fManuId = manuId;
250                                         buffer->fAdc = adc;
251                                         buffer->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->fManuId = manuId;
295                                 buffer->fAdc = adc;
296                                 buffer->fChannelId = manuChannel;
297                                 i++;
298                         }
299                 }
300
301                 current = current->fNext;
302         }
303
304         return timer.RealTime();
305 }
306
307 void Loop(const char* filename, Bool_t newDecoder)
308 {
309   AliCodeTimerAutoGeneral(Form("Loop %s",(newDecoder ? "NEW":"OLD")));
310   
311   AliRawReader* reader = AliRawReader::Create(filename);
312   
313   AliMUONVRawStreamTracker* stream;
314   
315   if ( newDecoder ) 
316   {
317     stream = new AliMUONRawStreamTrackerHP(reader);
318   }
319   else
320   {
321     stream = new AliMUONRawStreamTracker(reader);
322   }
323
324   Int_t busPatch;
325   UShort_t manuId, adc;
326   UChar_t manuChannel;
327   
328   while ( reader->NextEvent() ) 
329   {
330     stream->First();
331     
332     while ( stream->Next(busPatch,manuId,manuChannel,adc) ) 
333     {
334       adc *= 2;
335     }
336   }
337   
338   delete stream;
339   delete reader;
340 }
341
342 void MUONTimeRawStreamTrackerDumb(TString fileName)
343 {
344   AliCodeTimer::Instance()->Reset();
345   
346   // first check we can open the stream
347   AliRawReader* reader = AliRawReader::Create(fileName.Data());
348   if (!reader)
349   {
350     cerr << "Cannot create reader from " << fileName.Data() << endl;
351     return;
352   }
353   delete reader;
354   
355   // now start the timing per se
356   
357   Loop(fileName,kFALSE);
358   
359   Loop(fileName,kTRUE);
360   
361   AliCodeTimer::Instance()->Print();
362 }
363
364 void MUONTimeRawStreamTracker(TString fileName = "./", Int_t maxEvent = 1000)
365 {
366         /// Performs a timing of old and new decoders and reports this.
367
368         AliBufferInfo* list = NULL;
369         UInt_t bufferCount = LoadFiles(list, fileName, maxEvent);
370         if (bufferCount == 0)
371         {
372                 cerr << "ERROR: No DDL files found or read in." << endl;
373                 return;
374         }
375
376         UInt_t maxBufferSize = CountMaxDigits(list);
377         AliDigitInfo* buffer = new AliDigitInfo[maxBufferSize];
378         if (buffer == NULL)
379         {
380                 ReleaseBuffers(list);
381                 cerr << "ERROR: Out of memory, sorry. You should limit the number of events read in." << endl;
382                 return;
383         }
384         Double_t oldTimes[100];
385         for (Int_t i = 0; i < 100; i++)
386         {
387                 cout << "Timing old decoder: timing iteration " << i+1 << " of 100" << endl;
388                 oldTimes[i] = TimeUsingOldDecoder(list, buffer, maxBufferSize);
389         }
390         Double_t newTimes[100];
391         for (Int_t i = 0; i < 100; i++)
392         {
393                 cout << "Timing new decoder: timing iteration " << i+1 << " of 100" << endl;
394                 newTimes[i] = TimeUsingNewDecoder(list, buffer, maxBufferSize);
395         }
396         Double_t newTimes2[100];
397         for (Int_t i = 0; i < 100; i++)
398         {
399                 cout << "Timing new decoder with old interface: timing iteration " << i+1 << " of 100" << endl;
400                 newTimes2[i] = TimeUsingNewDecoderOldInterface(list, buffer, maxBufferSize);
401         }
402
403         ReleaseBuffers(list);
404         delete buffer;
405
406         Double_t oldTime = TMath::Mean(100, oldTimes) / Double_t(bufferCount);
407         Double_t oldTimeErr = TMath::RMS(100, oldTimes) / Double_t(bufferCount);
408         Double_t newTime = TMath::Mean(100, newTimes) / Double_t(bufferCount);
409         Double_t newTimeErr = TMath::RMS(100, newTimes) / Double_t(bufferCount);
410         Double_t newTime2 = TMath::Mean(100, newTimes2) / Double_t(bufferCount);
411         Double_t newTime2Err = TMath::RMS(100, newTimes2) / Double_t(bufferCount);
412
413         cout << "Average processing time per DDL for:" << endl;
414         cout << "                   Old decoder = " << oldTime*1e6 << " +/- " << oldTimeErr*1e6/TMath::Sqrt(100) << " micro seconds" << endl;
415         cout << "                   New decoder = " << newTime*1e6 << " +/- " << newTimeErr*1e6/TMath::Sqrt(100) << " micro seconds" << endl;
416         cout << "New decoder with old interface = " << newTime2*1e6 << " +/- " << newTime2Err*1e6/TMath::Sqrt(100) << " micro seconds" << endl;
417 }
418