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: Kenneth Aamodt <Kenneth.Aamodt@student.uib.no> *
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 AliHLTTPCHWCFDataReverterComponent.cxx
19 /// @author Kenneth Aamodt
21 /// @brief Component for reverting data for the HW clusterfinder
24 // see header file for class documentation //
26 // refer to README to build package //
28 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt //
30 #include "AliHLTTPCHWCFDataReverterComponent.h"
31 #include "AliHLTTPCDigitReader32Bit.h"
32 #include "AliHLTTPCTransform.h"
33 #include "AliHLTTPCDefinitions.h"
34 #include "AliHLTTPCDigitData.h"
35 #include "AliHLTTPCMapping.h"
41 #include "AliHLTAltroEncoder.h"
42 #include "AliRawDataHeader.h"
46 /** ROOT macro for the implementation of ROOT specific class methods */
47 ClassImp(AliHLTTPCHWCFDataReverterComponent)
49 AliHLTTPCHWCFDataReverterComponent::AliHLTTPCHWCFDataReverterComponent()
53 fNumberOfPadsInRow(NULL),
60 fVectorInitialized(kFALSE),
64 // see header file for class documentation
66 // refer to README to build package
68 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
71 AliHLTTPCHWCFDataReverterComponent::~AliHLTTPCHWCFDataReverterComponent()
73 // see header file for class documentation
74 if(fVectorInitialized){
75 DeInitializePadArray();
77 if(fNumberOfPadsInRow){
78 delete [] fNumberOfPadsInRow;
79 fNumberOfPadsInRow=NULL;
82 delete [] fFirstPadHigh;
95 // Public functions to implement AliHLTComponent's interface.
96 // These functions are required for the registration process
98 const char* AliHLTTPCHWCFDataReverterComponent::GetComponentID()
100 // see header file for class documentation
101 return "TPCHWCFDataReverter";
104 void AliHLTTPCHWCFDataReverterComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
106 // see header file for class documentation
108 list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
111 AliHLTComponentDataType AliHLTTPCHWCFDataReverterComponent::GetOutputDataType()
113 // see header file for class documentation
114 return kAliHLTDataTypeDDLRaw;
117 int AliHLTTPCHWCFDataReverterComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
119 // see header file for class documentation
121 tgtList.push_back(kAliHLTDataTypeDDLRaw);
122 return tgtList.size();
125 void AliHLTTPCHWCFDataReverterComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
127 // see header file for class documentation
132 AliHLTComponent* AliHLTTPCHWCFDataReverterComponent::Spawn()
134 // see header file for class documentation
135 return new AliHLTTPCHWCFDataReverterComponent();
138 int AliHLTTPCHWCFDataReverterComponent::DoInit( int argc, const char** argv )
140 // see header file for class documentation
147 // -- number of timebins
148 if ( !strcmp( argv[i], "-timebins" )) {
149 fNTimeBins = strtoul( argv[i+1], &cpErr ,0);
150 AliHLTTPCTransform::SetNTimeBins(fNTimeBins);
152 HLTError("Cannot convert ntimebins specifier '%s'.", argv[i+1]);
158 // -- number of timebins
159 if ( !strcmp( argv[i], "-interleave-off" )) {
160 fInterleave = kFALSE;
165 HLTError("HLT::TPCClusterFinder::DoInit", "Unknown Option", "Unknown option '%s'", argv[i] );
170 fDigitReader = new AliHLTTPCDigitReader32Bit();
175 int AliHLTTPCHWCFDataReverterComponent::DoDeinit()
177 // see header file for class documentation
181 Int_t AliHLTTPCHWCFDataReverterComponent::DeInitializePadArray()
183 // see header file for class documentation
184 if(fVectorInitialized){
185 for(Int_t i=0;i<fNumberOfRows;i++){
186 for(Int_t j=0;j<fNumberOfPadsInRow[i];j++){
187 delete fRowPadVector[i][j];
188 fRowPadVector[i][j]=NULL;
190 fRowPadVector[i].clear();
192 fRowPadVector.clear();
197 void AliHLTTPCHWCFDataReverterComponent::InitializePadArray(){
198 // see header file for class documentation
200 HLTFatal("Patch is not set");
204 fFirstRow = AliHLTTPCTransform::GetFirstRow(fCurrentPatch);
205 fLastRow = AliHLTTPCTransform::GetLastRow(fCurrentPatch);
207 fNumberOfRows=fLastRow-fFirstRow+1;
208 fNumberOfPadsInRow= new Int_t[fNumberOfRows];
209 fFirstPadHigh= new Int_t[fNumberOfRows];
211 memset( fNumberOfPadsInRow, 0, sizeof(Int_t)*(fNumberOfRows));
212 memset( fFirstPadHigh, 0, sizeof(Int_t)*(fNumberOfRows));
214 for(Int_t i=0;i<fNumberOfRows;i++){
215 fNumberOfPadsInRow[i]=AliHLTTPCTransform::GetNPads(i+fFirstRow);
216 AliHLTTPCPadVector tmpRow;
217 for(Int_t j=0;j<fNumberOfPadsInRow[i];j++){
218 AliHLTTPCPad *tmpPad = new AliHLTTPCPad();
219 if(fFirstPadHigh[i] == 0){
220 if(fMapping->GetHwAddress(i,j) > 2047){
225 tmpPad->SetDataToDefault();
226 tmpRow.push_back(tmpPad);
228 fRowPadVector.push_back(tmpRow);
230 fVectorInitialized=kTRUE;
234 int AliHLTTPCHWCFDataReverterComponent::DoEvent( const AliHLTComponentEventData& evtData,
235 const AliHLTComponentBlockData* blocks,
236 AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr,
237 AliHLTUInt32_t& size,
238 vector<AliHLTComponentBlockData>& outputBlocks )
240 // see header file for class documentation
242 if (!fDigitReader) return -ENODEV;
244 AliHLTUInt32_t capacity=size;
246 if (!IsDataEvent()) return 0;
248 // == init iter (pointer to datablock)
249 const AliHLTComponentBlockData* iter = NULL;
253 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ ){
257 HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
258 evtData.fEventID, evtData.fEventID,
259 DataType2Text( iter->fDataType).c_str(),
260 DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
262 if ( iter->fDataType != (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC)){
266 if (iter->fSize<=sizeof(AliRawDataHeader)) {
267 // forward empty DDLs
268 outputBlocks.push_back(*iter);
272 UInt_t slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
273 UInt_t patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
275 if(fDigitReader->InitBlock(iter->fPtr,iter->fSize,patch,slice)<0){
276 HLTWarning("Decoder failed to initialize, event aborted.");
280 fMapping = new AliHLTTPCMapping(patch);
282 if(!fVectorInitialized){
284 InitializePadArray();
287 //Here the reading of the data and the zerosuppression takes place
288 while(fDigitReader->NextChannel()){//Pad
290 Int_t row=fDigitReader->GetRow();
291 Int_t pad=fDigitReader->GetPad();
293 if(row >= fNumberOfRows || row < 0){
296 else if(pad >= fNumberOfPadsInRow[row] || pad < 0){
300 AliHLTTPCPad *tmpPad = fRowPadVector[row][pad];
302 tmpPad->SetDataToDefault();
305 //reading data to pad
306 while(fDigitReader->NextBunch()){
307 const UInt_t *bunchData= fDigitReader->GetSignals();
308 Int_t time=fDigitReader->GetTime();
309 for(Int_t i=0;i<fDigitReader->GetBunchSize();i++){
310 if(bunchData[i]>0){// disregarding 0 data.
311 if(time+i >= 0 && time+i < AliHLTTPCTransform::GetNTimeBins()){
313 tmpPad->SetDataSignal(time+i,bunchData[i]);
321 if( iter->fSize > sizeof(AliRawDataHeader )){
323 AliHLTAltroEncoder *altroEncoder = new AliHLTAltroEncoder;
324 altroEncoder->SetUse32BitFormat(kTRUE);
326 if (patch>1) ddlno+=72+4*slice+(patch-2);
327 else ddlno+=2*slice+patch;
328 altroEncoder->SetDDLid(ddlno);
329 altroEncoder->SetSlice(slice);
330 altroEncoder->SetPartition(patch);
332 altroEncoder->SetBuffer(outputPtr,capacity); //tests if one overwrite the buffer is done in the encoder
334 // set CDH from the beginning of buffer
335 altroEncoder->SetCDH((AliHLTUInt8_t*)iter->fPtr,sizeof(AliRawDataHeader));
337 UChar_t *RCUTrailer=NULL;
338 Int_t RCUTrailerSize=fDigitReader->GetRCUTrailerSize();
339 if (RCUTrailerSize<=0 || !fDigitReader->GetRCUTrailerData( RCUTrailer )) {
340 if(RCUTrailer==NULL){
341 HLTWarning("can not find RCU trailer for data block %s 0x%08x: skipping data block",
342 DataType2Text(iter->fDataType).c_str(), iter->fSpecification);
346 altroEncoder->SetRCUTrailer(RCUTrailer, RCUTrailerSize);
348 for(Int_t row = 0; row< fNumberOfRows;row++){
350 if(fInterleave == kFALSE){
351 Int_t currentTime = 0;
353 for(Int_t ipad=0;ipad<fNumberOfPadsInRow[row];ipad++){
354 AliHLTTPCPad * pad = fRowPadVector[row][ipad];
355 if(pad->GetNAddedSignals() > 0){
356 while(pad->GetNextGoodSignal(currentTime, bunchSize)){
357 for(Int_t i=bunchSize-1;i>=0;i--){
358 if (altroEncoder->AddSignal((AliHLTUInt16_t)(pad->GetDataSignal(currentTime+i)),(AliHLTUInt16_t)(currentTime+i))<0) {
359 HLTWarning("can not add channel: slice %d, partition %d, hw address %d, row %d, pad %d, time %d, bunch size %d Charge %d",
360 slice, patch, fMapping->GetHwAddress(row,ipad), row, ipad, currentTime+i, bunchSize,pad->GetDataSignal(currentTime+i));
365 altroEncoder->SetChannel(fMapping->GetHwAddress(row,ipad));
372 Int_t padHigh=fFirstPadHigh[row];
375 Int_t padHighIndex= padHigh;
377 while(padLowIndex < padHigh || padHighIndex < fNumberOfPadsInRow[row]){
378 Int_t currentTime = 0;
380 //add the data from low side
381 if(padLowIndex < padHigh){
382 AliHLTTPCPad * lowPad= fRowPadVector[row][padLowIndex];
383 if(lowPad->GetNAddedSignals()>0){
384 while(lowPad->GetNextGoodSignal(currentTime, bunchSize)){
385 for(Int_t i=bunchSize-1;i>=0;i--){
386 if (altroEncoder->AddSignal((AliHLTUInt16_t)(lowPad->GetDataSignal(currentTime+i)),(AliHLTUInt16_t)(currentTime+i))<0) {
387 HLTWarning("can not add channel: slice %d, partition %d, hw address %d, row %d, pad %d, time %d, bunch size %d",
388 slice, patch, fMapping->GetHwAddress(row,padLowIndex), row, padLowIndex, currentTime+i, bunchSize);
393 altroEncoder->SetChannel(fMapping->GetHwAddress(row,padLowIndex));
398 //add the data from the high side
399 if(padHighIndex < fNumberOfPadsInRow[row]){
400 AliHLTTPCPad * highPad= fRowPadVector[row][padHighIndex];
401 if(highPad->GetNAddedSignals()>0){
402 while(highPad->GetNextGoodSignal(currentTime, bunchSize)){
403 for(Int_t i=bunchSize-1;i>=0;i--){
404 if (altroEncoder->AddSignal((AliHLTUInt16_t)(highPad->GetDataSignal(currentTime+i)),(AliHLTUInt16_t)(currentTime+i))<0) {
405 HLTWarning("can not add channel: slice %d, partition %d, hw address %d, row %d, pad %d, time %d, bunch size %d",
406 slice, patch, fMapping->GetHwAddress(row,padHighIndex), row, padHighIndex, currentTime+i, bunchSize);
411 altroEncoder->SetChannel(fMapping->GetHwAddress(row,padHighIndex));
420 int sizeOfData=altroEncoder->SetLength();
424 HLTError("data encoding failed");
428 if(sizeOfData>(int)capacity){
429 HLTWarning("Buffer too small too add the altrodata: %d of %d byte(s) already used", sizeOfData, capacity);
434 AliHLTComponentBlockData bd;
437 bd.fSize = sizeOfData;
438 bd.fDataType = kAliHLTDataTypeDDLRaw|kAliHLTDataOriginTPC;
439 bd.fSpecification = iter->fSpecification;
440 outputBlocks.push_back( bd );
444 fDigitReader->Reset();
448 fDigitReader->Reset();
451 HLTDebug("Total size of output is: %d ",size);