From cce354f6461eaffb98dca5dd52f01e3b384f8680 Mon Sep 17 00:00:00 2001 From: cholm Date: Mon, 1 Sep 2008 22:17:59 +0000 Subject: [PATCH] Fixes for reading zero-suppressed data. Also fixes to simulated raw data making. Cvetan, perhaps you want to take a look at the member function AliFMDRawWriter::ZeroSuppress which correctly, I believe, simulates the zero suppression circuit of the ALTRO chip. --- FMD/AliFMDParameters.cxx | 3 ++ FMD/AliFMDParameters.h | 24 ++++++++++ FMD/AliFMDRawReader.cxx | 7 ++- FMD/AliFMDRawStream.cxx | 6 ++- FMD/AliFMDRawStream.h | 2 +- FMD/AliFMDRawWriter.cxx | 94 +++++++++++++++++++++++++++++++++++++--- FMD/AliFMDRawWriter.h | 20 ++++++--- 7 files changed, 140 insertions(+), 16 deletions(-) diff --git a/FMD/AliFMDParameters.cxx b/FMD/AliFMDParameters.cxx index 2cc4e8bb7f8..bbed9b2f0e4 100644 --- a/FMD/AliFMDParameters.cxx +++ b/FMD/AliFMDParameters.cxx @@ -86,6 +86,9 @@ AliFMDParameters::AliFMDParameters() fAltroChannelSize(0), fChannelsPerAltro(0), fPedestalFactor(0), + fZSPre(0), + fZSPost(0), + fZSPedSubtract(kFALSE), fFixedPedestal(0), fFixedPedestalWidth(0), fFixedZeroSuppression(0), diff --git a/FMD/AliFMDParameters.h b/FMD/AliFMDParameters.h index 9d0a26f500c..3e2ac16272e 100644 --- a/FMD/AliFMDParameters.h +++ b/FMD/AliFMDParameters.h @@ -146,6 +146,15 @@ public: void SetChannelsPerAltro(UShort_t size=128) { fChannelsPerAltro = size; } /** @param f Factor to use for accepting a signal. */ void SetPedestalFactor(Float_t f=3) { fPedestalFactor = f; } + /** @param n Number of pre-samples to keep during zero-suppression - + only used in simulation. */ + void SetZSPreSamples(UShort_t n=1) { fZSPre = (n & 0x3); } + /** @param n Number of post-samples to keep during zero-suppression - + only used in simulation. */ + void SetZSPostSamples(UShort_t n=1) { fZSPost = (n & 0x3); } + /** @param use If true, do pedestal subtraction before zero + suppression - only used in simulation */ + void SetZSPedSubtract(Bool_t use=kTRUE) { fZSPedSubtract = use; } /** @} */ /** @{ */ @@ -184,6 +193,15 @@ public: Float_t GetEdepMip() const; /** @return The factor used of signal acceptance */ Float_t GetPedestalFactor() const { return fPedestalFactor; } + /** @param n Number of pre-samples to keep during zero-suppression - + only used in simulation. */ + UShort_t GetZSPreSamples() const { return fZSPre; } + /** @param n Number of post-samples to keep during zero-suppression - + only used in simulation. */ + UShort_t GetZSPostSamples() const { return fZSPost; } + /** @param use If true, do pedestal subtraction before zero + suppression - only used in simulation */ + Bool_t IsZSPedSubtract() const { return fZSPedSubtract; } /** @} */ /** @{ */ @@ -432,6 +450,9 @@ protected: fAltroChannelSize(o.fAltroChannelSize), fChannelsPerAltro(o.fChannelsPerAltro), fPedestalFactor(o.fPedestalFactor), + fZSPre(o.fZSPre), + fZSPost(o.fZSPost), + fZSPedSubtract(o.fZSPedSubtract), fFixedPedestal(o.fFixedPedestal), fFixedPedestalWidth(o.fFixedPedestalWidth), fFixedZeroSuppression(o.fFixedZeroSuppression), @@ -494,6 +515,9 @@ protected: UShort_t fAltroChannelSize; // Largest # to store in 1 ADC ch. UShort_t fChannelsPerAltro; // Number of pre-amp. chan/adc chan. Float_t fPedestalFactor; // Number of pedestal widths + UShort_t fZSPre; // Number of pre-samples in ZS + UShort_t fZSPost; // Number of post-samples in ZS + Bool_t fZSPedSubtract; // Pedestal subtraction before ZS Float_t fFixedPedestal; // Pedestal to subtract Float_t fFixedPedestalWidth; // Width of pedestal diff --git a/FMD/AliFMDRawReader.cxx b/FMD/AliFMDRawReader.cxx index bc4c14255e4..02e83a55866 100644 --- a/FMD/AliFMDRawReader.cxx +++ b/FMD/AliFMDRawReader.cxx @@ -141,6 +141,9 @@ AliFMDRawReader::ReadAdcs(TClonesArray* array) Bool_t isGood = kTRUE; while (isGood) { + // Set data cache to all zero. + for (size_t i = 0; i < 2048; i++) data[i] = 0; + isGood = input.ReadChannel(ddl, hwaddr, last, data); // if (!isGood) break; if (ddl >= UInt_t(-1)) { @@ -165,8 +168,8 @@ AliFMDRawReader::ReadAdcs(TClonesArray* array) "hardware address 0x%03x, timebin %d", ddl, hwaddr, i)); continue; } - AliFMDDebug(10, ("0x%04x/0x%03x/%04d maps to FMD%d%c[%2d,%3d]-%d", - ddl, hwaddr, i, det, ring, sec, str, samp)); + AliFMDDebug(8, ("0x%04x/0x%03x/%04d maps to FMD%d%c[%2d,%3d]-%d = %d", + ddl, hwaddr, i, det, ring, sec, str, samp, data[i])); if (str < 0) { AliFMDDebug(8, ("Got presamples at timebin %d", i)); continue; diff --git a/FMD/AliFMDRawStream.cxx b/FMD/AliFMDRawStream.cxx index f463cc78337..757e5baf20e 100644 --- a/FMD/AliFMDRawStream.cxx +++ b/FMD/AliFMDRawStream.cxx @@ -54,7 +54,7 @@ AliFMDRawStream::AliFMDRawStream(AliRawReader* reader) //_____________________________________________________________________________ Bool_t AliFMDRawStream::ReadChannel(UInt_t& ddl, UInt_t& addr, - UInt_t& len, UShort_t* data) + UInt_t& len, volatile UShort_t* data) { // Read one channel and return. Returns 0 when there's no more // data. @@ -89,6 +89,10 @@ AliFMDRawStream::ReadChannel(UInt_t& ddl, UInt_t& addr, l = TMath::Max(l, t); data[t] = signal; last = 0xFFFF; +#if 0 + AliFMDDebug(signal > 512 ? 1 : 0, ("Signal @ %d (%d) is %d", + time, t, data[t])); +#endif } while (next); return next; } diff --git a/FMD/AliFMDRawStream.h b/FMD/AliFMDRawStream.h index 897224a06d8..68fda921335 100644 --- a/FMD/AliFMDRawStream.h +++ b/FMD/AliFMDRawStream.h @@ -48,7 +48,7 @@ public: @param data On return, the read ADC channels. @return @c true on success */ virtual Bool_t ReadChannel(UInt_t& ddl, UInt_t& addr, - UInt_t& len, UShort_t* data); + UInt_t& len, volatile UShort_t* data); protected: ClassDef(AliFMDRawStream, 0) // Read raw FMD Altro data diff --git a/FMD/AliFMDRawWriter.cxx b/FMD/AliFMDRawWriter.cxx index af05dd4ea1e..4b3c448f085 100644 --- a/FMD/AliFMDRawWriter.cxx +++ b/FMD/AliFMDRawWriter.cxx @@ -47,6 +47,8 @@ #include "AliFMDAltroMapping.h" // ALIFMDALTROMAPPING_H // #include "AliFMDAltroIO.h" // ALIFMDALTROWRITER_H #include // ROOT_TArrayI +#include // ROOT_TArrayI +#include // ROOT_TArrayI #include // ROOT_TClonesArray // #include #include "AliDAQ.h" @@ -183,6 +185,8 @@ AliFMDRawWriter::WriteDigits(TClonesArray* digits) // A buffer to hold 1 ALTRO channel - Normally, one ALTRO channel // holds 128 VA1_ALICE channels, sampled at a rate of `sampleRate' TArrayI data(pars->GetChannelsPerAltro() * 8); + TArrayF peds(pars->GetChannelsPerAltro() * 8); + TArrayF noise(pars->GetChannelsPerAltro() * 8); // The Altro buffer AliAltroBuffer* altro = 0; @@ -206,7 +210,7 @@ AliFMDRawWriter::WriteDigits(TClonesArray* digits) UInt_t addr; UShort_t time; - AliFMDDebug(10, ("Processing digit # %5d FMD%d%c[%2d,%3d]", + AliFMDDebug(15, ("Processing digit # %5d FMD%d%c[%2d,%3d]", i, det, ring, sector, strip)); threshold = pars->GetZeroSuppression(det, ring, sector, strip); sampleRate = pars->GetSampleRate(det, ring, sector, strip); @@ -216,7 +220,7 @@ AliFMDRawWriter::WriteDigits(TClonesArray* digits) AliFMDDebug(5, ("Got new detector: %d (was %d)", det, oldDet)); oldDet = det; } - AliFMDDebug(10, ("Sample rate is %d", sampleRate)); + AliFMDDebug(15, ("Sample rate is %d", sampleRate)); for (UShort_t j = 0; j < sampleRate; j++) { if (!pars->Detector2Hardware(det,ring,sector,strip,j,ddl,addr,time)){ @@ -236,7 +240,11 @@ AliFMDRawWriter::WriteDigits(TClonesArray* digits) (addr >> 7), (addr >> 4) & 0x7, addr & 0xf, time, prevaddr, nWords)); totalWords += nWords; + ZeroSuppress(data.fArray, nWords, peds.fArray, noise.fArray, threshold); if (altro) altro->WriteChannel(prevaddr,nWords,data.fArray,threshold); + data.Reset(-1); + peds.Reset(0); + noise.Reset(0); nWords = 0; prevaddr = addr; } @@ -267,16 +275,24 @@ AliFMDRawWriter::WriteDigits(TClonesArray* digits) altro->WriteDataHeader(kTRUE, kFALSE); } + // Get the pedestal value + peds[time] = pars->GetPedestal(det, ring, sector, strip); + noise[time] = pars->GetPedestalWidth(det, ring, sector, strip); + // Store the counts of the ADC in the channel buffer - AliFMDDebug(6, ("Storing FMD%d%c[%02d,%03d]-%d in timebin %d (%d)", + AliFMDDebug(15, ("Storing FMD%d%c[%02d,%03d]-%d in timebin %d (%d)", det, ring, sector, strip, j, time, preSamples)); - UShort_t count = digit->Count(j); - data[time] = count; + data[time] = digit->Count(j); nWords++; nCounts++; if (time == preSamples) { - AliFMDDebug(5, ("Filling in %4d for %d presamples", count, preSamples)); - for (int k = 0; k < preSamples; k++) data[k] = count; + AliFMDDebug(15, ("Filling in %4d for %d presamples", + data[time], preSamples)); + for (int k = 0; k < preSamples; k++) { + peds[k] = peds[time]; + noise[k] = noise[time]; + data[k] = data[time]; + } nWords += preSamples; } } @@ -284,6 +300,7 @@ AliFMDRawWriter::WriteDigits(TClonesArray* digits) // Finally, we need to close the final ALTRO buffer if it wasn't // already if (altro) { + ZeroSuppress(data.fArray, nWords, peds.fArray, noise.fArray, threshold); if (nWords > 0) altro->WriteChannel(prevaddr,nWords,data.fArray,threshold); altro->Flush(); altro->WriteDataHeader(kFALSE, kFALSE); @@ -292,6 +309,69 @@ AliFMDRawWriter::WriteDigits(TClonesArray* digits) AliFMDDebug(5, ("Wrote a total of %d words for %d counts", nWords, nCounts)); } +//____________________________________________________________________ +void +AliFMDRawWriter::ZeroSuppress(Int_t*& data, Int_t nWords, + const Float_t* peds, + const Float_t* noise, UShort_t threshold) const +{ + // Simulate the ALTRO zero-suppression filter. The data passed in + // the first array is modified, such that all suppressed channels + // are set to some value below threshold. + // + // If threshold == 0 zero suppression is considered disabled, and no + // action is taken. + if (threshold <= 0) return; + + // const Short_t width = 3; + // If fPedSubtract is false, compare data-(ped+f*noise), if true + // always modify data by -(ped+f*noise), and force negative values + // to zero. + Bool_t pedSubtract = AliFMDParameters::Instance()->IsZSPedSubtract(); + UShort_t pre = AliFMDParameters::Instance()->GetZSPreSamples(); + UShort_t post = AliFMDParameters::Instance()->GetZSPostSamples(); + Float_t factor = AliFMDParameters::Instance()->GetPedestalFactor(); + + TArrayC mask(nWords+1); + for (Short_t i = 0; i < nWords; i++) { + Float_t val = data[i] - peds[i] - factor * noise[i]; + if (val < 0.5) val = 0; + if (pedSubtract) data[i] = Int_t(val) & 0x3FF; + + mask[i] = (val > threshold ? 1 : 0); + AliFMDDebug(10, ("Comparing sample %d %d-%f-%f*%f=%f to %d -> %s", + i, data[i], peds[i], factor, noise[i], val, threshold, + (mask[i] ? "above" : "below"))); + } + + for (Short_t i = 0; i < nWords; i++) { + if (mask[i]) { // Signal above, so do nothing + AliFMDDebug(10, ("Sample %d, above", i)); + if (i < nWords-1 && !mask[i+1]) { + // After a valid sample. Increase the pointer to the next + // possible data, thereby skipping over the post-samples + AliFMDDebug(10, ("At sample %d, next is below, skipping %d to %d", + i, post, i+post)); + i += post; + } + continue; + } + + Short_t lookahead = TMath::Min(Short_t(nWords), Short_t(i+pre)); + AliFMDDebug(10, ("Sample %d, below, look to %d", i, lookahead)); + if (mask[lookahead] && pre > 0) { + AliFMDDebug(10, ("Sample %d is a pre-sample to %d", i, lookahead)); + // We're in a presample, so don't modify the data, and increase + // counter by the number of pre-samples + i += pre-1; + continue; + } + + // This sample must be surpressed + data[i] = threshold - 1; + } +} + #else //____________________________________________________________________ void diff --git a/FMD/AliFMDRawWriter.h b/FMD/AliFMDRawWriter.h index 6deabb95cfa..d1c309fd3b6 100644 --- a/FMD/AliFMDRawWriter.h +++ b/FMD/AliFMDRawWriter.h @@ -27,6 +27,7 @@ class AliFMD; class AliAltroBuffer; class TArrayI; +class TArrayF; class TClonesArray; //____________________________________________________________________ @@ -56,20 +57,29 @@ public: @param digits Array of AliFMDDigit objects to convert to raw ALTRO data. */ virtual void WriteDigits(TClonesArray* digits); + /** Do zero-suppression of channel data. + @param data Contain @a nWords of valid data. On input, it + contains the full channel data. On output it + will contain the zero-suppresed data. + @param peds Contain @a nWords pedestals + @param noise Contain @a nWords pedestal widths + @param threshold Zero suppression threshold. */ + void ZeroSuppress(Int_t*& data, Int_t nWords, const Float_t* peds, + const Float_t* noise, UShort_t threshold) const; protected: AliFMDRawWriter(const AliFMDRawWriter& o) : TTask(o), - fFMD(0), - fSampleRate(0), - fChannelsPerAltro(0), - fThreshold(0) + fFMD(o.fFMD), + fSampleRate(o.fSampleRate), + fChannelsPerAltro(o.fChannelsPerAltro), + fThreshold(o.fThreshold) {} AliFMDRawWriter& operator=(const AliFMDRawWriter&) { return *this; } AliFMD* fFMD; //! Pointer to detector description UShort_t fSampleRate; // The sample rate (0 -> inferred from data) UShort_t fChannelsPerAltro; // Number of pre-amp. channels/adc channel UShort_t fThreshold; // Threshold for zero-suppression - + ClassDef(AliFMDRawWriter, 0) // Write FMD raw data to a DDL file }; -- 2.43.0