SingleCRTMatching_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: SingleCRTMatching
3 // Plugin Type: analyzer (art v2_11_02)
4 // File: SingleCRTMatching_module.cc
5 //
6 // Written by: Richard Diurba
7 // Adapted from MCC Code by: Arbin Timilsina
8 // CRT Trigger Architecture by: Andrew Olivier
9 ////////////////////////////////////////////////////////////////////////
10 
11 //Framework includes
20 #include "fhiclcpp/ParameterSet.h"
23 #include "canvas/Persistency/Common/FindManyP.h"
24 #include "art_root_io/TFileService.h"
25 
26 //LArSoft includes
27 
31 #include "nug4/ParticleNavigation/ParticleList.h"
32 
37 
40 
42 
44 
45 
48 
53 
54 //Local includes
56 
57 //ROOT includes
58 #include "TH1.h"
59 #include "TH2.h"
60 #include "TCanvas.h"
61 #include "TImage.h"
62 #include "TTree.h"
63 #include "TH1D.h"
64 #include "TStyle.h"
65 #include "TString.h"
66 
67 //c++ includes
68 #include <numeric> //std::accumulate was moved from <algorithm> to <numeric> in c++14
69 #include <iostream>
70 #include <cmath>
71 using namespace std; // Namespaces established to make life easier
72 using namespace ROOT::Math;
73 namespace CRT {
74  class SingleCRTMatching;
75 }
76 
77 
79  public: // Setup functions and variables
81  const & p);
82  std::string fTrackModuleLabel = "pandoraTrack";
83  std::string fopModuleLabel= "opflash";
84  // The compiler-generated destructor is fine for non-base
85  // classes without bare pointers or other resource use.
86  // Plugins should not be copied or assigned.
88  const & ) = delete;
91  const & ) = delete;
92  SingleCRTMatching & operator = (SingleCRTMatching && ) = delete;
93  void analyze(art::Event
94  const & e) override;
95 // Declare functions and variables for validation
96  bool moduleMatcher(int module1, int module2);
97  void beginJob() override;
98  void endJob() override;
99  double setAngle(double angle);
100 int moduletoCTB(int module2, int module1);
101  int nEvents = 0;
102  int nHaloMuons = 0;
103  int track=0;
104  int matchedTrack=0;
105  int truthTrack=0;
106  int misMatchedTrack=0;
107  private: ofstream logFile;
108 
109  //Parameters for reading in CRT::Triggers and associated AuxDetSimChannels.
110  art::InputTag fCRTLabel; //Label for the module that produced
112  TTree * fCRTTree;
113  TTree * fMCCTree;
121 
122 
123  double dotCos;
124  int adcX, adcY;
125  double X_CRT, Y_CRT, Z_CRT;
126  double trackX1, trackX2, trackY1, trackY2, trackZ1, trackZ2;
127  int moduleX, moduleY;
128  int stripX, stripY;
129  double deltaX, deltaY;
130  double CRTT0;
131  double flashTime;
132  double opCRTTDiff;
135  double truthPosX, truthPosY, truthPosZ;
138  double mccE;
139  double mccT0;
140  double opCRTDiff, maxPurity;
141  long long timeStamp;
142  typedef struct // Structures for arrays to move hits from raw to reco to validation
143  {
144 
145  int channel;
146  int module;
148  int adc;
151  }
152  tempHits;
153 
154  typedef struct {
155  int tempId;
156  int adcX;
157  int adcY;
158 
159  double hitPositionX;
160  double hitPositionY;
161  double hitPositionZ;
162  double timeAvg;
163  int geoX;
164  int geoY;
165  int stripX;
166  int stripY;
169  }
170  recoHits;
171 
172  typedef struct // These are displacement metrics for track and hit reco
173  {
174  int tempId;
176  int recoId;
177  int adcX1;
178  int adcY1;
179  double deltaX;
180  double deltaY;
186  double X1;
187  double Y1;
188  double Z1;
189  int trackID;
192  int moduleX1, moduleY1;
193  int stripX1, stripY1;
194  double flashTDiff;
195  double timeAvg;
196  double xOffset;
198  double mccX, mccY, mccZ;
200  int truthId;
202  double mccE;
203  double mccT0;
204  }
205  tracksPair;
206 
207  struct removePairIndex // Struct to remove tracks after sorting
208  {
210  removePairIndex(const tracksPair & tracksPair0): tracksPair1(tracksPair0) {}
211 
212  bool operator()(const tracksPair & tracksPair2) {
213  return (tracksPair1.recoId == tracksPair2.recoId || ( tracksPair1.CRTTrackId == tracksPair2.CRTTrackId || (tracksPair1.stripX1==tracksPair2.stripX1 && tracksPair1.moduleX1==tracksPair2.moduleX1) || (tracksPair1.stripY1==tracksPair2.stripY1 && tracksPair1.moduleY1==tracksPair2.moduleY1)));
214  }
215  };
216 
217  struct sortPair // Struct to sort to find best CRT track for TPC track
218  {
219  bool operator()(const tracksPair & pair1,
220  const tracksPair & pair2) {
221 
222  //return (fabs(pair1.dotProductCos)>fabs(pair2.dotProductCos));
223  return (fabs(pair1.deltaX)+fabs(pair1.deltaY)<fabs(pair2.deltaX)+fabs(pair2.deltaY));
224  //return (fabs(pair1.deltaY)<fabs(pair2.deltaY));
225  }
226  };
227  std::vector < recoHits > primaryHits_F;
228  std::vector < recoHits > primaryHits_B;
229 
230  std::vector < tempHits > tempHits_F;
231  std::vector < tempHits > tempHits_B;
232  std::vector < tracksPair > tracksPair_F;
233  std::vector < tracksPair > tracksPair_B;
234 };
235 
237  const & p):
238  EDAnalyzer(p), fCRTLabel(p.get < art::InputTag > ("CRTLabel")), fCTBLabel(p.get<art::InputTag>("CTBLabel")) {
239  consumes < std::vector < CRT::Trigger >> (fCRTLabel);
240  consumes < std::vector < art::Assns < sim::AuxDetSimChannel, CRT::Trigger >>> (fCRTLabel); // CRT art consumables
241  fMCCSwitch=(p.get<bool>("MCC"));
242  fSCECorrection=(p.get<bool>("SCECorrection"));
243  }
244 
245 
246 // v6 Geo Channel Map
247 bool CRT::SingleCRTMatching::moduleMatcher(int module1, int module2) {
248  // Function checking if two hits could reasonably be matched into a 2D hit
249  if ((module1 == 6 && (module2 == 10 || module2 == 11)) || (module1 == 14 && (module2 == 10 || module2 == 11)) || (module1 == 19 && (module2 == 26 || module2 == 27)) || (module1 == 31 && (module2 == 26 || module2 == 27)) || (module1 == 7 && (module2 == 12 || module2 == 13)) || (module1 == 15 && (module2 == 12 || module2 == 13)) || (module1 == 18 && (module2 == 24 || module2 == 25)) || (module1 == 30 && (module2 == 24 || module2 == 25)) || (module1 == 1 && (module2 == 4 || module2 == 5)) || (module1 == 9 && (module2 == 4 || module2 == 5)) || (module1 == 16 && (module2 == 20 || module2 == 21)) || (module1 == 28 && (module2 == 20 || module2 == 21)) || (module1 == 0 && (module2 == 2 || module2 == 3)) || (module1 == 8 && (module2 == 2 || module2 == 3)) || (module1 == 17 && (module2 == 22 || module2 == 23)) || (module1 == 29 && (module2 == 22 || module2 == 23))) return 1;
250  else return 0;
251 
252 }
253 
254 int CRT::SingleCRTMatching::moduletoCTB(int module2, int module1){
255  if (module1 == 14 && module2 == 11 ) return 15;
256  else if (module1 == 14 && module2 == 10) return 10;
257  else if (module1 == 6 && module2 == 11) return 8;
258  else if (module1 == 6 && module2 == 10) return 9;
259  else if (module1 == 18 && module2 == 25) return 4;
260  else if (module1 == 18 && module2 == 24) return 13;
261  else if (module1 == 30 && module2 == 25) return 3;
262  else if (module1 == 30 && module2 == 24) return 2;
263  else if (module1 == 31 && module2 == 27) return 1;
264  else if (module1 == 31 && module2 == 26) return 0;
265  else if (module1 == 19 && module2 == 27) return 12;
266  else if (module1 == 19 && module2 == 26) return 11;
267  else if (module1 == 7 && module2 == 12) return 7;
268  else if (module1 == 7 && module2 == 13) return 6;
269  else if (module1 == 15 && module2 == 12) return 14;
270  else if (module1 == 15 && module2 == 13) return 5;
271  else if (module1 == 1 && module2 == 4) return 25;
272  else if (module1 == 1 && module2 == 5) return 24;
273  else if (module1 == 9 && module2 == 4) return 26;
274  else if (module1 == 9 && module2 == 5) return 31;
275  else if (module1 == 16 && module2 == 20) return 27;
276  else if (module1 == 16 && module2 == 21) return 28;
277  else if (module1 == 28 && module2 == 20) return 16;
278  else if (module1 == 28 && module2 == 21) return 17;
279  else if (module1 == 29 && module2 == 22) return 18;
280  else if (module1 == 29 && module2 == 23) return 19;
281  else if (module1 == 17 && module2 == 22) return 29;
282  else if (module1 == 17 && module2 == 23) return 20;
283  else if (module1 == 8 && module2 == 2) return 30;
284  else if (module1 == 8 && module2 == 3) return 21;
285  else if (module1 == 0 && module2 == 2) return 23;
286  else if (module1 == 0 && module2 == 3) return 22;
287  else return -1;
288 }
289 
290 double CRT::SingleCRTMatching::setAngle(double angle) {
291  if (angle < 0) {
292  angle += 3.14159265359;
293  }
294  angle *= 180.00 / 3.14159265359;
295  return angle;
296 }
297 
298 
300  const & event) // Analysis module
301 {
302 
303  if (fMCCSwitch){
304  fModuleSwitch=1;
305  fADCThreshold=800;
308  fOpCRTTDiffCut=200;
309 
310 }
311  else {
312  fModuleSwitch=0;
313  fADCThreshold=20;
316  fOpCRTTDiffCut=1000000;
317  art::ValidHandle<std::vector<raw::RDTimeStamp>> timingHandle = event.getValidHandle<std::vector<raw::RDTimeStamp>>("timingrawdecoder:daq");
318  timeStamp=timingHandle->at(0).GetTimeStamp();
319 
320 }
321 
322 
323  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(event);
324  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(event, clockData);
325 
326  int nHits = 0;
327  mccTruthCheck=0;
330 
331 
332  std::vector<art::Ptr<recob::OpFlash> > opHitList;
333  auto opListHandle = event.getHandle< std::vector<recob::OpFlash> >(fopModuleLabel);
334  if (opListHandle)
335  {
336  art::fill_ptr_vector(opHitList, opListHandle);
337  }
338 
339  auto const* SCE = lar::providerFrom<spacecharge::SpaceChargeService>();
340 
341  primaryHits_F.clear();
342  primaryHits_B.clear();
343  tracksPair_F.clear();
344  tracksPair_B.clear();
345  tempHits_F.clear();
346  tempHits_B.clear(); // Arrays to compile hits and move them through
347  primaryHits_F.clear();
348  //allTracksPair.clear();
349  logFile.open("ProtoDUNE.log"); // Logfile I don't use right now
350 
351  //Get triggers
352  //cout << "Getting triggers" << endl;
353  const auto & triggers = event.getValidHandle < std::vector < CRT::Trigger >> (fCRTLabel);
354 
355  art::FindManyP < sim::AuxDetSimChannel > trigToSim(triggers, event, fCRTLabel);
356 
357  //Get a handle to the Geometry service to look up AuxDetGeos from module numbers
359 
360  //Mapping from channel to trigger
361  std::unordered_map < size_t, double > prevTimes;
362  int hitID = 0;
363  //cout << "Looking for hits in Triggers" << endl;
364 
365 
366  int trigID=0;
367  for (const auto & trigger: * triggers) {
368  const auto & hits = trigger.Hits();
369  for (const auto & hit: hits) { // Collect hits on all modules
370  //cout<<hits.size()<<','<<hit.ADC()<<endl;
371  if (hit.ADC() > fADCThreshold) { // Keep if they are above threshold
372 
373  tempHits tHits;
374  if (!fMCCSwitch){
375 
376  tHits.module = trigger.Channel(); // Values to add to array
377  tHits.channel=hit.Channel();
378  tHits.adc = hit.ADC();
379  tHits.triggerTime=trigger.Timestamp()-timeStamp;
380  }
381  else{
382  tHits.module = trigger.Channel(); // Values to add to array
383  tHits.channel=hit.Channel();
384  tHits.adc = hit.ADC();
385  tHits.triggerTime=trigger.Timestamp();
386  }
387  //cout<<trigger.Channel()<<','<<hit.Channel()<<','<<hit.ADC()<<endl;
388  nHits++;
389  tHits.triggerNumber=trigID;
390  const auto & trigGeo = geom -> AuxDet(trigger.Channel()); // Get geo
391  const auto & csens = trigGeo.SensitiveVolume(hit.Channel());
392  const auto center = csens.GetCenter();
393  if (center.Z() < 100) tempHits_F.push_back(tHits); // Sort F/B from Z
394  else tempHits_B.push_back(tHits);
395  hitID++;
396  }
397  }
398  trigID++;
399  }
400 
401  cout << "Hits compiled for event: " << nEvents << endl;
402  cout << "Number of Hits above Threshold: " << hitID << endl;
403 
404  for (unsigned int f = 0; f < tempHits_F.size(); f++) {
405  for (unsigned int f_test = 0; f_test < tempHits_F.size(); f_test++) {
406  if (fabs(tempHits_F[f_test].triggerTime-tempHits_F[f].triggerTime)>fModuletoModuleTimingCut) continue;
407  const auto & trigGeo = geom -> AuxDet(tempHits_F[f].module);
408  const auto & trigGeo2 = geom -> AuxDet(tempHits_F[f_test].module);
409 
410  const auto & hit1Geo = trigGeo.SensitiveVolume(tempHits_F[f].channel);
411  const auto hit1Center = hit1Geo.GetCenter();
412  // Create 2D hits from geo of the Y and X modules
413  const auto & hit2Geo = trigGeo2.SensitiveVolume(tempHits_F[f_test].channel);
414  const auto hit2Center = hit2Geo.GetCenter();
415  bool moduleMatched;
416  moduleMatched=moduleMatcher(tempHits_F[f_test].module, tempHits_F[f].module);
417  if (moduleMatched) {
418  // Get the center of the hits (CRT_Res=2.5 cm)
419  double hitX = hit1Center.X();
420  for (unsigned int a = 0; a < tempHits_F.size(); a++)
421  {
422  if(tempHits_F[a].module==tempHits_F[f].module && (tempHits_F[a].channel-1)==tempHits_F[f].channel) hitX=hit1Center.X()+1.25;
423  }
424  double hitYPrelim=hit2Center.Y();
425  for (unsigned int a = 0; a < tempHits_F.size(); a++)
426  {
427  if(tempHits_F[a].module==tempHits_F[f_test].module && (tempHits_F[a].channel-1)==tempHits_F[f_test].channel) hitYPrelim=hit2Center.Y()+1.25;
428  }
429 
430 
431 
432  double hitY=hitYPrelim;
433  double hitZ = (hit1Center.Z() + hit2Center.Z()) / 2.f;
434 
435  recoHits rHits;
436  rHits.hitPositionX = hitX;
437  rHits.hitPositionY = hitY;
438  rHits.hitPositionZ = hitZ;
439  rHits.geoX=tempHits_F[f].module;
440  rHits.geoY=tempHits_F[f_test].module;
441  rHits.stripX=tempHits_F[f].channel;
442  rHits.stripY=tempHits_F[f_test].channel;
443 
444  rHits.adcX=tempHits_F[f].adc;
445  rHits.adcY=tempHits_F[f_test].adc;
446  rHits.trigNumberX=tempHits_F[f].triggerNumber;
447  rHits.trigNumberY=tempHits_F[f_test].triggerNumber;
448  rHits.timeAvg = (tempHits_F[f_test].triggerTime+tempHits_F[f].triggerTime)/2.0;
449  primaryHits_F.push_back(rHits); // Add array
450  }
451  }
452  }
453  for (unsigned int f = 0; f < tempHits_B.size(); f++) {
454  for (unsigned int f_test = 0; f_test < tempHits_B.size(); f_test++) { // Same as above but for back CRT
455  if (fabs(tempHits_B[f_test].triggerTime-tempHits_B[f].triggerTime)>fModuletoModuleTimingCut) continue;
456 
457  const auto & trigGeo = geom -> AuxDet(tempHits_B[f].module);
458  const auto & trigGeo2 = geom -> AuxDet(tempHits_B[f_test].module);
459  const auto & hit1Geo = trigGeo.SensitiveVolume(tempHits_B[f].channel);
460  const auto hit1Center = hit1Geo.GetCenter();
461 
462  const auto & hit2Geo = trigGeo2.SensitiveVolume(tempHits_B[f_test].channel);
463  const auto hit2Center = hit2Geo.GetCenter();
464  bool moduleMatched;
465  moduleMatched=moduleMatcher(tempHits_B[f_test].module, tempHits_B[f].module);
466 
467  if (moduleMatched) {
468  double hitX = hit1Center.X();
469 
470 
471  for (unsigned int a = 0; a < tempHits_B.size(); a++)
472  {
473  if(tempHits_B[a].module==tempHits_B[f].module && (tempHits_B[a].channel-1)==tempHits_B[f].channel) hitX=hit1Center.X()+1.25;
474  }
475 
476  double hitYPrelim = hit2Center.Y();
477 
478  for (unsigned int a = 0; a < tempHits_B.size(); a++)
479  {
480  if(tempHits_B[a].module==tempHits_B[f_test].module && (tempHits_B[a].channel-1)==tempHits_B[f_test].channel) hitYPrelim=hit2Center.Y()+1.25;
481  }
482  double hitY=hitYPrelim;
483 
484 
485  double hitZ = (hit1Center.Z() + hit2Center.Z()) / 2.f;
486 
487  recoHits rHits;
488  rHits.hitPositionX = hitX;
489  rHits.hitPositionY = hitY;
490  rHits.hitPositionZ = hitZ;
491  rHits.geoX=tempHits_B[f].module;
492  rHits.geoY=tempHits_B[f_test].module;
493  rHits.adcX=tempHits_B[f].adc;
494  rHits.adcY=tempHits_B[f_test].adc;
495  rHits.stripX=tempHits_B[f].channel;
496  rHits.stripY=tempHits_B[f_test].channel;
497  rHits.trigNumberX=tempHits_B[f].triggerNumber;
498  rHits.trigNumberY=tempHits_B[f_test].triggerNumber;
499  rHits.timeAvg = (tempHits_B[f_test].triggerTime+tempHits_B[f].triggerTime)/2.0;
500  primaryHits_B.push_back(rHits);
501 
502  }
503  }
504  }
505  // Reconstruciton information
506  art::Handle < vector < recob::Track > > trackListHandle;
507  vector < art::Ptr < recob::Track > > trackList;
508  vector<art::Ptr<recob::PFParticle> > pfplist;
509  auto PFPListHandle = event.getHandle< std::vector<recob::PFParticle> >(fTrackModuleLabel);
510  if (trackListHandle) {
511  art::fill_ptr_vector(trackList, trackListHandle);
512  }
513 
514  auto PFPListHandle2 = event.getHandle< std::vector<recob::PFParticle> >("pandora");
515  if (PFPListHandle2) art::fill_ptr_vector(pfplist, PFPListHandle2);
516 
517  art::FindManyP<anab::T0> trk_t0_assn_v(PFPListHandle2, event ,"pandora");
518  art::FindManyP<recob::PFParticle> pfp_trk_assn(trackListHandle,event,"pandoraTrack");
519  art::FindManyP<recob::Hit> trackHits(trackListHandle, event, "pandoraTrack");
520 
521  int nTracksReco = trackList.size();
522  art::FindManyP < recob::Hit > hitsFromTrack(trackListHandle, event, fTrackModuleLabel);
523  int tempId = 0;
524  for (int iRecoTrack = 0; iRecoTrack < nTracksReco; ++iRecoTrack) {
525  double mccX=-999; double mccY=-999; double mccZ=-999;
526  double mccE=-999; mccT0=0;
527  if (primaryHits_F.size()+primaryHits_B.size()<1) break;
528  std::vector< art::Ptr<recob::Hit> > allHits = hitsFromTrack.at(iRecoTrack);
529 
530  art::Ptr<recob::Track> ptrack(trackListHandle, iRecoTrack);
531 
532  std::vector<art::Ptr<recob::PFParticle>> pfps=pfp_trk_assn.at(iRecoTrack);
533  if(!pfps.size()) continue;
534  std::vector<art::Ptr<anab::T0>> t0s=trk_t0_assn_v.at(pfps[0].key());
535  int t_zero=-99999;
536  if(t0s.size()){
537  auto t0=t0s.at(0);
538  t_zero=t0->Time();
539  // cout<<"Pandora T0: "<<t_zero<<endl;
540  }
541  int firstHit=0;
542  int lastHit=allHits.size()-2;
543 
544 
545 // Get track positions and find angles
546  // if (fMCCSwith==1){
547  double trackStartPositionZ_noSCE = trackList[iRecoTrack]->Vertex().Z();
548  double trackEndPositionZ_noSCE = trackList[iRecoTrack] -> End().Z();
549 
550  double trackStartPositionX_noSCE = trackList[iRecoTrack]->Vertex().X();
551  double trackStartPositionY_noSCE = trackList[iRecoTrack]->Vertex().Y();
552 
553 
554  double trackEndPositionX_noSCE = trackList[iRecoTrack] -> End().X();
555  double trackEndPositionY_noSCE = trackList[iRecoTrack] -> End().Y();
556  if (trackStartPositionZ_noSCE>trackEndPositionZ_noSCE){
557  trackEndPositionZ_noSCE = trackList[iRecoTrack]->Vertex().Z();
558  trackStartPositionZ_noSCE = trackList[iRecoTrack] -> End().Z();
559  trackEndPositionX_noSCE = trackList[iRecoTrack]->Vertex().X();
560  trackEndPositionY_noSCE = trackList[iRecoTrack]->Vertex().Y();
561 
562 
563  trackStartPositionX_noSCE = trackList[iRecoTrack] -> End().X();
564  trackStartPositionY_noSCE = trackList[iRecoTrack] -> End().Y();
565  firstHit=lastHit;
566  lastHit=0;
567  }
568  if ((trackEndPositionZ_noSCE>90 && trackEndPositionZ_noSCE < 660 && trackStartPositionZ_noSCE <50 && trackStartPositionZ_noSCE<660) || (trackStartPositionZ_noSCE>90 && trackStartPositionZ_noSCE < 660 && trackEndPositionZ_noSCE <50 && trackEndPositionZ_noSCE<660)) {
569 
570 
571  double min_delta = DBL_MAX;
572 
573  double best_dotProductCos = DBL_MAX;
574  double best_deltaXF = DBL_MAX;
575  double best_deltaYF = DBL_MAX;
576  double best_T=DBL_MAX;
577  double best_trackX1=DBL_MAX;
578  double best_trackX2=DBL_MAX;
579  double best_xOffset=DBL_MAX;
580  int bestHitIndex_F=0;
581 
582  int beamRight=-1;
583  int beamLeft=-1;
584  int trackid=-1;
585  //cout<<trackid<<endl;
586  if (fMCCSwitch){
587  mccTruthCheck=0;
588  std::vector<art::Ptr<recob::Hit>> allHits=trackHits.at(iRecoTrack); //storing hits for ith track
589 
590  std::map<int,double> trkide;
591  std::map<int,double> trknumelec;
592 
593 
594  for(size_t h=0; h<allHits.size();h++){
595  art::Ptr<recob::Hit> hit=allHits[h];
596  std::vector<sim::TrackIDE> eveIDs = backTracker->HitToTrackIDEs(clockData, hit);
597  for(size_t e=0;e<eveIDs.size(); ++e){
598  trkide[eveIDs[e].trackID] += eveIDs[e].energy;
599  }
600  }
601  double maxe = -1;
602  double tote = 0;
603  for(std::map<int,double>::iterator ii = trkide.begin(); ii!=trkide.end(); ++ii){
604  tote += ii->second;
605  if((ii->second)>maxe){
606  maxe = ii->second;
607  trackid = ii->first;
608 
609  }
610  }
611  const simb::MCParticle *particle = partInventory->TrackIdToParticle_P(trackid);
612  const art::Ptr<simb::MCTruth> mc=partInventory->TrackIdToMCTruth_P(trackid);
613  int nTrajectory=particle->NumberTrajectoryPoints();
614 
615 
616  auto const startPos=particle->Position(0);
617  auto const endPos=particle->EndPosition();
618 
619  if (mc->Origin()==simb::kCosmicRay) partProcess=1;
620  else if (particle->Process()=="primary") partProcess=2;
621  else partProcess=3;
622  mccE=particle->E();
623  mccT0=particle->T();
624 
625  for (int i=0; i<nTrajectory-2; i++){
626 if (particle->Position(i).Z()>-286 && particle->Position(i).Z()<-278 && particle->Position(i).Y()>-40 && particle->Position(i).Y()<600 && particle->Position(i).X()>230 && particle->Position(i).X()<558){beamLeft=i; break;}
627  if (particle->Position(i).Z()>-258 && particle->Position(i).Z()<-254 && particle->Position(i).Y()>-40 && particle->Position(i).Y()<50 && particle->Position(i).X()>230 && particle->Position(i).X()<558){beamLeft=i; break;}}
628 
629 
630  for (int i=0; i<nTrajectory-2; i++){
631  if (particle->Position(i).Z()>-988 && particle->Position(i).Z()<-980 && particle->Position(i).Y()>-40 && particle->Position(i).Y()<540 && particle->Position(i).X()<120 && particle->Position(i).X()>-203){beamRight=i; break;}
632  if (particle->Position(i).Z()>-966 && particle->Position(i).Z()<-958 && particle->Position(i).Y()>-40 && particle->Position(i).Y()<500 && particle->Position(i).X()<120 && particle->Position(i).X()>-203){beamRight=i; break;} }
633 
634 if (beamRight!=-1){//cout<<"MC Truth: "<<iRecoTrack<<','<<particle->Position(beamRight).X()<<','<<particle->Position(beamRight).Y()<<','<<particle->Position(beamRight).Z()<<endl;
635  }
636 
637 else if (beamLeft!=-1){//cout<<"MC Truth: "<<iRecoTrack<<','<<particle->Position(beamLeft).X()<<','<<particle->Position(beamLeft).Y()<<','<<particle->Position(beamLeft).Z()<<endl;
638  }
639 
640 
641 
642  if (beamRight!=-1){
643  mccX=particle->Position(beamRight).X();
644  mccY=particle->Position(beamRight).Y();
645  mccZ=particle->Position(beamRight).Z();}
646 
647  if (beamLeft!=-1){
648  mccX=particle->Position(beamLeft).X();
649  mccY=particle->Position(beamLeft).Y();
650  mccZ=particle->Position(beamLeft).Z();}
651 
652 if (beamLeft!=-1 || beamRight!=-1){
653  truthTrack++;
654 for (unsigned int iHit_F = 0; iHit_F < primaryHits_F.size(); iHit_F++) {
655 
656 
657  double X1 = primaryHits_F[iHit_F].hitPositionX;
658 
659  double Y1 = primaryHits_F[iHit_F].hitPositionY;
660 
661  double Z1 = primaryHits_F[iHit_F].hitPositionZ;
662  double mccHitY=(endPos.Y()-startPos.Y())/(endPos.Z()-startPos.Z())*(Z1-startPos.Z())+startPos.Y();
663  double mccHitX=(endPos.X()-startPos.X())/(endPos.Z()-startPos.Z())*(Z1-startPos.Z())+startPos.X();
664 
665  if (fabs(X1-mccHitX)<60 && fabs(Y1-mccHitY)<60) {mccTruthCheck=1;
666  mccX=mccHitX;
667  mccY=mccHitY;
668  mccZ=Z1;
669  }
670 
671 
672  if (beamLeft!=-1){
673  if(fabs(particle->Position(beamLeft).X()-X1)<60 && fabs(particle->Position(beamLeft).Y()-Y1)<60 && fabs(particle->Position(beamLeft).Z()-Z1)<60){ matchedTrack=matchedTrack+mccTruthCheck;
674  truthPosX=mccX;
675  truthPosY=mccY;
676  truthPosZ=mccZ;
677  fMCCTree->Fill(); }
678  }
679 
680  if (beamRight!=-1){
681  if(fabs(particle->Position(beamRight).X()-X1)<60 && fabs(particle->Position(beamRight).Y()-Y1)<60 && fabs(particle->Position(beamRight).Z()-Z1)<60) {matchedTrack=matchedTrack+mccTruthCheck;
682  truthPosX=mccX;
683  truthPosY=mccY;
684  truthPosZ=mccZ;
685  fMCCTree->Fill();}
686 
687 
688  }
689 
690 
691 
692 
693 
694 }}
695 
696 }
697 
698 
699 
700  //track++;
701  for (unsigned int iHit_F = 0; iHit_F < primaryHits_F.size(); iHit_F++) {
702  double xOffset=0;
703 
704  double trackStartPositionX_notCorrected=trackStartPositionX_noSCE;
705  double trackEndPositionX_notCorrected=trackEndPositionX_noSCE;
706  if (!t0s.empty()){
707  if (event.isRealData() && fabs(t_zero-(primaryHits_F[iHit_F].timeAvg*20.f))>100000) continue;
708  if (!event.isRealData() && fabs(t_zero-primaryHits_F[iHit_F].timeAvg)>100000) continue;
709  }
710  if (t0s.empty()){
711 
712  int RDOffset=0;
713  if (!fMCCSwitch) RDOffset=111;
714  double ticksOffset=0;
715  //cout<<(primaryHits_F[iHit_F].timeAvg+RDOffset)<<endl;
716  //cout<<detProp.GetXTicksOffset(allHits[firstHit]->WireID().Plane, allHits[firstHit]->WireID().TPC, allHits[firstHit]->WireID().Cryostat)<<endl;
717  if (!fMCCSwitch) ticksOffset = (primaryHits_F[iHit_F].timeAvg+RDOffset)/25.f+detProp.GetXTicksOffset(allHits[firstHit]->WireID().Plane, allHits[firstHit]->WireID().TPC, allHits[firstHit]->WireID().Cryostat);
718 
719  else if (fMCCSwitch) ticksOffset = (primaryHits_F[iHit_F].timeAvg/500.f)+detProp.GetXTicksOffset(allHits[firstHit]->WireID().Plane, allHits[firstHit]->WireID().TPC, allHits[firstHit]->WireID().Cryostat);
720 
721  xOffset=detProp.ConvertTicksToX(ticksOffset,allHits[firstHit]->WireID().Plane, allHits[firstHit]->WireID().TPC, allHits[firstHit]->WireID().Cryostat);
722  //double xOffset=.08*ticksOffset
723 
724  trackStartPositionX_noSCE=trackStartPositionX_notCorrected-xOffset;
725  trackEndPositionX_noSCE=trackEndPositionX_notCorrected-xOffset;
726  if (fabs(xOffset)>300 || ((trackStartPositionX_notCorrected<0 && trackStartPositionX_noSCE>0) || (trackEndPositionX_notCorrected<0 && trackEndPositionX_noSCE>0)) || ((trackStartPositionX_notCorrected>0 && trackStartPositionX_noSCE<0) || (trackEndPositionX_notCorrected>0 && trackEndPositionX_noSCE<0)) ) continue;
727  }
728 
729  double trackStartPositionX=trackStartPositionX_noSCE;
730  double trackStartPositionY=trackStartPositionY_noSCE;
731  double trackStartPositionZ=trackStartPositionZ_noSCE;
732 
733  double trackEndPositionX=trackEndPositionX_noSCE;
734  double trackEndPositionY=trackEndPositionY_noSCE;
735  double trackEndPositionZ=trackEndPositionZ_noSCE;
736 // if (!fMCCSwitch && moduletoCTB(primaryHits_F[iHit_F].moduleX, primaryHits_F[iHit_F].moduleY)!=pixel0) continue;
737  double X1 = primaryHits_F[iHit_F].hitPositionX;
738 
739  double Y1 = primaryHits_F[iHit_F].hitPositionY;
740 
741  double Z1 = primaryHits_F[iHit_F].hitPositionZ;
742 
743 
744  //if (mccTruthCheck==1) cout<<iRecoTrack<<endl;
745 
746 
747  // Make metrics for a CRT pair to compare later
748  TVector3 trackStart(trackStartPositionX, trackStartPositionY, trackStartPositionZ);
749  TVector3 trackEnd(trackEndPositionX, trackEndPositionY, trackEndPositionZ);
750  TVector3 v1(X1,Y1,Z1);
751  TVector3 v2(trackStartPositionX, trackStartPositionY, trackStartPositionZ);
752 
753  TVector3 v4(trackStartPositionX,
754  trackStartPositionY,
755  trackStartPositionZ);
756  TVector3 v5(trackEndPositionX,
757  trackEndPositionY,
758  trackEndPositionZ);
759  TVector3 trackVector = (v5-v4).Unit();
760  TVector3 hitVector=(v2-v1).Unit();
761 
762 
763 
764 
765  double predictedHitPositionY1 = (v1.Z()-v5.Z())/(v4.Z()-v5.Z())*(v4.Y()-v5.Y())+v5.Y();
766 
767 
768  double predictedHitPositionX1 = (v1.Z()-v5.Z())/(v4.Z()-v5.Z())*(v4.X()-v5.X())+v5.X();
769 
770  if (predictedHitPositionX1<-200 || predictedHitPositionX1>580 || predictedHitPositionY1<-50 || predictedHitPositionY1>620) continue;
771 
772  double dotProductCos=trackVector*hitVector;
773 
774  double deltaX1 = (predictedHitPositionX1-X1);
775 
776 
777  double deltaY1 = (predictedHitPositionY1-Y1);
778 
779  if (min_delta > std::abs(deltaX1) + std::abs(deltaY1) ){
780 
781  min_delta=std::abs(deltaX1)+std::abs(deltaY1);
782 
783  best_dotProductCos = dotProductCos;
784  best_trackX1=trackStartPositionX;
785  best_trackX2=trackEndPositionX;
786  best_deltaXF = deltaX1;
787  best_deltaYF = deltaY1;
788  best_xOffset=xOffset;
789  best_T = primaryHits_F[iHit_F].timeAvg;
790  bestHitIndex_F=iHit_F;
791  if (!fMCCSwitch) best_T=(111.f+best_T)*20.f;
792 
793  // Added 111 tick CRT-CTB offset
794  }
795 
796  }
797  int f=bestHitIndex_F;
798  //double t0=best_T;
799  double deltaX=best_deltaXF; double deltaY=best_deltaYF;
800  double dotProductCos=best_dotProductCos;
801 
802  double trackStartPositionX=best_trackX1;
803  double trackStartPositionY=trackStartPositionY_noSCE;
804  double trackStartPositionZ=trackStartPositionZ_noSCE;
805 
806  double trackEndPositionX=best_trackX2;
807  double trackEndPositionY=trackEndPositionY_noSCE;
808  double trackEndPositionZ=trackEndPositionZ_noSCE;
809 
810 
811  TVector3 trackStart(trackStartPositionX, trackStartPositionY, trackStartPositionZ);
812  TVector3 trackEnd(trackEndPositionX, trackEndPositionY, trackEndPositionZ);
813 
814  if (deltaX==DBL_MAX || deltaY==DBL_MAX) continue;
815  //if (minTimeDifference>100000) continue;
816  double minTimeDifference=999999.99;
817  tracksPair tPair;
818  tPair.tempId = tempId;
819  tPair.CRTTrackId = f;
820  tPair.recoId = iRecoTrack;
821 
822  tPair.deltaX=deltaX;
823  tPair.deltaY=deltaY;
824  tPair.dotProductCos=dotProductCos;
825 
826  tPair.moduleX1 = primaryHits_F[f].geoX;
827  tPair.moduleY1 = primaryHits_F[f].geoY;
828 
829  tPair.adcX1=primaryHits_F[f].adcX;
830  tPair.adcY1=primaryHits_F[f].adcY;
831  tPair.xOffset=best_xOffset;
832  tPair.stripX1 = primaryHits_F[f].stripX;
833  tPair.stripY1 = primaryHits_F[f].stripY;
834  tPair.X1 = primaryHits_F[f].hitPositionX;
835  tPair.Y1 = primaryHits_F[f].hitPositionY;
836  tPair.Z1 = primaryHits_F[f].hitPositionZ;
837  tPair.mccX = mccX;
838  tPair.mccY = mccY;
839  tPair.mccZ =mccZ;
840  tPair.truthId=trackid;
841  tPair.timeAvg=primaryHits_F[f].timeAvg;
842  tPair.trackStartPosition=trackStart;
843  tPair.flashTDiff=minTimeDifference;
844  tPair.trackEndPosition=trackEnd;
846  tPair.partProcess=partProcess;
847  if (t0s.empty()) tPair.pandoraT0Check=0;
848  else tPair.pandoraT0Check=1;
849  tPair.mccT0=mccT0;
850  tPair.mccE=mccE;
851  tracksPair_B.push_back(tPair);
852 
853  }
854  if ( (trackStartPositionZ_noSCE<620 && trackEndPositionZ_noSCE > 660 && trackStartPositionZ_noSCE > 50 && trackEndPositionZ_noSCE > 50) || (trackStartPositionZ_noSCE>660 && trackEndPositionZ_noSCE < 620 && trackStartPositionZ_noSCE > 50 && trackEndPositionZ_noSCE > 50)) {
855 
856  double min_delta = DBL_MAX;
857 
858  double best_dotProductCos = DBL_MAX;
859  double best_deltaXF = DBL_MAX;
860  double best_deltaYF = DBL_MAX;
861  double best_T=DBL_MAX;
862  double best_xOffset=DBL_MAX;
863  int bestHitIndex_B=0;
864  double best_trackX1=DBL_MAX;
865  double best_trackX2=DBL_MAX;
866 
867  int trackid=-1;
868 if (fMCCSwitch){
869  mccTruthCheck=0;
870  std::vector<art::Ptr<recob::Hit>> allHits=trackHits.at(iRecoTrack); //storing hits for ith track
871 
872 
873  std::map<int,double> trkide;
874  std::map<int,double> trknumelec;
875 
876 
877  for(size_t h=0; h<allHits.size();h++){
878  art::Ptr<recob::Hit> hit=allHits[h];
879  std::vector<sim::TrackIDE> eveIDs = backTracker->HitToTrackIDEs(clockData, hit);
880  for(size_t e=0;e<eveIDs.size(); ++e){
881  trkide[eveIDs[e].trackID] += eveIDs[e].energy;
882  }
883  }
884  double maxe = -1;
885  double tote = 0;
886  for(std::map<int,double>::iterator ii = trkide.begin(); ii!=trkide.end(); ++ii){
887  tote += ii->second;
888  if((ii->second)>maxe){
889  maxe = ii->second;
890  trackid = ii->first;
891 
892  }
893  }
894  //cout<<trackid<<endl;
895 
896 
897  const simb::MCParticle *particle = partInventory->TrackIdToParticle_P(trackid);
898  const art::Ptr<simb::MCTruth> mc=partInventory->TrackIdToMCTruth_P(trackid);
899  int nTrajectory=particle->NumberTrajectoryPoints();
900 
901  auto const startPos=particle->Position(0);
902  auto const endPos=particle->EndPosition();
903 
904  if (mc->Origin()==simb::kCosmicRay) partProcess=1;
905  else if (particle->Process()=="primary") partProcess=2;
906  else partProcess=3;
907  mccE=particle->E();
908  mccT0=particle->T();
909  int approxExit=-1;
911 
912  for (int i=0; i<nTrajectory-2; i++){
913  if (particle->Position(i).Z()>1077 && particle->Position(i).Z()<1080 && particle->Position(i).Y()>-140 && ((particle->Position(i).Y()<540 && particle->Position(i).Y()>230) || (particle->Position(i).Y()<170 && particle->Position(i).Y()>-140)) && fabs(particle->Position(i).X())<340 && fabs(particle->Position(i).X())>30 ) { approxExit=i; break;}
914  }
915 
916 
917 if (approxExit!=-1){
918  truthTrack++;
919  mccX=particle->Position(approxExit).X();
920  mccY=particle->Position(approxExit).Y();
921  mccZ=particle->Position(approxExit).Z();
922 
923 //cout<<"MC Truth: "<<iRecoTrack<<','<<particle->Position(approxExit).X()<<','<<particle->Position(approxExit).Y()<<','<<particle->Position(approxExit).Z()<<endl;
924  }
925 if (approxExit!=-1){
926 for (unsigned int iHit_F = 0; iHit_F < primaryHits_B.size(); iHit_F++) {
927 
928 
929  double X1 = primaryHits_B[iHit_F].hitPositionX;
930 
931  double Y1 = primaryHits_B[iHit_F].hitPositionY;
932 
933  double Z1 = primaryHits_B[iHit_F].hitPositionZ;
934  double mccHitY=(endPos.Y()-startPos.Y())/(endPos.Z()-startPos.Z())*(Z1-startPos.Z())+startPos.Y();
935  double mccHitX=(endPos.X()-startPos.X())/(endPos.Z()-startPos.Z())*(Z1-startPos.Z())+startPos.X();
936  if (fabs(X1-mccHitX)<60 && fabs(Y1-mccHitY)<60) {mccTruthCheck=1;
937 
938  mccX=mccHitX;
939  mccY=mccHitY;
940  mccZ=Z1;}
941 
942  if(fabs(particle->Position(approxExit).X()-X1)<60 && fabs(particle->Position(approxExit).Y()-Y1)<60&& fabs(particle->Position(approxExit).Z()-Z1)<60 && approxExit!=-1){matchedTrack=matchedTrack+mccTruthCheck;
943 truthPosX=mccX;
944 truthPosY=mccY;
945 truthPosZ=mccZ; fMCCTree->Fill();
946  }
947 
948 
949 
950 
951 
952 }}
953 
954 }
955 
956  //track++;
957  for (unsigned int iHit_B = 0; iHit_B < primaryHits_B.size(); iHit_B++) {
958 double xOffset=0;
959 
960 
961  double trackStartPositionX_notCorrected=trackStartPositionX_noSCE;
962  double trackEndPositionX_notCorrected=trackEndPositionX_noSCE;
963 
964  if (!t0s.empty()){
965  if (event.isRealData() && fabs(t_zero-(primaryHits_B[iHit_B].timeAvg*20.f))>100000) continue;
966  if (!event.isRealData() && fabs(t_zero-primaryHits_B[iHit_B].timeAvg)>100000) continue;
967  }
968  if (t0s.empty()){
969 
970  int RDOffset=0;
971  if (!fMCCSwitch) RDOffset=111;
972  double ticksOffset=0;
973  //cout<<(primaryHits_B[iHit_B].timeAvg+RDOffset)<<endl;
974  //cout<<detProp.GetXTicksOffset(allHits[firstHit]->WireID().Plane, allHits[firstHit]->WireID().TPC, allHits[firstHit]->WireID().Cryostat)<<endl;
975  if (!fMCCSwitch) ticksOffset = (primaryHits_B[iHit_B].timeAvg+RDOffset)/25.f+detProp.GetXTicksOffset(allHits[firstHit]->WireID().Plane, allHits[firstHit]->WireID().TPC, allHits[firstHit]->WireID().Cryostat);
976 
977  else if (fMCCSwitch) ticksOffset = (primaryHits_B[iHit_B].timeAvg/500.f)+detProp.GetXTicksOffset(allHits[firstHit]->WireID().Plane, allHits[firstHit]->WireID().TPC, allHits[firstHit]->WireID().Cryostat);
978 
979  xOffset=detProp.ConvertTicksToX(ticksOffset,allHits[firstHit]->WireID().Plane, allHits[firstHit]->WireID().TPC, allHits[firstHit]->WireID().Cryostat);
980  //double xOffset=.08*ticksOffset
981 
982  trackStartPositionX_noSCE=trackStartPositionX_notCorrected-xOffset;
983  trackEndPositionX_noSCE=trackEndPositionX_notCorrected-xOffset;
984  if (fabs(xOffset)>300 || ((trackStartPositionX_notCorrected<0 && trackStartPositionX_noSCE>0) || (trackEndPositionX_notCorrected<0 && trackEndPositionX_noSCE>0)) || ((trackStartPositionX_notCorrected>0 && trackStartPositionX_noSCE<0) || (trackEndPositionX_notCorrected>0 && trackEndPositionX_noSCE<0)) ) continue;
985  }
986 
987  double trackStartPositionX=trackStartPositionX_noSCE;
988  double trackStartPositionY=trackStartPositionY_noSCE;
989  double trackStartPositionZ=trackStartPositionZ_noSCE;
990 
991  double trackEndPositionX=trackEndPositionX_noSCE;
992  double trackEndPositionY=trackEndPositionY_noSCE;
993  double trackEndPositionZ=trackEndPositionZ_noSCE;
994 
995  if (fSCECorrection && SCE->EnableCalSpatialSCE()){
996 if(geom->PositionToTPCID(geo::Point_t(trackEndPositionX, trackEndPositionY, trackEndPositionZ)).deepestIndex()<13 && geom->PositionToTPCID(geo::Point_t(trackStartPositionX, trackStartPositionY, trackStartPositionZ)).deepestIndex()<13){
997  auto const & posOffsets_F = SCE->GetCalPosOffsets(geo::Point_t(trackStartPositionX, trackStartPositionY, trackStartPositionZ), geom->PositionToTPCID(geo::Point_t(trackStartPositionX, trackStartPositionY, trackStartPositionZ)).deepestIndex());
998  trackStartPositionX -= posOffsets_F.X();
999  trackStartPositionY += posOffsets_F.Y();
1000  trackStartPositionZ += posOffsets_F.Z();
1001  auto const & posOffsets_B = SCE->GetCalPosOffsets(geo::Point_t(trackEndPositionX, trackEndPositionY, trackEndPositionZ), geom->PositionToTPCID(geo::Point_t(trackEndPositionX, trackEndPositionY, trackEndPositionZ)).deepestIndex());
1002  trackEndPositionX -= posOffsets_B.X();
1003  trackEndPositionY += posOffsets_B.Y();
1004  trackEndPositionZ += posOffsets_B.Z();
1005  }
1006  }
1007 
1008  double X1 = primaryHits_B[iHit_B].hitPositionX;
1009 
1010  double Y1 = primaryHits_B[iHit_B].hitPositionY;
1011 
1012  double Z1 = primaryHits_B[iHit_B].hitPositionZ;
1013 
1014 
1015  // Make metrics for a CRT pair to compare later
1016  TVector3 trackStart(trackStartPositionX, trackStartPositionY, trackStartPositionZ);
1017  TVector3 trackEnd(trackEndPositionX, trackEndPositionY, trackEndPositionZ);
1018  TVector3 v1(X1,Y1,Z1);
1019  TVector3 v2(trackStartPositionX, trackStartPositionY, trackStartPositionZ);
1020 
1021  TVector3 v4(trackStartPositionX,
1022  trackStartPositionY,
1023  trackStartPositionZ);
1024  TVector3 v5(trackEndPositionX,
1025  trackEndPositionY,
1026  trackEndPositionZ);
1027  TVector3 trackVector = (v5-v4).Unit();
1028  TVector3 hitVector=(v2-v1).Unit();
1029 
1030 
1031 
1032 
1033  double predictedHitPositionY1 = (v1.Z()-v5.Z())/(v4.Z()-v5.Z())*(v4.Y()-v5.Y())+v5.Y();
1034 
1035 
1036  double predictedHitPositionX1 = (v1.Z()-v5.Z())/(v4.Z()-v5.Z())*(v4.X()-v5.X())+v5.X();
1037 
1038  if (abs(predictedHitPositionX1)>340 || predictedHitPositionY1<-160 || predictedHitPositionY1>560) continue;
1039 
1040  double dotProductCos=trackVector*hitVector;
1041 
1042  double deltaX1 = (predictedHitPositionX1-X1);
1043 
1044 
1045  double deltaY1 = (predictedHitPositionY1-Y1);
1046 
1047 
1048  //std::cout<<deltaX1<<','<<deltaY1<<std::endl;
1049  if (min_delta > std::abs(deltaX1) + std::abs(deltaY1) ){
1050 
1051  min_delta=std::abs(deltaX1)+std::abs(deltaY1);
1052 
1053  best_dotProductCos = dotProductCos;
1054  best_trackX1=trackStartPositionX;
1055  best_trackX2=trackEndPositionX;
1056  best_deltaXF = deltaX1;
1057  best_deltaYF = deltaY1;
1058  best_xOffset=xOffset;
1059  best_T = primaryHits_F[iHit_B].timeAvg;
1060  bestHitIndex_B=iHit_B;
1061  if (!fMCCSwitch) best_T=(111.f+best_T)*20.f;
1062  // Added 111 tick CRT-CTB offset
1063  }
1064 
1065  }
1066  int f=bestHitIndex_B;
1067  //double t0=best_T;
1068  double deltaX=best_deltaXF; double deltaY=best_deltaYF;
1069  double dotProductCos=best_dotProductCos;
1070 
1071 
1072 
1073 
1074  double trackStartPositionX=best_trackX1;
1075  double trackStartPositionY=trackStartPositionY_noSCE;
1076  double trackStartPositionZ=trackStartPositionZ_noSCE;
1077 
1078  double trackEndPositionX=best_trackX2;
1079  double trackEndPositionY=trackEndPositionY_noSCE;
1080  double trackEndPositionZ=trackEndPositionZ_noSCE;
1081 
1082 
1083  TVector3 trackStart(trackStartPositionX, trackStartPositionY, trackStartPositionZ);
1084  TVector3 trackEnd(trackEndPositionX, trackEndPositionY, trackEndPositionZ);
1085 
1086  if (deltaX==DBL_MAX && deltaY==DBL_MAX) continue;
1087  //if (minTimeDifference>100000) continue;
1088  double minTimeDifference=999999.99;
1089  tracksPair tPair;
1090  tPair.tempId = tempId;
1091  tPair.CRTTrackId = f;
1092  tPair.recoId = iRecoTrack;
1093 
1094  tPair.deltaX=deltaX;
1095  tPair.deltaY=deltaY;
1096  tPair.dotProductCos=dotProductCos;
1097 
1098  tPair.moduleX1 = primaryHits_B[f].geoX;
1099  tPair.moduleY1 = primaryHits_B[f].geoY;
1100 
1101  tPair.adcX1=primaryHits_B[f].adcX;
1102  tPair.adcY1=primaryHits_B[f].adcY;
1103  tPair.xOffset=best_xOffset;
1104  tPair.stripX1 = primaryHits_B[f].stripX;
1105  tPair.stripY1 = primaryHits_B[f].stripY;
1106  tPair.X1 = primaryHits_B[f].hitPositionX;
1107  tPair.Y1 = primaryHits_B[f].hitPositionY;
1108  tPair.Z1 = primaryHits_B[f].hitPositionZ;
1109  tPair.mccX = mccX;
1110  tPair.mccY = mccY;
1111  tPair.mccZ =mccZ;
1112  tPair.truthId=trackid;
1113  tPair.timeAvg=primaryHits_B[f].timeAvg;
1114  tPair.trackStartPosition=trackStart;
1115  tPair.flashTDiff=minTimeDifference;
1116  tPair.trackEndPosition=trackEnd;
1118  tPair.partProcess=partProcess;
1119  if (t0s.empty()) tPair.pandoraT0Check=0;
1120  else tPair.pandoraT0Check=1;
1121  tPair.mccT0=mccT0;
1122  tPair.mccE=mccE;
1123  tracksPair_B.push_back(tPair);
1124 
1125 
1126  tempId++;
1127  } //iRecoTrack
1128  }
1129  std::cout<<tracksPair_B.size()<<std::endl;
1130  //Sort pair by ascending order of absolute distance
1131  sort(tracksPair_F.begin(), tracksPair_F.end(), sortPair());
1132  sort(tracksPair_B.begin(), tracksPair_B.end(), sortPair());
1133  // Compare, sort, and eliminate CRT hits for just the best one
1134  // Compare, sort, and eliminate CRT hits for just the best one
1135  //std::cout<<tracksPair_F.size()<<std::endl;
1136  vector < tracksPair > allUniqueTracksPair;
1137  while (tracksPair_F.size()) {
1138  allUniqueTracksPair.push_back(tracksPair_F.front());
1139  tracksPair_F.erase(remove_if(tracksPair_F.begin(), tracksPair_F.end(), removePairIndex(tracksPair_F.front())),
1140  tracksPair_F.end());
1141  }
1142 
1143  while (tracksPair_B.size()) {
1144  allUniqueTracksPair.push_back(tracksPair_B.front());
1145  tracksPair_B.erase(remove_if(tracksPair_B.begin(), tracksPair_B.end(), removePairIndex(tracksPair_B.front())),
1146  tracksPair_B.end());
1147  }
1148  std::cout<<tracksPair_B.size()<<','<<allUniqueTracksPair.size()<<std::endl;
1149  //cout<<"Number of reco and CRT pairs: "<<allUniqueTracksPair.size()<<endl;
1150 // For the best one, add the validation metrics to a tree
1151  if (allUniqueTracksPair.size() > 0) {
1152  for (unsigned int u = 0; u < allUniqueTracksPair.size(); u++) {
1153  deltaX=allUniqueTracksPair[u].deltaX;
1154 
1155  deltaY=allUniqueTracksPair[u].deltaY;
1156  measuredXOffset=allUniqueTracksPair[u].xOffset;
1157  opCRTTDiff=allUniqueTracksPair[u].flashTDiff;
1158 
1159  dotCos=fabs(allUniqueTracksPair[u].dotProductCos);
1160  trackX1=allUniqueTracksPair[u].trackStartPosition.X();
1161  trackY1=allUniqueTracksPair[u].trackStartPosition.Y();
1162  trackZ1=allUniqueTracksPair[u].trackStartPosition.Z();
1163 
1164  trackX2=allUniqueTracksPair[u].trackEndPosition.X();
1165  trackY2=allUniqueTracksPair[u].trackEndPosition.Y();
1166  trackZ2=allUniqueTracksPair[u].trackEndPosition.Z();
1167 
1168  truthPosX=allUniqueTracksPair[u].mccX;
1169  truthPosY=allUniqueTracksPair[u].mccY;
1170  truthPosZ=allUniqueTracksPair[u].mccZ;
1171 
1172  moduleX=allUniqueTracksPair[u].moduleX1;
1173  moduleY=allUniqueTracksPair[u].moduleY1;
1174  mccTruthCheck=allUniqueTracksPair[u].mccTruthCheck;
1175  adcX=allUniqueTracksPair[u].adcX1;
1176  adcY=allUniqueTracksPair[u].adcY1;
1177 
1178  CRTT0=allUniqueTracksPair[u].timeAvg;
1179  stripX=allUniqueTracksPair[u].stripX1;
1180  stripY=allUniqueTracksPair[u].stripY1;
1181  recoPandoraT0=allUniqueTracksPair[u].pandoraT0Check;
1182  X_CRT=allUniqueTracksPair[u].X1;
1183  Y_CRT=allUniqueTracksPair[u].Y1;
1184  Z_CRT=allUniqueTracksPair[u].Z1;
1185  partProcess=allUniqueTracksPair[u].partProcess;
1186  mccE=allUniqueTracksPair[u].mccE;
1187  mccT0=allUniqueTracksPair[u].mccT0;
1188  //if (fabs(deltaX)<100 && fabs(deltaY)<100) cout<<allUniqueTracksPair[u].recoId<<','<<deltaX<<','<<deltaY<<endl;
1189  //cout<<"Candidate: "<<X_CRT<<','<<Y_CRT<<','<<Z_CRT<<endl;
1190  //cout<<"Candidate Delta: "<<deltaX<<","<<deltaY<<endl;
1191 
1192 
1194  if (fabs(trackX1)<400 && fabs(trackX2)<400 && fabs(deltaX)<60 && fabs(deltaY)<60 && fabs(dotCos)>.9995) {
1195 std::cout<<"Final Track Metrics:"<<CRTT0<<','<<mccT0<<','<<deltaX<<','<<deltaY<<','<<trackX1<<','<<trackX2<<','<<dotCos<<std::endl;
1196  track++;
1197  //cout<<mccTruthCheck<<endl;
1198  //cout<<"CRT1-TruthT: "<<mccT0-CRTT0<<endl;
1199  if (fabs(mccT0-CRTT0)>0 && !event.isRealData()) {
1200  if (Z_CRT<100){
1201  for (unsigned int iHit_F = 0; iHit_F < primaryHits_F.size(); iHit_F++) {
1202  //cout<<"Candidate CRTT0:"<<primaryHits_F[iHit_F].timeAvg<<endl;
1203 
1204 
1205 }
1206 }
1207  else{
1208  for (unsigned int iHit_F = 0; iHit_F < primaryHits_B.size(); iHit_F++) {
1209  //cout<<"Candidate CRTT0:"<<primaryHits_B[iHit_F].timeAvg<<endl;
1210 
1211 
1212 }
1213 
1214 
1215 }
1216  const simb::MCParticle *particle = partInventory->TrackIdToParticle_P(allUniqueTracksPair[u].truthId);
1217 
1218  std::set<int> signal_trackids;
1219  signal_trackids.emplace(allUniqueTracksPair[u].truthId);
1221  double purity;
1222 opCRTDiff=-99999999;
1223 maxPurity=0;
1224 for(unsigned int i = 0; i < opHitList.size(); ++i) {
1225  recob::OpFlash TheFlash = *opHitList[i];
1226  art::Ptr<recob::OpFlash> FlashP = opHitList[i];
1227  std::vector< art::Ptr<recob::OpHit> > hitFromFlash = pbt->OpFlashToOpHits_Ps(FlashP);
1228  std::vector< art::Ptr<recob::OpHit> > matchedHits = pbt->OpFlashToOpHits_Ps(FlashP);
1229 
1230  // Calculate the flash purity
1231 
1232  purity = pbt->OpHitCollectionPurity(signal_trackids, matchedHits);
1233  if (purity>maxPurity) {opCRTTDiff=TheFlash.Time()*1000.f-allUniqueTracksPair[u].timeAvg;
1234  flashTime=TheFlash.Time();
1235  maxPurity=purity;}
1236  //if (purity>0) cout<<"Optical Purity and TDiff:"<<purity<<','<<TheFlash.Time()*1000.f-allUniqueTracksPair[u].timeAvg<<endl;
1237 }
1238  auto const startPos=particle->Position(0);
1239  auto const endPos=particle->EndPosition();
1240  if (fabs(mccT0-CRTT0)>100000){
1241  double mccHitY=(endPos.Y()-startPos.Y())/(endPos.Z()-startPos.Z())*(Z_CRT-startPos.Z())+startPos.Y();
1242  double mccHitX=(endPos.X()-startPos.X())/(endPos.Z()-startPos.Z())*(Z_CRT-startPos.Z())+startPos.X();
1243  std::cout<<mccHitX<<','<<mccHitY<<std::endl;
1244  }}
1245  fCRTTree->Fill();
1246  }
1247 
1248  }
1249  }
1250  nEvents++;
1251  //cout<<track<<endl;
1252  //cout<<matchedTrack<<endl;
1253 cout<<"Truth track and CRT reco:"<<track<<','<<matchedTrack<<','<<truthTrack<<','<<misMatchedTrack<<endl;
1254  }
1255 
1256 
1257 // Setup CRT
1259  art::ServiceHandle<art::TFileService> fileServiceHandle;
1260  fCRTTree = fileServiceHandle->make<TTree>("Displacement", "event by event info");
1261  fMCCTree= fileServiceHandle->make<TTree>("MCC", "event by event info");
1262  fCRTTree->Branch("nEvents", &nEvents, "fnEvents/I");
1263 
1264 
1265  fCRTTree->Branch("hdeltaX", &deltaX, "deltaX/D");
1266  fCRTTree->Branch("hdeltaY", &deltaY, "deltaY/D");
1267  fCRTTree->Branch("hdotProductCos", &dotCos, "dotCos/D");
1268 
1269 
1270  fCRTTree->Branch("hX_CRT", &X_CRT, "X_CRT/D");
1271  fCRTTree->Branch("hY_CRT", &Y_CRT, "Y_CRT/D");
1272  fCRTTree->Branch("hZ_CRT", &Z_CRT, "Z_CRT/D");
1273 
1274  fCRTTree->Branch("hCRTT0", &CRTT0, "CRTT0/D");
1275 
1276  fCRTTree->Branch("htrkT0", &recoPandoraT0, "recoPandoraT0/D");
1277 
1278 
1279  fCRTTree->Branch("htrackStartX", &trackX1, "trackX1/D");
1280  fCRTTree->Branch("htrackStartY", &trackY1, "trackY1/D");
1281  fCRTTree->Branch("htrackStartZ", &trackZ1, "trackZ1/D");
1282 
1283 
1284 
1285  fCRTTree->Branch("htrackEndX", &trackX2, "trackX2/D");
1286  fCRTTree->Branch("htrackEndY", &trackY2, "trackY2/D");
1287  fCRTTree->Branch("htrackEndZ", &trackZ2, "trackZ2/D");
1288 
1289  fCRTTree->Branch("hmoduleX", &moduleX, "moduleX/I");
1290  fCRTTree->Branch("hmoduleY", &moduleY, "moduleY/I");
1291 
1292  fCRTTree->Branch("hstripX", &stripX, "stripX/I");
1293  fCRTTree->Branch("hstripY", &stripY, "stripY/I");
1294 
1295  fCRTTree->Branch("hadcX", &adcX, "adcX/I");
1296  fCRTTree->Branch("hadcY", &adcY, "adcY/I");
1297  fCRTTree->Branch("hpartProcess", &partProcess, "partProcess/I");
1298  fCRTTree->Branch("hopCRTTDiff", &opCRTTDiff, "opCRTTDiff/D");
1299  fCRTTree->Branch("hflashTime", &flashTime, "flashTime/D");
1300  fCRTTree->Branch("hmeasuredXOffset", &measuredXOffset, "measuredXOffset/D");
1301  fCRTTree->Branch("hmccE", &mccE, "mccE/D");
1302  fCRTTree->Branch("htruthPosX", &truthPosX, "truthPosX/D");
1303  fCRTTree->Branch("htruthPosY", &truthPosY, "truthPosY/D");
1304  fCRTTree->Branch("htruthPosZ", &truthPosZ, "truthPosZ/D");
1305  fCRTTree->Branch("hmccT0", &mccT0, "mccT0/D");
1306  fCRTTree->Branch("hmaxPurity", &maxPurity, "maxPurity/D");
1307 
1308  fMCCTree->Branch("hpartProcess", &partProcess, "partProcess/I");
1309  fMCCTree->Branch("htruthPosX", &truthPosX, "truthPosX/D");
1310  fMCCTree->Branch("htruthPosY", &truthPosY, "truthPosY/D");
1311  fMCCTree->Branch("htruthPosZ", &truthPosZ, "truthPosZ/D");
1312  fMCCTree->Branch("hmccE", &mccE, "mccE/D");
1313  fMCCTree->Branch("hmccT0", &mccT0, "mccT0/D");
1314 
1315 }
1316 // Endjob actions
1318 {
1319 
1320 
1321 
1322 }
1323 
1324 
1325 
1326 
1327 
1328 
1329 
1330 
1331 
1332 
1333 
1334 
1335 
1336 
def analyze(root, level, gtrees, gbranches, doprint)
Definition: rootstat.py:69
double E(const int i=0) const
Definition: MCParticle.h:233
code to link reconstructed objects back to the MC truth information
intermediate_table::iterator iterator
unsigned int NumberTrajectoryPoints() const
Definition: MCParticle.h:218
void analyze(art::Event const &e) override
const TLorentzVector & Position(const int i=0) const
Definition: MCParticle.h:219
std::vector< tracksPair > tracksPair_B
const std::vector< art::Ptr< recob::OpHit > > OpFlashToOpHits_Ps(art::Ptr< recob::OpFlash > &flash_P)
const TLorentzVector & EndPosition() const
Definition: MCParticle.h:225
std::vector< sim::TrackIDE > HitToTrackIDEs(detinfo::DetectorClocksData const &clockData, recob::Hit const &hit) const
std::string string
Definition: nybbler.cc:12
const simb::MCParticle * TrackIdToParticle_P(int id) const
simb::Origin_t Origin() const
Definition: MCTruth.h:74
STL namespace.
geo::TPCID PositionToTPCID(geo::Point_t const &point) const
Returns the ID of the TPC at specified location.
uint8_t channel
Definition: CRTFragment.hh:201
std::string Process() const
Definition: MCParticle.h:215
const double OpHitCollectionPurity(std::set< int > const &tkIds, std::vector< art::Ptr< recob::OpHit > > const &opHits_Ps)
Particle class.
std::vector< recoHits > primaryHits_F
art framework interface to geometry description
bool operator()(const tracksPair &pair1, const tracksPair &pair2)
bool isRealData() const
T abs(T value)
double Time() const
Definition: OpFlash.h:106
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
void beginJob()
Definition: Breakpoints.cc:14
std::vector< tracksPair > tracksPair_F
def key(type, name=None)
Definition: graph.py:13
const art::Ptr< simb::MCTruth > & TrackIdToMCTruth_P(int id) const
const double a
T get(std::string const &key) const
Definition: ParameterSet.h:271
std::vector< tempHits > tempHits_F
double T(const int i=0) const
Definition: MCParticle.h:224
p
Definition: test.py:223
int moduletoCTB(int module2, int module1)
Detector simulation of raw signals on wires.
std::vector< recoHits > primaryHits_B
SingleCRTMatching(fhicl::ParameterSet const &p)
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:184
Declaration of signal hit object.
void End(void)
Definition: gXSecComp.cxx:210
def center(depos, point)
Definition: depos.py:117
Provides recob::Track data product.
bool operator()(const tracksPair &tracksPair2)
constexpr auto const & deepestIndex() const
Returns the value of the deepest ID available (TPC&#39;s).
Definition: geo_types.h:428
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:297
bool moduleMatcher(int module1, int module2)
recob::tracking::Plane Plane
Definition: TrackState.h:17
removePairIndex(const tracksPair &tracksPair0)
Cosmic rays.
Definition: MCTruth.h:24
QTextStream & endl(QTextStream &s)
Event finding and building.
std::vector< tempHits > tempHits_B