]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - FMD/AliFMDRawWriter.cxx
fixes
[u/mrichter/AliRoot.git] / FMD / AliFMDRawWriter.cxx
index e91daab14c155400617c61a17d69ba97b032066d..dec8f4e5de04c7885ff33a1492bcc2d280cce67f 100644 (file)
@@ -37,9 +37,9 @@
 // that format.  
 //
 // #include <AliLog.h>         // ALILOG_H
-#include "AliFMDDebug.h" // Better debug macros
+#include "AliFMDDebug.h"        // Better debug macros
 #include <AliLoader.h>         // ALILOADER_H
-#include <AliAltroBuffer.h>     // ALIALTROBUFFER_H
+#include <AliAltroBufferV3.h>   // ALIALTROBUFFER_H
 #include "AliFMD.h"            // ALIFMD_H
 #include "AliFMDParameters.h"  // ALIFMDPARAMETERS_H
 #include "AliFMDDigit.h"       // ALIFMDDIGIT_H
 #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 <TTree.h>
 // #include <fstream>
 #include "AliDAQ.h"
 
@@ -138,14 +141,15 @@ AliFMDRawWriter::Exec(Option_t*)
     return;
   }
   
-  TClonesArray* digits = new TClonesArray("AliFMDDigit", 1000);
   fFMD->SetTreeAddress();
-  TBranch* digitBranch = digitTree->GetBranch(fFMD->GetName());
-  if (!digitBranch) {
-    AliError(Form("no branch for %s", fFMD->GetName()));
-    return;
-  }
-  digitBranch->SetAddress(&digits);
+  TClonesArray* digits = fFMD->Digits(); 
+  // new TClonesArray("AliFMDDigit", 1000);
+  // TBranch* digitBranch = digitTree->GetBranch(fFMD->GetName());
+  // if (!digitBranch) {
+  //   AliError(Form("no branch for %s", fFMD->GetName()));
+  //   return;
+  // }
+  // digitBranch->SetAddress(&digits);
   
   Int_t nEvents = Int_t(digitTree->GetEntries());
   AliFMDDebug(5, ("Got a total of %5d events from tree", nEvents));
@@ -157,16 +161,17 @@ AliFMDRawWriter::Exec(Option_t*)
     WriteDigits(digits);
   }
   loader->UnloadDigits();
+  //delete digits;
 }
 
 #if 1
 //____________________________________________________________________
-void
+Long_t
 AliFMDRawWriter::WriteDigits(TClonesArray* digits)
 {
   // WRite an array of digits to disk file 
   Int_t nDigits = digits->GetEntries();
-  if (nDigits < 1) return;
+  if (nDigits < 1) return 0;
   AliFMDDebug(5, ("Got a total of %5d digits from tree", nDigits));
 
   AliFMDParameters* pars = AliFMDParameters::Instance();
@@ -178,17 +183,21 @@ AliFMDRawWriter::WriteDigits(TClonesArray* digits)
   // Which channel number in the ALTRO channel we're at 
   UShort_t nWords       = 0;
   UShort_t preSamples   = 0;
-  
-  // How many times the ALTRO Samples one VA1_ALICE channel 
-  Int_t sampleRate      = 1;
+  UShort_t sampleRate   = 0;
   
   // 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;
-    
+  AliAltroBufferV3* altro = 0;
+  
+  Int_t  totalWords = 0;
+  Int_t  nCounts    = 0;
+  Long_t nBits      = 0;
+
   // Loop over the digits in the event.  Note, that we assume the
   // the digits are in order in the branch.   If they were not, we'd
   // have to cache all channels before we could write the data to
@@ -201,85 +210,181 @@ AliFMDRawWriter::WriteDigits(TClonesArray* digits)
     Char_t   ring   = digit->Ring();
     UShort_t sector = digit->Sector();
     UShort_t strip  = digit->Strip();
-    UInt_t   ddl;
-    UInt_t   addr;  
+    UShort_t ddl, addr, time;
+
+    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);
+    preSamples = pars->GetPreSamples(det, ring, sector, strip);
+
     if (det != oldDet) {
       AliFMDDebug(5, ("Got new detector: %d (was %d)", det, oldDet));
       oldDet = det;
     }
-    AliFMDDebug(10, ("Processing digit # %5d FMD%d%c[%2d,%3d]", 
-                   i, det, ring, sector, strip));
-    threshold       = pars->GetZeroSuppression(det, ring, sector, strip);
-    if (!pars->Detector2Hardware(det, ring, sector, strip, ddl, addr)) {
-      AliError(Form("Failed to get hardware address for FMD%d%c[%2d,%3d]", 
-                   det, ring, sector, strip));
-      continue;
-    }
-    preSamples = pars->GetPreSamples(det, ring, sector, strip);
+    AliFMDDebug(15, ("Sample rate is %d", sampleRate));
     
-    AliFMDDebug(10, ("FMD%d%c[%2d,%3d]-> ddl: 0x%x addr: 0x%x", 
-                   det, ring, sector, strip, ddl, addr));
-    if (addr != prevaddr) {
-      // Flush a channel to output 
-      AliFMDDebug(15, ("Now hardware address 0x%x from FMD%d%c[%2d,%3d] "
-                      "(board 0x%x, chip 0x%x, channel 0x%x), flushing old "
-                      "channel at 0x%x with %d words", 
-                      addr, det, ring, sector, strip, 
-                      (addr >> 7), (addr >> 4) & 0x7, addr & 0xf, 
-                      prevaddr, nWords));
-      if (altro) altro->WriteChannel(prevaddr,nWords,data.fArray,threshold);
-      nWords   = preSamples;
-      prevaddr = addr;
-      for (size_t j = 0; j < nWords; j++) data[j] = digit->Count(0);
-    }
-    if (ddl != prevddl) {
-      AliFMDDebug(5, ("FMD: New DDL, was %d, now %d", prevddl, ddl));
-      // If an altro exists, delete the object, flushing the data to
-      // disk, and closing the file. 
-      if (altro) { 
-       // When the first argument is false, we write the real
-       // header. 
-       AliFMDDebug(15, ("Closing output"));
-       altro->Flush();
-       altro->WriteDataHeader(kFALSE, kFALSE);
-       delete altro;
-       altro = 0;
+    for (UShort_t j = 0; j < sampleRate; j++) { 
+      if (!pars->Detector2Hardware(det,ring,sector,strip,j,ddl,addr,time)){
+       AliError(Form("Failed to get hardware address for FMD%d%c[%2d,%3d]-%d", 
+                     det, ring, sector, strip, j));
+       continue;
       }
-      prevddl = ddl;
-      // Need to open a new DDL! 
-      TString filename(AliDAQ::DdlFileName(fFMD->GetName(),  ddl));
-      AliFMDDebug(5, ("New altro buffer with DDL file %s", filename.Data()));
-      // Create a new altro buffer - a `1' as the second argument
-      // means `write mode' 
-      altro = new AliAltroBuffer(filename.Data());
-      altro->SetMapping(pars->GetAltroMap());      
-      // Write a dummy (first argument is true) header to the DDL
-      // file - later on, when we close the file, we write the real
-      // header
-      altro->WriteDataHeader(kTRUE, kFALSE);
-    }
     
-    // Store the counts of the ADC in the channel buffer 
-    sampleRate = pars->GetSampleRate(det, ring, sector, strip);
-    for (int s = 0; s < sampleRate; s++) {
-      data[nWords] = digit->Count(s);
+      AliFMDDebug(10, ("FMD%d%c[%2d,%3d]-%d-> 0x%x/0x%x/%04d", 
+                      det, ring, sector, strip, j, ddl, addr, time));
+      if (addr != prevaddr) {
+       // Flush a channel to output 
+       AliFMDDebug(5, ("Now hardware address 0x%x from FMD%d%c[%2d,%3d]-%d"
+                        "(b: 0x%02x, a: 0x%01x, c: 0x%02x, t: %04d), "
+                        "flushing old channel at 0x%x with %d words", 
+                        addr, det, ring, sector, strip, j,
+                        (addr >> 7), (addr >> 4) & 0x7, addr & 0xf, 
+                        time, prevaddr, nWords));
+       totalWords += nWords;
+       ZeroSuppress(data.fArray, nWords, peds.fArray, noise.fArray, threshold);
+       if (altro) 
+         /*nBits+=*/altro->WriteChannel(prevaddr,nWords,data.fArray,threshold);
+       data.Reset(-1);
+       peds.Reset(0);
+       noise.Reset(0);
+       nWords   = 0;
+       prevaddr = addr;
+      }
+      if (ddl != prevddl) {
+       AliFMDDebug(10, ("FMD: New DDL, was %d, now %d", prevddl, ddl));
+       // If an altro exists, delete the object, flushing the data to
+       // disk, and closing the file. 
+       if (altro) { 
+         // When the first argument is false, we write the real
+         // header. 
+         AliFMDDebug(15, ("Closing output"));
+         /* nBits += */ altro->Flush();
+         /* nBits += */ altro->WriteDataHeader(kFALSE, kFALSE);
+         delete altro;
+         altro = 0;
+       }
+       prevddl = ddl;
+       // Need to open a new DDL! 
+       TString filename(AliDAQ::DdlFileName(fFMD ? fFMD->GetName() : "FMD",  ddl));
+       AliFMDDebug(5, ("New altro buffer with DDL file %s", filename.Data()));
+       // Create a new altro buffer - a `1' as the second argument
+       // means `write mode' 
+       altro = new AliAltroBufferV3(filename.Data());
+       altro->SetMapping(pars->GetAltroMap());      
+       // Write a dummy (first argument is true) header to the DDL
+       // file - later on, when we close the file, we write the real
+       // header
+       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(15, ("Storing FMD%d%c[%02d,%03d]-%d in timebin %d (%d)",
+                     det, ring, sector, strip, j, time, preSamples));
+      data[time] = digit->Count(j);
       nWords++;
+      nCounts++;
+      if (time == preSamples) {
+       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;
+      }
     }
   }
   // Finally, we need to close the final ALTRO buffer if it wasn't
   // already 
   if (altro) {
-    if (nWords > 0) altro->WriteChannel(prevaddr,nWords,data.fArray,threshold);
-    altro->Flush();
-    altro->WriteDataHeader(kFALSE, kFALSE);
+    ZeroSuppress(data.fArray, nWords, peds.fArray, noise.fArray, threshold);
+    if (nWords > 0) 
+      /* nBits += */ altro->WriteChannel(prevaddr,nWords,data.fArray,threshold);
+    /* nBits += */ altro->Flush();
+    /* nBits += */ altro->WriteDataHeader(kFALSE, kFALSE);
     delete altro;
   }
+  AliFMDDebug(5, ("Wrote a total of %d words in %ld bytes for %d counts", 
+                 nWords, nBits / 8, nCounts));
+  return nBits;
 }
+//____________________________________________________________________
+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
 AliFMDRawWriter::WriteDigits(TClonesArray* digits)
 {
+  // 
+  // Write digits to file 
+  //
   Int_t nDigits = digits->GetEntries();
   if (nDigits < 1) return;
 
@@ -368,3 +473,4 @@ AliFMDRawWriter::WriteDigits(TClonesArray* digits)
 // 
 // EOF
 //
+