Line data Source code
1 : // $Id$
2 :
3 : //*************************************************************************
4 : // This file is property of and copyright by the ALICE HLT Project *
5 : // ALICE Experiment at CERN, All rights reserved. *
6 : // *
7 : // Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 : // Timm Steinbeck <timm@kip.uni-heidelberg.de> *
9 : // Jochen Thaeder <thaeder@kip.uni-heidelberg.de> *
10 : // for The ALICE HLT Project. *
11 : // *
12 : // Permission to use, copy, modify and distribute this software and its *
13 : // documentation strictly for non-commercial purposes is hereby granted *
14 : // without fee, provided that the above copyright notice appears in all *
15 : // copies and that both the copyright notice and this permission notice *
16 : // appear in the supporting documentation. The authors make no claims *
17 : // about the suitability of this software for any purpose. It is *
18 : // provided "as is" without express or implied warranty. *
19 : //*************************************************************************/
20 :
21 : /** @file AliHLTTPCDigitReaderUnpacked.cxx
22 : @author Timm Steinbeck, Jochen Thaeder, Matthias Richter
23 : @date
24 : @brief A digit reader implementation for unpacked TPC data.
25 : */
26 :
27 : #include <cassert>
28 : #include "AliHLTTPCDigitReaderUnpacked.h"
29 : #include "AliHLTTPCDigitData.h"
30 : #include "AliHLTTPCGeometry.h"
31 : #include "AliHLTStdIncludes.h"
32 : #include "AliHLTTPCMapping.h"
33 :
34 : using namespace std;
35 :
36 6 : ClassImp(AliHLTTPCDigitReaderUnpacked)
37 :
38 0 : AliHLTTPCDigitReaderUnpacked::AliHLTTPCDigitReaderUnpacked()
39 : :
40 0 : fDigitRowData(NULL),
41 0 : fActRowData(NULL),
42 0 : fData(NULL),
43 0 : fPtr(NULL),
44 0 : fSize(0),
45 0 : fBin(0),
46 0 : fRow(0),
47 0 : fFirstRow(0),
48 0 : fLastRow(0),
49 0 : fUnsorted(kFALSE),
50 0 : fDataBunch(),
51 0 : fTrackIDs(),
52 0 : fTrackIDCounts(),
53 0 : fEndOfDataReached(kFALSE),
54 0 : fEndOfChannelReached(kFALSE),
55 0 : fPrevTime(0),
56 0 : fEndTimeBinOfBunch(0),
57 0 : fPrevSignal(0),
58 0 : fPrevPad(-1),
59 0 : fPrevRow(-1),
60 0 : fNextChannelIsAlreadyConfirmed(kFALSE),
61 0 : fMapping(NULL),
62 0 : fDigitsVector(),
63 0 : fBinRowPositionSorted(),
64 0 : fPatch(0)
65 0 : {
66 : // see header file for class documentation
67 : // or
68 : // refer to README to build package
69 : // or
70 : // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
71 0 : }
72 :
73 0 : AliHLTTPCDigitReaderUnpacked::~AliHLTTPCDigitReaderUnpacked(){
74 : // see header file for class documentation
75 0 : if(fMapping){
76 0 : delete fMapping;
77 : }
78 0 : fMapping=NULL;
79 0 : }
80 :
81 : int AliHLTTPCDigitReaderUnpacked::InitBlock(void* ptr,unsigned long size, Int_t patch, Int_t slice){
82 : // see header file for class documentation
83 : int iResult=0;
84 : AliHLTTPCUnpackedRawData *tmpptr=NULL;
85 0 : fPtr = ptr;
86 0 : fSize = size;
87 :
88 0 : fPatch=patch;
89 0 : fEndOfDataReached=kFALSE;
90 0 : fEndOfChannelReached=kFALSE;
91 0 : fPrevTime=0;
92 0 : fEndTimeBinOfBunch=0;
93 0 : fPrevSignal=0;
94 0 : fPrevPad=-1;
95 0 : fPrevRow=-1;
96 0 : fNextChannelIsAlreadyConfirmed=kFALSE;
97 0 : fDigitsVector.clear();
98 :
99 0 : tmpptr = reinterpret_cast<AliHLTTPCUnpackedRawData*>(fPtr);
100 0 : fDigitRowData = (AliHLTTPCDigitRowData*) tmpptr->fDigits;
101 0 : fActRowData = fDigitRowData;
102 :
103 0 : if(!fMapping){
104 0 : fMapping = new AliHLTTPCMapping(patch);
105 0 : }
106 :
107 0 : while (fActRowData && ((iResult=GetNextRowData(fActRowData))>=0)) {/* empty body */};
108 :
109 0 : if (iResult>=0) {
110 0 : fActRowData = fDigitRowData;
111 0 : fBin = -1;
112 :
113 0 : int dummy=0;
114 0 : AliHLTTPCGeometry::Slice2Sector(slice, AliHLTTPCGeometry::GetFirstRow(patch), dummy, fFirstRow);
115 0 : AliHLTTPCGeometry::Slice2Sector(slice, AliHLTTPCGeometry::GetLastRow(patch), dummy, fLastRow);
116 :
117 0 : fRow = fFirstRow;
118 :
119 0 : if ((Int_t)fActRowData->fRow != fRow){
120 0 : HLTWarning("Row number should match! fActRowData->fRow=%d fRow=%d", fActRowData->fRow, fRow);
121 : }
122 0 : } else {
123 0 : fActRowData=NULL;
124 : }
125 0 : return iResult;
126 0 : }
127 :
128 : int AliHLTTPCDigitReaderUnpacked::GetNextRowData(AliHLTTPCDigitRowData*& pRow) const
129 : {
130 : // get new row data from the current row data
131 : int iResult=0;
132 0 : AliHLTTPCDigitRowData* pCurrent=pRow;
133 0 : assert(pCurrent);
134 0 : pRow=NULL;
135 0 : if (!pCurrent) return -EINVAL;
136 0 : Byte_t *tmp = (Byte_t*) pCurrent;
137 0 : Int_t size = sizeof(AliHLTTPCDigitRowData) + pCurrent->fNDigit*sizeof(AliHLTTPCDigitData);
138 0 : tmp += size;
139 0 : pRow = reinterpret_cast<AliHLTTPCDigitRowData*>(tmp);
140 :
141 : // check if the new pointer is within the range
142 0 : if (((Byte_t*)fPtr) + fSize <= tmp){
143 0 : if (((Byte_t*)fPtr) + fSize < tmp) {
144 : // if the increment does not match exactly there is a format error
145 0 : HLTError("input format not recognized: buffer %p %d, current row data %p, %d digits", fPtr, fSize, pCurrent, pCurrent->fNDigit);
146 : iResult=-EBADF;
147 0 : }
148 0 : pRow=NULL;
149 0 : } else {
150 : // check if the current row structure has the right format
151 0 : size = sizeof(AliHLTTPCDigitRowData) + pRow->fNDigit*sizeof(AliHLTTPCDigitData);
152 0 : tmp += size;
153 0 : if (((Byte_t*)fPtr) + fSize < tmp){
154 0 : HLTError("Current row data not recognized %p (buffer %p %d) %d digits", pRow, fPtr, fSize, pRow->fNDigit);
155 0 : pRow=NULL;
156 : iResult=-EBADF;
157 0 : }
158 : }
159 :
160 : return iResult;
161 0 : }
162 : void AliHLTTPCDigitReaderUnpacked::SortBunchBinVector(){
163 0 : fBinRowPositionSorted.clear();
164 :
165 0 : fBinRowPositionSorted.push_back(0);
166 : Int_t nAdded=0;
167 : Int_t beginningOfPadIndex=0;
168 : Int_t totalAdded=0;
169 0 : for(Int_t i=1;i<(Int_t)fActRowData->fNDigit;i++){
170 0 : if(fData[i-1].fPad == fData[i].fPad){// means that these sinals belong to the same pad
171 0 : if(fData[i-1].fTime+1 == fData[i].fTime){ //means that the signal belong to the same bunch
172 0 : nAdded++;
173 0 : totalAdded++;
174 0 : fBinRowPositionSorted.insert(fBinRowPositionSorted.begin()+beginningOfPadIndex+nAdded,i);
175 0 : }
176 : else{//we have a new bunch on this pad, put it in fornt of the previous bunch
177 0 : totalAdded++;
178 : nAdded=0;
179 0 : fBinRowPositionSorted.insert(fBinRowPositionSorted.begin()+beginningOfPadIndex,i);
180 : }
181 : }
182 : else{
183 0 : totalAdded++;
184 : beginningOfPadIndex=totalAdded;
185 0 : fBinRowPositionSorted.push_back(i);
186 : nAdded=0;
187 : }
188 : }
189 0 : }
190 :
191 : bool AliHLTTPCDigitReaderUnpacked::NextSignal(){
192 : // see header file for class documentation
193 0 : if (fActRowData==NULL) return false;
194 :
195 : bool rreadvalue = true;
196 :
197 0 : fBin++;
198 :
199 0 : while ( fBin >= (Int_t)fActRowData->fNDigit ){
200 0 : fRow++;
201 0 : if ((fRow >= fFirstRow) && (fRow <= fLastRow)){
202 :
203 : //new row
204 0 : if (GetNextRowData(fActRowData)<0) {
205 : rreadvalue = false;
206 0 : return rreadvalue;
207 : }
208 0 : fBin = 0;
209 : }
210 : else {
211 : rreadvalue = false;
212 0 : return rreadvalue;
213 : }
214 0 : if(!fActRowData){
215 0 : return false;
216 : }
217 0 : if ((Int_t)fActRowData->fRow != fRow){
218 0 : HLTWarning("Row number should match! fActRowData->fRow=%d fRow=%d", fActRowData->fRow, fRow);
219 : }
220 : }
221 :
222 0 : fData = fActRowData->fDigitData;
223 :
224 0 : if(fBin==0){
225 0 : SortBunchBinVector();
226 0 : }
227 :
228 0 : if(fPrevPad == -1){
229 0 : fPrevPad = GetSortedPad();
230 0 : }
231 :
232 0 : return rreadvalue;
233 0 : }
234 :
235 : int AliHLTTPCDigitReaderUnpacked::GetRow(){
236 : // see header file for class documentation
237 : int rrow;
238 :
239 0 : if(fUnsorted == kFALSE){
240 0 : rrow = fRow;
241 0 : }
242 : else{
243 0 : rrow = fRow-AliHLTTPCGeometry::GetFirstRow(fPatch);
244 0 : if(fPatch>1){
245 0 : rrow += AliHLTTPCGeometry::GetFirstRow(2);
246 0 : }
247 : }
248 :
249 0 : return rrow;
250 : }
251 :
252 : int AliHLTTPCDigitReaderUnpacked::GetPad(){
253 : // see header file for class documentation
254 : int rpad;
255 0 : if(fUnsorted == kFALSE){
256 0 : rpad = GetSortedPad();
257 0 : }
258 : else{
259 0 : rpad = fPrevPad;
260 : }
261 0 : return rpad ;
262 : }
263 :
264 : int AliHLTTPCDigitReaderUnpacked::GetSignal(){
265 : // see header file for class documentation
266 : int rsignal;
267 0 : if(fUnsorted == kFALSE){
268 0 : rsignal = GetSortedSignal();
269 0 : }
270 : else{
271 0 : rsignal = fPrevSignal;
272 : }
273 0 : return rsignal;
274 : }
275 :
276 : int AliHLTTPCDigitReaderUnpacked::GetTime(){
277 : // see header file for class documentation
278 : int rtime;
279 0 : if(fUnsorted==kFALSE){
280 0 : rtime = GetSortedTime();
281 0 : }
282 : else{
283 0 : rtime = fPrevTime+1-fDataBunch.size();
284 : }
285 0 : return rtime;
286 : }
287 :
288 : AliHLTUInt32_t AliHLTTPCDigitReaderUnpacked::GetAltroBlockHWaddr() const
289 : {
290 : // see header file for class documentation
291 0 : return (AliHLTUInt32_t)(fMapping->GetHwAddress((UInt_t)GetSortedRow(),(UInt_t)GetSortedPad()));//fTPCRawStream->GetHWAddress();
292 : }
293 :
294 : AliHLTTPCDigitData AliHLTTPCDigitReaderUnpacked::GetSortedDigit(){
295 : // see header file for class documentation
296 0 : assert(fData);
297 0 : if (!fData) return AliHLTTPCDigitData();
298 0 : return fData[fBinRowPositionSorted.at(fBin)];
299 0 : }
300 :
301 : Int_t AliHLTTPCDigitReaderUnpacked::GetSortedTime(){
302 : // see header file for class documentation
303 0 : assert(fData);
304 0 : if (!fData) return -1;
305 : int rtime;
306 0 : rtime = (int)fData[fBinRowPositionSorted.at(fBin)].fTime;
307 0 : if(fDataBunch.size()>1){
308 0 : fEndTimeBinOfBunch=rtime;
309 0 : }
310 : return rtime;
311 0 : }
312 :
313 : Int_t AliHLTTPCDigitReaderUnpacked::GetSortedSignal(){
314 : // see header file for class documentation
315 0 : assert(fData);
316 0 : if (!fData) return -1;
317 : int rsignal;
318 0 : rsignal = (int)fData[fBinRowPositionSorted.at(fBin)].fCharge;
319 : return rsignal;
320 :
321 0 : }
322 :
323 : Int_t AliHLTTPCDigitReaderUnpacked::GetSortedPad() const{
324 : // see header file for class documentation
325 0 : assert(fData);
326 0 : if (!fData) return -1;
327 : int rpad;
328 0 : rpad = (int)fData[fBinRowPositionSorted.at(fBin)].fPad;
329 : return rpad ;
330 0 : }
331 :
332 : int AliHLTTPCDigitReaderUnpacked::GetSortedRow() const {
333 : // see header file for class documentation
334 : int rrow;
335 0 : rrow = fRow-AliHLTTPCGeometry::GetFirstRow(fPatch);
336 0 : if(fPatch>1){
337 0 : rrow += AliHLTTPCGeometry::GetFirstRow(2);
338 0 : }
339 0 : return rrow;
340 : }
341 :
342 : bool AliHLTTPCDigitReaderUnpacked::NextChannel()
343 : {
344 : // see header file for class documentation
345 :
346 : // If the next channel is already confirmed by the next bunch function
347 : // or there are more signals (this will only be for the first signal)
348 :
349 0 : if(fEndOfDataReached == kTRUE){
350 0 : return false;
351 : }
352 0 : if(fNextChannelIsAlreadyConfirmed){
353 0 : fNextChannelIsAlreadyConfirmed = kFALSE;
354 0 : fPrevTime=GetSortedTime();
355 0 : fPrevSignal=GetSortedSignal();
356 0 : fPrevPad = GetSortedPad();
357 0 : fPrevRow = GetSortedRow();
358 :
359 0 : if(GetAltroBlockHWaddr() == (UInt_t)-1){
360 0 : fPrevPad = -1;
361 0 : return NextChannel();
362 : }
363 :
364 0 : return true;
365 : }
366 0 : else if(NextSignal()) { // there is data
367 :
368 0 : if(GetAltroBlockHWaddr() == (UInt_t)-1){
369 0 : fPrevPad = -1;
370 0 : return NextChannel();
371 : }
372 0 : return true;
373 : }
374 0 : return false;
375 0 : }
376 :
377 : int AliHLTTPCDigitReaderUnpacked::NextBunch()
378 : {
379 : // see header file for class documentation
380 :
381 0 : if(fEndOfDataReached == kTRUE || fEndOfChannelReached == kTRUE){
382 : // sets fEndOfChannelReached back to false, for the next channel
383 : // and returns 0 to tell stop the NextBunch calls for this channel.
384 0 : fEndOfChannelReached=kFALSE;
385 0 : return 0;
386 : }
387 :
388 :
389 0 : fDataBunch.clear();
390 0 : fDigitsVector.clear();
391 :
392 : //adding the first signal (will always be the leftover from either NextChannel call or previous bunch)
393 0 : fPrevTime=GetSortedTime();
394 0 : fPrevSignal=GetSortedSignal();
395 0 : fPrevPad = GetSortedPad();
396 0 : fPrevRow = GetSortedRow();
397 0 : fDataBunch.push_back(GetSortedSignal());
398 0 : fDigitsVector.push_back(GetSortedDigit());
399 :
400 0 : do{
401 0 : if(NextSignal()){
402 0 : if((fPrevPad == GetSortedPad()) && (fPrevRow == GetSortedRow())){//check if there is a change in channel(new pad or row)
403 0 : if(fPrevTime+1 == GetSortedTime()){//if true means that we have consecutive signals
404 0 : fPrevTime = GetSortedTime();
405 : //fDataBunch.insert(fDataBunch.begin(), GetSortedSignal());// add the signal to the beginning of the buffer
406 0 : fDataBunch.push_back(GetSortedSignal());// add the signal to the beginning of the buffer
407 0 : fDigitsVector.push_back(GetSortedDigit());
408 : }
409 : else{//end of bunch but not of channel
410 : break;
411 : }
412 : }
413 : else{
414 : // end of channel, last bunch will be completed
415 0 : fEndOfChannelReached = kTRUE;
416 : // the next channel is already confirmed since the next channel returned true
417 0 : fNextChannelIsAlreadyConfirmed = kTRUE;
418 0 : break;
419 : }
420 : }
421 : else{
422 : // end of data, but there is one bunch to be completed.
423 0 : fEndOfDataReached = kTRUE;
424 0 : break;
425 : }
426 0 : }while(1);
427 :
428 0 : return fDataBunch.size();
429 0 : }
430 :
431 : int AliHLTTPCDigitReaderUnpacked::GetBunchSize(){
432 : // see header file for class documentation
433 0 : return fDataBunch.size();
434 : }
435 :
436 : const UInt_t* AliHLTTPCDigitReaderUnpacked::GetSignals()
437 : {
438 : // see header file for class documentation
439 0 : return &fDataBunch[0];
440 : }
441 :
442 : const AliHLTTPCDigitData* AliHLTTPCDigitReaderUnpacked::GetBunchDigits()
443 : {
444 : // see header file for class documentation
445 0 : return &fDigitsVector[0];
446 : }
447 : int AliHLTTPCDigitReaderUnpacked::GetRowOffset() const
448 : {
449 : // see header file for class documentation
450 0 : return AliHLTTPCGeometry::GetFirstRow(fPatch);
451 : }
|