2 /**************************************************************************
3 * This file is property of and copyright by the ALICE HLT Project *
4 * ALICE Experiment at CERN, All rights reserved. *
6 * Primary Authors: Artur Szostak <artursz@iafrica.com> *
7 * for The ALICE HLT Project. *
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 **************************************************************************/
18 /// @file AliHLTTPCDataCheckerComponent.cxx
19 /// @author Artur Szostak <artursz@iafrica.com>
21 /// @brief Implementation of the AliHLTTPCDataCheckerComponent class.
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.
26 #include "AliHLTTPCDataCheckerComponent.h"
27 #include "AliHLTTPCDefinitions.h"
28 #include "AliTPCRawStreamV3.h"
29 #include "AliRawReaderMemory.h"
34 ClassImp(AliHLTTPCDataCheckerComponent)
37 AliHLTTPCDataCheckerComponent::AliHLTTPCDataCheckerComponent() :
40 fForwardBadBlocks(false),
41 fForwardGoodBlocks(false),
45 fHandleAllEvents(false)
47 // Default constructor.
51 AliHLTTPCDataCheckerComponent::~AliHLTTPCDataCheckerComponent()
53 // Default destructor.
55 if (fRawStream != NULL) delete fRawStream;
56 if (fRawReader != NULL) delete fRawReader;
60 const char* AliHLTTPCDataCheckerComponent::GetComponentID()
62 // Returns the component ID.
63 return "TPCDataChecker";
67 void AliHLTTPCDataCheckerComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
69 // Returns the list of input data types that are handled.
70 list.push_back(kAliHLTAnyDataType | kAliHLTDataOriginTPC);
74 AliHLTComponentDataType AliHLTTPCDataCheckerComponent::GetOutputDataType()
76 // Returns kAliHLTMultipleDataType.
77 return kAliHLTMultipleDataType;
81 int AliHLTTPCDataCheckerComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
83 // Returns the list of output data block types generated.
84 list.push_back(kAliHLTAnyDataType);
85 return int(list.size());
89 void AliHLTTPCDataCheckerComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
91 // Returns the buffer size requirements.
97 AliHLTComponent* AliHLTTPCDataCheckerComponent::Spawn()
99 // Creates a new instance of the component.
100 return new AliHLTTPCDataCheckerComponent;
104 Int_t AliHLTTPCDataCheckerComponent::DoInit(int argc, const char** argv)
106 // Initialises the data checker component from the command line.
108 HLTInfo("Starting TPC data checker component.");
110 fForwardBadBlocks = true;
111 fForwardGoodBlocks = true;
113 fIgnoreOrigin = false;
115 fHandleAllEvents = false;
117 for (int i = 0; i < argc; ++i)
119 if (strcmp(argv[i], "-filter") == 0)
123 if (strcmp(argv[i+1], "forwardbad") == 0)
125 fForwardBadBlocks = true;
126 fForwardGoodBlocks = false;
129 else if (strcmp(argv[i+1], "forwardgood") == 0)
131 fForwardBadBlocks = false;
132 fForwardGoodBlocks = true;
136 fForwardBadBlocks = true;
137 fForwardGoodBlocks = false;
141 if (strcmp(argv[i], "-ignoretype") == 0)
147 if (strcmp(argv[i], "-ignoreorigin") == 0)
149 fIgnoreOrigin = true;
153 if (strcmp(argv[i], "-ignorespec") == 0)
159 if (strcmp(argv[i], "-handle-all-events") == 0)
161 fHandleAllEvents = true;
165 HLTError("Unknown option '%s'.", argv[i]);
169 if (fRawReader == NULL)
171 fRawReader = new AliRawReaderMemory();
172 if (fRawReader == NULL)
174 HLTError("Could not allocate new AliRawReaderMemory object.");
178 if (fRawStream == NULL)
180 fRawStream = new AliTPCRawStreamV3(fRawReader);
181 if (fRawStream == NULL)
183 HLTError("Could not allocate new AliTPCRawStreamV3 object.");
186 fRawStream->SelectRawData("TPC");
193 Int_t AliHLTTPCDataCheckerComponent::DoDeinit()
195 // Cleans up the data checker component.
196 HLTInfo("Stopping TPC data checker component.");
197 if (fRawReader != NULL)
199 fRawReader->ClearBuffers();
202 if (fRawStream != NULL)
210 int AliHLTTPCDataCheckerComponent::DoEvent(
211 const AliHLTComponentEventData& evtData,
212 const AliHLTComponentBlockData* blocks,
213 AliHLTComponentTriggerData& /*trigData*/,
214 AliHLTUInt8_t* /*outputPtr*/,
215 AliHLTUInt32_t& size,
216 AliHLTComponentBlockDataList& /*outputBlocks*/
219 // Check all the input data blocks.
221 if (fRawReader == NULL)
223 HLTError("The raw reader is not set.");
227 if (fRawStream == NULL)
229 HLTError("The TPC raw stream is not set.");
234 if (not IsDataEvent() and not fHandleAllEvents)
236 // Forward all data blocks if we are not supposed to handle this event.
237 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; ++n)
245 AliHLTEventID_t event = evtData.fEventID;
246 AliHLTComponentDataType anyPrivateType = AliHLTComponentDataTypeInitializer(
247 kAliHLTAnyDataType, kAliHLTDataOriginPrivate
250 // Setup the markers indicating the bad blocks.
251 std::vector<bool> badBlock(evtData.fBlockCnt, false);
253 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; ++n)
255 // Skip private data blocks from the framework.
256 if (blocks[n].fDataType == anyPrivateType) continue;
258 char ddltype[kAliHLTComponentDataTypefIDsize] = kAliHLTDDLRawDataTypeID;
259 if (memcmp(&(blocks[n].fDataType.fID), &ddltype, sizeof(ddltype)) == 0)
261 badBlock[n] = not CheckRawDataBlock(event, n, blocks + n);
263 else if (not fIgnoreType)
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
272 // Forward the different blocks.
273 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; ++n)
275 if (badBlock[n] and fForwardBadBlocks)
277 //int result = Forward(blocks + n);
278 int result = Forward(blocks + n);
285 if (not badBlock[n] and fForwardGoodBlocks)
287 int result = Forward(blocks + n);
301 bool AliHLTTPCDataCheckerComponent::CheckRawDataBlock(
302 AliHLTEventID_t event, AliHLTUInt32_t index,
303 const AliHLTComponentBlockData* block
306 // Checks TPC raw DDL data blocks.
308 assert(fRawReader != NULL);
309 assert(fRawStream != NULL);
311 // Check the origin field of the data block.
312 if (not fIgnoreOrigin and
313 memcmp(&(block->fDataType.fOrigin), &kAliHLTDataOriginTPC, sizeof(kAliHLTDataOriginTPC)) != 0
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
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))
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))
340 if (patch != AliHLTTPCDefinitions::GetMaxPatchNr(block->fSpecification))
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))
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
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.
362 fRawReader->ClearBuffers();
365 fRawReader->AddBuffer(reinterpret_cast<UChar_t*>(block->fPtr), block->fSize, ddlid);
366 if (fRawStream->NextDDL())
368 while (fRawStream->NextChannel())
370 while (fRawStream->NextBunch())
372 Int_t bunchLength = fRawStream->GetBunchLength();
373 const UShort_t* bunchData = fRawStream->GetSignals();
374 for (Int_t i = 0; i < bunchLength; ++i)
376 // Check that the 10 bit signal is within range.
377 if (bunchData[i] >= 1024)
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
392 HLTError("Cannot decode the raw DDL data (DDL ID = %d) from"
393 " data block %d in event %lld.",
400 HLTFatal("Caught an exception when processing raw DDL data (DDL ID = %d)"
401 " from data block %d in event %lld.",