Added shuttle preprocessor code from Hans Dalsgaard (with several
authorcholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sun, 21 Oct 2007 09:46:21 +0000 (09:46 +0000)
committercholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sun, 21 Oct 2007 09:46:21 +0000 (09:46 +0000)
corrections).   Added test script script/TestPreprocessor.C too.  The
test script generates its own input, runs the (test) shuttle with that
input, reads back the newly written values, and compares to the known
input.

Added extra convinience member functions to AliFMDAltroMapping, including
the Print member function to dump the map to standard out.

Added parameter to AliFMDParameters::Init to enable getting only a
subset of the calibration parameters.  This is needed by the shuttle
preprocessor in order to be independt of previously written data.

FMD/.cvsignore
FMD/AliFMDAltroMapping.cxx
FMD/AliFMDAltroMapping.h
FMD/AliFMDParameters.cxx
FMD/AliFMDParameters.h
FMD/AliFMDPreprocessor.cxx [new file with mode: 0644]
FMD/AliFMDPreprocessor.h [new file with mode: 0644]
FMD/FMDbaseLinkDef.h
FMD/libFMDbase.pkg
FMD/scripts/TestPreprocessor.C [new file with mode: 0644]

index 5ce09ed..c39dcb8 100644 (file)
@@ -6,3 +6,4 @@ geant*
 runIt.C
 runflukageo.sh
 rungeant3geo.sh
+TestCDB
index 11048dc..0fffc02 100644 (file)
@@ -37,6 +37,8 @@
 #include "AliFMDAltroMapping.h"                // ALIFMDALTROMAPPING_H
 #include "AliFMDParameters.h"
 #include "AliLog.h"
+#include <iostream>
+#include <iomanip>
 
 //____________________________________________________________________
 ClassImp(AliFMDAltroMapping)
@@ -73,6 +75,22 @@ AliFMDAltroMapping::Hardware2Detector(UInt_t    ddl, UInt_t    addr,
                                      UShort_t& sec, UShort_t& str) const
 {
   // Translate a hardware address to detector coordinates. 
+  // 
+  // See also Hardware2Detector that accepts 4 inputs 
+  UInt_t board =  (addr >> 7) & 0x1F;
+  UInt_t altro =  (addr >> 4) & 0x7;
+  UInt_t chan  =  (addr & 0xf);
+  return Hardware2Detector(ddl, board, altro, chan, det, ring, sec, str);
+}
+
+//____________________________________________________________________
+Bool_t 
+AliFMDAltroMapping::Hardware2Detector(UInt_t    ddl,   UInt_t    board, 
+                                     UInt_t    altro, UInt_t    chan,
+                                     UShort_t& det,   Char_t&   ring, 
+                                     UShort_t& sec,   UShort_t& str) const
+{
+  // Translate a hardware address to detector coordinates. 
   // The detector is simply 
   // 
   //    ddl + 1
@@ -142,9 +160,6 @@ AliFMDAltroMapping::Hardware2Detector(UInt_t    ddl, UInt_t    addr,
   // return the first strip in the given range. 
   //
   det          =  ddl + 1;
-  UInt_t board =  (addr >> 7) & 0x1F;
-  UInt_t altro =  (addr >> 4) & 0x7;
-  UInt_t chan  =  (addr & 0xf);
   ring         =  (board % 2) == 0 ? 'I' : 'O';
   switch (ring) {
   case 'i':
@@ -165,9 +180,10 @@ AliFMDAltroMapping::Hardware2Detector(UInt_t    ddl, UInt_t    addr,
 
 //____________________________________________________________________
 Bool_t 
-AliFMDAltroMapping::Detector2Hardware(UShort_t  det, Char_t    ring, 
-                                     UShort_t  sec, UShort_t  str,
-                                     UInt_t&   ddl, UInt_t&   addr) const
+AliFMDAltroMapping::Detector2Hardware(UShort_t  det,   Char_t    ring, 
+                                     UShort_t  sec,   UShort_t  str,
+                                     UInt_t&   ddl,   UInt_t&   board,
+                                     UInt_t&   altro, UInt_t&   chan) const
 {
   // Translate detector coordinates to a hardware address.
   // The ddl is simply 
@@ -250,28 +266,40 @@ AliFMDAltroMapping::Detector2Hardware(UShort_t  det, Char_t    ring,
   // give us a unique hardware address 
   //
   ddl          =  (det - 1);
-  UInt_t board = 0;
-  UInt_t altro = 0;
-  UInt_t chan  = 0;
   UInt_t tmp   = 0;
   switch (ring) {
   case 'I':
   case 'i':
-    board += (sec / 10) * 16;
+    board =  (sec / 10) * 16;
     altro =  (sec % 10) < 4 ? 0 : (sec % 10) < 6 ? 1 : 2;
     tmp   =  (sec % 10) - (altro == 0 ? 0 : altro == 1 ? 4 : 6);
     chan  =  2  * (str / 128) + (sec % 2) + ((tmp / 2) % 2) * 8;
     break;
   case 'O':
   case 'o':
-    board += (sec / 20) * 20 + 1;
+    board =  (sec / 20) * 16 + 1;
     altro =  (sec % 20) < 8 ? 0 : (sec % 20) < 12 ? 1 : 2;
     tmp   =  (sec % 20) - (altro == 0 ? 0 : altro == 1 ? 8 : 12);
     chan  =  2 * (str / 128) + (sec % 2) + ((tmp / 2) % 4) * 4;
     break;
   }
-  addr         =  chan + (altro << 4) + (board << 7);
-  
+  return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t 
+AliFMDAltroMapping::Detector2Hardware(UShort_t  det, Char_t    ring, 
+                                     UShort_t  sec, UShort_t  str,
+                                     UInt_t&   ddl, UInt_t&   addr) const
+{
+  // Translate detector coordinates to a hardware address.  
+  // 
+  // See also Detector2Hardware that returns 4 parameters.  
+  UInt_t board = 0;
+  UInt_t altro = 0;
+  UInt_t chan  = 0;
+  if (!Detector2Hardware(det,ring,sec,str,ddl,board,altro,chan)) return kFALSE;
+  addr =  chan + (altro << 4) + (board << 7);
   return kTRUE;
 }
 
@@ -361,6 +389,88 @@ AliFMDAltroMapping::GetSector(Int_t hwaddr) const
   return Int_t(ring);
 }
 
+//____________________________________________________________________
+void
+AliFMDAltroMapping::Print(Option_t* option) const
+{
+  TString opt(option);
+  opt.ToLower();
+  UInt_t ddl, board, chip, chan, addr;
+  UShort_t det, sec, str;
+  Char_t   rng;
+  
+  if (opt.Contains("hw") || opt.Contains("hardware")) { 
+    std::cout << " DDL | Board | Chip | Chan | Address | Detector\n"
+             << "=====+=======+======+======+=========+===============" 
+             << std::endl;
+    for (ddl = 0; ddl <= 2; ddl++) { 
+      Int_t  boards[] = { 0, 16, (ddl == 0 ? 32 : 1), 17, 32};
+      Int_t* ptr      = boards;
+      while ((board = *(ptr++)) < 32) { 
+       for (chip = 0; chip <= 2; chip++) { 
+         UInt_t nchan = (chip == 1 ? 8 : 16);
+         for (chan = 0; chan < nchan; chan++) { 
+           Hardware2Detector(ddl, board, chip, chan, det, rng, sec, str);
+           addr = ((board & 0x1f) << 7) | ((chip & 0x7) << 4) | (chan & 0xf);
+           std::cout << " "  
+                     << std::setw(3) << ddl   << " | " 
+                     << std::setfill('0')     << std::hex << " 0x"
+                     << std::setw(2) << board << " |  0x"
+                     << std::setw(1) << chip  << " |  0x"
+                     << std::setw(1) << chan  << " |   0x" 
+                     << std::setw(3) << addr  << " | " 
+                     << std::setfill(' ')     << std::dec << " FMD" 
+                     << std::setw(1) << det << rng << "[" 
+                     << std::setw(2) << sec << "," << std::setw(3) << str
+                     << "]" << std::endl;
+         } // for chan ...
+         if (chip == 2 && *ptr >= 32) continue;
+         std::cout << "     +       +      +      +         +              " 
+                   << std::endl;
+       } // for chip ... 
+      } // while board 
+      std::cout << "-----+-------+------+------+---------+---------------" 
+               << std::endl;
+    } // for ddl ... 
+  } // if hw 
+  if (opt.Contains("det")) { 
+    std::cout << " Detector      | DDL | Board | Chip | Chan | Address\n"
+             << "===============+=====+=======+======+======+========"
+             << std::endl;
+    for (det = 1; det <= 3; det++) { 
+      Char_t  rings[] = { 'I', (det == 1 ? '\0' : 'O'),'\0' };
+      Char_t* ptr     = rings;
+      while ((rng = *(ptr++)) != '\0') { 
+       UShort_t nsec = (rng == 'I' ?  20 :  40);
+       UShort_t nstr = (rng == 'I' ? 512 : 256);
+       for (sec = 0; sec < nsec; sec++) { 
+         for (str = 0; str < nstr; str += 128) {
+           ddl = board = chip = chan;
+           Detector2Hardware(det,rng,sec,str,ddl,board,chip,chan);
+           addr = ((board & 0x1f) << 7) | ((chip & 0x7) << 4) | (chan & 0xf);
+           std::cout << std::setfill(' ')     << std::dec << " FMD" 
+                     << std::setw(1) << det   << rng      << "[" 
+                     << std::setw(2) << sec   << "," 
+                     << std::setw(3) << str   << "] | " 
+                     << std::setw(3) << ddl   << " |  0x"
+                     << std::setfill('0')     << std::hex  
+                     << std::setw(2) << board << " |  0x"
+                     << std::setw(1) << chip  << " |  0x"
+                     << std::setw(1) << chan  << " |   0x" 
+                     << std::setw(3) << addr  << std::endl;
+         } // for str ...
+       } // for sec ... 
+       if (*ptr == '\0') continue;
+       std::cout << "               +     +       +      +      +        " 
+                 << std::endl;
+      } // while rng ... 
+      std::cout << "---------------+-----+-------+------+------+--------" 
+               << std::endl;
+
+    } // for det ... 
+  } // if det 
+}
+
 //_____________________________________________________________________________
 //
 // EOF
index 1f98aa3..3f2bdad 100644 (file)
@@ -62,11 +62,39 @@ public:
       @param det    On return, the detector #
       @param ring   On return, the ring ID
       @param sec    On return, the sector #
-      @param str    On return, the strip #
+      @param str    On return, the base of strip #
       @return @c true on success, false otherwise */
   Bool_t Hardware2Detector(UInt_t    ddl, UInt_t    hwaddr, 
                           UShort_t& det, Char_t&   ring, 
                           UShort_t& sec, UShort_t& str) const;
+  /** Map a hardware address into a detector index. 
+      @param ddl     Hardware DDL number 
+      @param board   FEC number
+      @param altro   ALTRO number 
+      @param channel Channel number 
+      @param det     On return, the detector #
+      @param ring    On return, the ring ID
+      @param sec     On return, the sector #
+      @param str     On return, the base of strip #
+      @return @c true on success, false otherwise */
+  Bool_t Hardware2Detector(UInt_t    ddl,   UInt_t    board, 
+                          UInt_t    altro, UInt_t    channel,
+                          UShort_t& det,   Char_t&   ring, 
+                          UShort_t& sec,   UShort_t& str) const;
+  /** Map a detector index into a hardware address. 
+      @param det     The detector #
+      @param ring    The ring ID
+      @param sec     The sector #
+      @param str     The strip #
+      @param ddl     On return, hardware DDL number 
+      @param board   On return, the FEC board address (local to DDL)
+      @param altro   On return, the ALTRO number (local to FEC)
+      @param channel On return, the channel number (local to ALTRO)
+      @return @c true on success, false otherwise */
+  Bool_t Detector2Hardware(UShort_t  det,   Char_t    ring, 
+                          UShort_t  sec,   UShort_t  str,
+                          UInt_t&   ddl,   UInt_t&   board, 
+                          UInt_t&   altro, UInt_t&   channel) const;
   /** Map a detector index into a hardware address. 
       @param det    The detector #
       @param ring   The ring ID
@@ -105,6 +133,9 @@ public:
       @param hwaddr hardware address
       @return Ring ID as an integer */
   Int_t  GetSector(Int_t hwaddr) const;
+  /** Print map to standard out 
+      @param option Option string (hw, or det) */
+  void Print(Option_t* option="hw") const;
 protected:
   /** Read map from file - not used 
       @return @c true on success */
index 6ff951a..f324faf 100644 (file)
@@ -113,18 +113,18 @@ AliFMDParameters::AliFMDParameters()
 
 //__________________________________________________________________
 void
-AliFMDParameters::Init(Bool_t forceReInit)
+AliFMDParameters::Init(Bool_t forceReInit, UInt_t what)
 {
   // Initialize the parameters manager.  We need to get stuff from the
   // CDB here. 
   if (forceReInit) fIsInit = kFALSE;
   if (fIsInit) return;
-  InitPulseGain();
-  InitPedestal();
-  InitDeadMap();
-  InitSampleRate();
-  InitZeroSuppression();
-  InitAltroMap();
+  if (what & kPulseGain)       InitPulseGain();
+  if (what & kPedestal)        InitPedestal();
+  if (what & kDeadMap)         InitDeadMap();
+  if (what & kSampleRate)      InitSampleRate();
+  if (what & kZeroSuppression) InitZeroSuppression();
+  if (what & kAltroMap)        InitAltroMap();
   fIsInit = kTRUE;
   
 }
@@ -701,9 +701,20 @@ AliFMDParameters::GetAltroMap() const
 
 //__________________________________________________________________
 Bool_t
-AliFMDParameters::Hardware2Detector(UInt_t ddl, UInt_t addr, UShort_t& det,
-                                   Char_t& ring, UShort_t& sec, 
-                                   UShort_t& str) const
+AliFMDParameters::Hardware2Detector(UInt_t    ddl,  UInt_t    board, 
+                                   UInt_t    chip, UInt_t    chan,
+                                   UShort_t& det,  Char_t&   ring, 
+                                   UShort_t& sec,  UShort_t& str) const
+{
+  // Map hardware address to detector index
+  if (!fAltroMap) return kFALSE;
+  return fAltroMap->Hardware2Detector(ddl,board,chip,chan, det,ring,sec,str);
+}
+//__________________________________________________________________
+Bool_t
+AliFMDParameters::Hardware2Detector(UInt_t    ddl,  UInt_t    addr, 
+                                   UShort_t& det,  Char_t&   ring, 
+                                   UShort_t& sec,  UShort_t& str) const
 {
   // Map hardware address to detector index
   if (!fAltroMap) return kFALSE;
@@ -712,9 +723,21 @@ AliFMDParameters::Hardware2Detector(UInt_t ddl, UInt_t addr, UShort_t& det,
 
 //__________________________________________________________________
 Bool_t
-AliFMDParameters::Detector2Hardware(UShort_t det, Char_t ring, UShort_t sec, 
-                                   UShort_t str, UInt_t& ddl, 
-                                   UInt_t& addr) const                       
+AliFMDParameters::Detector2Hardware(UShort_t det,  Char_t   ring, 
+                                   UShort_t sec,  UShort_t str, 
+                                   UInt_t&  ddl,  UInt_t&  board, 
+                                   UInt_t&  chip, UInt_t&  chan) const
+{
+  // Map detector index to hardware address
+  if (!fAltroMap) return kFALSE;
+  return fAltroMap->Detector2Hardware(det,ring,sec,str, ddl,board,chip,chan);
+}
+
+//__________________________________________________________________
+Bool_t
+AliFMDParameters::Detector2Hardware(UShort_t det, Char_t   ring, 
+                                   UShort_t sec, UShort_t str, 
+                                   UInt_t&  ddl, UInt_t&  addr) const
 {
   // Map detector index to hardware address
   if (!fAltroMap) return kFALSE;
index 21ed1f5..b8e6891 100644 (file)
@@ -75,6 +75,22 @@ class AliFMDAltroMapping;
 class AliFMDParameters : public TNamed
 {
 public:
+  /** Enumeration of things to initialize */ 
+  enum What { 
+    /** Pulser gain */ 
+    kPulseGain = 0x1, // Pulser gain 
+    /** Pedestals and noise */ 
+    kPedestal = 0x2, // Pedestal and noise 
+    /** Dead channel map */ 
+    kDeadMap = 0x4, // Dead channel map
+    /**  Over sampling rate */ 
+    kSampleRate = 0x8, // Over sampling rate 
+    /** Zero suppression parameters */ 
+    kZeroSuppression = 0x10, // Zero suppression parameters 
+    /** ALTRO data map */ 
+    kAltroMap = 0x20 // Altro channel map
+  };
+  
   /** Singleton access
       @return  single to */
   static AliFMDParameters* Instance();
@@ -82,7 +98,9 @@ public:
   /** Initialize the manager.  This tries to read the parameters from
       CDB.  If that fails, the class uses the hard-coded parameters. 
    */
-  void Init(Bool_t forceReInit=kFALSE);
+  void Init(Bool_t forceReInit=kFALSE, 
+           UInt_t what = (kPulseGain|kPedestal|kDeadMap|kSampleRate|
+                          kZeroSuppression|kAltroMap));
   /** Print all parameters. 
       @param option Option string */
   void Print(Option_t* option="A") const;
@@ -235,6 +253,20 @@ public:
                       UShort_t strip) const;
   /** Translate hardware address to detector coordinates 
       @param ddl      DDL number 
+      @param board    Board address
+      @param chip     Chip #
+      @param channel  Channel #
+      @param det      On return, Detector # (1-3)
+      @param ring     On return, Ring ID ('I' or 'O')
+      @param sec      On return, Sector number (0-39)
+      @param str      On return, Strip number (0-511)
+      @return @c true on success. */
+  Bool_t   Hardware2Detector(UInt_t ddl,    UInt_t    board, 
+                            UInt_t chip,   UInt_t    channel, 
+                            UShort_t& det, Char_t&   ring, 
+                            UShort_t& sec, UShort_t& str) const;
+  /** Translate hardware address to detector coordinates 
+      @param ddl      DDL number 
       @param addr     Hardware address
       @param det      On return, Detector # (1-3)
       @param ring     On return, Ring ID ('I' or 'O')
@@ -243,6 +275,21 @@ public:
       @return @c true on success. */
   Bool_t   Hardware2Detector(UInt_t ddl, UInt_t addr, UShort_t& det,
                             Char_t& ring, UShort_t& sec, UShort_t& str) const;
+
+  /** Translate detector coordinates to hardware address 
+      @param det      Detector # (1-3)
+      @param ring     Ring ID ('I' or 'O')
+      @param sec      Sector number (0-39)
+      @param str      Strip number (0-511)
+      @param ddl      On return, DDL number 
+      @param board    On return, Board address
+      @param chip     On return, Chip #
+      @param channel  On return, Channel #
+      @return @c true on success. */
+  Bool_t   Detector2Hardware(UShort_t det, Char_t ring, 
+                            UShort_t sec, UShort_t str, 
+                            UInt_t& ddl,  UInt_t& board,
+                            UInt_t& chip, UInt_t& channel) const;
   /** Translate detector coordinates to hardware address 
       @param det      Detector # (1-3)
       @param ring     Ring ID ('I' or 'O')
diff --git a/FMD/AliFMDPreprocessor.cxx b/FMD/AliFMDPreprocessor.cxx
new file mode 100644 (file)
index 0000000..6c5df9d
--- /dev/null
@@ -0,0 +1,274 @@
+/**************************************************************************
+ * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * 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.                  *
+ **************************************************************************/
+/* $Id$ */
+/** @file    AliFMDPreprocessor.cxx
+    @author  Hans Hjersing Dalsgaard <canute@nbi.dk>
+    @date    Mon Mar 27 12:39:09 2006
+    @brief   Shuttle "preprocessor" for the FMD
+*/
+//___________________________________________________________________
+//
+// The class processes data points from DCS (via Amanada), and DAQ DA
+// files (via FXS) to make calibration data for the FMD. 
+//
+// Data points: 
+//    *  Nothing yet. 
+//
+// DAQ FXS file:
+//    * pedestals - a (ASCII) Comma Separated Values files with the
+//                  fields 
+//                       rcu    DDL number 
+//                       board   FEC board number 
+//                       chip    ALTRO chip number on FEC
+//                       channel ALTRO channel number
+//                       strip   VA1 strip number
+//                       sample  Sample number
+//                       ped     Mean of ADC spectra
+//                       noise   Spread of ADC spectra
+//                       mu      Mean of Gaussian fit to ADC spectra
+//                       sigma   Variance of Gaussian fit to ADC spectra
+//                       chi2    Chi^2 per degrees of freedom of fit
+//    * Gains     - a (ASCII) Comma Separated Values files with the
+//                  fields 
+//                       rcu    DDL number 
+//                       board   FEC board number 
+//                       chip    ALTRO chip number on FEC
+//                       channel ALTRO channel number
+//                       strip   VA1 strip number
+//                       gain    Slope of gain
+//                       error   Error on gain
+//                       chi2    Chi^2 per degrees of freedom of fit
+//                  
+// Latest changes by Christian Holm Christensen
+//
+
+// #include <iostream>
+
+#include <fstream>
+#include "AliFMDPreprocessor.h"
+#include "AliFMDCalibPedestal.h"
+#include "AliFMDCalibGain.h"
+#include "AliFMDParameters.h"
+#include "AliCDBMetaData.h"
+#include "AliCDBManager.h"
+// #include "AliDCSValue.h"
+#include "AliLog.h"
+#include <TTimeStamp.h>
+// #include <TFile.h>
+#include <TObjString.h>
+#include <TString.h>
+#include <TNamed.h>
+
+
+ClassImp(AliFMDPreprocessor)
+#if 0 // Do not remove - here to make Emacs happy
+;
+#endif 
+
+//____________________________________________________
+UInt_t AliFMDPreprocessor::Process(TMap* /* dcsAliasMap */)
+{
+  // Main member function. 
+  // Parameters: 
+  //    dcsAliassMap   Map of DCS data point aliases.
+  // Return 
+  //    ? 
+
+  // Do we need this ?
+  // if(!dcsAliasMap) return 1;
+  // 
+  // Invoking the cdb manager and the FMD parameters class
+  // AliCDBManager* cdb   = AliCDBManager::Instance();
+  // cdb->SetDefaultStorage("local://$ALICE_ROOT");
+  // cdb->SetRun(0);
+  AliFMDParameters* pars = AliFMDParameters::Instance();
+  pars->Init(false, AliFMDParameters::kAltroMap);
+  
+  //Creating calibration objects
+  TList*               pedFiles     = GetFileSources(kDAQ,"pedestal");
+  TList*               gainFiles    = GetFileSources(kDAQ, "gain");
+  AliFMDCalibPedestal* calibPed     = GetPedestalCalibration(pedFiles);
+  AliFMDCalibGain*     calibGain    = GetGainCalibration(gainFiles);
+  
+  
+  //Storing Calibration objects  
+  AliCDBMetaData metaData;
+  metaData.SetBeamPeriod(0);
+  metaData.SetResponsible("Hans H. Dalsgaard");
+  metaData.SetComment("Preprocessor stores pedestals and gains for the FMD.");
+  
+  Bool_t resultPed = kFALSE, resultGain = kFALSE;
+  if(calibPed)  resultPed  = Store("Calib","Pedestal", calibPed, &metaData);
+  if(calibGain) resultGain = Store("Calib","PulseGain", calibGain, &metaData);
+  if (calibPed)  delete calibPed;
+  if (calibGain) delete calibGain;
+  
+  return (resultPed && resultGain ? 0 : 1);
+}
+
+//____________________________________________________________________
+AliFMDCalibPedestal* 
+AliFMDPreprocessor::GetPedestalCalibration(TList* pedFiles)
+{
+  // Read DAQ DA produced CSV files of pedestals, and return a
+  // calibration object. 
+  // Parameters:
+  //   pedFiles     List of pedestal files 
+  // Return 
+  //   A pointer to a newly allocated AliFMDCalibPedestal object, or
+  //   null in case of errors. 
+  if(!pedFiles) return 0;
+
+  AliFMDCalibPedestal* calibPed = new AliFMDCalibPedestal();
+  AliFMDParameters*    pars     = AliFMDParameters::Instance();
+  TIter                iter(pedFiles);
+  TObjString*          fileSource;
+  
+  while((fileSource = dynamic_cast<TObjString*>(iter.Next()))) {
+    const Char_t* filename = GetFile(kDAQ, "pedestal", fileSource->GetName());
+    std::ifstream in(filename);
+    if(!in) {
+      AliError(Form("File %s not found!", filename));
+      continue;
+    }
+
+    // Get header (how long is it ?)
+    TString header;
+    header.ReadLine(in);
+    header.ToLower();
+    if(!header.Contains("pedestal")) {
+      AliError("File header is not from pedestal!");
+      continue;
+    }
+    Log("File contains data from pedestals");
+    
+    // Read columns line
+    int lineno = 2;
+    header.ReadLine(in);
+    
+    // Loop until EOF
+    while(!in.eof()) {
+      if(in.bad()) { 
+       AliError(Form("Bad read at line %d in %s", lineno, filename));
+       break;
+      }
+      UInt_t ddl=2, board, chip, channel, strip, tb;
+      Float_t ped, noise, mu, sigma, chi2ndf;
+      Char_t c[10];
+         
+      in // >> ddl      >> c[0] 
+        >> board    >> c[1]
+        >> chip     >> c[2]
+        >> channel  >> c[3]
+        >> strip    >> c[4]
+        >> tb       >> c[5]
+        >> ped      >> c[6]
+        >> noise    >> c[7]
+        >> mu       >> c[8]
+        >> sigma    >> c[9]
+        >> chi2ndf;
+      lineno++;
+      // Ignore trailing garbage 
+      if (strip > 127) continue;
+      
+      //Setting the pedestals via the hardware address
+      UShort_t det, sec, str;
+      Char_t ring;
+         
+      pars->Hardware2Detector(ddl,board,chip,channel,det,ring,sec,str);
+      strip += str;
+      calibPed->Set(det,ring,sec,strip,ped,noise);
+    }
+  }
+  return calibPed;
+}      
+
+//____________________________________________________________________
+AliFMDCalibGain* 
+AliFMDPreprocessor::GetGainCalibration(TList* gainFiles)
+{
+  // Read DAQ DA produced CSV files of pedestals, and return a
+  // calibration object. 
+  // Parameters:
+  //   pedFiles     List of pedestal files 
+  // Return 
+  //   A pointer to a newly allocated AliFMDCalibPedestal object, or
+  //   null in case of errors. 
+  if(!gainFiles) return 0;
+  
+  AliFMDCalibGain*  calibGain  = new AliFMDCalibGain();
+  AliFMDParameters* pars       = AliFMDParameters::Instance();
+  TIter             iter(gainFiles);
+  TObjString*       fileSource;
+  while((fileSource = dynamic_cast<TObjString *>(iter.Next()))) {
+    const Char_t* filename = GetFile(kDAQ, "gain", fileSource->GetName());
+    std::ifstream in(filename);
+    if(!in) {
+      AliError(Form("File %s not found!", filename));
+      continue;
+    }
+
+    //Get header (how long is it ?)
+    TString header;
+    header.ReadLine(in);
+    header.ToLower();
+    if(!header.Contains("gain")) {
+      AliError("File header is not from gain!");
+      continue;
+    }
+    Log("File contains data from pulse gain");
+
+    // Read column headers
+    header.ReadLine(in);
+
+    int lineno  = 2;
+    // Read until EOF 
+    while(!in.eof()) {
+      if(in.bad()) { 
+       AliError(Form("Bad read at line %d in %s", lineno, filename));
+       break;
+      }
+      UInt_t ddl=2, board, chip, channel, strip;
+      Float_t gain,error,  chi2ndf;
+      Char_t c[7];
+             
+      in // >> ddl      >> c[0] 
+        >> board    >> c[1]
+        >> chip     >> c[2]
+        >> channel  >> c[3]
+        >> strip    >> c[4]
+        >> gain     >> c[5]
+        >> error    >> c[6]
+        >> chi2ndf;
+      lineno++;
+      // Ignore trailing garbage
+      if(strip > 127) continue;
+      
+      //Setting the pedestals via the hardware address
+      UShort_t det, sec, str;
+      Char_t ring;
+      pars->Hardware2Detector(ddl,board,chip,channel,det,ring,sec,str);
+
+      strip += str;
+      calibGain->Set(det,ring,sec,strip,gain);
+    }
+  }
+  return calibGain;
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
diff --git a/FMD/AliFMDPreprocessor.h b/FMD/AliFMDPreprocessor.h
new file mode 100644 (file)
index 0000000..3662282
--- /dev/null
@@ -0,0 +1,85 @@
+#ifndef ALI_FMD_PREPROCESSOR_H
+#define ALI_FMD_PREPRECESSOR_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
+ * reserved. 
+ *
+ * See cxx source for full Copyright notice                               
+ */
+//___________________________________________________________________
+// The class processes data points from DCS (via Amanada), and DAQ DA
+// files (via FXS) to make calibration data for the FMD.
+// More to come. 
+
+
+#include "AliPreprocessor.h"
+class AliFMDCalibPedestal;
+class AliFMDCalibGain;
+class TList;
+
+//___________________________________________________________________
+/** The class processes data points from DCS (via Amanada), and DAQ DA
+    files (via FXS) to make calibration data for the FMD.
+
+    Data points: 
+       *  Nothing yet. 
+
+    DAQ FXS file:
+       * pedestals - a (ASCII) Comma Separated Values files with the
+                     fields 
+                          rcu   DDL number 
+                          board   FEC board number 
+                          chip    ALTRO chip number on FEC
+                          channel ALTRO channel number
+                          strip   VA1 strip number
+                          sample  Sample number
+                          ped     Mean of ADC spectra
+                          noise   Spread of ADC spectra
+                          mu      Mean of Gaussian fit to ADC spectra
+                          sigma   Variance of Gaussian fit to ADC spectra
+                          chi2    Chi^2 per degrees of freedom of fit
+       * Gains     - a (ASCII) Comma Separated Values files with the
+                     fields 
+                          rcu   DDL number 
+                          board   FEC board number 
+                          chip    ALTRO chip number on FEC
+                          channel ALTRO channel number
+                          strip   VA1 strip number
+                          gain    Slope of gain
+                          error   Error on gain
+                          chi2    Chi^2 per degrees of freedom of fit
+*/
+class AliFMDPreprocessor: public AliPreprocessor 
+{
+public:
+  /** Constructor */
+  AliFMDPreprocessor(): AliPreprocessor("FMD",0) { }
+  /** Constructor 
+      @param shuttle Shuttle */
+  AliFMDPreprocessor(AliShuttleInterface* shuttle)
+    : AliPreprocessor("FMD", shuttle)
+  {}
+  /** Destructor */
+  virtual ~AliFMDPreprocessor() {}
+protected:
+  /** Get the pedestal calibrations 
+      @param list List of files */
+  AliFMDCalibPedestal*   GetPedestalCalibration(TList* list);
+  /** Get the gain calibrations 
+      @param list List of files */
+  AliFMDCalibGain*       GetGainCalibration(TList*);
+  /** Entry method 
+      @param dcsAliasMap Map of DCS data points */
+  virtual UInt_t Process(TMap* dcsAliasMap);
+private:
+  ClassDef(AliFMDPreprocessor, 1)
+};
+
+#endif
+//____________________________________________________________________
+//
+// Local Variables:
+//   mode: C++
+// End:
+//
+// EOF
+//
index daff1c5..e78fa60 100644 (file)
@@ -32,6 +32,7 @@
 #pragma link C++ class  AliFMDCalibSampleRate+;
 #pragma link C++ class  AliFMDCalibStripRange+;
 #pragma link C++ class  AliFMDAltroMapping+;
+#pragma link C++ class  AliFMDPreprocessor+;
 // #pragma link C++ class  AliFMDAltroIO+;
 // #pragma link C++ class  AliFMDAltroReader+;
 // #pragma link C++ class  AliFMDAltroWriter+;
index 8323c1d..08dce15 100644 (file)
@@ -19,7 +19,8 @@ SRCS          =  AliFMDIndex.cxx              \
                   AliFMDDetector.cxx           \
                   AliFMD1.cxx                  \
                   AliFMD2.cxx                  \
-                  AliFMD3.cxx                  
+                  AliFMD3.cxx                  \
+                  AliFMDPreprocessor.cxx       
 
 #                 AliFMDAltroIO.cxx            
 
diff --git a/FMD/scripts/TestPreprocessor.C b/FMD/scripts/TestPreprocessor.C
new file mode 100644 (file)
index 0000000..08885eb
--- /dev/null
@@ -0,0 +1,385 @@
+/* $Id$ */
+
+//====================================================================
+//
+// Helper classes
+//
+#include <iostream>
+#include <fstream>
+#ifndef __CINT__
+# include <TString.h>
+# include <AliPreprocessor.h>
+# include <../FMD/AliFMDPreprocessor.h>
+# include <AliShuttleInterface.h>
+# include <AliCDBStorage.h>
+# include <AliCDBEntry.h>
+# include <AliCDBManager.h>
+# include <AliCDBId.h>
+# include <AliCDBMetaData.h>
+# include <AliDCSValue.h>
+# include <AliLog.h>
+// # include <../FMD/AliFMDCalibZeroSuppression.h>
+// # include <../FMD/AliFMDCalibDeadMap.h>
+# include <../FMD/AliFMDParameters.h>
+# include <../SHUTTLE/TestShuttle/AliTestShuttle.h>
+# include <TRandom.h>
+# include <TSystem.h>
+# include <TObjString.h>
+# include <TMap.h>
+# include <TError.h>
+#endif
+
+namespace { 
+  //====================================================================
+  //
+  // Helper functions
+  //
+  Float_t Hardware2Ped(int ddl, int board, int chip, int, int) 
+  {
+    return ((chip & 0xf) | ((board & 0x1F) << 4) | (ddl << 9) & 0x3);
+  }
+  Float_t Hardware2Noise(int ddl, int board, int chip, int channel, int strip)
+  {
+    return ((strip & 0x7f) | ((channel & 0xf) << 7));
+  }
+  Float_t Hardware2Gain(int ddl, int board, int chip, int channel, int strip) 
+  {
+    return (((strip   & 0x7f) <<  0) | 
+           ((channel & 0x0f) <<  7) | 
+           ((chip    & 0x07) << 11) |
+           ((board   & 0x1f) << 14) | 
+           ((ddl     & 0x03) << 19));
+  }
+
+  //====================================================================
+  //
+  // Helper classes
+  //
+  //__________________________________________________________________
+  class CreateDummyDaData
+  {
+  public:
+    CreateDummyDaData(const char* output,
+                     int firstDDL,   int lastDDL, 
+                     int firstStrip, int lastStrip)
+      : fOutput(output),
+       fFirstDDL(firstDDL),     fLastDDL(lastDDL), 
+       fFirstStrip(firstStrip), fLastStrip(lastStrip)
+    {}
+    void Exec()
+    {
+      std::cout << "Will write on " << fOutput << std::endl;
+      std::ofstream file(fOutput.Data());
+      if (file.bad()) { 
+       std::cerr << "Failed to open output file " << fOutput << std::endl;
+       return;
+      }
+      Header(file);
+      for (int ddl = fFirstDDL; ddl <= fLastDDL; ddl++) { 
+       int  boards[] = { 0, 16, (ddl==1 ? -1 : 1), (ddl==1 ? -1 : 17), -1};
+       int* bptr     = boards;
+       int  board    = -1;
+       while ((board = (*bptr++)) >= 0) { 
+         for (int chip = 0; chip < 3; chip++) { 
+           for (int channel = 0; channel < (chip == 1 ? 8 : 16); channel++) { 
+             for (int strip = fFirstStrip; strip <= fLastStrip; strip++) {
+               Output(file, ddl, board, chip, channel, strip);
+             }
+           } // for channel 
+         } // for chip
+       } // while board 
+      } // for ddl
+      file.close();
+    }
+    virtual void Header(std::ostream& file) = 0;
+    virtual void Output(std::ostream& file, int ddl, int board, int chip, 
+                       int channel, int strip) = 0;
+  protected:
+    TString fOutput;
+    int fFirstDDL;
+    int fLastDDL;
+    int fFirstStrip;
+    int fLastStrip;
+  };
+
+  //__________________________________________________________________
+  class CreateDummyPeds : public  CreateDummyDaData
+  {
+  public:
+    CreateDummyPeds(const char* out="peds.csv", 
+                   int overSampling=4,
+                   int firstDDL=0,   int lastDDL=2, 
+                   int firstStrip=0, int lastStrip=127)
+      : CreateDummyDaData(out, firstDDL, lastDDL, firstStrip, lastStrip), 
+       fOverSampling(overSampling)
+    {}
+    void Output(std::ostream& file, int ddl, int board, int chip, int channel, 
+               int strip)
+    {
+      // Format is
+      //   ddl,board,chip,channel,strip,sample,ped,noise,mu,sigma,chi2
+      for (int sample = 0; sample < fOverSampling; sample++) {
+       Float_t ped   = Hardware2Ped(ddl, board, chip, channel, strip);
+       Float_t noise = Hardware2Noise(ddl, board, chip, channel, strip);
+       file // << ddl     << ","
+            << board   << "," 
+            << chip    << ","
+            << channel << ","
+            << strip   << ","
+            << sample  << ","
+            << ped     << ","  
+            << noise   << ","  
+            << chip    << ","  // Predictable mu
+            << channel << ","  // Predictable sigma 
+            << strip           // Predictable chi2/ndf
+            << endl;
+      }
+    }
+    void Header(std::ostream& file) 
+    { 
+      file << "# Pedestals\n" 
+          << "# ddl,board,chip,channel,strip,sample,mean,noise,mu,sigma,chi"
+          << std::endl;
+    }
+  protected:
+    int fOverSampling;
+  };
+
+  //__________________________________________________________________
+  class CreateDummyGains : public  CreateDummyDaData
+  {
+  public:
+    CreateDummyGains(const char* out="gains.csv", 
+                    int firstDDL=0,   int lastDDL=2, 
+                    int firstStrip=0, int lastStrip=127)
+      : CreateDummyDaData(out, firstDDL, lastDDL, firstStrip, lastStrip) 
+    {}
+    void Output(std::ostream& file, int ddl, int board, int chip, int channel, 
+               int strip)
+    {
+      // Format is
+      //   ddl,board,chip,channel,strip,gain,error,chi2
+      Float_t gain = Hardware2Gain(ddl, board, chip, channel, strip);
+      file // << ddl     << ","
+          << board   << "," 
+          << chip    << ","
+          << channel << ","
+          << strip   << ","
+          << gain    << ","  // Predictable gain
+          << board   << ","  // Predictable error
+          << strip           // Predictable chi2/ndf
+          << endl;
+    }
+    void Header(std::ostream& file) 
+    { 
+      file << "# Gains\n" 
+          << "# ddl,board,chip,channel,strip,gain,errorchi"
+          << std::endl;
+    }
+  };
+}
+
+//====================================================================
+//
+// Read back the calibrations written, and check the values 
+//
+void ReadBack(const char* dbBase="local://$ALICE_ROOT/FMD/")
+{
+  AliLog::SetModuleDebugLevel("FMD", 1);
+  // Set specific storage of FMD ALTRO map 
+  AliCDBManager::Instance()->SetDefaultStorage(Form("%s/TestCDB", dbBase));
+  AliCDBManager::Instance()->SetSpecificStorage("FMD/Calib/AltroMap",
+                                               "local://$ALICE_ROOT");
+  AliCDBManager::Instance()->SetRun(0);
+  
+  AliFMDParameters* param = AliFMDParameters::Instance();
+  std::cout << "Getting the stuff via AliFMDParameters ... " << std::flush;
+  param->Init(kTRUE,AliFMDParameters::kPulseGain|
+             AliFMDParameters::kPedestal|
+             AliFMDParameters::kAltroMap);
+  std::cout << "done" << std::endl;
+  // param->Print("FMD1I[*,*]");
+  
+  for (UShort_t det = 3; det <= 3; det++) { 
+    Char_t  rs[] = { 'I', (det==1 ? '\0' : 'O'), '\0' };
+    Char_t* pr   = rs;
+    Char_t  rng  = '\0';
+    while ((rng = *(pr++)) != '\0') { 
+      UShort_t nsec = (rng == 'I' ?  20 :  40);
+      UShort_t nstr = (rng == 'I' ? 512 : 256);
+      for (UShort_t sec = 0; sec < nsec; sec++) { 
+       for (UShort_t str = 0; str < nstr; str++) { 
+         Float_t  gain    = param->GetPulseGain(det,rng,sec,str);
+         Float_t  ped     = param->GetPedestal(det,rng,sec,str);
+         Float_t  noise   = param->GetPedestalWidth(det,rng,sec,str);
+         UInt_t   ddl, board, chip, channel;
+         param->Detector2Hardware(det,rng,sec,str,ddl,board,chip,channel);
+         UShort_t strip   = str % 128;
+         Float_t  eped    = Hardware2Ped(ddl, board, chip, channel, strip);
+         Float_t  enoise  = Hardware2Noise(ddl, board, chip, channel, strip);
+         Float_t  egain   = Hardware2Gain(ddl, board, chip, channel, strip);
+         if (ped  != eped) 
+           Error(Form("FMD%d%c[%2d,%3d] (%d,%2d,%1d,%2d)",
+                      det,rng,sec,str,ddl,board,chip,channel),
+                 "pedestal=%14.7f != %14.7f", ped, eped);
+         if (noise  != enoise) 
+           Error(Form("FMD%d%c[%2d,%3d] (%d,%2d,%1d,%2d)",
+                      det,rng,sec,str,ddl,board,chip,channel),
+                 "noise=%14.7f != %14.7f", noise, enoise);
+#if 0
+         // Will fail due to rounding errors.
+         if (gain  != egain) 
+           Error(Form("FMD%d%c[%2d,%3d] (%d,%2d,%1d,%2d)",
+                      det,rng,sec,str,ddl,board,chip,channel),
+                 "gain=%14.7f != %14.7f", gain, egain);
+#endif
+       }
+      }
+    }
+  }
+}
+
+//====================================================================
+//
+// This script runs the test preprocessor. It uses AliTestShuttle to
+// simulate a full Shuttle process
+//
+// The input data is created in the functions
+//
+//   CreateDCSAliasMap()   creates input that would in the same way come
+//                         from DCS 
+//   ReadDCSAliasMap()     reads from a file
+//   CreateInputFilesMap() creates a list of local files, that can be
+//                         accessed by the shuttle 
+//
+void TestPreprocessor(Bool_t createDummies=kTRUE,
+                     const char* dbBase="local://$ALICE_ROOT/FMD/")
+{
+  // Dummy data
+  if (createDummies) { 
+    CreateDummyPeds pedMaker;
+    pedMaker.Exec();
+    CreateDummyGains gainMaker;
+    gainMaker.Exec();
+  }
+  
+  // load library - needs to be built using make
+  gSystem->Load("libTestSHUTTLE.so"); 
+
+   // create AliTestShuttle instance
+  // The parameters are run, startTime, endTime
+  AliTestShuttle* shuttle = new AliTestShuttle(0, 0, 1);
+
+  // Set specific storage of FMD ALTRO map 
+  AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT");
+  AliCDBManager::Instance()->SetSpecificStorage("FMD/Calib/AltroMap",
+                                               "local://$ALICE_ROOT");
+  AliCDBManager::Instance()->SetRun(0);
+  // TODO if needed, change location of OCDB and Reference test
+  // folders by default they are set to
+  // $ALICE_ROOT/TestCDB and TestReference
+  AliTestShuttle::SetMainCDB(Form("%s/TestCDB", dbBase));
+  AliTestShuttle::SetMainRefStorage(Form("%s/TestReference", dbBase));
+
+  std::cout << "Test OCDB storage URI: " << AliShuttleInterface::GetMainCDB()
+           << "\n"
+           << "Test Reference storage Uri: "
+           << AliShuttleInterface::GetMainRefStorage().Data()
+           << std::endl;
+  
+  shuttle->AddInputFile(AliShuttleInterface::kDAQ, "FMD", "pedestal", 
+                       "source1", "peds.csv");
+  shuttle->AddInputFile(AliShuttleInterface::kDAQ, "FMD", "gain", 
+                       "source2", "gains.csv");
+  shuttle->SetInputRunType("PHYSICS");
+
+  new AliFMDPreprocessor(shuttle);
+  // Test the preprocessor
+  shuttle->Process();
+
+
+  // Read back 
+  ReadBack(dbBase);
+}
+      
+//____________________________________________________________________
+// We do not use this functions .....yet
+TMap* CreateDCSAliasMap()
+{
+  // Creates a DCS structure
+  // The structure is the following:
+  // 
+  //   TMap (key --> value)
+  //     <DCSAlias> --> <valueList>
+  //     <DCSAlias> is a string
+  //     <valueList> is a TObjArray of AliDCSValue
+  //     An AliDCSValue consists of timestamp and a value in form of a
+  //     AliSimpleValue 
+  // 
+  // In this example 6 aliases exists: DCSAlias1 ... DCSAlias6
+  // Each contains 1000 values randomly generated by TRandom::Gaus +
+  // 5*nAlias 
+  TRandom random;
+  TMap*   aliasMap = new TMap;
+  aliasMap->SetOwner(1);
+
+  for(int nAlias=0;nAlias<6;nAlias++) {
+    TObjArray* valueSet = new TObjArray;
+    valueSet->SetOwner(1);
+
+    TString aliasName="DCSAlias";
+    aliasName += nAlias;
+    //printf("\n\n alias: %s\n\n",aliasName.Data());
+    for (int timeStamp = 0; timeStamp < 1000; timeStamp += 10) {
+      Float_t      x      =  Float_t(random.Gaus()+5*nAlias);
+      AliDCSValue* dcsVal = new AliDCSValue(x, timeStamp);
+      valueSet->Add(dcsVal);
+    }
+    aliasMap->Add(new TObjString(aliasName), valueSet);
+  }
+
+  return aliasMap;
+}
+
+//____________________________________________________________________
+TMap* ReadDCSAliasMap()
+{
+  // Open a file that contains DCS input data
+  // 
+  // The CDB framework is used to open the file, this means the file
+  // is located in 
+  //  
+  //   $ALICE_ROOT/FMD/TestCDB/<detector>/DCS/Data
+  // 
+  // The file contains an AliCDBEntry that contains a TMap with the
+  // DCS structure.  An explanation of the structure can be found in
+  // CreateDCSAliasMap() 
+  AliCDBEntry *entry = 
+    AliCDBManager::Instance()->GetStorage(AliShuttleInterface::GetMainCDB())
+    ->Get("DET/DCS/Data", 0);
+  return dynamic_cast<TMap*> (entry->GetObject());
+}
+
+//____________________________________________________________________
+void WriteDCSAliasMap()
+{
+  // This writes the output from CreateDCSAliasMap to a CDB file
+
+  TMap*          dcsAliasMap = CreateDCSAliasMap();
+  AliCDBMetaData metaData;
+  metaData.SetBeamPeriod(0);
+  metaData.SetResponsible("Responsible person");
+  metaData.SetComment("Test object for TestPreprocessor.C");
+
+  AliCDBId id("DET/DCS/Data", 0, 0);
+  
+  // look into AliTestShuttle's CDB main folder
+  AliCDBManager::Instance()->GetStorage(AliShuttleInterface::GetMainCDB())
+    ->Put(dcsAliasMap, id, &metaData);
+}
+
+//____________________________________________________________________
+//
+// EOF
+//