MuIDReadoutSimStandardAlg.cxx
Go to the documentation of this file.
1 //
2 // ECALReadoutSimStandardAlg.cxx
3 //
4 // Created by Eldwan Brianne on 8/27/18
5 //
6 
9 
12 #include "Geometry/GeometryGAr.h"
13 #include "Geometry/LocalTransformation.h"
14 #include "CoreUtils/ServiceUtil.h"
15 
18 
19 #include "CLHEP/Units/SystemOfUnits.h"
20 #include "CLHEP/Random/RandGauss.h"
21 #include "CLHEP/Random/RandBinomial.h"
22 
23 #include "TGeoManager.h"
24 
25 namespace gar {
26  namespace rosim{
27 
28  //----------------------------------------------------------------------------
30  : SiPMReadoutSimAlg(engine, pset)
31  {
32  fGeo = gar::providerFrom<geo::GeometryGAr>();
34  fDetProp = gar::providerFrom<detinfo::DetectorPropertiesService>();
35 
36  this->reconfigure(pset);
37 
38  return;
39  }
40 
41  //----------------------------------------------------------------------------
43  {
44  return;
45  }
46 
47  //----------------------------------------------------------------------------
49  {
50  fAddNoise = pset.get<bool>("AddNoise", false);
51  fSaturation = pset.get<bool>("Saturation", false);
52  fTimeSmearing = pset.get<bool>("TimeSmearing", false);
53 
54  fSiPMUtils = std::make_unique<util::SiPMUtils>(fDetProp->EffectivePixel());
55 
56  return;
57  }
58 
59  //----------------------------------------------------------------------------
61  {
62  m_SimCaloHitVec.clear();
63  m_DigitHitVec.clear();
64  }
65 
66  //----------------------------------------------------------------------------
68  {
69  //Clear the lists
70  ClearLists();
71 
72  //Loop over all hits
73  for (std::vector< art::Ptr<sdp::CaloDeposit> >::const_iterator iter = hitVector.begin(), iterEnd = hitVector.end(); iter != iterEnd; ++iter)
74  {
75  art::Ptr<sdp::CaloDeposit> hitPtr = *iter;
76  const sdp::CaloDeposit *hit = hitPtr.get();
77  m_SimCaloHitVec.emplace_back(hit);
78  }
79 
80  //Sort the list by time
81  std::sort(m_SimCaloHitVec.begin(), m_SimCaloHitVec.end(), [](const sdp::CaloDeposit *rha, const sdp::CaloDeposit *rhb) { return rha->Time() < rhb->Time(); } );
82 
83  return;
84  }
85 
86  //----------------------------------------------------------------------------
88  {
89  MF_LOG_DEBUG("MuIDReadoutSimStandardAlg") << "DoDigitization()";
90 
91  //Treating tiled hits
92  for(auto const &it : m_SimCaloHitVec)
93  {
94  float energy = it->Energy();
95  float time = it->Time();
96  float x = it->X();
97  float y = it->Y();
98  float z = it->Z();
99  raw::CellID_t cellID = it->CellID();
100 
101  raw::CaloRawDigit *digihit = this->DoStripDigitization(x, y, z, energy, time, cellID);
102 
103  if( nullptr != digihit) {
104  m_DigitHitVec.emplace_back(digihit);
105  } else {
106  MF_LOG_DEBUG("MuIDReadoutSimStandardAlg")
107  << "Could not digitize the simulated hit " << it;
108  }
109  }
110  }
111 
112  //----------------------------------------------------------------------------
114  {
115  MF_LOG_DEBUG("MuIDReadoutSimStandardAlg") << "DoStripDigitization()";
116 
117  //Calculate the light propagation along the strip
118  std::pair<float, float> times = this->DoLightPropagation(x, y, z, time, cID);
119 
120  //Calculate the SiPM energy
121  float new_energy = this->DoPhotonStatistics(x, y, z, energy);
122 
123  //Calculate the position of the strip
124  std::pair< std::array<double, 3>, bool > calc_pos = this->CalculatePosition(x, y, z, cID);
125  //Check if need to drop the hit
126  if ( calc_pos.second ) {
127  return nullptr;
128  }
129 
130  std::array<double, 3> pos = calc_pos.first;
131 
132  //make the shared ptr
133  raw::CaloRawDigit *digihit = new raw::CaloRawDigit( static_cast<unsigned int>(new_energy), times, pos[0], pos[1], pos[2], cID );
134 
135  MF_LOG_DEBUG("MuIDReadoutSimStandardAlg") << "Strip digihit " << digihit
136  << " with cellID " << cID
137  << " has energy " << static_cast<unsigned int>(new_energy)
138  << " time (" << times.first << ", " << times.second << ")"
139  << " pos (" << pos[0] << ", " << pos[1] << ", " << pos[2] << ")";
140 
141  return digihit;
142  }
143 
144  //----------------------------------------------------------------------------
145  float MuIDReadoutSimStandardAlg::DoPhotonStatistics(float x, float y, float z, float energy) const
146  {
147  MF_LOG_DEBUG("MuIDReadoutSimStandardAlg") << "DoPhotonStatistics()";
148  CLHEP::RandBinomial BinomialRand(fEngine);
149 
150  TVector3 point(x, y, z);
151  float factor = fGeo->GetSensVolumeThickness(point) / 0.5;
152 
153  //Convert energy from GeV to MIP
154  float energy_mip = energy / (fDetProp->MeVtoMIP() * factor * CLHEP::MeV / CLHEP::GeV);
155 
156  //conversion to px
157  float pixel = energy_mip * fDetProp->LightYield();
158 
159  //Saturation
160  float sat_pixel = 0.;
161  if(fSaturation)
162  sat_pixel = fSiPMUtils->Saturate(pixel);
163  else
164  sat_pixel = pixel;
165 
166  //Binomial Smearing
167  double prob = sat_pixel / fDetProp->EffectivePixel();
168  float smeared_px = BinomialRand.shoot(fDetProp->EffectivePixel(), prob);
169 
170  float smeared_px_noise = smeared_px;
171  //Add noise
172  if(fAddNoise)
173  smeared_px_noise = this->AddElectronicNoise(smeared_px);
174 
175  //Convertion to ADC
176  float ADC = 0.;
177 
178  if(smeared_px_noise > 0)
179  ADC = smeared_px_noise * fDetProp->SiPMGain();
180 
183 
184  return ADC;
185  }
186 
187  //----------------------------------------------------------------------------
189  {
190  MF_LOG_DEBUG("MuIDReadoutSimStandardAlg") << "DoTimeSmearing()";
191  CLHEP::RandGauss GausRand(fEngine);
192  float smeared_time = time + GausRand.fire(0., fDetProp->TimeResolution());
193  return smeared_time;
194  }
195 
196  //----------------------------------------------------------------------------
198  {
199  MF_LOG_DEBUG("MuIDReadoutSimStandardAlg") << "AddElectronicNoise()";
200 
201  //Random noise shooting (Gaussian electronic noise)
202  CLHEP::RandGauss GausRand(fEngine);
203  float smeared_energy = energy + GausRand.shoot(0., fDetProp->NoisePx());
204  return smeared_energy;
205  }
206 
207  //----------------------------------------------------------------------------
208  std::pair< std::array<double, 3>, bool > MuIDReadoutSimStandardAlg::CalculatePosition(float x, float y, float z, raw::CellID_t cID) const
209  {
210  bool drop = false;
211 
212  //Use the segmentation algo to get the position
213  std::array<double, 3> point = {x, y, z};
214  TGeoNode *node = fGeo->FindNode(point);//Node in cm...
215  std::string nodename = node->GetName();
216  std::array<double, 3> pointLocal;
218  fGeo->WorldToLocal(point, pointLocal, trans);
219 
220  std::array<double, 3> pointLocal_back = fGeo->GetPosition(node, cID);//returns in cm
221  std::array<double, 3> point_back;
222  fGeo->LocalToWorld(pointLocal_back, point_back, trans);
223  TGeoNode *new_node = fGeo->FindNode(point_back);//Node in cm...
224  std::string newnodename = new_node->GetName();
225 
226  //get the base of the node names (slice can be added in the new node)
227  std::string base_node_name = nodename.substr(0, nodename.find("_layer_") + 9);
228  std::string base_new_node_name = newnodename.substr(0, newnodename.find("_layer_") + 9);
229 
230  if( base_new_node_name != base_node_name ){
231  MF_LOG_DEBUG("MuIDReadoutSimStandardAlg") << "CalculatePosition()"
232  << " Strip length " << fGeo->getStripLength(point, cID) << "\n"
233  << " Local Point before new position ( " << pointLocal[0] << ", " << pointLocal[1] << ", " << pointLocal[2] << " ) in node " << nodename << "\n"
234  << " Local Point after new position ( " << pointLocal_back[0] << ", " << pointLocal_back[1] << ", " << pointLocal_back[2] << " ) in node " << newnodename << "\n"
235  << " Dropping the hit ";
236 
237  //Drop the hit
238  drop = true;
239  }
240 
241  return std::make_pair(point_back, drop);
242  }
243 
244  //----------------------------------------------------------------------------
245  std::pair<float, float> MuIDReadoutSimStandardAlg::DoLightPropagation(float x, float y, float z, float time, raw::CellID_t cID) const
246  {
247  //Find the volume path
248  std::array<double, 3> point = {x, y, z};
249  std::array<double, 3> pointLocal;
251  fGeo->WorldToLocal(point, pointLocal, trans);
252 
253  //Calculate light propagation along the strip
254  std::pair<float, float> times = fGeo->CalculateLightPropagation(point, pointLocal, cID);
255 
256  //t1 is left SiPM, t2 is right SiPM
257  float time1 = time + times.first;
258  float time2 = time + times.second;
259 
260  //Smear the times
261  float smeared_time1 = this->DoTimeSmearing(time1);
262  float smeared_time2 = this->DoTimeSmearing(time2);
263 
264  return std::make_pair(smeared_time1, smeared_time2);
265  }
266 
267  } // rosim
268 } // gar
TGeoNode * FindNode(T const &x, T const &y, T const &z) const
virtual double SiPMGain() const =0
bool WorldToLocal(std::array< double, 3 > const &world, std::array< double, 3 > &local, gar::geo::LocalTransformation< TGeoHMatrix > &trans) const
float GetSensVolumeThickness(const TVector3 &point) const
float const & Time() const
Definition: CaloDeposit.h:71
bool fSaturation
flag for sipm saturation or not
std::vector< raw::CaloRawDigit * > m_DigitHitVec
vector of digitized hits
float DoPhotonStatistics(float x, float y, float z, float energy) const
MuIDReadoutSimStandardAlg(CLHEP::HepRandomEngine &engine, fhicl::ParameterSet const &pset)
std::string string
Definition: nybbler.cc:12
struct vector vector
CLHEP::HepRandomEngine & fEngine
random number engine
virtual double IntercalibrationFactor() const =0
static constexpr double MeV
Definition: Units.h:129
std::pair< float, float > DoLightPropagation(float x, float y, float z, float time, raw::CellID_t cID) const
double getStripLength(const std::array< double, 3 > &point, const gar::raw::CellID_t &cID) const
const detinfo::DetectorProperties * fDetProp
detector properties
virtual double EffectivePixel() const =0
Class to transform between world and local coordinates.
virtual double ADCSaturation() const =0
bool fAddNoise
flag to add noise or not
virtual double NoisePx() const =0
std::vector< const sdp::CaloDeposit * > m_SimCaloHitVec
used to store the simulated hits
std::array< double, 3 > GetPosition(const TGeoNode *node, const gar::raw::CellID_t &cID) const
void reconfigure(fhicl::ParameterSet const &pset)
std::pair< std::array< double, 3 >, bool > CalculatePosition(float x, float y, float z, raw::CellID_t cID) const
std::unique_ptr< util::SiPMUtils > fSiPMUtils
used for the SiPM saturation
static constexpr double GeV
Definition: Units.h:28
T get(std::string const &key) const
Definition: ParameterSet.h:271
virtual double LightYield() const =0
raw::CaloRawDigit * DoStripDigitization(float x, float y, float z, float energy, float time, raw::CellID_t cID) const
bool LocalToWorld(std::array< double, 3 > const &local, std::array< double, 3 > &world, gar::geo::LocalTransformation< TGeoHMatrix > const &trans) const
TGeoManager * ROOTGeoManager() const
Access to the ROOT geometry description manager.
Definition of basic calo raw digits.
long long int CellID_t
Definition: CaloRawDigit.h:24
Detector simulation of raw signals on wires.
virtual double MeVtoMIP() const =0
General GArSoft Utilities.
void PrepareAlgo(const std::vector< art::Ptr< sdp::CaloDeposit > > &hitVector)
virtual double TimeResolution() const =0
#define MF_LOG_DEBUG(id)
list x
Definition: train.py:276
bool fTimeSmearing
flag for time smearing or not
std::pair< float, float > CalculateLightPropagation(const std::array< double, 3 > &point, const std::array< double, 3 > &local, const gar::raw::CellID_t &cID) const
T const * get() const
Definition: Ptr.h:149
art framework interface to geometry description
Definition: fwd.h:31
gar::geo::GeometryCore const * fGeo
geometry information