Added AliFMDAltroMapping
authorcholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 17 Mar 2006 22:27:07 +0000 (22:27 +0000)
committercholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 17 Mar 2006 22:27:07 +0000 (22:27 +0000)
FMD/AliFMDAltroMapping.cxx [new file with mode: 0644]
FMD/AliFMDAltroMapping.h [new file with mode: 0644]
FMD/AliFMDGeometry.h
FMD/AliFMDParameters.cxx
FMD/AliFMDParameters.h
FMD/FMDbaseLinkDef.h
FMD/libFMDbase.pkg

diff --git a/FMD/AliFMDAltroMapping.cxx b/FMD/AliFMDAltroMapping.cxx
new file mode 100644 (file)
index 0000000..d948d5e
--- /dev/null
@@ -0,0 +1,346 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, 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$ */
+
+//____________________________________________________________________
+//                                                                          
+// Mapping of ALTRO hardware channel to detector coordinates 
+//
+#include "AliFMDAltroMapping.h"                // ALIFMDALTROMAPPING_H
+#include "AliFMDParameters.h"
+#include "AliLog.h"
+
+//____________________________________________________________________
+ClassImp(AliFMDAltroMapping)
+#if 0
+  ; // This is here to keep Emacs for indenting the next line
+#endif
+
+//_____________________________________________________________________________
+AliFMDAltroMapping::AliFMDAltroMapping()
+  : AliAltroMapping(0)
+{}
+
+
+//_____________________________________________________________________________
+Bool_t
+AliFMDAltroMapping::ReadMapping()
+{
+  return kTRUE;
+}
+
+//_____________________________________________________________________________
+void
+AliFMDAltroMapping::DeleteMappingArrays()
+{}
+
+//____________________________________________________________________
+Bool_t 
+AliFMDAltroMapping::Hardware2Detector(UInt_t    ddl, UInt_t    addr, 
+                                     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 - kBaseDDL + 1
+  // 
+  // The ring number, sector, and strip number is given by the addr
+  // argument.  The address argument, has the following format 
+  // 
+  //   12            7          4          0
+  //   +-------------+----------+----------+
+  //   | Board       | ALTRO    | Channel  |
+  //   +-------------+----------+----------+
+  // 
+  // The board number identifier among other things the ring.  There's
+  // up to 4 boards per DDL, and the two first (0 and 1) corresponds
+  // to the inner rings, while the two last (2 and 3) corresponds to
+  // the outer rings. 
+  // 
+  // The board number and ALTRO number together identifies the sensor,
+  // and hence.  The lower board number (0 or 2) are the first N / 2
+  // sensors (where N is the number of sensors in the ring).  
+  // 
+  // There are 3 ALTRO's per card, and each ALTRO serves up to 4
+  // sensors.  Which of sensor is determined by the channel number.
+  // For the inner rings, the map is
+  // 
+  //    ALTRO 0, Channel  0 to  7   -> Sensor 0 or 5
+  //    ALTRO 0, Channel  8 to 15   -> Sensor 1 or 6
+  //    ALTRO 1, Channel  0 to  7   -> Sensor 2 or 7 
+  //    ALTRO 2, Channel  0 to  7   -> Sensor 3 or 8
+  //    ALTRO 2, Channel  8 to 15   -> Sensor 4 or 9
+  // 
+  // For the outer rings, the map is 
+  // 
+  //    ALTRO 0, Channel  0 to  3   -> Sensor 0 or 10
+  //    ALTRO 0, Channel  4 to  7   -> Sensor 1 or 11
+  //    ALTRO 0, Channel  8 to 11   -> Sensor 2 or 12
+  //    ALTRO 0, Channel 12 to 15   -> Sensor 3 or 13
+  //    ALTRO 1, Channel  0 to  3   -> Sensor 4 or 14
+  //    ALTRO 1, Channel  4 to  7   -> Sensor 5 or 15
+  //    ALTRO 2, Channel  0 to  3   -> Sensor 6 or 16
+  //    ALTRO 2, Channel  4 to  7   -> Sensor 7 or 17
+  //    ALTRO 2, Channel  8 to 11   -> Sensor 8 or 18
+  //    ALTRO 2, Channel 12 to 15   -> Sensor 9 or 19
+  // 
+  // Which divison of the sensor we're in, depends on the channel
+  // number only.  For the inner rings, the map is 
+  // 
+  //    Channel 0                   -> Sector 0, strips   0-127
+  //    Channel 1                   -> Sector 1, strips   0-127
+  //    Channel 3                   -> Sector 0, strips 128-255
+  //    Channel 4                   -> Sector 1, strips 128-255
+  //    Channel 5                   -> Sector 0, strips 256-383
+  //    Channel 6                   -> Sector 1, strips 256-383
+  //    Channel 7                   -> Sector 0, strips 384-511
+  //    Channel 8                   -> Sector 1, strips 384-511 
+  // 
+  // There are only half as many strips in the outer sensors, so there
+  // only 4 channels are used for a full sensor.  The map is 
+  // 
+  //    Channel 0                   -> Sector 0, strips   0-127
+  //    Channel 1                   -> Sector 1, strips   0-127
+  //    Channel 3                   -> Sector 0, strips 128-255
+  //    Channel 4                   -> Sector 1, strips 128-255
+  // 
+  // With this information, we can decode the hardware address to give
+  // us detector coordinates, unique at least up a 128 strips.  We
+  // return the first strip in the given range. 
+  //
+  det          =  (ddl - AliFMDParameters::kBaseDDL) + 1;
+  UInt_t board =  (addr >> 7) & 0x1F;
+  UInt_t altro =  (addr >> 4) & 0x7;
+  UInt_t chan  =  (addr & 0xf);
+  if (board > 3) {
+    AliError(Form("Invalid board address %d for the FMD", board));
+    return kFALSE;
+  }
+  if (altro > 2) {
+    AliError(Form("Invalid ALTRO address %d for the FMD digitizer %d", 
+                 altro, board));
+    return kFALSE;
+  }
+  ring         =  (board > 1 ? 'O' : 'I');
+  UInt_t nsen  =  (ring == 'I' ? 10 : 20);
+  UInt_t nsa   =  (ring == 'I' ? 2 : 4);   // Sensors per ALTRO
+  UInt_t ncs   =  (ring == 'I' ? 8 : 4);   // Channels per sensor 
+  UInt_t sen   =  (board % 2) * nsen / 2;  // Base for half-ring
+  sen          += chan / ncs + (altro == 0 ? 0   : 
+                               altro == 1 ? nsa : UInt_t(1.5 * nsa));
+  sec          =  2 * sen + (chan % 2);
+  str          =  (chan % ncs) / 2 * 128;
+  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.
+  // The ddl is simply 
+  // 
+  //    kBaseDDL + (det - 1)
+  // 
+  // The ring number, sector, and strip number must be encoded into a
+  // hardware address.  The address argument, will have the following
+  // format on output
+  // 
+  //   12            7          4          0
+  //   +-------------+----------+----------+
+  //   | Board       | ALTRO    | Channel  |
+  //   +-------------+----------+----------+
+  // 
+  // The board number is given by the ring and sector.  The inner
+  // rings board 0 and 1, while the outer are 2 and 3.  Which of these
+  // depends on the sector.  The map is 
+  // 
+  //    Ring I, sector  0- 9       ->   board 0 
+  //    Ring I, sector 10-19       ->   board 1
+  //    Ring O, sector  0-19       ->   board 2 
+  //    Ring O, sector 20-39       ->   board 3
+  // 
+  // There are 3 ALTRO's per board.  The ALTRO number is given by the
+  // sector number.  For the inner rings, these are given by
+  // 
+  //    Sector  0- 3  or  10-13    ->   ALTRO 0 
+  //    Sector  4- 5  or  14-15    ->   ALTRO 1 
+  //    Sector  6- 9  or  16-19    ->   ALTRO 2 
+  // 
+  // For the outers, it's given by 
+  // 
+  //    Sector  0- 7  or  20-27    ->   ALTRO 0 
+  //    Sector  8-11  or  28-31    ->   ALTRO 1 
+  //    Sector 12-19  or  32-39    ->   ALTRO 2 
+  //
+  // The channel number is given by the sector and strip number.  For
+  // the inners, the map is 
+  // 
+  //    Sector  0, strips   0-127  ->   Channel  0
+  //    Sector  0, strips 128-255  ->   Channel  2
+  //    Sector  0, strips 256-383  ->   Channel  4
+  //    Sector  0, strips 384-511  ->   Channel  6
+  //    Sector  1, strips   0-127  ->   Channel  1
+  //    Sector  1, strips 128-255  ->   Channel  3
+  //    Sector  1, strips 256-383  ->   Channel  5
+  //    Sector  1, strips 384-511  ->   Channel  7
+  //    Sector  2, strips   0-127  ->   Channel  8
+  //    Sector  2, strips 128-255  ->   Channel 10
+  //    Sector  2, strips 256-383  ->   Channel 12
+  //    Sector  2, strips 384-511  ->   Channel 14
+  //    Sector  3, strips   0-127  ->   Channel  9
+  //    Sector  3, strips 128-255  ->   Channel 11
+  //    Sector  3, strips 256-383  ->   Channel 13
+  //    Sector  3, strips 384-511  ->   Channel 15
+  // 
+  // and so on, up to sector 19.  For the outer, the map is 
+  // 
+  //    Sector  0, strips   0-127  ->   Channel  0
+  //    Sector  0, strips 128-255  ->   Channel  2
+  //    Sector  1, strips   0-127  ->   Channel  1
+  //    Sector  1, strips 128-255  ->   Channel  3
+  //    Sector  2, strips   0-127  ->   Channel  4
+  //    Sector  2, strips 128-255  ->   Channel  6
+  //    Sector  3, strips   0-127  ->   Channel  5
+  //    Sector  3, strips 128-255  ->   Channel  7
+  //    Sector  4, strips   0-127  ->   Channel  8
+  //    Sector  4, strips 128-255  ->   Channel 10
+  //    Sector  5, strips   0-127  ->   Channel  9
+  //    Sector  5, strips 128-255  ->   Channel 11
+  //    Sector  6, strips   0-127  ->   Channel 12
+  //    Sector  6, strips 128-255  ->   Channel 14
+  //    Sector  7, strips   0-127  ->   Channel 13
+  //    Sector  7, strips 128-255  ->   Channel 15
+  // 
+  // and so on upto sector 40. 
+  // 
+  // With this information, we can decode the detector coordinates to
+  // give us a unique hardware address 
+  //
+  ddl          =  AliFMDParameters::kBaseDDL + (det - 1);
+  UInt_t nsen  =  (ring == 'I' ? 10 : 20);
+  UInt_t nsa   =  (ring == 'I' ? 2 : 4);   // Sensors per ALTRO
+  UInt_t ncs   =  (ring == 'I' ? 8 : 4);   // Channels per sensor 
+  UInt_t bbase =  (ring == 'I' ? 0 : 2);
+  UInt_t board =  bbase + sec / nsen;
+  UInt_t lsen  =  (sec - (board - bbase) * nsen);
+  UInt_t altro =  (lsen < 2 * nsa ? 0 : (lsen < 3 * nsa ? 1 : 2));
+  UInt_t sbase =  (lsen < 2 * nsa ? 0 : (lsen < 3 * nsa ? 2*nsa : 3*nsa));
+  UInt_t chan  =  (sec % 2) + (lsen-sbase) / 2 * ncs + 2 * str / 128;
+  AliDebug(40, Form("\n"
+                   "  chan = (%d %% 2) + (%d-%d) / %d * %d + 2 * %d / 128\n"
+                   "       = %d + %d + %d = %d", 
+                   sec, lsen, sbase, 2, ncs, str, 
+                   (sec % 2), (lsen - sbase) / 2 * ncs, 
+                   2 * str / 128, chan));
+  addr         =  chan + (altro << 4) + (board << 7);
+  
+  return kTRUE;
+}
+
+//____________________________________________________________________
+Int_t
+AliFMDAltroMapping::GetHWAddress(Int_t sec, Int_t str, Int_t ring) const
+{
+  // Return hardware address corresponding to sector sec, strip str,
+  // and ring ring.   Mapping from TPC to FMD coordinates are 
+  // 
+  //   TPC     | FMD
+  //   --------+------
+  //   padrow  | sector
+  //   pad     | strip
+  //   sector  | ring 
+  //
+  UInt_t ddl, hwaddr;
+  Char_t r = Char_t(ring);
+  if (!Detector2Hardware(1, r, sec, str, ddl, hwaddr)) 
+    return -1;
+  return hwaddr;
+}
+
+//____________________________________________________________________
+Int_t
+AliFMDAltroMapping::GetPadRow(Int_t hwaddr) const
+{
+  // Return sector corresponding to hardware address hwaddr.  Mapping
+  // from TPC to FMD coordinates are  
+  // 
+  //   TPC     | FMD
+  //   --------+------
+  //   padrow  | sector
+  //   pad     | strip
+  //   sector  | ring 
+  //
+  UShort_t det;
+  Char_t   ring;
+  UShort_t sec;
+  UShort_t str;
+  Int_t    ddl = AliFMDParameters::kBaseDDL;
+  if (!Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) return -1;
+  return Int_t(sec);
+}
+
+//____________________________________________________________________
+Int_t
+AliFMDAltroMapping::GetPad(Int_t hwaddr) const
+{
+  // Return strip corresponding to hardware address hwaddr.  Mapping
+  // from TPC to FMD coordinates are  
+  // 
+  //   TPC     | FMD
+  //   --------+------
+  //   padrow  | sector
+  //   pad     | strip
+  //   sector  | ring 
+  //
+  UShort_t det;
+  Char_t   ring;
+  UShort_t sec;
+  UShort_t str;
+  Int_t    ddl = AliFMDParameters::kBaseDDL;
+  if (!Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) return -1;
+  return Int_t(str);
+}
+  
+//____________________________________________________________________
+Int_t
+AliFMDAltroMapping::GetSector(Int_t hwaddr) const
+{
+  // Return ring corresponding to hardware address hwaddr.  Mapping
+  // from TPC to FMD coordinates are  
+  // 
+  //   TPC     | FMD
+  //   --------+------
+  //   padrow  | sector
+  //   pad     | strip
+  //   sector  | ring 
+  //
+  UShort_t det;
+  Char_t   ring;
+  UShort_t sec;
+  UShort_t str;
+  Int_t    ddl = AliFMDParameters::kBaseDDL;
+  if (!Hardware2Detector(ddl, hwaddr, det, ring, sec, str)) return -1;
+  return Int_t(ring);
+}
+
+//_____________________________________________________________________________
+//
+// EOF
+//
diff --git a/FMD/AliFMDAltroMapping.h b/FMD/AliFMDAltroMapping.h
new file mode 100644 (file)
index 0000000..769efd1
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef ALIFMDALTROMAPPING_H
+#define ALIFMDALTROMAPPING_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
+ * reserved. 
+ *
+ * Latest changes by Christian Holm Christensen <cholm@nbi.dk>
+ *
+ * See cxx source for full Copyright notice                               
+ */
+#ifndef ALIALTROMAPPING_H
+# include <AliAltroMapping.h>
+#endif
+#ifndef ALIFMDUSHORTMAP_H
+# include "AliFMDUShortMap.h"
+#endif
+#ifndef ROOT_TArrayI
+# include <TArrayI.h>
+#endif
+
+class AliFMDAltroMapping : public AliAltroMapping
+{
+public:
+  AliFMDAltroMapping();
+  Bool_t Hardware2Detector(UInt_t    ddl, UInt_t    hwaddr, 
+                          UShort_t& det, Char_t&   ring, 
+                          UShort_t& sec, UShort_t& str) const;
+  Bool_t Detector2Hardware(UShort_t  det, Char_t    ring, 
+                          UShort_t  sec, UShort_t  str,
+                          UInt_t&   ddl, UInt_t&   hwaddr) const;
+  Int_t  GetHWAdress(Int_t sector, Int_t str, Int_t ring) const
+  {
+    return GetHWAdress(sector, str, ring);
+  }
+  Int_t  GetHWAddress(Int_t sector, Int_t str, Int_t ring) const;
+  Int_t  GetPadRow(Int_t hwaddr) const;
+  Int_t  GetPad(Int_t hwaddr) const;
+  Int_t  GetSector(Int_t hwaddr) const;
+protected:
+  virtual Bool_t ReadMapping();
+  virtual void   DeleteMappingArrays();
+  
+  ClassDef(AliFMDAltroMapping, 1) // Read raw FMD Altro data 
+};
+
+#endif
+//____________________________________________________________________
+//
+// Local Variables:
+//   mode: C++
+// End:
+//
+// EOF
+//
index 7a71c7b..f389366 100644 (file)
 #ifndef ALIGEOMETRY_H
 # include <AliGeometry.h>
 #endif
+#ifndef ROOT_TArrayI
+# include <TArrayI.h>
+#endif
+#ifndef ROOT_TMatrixFfwd
+# include <TMatrixFfwd.h>
+#endif
+class TVector3;
 class TParticle;
 class AliRecPoint;
 class AliFMDRing;
@@ -24,9 +31,6 @@ class AliFMDDetector;
 class AliFMD1;
 class AliFMD2;
 class AliFMD3;
-#ifndef ROOT_TArrayI
-# include <TArrayI.h>
-#endif
 class AliFMDGeometryBuilder;
 
 
index 22a54aa..e90e295 100644 (file)
@@ -31,6 +31,9 @@
 #include "AliFMDCalibGain.h"       // ALIFMDCALIBGAIN_H
 #include "AliFMDCalibPedestal.h"   // ALIFMDCALIBPEDESTAL_H
 #include "AliFMDCalibSampleRate.h" // ALIFMDCALIBPEDESTAL_H
+#include "AliFMDAltroMapping.h"    // ALIFMDALTROMAPPING_H
+#include <AliCDBManager.h>         // ALICDBMANAGER_H
+#include <AliCDBEntry.h>           // ALICDBMANAGER_H
 #include <Riostream.h>
 
 //====================================================================
@@ -43,6 +46,15 @@ ClassImp(AliFMDParameters)
 AliFMDParameters* AliFMDParameters::fgInstance = 0;
 
 //____________________________________________________________________
+const char* AliFMDParameters::fgkPulseGain      = "FMD/Calib/PulseGain";
+const char* AliFMDParameters::fgkPedestal       = "FMD/Calib/Pedestal";
+const char* AliFMDParameters::fgkDead           = "FMD/Calib/Dead";
+const char* AliFMDParameters::fgkSampleRate     = "FMD/Calib/SampleRate";
+const char* AliFMDParameters::fgkAltroMap       = "FMD/Calib/AltroMap";
+const char* AliFMDParameters::fgkZeroSuppression = "FMD/Calib/ZeroSuppression";
+
+
+//____________________________________________________________________
 AliFMDParameters* 
 AliFMDParameters::Instance() 
 {
@@ -53,14 +65,16 @@ AliFMDParameters::Instance()
 
 //____________________________________________________________________
 AliFMDParameters::AliFMDParameters() 
-  : fSiDeDxMip(1.664), 
+  : fIsInit(kFALSE),
+    fSiDeDxMip(1.664), 
     fFixedPulseGain(0), 
     fEdepMip(0),
     fZeroSuppression(0), 
     fSampleRate(0), 
     fPedestal(0), 
     fPulseGain(0), 
-    fDeadMap(0)
+    fDeadMap(0), 
+    fAltroMap(0)
 {
   // Default constructor 
   SetVA1MipRange();
@@ -75,6 +89,65 @@ AliFMDParameters::AliFMDParameters()
 }
 
 //__________________________________________________________________
+void
+AliFMDParameters::Init()
+{
+  // Initialize the parameters manager.  We need to get stuff from the
+  // CDB here. 
+  if (fIsInit) return;
+  
+  AliCDBManager* cdb      = AliCDBManager::Instance();
+  AliCDBEntry*   gain     = cdb->Get(fgkPulseGain);
+  AliCDBEntry*   pedestal = cdb->Get(fgkPedestal);
+  AliCDBEntry*   deadMap  = cdb->Get(fgkDead);
+  AliCDBEntry*   zeroSup  = cdb->Get(fgkZeroSuppression);
+  AliCDBEntry*   sampRat  = cdb->Get(fgkSampleRate);
+  AliCDBEntry*   hwMap    = cdb->Get(fgkAltroMap);       
+  
+  if (gain) {
+    AliDebug(1, Form("Got gain from CDB"));
+    fPulseGain = dynamic_cast<AliFMDCalibGain*>(gain->GetObject());
+    if (!fPulseGain) 
+      AliWarning("Invalid pulser gain object from CDB");
+  }
+  if (pedestal) {
+    AliDebug(1, Form("Got pedestal from CDB"));
+    fPedestal = dynamic_cast<AliFMDCalibPedestal*>(pedestal->GetObject());
+    if (!fPedestal) 
+      AliWarning("Invalid pedestal object from CDB");
+  }
+  if (deadMap) {
+    AliDebug(1, Form("Got dead map from CDB"));
+    fDeadMap = dynamic_cast<AliFMDCalibDeadMap*>(deadMap->GetObject());
+    if (!fDeadMap) 
+      AliWarning("Invalid dead map object from CDB");
+  }
+  if (zeroSup) {
+    AliDebug(1, Form("Got zero suppression from CDB"));
+    fZeroSuppression = 
+      dynamic_cast<AliFMDCalibZeroSuppression*>(zeroSup->GetObject());
+    if (!fZeroSuppression) 
+      AliWarning("Invalid zero suppression object from CDB");
+  }
+  if (sampRat) {
+    AliDebug(1, Form("Got zero suppression from CDB"));
+    fSampleRate = 
+      dynamic_cast<AliFMDCalibSampleRate*>(sampRat->GetObject());
+    if (!fSampleRate) 
+      AliWarning("Invalid zero suppression object from CDB");
+  }
+  if (hwMap) {
+    AliDebug(1, Form("Got ALTRO map from CDB"));
+    fAltroMap = dynamic_cast<AliFMDAltroMapping*>(hwMap->GetObject());
+    if (!fAltroMap) 
+      AliWarning("Invalid ALTRO map object from CDB");
+  }
+  if (!fAltroMap) fAltroMap = new AliFMDAltroMapping;
+  
+  fIsInit = kTRUE;
+}
+
+//__________________________________________________________________
 Float_t
 AliFMDParameters::GetThreshold() const
 {
@@ -150,229 +223,50 @@ AliFMDParameters::GetPedestalWidth(UShort_t detector, Char_t ring,
   return fPedestal->Width(detector, ring, sector, strip);
 }
   
-                             
-
 //__________________________________________________________________
-Float_t
-AliFMDParameters::GetEdepMip() const 
-{ 
-  // Get energy deposited by a MIP in the silicon sensors
-  if (fEdepMip <= 0){
-    AliFMDGeometry* fmd = AliFMDGeometry::Instance();
-    fEdepMip = (fSiDeDxMip 
-               * fmd->GetRing('I')->GetSiThickness() 
-               * fmd->GetSiDensity());
-  }
-  return fEdepMip;
+AliFMDAltroMapping*
+AliFMDParameters::GetAltroMap() const
+{
+  return fAltroMap;
 }
 
+
 //__________________________________________________________________
 Bool_t
 AliFMDParameters::Hardware2Detector(UInt_t ddl, UInt_t addr, 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 - kBaseDDL + 1
-  // 
-  // The ring number, sector, and strip number is given by the addr
-  // argument.  The address argument, has the following format 
-  // 
-  //   12            7          4          0
-  //   +-------------+----------+----------+
-  //   | Board       | ALTRO    | Channel  |
-  //   +-------------+----------+----------+
-  // 
-  // The board number identifier among other things the ring.  There's
-  // up to 4 boards per DDL, and the two first (0 and 1) corresponds
-  // to the inner rings, while the two last (2 and 3) corresponds to
-  // the outer rings. 
-  // 
-  // The board number and ALTRO number together identifies the sensor,
-  // and hence.  The lower board number (0 or 2) are the first N / 2
-  // sensors (where N is the number of sensors in the ring).  
-  // 
-  // There are 3 ALTRO's per card, and each ALTRO serves up to 4
-  // sensors.  Which of sensor is determined by the channel number.
-  // For the inner rings, the map is
-  // 
-  //    ALTRO 0, Channel  0 to  7   -> Sensor 0 or 5
-  //    ALTRO 0, Channel  8 to 15   -> Sensor 1 or 6
-  //    ALTRO 1, Channel  0 to  7   -> Sensor 2 or 7 
-  //    ALTRO 2, Channel  0 to  7   -> Sensor 3 or 8
-  //    ALTRO 2, Channel  8 to 15   -> Sensor 4 or 9
-  // 
-  // For the outer rings, the map is 
-  // 
-  //    ALTRO 0, Channel  0 to  3   -> Sensor 0 or 10
-  //    ALTRO 0, Channel  4 to  7   -> Sensor 1 or 11
-  //    ALTRO 0, Channel  8 to 11   -> Sensor 2 or 12
-  //    ALTRO 0, Channel 12 to 15   -> Sensor 3 or 13
-  //    ALTRO 1, Channel  0 to  3   -> Sensor 4 or 14
-  //    ALTRO 1, Channel  4 to  7   -> Sensor 5 or 15
-  //    ALTRO 2, Channel  0 to  3   -> Sensor 6 or 16
-  //    ALTRO 2, Channel  4 to  7   -> Sensor 7 or 17
-  //    ALTRO 2, Channel  8 to 11   -> Sensor 8 or 18
-  //    ALTRO 2, Channel 12 to 15   -> Sensor 9 or 19
-  // 
-  // Which divison of the sensor we're in, depends on the channel
-  // number only.  For the inner rings, the map is 
-  // 
-  //    Channel 0                   -> Sector 0, strips   0-127
-  //    Channel 1                   -> Sector 1, strips   0-127
-  //    Channel 3                   -> Sector 0, strips 128-255
-  //    Channel 4                   -> Sector 1, strips 128-255
-  //    Channel 5                   -> Sector 0, strips 256-383
-  //    Channel 6                   -> Sector 1, strips 256-383
-  //    Channel 7                   -> Sector 0, strips 384-511
-  //    Channel 8                   -> Sector 1, strips 384-511 
-  // 
-  // There are only half as many strips in the outer sensors, so there
-  // only 4 channels are used for a full sensor.  The map is 
-  // 
-  //    Channel 0                   -> Sector 0, strips   0-127
-  //    Channel 1                   -> Sector 1, strips   0-127
-  //    Channel 3                   -> Sector 0, strips 128-255
-  //    Channel 4                   -> Sector 1, strips 128-255
-  // 
-  // With this information, we can decode the hardware address to give
-  // us detector coordinates, unique at least up a 128 strips.  We
-  // return the first strip in the given range. 
-  //
-  det          =  (ddl - kBaseDDL) + 1;
-  UInt_t board =  (addr >> 7) & 0x1F;
-  UInt_t altro =  (addr >> 4) & 0x7;
-  UInt_t chan  =  (addr & 0xf);
-  if (board > 3) {
-    AliError(Form("Invalid board address %d for the FMD", board));
-    return kFALSE;
-  }
-  if (altro > 2) {
-    AliError(Form("Invalid ALTRO address %d for the FMD digitizer %d", 
-                 altro, board));
-    return kFALSE;
-  }
-  ring         =  (board > 1 ? 'O' : 'I');
-  UInt_t nsen  =  (ring == 'I' ? 10 : 20);
-  UInt_t nsa   =  (ring == 'I' ? 2 : 4);   // Sensors per ALTRO
-  UInt_t ncs   =  (ring == 'I' ? 8 : 4);   // Channels per sensor 
-  UInt_t sen   =  (board % 2) * nsen / 2;  // Base for half-ring
-  sen          += chan / ncs + (altro == 0 ? 0   : 
-                               altro == 1 ? nsa : UInt_t(1.5 * nsa));
-  sec          =  2 * sen + (chan % 2);
-  str          =  (chan % ncs) / 2 * 128;
-  return kTRUE;
+  if (!fAltroMap) return kFALSE;
+  return fAltroMap->Hardware2Detector(ddl, addr, det, ring, sec, str);
 }
 
 //__________________________________________________________________
 Bool_t
 AliFMDParameters::Detector2Hardware(UShort_t det, Char_t ring, UShort_t sec, 
-                                   UShort_t str, UInt_t& ddl, UInt_t& addr) 
-  const
+                                   UShort_t str, UInt_t& ddl, 
+                                   UInt_t& addr) const                       
 {
-  // Translate detector coordinates to a hardware address.
-  // The ddl is simply 
-  // 
-  //    kBaseDDL + (det - 1)
-  // 
-  // The ring number, sector, and strip number must be encoded into a
-  // hardware address.  The address argument, will have the following
-  // format on output
-  // 
-  //   12            7          4          0
-  //   +-------------+----------+----------+
-  //   | Board       | ALTRO    | Channel  |
-  //   +-------------+----------+----------+
-  // 
-  // The board number is given by the ring and sector.  The inner
-  // rings board 0 and 1, while the outer are 2 and 3.  Which of these
-  // depends on the sector.  The map is 
-  // 
-  //    Ring I, sector  0- 9       ->   board 0 
-  //    Ring I, sector 10-19       ->   board 1
-  //    Ring O, sector  0-19       ->   board 2 
-  //    Ring O, sector 20-39       ->   board 3
-  // 
-  // There are 3 ALTRO's per board.  The ALTRO number is given by the
-  // sector number.  For the inner rings, these are given by
-  // 
-  //    Sector  0- 3  or  10-13    ->   ALTRO 0 
-  //    Sector  4- 5  or  14-15    ->   ALTRO 1 
-  //    Sector  6- 9  or  16-19    ->   ALTRO 2 
-  // 
-  // For the outers, it's given by 
-  // 
-  //    Sector  0- 7  or  20-27    ->   ALTRO 0 
-  //    Sector  8-11  or  28-31    ->   ALTRO 1 
-  //    Sector 12-19  or  32-39    ->   ALTRO 2 
-  //
-  // The channel number is given by the sector and strip number.  For
-  // the inners, the map is 
-  // 
-  //    Sector  0, strips   0-127  ->   Channel  0
-  //    Sector  0, strips 128-255  ->   Channel  2
-  //    Sector  0, strips 256-383  ->   Channel  4
-  //    Sector  0, strips 384-511  ->   Channel  6
-  //    Sector  1, strips   0-127  ->   Channel  1
-  //    Sector  1, strips 128-255  ->   Channel  3
-  //    Sector  1, strips 256-383  ->   Channel  5
-  //    Sector  1, strips 384-511  ->   Channel  7
-  //    Sector  2, strips   0-127  ->   Channel  8
-  //    Sector  2, strips 128-255  ->   Channel 10
-  //    Sector  2, strips 256-383  ->   Channel 12
-  //    Sector  2, strips 384-511  ->   Channel 14
-  //    Sector  3, strips   0-127  ->   Channel  9
-  //    Sector  3, strips 128-255  ->   Channel 11
-  //    Sector  3, strips 256-383  ->   Channel 13
-  //    Sector  3, strips 384-511  ->   Channel 15
-  // 
-  // and so on, up to sector 19.  For the outer, the map is 
-  // 
-  //    Sector  0, strips   0-127  ->   Channel  0
-  //    Sector  0, strips 128-255  ->   Channel  2
-  //    Sector  1, strips   0-127  ->   Channel  1
-  //    Sector  1, strips 128-255  ->   Channel  3
-  //    Sector  2, strips   0-127  ->   Channel  4
-  //    Sector  2, strips 128-255  ->   Channel  6
-  //    Sector  3, strips   0-127  ->   Channel  5
-  //    Sector  3, strips 128-255  ->   Channel  7
-  //    Sector  4, strips   0-127  ->   Channel  8
-  //    Sector  4, strips 128-255  ->   Channel 10
-  //    Sector  5, strips   0-127  ->   Channel  9
-  //    Sector  5, strips 128-255  ->   Channel 11
-  //    Sector  6, strips   0-127  ->   Channel 12
-  //    Sector  6, strips 128-255  ->   Channel 14
-  //    Sector  7, strips   0-127  ->   Channel 13
-  //    Sector  7, strips 128-255  ->   Channel 15
-  // 
-  // and so on upto sector 40. 
-  // 
-  // With this information, we can decode the detector coordinates to
-  // give us a unique hardware address 
-  //
-  ddl          =  kBaseDDL + (det - 1);
-  UInt_t nsen  =  (ring == 'I' ? 10 : 20);
-  UInt_t nsa   =  (ring == 'I' ? 2 : 4);   // Sensors per ALTRO
-  UInt_t ncs   =  (ring == 'I' ? 8 : 4);   // Channels per sensor 
-  UInt_t bbase =  (ring == 'I' ? 0 : 2);
-  UInt_t board =  bbase + sec / nsen;
-  UInt_t lsen  =  (sec - (board - bbase) * nsen);
-  UInt_t altro =  (lsen < 2 * nsa ? 0 : (lsen < 3 * nsa ? 1 : 2));
-  UInt_t sbase =  (lsen < 2 * nsa ? 0 : (lsen < 3 * nsa ? 2*nsa : 3*nsa));
-  UInt_t chan  =  (sec % 2) + (lsen-sbase) / 2 * ncs + 2 * str / 128;
-  AliDebug(40, Form("\n"
-                   "  chan = (%d %% 2) + (%d-%d) / %d * %d + 2 * %d / 128\n"
-                   "       = %d + %d + %d = %d", 
-                   sec, lsen, sbase, 2, ncs, str, 
-                   (sec % 2), (lsen - sbase) / 2 * ncs, 
-                   2 * str / 128, chan));
-  addr         =  chan + (altro << 4) + (board << 7);
-  
-  return kTRUE;
+  if (!fAltroMap) return kFALSE;
+  return fAltroMap->Detector2Hardware(det, ring, sec, str, ddl, addr);
 }
 
+
+//__________________________________________________________________
+Float_t
+AliFMDParameters::GetEdepMip() const 
+{ 
+  // Get energy deposited by a MIP in the silicon sensors
+  if (fEdepMip <= 0){
+    AliFMDGeometry* fmd = AliFMDGeometry::Instance();
+    fEdepMip = (fSiDeDxMip 
+               * fmd->GetRing('I')->GetSiThickness() 
+               * fmd->GetSiDensity());
+  }
+  return fEdepMip;
+}
+
+
   
   
   
index 15dddae..5832108 100644 (file)
@@ -31,11 +31,14 @@ typedef AliFMDBoolMap   AliFMDCalibDeadMap;
 class AliFMDCalibPedestal;
 class AliFMDCalibGain;
 class AliFMDCalibSampleRate;
+class AliFMDAltroMapping;
 
 class AliFMDParameters : public TNamed
 {
 public:
   static AliFMDParameters* Instance();
+
+  void Init();
   
   // Set various `Fixed' parameters 
   void SetVA1MipRange(UShort_t r=20)          { fVA1MipRange = r; }
@@ -85,14 +88,23 @@ public:
                             Char_t& ring, UShort_t& sec, UShort_t& str) const;
   Bool_t   Detector2Hardware(UShort_t det, Char_t ring, UShort_t sec, 
                             UShort_t str, UInt_t& ddl, UInt_t& addr) const;
+  AliFMDAltroMapping* GetAltroMap() const;
   enum { 
     kBaseDDL = 0x1000 // DDL offset for the FMD
   };
 protected:
   AliFMDParameters();
   virtual ~AliFMDParameters() {}
-  static AliFMDParameters* fgInstance; // Static singleton instance
-  
+  static AliFMDParameters* fgInstance;   // Static singleton instance
+  static const char* fgkPulseGain;      // Path to PulseGain calib object
+  static const char* fgkPedestal;       // Path to Pedestal calib object
+  static const char* fgkDead;           // Path to Dead calib object
+  static const char* fgkSampleRate;     // Path to SampleRate calib object
+  static const char* fgkAltroMap;       // Path to AltroMap calib object
+  static const char* fgkZeroSuppression; // Path to ZeroSuppression cal object
+
+  Bool_t          fIsInit;               // Whether we've been initialised  
+
   const Float_t   fSiDeDxMip;            // MIP dE/dx in Silicon
   UShort_t        fVA1MipRange;          // # MIPs the pre-amp can do    
   UShort_t        fAltroChannelSize;     // Largest # to store in 1 ADC ch.
@@ -112,9 +124,9 @@ protected:
   AliFMDCalibPedestal*        fPedestal;        // Pedestals 
   AliFMDCalibGain*            fPulseGain;       // Pulser gain
   AliFMDCalibDeadMap*         fDeadMap;         // Pulser gain
+  AliFMDAltroMapping*         fAltroMap;        // Map of hardware
   
-  
-  ClassDef(AliFMDParameters,2)
+  ClassDef(AliFMDParameters,3)
 };
 
 #endif
index a2933f4..0c8efec 100644 (file)
@@ -24,6 +24,7 @@
 #pragma link C++ class  AliFMDCalibPedestal+;
 #pragma link C++ class  AliFMDCalibGain+;
 #pragma link C++ class  AliFMDCalibSampleRate+;
+#pragma link C++ class  AliFMDAltroMapping+;
 
 #else
 # error Not for compilation 
index 797525c..9cb54e1 100644 (file)
@@ -8,6 +8,7 @@ SRCS            =  AliFMDDigit.cxx              \
                   AliFMDCalibPedestal.cxx      \
                   AliFMDCalibGain.cxx          \
                   AliFMDCalibSampleRate.cxx    \
+                  AliFMDAltroMapping.cxx       \
                   AliFMDParameters.cxx         \
                   AliFMDGeometry.cxx           \
                   AliFMDRing.cxx               \