From: richterm Date: Wed, 30 Aug 2006 14:19:09 +0000 (+0000) Subject: - added TPCPad handling class X-Git-Url: http://git.uio.no/git/?a=commitdiff_plain;h=46b33a2462a8b64f7dd44607bb8603826b2e39a8;p=u%2Fmrichter%2FAliRoot.git - added TPCPad handling class - added zero suppression to TPC cluster finder - minor eff C++ changes --- diff --git a/HLT/TPCLib/AliHLTTPCClusterFinder.cxx b/HLT/TPCLib/AliHLTTPCClusterFinder.cxx index 975af3355b2..5edd95a619e 100644 --- a/HLT/TPCLib/AliHLTTPCClusterFinder.cxx +++ b/HLT/TPCLib/AliHLTTPCClusterFinder.cxx @@ -16,6 +16,7 @@ #include "AliHLTTPCTransform.h" #include "AliHLTTPCSpacePointData.h" #include "AliHLTTPCMemHandler.h" +#include "AliHLTTPCPad.h" #if __GNUC__ >= 3 using namespace std; @@ -95,21 +96,55 @@ using namespace std; ClassImp(AliHLTTPCClusterFinder) AliHLTTPCClusterFinder::AliHLTTPCClusterFinder() + : + fMatch(1), + fThreshold(10), + fXYErr(0.2), + fZErr(0.3), + fDeconvPad(kTRUE), + fDeconvTime(kTRUE), + fStdout(kFALSE), + fCalcerr(kTRUE), + fRawSP(kFALSE), + fFirstRow(0), + fLastRow(0), + fDigitReader(NULL) { //constructor - fMatch = 1; - fThreshold = 10; - fXYErr = 0.2; - fZErr = 0.3; - fDeconvPad = kTRUE; - fDeconvTime = kTRUE; - fStdout = kFALSE; - fCalcerr = kTRUE; - fRawSP = kFALSE; - fFirstRow=0; - fLastRow=0; - fDigitReader = 0; +} + +AliHLTTPCClusterFinder::AliHLTTPCClusterFinder(const AliHLTTPCClusterFinder& src) + : + fMatch(src.fMatch), + fThreshold(src.fThreshold), + fXYErr(src.fXYErr), + fZErr(src.fZErr), + fDeconvPad(src.fDeconvPad), + fDeconvTime(src.fDeconvTime), + fStdout(src.fStdout), + fCalcerr(src.fCalcerr), + fRawSP(src.fRawSP), + fFirstRow(src.fFirstRow), + fLastRow(src.fLastRow), + fDigitReader(src.fDigitReader) +{ +} +AliHLTTPCClusterFinder& AliHLTTPCClusterFinder::operator=(const AliHLTTPCClusterFinder& src) +{ + fMatch=src.fMatch; + fThreshold=src.fThreshold; + fXYErr=src.fXYErr; + fZErr=src.fZErr; + fDeconvPad=src.fDeconvPad; + fDeconvTime=src.fDeconvTime; + fStdout=src.fStdout; + fCalcerr=src.fCalcerr; + fRawSP=src.fRawSP; + fFirstRow=src.fFirstRow; + fLastRow=src.fLastRow; + fDigitReader=src.fDigitReader; + return (*this); } AliHLTTPCClusterFinder::~AliHLTTPCClusterFinder() @@ -156,9 +191,9 @@ void AliHLTTPCClusterFinder::ProcessDigits() bool readValue = true; Int_t newRow = 0; Int_t rowOffset = 0; - UChar_t pad; - UShort_t time,newTime=0; - UInt_t charge,newPad=0; + UShort_t time=0,newTime=0; + UInt_t pad=0,newPad=0; + AliHLTTPCSignal_t charge=0; fNClusters = 0; @@ -188,6 +223,18 @@ void AliHLTTPCClusterFinder::ProcessDigits() previousPt = pad1; UInt_t nprevious=0,ncurrent=0,ntotal=0; + /* quick implementation of baseline calculation and zero suppression + open a pad object for each pad and delete it after processing. + later a list of pad objects with base line history can be used + The whole thing only works if we really get unprocessed raw data, if + the data is already zero suppressed, there might be gaps in the time + bins. + */ + Int_t gatingGridOffset=50; + AliHLTTPCPad baseline(gatingGridOffset, AliHLTTPCTransform::GetNTimeBins()); + // just to make later conversion to a list of objects easier + AliHLTTPCPad* pCurrentPad=&baseline; + while ( readValue ){ // Reads through all digits in block if(pad != lastpad){ @@ -229,10 +276,41 @@ void AliHLTTPCClusterFinder::ProcessDigits() lastwas_falling = 0; } + while(1){ //Loop over time bins of current pad + // read all the values for one pad at once to calculate the base line + if (pCurrentPad) { + if (!pCurrentPad->IsStarted()) { + //HLTDebug("reading data for pad %d, padrow %d", fDigitReader->GetPad(), fDigitReader->GetRow()+rowOffset); + pCurrentPad->SetID(fDigitReader->GetRow()+rowOffset,fDigitReader->GetPad()); + if ((pCurrentPad->StartEvent())>=0) { + do { + if ((fDigitReader->GetRow()+rowOffset)!=pCurrentPad->GetRowNumber()) break; + if (fDigitReader->GetPad()!=pCurrentPad->GetPadNumber()) break; + pCurrentPad->SetRawData(fDigitReader->GetTime(), fDigitReader->GetSignal()); + //HLTDebug("set raw data to pad: bin %d charge %d", fDigitReader->GetTime(), fDigitReader->GetSignal()); + } while ((readValue = fDigitReader->Next())!=0); + } + pCurrentPad->CalculateBaseLine(AliHLTTPCTransform::GetNTimeBins()/2); + if (pCurrentPad->Next(kTRUE/*do zero suppression*/)==0) { + HLTDebug("no data available after zero suppression"); + pCurrentPad->StopEvent(); + pCurrentPad->ResetHistory(); + break; + } + time=pCurrentPad->GetCurrentPosition(); + if (time>pCurrentPad->GetSize()) { + HLTError("invalid time bin for pad"); + break; + } + } + } - // LOOP OVER CURRENR SEQUENCE - while(1){ //Loop over current + if (pCurrentPad) { + charge = pCurrentPad->GetCorrectedData(); + } else { charge = fDigitReader->GetSignal(); + } + //HLTDebug("get next charge value: position %d charge %d", time, charge); // CHARGE DEBUG @@ -242,13 +320,12 @@ void AliHLTTPCClusterFinder::ProcessDigits() } - if(time >= AliHLTTPCTransform::GetNTimeBins()){ - LOG(AliHLTTPCLog::kFatal,"AliHLTTPCClusterFinder::ProcessRow","Digits") - <<"Timebin out of range "<<(Int_t)time<Next(kTRUE/*do zero suppression*/))==0) { + pCurrentPad->StopEvent(); + pCurrentPad->ResetHistory(); + if(readValue) { + newPad = fDigitReader->GetPad(); + newTime = fDigitReader->GetTime(); + newRow = fDigitReader->GetRow() + rowOffset; + } + break; + } + + newPad=pCurrentPad->GetPadNumber(); + newTime=pCurrentPad->GetCurrentPosition(); + newRow=pCurrentPad->GetRowNumber(); + } else { readValue = fDigitReader->Next(); - //Check where to stop: if(!readValue) break; //No more value newPad = fDigitReader->GetPad(); newTime = fDigitReader->GetTime(); newRow = fDigitReader->GetRow() + rowOffset; + } if(newPad != pad)break; //new pad if(newTime != time+1) break; //end of sequence @@ -285,6 +379,12 @@ void AliHLTTPCClusterFinder::ProcessDigits() }//end loop over sequence + //HLTDebug("ended time bin sequence loop: seqcharge=%d readValue=%d", seqcharge, readValue); + //HLTDebug("pad=%d newpad=%d current row=%d newrow=%d", pad, newPad, fCurrentRow, newRow); + if (seqcharge<=0) { + // with active zero suppression zero values are possible + continue; + } //Calculate mean of sequence: Int_t seqmean=0; @@ -377,8 +477,7 @@ void AliHLTTPCClusterFinder::ProcessDigits() // to prevent endless loop if(time >= AliHLTTPCTransform::GetNTimeBins()){ - LOG(AliHLTTPCLog::kFatal,"AliHLTTPCClusterFinder::ProcessRow","Digits") - <<"Timebin out of range "<<(Int_t)time<StopEvent(); + WriteClusters(ntotal,clusterlist); - LOG(AliHLTTPCLog::kInformational,"AliHLTTPCClusterFinder::ProcessDigits","Space points") - << "ClusterFinder found " << fNClusters << " clusters in slice " << fCurrentSlice << " patch " - << fCurrentPatch << ENDLOG; + HLTInfo("ClusterFinder found %d clusters in slice %d patch %d", fNClusters, fCurrentSlice, fCurrentPatch); } // ENDEND diff --git a/HLT/TPCLib/AliHLTTPCClusterFinder.h b/HLT/TPCLib/AliHLTTPCClusterFinder.h index 7bf399c476b..439c6cc71ed 100644 --- a/HLT/TPCLib/AliHLTTPCClusterFinder.h +++ b/HLT/TPCLib/AliHLTTPCClusterFinder.h @@ -4,10 +4,12 @@ #ifndef AliHLTTPC_ClusterFinder #define AliHLTTPC_ClusterFinder +#include "AliHLTLogging.h" + class AliHLTTPCSpacePointData; class AliHLTTPCDigitReader; -class AliHLTTPCClusterFinder { +class AliHLTTPCClusterFinder : public AliHLTLogging { public: struct AliClusterData @@ -55,7 +57,13 @@ class AliHLTTPCClusterFinder { #endif public: + /** standard constructor */ AliHLTTPCClusterFinder(); + /** not a valid copy constructor, defined according to effective C++ style */ + AliHLTTPCClusterFinder(const AliHLTTPCClusterFinder&); + /** not a valid assignment op, but defined according to effective C++ style */ + AliHLTTPCClusterFinder& operator=(const AliHLTTPCClusterFinder&); + /** destructor */ virtual ~AliHLTTPCClusterFinder(); void Read(void* ptr,unsigned long size); diff --git a/HLT/TPCLib/AliHLTTPCPad.cxx b/HLT/TPCLib/AliHLTTPCPad.cxx new file mode 100644 index 00000000000..1a673e33ac3 --- /dev/null +++ b/HLT/TPCLib/AliHLTTPCPad.cxx @@ -0,0 +1,325 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Authors: Matthias Richter * + * for The ALICE Off-line Project. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/** @file AliHLTTPCPad.cxx + @author Matthias Richter + @date + @brief Container Class for TPC Pads. +*/ + +#if __GNUC__>= 3 +using namespace std; +#endif + +#include +#include "AliHLTTPCPad.h" + +/** margin for the base line be re-avaluated */ +#define ALIHLTPAD_BASELINE_MARGIN (2*fAverage) + +/** ROOT macro for the implementation of ROOT specific class methods */ +ClassImp(AliHLTTPCPad) + +AliHLTTPCPad::AliHLTTPCPad() + : + fRowNo(-1), + fPadNo(-1), + fThreshold(0), + fAverage(-1), + fNofEvents(0), + fSum(0), + fBLMax(-1), + fBLMaxBin(-1), + fCount(0), + fTotal(0), + fpRawData(NULL), + fFirstBLBin(0), + fNofBins(0), + fReadPos(0) +{ +} + +AliHLTTPCPad::AliHLTTPCPad(Int_t offset, Int_t nofBins) + : + fRowNo(-1), + fPadNo(-1), + fThreshold(0), + fAverage(-1), + fNofEvents(0), + fSum(0), + fBLMax(-1), + fBLMaxBin(-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), + fCount(0), + fTotal(0), + fpRawData(NULL), + fFirstBLBin(0), + fNofBins(0), + fReadPos(0) +{ + HLTFatal("copy constructor not implemented"); +} + +AliHLTTPCPad& AliHLTTPCPad::operator=(const AliHLTTPCPad&) +{ + HLTFatal("assignment operator not implemented"); + return (*this); +} + +AliHLTTPCPad::~AliHLTTPCPad() +{ + if (fpRawData) { + HLTWarning("event data acquisition not stopped"); + StopEvent(); + } +} + +Int_t AliHLTTPCPad::SetID(Int_t rowno, Int_t padno) +{ + fRowNo=rowno; + fPadNo=padno; +} + +Int_t AliHLTTPCPad::StartEvent() +{ + Int_t iResult=0; + if (fpRawData==NULL) { + fBLMax=-1; + fBLMaxBin=-1; + fSum=0; + fCount=0; + fTotal=0; + if (fNofBins>0) { + fpRawData=new AliHLTTPCSignal_t[fNofBins]; + if (fpRawData) { + for (int i=0; i=reqMinCount && fCount>=fTotal/2) { + fAverage=fCount>0?fSum/fCount:0; + if (fAverage>0) { + HLTDebug("average for current event %f", fAverage); + fCount=0;fSum=-1; + if (fBLMax>ALIHLTPAD_BASELINE_MARGIN) { + // calculate again + HLTDebug("maximum value %f exceeds margin for base line %f " + "-> re-evaluate base line", fBLMax, ALIHLTPAD_BASELINE_MARGIN); + if (fpRawData) { + for (Int_t i=fFirstBLBin; i=0) AddBaseLineValue(i, fpRawData[i]); + if (fCount>0 && fCount>=reqMinCount && fCount>=fTotal/2) { + fAverage=fSum/fCount; + HLTDebug("new average %f", fAverage); + } else { + HLTWarning("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; + } else { + HLTError("missing raw data for base line calculation"); + iResult=-ENOBUFS; + } + } + if (iResult>=0) { + // calculate average for all events + fAverage=((avBackup*fNofEvents)+fAverage)/(fNofEvents+1); + HLTDebug("base line average for %d events: %f", fNofEvents+1, fAverage); + } else { + fAverage=avBackup; + } + } else { + fAverage=avBackup; + } + } else { + HLTWarning("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() +{ + Int_t iResult=0; + if (fpRawData) { + AliHLTTPCSignal_t* pData=fpRawData; + fpRawData=NULL; + delete [] pData; + fTotal=0; + fNofEvents++; + Rewind(); + } else if (fNofBins>0) { + HLTError("event data acquisition not started"); + iResult=-EBADF; + } + return iResult; +} + +Int_t AliHLTTPCPad::ResetHistory() +{ + Int_t iResult=0; + fAverage=-1; + fNofEvents=0; + return iResult; +} + +Int_t AliHLTTPCPad::SetThreshold(AliHLTTPCSignal_t thresh) +{ + Int_t iResult=0; + fThreshold=thresh; + return iResult; +} + +Int_t AliHLTTPCPad::AddBaseLineValue(Int_t bin, AliHLTTPCSignal_t value) +{ + Int_t iResult=0; + if (bin>=fFirstBLBin) { + if (fAverage<0 || value=0) { + if (fpRawData[bin]<0) { + AddBaseLineValue(bin, value); + fTotal++; + } else { + // ignore value for average calculation + HLTWarning("overriding content of bin %d (%f)", bin, fpRawData[bin]); + } + fpRawData[bin]=value; + } else { + HLTWarning("ignoring neg. raw data"); + } + } else { + HLTWarning("bin %d out of range (%d)", bin, fNofBins); + iResult=-ERANGE; + } + } else if (fNofBins>0) { + HLTError("event cycle not started"); + iResult=-EBADF; + } + return iResult; +} + +Int_t AliHLTTPCPad::Next(Int_t bZeroSuppression) +{ + if (fpRawData==NULL) return 0; + Int_t iResult=fReadPos0 && (iResult=(++fReadPos0) { + if (bZeroSuppression) { + while ((iResult=(fReadPos0 && + GetCorrectedData(fReadPos)<=0) + fReadPos++; + } + } + return iResult; +} + +Int_t AliHLTTPCPad::Rewind(Int_t bZeroSuppression) +{ + fReadPos=(bZeroSuppression>0?0:fFirstBLBin)-1; + return Next(bZeroSuppression); +} + +AliHLTTPCSignal_t AliHLTTPCPad::GetRawData(Int_t bin) const +{ + AliHLTTPCSignal_t data=0; + if (fpRawData) { + if (bin0) { + HLTWarning("data only available within event cycle"); + } + return data; +} + +AliHLTTPCSignal_t AliHLTTPCPad::GetCorrectedData(Int_t bin) const +{ + AliHLTTPCSignal_t data=GetRawData(bin)-GetBaseLine(bin); + if (fThreshold>0) data-=fThreshold; + if (data<0) data=0; + if (bin0?fAverage:0; +} + +AliHLTTPCSignal_t AliHLTTPCPad::GetAverage() const +{ + return fAverage>0?fAverage:0; +} + diff --git a/HLT/TPCLib/AliHLTTPCPad.h b/HLT/TPCLib/AliHLTTPCPad.h new file mode 100644 index 00000000000..ccfcae78f6c --- /dev/null +++ b/HLT/TPCLib/AliHLTTPCPad.h @@ -0,0 +1,254 @@ +// @(#) $Id$ + +#ifndef ALIHLTPAD_H +#define ALIHLTPAD_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/** @file AliHLTTPCPad.h + @author Matthias Richter + @date + @brief Container Class for TPC Pads. +*/ + +#include "AliHLTLogging.h" + +typedef Int_t AliHLTTPCSignal_t; + +/** + * @class AliHLTTPCPad + * The class is a container for the raw ADC data of one TPCS pad. In order to + * avoid multiple unpacking/handling of the incoming raw data, the class holds + * a copy of the incoming data for one event. The copy is released when the + * end of the event was announced. + * The class calculates the base line of a TPC channel. Currently, only the + * average value is calculated, but further extension will include channel by + * channel histograming. The baseline history is kept and used for baseline + * re-evaluation and correction of subsequent events. + * @ingroup alihlt_tpc + */ +class AliHLTTPCPad : public AliHLTLogging { + public: + /** standard constructor */ + AliHLTTPCPad(); + + /** + * Constructor + * @param offset The number of bins to ignore at the beginning + * of the channels + * @param nofBins The total number of bins for one channel + */ + AliHLTTPCPad(Int_t offset, Int_t nofBins); + + /** not a valid copy constructor, defined according to effective C++ style */ + AliHLTTPCPad(const AliHLTTPCPad&); + /** not a valid assignment op, but defined according to effective C++ style */ + AliHLTTPCPad& operator=(const AliHLTTPCPad&); + /** standard destructor */ + virtual ~AliHLTTPCPad(); + + /** + * Set the address the pad. + * The address consists of row and pad number. + * @param rowno The row number + * @param padno The pad number. + */ + Int_t SetID(Int_t rowno, Int_t padno); + + /** + * Get the row number. + */ + Int_t GetRowNumber() const {return fRowNo;} + + /** + * Get the pad number. + */ + Int_t GetPadNumber() const {return fPadNo;} + + /** + * Start accumulation for a new event. + * The class holds internally a history of the event data. The data can + * be fetched from the class without unpacking the input stream again. + * @return neg. error value if failed + * - ENOMEM memory allocation failed + * - EALREADY event data acquisition already started + */ + Int_t StartEvent(); + + /** + * Check whether the event is started + * @return 1 if started, 0 if not + */ + Int_t IsStarted() const { return fpRawData!=NULL;}; + + /** + * Calculate the base line from the current event data. + * Only available within an event cycle.
+ * The calculation requires a minimum number of bins which contribute + * to the sum, which can be specified by @param reqMinCount. The base line + * calculation will also be skipped if the number of contributing bins is + * less than half of the total number of time bins. + * @param reqMinCount the minimum number of bins contributing to the sum + * @return neg. error value if failed + * - ENODATA to little contributing bins + * - ENOBUFS no raw data available + */ + Int_t CalculateBaseLine(Int_t reqMinCount=1); + + /** + * Stop processing of one event. + * The data history of the event will be released. + * @return neg. error value if failed + * - EBADF event not started + */ + Int_t StopEvent(); + + /** + * Reset the base line history. + * @return neg. error code if failed + */ + Int_t ResetHistory(); + + /** + * Set threshold. + * The threshold effects to corrected data, signals smaller than threshold + * are suppressed. + * @param thresh Threshold for signal correction + * @return neg. error code if failed + */ + Int_t SetThreshold(AliHLTTPCSignal_t thresh); + + /** + * Set the raw data value of a certain channel. + * @param bin Channel number + * @param value ADC value + * @return neg. error value if failed + * - ERANGE bin out of range + * - BADF event cycle not started + */ + Int_t SetRawData(Int_t bin, AliHLTTPCSignal_t value); + + /** + * Get the raw data value of the current bin. + * The class holds the current read position which can be incremented by + * @ref Next() and reseted by @ref Rewind(). + * Raw data is only available within an event cycle. + * @return raw data value + */ + AliHLTTPCSignal_t GetRawData() const {return GetRawData(fReadPos);} + + /** + * Get the corrected data value the current bin. + * Corrected raw data is only available within an event cycle. + * The base line value is substracted from the bin's value and suppressed + * by the threshold. Bins smaller than the first bin considered for base + * line calculation return 0. + * The class holds the current read position which can be incremented by + * @ref Next() and reseted by @ref Rewind(). + * @return corrected value + */ + AliHLTTPCSignal_t GetCorrectedData() const {return GetCorrectedData(fReadPos);} + + /** + * Increment the read position. + * @param bZeroSuppression skip all bins effected by the zero suppression + * @return 1 if more data available, 0 if not + */ + Int_t Next(Int_t bZeroSuppression=kTRUE); + + /** + * Rewind the read position. + * The read position is set to the first bin over the zero suppression. + * @param bZeroSuppression skip all bins effected by the zero suppression + * @return 1 if more data available, 0 if not + */ + Int_t Rewind(Int_t bZeroSuppression=kTRUE); + + /** + * Get the current read position. + * @return read position, -1 if no data available + */ + Int_t GetCurrentPosition() const {return fReadPos