+// @(#) $Id$
+
/**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * This file is property of and copyright by the ALICE HLT Project *
+ * ALICE Experiment at CERN, All rights reserved. *
* *
- * Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
- * for The ALICE Off-line Project. *
+ * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
+ * Kenneth Aamodt <Kenneth.aamodt@ift.uib.no> *
+ * for The ALICE HLT Project. *
* *
* Permission to use, copy, modify and distribute this software and its *
* documentation strictly for non-commercial purposes is hereby granted *
**************************************************************************/
/** @file AliHLTTPCPad.cxx
- @author Matthias Richter
+ @author Matthias Richter, Kenneth Aamodt
@date
@brief Container Class for TPC Pads.
*/
+// see header file for class documentation
+// or
+// refer to README to build package
+// or
+// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+
#if __GNUC__>= 3
using namespace std;
#endif
#include "AliHLTTPCPad.h"
#include "AliHLTStdIncludes.h"
+
+//added by kenneth
+#include "AliHLTTPCTransform.h"
+#include "AliHLTTPCClusters.h"
+#include <sys/time.h>
+//------------------------------
+
/** margin for the base line be re-avaluated */
#define ALIHLTPAD_BASELINE_MARGIN (2*fAverage)
AliHLTTPCPad::AliHLTTPCPad()
:
+ fClusterCandidates(),
+ fUsedClusterCandidates(),
fRowNo(-1),
fPadNo(-1),
fThreshold(0),
fAverage(-1),
fNofEvents(0),
fSum(0),
+ fCount(0),
+ fTotal(0),
fBLMax(-1),
fBLMaxBin(-1),
fBLMin(-1),
fBLMinBin(-1),
- fCount(0),
- fTotal(0),
- fpRawData(NULL),
fFirstBLBin(0),
fNofBins(0),
- fReadPos(0)
+ fReadPos(0),
+ fpRawData(NULL),
+ fDataSignals(NULL),
+ fSignalPositionArray(NULL),
+ fSizeOfSignalPositionArray(0),
+ fNSigmaThreshold(0),
+ fSignalThreshold(0)
{
+ // see header file for class documentation
+ // or
+ // refer to README to build package
+ // or
+ // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+ // HLTInfo("Entering default constructor");
+ fDataSignals= new AliHLTTPCSignal_t[AliHLTTPCTransform::GetNTimeBins()];
+ memset( fDataSignals, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
+
+ fSignalPositionArray= new AliHLTTPCSignal_t[AliHLTTPCTransform::GetNTimeBins()];
+ memset( fSignalPositionArray, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
+ fSizeOfSignalPositionArray=0;
}
AliHLTTPCPad::AliHLTTPCPad(Int_t offset, Int_t nofBins)
:
+ fClusterCandidates(),
+ fUsedClusterCandidates(),
fRowNo(-1),
fPadNo(-1),
fThreshold(0),
fAverage(-1),
fNofEvents(0),
fSum(0),
- fBLMax(-1),
- fBLMaxBin(-1),
- fBLMin(-1),
- fBLMinBin(-1),
fCount(0),
fTotal(0),
- fpRawData(NULL),
- fFirstBLBin(offset),
- fNofBins(nofBins),
- fReadPos(0)
-{
-}
-
-AliHLTTPCPad::AliHLTTPCPad(const AliHLTTPCPad& srcPad)
- :
- fRowNo(srcPad.fRowNo),
- fPadNo(srcPad.fPadNo),
- fThreshold(0),
- fAverage(-1),
- fNofEvents(0),
- fSum(0),
fBLMax(-1),
fBLMaxBin(-1),
fBLMin(-1),
fBLMinBin(-1),
- fCount(0),
- fTotal(0),
+ fFirstBLBin(offset),
+ fNofBins(nofBins),
+ fReadPos(0),
fpRawData(NULL),
- fFirstBLBin(0),
- fNofBins(0),
- fReadPos(0)
-{
- HLTFatal("copy constructor not implemented");
-}
-
-AliHLTTPCPad& AliHLTTPCPad::operator=(const AliHLTTPCPad&)
+ fDataSignals(NULL),
+ fSignalPositionArray(NULL),
+ fSizeOfSignalPositionArray(0),
+ fNSigmaThreshold(0),
+ fSignalThreshold(0)
{
- HLTFatal("assignment operator not implemented");
- return (*this);
+ // see header file for class documentation
}
AliHLTTPCPad::~AliHLTTPCPad()
{
+ // see header file for class documentation
if (fpRawData) {
HLTWarning("event data acquisition not stopped");
StopEvent();
}
+ if (fDataSignals) {
+ AliHLTTPCSignal_t* pData=fDataSignals;
+ fDataSignals=NULL;
+ delete [] pData;
+ }
+ if (fSignalPositionArray) {
+ //AliHLTTPCSignal_t* pData=fSignalPositionArray;
+ fSignalPositionArray=NULL;
+ // delete [] pData;
+ }
+
}
Int_t AliHLTTPCPad::SetID(Int_t rowno, Int_t padno)
{
+ // see header file for class documentation
fRowNo=rowno;
fPadNo=padno;
+ return 0;
}
Int_t AliHLTTPCPad::StartEvent()
{
+ // see header file for class documentation
Int_t iResult=0;
if (fpRawData==NULL) {
fBLMax=-1;
Int_t AliHLTTPCPad::CalculateBaseLine(Int_t reqMinCount)
{
+ // see header file for class documentation
Int_t iResult=0;
AliHLTTPCSignal_t avBackup=fAverage;
//HLTDebug("reqMinCount=%d fCount=%d fTotal=%d fSum=%d fBLMax=%d fBLMin=%d", reqMinCount, fCount, fTotal, fSum, fBLMax, fBLMin);
fAverage=fSum/fCount;
//HLTDebug("new average %d", fAverage);
} else {
-// HLTDebug("baseline re-eveluation skipped because of to few "
-// "contributing bins: total=%d, contributing=%d, req=%d"
-// "\ndata might be already zero suppressed"
-// , fTotal, fCount, reqMinCount);
+ // HLTDebug("baseline re-eveluation skipped because of to few "
+ // "contributing bins: total=%d, contributing=%d, req=%d"
+ // "\ndata might be already zero suppressed"
+ // , fTotal, fCount, reqMinCount);
iResult=-ENODATA;
}
fCount=0;fSum=-1;
fAverage=avBackup;
}
} else {
-// HLTDebug("baseline calculation skipped because of to few contributing "
-// "bins: total=%d, contributing=%d, required=%d \ndata might be "
-// "already zero suppressed", fTotal, fCount, reqMinCount);
+ // HLTDebug("baseline calculation skipped because of to few contributing "
+ // "bins: total=%d, contributing=%d, required=%d \ndata might be "
+ // "already zero suppressed", fTotal, fCount, reqMinCount);
}
return iResult;
Int_t AliHLTTPCPad::StopEvent()
{
+ // see header file for class documentation
Int_t iResult=0;
if (fpRawData) {
AliHLTTPCSignal_t* pData=fpRawData;
Int_t AliHLTTPCPad::ResetHistory()
{
+ // see header file for class documentation
Int_t iResult=0;
fAverage=-1;
fNofEvents=0;
Int_t AliHLTTPCPad::SetThreshold(AliHLTTPCSignal_t thresh)
{
+ // see header file for class documentation
Int_t iResult=0;
fThreshold=thresh;
return iResult;
Int_t AliHLTTPCPad::AddBaseLineValue(Int_t bin, AliHLTTPCSignal_t value)
{
+ // see header file for class documentation
Int_t iResult=0;
if (bin>=fFirstBLBin) {
if (fAverage<0 || value<ALIHLTPAD_BASELINE_MARGIN) {
fBLMinBin=bin;
}
} else {
-// HLTDebug("ignoring value %d (bin %d) for base line calculation "
-// "(current average is %d)",
-// value, bin, fAverage);
+ // HLTDebug("ignoring value %d (bin %d) for base line calculation "
+ // "(current average is %d)",
+ // value, bin, fAverage);
}
}
return iResult;
Int_t AliHLTTPCPad::SetRawData(Int_t bin, AliHLTTPCSignal_t value)
{
+ // see header file for class documentation
Int_t iResult=0;
if (fpRawData) {
if (bin<fNofBins) {
Int_t AliHLTTPCPad::Next(Int_t bZeroSuppression)
{
+ // see header file for class documentation
if (fpRawData==NULL) return 0;
Int_t iResult=fReadPos<fNofBins;
if (iResult>0 && (iResult=(++fReadPos<fNofBins))>0) {
Int_t AliHLTTPCPad::Rewind(Int_t bZeroSuppression)
{
+ // see header file for class documentation
fReadPos=(bZeroSuppression>0?0:fFirstBLBin)-1;
return Next(bZeroSuppression);
}
AliHLTTPCSignal_t AliHLTTPCPad::GetRawData(Int_t bin) const
{
+ // see header file for class documentation
AliHLTTPCSignal_t data=0;
if (fpRawData) {
if (bin<fNofBins) {
AliHLTTPCSignal_t AliHLTTPCPad::GetCorrectedData(Int_t bin) const
{
+ // see header file for class documentation
AliHLTTPCSignal_t data=GetRawData(bin)-GetBaseLine(bin);
AliHLTTPCSignal_t prev=0;
if (bin>1) prev=GetRawData(bin-1)-GetBaseLine(bin-1);
return data;
}
-AliHLTTPCSignal_t AliHLTTPCPad::GetBaseLine(Int_t bin) const
+AliHLTTPCSignal_t AliHLTTPCPad::GetBaseLine(Int_t /*bin*/) const //TODO: Why is bin being ignored?
{
+ // see header file for class documentation
AliHLTTPCSignal_t val=0;
if (fAverage>0) {
// we take the minumum value as the base line if it doesn't differ from
// the average to much
- const AliHLTTPCSignal_t kMaxDifference=15;
val=fAverage;
#ifdef KEEP_NOISE
+ const AliHLTTPCSignal_t kMaxDifference=15;
if ((fAverage-fBLMin)<=kMaxDifference) val=fBLMin;
else val>kMaxDifference?val-=kMaxDifference:0;
#endif
AliHLTTPCSignal_t AliHLTTPCPad::GetAverage() const
{
+ // see header file for class documentation
return fAverage>0?fAverage:0;
}
Float_t AliHLTTPCPad::GetOccupancy() const
{
+ // see header file for class documentation
Float_t occupancy=0;
if (fpRawData && fNofBins>0) {
for (Int_t i=fFirstBLBin; i<fNofBins; i++) {
Float_t AliHLTTPCPad::GetAveragedOccupancy() const
{
+ // see header file for class documentation
+
// history is not yet implemented
return GetOccupancy();
}
+void AliHLTTPCPad::PrintRawData()
+{
+ // see header file for class documentation
+ for(Int_t bin=0;bin<AliHLTTPCTransform::GetNTimeBins();bin++){
+ if(GetDataSignal(bin)>0)
+ cout<<fRowNo<<"\t"<<fPadNo<<"\t"<<bin<<"\t"<<GetDataSignal(bin)<<endl;;
+ }
+ cout<<"bins: "<<AliHLTTPCTransform::GetNTimeBins()<<endl;
+}
+
+void AliHLTTPCPad::SetDataToDefault()
+{
+ // see header file for class documentation
+ if(fpRawData){
+ memset( fDataSignals, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
+ memset( fSignalPositionArray, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
+ fSizeOfSignalPositionArray=0;
+ }
+}
+
+void AliHLTTPCPad::SetDataSignal(Int_t bin,Int_t signal)
+{
+ // see header file for class documentation
+ fDataSignals[bin]=signal;
+ fSignalPositionArray[fSizeOfSignalPositionArray]=bin;
+ fSizeOfSignalPositionArray++;
+}
+
+Int_t AliHLTTPCPad::GetDataSignal(Int_t bin) const
+{
+ // see header file for class documentation
+ return fDataSignals[bin];
+}
+
+void AliHLTTPCPad::ZeroSuppress(Double_t nSigma = 3,Int_t threshold = 20 ,Int_t reqMinPoint = AliHLTTPCTransform::GetNTimeBins()/2, Int_t beginTime = 50,Int_t endTime = AliHLTTPCTransform::GetNTimeBins()-1){
+ //see headerfile for documentation
+
+ Bool_t useSigma= kFALSE;
+ if(nSigma>0){
+ useSigma=kTRUE;
+ }
+ if(threshold<1 && nSigma<=0){
+ //setting the data to -1 for this pad
+ memset( fDataSignals, 0xFF, sizeof(Int_t)*(AliHLTTPCTransform::GetNTimeBins()));
+ fSizeOfSignalPositionArray=0;
+ return;
+ }
+ if(endTime>=AliHLTTPCTransform::GetNTimeBins()){
+ endTime=AliHLTTPCTransform::GetNTimeBins()-1;
+ }
+
+ Int_t fThresholdUsed=threshold;
+
+ Int_t nAdded=0;
+ Int_t sumNAdded=0;
+ fSizeOfSignalPositionArray=0;
+ for(Int_t i=beginTime;i<endTime+1;i++){
+ if(fDataSignals[i]>0){
+ nAdded++;
+ sumNAdded+=fDataSignals[i];
+ }
+ }
+
+ if(nAdded<reqMinPoint){
+ return; //This will ensure that no data is read in FindClusterCandidates() (since fSizeOfSignalPositionArray=0)
+ }
+
+ Double_t averageValue=sumNAdded/nAdded;
+
+ Double_t sigma=0;
+ if(useSigma){
+ //Calculate the sigma
+ Double_t sumOfDifferenceSquared=0;
+ for(Int_t i=endTime;i>=beginTime;i--){
+ if(fDataSignals[i]>0){
+ if(fDataSignals[i]-averageValue<50){
+ sumOfDifferenceSquared+=(fDataSignals[i]-averageValue)*(fDataSignals[i]-averageValue);
+ }
+ else{
+ nAdded--;
+ }
+ }
+ }
+ sigma=sumOfDifferenceSquared/nAdded;
+ fThresholdUsed=(Int_t)(nSigma*sigma);
+ }
+
+ //For now just set the adc value outside [beginTime,endTime] to -1
+ for(Int_t i=0;i<beginTime;i++){
+ fDataSignals[i]=-1;
+ }
+ for(Int_t i=endTime+1;i<AliHLTTPCTransform::GetNTimeBins();i++){
+ fDataSignals[i]=-1;
+ }
+
+ // Do zero suppression on the adc values within [beginTime,endTime]
+ for(Int_t i=endTime;i>=beginTime;i--){
+ //the +1 in the if below is there to avoid getting a signal which is 0, adding to the numbers you have to loop over in the end
+ //(better to set it to -1 which is default for no signal)
+ if(fDataSignals[i]>(Int_t)(averageValue+fThresholdUsed+1) && fDataSignals[i-1]>(Int_t)(averageValue+fThresholdUsed+1)){
+ //here the signals below threshold to the right of the candidate is added
+ Bool_t contRight=kTRUE;
+ Int_t endRight=i;
+ Int_t nToAddRight=0;
+ while(contRight){
+ if(endRight+1<endTime){
+ // cout<<fDataSignals[endRight+1]<<" "<<fDataSignals[endRight+2]<<endl;;
+ if(fDataSignals[endRight+1]>=fDataSignals[endRight+2] && fDataSignals[endRight+1]>averageValue){
+ nToAddRight++;
+ }
+ else{
+ if(fDataSignals[endRight+1]> averageValue){
+ nToAddRight++;
+ }
+ contRight=kFALSE;
+ }
+ }
+ else if(endRight>endTime+1){
+ contRight=kFALSE;
+ }
+ endRight++;
+ }
+ for(int j=i+nToAddRight;j>i;j--){
+ fDataSignals[j]=(Int_t)(fDataSignals[j]-averageValue);
+ fSignalPositionArray[fSizeOfSignalPositionArray]=j;
+ fSizeOfSignalPositionArray++;
+ }
+
+
+ //before while the two consecutive timebin values are added
+ fDataSignals[i]=(Int_t)(fDataSignals[i]-averageValue);
+ fSignalPositionArray[fSizeOfSignalPositionArray]=i;
+ fSizeOfSignalPositionArray++;
+ fDataSignals[i-1]=(Int_t)(fDataSignals[i-1]-averageValue);
+ fSignalPositionArray[fSizeOfSignalPositionArray]=i-1;
+ fSizeOfSignalPositionArray++;
+ i--;
+ // cout<<""<<endl;
+ //Here the consecutive pads after the two first are added
+ if(i-1>0){
+ while(fDataSignals[i-1]>(Int_t)(averageValue+fThresholdUsed+1)){
+ fDataSignals[i-1]=(Int_t)(fDataSignals[i-1]-averageValue);
+ fSignalPositionArray[fSizeOfSignalPositionArray]=i-1;
+ fSizeOfSignalPositionArray++;
+ i--;
+ }
+ }
+ //adding the signal below threshold belonging to the total signal
+ Bool_t contLeft=kTRUE;
+ while(contLeft){
+ if(i-2>0){
+ if(fDataSignals[i-1]>=fDataSignals[i-2] && fDataSignals[i-1]>averageValue){
+ fDataSignals[i-1]=(Int_t)(fDataSignals[i-1]-averageValue);
+ fSignalPositionArray[fSizeOfSignalPositionArray]=i-1;
+ fSizeOfSignalPositionArray++;
+ i--;
+ }
+ else{
+ if(fDataSignals[i-1]> averageValue){
+ fDataSignals[i-1]=(Int_t)(fDataSignals[i-1]-averageValue);
+ fSignalPositionArray[fSizeOfSignalPositionArray]=i-1;
+ fSizeOfSignalPositionArray++;
+ i--;
+ }
+ contLeft=kFALSE;
+ }
+ }
+ else{
+ contLeft=kFALSE;
+ }
+
+ }
+ }
+ }
+ Int_t nReadFromPositionArray=0;
+ for(Int_t i=endTime;i>=beginTime;i--){
+ if(i==fSignalPositionArray[nReadFromPositionArray]){
+ nReadFromPositionArray++;
+ }
+ else{
+ fDataSignals[i]=-1;
+ }
+ }
+}
+
+void AliHLTTPCPad::FindClusterCandidates()
+{
+ // see header file for class documentation
+
+ if(fNSigmaThreshold>0){
+ ZeroSuppress(fNSigmaThreshold);
+ }
+ else if(fSignalThreshold>0){
+ ZeroSuppress((Double_t)0,(Int_t)fSignalThreshold);
+ }
+ UInt_t seqcharge=0;
+ UInt_t seqaverage=0;
+ UInt_t seqerror=0;
+ vector<Int_t> tmpPos;
+ vector<Int_t> tmpSig;
+ UInt_t isFalling=0;
+
+ for(Int_t pos=fSizeOfSignalPositionArray-2;pos>=0;pos--){
+ if(fSignalPositionArray[pos]==fSignalPositionArray[pos+1]+1){
+ seqcharge+=fDataSignals[fSignalPositionArray[pos+1]];
+ seqaverage += fSignalPositionArray[pos+1]*fDataSignals[fSignalPositionArray[pos+1]];
+ seqerror += fSignalPositionArray[pos+1]*fSignalPositionArray[pos+1]*fDataSignals[fSignalPositionArray[pos+1]];
+
+ tmpPos.push_back(fSignalPositionArray[pos+1]);
+ tmpSig.push_back(fDataSignals[fSignalPositionArray[pos+1]]);
+
+ if(fDataSignals[fSignalPositionArray[pos+1]]>fDataSignals[fSignalPositionArray[pos]]){
+ isFalling=1;
+ }
+ if(fDataSignals[fSignalPositionArray[pos+1]]<fDataSignals[fSignalPositionArray[pos]]&&isFalling){
+ Int_t seqmean=0;
+ seqmean = seqaverage/seqcharge;
+
+ //Calculate mean in pad direction:
+ Int_t padmean = seqcharge*fPadNo;
+ Int_t paderror = fPadNo*padmean;
+ AliHLTTPCClusters candidate;
+ candidate.fTotalCharge = seqcharge;
+ candidate.fPad = padmean;
+ candidate.fPad2 = paderror;
+ candidate.fTime = seqaverage;
+ candidate.fTime2 = seqerror;
+ candidate.fMean = seqmean;
+ candidate.fLastMergedPad = fPadNo;
+ fClusterCandidates.push_back(candidate);
+ fUsedClusterCandidates.push_back(0);
+ isFalling=0;
+ seqcharge=0;
+ seqaverage=0;
+ seqerror=0;
+
+ tmpPos.clear();
+ tmpSig.clear();
+
+ continue;
+ }
+
+ if(pos<1){
+ seqcharge+=fDataSignals[fSignalPositionArray[0]];
+ seqaverage += fSignalPositionArray[0]*fDataSignals[fSignalPositionArray[0]];
+ seqerror += fSignalPositionArray[0]*fSignalPositionArray[0]*fDataSignals[fSignalPositionArray[0]];
+ tmpPos.push_back(fSignalPositionArray[0]);
+ tmpSig.push_back(fDataSignals[fSignalPositionArray[0]]);
+
+ //Calculate mean of sequence:
+ Int_t seqmean=0;
+ seqmean = seqaverage/seqcharge;
+
+ //Calculate mean in pad direction:
+ Int_t padmean = seqcharge*fPadNo;
+ Int_t paderror = fPadNo*padmean;
+ AliHLTTPCClusters candidate;
+ candidate.fTotalCharge = seqcharge;
+ candidate.fPad = padmean;
+ candidate.fPad2 = paderror;
+ candidate.fTime = seqaverage;
+ candidate.fTime2 = seqerror;
+ candidate.fMean = seqmean;
+ candidate.fLastMergedPad = fPadNo;
+ fClusterCandidates.push_back(candidate);
+ fUsedClusterCandidates.push_back(0);
+ isFalling=0;
+ seqcharge=0;
+ seqaverage=0;
+ seqerror=0;
+
+ tmpPos.clear();
+ tmpSig.clear();
+ }
+ }
+ else if(seqcharge>0){
+ seqcharge+=fDataSignals[fSignalPositionArray[pos+1]];
+ seqaverage += fSignalPositionArray[pos+1]*fDataSignals[fSignalPositionArray[pos+1]];
+ seqerror += fSignalPositionArray[pos+1]*fSignalPositionArray[pos+1]*fDataSignals[fSignalPositionArray[pos+1]];
+ tmpPos.push_back(fSignalPositionArray[pos+1]);
+ tmpSig.push_back(fDataSignals[fSignalPositionArray[pos+1]]);
+
+ //Calculate mean of sequence:
+ Int_t seqmean=0;
+ seqmean = seqaverage/seqcharge;
+
+ //Calculate mean in pad direction:
+ Int_t padmean = seqcharge*fPadNo;
+ Int_t paderror = fPadNo*padmean;
+ AliHLTTPCClusters candidate;
+ candidate.fTotalCharge = seqcharge;
+ candidate.fPad = padmean;
+ candidate.fPad2 = paderror;
+ candidate.fTime = seqaverage;
+ candidate.fTime2 = seqerror;
+ candidate.fMean = seqmean;
+ candidate.fLastMergedPad = fPadNo;
+ fClusterCandidates.push_back(candidate);
+ fUsedClusterCandidates.push_back(0);
+ isFalling=0;
+ seqcharge=0;
+ seqaverage=0;
+ seqerror=0;
+
+ tmpPos.clear();
+ tmpSig.clear();
+ }
+ }
+}
+