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(),
76 fSignalPositionArray(NULL),
77 fSizeOfSignalPositionArray(0),
82 // see header file for class documentation
84 // refer to README to build package
86 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
87 // HLTInfo("Entering default constructor");
88 fDataSignals= new AliHLTTPCSignal_t[AliHLTTPCTransform::GetNTimeBins()];
89 memset( fDataSignals, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
91 fSignalPositionArray= new Int_t[AliHLTTPCTransform::GetNTimeBins()];
92 memset( fSignalPositionArray, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
93 fSizeOfSignalPositionArray=0;
97 AliHLTTPCPad::AliHLTTPCPad(Int_t dummy)
100 fUsedClusterCandidates(),
118 fSignalPositionArray(NULL),
119 fSizeOfSignalPositionArray(0),
120 fNGoodSignalsSent(0),
124 // see header file for class documentation
126 // refer to README to build package
128 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
129 dummy=0;//to get rid of warning until things are cleaned up better
132 AliHLTTPCPad::AliHLTTPCPad(Int_t offset, Int_t nofBins)
134 fClusterCandidates(),
135 fUsedClusterCandidates(),
153 fSignalPositionArray(NULL),
154 fSizeOfSignalPositionArray(0),
155 fNGoodSignalsSent(0),
159 // see header file for class documentation
162 AliHLTTPCPad::~AliHLTTPCPad()
164 // see header file for class documentation
166 HLTWarning("event data acquisition not stopped");
170 delete [] fDataSignals;
173 if (fSignalPositionArray!=NULL) {
174 delete [] fSignalPositionArray;
175 fSignalPositionArray=NULL;
179 Int_t AliHLTTPCPad::SetID(Int_t rowno, Int_t padno)
181 // see header file for class documentation
188 Int_t AliHLTTPCPad::StartEvent()
190 // see header file for class documentation
192 if (fpRawData==NULL) {
201 fpRawData=new AliHLTTPCSignal_t[fNofBins];
203 for (int i=0; i<fNofBins; i++) fpRawData[i]=-1;
205 HLTError("memory allocation failed");
210 HLTWarning("event data acquisition already started");
216 Int_t AliHLTTPCPad::CalculateBaseLine(Int_t reqMinCount)
218 // see header file for class documentation
220 AliHLTTPCSignal_t avBackup=fAverage;
221 //HLTDebug("reqMinCount=%d fCount=%d fTotal=%d fSum=%d fBLMax=%d fBLMin=%d", reqMinCount, fCount, fTotal, fSum, fBLMax, fBLMin);
222 if (fCount>=reqMinCount && fCount>=fTotal/2) {
223 fAverage=fCount>0?fSum/fCount:0;
225 //HLTDebug("average for current event %d (%d - %d)", fAverage, fBLMax, fBLMin);
227 if (fBLMax>ALIHLTPAD_BASELINE_MARGIN) {
229 //HLTDebug("maximum value %d exceeds margin for base line (%d) "
230 // "-> re-evaluate base line", fBLMax, ALIHLTPAD_BASELINE_MARGIN);
232 for (Int_t i=fFirstBLBin; i<fNofBins; i++)
233 if (fpRawData[i]>=0) AddBaseLineValue(i, fpRawData[i]);
234 if (fCount>0 && fCount>=reqMinCount && fCount>=fTotal/2) {
235 fAverage=fSum/fCount;
236 //HLTDebug("new average %d", fAverage);
238 // HLTDebug("baseline re-eveluation skipped because of to few "
239 // "contributing bins: total=%d, contributing=%d, req=%d"
240 // "\ndata might be already zero suppressed"
241 // , fTotal, fCount, reqMinCount);
246 HLTError("missing raw data for base line calculation");
251 // calculate average for all events
252 fAverage=((avBackup*fNofEvents)+fAverage)/(fNofEvents+1);
253 //HLTDebug("base line average for %d event(s): %d", fNofEvents+1, fAverage);
261 // HLTDebug("baseline calculation skipped because of to few contributing "
262 // "bins: total=%d, contributing=%d, required=%d \ndata might be "
263 // "already zero suppressed", fTotal, fCount, reqMinCount);
269 Int_t AliHLTTPCPad::StopEvent()
271 // see header file for class documentation
274 AliHLTTPCSignal_t* pData=fpRawData;
280 } else if (fNofBins>0) {
281 HLTError("event data acquisition not started");
287 Int_t AliHLTTPCPad::ResetHistory()
289 // see header file for class documentation
296 Int_t AliHLTTPCPad::SetThreshold(AliHLTTPCSignal_t thresh)
298 // see header file for class documentation
304 Int_t AliHLTTPCPad::AddBaseLineValue(Int_t bin, AliHLTTPCSignal_t value)
306 // see header file for class documentation
308 if (bin>=fFirstBLBin) {
309 if (fAverage<0 || value<ALIHLTPAD_BASELINE_MARGIN) {
310 // add to the current sum and count
314 // keep the maximum value for later quality control of the base
319 if (fBLMin<0 || fBLMin>value) {
320 // keep the minimum value for later quality control of the base
326 // HLTDebug("ignoring value %d (bin %d) for base line calculation "
327 // "(current average is %d)",
328 // value, bin, fAverage);
334 Int_t AliHLTTPCPad::SetRawData(Int_t bin, AliHLTTPCSignal_t value)
336 // see header file for class documentation
337 // printf("Row: %d Pad: %d Time: %d Charge %d", fRowNo, fPadNo, bin, value);
342 if (fpRawData[bin]<0) {
343 AddBaseLineValue(bin, value);
346 // ignore value for average calculation
347 HLTWarning("overriding content of bin %d (%d)", bin, fpRawData[bin]);
349 fpRawData[bin]=value;
351 HLTWarning("ignoring neg. raw data");
354 HLTWarning("bin %d out of range (%d)", bin, fNofBins);
357 } else if (fNofBins>0) {
358 HLTError("event cycle not started");
364 Int_t AliHLTTPCPad::Next(Int_t bZeroSuppression)
366 // see header file for class documentation
367 if (fpRawData==NULL) return 0;
368 Int_t iResult=fReadPos<fNofBins;
369 if (iResult>0 && (iResult=(++fReadPos<fNofBins))>0) {
370 if (bZeroSuppression) {
371 while ((iResult=(fReadPos<fNofBins))>0 &&
372 GetCorrectedData(fReadPos)<=0)
379 Int_t AliHLTTPCPad::Rewind(Int_t bZeroSuppression)
381 // see header file for class documentation
382 fReadPos=(bZeroSuppression>0?0:fFirstBLBin)-1;
383 return Next(bZeroSuppression);
386 AliHLTTPCSignal_t AliHLTTPCPad::GetRawData(Int_t bin) const
388 // see header file for class documentation
389 AliHLTTPCSignal_t data=0;
394 HLTWarning("requested bin %d out of range (%d)", bin, fNofBins);
396 } else if (fNofBins>0) {
397 HLTWarning("data only available within event cycle");
402 AliHLTTPCSignal_t AliHLTTPCPad::GetCorrectedData(Int_t bin) const
404 // see header file for class documentation
405 AliHLTTPCSignal_t data=GetRawData(bin)-GetBaseLine(bin);
406 AliHLTTPCSignal_t prev=0;
407 if (bin>1) prev=GetRawData(bin-1)-GetBaseLine(bin-1);
408 AliHLTTPCSignal_t succ=0;
409 if (bin+1<GetSize()) succ=GetRawData(bin+1)-GetBaseLine(bin+1);
417 // the signal is below the base-line and threshold
421 // the neighboring bins are both below base-line/threshold
422 // a real signal is always more than one bin wide because of the shaper
423 if (prev<=0 && succ<=0) data=0;
426 // the bin is inside the range of ignored bins
427 if (bin<fFirstBLBin) data=0;
428 //HLTDebug("fReadPos=%d data=%d threshold=%d raw data=%d base line=%d", fReadPos, data, fThreshold, GetRawData(bin), GetBaseLine(bin));
432 AliHLTTPCSignal_t AliHLTTPCPad::GetBaseLine(Int_t /*bin*/) const //TODO: Why is bin being ignored?
434 // see header file for class documentation
435 AliHLTTPCSignal_t val=0;
437 // we take the minumum value as the base line if it doesn't differ from
438 // the average to much
441 const AliHLTTPCSignal_t kMaxDifference=15;
442 if ((fAverage-fBLMin)<=kMaxDifference) val=fBLMin;
443 else val>kMaxDifference?val-=kMaxDifference:0;
447 // here we should never get
449 HLTFatal("wrong base line value");
454 AliHLTTPCSignal_t AliHLTTPCPad::GetAverage() const
456 // see header file for class documentation
457 return fAverage>0?fAverage:0;
460 Float_t AliHLTTPCPad::GetOccupancy() const
462 // see header file for class documentation
464 if (fpRawData && fNofBins>0) {
465 for (Int_t i=fFirstBLBin; i<fNofBins; i++) {
466 if (GetCorrectedData(i)>0) occupancy+=1;
468 if (fNofBins-fFirstBLBin>0)
469 occupancy/=fNofBins-fFirstBLBin;
474 Float_t AliHLTTPCPad::GetAveragedOccupancy() const
476 // see header file for class documentation
478 // history is not yet implemented
479 return GetOccupancy();
481 void AliHLTTPCPad::PrintRawData()
483 // see header file for class documentation
484 for(Int_t bin=0;bin<AliHLTTPCTransform::GetNTimeBins();bin++){
485 if(GetDataSignal(bin)>0)
486 //This cout should be here since using logging produces output that is much more difficult to read
487 cout<<fRowNo<<"\t"<<fPadNo<<"\t"<<bin<<"\t"<<GetDataSignal(bin)<<endl;
491 void AliHLTTPCPad::ClearCandidates(){
492 fClusterCandidates.clear();
493 fUsedClusterCandidates.clear();
496 void AliHLTTPCPad::SetDataToDefault()
498 // see header file for class documentation
499 // if(fDataSignals && fSignalPositionArray){
500 for(Int_t i =0;i<fSizeOfSignalPositionArray;i++){
501 fDataSignals[fSignalPositionArray[i]]=-1;
503 fSizeOfSignalPositionArray=0;
504 fNGoodSignalsSent = 0;
508 void AliHLTTPCPad::SetDataSignal(Int_t bin,Int_t signal)
510 // see header file for class documentation
511 fDataSignals[bin]=signal;
512 fSignalPositionArray[fSizeOfSignalPositionArray]=bin;
513 fSizeOfSignalPositionArray++;
516 Bool_t AliHLTTPCPad::GetNextGoodSignal(Int_t &time, Int_t &signal){
517 if(fNGoodSignalsSent<fSizeOfSignalPositionArray&&fSizeOfSignalPositionArray>0){
518 time = fSignalPositionArray[fNGoodSignalsSent];
519 signal = GetDataSignal(time);
527 Bool_t AliHLTTPCPad::GetNextGoodSignal(Int_t &time,Int_t &bunchSize,Int_t dummy){
528 dummy=0;//to get rid of warning until things are cleaned up better
529 if(fNGoodSignalsSent<fSizeOfSignalPositionArray&&fSizeOfSignalPositionArray>0){
530 time = fSignalPositionArray[fNGoodSignalsSent];
533 while(fNGoodSignalsSent<fSizeOfSignalPositionArray){
534 if(fDataSignals[time+bunchSize+1]>0){
548 Int_t AliHLTTPCPad::GetDataSignal(Int_t bin) const
550 // see header file for class documentation
551 return fDataSignals[bin];
554 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){
555 //see headerfile for documentation
557 //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);
559 Bool_t useRMS= kFALSE;
563 HLTInfo("Both RMSThreshold and SignalThreshold defined, using RMSThreshold");
566 if(threshold<1 && nRMS<=0){
567 //setting the data to -1 for this pad
568 HLTInfo("Neither of RMSThreshold and SignalThreshold set, zerosuppression aborted");
572 Int_t fThresholdUsed=threshold;
576 fSizeOfSignalPositionArray=0;
578 for(Int_t i=beginTime;i<endTime+1;i++){
579 if(fDataSignals[i]>0){
581 sumNAdded+=fDataSignals[i]*fDataSignals[i];
585 else if(threshold>0){
586 for(Int_t i=beginTime;i<endTime+1;i++){
587 if(fDataSignals[i]>0){
589 sumNAdded+=fDataSignals[i];
594 HLTFatal("This should never happen because this is tested earlier in the code.(nRMSThreshold<1&&signal-threshold<1)");
596 if(nAdded<reqMinPoint){
597 HLTInfo("Number of signals is less than required, zero suppression aborted");
602 HLTInfo("No signals added for this pad, zerosuppression aborted: pad %d row %d",fPadNo,fRowNo);
606 Double_t averageValue=(Double_t)sumNAdded/nAdded;//true average for threshold approach, average of signals squared for rms approach
611 fThresholdUsed =(Int_t)(TMath::Sqrt(averageValue)*nRMS);
614 HLTFatal("average value in ZeroSuppression less than 0, investigation needed. This should never happen");
618 fThresholdUsed = (Int_t)(averageValue + threshold);
621 // Do zero suppression on the adc values within [beginTime,endTime](add the good values)
622 for(Int_t i=beginTime;i<endTime;i++){
623 if(fDataSignals[i]>fThresholdUsed){
624 Int_t firstSignalTime=i;
625 for(Int_t left=1;left<timebinsLeft;left++){//looking 5 to the left of the signal to add tail
626 if(fDataSignals[i-left]-averageValue+valueUnderAverage>0 && i-left>=beginTime){
633 Int_t lastSignalTime=i;
634 while(fDataSignals[lastSignalTime+1]>fThresholdUsed && lastSignalTime+1<endTime){
637 for(Int_t right=1;right<timebinsRight;right++){//looking 5 to the left of the signal to add tail
638 if(fDataSignals[i+right]-averageValue+valueUnderAverage>0&&i+right<endTime){
646 for(Int_t t=firstSignalTime;t<lastSignalTime;t++){
647 fDataSignals[t]=(AliHLTTPCSignal_t)(fDataSignals[t]-averageValue + valueUnderAverage);
648 fSignalPositionArray[fSizeOfSignalPositionArray]=t;
649 fSizeOfSignalPositionArray++;
654 //reset the rest of the data
655 Int_t counterSize=fSizeOfSignalPositionArray;
657 for(Int_t d=endTime;d>=beginTime;d--){
658 if(d==fSignalPositionArray[counterSize-1]&&counterSize-1>=0){
665 if(fDataSignals[beginTime+1]<1){
666 fDataSignals[beginTime]=0;
670 void AliHLTTPCPad::AddClusterCandidate(AliHLTTPCClusters candidate){
671 fClusterCandidates.push_back(candidate);
672 fUsedClusterCandidates.push_back(0);