From 57c3c593e20f5685cdc6f7ba8fbb230c9426b848 Mon Sep 17 00:00:00 2001 From: cholm Date: Fri, 17 Mar 2006 22:27:07 +0000 Subject: [PATCH] Added AliFMDAltroMapping --- FMD/AliFMDAltroMapping.cxx | 346 +++++++++++++++++++++++++++++++++++++ FMD/AliFMDAltroMapping.h | 53 ++++++ FMD/AliFMDGeometry.h | 10 +- FMD/AliFMDParameters.cxx | 310 +++++++++++---------------------- FMD/AliFMDParameters.h | 20 ++- FMD/FMDbaseLinkDef.h | 1 + FMD/libFMDbase.pkg | 1 + 7 files changed, 526 insertions(+), 215 deletions(-) create mode 100644 FMD/AliFMDAltroMapping.cxx create mode 100644 FMD/AliFMDAltroMapping.h diff --git a/FMD/AliFMDAltroMapping.cxx b/FMD/AliFMDAltroMapping.cxx new file mode 100644 index 00000000000..d948d5ee863 --- /dev/null +++ b/FMD/AliFMDAltroMapping.cxx @@ -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 index 00000000000..769efd11dd8 --- /dev/null +++ b/FMD/AliFMDAltroMapping.h @@ -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 + * + * See cxx source for full Copyright notice + */ +#ifndef ALIALTROMAPPING_H +# include +#endif +#ifndef ALIFMDUSHORTMAP_H +# include "AliFMDUShortMap.h" +#endif +#ifndef ROOT_TArrayI +# include +#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 +// diff --git a/FMD/AliFMDGeometry.h b/FMD/AliFMDGeometry.h index 7a71c7b1555..f3893669eff 100644 --- a/FMD/AliFMDGeometry.h +++ b/FMD/AliFMDGeometry.h @@ -17,6 +17,13 @@ #ifndef ALIGEOMETRY_H # include #endif +#ifndef ROOT_TArrayI +# include +#endif +#ifndef ROOT_TMatrixFfwd +# include +#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 -#endif class AliFMDGeometryBuilder; diff --git a/FMD/AliFMDParameters.cxx b/FMD/AliFMDParameters.cxx index 22a54aaa17f..e90e295032e 100644 --- a/FMD/AliFMDParameters.cxx +++ b/FMD/AliFMDParameters.cxx @@ -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 +#include // ALICDBMANAGER_H #include //==================================================================== @@ -42,6 +45,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(); @@ -74,6 +88,65 @@ AliFMDParameters::AliFMDParameters() SetThreshold(); } +//__________________________________________________________________ +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(gain->GetObject()); + if (!fPulseGain) + AliWarning("Invalid pulser gain object from CDB"); + } + if (pedestal) { + AliDebug(1, Form("Got pedestal from CDB")); + fPedestal = dynamic_cast(pedestal->GetObject()); + if (!fPedestal) + AliWarning("Invalid pedestal object from CDB"); + } + if (deadMap) { + AliDebug(1, Form("Got dead map from CDB")); + fDeadMap = dynamic_cast(deadMap->GetObject()); + if (!fDeadMap) + AliWarning("Invalid dead map object from CDB"); + } + if (zeroSup) { + AliDebug(1, Form("Got zero suppression from CDB")); + fZeroSuppression = + dynamic_cast(zeroSup->GetObject()); + if (!fZeroSuppression) + AliWarning("Invalid zero suppression object from CDB"); + } + if (sampRat) { + AliDebug(1, Form("Got zero suppression from CDB")); + fSampleRate = + dynamic_cast(sampRat->GetObject()); + if (!fSampleRate) + AliWarning("Invalid zero suppression object from CDB"); + } + if (hwMap) { + AliDebug(1, Form("Got ALTRO map from CDB")); + fAltroMap = dynamic_cast(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; +} + + diff --git a/FMD/AliFMDParameters.h b/FMD/AliFMDParameters.h index 15dddaee4ed..5832108e605 100644 --- a/FMD/AliFMDParameters.h +++ b/FMD/AliFMDParameters.h @@ -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 diff --git a/FMD/FMDbaseLinkDef.h b/FMD/FMDbaseLinkDef.h index a2933f4a00e..0c8efec9374 100644 --- a/FMD/FMDbaseLinkDef.h +++ b/FMD/FMDbaseLinkDef.h @@ -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 diff --git a/FMD/libFMDbase.pkg b/FMD/libFMDbase.pkg index 797525ce86b..9cb54e18a8b 100644 --- a/FMD/libFMDbase.pkg +++ b/FMD/libFMDbase.pkg @@ -8,6 +8,7 @@ SRCS = AliFMDDigit.cxx \ AliFMDCalibPedestal.cxx \ AliFMDCalibGain.cxx \ AliFMDCalibSampleRate.cxx \ + AliFMDAltroMapping.cxx \ AliFMDParameters.cxx \ AliFMDGeometry.cxx \ AliFMDRing.cxx \ -- 2.39.3