]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/TPCLib/AliHLTTPCDataCheckerComponent.cxx
correcting the drift time transformation; optional output of cluster id array in...
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCDataCheckerComponent.cxx
CommitLineData
2119b756 1// $Id$
098c0d28 2/**************************************************************************
3 * This file is property of and copyright by the ALICE HLT Project *
4 * ALICE Experiment at CERN, All rights reserved. *
5 * *
6 * Primary Authors: Artur Szostak <artursz@iafrica.com> *
7 * for The ALICE HLT Project. *
8 * *
9 * Permission to use, copy, modify and distribute this software and its *
10 * documentation strictly for non-commercial purposes is hereby granted *
11 * without fee, provided that the above copyright notice appears in all *
12 * copies and that both the copyright notice and this permission notice *
13 * appear in the supporting documentation. The authors make no claims *
14 * about the suitability of this software for any purpose. It is *
15 * provided "as is" without express or implied warranty. *
16 **************************************************************************/
17
18/// @file AliHLTTPCDataCheckerComponent.cxx
19/// @author Artur Szostak <artursz@iafrica.com>
20/// @date 9 Aug 2010
21/// @brief Implementation of the AliHLTTPCDataCheckerComponent class.
22///
23/// The AliHLTTPCDataCheckerComponent is used to perform data sanity and integrity
24/// checks on the TPC data. This component should be used for testing and debugging.
25
26#include "AliHLTTPCDataCheckerComponent.h"
27#include "AliHLTTPCDefinitions.h"
28#include "AliTPCRawStreamV3.h"
29#include "AliRawReaderMemory.h"
30#include <vector>
31#include <cstring>
32#include <cassert>
33
34ClassImp(AliHLTTPCDataCheckerComponent)
35
36
37AliHLTTPCDataCheckerComponent::AliHLTTPCDataCheckerComponent() :
38 fRawStream(NULL),
39 fRawReader(NULL),
40 fForwardBadBlocks(false),
41 fForwardGoodBlocks(false),
42 fIgnoreType(false),
43 fIgnoreOrigin(false),
44 fIgnoreSpec(false),
45 fHandleAllEvents(false)
46{
47 // Default constructor.
48}
49
50
51AliHLTTPCDataCheckerComponent::~AliHLTTPCDataCheckerComponent()
52{
53 // Default destructor.
54
55 if (fRawStream != NULL) delete fRawStream;
56 if (fRawReader != NULL) delete fRawReader;
57}
58
59
60const char* AliHLTTPCDataCheckerComponent::GetComponentID()
61{
62 // Returns the component ID.
63 return "TPCDataChecker";
64}
65
66
67void AliHLTTPCDataCheckerComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
68{
69 // Returns the list of input data types that are handled.
70 list.push_back(kAliHLTAnyDataType | kAliHLTDataOriginTPC);
71}
72
73
74AliHLTComponentDataType AliHLTTPCDataCheckerComponent::GetOutputDataType()
75{
76 // Returns kAliHLTMultipleDataType.
77 return kAliHLTMultipleDataType;
78}
79
80
81int AliHLTTPCDataCheckerComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
82{
83 // Returns the list of output data block types generated.
84 list.push_back(kAliHLTAnyDataType);
85 return int(list.size());
86}
87
88
89void AliHLTTPCDataCheckerComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
90{
91 // Returns the buffer size requirements.
92 constBase = 0;
93 inputMultiplier = 0;
94}
95
96
97AliHLTComponent* AliHLTTPCDataCheckerComponent::Spawn()
98{
99 // Creates a new instance of the component.
100 return new AliHLTTPCDataCheckerComponent;
101}
102
103
104Int_t AliHLTTPCDataCheckerComponent::DoInit(int argc, const char** argv)
105{
106 // Initialises the data checker component from the command line.
107
108 HLTInfo("Starting TPC data checker component.");
109
110 fForwardBadBlocks = true;
111 fForwardGoodBlocks = true;
112 fIgnoreType = false;
113 fIgnoreOrigin = false;
114 fIgnoreSpec = false;
115 fHandleAllEvents = false;
116
117 for (int i = 0; i < argc; ++i)
118 {
119 if (strcmp(argv[i], "-filter") == 0)
120 {
121 if (i+1 < argc)
122 {
123 if (strcmp(argv[i+1], "forwardbad") == 0)
124 {
125 fForwardBadBlocks = true;
126 fForwardGoodBlocks = false;
127 ++i;
128 }
129 else if (strcmp(argv[i+1], "forwardgood") == 0)
130 {
131 fForwardBadBlocks = false;
132 fForwardGoodBlocks = true;
133 ++i;
134 }
135 }
136 fForwardBadBlocks = true;
137 fForwardGoodBlocks = false;
138 continue;
139 }
140
141 if (strcmp(argv[i], "-ignoretype") == 0)
142 {
143 fIgnoreType = true;
144 continue;
145 }
146
147 if (strcmp(argv[i], "-ignoreorigin") == 0)
148 {
149 fIgnoreOrigin = true;
150 continue;
151 }
152
153 if (strcmp(argv[i], "-ignorespec") == 0)
154 {
155 fIgnoreSpec = true;
156 continue;
157 }
158
159 if (strcmp(argv[i], "-handle-all-events") == 0)
160 {
161 fHandleAllEvents = true;
162 continue;
163 }
164
165 HLTError("Unknown option '%s'.", argv[i]);
166 return -EINVAL;
167 } // for loop
168
169 if (fRawReader == NULL)
170 {
171 fRawReader = new AliRawReaderMemory();
172 if (fRawReader == NULL)
173 {
174 HLTError("Could not allocate new AliRawReaderMemory object.");
175 return -ENOMEM;
176 }
177 }
178 if (fRawStream == NULL)
179 {
180 fRawStream = new AliTPCRawStreamV3(fRawReader);
181 if (fRawStream == NULL)
182 {
183 HLTError("Could not allocate new AliTPCRawStreamV3 object.");
184 return -ENOMEM;
185 }
186 fRawStream->SelectRawData("TPC");
187 }
188
189 return 0;
190}
191
192
193Int_t AliHLTTPCDataCheckerComponent::DoDeinit()
194{
195 // Cleans up the data checker component.
196 HLTInfo("Stopping TPC data checker component.");
197 if (fRawReader != NULL)
198 {
199 fRawReader->ClearBuffers();
200 fRawReader->Reset();
201 }
202 if (fRawStream != NULL)
203 {
204 fRawStream->Reset();
205 }
206 return 0;
207}
208
209
210int AliHLTTPCDataCheckerComponent::DoEvent(
211 const AliHLTComponentEventData& evtData,
212 const AliHLTComponentBlockData* blocks,
2119b756 213 AliHLTComponentTriggerData& /*trigData*/,
214 AliHLTUInt8_t* /*outputPtr*/,
098c0d28 215 AliHLTUInt32_t& size,
2119b756 216 AliHLTComponentBlockDataList& /*outputBlocks*/
098c0d28 217 )
218{
219 // Check all the input data blocks.
220
221 if (fRawReader == NULL)
222 {
223 HLTError("The raw reader is not set.");
224 size = 0;
225 return -ENOENT;
226 }
227 if (fRawStream == NULL)
228 {
229 HLTError("The TPC raw stream is not set.");
230 size = 0;
231 return -ENOENT;
232 }
233
234 if (not IsDataEvent() and not fHandleAllEvents)
235 {
236 // Forward all data blocks if we are not supposed to handle this event.
237 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; ++n)
238 {
239 Forward(blocks + n);
240 }
241 size = 0;
242 return 0;
243 }
244
245 AliHLTEventID_t event = evtData.fEventID;
a91fcff2 246 AliHLTComponentDataType anyPrivateType = AliHLTComponentDataTypeInitializer(
247 kAliHLTAnyDataType, kAliHLTDataOriginPrivate
248 );
098c0d28 249
250 // Setup the markers indicating the bad blocks.
251 std::vector<bool> badBlock(evtData.fBlockCnt, false);
252
253 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; ++n)
254 {
a91fcff2 255 // Skip private data blocks from the framework.
256 if (blocks[n].fDataType == anyPrivateType) continue;
257
098c0d28 258 char ddltype[kAliHLTComponentDataTypefIDsize] = kAliHLTDDLRawDataTypeID;
259 if (memcmp(&(blocks[n].fDataType.fID), &ddltype, sizeof(ddltype)) == 0)
260 {
261 badBlock[n] = not CheckRawDataBlock(event, n, blocks + n);
262 }
263 else if (not fIgnoreType)
264 {
265 HLTError("Received raw data block %d in event %lld that we do not know how to handle."
266 " The data block has data type '%s' and specification 0x%8.8X.",
267 n, event, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
268 );
269 }
270 }
271
272 // Forward the different blocks.
273 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; ++n)
274 {
275 if (badBlock[n] and fForwardBadBlocks)
276 {
277 //int result = Forward(blocks + n);
278 int result = Forward(blocks + n);
279 if (result != 0)
280 {
281 size = 0;
282 return result;
283 }
284 }
285 if (not badBlock[n] and fForwardGoodBlocks)
286 {
287 int result = Forward(blocks + n);
288 if (result != 0)
289 {
290 size = 0;
291 return result;
292 }
293 }
294 }
295
296 size = 0;
297 return 0;
298}
299
300
301bool AliHLTTPCDataCheckerComponent::CheckRawDataBlock(
302 AliHLTEventID_t event, AliHLTUInt32_t index,
303 const AliHLTComponentBlockData* block
304 )
305{
306 // Checks TPC raw DDL data blocks.
307
308 assert(fRawReader != NULL);
309 assert(fRawStream != NULL);
310
311 // Check the origin field of the data block.
312 if (not fIgnoreOrigin and
313 memcmp(&(block->fDataType.fOrigin), &kAliHLTDataOriginTPC, sizeof(kAliHLTDataOriginTPC)) != 0
314 )
315 {
316 char origin[kAliHLTComponentDataTypefOriginSize+1];
317 char expectedOrigin[kAliHLTComponentDataTypefOriginSize+1];
318 memcpy(&origin, &(block->fDataType.fOrigin), kAliHLTComponentDataTypefOriginSize);
319 memcpy(&expectedOrigin, &(kAliHLTDataOriginTPC), kAliHLTComponentDataTypefOriginSize);
320 origin[kAliHLTComponentDataTypefOriginSize] = '\0'; // remember the NULL character for the ANSI string.
321 expectedOrigin[kAliHLTComponentDataTypefOriginSize] = '\0';
322 HLTError("Received raw DDL data block %d in event %lld which has an origin '%s', but expected '%s'.",
323 index, event, origin, expectedOrigin
324 );
325 return false;
326 }
327
328 // Decode and check the specification bits.
329 AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(block->fSpecification);
330 AliHLTUInt8_t patch = AliHLTTPCDefinitions::GetMinPatchNr(block->fSpecification);
331 Int_t ddlid = AliHLTTPCDefinitions::SlicePatchToDDLId(slice, patch);
332 if (slice != AliHLTTPCDefinitions::GetMaxSliceNr(block->fSpecification))
333 {
334 HLTError("Received raw DDL data block %d in event %lld which has a"
335 " different minimum and maximum slice number (%d verse %d).",
336 index, event, int(slice), int(AliHLTTPCDefinitions::GetMaxSliceNr(block->fSpecification))
337 );
338 return false;
339 }
340 if (patch != AliHLTTPCDefinitions::GetMaxPatchNr(block->fSpecification))
341 {
342 HLTError("Received raw DDL data block %d in event %lld which has a"
343 " different minimum and maximum patch number (%d verse %d).",
344 index, event, int(patch), int(AliHLTTPCDefinitions::GetMaxPatchNr(block->fSpecification))
345 );
346 return false;
347 }
348 if (ddlid == -1)
349 {
350 HLTError("Received raw DDL data block %d in event %lld which has an"
351 " invalid specification 0x%8.8X. Cannot decode the DDL ID number.",
352 index, event, block->fSpecification
353 );
354 return false;
355 }
356
357 // Now try decode the DDL data. Do it in a try catch block in case
358 // the decoder segfaults. We want to know about this and log it.
359 bool result = false;
360 try
361 {
362 fRawReader->ClearBuffers();
363 fRawReader->Reset();
364 fRawStream->Reset();
365 fRawReader->AddBuffer(reinterpret_cast<UChar_t*>(block->fPtr), block->fSize, ddlid);
366 if (fRawStream->NextDDL())
367 {
368 while (fRawStream->NextChannel())
369 {
370 while (fRawStream->NextBunch())
371 {
098c0d28 372 Int_t bunchLength = fRawStream->GetBunchLength();
373 const UShort_t* bunchData = fRawStream->GetSignals();
098c0d28 374 for (Int_t i = 0; i < bunchLength; ++i)
375 {
a91fcff2 376 // Check that the 10 bit signal is within range.
377 if (bunchData[i] >= 1024)
6a644371 378 {
379 HLTWarning("Data signal %d in sector %d row %d pad %d is a strange value %d,"
380 " for data block %d (DDL ID = %d) in event %lld.",
381 i, fRawStream->GetSector(), fRawStream->GetRow(),
382 fRawStream->GetPad(), bunchData[i], index, ddlid, event
383 );
384 }
098c0d28 385 }
386 }
387 }
388 result = true;
389 }
390 else
391 {
392 HLTError("Cannot decode the raw DDL data (DDL ID = %d) from"
393 " data block %d in event %lld.",
394 ddlid, index, event
395 );
396 }
397 }
398 catch (...)
399 {
a91fcff2 400 HLTFatal("Caught an exception when processing raw DDL data (DDL ID = %d)"
098c0d28 401 " from data block %d in event %lld.",
402 ddlid, index, event
403 );
a91fcff2 404 throw;
098c0d28 405 }
406 return result;
407}
408