X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=FMD%2FAliFMDParameters.cxx;h=b5673afa8fd9d4daed3abc3357e7bcb26ad243b7;hb=83294c22763ab9569f670e89936d4bf7096a4c52;hp=8ec4a78e00ead701db94046387cbee98be1d1841;hpb=1a1fdef7df14ded810885ec1c2da3dc3d7d1100c;p=u%2Fmrichter%2FAliRoot.git diff --git a/FMD/AliFMDParameters.cxx b/FMD/AliFMDParameters.cxx index 8ec4a78e00e..b5673afa8fd 100644 --- a/FMD/AliFMDParameters.cxx +++ b/FMD/AliFMDParameters.cxx @@ -1,4 +1,4 @@ -/************************************************************************** +/************************************************************************* * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * * * Author: The ALICE Off-line Project. * @@ -11,22 +11,43 @@ * 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$ */ - + ************************************************************************* + * $Id$ */ +/** + * @file AliFMDParameters.cxx + * @author Christian Holm Christensen + * @date Mon Mar 27 12:44:26 2006 + * @brief Manager of FMD parameters + */ //____________________________________________________________________ // // Forward Multiplicity Detector based on Silicon wafers. // // This class is a singleton that handles various parameters of // the FMD detectors. +// The manager normally serves the parameters from the Conditions +// Database (CDB). These are retrivied by the member function +// `Init'. Optionally, the class can serve hard-coded constants, if +// no CDB is available. // -#include "AliFMDParameters.h" // ALIFMDPARAMETERS_H -#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H -#include "AliFMDRing.h" // ALIFMDRING_H -#include "AliLog.h" // ALILOG_H +#include "AliFMDDebug.h" // ALILOG_H +#include "AliFMDParameters.h" // ALIFMDPARAMETERS_H +#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H +#include "AliFMDRing.h" // ALIFMDRING_H +#include "AliFMDCalibGain.h" // ALIFMDCALIBGAIN_H +#include "AliFMDCalibPedestal.h" // ALIFMDCALIBPEDESTAL_H +#include "AliFMDCalibSampleRate.h" // ALIFMDCALIBSAMPLERATE_H +#include "AliFMDCalibStripRange.h" // ALIFMDCALIBSTRIPRANGE_H +#include "AliFMDAltroMapping.h" // ALIFMDALTROMAPPING_H +#include // ALICDBMANAGER_H +#include // ALICDBMANAGER_H +#include +#include #include +#include +#include +#include +#include //==================================================================== ClassImp(AliFMDParameters) @@ -37,20 +58,62 @@ 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"; +const char* AliFMDParameters::fgkStripRange = "FMD/Calib/StripRange"; +const char* AliFMDParameters::fkPedestalShuttleID = "pedestals"; +const char* AliFMDParameters::fkGainShuttleID = "gains"; +const char* AliFMDParameters::fkConditionsShuttleID = "conditions"; + //____________________________________________________________________ AliFMDParameters* AliFMDParameters::Instance() { + // // Get static instance + // if (!fgInstance) fgInstance = new AliFMDParameters; return fgInstance; } //____________________________________________________________________ AliFMDParameters::AliFMDParameters() - : fSiDeDxMip(1.664) + : fIsInit(kFALSE), + fkSiDeDxMip(1.664), + fVA1MipRange(0), + fAltroChannelSize(0), + fChannelsPerAltro(0), + fPedestalFactor(0), + fZSPre(1), + fZSPost(1), + fZSPedSubtract(kTRUE), + fFixedPedestal(100), + fFixedPedestalWidth(2), + fFixedZeroSuppression(1), + fFixedSampleRate(2), + fFixedThreshold(0), + fFixedMinStrip(0), + fFixedMaxStrip(127), + fFixedPulseGain(2), + fEdepMip(0), + fHasCompleteHeader(kTRUE), + fZeroSuppression(0), + fSampleRate(0), + fPedestal(0), + fPulseGain(0), + fDeadMap(0), + fAltroMap(0), + fStripRange(0), + fRunNo(-1) { + // // Default constructor + // SetVA1MipRange(); SetAltroChannelSize(); SetChannelsPerAltro(); @@ -59,21 +122,1209 @@ AliFMDParameters::AliFMDParameters() SetPedestal(); SetPedestalWidth(); SetPedestalFactor(); + SetThreshold(); + SetStripRange(); + SetGain(); + fAltroMap = new AliFMDAltroMapping; +} + +//__________________________________________________________________ +Bool_t +AliFMDParameters::CheckForNewRun() +{ + Int_t run = AliCDBManager::Instance()->GetRun(); + if (run != fRunNo) { + fIsInit = false; + fRunNo = run; + } + return run != fRunNo; +} + +//__________________________________________________________________ +UShort_t +AliFMDParameters::Init(Bool_t forceReInit, UInt_t what) +{ + // + // Initialize the manager. This tries to read the parameters from + // CDB. If that fails, the class uses the hard-coded parameters. + // + // Parameters: + // forceReInit Force (re-)initalize flag + // what What to initialize + // + if (forceReInit) fIsInit = kFALSE; + CheckForNewRun(); + + if (fIsInit) return 0; + + UShort_t errMask = 0; + if (what & kPulseGain) errMask |= InitPulseGain(); + if (what & kPedestal) errMask |= InitPedestal(); + if (what & kDeadMap) errMask |= InitDeadMap(); + if (what & kSampleRate) errMask |= InitSampleRate(); + if (what & kZeroSuppression) errMask |= InitZeroSuppression(); + if (what & kAltroMap) errMask |= InitAltroMap(); + if (what & kStripRange) errMask |= InitStripRange(); + fIsInit = kTRUE; + + return errMask; +} +//__________________________________________________________________ +UShort_t +AliFMDParameters::Init(AliFMDPreprocessor* pp, Bool_t forceReInit, UInt_t what) +{ + // + // Initialize the manager. This tries to read the parameters from + // CDB. If that fails, the class uses the hard-coded parameters. + // + // Parameters: + // pp Preprocessor + // forceReInit Force (re-)initalize flag + // what What to initialize + // + if (forceReInit) fIsInit = kFALSE; + CheckForNewRun(); + + if (fIsInit) return 0; + + UShort_t errMask = 0; + if (what & kPulseGain) errMask |= InitPulseGain(pp); + if (what & kPedestal) errMask |= InitPedestal(pp); + if (what & kDeadMap) errMask |= InitDeadMap(pp); + if (what & kSampleRate) errMask |= InitSampleRate(pp); + if (what & kZeroSuppression) errMask |= InitZeroSuppression(pp); + if (what & kAltroMap) errMask |= InitAltroMap(pp); + if (what & kStripRange) errMask |= InitStripRange(pp); + fIsInit = kTRUE; + + return errMask; +} + +//__________________________________________________________________ +Bool_t +AliFMDParameters::CheckFile(const char* prefix, + const char* path, + int number, + TString& f) const +{ + // + // Check if the file prefixnumber exists in @a path, + // and write the full path to @a f. + // + // Parameters: + // prefix File prefix (cond, peds, gains, ...) + // path Path to files + // number Detector number (1, 2, or 3) + // f On return full path to file (if found) + // + // Return: + // @c true if file exists and is readable, @c false otherwise + // + f = (Form("%s%d.csv", prefix, number)); + AliFMDDebug(5, ("Checking if %s exists in %s ...", f.Data(), path)); + f = gSystem->Which(path, f.Data()); + AliFMDDebug(5, ("Got back '%s'", f.Data())); + return !f.IsNull(); +} + +//__________________________________________________________________ +UShort_t +AliFMDParameters::Init(const char* path, Bool_t forceReInit, UInt_t what) +{ + // + // Initialize the manager. This will try to read some calibrations + // (sample rate, strip range, gains, pedestals) from local comma + // separated value (CSV) files in the directory pointed at by @a + // path. If they are not found, then they will be retrieved from + // OCDB as appropriately. Other calibrations are always read from + // OCDB. + // + // The CSV files should be named as + // + // - Pedestals: pedsdet_number.csv + // - Gains: gainsdet_number.csv + // - Sample Rate: conditionsdet_number.csv + // - Strip Range: conditionsdet_number.csv + // + // where det_number is the detector number (1, 2, or 3). + // + // Parameters: + // path Where to look for the CSV files + // forceReInit Always reinitialise + // what What calibrations to load. + // + if (forceReInit) fIsInit = kFALSE; + CheckForNewRun(); + + if (fIsInit) return 0; + + AliFMDCalibStripRange* range = 0; + AliFMDCalibSampleRate* rate = 0; + AliFMDCalibPedestal* peds = 0; + AliFMDCalibGain* gains = 0; + + for (Int_t i = 1; i <= 3; i++) { + TString f; + if (((what & kSampleRate) || (what & kStripRange)) && + CheckFile("conditions", path, i, f)) { + if (!rate && (what & kSampleRate)) rate = new AliFMDCalibSampleRate; + if (!range && (what & kStripRange)) range = new AliFMDCalibStripRange; + std::ifstream in(f.Data()); + if (range) range->ReadFromFile(in); + if (rate) rate->ReadFromFile(in); + in.close(); + } + if ((what & kPedestal) && CheckFile("peds", path, i, f)) { + if (!peds) peds = new AliFMDCalibPedestal; + std::ifstream in(f.Data()); + peds->ReadFromFile(in); + in.close(); + } + if ((what & kPulseGain) && CheckFile("gains", path, i, f)) { + if (!gains) gains = new AliFMDCalibGain; + std::ifstream in(f.Data()); + gains->ReadFromFile(in); + in.close(); + } + } + + if (range) what &= ~kStripRange; + if (rate) what &= ~kSampleRate; + if (peds) what &= ~kPedestal; + if (gains) what &= ~kPulseGain; + + UShort_t ret = Init(kFALSE, what); + + if (range) SetStripRange(range); + if (rate) SetSampleRate(rate); + if (peds) SetPedestal(peds); + if (gains) SetGain(gains); + + fIsInit = kTRUE; + + return ret; +} + +//__________________________________________________________________ +void +AliFMDParameters::MakeDeadMap(Float_t maxNoise, + Float_t minGain, + Float_t maxGain) +{ + // + // Automatically generate a dead map from the pedestals and gains. + // A channel is marked as dead of the noise is too high (currently + // more than 10 ADC counts), or the gain is unreasonable (currently + // larger than 10, or smaller than 0.1). + // + // The procedure does not overwrite channels previously marked as + // dead - e.g., channels marked as dead in the calibration loaded + // from OCDB will continue to be marked as dead. That is, this + // procedure will never make a channel un-dead. + // + // Parameters: + // maxNoise Maximum noise value before a channel is marked + // as dead. + // minGain Minimum value of the calibrated gain before a + // channel is considered dead. + // maxGain Maximum value of the calibrated gain before a + // channel is considered dead. + // + if (fPedestal) + fDeadMap = fPedestal->MakeDeadMap(maxNoise, fDeadMap); + if (fPulseGain) + fDeadMap = fPulseGain->MakeDeadMap(minGain, maxGain, fDeadMap); +} +//__________________________________________________________________ +#define DET2IDX(det,ring,sec,str) \ + (det * 1000 + (ring == 'I' ? 0 : 512) + str) + +//__________________________________________________________________ +void +AliFMDParameters::Draw(Option_t* option) +{ + // + // Draw parameters. + // + // Parameters: + // option What to draw. Should be one of + // - dead Dead channels + // - threshold Threshold + // - gain Gain + // - pedestal Pedestal + // - noise Noise (or pedestal width) + // - zero Zero suppression + // - rate Sampling rate (VA1 clock / ALTRO clock) + // - min Minimum strip read out + // - max Maximum strip read out + // - map hardware address + // + TString opt(option); + enum { + kLocalPulseGain, // Path to PulseGain calib object + kLocalThreshold, // Path to PulseGain calib object + kLocalPedestal, // Path to Pedestal calib object + kLocalPedestalWidth, // Path to Pedestal calib object + kLocalDead, // Path to Dead calib object + kLocalSampleRate, // Path to SampleRate calib object + kLocalAltroMap, // Path to AltroMap calib object + kLocalZeroSuppression, // Path to ZeroSuppression cal object + kLocalMinStripRange, // Path to strip range cal object + kLocalMaxStripRange // Path to strip range cal object + } what; + + if (opt.Contains("dead", TString::kIgnoreCase)) + what = kLocalDead; + else if (opt.Contains("threshold",TString::kIgnoreCase)) + what = kLocalThreshold; + else if (opt.Contains("gain",TString::kIgnoreCase)) + what = kLocalPulseGain; + else if (opt.Contains("pedestal",TString::kIgnoreCase)) + what = kLocalPedestal; + else if (opt.Contains("noise",TString::kIgnoreCase)) + what = kLocalPedestalWidth; + else if (opt.Contains("zero",TString::kIgnoreCase)) + what = kLocalZeroSuppression; + else if (opt.Contains("rate",TString::kIgnoreCase)) + what = kLocalSampleRate; + else if (opt.Contains("min",TString::kIgnoreCase)) + what = kLocalMinStripRange; + else if (opt.Contains("max",TString::kIgnoreCase)) + what = kLocalMaxStripRange; + else if (opt.Contains("map",TString::kIgnoreCase)) + what = kLocalAltroMap; + else { + Warning("Draw", "unknown parameter: %s\n\tShould be one of\n\t" + "dead, threshold, gain, pedestal, noise, zero, rate, " + "min, max, map", + option); + return; + } + + TArrayD xbins(3 * 512 + 2 * 256 + 5); + Int_t i = 1; + Bool_t skip = kTRUE; + for (UShort_t det = 1; det <= 3; det++) { + UShort_t nRings = (det == 1 ? 1 : 2); + for (UShort_t iring = 0; iring < nRings; iring++) { + UShort_t nStrip = (iring == 0 ? 512 : 256); + Char_t ring = (iring == 0 ? 'I' : 'O'); + for (UShort_t str = 0; str < nStrip; str++) { + // UShort_t nSec = (iring == 0 ? 20 : 40); + // Char_t ring = (iring == 0 ? 'I' : 'O'); + // for (UShort_t sec = 0; sec < nSec; sec++) { + Int_t idx = DET2IDX(det, ring, 0, str); + // Int_t idx = DET2IDX(det, ring, sec, 0); + if (skip) { + xbins[i-1] = idx - .5; + skip = kFALSE; + } + xbins[i] = idx + .5; + i++; + } + skip = kTRUE; + i++; + } + } + TArrayD ybins(41); + for (/*Int_t*/ i = 0; i < ybins.fN; i++) ybins[i] = Float_t(i - .5); + TH2D* hist = new TH2D("calib", Form("Calibration %s", option), + xbins.fN-1, xbins.fArray, + ybins.fN-1, ybins.fArray); + hist->GetXaxis()->SetTitle("1000 #times detector + 512 #times ring + strip"); + hist->GetYaxis()->SetTitle("sector"); + + // hist->Draw("Lego"); + // return; + + for (UShort_t det = 1; det <= 3; det++) { + UShort_t nRings = (det == 1 ? 1 : 2); + for (UShort_t iring = 0; iring < nRings; iring++) { + UShort_t nSector = (iring == 0 ? 20 : 40); + UShort_t nStrip = (iring == 0 ? 512 : 256); + Char_t ring = (iring == 0 ? 'I' : 'O'); + for (UShort_t sec = 0; sec < nSector; sec++) { + for (UShort_t str = 0; str < nStrip; str++) { + Int_t idx = DET2IDX(det, ring, sec, str); + UShort_t ddl, addr, time, sam=0; + Double_t val = 0; + switch (what) { + case kLocalPulseGain: // Path to PulseGain calib object + val = GetPulseGain(det,ring,sec,str); break; + case kLocalThreshold: // Path to PulseGain calib object + val = GetThreshold(); break; + case kLocalPedestal: // Path to Pedestal calib object + val = GetPedestal(det,ring,sec,str); break; + case kLocalPedestalWidth: // Path to Pedestal calib object + val = GetPedestalWidth(det,ring,sec,str); break; + case kLocalDead: // Path to Dead calib object + val = IsDead(det,ring,sec,str); break; + case kLocalSampleRate: // Path to SampleRate calib object + val = GetSampleRate(det,ring,sec,str); break; + case kLocalAltroMap: // Path to AltroMap calib object + Detector2Hardware(det,ring,sec,str,sam,ddl,addr,time); + val = addr; break; + case kLocalZeroSuppression: // Path to ZeroSuppression cal object + val = GetZeroSuppression(det,ring,sec,str); break; + case kLocalMinStripRange: // Path to strip range cal object + val = GetMinStrip(det,ring,sec,str); break; + case kLocalMaxStripRange: // Path to strip range cal object + val = GetMaxStrip(det,ring,sec,str); break; + } + hist->Fill(idx,sec,val); + // hist->Fill(idx,str,val); + } + } + } + } + hist->Draw("lego"); +} + +//__________________________________________________________________ +void +AliFMDParameters::Print(Option_t* option) const +{ + // Print information. + // If option contains an 'A' then everything is printed. + // If the option contains the string "FMD" the function will search + // for detector, ring, sector, and strip numbers to print, in the + // format + // + // FMD[,] + // + // The wild card '*' means all of , , , or + // . + TString opt(option); + Bool_t showStrips = opt.Contains("a", TString::kIgnoreCase); + UShort_t ds[] = { 1, 2, 3, 0 }; + Char_t rs[] = { 'I', 'O', '\0' }; + UShort_t minStrip = 0; + UShort_t maxStrip = 512; + UShort_t minSector = 0; + UShort_t maxSector = 40; + + + if (opt.Contains("fmd",TString::kIgnoreCase)) { + Int_t i = opt.Index("fmd",TString::kIgnoreCase); + Int_t j = opt.Index("]",TString::kIgnoreCase); + if (j != kNPOS) + showStrips = kTRUE; + else + j = opt.Length(); + enum { + kReadDet, + kReadRing, + kReadLbrack, + kReadSector, + kReadComma, + kReadStrip, + kReadRbrack, + kEnd + } state = kReadDet; + std::stringstream s(opt(i+4, j-i-3).Data()); + while (state != kEnd) { + Char_t tmp = s.peek(); + if (tmp == ' ' || tmp == '\t') { + s.get(); + continue; + } + switch (state) { + case kReadDet: { // First, try to kRead the detector + if (tmp == '*') s.get(); + else { + UShort_t det; + s >> det; + if (!s.bad()) { + ds[0] = det; + ds[1] = 0; + } + } + state = (s.bad() ? kEnd : kReadRing); + } break; + case kReadRing: { // Then try to read the ring; + Char_t ring; + s >> ring; + if (ring != '*' && !s.bad()) { + rs[0] = ring; + rs[1] = '\0'; + } + state = (s.bad() ? kEnd : kReadLbrack); + } break; + case kReadLbrack: { // Try to read a left bracket + Char_t lbrack; + s >> lbrack; + state = (s.bad() ? kEnd : kReadSector); + } break; + case kReadSector: { // Try to read a sector + if (tmp == '*') s.get(); + else { + UShort_t sec; + s >> sec; + if (!s.bad()) { + minSector = sec; + maxSector = sec + 1; + } + } + state = (s.bad() ? kEnd : kReadComma); + } break; + case kReadComma: { // Try to read a left bracket + Char_t comma; + s >> comma; + state = (s.bad() ? kEnd : kReadStrip); + } break; + case kReadStrip: { // Try to read a strip + if (tmp == '*') s.get(); + else { + UShort_t str; + s >> str; + if (!s.bad()) { + minStrip = str; + maxStrip = str + 1; + } + } + state = (s.bad() ? kEnd : kReadRbrack); + } break; + case kReadRbrack: { // Try to read a left bracket + Char_t rbrack; + s >> rbrack; + state = kEnd; + } break; + case kEnd: + break; + } + } + } + UShort_t* dp = ds; + UShort_t det; + while ((det = *(dp++))) { + + Char_t* rp = rs; + Char_t ring; + while ((ring = *(rp++))) { + if (det == 1 && ring == 'O') continue; + UShort_t min = GetMinStrip(det, ring, 0, 0); + UShort_t max = GetMaxStrip(det, ring, 0, 0); + std::cout << "FMD" << det << ring + << " Strip range: " + << std::setw(3) << min << "," + << std::setw(3) << max << std::endl; + + UShort_t nSec = ( ring == 'I' ? 20 : 40 ); + UShort_t nStr = ( ring == 'I' ? 512 : 256 ); + for (UShort_t sec = minSector; sec < maxSector && sec < nSec; sec++) { + + UShort_t rate = GetSampleRate(det, ring, sec, 0); + std::cout << "FMD" << det << ring << "[" << std::setw(2) << sec + << "] sample rate: " << rate << std::endl; + + if (!showStrips) continue; + std::cout + << " Strip | Pedestal | Gain | ZS thr. | Address\n" + << "--------+-------------------+------------+---------+---------" + << std::endl; + for (UShort_t str = minStrip; str < nStr && str < maxStrip; str++) { + if (str == minStrip) std::cout << std::setw(3) << sec << ","; + else std::cout << " "; + std::cout << std::setw(3) << str << " | "; + if (IsDead(det, ring, sec, str)) { + std::cout << "dead" << std::endl; + continue; + } + UShort_t ddl, addr, time, sam=0; + Detector2Hardware(det, ring, sec, str, sam, ddl, addr, time); + std::cout << std::setw(7) << GetPedestal(det, ring, sec, str) + << "+/-" << std::setw(7) + << GetPedestalWidth(det, ring, sec, str) + << " | " << std::setw(10) + << GetPulseGain(det, ring, sec, str) + << " | " << std::setw(7) + << GetZeroSuppression(det, ring, sec, str) + << " | 0x" << std::hex << std::setw(4) + << std::setfill('0') << ddl << ",0x" << std::setw(3) + << addr << std::dec << std::setfill(' ') << std::endl; + } // for (strip) + } // for (sector) + std::cout + << "=============================================================" + << std::endl; + } // while (ring) + } // while (det) + +} + +//__________________________________________________________________ +AliCDBEntry* +AliFMDParameters::GetEntry(const char* path, AliFMDPreprocessor* pp, + Bool_t fatal) const +{ + // + // Get an entry from either global AliCDBManager or passed + // AliFMDPreprocessor. + // + // Parameters: + // path Path to CDB object. + // pp AliFMDPreprocessor + // fatal If true, raise a fatal flag if we didn't get the entry. + // Return: + // AliCDBEntry if found + // + AliCDBEntry* entry = 0; + if (!pp) { + AliCDBManager* cdb = AliCDBManager::Instance(); + entry = cdb->Get(path); + } + else { + const char* third = gSystem->BaseName(path); + const char* second = gSystem->BaseName(gSystem->DirName(path)); + entry = pp->GetFromCDB(second, third); + } + if (!entry) { + TString msg(Form("No %s found in CDB, perhaps you need to " + "use AliFMDCalibFaker?", path)); + if (fatal) { AliFatal(msg.Data()); } + else AliLog::Message(AliLog::kWarning, msg.Data(), "FMD", + "AliFMDParameters", "GetEntry", __FILE__, + __LINE__); + return 0; + } + if (entry && AliLog::GetDebugLevel("FMD", "") > 0) { + AliInfoF("Got entry %p for %s", entry, path); + entry->PrintId(); + entry->PrintMetaData(); + entry->Print(); + } + return entry; +} + + +//__________________________________________________________________ +UShort_t +AliFMDParameters::InitPulseGain(AliFMDPreprocessor* pp) +{ + // + // Initialize gains. Try to get them from CDB + // + // Parameters: + // pp Pre-processor if called from shuttle + // + AliCDBEntry* gain = GetEntry(fgkPulseGain, pp); + if (!gain) return kPulseGain; + + AliFMDDebug(5, ("Got gain from CDB")); + fPulseGain = dynamic_cast(gain->GetObject()); + if (!fPulseGain) { + AliError("Invalid pulser gain object from CDB"); + return kPulseGain; + } + if (!fPulseGain->Values().Ptr()) { + AliError("Empty pulser gain object from CDB"); + return kPulseGain; + } + return 0; +} +//__________________________________________________________________ +UShort_t +AliFMDParameters::InitPedestal(AliFMDPreprocessor* pp) +{ + // + // Initialize pedestals. Try to get them from CDB + // + // Parameters: + // pp Pre-processor if called from shuttle + // + AliCDBEntry* pedestal = GetEntry(fgkPedestal, pp); + if (!pedestal) return kPedestal; + + AliFMDDebug(5, ("Got pedestal from CDB")); + fPedestal = dynamic_cast(pedestal->GetObject()); + if (!fPedestal) { + AliError("Invalid pedestal object from CDB"); + return kPedestal; + } + if (!fPedestal->Values().Ptr()) { + AliError("Empty pedestal object from CDB"); + return kPedestal; + } + return 0; +} + +//__________________________________________________________________ +UShort_t +AliFMDParameters::InitDeadMap(AliFMDPreprocessor* pp) +{ + // + // Initialize dead map. Try to get it from CDB + // + // Parameters: + // pp Pre-processor if called from shuttle + // + AliCDBEntry* deadMap = GetEntry(fgkDead, pp); + if (!deadMap) return kDeadMap; + + AliFMDDebug(5, ("Got dead map from CDB")); + fDeadMap = dynamic_cast(deadMap->GetObject()); + if (!fDeadMap) { + AliError("Invalid dead map object from CDB"); + return kDeadMap; + } + if (!fDeadMap->Ptr()) { + AliError("Empty dead map object from CDB"); + return kDeadMap; + } + return 0; +} + +//__________________________________________________________________ +UShort_t +AliFMDParameters::InitZeroSuppression(AliFMDPreprocessor* pp) +{ + // + // Initialize zero suppression thresholds. Try to get them from CDB + // + // Parameters: + // pp Pre-processor if called from shuttle + // + AliCDBEntry* zeroSup = GetEntry(fgkZeroSuppression, pp); + if (!zeroSup) return kZeroSuppression; + + AliFMDDebug(5, ("Got zero suppression from CDB")); + fZeroSuppression = + dynamic_cast(zeroSup->GetObject()); + if (!fZeroSuppression) { + AliError("Invalid zero suppression object from CDB"); + return kZeroSuppression; + } + if (!fZeroSuppression->Ptr()) { + AliWarningF("Empty zero suppression object from CDB, assuming %d", + fFixedZeroSuppression); + AliCDBManager* cdbMan = AliCDBManager::Instance(); + if(!cdbMan || !cdbMan->GetCacheFlag()) + delete fZeroSuppression; + fZeroSuppression = 0; + } + return 0; +} + +//__________________________________________________________________ +UShort_t +AliFMDParameters::InitSampleRate(AliFMDPreprocessor* pp) +{ + // + // Initialize sample rates. Try to get them from CDB + // + // Parameters: + // pp Pre-processor if called from shuttle + // + AliCDBEntry* sampRat = GetEntry(fgkSampleRate, pp); + if (!sampRat) return kSampleRate; + + AliFMDDebug(5, ("Got zero suppression from CDB")); + fSampleRate = dynamic_cast(sampRat->GetObject()); + if (!fSampleRate) { + AliError("Invalid sample rate object from CDB"); + return kSampleRate; + } + if (!fSampleRate->Rates().Ptr()) { + AliError("empty sample rate object from CDB"); + return kSampleRate; + } + return 0; +} + +//__________________________________________________________________ +UShort_t +AliFMDParameters::InitAltroMap(AliFMDPreprocessor* pp) +{ + // + // Initialize hardware map. Try to get it from CDB + // + // Parameters: + // pp Pre-processor if called from shuttle + // + if (fAltroMap) { + delete fAltroMap; + fAltroMap = 0; + } + AliCDBEntry* hwMap = GetEntry(fgkAltroMap, pp, kFALSE); + if (hwMap) { + AliFMDDebug(5, ("Got ALTRO map from CDB")); + fAltroMap = dynamic_cast(hwMap->GetObject()); + } + if (!fAltroMap) { + AliError("Invalid ALTRO map object from CDB"); + fAltroMap = new AliFMDAltroMapping; + // return kAltroMap; + } + return 0; +} + +//__________________________________________________________________ +UShort_t +AliFMDParameters::InitStripRange(AliFMDPreprocessor* pp) +{ + // + // Initialize strip range. Try to get it from CDB + // + // Parameters: + // pp Pre-processor if called from shuttle + // + AliCDBEntry* range = GetEntry(fgkStripRange, pp); + if (!range) return kStripRange; + + AliFMDDebug(5, ("Got strip range from CDB")); + fStripRange = dynamic_cast(range->GetObject()); + + if (!fStripRange) { + AliError("Invalid strip range object from CDB"); + return kStripRange; + } + if (!fStripRange->Ranges().Ptr()) { + AliError("Empty strip range object from CDB"); + return kStripRange; + } + return 0; +} + + +//__________________________________________________________________ +Float_t +AliFMDParameters::GetThreshold() const +{ + // + // Get the threshold in the pulser gain + // + // + // Return: + // Threshold from pulser + // + if (!fPulseGain) return fFixedThreshold; + return fPulseGain->Threshold(); +} + +//__________________________________________________________________ +Float_t +AliFMDParameters::GetPulseGain(UShort_t detector, Char_t ring, + UShort_t sector, UShort_t strip) const +{ + // + // Gain of pre-amp. for strip, sector, ring, detector + // + // For simulations this is normally set to + // + // @f[ + // \frac{\mbox{VA1_MIP_Range}{\mbox{ALTRO_channel_size}}\mbox{MIP_Energy_Loss} + // @f] + // + // + // Parameters: + // detector Detector # (1-3) + // ring Ring ID ('I' or 'O') + // sector Sector number (0-39) + // strip Strip number (0-511) + // + // Return: + // Gain of pre-amp. + // + if (!fPulseGain) { + if (fFixedPulseGain <= 0) + fFixedPulseGain = fVA1MipRange * GetEdepMip() / fAltroChannelSize; + return fFixedPulseGain; + } + AliFMDDebug(50, ("pulse gain for FMD%d%c[%2d,%3d]=%f", + detector, ring, sector, strip, + fPulseGain->Value(detector, ring, sector, strip))); + return fPulseGain->Value(detector, ring, sector, strip); +} + +//__________________________________________________________________ +Bool_t +AliFMDParameters::IsDead(UShort_t detector, Char_t ring, + UShort_t sector, UShort_t strip) const +{ + // + // Whether the strip is considered dead + // + // Parameters: + // detector Detector # (1-3) + // ring Ring ID ('I' or 'O') + // sector Sector number (0-39) + // strip Strip number (0-511) + // + // Return: + // @c true if the strip is considered dead, @c false if it's + // OK. + // + if (!fDeadMap) return kFALSE; + AliFMDDebug(50, ("Dead for FMD%d%c[%2d,%3d]=%s", + detector, ring, sector, strip, + fDeadMap->operator()(detector, ring, sector, strip) ? + "no" : "yes")); + return fDeadMap->operator()(detector, ring, sector, strip); +} + +//__________________________________________________________________ +UShort_t +AliFMDParameters::GetZeroSuppression(UShort_t detector, Char_t ring, + UShort_t sector, UShort_t strip) const +{ + // + // zero suppression threshold (in ADC counts) + // + // Parameters: + // detector Detector # (1-3) + // ring Ring ID ('I' or 'O') + // sector Sector number (0-39) + // strip Strip number (0-511) + // + // Return: + // zero suppression threshold (in ADC counts) + // + if (!fZeroSuppression) return fFixedZeroSuppression; + + // In case of empty zero suppression objects. + if (!fZeroSuppression->Ptr() || + fZeroSuppression->MaxIndex() <= 0) return fFixedZeroSuppression; + + // Need to map strip to ALTRO chip. + AliFMDDebug(50, ("zero sup. for FMD%d%c[%2d,%3d]=%d", + detector, ring, sector, strip, + fZeroSuppression->operator()(detector, ring, + sector, strip))); + return fZeroSuppression->operator()(detector, ring, sector, strip/128); +} + +//__________________________________________________________________ +UShort_t +AliFMDParameters::GetSampleRate(UShort_t det, Char_t ring, UShort_t sector, + UShort_t str) const +{ + // + // Get the sampling rate + // + // Parameters: + // detector Detector # (1-3) + // ring Ring ID ('I' or 'O') + // sector Sector number (0-39) + // strip Strip number (0-511) + // + // Return: + // The sampling rate + // + if (!fSampleRate) return fFixedSampleRate; + // Need to map sector to digitizier card. + UInt_t ret = fSampleRate->Rate(det, ring, sector, str); + AliFMDDebug(50, ("Sample rate for FMD%d%c[%2d,%3d]=%d", + det, ring, sector, str, ret)); + return ret; +} + +//__________________________________________________________________ +UShort_t +AliFMDParameters::GetMinStrip(UShort_t det, Char_t ring, UShort_t sector, + UShort_t str) const +{ + // + // Get the minimum strip in the read-out range + // + // Parameters: + // detector Detector # (1-3) + // ring Ring ID ('I' or 'O') + // sector Sector number (0-39) + // strip Strip number (0-511) + // + // Return: + // Minimum strip + // + if (!fStripRange) return fFixedMinStrip; + // Need to map sector to digitizier card. + UInt_t ret = fStripRange->Min(det, ring, sector, str); + AliFMDDebug(50, ("Min strip # for FMD%d%c[%2d,%3d]=%d", + det, ring, sector, str, ret)); + return ret; } +//__________________________________________________________________ +UShort_t +AliFMDParameters::GetMaxStrip(UShort_t det, Char_t ring, UShort_t sector, + UShort_t str) const +{ + // + // Get the maximum strip in the read-out range + // + // Parameters: + // detector Detector # (1-3) + // ring Ring ID ('I' or 'O') + // sector Sector number (0-39) + // strip Strip number (0-511) + // + // Return: + // Maximum strip + // + if (!fStripRange) return fFixedMaxStrip; + // Need to map sector to digitizier card. + UInt_t ret = fStripRange->Max(det, ring, sector, str); + AliFMDDebug(50, ("Max strip # for FMD%d%c[%2d,%3d]=%d", + det, ring, sector, str, ret)); + return ret; +} + +//__________________________________________________________________ +Float_t +AliFMDParameters::GetPedestal(UShort_t detector, Char_t ring, + UShort_t sector, UShort_t strip) const +{ + // + // Get mean of pedestal + // + // Parameters: + // detector Detector # (1-3) + // ring Ring ID ('I' or 'O') + // sector Sector number (0-39) + // strip Strip number (0-511) + // + // Return: + // Mean of pedestal + // + if (!fPedestal) return fFixedPedestal; + AliFMDDebug(50, ("pedestal for FMD%d%c[%2d,%3d]=%f", + detector, ring, sector, strip, + fPedestal->Value(detector, ring, sector, strip))); + return fPedestal->Value(detector, ring, sector, strip); +} + +//__________________________________________________________________ +Float_t +AliFMDParameters::GetPedestalWidth(UShort_t detector, Char_t ring, + UShort_t sector, UShort_t strip) const +{ + // + // Width of pedestal + // + // Parameters: + // detector Detector # (1-3) + // ring Ring ID ('I' or 'O') + // sector Sector number (0-39) + // strip Strip number (0-511) + // + // Return: + // Width of pedestal + // + if (!fPedestal) return fFixedPedestalWidth; + AliFMDDebug(50, ("pedetal width for FMD%d%c[%2d,%3d]=%f", + detector, ring, sector, strip, + fPedestal->Width(detector, ring, sector, strip))); + return fPedestal->Width(detector, ring, sector, strip); +} + +//__________________________________________________________________ +AliFMDAltroMapping* +AliFMDParameters::GetAltroMap() const +{ + // + // Get the map that translates hardware to detector coordinates + // + // Return: + // Get the map that translates hardware to detector + // coordinates + // + return fAltroMap; +} + + +//____________________________________________________________________ +Bool_t +AliFMDParameters::Hardware2Detector(UShort_t ddl, UShort_t addr, + UShort_t timebin, + UShort_t& det, Char_t& ring, + UShort_t& sec, Short_t& str, + UShort_t& sam) const +{ + // + // Map a hardware address into a detector index. + // + // Parameters: + // ddl Hardware DDL number + // addr Hardware address. + // timebin Timebin + // det On return, the detector # + // ring On return, the ring ID + // sec On return, the sector # + // str On return, the base of strip # + // sam On return, the sample number for this strip + // + // Return: + // @c true on success, false otherwise + // + if (!fAltroMap) return kFALSE; + UShort_t board, chip, chan; + fAltroMap->ChannelAddress(addr, board, chip, chan); + return Hardware2Detector(ddl,board,chip,chan,timebin,det,ring,sec,str,sam); +} +//____________________________________________________________________ +Bool_t +AliFMDParameters::Hardware2Detector(UShort_t ddl, UShort_t board, + UShort_t chip, UShort_t chan, + UShort_t timebin, + UShort_t& det, Char_t& ring, + UShort_t& sec, Short_t& str, + UShort_t& sam) const +{ + // + // Map a hardware address into a detector index. + // + // Parameters: + // ddl Hardware DDL number + // board FEC number + // altro ALTRO number + // channel Channel number + // timebin Timebin + // det On return, the detector # + // ring On return, the ring ID + // sec On return, the sector # + // str On return, the base of strip # + // sam On return, the sample number for this strip + // + // Return: + // @c true on success, false otherwise + // + if (!fAltroMap) { + AliFMDDebug(1, ("No ALTRO map available")); + return kFALSE; + } + if (fAltroMap->DDL2Detector(ddl) < 0) { + AliFMDDebug(1, ("Invalid DDL number %d", ddl)); + return kFALSE; + } + det = fAltroMap->DDL2Detector(ddl); + Short_t stripBase = 0; + if (!fAltroMap->Channel2StripBase(board,chip,chan, ring, sec, stripBase)) { + AliFMDDebug(1, ("Failed to translate " + "%d/0x%02x/0x%x/0x%x/%04d -> " + "FMD%d%c[%2d,%3d] to detector", + ddl, board, chip, chan, timebin, + det, ring, sec, stripBase)); + return kFALSE; + } + UShort_t preSamples = GetPreSamples(det, ring, sec, stripBase); + UShort_t sampleRate = GetSampleRate(det, ring, sec, stripBase); + Short_t stripOff = 0; + fAltroMap->Timebin2Strip(sec, timebin, preSamples, sampleRate, stripOff, sam); + str = stripBase + stripOff; + AliFMDDebug(50, ("%d/0x%02x/0x%x/0x%x/%04d -> FMD%d%c[%02d,%03d]-%d" + " (pre=%2d, rate=%d)", + ddl, board, chip, chan, timebin, + det, ring, sec, str, sam, preSamples, sampleRate)); + return kTRUE; +} + + +//____________________________________________________________________ +Bool_t +AliFMDParameters::Detector2Hardware(UShort_t det, Char_t ring, + UShort_t sec, UShort_t str, + UShort_t sam, + UShort_t& ddl, UShort_t& board, + UShort_t& altro, UShort_t& channel, + UShort_t& timebin) const +{ + // + // Map a detector index into a hardware address. + // + // Parameters: + // det The detector # + // ring The ring ID + // sec The sector # + // str The strip # + // sam The sample number + // ddl On return, hardware DDL number + // board On return, the FEC board address (local to DDL) + // altro On return, the ALTRO number (local to FEC) + // channel On return, the channel number (local to ALTRO) + // timebin On return, the timebin number (local to ALTRO) + // + // Return: + // @c true on success, false otherwise + // + if (!fAltroMap) { + AliFMDDebug(1, ("No ALTRO map available")); + return kFALSE; + } + UShort_t preSamples = GetPreSamples(det, ring, sec, str); + UShort_t sampleRate = GetSampleRate(det, ring, sec, str); + UShort_t strip = str - GetMinStrip(det,ring,sec,str); + return fAltroMap->Detector2Hardware(det, ring, sec, strip, sam, + preSamples, sampleRate, + ddl, board, altro, channel, timebin); +} + + + +//____________________________________________________________________ +Bool_t +AliFMDParameters::Detector2Hardware(UShort_t det, Char_t ring, + UShort_t sec, UShort_t str, + UShort_t sam, + UShort_t& ddl, UShort_t& addr, + UShort_t& timebin) const +{ + // + // Map a detector index into a hardware address. + // + // Parameters: + // det The detector # + // ring The ring ID + // sec The sector # + // str The strip # + // sam The sample number + // ddl On return, hardware DDL number + // addr On return, hardware address. + // timebin On return, the timebin number (local to ALTRO) + // + // Return: + // @c true on success, false otherwise + // + if (!fAltroMap) return kFALSE; + UShort_t preSamples = GetPreSamples(det, ring, sec, str); + UShort_t sampleRate = GetSampleRate(det, ring, sec, str); + UShort_t strip = str - GetMinStrip(det,ring,sec,str); + return fAltroMap->Detector2Hardware(det, ring, sec, strip, sam, + preSamples, sampleRate, + ddl, addr, timebin); +} //__________________________________________________________________ Float_t AliFMDParameters::GetEdepMip() const { - // Get energy deposited by a MIP in the silicon sensors - AliFMDGeometry* fmd = AliFMDGeometry::Instance(); - return (fSiDeDxMip - * fmd->GetRing('I')->GetSiThickness() - * fmd->GetSiDensity()); + // + // Return: + // The average energy deposited by one MIP + // + if (fEdepMip <= 0){ + AliFMDGeometry* fmd = AliFMDGeometry::Instance(); + fEdepMip = (fkSiDeDxMip + * fmd->GetRing('I')->GetSiThickness() + * fmd->GetSiDensity()); + } + return fEdepMip; } - +//____________________________________________________________________ +Float_t +AliFMDParameters::GetDACPerMIP() const +{ + // + // This is the conversion from Digital-to-Analog-Converter setting + // to the number of MIPs. The number was measured in the NBI lab during + // August 2008. + // + // Return: + // The conversion factor from DAC to ADC + // + return 29.67; + +} + //____________________________________________________________________ // // EOF