LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
DisambigAlg.cxx
Go to the documentation of this file.
1 //
3 // DisambigAlg.cxx
4 //
5 // tylerdalion@gmail.com
6 //
7 // description
8 //
9 //
10 // Since we are letting the module make the final column of hits, a disambiguated
11 // hit in this algorithm is a pair< art::Ptr<recob::Hit>, geo::WireID >
12 //
13 //
15 
16 
17 //Framework includes:
23 
32 
33 
34 
35 #include <map>
36 #include <cmath>
37 #include <vector>
38 #include <iostream>
39 #include <fstream>
40 #include <cstdlib>
41 
42 
43 namespace apa{
44 
46  : fAPAGeo(pset.get< fhicl::ParameterSet >("APAGeometryAlg"))
47 {
48  this->reconfigure(pset);
49 }
50 
51 //----------------------------------------------------------
53 {
54 }
55 
56 //----------------------------------------------------------
58 {
59 
60  fCrawl = p.get< bool >("Crawl");
61  fUseEndP = p.get< bool >("UseEndP");
62  fCompareViews = p.get< bool >("CompareViews");
63  fCloseHitsRadius = p.get< double >("CloseHitsRadius");
64  fMaxEndPDegRange = p.get< double >("MaxEndPDegRange");
65  fNChanJumps = p.get< unsigned int >("NChanJumps");
66 
67 }
68 
69 
70 //----------------------------------------------------------
71 //----------------------------------------------------------
72 void DisambigAlg::RunDisambig( art::Handle< std::vector<recob::Hit> > ChannelHits )
73 {
74 
75  // **tomporarily** here to look at performance without noise hits
77 
78  fUeffSoFar.clear();
79  fVeffSoFar.clear();
80  fnUSoFar.clear();
81  fnVSoFar.clear();
82  fnDUSoFar.clear();
83  fnDVSoFar.clear();
84  fChannelToHits.clear();
85  fAPAToUVHits.clear();
86  fAPAToZHits.clear();
87  fAPAToHits.clear();
88  fAPAToEndPHits.clear();
89  fAPAToDHits.clear();
90  fDisambigHits.clear();
91  fChanTimeToWid.clear();
92  fHasBeenDisambiged.clear();
93 
94 
95  std::vector< art::Ptr<recob::Hit> > ChHits;
96  art::fill_ptr_vector(ChHits, ChannelHits);
97 
98 
99  fHasBeenDisambiged.clear();
100  unsigned int skipNoise(0);
101  // Map hits by channel/APA, initialize the disambiguation status map
102  for( size_t h = 0; h < ChHits.size(); h++ ){
103  art::Ptr<recob::Hit> hit = ChHits[h];
104 
105  // **temporary** option to skip noise hits
106  try{ bt_serv->HitToXYZ(hit); }
107  catch(...){
108  skipNoise++;
109  continue;
110  }
111 
112  geo::View_t view = hit->View();
113  unsigned int apa(0), cryo(0);
114  fAPAGeo.ChannelToAPA(hit->Channel(), apa, cryo);
115  fAPAToHits[apa].push_back(hit);
116  if( view == geo::kZ ){
117  fAPAToZHits[apa].push_back(hit);
118  continue;
119  } else if ( view==geo::kU || view==geo::kV ){
120  std::pair<double,double> ChanTime( hit->Channel()*1., hit->PeakTime()*1. );
121  this->fHasBeenDisambiged[apa][ChanTime] = false;
122  fChannelToHits[ hit->Channel() ].push_back( hit );
123  fAPAToUVHits[apa].push_back(hit);
124  }
125  }
126 
127  if(skipNoise>0)
128  mf::LogWarning("DisambigAlg")<<"\nSkipped "<< skipNoise <<" induction noise hits using the BackTrackerService.\n"
129  <<"This is only to temporarily deal with the excessive amount of noise due to the bad deconvolution.\n";
130 
131  mf::LogVerbatim("RunDisambig")<<"\n~~~~~~~~~~~ Running Disambiguation ~~~~~~~~~~~\n";
132 
133  std::map<unsigned int, std::vector< art::Ptr< recob::Hit> > >::iterator APA_it;
134  for( APA_it = fAPAToUVHits.begin(); APA_it != fAPAToUVHits.end(); APA_it++ ){
135  unsigned int apa = APA_it->first;
136 
137  mf::LogVerbatim("RunDisambig")<<"APA "<<apa<<":";
138 
139  fUeffSoFar[apa] = 0.; fVeffSoFar[apa] = 0.;
140  fnUSoFar[apa] = 0; fnVSoFar[apa] = 0;
141  fnDUSoFar[apa] = 0; fnDVSoFar[apa] = 0;
142 
143  // Always run this...
144  this->TrivialDisambig(apa);
145  this->AssessDisambigSoFar(apa);
146  mf::LogVerbatim("RunDisambig") << " Trivial Disambig --> "
147  << fnDUSoFar[apa] << " / " << fnUSoFar[apa] << " U, "
148  << fnDVSoFar[apa] << " / " << fnVSoFar[apa] << " V";
149 
150 
151  // ... and pick the rest with the configurations.
152  if( fCrawl ){
153  this->Crawl(apa);
154  this->AssessDisambigSoFar(apa);
155  mf::LogVerbatim("RunDisambig") << " Crawl --> "
156  << fnDUSoFar[apa] << " / " << fnUSoFar[apa] << " U, "
157  << fnDVSoFar[apa] << " / " << fnVSoFar[apa] << " V";
158  }
159 
160 
161  if(fUseEndP){
162  this->FindChanTimeEndPts(apa);
163  this->UseEndPts(apa); // does the crawl from inside
164  this->AssessDisambigSoFar(apa);
165  mf::LogVerbatim("RunDisambig") << " Endpoint Crawl --> "
166  << fnDUSoFar[apa] << " / " << fnUSoFar[apa] << " U, "
167  << fnDVSoFar[apa] << " / " << fnVSoFar[apa] << " V";
168  }
169 
170 
171  if(fCompareViews){
172  unsigned int nDisambig(1);
173  while(nDisambig > 0){
174  nDisambig = 0;
175  nDisambig = this->CompareViews(apa);
176  this->Crawl(apa);
177  }
178  this->AssessDisambigSoFar(apa);
179  mf::LogVerbatim("RunDisambig") << " Compare Views --> "
180  << fnDUSoFar[apa] << " / " << fnUSoFar[apa] << " U, "
181  << fnDVSoFar[apa] << " / " << fnVSoFar[apa] << " V";
182  }
183 
184 
185  //this->GatherLeftoverHits()
186 
187  // For now just buld a simple list to get from the module
188  for(size_t i=0; i<fAPAToDHits[apa].size(); i++)
189  fDisambigHits.push_back(fAPAToDHits[apa][i]);
190 
191  } // end loop through APA
192 
193 
194 }
195 
196 
197 
198 
199 //-------------------------------------------------
200 //-------------------------------------------------
202  geo::WireID wid,
203  unsigned int apa )
204 {
205 
206  std::pair<double,double> ChanTime( hit->Channel()*1., hit->PeakTime()*1. );
207  if( fHasBeenDisambiged[apa][ChanTime] ) return;
208 
209  if( !wid.isValid ){
210  mf::LogWarning("InvalidWireID") << "wid is invalid, hit not being made\n";
211  return; }
212 
213  std::pair<art::Ptr<recob::Hit>,geo::WireID> Dhit(hit, wid);
214  fAPAToDHits[apa].push_back(Dhit);
215  fHasBeenDisambiged[apa][ChanTime] = true;
216  fChanTimeToWid[ChanTime] = wid;
217  return;
218 
219 }
220 
221 
222 
223 //----------------------------------------------------------
224 //----------------------------------------------------------
226  art::Ptr<recob::Hit> hitB )
227 {
228  double AsT = hitA->PeakTimeMinusRMS();
229  double AeT = hitA->PeakTimePlusRMS();
230  double BsT = hitB->PeakTimeMinusRMS();
231  double BeT = hitB->PeakTimePlusRMS();
232 
233  const detinfo::DetectorProperties* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
234 
235  if( hitA->View() == geo::kU ){ AsT -= detprop->TimeOffsetU(); AeT -= detprop->TimeOffsetU(); }
236  else if( hitA->View() == geo::kV ){ AsT -= detprop->TimeOffsetV(); AeT -= detprop->TimeOffsetV(); }
237  else if( hitA->View() == geo::kZ ){ AsT -= detprop->TimeOffsetZ(); AeT -= detprop->TimeOffsetZ(); }
238  if( hitB->View() == geo::kU ){ BsT += detprop->TimeOffsetU(); BeT -= detprop->TimeOffsetU(); }
239  else if( hitB->View() == geo::kV ){ BsT -= detprop->TimeOffsetV(); BeT -= detprop->TimeOffsetV(); }
240  else if( hitA->View() == geo::kZ ){ AsT -= detprop->TimeOffsetZ(); AeT -= detprop->TimeOffsetZ(); }
241 
242  return (AsT<=BsT && BsT<=AeT) || (AsT<=BeT && BeT<=AeT) ||
243  (BsT<=AsT && AsT<=BeT) || (BsT<=AeT && AeT<=BeT);
244 }
245 
246 
247 
248 //----------------------------------------------------------
249 //----------------------------------------------------------
250 void DisambigAlg::TrivialDisambig( unsigned int apa )
251 {
252 
253  // Loop through ambiguous hits (U/V) in this APA
254  for( size_t h=0; h<fAPAToUVHits[apa].size(); h++ ){
255  const art::Ptr<recob::Hit> hit = fAPAToUVHits[apa][h];
256  raw::ChannelID_t chan = hit->Channel();
257  unsigned int peakT = hit->PeakTime();
258 
259  std::vector<geo::WireID> hitwids = geom->ChannelToWire(chan);
260  std::vector<bool> IsReasonableWid(hitwids.size(),false);
261  unsigned short nPossibleWids(0);
262  for(size_t w=0; w<hitwids.size(); w++){
263  geo::WireID wid = hitwids[w];
264 
265  double xyzStart[3] = {0.}; double xyzEnd[3] = {0.};
266  geom->WireEndPoints(wid.Cryostat, wid.TPC, wid.Plane, wid.Wire, xyzStart, xyzEnd);
267  unsigned int side(wid.TPC%2), cryo(wid.Cryostat);
268  double zminPos(xyzStart[2]), zmaxPos(xyzEnd[2]);
269 
270  // get appropriate x and y with tpc center
271  TVector3 tpcCenter(0,0,0);
272  unsigned int tpc = 2*apa + side - cryo*geom->NTPC(); // apa number does not reset per cryo
273  tpcCenter = geom->Cryostat(cryo).TPC(tpc).LocalToWorld(tpcCenter);
274 
275  // get channel range
276  TVector3 Min(tpcCenter); Min[2] = zminPos;
277  TVector3 Max(tpcCenter); Max[2] = zmaxPos;
278  raw::ChannelID_t ZminChan = geom->NearestChannel( Min, 2, tpc, cryo );
279  raw::ChannelID_t ZmaxChan = geom->NearestChannel( Max, 2, tpc, cryo );
280 
281  for( size_t z=0; z < fAPAToZHits[apa].size(); z++ ){
282  raw::ChannelID_t chan = fAPAToZHits[apa][z]->Channel();
283  if( chan <= ZminChan || ZmaxChan <= chan ) continue;
284  art::Ptr<recob::Hit> zhit = fAPAToZHits[apa][z];
285 
286 // try{ bt_serv->HitToXYZ(zhit); }
287 // catch(...){
288 // mf::LogWarning("DisambigAlg")<<"skipping a noise collection hit";
289 // continue;
290 // }
291 
292  if( this->HitsOverlapInTime(hit,zhit) ){
293  IsReasonableWid[w] = true; nPossibleWids++; break; }
294  }
295 
296  } // end hit chan-wid loop
297 
298 
299 
300  if(nPossibleWids==0){
301  std::vector<double> xyz;
302  try{ xyz = bt_serv->HitToXYZ(hit); } // TEMPORARY
303  catch(...){ continue; }
305  mf::LogWarning ("UniqueTimeSeg") << "U/V hit inconsistent with Z info; peak time is "
306  << peakT << " in APA " << apa << " on channel " << hit->Channel();
307  }
308  else if(nPossibleWids==1){
309  for(size_t d=0; d<hitwids.size(); d++)
310  if(IsReasonableWid[d]) this->MakeDisambigHit( hit, hitwids[d], apa );
311  }
312  else if(nPossibleWids==2){
314  }
315 
316 
317  } // end ambig hits loop
318 
319 
320 }
321 
322 
323 
324 //----------------------------------------------------------
325 //----------------------------------------------------------
326 unsigned int DisambigAlg::MakeCloseHits( int ext, geo::WireID Dwid, double Dmin, double Dmax)
327 {
328 
329  // Function to look, on a channel *ext* channels away from
330  // a disambiguated hit channel, for hits with time windows
331  // touching range *Dmin to Dmax*. If found, make such a
332  // hit to have a wireID adjacent to supplied *wid*.
333  // Returns number of NEW hits made.
334 
335 
336 
337  raw::ChannelID_t Dchan = geom->PlaneWireToChannel(Dwid.Plane, Dwid.Wire, Dwid.TPC, Dwid.Cryostat);
338  geo::View_t view = geom->View(Dchan);
339  if(view==geo::kZ)
340  throw cet::exception("MakeCloseHits") << "Function not meant for non-wrapped channels.\n";
341 
342  // Account for wrapping
343  raw::ChannelID_t firstChan = fAPAGeo.FirstChannelInView(view, Dchan);
344  unsigned int ChanPerView = fAPAGeo.ChannelsInView(view);
345  int tempchan = Dchan + ext; // need sign for the set of channels starting with channel 0
346  if( tempchan < (int)firstChan ) tempchan += ChanPerView;
347  if( tempchan > (int)(firstChan+ChanPerView-1) ) tempchan -= ChanPerView;
348  raw::ChannelID_t chan = (raw::ChannelID_t)(tempchan);
349 
350  // There may just be no hits
351  if( fChannelToHits.count(chan) == 0 ) return 0;
352 
353  // There are close channel hits, so for each
354  unsigned int apa(0), cryo(0);
355  fAPAGeo.ChannelToAPA(chan, apa, cryo);
356  unsigned int MakeCount(0);
357  for(size_t i=0; i<fChannelToHits[chan].size(); i++){
358  art::Ptr< recob::Hit > closeHit = fChannelToHits[chan][i];
359  double st = closeHit->PeakTimeMinusRMS();
360  double et = closeHit->PeakTimePlusRMS();
361  std::vector<geo::WireID> wids = geom->ChannelToWire(chan);
362 
363  if( !(Dmin <= st && st <= Dmax) && !(Dmin <= et && et <= Dmax) ) continue;
364 
365 
366  // Found hit with window overlapping given range,
367  // now find the only reasonable wireID.
368  for(size_t w=0; w<wids.size(); w++){
369  if( wids[w].TPC != Dwid.TPC ) continue;
370  if( (int)(wids[w].Wire)-(int)(Dwid.Wire) != ext ) continue;
371 
372  // In this case, we have a unique wireID.
373  // Check to see if it has already been made - if so, do not incriment count
374  std::pair<double,double> ChanTime( closeHit->Channel()*1., closeHit->PeakTime()*1. );
375  if( !fHasBeenDisambiged[apa][ChanTime] ){
376  this->MakeDisambigHit(closeHit, wids[w], apa);
377  MakeCount++;
378  //std::cout << " Close hit found on channel " << chan << ", time " << st<<"-"<<et << "... \n";
379  //std::cout << " ... giving it wireID ("<< Dwid.Cryostat <<"," << Dwid.TPC
380  // << "," << Dwid.Plane << "," << Dwid.Wire << ")\n";
381  }
382  break;
383  } // end find right wireID
384 
385 
386  } // end loop through all hits on chan
387 
388  return MakeCount;
389 
390 }
391 
392 
393 
394 
395 
396 
397 //----------------------------------------------------------
398 //----------------------------------------------------------
399 void DisambigAlg::Crawl( unsigned int apa )
400 {
401 
402  std::vector<art::Ptr<recob::Hit> > hits = fAPAToUVHits[apa];
403 
404  // repeat this method until stable
405  unsigned int nExtended(1);
406  while( nExtended > 0 ){
407  nExtended = 0;
408 
409  // Look for any disambiguated hit ...
410  for(size_t h=0; h < hits.size(); h++){
411  std::pair<double,double> ChanTime( hits[h]->Channel()*1., hits[h]->PeakTime()*1. );
412  if( !fHasBeenDisambiged[apa][ChanTime] ) continue;
413  double stD = hits[h]->PeakTimePlusRMS(-1.);
414  double etD = hits[h]->PeakTimePlusRMS(+1.);
415  double hitWindow = etD - stD;
416  geo::WireID Dwid = fChanTimeToWid[ChanTime];
417 
418  // ... and if any neighboring-channel hits are close enough in time,
419  // extend the disambiguation to the neighboring wire.
420  unsigned int extensions = 0;
421  for( unsigned int ext=1; ext < fNChanJumps+1; ext++ ){
423  unsigned int N(0);
424  double timeExt = hitWindow*ext;
425  N += this->MakeCloseHits( (int)(-ext), Dwid, stD-5-timeExt, etD+5+timeExt);
426  N += this->MakeCloseHits( (int)(ext), Dwid, stD-5-timeExt, etD+5+timeExt);
427  extensions += N;
428  }
429  nExtended += extensions;
430 
431  } // end UV hits loop
432 
433  } // end while still disambiguating***
434 
435  // *** nested while loops allow disambigauation to hop the channel-wrap-boundary
436 
437 
438 }
439 
440 
441 
442 //----------------------------------------------------------
443 //----------------------------------------------------------
444 unsigned int DisambigAlg::FindChanTimeEndPts( unsigned int apa )
445 {
446 
449 
450  double pi = 3.14159265;
451  double fMaxEndPRadRange = fMaxEndPDegRange/180. * (2*pi);
452 
453  const detinfo::DetectorProperties* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
454 
455  for(size_t h=0; h<fAPAToHits[apa].size(); h++){
456  art::Ptr<recob::Hit> centhit = fAPAToHits[apa][h];
457  geo::View_t view = centhit->View();
458  unsigned int plane = 0; if(view==geo::kV){ plane = 1; } else if(view==geo::kZ) plane = 2;
459  std::vector<double> ChanTimeCenter(2, 0.);
460  unsigned int relchan = centhit->Channel() - fAPAGeo.FirstChannelInView(centhit->Channel());
461  ChanTimeCenter[0] = relchan*geom->WirePitch(view);
462  ChanTimeCenter[1] = detprop->ConvertTicksToX( centhit->PeakTime(),
463  plane,
464  apa*2, // tpc doesnt matter
465  centhit->WireID().Cryostat );
466  //std::vector< art::Ptr<recob::Hit> > CloseHits;
467  std::vector<std::vector<double> > CloseHitsChanTime;
468  std::vector<double> FurthestCloseChanTime(2,0.); //double maxDist = 0.;
469  std::vector<double> ClosestChanTime(2,0.); double minDist = fCloseHitsRadius+1.;
470  double ChanDistRange = fAPAGeo.ChannelsInView(view)*geom->WirePitch(view);
471 
472  for(size_t c=0; c<fAPAToHits[apa].size(); c++){
473  art::Ptr<recob::Hit> closehit = fAPAToHits[apa][c];
474  if(view!=closehit->View()) continue;
475  if(view==geo::kZ && centhit->WireID().TPC != closehit->WireID().TPC ) continue;
476  unsigned int plane = 0; if(view==geo::kV){ plane = 1; } else if(view==geo::kZ) plane = 2;
477  std::vector<double> ChanTimeClose(2, 0.);
478  unsigned int relchanclose = closehit->Channel() - fAPAGeo.FirstChannelInView(closehit->Channel());
479  ChanTimeClose[0] = relchanclose*geom->WirePitch(view);
480  ChanTimeClose[1] = detprop->ConvertTicksToX( closehit->PeakTime(),
481  plane,
482  apa*2, // tpc doesnt matter
483  closehit->WireID().Cryostat );
484  if(ChanTimeClose == ChanTimeCenter) continue; // move on if the same one
485 
486  double ChanDist = ChanTimeClose[0]-ChanTimeCenter[0];
487  if( ChanDist > ChanDistRange/2 ) ChanDist = ChanDistRange - ChanDist;
488 
489  double distance = std::sqrt( std::pow(ChanDist,2)
490  + std::pow(ChanTimeClose[1]-ChanTimeCenter[1],2) );
491 
492  if( distance <= fCloseHitsRadius ) CloseHitsChanTime.push_back(ChanTimeClose);
493 
494  if( distance < minDist ){
495  ClosestChanTime = ChanTimeClose;
496  minDist = distance;
497  }
498 
499  } // end close-by hit loop
500 
501  if(CloseHitsChanTime.size()<5) continue; // quick fix, to-be improved
502 
503  double minRad(2*pi+1.), maxRad(0.);
504  bool CloseToNegPi(false), CloseToPosPi(false);
505  for(size_t i=0; i<CloseHitsChanTime.size(); i++){
506  std::vector<double> ThisChanTime(CloseHitsChanTime[i]);
507  //if(ThisChanTime==ClosestChanTime) continue;
508  double ChanDist = ThisChanTime[0]-ChanTimeCenter[0];
509  if( ChanDist > ChanDistRange/2 ) ChanDist = ChanDistRange - ChanDist;
510  double hitrad = std::atan2( ThisChanTime[1]-ChanTimeCenter[1] ,
511  ChanDist );
512  if( hitrad > maxRad ) maxRad = hitrad;
513  if( hitrad < minRad ) minRad = hitrad;
514  if( hitrad + fMaxEndPRadRange > pi ) CloseToPosPi = true;
515  else if( hitrad - fMaxEndPRadRange < -pi ) CloseToNegPi = true;
516  }
517 
518  // activity at this boundary automatically kills the test, move boundary and redo
519  if(CloseToPosPi&&CloseToNegPi){
520  for(size_t i=0; i<CloseHitsChanTime.size(); i++){
521  std::vector<double> ThisChanTime(CloseHitsChanTime[i]);
522  //if(ThisChanTime==ClosestChanTime) continue;
523  double ChanDist = ThisChanTime[0]-ChanTimeCenter[0];
524  if( ChanDist > ChanDistRange/2 ) ChanDist = ChanDistRange - ChanDist;
525  double hitrad = std::atan2( ThisChanTime[1]-ChanTimeCenter[1] ,
526  ChanDist );
527  if( hitrad > 0 ) hitrad = pi - hitrad; // reflec across pi/2 line
528  if( hitrad < 0 ) hitrad = -pi - hitrad;
529  if( hitrad > maxRad ) maxRad = hitrad;
530  if( hitrad < minRad ) minRad = hitrad;
531  }
532  }
533 
534  if( maxRad - minRad < fMaxEndPRadRange ) fAPAToEndPHits[apa].push_back( centhit );
535 
536  } // end UV hit loop
537 
538  if(fAPAToEndPHits[apa].size()==0) return 0;
539  mf::LogVerbatim("FindChanTimeEndPts") << " Found " << fAPAToEndPHits[apa].size()
540  << " endpoint hits in apa " << apa << std::endl;
541  for(size_t ep=0; ep<fAPAToEndPHits[apa].size(); ep++){
542  art::Ptr<recob::Hit> epHit = fAPAToEndPHits[apa][ep];
543  mf::LogVerbatim("FindChanTimeEndPts") << " endP on channel " << epHit->Channel()
544  << " at time " << epHit->PeakTime() << std::endl;
545  }
546 
547  return fAPAToEndPHits[apa].size();
548 
549 }
550 
551 
552 
553 
554 
555 //----------------------------------------------------------
556 //----------------------------------------------------------
557 void DisambigAlg::UseEndPts( unsigned int apa )
558 {
559 
561 
562  if(fAPAToEndPHits[apa].size()==0){
563  mf::LogVerbatim("UseEndPts") << " APA " << apa << " has no endpoints.";
564  return; }
565  std::vector< art::Ptr<recob::Hit> > endPts = fAPAToEndPHits[apa];
566 
567 
568  std::vector<std::vector< art::Ptr<recob::Hit> > > EndPMatch;
569  unsigned short nZendPts(0);
570  for(size_t ep=0; ep<endPts.size(); ep++){
571  if(endPts[ep]->View()!=geo::kZ) continue;
572  art::Ptr<recob::Hit> Zhit = endPts[ep];
573  art::Ptr<recob::Hit> Uhit(Zhit), Vhit(Zhit);
574  unsigned short Umatch(0), Vmatch(0);
575  nZendPts++;
576 
577  // look for U and V hits overlapping in time
578  for(size_t p=0; p<endPts.size(); p++){
579  if(endPts[p]->View()==geo::kU){
580  if( this->HitsOverlapInTime(Zhit, endPts[p]) ){
581  Uhit = endPts[p];
582  //endPts.erase(endPts.begin()+p);
583  Umatch++; }
584  } else if(endPts[p]->View()==geo::kV){
585  if( this->HitsOverlapInTime(Zhit, endPts[p]) ){
586  Vhit = endPts[p];
587  //endPts.erase(endPts.begin()+p);
588  Vmatch++; }
589  }
590  }
591 
592 
593  TVector3 tpcCenter(0,0,0);
594  unsigned int tpc(endPts[ep]->WireID().TPC), cryo(endPts[ep]->WireID().Cryostat);
595  tpcCenter = geom->Cryostat(cryo).TPC(tpc).LocalToWorld(tpcCenter);
596 
597 
598  if(Umatch == 1 && Vmatch == 1){
599 
600  std::vector<double> yzEndPt
601  = fAPAGeo.ThreeChanPos(Uhit->Channel(), Vhit->Channel(), endPts[ep]->Channel());
602  double intersect[3] = {tpcCenter[0], yzEndPt[0], yzEndPt[1]};
603 
604  geo::WireID Uwid = fAPAGeo.NearestWireIDOnChan(intersect, Uhit->Channel(), 0, tpc, cryo);
605  geo::WireID Vwid = fAPAGeo.NearestWireIDOnChan(intersect, Vhit->Channel(), 1, tpc, cryo);
606  this->MakeDisambigHit(Uhit, Uwid, apa);
607  this->MakeDisambigHit(Vhit, Vwid, apa);
608 
609  } else if(Umatch == 1 && Vmatch != 1){
610 
611  std::vector< geo::WireIDIntersection > widIntersects;
612  fAPAGeo.APAChannelsIntersect(Uhit->Channel(), Zhit->Channel(), widIntersects);
613  if( widIntersects.size() == 0 ) continue;
614  else if( widIntersects.size() == 1 ){
615  double intersect[3] = {tpcCenter[0], widIntersects[0].y, widIntersects[0].z};
616  geo::WireID Uwid = fAPAGeo.NearestWireIDOnChan(intersect, Uhit->Channel(), 0, tpc, cryo);
617  this->MakeDisambigHit(Uhit, Uwid, apa);
618  } else {
619  for(size_t i=0; i < widIntersects.size(); i++){
620  // compare to V hit times, see if only one makes sense
621  }
622  }
623 
624  } else if(Umatch == 1 && Vmatch != 1){
625 
626  std::vector< geo::WireIDIntersection > widIntersects;
627  fAPAGeo.APAChannelsIntersect(Vhit->Channel(), Zhit->Channel(), widIntersects);
628  if( widIntersects.size() == 0 ) continue;
629  else if( widIntersects.size() == 1 ){
630  double intersect[3] = {tpcCenter[0], widIntersects[0].y, widIntersects[0].z};
631  geo::WireID Vwid = fAPAGeo.NearestWireIDOnChan(intersect, Vhit->Channel(), 0, tpc, cryo);
632  this->MakeDisambigHit(Vhit, Vwid, apa);
633  } else {
634  for(size_t i=0; i < widIntersects.size(); i++){
635  // compare to V hit times, see if only one makes sense
636  }
637  }
638 
639  }
640 
641  //endPts.erase(endPts.begin()+ep);
642  }
643 
644 
645  if( nZendPts==0 && endPts.size()==2 && this->HitsOverlapInTime(endPts[0],endPts[1]) ){
646  std::vector< geo::WireIDIntersection > widIntersects;
647  fAPAGeo.APAChannelsIntersect(endPts[0]->Channel(), endPts[1]->Channel(), widIntersects);
648  if( widIntersects.size() == 1 ){
649  TVector3 tpcCenter(0,0,0);
650  unsigned int cryo = endPts[0]->WireID().Cryostat;
651  unsigned int tpc = widIntersects[0].TPC;
652  tpcCenter = geom->Cryostat(cryo).TPC(tpc).LocalToWorld(tpcCenter);
653  double intersect[3] = {tpcCenter[0], widIntersects[0].y, widIntersects[0].z};
654  unsigned int plane0(0), plane1(0);
655  if( endPts[0]->View()==geo::kV ) plane0=1;
656  if( endPts[1]->View()==geo::kV ) plane1=1;
657  geo::WireID wid0 = fAPAGeo.NearestWireIDOnChan(intersect, endPts[0]->Channel(), plane0, tpc, cryo);
658  this->MakeDisambigHit(endPts[0], wid0, apa);
659  geo::WireID wid1 = fAPAGeo.NearestWireIDOnChan(intersect, endPts[1]->Channel(), plane1, tpc, cryo);
660  this->MakeDisambigHit(endPts[1], wid1, apa);
661  } else if( widIntersects.size() > 1 ){
662  for(size_t i=0; i < widIntersects.size(); i++){
663  // compare to V hit times, see if only one makes sense
664  }
665  }
666  }
667 
668 
669  this->Crawl(apa);
670 
671 }
672 
673 
674 //----------------------------------------------------------
675 //----------------------------------------------------------
677 {
678 
679  unsigned int nU(0), nV(0);
680  for(size_t h=0; h < fAPAToUVHits[apa].size(); h++){
682  if(hit->View()==geo::kU) nU++;
683  else if(hit->View()==geo::kV) nV++;
684  }
685 
686  unsigned int nDU(0), nDV(0);
687  for(size_t h=0; h < fAPAToDHits[apa].size(); h++){
688  art::Ptr<recob::Hit> hit = fAPAToDHits[apa][h].first;
689  if(hit->View()==geo::kU) nDU++;
690  else if(hit->View()==geo::kV) nDV++;
691  }
692 
693  fUeffSoFar[apa] = (nDU*1.)/(nU*1.);
694  fVeffSoFar[apa] = (nDV*1.)/(nV*1.);
695  fnUSoFar[apa] = nU;
696  fnVSoFar[apa] = nV;
697  fnDUSoFar[apa] = nDU;
698  fnDVSoFar[apa] = nDV ;
699 
700 
701 }
702 
703 
704 //----------------------------------------------------------
705 //----------------------------------------------------------
706 unsigned int DisambigAlg::CompareViews( unsigned int apa )
707 {
708 
709  unsigned int nDisambiguations(0);
710 
711  // loop through all hits that are still ambiguous
712  for(size_t h=0; h < fAPAToUVHits[apa].size(); h++){
713  art::Ptr<recob::Hit> ambighit = fAPAToUVHits[apa][h];
714  raw::ChannelID_t ambigchan = ambighit->Channel();
715  std::pair<double,double> ambigChanTime(ambigchan*1.,ambighit->PeakTime());
716  if( fHasBeenDisambiged[apa][ambigChanTime] ) continue;
717  geo::View_t view = ambighit->View();
718  std::vector<geo::WireID> ambigwids = geom->ChannelToWire(ambigchan);
719  std::vector<unsigned int> widDcounts (ambigwids.size(), 0);
720  std::vector<unsigned int> widAcounts (ambigwids.size(), 0);
721 
722 
723 
724  // loop through hits in the other view which are close in time
725  for(size_t i=0; i < fAPAToUVHits[apa].size(); i++){
727  if(hit->View()==view || !this->HitsOverlapInTime(ambighit, hit)) continue;
728 
729  // An other-view-hit overlaps in time, see what
730  // wids of the ambiguous hit's channels it overlaps
731  raw::ChannelID_t chan = hit->Channel();
732  std::vector<geo::WireID> wids = geom->ChannelToWire(chan);
733  std::pair<double,double> ChanTime(chan*1.,hit->PeakTime());
734  geo::WireIDIntersection widIntersect; // only so we can use the function
735  if( fHasBeenDisambiged[apa][ChanTime] ){
736  for(size_t a=0; a<ambigwids.size(); a++)
737  if( ambigwids[a].TPC == fChanTimeToWid[ChanTime].TPC &&
738  geom->WireIDsIntersect(ambigwids[a], fChanTimeToWid[ChanTime], widIntersect) ) widDcounts[a]++;
739  } else {
740  // still might be able to glean disambiguation
741  // from the ambiguous hits at this time
742  for(size_t a=0; a<ambigwids.size(); a++)
743  for(size_t w=0; w<wids.size(); w++)
744  if( ambigwids[a].TPC == wids[w].TPC &&
745  geom->WireIDsIntersect(ambigwids[a], wids[w], widIntersect) ) widAcounts[a]++;
746  }
747  } // end loop through close-time hits
748 
749 
750  // For now, just make a hit if either ambig or disambig hits
751  // unanimously intersect a single wireID
752  unsigned int Dcount(0), Acount(0);
753  for(size_t d=0; d<widDcounts.size(); d++) Dcount += widDcounts[d];
754  for(size_t a=0; a<widAcounts.size(); a++) Acount += widAcounts[a];
755  for(size_t d=0; d<widDcounts.size(); d++){
756  if( Dcount == widDcounts[d] && Dcount>0 && Acount==0 ){
757  this->MakeDisambigHit(ambighit, ambigwids[d], apa);
758  nDisambiguations++; } }
759  for(size_t a=0; a<widAcounts.size(); a++){
760  if( Acount == widAcounts[a] && Acount==1 ){
761  //this->MakeDisambigHit(ambighit, ambigwids[a], apa);
762  //nDisambiguations++;
763  } }
764 
765 
766  } // end loop through still ambiguous hits
767 
768 
769  return nDisambiguations;
770 }
771 
772 
773 } //end namespace apa
bool APAChannelsIntersect(uint32_t chan1, uint32_t chan2, std::vector< geo::WireIDIntersection > &IntersectVector)
If the channels intersect, get all intersections.
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::map< std::pair< double, double >, geo::WireID > fChanTimeToWid
If a hit is disambiguated, map its chan and peak time to the chosen wireID.
Definition: DisambigAlg.h:90
Encapsulate the construction of a single cyostat.
const std::vector< double > HitToXYZ(const recob::Hit &hit)
double fCloseHitsRadius
Distance (cm) away from a hit to look when checking if it&#39;s an endpoint.
Definition: DisambigAlg.h:115
virtual ~DisambigAlg()
Definition: DisambigAlg.cxx:52
std::map< unsigned int, unsigned int > fnDVSoFar
Definition: DisambigAlg.h:65
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
Planes which measure V.
Definition: geo_types.h:77
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
apa::APAGeometryAlg fAPAGeo
Definition: DisambigAlg.h:73
unsigned int ChannelToAPA(uint32_t chan)
Get number of the APA containing the given channel.
Declaration of signal hit object.
std::map< unsigned int, unsigned int > fnVSoFar
Definition: DisambigAlg.h:63
Double_t z
Definition: plot.C:279
bool isValid
Whether this ID points to a valid element.
Definition: geo_types.h:129
void Crawl(unsigned int apa)
Extend what we disambiguation we do have in apa.
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:130
Planes which measure Z direction.
Definition: geo_types.h:79
geo::View_t View() const
View for the plane of the hit.
Definition: Hit.h:233
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:313
bool HitsOverlapInTime(art::Ptr< recob::Hit > hitA, art::Ptr< recob::Hit > hitB)
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
std::vector< std::pair< art::Ptr< recob::Hit >, geo::WireID > > fDisambigHits
The final list of hits to pass back to be made.
Definition: DisambigAlg.h:67
art::ServiceHandle< cheat::BackTrackerService > bt_serv
For TEMPORARY monitering of potential problems.
Definition: DisambigAlg.h:76
Planes which measure U.
Definition: geo_types.h:76
void TrivialDisambig(unsigned int apa)
Make the easiest and safest disambiguations in apa.
void hits()
Definition: readHits.C:15
std::map< unsigned int, std::vector< art::Ptr< recob::Hit > > > fAPAToEndPHits
\ todo: Channel/APA to hits can be done in a unified way
Definition: DisambigAlg.h:83
uint32_t FirstChannelInView(geo::View_t geoview, unsigned int apa, unsigned int cryo)
void AssessDisambigSoFar(unsigned int apa)
See how much disambiguation has been done in this apa so far.
virtual double TimeOffsetV() const =0
parameter set interface
T get(std::string const &key) const
Definition: ParameterSet.h:231
std::map< raw::ChannelID_t, std::vector< art::Ptr< recob::Hit > > > fChannelToHits
Definition: DisambigAlg.h:79
DisambigAlg(fhicl::ParameterSet const &pset)
Definition: DisambigAlg.cxx:45
std::vector< double > ThreeChanPos(uint32_t u, uint32_t v, uint32_t z)
Find the center of the 3 intersections, choose best if multiple.
Float_t d
Definition: plot.C:237
virtual double TimeOffsetZ() const =0
std::map< unsigned int, double > fVeffSoFar
Definition: DisambigAlg.h:61
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:258
unsigned int fNChanJumps
Number of channels the crawl can jump over.
Definition: DisambigAlg.h:114
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
void reconfigure(fhicl::ParameterSet const &p)
Definition: DisambigAlg.cxx:57
float PeakTimeMinusRMS(float sigmas=+1.) const
Returns a time sigmas RMS away from the peak time.
Definition: Hit.h:240
unsigned int FindChanTimeEndPts(unsigned int apa)
Basic endpoint-hit finder per apa.
Detector simulation of raw signals on wires.
unsigned int CompareViews(unsigned int apa)
Compare U and V to see if one says something about the other.
Encapsulate the geometry of a wire.
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
void UseEndPts(unsigned int apa)
Try to associate endpoint hits and crawl from there.
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, geo::Point_t &intersection) const
Computes the intersection between two wires.
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:219
std::map< unsigned int, std::map< std::pair< double, double >, bool > > fHasBeenDisambiged
Convenient way to keep track of disambiguation so far.
Definition: DisambigAlg.h:92
Utility object to perform functions of association.
Encapsulate the construction of a single detector plane.
unsigned int ChannelsInView(geo::View_t geoview)
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc&#39;th TPC in the cryostat.
std::map< unsigned int, std::vector< art::Ptr< recob::Hit > > > fAPAToHits
Definition: DisambigAlg.h:81
std::map< unsigned int, std::vector< art::Ptr< recob::Hit > > > fAPAToUVHits
Definition: DisambigAlg.h:80
bool fCrawl
\ todo: Write function that compares hits more detailedly
Definition: DisambigAlg.h:111
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
std::map< unsigned int, std::vector< std::pair< art::Ptr< recob::Hit >, geo::WireID > > > fAPAToDHits
Hold the disambiguations per APA.
Definition: DisambigAlg.h:84
std::map< unsigned int, std::vector< art::Ptr< recob::Hit > > > fAPAToZHits
Definition: DisambigAlg.h:80
void WireEndPoints(geo::WireID const &wireid, double *xyzStart, double *xyzEnd) const
Fills two arrays with the coordinates of the wire end points.
double fMaxEndPDegRange
Definition: DisambigAlg.h:116
Declaration of basic channel signal object.
std::map< unsigned int, double > fUeffSoFar
Definition: DisambigAlg.h:60
void MakeDisambigHit(art::Ptr< recob::Hit > hit, geo::WireID, unsigned int apa)
Makes a disambiguated hit while keeping track of what has already been disambiguated.
float PeakTimePlusRMS(float sigmas=+1.) const
Returns a time sigmas RMS away from the peak time.
Definition: Hit.h:237
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:27
art::ServiceHandle< geo::Geometry > geom
Definition: DisambigAlg.h:74
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:464
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:203
raw::ChannelID_t NearestChannel(geo::Point_t const &worldLoc, geo::PlaneID const &planeid) const
Returns the ID of the channel nearest to the specified position.
std::map< unsigned int, unsigned int > fnUSoFar
Definition: DisambigAlg.h:62
virtual double TimeOffsetU() const =0
Float_t w
Definition: plot.C:23
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
Definition: Hit.h:231
void LocalToWorld(const double *tpc, double *world) const
Transform point from local TPC frame to world frame.
Definition: TPCGeo.h:490
unsigned int MakeCloseHits(int ext, geo::WireID wid, double Dmin, double Dmax)
Having disambiguated a time range on a wireID, extend to neighboring channels.
const detinfo::DetectorProperties * detprop
Definition: DisambigAlg.h:75
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Encapsulate the construction of a single detector plane.
void RunDisambig(art::Handle< std::vector< recob::Hit > > GausHits)
Run disambiguation as currently configured.
Definition: DisambigAlg.cxx:72
geo::WireID NearestWireIDOnChan(const double WorldLoc[3], uint32_t chan, unsigned int const plane, unsigned int const tpc=0, unsigned int const cstat=0)
std::map< unsigned int, unsigned int > fnDUSoFar
Definition: DisambigAlg.h:64