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;
247 // Setup the markers indicating the bad blocks.
248 std::vector<bool> badBlock(evtData.fBlockCnt, false);
250 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; ++n)
252 char ddltype[kAliHLTComponentDataTypefIDsize] = kAliHLTDDLRawDataTypeID;
253 if (memcmp(&(blocks[n].fDataType.fID), &ddltype, sizeof(ddltype)) == 0)
255 badBlock[n] = not CheckRawDataBlock(event, n, blocks + n);
257 else if (not fIgnoreType)
259 HLTError("Received raw data block %d in event %lld that we do not know how to handle."
260 " The data block has data type '%s' and specification 0x%8.8X.",
261 n, event, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
266 // Forward the different blocks.
267 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; ++n)
269 if (badBlock[n] and fForwardBadBlocks)
271 //int result = Forward(blocks + n);
272 int result = Forward(blocks + n);
279 if (not badBlock[n] and fForwardGoodBlocks)
281 int result = Forward(blocks + n);
295 bool AliHLTTPCDataCheckerComponent::CheckRawDataBlock(
296 AliHLTEventID_t event, AliHLTUInt32_t index,
297 const AliHLTComponentBlockData* block
300 // Checks TPC raw DDL data blocks.
302 assert(fRawReader != NULL);
303 assert(fRawStream != NULL);
305 // Check the origin field of the data block.
306 if (not fIgnoreOrigin and
307 memcmp(&(block->fDataType.fOrigin), &kAliHLTDataOriginTPC, sizeof(kAliHLTDataOriginTPC)) != 0
310 char origin[kAliHLTComponentDataTypefOriginSize+1];
311 char expectedOrigin[kAliHLTComponentDataTypefOriginSize+1];
312 memcpy(&origin, &(block->fDataType.fOrigin), kAliHLTComponentDataTypefOriginSize);
313 memcpy(&expectedOrigin, &(kAliHLTDataOriginTPC), kAliHLTComponentDataTypefOriginSize);
314 origin[kAliHLTComponentDataTypefOriginSize] = '\0'; // remember the NULL character for the ANSI string.
315 expectedOrigin[kAliHLTComponentDataTypefOriginSize] = '\0';
316 HLTError("Received raw DDL data block %d in event %lld which has an origin '%s', but expected '%s'.",
317 index, event, origin, expectedOrigin
322 // Decode and check the specification bits.
323 AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(block->fSpecification);
324 AliHLTUInt8_t patch = AliHLTTPCDefinitions::GetMinPatchNr(block->fSpecification);
325 Int_t ddlid = AliHLTTPCDefinitions::SlicePatchToDDLId(slice, patch);
326 if (slice != AliHLTTPCDefinitions::GetMaxSliceNr(block->fSpecification))
328 HLTError("Received raw DDL data block %d in event %lld which has a"
329 " different minimum and maximum slice number (%d verse %d).",
330 index, event, int(slice), int(AliHLTTPCDefinitions::GetMaxSliceNr(block->fSpecification))
334 if (patch != AliHLTTPCDefinitions::GetMaxPatchNr(block->fSpecification))
336 HLTError("Received raw DDL data block %d in event %lld which has a"
337 " different minimum and maximum patch number (%d verse %d).",
338 index, event, int(patch), int(AliHLTTPCDefinitions::GetMaxPatchNr(block->fSpecification))
344 HLTError("Received raw DDL data block %d in event %lld which has an"
345 " invalid specification 0x%8.8X. Cannot decode the DDL ID number.",
346 index, event, block->fSpecification
351 // Now try decode the DDL data. Do it in a try catch block in case
352 // the decoder segfaults. We want to know about this and log it.
356 fRawReader->ClearBuffers();
359 fRawReader->AddBuffer(reinterpret_cast<UChar_t*>(block->fPtr), block->fSize, ddlid);
360 if (fRawStream->NextDDL())
362 while (fRawStream->NextChannel())
364 while (fRawStream->NextBunch())
366 UInt_t startTimeBin = fRawStream->GetStartTimeBin();
367 UInt_t endTimeBin = fRawStream->GetEndTimeBin();
368 Int_t bunchLength = fRawStream->GetBunchLength();
369 const UShort_t* bunchData = fRawStream->GetSignals();
370 cout << "startTimeBin = " << startTimeBin << endl;
371 cout << "endTimeBin = " << endTimeBin << endl;
372 cout << "bunchLength = " << bunchLength << endl;
373 for (Int_t i = 0; i < bunchLength; ++i)
375 cout << "bunchData[" << i << "] = " << bunchData[i] << endl;
383 HLTError("Cannot decode the raw DDL data (DDL ID = %d) from"
384 " data block %d in event %lld.",
391 HLTError("Caught an exception when processing raw DDL data (DDL ID = %d)"
392 " from data block %d in event %lld.",