19#include "TClonesArray.h"
21#include "TGeoMatrix.h"
22#include "TGeoPhysicalNode.h"
23#include "TGeoVolume.h"
26#include "FairEventHeader.h"
29#include "FairLogger.h"
30#include "FairMCEventHeader.h"
31#include "FairMCPoint.h"
32#include "FairRunAna.h"
33#include "FairRunSim.h"
34#include "FairRuntimeDb.h"
39#include "CbmMCTrack.h"
53using std::setprecision;
89 fSensorTemperature(268.),
90 fSensorCcoupling(17.5),
91 fSensorCinterstrip(1.),
92 fModuleDynRange(75000.),
93 fModuleThreshold(3000.),
98 fModuleZeroNoiseRate(3.9789e-3),
99 fModuleFracDeadChan(0.),
100 fSensorParameterFile(),
101 fSensorConditionFile(),
102 fModuleParameterFile(),
126 LOG(debug) <<
"Destructing " << fName;
136Int_t BmnSsdDigitize::BufferSize()
const {
142 for (Int_t iModule = 0; iModule < fSetup->
GetNofModules(); iModule++) {
144 nSignals += nSigModule;
154string BmnSsdDigitize::BufferStatus()
const {
164 for (Int_t iModule = 0; iModule < fSetup->
GetNofModules(); iModule++) {
167 nSignals += nSigModule;
168 t1 = t1 < 0. ? t1Module : TMath::Min(t1, t1Module);
169 t2 = TMath::Max(t2, t2Module);
173 std::stringstream ss;
174 ss << nSignals << ( nSignals == 1 ?
" signal " :
" signals " )
175 <<
"in analogue buffers";
176 if ( nSignals ) ss <<
" ( from " << fixed << setprecision(3)
177 << t1 <<
" ns to " << t2 <<
" ns )";
194 fTimeDigiFirst = fNofDigis ?
195 TMath::Min(fTimeDigiFirst, Double_t(time)) : time;
196 fTimeDigiLast = TMath::Max(fTimeDigiLast, Double_t(time));
206 LOG(debug3) << GetName() <<
": created digi at " << time
207 <<
" ns with ADC " << adc <<
" at address " << address
210 <<
", channel " << channel
226 if ( gLogger->IsLogNeeded(DEBUG)) {
227 std::cout << std::endl;
228 LOG(debug) << GetName() <<
": " << BufferStatus();
238 Double_t tNoiseStart = fNofEvents ? eventTimePrevious : 0.;
240 for (Int_t iModule = 0; iModule < fSetup->
GetNofModules(); iModule++)
243 fNofNoiseTot += Double_t(nNoise);
244 LOG(info) <<
"+ " << setw(20) << GetName() <<
": Generated " << nNoise
245 <<
" noise signals from t = " << tNoiseStart <<
" ns to "
246 << tNoiseEnd <<
" ns";
251 LOG(debug) << GetName() <<
": " << fNofSignalsF + fNofSignalsB
252 <<
" signals generated ( "
253 << fNofSignalsF <<
" / " << fNofSignalsB <<
" )"
256 if ( gLogger->IsLogNeeded(DEBUG)) {
257 LOG(debug) << GetName() <<
": " << BufferStatus();
268 ProcessAnalogBuffers(readoutTime);
271 if ( gLogger->IsLogNeeded(DEBUG)) {
272 LOG(debug) << GetName() <<
": " << BufferStatus();
276 LOG(info) <<
"+ " << setw(15) << GetName() <<
": Event " << setw(6)
277 << right <<
fCurrentEvent <<
" at " << fixed << setprecision(3)
279 <<
", signals: " << fNofSignalsF <<
" / " << fNofSignalsB
280 <<
", digis: " << fNofDigis <<
". Exec time " << setprecision(6)
281 << fTimer.RealTime() <<
" s.";
286 fNofPointsTot += fNofPoints;
287 fNofSignalsFTot += fNofSignalsF;
288 fNofSignalsBTot += fNofSignalsB;
289 fNofDigisTot += fNofDigis;
290 fTimeTot += fTimer.RealTime();
298void BmnSsdDigitize::Finish() {
309 if ( BufferSize() ) {
310 LOG(info) << fName << BufferStatus();
311 LOG(fatal) << fName <<
": Non-empty analogue buffers at end of event "
312 <<
" in event-by-event mode!";
318 std::cout << std::endl;
319 LOG(info) << GetName() <<
": Finish run";
320 LOG(info) << GetName() <<
": " << BufferStatus()
322 LOG(info) << GetName() <<
": Processing analogue buffers"
326 for (Int_t iModule = 0; iModule < fSetup->
GetNofModules(); iModule++)
330 LOG(info) << GetName() <<
": " << fNofDigis
331 << ( fNofDigis == 1 ?
" digi " :
" digis " )
332 <<
"created and sent to DAQ ";
333 if ( fNofDigis ) LOG(debug) <<
"( from " << fixed
334 << setprecision(3) << fTimeDigiFirst <<
" ns to "
335 << fTimeDigiLast <<
" ns )";
337 LOG(info) << GetName() <<
": " << BufferStatus()
342 fNofPointsTot += fNofPoints;
343 fNofSignalsFTot += fNofSignalsF;
344 fNofSignalsBTot += fNofSignalsB;
345 fNofDigisTot += fNofDigis;
346 fTimeTot += fTimer.RealTime();
348 std::cout << std::endl;
349 LOG(info) <<
"=====================================";
350 LOG(info) << GetName() <<
": Run summary";
351 LOG(info) <<
"Events processed : " << fNofEvents;
352 LOG(info) <<
"SsdPoint / event : " << setprecision(1)
353 << fNofPointsTot / Double_t(fNofEvents)
355 LOG(info) <<
"Signals / event : "
356 << fNofSignalsFTot / Double_t(fNofEvents)
357 <<
" / " << fNofSignalsBTot / Double_t(fNofEvents)
359 LOG(info) <<
"SsdDigi / event : "
360 << fNofDigisTot / Double_t(fNofEvents);
361 LOG(info) <<
"Digis per point : " << setprecision(6)
362 << fNofDigisTot / fNofPointsTot;
363 LOG(info) <<
"Digis per signal : "
364 << fNofDigisTot / ( fNofSignalsFTot + fNofSignalsBTot )
366 LOG(info) <<
"Noise digis / event : " << fNofNoiseTot / Double_t(fNofEvents)
368 LOG(info) <<
"Noise fraction : " << fNofNoiseTot / fNofDigisTot
370 LOG(info) <<
"Real time per event : " << fTimeTot / Double_t(fNofEvents)
372 LOG(info) <<
"=====================================";
413InitStatus BmnSsdDigitize::Init() {
419 std::cout << std::endl;
420 LOG(info) <<
"==========================================================";
421 LOG(info) << GetName() <<
": Initialisation";
425 LOG(info) << GetName() <<
": Using event mode.";
436 fUseCrossTalk, fGenerateNoise);
442 FairRootManager* ioman = FairRootManager::Instance();
446 fPoints = (TClonesArray*) ioman->GetObject(
"SsdPoint");
450 fTracks = (TClonesArray*) ioman->GetObject(
"MCTrack");
454 fDigis =
new TClonesArray(
"BmnSsdDigi",1000);
455 ioman->Register(
"SsdDigi",
"SSD", fDigis,
456 IsOutputBranchPersistent(
"SsdDigi"));
461 fMatches =
new TClonesArray(
"BmnMatch", 1000);
462 ioman->Register(
"SsdDigiMatch",
"SSD", fMatches,
463 IsOutputBranchPersistent(
"SsdDigiMatch"));
467 LOG(info) << GetName() <<
": Initialisation successful"
469 LOG(info) <<
"=========================================================="
471 std::cout << std::endl;
474 fIsInitialised = kTRUE;
494 fSensorStereoF, fSensorStereoB);
495 if ( fSensorParameterFile.IsNull() ) fSetup->
Init();
496 else fSetup->
Init(
nullptr, fSensorParameterFile);
499 if ( fSensorConditionFile.IsNull() )
501 fSensorTemperature, fSensorCcoupling,
507 if ( fModuleParameterFile.IsNull() )
509 fModuleNofAdc, fModuleTresol, fModuleTdead,
510 fModuleNoise, fModuleZeroNoiseRate,
511 fModuleFracDeadChan);
521void BmnSsdDigitize::ProcessAnalogBuffers(Double_t readoutTime) {
524 LOG(debug) << GetName() <<
": Processing analog buffers with readout "
525 <<
"time " << readoutTime <<
" ns";
528 for (Int_t iModule = 0; iModule < fSetup->
GetNofModules(); iModule++)
532 LOG(debug) << GetName() <<
": " << fNofDigis
533 << ( fNofDigis == 1 ?
" digi " :
" digis " )
534 <<
"created and sent to DAQ ";
535 if ( fNofDigis ) LOG(debug) <<
"( from " << fixed
536 << setprecision(3) << fTimeDigiFirst <<
" ns to "
537 << fTimeDigiLast <<
" ns )";
546void BmnSsdDigitize::ProcessMCEvent() {
549 LOG(debug) << GetName() <<
": Processing event " <<
fCurrentEvent
551 <<
" ns with " << fPoints->GetEntriesFast() <<
" SsdPoints "
557 for (Int_t iPoint=0; iPoint<fPoints->GetEntriesFast(); iPoint++) {
563 Int_t iTrack = point->GetTrackID();
582void BmnSsdDigitize::ProcessPoint(
const BmnSsdPoint* point,
583 Double_t eventTime,
BmnLink* link) {
586 if ( FairLogger::GetLogger()->IsLogNeeded(DEBUG2) ) point->Print();
587 LOG(debug2) << GetName() <<
": Point coordinates: in (" << point->
GetXIn()
588 <<
", " << point->
GetYIn() <<
", " << point->
GetZIn() <<
")"
590 <<
", " << point->
GetZOut() <<
")";
594 Int_t address = point->GetDetectorID();
598 LOG(info) << GetName() <<
": No sensor for address " << address
607 if ( ! sensor ) LOG(error) << GetName() <<
": Sensor of SsdPoint not found!"
610 LOG(debug2) << GetName() <<
": Sending point to sensor "
611 << sensor->GetName() <<
" ( " << sensor->
GetAddress()
615 Int_t status = sensor->
ProcessPoint(point, eventTime, link);
618 Int_t nSignalsF = status / 1000;
619 Int_t nSignalsB = status - 1000 * nSignalsF;
620 LOG(debug2) << GetName() <<
": Produced signals: "
621 << nSignalsF + nSignalsB <<
" ( " << nSignalsF <<
" / "
622 << nSignalsB <<
" )";
623 fNofSignalsF += nSignalsF;
624 fNofSignalsB += nSignalsB;
645 if ( fDigis ) fDigis->Delete();
646 if ( fMatches ) fMatches->Delete();
653void BmnSsdDigitize::ResetCounters() {
654 fTimeDigiFirst = fTimeDigiLast = -1.;
655 fNofPoints = fNofSignalsF = fNofSignalsB = fNofDigis = 0;
665 Double_t timeResolution,
668 Double_t zeroNoiseRate,
669 Double_t fracDeadChan) {
670 assert( ! fIsInitialised );
672 assert( fracDeadChan >= 0. && fracDeadChan <= 1.);
673 fModuleDynRange = dynRange;
674 fModuleThreshold = threshold;
675 fModuleNofAdc = nAdc;
676 fModuleTresol = timeResolution;
677 fModuleTdead = deadTime;
678 fModuleNoise = noise;
679 fModuleZeroNoiseRate = zeroNoiseRate;
680 fModuleFracDeadChan = fracDeadChan;
689 Double_t temperature,
691 Double_t cInterstrip) {
692 assert( ! fIsInitialised );
694 fSensorVbias = vBias;
695 fSensorTemperature = temperature;
696 fSensorCcoupling = cCoupling;
697 fSensorCinterstrip = cInterstrip;
708 assert( ! fIsInitialised );
709 assert( dInact >= 0.);
710 assert( pitch >= 0. );
711 fSensorDinact = dInact;
712 fSensorPitch = pitch;
713 fSensorStereoF = stereoF;
714 fSensorStereoB = stereoB;
723 if ( fIsInitialised ) {
724 LOG(error) << GetName() <<
": physics processes must be set before "
725 <<
"initialisation! Statement will have no effect."
730 fGenerateNoise = choice;
739 assert( ! fIsInitialised );
740 fModuleParameterFile = fileName;
749 Int_t nAdc, Double_t timeResolution,
750 Double_t deadTime, Double_t noise,
751 Double_t zeroNoiseRate,
752 Double_t deadChannelFrac) {
754 if ( fIsInitialised ) {
755 LOG(error) << GetName() <<
": physics processes must be set before "
756 <<
"initialisation! Statement will have no effect."
762 deadTime, noise, zeroNoiseRate,
771 Bool_t useLorentzShift,
774 Bool_t generateNoise) {
775 if ( fIsInitialised ) {
776 LOG(error) << GetName() <<
": physics processes must be set before "
777 <<
"initialisation! Statement will have no effect."
781 fEnergyLossModel = eLossModel;
782 fUseLorentzShift = useLorentzShift;
783 fUseDiffusion = useDiffusion;
784 fUseCrossTalk = useCrossTalk;
785 fGenerateNoise = generateNoise;
794 if ( fIsInitialised ) {
795 LOG(fatal) << GetName()
796 <<
": sensor conditions must be set before initialisation!"
800 fSensorConditionFile = fileName;
810 if ( fIsInitialised ) {
811 LOG(fatal) << GetName()
812 <<
": sensor parameters must be set before initialisation!"
816 fSensorParameterFile = fileName;
828 if ( ! ssdDigi ) LOG(fatal) << fName
829 <<
": not a valid SsdDigi pointer!";
833 Int_t nDigis = fDigis->GetEntriesFast();
834 new( (*fDigis)[nDigis] )
BmnSsdDigi(*ssdDigi);
Bool_t fIsInitialised
kTRUE if Init() was called
Int_t fEnergyLossModel
Energy loss model.
BmnSsdDigitizeParameters * fDigiPar
Digitisation parameters.
Base class for persistent representation of digital information.
BmnMatch * GetMatch() const
void SetMatch(BmnMatch *match)
Abstract base class for BMN digitisation tasks.
void GetEventInfo()
Get event information.
Double_t fCurrentEventTime
void SendDigi(BmnDigi *digi)
Send a digi object to the DAQ.
Data class for a single-channel message in the SSD.
Parameters for SSD digitization.
void SetModuleParameters(Double_t dynRange, Double_t threshold, Int_t nAdc, Double_t timeResol, Double_t deadTime, Double_t noise, Double_t zeroNoiseRate, Double_t deadChannelFrac)
Set digital response parameters.
Bool_t GetGenerateNoise() const
void SetProcesses(Int_t eLossModel, Bool_t useLorentzShift, Bool_t useDiffusion, Bool_t useCrossTalk, Bool_t generateNoise=kFALSE)
Switch analogue response processes on or off.
Bool_t GetDiscardSecondaries() const
virtual std::string ToString() const
void SetModuleParameterFile(const char *fileName)
Set the file name with module parameters.
virtual void Exec(Option_t *opt)
void SetParameters(Double_t dynRange, Double_t threshold, Int_t nAdc, Double_t timeResolution, Double_t deadTime, Double_t noise, Double_t zeroNoiseRate, Double_t deadChannelFrac=0.)
void SetProcesses(Int_t eLossModel, Bool_t useLorentzShift=kTRUE, Bool_t useDiffusion=kTRUE, Bool_t useCrossTalk=kTRUE, Bool_t generateNoise=kFALSE)
void CreateDigi(Int_t address, UShort_t channel, Long64_t time, UShort_t adc, const BmnMatch &match)
void SetDefaultSensorConditions(Double_t vDep, Double_t vBias, Double_t temperature, Double_t cCoupling, Double_t cInterstrip)
Set the default sensor conditions.
virtual InitStatus ReInit()
virtual void ResetArrays()
Clear data arrays.
virtual ~BmnSsdDigitize()
void SetSensorParameterFile(const char *fileName)
Set the file name with sensor parameters.
void SetGenerateNoise(Bool_t choise=kTRUE)
Activate noise generation.
void SetDefaultModuleParameters(Double_t dynRange, Double_t threshold, Int_t nAdc, Double_t timeResolution, Double_t deadTime, Double_t noise, Double_t zeroNoiseRate, Double_t fracDeadChan)
Set the default module parameters.
void SetDefaultSensorParameters(Double_t dInact, Double_t pitch, Double_t stereoF, Double_t stereoB)
Set the default sensor parameters.
virtual void WriteDigi(BmnDigi *digi)
Write a digi to the output tree.
virtual void SetParContainers()
Inherited from FairTask.
void SetSensorConditionFile(const char *fileName)
Set the file name with sensor conditions.
Int_t ProcessAnalogBuffer(Double_t readoutTime)
Int_t GenerateNoise(Double_t t1, Double_t t2)
Generate noise.
void BufferStatus(Int_t &nofSignals, Double_t &timeFirst, Double_t &timeLast)
static BmnSsdPhysics * Instance()
Class representing an instance of a sensor in the BMN-SSD.
Int_t ProcessPoint(const BmnSsdPoint *point, Double_t eventTime=0., BmnLink *link=NULL)
void SetDefaultSensorParameters(Double_t dInact, Double_t pitch, Double_t stereoF, Double_t stereoB)
Set the default sensor parameters.
static BmnSsdSetup * Instance()
Int_t SetModuleParameters(Double_t dynRange, Double_t threshold, Int_t nAdc, Double_t timeResolution, Double_t deadTime, Double_t noise, Double_t zeroNoiseRate, Double_t fracDeadChannels)
Set parameters for all modules.
void SetDigitizer(BmnSsdDigitize *digitizer)
Set the digitiser task.
Int_t GetNofModules() const
BmnSsdModule * GetModule(Int_t index)
Get a module from the module array.
Bool_t Init(const char *geometryFile=nullptr, const char *sensorParameterFile=nullptr)
Initialise the setup.
Int_t SetSensorConditions()
Set conditions for all sensors (same values for all)
BmnSsdElement * GetElement(Int_t address, Int_t level)
void SetDigiParameters(BmnSsdDigitizeParameters *settings)
Set the digitiser parameters.
Int_t GetMotherId() const
UInt_t GetElementId(Int_t address, Int_t level)
Get the index of an element.