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: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 * Kenneth Aamodt <Kenneth.aamodt@ift.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.
26 // see header file for class documentation
28 // refer to README to build package
30 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
37 #include "AliHLTTPCPad.h"
38 #include "AliHLTStdIncludes.h"
42 #include "AliHLTTPCTransform.h"
43 #include "AliHLTTPCClusters.h"
47 //------------------------------
49 /** margin for the base line be re-avaluated */
50 #define ALIHLTPAD_BASELINE_MARGIN (2*fAverage)
52 /** ROOT macro for the implementation of ROOT specific class methods */
53 ClassImp(AliHLTTPCPad)
55 AliHLTTPCPad::AliHLTTPCPad()
58 fUsedClusterCandidates(),
78 fSignalPositionArray(NULL),
79 fSizeOfSignalPositionArray(0),
84 // see header file for class documentation
86 // refer to README to build package
88 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
89 // HLTInfo("Entering default constructor");
90 fDataSignals= new AliHLTTPCSignal_t[AliHLTTPCTransform::GetNTimeBins()];
91 memset( fDataSignals, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
93 fSignalPositionArray= new Int_t[AliHLTTPCTransform::GetNTimeBins()];
94 memset( fSignalPositionArray, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
95 fSizeOfSignalPositionArray=0;
99 AliHLTTPCPad::AliHLTTPCPad(Int_t dummy)
101 fClusterCandidates(),
102 fUsedClusterCandidates(),
103 fSelectedPad(kFALSE),
122 fSignalPositionArray(NULL),
123 fSizeOfSignalPositionArray(0),
124 fNGoodSignalsSent(0),
128 // see header file for class documentation
130 // refer to README to build package
132 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
133 dummy=0;//to get rid of warning until things are cleaned up better
136 AliHLTTPCPad::AliHLTTPCPad(Int_t offset, Int_t nofBins)
138 fClusterCandidates(),
139 fUsedClusterCandidates(),
140 fSelectedPad(kFALSE),
159 fSignalPositionArray(NULL),
160 fSizeOfSignalPositionArray(0),
161 fNGoodSignalsSent(0),
165 // see header file for class documentation
168 AliHLTTPCPad::~AliHLTTPCPad()
170 // see header file for class documentation
172 HLTWarning("event data acquisition not stopped");
176 delete [] fDataSignals;
179 if (fSignalPositionArray!=NULL) {
180 delete [] fSignalPositionArray;
181 fSignalPositionArray=NULL;
185 Int_t AliHLTTPCPad::SetID(Int_t rowno, Int_t padno)
187 // see header file for class documentation
194 Int_t AliHLTTPCPad::StartEvent()
196 // see header file for class documentation
198 if (fpRawData==NULL) {
207 fpRawData=new AliHLTTPCSignal_t[fNofBins];
209 for (int i=0; i<fNofBins; i++) fpRawData[i]=-1;
211 HLTError("memory allocation failed");
216 HLTWarning("event data acquisition already started");
222 Int_t AliHLTTPCPad::CalculateBaseLine(Int_t reqMinCount)
224 // see header file for class documentation
226 AliHLTTPCSignal_t avBackup=fAverage;
227 //HLTDebug("reqMinCount=%d fCount=%d fTotal=%d fSum=%d fBLMax=%d fBLMin=%d", reqMinCount, fCount, fTotal, fSum, fBLMax, fBLMin);
228 if (fCount>=reqMinCount && fCount>=fTotal/2) {
229 fAverage=fCount>0?fSum/fCount:0;
231 //HLTDebug("average for current event %d (%d - %d)", fAverage, fBLMax, fBLMin);
233 if (fBLMax>ALIHLTPAD_BASELINE_MARGIN) {
235 //HLTDebug("maximum value %d exceeds margin for base line (%d) "
236 // "-> re-evaluate base line", fBLMax, ALIHLTPAD_BASELINE_MARGIN);
238 for (Int_t i=fFirstBLBin; i<fNofBins; i++)
239 if (fpRawData[i]>=0) AddBaseLineValue(i, fpRawData[i]);
240 if (fCount>0 && fCount>=reqMinCount && fCount>=fTotal/2) {
241 fAverage=fSum/fCount;
242 //HLTDebug("new average %d", fAverage);
244 // HLTDebug("baseline re-eveluation skipped because of to few "
245 // "contributing bins: total=%d, contributing=%d, req=%d"
246 // "\ndata might be already zero suppressed"
247 // , fTotal, fCount, reqMinCount);
252 HLTError("missing raw data for base line calculation");
257 // calculate average for all events
258 fAverage=((avBackup*fNofEvents)+fAverage)/(fNofEvents+1);
259 //HLTDebug("base line average for %d event(s): %d", fNofEvents+1, fAverage);
267 // HLTDebug("baseline calculation skipped because of to few contributing "
268 // "bins: total=%d, contributing=%d, required=%d \ndata might be "
269 // "already zero suppressed", fTotal, fCount, reqMinCount);
275 Int_t AliHLTTPCPad::StopEvent()
277 // see header file for class documentation
280 AliHLTTPCSignal_t* pData=fpRawData;
286 } else if (fNofBins>0) {
287 HLTError("event data acquisition not started");
293 Int_t AliHLTTPCPad::ResetHistory()
295 // see header file for class documentation
302 Int_t AliHLTTPCPad::SetThreshold(AliHLTTPCSignal_t thresh)
304 // see header file for class documentation
310 Int_t AliHLTTPCPad::AddBaseLineValue(Int_t bin, AliHLTTPCSignal_t value)
312 // see header file for class documentation
314 if (bin>=fFirstBLBin) {
315 if (fAverage<0 || value<ALIHLTPAD_BASELINE_MARGIN) {
316 // add to the current sum and count
320 // keep the maximum value for later quality control of the base
325 if (fBLMin<0 || fBLMin>value) {
326 // keep the minimum value for later quality control of the base
332 // HLTDebug("ignoring value %d (bin %d) for base line calculation "
333 // "(current average is %d)",
334 // value, bin, fAverage);
340 Int_t AliHLTTPCPad::SetRawData(Int_t bin, AliHLTTPCSignal_t value)
342 // see header file for class documentation
343 // printf("Row: %d Pad: %d Time: %d Charge %d", fRowNo, fPadNo, bin, value);
348 if (fpRawData[bin]<0) {
349 AddBaseLineValue(bin, value);
352 // ignore value for average calculation
353 HLTWarning("overriding content of bin %d (%d)", bin, fpRawData[bin]);
355 fpRawData[bin]=value;
357 HLTWarning("ignoring neg. raw data");
360 HLTWarning("bin %d out of range (%d)", bin, fNofBins);
363 } else if (fNofBins>0) {
364 HLTError("event cycle not started");
370 Int_t AliHLTTPCPad::Next(Int_t bZeroSuppression)
372 // see header file for class documentation
373 if (fpRawData==NULL) return 0;
374 Int_t iResult=fReadPos<fNofBins;
375 if (iResult>0 && (iResult=(++fReadPos<fNofBins))>0) {
376 if (bZeroSuppression) {
377 while ((iResult=(fReadPos<fNofBins))>0 &&
378 GetCorrectedData(fReadPos)<=0)
385 Int_t AliHLTTPCPad::Rewind(Int_t bZeroSuppression)
387 // see header file for class documentation
388 fReadPos=(bZeroSuppression>0?0:fFirstBLBin)-1;
389 return Next(bZeroSuppression);
392 AliHLTTPCSignal_t AliHLTTPCPad::GetRawData(Int_t bin) const
394 // see header file for class documentation
395 AliHLTTPCSignal_t data=0;
400 HLTWarning("requested bin %d out of range (%d)", bin, fNofBins);
402 } else if (fNofBins>0) {
403 HLTWarning("data only available within event cycle");
408 AliHLTTPCSignal_t AliHLTTPCPad::GetCorrectedData(Int_t bin) const
410 // see header file for class documentation
411 AliHLTTPCSignal_t data=GetRawData(bin)-GetBaseLine(bin);
412 AliHLTTPCSignal_t prev=0;
413 if (bin>1) prev=GetRawData(bin-1)-GetBaseLine(bin-1);
414 AliHLTTPCSignal_t succ=0;
415 if (bin+1<GetSize()) succ=GetRawData(bin+1)-GetBaseLine(bin+1);
423 // the signal is below the base-line and threshold
427 // the neighboring bins are both below base-line/threshold
428 // a real signal is always more than one bin wide because of the shaper
429 if (prev<=0 && succ<=0) data=0;
432 // the bin is inside the range of ignored bins
433 if (bin<fFirstBLBin) data=0;
434 //HLTDebug("fReadPos=%d data=%d threshold=%d raw data=%d base line=%d", fReadPos, data, fThreshold, GetRawData(bin), GetBaseLine(bin));
438 AliHLTTPCSignal_t AliHLTTPCPad::GetBaseLine(Int_t /*bin*/) const //TODO: Why is bin being ignored?
440 // see header file for class documentation
441 AliHLTTPCSignal_t val=0;
443 // we take the minumum value as the base line if it doesn't differ from
444 // the average to much
447 const AliHLTTPCSignal_t kMaxDifference=15;
448 if ((fAverage-fBLMin)<=kMaxDifference) val=fBLMin;
449 else val>kMaxDifference?val-=kMaxDifference:0;
453 // here we should never get
455 HLTFatal("wrong base line value");
460 AliHLTTPCSignal_t AliHLTTPCPad::GetAverage() const
462 // see header file for class documentation
463 return fAverage>0?fAverage:0;
466 Float_t AliHLTTPCPad::GetOccupancy() const
468 // see header file for class documentation
470 if (fpRawData && fNofBins>0) {
471 for (Int_t i=fFirstBLBin; i<fNofBins; i++) {
472 if (GetCorrectedData(i)>0) occupancy+=1;
474 if (fNofBins-fFirstBLBin>0)
475 occupancy/=fNofBins-fFirstBLBin;
480 Float_t AliHLTTPCPad::GetAveragedOccupancy() const
482 // see header file for class documentation
484 // history is not yet implemented
485 return GetOccupancy();
487 void AliHLTTPCPad::PrintRawData()
489 // see header file for class documentation
490 for(Int_t bin=0;bin<AliHLTTPCTransform::GetNTimeBins();bin++){
491 if(GetDataSignal(bin)>0)
492 //This cout should be here since using logging produces output that is much more difficult to read
493 cout<<fRowNo<<"\t"<<fPadNo<<"\t"<<bin<<"\t"<<GetDataSignal(bin)<<endl;
497 void AliHLTTPCPad::ClearCandidates(){
498 fClusterCandidates.clear();
499 fUsedClusterCandidates.clear();
502 void AliHLTTPCPad::SetDataToDefault()
504 // see header file for class documentation
505 // if(fDataSignals && fSignalPositionArray){
506 for(Int_t i =0;i<fSizeOfSignalPositionArray;i++){
507 fDataSignals[fSignalPositionArray[i]]=-1;
509 fSizeOfSignalPositionArray=0;
510 fNGoodSignalsSent = 0;
514 void AliHLTTPCPad::SetDataSignal(Int_t bin,Int_t signal)
516 // see header file for class documentation
517 fDataSignals[bin]=signal;
518 fSignalPositionArray[fSizeOfSignalPositionArray]=bin;
519 fSizeOfSignalPositionArray++;
522 Bool_t AliHLTTPCPad::GetNextGoodSignal(Int_t &time, Int_t &signal){
523 if(fNGoodSignalsSent<fSizeOfSignalPositionArray&&fSizeOfSignalPositionArray>0){
524 time = fSignalPositionArray[fNGoodSignalsSent];
525 signal = GetDataSignal(time);
533 Bool_t AliHLTTPCPad::GetNextGoodSignal(Int_t &time,Int_t &bunchSize,Int_t dummy){
534 dummy=0;//to get rid of warning until things are cleaned up better
535 if(fNGoodSignalsSent<fSizeOfSignalPositionArray&&fSizeOfSignalPositionArray>0){
536 time = fSignalPositionArray[fNGoodSignalsSent];
539 while(fNGoodSignalsSent<fSizeOfSignalPositionArray){
540 if(fDataSignals[time+bunchSize+1]>0){
554 Int_t AliHLTTPCPad::GetDataSignal(Int_t bin) const
556 // see header file for class documentation
557 return fDataSignals[bin];
560 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){
561 //see headerfile for documentation
563 //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);
565 Bool_t useRMS= kFALSE;
569 HLTInfo("Both RMSThreshold and SignalThreshold defined, using RMSThreshold");
572 if(threshold<1 && nRMS<=0){
573 //setting the data to -1 for this pad
574 HLTInfo("Neither of RMSThreshold and SignalThreshold set, zerosuppression aborted");
578 Int_t fThresholdUsed=threshold;
582 fSizeOfSignalPositionArray=0;
584 for(Int_t i=beginTime;i<endTime+1;i++){
585 if(fDataSignals[i]>0){
587 sumNAdded+=fDataSignals[i]*fDataSignals[i];
591 else if(threshold>0){
592 for(Int_t i=beginTime;i<endTime+1;i++){
593 if(fDataSignals[i]>0){
595 sumNAdded+=fDataSignals[i];
600 HLTFatal("This should never happen because this is tested earlier in the code.(nRMSThreshold<1&&signal-threshold<1)");
602 if(nAdded<reqMinPoint){
603 HLTInfo("Number of signals is less than required, zero suppression aborted");
608 HLTInfo("No signals added for this pad, zerosuppression aborted: pad %d row %d",fPadNo,fRowNo);
612 Double_t averageValue=(Double_t)sumNAdded/nAdded;//true average for threshold approach, average of signals squared for rms approach
617 fThresholdUsed =(Int_t)(TMath::Sqrt(averageValue)*nRMS);
620 HLTFatal("average value in ZeroSuppression less than 0, investigation needed. This should never happen");
624 fThresholdUsed = (Int_t)(averageValue + threshold);
627 // Do zero suppression on the adc values within [beginTime,endTime](add the good values)
628 for(Int_t i=beginTime;i<endTime;i++){
629 if(fDataSignals[i]>fThresholdUsed){
630 Int_t firstSignalTime=i;
631 for(Int_t left=1;left<timebinsLeft;left++){//looking 5 to the left of the signal to add tail
632 if(fDataSignals[i-left]-averageValue+valueUnderAverage>0 && i-left>=beginTime){
639 Int_t lastSignalTime=i;
640 while(fDataSignals[lastSignalTime+1]>fThresholdUsed && lastSignalTime+1<endTime){
643 for(Int_t right=1;right<timebinsRight;right++){//looking 5 to the left of the signal to add tail
644 if(fDataSignals[i+right]-averageValue+valueUnderAverage>0&&i+right<endTime){
652 for(Int_t t=firstSignalTime;t<lastSignalTime;t++){
653 fDataSignals[t]=(AliHLTTPCSignal_t)(fDataSignals[t]-averageValue + valueUnderAverage);
654 fSignalPositionArray[fSizeOfSignalPositionArray]=t;
655 fSizeOfSignalPositionArray++;
660 //reset the rest of the data
661 Int_t counterSize=fSizeOfSignalPositionArray;
663 for(Int_t d=endTime;d>=beginTime;d--){
664 if(d==fSignalPositionArray[counterSize-1]&&counterSize-1>=0){
671 if(fDataSignals[beginTime+1]<1){
672 fDataSignals[beginTime]=0;
676 void AliHLTTPCPad::AddClusterCandidate(AliHLTTPCClusters candidate){
677 fClusterCandidates.push_back(candidate);
678 fUsedClusterCandidates.push_back(0);