]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCPad.cxx
Bugfix, For interleaved data the channel was sett for branch B even if the channel...
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCPad.cxx
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: Timm Steinbeck, Matthias Richter                      *
8 //* Developers:      Kenneth Aamodt <kenneth.aamodt@student.uib.no>        *
9 //*                  for The ALICE HLT Project.                            *
10 //*                                                                        *
11 //* Permission to use, copy, modify and distribute this software and its   *
12 //* documentation strictly for non-commercial purposes is hereby granted   *
13 //* without fee, provided that the above copyright notice appears in all   *
14 //* copies and that both the copyright notice and this permission notice   *
15 //* appear in the supporting documentation. The authors make no claims     *
16 //* about the suitability of this software for any purpose. It is          *
17 //* provided "as is" without express or implied warranty.                  *
18 //**************************************************************************
19
20 /** @file   AliHLTTPCPad.cxx
21     @author Matthias Richter, Kenneth Aamodt
22     @date   
23     @brief  Container Class for TPC Pads.
24 */
25
26 #if __GNUC__>= 3
27 using namespace std;
28 #endif
29
30 #include <cerrno>
31 #include "AliHLTTPCPad.h"
32 #include "AliHLTStdIncludes.h"
33
34
35 //added by kenneth
36 #include "AliHLTTPCTransform.h"
37 #include "AliHLTTPCClusters.h"
38 #include <sys/time.h>
39 #include "TMath.h"
40 #include "TFile.h"
41 //------------------------------
42
43 /** margin for the base line be re-avaluated */
44 #define ALIHLTPAD_BASELINE_MARGIN (2*fAverage)
45
46 /** ROOT macro for the implementation of ROOT specific class methods */
47 ClassImp(AliHLTTPCPad)
48
49 AliHLTTPCPad::AliHLTTPCPad()
50   :
51   fClusterCandidates(),
52   fUsedClusterCandidates(),
53   fSelectedPad(kFALSE),
54   fHWAddress(0),
55   fRowNo(-1),
56   fPadNo(-1),
57   fThreshold(0),
58   fAverage(-1),
59   fNofEvents(0),
60   fSum(0),
61   fCount(0),
62   fTotal(0),
63   fBLMax(-1),
64   fBLMaxBin(-1),
65   fBLMin(-1),
66   fBLMinBin(-1),
67   fFirstBLBin(0),
68   fNofBins(0),
69   fReadPos(0),
70   fpRawData(NULL),
71   fDataSignals(NULL),
72   fSignalPositionArray(NULL),
73   fSizeOfSignalPositionArray(0),
74   fNGoodSignalsSent(0),
75   fCandidateDigitsVector()
76 {
77   // see header file for class documentation
78   // or
79   // refer to README to build package
80   // or
81   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
82   //  HLTInfo("Entering default constructor");
83   fDataSignals= new AliHLTTPCSignal_t[AliHLTTPCTransform::GetNTimeBins()];
84   memset( fDataSignals, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
85   
86   fSignalPositionArray= new Int_t[AliHLTTPCTransform::GetNTimeBins()];
87   memset( fSignalPositionArray, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
88   fSizeOfSignalPositionArray=0;
89
90 }
91
92 AliHLTTPCPad::AliHLTTPCPad(Int_t dummy)
93   :
94   fClusterCandidates(),
95   fUsedClusterCandidates(),
96   fSelectedPad(kFALSE),
97   fHWAddress(0),
98   fRowNo(-1),
99   fPadNo(-1),
100   fThreshold(0),
101   fAverage(-1),
102   fNofEvents(0),
103   fSum(0),
104   fCount(0),
105   fTotal(0),
106   fBLMax(-1),
107   fBLMaxBin(-1),
108   fBLMin(-1),
109   fBLMinBin(-1),
110   fFirstBLBin(0),
111   fNofBins(0),
112   fReadPos(0),
113   fpRawData(NULL),
114   fDataSignals(NULL),
115   fSignalPositionArray(NULL),
116   fSizeOfSignalPositionArray(0),
117   fNGoodSignalsSent(0),
118   fCandidateDigitsVector()
119 {
120   // see header file for class documentation
121   // or
122   // refer to README to build package
123   // or
124   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
125   dummy=0;//to get rid of warning until things are cleaned up better
126 }
127
128 AliHLTTPCPad::AliHLTTPCPad(Int_t offset, Int_t nofBins)
129   :
130   fClusterCandidates(),
131   fUsedClusterCandidates(),
132   fSelectedPad(kFALSE),
133   fHWAddress(0),
134   fRowNo(-1),
135   fPadNo(-1),
136   fThreshold(0),
137   fAverage(-1),
138   fNofEvents(0),
139   fSum(0),
140   fCount(0),
141   fTotal(0),
142   fBLMax(-1),
143   fBLMaxBin(-1),
144   fBLMin(-1),
145   fBLMinBin(-1),
146   fFirstBLBin(offset),
147   fNofBins(nofBins),
148   fReadPos(0),
149   fpRawData(NULL),
150   fDataSignals(NULL),
151   fSignalPositionArray(NULL),
152   fSizeOfSignalPositionArray(0),
153   fNGoodSignalsSent(0),
154   fCandidateDigitsVector()
155 {
156   // see header file for class documentation
157 }
158
159 AliHLTTPCPad::~AliHLTTPCPad()
160 {
161   // see header file for class documentation
162   if (fpRawData) {
163     HLTWarning("event data acquisition not stopped");
164     StopEvent();
165   }
166   if (fDataSignals) {
167     delete [] fDataSignals;
168     fDataSignals=NULL;
169   }
170   if (fSignalPositionArray!=NULL) {
171     delete [] fSignalPositionArray;
172     fSignalPositionArray=NULL;
173   }
174 }
175
176 Int_t AliHLTTPCPad::SetID(Int_t rowno, Int_t padno)
177 {
178   // see header file for class documentation
179   fRowNo=rowno;
180   fPadNo=padno;
181
182   return 0;
183 }
184
185 Int_t AliHLTTPCPad::StartEvent()
186 {
187   // see header file for class documentation
188   Int_t iResult=0;
189   if (fpRawData==NULL) {
190     fBLMax=-1;
191     fBLMaxBin=-1;
192     fBLMin=-1;
193     fBLMinBin=-1;
194     fSum=0;
195     fCount=0;
196     fTotal=0;
197     if (fNofBins>0) {
198       fpRawData=new AliHLTTPCSignal_t[fNofBins];
199       if (fpRawData) {
200         for (int i=0; i<fNofBins; i++) fpRawData[i]=-1;
201       } else {
202         HLTError("memory allocation failed");
203         iResult=-ENOMEM;
204       }
205     }
206   } else {
207     HLTWarning("event data acquisition already started");
208     iResult=-EALREADY;
209   }
210   return iResult;
211 }
212
213 Int_t AliHLTTPCPad::CalculateBaseLine(Int_t reqMinCount)
214 {
215   // see header file for class documentation
216   Int_t iResult=0;
217   AliHLTTPCSignal_t avBackup=fAverage;
218   //HLTDebug("reqMinCount=%d fCount=%d fTotal=%d fSum=%d fBLMax=%d fBLMin=%d", reqMinCount, fCount, fTotal, fSum, fBLMax, fBLMin);
219   if (fCount>=reqMinCount && fCount>=fTotal/2) {
220     fAverage=fCount>0?fSum/fCount:0;
221     if (fAverage>0) {
222       //HLTDebug("average for current event %d (%d - %d)", fAverage, fBLMax, fBLMin);
223       fCount=0;fSum=-1;
224       if (fBLMax>ALIHLTPAD_BASELINE_MARGIN) {
225         // calculate again
226         //HLTDebug("maximum value %d exceeds margin for base line (%d) "
227         //       "-> re-evaluate base line", fBLMax, ALIHLTPAD_BASELINE_MARGIN);
228         if (fpRawData) {
229           for (Int_t i=fFirstBLBin; i<fNofBins; i++)
230             if (fpRawData[i]>=0) AddBaseLineValue(i, fpRawData[i]);
231           if (fCount>0 && fCount>=reqMinCount && fCount>=fTotal/2) {
232             fAverage=fSum/fCount;
233             //HLTDebug("new average %d", fAverage);
234           } else {
235             //      HLTDebug("baseline re-eveluation skipped because of to few "
236             //                 "contributing bins: total=%d, contributing=%d, req=%d"
237             //                 "\ndata might be already zero suppressed"
238             //                 , fTotal, fCount, reqMinCount);
239             iResult=-ENODATA;
240           }
241           fCount=0;fSum=-1;
242         } else {
243           HLTError("missing raw data for base line calculation");
244           iResult=-ENOBUFS;
245         }
246       }
247       if (iResult>=0) {
248         // calculate average for all events
249         fAverage=((avBackup*fNofEvents)+fAverage)/(fNofEvents+1);
250         //HLTDebug("base line average for %d event(s): %d", fNofEvents+1, fAverage);
251       } else {
252         fAverage=avBackup;      
253       }
254     } else {
255       fAverage=avBackup;
256     }
257   } else {
258     //     HLTDebug("baseline calculation skipped because of to few contributing "
259     //         "bins: total=%d, contributing=%d, required=%d \ndata might be "
260     //         "already zero suppressed", fTotal, fCount, reqMinCount);
261   }
262
263   return iResult;
264 }
265
266 Int_t AliHLTTPCPad::StopEvent()
267 {
268   // see header file for class documentation
269   Int_t iResult=0;
270   if (fpRawData) {
271     AliHLTTPCSignal_t* pData=fpRawData;
272     fpRawData=NULL;
273     delete [] pData;
274     fTotal=0;
275     fNofEvents++;
276     Rewind();
277   } else if (fNofBins>0) {
278     HLTError("event data acquisition not started");
279     iResult=-EBADF;
280   }
281   return iResult;
282 }
283
284 Int_t AliHLTTPCPad::ResetHistory()
285 {
286   // see header file for class documentation
287   Int_t iResult=0;
288   fAverage=-1;
289   fNofEvents=0;
290   return iResult;
291 }
292
293 Int_t AliHLTTPCPad::SetThreshold(AliHLTTPCSignal_t thresh)
294 {
295   // see header file for class documentation
296   Int_t iResult=0;
297   fThreshold=thresh;
298   return iResult;
299 }
300
301 Int_t AliHLTTPCPad::AddBaseLineValue(Int_t bin, AliHLTTPCSignal_t value)
302 {
303   // see header file for class documentation
304   Int_t iResult=0;
305   if (bin>=fFirstBLBin) {
306     if (fAverage<0 || value<ALIHLTPAD_BASELINE_MARGIN) {
307       // add to the current sum and count
308       fSum+=value;
309       fCount++;
310       if (fBLMax<value) {
311         // keep the maximum value for later quality control of the base 
312         // line calculation
313         fBLMax=value;
314         fBLMaxBin=bin;
315       }
316       if (fBLMin<0 || fBLMin>value) {
317         // keep the minimum value for later quality control of the base 
318         // line calculation
319         fBLMin=value;
320         fBLMinBin=bin;
321       }
322     } else {
323       //       HLTDebug("ignoring value %d (bin %d) for base line calculation "
324       //               "(current average is %d)",
325       //               value, bin, fAverage);
326     }
327   }
328   return iResult;
329 }
330
331 Int_t AliHLTTPCPad::SetRawData(Int_t bin, AliHLTTPCSignal_t value)
332 {
333   // see header file for class documentation
334   //  printf("Row: %d    Pad: %d  Time: %d Charge %d", fRowNo, fPadNo, bin, value);
335   Int_t iResult=0;
336   if (fpRawData) {
337     if (bin<fNofBins) {
338       if (value>=0) {
339         if (fpRawData[bin]<0) {
340           AddBaseLineValue(bin, value);
341           fTotal++;
342         } else {
343           // ignore value for average calculation
344           HLTWarning("overriding content of bin %d (%d)", bin, fpRawData[bin]);
345         }
346         fpRawData[bin]=value;
347       } else {
348         HLTWarning("ignoring neg. raw data");
349       }
350     } else {
351       HLTWarning("bin %d out of range (%d)", bin, fNofBins);
352       iResult=-ERANGE;
353     }
354   } else if (fNofBins>0) {
355     HLTError("event cycle not started");
356     iResult=-EBADF;
357   }
358   return iResult;
359 }
360
361 Int_t AliHLTTPCPad::Next(Int_t bZeroSuppression) 
362 {
363   // see header file for class documentation
364   if (fpRawData==NULL) return 0;
365   Int_t iResult=fReadPos<fNofBins;
366   if (iResult>0 && (iResult=(++fReadPos<fNofBins))>0) {
367     if (bZeroSuppression) {
368       while ((iResult=(fReadPos<fNofBins))>0 &&
369              GetCorrectedData(fReadPos)<=0)
370         fReadPos++;
371     }
372   }
373   return iResult;
374 }
375
376 Int_t AliHLTTPCPad::Rewind(Int_t bZeroSuppression)
377 {
378   // see header file for class documentation
379   fReadPos=(bZeroSuppression>0?0:fFirstBLBin)-1;
380   return Next(bZeroSuppression);
381 }
382
383 AliHLTTPCSignal_t AliHLTTPCPad::GetRawData(Int_t bin) const
384 {
385   // see header file for class documentation
386   AliHLTTPCSignal_t data=0;
387   if (fpRawData) {
388     if (bin<fNofBins) {
389       data=fpRawData[bin];
390     } else {
391       HLTWarning("requested bin %d out of range (%d)", bin, fNofBins);
392     }
393   } else if (fNofBins>0) {
394     HLTWarning("data only available within event cycle");
395   }
396   return data;
397 }
398
399 AliHLTTPCSignal_t AliHLTTPCPad::GetCorrectedData(Int_t bin) const
400 {
401   // see header file for class documentation
402   AliHLTTPCSignal_t data=GetRawData(bin)-GetBaseLine(bin);
403   AliHLTTPCSignal_t prev=0;
404   if (bin>1) prev=GetRawData(bin-1)-GetBaseLine(bin-1);
405   AliHLTTPCSignal_t succ=0;
406   if (bin+1<GetSize()) succ=GetRawData(bin+1)-GetBaseLine(bin+1);
407   if (fThreshold>0) {
408     data-=fThreshold;
409     prev-=fThreshold;
410     succ-=fThreshold;
411   }
412  
413   // case 1:
414   // the signal is below the base-line and threshold
415   if (data<0) data=0;
416
417   //case 2:
418   // the neighboring bins are both below base-line/threshold
419   // a real signal is always more than one bin wide because of the shaper 
420   if (prev<=0 && succ<=0) data=0;
421  
422   // case 3:
423   // the bin is inside the range of ignored bins
424   if (bin<fFirstBLBin) data=0;
425   //HLTDebug("fReadPos=%d data=%d threshold=%d raw data=%d base line=%d", fReadPos, data, fThreshold, GetRawData(bin), GetBaseLine(bin));
426   return data;
427 }
428
429 AliHLTTPCSignal_t AliHLTTPCPad::GetBaseLine(Int_t /*bin*/) const //TODO: Why is bin being ignored?
430 {
431   // see header file for class documentation
432   AliHLTTPCSignal_t val=0;
433   if (fAverage>0) {
434     // we take the minumum value as the base line if it doesn't differ from
435     // the average to much
436     val=fAverage;
437 #ifdef KEEP_NOISE
438     const AliHLTTPCSignal_t kMaxDifference=15;
439     if ((fAverage-fBLMin)<=kMaxDifference) val=fBLMin;
440     else val>kMaxDifference?val-=kMaxDifference:0;
441 #endif
442   }
443   if (val<0) {
444     // here we should never get
445     val=0;
446     HLTFatal("wrong base line value");
447   }
448   return val;
449 }
450
451 AliHLTTPCSignal_t AliHLTTPCPad::GetAverage() const
452 {
453   // see header file for class documentation
454   return fAverage>0?fAverage:0;
455 }
456
457 Float_t AliHLTTPCPad::GetOccupancy() const
458 {
459   // see header file for class documentation
460   Float_t occupancy=0;
461   if (fpRawData && fNofBins>0) {
462     for (Int_t i=fFirstBLBin; i<fNofBins; i++) {
463       if (GetCorrectedData(i)>0) occupancy+=1;
464     }
465     if (fNofBins-fFirstBLBin>0)
466       occupancy/=fNofBins-fFirstBLBin;
467   }
468   return occupancy;
469 }
470
471 Float_t AliHLTTPCPad::GetAveragedOccupancy() const
472 {
473   // see header file for class documentation
474
475   // history is not yet implemented
476   return GetOccupancy();
477 }
478 void AliHLTTPCPad::PrintRawData()
479 {
480   // see header file for class documentation
481   for(Int_t bin=0;bin<AliHLTTPCTransform::GetNTimeBins();bin++){
482     if(GetDataSignal(bin)>0)
483       //This cout should be here since using logging produces output that is much more difficult to read
484         cout<<fRowNo<<"\t"<<fPadNo<<"\t"<<bin<<"\t"<<GetDataSignal(bin)<<endl;
485   }
486 }
487
488 void AliHLTTPCPad::ClearCandidates(){
489   fClusterCandidates.clear();
490   fUsedClusterCandidates.clear();
491   fCandidateDigitsVector.clear();
492 }
493
494 void AliHLTTPCPad::SetDataToDefault()
495 {
496   // see header file for class documentation
497   //  if(fDataSignals && fSignalPositionArray){
498     for(Int_t i =0;i<fSizeOfSignalPositionArray;i++){
499       fDataSignals[fSignalPositionArray[i]]=-1;
500     }
501     fSizeOfSignalPositionArray=0;
502     fNGoodSignalsSent = 0;
503     //  }
504 }
505
506 void AliHLTTPCPad::SetDataSignal(Int_t bin,Int_t signal)
507 {
508   // see header file for class documentation
509   fDataSignals[bin]=signal;
510   fSignalPositionArray[fSizeOfSignalPositionArray]=bin;
511   fSizeOfSignalPositionArray++;
512 }
513
514 Bool_t AliHLTTPCPad::GetNextGoodSignal(Int_t &time,Int_t &bunchSize){
515
516   if(fNGoodSignalsSent<fSizeOfSignalPositionArray&&fSizeOfSignalPositionArray>0){
517     time = fSignalPositionArray[fNGoodSignalsSent];
518     bunchSize=1;
519     fNGoodSignalsSent++;
520     while(fNGoodSignalsSent<fSizeOfSignalPositionArray){
521       if(fDataSignals[time+bunchSize+1]>0){
522         bunchSize++;
523         fNGoodSignalsSent++;
524       }
525       else{
526         break;
527       }
528     }
529     //    fNGoodSignalsSent++;
530    return kTRUE;
531   }
532   return kFALSE;
533 }
534
535 Int_t AliHLTTPCPad::GetDataSignal(Int_t bin) const
536 {
537   // see header file for class documentation
538   return fDataSignals[bin];
539 }
540
541 void AliHLTTPCPad::ZeroSuppress(Double_t nRMS, Int_t threshold, Int_t reqMinPoint, Int_t beginTime, Int_t endTime, Int_t timebinsLeft, Int_t timebinsRight, Int_t valueUnderAverage, bool speedup){
542   //see headerfile for documentation
543  
544   //HLTDebug("In Pad: nRMS=%d, threshold=%d, reqMinPoint=%d, beginTime=%d, endTime=%d, timebinsLeft=%d timebinsRight=%d valueUnderAverage=%d \n",nRMS,threshold,reqMinPoint,beginTime,endTime,timebinsLeft,timebinsRight,valueUnderAverage);
545
546   Bool_t useRMS= kFALSE;
547   if(nRMS>0){
548     useRMS=kTRUE;
549     if(threshold>0){
550       HLTInfo("Both RMSThreshold and SignalThreshold defined, using RMSThreshold");
551     }
552   }
553   if(threshold<1 && nRMS<=0){
554     //setting the data to -1 for this pad
555     HLTInfo("Neither of RMSThreshold and SignalThreshold set, zerosuppression aborted");
556     return;
557   }
558  
559   Int_t fThresholdUsed=threshold;
560
561   Int_t maxVal=0;
562   Int_t nAdded=0;
563   Int_t sumNAdded=0;
564   fSizeOfSignalPositionArray=0;
565   if(useRMS){
566     for(Int_t i=beginTime;i<endTime+1;i++){
567       if(fDataSignals[i]>0){
568         nAdded++;
569         sumNAdded+=fDataSignals[i]*fDataSignals[i];
570         if (maxVal<fDataSignals[i]) maxVal=fDataSignals[i];
571       }
572     }
573   }
574   else if(threshold>0){
575     for(Int_t i=beginTime;i<endTime+1;i++){
576       if(fDataSignals[i]>0){
577         nAdded++;
578         sumNAdded+=fDataSignals[i];
579         if (maxVal<fDataSignals[i]) maxVal=fDataSignals[i];
580       }
581     }
582   }
583   else{
584     HLTFatal("This should never happen because this is tested earlier in the code.(nRMSThreshold<1&&signal-threshold<1)");
585   }
586   if(nAdded<reqMinPoint){
587     HLTInfo("Number of signals is less than required, zero suppression aborted");
588     return;
589   }
590  
591   if(nAdded==0){
592     HLTInfo("No signals added for this pad, zerosuppression aborted: pad %d row %d",fPadNo,fRowNo);
593     return;
594   }
595
596   Double_t averageValue=(Double_t)sumNAdded/nAdded;//true average for threshold approach, average of signals squared for rms approach
597  
598   if(useRMS){
599     //Calculate the RMS
600     if(averageValue>0){
601       fThresholdUsed =(Int_t)(TMath::Sqrt(averageValue)*nRMS);
602     }
603     else{
604       HLTFatal("average value in ZeroSuppression less than 0, investigation needed. This should never happen");
605     }
606   }
607   else{
608     fThresholdUsed = (Int_t)(averageValue + threshold); 
609   }
610   if (maxVal<fThresholdUsed) return;
611
612   // Do zero suppression on the adc values within [beginTime,endTime](add the good values)
613   for(Int_t i=beginTime;i<endTime;i++){
614     if(fDataSignals[i]>fThresholdUsed){
615       Int_t firstSignalTime=i;
616       for(Int_t left=1;left<timebinsLeft;left++){//looking 5 to the left of the signal to add tail
617         if(fDataSignals[i-left]-averageValue+valueUnderAverage>0 && i-left>=beginTime){
618           firstSignalTime--;
619         }
620         else{
621           break;
622         }
623       }
624       Int_t lastSignalTime=i;
625       while(fDataSignals[lastSignalTime+1]>fThresholdUsed && lastSignalTime+1<endTime){
626         lastSignalTime++;
627       }
628       for(Int_t right=1;right<timebinsRight;right++){//looking 5 to the left of the signal to add tail
629         if(fDataSignals[i+right]-averageValue+valueUnderAverage>0&&i+right<endTime){
630           lastSignalTime++;
631         }
632         else{
633           break;
634         }       
635       }
636       
637       for(Int_t t=firstSignalTime;t<lastSignalTime;t++){
638         fDataSignals[t]=(AliHLTTPCSignal_t)(fDataSignals[t]-averageValue + valueUnderAverage);
639         fSignalPositionArray[fSizeOfSignalPositionArray]=t;
640         fSizeOfSignalPositionArray++;
641         // Matthias Oct 10 2008: trying hard to make the code faster for the
642         // AltroChannelSelection. For that we only need to know there is data
643         if (speedup) return;
644       }
645       i+=lastSignalTime;
646     }
647   }
648   //reset the rest of the data
649   Int_t counterSize=fSizeOfSignalPositionArray;
650
651   for(Int_t d=endTime;d>=beginTime;d--){
652     if(d==fSignalPositionArray[counterSize-1]&&counterSize-1>=0){
653       counterSize--;
654     }
655     else{
656       fDataSignals[d]=-1;
657     }
658   }
659   if(fDataSignals[beginTime+1]<1){
660     fDataSignals[beginTime]=0;
661   }
662 }
663
664 void AliHLTTPCPad::AddClusterCandidate(AliHLTTPCClusters candidate){
665   fClusterCandidates.push_back(candidate);
666   fUsedClusterCandidates.push_back(0);
667 }
668
669 void AliHLTTPCPad::AddCandidateDigits(vector<AliHLTTPCDigitData> candidateDigits){
670   fCandidateDigitsVector.push_back(candidateDigits); 
671 }
672
673 vector<AliHLTTPCDigitData> AliHLTTPCPad::GetCandidateDigits(Int_t candidateIndex){
674   return fCandidateDigitsVector.at(candidateIndex);
675 }