LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
FlashClusterMatch_module.cc
Go to the documentation of this file.
1 // Some kinda description here, maybe
2 //
3 // It does optical stuff.
4 
5 
6 
12 
13 // ROOT includes.
14 #include <Rtypes.h>
15 #ifndef FlashClusterMatch_h
16 #define FlashClusterMatch_h 1
17 
18 
19 namespace recob{
20  class OpFlash;
21  class Cluster;
22  class Hit;
23 }
24 
25 
26 namespace opdet {
27 
28 
30  public:
31 
33  virtual ~FlashClusterMatch();
34 
35  void produce(art::Event&);
36  void reconfigure(fhicl::ParameterSet const& p);
37 
38 
39  void beginJob();
40 
41 
42  private:
43 
44  std::vector<double> GetLightHypothesis(std::vector<recob::SpacePoint> spts);
45  bool CheckCompatibility(std::vector<double>& hypothesis, std::vector<double>& signal);
46 
47 
50 
51  std::string fClusterModuleLabel;
52  std::string fFlashModuleLabel;
55  double fIntegralCut;
56  };
57 
58 }
59 
60 #endif
61 
62 
63 
64 
70 // Framework includes
72 
73 namespace opdet{
74 
76 
77 }//end namespace opdet
79 
80 
81 // LArSoft includes
88 
89 
90 // FMWK includes
93 #include "fhiclcpp/ParameterSet.h"
103 
104 // C++ language includes
105 #include <iostream>
106 #include <sstream>
107 #include <cstring>
108 #include <vector>
109 
110 
111 
112 namespace opdet {
113 
114  //-------------------------------------------------
115 
116  FlashClusterMatch::FlashClusterMatch(fhicl::ParameterSet const& pset)
117  {
118  produces< std::vector<anab::CosmicTag> >();
119  produces< art::Assns<recob::Cluster, anab::CosmicTag> >();
120 
121  this->reconfigure(pset);
122  }
123 
124 
125  //-------------------------------------------------
126 
127  void FlashClusterMatch::reconfigure(fhicl::ParameterSet const& pset)
128  {
129  fClusterModuleLabel = pset.get<std::string>("ClusterModuleLabel");
130  fFlashModuleLabel = pset.get<std::string>("FlashModuleLabel");
131  fMinSptsForOverlap = pset.get<int>("MinSptsForOverlap");
132 
133  fSingleChannelCut = pset.get<int>("SingleChannelCut");
134  fIntegralCut = pset.get<int>("IntegralCut");
135 
136  fSptalg = new trkf::SpacePointAlg(pset.get<fhicl::ParameterSet>("SpacePointAlg"));
137  fCaloAlg = new calo::CalorimetryAlg(pset.get< fhicl::ParameterSet >("CaloAlg"));
138 
139  }
140 
141 
142  //-------------------------------------------------
143 
145  {
146  }
147 
148 
149 
150  //-------------------------------------------------
151 
152  FlashClusterMatch::~FlashClusterMatch()
153  {
154  }
155 
156 
157 
158 
159 
160  //-------------------------------------------------
161 
162 
163  void FlashClusterMatch::produce(art::Event& evt)
164  {
165 
166  int n=0;
167 
168 
169  top:
170  n++;
171 
172  // DO NOT REMOVE THIS LINE:
173  mf::LogWarning("RecoBaseDefaultCtor") << "using default Hit ctor - should only ever"
174  << " be done when getting hits out of an event"
175  << " not when trying to produce new hits to store"
176  << " in the event";
177 
178  std::cerr<< " Warning : you have disabled the RecoBaseDefaultCtor message." ;
179  std::cerr<< " Should only ever be done when trying to avoid messages when getting hits out of an event, not when trying to produce new hits to store in the event."<< std::endl;
180 
181  ++n;
182  if(n<10) goto top;
183 
184 
185 
186  std::unique_ptr< std::vector<anab::CosmicTag> > cosmic_tags ( new std::vector<anab::CosmicTag>);
187  std::unique_ptr< art::Assns<recob::Cluster, anab::CosmicTag > > assn_tag( new art::Assns<recob::Cluster, anab::CosmicTag>);
188 
189 
190 
191 
192  // Read in flashes from the event
194  evt.getByLabel(fFlashModuleLabel, flashh);
195  std::vector<art::Ptr<recob::OpFlash> > Flashes;
196  for(unsigned int i=0; i < flashh->size(); ++i)
197  {
198  art::Ptr<recob::OpFlash> flash(flashh,i);
199  Flashes.push_back(flash);
200  }
201 
202  // Read in clusters from the event
204  evt.getByLabel(fClusterModuleLabel, clusterh);
205  std::vector<art::Ptr<recob::Cluster> > Clusters;
206  for(unsigned int i=0; i < clusterh->size(); ++i)
207  {
208  art::Ptr<recob::Cluster> cluster(clusterh,i);
209  Clusters.push_back(cluster);
210  }
211 
212  // Pull associated hits from event
213  art::FindManyP<recob::Hit> hits(clusterh, evt, fClusterModuleLabel);
214 
215 
216  // Extract flash shape info
217  std::vector<std::vector<double> > FlashShapes;
219  size_t NOpDets = geom->NOpDets();
220 
221  for(size_t f=0; f!=Flashes.size(); ++f)
222  {
223  if(Flashes.at(f)->OnBeamTime())
224  {
225  std::vector<double> ThisFlashShape(NOpDets,0);
226  for (unsigned int c = 0; c < geom->NOpChannels(); c++){
227  unsigned int o = geom->OpDetFromOpChannel(c);
228  ThisFlashShape[o]+=Flashes.at(f)->PE(c);
229  }
230  FlashShapes.push_back(ThisFlashShape);
231  }
232  }
233 
234 
235 
236  std::vector<std::vector<int> > SortedByViews(3);
237 
238  // std::vector<int> MaxWire(Clusters.size(), 0);
239  // std::vector<int> MinWire(Clusters.size(), 10000);
240 
241  std::vector<int> MaxTime(Clusters.size(), 0);
242  std::vector<int> MinTime(Clusters.size(), 10000);
243 
244 
245  // Sort clusters by view
246  for(size_t iClus=0; iClus!=Clusters.size(); ++iClus)
247  {
248  SortedByViews[Clusters.at(iClus)->View()].push_back(iClus);
249  for(size_t iHit=0; iHit!=hits.at(iClus).size(); ++iHit)
250  {
251  double Time = hits.at(iClus).at(iHit)->PeakTime();
252  if(Time > MaxTime[iClus]) MaxTime[iClus] = Time;
253  if(Time < MinTime[iClus]) MinTime[iClus] = Time;
254 
255  // Equivalent info for wires, maybe we want it later.
256  // int Wire = hits.at(iClus).at(iHit)->WireID().Wire;
257  // if(Wire < MinWire[iClus]) MinWire[iClus] = Wire;
258  // if(Wire > MaxWire[iClus]) MaxWire[iClus] = Wire;
259 
260  }
261  }
262 
263  std::vector<std::vector<double> > hypotheses;
264 
265  // Loop over sets of 3 clusters
266  for(size_t nU=0; nU!=SortedByViews[0].size(); ++nU)
267  for(size_t nV=0; nV!=SortedByViews[1].size(); ++nV)
268  for(size_t nW=0; nW!=SortedByViews[2].size(); ++nW)
269  {
270  int indexU = SortedByViews[0][nU];
271  int indexV = SortedByViews[1][nV];
272  int indexW = SortedByViews[2][nW];
273 
274  bool NoOverlap = false;
275 
276  // Skip over clusters with no time overlap
277  for(size_t v=0; v!=3; ++v)
278  {
279  int v1 = (v+1)%3;
280  int v2 = (v+2)%3;
281 
282  if(MinTime[v] > std::min(MaxTime[v1],MaxTime[v2]))
283  NoOverlap = true;
284 
285  if(MaxTime[v] < std::max(MinTime[v1],MinTime[v2]))
286  NoOverlap = true;
287  }
288 
289  if(NoOverlap) continue;
290 
291  // Prepare flattened vector for space pointery
293 
294  FlatHits.insert(FlatHits.begin(), hits.at(indexU).begin(), hits.at(indexU).end());
295  FlatHits.insert(FlatHits.begin(), hits.at(indexV).begin(), hits.at(indexV).end());
296  FlatHits.insert(FlatHits.begin(), hits.at(indexW).begin(), hits.at(indexW).end());
297 
298  // Make the spacepoints
299  std::vector<recob::SpacePoint> spts;
300  fSptalg->makeSpacePoints(FlatHits, spts);
301 
302  if(int(spts.size()) < fMinSptsForOverlap) continue;
303 
304  // Get light hypothesis for this collection
305  std::vector<double> hypothesis = GetLightHypothesis(spts);
306 
307  bool IsCompatible = false;
308 
309  // Check for each flash, whether this subevent is compatible
310  for(size_t jFlash=0; jFlash!=FlashShapes.size(); ++jFlash)
311  {
312  // It is compatible with the beam flash.
313  if(CheckCompatibility(hypothesis,FlashShapes.at(jFlash)))
314  {
315  IsCompatible=true;
316  }
317  }
318 
319  // If not compatible with any beam flash, throw out
320  if(!IsCompatible)
321  {
322  cosmic_tags->push_back(anab::CosmicTag(1.));
323  util::CreateAssn(*this, evt, *(cosmic_tags.get()), Clusters.at(indexU), *(assn_tag.get()), cosmic_tags->size()-1);
324  util::CreateAssn(*this, evt, *(cosmic_tags.get()), Clusters.at(indexV), *(assn_tag.get()), cosmic_tags->size()-1);
325  util::CreateAssn(*this, evt, *(cosmic_tags.get()), Clusters.at(indexW), *(assn_tag.get()), cosmic_tags->size()-1);
326  }
327 
328  }
329 
330 
331 
332 
333  evt.put(std::move(cosmic_tags));
334  evt.put(std::move(assn_tag));
335  }
336 
337 
338 
339  //---------------------------------------------------------
340 
341 
342  // Get a hypothesis for the light from a spacepoint collection
343  std::vector<double> FlashClusterMatch::GetLightHypothesis(std::vector<recob::SpacePoint> spts)
344  {
346  std::vector<double> ReturnVector(geom->NOpDets(),0);
347 
349 
350 
351  for (size_t s=0; s!=spts.size(); s++)
352  {
353  const art::PtrVector<recob::Hit>& assochits = fSptalg->getAssociatedHits(spts.at(s));
354 
355  double Charge = 0;
356  double WirePitch = 0.3;
357 
358  for(size_t iHit=0; iHit!=assochits.size(); ++iHit)
359  if(assochits.at(iHit)->View()==2) Charge += WirePitch * fCaloAlg->dEdx_AMP(assochits.at(iHit), 1);
360 
361 
362  double xyz[3];
363 
364  for(size_t i=0; i!=3; ++i) xyz[i] = spts.at(s).XYZ()[i];
365 
366  const float* PointVisibility = pvs->GetAllVisibilities(xyz);
367  if (!PointVisibility) continue; // point not covered by the service
368  for(size_t OpDet =0; OpDet!=pvs->NOpChannels(); OpDet++)
369  {
370  ReturnVector.at(OpDet)+= PointVisibility[OpDet];
371  }
372  }
373  double PhotonYield = 24000;
374  double QE = 0.01;
375 
376  for(size_t i=0; i!=ReturnVector.size(); ++i)
377  {
378  ReturnVector[i] *= QE * PhotonYield;
379  }
380 
381  return ReturnVector;
382  }
383 
384 
385  //----------------------------------------------
386  bool FlashClusterMatch::CheckCompatibility(std::vector<double>& hypothesis, std::vector<double>& signal)
387  {
388  double sigintegral=0, hypintegral=0;
389  for(size_t i=0; i!=hypothesis.size(); ++i)
390  {
391  sigintegral+=signal.at(i);
392  hypintegral+=hypothesis.at(i);
393  double HypErr = pow(hypothesis.at(i),0.5);
394  if(( (hypothesis.at(i) - signal.at(i)) / HypErr) > fSingleChannelCut) return false;
395  }
396  double HypIntErr= pow(hypintegral,0.5);
397 
398  if( ( (hypintegral - sigintegral)/HypIntErr) > fIntegralCut) return false;
399  return true;
400  }
401 
402 
403 
404 
405 }
406 
407 
Float_t s
Definition: plot.C:23
Reconstruction base classes.
iterator begin()
Definition: PtrVector.h:223
Declaration of signal hit object.
Cluster finding and building.
unsigned int NOpChannels() const
Number of electronics channels for all the optical detectors.
unsigned int OpDetFromOpChannel(int opChannel) const
Convert unique channel to detector number.
TFile f
Definition: plotHisto.C:6
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
Int_t max
Definition: plot.C:27
void hits()
Definition: readHits.C:15
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:42
void beginJob()
Definition: Breakpoints.cc:14
T get(std::string const &key) const
Definition: ParameterSet.h:231
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
reference at(size_type n)
Definition: PtrVector.h:365
Declaration of cluster object.
unsigned int NOpDets() const
Number of OpDets in the whole detector.
size_type size() const
Definition: PtrVector.h:308
iterator insert(iterator position, Ptr< U > const &p)
Utility object to perform functions of association.
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
calo::CalorimetryAlg * fCaloAlg
Int_t min
Definition: plot.C:26
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
Char_t n[5]
TCEvent evt
Definition: DataStructs.cxx:5
Algorithm for generating space points from hits.
art framework interface to geometry description