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