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),
75 fCandidateDigitsVector()
77 // see header file for class documentation
79 // refer to README to build package
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()));
86 fSignalPositionArray= new Int_t[AliHLTTPCTransform::GetNTimeBins()];
87 memset( fSignalPositionArray, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
88 fSizeOfSignalPositionArray=0;
92 AliHLTTPCPad::AliHLTTPCPad(Int_t /*dummy*/)
95 fUsedClusterCandidates(),
115 fSignalPositionArray(NULL),
116 fSizeOfSignalPositionArray(0),
117 fNGoodSignalsSent(0),
118 fCandidateDigitsVector()
120 // see header file for class documentation
122 // refer to README to build package
124 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
127 AliHLTTPCPad::AliHLTTPCPad(Int_t offset, Int_t nofBins)
129 fClusterCandidates(),
130 fUsedClusterCandidates(),
131 fSelectedPad(kFALSE),
150 fSignalPositionArray(NULL),
151 fSizeOfSignalPositionArray(0),
152 fNGoodSignalsSent(0),
153 fCandidateDigitsVector()
155 // see header file for class documentation
158 AliHLTTPCPad::~AliHLTTPCPad()
160 // see header file for class documentation
162 HLTWarning("event data acquisition not stopped");
166 delete [] fDataSignals;
169 if (fSignalPositionArray!=NULL) {
170 delete [] fSignalPositionArray;
171 fSignalPositionArray=NULL;
175 Int_t AliHLTTPCPad::SetID(Int_t rowno, Int_t padno)
177 // see header file for class documentation
184 Int_t AliHLTTPCPad::StartEvent()
186 // see header file for class documentation
188 if (fpRawData==NULL) {
197 fpRawData=new AliHLTTPCSignal_t[fNofBins];
199 for (int i=0; i<fNofBins; i++) fpRawData[i]=-1;
201 HLTError("memory allocation failed");
206 HLTWarning("event data acquisition already started");
212 Int_t AliHLTTPCPad::CalculateBaseLine(Int_t reqMinCount)
214 // see header file for class documentation
216 AliHLTTPCSignal_t avBackup=fAverage;
217 //HLTDebug("reqMinCount=%d fCount=%d fTotal=%d fSum=%d fBLMax=%d fBLMin=%d", reqMinCount, fCount, fTotal, fSum, fBLMax, fBLMin);
218 if (fCount>=reqMinCount && fCount>=fTotal/2) {
219 fAverage=fCount>0?fSum/fCount:0;
221 //HLTDebug("average for current event %d (%d - %d)", fAverage, fBLMax, fBLMin);
223 if (fBLMax>ALIHLTPAD_BASELINE_MARGIN) {
225 //HLTDebug("maximum value %d exceeds margin for base line (%d) "
226 // "-> re-evaluate base line", fBLMax, ALIHLTPAD_BASELINE_MARGIN);
228 for (Int_t i=fFirstBLBin; i<fNofBins; i++)
229 if (fpRawData[i]>=0) AddBaseLineValue(i, fpRawData[i]);
230 if (fCount>0 && fCount>=reqMinCount && fCount>=fTotal/2) {
231 fAverage=fSum/fCount;
232 //HLTDebug("new average %d", fAverage);
234 // HLTDebug("baseline re-eveluation skipped because of to few "
235 // "contributing bins: total=%d, contributing=%d, req=%d"
236 // "\ndata might be already zero suppressed"
237 // , fTotal, fCount, reqMinCount);
242 HLTError("missing raw data for base line calculation");
247 // calculate average for all events
248 fAverage=((avBackup*fNofEvents)+fAverage)/(fNofEvents+1);
249 //HLTDebug("base line average for %d event(s): %d", fNofEvents+1, fAverage);
257 // HLTDebug("baseline calculation skipped because of to few contributing "
258 // "bins: total=%d, contributing=%d, required=%d \ndata might be "
259 // "already zero suppressed", fTotal, fCount, reqMinCount);
265 Int_t AliHLTTPCPad::StopEvent()
267 // see header file for class documentation
270 AliHLTTPCSignal_t* pData=fpRawData;
276 } else if (fNofBins>0) {
277 HLTError("event data acquisition not started");
283 Int_t AliHLTTPCPad::ResetHistory()
285 // see header file for class documentation
292 Int_t AliHLTTPCPad::SetThreshold(AliHLTTPCSignal_t thresh)
294 // see header file for class documentation
300 Int_t AliHLTTPCPad::AddBaseLineValue(Int_t bin, AliHLTTPCSignal_t value)
302 // see header file for class documentation
304 if (bin>=fFirstBLBin) {
305 if (fAverage<0 || value<ALIHLTPAD_BASELINE_MARGIN) {
306 // add to the current sum and count
310 // keep the maximum value for later quality control of the base
315 if (fBLMin<0 || fBLMin>value) {
316 // keep the minimum value for later quality control of the base
322 // HLTDebug("ignoring value %d (bin %d) for base line calculation "
323 // "(current average is %d)",
324 // value, bin, fAverage);
330 Int_t AliHLTTPCPad::SetRawData(Int_t bin, AliHLTTPCSignal_t value)
332 // see header file for class documentation
333 // printf("Row: %d Pad: %d Time: %d Charge %d", fRowNo, fPadNo, bin, value);
338 if (fpRawData[bin]<0) {
339 AddBaseLineValue(bin, value);
342 // ignore value for average calculation
343 HLTWarning("overriding content of bin %d (%d)", bin, fpRawData[bin]);
345 fpRawData[bin]=value;
347 HLTWarning("ignoring neg. raw data");
350 HLTWarning("bin %d out of range (%d)", bin, fNofBins);
353 } else if (fNofBins>0) {
354 HLTError("event cycle not started");
360 Int_t AliHLTTPCPad::Next(Int_t bZeroSuppression)
362 // see header file for class documentation
363 if (fpRawData==NULL) return 0;
364 Int_t iResult=fReadPos<fNofBins;
365 if (iResult>0 && (iResult=(++fReadPos<fNofBins))>0) {
366 if (bZeroSuppression) {
367 while ((iResult=(fReadPos<fNofBins))>0 &&
368 GetCorrectedData(fReadPos)<=0)
375 Int_t AliHLTTPCPad::Rewind(Int_t bZeroSuppression)
377 // see header file for class documentation
378 fReadPos=(bZeroSuppression>0?0:fFirstBLBin)-1;
379 return Next(bZeroSuppression);
382 AliHLTTPCSignal_t AliHLTTPCPad::GetRawData(Int_t bin) const
384 // see header file for class documentation
385 AliHLTTPCSignal_t data=0;
390 HLTWarning("requested bin %d out of range (%d)", bin, fNofBins);
392 } else if (fNofBins>0) {
393 HLTWarning("data only available within event cycle");
398 AliHLTTPCSignal_t AliHLTTPCPad::GetCorrectedData(Int_t bin) const
400 // see header file for class documentation
401 AliHLTTPCSignal_t data=GetRawData(bin)-GetBaseLine(bin);
402 AliHLTTPCSignal_t prev=0;
403 if (bin>1) prev=GetRawData(bin-1)-GetBaseLine(bin-1);
404 AliHLTTPCSignal_t succ=0;
405 if (bin+1<GetSize()) succ=GetRawData(bin+1)-GetBaseLine(bin+1);
413 // the signal is below the base-line and threshold
417 // the neighboring bins are both below base-line/threshold
418 // a real signal is always more than one bin wide because of the shaper
419 if (prev<=0 && succ<=0) data=0;
422 // the bin is inside the range of ignored bins
423 if (bin<fFirstBLBin) data=0;
424 //HLTDebug("fReadPos=%d data=%d threshold=%d raw data=%d base line=%d", fReadPos, data, fThreshold, GetRawData(bin), GetBaseLine(bin));
428 AliHLTTPCSignal_t AliHLTTPCPad::GetBaseLine(Int_t /*bin*/) const //TODO: Why is bin being ignored?
430 // see header file for class documentation
431 AliHLTTPCSignal_t val=0;
433 // we take the minumum value as the base line if it doesn't differ from
434 // the average to much
437 const AliHLTTPCSignal_t kMaxDifference=15;
438 if ((fAverage-fBLMin)<=kMaxDifference) val=fBLMin;
439 else val>kMaxDifference?val-=kMaxDifference:0;
443 // here we should never get
445 HLTFatal("wrong base line value");
450 AliHLTTPCSignal_t AliHLTTPCPad::GetAverage() const
452 // see header file for class documentation
453 return fAverage>0?fAverage:0;
456 Float_t AliHLTTPCPad::GetOccupancy() const
458 // see header file for class documentation
460 if (fpRawData && fNofBins>0) {
461 for (Int_t i=fFirstBLBin; i<fNofBins; i++) {
462 if (GetCorrectedData(i)>0) occupancy+=1;
464 if (fNofBins-fFirstBLBin>0)
465 occupancy/=fNofBins-fFirstBLBin;
470 Float_t AliHLTTPCPad::GetAveragedOccupancy() const
472 // see header file for class documentation
474 // history is not yet implemented
475 return GetOccupancy();
477 void AliHLTTPCPad::PrintRawData()
479 // see header file for class documentation
480 for(Int_t bin=0;bin<AliHLTTPCTransform::GetNTimeBins();bin++){
481 if(GetDataSignal(bin)>0)
482 //This cout should be here since using logging produces output that is much more difficult to read
483 cout<<fRowNo<<"\t"<<fPadNo<<"\t"<<bin<<"\t"<<GetDataSignal(bin)<<endl;
487 void AliHLTTPCPad::ClearCandidates(){
488 fClusterCandidates.clear();
489 fUsedClusterCandidates.clear();
490 fCandidateDigitsVector.clear();
493 void AliHLTTPCPad::SetDataToDefault()
495 // see header file for class documentation
496 // if(fDataSignals && fSignalPositionArray){
497 for(Int_t i =0;i<fSizeOfSignalPositionArray;i++){
498 fDataSignals[fSignalPositionArray[i]]=-1;
500 fSizeOfSignalPositionArray=0;
501 fNGoodSignalsSent = 0;
505 void AliHLTTPCPad::SetDataSignal(Int_t bin,Int_t signal)
507 // see header file for class documentation
508 fDataSignals[bin]=signal;
509 fSignalPositionArray[fSizeOfSignalPositionArray]=bin;
510 fSizeOfSignalPositionArray++;
513 Bool_t AliHLTTPCPad::GetNextGoodSignal(Int_t &time,Int_t &bunchSize){
515 if(fNGoodSignalsSent<fSizeOfSignalPositionArray&&fSizeOfSignalPositionArray>0){
516 time = fSignalPositionArray[fNGoodSignalsSent];
519 while(fNGoodSignalsSent<fSizeOfSignalPositionArray){
520 if(fDataSignals[time+bunchSize+1]>0){
528 // fNGoodSignalsSent++;
534 Int_t AliHLTTPCPad::GetDataSignal(Int_t bin) const
536 // see header file for class documentation
537 return fDataSignals[bin];
540 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){
541 //see headerfile for documentation
543 //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 Bool_t useRMS= kFALSE;
549 HLTInfo("Both RMSThreshold and SignalThreshold defined, using RMSThreshold");
552 if(threshold<1 && nRMS<=0){
553 //setting the data to -1 for this pad
554 HLTInfo("Neither of RMSThreshold and SignalThreshold set, zerosuppression aborted");
558 Int_t fThresholdUsed=threshold;
563 fSizeOfSignalPositionArray=0;
565 for(Int_t i=beginTime;i<endTime+1;i++){
566 if(fDataSignals[i]>0){
568 sumNAdded+=fDataSignals[i]*fDataSignals[i];
569 if (maxVal<fDataSignals[i]) maxVal=fDataSignals[i];
573 else if(threshold>0){
574 for(Int_t i=beginTime;i<endTime+1;i++){
575 if(fDataSignals[i]>0){
577 sumNAdded+=fDataSignals[i];
578 if (maxVal<fDataSignals[i]) maxVal=fDataSignals[i];
583 HLTFatal("This should never happen because this is tested earlier in the code.(nRMSThreshold<1&&signal-threshold<1)");
585 if(nAdded<reqMinPoint){
586 HLTInfo("Number of signals is less than required, zero suppression aborted");
591 HLTInfo("No signals added for this pad, zerosuppression aborted: pad %d row %d",fPadNo,fRowNo);
595 Double_t averageValue=(Double_t)sumNAdded/nAdded;//true average for threshold approach, average of signals squared for rms approach
600 fThresholdUsed =(Int_t)(TMath::Sqrt(averageValue)*nRMS);
603 HLTFatal("average value in ZeroSuppression less than 0, investigation needed. This should never happen");
607 fThresholdUsed = (Int_t)(averageValue + threshold);
609 if (maxVal<fThresholdUsed) return;
611 // Do zero suppression on the adc values within [beginTime,endTime](add the good values)
612 for(Int_t i=beginTime;i<endTime;i++){
613 if(fDataSignals[i]>fThresholdUsed){
614 Int_t firstSignalTime=i;
615 for(Int_t left=1;left<timebinsLeft;left++){//looking 5 to the left of the signal to add tail
616 if(fDataSignals[i-left]-averageValue+valueUnderAverage>0 && i-left>=beginTime){
623 Int_t lastSignalTime=i;
624 while(fDataSignals[lastSignalTime+1]>fThresholdUsed && lastSignalTime+1<endTime){
627 for(Int_t right=1;right<timebinsRight;right++){//looking 5 to the left of the signal to add tail
628 if(fDataSignals[i+right]-averageValue+valueUnderAverage>0&&i+right<endTime){
636 for(Int_t t=firstSignalTime;t<lastSignalTime;t++){
637 fDataSignals[t]=(AliHLTTPCSignal_t)(fDataSignals[t]-averageValue + valueUnderAverage);
638 fSignalPositionArray[fSizeOfSignalPositionArray]=t;
639 fSizeOfSignalPositionArray++;
640 // Matthias Oct 10 2008: trying hard to make the code faster for the
641 // AltroChannelSelection. For that we only need to know there is data
647 //reset the rest of the data
648 Int_t counterSize=fSizeOfSignalPositionArray;
650 for(Int_t d=endTime;d>=beginTime;d--){
651 if(d==fSignalPositionArray[counterSize-1]&&counterSize-1>=0){
658 if(fDataSignals[beginTime+1]<1){
659 fDataSignals[beginTime]=0;
663 void AliHLTTPCPad::AddClusterCandidate(const AliHLTTPCClusters& candidate){
664 fClusterCandidates.push_back(candidate);
665 fUsedClusterCandidates.push_back(0);
668 void AliHLTTPCPad::AddCandidateDigits(const vector<AliHLTTPCDigitData>& candidateDigits){
669 fCandidateDigitsVector.push_back(candidateDigits);
672 vector<AliHLTTPCDigitData> *AliHLTTPCPad::GetCandidateDigits(Int_t candidateIndex){
673 return (size_t(candidateIndex) < fCandidateDigitsVector.size()) ? &fCandidateDigitsVector.at(candidateIndex) :0;