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