CbmRoot
CbmDigitize.h
Go to the documentation of this file.
1 
6 #ifndef CBMDIGITIZE_H
7 #define CBMDIGITIZE_H 1
8 
9 #include <Rtypes.h> // for THashConsistencyHolder, ClassDef
10 #include <RtypesCore.h> // for Double_t, Bool_t, ULong64_t, kFALSE, kTRUE
11 
12 
13 #include <FairLogger.h> // for LOG
14 #include <FairTask.h>
15 
16 #include <map>
17 #include <memory>
18 #include <sstream>
19 #include <string>
20 #include <utility>
21 
22 #include "CbmDaq.h"
23 #include "CbmDigitizeBase.h"
24 #include "CbmMatch.h"
25 #include "CbmTimeSlice.h"
26 
27 
38 template<class Digi>
39 class CbmDigitize : public CbmDigitizeBase {
40 
41 public:
43  typedef std::pair<std::unique_ptr<Digi>, std::unique_ptr<CbmMatch>> Data;
44 
45 
48 
49 
53  CbmDigitize(const char* name, const char* branchName = "")
54  : CbmDigitizeBase(name), fBranchName(branchName) {};
55 
56 
58  virtual ~CbmDigitize() {};
59 
60 
61  // --------------------------------------------------------------------------
63  Bool_t CheckOutput() {
64  assert(fDigis);
65  if (fDigis->empty()) return kTRUE;
66  Double_t prevTime = fDigis->begin()->GetTime();
67  for (auto it = (fDigis->begin())++; it != fDigis->end(); it++) {
68  if (it->GetTime() < prevTime) {
69  LOG(error) << GetName()
70  << ": CheckBuffer: Found digi at t = " << it->GetTime()
71  << " ns after digi at t = " << prevTime << " ns";
72  return kFALSE;
73  break;
74  }
75  prevTime = it->GetTime();
76  }
77  return kTRUE;
78  }
79  // --------------------------------------------------------------------------
80 
81 
82  // --------------------------------------------------------------------------
84  void ClearOutput() {
85  if (fDigis) fDigis->clear();
86  if (fCreateMatches)
87  if (fMatches != nullptr) fMatches->clear();
88  }
89  // --------------------------------------------------------------------------
90 
91 
92  // --------------------------------------------------------------------------
101  ULong64_t FillTimeSlice(CbmTimeSlice* timeSlice) {
102  return FillTimeSlice(timeSlice, kFALSE, -1.);
103  }
104  // --------------------------------------------------------------------------
105 
106 
107  // --------------------------------------------------------------------------
118  ULong64_t FillTimeSlice(CbmTimeSlice* timeSlice, Double_t fillTime) {
119  return FillTimeSlice(timeSlice, kTRUE, fillTime);
120  }
121  // --------------------------------------------------------------------------
122 
123 
124  // --------------------------------------------------------------------------
128  ULong64_t GetDaqBufferSize() const { return fDaqBuffer.size(); }
129  // --------------------------------------------------------------------------
130 
131 
132  // --------------------------------------------------------------------------
136  std::string GetDaqBufferStatus() const {
137  std::stringstream ss;
138  ss << "Status DAQ buffer: " << GetDaqBufferSize()
139  << " data from t = " << GetDaqBufferTimeFirst() << " to "
140  << GetDaqBufferTimeLast() << " ns";
141  return ss.str();
142  }
143  // --------------------------------------------------------------------------
144 
145 
146  // --------------------------------------------------------------------------
150  Double_t GetDaqBufferTimeFirst() const {
151  if (fDaqBuffer.empty()) return -1.;
152  return fDaqBuffer.begin()->first;
153  }
154  // --------------------------------------------------------------------------
155 
156 
157  // --------------------------------------------------------------------------
161  Double_t GetDaqBufferTimeLast() const {
162  if (fDaqBuffer.empty()) return -1.;
163  return (--fDaqBuffer.end())->first;
164  }
165  // --------------------------------------------------------------------------
166 
167 
168  // --------------------------------------------------------------------------
175  void RegisterOutput() {
176 
177  // --- Get FairRootManager instance
178  FairRootManager* ioman = FairRootManager::Instance();
179  assert(ioman);
180 
181  // --- Digi branch name. If not set otherwise (through constructor), it
182  // --- equals the digi class name minus the leading "Cbm".
183  TString digiBranchName = fBranchName;
184  if (digiBranchName.IsNull()) {
185  TString digiClassName = Digi::GetClassName();
186  if (digiClassName.BeginsWith("Cbm"))
187  digiBranchName = digiClassName(3, digiClassName.Length());
188  } //? No branch name set via constructor
189 
190 
191  // --- Branch for digis
192  fDigis = new std::vector<Digi>();
193  ioman->RegisterAny(
194  digiBranchName.Data(), fDigis, IsOutputBranchPersistent(digiBranchName));
195  LOG(info) << GetName() << ": Registered branch " << digiBranchName;
196 
197  // --- Branch for matches
198  if (fCreateMatches) {
199  TString matchBranchName = digiBranchName + "Match";
200  fMatches = new std::vector<CbmMatch>();
201  ioman->RegisterAny(matchBranchName.Data(),
202  fMatches,
203  IsOutputBranchPersistent(matchBranchName));
204  LOG(info) << GetName() << ": Registered branch " << matchBranchName;
205  }
206  }
207  // --------------------------------------------------------------------------
208 
209 
210  // --------------------------------------------------------------------------
219  void SendData(Digi* digi, CbmMatch* match = nullptr) {
220  std::unique_ptr<Digi> tmpDigi(digi);
221  std::unique_ptr<CbmMatch> tmpMatch(match);
222  fDaqBuffer.insert(
223  make_pair(digi->GetTime(),
224  std::make_pair(std::move(tmpDigi), std::move(tmpMatch))));
225  }
226  // --------------------------------------------------------------------------
227 
228 
229 private:
230  TString fBranchName = "";
231  std::vector<Digi>* fDigis = nullptr;
232  std::vector<CbmMatch>* fMatches = nullptr;
233 
234 
235 private:
239  std::multimap<double, Data> fDaqBuffer;
240 
241 
242  // --------------------------------------------------------------------------
255  ULong64_t
256  FillTimeSlice(CbmTimeSlice* timeSlice, Bool_t checkLimit, Double_t fillTime) {
257 
258  assert(timeSlice);
259  ULong64_t nData = 0;
260  Double_t tMin = timeSlice->GetStartTime();
261  Double_t tMax = timeSlice->GetEndTime();
262  Bool_t checkMinTime = kTRUE;
263  Bool_t checkMaxTime = kTRUE;
264  if (timeSlice->IsRegular()) {
265  if (checkLimit && fillTime < tMax) tMax = fillTime;
266  } else if (timeSlice->IsFlexible() || timeSlice->IsEvent()) {
267  checkMinTime = kFALSE;
268  checkMaxTime = checkLimit;
269  tMax = fillTime;
270  } else {
271  LOG(fatal) << GetName() << ": Unknown time-slice type!";
272  }
273 
274  // This implementation makes use of the fact that the data in the
275  // DAQ buffer are time-sorted.
276  auto it = fDaqBuffer.begin();
277  while (it != fDaqBuffer.end() && ((!checkMaxTime) || it->first < tMax)) {
278 
279  // For regular time-slices, discard digis with negative times.
280  // The first time slice starts at t = 0. All data before are just
281  // not recorded.
282  if (timeSlice->IsRegular() && it->first < 0.) {
283  it++;
284  continue;
285  }
286 
287  // Digi times before the start of the current time slice
288  // should not happen.
289  assert((!checkMinTime) || it->first >= tMin);
290 
291  // TODO: This implementation uses the implicit copy constructor and
292  // manual removal from the source vector. There might be a more
293  // elegant way.
294  assert(fDigis);
295  assert(it->second.first);
296  fDigis->push_back(*(it->second.first));
297  if (fCreateMatches) {
298  assert(fMatches);
299  assert(it->second.second);
300  fMatches->push_back(*(it->second.second));
301  }
302 
303  // Register datum to the time slice header
304  if (fCreateMatches)
305  timeSlice->RegisterData(
306  GetSystemId(), it->first, fMatches->at(fMatches->size() - 1));
307  else
308  timeSlice->RegisterData(GetSystemId(), it->first);
309 
310  nData++;
311  it++;
312  }
313 
314  // Remove the corresponding elements from the buffer
315  fDaqBuffer.erase(fDaqBuffer.begin(), it);
316 
317  return nData;
318  }
319  // --------------------------------------------------------------------------
320 
321 
323 };
324 
325 #endif /* CBMDIGITIZE_H */
CbmDigitizeBase.h
CbmMatch
Definition: CbmMatch.h:22
CbmTimeSlice::IsEvent
Bool_t IsEvent() const
Definition: CbmTimeSlice.h:141
CbmDigitize::~CbmDigitize
virtual ~CbmDigitize()
Destructor.
Definition: CbmDigitize.h:58
CbmDaq.h
CbmTimeSlice::IsRegular
Bool_t IsRegular() const
Definition: CbmTimeSlice.h:153
CbmDigitizeBase::fCreateMatches
Bool_t fCreateMatches
Flag for production of inter-event noise.
Definition: CbmDigitizeBase.h:161
CbmDigitize::fBranchName
TString fBranchName
Output branch name.
Definition: CbmDigitize.h:230
CbmDigitize::fDigis
std::vector< Digi > * fDigis
Definition: CbmDigitize.h:231
CbmTimeSlice::IsFlexible
Bool_t IsFlexible() const
Definition: CbmTimeSlice.h:147
CbmDigitize::GetDaqBufferSize
ULong64_t GetDaqBufferSize() const
Size of DAQ buffer @value Number of data in the DAQ buffer.
Definition: CbmDigitize.h:128
CbmDigitize::CheckOutput
Bool_t CheckOutput()
Check the output for being time-sorted.
Definition: CbmDigitize.h:63
CbmTimeSlice::RegisterData
Bool_t RegisterData(ECbmModuleId system, Double_t time)
Register data to time-slice header.
Definition: CbmTimeSlice.cxx:117
CbmDigitize::ClearOutput
void ClearOutput()
Clear the output arrays.
Definition: CbmDigitize.h:84
CbmTimeSlice::GetStartTime
Double_t GetStartTime() const
Definition: CbmTimeSlice.h:108
CbmMatch.h
CbmDigitize::CbmDigitize
CbmDigitize(const char *name, const char *branchName="")
Constructor with name.
Definition: CbmDigitize.h:53
CbmTimeSlice.h
CbmDigitize::FillTimeSlice
ULong64_t FillTimeSlice(CbmTimeSlice *timeSlice, Double_t fillTime)
Move data from the DaqBuffer into the current time slice.
Definition: CbmDigitize.h:118
CbmTimeSlice::GetEndTime
Double_t GetEndTime() const
Definition: CbmTimeSlice.cxx:94
CbmDigitize::fMatches
std::vector< CbmMatch > * fMatches
Output array (Digi)
Definition: CbmDigitize.h:232
CbmDigitize::fDaqBuffer
std::multimap< double, Data > fDaqBuffer
Output array (CbmMatch)
Definition: CbmDigitize.h:239
CbmDigitize::FillTimeSlice
ULong64_t FillTimeSlice(CbmTimeSlice *timeSlice)
Move data from the DaqBuffer into the current time slice.
Definition: CbmDigitize.h:101
CbmDigitize
Base class template for CBM digitisation tasks.
Definition: CbmDigitize.h:39
CbmDigitize::GetDaqBufferTimeFirst
Double_t GetDaqBufferTimeFirst() const
Time stamp of first data in the DAQ buffer @value Time stamp of first data in the DAQ buffer.
Definition: CbmDigitize.h:150
CbmDigitize::ClassDef
ClassDef(CbmDigitize, 1)
CbmDigitize::CbmDigitize
CbmDigitize()
Default constructor.
Definition: CbmDigitize.h:47
CbmDigitize::SendData
void SendData(Digi *digi, CbmMatch *match=nullptr)
Send a digi and the corresponding match object to the DAQ.
Definition: CbmDigitize.h:219
CbmDigitize::FillTimeSlice
ULong64_t FillTimeSlice(CbmTimeSlice *timeSlice, Bool_t checkLimit, Double_t fillTime)
Move data from the DaqBuffer into the current time slice.
Definition: CbmDigitize.h:256
CbmDigitize::GetDaqBufferStatus
std::string GetDaqBufferStatus() const
Debug output of DAQ buffer status @value String with status of DAQ buffer.
Definition: CbmDigitize.h:136
CbmTimeSlice
Bookkeeping of time-slice content.
Definition: CbmTimeSlice.h:29
CbmDigitize::GetDaqBufferTimeLast
Double_t GetDaqBufferTimeLast() const
Time stamp of last data in the DAQ buffer @value Time stamp of last data in the DAQ buffer.
Definition: CbmDigitize.h:161
CbmDigitizeBase::GetSystemId
virtual ECbmModuleId GetSystemId() const =0
Detector system ID.
CbmDigitize::RegisterOutput
void RegisterOutput()
Register the output arrays.
Definition: CbmDigitize.h:175
CbmDigitizeBase
Abstract base class for CBM digitisation tasks.
Definition: CbmDigitizeBase.h:26
CbmDigitize::Data
std::pair< std::unique_ptr< Digi >, std::unique_ptr< CbmMatch > > Data
Short for data to be handled (pair of digi and match)
Definition: CbmDigitize.h:43