diff --git a/core/base/CbmDigitize.h b/core/base/CbmDigitize.h index 78a137ee69f263cbf1140d2db5a8529e297fa575..286180bd277626a3caf78a712ce21455930a5143 100644 --- a/core/base/CbmDigitize.h +++ b/core/base/CbmDigitize.h @@ -24,6 +24,7 @@ #include <map> #include <memory> +#include <set> #include <sstream> #include <string> #include <utility> @@ -227,9 +228,11 @@ public: **/ void SendData(Double_t time, Digi* digi, CbmMatch* match = nullptr) { - std::unique_ptr<Digi> tmpDigi(digi); - std::unique_ptr<CbmMatch> tmpMatch(match); - fDaqBuffer.insert(make_pair(time, std::make_pair(std::move(tmpDigi), std::move(tmpMatch)))); + if (IsChannelActive(*digi)) { + std::unique_ptr<Digi> tmpDigi(digi); + std::unique_ptr<CbmMatch> tmpMatch(match); + fDaqBuffer.insert(make_pair(time, std::make_pair(std::move(tmpDigi), std::move(tmpMatch)))); + } } // -------------------------------------------------------------------------- @@ -330,6 +333,19 @@ private: // -------------------------------------------------------------------------- + // -------------------------------------------------------------------------- + /** @brief Test if the channel of a digi object is set active + ** @param digi object + ** @return .true. if the respective channel is active + **/ + bool IsChannelActive(const Digi& digi) + { + if (fInactiveChannels.count(digi.GetAddress())) return false; + return true; + } + // -------------------------------------------------------------------------- + + ClassDef(CbmDigitize, 1); }; diff --git a/core/base/CbmDigitizeBase.cxx b/core/base/CbmDigitizeBase.cxx index 66ef864c968f1fa5e06784966b343aadac0a9ef7..0d56f13c0fd3c29417544912f35203ff37dbb2ed 100644 --- a/core/base/CbmDigitizeBase.cxx +++ b/core/base/CbmDigitizeBase.cxx @@ -16,6 +16,7 @@ #include <TGenericClassInfo.h> // for TGenericClassInfo #include <cassert> // for assert +#include <cstdio> // ----- Default constructor -------------------------------------------- CbmDigitizeBase::CbmDigitizeBase() @@ -75,4 +76,27 @@ void CbmDigitizeBase::GetEventInfo() // -------------------------------------------------------------------------- +// ----- Read list of inactive channels --------------------------------- +std::pair<size_t, bool> CbmDigitizeBase::ReadInactiveChannels() +{ + + if (fInactiveChannelFileName.IsNull()) return std::make_pair(0, true); + + FILE* channelFile = fopen(fInactiveChannelFileName.Data(), "r"); + if (channelFile == nullptr) return std::make_pair(0, false); + + size_t nLines = 0; + uint32_t channel = 0; + while (fscanf(channelFile, "%u", &channel) == 1) { + fInactiveChannels.insert(channel); + nLines++; + } + bool success = feof(channelFile); + + fclose(channelFile); + return std::make_pair(nLines, success); +} +// -------------------------------------------------------------------------- + + ClassImp(CbmDigitizeBase) diff --git a/core/base/CbmDigitizeBase.h b/core/base/CbmDigitizeBase.h index 2b960bb81e779938b067320ce0707ac76eb40f26..a2bca30e4652dfdfd5b2eaa9f4c96e0946b6488b 100644 --- a/core/base/CbmDigitizeBase.h +++ b/core/base/CbmDigitizeBase.h @@ -17,9 +17,12 @@ #include <Rtypes.h> // for THashConsistencyHolder, ClassDef #include <RtypesCore.h> // for Bool_t, Double_t, Int_t, kTRUE, ULong64_t +#include <set> #include <string> // for string + class CbmTimeSlice; + /** @class CbmDigitizeBase ** @brief Abstract base class for CBM digitisation tasks ** @author Volker Friese <v.friese@gsi.de> @@ -152,6 +155,15 @@ public: void SetEventMode(Bool_t choice = kTRUE) { fEventMode = choice; } + /** @brief Set the file containing the list of inactive channels + ** @param fileName Name of file + ** + ** Channels are identified by their CbmAddress. The file must contain a list of addresses, + ** one per line. Comments after the address are allowed if separated by a blank. + **/ + void SetInactiveChannelFile(const char* fileName) { fInactiveChannelFileName = fileName; } + + /** @brief Set production of inter-event noise ** @param Choice If kTRUE, the digitizer will produce noise **/ @@ -159,13 +171,24 @@ public: protected: - Bool_t fEventMode; /// Flag for event-by-event mode - Bool_t fProduceNoise; /// Flag for production of inter-event noise - Bool_t fCreateMatches; /// Flag for creation of links to MC - Int_t fCurrentInput; /// Number of current input - Int_t fCurrentEvent; /// Number of current MC event - Int_t fCurrentMCEntry; /// Number of current MC entry - Double_t fCurrentEventTime; /// Time of current MC event [ns] + Bool_t fEventMode; /// Flag for event-by-event mode + Bool_t fProduceNoise; /// Flag for production of inter-event noise + Bool_t fCreateMatches; /// Flag for creation of links to MC + Int_t fCurrentInput; /// Number of current input + Int_t fCurrentEvent; /// Number of current MC event + Int_t fCurrentMCEntry; /// Number of current MC entry + Double_t fCurrentEventTime; /// Time of current MC event [ns] + TString fInactiveChannelFileName = ""; /// Name of file with inactive channels + std::set<uint32_t> fInactiveChannels = {}; /// Set of inactive channels, indicated by CbmAddress + + /** @brief Read the list of inactive channels from file + ** @param fileName File name + ** @return Number of channels read from file, success of file reading + ** + ** Reading from the file will stop when a read error occurs. In that case, or when the file + ** could not be opened at all, the success flag will be .false. + **/ + virtual std::pair<size_t, bool> ReadInactiveChannels(); private: diff --git a/sim/detectors/sts/CbmStsDigitize.cxx b/sim/detectors/sts/CbmStsDigitize.cxx index 5571246d0c498eefc40644be0ff7cd9884ffcb2f..7778459d33832119131da3cd4f8d047760183163 100644 --- a/sim/detectors/sts/CbmStsDigitize.cxx +++ b/sim/detectors/sts/CbmStsDigitize.cxx @@ -17,6 +17,7 @@ #include <iomanip> #include <iostream> #include <sstream> +#include <tuple> // Includes from ROOT #include "TClonesArray.h" @@ -152,6 +153,9 @@ void CbmStsDigitize::CreateDigi(Int_t address, UShort_t channel, Long64_t time, { assert(time >= 0); + // No action if the channel is marked inactive + if (!IsChannelActiveSts(address, channel)) return; + // Update times of first and last digi fTimeDigiFirst = fNofDigis ? TMath::Min(fTimeDigiFirst, Double_t(time)) : time; fTimeDigiLast = TMath::Max(fTimeDigiLast, Double_t(time)); @@ -334,6 +338,21 @@ InitStatus CbmStsDigitize::Init() // --- Initialise parameters InitParams(); + // --- Read list of inactive channels + if (!fInactiveChannelFileName.IsNull()) { + LOG(info) << GetName() << ": Reading inactive channels from " << fInactiveChannelFileName; + auto result = ReadInactiveChannels(); + if (!result.second) { + LOG(error) << GetName() << ": Error in reading from file! Task will be inactive."; + return kFATAL; + } + LOG(info) << GetName() << ": " << std::get<0>(result) << " lines read from file"; + } + size_t nChanInactive = 0; + for (auto& entry : fInactiveChannelsSts) + nChanInactive += entry.second.size(); + LOG(info) << GetName() << ": " << nChanInactive << " channels set inactive"; + // Instantiate modules UInt_t nModules = InitModules(); LOG(info) << GetName() << ": Created " << nModules << " modules"; @@ -342,7 +361,6 @@ InitStatus CbmStsDigitize::Init() UInt_t nSensors = InitSensors(); LOG(info) << GetName() << ": Created " << nSensors << " sensors"; - // --- Get FairRootManager instance FairRootManager* ioman = FairRootManager::Instance(); assert(ioman); @@ -355,6 +373,7 @@ InitStatus CbmStsDigitize::Init() fTracks = (TClonesArray*) ioman->GetObject("MCTrack"); assert(fTracks); + // --- Register the output branches RegisterOutput(); // --- Screen output @@ -594,6 +613,17 @@ void CbmStsDigitize::InitSetup() // ------------------------------------------------------------------------- +// ----- Check for channel being active -------------------------------- +bool CbmStsDigitize::IsChannelActiveSts(Int_t address, UShort_t channel) +{ + auto it = fInactiveChannelsSts.find(address); + if (it == fInactiveChannelsSts.end()) return true; + if (it->second.count(channel)) return false; + return true; +} +// ------------------------------------------------------------------------- + + // ----- Process the analogue buffers of all modules ------------------- void CbmStsDigitize::ProcessAnalogBuffers(Double_t readoutTime) { @@ -668,6 +698,30 @@ void CbmStsDigitize::ProcessPoint(const CbmStsPoint* point, Double_t eventTime, // ------------------------------------------------------------------------- +// ----- Read list of inactive channels from file ----------------------- +std::pair<size_t, bool> CbmStsDigitize::ReadInactiveChannels() +{ + + if (fInactiveChannelFileName.IsNull()) return std::make_pair(0, true); + + FILE* channelFile = fopen(fInactiveChannelFileName.Data(), "r"); + if (channelFile == nullptr) return std::make_pair(0, false); + + size_t nLines = 0; + uint32_t address = 0; + uint16_t channel = 0; + while (fscanf(channelFile, "%u %hu", &address, &channel) == 2) { + fInactiveChannelsSts[address].insert(channel); + nLines++; + } + bool success = feof(channelFile); + + fclose(channelFile); + return std::make_pair(nLines, success); +} +// ------------------------------------------------------------------------- + + // ----- Private method ReInit ----------------------------------------- InitStatus CbmStsDigitize::ReInit() { diff --git a/sim/detectors/sts/CbmStsDigitize.h b/sim/detectors/sts/CbmStsDigitize.h index 5679ac6cacc7a2649844ca1f7b27fc6c0f2f93d1..a2a104486de949d88043451ee7b6516e1b8a0248 100644 --- a/sim/detectors/sts/CbmStsDigitize.h +++ b/sim/detectors/sts/CbmStsDigitize.h @@ -288,7 +288,7 @@ private: Int_t fNofDigis = 0; ///< Number of created digis in Exec // --- Run counters - Int_t fNofEvents = 0; ///< Total number of procesed events + Int_t fNofEvents = 0; ///< Total number of processed events Double_t fNofPointsProcTot = 0; ///< Total number of processed points Double_t fNofPointsIgnoTot = 0; ///< Total number of ignored points Double_t fNofSignalsFTot = 0; ///< Number of signals on front side @@ -297,6 +297,11 @@ private: Double_t fNofNoiseTot = 0; ///< Total number of noise digis Double_t fTimeTot = 0.; ///< Total execution time + // --- List of inactive channels + // --- We do not use the base class here since STS channels are identified not only by + // --- CbmAddress like in all other detectors, but by address plus channel number. + std::map<Int_t, std::set<UShort_t>> fInactiveChannelsSts = {}; + /** @brief Number of signals in the analogue buffers ** @value nSignals Sum of number of signals in all modules @@ -335,6 +340,17 @@ private: UInt_t InitSensors(); + /** @brief Test if the channel of a digi object is set active + ** @param address CbmStdAddress of module + ** @param channel Channel number in module + ** @return .true. if the respective channel is active + ** + ** We do not use the base class method IsChannelActive(), because unlike for the other detector systems, + ** an STS channel is not identified by the address only, but by address plus channel number. + **/ + bool IsChannelActiveSts(Int_t address, UShort_t channel); + + /** Process the analog buffers of all modules ** @param readoutTime Time of readout [ns] **/ @@ -352,6 +368,21 @@ private: void ProcessPoint(const CbmStsPoint* point, Double_t eventTime, const CbmLink& link); + /** @brief Read the list of inactive channels from file + ** @param fileName File name + ** @return Number of channels read from file, success of file reading + ** + ** This re-implements the respective method from the base class by reading not only the address, + ** but also the channel number from file. The file must contain one line for each channel + ** containing the module address and the channel number, separated by a blank. Comments can + ** follow after the channel number, if separated by a blank. + ** + ** Reading from the file will stop when a read error occurs. In that case, or when the file + ** could not be opened at all, the success flag will be .false. + **/ + std::pair<size_t, bool> ReadInactiveChannels(); + + /** @brief Reset event counters **/ void ResetCounters();