]>
Commit | Line | Data |
---|---|---|
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. | |
43 | typedef const AliHLTMUONMansoTrackStruct* AliHLTMUONMansoTrackStructP; | |
44 | ||
45 | ||
46 | ClassImp(AliHLTMUONRawDataHistoComponent); | |
47 | ||
48 | ||
49 | AliHLTMUONRawDataHistoComponent::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 | ||
83 | AliHLTMUONRawDataHistoComponent::~AliHLTMUONRawDataHistoComponent() | |
84 | { | |
85 | /// Default destructor deletes all histogram objects if they are still allocated. | |
86 | ||
87 | } | |
88 | ||
89 | ||
90 | const char* AliHLTMUONRawDataHistoComponent::GetComponentID() | |
91 | { | |
a63da6d6 | 92 | /// Inherited from AliHLTComponent. Returns the component ID. |
a63da6d6 | 93 | |
94 | return AliHLTMUONConstants::RawDataHistogrammerId(); | |
95 | } | |
96 | ||
97 | ||
98 | void 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 | ||
107 | AliHLTComponentDataType AliHLTMUONRawDataHistoComponent::GetOutputDataType() | |
108 | { | |
109 | /// Inherited from AliHLTComponent. Returns kAliHLTHistogramDataTypeID. | |
110 | ||
111 | return AliHLTMUONConstants::HistogramDataType(); | |
112 | } | |
113 | ||
114 | ||
115 | void 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 | ||
126 | AliHLTComponent* AliHLTMUONRawDataHistoComponent::Spawn() | |
127 | { | |
a63da6d6 | 128 | /// Inherited from AliHLTComponent. Creates a new object instance. |
a63da6d6 | 129 | |
130 | return new AliHLTMUONRawDataHistoComponent; | |
131 | } | |
132 | ||
133 | ||
134 | bool 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 | ||
151 | int 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 | ||
272 | int 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 | ||
284 | int 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 | ||
359 | void 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 | ||
388 | void 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 | ||
416 | void 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 |