CbmRoot
Loading...
Searching...
No Matches
CbmStsDigitize.cxx
Go to the documentation of this file.
1/* Copyright (C) 2014-2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Volker Friese [committer] */
4
10// Include class header
11#include "CbmStsDigitize.h"
12
13// Includes from C++
14#include <cassert>
15#include <cstring>
16#include <fstream>
17#include <iomanip>
18#include <iostream>
19#include <sstream>
20#include <tuple>
21
22// Includes from ROOT
23#include "TClonesArray.h"
24#include "TGeoBBox.h"
25#include "TGeoMatrix.h"
26#include "TGeoPhysicalNode.h"
27#include "TGeoVolume.h"
28#include <TMCProcess.h>
29
30// Includes from FairRoot
31#include "FairEventHeader.h"
32#include "FairField.h"
33#include "FairLink.h"
34#include "FairMCEventHeader.h"
35#include "FairMCPoint.h"
36#include "FairRunAna.h"
37#include "FairRunSim.h"
38#include "FairRuntimeDb.h"
39#include <Logger.h>
40
41// Includes from CbmRoot
42#include "CbmMCTrack.h"
43#include "CbmStsDigi.h"
44#include "CbmStsPoint.h"
45
46// Includes from STS
47#include "CbmStsModule.h"
48#include "CbmStsParAsic.h"
49#include "CbmStsParModule.h"
50#include "CbmStsParSensor.h"
51#include "CbmStsParSensorCond.h"
52#include "CbmStsParSetModule.h"
53#include "CbmStsParSetSensor.h"
55#include "CbmStsParSim.h"
56#include "CbmStsPhysics.h"
57#include "CbmStsSensor.h"
58#include "CbmStsSetup.h"
60
61using std::fixed;
62using std::left;
63using std::right;
64using std::setprecision;
65using std::setw;
66using std::string;
67using std::stringstream;
68
69using namespace CbmSts;
70
71
72// ----- Standard constructor ------------------------------------------
74 : CbmDigitize<CbmStsDigi>("StsDigitize")
75 , fIsInitialised(kFALSE)
76 ,
77 //fModuleParameterMap(),
78 fSetup(nullptr)
79 , fPoints(nullptr)
80 , fTracks(nullptr)
81 , fTimer()
82 , fSensorDinact(0.12)
83 , fSensorPitch(0.0058)
84 , fSensorStereoF(0.)
85 , fSensorStereoB(7.5)
86 , fSensorParameterFile()
87 , fSensorConditionFile()
88 , fModuleParameterFile()
89 , fTimePointLast(-1.)
90 , fTimeDigiFirst(-1.)
91 , fTimeDigiLast(-1.)
92{
95}
96// -------------------------------------------------------------------------
97
98
99// ----- Destructor ----------------------------------------------------
101// -------------------------------------------------------------------------
102
103
104// ----- Content of analogue buffers -----------------------------------
106{
107 Int_t nSignals = 0;
108 Int_t nSigModule;
109 Double_t t1Module;
110 Double_t t2Module;
111
112 for (auto& entry : fModules) {
113 entry.second->BufferStatus(nSigModule, t1Module, t2Module);
114 nSignals += nSigModule;
115 } //# modules
116
117 return nSignals;
118}
119// -------------------------------------------------------------------------
120
121
122// ----- Print the status of the analogue buffers ----------------------
124{
125
126 Int_t nSignals = 0;
127 Double_t t1 = -1;
128 Double_t t2 = -1.;
129
130 Int_t nSigModule;
131 Double_t t1Module;
132 Double_t t2Module;
133
134 for (auto& entry : fModules) {
135 entry.second->BufferStatus(nSigModule, t1Module, t2Module);
136 if (nSigModule) {
137 nSignals += nSigModule;
138 t1 = t1 < 0. ? t1Module : TMath::Min(t1, t1Module);
139 t2 = TMath::Max(t2, t2Module);
140 } //? signals in module buffer?
141 } //# modules in setup
142
143 std::stringstream ss;
144 ss << nSignals << (nSignals == 1 ? " signal " : " signals ") << "in analogue buffers";
145 if (nSignals) ss << " ( from " << fixed << setprecision(3) << t1 << " ns to " << t2 << " ns )";
146 return ss.str();
147}
148// -------------------------------------------------------------------------
149
150
151// ----- Create a digi object ------------------------------------------
152void CbmStsDigitize::CreateDigi(Int_t address, UShort_t channel, Long64_t time, UShort_t adc, const CbmMatch& match)
153{
154 assert(time >= 0);
155
156 // No action if the channel is marked inactive
157 if (!IsChannelActiveSts(address, channel)) return;
158
159 // Update times of first and last digi
160 fTimeDigiFirst = fNofDigis ? TMath::Min(fTimeDigiFirst, Double_t(time)) : time;
161 fTimeDigiLast = TMath::Max(fTimeDigiLast, Double_t(time));
162
163 // Create digi and (if required) match and send them to DAQ
164 // Digi time is set later, when creating the timestamp
165 CbmStsDigi* digi = new CbmStsDigi(address, channel, 0, adc);
166 if (fCreateMatches) {
167 CbmMatch* digiMatch = new CbmMatch(match);
168 SendData(time, digi, digiMatch);
169 }
170 else
171 SendData(time, digi);
172 fNofDigis++;
173}
174// -------------------------------------------------------------------------
175
176
177// ----- Task execution ------------------------------------------------
178void CbmStsDigitize::Exec(Option_t* /*opt*/)
179{
180
181 // --- Start timer and reset counters
182 fTimer.Start();
184
185 // --- For debug: status of analogue buffers
186 if (fair::Logger::Logging(fair::Severity::debug)) {
187 std::cout << std::endl;
188 LOG(debug) << GetName() << ": " << BufferStatus();
189 }
190
191 // --- Store previous event time. Get current event time.
192 Double_t eventTimePrevious = fCurrentEventTime;
193 GetEventInfo();
194
195 // --- Generate noise from previous to current event time
196 if (fParSim->Noise()) {
197 Int_t nNoise = 0;
198 Double_t tNoiseStart = fNofEvents ? eventTimePrevious : fRunStartTime;
199 Double_t tNoiseEnd = fCurrentEventTime;
200 for (auto& entry : fModules)
201 nNoise += entry.second->GenerateNoise(tNoiseStart, tNoiseEnd);
202 fNofNoiseTot += Double_t(nNoise);
203 LOG(info) << "+ " << setw(20) << GetName() << ": Generated " << nNoise << " noise signals from t = " << tNoiseStart
204 << " ns to " << tNoiseEnd << " ns";
205 }
206
207 // --- Analogue response: Process the input array of StsPoints
209 LOG(debug) << GetName() << ": " << fNofSignalsF + fNofSignalsB << " signals generated ( " << fNofSignalsF << " / "
210 << fNofSignalsB << " )";
211 // --- For debug: status of analogue buffers
212 if (fair::Logger::Logging(fair::Severity::debug)) { LOG(debug) << GetName() << ": " << BufferStatus(); }
213
214 // --- Readout time: in stream mode the time of the current event.
215 // --- Analogue buffers will be digitised for signals at times smaller than
216 // --- that time minus a safety margin depending on the module properties
217 // --- (dead time and time resolution). In event mode, the readout time
218 // --- is set to -1., meaning to digitise everything in the readout buffers.
219 Double_t readoutTime = fEventMode ? -1. : fCurrentEventTime;
220
221 // --- Digital response: Process buffers of all modules
222 ProcessAnalogBuffers(readoutTime);
223
224 // --- Check status of analogue module buffers
225 if (fair::Logger::Logging(fair::Severity::debug)) { LOG(debug) << GetName() << ": " << BufferStatus(); }
226
227 // --- Event log
228 LOG(info) << left << setw(15) << GetName() << "[" << fixed << setprecision(3) << fTimer.RealTime() << " s]"
229 << " Points: processed " << fNofPointsProc << ", ignored " << fNofPointsIgno
230 << ", signals: " << fNofSignalsF << " / " << fNofSignalsB << ", digis: " << fNofDigis;
231
232 // --- Counters
233 fTimer.Stop();
234 fNofEvents++;
240 fTimeTot += fTimer.RealTime();
241}
242// -------------------------------------------------------------------------
243
244
245// ----- Finish run ---------------------------------------------------
247{
248
249 // --- Start timer and reset counters
250 fTimer.Start();
252
253 // --- In event-by-event mode, the analogue buffers should be empty.
254 if (fEventMode) {
255 if (BufferSize()) {
256 LOG(info) << fName << BufferStatus();
257 LOG(fatal) << fName << ": Non-empty analogue buffers at end of event "
258 << " in event-by-event mode!";
259 } //? buffers not empty
260 } //? event-by-event mode
261
262 // --- In time-based mode: process the remaining signals in the buffers
263 else {
264 std::cout << std::endl;
265 LOG(info) << GetName() << ": Finish run";
266 LOG(info) << GetName() << ": " << BufferStatus();
267 LOG(info) << GetName() << ": Processing analogue buffers";
268
269 // --- Process buffers of all modules
270 for (auto& entry : fModules)
271 entry.second->ProcessAnalogBuffer(-1.);
272
273 // --- Screen output
274 stringstream ss;
275 ss << GetName() << ": " << fNofDigis << (fNofDigis == 1 ? " digi " : " digis ") << "created and sent to DAQ ";
276 if (fNofDigis)
277 ss << "( from " << fixed << setprecision(3) << fTimeDigiFirst << " ns to " << fTimeDigiLast << " ns )";
278 LOG(info) << ss.str();
279 LOG(info) << GetName() << ": " << BufferStatus();
280 }
281
282 fTimer.Stop();
288 fTimeTot += fTimer.RealTime();
289
290 std::cout << std::endl;
291 LOG(info) << "=====================================";
292 LOG(info) << GetName() << ": Run summary";
293 LOG(info) << "Events processed : " << fNofEvents;
294 LOG(info) << "Points processed / evt : " << fixed << setprecision(1) << fNofPointsProcTot / Double_t(fNofEvents);
295 LOG(info) << "Points ignored / evt : " << fixed << setprecision(1) << fNofPointsIgnoTot / Double_t(fNofEvents);
296 LOG(info) << "Signals / event : " << fNofSignalsFTot / Double_t(fNofEvents) << " / "
297 << fNofSignalsBTot / Double_t(fNofEvents);
298 LOG(info) << "StsDigi / event : " << fNofDigisTot / Double_t(fNofEvents);
299 LOG(info) << "Digis per point : " << setprecision(6) << fNofDigisTot / fNofPointsProcTot;
300 LOG(info) << "Digis per signal : " << fNofDigisTot / (fNofSignalsFTot + fNofSignalsBTot);
301 LOG(info) << "Noise digis / event : " << fNofNoiseTot / Double_t(fNofEvents);
302 LOG(info) << "Noise fraction : " << fNofNoiseTot / fNofDigisTot;
303 LOG(info) << "Real time per event : " << fTimeTot / Double_t(fNofEvents) << " s";
304 LOG(info) << "=====================================";
305}
306// -------------------------------------------------------------------------
307
308
309// ----- Get parameter container from runtime DB -----------------------
311{
312 assert(FairRunAna::Instance());
313 FairRuntimeDb* rtdb = FairRunAna::Instance()->GetRuntimeDb();
314 fParSim = static_cast<CbmStsParSim*>(rtdb->getContainer("CbmStsParSim"));
315 fParSetModule = static_cast<CbmStsParSetModule*>(rtdb->getContainer("CbmStsParSetModule"));
316 fParSetSensor = static_cast<CbmStsParSetSensor*>(rtdb->getContainer("CbmStsParSetSensor"));
317 fParSetCond = static_cast<CbmStsParSetSensorCond*>(rtdb->getContainer("CbmStsParSetSensorCond"));
318}
319// -------------------------------------------------------------------------
320
321
322// ----- Initialisation -----------------------------------------------
324{
325
326 // Screen output
327 std::cout << std::endl;
328 LOG(info) << "==========================================================";
329 LOG(info) << GetName() << ": Initialisation \n\n";
330
331 // Initialise the STS setup interface from TGeoManager
333 fSetup->Init();
334
335 // --- Instantiate StsPhysics
337
338 // --- Initialise parameters
339 InitParams();
340
341 // --- Read list of inactive channels
342 if (!fInactiveChannelFileName.IsNull()) {
343 LOG(info) << GetName() << ": Reading inactive channels from " << fInactiveChannelFileName;
344 auto result = ReadInactiveChannels();
345 if (!result.second) {
346 LOG(error) << GetName() << ": Error in reading from file! Task will be inactive.";
347 return kFATAL;
348 }
349 LOG(info) << GetName() << ": " << std::get<0>(result) << " lines read from file";
350 }
351 size_t nChanInactive = 0;
352 for (auto& entry : fInactiveChannelsSts)
353 nChanInactive += entry.second.size();
354 LOG(info) << GetName() << ": " << nChanInactive << " channels set inactive";
355
356 // Instantiate modules
357 UInt_t nModules = InitModules();
358 LOG(info) << GetName() << ": Created " << nModules << " modules";
359
360 // Instantiate sensors
361 UInt_t nSensors = InitSensors();
362 LOG(info) << GetName() << ": Created " << nSensors << " sensors";
363
364 // --- Get FairRootManager instance
365 FairRootManager* ioman = FairRootManager::Instance();
366 assert(ioman);
367
368 // --- Get input array (CbmStsPoint)
369 fPoints = (TClonesArray*) ioman->GetObject("StsPoint");
370 assert(fPoints);
371
372 // --- Get input array (CbmMCTrack)
373 fTracks = (TClonesArray*) ioman->GetObject("MCTrack");
374 assert(fTracks);
375
376 // --- Register the output branches
378
379 // --- Screen output
380 LOG(info) << GetName() << ": Initialisation successful";
381 LOG(info) << "==========================================================";
382 std::cout << std::endl;
383
384 // Set static initialisation flag
385 fIsInitialised = kTRUE;
386
387 return kSUCCESS;
388}
389// -------------------------------------------------------------------------
390
391
392// ----- Instantiation of modules --------------------------------------
394{
395
396 UInt_t nModules = 0;
397 fModules.clear();
398
399 for (Int_t iModule = 0; iModule < fSetup->GetNofModules(); iModule++) {
400 CbmStsElement* geoModule = fSetup->GetModule(iModule);
401 assert(geoModule);
402 UInt_t address = geoModule->GetAddress();
403 auto& modulePar = fParSetModule->GetParModule(address);
404 CbmStsSimModule* module = new CbmStsSimModule(geoModule, &modulePar, this);
405 auto result = fModules.insert({address, module});
406 assert(result.second); // If false, module was already in map
407 nModules++;
408 } //# modules in setup
409
410 assert(nModules == fModules.size());
411 return nModules;
412}
413// -------------------------------------------------------------------------
414
415
416// ----- Initialise parameters -----------------------------------------
418{
419
420 // --- The parameter containers are completely initialised here.
421 // --- Any contents possibly obtained from the runtimeDb are ignored
422 // --- and overwritten.
423
424 // --- Simulation settings
425 assert(fParSim);
426 assert(fUserParSim);
427 *fParSim = *fUserParSim; // adapt user settings
428 fParSim->SetEventMode(fEventMode); // from CbmDigitizeBase
429 fParSim->SetGenerateNoise(fProduceNoise); // from CbmDigitizeBase
430 /* fParSim->SetProcesses(fUserParSim->ELossModel(),
431 fUserParSim->LorentzShift(),
432 fUserParSim->Diffusion(),
433 fUserParSim->CrossTalk());
434 */
435 if (fEventMode) fParSim->SetGenerateNoise(kFALSE);
436 fParSim->setChanged();
437 fParSim->setInputVersion(-2, 1);
438 LOG(info) << "--- Settings: " << fParSim->ToString();
439
440 // --- Module parameters (global for the time being)
441 assert(fParSetModule);
443 assert(fUserParModule);
444 assert(fUserParAsic);
446 for (Int_t iModule = 0; iModule < fSetup->GetNofModules(); iModule++) {
447 UInt_t address = fSetup->GetModule(iModule)->GetAddress();
449 }
450 UInt_t deactivated = 0;
452 fParSetModule->setChanged();
453 fParSetModule->setInputVersion(-2, 1);
454 LOG(info) << "--- Using global ASIC parameters: \n " << fUserParAsic->ToString();
455 LOG(info) << "--- Module parameters: " << fParSetModule->ToString();
456 LOG(info) << "--- Deactive channels: " << deactivated << " " << fUserFracDeadChan;
457
458 // --- Sensor parameters
459 // TODO: The code above is highly unsatisfactory. A better implementation
460 // would use data sheets with the actual sensor design parameters.
461 assert(fParSetSensor);
463 assert(fUserParSensor);
464 for (Int_t iSensor = 0; iSensor < fSetup->GetNofSensors(); iSensor++) {
465 CbmStsSensor* sensor = fSetup->GetSensor(iSensor);
466 UInt_t address = sensor->GetAddress();
467 TGeoBBox* box = dynamic_cast<TGeoBBox*>(sensor->GetPnode()->GetShape());
468 assert(box);
469 Double_t lX = 2. * box->GetDX();
470 Double_t lY = 2. * box->GetDY();
471 Double_t lZ = 2. * box->GetDZ();
472 Double_t dX = lX - 2. * fUserDinactive;
473 Double_t dY = lY - 2. * fUserDinactive;
474
475 // In general, the number of strips is given by the active size in x
476 // divided by the strip pitch.
477 Double_t pitchF = fUserParSensor->GetPar(6);
478 Double_t pitchB = fUserParSensor->GetPar(7);
479 Double_t nStripsF = dX / pitchF;
480 Double_t nStripsB = dX / pitchB;
481
482 // The stereo sensors with 6.2092 cm width have 1024 strips à 58 mum.
483 if (fUserParSensor->GetClass() == CbmStsSensorClass::kDssdStereo && TMath::Abs(lX - 6.2092) < 0.0001
484 && TMath::Abs(pitchF - 0.0058) < 0.0001) {
485 nStripsF = 1024.;
486 nStripsB = 1024.;
487 }
488
489 // Same for sensors with 6.2000 cm width
490 if (fUserParSensor->GetClass() == CbmStsSensorClass::kDssdStereo && TMath::Abs(lX - 6.2) < 0.0001
491 && TMath::Abs(pitchF - 0.0058) < 0.0001) {
492 nStripsF = 1024.;
493 nStripsB = 1024.;
494 }
495
496 // Create a sensor parameter object and add it to the container
498 par.SetPar(0, lX); // Extension in x
499 par.SetPar(1, lY); // Extension in y
500 par.SetPar(2, lZ); // Extension in z
501 par.SetPar(3, dY); // Active size in y
502 par.SetPar(4, nStripsF); // Number of strips front side
503 par.SetPar(5, nStripsB); // Number of strips back side
504 for (UInt_t parIndex = 6; parIndex < 10; parIndex++) {
505 par.SetPar(parIndex, fUserParSensor->GetPar(parIndex));
506 } //# parameters 6 - 9 (pitches and stereo angles) set by user or default
507 fParSetSensor->SetParSensor(address, par);
508
509 } //# sensors in setup
510 LOG(info) << "--- Sensor parameters: " << fParSetSensor->ToString();
511 fParSetSensor->setChanged();
512 fParSetSensor->setInputVersion(-2, 1);
513
514 // --- Sensor conditions
515 assert(fParSetCond);
518 LOG(info) << "--- Sensor conditions: " << fParSetCond->ToString();
519 fParSetCond->setChanged();
520 fParSetCond->setInputVersion(-2, 1);
521}
522// -------------------------------------------------------------------------
523
524
525// ----- Instantiation of sensors --------------------------------------
527{
528
529 UInt_t nSensors = 0;
530 fSensors.clear();
531
533 for (Int_t iSensor = 0; iSensor < fSetup->GetNofSensors(); iSensor++) {
534
535 // --- Sensor and module elements in setup
536 CbmStsElement* geoSensor = fSetup->GetSensor(iSensor);
537 assert(geoSensor); // Valid geo sensor
538 UInt_t sensAddress = geoSensor->GetAddress();
539 CbmStsElement* geoModule = geoSensor->GetMother();
540 assert(geoModule); // Valid geo mother module
541 UInt_t moduAddress = geoModule->GetAddress();
542
543 // --- Simulation module
544 auto moduIt = fModules.find(moduAddress);
545 assert(moduIt != fModules.end());
546 assert(moduIt->second); // Valid sim module
547
548 // --- Sensor parameters
549 const CbmStsParSensor& sensorPar = fParSetSensor->GetParSensor(sensAddress);
550
551 // --- Create simulation sensor accordoing to its class
552 auto result = fSensors.insert(std::make_pair(sensAddress, fSensorFactory->CreateSensor(sensorPar)));
553 assert(result.second); // If false, sensor was already in map
554 auto& sensor = result.first->second;
555 assert(sensor); // Valid sensor pointer
556
557 // Assign setup element and module
558 sensor->SetElement(geoSensor);
559 sensor->SetModule(moduIt->second);
560
561 // Assign simulation settings
562 sensor->SetSimSettings(fParSim);
563
564 // Set sensor conditions
565 assert(fParSetCond);
566 const CbmStsParSensorCond& cond = fParSetCond->GetParSensor(sensAddress);
567 sensor->SetConditions(&cond);
568
569 // Get the magnetic field in the sensor centre
570 Double_t bx = 0.;
571 Double_t by = 0.;
572 Double_t bz = 0.;
573 if (FairRun::Instance()->GetField()) {
574 Double_t local[3] = {0., 0., 0.}; // sensor centre in local C.S.
575 Double_t global[3]; // sensor centre in global C.S.
576 geoSensor->GetPnode()->GetMatrix()->LocalToMaster(local, global);
577 Double_t field[3] = {0., 0., 0.}; // magnetic field components
578 FairRun::Instance()->GetField()->Field(global, field);
579 bx = field[0] / 10.; // kG->T
580 by = field[1] / 10.; // kG->T
581 bz = field[2] / 10.; // kG->T
582 } //? field present
583 sensor->SetField(bx, by, bz);
584
585 // Initialise sensor
586 assert(sensor->Init());
587
588 nSensors++;
589 } //# sensors in setup
590
591 assert(nSensors == fSensors.size());
592 return nSensors;
593}
594// -------------------------------------------------------------------------
595
596
597// ----- Initialisation of setup --------------------------------------
599{
600
601 // Initialise the STS setup interface from TGeoManager
603 fSetup->Init();
604
605 // Set parameters to modules and sensor
609
610 // Individual configuration
611 //fSetup->SetModuleParameterMap(fModuleParameterMap);
612}
613// -------------------------------------------------------------------------
614
615
616// ----- Check for channel being active --------------------------------
617bool CbmStsDigitize::IsChannelActiveSts(Int_t address, UShort_t channel)
618{
619 auto it = fInactiveChannelsSts.find(address);
620 if (it == fInactiveChannelsSts.end()) return true;
621 if (it->second.count(channel)) return false;
622 return true;
623}
624// -------------------------------------------------------------------------
625
626
627// ----- Process the analogue buffers of all modules -------------------
628void CbmStsDigitize::ProcessAnalogBuffers(Double_t readoutTime)
629{
630
631 // --- Process analogue buffers of all modules
632 for (auto& it : fModules)
633 it.second->ProcessAnalogBuffer(readoutTime);
634}
635// -------------------------------------------------------------------------
636
637
638// ----- Process points from MC event ---------------------------------
640{
641
642 // --- Loop over all StsPoints and execute the ProcessPoint method
643 assert(fPoints);
644 for (Int_t iPoint = 0; iPoint < fPoints->GetEntriesFast(); iPoint++) {
645 const CbmStsPoint* point = (const CbmStsPoint*) fPoints->At(iPoint);
646
647 // --- Ignore points from secondaries if the respective flag is set
648 if (fParSim->OnlyPrimaries()) {
649 Int_t iTrack = point->GetTrackID();
650 if (iTrack >= 0) { // MC track is present
651 CbmMCTrack* track = (CbmMCTrack*) fTracks->At(iTrack);
652 assert(track);
653 if (track->GetGeantProcessId() != kPPrimary) {
655 continue;
656 }
657 } //? MC track present
658 } //? discard secondaries
659
660 // --- Ignore points with unphysical time
661 // Such instances were observed using Geant4 in the fairsoft jun19 version.
662 // The cut at 1 ms from the event start is somehow arbitrary, but should suit the purpose.
663 // If not cut here, the time range for the StsDigi (2^31 ns) might be exceeded in
664 // flexible time slices or in event-by-event simulation.
665 if (point->GetTime() > 1.e6) {
667 continue;
668 }
669
670 // --- Process the StsPoint
671 CbmLink link(1., iPoint, fCurrentMCEntry, fCurrentInput);
672 ProcessPoint(point, fCurrentEventTime, link);
674 } //# StsPoints
675}
676// -------------------------------------------------------------------------
677
678
679// ----- Process a StsPoint ---------------------------------------------
680void CbmStsDigitize::ProcessPoint(const CbmStsPoint* point, Double_t eventTime, const CbmLink& link)
681{
682
683 // --- Get the sensor the point is in
684 UInt_t address = static_cast<UInt_t>(point->GetDetectorID());
685 assert(fSensors.count(address));
686 auto& sensor = fSensors.find(address)->second;
687 assert(sensor);
688 Int_t status = sensor->ProcessPoint(point, eventTime, link);
689
690 // --- Statistics
691 Int_t nSignalsF = status / 1000;
692 Int_t nSignalsB = status - 1000 * nSignalsF;
693 LOG(debug2) << GetName() << ": Produced signals: " << nSignalsF + nSignalsB << " ( " << nSignalsF << " / "
694 << nSignalsB << " )";
695 fNofSignalsF += nSignalsF;
696 fNofSignalsB += nSignalsB;
697}
698// -------------------------------------------------------------------------
699
700
701// ----- Read list of inactive channels from file -----------------------
703{
704
705 if (fInactiveChannelFileName.IsNull()) return std::make_pair(0, true);
706
707 FILE* channelFile = fopen(fInactiveChannelFileName.Data(), "r");
708 if (channelFile == nullptr) return std::make_pair(0, false);
709
710 size_t nLines = 0;
711 uint32_t address = 0;
712 uint16_t channel = 0;
713 while (fscanf(channelFile, "%u %hu", &address, &channel) == 2) {
714 fInactiveChannelsSts[address].insert(channel);
715 nLines++;
716 }
717 bool success = feof(channelFile);
718
719 fclose(channelFile);
720 return std::make_pair(nLines, success);
721}
722// -------------------------------------------------------------------------
723
724
725// ----- Private method ReInit -----------------------------------------
727{
728
730
731 return kERROR;
732}
733// -------------------------------------------------------------------------
734
735
736// ----- Reset event counters ------------------------------------------
738{
740 fNofPointsProc = 0;
741 fNofPointsIgno = 0;
742 fNofSignalsF = 0;
743 fNofSignalsB = 0;
744 fNofDigis = 0;
745}
746// -------------------------------------------------------------------------
747
748
749// ----- Global default values for parameters --------------------------
751{
752
753 // The global default values cannot be directly stored in the parameter
754 // containers, since these are not yet initialised from the database.
755
756 // --- Protect against setting after initialisation
757 assert(!fIsInitialised);
758
759 // --- Simulation settings
760 if (fUserParSim) delete fUserParSim;
762 Bool_t eventMode = kFALSE;
763 CbmStsELoss eLossModel = CbmStsELoss::kUrban;
764 Bool_t lorentzShift = kTRUE;
765 Bool_t diffusion = kTRUE;
766 Bool_t crossTalk = kTRUE;
767 Bool_t generateNoise = kTRUE;
768 fUserParSim->SetEventMode(eventMode);
769 fUserParSim->SetProcesses(eLossModel, lorentzShift, diffusion, crossTalk);
770 fUserParSim->SetGenerateNoise(generateNoise);
771 // Note that the run mode and the generation of noise are centrally set
772 // through the base class CbmDigitizeBase, such that the settings here
773 // will be overwritten later (in Init).
774
775 // --- Module parameters
776 if (fUserParModule) delete fUserParModule;
777 UInt_t nChannels = 2048; // Number of module readout channels
778 UInt_t nAsicChannels = 128; // Number of readout channels per ASIC
779 fUserParModule = new CbmStsParModule(nChannels, nAsicChannels);
780
781 // --- ASIC parameters
782 if (fUserParAsic) delete fUserParAsic;
783 UShort_t nAdc = 32; // Number of ADC channels (5 bit)
784 Double_t dynRange = 75000.; // Dynamic range [e]
785 Double_t threshold = 3000.; // Threshold [e]
786 Double_t timeResol = 5.; // Time resolution [ns]
787 Double_t deadTime = 800.; // Channel dead time [ns]
788 Double_t noiseRms = 1000.; // RMS of noise [e]
789 Double_t znr = 3.9789e-3; // Zero-crossing noise rate [1/ns]
790 fUserParAsic = new CbmStsParAsic(nAsicChannels, nAdc, dynRange, threshold, timeResol, deadTime, noiseRms, znr);
791 // --- Sensor parameters
792 // --- Here, only the default pitch and stereo angles are defined. The
793 // --- other parameters are extracted from the geometry.
794 if (fUserParSensor) delete fUserParSensor;
796 fUserParSensor = new CbmStsParSensor(sClass);
797 Double_t pitchF = 0.0058; // Strip pitch front side
798 Double_t pitchB = 0.0058; // Strip pitch back side
799 Double_t stereoF = 0.; // Stereo angle front side
800 Double_t stereoB = 7.5; // Stereo angle back side [deg]
801 fUserParSensor->SetPar(6, pitchF);
802 fUserParSensor->SetPar(7, pitchB);
803 fUserParSensor->SetPar(8, stereoF);
804 fUserParSensor->SetPar(9, stereoB);
805 fUserDinactive = 0.12; // Size of inactive sensor border [cm]
806
807 // --- Sensor conditions
808 if (fUserParCond) delete fUserParCond;
809 Double_t vFd = 70.; // Full-depletion voltage
810 Double_t vBias = 140.; // Bias voltage
811 Double_t temperature = 268.; // Temperature
812 Double_t cCoupling = 17.5; // Coupling capacitance [pF]
813 Double_t cInterstrip = 1.; // Inter-strip capacitance
814 fUserParCond = new CbmStsParSensorCond(vFd, vBias, temperature, cCoupling, cInterstrip);
815}
816// -------------------------------------------------------------------------
817
818
819// ----- Set the global module parameters ------------------------------
820void CbmStsDigitize::SetGlobalAsicParams(UShort_t nChannels, UShort_t nAdc, Double_t dynRange, Double_t threshold,
821 Double_t timeResolution, Double_t deadTime, Double_t noise,
822 Double_t zeroNoiseRate)
823{
824 assert(!fIsInitialised);
825 assert(nAdc > 0);
826 if (fUserParAsic) delete fUserParAsic;
828 new CbmStsParAsic(nChannels, nAdc, dynRange, threshold, timeResolution, deadTime, noise, zeroNoiseRate);
829}
830// -------------------------------------------------------------------------
831
832
833// ----- Set the global module parameters ------------------------------
834void CbmStsDigitize::SetGlobalModuleParams(UInt_t nChannels, UInt_t nAsicChannels)
835{
836 assert(!fIsInitialised);
837
838 if (fUserParModule) delete fUserParModule;
839 fUserParModule = new CbmStsParModule(nChannels, nAsicChannels);
840}
841// -------------------------------------------------------------------------
842
843
844// ----- Set the global sensor conditions ------------------------------
845void CbmStsDigitize::SetGlobalSensorConditions(Double_t vFd, Double_t vBias, Double_t temperature, Double_t cCoupling,
846 Double_t cInterstrip)
847{
848 assert(!fIsInitialised);
849
850 if (fUserParCond) delete fUserParCond;
851 fUserParCond = new CbmStsParSensorCond(vFd, vBias, temperature, cCoupling, cInterstrip);
852}
853// -------------------------------------------------------------------------
854
855
856// ----- Set sensor parameter file -------------------------------------
858{
859
860 assert(!fIsInitialised);
861 fModuleParameterFile = fileName;
862}
863// -------------------------------------------------------------------------
864
865
866// ----- Set physical processes for the analogue response ---------------
867void CbmStsDigitize::SetProcesses(CbmStsELoss eLossModel, Bool_t useLorentzShift, Bool_t useDiffusion,
868 Bool_t useCrossTalk)
869{
870 if (fIsInitialised) {
871 LOG(error) << GetName() << ": physics processes must be set before "
872 << "initialisation! Statement will have no effect.";
873 return;
874 }
875
876 fUserParSim->SetProcesses(eLossModel, useLorentzShift, useDiffusion, useCrossTalk);
877}
878// -------------------------------------------------------------------------
879
880
881// ----- Set sensor condition file -------------------------------------
883{
884
885 if (fIsInitialised) {
886 LOG(fatal) << GetName() << ": sensor conditions must be set before initialisation!";
887 return;
888 }
889 fSensorConditionFile = fileName;
890}
891// -------------------------------------------------------------------------
892
893
894// ----- Set sensor parameter file -------------------------------------
896{
897
898 if (fIsInitialised) {
899 LOG(fatal) << GetName() << ": sensor parameters must be set before initialisation!";
900 return;
901 }
902 fSensorParameterFile = fileName;
903}
904// -------------------------------------------------------------------------
905
906
907// ----- Usage of primary tracks only ----------------------------------
909// -------------------------------------------------------------------------
910
ClassImp(CbmConverterManager)
CbmStsSensorClass
Sensor classes.
Definition CbmStsDefs.h:68
CbmStsELoss
Energy loss model used in simulation.
Definition CbmStsDefs.h:49
TString fInactiveChannelFileName
Time of current MC event [ns].
Double_t fRunStartTime
Flag for creation of links to MC.
void GetEventInfo()
Get event information.
Int_t fCurrentInput
Start time of run [ns].
Double_t fCurrentEventTime
Number of current MC entry.
Int_t fCurrentMCEntry
Number of current MC event.
Bool_t fCreateMatches
Flag for production of inter-event noise.
Bool_t fProduceNoise
Flag for event-by-event mode.
Base class template for CBM digitisation tasks.
Definition CbmDigitize.h:44
void SendData(Double_t time, CbmStsDigi *digi, CbmMatch *match=nullptr)
uint32_t GetGeantProcessId() const
Definition CbmMCTrack.h:67
Data class for a single-channel message in the STS.
Definition CbmStsDigi.h:40
Task class for simulating the detector response of the STS.
TString fSensorConditionFile
File with sensor conditions.
Double_t fTimeTot
Total execution time.
void SetGlobalDefaults()
Set global default parameters.
UInt_t InitModules()
Instantiate modules.
virtual void Exec(Option_t *opt)
Bool_t fIsInitialised
kTRUE if Init() was called
Double_t fNofPointsIgnoTot
Total number of ignored points.
virtual ~CbmStsDigitize()
CbmStsParModule * fUserParModule
User defined, global.
void SetSensorParameterFile(const char *fileName)
Set the file name with sensor parameters.
TClonesArray * fTracks
Input array of CbmMCTrack.
void SetSensorConditionFile(const char *fileName)
Set the file name with sensor conditions.
Int_t fNofSignalsF
Number of signals on front side.
TClonesArray * fPoints
Sensor factory.
CbmStsParAsic * fUserParAsic
User defined, global.
std::map< UInt_t, std::unique_ptr< CbmStsSimSensor > > fSensors
virtual InitStatus Init()
Double_t fNofSignalsFTot
Number of signals on front side.
void SetGlobalModuleParams(UInt_t nChannels, UInt_t nAsicChannels)
Set the global module parameters.
Int_t fNofPointsProc
Number of processed points.
Double_t fTimeDigiFirst
Time of first digi sent to DAQ.
CbmStsSimSensorFactory * fSensorFactory
STS setup interface.
TStopwatch fTimer
ROOT timer.
void ProcessAnalogBuffers(Double_t readoutTime)
Int_t fNofDigis
Number of created digis in Exec.
Int_t BufferSize() const
Number of signals in the analogue buffers @value nSignals Sum of number of signals in all modules.
TString fModuleParameterFile
File with module parameters.
Double_t fNofDigisTot
Total number of digis created.
CbmStsParSensor * fUserParSensor
User defined, global.
TString fSensorParameterFile
File with sensor parameters.
CbmStsParSim * fParSim
Simulation settings.
void SetGlobalAsicParams(UShort_t nChannels, UShort_t nAdc, Double_t dynRange, Double_t threshold, Double_t timeResolution, Double_t deadTime, Double_t noise, Double_t zeroNoiseRate)
Set individual module parameters.
void UseOnlyPrimaries(Bool_t flag=kTRUE)
Discard processing of secondary tracks.
virtual InitStatus ReInit()
Double_t fNofPointsProcTot
Total number of processed points.
CbmStsParSetModule * fParSetModule
Module parameter.
std::map< UInt_t, CbmStsSimModule * > fModules
virtual void Finish()
CbmStsSetup * fSetup
Double_t fNofNoiseTot
Total number of noise digis.
void ProcessPoint(const CbmStsPoint *point, Double_t eventTime, const CbmLink &link)
CbmStsParSim * fUserParSim
Settings for simulation.
CbmStsParSetSensorCond * fParSetCond
Sensor conditions.
bool IsChannelActiveSts(Int_t address, UShort_t channel)
Test if the channel of a digi object is set active.
void CreateDigi(Int_t address, UShort_t channel, Long64_t time, UShort_t adc, const CbmMatch &match)
std::pair< size_t, bool > ReadInactiveChannels()
Read the list of inactive channels from file.
std::string BufferStatus() const
Status of the analogue buffers.
void SetProcesses(CbmStsELoss eLossModel, Bool_t useLorentzShift=kTRUE, Bool_t useDiffusion=kTRUE, Bool_t useCrossTalk=kTRUE)
Double_t fUserFracDeadChan
Fraction of inactive ASIC channels.
void InitParams()
Initialise the parameters.
std::map< Int_t, std::set< UShort_t > > fInactiveChannelsSts
Int_t fNofEvents
Total number of processed events.
void SetGlobalSensorConditions(Double_t vDep, Double_t vBias, Double_t temperature, Double_t cCoupling, Double_t cInterstrip)
Set the global sensor conditions.
void SetModuleParameterFile(const char *fileName)
Set the file name with module parameters.
CbmStsParSensorCond * fUserParCond
User defined, global.
Int_t fNofPointsIgno
Number of ignored points.
Int_t fNofSignalsB
Number of signals on back side.
Double_t fNofSignalsBTot
Number of signals on back side.
UInt_t InitSensors()
Instantiate sensors.
Double_t fUserDinactive
Size of inactive sensor border [cm].
void ResetCounters()
Reset event counters.
CbmStsParSetSensor * fParSetSensor
Sensor parameters.
virtual void SetParContainers()
Inherited from FairTask.
Double_t fTimeDigiLast
Time of last digi sent to DAQ.
Class representing an element of the STS setup.
CbmStsElement * GetMother() const
Int_t GetAddress() const
TGeoPhysicalNode * GetPnode() const
Parameters of the STS readout ASIC.
std::string ToString() const
Info to string.
Parameters for one STS module.
void SetAllAsics(const CbmStsParAsic &asicPar)
Set all ASICs with the same parameter set.
Parameters for operating conditions of a STS sensor.
Constructional parameters of a STS sensor.
void SetPar(UInt_t index, Float_t value)
Set a parameter.
CbmStsSensorClass GetClass() const
Get the sensor class.
Float_t GetPar(UInt_t index) const
Get a parameter.
Parameters container for CbmStsParModule.
const CbmStsParModule & GetParModule(UInt_t address)
Get condition parameters of a sensor.
virtual void clear()
Reset all parameters.
void SetParModule(UInt_t address, const CbmStsParModule &par)
Set the parameters for a module.
UInt_t DeactivateRandomChannels(Double_t fraction)
Randomly deactivate a fraction of the channels.
std::string ToString() const
Info to string.
Parameters container for CbmStsParSensorCond.
std::string ToString()
Info to string.
void SetGlobalPar(Double_t vDep, Double_t vBias, Double_t temperature, Double_t cCoupling, Double_t cInterstrip)
Set global conditions (for all sensors)
virtual void clear()
Reset all parameters.
const CbmStsParSensorCond & GetParSensor(UInt_t address)
Get condition parameters of a sensor.
Parameters container for CbmStsParSensor.
void SetParSensor(UInt_t address, const CbmStsParSensor &par)
Set the parameters for a sensor.
std::string ToString() const
Info to string.
const CbmStsParSensor & GetParSensor(UInt_t address)
Get condition parameters of a sensor.
virtual void clear()
Reset all parameters.
Settings for STS simulation (digitizer)
std::string ToString() const
String output.
Bool_t Noise() const
Check whether inter-event noise is generated.
void SetGenerateNoise(Bool_t choice=kTRUE)
Activate or de-activate inter-event noise.
void SetProcesses(CbmStsELoss eLossModel, Bool_t useLorentzShift, Bool_t useDiffusion, Bool_t useCrossTalk)
void SetEventMode(Bool_t choice=kTRUE)
Set event-by-event simulation mode.
void SetOnlyPrimaries(Bool_t choice=kTRUE)
Process only primary tracks.
Bool_t OnlyPrimaries() const
Process only primary tracks.
static CbmStsPhysics * Instance()
Accessor to singleton instance.
Class representing an instance of a sensor in the CBM-STS.
Int_t GetNofSensors() const
Definition CbmStsSetup.h:90
Bool_t Init(const char *geometryFile=nullptr)
Initialise the setup.
CbmStsModule * GetModule(Int_t index) const
Get a module from the module array.
Definition CbmStsSetup.h:72
UInt_t SetSensorConditions(CbmStsParSetSensorCond *conds)
Set sensor conditions from parameter container.
static CbmStsSetup * Instance()
UInt_t SetModuleParameters(CbmStsParSetModule *modulePars)
Set module parameters from parameter container.
CbmStsSensor * GetSensor(Int_t index) const
Get a sensor from the sensor array.
Definition CbmStsSetup.h:82
UInt_t SetSensorParameters(CbmStsParSetSensor *parSet)
Set sensor parameters from parameter container.
Int_t GetNofModules() const
Definition CbmStsSetup.h:86
Class for the simulation of a readout unit in the CBM-STS.
UP_sensor CreateSensor(const CbmStsParSensor &par)
Create a sensor.