SiPMHitFinder_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: SiPMHitFinder
3 // Plugin Type: producer (art v2_11_02)
4 // File: CompressedHitFinder_module.cc
5 //
6 // Generated at Wed Jun 13 15:27:13 2018 by Thomas Junk using cetskelgen
7 // from cetlib version v3_03_01.
8 // Report the compressed raw digit blocks as hits -- just a threshold
9 ////////////////////////////////////////////////////////////////////////
10 
19 #include "fhiclcpp/ParameterSet.h"
22 
25 #include "Geometry/GeometryGAr.h"
27 #include "Geometry/LocalTransformation.h"
28 #include "Geometry/BitFieldCoder.h"
29 
30 #include "RecoAlg/SiPMUtils.h"
31 
32 #include "CLHEP/Units/SystemOfUnits.h"
33 
34 #include "TGeoNode.h"
35 #include "TGeoManager.h"
36 
37 #include <memory>
38 
39 namespace gar {
40  namespace rec {
41 
42  class SiPMHitFinder : public art::EDProducer {
43  public:
44  explicit SiPMHitFinder(fhicl::ParameterSet const & p);
45  // The compiler-generated destructor is fine for non-base
46  // classes without bare pointers or other resource use.
47 
48  // Plugins should not be copied or assigned.
49  SiPMHitFinder(SiPMHitFinder const &) = delete;
50  SiPMHitFinder(SiPMHitFinder &&) = delete;
51  SiPMHitFinder & operator = (SiPMHitFinder const &) = delete;
53 
54  // Required functions.
55  void produce(art::Event & e) override;
56 
57  protected:
59 
60  float CalibrateToMIP(unsigned int ADC);
61 
62  float CalibratetoMeV(float x, float y, float z, double MIP);
63 
64  std::array<double, 3U> CalculateStripHitPosition(float x, float y, float z, std::pair<float, float> hitTime, raw::CellID_t cID);
65 
66  float CorrectStripHitTime(float x, float y, float z, std::pair<float, float> hitTime, raw::CellID_t cID);
67 
68  private:
69 
70  // Declare member data here.
71  std::string fRawDigitLabel; ///< label to find the right raw digits
72  std::string fInstanceLabelName; ///< product instance name
73 
74  float fMIPThreshold; ///< zero-suppression threshold (in case the raw digits need to be zero-suppressed)
75  bool fDesaturation; ///< flag to perform the SiPM desaturation
78 
79  const detinfo::DetectorProperties* fDetProp; ///< detector properties
80  const geo::GeometryCore* fGeo; ///< pointer to the geometry
81  std::unique_ptr<util::SiPMUtils> fSiPMUtils; ///< pointer to the Util fcn containing the SiPM desaturation function
83  };
84 
85 
87  {
88  fRawDigitLabel = p.get<std::string>("RawDigitLabel", "daqsipm");
89  fInstanceLabelName = p.get<std::string>("InstanceLabelName", "");
90 
91  fMIPThreshold = p.get<float>("MIPThreshold", 0.25);
92  fDesaturation = p.get<bool>("Desaturation", false);
93  fSamplingCorrection = p.get<float>("ECALSamplingFactorGeV", 1.0);
94  fUseTimePositionReco = p.get<bool>("UseTimePositionReco", true);
95 
96  fGeo = gar::providerFrom<geo::GeometryGAr>();
97  fDetProp = gar::providerFrom<detinfo::DetectorPropertiesService>();
98  fSiPMUtils = std::make_unique<util::SiPMUtils>(fDetProp->EffectivePixel());
99 
100  std::string fEncoding = fGeo->GetECALCellIDEncoding();
101  art::InputTag tag(fRawDigitLabel, fInstanceLabelName);
102  consumes< std::vector<raw::CaloRawDigit> >(tag);
103  produces< std::vector<rec::CaloHit> >(fInstanceLabelName);
104  produces< art::Assns<rec::CaloHit, raw::CaloRawDigit> >(fInstanceLabelName);
105 
106  if(fInstanceLabelName.compare("MuID") == 0) {
107  fEncoding = fGeo->GetMuIDCellIDEncoding();
108  fSamplingCorrection = p.get<float>("MuIDSamplingFactorGeV", 1.0);
109  }
110 
111  fFieldDecoder = new gar::geo::BitFieldCoder( fEncoding );
112  }
113 
115  {
116  // create an emtpy output hit collection -- to add to.
117  std::unique_ptr< std::vector<rec::CaloHit> > hitCol ( new std::vector< rec::CaloHit > );
118  std::unique_ptr< art::Assns<rec::CaloHit, raw::CaloRawDigit> > RecoDigiHitsAssns( new art::Assns<rec::CaloHit, raw::CaloRawDigit> );
119 
120  //Collect the hits to be passed to the algo
121  std::vector< art::Ptr<gar::raw::CaloRawDigit> > artDigiHits;
122  this->CollectDigiHits(e, fRawDigitLabel, fInstanceLabelName, artDigiHits);
123 
125 
126  for (std::vector< art::Ptr<gar::raw::CaloRawDigit> >::const_iterator iter = artDigiHits.begin(), iterEnd = artDigiHits.end(); iter != iterEnd; ++iter)
127  {
128  art::Ptr<gar::raw::CaloRawDigit> digiArtPtr = *iter;
129  const gar::raw::CaloRawDigit &digitHit = *(digiArtPtr.get());
130 
131  unsigned int hitADC = digitHit.ADC().first;
132  std::pair<float, float> hitTime = digitHit.Time();
133  float x = digitHit.X();
134  float y = digitHit.Y();
135  float z = digitHit.Z();
136  raw::CellID_t cellID = digitHit.CellID();
137 
138  //Do Calibration of the hit in MIPs
139  float hitMIP = this->CalibrateToMIP(hitADC);
140 
141  if (hitMIP < fMIPThreshold)
142  {
143  MF_LOG_DEBUG("SiPMHitFinder") << "Signal under the " << fMIPThreshold << " MIP threshold" << std::endl;
144  continue;
145  }
146 
147  //Desaturation
148  float energy = 0.;
149  if (fDesaturation)
150  {
151  double sat_px = hitMIP * fDetProp->LightYield();
152  //DeSaturate
153  double unsat_px = fSiPMUtils->DeSaturate(sat_px);
154 
155  //Calibrate to the MeV scale
156  double unsat_energy = unsat_px / fDetProp->LightYield();
157  energy = this->CalibratetoMeV(x, y, z, unsat_energy);
158  }
159  else {
160  //Calibrate to the MeV scale
161  energy = this->CalibratetoMeV(x, y, z, hitMIP);
162  }
163 
164  //Position reconstruction based on time for the strips
165  float pos[3] = {0., 0., 0.};
166  std::pair<float, float> time;
167  const std::array<double, 3> point = { x, y, z };
168 
169  if (fGeo->isTile(point, cellID))
170  {
171  pos[0] = x;
172  pos[1] = y;
173  pos[2] = z;
174  time = hitTime;
175  }
176  else {
177  if( fUseTimePositionReco) {
178  std::array<double, 3> strip_pos = this->CalculateStripHitPosition(x, y, z, hitTime, cellID);
179  pos[0] = strip_pos[0];
180  pos[1] = strip_pos[1];
181  pos[2] = strip_pos[2];
182  time = std::make_pair( this->CorrectStripHitTime(pos[0], pos[1], pos[2], hitTime, cellID), 0. );
183  } else {
184  pos[0] = x;
185  pos[1] = y;
186  pos[2] = z;
187  time = hitTime;
188  }
189  }
190 
191  //Store the hit (energy in GeV, time in ns, pos in cm and cellID)
192  unsigned int layer = fFieldDecoder->get(cellID, "layer");
193  rec::CaloHit hit(fSamplingCorrection * energy * CLHEP::MeV / CLHEP::GeV, time, pos, cellID, layer);
194  hitCol->emplace_back(hit);
195 
196  MF_LOG_DEBUG("SiPMHitFinder") << "recohit " << &hit
197  << " with cellID " << cellID
198  << " has energy " << fSamplingCorrection * energy * CLHEP::MeV / CLHEP::GeV
199  << " pos (" << pos[0] << ", " << pos[1] << ", " << pos[2] << ")";
200 
201  //Make association between digi hits and reco hits
202  art::Ptr<rec::CaloHit> hitPtr = makeHitPtr(hitCol->size() - 1);
203  RecoDigiHitsAssns->addSingle(hitPtr, digiArtPtr);
204  }
205 
206  //move the reco hit collection
207  e.put(std::move(hitCol), fInstanceLabelName);
208  e.put(std::move(RecoDigiHitsAssns), fInstanceLabelName);
209 
210  return;
211  }
212 
213  //----------------------------------------------------------------------------
215  {
216  art::InputTag itag(label,instance);
217  auto theHits = evt.getHandle< std::vector<gar::raw::CaloRawDigit> >(itag);
218  if (!theHits) return;
219 
220  for (unsigned int i = 0; i < theHits->size(); ++i)
221  {
222  const art::Ptr<gar::raw::CaloRawDigit> hit(theHits, i);
223  hitVector.push_back(hit);
224  }
225  return;
226  }
227 
228  //----------------------------------------------------------------------------
229  float SiPMHitFinder::CalibrateToMIP(unsigned int ADC)
230  {
231  float calibrated_ADC = 0.;
232  if (ADC <= 0) {
233  return calibrated_ADC;
234  }
235 
236  calibrated_ADC = ADC / (fDetProp->LightYield() * fDetProp->SiPMGain());
237  return calibrated_ADC;
238  }
239 
240  //----------------------------------------------------------------------------
241  float SiPMHitFinder::CalibratetoMeV(float x, float y, float z, double MIP)
242  {
243  float calibrated_MIP = 0.;
244  if(MIP <= 0) {
245  return calibrated_MIP;
246  }
247 
248  TVector3 point(x, y, z);
249  float factor = fGeo->GetSensVolumeThickness(point) / 0.5;
250 
251  calibrated_MIP = MIP * fDetProp->MeVtoMIP() * factor;
252  return calibrated_MIP; // MeV
253  }
254 
255  //----------------------------------------------------------------------------
256  std::array<double, 3> SiPMHitFinder::CalculateStripHitPosition(float x, float y, float z, std::pair<float, float> hitTime, raw::CellID_t cID)
257  {
258  std::array<double, 3> point = {x, y, z};
259  std::array<double, 3> pointLocal;
261  fGeo->WorldToLocal(point, pointLocal, trans);
262 
263  //Calculate the position of the hit based on the time of both SiPM along the strip
264  // pos along strip is
265  // x = c * (t1 - t2) / 2 (0 is the center of the strip)
266  float c = (CLHEP::c_light * CLHEP::mm / CLHEP::ns) / CLHEP::cm; // in cm/ns
267  float xlocal = c * ( hitTime.first - hitTime.second ) / 2.;
268 
269  std::array<double, 3> local_back = fGeo->ReconstructStripHitPosition(point, pointLocal, xlocal, cID);
270  std::array<double, 3> world_back;
271  fGeo->LocalToWorld(local_back, world_back, trans);
272 
273  return world_back;
274  }
275 
276  //----------------------------------------------------------------------------
277  float SiPMHitFinder::CorrectStripHitTime(float x, float y, float z, std::pair<float, float> hitTime, raw::CellID_t cID)
278  {
279  std::array<double, 3> point = {x, y, z};
280  double stripLength = fGeo->getStripLength(point, cID); // in cm
281 
282  float c = (CLHEP::c_light * CLHEP::mm / CLHEP::ns) / CLHEP::cm; // in cm/ns
283  float time = (hitTime.first + hitTime.second) / 2. - (stripLength / (2 * c));
284 
285  return time;
286  }
287 
289 
290  } // namespace rec
291 } // namespace gar
static constexpr double cm
Definition: Units.h:68
SiPMHitFinder & operator=(SiPMHitFinder const &)=delete
float fMIPThreshold
zero-suppression threshold (in case the raw digits need to be zero-suppressed)
virtual double SiPMGain() const =0
rec
Definition: tracks.py:88
float CalibratetoMeV(float x, float y, float z, double MIP)
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
std::pair< float, float > Time() const
Timestmap.
Definition: CaloRawDigit.h:79
gar::geo::BitFieldCoder const * fFieldDecoder
float Y() const
Y position.
Definition: CaloRawDigit.h:81
std::pair< unsigned int, unsigned int > ADC() const
Reference to the compressed ADC count vector.
Definition: CaloRawDigit.h:78
void CollectDigiHits(const art::Event &evt, const std::string &label, const std::string &instance, std::vector< art::Ptr< gar::raw::CaloRawDigit > > &hitVector)
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::string string
Definition: nybbler.cc:12
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
float CorrectStripHitTime(float x, float y, float z, std::pair< float, float > hitTime, raw::CellID_t cID)
float X() const
X position.
Definition: CaloRawDigit.h:80
struct vector vector
const std::string instance
Description of geometry of one entire detector.
Definition: GeometryCore.h:436
static constexpr double MeV
Definition: Units.h:129
double getStripLength(const std::array< double, 3 > &point, const gar::raw::CellID_t &cID) const
std::string fInstanceLabelName
product instance name
Class to transform between world and local coordinates.
std::array< double, 3U > CalculateStripHitPosition(float x, float y, float z, std::pair< float, float > hitTime, raw::CellID_t cID)
bool isTile(const std::array< double, 3 > &point, const gar::raw::CellID_t &cID) const
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
void produce(art::Event &e) override
static constexpr double GeV
Definition: Units.h:28
CellID_t CellID() const
cellID
Definition: CaloRawDigit.h:83
Helper class for decoding and encoding a bit field of 64bits for convenient declaration.
Interface to SiPMReadoutSimAlg class for SiPM specific.
def move(depos, offset)
Definition: depos.py:107
virtual double LightYield() const =0
bool LocalToWorld(std::array< double, 3 > const &local, std::array< double, 3 > &world, gar::geo::LocalTransformation< TGeoHMatrix > const &trans) const
p
Definition: test.py:223
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
Definition of basic calo raw digits.
long long int CellID_t
Definition: CaloRawDigit.h:24
const geo::GeometryCore * fGeo
pointer to the geometry
bool fDesaturation
flag to perform the SiPM desaturation
virtual double MeVtoMIP() const =0
General GArSoft Utilities.
long64 get(long64 bitfield, size_t index) const
const detinfo::DetectorProperties * fDetProp
detector properties
float CalibrateToMIP(unsigned int ADC)
#define MF_LOG_DEBUG(id)
std::array< double, 3 > ReconstructStripHitPosition(const std::array< double, 3 > &point, const std::array< double, 3 > &local, const float &xlocal, const gar::raw::CellID_t &cID) const
static constexpr double mm
Definition: Units.h:65
list x
Definition: train.py:276
SiPMHitFinder(fhicl::ParameterSet const &p)
TCEvent evt
Definition: DataStructs.cxx:7
T const * get() const
Definition: Ptr.h:149
art framework interface to geometry description
std::unique_ptr< util::SiPMUtils > fSiPMUtils
pointer to the Util fcn containing the SiPM desaturation function
QAsciiDict< Entry > ns
float Z() const
Z position.
Definition: CaloRawDigit.h:82
Definition: fwd.h:31
std::string fRawDigitLabel
label to find the right raw digits
QTextStream & endl(QTextStream &s)