Fixes for reading zero-suppressed data. Also fixes to simulated raw
authorcholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 1 Sep 2008 22:17:59 +0000 (22:17 +0000)
committercholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 1 Sep 2008 22:17:59 +0000 (22:17 +0000)
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
FMD/AliFMDParameters.h
FMD/AliFMDRawReader.cxx
FMD/AliFMDRawStream.cxx
FMD/AliFMDRawStream.h
FMD/AliFMDRawWriter.cxx
FMD/AliFMDRawWriter.h

index 2cc4e8b..bbed9b2 100644 (file)
@@ -86,6 +86,9 @@ AliFMDParameters::AliFMDParameters()
     fAltroChannelSize(0),
     fChannelsPerAltro(0),
     fPedestalFactor(0),
+    fZSPre(0),
+    fZSPost(0),
+    fZSPedSubtract(kFALSE),
     fFixedPedestal(0),
     fFixedPedestalWidth(0),
     fFixedZeroSuppression(0),
index 9d0a26f..3e2ac16 100644 (file)
@@ -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
index bc4c142..02e83a5 100644 (file)
@@ -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;
index f463cc7..757e5ba 100644 (file)
@@ -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;
 }
index 897224a..68fda92 100644 (file)
@@ -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 
index af05dd4..4b3c448 100644 (file)
@@ -47,6 +47,8 @@
 #include "AliFMDAltroMapping.h" // ALIFMDALTROMAPPING_H
 // #include "AliFMDAltroIO.h"   // ALIFMDALTROWRITER_H
 #include <TArrayI.h>           // ROOT_TArrayI
+#include <TArrayF.h>           // ROOT_TArrayI
+#include <TArrayC.h>           // ROOT_TArrayI
 #include <TClonesArray.h>      // ROOT_TClonesArray
 // #include <fstream>
 #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
index 6deabb9..d1c309f 100644 (file)
@@ -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
 };