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