Added a new component (AliHLTTPCHWCFDataReverterComponent) which reads the data,...
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCHWCFDataReverterComponent.cxx
CommitLineData
a912b63b 1/**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * ALICE Experiment at CERN, All rights reserved. *
4 * *
5 * Primary Authors: Kenneth Aamodt <Kenneth.Aamodt@student.uib.no> *
6 * for The ALICE HLT Project. *
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/** @file AliHLTTPCHWCFDataReverterComponent.cxx
18 @author Kenneth Aamodt
19 @date
20 @brief Component for reverting data for the HW clusterfinder
21*/
22
23// see header file for class documentation //
24// or //
25// refer to README to build package //
26// or //
27// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt //
28
29#if __GNUC__>= 3
30using namespace std;
31#endif
32#include "AliHLTTPCHWCFDataReverterComponent.h"
33#include "AliHLTTPCDigitReaderDecoder.h"
34#include "AliHLTTPCTransform.h"
35#include "AliHLTTPCDefinitions.h"
36#include "AliHLTTPCDigitData.h"
37#include "AliHLTTPCMapping.h"
38#include <cstdlib>
39#include <cerrno>
40#include <cassert>
41#include "TString.h"
42#include <sys/time.h>
43#include "AliHLTAltroEncoder.h"
44#include "AliRawDataHeader.h"
45
46/** ROOT macro for the implementation of ROOT specific class methods */
47ClassImp(AliHLTTPCHWCFDataReverterComponent)
48
49 AliHLTTPCHWCFDataReverterComponent::AliHLTTPCHWCFDataReverterComponent()
50 :
51 fDigitReader(NULL),
52 fRowPadVector(),
53 fNumberOfPadsInRow(NULL),
54 fFirstPadHigh(NULL),
55 fNumberOfRows(0),
56 fCurrentPatch(0),
57 fFirstRow(0),
58 fLastRow(0),
59 fNTimeBins(0),
60 fVectorInitialized(kFALSE),
61 fMapping(NULL)
62{
63 // see header file for class documentation
64 // or
65 // refer to README to build package
66 // or
67 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
68}
69
70AliHLTTPCHWCFDataReverterComponent::~AliHLTTPCHWCFDataReverterComponent()
71{
72 // see header file for class documentation
73 if(fVectorInitialized){
74 DeInitializePadArray();
75 }
76 if(fNumberOfPadsInRow){
77 delete [] fNumberOfPadsInRow;
78 fNumberOfPadsInRow=NULL;
79 }
80 if(fFirstPadHigh){
81 delete [] fFirstPadHigh;
82 fFirstPadHigh=NULL;
83 }
84 if(fDigitReader){
85 delete fDigitReader;
86 fDigitReader=NULL;
87 }
88 if(fMapping){
89 delete fMapping;
90 fMapping = NULL;
91 }
92}
93
94// Public functions to implement AliHLTComponent's interface.
95// These functions are required for the registration process
96
97const char* AliHLTTPCHWCFDataReverterComponent::GetComponentID()
98{
99 // see header file for class documentation
100 return "TPCHWCFDataReverter";
101}
102
103void AliHLTTPCHWCFDataReverterComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
104{
105 // see header file for class documentation
106 list.clear();
107 list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
108}
109
110AliHLTComponentDataType AliHLTTPCHWCFDataReverterComponent::GetOutputDataType()
111{
112 // see header file for class documentation
113 return kAliHLTDataTypeDDLRaw;
114}
115
116int AliHLTTPCHWCFDataReverterComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
117{
118 // see header file for class documentation
119 tgtList.clear();
120 tgtList.push_back(kAliHLTDataTypeDDLRaw);
121 return tgtList.size();
122}
123
124void AliHLTTPCHWCFDataReverterComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
125{
126 // see header file for class documentation
127 constBase=0;
128 inputMultiplier=1.0;
129}
130
131AliHLTComponent* AliHLTTPCHWCFDataReverterComponent::Spawn()
132{
133 // see header file for class documentation
134 return new AliHLTTPCHWCFDataReverterComponent();
135}
136
137int AliHLTTPCHWCFDataReverterComponent::DoInit( int argc, const char** argv )
138{
139 // see header file for class documentation
140
141 Int_t i = 0;
142 Char_t* cpErr;
143
144 while ( i < argc ) {
145
146 // -- number of timebins
147 if ( !strcmp( argv[i], "-timebins" )) {
148 fNTimeBins = strtoul( argv[i+1], &cpErr ,0);
149 AliHLTTPCTransform::SetNTimeBins(fNTimeBins);
150 if ( *cpErr ) {
151 HLTError("Cannot convert ntimebins specifier '%s'.", argv[i+1]);
152 return EINVAL;
153 }
154 i+=2;
155 continue;
156 }
157
158 HLTError("HLT::TPCClusterFinder::DoInit", "Unknown Option", "Unknown option '%s'", argv[i] );
159
160 return EINVAL;
161 }
162
163 HLTDebug("using AliHLTTPCDigitReaderDecoder");
164 fDigitReader = new AliHLTTPCDigitReaderDecoder();
165
166 return 0;
167}
168
169int AliHLTTPCHWCFDataReverterComponent::DoDeinit()
170{
171 // see header file for class documentation
172 return 0;
173}
174
175Int_t AliHLTTPCHWCFDataReverterComponent::DeInitializePadArray()
176{
177 // see header file for class documentation
178 if(fVectorInitialized){
179 for(Int_t i=0;i<fNumberOfRows;i++){
180 for(Int_t j=0;j<fNumberOfPadsInRow[i];j++){
181 delete fRowPadVector[i][j];
182 fRowPadVector[i][j]=NULL;
183 }
184 fRowPadVector[i].clear();
185 }
186 fRowPadVector.clear();
187 }
188 return 1;
189}
190
191void AliHLTTPCHWCFDataReverterComponent::InitializePadArray(){
192 // see header file for class documentation
193 if(fCurrentPatch>5){
194 HLTFatal("Patch is not set");
195 return;
196 }
197
198 fFirstRow = AliHLTTPCTransform::GetFirstRow(fCurrentPatch);
199 fLastRow = AliHLTTPCTransform::GetLastRow(fCurrentPatch);
200
201 fNumberOfRows=fLastRow-fFirstRow+1;
202 fNumberOfPadsInRow= new Int_t[fNumberOfRows];
203 fFirstPadHigh= new Int_t[fNumberOfRows];
204
205 memset( fNumberOfPadsInRow, 0, sizeof(Int_t)*(fNumberOfRows));
206 memset( fFirstPadHigh, 0, sizeof(Int_t)*(fNumberOfRows));
207
208 for(Int_t i=0;i<fNumberOfRows;i++){
209 fNumberOfPadsInRow[i]=AliHLTTPCTransform::GetNPads(i+fFirstRow);
210 AliHLTTPCPadVector tmpRow;
211 for(Int_t j=0;j<fNumberOfPadsInRow[i];j++){
212 AliHLTTPCPad *tmpPad = new AliHLTTPCPad();
213 if(fFirstPadHigh[i] != 0){
214 if(fMapping->GetHwAddress(i,j) > 2047){
215 fFirstPadHigh[i]=j;
216 }
217 }
218 tmpPad->SetID(i,j);
219 tmpRow.push_back(tmpPad);
220 }
221 fRowPadVector.push_back(tmpRow);
222 }
223 fVectorInitialized=kTRUE;
224}
225
226
227int AliHLTTPCHWCFDataReverterComponent::DoEvent( const AliHLTComponentEventData& evtData,
228 const AliHLTComponentBlockData* blocks,
229 AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr,
230 AliHLTUInt32_t& size,
231 vector<AliHLTComponentBlockData>& outputBlocks )
232{
233 // see header file for class documentation
234 int iResult=0;
235 if (!fDigitReader) return -ENODEV;
236
237 AliHLTUInt32_t capacity=size;
238 size=0;
239 if (!IsDataEvent()) return 0;
240
241 // == init iter (pointer to datablock)
242 const AliHLTComponentBlockData* iter = NULL;
243 unsigned long ndx;
244
245 //reading the data
246 for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ ){
247
248 iter = blocks+ndx;
249
250 HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
251 evtData.fEventID, evtData.fEventID,
252 DataType2Text( iter->fDataType).c_str(),
253 DataType2Text(kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC).c_str());
254
255 if ( iter->fDataType != (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC)){
256 continue;
257 }
258
259 if (iter->fSize<=sizeof(AliRawDataHeader)) {
260 // forward empty DDLs
261 outputBlocks.push_back(*iter);
262 continue;
263 }
264
265 UInt_t slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
266 UInt_t patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
267
268 if(fDigitReader->InitBlock(iter->fPtr,iter->fSize,patch,slice)<0){
269 HLTWarning("Decoder failed to initialize, event aborted.");
270 continue;
271 }
272
273 fMapping = new AliHLTTPCMapping(patch);
274
275 if(!fVectorInitialized){
276 fCurrentPatch=patch;
277 InitializePadArray();
278 }
279
280 //Here the reading of the data and the zerosuppression takes place
281 while(fDigitReader->NextChannel()){//Pad
282
283 Int_t row=fDigitReader->GetRow();
284 Int_t pad=fDigitReader->GetPad();
285
286 if(row >= fNumberOfRows || row < 0){
287 continue;
288 }
289 else if(pad >= fNumberOfPadsInRow[row] || pad < 0){
290 continue;
291 }
292
293 AliHLTTPCPad *tmpPad = fRowPadVector[row][pad];
294 if (tmpPad){
295 tmpPad->SetDataToDefault();
296 }
297
298 //reading data to pad
299 while(fDigitReader->NextBunch()){
300 const UInt_t *bunchData= fDigitReader->GetSignals();
301 Int_t time=fDigitReader->GetTime();
302 for(Int_t i=0;i<fDigitReader->GetBunchSize();i++){
303 if(bunchData[i]>0){// disregarding 0 data.
304 if(time+i >= 0 && time+i < AliHLTTPCTransform::GetNTimeBins()){
305 if (tmpPad){
306 tmpPad->SetDataSignal(time+i,bunchData[i]);
307 }
308 }
309 }
310 }
311 }
312 }
313
314 if( iter->fSize > sizeof(AliRawDataHeader )){
315
316 AliHLTAltroEncoder *altroEncoder = new AliHLTAltroEncoder;
317 altroEncoder->SetBuffer(outputPtr,capacity); //tests if one overwrite the buffer is done in the encoder
318
319 // set CDH from the beginning of buffer
320 altroEncoder->SetCDH((AliHLTUInt8_t*)iter->fPtr,sizeof(AliRawDataHeader));
321
322 UChar_t *RCUTrailer=NULL;
323 Int_t RCUTrailerSize=fDigitReader->GetRCUTrailerSize();
324 if (RCUTrailerSize<=0 || !fDigitReader->GetRCUTrailerData( RCUTrailer )) {
325 if(RCUTrailer==NULL){
326 HLTWarning("can not find RCU trailer for data block %s 0x%08x: skipping data block",
327 DataType2Text(iter->fDataType).c_str(), iter->fSpecification);
328 continue;
329 }
330 }
331 altroEncoder->SetRCUTrailer(RCUTrailer, RCUTrailerSize);
332
333 for(Int_t row = 0; row< fNumberOfRows;row++){
334 Int_t padHigh=fFirstPadHigh[row];
335
336 Int_t padLowIndex=0;
337 Int_t padHighIndex= padHigh;
338
339 while(padLowIndex < padHigh || padHighIndex < fNumberOfPadsInRow[row]){
340 Int_t currentTime = 0;
341 Int_t bunchSize = 0;
342 //add the data from low side
343 if(padLowIndex < padHigh){
344 AliHLTTPCPad * lowPad= fRowPadVector[row][padLowIndex];
345 while(lowPad->GetNextGoodSignal(currentTime, bunchSize)){
346 for(Int_t i=0;i<bunchSize;i++){
347 if (altroEncoder->AddSignal((AliHLTUInt16_t)(lowPad->GetDataSignal(currentTime+i)),(AliHLTUInt16_t)(currentTime+i))<0) {
348 HLTWarning("can not add channel: slice %d, partition %d, hw address %d, row %d, pad %d, time %d, bunch size %d",
349 slice, patch, fMapping->GetHwAddress(row,padLowIndex), row, padLowIndex, currentTime+i, bunchSize);
350 break;
351 }
352 }
353 }
354 altroEncoder->SetChannel(fMapping->GetHwAddress(row,padLowIndex));
355 }
356 currentTime = 0;
357 bunchSize = 0;
358 //add the data from the high side
359 if(padHighIndex < fNumberOfPadsInRow[row]){
360 AliHLTTPCPad * highPad= fRowPadVector[row][padHighIndex];
361 while(highPad->GetNextGoodSignal(currentTime, bunchSize)){
362 for(Int_t i=0;i<bunchSize;i++){
363 if (altroEncoder->AddSignal((AliHLTUInt16_t)(highPad->GetDataSignal(currentTime+i)),(AliHLTUInt16_t)(currentTime+i))<0) {
364 HLTWarning("can not add channel: slice %d, partition %d, hw address %d, row %d, pad %d, time %d, bunch size %d",
365 slice, patch, fMapping->GetHwAddress(row,padHighIndex), row, padHighIndex, currentTime+i, bunchSize);
366 break;
367 }
368 }
369 }
370 altroEncoder->SetChannel(fMapping->GetHwAddress(row,padHighIndex));
371 }
372 padLowIndex++;
373 padHighIndex++;
374 }
375 }
376
377 altroEncoder->Revert40BitWords(sizeof(AliRawDataHeader),RCUTrailerSize);
378
379 int sizeOfData=altroEncoder->SetLength();
380
381 if (sizeOfData<0) {
382 HLTError("data encoding failed");
383 iResult=sizeOfData;
384 break;
385 }
386 if(sizeOfData>(int)capacity){
387 HLTWarning("Buffer too small too add the altrodata: %d of %d byte(s) already used", sizeOfData, capacity);
388 iResult=-ENOSPC;
389 break;
390 }
391
392 AliHLTComponentBlockData bd;
393 FillBlockData( bd );
394 bd.fOffset = 0;
395 bd.fSize = sizeOfData;
396 bd.fDataType = kAliHLTDataTypeDDLRaw|kAliHLTDataOriginTPC;
397 bd.fSpecification = iter->fSpecification;
398 outputBlocks.push_back( bd );
399
400 size+=sizeOfData;
401 }
402 fDigitReader->Reset();
403 }
404
405 if(iResult < 0) {
406 fDigitReader->Reset();
407 size=0;
408 }
409 HLTDebug("Total size of output is: %d ",size);
410 return iResult;
411}