FairRoot/PandaRoot
PndDiscSensorGridPhotodetector.cxx
Go to the documentation of this file.
1 //-------------------------------------------------------------------------
2 // Author: Oliver Merle (Oliver.Merle@exp2.physik.uni-giessen.de)
3 // Changes: Mustafa Schmidt (Mustafa.A.Schmidt@physik.uni-giessen.de)
4 // Date: 30.11.2015
5 // Description: Class to handle tiled sensors
6 //-------------------------------------------------------------------------
7 
9 #include "PndDiscSensorGrid.h"
10 
11 #include <TRandom3.h>
12 #include <fstream>
13 
14 #include <FairLogger.h>
15 
16 namespace SensorGrid {
17 
18 
20  double efficiency; // pixel efficiency (additional to pde)
21  double noise_rate; // pixel noise rate
22  double time_res_ns; // per pixel time resolution
23 };
24 
25 
26 SensorGridPhotodetector::SensorGridPhotodetector(SensorGridBase* sensor_grid_, bool per_pixel_traits_, double const & efficiency_init, double const & noise_rate_init, double const & time_res_init)
27  : per_pixel_traits(per_pixel_traits_), use_inhomogenity_factor(false),sensor_grid(sensor_grid_)
28 {
29  Init(sensor_grid_, per_pixel_traits_, efficiency_init, noise_rate_init, time_res_init);
30 }
31 
32 
34 void SensorGridPhotodetector::Init(SensorGridBase* sensor_grid_, bool per_pixel_traits_, double const & efficiency_init, double const & noise_rate_init, double const & time_res_init) {
35  sensor_grid = sensor_grid_;
36  sensor_grid->LockGrid(true);
37  per_pixel_traits = per_pixel_traits_;
38  if(per_pixel_traits) {
40  //if(pixel_traits == NULL)
41  // throw ...
42  for(int i = 0; i< sensor_grid->GetNumberOfPixels(); ++i) {
43  pixel_traits[i].efficiency = efficiency_init;
44  pixel_traits[i].noise_rate = noise_rate_init;
45  pixel_traits[i].time_res_ns = time_res_init;
46  }
47  } else {
48  pixel_traits = new PixelTraits();
49  pixel_traits->efficiency = efficiency_init;
50  pixel_traits->noise_rate = noise_rate_init;
51  pixel_traits->time_res_ns = time_res_init;
52  }
53 }
54 
55 //#define DETECT_DEBUG
56 
57 #ifdef DETECT_DEBUG
58 std::ofstream ofs_detect_debug("detect_debug.txt");
59 #endif
60 
62 int SensorGridPhotodetector::Detect(double const & hit_pos_x, double const & hit_pos_y, double const & hit_time_ns, double const & wavelength_nm, PixelInfo & pixel_info, double & smeared_time_ns) const {
63 #ifdef DETECT_DEBUG
64  ofs_detect_debug << "X: " << hit_pos_x << " Y: " << hit_pos_y ;
65 #endif
66  if(!sensor_grid->PositionToPixel(hit_pos_x, hit_pos_y, pixel_info)) {
67 #ifdef DETECT_DEBUG
68  ofs_detect_debug << " not detected\n";
69 #endif
70  return -1; // no pixel (geometric efficiency)
71  }
72 #ifdef DETECT_DEBUG
73  ofs_detect_debug << "Pixel: " << pixel_info.pixel_number << " Grid: " << pixel_info.grid_id << " Column/row: " << pixel_info.column_on_grid << " / " << pixel_info.row_on_grid << std::endl;
74 #endif
75 
76  double global_pde = GetPDE(wavelength_nm);
77  if(use_inhomogenity_factor) global_pde*=GetInhomegenityFactor(hit_pos_x, hit_pos_y);
78 
79  if(per_pixel_traits) {
80  if(gRandom->Uniform() > pixel_traits[pixel_info.pixel_number].efficiency*global_pde) return -1; // global PDE and per pixel efficiency (e.g. due to bad gain uniformity)
81  smeared_time_ns = gRandom->Gaus(hit_time_ns, pixel_traits[pixel_info.pixel_number].time_res_ns);
82  } else {
83  if(gRandom->Uniform() > pixel_traits->efficiency*global_pde) return -1;
84  smeared_time_ns = gRandom->Gaus(hit_time_ns, pixel_traits->time_res_ns);
85  }
86  return pixel_info.pixel_number;
87 }
88 
89 
91 void SensorGridPhotodetector::GenerateNoise(double const & time_start_ns, double const & time_window_ns, std::vector<std::pair<int, double> > & hits) const {
92  int i, n_hits, n_pixels = sensor_grid->GetNumberOfPixels();
93  double avg_n_hits;
94  std::pair<int, double> hit;
95 
96  // loop over all pixel numbers
97  for(hit.first = 0; hit.first < n_pixels; ++hit.first) {
98  // average number of noise events per pixel:
100  avg_n_hits = pixel_traits[hit.first].noise_rate*time_window_ns*1E-9;
101  else
102  avg_n_hits = pixel_traits->noise_rate*time_window_ns*1E-9;
103 
104  n_hits = gRandom->Poisson(avg_n_hits); // compute number of hits on this pixel
105  // generate the hits in the given time window:
106  for(i=0; i<n_hits; ++i) {
107  hit.second = time_start_ns + gRandom->Uniform(time_window_ns); // distribute hit times in window
108  hits.push_back(hit); // append hits to vector
109  }
110  }
111 }
112 
113 
115 int SensorGridPhotodetector::GenerateNoise(double const & time_start_ns, double const & time_window_ns) {
117  noisegen_n_hits = 0;
119  noisegen_time_start_ns = time_start_ns;
120  noisegen_time_window_ns = time_window_ns;
121 
122  return noisegen_n_hits;
123 }
124 
125 
127 bool SensorGridPhotodetector::GetNoiseHit(int & pixel_number, double & hit_time_ns, double & smeared_time_ns) {
128  if(noisegen_pixel_number >= sensor_grid->GetNumberOfPixels()) return false;
129 
130  // after iterating over all hits, switch to next pixel.
132  do{
133  // next pixel:
135  if(noisegen_pixel_number >= sensor_grid->GetNumberOfPixels()) return false;
136 
137  // average number of noise events on this pixel:
138  double avg_n_hits = 0.0;
139  if(per_pixel_traits) {
140  avg_n_hits = pixel_traits[pixel_number].noise_rate*noisegen_time_window_ns*1E-9;
142  }
143  else {
146  }
147 
148  // number of hits on this pixel:
149  noisegen_n_hits = gRandom->Poisson(avg_n_hits); // compute number of hits on this pixel
150  }
151  while(noisegen_n_hits == 0);
152 
154  LOG(INFO) << Form("Number of generated hits on pixel %d are: %d\n", noisegen_pixel_number, noisegen_n_hits);
155  }
156 
157  pixel_number = noisegen_pixel_number;
158  hit_time_ns = noisegen_time_start_ns + gRandom->Uniform(noisegen_time_window_ns); // distribute hit times in window
159  smeared_time_ns = gRandom->Gaus(hit_time_ns, noisegen_current_time_sigma);
161 
162  return true;
163 }
164 
165 
171 double SensorGridPhotodetector::GetSmearedTime(double const & hit_time_ns, PixelInfo const & pixel_info) const {
172  double smeared_time_ns;
173  if(per_pixel_traits) {
174  smeared_time_ns = gRandom->Gaus(hit_time_ns, pixel_traits[pixel_info.pixel_number].time_res_ns);
175  } else {
176  smeared_time_ns = gRandom->Gaus(hit_time_ns, pixel_traits->time_res_ns);
177  }
178  return smeared_time_ns;
179 }
180 
181 
185 void SensorGridPhotodetector::SetDCR(double const & dcr_Hz) {
186  if(per_pixel_traits) {
187  int n_pixels = sensor_grid->GetNumberOfPixels();
188  for(int i=0; i<n_pixels; ++i) {
189  pixel_traits[i].noise_rate = dcr_Hz;
190  }
191  }
192  else
193  pixel_traits->noise_rate = dcr_Hz;
194 }
195 
196 
197 }
void SetDCR(double const &dcr_Hz)
Set the dark count rate for all pixels to dcr_Hz.
Int_t i
Definition: run_full.C:25
Common base class for sensor grids.
bool GetNoiseHit(int &pixel_number, double &hit_time_ns, double &smeared_time_ns)
Noise hit generator function which has to be called after GenerateNoise() to retrieve the noise hits...
void GenerateNoise(double const &time_start_ns, double const &time_window_ns, std::vector< std::pair< int, double > > &hits) const
Generate noise hits.
virtual bool PositionToPixel(const double &x, const double &y, PixelInfo &pixel_info) const =0
void LockGrid(bool lock)
Lock the grid:
void Init(SensorGridBase *sensor_grid_, bool per_pixel_traits_, double const &efficiency_init, double const &noise_rate_init, double const &time_res_init)
Initialization - can also be used in derived class ctors (avoid code duplication).
virtual double GetPDE(const double &) const
Derived classes should override this function and return the average pde of the sensor.
int hit(Int_t nEvents=0, TString inFile="sim.root", TString parFile="par.root", TString inDigi="digi.root", TString outFile="hit.root", Int_t timeBased=0)
Definition: hit.C:1
CbmHit * hits[nHits]
Definition: RiemannTest.C:19
int Detect(double const &hit_pos_x, double const &hit_pos_y, double const &hit_time_ns, double const &wavelength_nm, PixelInfo &pixel_info, double &smeared_time_ns) const
Handle photon detection:
double GetSmearedTime(double const &time_value, PixelInfo const &pixel_info) const
Apply time smearing.
virtual double GetInhomegenityFactor(double const &, double const &) const
Derived classes should override this function to account for spatial PDE deviations (e...