From 5515605e0bdb2ba596fa2e1adcdb8f25900bdb0b Mon Sep 17 00:00:00 2001 From: Alexandru Bercuci <abercuci@niham.nipne.ro> Date: Thu, 11 May 2023 11:46:20 +0300 Subject: [PATCH] add masking for silent FEE channels at the level of ASIC parameter definition. Details include: - global access to the masking status (CbmTrdModuleAbstract) - implementation of channel masking (CbmTrdParFasp) - updates in the R/W of FASP parameters (CbmTrdParSetAsic) - documentation for the ASIC param class (bmTrdParAsic.h) - online monitoring of mask/working channels (CbmTrdUnpackFaspMonitor) --- core/detectors/trd/CbmTrdModuleAbstract.cxx | 12 ++++ core/detectors/trd/CbmTrdModuleAbstract.h | 5 ++ core/detectors/trd/CbmTrdParAsic.h | 1 + core/detectors/trd/CbmTrdParFasp.cxx | 45 ++++++++++++--- core/detectors/trd/CbmTrdParFasp.h | 14 ++++- core/detectors/trd/CbmTrdParSetAsic.cxx | 34 +++++------ core/detectors/trd/CbmTrdParSetAsic.h | 56 ++++++++++++++++++- .../trd/unpack/CbmTrdUnpackFaspMonitor.cxx | 36 ++++++++++++ .../trd/unpack/CbmTrdUnpackFaspMonitor.h | 3 + 9 files changed, 178 insertions(+), 28 deletions(-) diff --git a/core/detectors/trd/CbmTrdModuleAbstract.cxx b/core/detectors/trd/CbmTrdModuleAbstract.cxx index 0230771725..63c7f1c182 100644 --- a/core/detectors/trd/CbmTrdModuleAbstract.cxx +++ b/core/detectors/trd/CbmTrdModuleAbstract.cxx @@ -3,6 +3,9 @@ Authors: Florian Uhlig [committer], Alexandru Bercuci */ #include "CbmTrdModuleAbstract.h" +#include "CbmTrdParAsic.h" + +#include <Logger.h> //_______________________________________________________________________________ CbmTrdModuleAbstract::CbmTrdModuleAbstract() @@ -40,6 +43,15 @@ CbmTrdModuleAbstract::~CbmTrdModuleAbstract() if (fAsicPar) delete fAsicPar; } +//_______________________________________________________________________________ +bool CbmTrdModuleAbstract::IsChannelMasked(int ch) const +{ + if (!fAsicPar) return false; + const CbmTrdParAsic *p = fAsicPar->GetAsicPar(ch); + if (!p) return false; + return p->IsChannelMasked(ch); +} + //_______________________________________________________________________________ void CbmTrdModuleAbstract::LocalToMaster(Double_t in[3], Double_t out[3]) { diff --git a/core/detectors/trd/CbmTrdModuleAbstract.h b/core/detectors/trd/CbmTrdModuleAbstract.h index c384e56d73..3a04a3bed8 100644 --- a/core/detectors/trd/CbmTrdModuleAbstract.h +++ b/core/detectors/trd/CbmTrdModuleAbstract.h @@ -73,6 +73,11 @@ public: */ bool Has2dPadPlane() const { return TESTBIT(fModConfig, eCbmTrdModuleDef::kTrd2d); } + /** \brief Inquire the ASIC par set + * \return true for actively masked channel + */ + bool IsChannelMasked(int ch) const; + virtual void LocalToMaster(Double_t in[3], Double_t out[3]); virtual void SetAsicPar(CbmTrdParSetAsic* p = nullptr) { fAsicPar = p; } diff --git a/core/detectors/trd/CbmTrdParAsic.h b/core/detectors/trd/CbmTrdParAsic.h index d8395bb14f..a56886293a 100644 --- a/core/detectors/trd/CbmTrdParAsic.h +++ b/core/detectors/trd/CbmTrdParAsic.h @@ -45,6 +45,7 @@ public: virtual Int_t GetNchannels() const = 0; virtual Int_t GetFebGrouping() const { return fFebGrouping; } virtual std::vector<Int_t> GetChannelAddresses() const { return fChannelAddresses; } + virtual bool IsChannelMasked(int) const { return false; } virtual void LoadParams(FairParamList*) { ; } virtual void Print(Option_t* opt = "") const; /** \brief Query ASIC for specific pad address diff --git a/core/detectors/trd/CbmTrdParFasp.cxx b/core/detectors/trd/CbmTrdParFasp.cxx index aff68e2723..609e845a06 100644 --- a/core/detectors/trd/CbmTrdParFasp.cxx +++ b/core/detectors/trd/CbmTrdParFasp.cxx @@ -38,6 +38,13 @@ const CbmTrdParFaspChannel* CbmTrdParFasp::GetChannel(Int_t ch_address) const return &fCalib[ch_address]; } +//___________________________________________________________________ +bool CbmTrdParFasp::IsChannelMasked(int ch_address) const +{ + if (ch_address < 0 || ch_address >= NFASPCH) return false; + return fCalib[ch_address].IsMasked(); +} + //___________________________________________________________________ void CbmTrdParFasp::LoadParams(FairParamList* l) { @@ -62,16 +69,16 @@ void CbmTrdParFasp::LoadParams(FairParamList* l) fCalib[ich].fMinDelaySignal = value[ich]; } -void CbmTrdParFasp::LoadParams(TArrayI& valArray, Int_t iAsic) +//___________________________________________________________________ +void CbmTrdParFasp::LoadParams(int* valArray) { - // Where does the asic info start in large array - Int_t offset = iAsic * (1 + NFASPCH * 4); - // Int_t asicAddress = valArray[ offset++ ]; - offset++; + printf("CbmTrdParFasp::LoadParams(%d)\n", fAddress); + int offset(0); + SetChannelMask(valArray[offset++]); for (Int_t ich(0); ich < NFASPCH; ich++) { - Int_t pair = ich % 2; // TODO pairing should be set from the external parameters - SetChannelAddress(valArray[offset++]); - fCalib[ich].SetPairing(pair); + int chAddress = valArray[offset++]; + SetChannelAddress(abs(chAddress)); + fCalib[ich].SetPairing(bool(chAddress>0)); } for (Int_t ich(0); ich < NFASPCH; ich++) { fCalib[ich].fPileUpTime = valArray[offset++]; @@ -107,6 +114,26 @@ Bool_t CbmTrdParFasp::SetCalibParameters(Int_t ch, Double_t const* par) return kTRUE; } +//___________________________________________________________________ +void CbmTrdParFasp::SetChannelMask(uint32_t mask) +{ + for (Int_t ich(0); ich < NFASPCH; ich++) { + bool on = !bool((mask>>ich)&0x1); + fCalib[ich].SetMask(on); + } +} + +//___________________________________________________________________ +uint32_t CbmTrdParFasp::GetChannelMask() const +{ + uint32_t mask(0); + for (Int_t ich(0); ich < NFASPCH; ich++) { + if(!fCalib[ich].IsMasked()) mask |= 0x1; + mask <<= 1; + } + return mask; +} + //___________________________________________________________________ void CbmTrdParFasp::Print(Option_t* opt) const { @@ -133,7 +160,7 @@ CbmTrdParFaspChannel::CbmTrdParFaspChannel(Int_t pup, Int_t ft, Int_t thr, Int_t //___________________________________________________________________ void CbmTrdParFaspChannel::Print(Option_t* /*opt*/) const { - printf("[%c]; CALIB { PUT[ns]=%3d FT[clk]=%2d THR[ADC]=%4d MDS[ADC]=%4d }\n", (HasPairingR() ? 'R' : 'T'), + printf("[%c]; MASK{%c}; CALIB{ PUT[ns]=%3d FT[clk]=%2d THR[ADC]=%4d MDS[ADC]=%4d }\n", (HasPairingR() ? 'R' : 'T'), (IsMasked() ? 'X' : ' '), fPileUpTime, fFlatTop, fThreshold, fMinDelaySignal); } diff --git a/core/detectors/trd/CbmTrdParFasp.h b/core/detectors/trd/CbmTrdParFasp.h index 9e023c0749..1734d3c778 100644 --- a/core/detectors/trd/CbmTrdParFasp.h +++ b/core/detectors/trd/CbmTrdParFasp.h @@ -9,6 +9,9 @@ #define NCROBMOD 5 #define NFASPCROB NFASPMOD / NCROBMOD #define NFASPCH 16 +// The size of the parameter translation is calculated as follows: +// size = detId + chMask + NFASPCH*(chAddress + pileUp + threshold + delay) +#define NFASPPARS 2 + 4 * NFASPCH #define FASP_EPOCH_LENGTH 128 @@ -33,6 +36,7 @@ public: enum CbmTrdParFaspChannelDef { kPair = 0 //< pad pairing type definition see SetPairing() + ,kMask = 1 //< pad masking. See SetMask() }; /** \brief Parametrization of a FASP channel based on CADENCE simulations from 12.01.2018 and * parabolic parametrization of dt(signal). @@ -48,12 +52,15 @@ public: /** \brief Query pad pairing type.*/ Bool_t HasPairingR() const { return TESTBIT(fConfig, kPair); } Bool_t HasPairingT() const { return !TESTBIT(fConfig, kPair); } + bool IsMasked() const { return TESTBIT(fConfig, kMask); } void Print(Option_t* opt = "") const; /** \brief Specify pad pairing type. *\param[in] rect if rect=kTRUE rectangular pairing; tilt otherwise */ void SetPairing(Bool_t rect) { rect ? SETBIT(fConfig, kPair) : CLRBIT(fConfig, kPair); } + /** \brief Mask channel for processing.*/ + void SetMask(Bool_t set) { set ? SETBIT(fConfig, kMask) : CLRBIT(fConfig, kMask); } protected: UShort_t fPileUpTime; ///< Signal formation time in ns @@ -83,19 +90,22 @@ public: { return ((ich < 0 || ich >= GetNchannels()) ? 0 : fChannelAddresses[ich]); } + virtual uint32_t GetChannelMask() const; + virtual bool IsChannelMasked(int ch) const; Int_t GetPadAddress(Int_t ich) const { return 0.5 * GetChannelAddress(ich); } Double_t GetSizeX() const { return fgSizeX; } Double_t GetSizeY() const { return fgSizeY; } Double_t GetSizeZ() const { return fgSizeZ; } virtual void LoadParams(FairParamList* l); - void LoadParams(TArrayI&, Int_t); + /** \brief Load ASIC parameters from param file. Called from e.g. CbmTrdParSetAsic*/ + void LoadParams(int* vals); virtual void Print(Option_t* opt = "") const; /** \brief Load FASP calibration parameters for a specific channel *\param ch Address of the channel inside FASP *\param par pointer to the list of parameters */ virtual Bool_t SetCalibParameters(Int_t ch, Double_t const* par); - + virtual void SetChannelMask(uint32_t mask); private: static Double_t fgSizeX; ///< FASP half size in x [cm] static Double_t fgSizeY; ///< FASP half size in y [cm] diff --git a/core/detectors/trd/CbmTrdParSetAsic.cxx b/core/detectors/trd/CbmTrdParSetAsic.cxx index 033aa06fe7..29884ffe4e 100644 --- a/core/detectors/trd/CbmTrdParSetAsic.cxx +++ b/core/detectors/trd/CbmTrdParSetAsic.cxx @@ -4,6 +4,7 @@ #include "CbmTrdParSetAsic.h" +#include "CbmTrdDigi.h" // for eCbmTrdAsicType #include "CbmTrdParAsic.h" // for CbmTrdParAsic #include "CbmTrdParFasp.h" // for CbmTrdParFasp, NFASPCH, CbmTrdParFasp... #include "CbmTrdParMod.h" // for CbmTrdParMod @@ -14,7 +15,10 @@ #include <TArrayI.h> // for TArrayI #include <TGenericClassInfo.h> // for TGenericClassInfo +#include <TObjArray.h> +#include <TObjString.h> #include <TString.h> // for Form +#include <TSystem.h> #include <utility> // for pair @@ -79,19 +83,18 @@ Bool_t CbmTrdParSetAsic::getParams(FairParamList* l) new CbmTrdParSetAsic(GetName(), Form("%s for Module %d", GetTitle(), moduleId[i]) /*, GetContext()*/); // only for FASP if (9 == typeAsic[i]) { - Int_t sizePerFasp = 1 + NFASPCH * 4; - Int_t maxValues = maxNrAsics * (sizePerFasp); + Int_t maxValues = maxNrAsics * (NFASPPARS); TArrayI values(maxValues); if (!l->fill(Form("FaspInfo - Module %d", moduleId[i]), &values)) continue; for (Int_t iasic = 0; iasic < nAsic[i]; iasic++) { - Int_t offset = iasic * (sizePerFasp); - address = values[offset + 0]; + Int_t offset = iasic * (NFASPPARS); + address = values[offset++]; if (address == moduleId[i] * 1000 + 999) continue; asic = new CbmTrdParFasp(address); - static_cast<CbmTrdParFasp*>(asic)->LoadParams(values, iasic); + static_cast<CbmTrdParFasp*>(asic)->LoadParams(&(values.GetArray()[offset])); fModPar[moduleId[i]]->SetAsicPar(address, asic); } - fModPar[moduleId[i]]->SetAsicType(1); + fModPar[moduleId[i]]->SetAsicType((int)CbmTrdDigi::eCbmTrdAsicType::kFASP); } else { Int_t maxValues = maxNrAsics * (5 + NSPADICCH); @@ -111,7 +114,7 @@ Bool_t CbmTrdParSetAsic::getParams(FairParamList* l) asic->SetChannelAddresses(addresses); fModPar[moduleId[i]]->SetAsicPar(address, asic); } - fModPar[moduleId[i]]->SetAsicType(0); + fModPar[moduleId[i]]->SetAsicType((int)CbmTrdDigi::eCbmTrdAsicType::kSPADIC); } } return kTRUE; @@ -177,29 +180,28 @@ void CbmTrdParSetAsic::putParams(FairParamList* l) l->add(Form("SpadicInfo - Module %d", moduleId[i]), asicInfo); } if (mod->fModuleMap.begin()->second->IsA() == CbmTrdParFasp::Class()) { - - Int_t sizePerFasp = 1 + NFASPCH * 4; - Int_t fullSize = nAsic[i] * sizePerFasp; + Int_t fullSize = nAsic[i] * NFASPPARS; TArrayI asicInfo(fullSize); iAsicNr = 0; for (auto iModuleIt : mod->fModuleMap) { - int offset = iAsicNr * sizePerFasp; - asicInfo[offset] = iModuleIt.first; + int offset = iAsicNr * NFASPPARS; + asicInfo[offset++] = iModuleIt.first; CbmTrdParFasp* fasp = (CbmTrdParFasp*) iModuleIt.second; + asicInfo[offset++] = fasp->GetChannelMask(); Int_t ich(0); for (auto chAddress : fasp->GetChannelAddresses()) { - asicInfo[offset + 1 + ich] = chAddress; + asicInfo[offset + ich] = chAddress; const CbmTrdParFaspChannel* ch = fasp->GetChannel(ich); if (!ch) { LOG(info) << "Missing calib for Fasp[" << offset << "] pad " << chAddress; ich++; continue; } - asicInfo[offset + 1 + (1 * NFASPCH) + ich] = ch->GetPileUpTime(); - asicInfo[offset + 1 + (2 * NFASPCH) + ich] = ch->GetThreshold(); - asicInfo[offset + 1 + (3 * NFASPCH) + ich] = ch->GetMinDelaySignal(); + asicInfo[offset + (1 * NFASPCH) + ich] = ch->GetPileUpTime(); + asicInfo[offset + (2 * NFASPCH) + ich] = ch->GetThreshold(); + asicInfo[offset + (3 * NFASPCH) + ich] = ch->GetMinDelaySignal(); ich++; } iAsicNr++; diff --git a/core/detectors/trd/CbmTrdParSetAsic.h b/core/detectors/trd/CbmTrdParSetAsic.h index 8e7475a7fc..3efa40c456 100644 --- a/core/detectors/trd/CbmTrdParSetAsic.h +++ b/core/detectors/trd/CbmTrdParSetAsic.h @@ -18,6 +18,12 @@ class FairParamList; /** * \brief Describe TRD module ASIC settings (electronic gain, delays, etc) + * + * The following concepts are used : + * - DAQ id : unique id of an ASIC composed of the format modId*1000+asicId. + * - modId : is calculated according to the CbmTrdAddress::GetModuleId(). + * - asicId : uniquely identify the ASICs in one module. + * - chAddress : identify the read-out pad(s) connected to the ASIC. In the case of FASP it distinguish between R and T pairing **/ class CbmTrdParSetAsic : public CbmTrdParSet { public: @@ -30,22 +36,70 @@ public: /** \brief Reset all parameters **/ virtual void clear() { ; } + /** \brief Add ASIC par to the current module + * It applies to the list of ASICs. + * \param mod ASIC par (FASP or SPADIC) + */ virtual void addParam(CbmTrdParMod* mod); + /** \brief Add Module list of ASIC par to the setup list + * It applies to the list of lists. + * \param module list + */ void AddParameters(CbmTrdParSetAsic*); // (VF) renamed to avoid shadowing of virtual method + + /** \brief Build the ASICs par for the current module from the info stored in the param file + * It applies to the list of ASICs. + * \param module ASICs par (FASP or SPADIC) + */ Bool_t getParams(FairParamList*); + /** \brief Store the ASICs par info for the current module into the param file + * It applies to the list of ASICs. + * \param module ASICs par (FASP or SPADIC) + */ void putParams(FairParamList*); + + /** \brief Query the ASICs in the module for their DAQ address. + * It applies to the list of ASICs. + * Returns the list of id of the ASICs within the module. + */ virtual void GetAsicAddresses(std::vector<Int_t>* a) const; /** \brief Look for the ASIC which operates on a specific channel - *\param chAddress Address of the channel + * It applies to the list of ASICs. + *\param chAddress Pad address of the channel *\return id of the ASIC operating on the channel. -1 in case of failure */ virtual Int_t GetAsicAddress(Int_t chAddress) const; + /** \brief Look for the ASIC parameters of a given DAQ id + * It applies to the list of ASICs. + * \param address ASIC address from DAQ + * \return A read-only pointer to the parameters + */ virtual const CbmTrdParAsic* GetAsicPar(Int_t address) const { return (CbmTrdParAsic*) GetModulePar(address); } + /** \brief Look for the ASIC parameters of a given DAQ id + * It applies to the list of ASICs. + * \param address ASIC address from DAQ + * \return A read-write pointer to the parameters + */ virtual CbmTrdParAsic* GetAsicPar(Int_t address) { return (CbmTrdParAsic*) GetModulePar(address); } + /** \brief Query the type of ASICs in the list + * It applies to the list of ASICs. + */ virtual Int_t GetAsicType() const { return fType; } + /** \brief Returns the set of ASIC pars corresponding to a whole module + * It applies to the list of lists. + * \param detId module Identifier in the CBM geometry + */ virtual const CbmTrdParSet* GetModuleSet(Int_t detId) const; + /** \brief Returns the number of ASICs for the current module + * It applies to the list of ASICs. + */ virtual Int_t GetNofAsics() const { return GetNrOfModules(); } + virtual void Print(Option_t* opt = "") const; + /** \brief Initialize the ASIC parameters for DAQ id + * It applies to the list of ASICs. + * \param address DAQ id of the ASIC in the current module + */ virtual void SetAsicPar(Int_t address, CbmTrdParAsic* p); virtual void SetAsicType(Int_t t) { fType = t; } diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackFaspMonitor.cxx b/reco/detectors/trd/unpack/CbmTrdUnpackFaspMonitor.cxx index e41945bf02..d74a5409f5 100644 --- a/reco/detectors/trd/unpack/CbmTrdUnpackFaspMonitor.cxx +++ b/reco/detectors/trd/unpack/CbmTrdUnpackFaspMonitor.cxx @@ -114,6 +114,34 @@ Bool_t CbmTrdUnpackFaspMonitor::Init() return kTRUE; } +//_________________________________________________________________________________ +void CbmTrdUnpackFaspMonitor::MapMaskedChannels(const CbmTrdParSetAsic *par) +{ + int ncol(-1), modAddress(-1); + std::shared_ptr<TH1> histo = nullptr; + + std::vector<int> faspAddress; + par->GetAsicAddresses(&faspAddress); + for (auto address : faspAddress) { + CbmTrdParFasp* fasp = (CbmTrdParFasp*) par->GetModulePar(address); + + if (modAddress != address / 1000) { + modAddress = address / 1000; + auto modpair = fDigiHistoMap[eDigiHistos::kMap_St]; + if (modpair.find(modAddress) == modpair.end()) continue; + if (!(histo = modpair[modAddress])) continue; + + if (fModuleDef.find(modAddress) == fModuleDef.end()) continue; + ncol = std::get<1>(fModuleDef[modAddress]); + } + for (int ich(0); ich < NFASPCH; ich++) { + const CbmTrdParFaspChannel* faspCh = fasp->GetChannel(ich); + int pad = fasp->GetChannelAddress(ich) / 2, row = pad / ncol, col = pad % ncol; + if (faspCh->IsMasked()) histo->Fill(col + (faspCh->HasPairingR() ? 1 : -1) * 0.25, row); + } + } +} + //_________________________________________________________________________ void CbmTrdUnpackFaspMonitor::addParam(uint32_t madd, const CbmTrdParSetAsic* asics) { @@ -174,6 +202,14 @@ void CbmTrdUnpackFaspMonitor::createHisto(eDigiHistos kHisto) newhisto->SetZTitle("Yield"); break; + case eDigiHistos::kMap_St: + newhisto = std::make_shared<TH2I>(histoname.data(), Form("%s %d", histoname.data(), modId), 2 * ncols, -0.5, + (ncols - 0.5), nrows, -0.5, (nrows - 0.5)); + newhisto->SetXTitle("COL (pad)"); + newhisto->SetYTitle("ROW (pad)"); + newhisto->SetZTitle("Mask"); + break; + case eDigiHistos::kCharge: newhisto = std::make_shared<TH2I>(histoname.data(), Form("%s %d", histoname.data(), modId), 2 * nchs, -0.5, (nchs - 0.5), 4095, 0.5, 4095.5); diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackFaspMonitor.h b/reco/detectors/trd/unpack/CbmTrdUnpackFaspMonitor.h index 3dce9adbdc..80fa9297f4 100644 --- a/reco/detectors/trd/unpack/CbmTrdUnpackFaspMonitor.h +++ b/reco/detectors/trd/unpack/CbmTrdUnpackFaspMonitor.h @@ -70,6 +70,9 @@ public: /** @brief Init all required parameter informations */ Bool_t Init(); + /** @brief Special call for monitoring the masked channel map*/ + void MapMaskedChannels(const CbmTrdParSetAsic *asics); + /** @brief transfer the enums for the histos to be activated to the member vector */ void SetActiveHistos(std::vector<eDigiHistos> vec) { fActiveDigiHistos.swap(vec); } -- GitLab