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