CbmRoot
CbmStsSimModule.cxx
Go to the documentation of this file.
1 
6 #include "CbmStsSimModule.h"
7 
8 #include "CbmStsDigitize.h"
9 #include "CbmStsElement.h"
10 
11 
12 using namespace std;
13 
15 
16 
17  // ----- Default constructor -------------------------------------------
19  const CbmStsParModule* params,
20  CbmStsDigitize* digitizer)
21  : fElement(element), fDigitizer(digitizer), fParams(params) {}
22 // -------------------------------------------------------------------------
23 
24 
25 // --- Destructor --------------------------------------------------------
27 
28  // --- Clean analog buffer
29  for (auto chanIt = fAnalogBuffer.begin(); chanIt != fAnalogBuffer.end();
30  chanIt++) {
31  for (auto sigIt = (chanIt->second).begin(); sigIt != (chanIt->second).end();
32  sigIt++) {
33  delete (*sigIt);
34  }
35  }
36 }
37 // -------------------------------------------------------------------------
38 
39 
40 // ----- Add a signal to the buffer ------------------------------------
41 void CbmStsSimModule::AddSignal(UShort_t channel,
42  Double_t time,
43  Double_t charge,
44  Int_t index,
45  Int_t entry,
46  Int_t file) {
47 
48  // --- Check channel number
49  assert(channel < GetNofChannels());
50 
51  // --- Discard charge if the channel is dead
52  if (!fParams->IsChannelActive(channel)) return;
53 
54  // --- If the channel is not yet active: create a new set and insert
55  // --- new signal into it.
56  if (fAnalogBuffer.find(channel) == fAnalogBuffer.end()) {
57  CbmStsSignal* signal = new CbmStsSignal(time, charge, index, entry, file);
58  fAnalogBuffer[channel].insert(signal);
59  return;
60  } //? Channel not yet active
61 
62  // --- The channel is active: there are already signals in.
63  // --- Loop over all signals in the channels and compare their time.
64  //TODO: Loop over all signals is not needed, since they are time-ordered.
65  Bool_t isMerged = kFALSE;
66  sigset::iterator it;
67  Double_t deadTime = fParams->GetParAsic(channel).GetDeadTime();
68  for (it = fAnalogBuffer[channel].begin(); it != fAnalogBuffer[channel].end();
69  it++) {
70 
71  // Time between new and old signal smaller than dead time: merge signals
72  if (TMath::Abs((*it)->GetTime() - time) < deadTime) {
73 
74  // Current implementation of merging signals:
75  // Add charges, keep first signal time
76  // TODO: Check with STS electronics people on more realistic behaviour.
77  (*it)->SetTime(TMath::Min((*it)->GetTime(), time));
78  (*it)->AddLink(charge, index, entry, file);
79  isMerged = kTRUE; // mark new signal as merged
80  break; // Merging should be necessary only for one buffer signal
81 
82  } //? Time difference smaller than dead time
83 
84  } // Loop over signals in buffer for this channel
85 
86  // --- If signal was merged: no further action
87  if (isMerged) return;
88 
89  // --- Arriving here, the signal did not interfere with existing ones.
90  // --- So, it is added to the analog buffer.
91  CbmStsSignal* signal = new CbmStsSignal(time, charge, index, entry, file);
92  fAnalogBuffer[channel].insert(signal);
93 }
94 // -------------------------------------------------------------------------
95 
96 
97 // ----- Status of analogue buffer -------------------------------------
98 void CbmStsSimModule::BufferStatus(Int_t& nofSignals,
99  Double_t& timeFirst,
100  Double_t& timeLast) {
101 
102 
103  Int_t nSignals = 0;
104  Double_t tFirst = -1.;
105  Double_t tLast = -1.;
106  Double_t tSignal = -1.;
107 
108  // --- Loop over active channels
109  for (auto chanIt = fAnalogBuffer.begin(); chanIt != fAnalogBuffer.end();
110  chanIt++) {
111 
112  // --- Loop over signals in channel
113  for (auto sigIt = (chanIt->second).begin(); sigIt != (chanIt->second).end();
114  sigIt++) {
115 
116  tSignal = (*sigIt)->GetTime();
117  nSignals++;
118  tFirst = tFirst < 0. ? tSignal : TMath::Min(tFirst, tSignal);
119  tLast = TMath::Max(tLast, tSignal);
120 
121  } // signals in channel
122 
123  } // channels in module
124 
125  nofSignals = nSignals;
126  timeFirst = tFirst;
127  timeLast = tLast;
128 }
129 // -------------------------------------------------------------------------
130 
131 
132 // ----- Digitise an analogue charge signal ----------------------------
133 void CbmStsSimModule::Digitize(UShort_t channel, CbmStsSignal* signal) {
134 
135  // --- Check channel number
136  assert(channel < GetNofChannels());
137 
138  auto& asic = fParams->GetParAsic(channel);
139 
140  // --- No action if charge is below threshold
141  Double_t charge = signal->GetCharge();
142 
143  // --- Digitise charge
144  Short_t adc = asic.ChargeToAdc(charge);
145  if (adc < 0) return; // Charge below threshold
146 
147  // --- Digitise time
148  Double_t deltaT = gRandom->Gaus(0., asic.GetTimeResol());
149  Long64_t dTime = Long64_t(round(signal->GetTime() + deltaT));
150 
151  // --- Send the message to the digitiser task
152  UInt_t address = fElement->GetAddress();
153  if (fDigitizer)
154  fDigitizer->CreateDigi(address, channel, dTime, adc, signal->GetMatch());
155 
156  // --- If no digitiser task is present (debug mode): create a digi and
157  // --- add it to the digi buffer.
158  else
159  return;
160 }
161 // -------------------------------------------------------------------------
162 
163 
164 // ----- Generate noise ------------------------------------------------
165 Int_t CbmStsSimModule::GenerateNoise(Double_t t1, Double_t t2) {
166 
167  assert(t2 > t1);
168  Int_t nNoiseAll = 0;
169  UInt_t nAsicChannels = fParams->GetNofAsicChannels();
170 
171  for (UInt_t iAsic = 0; iAsic < fParams->GetNofAsics(); iAsic++) {
172  auto& asic = fParams->GetAsicParams().at(iAsic);
173 
174  // --- Mean number of noise digis in [t1, t2]
175  Double_t nNoiseMean = asic.GetNoiseRate() * nAsicChannels * (t2 - t1);
176 
177  // --- Sample number of noise digis
178  Int_t nNoise = gRandom->Poisson(nNoiseMean);
179 
180  // --- Create noise digis
181  for (Int_t iNoise = 0; iNoise < nNoise; iNoise++) {
182 
183  // --- Random channel number, time and charge
184  UInt_t channel = UInt_t(gRandom->Uniform(Double_t(nAsicChannels)));
185  Double_t time = gRandom->Uniform(t1, t2);
186  Double_t charge = asic.GetRandomNoiseCharge();
187  UInt_t moduleChannel = iAsic * nAsicChannels + channel;
188 
189  // --- Insert a signal object (without link index, entry and file)
190  // --- into the analogue buffer.
191  AddSignal(moduleChannel, time, charge, -1, -1, -1);
192  } //# noise digis
193 
194  nNoiseAll += nNoise;
195  }
196 
197  return nNoiseAll;
198 }
199 // -------------------------------------------------------------------------
200 
201 
202 // ----- Get the unique address from the sensor name (static) ----------
204 
205  Bool_t isValid = kTRUE;
206  if (name.Length() != 16) isValid = kFALSE;
207  if (isValid) {
208  if (!name.BeginsWith("STS")) isValid = kFALSE;
209  if (name[4] != 'U') isValid = kFALSE;
210  if (name[8] != 'L') isValid = kFALSE;
211  if (name[13] != 'M') isValid = kFALSE;
212  }
213  assert(isValid);
214 
215  Int_t unit = 10 * (name[5] - '0') + name[6] - '0' - 1;
216  Int_t ladder = 10 * (name[9] - '0') + name[10] - '0' - 1;
217  Int_t hLadder = (name[11] == 'U' ? 0 : 1);
218  Int_t module = 10 * (name[14] - '0') + name[15] - '0' - 1;
219 
220  return CbmStsAddress::GetAddress(unit, ladder, hLadder, module);
221 }
222 // -------------------------------------------------------------------------
223 
224 
225 // ----- Initialise the analogue buffer ---------------------------------
227 
228  for (UShort_t channel = 0; channel < fParams->GetNofChannels(); channel++) {
229  multiset<CbmStsSignal*, CbmStsSignal::Before> mset;
230  fAnalogBuffer[channel] = mset;
231  } //# channels
232 }
233 // -------------------------------------------------------------------------
234 
235 
236 // ----- Process the analogue buffer -----------------------------------
237 Int_t CbmStsSimModule::ProcessAnalogBuffer(Double_t readoutTime) {
238 
239  // --- Counter
240  Int_t nDigis = 0;
241 
242  // Create iterators needed for inner loop
243  sigset::iterator sigIt;
244  ;
245  sigset::iterator oldIt;
246  sigset::iterator endIt;
247 
248  // --- Iterate over active channels
249  for (auto& chanIt : fAnalogBuffer) {
250 
251  // Only do something if there are signals for the channel
252  if (!(chanIt.second).empty()) {
253  auto& asic = fParams->GetParAsic(chanIt.first);
254 
255  // --- Time limit up to which signals are digitised and sent to DAQ.
256  // --- Up to that limit, it is guaranteed that future signals do not
257  // --- interfere with the buffered ones. The readoutTime is the time
258  // --- of the last processed StsPoint. All coming points will be later
259  // --- in time. So, the time limit is defined by this time minus
260  // --- 5 times the time resolution (maximal deviation of signal time
261  // --- from StsPoint time) minus the dead time, within which
262  // --- interference of signals can happen.
263  Double_t timeLimit =
264  readoutTime - 5. * asic.GetTimeResol() - asic.GetDeadTime();
265 
266  // --- Digitise all signals up to the specified time limit
267  sigIt = (chanIt.second).begin();
268  oldIt = sigIt;
269  endIt = (chanIt.second).end();
270  while (sigIt != endIt) {
271 
272  // --- Exit loop if signal time is larger than time limit
273  // --- N.b.: Readout time < 0 means digitise everything
274  if (readoutTime >= 0. && (*sigIt)->GetTime() > timeLimit) break;
275 
276  // --- Digitise signal
277  Digitize(chanIt.first, (*sigIt));
278  nDigis++;
279 
280  // --- Increment iterator before it becomes invalid
281  oldIt = sigIt;
282  sigIt++;
283 
284  // --- Delete digitised signal
285  delete (*oldIt);
286  (chanIt.second).erase(oldIt);
287  } // Iterate over signals in channel
288  } // if there are signals
289  } // Iterate over channels
290 
291  return nDigis;
292 }
293 // -------------------------------------------------------------------------
294 
295 
296 // ----- String output -------------------------------------------------
298  stringstream ss;
299  auto& asic = fParams->GetParAsic(0);
300  ss << "Module " << fElement->GetName() << ": dynRange " << asic.GetDynRange()
301  << "e, thresh. " << asic.GetThreshold() << "e, nAdc " << asic.GetNofAdc()
302  << ", time res. " << asic.GetTimeResol() << "ns, dead time "
303  << asic.GetDeadTime() << "ns, noise " << asic.GetNoise()
304  << "e, zero noise rate " << asic.GetZeroNoiseRate() << "/ns";
305  return ss.str();
306 }
307 // -------------------------------------------------------------------------
CbmStsParModule::IsChannelActive
Bool_t IsChannelActive(UInt_t channel) const
Check for a channel being active.
Definition: CbmStsParModule.cxx:40
CbmStsElement::GetAddress
Int_t GetAddress() const
Definition: CbmStsElement.h:65
CbmStsSimModule::BufferStatus
void BufferStatus(Int_t &nofSignals, Double_t &timeFirst, Double_t &timeLast)
Definition: CbmStsSimModule.cxx:98
CbmStsAddress::GetAddress
Int_t GetAddress(UInt_t unit=0, UInt_t ladder=0, UInt_t halfladder=0, UInt_t module=0, UInt_t sensor=0, UInt_t side=0, UInt_t version=kCurrentVersion)
Construct address.
Definition: CbmStsAddress.cxx:90
CbmStsParModule::GetAsicParams
const std::vector< CbmStsParAsic > & GetAsicParams() const
All ASIC parameters.
Definition: CbmStsParModule.h:56
CbmStsParModule::GetNofChannels
UInt_t GetNofChannels() const
Number of channels.
Definition: CbmStsParModule.h:74
CbmStsSimModule::AddSignal
void AddSignal(UShort_t channel, Double_t time, Double_t charge, Int_t index=0, Int_t entry=0, Int_t file=0)
Definition: CbmStsSimModule.cxx:41
CbmStsParModule::GetNofAsics
UInt_t GetNofAsics() const
Number of ASICs.
Definition: CbmStsParModule.h:68
CbmStsDigitize
Task class for simulating the detector response of the STS.
Definition: CbmStsDigitize.h:50
CbmStsDigitize.h
CbmStsSimModule::GetNofChannels
UShort_t GetNofChannels() const
Number of electronic channels @value Number of ADC channels.
Definition: CbmStsSimModule.h:120
CbmStsSimModule::ProcessAnalogBuffer
Int_t ProcessAnalogBuffer(Double_t readoutTime)
Definition: CbmStsSimModule.cxx:237
CbmStsSimModule::fElement
CbmStsElement * fElement
Definition: CbmStsSimModule.h:198
CbmStsSimModule::CbmStsSimModule
CbmStsSimModule(CbmStsElement *setupModule=nullptr, const CbmStsParModule *modulePar=nullptr, CbmStsDigitize *digitizer=nullptr)
Standard constructor.
CbmStsSignal::GetTime
Double_t GetTime() const
Definition: CbmStsSignal.h:75
CbmStsSignal
Data class for an analog signal in the STS.
Definition: CbmStsSignal.h:27
CbmStsSimModule::fDigitizer
CbmStsDigitize * fDigitizer
Element in geometry setup.
Definition: CbmStsSimModule.h:199
CbmStsParModule::GetParAsic
const CbmStsParAsic & GetParAsic(UInt_t channel) const
ASIC parameters for a given channel.
Definition: CbmStsParModule.cxx:29
CbmStsParModule
Parameters for one STS module.
Definition: CbmStsParModule.h:28
CbmStsSimModule::fParams
const CbmStsParModule * fParams
Digitizer.
Definition: CbmStsSimModule.h:200
CbmStsElement.h
CbmStsDigitize::CreateDigi
void CreateDigi(Int_t address, UShort_t channel, Long64_t time, UShort_t adc, const CbmMatch &match)
Definition: CbmStsDigitize.cxx:149
CbmStsSignal::GetMatch
const CbmMatch & GetMatch() const
Definition: CbmStsSignal.h:69
CbmStsSimModule::Digitize
void Digitize(UShort_t channel, CbmStsSignal *signal)
Definition: CbmStsSimModule.cxx:133
CbmStsSimModule::~CbmStsSimModule
virtual ~CbmStsSimModule()
Destructor.
Definition: CbmStsSimModule.cxx:26
CbmStsSimModule::InitAnalogBuffer
void InitAnalogBuffer()
Definition: CbmStsSimModule.cxx:226
ClassImp
ClassImp(CbmStsSimModule) CbmStsSimModule
Definition: CbmStsSimModule.cxx:14
CbmStsSimModule::GetAddressFromName
static Int_t GetAddressFromName(TString name)
Get the address from the module name (static)
Definition: CbmStsSimModule.cxx:203
CbmStsSimModule
Class for the simulation of a readout unit in the CBM-STS.
Definition: CbmStsSimModule.h:42
CbmStsParAsic::GetDeadTime
Double_t GetDeadTime() const
Single-channel dead time.
Definition: CbmStsParAsic.h:91
CbmStsSimModule.h
CbmStsSimModule::ToString
std::string ToString() const
Definition: CbmStsSimModule.cxx:297
CbmStsSignal::GetCharge
Double_t GetCharge() const
Definition: CbmStsSignal.h:63
CbmStsElement
Class representing an element of the STS setup.
Definition: CbmStsElement.h:32
CbmStsParModule::GetNofAsicChannels
UInt_t GetNofAsicChannels() const
Number of channels per ASIC.
Definition: CbmStsParModule.h:62
CbmStsSimModule::GenerateNoise
Int_t GenerateNoise(Double_t t1, Double_t t2)
Generate noise.
Definition: CbmStsSimModule.cxx:165
CbmStsSimModule::fAnalogBuffer
std::map< UShort_t, sigset > fAnalogBuffer
Definition: CbmStsSimModule.h:210
CbmStsParAsic::GetTimeResol
Double_t GetTimeResol() const
Time resolution.
Definition: CbmStsParAsic.h:137