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.
27 #include "AliHLTTPCPad.h"
28 #include "AliHLTStdIncludes.h"
32 #include "AliHLTTPCTransform.h"
33 #include "AliHLTTPCClusters.h"
37 //------------------------------
39 /** margin for the base line be re-avaluated */
40 #define ALIHLTPAD_BASELINE_MARGIN (2*fAverage)
42 /** ROOT macro for the implementation of ROOT specific class methods */
43 ClassImp(AliHLTTPCPad)
45 AliHLTTPCPad::AliHLTTPCPad()
48 fUsedClusterCandidates(),
68 fSignalPositionArray(NULL),
69 fSizeOfSignalPositionArray(0),
71 fCandidateDigitsVector()
73 // see header file for class documentation
75 // refer to README to build package
77 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
78 // HLTInfo("Entering default constructor");
79 fDataSignals= new AliHLTTPCSignal_t[AliHLTTPCTransform::GetNTimeBins()];
80 memset( fDataSignals, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
82 fSignalPositionArray= new Int_t[AliHLTTPCTransform::GetNTimeBins()];
83 memset( fSignalPositionArray, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
84 fSizeOfSignalPositionArray=0;
88 AliHLTTPCPad::AliHLTTPCPad(Int_t /*dummy*/)
91 fUsedClusterCandidates(),
111 fSignalPositionArray(NULL),
112 fSizeOfSignalPositionArray(0),
113 fNGoodSignalsSent(0),
114 fCandidateDigitsVector()
116 // see header file for class documentation
118 // refer to README to build package
120 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
123 AliHLTTPCPad::AliHLTTPCPad(Int_t offset, Int_t nofBins)
125 fClusterCandidates(),
126 fUsedClusterCandidates(),
127 fSelectedPad(kFALSE),
146 fSignalPositionArray(NULL),
147 fSizeOfSignalPositionArray(0),
148 fNGoodSignalsSent(0),
149 fCandidateDigitsVector()
151 // see header file for class documentation
154 AliHLTTPCPad::~AliHLTTPCPad()
156 // see header file for class documentation
158 HLTWarning("event data acquisition not stopped");
162 delete [] fDataSignals;
165 if (fSignalPositionArray!=NULL) {
166 delete [] fSignalPositionArray;
167 fSignalPositionArray=NULL;
171 Int_t AliHLTTPCPad::SetID(Int_t rowno, Int_t padno)
173 // see header file for class documentation
180 Int_t AliHLTTPCPad::StartEvent()
182 // see header file for class documentation
184 if (fpRawData==NULL) {
193 fpRawData=new AliHLTTPCSignal_t[fNofBins];
195 for (int i=0; i<fNofBins; i++) fpRawData[i]=-1;
197 HLTError("memory allocation failed");
202 HLTWarning("event data acquisition already started");
208 Int_t AliHLTTPCPad::CalculateBaseLine(Int_t reqMinCount)
210 // see header file for class documentation
212 AliHLTTPCSignal_t avBackup=fAverage;
213 //HLTDebug("reqMinCount=%d fCount=%d fTotal=%d fSum=%d fBLMax=%d fBLMin=%d", reqMinCount, fCount, fTotal, fSum, fBLMax, fBLMin);
214 if (fCount>=reqMinCount && fCount>=fTotal/2) {
215 fAverage=fCount>0?fSum/fCount:0;
217 //HLTDebug("average for current event %d (%d - %d)", fAverage, fBLMax, fBLMin);
219 if (fBLMax>ALIHLTPAD_BASELINE_MARGIN) {
221 //HLTDebug("maximum value %d exceeds margin for base line (%d) "
222 // "-> re-evaluate base line", fBLMax, ALIHLTPAD_BASELINE_MARGIN);
224 for (Int_t i=fFirstBLBin; i<fNofBins; i++)
225 if (fpRawData[i]>=0) AddBaseLineValue(i, fpRawData[i]);
226 if (fCount>0 && fCount>=reqMinCount && fCount>=fTotal/2) {
227 fAverage=fSum/fCount;
228 //HLTDebug("new average %d", fAverage);
230 // HLTDebug("baseline re-eveluation skipped because of to few "
231 // "contributing bins: total=%d, contributing=%d, req=%d"
232 // "\ndata might be already zero suppressed"
233 // , fTotal, fCount, reqMinCount);
238 HLTError("missing raw data for base line calculation");
243 // calculate average for all events
244 fAverage=((avBackup*fNofEvents)+fAverage)/(fNofEvents+1);
245 //HLTDebug("base line average for %d event(s): %d", fNofEvents+1, fAverage);
253 // HLTDebug("baseline calculation skipped because of to few contributing "
254 // "bins: total=%d, contributing=%d, required=%d \ndata might be "
255 // "already zero suppressed", fTotal, fCount, reqMinCount);
261 Int_t AliHLTTPCPad::StopEvent()
263 // see header file for class documentation
266 AliHLTTPCSignal_t* pData=fpRawData;
272 } else if (fNofBins>0) {
273 HLTError("event data acquisition not started");
279 Int_t AliHLTTPCPad::ResetHistory()
281 // see header file for class documentation
288 Int_t AliHLTTPCPad::SetThreshold(AliHLTTPCSignal_t thresh)
290 // see header file for class documentation
296 Int_t AliHLTTPCPad::AddBaseLineValue(Int_t bin, AliHLTTPCSignal_t value)
298 // see header file for class documentation
300 if (bin>=fFirstBLBin) {
301 if (fAverage<0 || value<ALIHLTPAD_BASELINE_MARGIN) {
302 // add to the current sum and count
306 // keep the maximum value for later quality control of the base
311 if (fBLMin<0 || fBLMin>value) {
312 // keep the minimum value for later quality control of the base
318 // HLTDebug("ignoring value %d (bin %d) for base line calculation "
319 // "(current average is %d)",
320 // value, bin, fAverage);
326 Int_t AliHLTTPCPad::SetRawData(Int_t bin, AliHLTTPCSignal_t value)
328 // see header file for class documentation
329 // printf("Row: %d Pad: %d Time: %d Charge %d", fRowNo, fPadNo, bin, value);
334 if (fpRawData[bin]<0) {
335 AddBaseLineValue(bin, value);
338 // ignore value for average calculation
339 HLTWarning("overriding content of bin %d (%d)", bin, fpRawData[bin]);
341 fpRawData[bin]=value;
343 HLTWarning("ignoring neg. raw data");
346 HLTWarning("bin %d out of range (%d)", bin, fNofBins);
349 } else if (fNofBins>0) {
350 HLTError("event cycle not started");
356 Int_t AliHLTTPCPad::Next(Int_t bZeroSuppression)
358 // see header file for class documentation
359 if (fpRawData==NULL) return 0;
360 Int_t iResult=fReadPos<fNofBins;
361 if (iResult>0 && (iResult=(++fReadPos<fNofBins))>0) {
362 if (bZeroSuppression) {
363 while ((iResult=(fReadPos<fNofBins))>0 &&
364 GetCorrectedData(fReadPos)<=0)
371 Int_t AliHLTTPCPad::Rewind(Int_t bZeroSuppression)
373 // see header file for class documentation
374 fReadPos=(bZeroSuppression>0?0:fFirstBLBin)-1;
375 return Next(bZeroSuppression);
378 AliHLTTPCSignal_t AliHLTTPCPad::GetRawData(Int_t bin) const
380 // see header file for class documentation
381 AliHLTTPCSignal_t data=0;
386 HLTWarning("requested bin %d out of range (%d)", bin, fNofBins);
388 } else if (fNofBins>0) {
389 HLTWarning("data only available within event cycle");
394 AliHLTTPCSignal_t AliHLTTPCPad::GetCorrectedData(Int_t bin) const
396 // see header file for class documentation
397 AliHLTTPCSignal_t data=GetRawData(bin)-GetBaseLine(bin);
398 AliHLTTPCSignal_t prev=0;
399 if (bin>1) prev=GetRawData(bin-1)-GetBaseLine(bin-1);
400 AliHLTTPCSignal_t succ=0;
401 if (bin+1<GetSize()) succ=GetRawData(bin+1)-GetBaseLine(bin+1);
409 // the signal is below the base-line and threshold
413 // the neighboring bins are both below base-line/threshold
414 // a real signal is always more than one bin wide because of the shaper
415 if (prev<=0 && succ<=0) data=0;
418 // the bin is inside the range of ignored bins
419 if (bin<fFirstBLBin) data=0;
420 //HLTDebug("fReadPos=%d data=%d threshold=%d raw data=%d base line=%d", fReadPos, data, fThreshold, GetRawData(bin), GetBaseLine(bin));
424 AliHLTTPCSignal_t AliHLTTPCPad::GetBaseLine(Int_t /*bin*/) const //TODO: Why is bin being ignored?
426 // see header file for class documentation
427 AliHLTTPCSignal_t val=0;
429 // we take the minumum value as the base line if it doesn't differ from
430 // the average to much
433 const AliHLTTPCSignal_t kMaxDifference=15;
434 if ((fAverage-fBLMin)<=kMaxDifference) val=fBLMin;
435 else val>kMaxDifference?val-=kMaxDifference:0;
439 // here we should never get
441 HLTFatal("wrong base line value");
446 AliHLTTPCSignal_t AliHLTTPCPad::GetAverage() const
448 // see header file for class documentation
449 return fAverage>0?fAverage:0;
452 Float_t AliHLTTPCPad::GetOccupancy() const
454 // see header file for class documentation
456 if (fpRawData && fNofBins>0) {
457 for (Int_t i=fFirstBLBin; i<fNofBins; i++) {
458 if (GetCorrectedData(i)>0) occupancy+=1;
460 if (fNofBins-fFirstBLBin>0)
461 occupancy/=fNofBins-fFirstBLBin;
466 Float_t AliHLTTPCPad::GetAveragedOccupancy() const
468 // see header file for class documentation
470 // history is not yet implemented
471 return GetOccupancy();
473 void AliHLTTPCPad::PrintRawData()
475 // see header file for class documentation
476 for(Int_t bin=0;bin<AliHLTTPCTransform::GetNTimeBins();bin++){
477 if(GetDataSignal(bin)>0)
478 //This cout should be here since using logging produces output that is much more difficult to read
479 cout<<fRowNo<<"\t"<<fPadNo<<"\t"<<bin<<"\t"<<GetDataSignal(bin)<<endl;
483 void AliHLTTPCPad::ClearCandidates(){
484 fClusterCandidates.clear();
485 fUsedClusterCandidates.clear();
486 fCandidateDigitsVector.clear();
489 void AliHLTTPCPad::SetDataToDefault()
491 // see header file for class documentation
492 // if(fDataSignals && fSignalPositionArray){
493 for(Int_t i =0;i<fSizeOfSignalPositionArray;i++){
494 fDataSignals[fSignalPositionArray[i]]=-1;
496 fSizeOfSignalPositionArray=0;
497 fNGoodSignalsSent = 0;
501 void AliHLTTPCPad::SetDataSignal(Int_t bin,Int_t signal)
503 // see header file for class documentation
504 fDataSignals[bin]=signal;
505 fSignalPositionArray[fSizeOfSignalPositionArray]=bin;
506 fSizeOfSignalPositionArray++;
509 Bool_t AliHLTTPCPad::GetNextGoodSignal(Int_t &time,Int_t &bunchSize){
511 if(fNGoodSignalsSent<fSizeOfSignalPositionArray&&fSizeOfSignalPositionArray>0){
512 time = fSignalPositionArray[fNGoodSignalsSent];
515 while(fNGoodSignalsSent<fSizeOfSignalPositionArray){
516 if(fDataSignals[time+bunchSize+1]>0){
524 // fNGoodSignalsSent++;
530 Int_t AliHLTTPCPad::GetDataSignal(Int_t bin) const
532 // see header file for class documentation
533 return fDataSignals[bin];
536 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){
537 //see headerfile for documentation
539 //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 Bool_t useRMS= kFALSE;
545 HLTInfo("Both RMSThreshold and SignalThreshold defined, using RMSThreshold");
548 if(threshold<1 && nRMS<=0){
549 //setting the data to -1 for this pad
550 HLTInfo("Neither of RMSThreshold and SignalThreshold set, zerosuppression aborted");
554 Int_t fThresholdUsed=threshold;
559 fSizeOfSignalPositionArray=0;
561 for(Int_t i=beginTime;i<endTime+1;i++){
562 if(fDataSignals[i]>0){
564 sumNAdded+=fDataSignals[i]*fDataSignals[i];
565 if (maxVal<fDataSignals[i]) maxVal=fDataSignals[i];
569 else if(threshold>0){
570 for(Int_t i=beginTime;i<endTime+1;i++){
571 if(fDataSignals[i]>0){
573 sumNAdded+=fDataSignals[i];
574 if (maxVal<fDataSignals[i]) maxVal=fDataSignals[i];
579 HLTFatal("This should never happen because this is tested earlier in the code.(nRMSThreshold<1&&signal-threshold<1)");
581 if(nAdded<reqMinPoint){
582 HLTInfo("Number of signals is less than required, zero suppression aborted");
587 HLTInfo("No signals added for this pad, zerosuppression aborted: pad %d row %d",fPadNo,fRowNo);
591 Double_t averageValue=(Double_t)sumNAdded/nAdded;//true average for threshold approach, average of signals squared for rms approach
596 fThresholdUsed =(Int_t)(TMath::Sqrt(averageValue)*nRMS);
599 HLTFatal("average value in ZeroSuppression less than 0, investigation needed. This should never happen");
603 fThresholdUsed = (Int_t)(averageValue + threshold);
605 if (maxVal<fThresholdUsed) return;
607 // Do zero suppression on the adc values within [beginTime,endTime](add the good values)
608 for(Int_t i=beginTime;i<endTime;i++){
609 if(fDataSignals[i]>fThresholdUsed){
610 Int_t firstSignalTime=i;
611 for(Int_t left=1;left<timebinsLeft;left++){//looking 5 to the left of the signal to add tail
612 if(fDataSignals[i-left]-averageValue+valueUnderAverage>0 && i-left>=beginTime){
619 Int_t lastSignalTime=i;
620 while(fDataSignals[lastSignalTime+1]>fThresholdUsed && lastSignalTime+1<endTime){
623 for(Int_t right=1;right<timebinsRight;right++){//looking 5 to the left of the signal to add tail
624 if(fDataSignals[i+right]-averageValue+valueUnderAverage>0&&i+right<endTime){
632 for(Int_t t=firstSignalTime;t<lastSignalTime;t++){
633 fDataSignals[t]=(AliHLTTPCSignal_t)(fDataSignals[t]-averageValue + valueUnderAverage);
634 fSignalPositionArray[fSizeOfSignalPositionArray]=t;
635 fSizeOfSignalPositionArray++;
636 // Matthias Oct 10 2008: trying hard to make the code faster for the
637 // AltroChannelSelection. For that we only need to know there is data
643 //reset the rest of the data
644 Int_t counterSize=fSizeOfSignalPositionArray;
646 for(Int_t d=endTime;d>=beginTime;d--){
647 if(d==fSignalPositionArray[counterSize-1]&&counterSize-1>=0){
654 if(fDataSignals[beginTime+1]<1){
655 fDataSignals[beginTime]=0;
659 void AliHLTTPCPad::AddClusterCandidate(const AliHLTTPCClusters& candidate){
660 fClusterCandidates.push_back(candidate);
661 fUsedClusterCandidates.push_back(0);
664 void AliHLTTPCPad::AddCandidateDigits(const vector<AliHLTTPCDigitData>& candidateDigits){
665 fCandidateDigitsVector.push_back(candidateDigits);
668 vector<AliHLTTPCDigitData> *AliHLTTPCPad::GetCandidateDigits(Int_t candidateIndex){
669 return (size_t(candidateIndex) < fCandidateDigitsVector.size()) ? &fCandidateDigitsVector.at(candidateIndex) :0;