23#include <FairRootManager.h>
26#include <TClonesArray.h>
29#include <TStopwatch.h>
38using std::setprecision;
43 std::cout << std::endl;
44 LOG(info) <<
"==========================================================";
45 LOG(info) << GetName() <<
": Initialisation";
47 if (!
fEventMode) { LOG(info) <<
"CbmRichDigitizer uses TimeBased mode."; }
49 LOG(info) <<
"CbmRichDigitizer uses Events mode.";
52 FairRootManager* manager = FairRootManager::Instance();
59 fRichPoints =
static_cast<TClonesArray*
>(manager->GetObject(
"RichPoint"));
60 if (!
fRichPoints) LOG(fatal) <<
"CbmRichDigitizer::Init: No RichPoint array!";
62 fMcTracks =
static_cast<TClonesArray*
>(manager->GetObject(
"MCTrack"));
63 if (!
fMcTracks) LOG(fatal) <<
"CbmRichDigitizer::Init: No MCTrack array!";
72 LOG(error) << GetName() <<
": Error in reading from file! Task will be inactive.";
75 LOG(info) << GetName() <<
": " << std::get<0>(result) <<
" lines read from file, " <<
fInactiveChannels.size()
76 <<
" channels set inactive";
79 LOG(info) << GetName() <<
": Initialisation successful";
80 LOG(info) <<
"==========================================================";
81 std::cout << std::endl;
111 LOG(info) <<
"+ " << setw(15) << GetName() <<
": Event " << setw(6) << right <<
fCurrentEvent <<
" at " << fixed
112 << setprecision(3) <<
fCurrentEventTime <<
" ns, points: " << nPoints <<
", digis: " << nDigis
113 <<
". Exec time " << setprecision(6) << timer.RealTime() <<
" s.";
120 std::cout << std::endl;
121 LOG(info) << GetName() <<
": Finish run";
122 LOG(info) << GetName() <<
": Processing analogue buffers";
127 LOG(info) << GetName() <<
": " << nDigis <<
" digis created and sent to DAQ";
131 std::cout << std::endl;
132 LOG(info) <<
"=====================================";
133 LOG(info) << GetName() <<
": Run summary";
134 LOG(info) <<
"Events processed : " <<
fEventNum;
135 LOG(info) <<
"RichPoint / event : " << setprecision(6) <<
fNofPoints / Double_t(
fEventNum);
139 LOG(info) <<
"=====================================";
144 Int_t nofRichPoints =
fRichPoints->GetEntriesFast();
149 for (Int_t j = 0; j < nofRichPoints; j++) {
156 return nofRichPoints;
161 Int_t address = point->GetDetectorID();
163 LOG(error) <<
"CbmRichDigitizer::ProcessPoint: address == -1";
166 Int_t trackId = point->GetTrackID();
167 if (trackId < 0)
return;
169 if (!mcTrack)
return;
170 Int_t gcode = TMath::Abs(mcTrack->
GetPdgCode());
172 Bool_t isDetected =
false;
174 if (gcode == 50000050) {
176 point->Momentum(mom);
177 Double_t momTotal = TMath::Sqrt(mom.Px() * mom.Px() + mom.Py() * mom.Py() + mom.Pz() * mom.Pz());
188 CbmLink link(1., pointId, eventNum, inputNum);
190 if (gcode == 50000050 && address > 0)
AddCrossTalk(address, time, link);
204 std::vector<Int_t> directHorizontalPixels =
206 std::vector<Int_t> directVerticalPixels =
210 Double_t crosstalkProbability = 1 - pow(1 -
fCrossTalkProbability[0], directHorizontalPixels.size()) *
213 Int_t crosstalkAddress = -1;
214 if (gRandom->Uniform() < crosstalkProbability) {
222 Double_t rnd = gRandom->Uniform();
223 if (rnd < thHorizontal) {
224 crosstalkAddress = directHorizontalPixels[gRandom->Integer(directHorizontalPixels.size())];
226 else if (rnd < thVertical) {
227 crosstalkAddress = directVerticalPixels[gRandom->Integer(directVerticalPixels.size())];
229 crosstalkAddress = diagonalPixels[gRandom->Integer(diagonalPixels.size())];
240 std::vector<Int_t> neighbourAddresses =
242 for (
const Int_t& addr : neighbourAddresses) {
244 Double_t d = TMath::Sqrt((sourcePixelIdx.rem - iPixelIdx.rem) * (sourcePixelIdx.rem - iPixelIdx.rem)
245 + (sourcePixelIdx.quot - iPixelIdx.quot) * (sourcePixelIdx.quot - iPixelIdx.quot));
247 CbmLink link(1., -1, eventNum, inputNum);
256 Double_t nofRichPoints =
fRichPoints->GetEntriesFast();
259 LOG(debug) <<
"CbmRichDigitizer::AddEventNoise NofAllPixels:" << nofPixels <<
" nofNoiseDigis:" << nofNoiseDigis;
261 for (Int_t j = 0; j < nofNoiseDigis; j++) {
263 CbmLink link(1., -1, eventNum, inputNum);
272 Double_t dT = newEventTime - oldEventTime;
275 LOG(debug) <<
"CbmRichDigitizer::AddDarkRateNoise deltaTime:" << dT <<
" nofPixels:" << nofPixels
276 <<
" nofNoisePixels:" << nofNoisePixels;
278 for (Int_t j = 0; j < nofNoisePixels; j++) {
281 Double_t time = gRandom->Uniform(oldEventTime, newEventTime);
293 dm.second.begin(), dm.second.end(),
294 [](
const std::pair<Double_t, CbmLink*>& a,
const std::pair<Double_t, CbmLink*>& b) { return a.first < b.first; });
298 auto it = dm.second.begin();
299 for (; it != dm.second.end(); ++it) {
300 Double_t signalTime = it->first;
301 if (processTime >= 0. && signalTime > processTime)
break;
303 Bool_t createsDigi =
true;
307 Double_t lastFiredTime = itFpm->second;
308 if (signalTime - lastFiredTime <
fPixelDeadTime) createsDigi =
false;
319 if (processTime >= 0. && digiTime > maxNewDigiTime)
break;
330 if (digi && digiMatch) digiMatch->
AddLink(*link);
334 dm.second.erase(dm.second.begin(), it);
ClassImp(CbmConverterManager)
Class for producing RICH digis from from MCPoints.
virtual std::pair< size_t, bool > ReadInactiveChannels()
Set of inactive channels, indicated by CbmAddress.
Int_t fCurrentEvent
Number of current input.
TString fInactiveChannelFileName
Time of current MC event [ns].
std::set< uint32_t > fInactiveChannels
Name of file with inactive channels.
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.
void SendData(Double_t time, CbmRichDigi *digi, CbmMatch *match=nullptr)
double GetCharge() const
Charge of the associated particle.
int32_t GetPdgCode() const
void AddLink(const CbmLink &newLink)
static CbmRichDigiMapManager & GetInstance()
Return Instance of CbmRichGeoManager.
std::vector< Int_t > GetDirectNeighbourPixels(Int_t address, Bool_t horizontal=true, Bool_t vertical=true)
Return the addresses of the direct neighbour pixels.
std::vector< Int_t > GetNxNNeighbourPixels(Int_t address, Int_t n)
Return the addresses of pixels in a (2n+1)*(2n+1) grid, with the address pixel in the center of the g...
Int_t GetRandomPixelAddress()
Return random address. Needed for noise digi.
std::vector< Int_t > GetPixelAddresses()
Return addresses of all pixels.
std::vector< Int_t > GetDiagonalNeighbourPixels(Int_t address)
Return the addresses of the diagonal neighbour pixels.
void SetTime(double time)
void SetAddress(int32_t address)
Class for producing RICH digis from from MCPoints.
Int_t ProcessBuffers(Double_t processTime)
Process signals in all buffers until processTime. New Digis are only created until processTime - fPix...
virtual void Exec(Option_t *option)
std::map< Int_t, Double_t > fPixelsLastFiredTime
Double_t fDarkRatePerPixel
Int_t ProcessMcEvent()
Process current MC event.
std::map< Int_t, std::vector< std::pair< Double_t, CbmLink * > > > fSignalBuffer
TClonesArray * fRichPoints
std::array< Double_t, 3 > fCrossTalkProbability
Double_t fClusterSignalProbability
void ProcessPoint(CbmRichPoint *point, Int_t pointId, Int_t eventNum, Int_t inputNum)
CbmRichPmtTypeEnum fDetectorType
Double_t fEventNoiseInterval
virtual InitStatus Init()
void AddEventNoise(Int_t eventNum, Int_t inputNum)
Add additional noise for each event based on fEventNoiseRate and fEventNoiseInterval.
void AddCrossTalk(Int_t address, Double_t time, const CbmLink &link)
Add crosstalk assuming fCrossTalkProbability. Only add maximum one cross talk signal per MC point....
void AddSignalToBuffer(Int_t address, Double_t time, const CbmLink &link)
void AddChargedParticleCluster(Int_t address, Double_t time, Int_t eventNum, Int_t inputNum)
Add additional signals to nearby pixels if a charged particle directly passes through the PMT,...
void AddDarkRateNoise(Double_t oldEventTime, Double_t newEventTime)
static CbmRichGeoManager & GetInstance()
Bool_t isPhotonDetected(CbmRichPmtTypeEnum detType, Double_t momentum)