]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/MUON/utils/AliHLTMUONRawDataHistoComponent.cxx
Fixing buffer size requirements and reseting histograms after publishing them.
[u/mrichter/AliRoot.git] / HLT / MUON / utils / AliHLTMUONRawDataHistoComponent.cxx
CommitLineData
a63da6d6 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/* $Id: $ */
18
19///
20/// @file AliHLTMUONRawDataHistoComponent.cxx
21/// @author Artur Szostak <artursz@iafrica.com>
22/// @date 30 April 2008
23/// @brief Implementation of the raw data histogramming component for dHLT.
24///
25/// The class implements
26
27#include "AliHLTMUONRawDataHistoComponent.h"
28#include "AliHLTMUONConstants.h"
29#include "AliHLTMUONUtils.h"
30#include "AliHLTDataTypes.h"
31#include "AliCDBEntry.h"
32#include "AliCDBManager.h"
33#include "AliRawDataHeader.h"
a63da6d6 34#include "TTimeStamp.h"
35#include <cstdlib>
36#include <cstring>
37#include <cerrno>
38#include <cmath>
39#include <new>
40
41
42// Helper type for memory allocation.
43typedef const AliHLTMUONMansoTrackStruct* AliHLTMUONMansoTrackStructP;
44
45
46ClassImp(AliHLTMUONRawDataHistoComponent);
47
48
49AliHLTMUONRawDataHistoComponent::AliHLTMUONRawDataHistoComponent() :
50 AliHLTMUONProcessor(),
7989fd8e 51 fTrackerDecoder(),
52 fTriggerDecoder(),
a63da6d6 53 fLastPublishTime(-1),
54 fCurrentEventTime(-1),
7989fd8e 55 fPublishDelay(1),
56 fSuppressEmptyHists(false),
57 fProcessDataEventsOnly(false)
a63da6d6 58{
59 /// Default constructor initialises all histogram object pointers to NULL.
60
61 for (int i = 0; i < 22; i++)
62 {
63 fErrorHist[i] = NULL;
64 }
65 for (int i = 0; i < 20; i++)
66 {
67 fManuHist[i] = NULL;
68 fSignalHist[i] = NULL;
69 }
7989fd8e 70
71 fTrackerDecoder.ExitOnError(false);
72 fTrackerDecoder.TryRecover(false);
73 fTrackerDecoder.SendDataOnParityError(true);
74 fTrackerDecoder.AutoDetectTrailer(true);
75 fTrackerDecoder.CheckForTrailer(true);
76
77 fTriggerDecoder.ExitOnError(false);
78 fTriggerDecoder.TryRecover(false);
79 fTriggerDecoder.AutoDetectScalars(false);
a63da6d6 80}
81
82
83AliHLTMUONRawDataHistoComponent::~AliHLTMUONRawDataHistoComponent()
84{
85 /// Default destructor deletes all histogram objects if they are still allocated.
86
87}
88
89
90const char* AliHLTMUONRawDataHistoComponent::GetComponentID()
91{
a63da6d6 92 /// Inherited from AliHLTComponent. Returns the component ID.
a63da6d6 93
94 return AliHLTMUONConstants::RawDataHistogrammerId();
95}
96
97
98void AliHLTMUONRawDataHistoComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
99{
a63da6d6 100 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
a63da6d6 101
102 assert( list.empty() );
103 list.push_back( AliHLTMUONConstants::DDLRawDataType() );
104}
105
106
107AliHLTComponentDataType AliHLTMUONRawDataHistoComponent::GetOutputDataType()
108{
109 /// Inherited from AliHLTComponent. Returns kAliHLTHistogramDataTypeID.
110
111 return AliHLTMUONConstants::HistogramDataType();
112}
113
114
115void AliHLTMUONRawDataHistoComponent::GetOutputDataSize(
116 unsigned long& constBase, double& inputMultiplier
117 )
118{
a63da6d6 119 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
a63da6d6 120
95c6f20f 121 constBase = (sizeof(TH1D)+50*sizeof(double))*22 + (sizeof(TH1D)+1024*4*sizeof(double))*20*2;
a63da6d6 122 inputMultiplier = 0;
123}
124
125
126AliHLTComponent* AliHLTMUONRawDataHistoComponent::Spawn()
127{
a63da6d6 128 /// Inherited from AliHLTComponent. Creates a new object instance.
a63da6d6 129
130 return new AliHLTMUONRawDataHistoComponent;
131}
132
133
134bool AliHLTMUONRawDataHistoComponent::IgnoreArgument(const char* arg) const
135{
136 /// Return true if the argument is one of -cdbpath -run or -delaysetup
137 /// to prevent the parent class from parsing these arguments in DoInit.
138
139 if (strcmp(arg, "-cdbpath") == 0 or strcmp(arg, "-run") == 0 or
140 strcmp(arg, "-delaysetup") == 0)
141 {
142 return true;
143 }
144 else
145 {
146 return false;
147 }
148}
149
150
151int AliHLTMUONRawDataHistoComponent::DoInit(int argc, const char** argv)
152{
153 /// Inherited from AliHLTComponent.
154 /// Parses the command line parameters and initialises the component.
155
156 HLTInfo("Initialising dHLT raw data histogrammer component.");
157
158 // Inherit the parents functionality.
159 int result = AliHLTMUONProcessor::DoInit(argc, argv);
160 if (result != 0) return result;
161
162 fLastPublishTime = fCurrentEventTime = -1;
163 fPublishDelay = 1;
164 bool pubDelaySet = false;
7989fd8e 165 fSuppressEmptyHists = false;
166 fProcessDataEventsOnly = false;
167 fTrackerDecoder.TryRecover(false);
168 fTriggerDecoder.TryRecover(false);
a63da6d6 169
170 for (int i = 0; i < argc; i++)
171 {
172 if (ArgumentAlreadyHandled(i, argv[i])) continue;
173
174 if (strcmp(argv[i], "-pubdelay") == 0)
175 {
176 if (pubDelaySet)
177 {
178 HLTWarning("The publishing delay value was already specified."
179 " Will replace previous value given by -pubdelay."
180 );
181 }
182
183 if (argc <= i+1)
184 {
185 HLTError("The value for the publishing delay was not specified.");
186 return -EINVAL;
187 }
188
189 char* cpErr = NULL;
190 double num = strtod(argv[i+1], &cpErr);
191 if (cpErr == NULL or *cpErr != '\0' or num < 0)
192 {
193 HLTError("Cannot convert '%s' to a positive floating point number.",
194 argv[i+1]
195 );
196 return -EINVAL;
197 }
198 fPublishDelay = num;
199 pubDelaySet = true;
200
201 i++;
202 continue;
203 }
7989fd8e 204
205 if (strcmp(argv[i], "-noemptyhists") == 0)
206 {
207 fSuppressEmptyHists = true;
208 continue;
209 }
210
211 if (strcmp(argv[i], "-onlydataevents") == 0)
212 {
213 fProcessDataEventsOnly = true;
214 continue;
215 }
216
217 if (strcmp(argv[i], "-tryrecover") == 0)
218 {
219 fTrackerDecoder.TryRecover(true);
220 fTriggerDecoder.TryRecover(true);
221 continue;
222 }
a63da6d6 223
224 HLTError("Unknown option '%s'.", argv[i]);
225 return -EINVAL;
226 }
227
228 try
229 {
230 char name[256];
231 char title[1024];
232
233 // Do not add to current directory to prevent memory leak warning.
234 // We will not be leaking any memory if we dont add to the directory.
235 TH1::AddDirectory(kFALSE);
236
237 for (int i = 0; i < 22; i++)
238 {
239 AliHLTInt32_t equipId = AliHLTMUONUtils::DDLNumberToEquipId(i);
240 sprintf(name, "rawDataErrors_%d", equipId);
241 sprintf(title, "Distribution of errors found in raw data from DDL %d.", equipId);
a63da6d6 242 fErrorHist[i] = new TH1D(name, title, 40, 0.5, 40.5);
243 fErrorHist[i]->SetXTitle("Error code");
244 fErrorHist[i]->SetYTitle("Number of errors");
245 }
246 for (int i = 0; i < 20; i++)
247 {
248 AliHLTInt32_t equipId = AliHLTMUONUtils::DDLNumberToEquipId(i);
249 sprintf(name, "manuDistrib_%d", equipId);
250 sprintf(title, "Distribution of MANUs containing raw data in DDL %d.", equipId);
251 fManuHist[i] = new TH1D(name, title, 2048, -0.5, 2047.5);
252 fManuHist[i]->SetXTitle("MANU number (as seen in raw data)");
253 fManuHist[i]->SetYTitle("Number of signals read.");
254 sprintf(name, "signalDistrib_%d", equipId);
255 sprintf(title, "Distribution of signals in raw data from DDL %d.", equipId);
256 fSignalHist[i] = new TH1D(name, title, 4096, -0.5, 4095.5);
257 fSignalHist[i]->SetXTitle("Channels");
258 fSignalHist[i]->SetYTitle("dN/dChannel");
259 }
260 }
261 catch (const std::bad_alloc&)
262 {
263 HLTError("Could not allocate more memory for histogram objects.");
264 FreeObjects();
265 return -ENOMEM;
266 }
267
268 return 0;
269}
270
271
272int AliHLTMUONRawDataHistoComponent::DoDeinit()
273{
274 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
275 /// Will delete all histogram objects.
276
277 HLTInfo("Deinitialising dHLT raw data histogrammer component.");
278 fCurrentEventTime = -1;
279 FreeObjects();
280 return 0;
281}
282
283
284int AliHLTMUONRawDataHistoComponent::DoEvent(
285 const AliHLTComponentEventData& /*evtData*/,
286 AliHLTComponentTriggerData& /*trigData*/
287 )
288{
289 /// Inherited from AliHLTProcessor.
290 /// Processes the new event data and generates summary histograms.
291
7989fd8e 292 if (fProcessDataEventsOnly and not IsDataEvent()) return 0; // Only process data events.
293
a63da6d6 294 fCurrentEventTime = TTimeStamp().AsDouble();
295
296 const AliHLTComponentBlockData* block = GetFirstInputBlock(AliHLTMUONConstants::DDLRawDataType());
297 for ( ; block != NULL; block = GetNextInputBlock())
298 {
299 HLTDebug("Handling block with fDataType = '%s', fPtr = %p,"
300 " fSize = %u bytes and fSpecification = 0x%8.8X.",
301 DataType2Text(block->fDataType).c_str(), block->fPtr,
302 block->fSize, block->fSpecification
303 );
304
305 if (AliHLTMUONUtils::IsTrackerDDL(block->fSpecification))
306 {
307 ProcessTrackerDDL(block);
308 }
309 else if (AliHLTMUONUtils::IsTriggerDDL(block->fSpecification))
310 {
311 ProcessTriggerDDL(block);
312 }
313 else
314 {
315 HLTError("Received a raw data block with an invalid specification of"
316 " 0x%8.8X. Expected raw data only from one DDL and not multiple"
317 " DDLs as indicated by the specification.",
318 block->fSpecification
319 );
320 }
321 }
322
7989fd8e 323 // See if 'fPublishDelay' number of seconds has elapsed or this is the first event,
324 // in that case publish the histograms. Do not publish histograms that are empty
325 // if the fSuppressEmptyHists flag is set.
326 if (fLastPublishTime == -1 or fCurrentEventTime - fLastPublishTime >= fPublishDelay)
a63da6d6 327 {
328 for (int i = 0; i < 22; i++)
329 {
7989fd8e 330 if (fSuppressEmptyHists and fErrorHist[i]->GetEntries() == 0) continue;
a63da6d6 331 PushBack(fErrorHist[i],
332 AliHLTMUONConstants::HistogramDataType(),
333 AliHLTMUONUtils::DDLNumberToSpec(i)
334 );
95c6f20f 335 // clear histogram when published.
336 fErrorHist[i]->Reset("M");
a63da6d6 337 }
338 for (int i = 0; i < 20; i++)
339 {
340 AliHLTUInt32_t spec = AliHLTMUONUtils::DDLNumberToSpec(i);
7989fd8e 341 if (not (fSuppressEmptyHists and fManuHist[i]->GetEntries() == 0))
342 {
343 PushBack(fManuHist[i], AliHLTMUONConstants::HistogramDataType(), spec);
95c6f20f 344 fManuHist[i]->Reset("M");
7989fd8e 345 }
346 if (not (fSuppressEmptyHists and fSignalHist[i]->GetEntries() == 0))
347 {
348 PushBack(fSignalHist[i], AliHLTMUONConstants::HistogramDataType(), spec);
95c6f20f 349 fSignalHist[i]->Reset("M");
7989fd8e 350 }
a63da6d6 351 }
352 fLastPublishTime = fCurrentEventTime;
353 }
354
355 return 0;
356}
357
358
359void AliHLTMUONRawDataHistoComponent::ProcessTrackerDDL(const AliHLTComponentBlockData* block)
360{
361 /// Processes a raw data block from the tracker stations.
362
363 AliHLTInt32_t ddl = AliHLTMUONUtils::SpecToDDLNumber(block->fSpecification);
364 assert(0 <= ddl and ddl < 20);
365
7989fd8e 366 fTrackerDecoder.GetHandler().ErrorHist(fErrorHist[ddl]);
367 fTrackerDecoder.GetHandler().ManuHist(fManuHist[ddl]);
368 fTrackerDecoder.GetHandler().SignalHist(fSignalHist[ddl]);
369
a63da6d6 370 if (block->fSize >= sizeof(AliRawDataHeader))
371 {
7989fd8e 372 AliHLTUInt8_t* payload = reinterpret_cast<AliHLTUInt8_t*>(block->fPtr)
373 + sizeof(AliRawDataHeader);
374 UInt_t payloadSize = UInt_t(block->fSize) - sizeof(AliRawDataHeader);
375 fTrackerDecoder.Decode(payload, payloadSize);
a63da6d6 376 }
377 else
378 {
379 HLTError("Received a raw data block that is too short to be valid."
380 " Its size is only %d bytes",
381 block->fSize
382 );
383 fErrorHist[ddl]->Fill(40);
384 }
385}
386
387
388void AliHLTMUONRawDataHistoComponent::ProcessTriggerDDL(const AliHLTComponentBlockData* block)
389{
390 /// Processes a raw data block from the trigger stations.
391
a63da6d6 392 AliHLTInt32_t ddl = AliHLTMUONUtils::SpecToDDLNumber(block->fSpecification);
393 assert(21 <= ddl and ddl < 22);
394
7989fd8e 395 fTriggerDecoder.GetHandler().ErrorHist(fErrorHist[ddl]);
396
a63da6d6 397 if (block->fSize >= sizeof(AliRawDataHeader))
398 {
399 AliRawDataHeader* header = reinterpret_cast<AliRawDataHeader*>(block->fPtr);
7989fd8e 400 AliHLTUInt8_t* payload = reinterpret_cast<AliHLTUInt8_t*>(header+1);
401 UInt_t payloadSize = UInt_t(block->fSize) - sizeof(AliRawDataHeader);
402 bool scalarEvent = ((header->GetL1TriggerMessage() & 0x1) == 0x1);
403 fTriggerDecoder.Decode(payload, payloadSize, scalarEvent);
a63da6d6 404 }
405 else
406 {
407 HLTError("Received a raw data block that is too short to be valid."
408 " Its size is only %d bytes",
409 block->fSize
410 );
411 fErrorHist[ddl]->Fill(40);
412 }
413}
414
415
416void AliHLTMUONRawDataHistoComponent::FreeObjects()
417{
418 /// Deletes all the histogram objects that were allocated.
419
420 for (int i = 0; i < 22; i++)
421 {
422 if (fErrorHist[i] != NULL)
423 {
424 delete fErrorHist[i];
425 fErrorHist[i] = NULL;
426 }
427 }
428 for (int i = 0; i < 20; i++)
429 {
430 if (fManuHist[i] != NULL)
431 {
432 delete fManuHist[i];
433 fManuHist[i] = NULL;
434 }
435 if (fSignalHist[i] != NULL)
436 {
437 delete fSignalHist[i];
438 fSignalHist[i] = NULL;
439 }
440 }
441}
7989fd8e 442