3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Timm Steinbeck, Matthias Richter *
8 //* Developers: Kenneth Aamodt <kenneth.aamodt@student.uib.no> *
9 //* for The ALICE HLT Project. *
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 //**************************************************************************
20 /** @file AliHLTTPCPad.cxx
21 @author Matthias Richter, Kenneth Aamodt
23 @brief Container Class for TPC Pads.
31 #include "AliHLTTPCPad.h"
32 #include "AliHLTStdIncludes.h"
36 #include "AliHLTTPCTransform.h"
37 #include "AliHLTTPCClusters.h"
41 //------------------------------
43 /** margin for the base line be re-avaluated */
44 #define ALIHLTPAD_BASELINE_MARGIN (2*fAverage)
46 /** ROOT macro for the implementation of ROOT specific class methods */
47 ClassImp(AliHLTTPCPad)
49 AliHLTTPCPad::AliHLTTPCPad()
52 fUsedClusterCandidates(),
72 fSignalPositionArray(NULL),
73 fSizeOfSignalPositionArray(0),
76 // see header file for class documentation
78 // refer to README to build package
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()));
85 fSignalPositionArray= new Int_t[AliHLTTPCTransform::GetNTimeBins()];
86 memset( fSignalPositionArray, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
87 fSizeOfSignalPositionArray=0;
91 AliHLTTPCPad::AliHLTTPCPad(Int_t dummy)
94 fUsedClusterCandidates(),
114 fSignalPositionArray(NULL),
115 fSizeOfSignalPositionArray(0),
118 // see header file for class documentation
120 // refer to README to build package
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
126 AliHLTTPCPad::AliHLTTPCPad(Int_t offset, Int_t nofBins)
128 fClusterCandidates(),
129 fUsedClusterCandidates(),
130 fSelectedPad(kFALSE),
149 fSignalPositionArray(NULL),
150 fSizeOfSignalPositionArray(0),
153 // see header file for class documentation
156 AliHLTTPCPad::~AliHLTTPCPad()
158 // see header file for class documentation
160 HLTWarning("event data acquisition not stopped");
164 delete [] fDataSignals;
167 if (fSignalPositionArray!=NULL) {
168 delete [] fSignalPositionArray;
169 fSignalPositionArray=NULL;
173 Int_t AliHLTTPCPad::SetID(Int_t rowno, Int_t padno)
175 // see header file for class documentation
182 Int_t AliHLTTPCPad::StartEvent()
184 // see header file for class documentation
186 if (fpRawData==NULL) {
195 fpRawData=new AliHLTTPCSignal_t[fNofBins];
197 for (int i=0; i<fNofBins; i++) fpRawData[i]=-1;
199 HLTError("memory allocation failed");
204 HLTWarning("event data acquisition already started");
210 Int_t AliHLTTPCPad::CalculateBaseLine(Int_t reqMinCount)
212 // see header file for class documentation
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;
219 //HLTDebug("average for current event %d (%d - %d)", fAverage, fBLMax, fBLMin);
221 if (fBLMax>ALIHLTPAD_BASELINE_MARGIN) {
223 //HLTDebug("maximum value %d exceeds margin for base line (%d) "
224 // "-> re-evaluate base line", fBLMax, ALIHLTPAD_BASELINE_MARGIN);
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);
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);
240 HLTError("missing raw data for base line calculation");
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);
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);
263 Int_t AliHLTTPCPad::StopEvent()
265 // see header file for class documentation
268 AliHLTTPCSignal_t* pData=fpRawData;
274 } else if (fNofBins>0) {
275 HLTError("event data acquisition not started");
281 Int_t AliHLTTPCPad::ResetHistory()
283 // see header file for class documentation
290 Int_t AliHLTTPCPad::SetThreshold(AliHLTTPCSignal_t thresh)
292 // see header file for class documentation
298 Int_t AliHLTTPCPad::AddBaseLineValue(Int_t bin, AliHLTTPCSignal_t value)
300 // see header file for class documentation
302 if (bin>=fFirstBLBin) {
303 if (fAverage<0 || value<ALIHLTPAD_BASELINE_MARGIN) {
304 // add to the current sum and count
308 // keep the maximum value for later quality control of the base
313 if (fBLMin<0 || fBLMin>value) {
314 // keep the minimum value for later quality control of the base
320 // HLTDebug("ignoring value %d (bin %d) for base line calculation "
321 // "(current average is %d)",
322 // value, bin, fAverage);
328 Int_t AliHLTTPCPad::SetRawData(Int_t bin, AliHLTTPCSignal_t value)
330 // see header file for class documentation
331 // printf("Row: %d Pad: %d Time: %d Charge %d", fRowNo, fPadNo, bin, value);
336 if (fpRawData[bin]<0) {
337 AddBaseLineValue(bin, value);
340 // ignore value for average calculation
341 HLTWarning("overriding content of bin %d (%d)", bin, fpRawData[bin]);
343 fpRawData[bin]=value;
345 HLTWarning("ignoring neg. raw data");
348 HLTWarning("bin %d out of range (%d)", bin, fNofBins);
351 } else if (fNofBins>0) {
352 HLTError("event cycle not started");
358 Int_t AliHLTTPCPad::Next(Int_t bZeroSuppression)
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)
373 Int_t AliHLTTPCPad::Rewind(Int_t bZeroSuppression)
375 // see header file for class documentation
376 fReadPos=(bZeroSuppression>0?0:fFirstBLBin)-1;
377 return Next(bZeroSuppression);
380 AliHLTTPCSignal_t AliHLTTPCPad::GetRawData(Int_t bin) const
382 // see header file for class documentation
383 AliHLTTPCSignal_t data=0;
388 HLTWarning("requested bin %d out of range (%d)", bin, fNofBins);
390 } else if (fNofBins>0) {
391 HLTWarning("data only available within event cycle");
396 AliHLTTPCSignal_t AliHLTTPCPad::GetCorrectedData(Int_t bin) const
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);
411 // the signal is below the base-line and threshold
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;
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));
426 AliHLTTPCSignal_t AliHLTTPCPad::GetBaseLine(Int_t /*bin*/) const //TODO: Why is bin being ignored?
428 // see header file for class documentation
429 AliHLTTPCSignal_t val=0;
431 // we take the minumum value as the base line if it doesn't differ from
432 // the average to much
435 const AliHLTTPCSignal_t kMaxDifference=15;
436 if ((fAverage-fBLMin)<=kMaxDifference) val=fBLMin;
437 else val>kMaxDifference?val-=kMaxDifference:0;
441 // here we should never get
443 HLTFatal("wrong base line value");
448 AliHLTTPCSignal_t AliHLTTPCPad::GetAverage() const
450 // see header file for class documentation
451 return fAverage>0?fAverage:0;
454 Float_t AliHLTTPCPad::GetOccupancy() const
456 // see header file for class documentation
458 if (fpRawData && fNofBins>0) {
459 for (Int_t i=fFirstBLBin; i<fNofBins; i++) {
460 if (GetCorrectedData(i)>0) occupancy+=1;
462 if (fNofBins-fFirstBLBin>0)
463 occupancy/=fNofBins-fFirstBLBin;
468 Float_t AliHLTTPCPad::GetAveragedOccupancy() const
470 // see header file for class documentation
472 // history is not yet implemented
473 return GetOccupancy();
475 void AliHLTTPCPad::PrintRawData()
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;
485 void AliHLTTPCPad::ClearCandidates(){
486 fClusterCandidates.clear();
487 fUsedClusterCandidates.clear();
490 void AliHLTTPCPad::SetDataToDefault()
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;
497 fSizeOfSignalPositionArray=0;
498 fNGoodSignalsSent = 0;
502 void AliHLTTPCPad::SetDataSignal(Int_t bin,Int_t signal)
504 // see header file for class documentation
505 fDataSignals[bin]=signal;
506 fSignalPositionArray[fSizeOfSignalPositionArray]=bin;
507 fSizeOfSignalPositionArray++;
510 Bool_t AliHLTTPCPad::GetNextGoodSignal(Int_t &time,Int_t &bunchSize){
512 if(fNGoodSignalsSent<fSizeOfSignalPositionArray&&fSizeOfSignalPositionArray>0){
513 time = fSignalPositionArray[fNGoodSignalsSent];
516 while(fNGoodSignalsSent<fSizeOfSignalPositionArray){
517 if(fDataSignals[time+bunchSize+1]>0){
531 Int_t AliHLTTPCPad::GetDataSignal(Int_t bin) const
533 // see header file for class documentation
534 return fDataSignals[bin];
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
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);
542 Bool_t useRMS= kFALSE;
546 HLTInfo("Both RMSThreshold and SignalThreshold defined, using RMSThreshold");
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");
555 Int_t fThresholdUsed=threshold;
560 fSizeOfSignalPositionArray=0;
562 for(Int_t i=beginTime;i<endTime+1;i++){
563 if(fDataSignals[i]>0){
565 sumNAdded+=fDataSignals[i]*fDataSignals[i];
566 if (maxVal<fDataSignals[i]) maxVal=fDataSignals[i];
570 else if(threshold>0){
571 for(Int_t i=beginTime;i<endTime+1;i++){
572 if(fDataSignals[i]>0){
574 sumNAdded+=fDataSignals[i];
575 if (maxVal<fDataSignals[i]) maxVal=fDataSignals[i];
580 HLTFatal("This should never happen because this is tested earlier in the code.(nRMSThreshold<1&&signal-threshold<1)");
582 if(nAdded<reqMinPoint){
583 HLTInfo("Number of signals is less than required, zero suppression aborted");
588 HLTInfo("No signals added for this pad, zerosuppression aborted: pad %d row %d",fPadNo,fRowNo);
592 Double_t averageValue=(Double_t)sumNAdded/nAdded;//true average for threshold approach, average of signals squared for rms approach
597 fThresholdUsed =(Int_t)(TMath::Sqrt(averageValue)*nRMS);
600 HLTFatal("average value in ZeroSuppression less than 0, investigation needed. This should never happen");
604 fThresholdUsed = (Int_t)(averageValue + threshold);
606 if (maxVal<fThresholdUsed) return;
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){
620 Int_t lastSignalTime=i;
621 while(fDataSignals[lastSignalTime+1]>fThresholdUsed && lastSignalTime+1<endTime){
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){
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
644 //reset the rest of the data
645 Int_t counterSize=fSizeOfSignalPositionArray;
647 for(Int_t d=endTime;d>=beginTime;d--){
648 if(d==fSignalPositionArray[counterSize-1]&&counterSize-1>=0){
655 if(fDataSignals[beginTime+1]<1){
656 fDataSignals[beginTime]=0;
660 void AliHLTTPCPad::AddClusterCandidate(AliHLTTPCClusters candidate){
661 fClusterCandidates.push_back(candidate);
662 fUsedClusterCandidates.push_back(0);