LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
shower::EMShowerAlg Class Reference

#include "EMShowerAlg.h"

Public Member Functions

 EMShowerAlg (fhicl::ParameterSet const &pset)
 
void AssociateClustersAndTracks (std::vector< art::Ptr< recob::Cluster > > const &clusters, art::FindManyP< recob::Hit > const &fmh, art::FindManyP< recob::Track > const &fmt, std::map< int, std::vector< int > > &clusterToTracks, std::map< int, std::vector< int > > &trackToClusters)
 Map associated tracks and clusters together given their associated hits. More...
 
void AssociateClustersAndTracks (std::vector< art::Ptr< recob::Cluster > > const &clusters, art::FindManyP< recob::Hit > const &fmh, art::FindManyP< recob::Track > const &fmt, std::vector< int > const &clustersToIgnore, std::map< int, std::vector< int > > &clusterToTracks, std::map< int, std::vector< int > > &trackToClusters)
 Map associated tracks and clusters together given their associated hits, whilst ignoring certain clusters. More...
 
std::vector< int > CheckShowerPlanes (std::vector< std::vector< int > > const &initialShowers, std::vector< art::Ptr< recob::Cluster > > const &clusters, art::FindManyP< recob::Hit > const &fmh)
 Takes the initial showers found and tries to resolve issues where one bad view ruins the event. More...
 
std::unique_ptr< recob::TrackConstructTrack (std::vector< art::Ptr< recob::Hit > > const &track1, std::vector< art::Ptr< recob::Hit > > const &track2, std::map< int, TVector2 > const &showerCentreMap)
 
std::unique_ptr< recob::TrackConstructTrack (std::vector< art::Ptr< recob::Hit > > const &track1, std::vector< art::Ptr< recob::Hit > > const &track2)
 
void FindInitialTrack (const std::map< int, std::vector< art::Ptr< recob::Hit > > > &hits, std::unique_ptr< recob::Track > &initialTrack, std::map< int, std::vector< art::Ptr< recob::Hit > > > &initialTrackHits, int plane)
 Finds the initial track-like part of the shower and the hits in all views associated with it. More...
 
std::vector< std::vector< int > > FindShowers (std::map< int, std::vector< int > > const &trackToClusters)
 Makes showers given a map between tracks and all clusters associated with them. More...
 
recob::Shower MakeShower (art::PtrVector< recob::Hit > const &hits, std::unique_ptr< recob::Track > const &initialTrack, std::map< int, std::vector< art::Ptr< recob::Hit > > > const &initialTrackHits)
 Makes a recob::Shower object given the hits in the shower and the initial track-like part. More...
 
recob::Shower MakeShower (art::PtrVector< recob::Hit > const &hits, art::Ptr< recob::Vertex > const &vertex, int &iok)
 <Tingjun to="" document>=""> More...
 
std::vector< recob::SpacePointMakeSpacePoints (std::map< int, std::vector< art::Ptr< recob::Hit > > > hits, std::vector< std::vector< art::Ptr< recob::Hit > > > &hitAssns)
 Makes space points from the shower hits in each plane. More...
 
std::map< int, std::vector< art::Ptr< recob::Hit > > > OrderShowerHits (const art::PtrVector< recob::Hit > &shower, int plane)
 Takes the hits associated with a shower and orders them so they follow the direction of the shower. More...
 
void FindInitialTrackHits (std::vector< art::Ptr< recob::Hit > >const &showerHits, art::Ptr< recob::Vertex > const &vertex, std::vector< art::Ptr< recob::Hit > > &trackHits)
 <Tingjun to="" document>=""> More...
 
Int_t WeightedFit (const Int_t n, const Double_t *x, const Double_t *y, const Double_t *w, Double_t *parm)
 <Tingjun to="" document>=""> More...
 
bool isCleanShower (std::vector< art::Ptr< recob::Hit > > const &hits)
 <Tingjun to="" document>=""> More...
 

Public Attributes

int fDebug
 

Private Member Functions

void CheckIsolatedHits (std::map< int, std::vector< art::Ptr< recob::Hit > > > &showerHitsMap)
 Checks the hits across the views in a given shower to determine if there is one in the incorrect TPC. More...
 
bool CheckShowerHits (std::map< int, std::vector< art::Ptr< recob::Hit > > > const &showerHitsMap)
 
TVector3 Construct3DPoint (art::Ptr< recob::Hit > const &hit1, art::Ptr< recob::Hit > const &hit2)
 Constructs a 3D point (in [cm]) to represent the hits given in two views. More...
 
double FinddEdx (std::vector< art::Ptr< recob::Hit > > const &trackHits, std::unique_ptr< recob::Track > const &track)
 Finds dE/dx for the track given a set of hits. More...
 
std::vector< art::Ptr< recob::Hit > > FindOrderOfHits (std::vector< art::Ptr< recob::Hit > > const &hits, bool perpendicular=false)
 
std::map< int, std::vector< art::Ptr< recob::Hit > > > FindShowerStart (std::map< int, std::vector< art::Ptr< recob::Hit > > > const &orderedShowerMap)
 
std::map< int, std::map< int, bool > > GetPlanePermutations (const std::map< int, std::vector< art::Ptr< recob::Hit > > > &showerHitsMap)
 
double GlobalWire (const geo::WireID &wireID)
 Find the global wire position. More...
 
TVector2 HitCoordinates (art::Ptr< recob::Hit > const &hit)
 Return the coordinates of this hit in global wire/tick space. More...
 
TVector2 HitPosition (art::Ptr< recob::Hit > const &hit)
 Return the coordinates of this hit in units of cm. More...
 
TVector2 HitPosition (TVector2 const &pos, geo::PlaneID planeID)
 Return the coordinates of this hit in units of cm. More...
 
std::unique_ptr< recob::TrackMakeInitialTrack (std::map< int, std::vector< art::Ptr< recob::Hit > > > const &initialHitsMap, std::map< int, std::vector< art::Ptr< recob::Hit > > > const &showerHitsMap)
 Takes initial track hits from multiple views and forms a track object which best represents the start of the shower. More...
 
void OrderShowerHits (std::vector< art::Ptr< recob::Hit > > const &shower, std::vector< art::Ptr< recob::Hit > > &orderedShower, art::Ptr< recob::Vertex > const &vertex)
 Takes the hits associated with a shower and orders then so they follow the direction of the shower. More...
 
TVector2 Project3DPointOntoPlane (TVector3 const &point, int plane, int cryostat=0)
 
std::map< double, int > RelativeWireWidth (const std::map< int, std::vector< art::Ptr< recob::Hit > > > &showerHitsMap)
 
TVector2 ShowerCentre (const std::vector< art::Ptr< recob::Hit > > &showerHits)
 Returns the charge-weighted shower centre. More...
 
TVector2 ShowerDirection (const std::vector< art::Ptr< recob::Hit > > &showerHits)
 Returns a rough charge-weighted shower 'direction' given the hits in the shower. More...
 
double ShowerHitRMS (const std::vector< art::Ptr< recob::Hit > > &showerHits)
 Returns the RMS of the hits from the central shower 'axis' along the length of the shower. More...
 
double ShowerHitRMSGradient (const std::vector< art::Ptr< recob::Hit > > &showerHits, TVector2 trueStart=TVector2(0, 0))
 Returns the gradient of the RMS vs shower segment graph. More...
 
int WorstPlane (const std::map< int, std::vector< art::Ptr< recob::Hit > > > &showerHitsMap)
 Returns the plane which is determined to be the least likely to be correct. More...
 
int FindTrueParticle (const std::vector< art::Ptr< recob::Hit > > &showerHits)
 
int FindParticleID (const art::Ptr< recob::Hit > &hit)
 
void MakePicture ()
 

Private Attributes

double fMinTrackLength
 
double fdEdxTrackLength
 
double fSpacePointSize
 
unsigned int fNfitpass
 
std::vector< unsigned int > fNfithits
 
std::vector< double > fToler
 
art::ServiceHandle< geo::GeometryfGeom
 
detinfo::DetectorProperties const * fDetProp
 
art::ServiceHandle< art::TFileServicetfs
 
shower::ShowerEnergyAlg fShowerEnergyAlg
 
calo::CalorimetryAlg fCalorimetryAlg
 
pma::ProjectionMatchingAlg fProjectionMatchingAlg
 
std::string fDetector
 
art::ServiceHandle< cheat::BackTrackerServicebt_serv
 
TH1I * hTrueDirection
 
TProfile * hNumHitsInSegment
 
TProfile * hNumSegments
 
bool fMakeGradientPlot
 
bool fMakeRMSGradientPlot
 
int fNumShowerSegments
 

Detailed Description

Definition at line 74 of file EMShowerAlg.h.

Constructor & Destructor Documentation

shower::EMShowerAlg::EMShowerAlg ( fhicl::ParameterSet const &  pset)

Definition at line 13 of file EMShowerAlg.cxx.

References art::errors::Configuration, fdEdxTrackLength, fDetector, fMakeGradientPlot, fMakeRMSGradientPlot, fMinTrackLength, fNfithits, fNfitpass, fNumShowerSegments, fSpacePointSize, fToler, fhicl::ParameterSet::get(), hNumHitsInSegment, hNumSegments, hTrueDirection, art::TFileDirectory::make(), and tfs.

13  : fDetProp(lar::providerFrom<detinfo::DetectorPropertiesService>()),
14  fShowerEnergyAlg(pset.get<fhicl::ParameterSet>("ShowerEnergyAlg")),
15  fCalorimetryAlg(pset.get<fhicl::ParameterSet>("CalorimetryAlg")),
16  fProjectionMatchingAlg(pset.get<fhicl::ParameterSet>("ProjectionMatchingAlg")) {
17 
18  fMinTrackLength = pset.get<double>("MinTrackLength");
19  fdEdxTrackLength = pset.get<double>("dEdxTrackLength");
20  fSpacePointSize = pset.get<double>("SpacePointSize");
21  fNfitpass = pset.get<unsigned int>("Nfitpass");
22  fNfithits = pset.get<std::vector<unsigned int> >("Nfithits");
23  fToler = pset.get<std::vector<double> >("Toler");
24  if (fNfitpass!=fNfithits.size() ||
25  fNfitpass!=fToler.size()) {
27  << "EMShowerAlg: fNfithits and fToler need to have size fNfitpass";
28  }
29  fDetector = pset.get<std::string>("Detector","dune35t");
30 
31  hTrueDirection = tfs->make<TH1I>("trueDir","",2,0,2);
32 
33  //this->MakePicture();
34  // tmp
35  fMakeGradientPlot = pset.get<bool>("MakeGradientPlot",false);
36  fMakeRMSGradientPlot = pset.get<bool>("MakeRMSGradientPlot",false);
37  fNumShowerSegments = pset.get<int>("NumShowerSegments",4);
38  hNumHitsInSegment = tfs->make<TProfile>("NumHitsInSegment","",100,0,100);
39  hNumSegments = tfs->make<TProfile>("NumSegments","",100,0,100);
40 
41 }
TProfile * hNumSegments
Definition: EMShowerAlg.h:251
std::vector< double > fToler
Definition: EMShowerAlg.h:231
calo::CalorimetryAlg fCalorimetryAlg
Definition: EMShowerAlg.h:240
unsigned int fNfitpass
Definition: EMShowerAlg.h:229
std::string fDetector
Definition: EMShowerAlg.h:243
shower::ShowerEnergyAlg fShowerEnergyAlg
Definition: EMShowerAlg.h:239
pma::ProjectionMatchingAlg fProjectionMatchingAlg
Definition: EMShowerAlg.h:241
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
T * make(ARGS...args) const
art::ServiceHandle< art::TFileService > tfs
Definition: EMShowerAlg.h:236
TProfile * hNumHitsInSegment
Definition: EMShowerAlg.h:251
detinfo::DetectorProperties const * fDetProp
Definition: EMShowerAlg.h:235
std::vector< unsigned int > fNfithits
Definition: EMShowerAlg.h:230

Member Function Documentation

void shower::EMShowerAlg::AssociateClustersAndTracks ( std::vector< art::Ptr< recob::Cluster > > const &  clusters,
art::FindManyP< recob::Hit > const &  fmh,
art::FindManyP< recob::Track > const &  fmt,
std::map< int, std::vector< int > > &  clusterToTracks,
std::map< int, std::vector< int > > &  trackToClusters 
)

Map associated tracks and clusters together given their associated hits.

Definition at line 43 of file EMShowerAlg.cxx.

Referenced by shower::EMShower::produce().

47  {
48 
49  std::vector<int> clustersToIgnore = {-999};
50  this->AssociateClustersAndTracks(clusters, fmh, fmt, clustersToIgnore, clusterToTracks, trackToClusters);
51 
52  return;
53 
54 }
void AssociateClustersAndTracks(std::vector< art::Ptr< recob::Cluster > > const &clusters, art::FindManyP< recob::Hit > const &fmh, art::FindManyP< recob::Track > const &fmt, std::map< int, std::vector< int > > &clusterToTracks, std::map< int, std::vector< int > > &trackToClusters)
Map associated tracks and clusters together given their associated hits.
Definition: EMShowerAlg.cxx:43
void shower::EMShowerAlg::AssociateClustersAndTracks ( std::vector< art::Ptr< recob::Cluster > > const &  clusters,
art::FindManyP< recob::Hit > const &  fmh,
art::FindManyP< recob::Track > const &  fmt,
std::vector< int > const &  clustersToIgnore,
std::map< int, std::vector< int > > &  clusterToTracks,
std::map< int, std::vector< int > > &  trackToClusters 
)

Map associated tracks and clusters together given their associated hits, whilst ignoring certain clusters.

Definition at line 56 of file EMShowerAlg.cxx.

References evd::details::begin(), evd::details::end(), fDebug, fMinTrackLength, track, and lar::dump::vector().

61  {
62 
63  // Look through all the clusters
64  for (std::vector<art::Ptr<recob::Cluster> >::const_iterator clusterIt = clusters.begin(); clusterIt != clusters.end(); ++clusterIt) {
65 
66  // Get the hits in this cluster
67  std::vector<art::Ptr<recob::Hit> > clusterHits = fmh.at(clusterIt->key());
68 
69  // Look at all these hits and find the associated tracks
70  for (std::vector<art::Ptr<recob::Hit> >::iterator clusterHitIt = clusterHits.begin(); clusterHitIt != clusterHits.end(); ++clusterHitIt) {
71 
72  // Get the tracks associated with this hit
73  std::vector<art::Ptr<recob::Track> > clusterHitTracks = fmt.at(clusterHitIt->key());
74  if (clusterHitTracks.size() > 1) { std::cout << "More than one track associated with this hit!" << std::endl; continue; }
75  if (clusterHitTracks.size() < 1) continue;
76  if (clusterHitTracks.at(0)->Length() < fMinTrackLength) {
77  if (fDebug > 2)
78  std::cout << "Track " << clusterHitTracks.at(0)->ID() << " is too short! (" << clusterHitTracks.at(0)->Length() << ")" << std::endl;
79  continue;
80  }
81 
82  // Add this cluster to the track map
83  int track = clusterHitTracks.at(0).key();
84  //int trackID = clusterHitTracks.at(0)->ID();
85  int cluster = (*clusterIt).key();
86  if (std::find(clustersToIgnore.begin(), clustersToIgnore.end(), cluster) != clustersToIgnore.end())
87  continue;
88  if (std::find(trackToClusters[track].begin(), trackToClusters[track].end(), cluster) == trackToClusters[track].end())
89  trackToClusters[track].push_back(cluster);
90  if (std::find(clusterToTracks[cluster].begin(), clusterToTracks[cluster].end(), track) == clusterToTracks[cluster].end())
91  clusterToTracks[cluster].push_back(track);
92 
93  }
94 
95  }
96 
97  return;
98 
99 }
Cluster finding and building.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
Float_t track
Definition: plot.C:34
void shower::EMShowerAlg::CheckIsolatedHits ( std::map< int, std::vector< art::Ptr< recob::Hit > > > &  showerHitsMap)
private

Checks the hits across the views in a given shower to determine if there is one in the incorrect TPC.

Definition at line 101 of file EMShowerAlg.cxx.

References fGeom, geo::GeometryCore::MaxPlanes(), and lar::dump::vector().

Referenced by OrderShowerHits().

101  {
102 
103  std::map<int,std::vector<int> > firstTPC;
104  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt)
105  firstTPC[showerHitsIt->second.at(0)->WireID().TPC].push_back(showerHitsIt->first);
106 
107  // If all in the same TPC then that's great!
108  if (firstTPC.size() == 1)
109  return;
110 
111  // If they are in more than two TPCs, not much we can do
112  else if (firstTPC.size() > 2)
113  return;
114 
115  // If we get to this point, there should be something we can do!
116 
117  // Find the problem plane
118  int problemPlane = -1;
119  for (std::map<int,std::vector<int> >::iterator firstTPCIt = firstTPC.begin(); firstTPCIt != firstTPC.end(); ++firstTPCIt)
120  if (firstTPCIt->second.size() == 1)
121  problemPlane = firstTPCIt->second.at(0);
122 
123  // Require three hits
124  if (showerHitsMap.at(problemPlane).size() < 3)
125  return;
126 
127  // and get the other planes with at least three hits
128  std::vector<int> otherPlanes;
129  for (int plane = 0; plane < (int)fGeom->MaxPlanes(); ++plane)
130  if (plane != problemPlane and
131  showerHitsMap.count(plane) and
132  showerHitsMap.at(plane).size() >= 3)
133  otherPlanes.push_back(plane);
134 
135  if (otherPlanes.size() == 0)
136  return;
137 
138  // Look at the hits after the first one
139  unsigned int wrongTPC = showerHitsMap.at(problemPlane).at(0)->WireID().TPC;
140  unsigned int nHits = 0;
141  for (std::vector<art::Ptr<recob::Hit> >::iterator hitIt = showerHitsMap.at(problemPlane).begin();
142  hitIt != showerHitsMap.at(problemPlane).end() and (*hitIt)->WireID().TPC == wrongTPC;
143  ++hitIt)
144  ++nHits;
145 
146  // If there are more than two hits in the 'wrong TPC', we can't be sure it is indeed wrong
147  if (nHits > 2)
148  return;
149 
150  // See if at least the next four times as many hits are in a different TPC
151  std::map<int,int> otherTPCs;
152  for (std::vector<art::Ptr<recob::Hit> >::iterator hitIt = std::next(showerHitsMap.at(problemPlane).begin(),nHits);
153  hitIt != showerHitsMap.at(problemPlane).end() and std::distance(std::next(showerHitsMap.at(problemPlane).begin(),nHits),hitIt) < 4*nHits;
154  ++hitIt)
155  ++otherTPCs[(*hitIt)->WireID().TPC];
156 
157  if (otherTPCs.size() > 1)
158  return;
159 
160  // If we get this far, we can move the problem hits from the front of the shower to the back
161  std::map<int,int> tpcCount;
162  for (std::vector<int>::iterator otherPlaneIt = otherPlanes.begin(); otherPlaneIt != otherPlanes.end(); ++otherPlaneIt)
163  for (std::vector<art::Ptr<recob::Hit> >::iterator hitIt = std::next(showerHitsMap.at(*otherPlaneIt).begin());
164  hitIt != showerHitsMap.at(*otherPlaneIt).end() and hitIt != std::next(showerHitsMap.at(*otherPlaneIt).begin(),2);
165  ++hitIt)
166  ++tpcCount[(*hitIt)->WireID().TPC];
167 
168  // Remove the first hit if it is in the wrong TPC
169  if (tpcCount.size() == 1 and tpcCount.begin()->first == (int)(*std::next(showerHitsMap.at(problemPlane).begin(),nHits))->WireID().TPC) {
170  std::vector<art::Ptr<recob::Hit> > naughty_hits;
171  for (std::vector<art::Ptr<recob::Hit> >::iterator hitIt = showerHitsMap.at(problemPlane).begin(); hitIt != std::next(showerHitsMap.at(problemPlane).begin(),nHits); ++hitIt) {
172  naughty_hits.push_back(*hitIt);
173  showerHitsMap.at(problemPlane).erase(hitIt);
174  }
175  for (std::vector<art::Ptr<recob::Hit> >::iterator naughty_hitIt = naughty_hits.begin(); naughty_hitIt != naughty_hits.end(); ++naughty_hitIt)
176  showerHitsMap.at(problemPlane).push_back(*naughty_hitIt);
177  }
178 
179  return;
180 
181 }
intermediate_table::iterator iterator
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.
art::ServiceHandle< geo::Geometry > fGeom
Definition: EMShowerAlg.h:234
bool shower::EMShowerAlg::CheckShowerHits ( std::map< int, std::vector< art::Ptr< recob::Hit > > > const &  showerHitsMap)
private

Takes the shower hits in all views and ensure the ordering is consistent Returns bool, indicating whether or not everything makes sense!

Definition at line 183 of file EMShowerAlg.cxx.

References Construct3DPoint(), fDebug, HitPosition(), Project3DPointOntoPlane(), lar::dump::vector(), X, and Y.

Referenced by MakeInitialTrack(), and OrderShowerHits().

183  {
184 
185  bool consistencyCheck = true;
186 
187  if (showerHitsMap.size() < 2)
188  consistencyCheck = true;
189 
190  else if (showerHitsMap.size() == 2) {
191 
192  // With two views, we can check:
193  // -- timing between views is consistent
194  // -- the 3D start point makes sense when projected back onto the individual planes
195 
196  std::vector<art::Ptr<recob::Hit> > startHits;
197  std::vector<int> planes;
198  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt) {
199  startHits.push_back(showerHitsIt->second.front());
200  planes.push_back(showerHitsIt->first);
201  }
202 
203  TVector3 showerStartPos = Construct3DPoint(startHits.at(0), startHits.at(1));
204  TVector2 proj1 = Project3DPointOntoPlane(showerStartPos, planes.at(0));
205  TVector2 proj2 = Project3DPointOntoPlane(showerStartPos, planes.at(1));
206 
207  double timingDifference = TMath::Abs( startHits.at(0)->PeakTime() - startHits.at(1)->PeakTime() );
208  double projectionDifference = ( (HitPosition(startHits.at(0)) - proj1).Mod() + (HitPosition(startHits.at(1)) - proj2).Mod() ) / (double)2;
209 
210  if (timingDifference > 40 or
211  projectionDifference > 5 or
212  showerStartPos.X() == -9999 or showerStartPos.Y() == -9999 or showerStartPos.Z() == -9999)
213  consistencyCheck = false;
214 
215  if (fDebug > 1)
216  std::cout << "Timing difference is " << timingDifference << " and projection distance is " << projectionDifference << " (start is (" << showerStartPos.X() << ", " << showerStartPos.Y() << ", " << showerStartPos.Z() << ")" << std::endl;
217 
218  }
219 
220  else if (showerHitsMap.size() == 3) {
221 
222  // With three views, we can check:
223  // -- the timing between views is consistent
224  // -- the 3D start point formed by two views and projected back into the third is close to the start point in that view
225 
226  std::map<int,art::Ptr<recob::Hit> > start2DMap;
227  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator showerHitIt = showerHitsMap.begin(); showerHitIt != showerHitsMap.end(); ++showerHitIt)
228  start2DMap[showerHitIt->first] = showerHitIt->second.front();
229 
230  std::map<int,double> projDiff;
231  std::map<int,double> timingDiff;
232 
233  for (int plane = 0; plane < 3; ++plane) {
234 
235  std::vector<int> otherPlanes;
236  for (int otherPlane = 0; otherPlane < 3; ++otherPlane)
237  if (otherPlane != plane)
238  otherPlanes.push_back(otherPlane);
239 
240  TVector3 showerStartPos = Construct3DPoint(start2DMap.at(otherPlanes.at(0)), start2DMap.at(otherPlanes.at(1)));
241  TVector2 showerStartProj = Project3DPointOntoPlane(showerStartPos, plane);
242 
243  if (fDebug > 2) {
244  std::cout << "Plane... " << plane << std::endl;
245  std::cout << "Start position in this plane is " << HitPosition(start2DMap.at(plane)).X() << ", " << HitPosition(start2DMap.at(plane)).Y() << ")" << std::endl;
246  std::cout << "Shower start from other two planes is (" << showerStartPos.X() << ", " << showerStartPos.Y() << ", " << showerStartPos.Z() << ")" << std::endl;
247  std::cout << "Projecting the other two planes gives position (" << showerStartProj.X() << ", " << showerStartProj.Y() << ")" << std::endl;
248  }
249 
250  double projDiff = TMath::Abs((showerStartProj-HitPosition(start2DMap.at(plane))).Mod());
251  double timeDiff = TMath::Max(TMath::Abs(start2DMap.at(plane)->PeakTime() - start2DMap.at(otherPlanes.at(0))->PeakTime()),
252  TMath::Abs(start2DMap.at(plane)->PeakTime() - start2DMap.at(otherPlanes.at(1))->PeakTime()));
253 
254  if (fDebug > 1)
255  std::cout << "Plane " << plane << " has projDiff " << projDiff << " and timeDiff " << timeDiff << std::endl;
256 
257  if (projDiff > 5 or timeDiff > 40)
258  consistencyCheck = false;
259 
260  }
261 
262  }
263 
264  if (fDebug > 1)
265  std::cout << "Consistency check is " << consistencyCheck << std::endl;
266 
267  return consistencyCheck;
268 
269 }
TVector3 Construct3DPoint(art::Ptr< recob::Hit > const &hit1, art::Ptr< recob::Hit > const &hit2)
Constructs a 3D point (in [cm]) to represent the hits given in two views.
Float_t Y
Definition: plot.C:39
TVector2 Project3DPointOntoPlane(TVector3 const &point, int plane, int cryostat=0)
TVector2 HitPosition(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in units of cm.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
Float_t X
Definition: plot.C:39
std::vector< int > shower::EMShowerAlg::CheckShowerPlanes ( std::vector< std::vector< int > > const &  initialShowers,
std::vector< art::Ptr< recob::Cluster > > const &  clusters,
art::FindManyP< recob::Hit > const &  fmh 
)

Takes the initial showers found and tries to resolve issues where one bad view ruins the event.

Definition at line 271 of file EMShowerAlg.cxx.

References fDebug, hits(), art::Ptr< T >::key(), geo::PlaneID::Plane, recob::Cluster::Plane(), util::flags::to_string(), and lar::dump::vector().

Referenced by shower::EMShower::produce().

273  {
274 
275  std::vector<int> clustersToIgnore;
276 
277  // // Look at each shower
278  // for (std::vector<std::vector<int> >::const_iterator initialShowerIt = initialShowers.begin(); initialShowerIt != initialShowers.end(); ++initialShowerIt) {
279 
280  // // Map the clusters and cluster hits to each view
281  // std::map<int,std::vector<art::Ptr<recob::Cluster> > > planeClusters;
282  // std::map<int,std::vector<art::Ptr<recob::Hit> > > planeClusterHits;
283  // for (std::vector<int>::const_iterator clusterIt = initialShowerIt->begin(); clusterIt != initialShowerIt->end(); ++clusterIt) {
284  // art::Ptr<recob::Cluster> cluster = clusters.at(*clusterIt);
285  // std::vector<art::Ptr<recob::Hit> > hits = fmh.at(cluster.key());
286  // planeClusters[cluster->Plane().Plane].push_back(cluster);
287  // for (std::vector<art::Ptr<recob::Hit> >::iterator hitIt = hits.begin(); hitIt != hits.end(); ++hitIt)
288  // planeClusterHits[cluster.key()].push_back(*hitIt);
289  // }
290 
291  // // Can't do much with fewer than three views
292  // if (planeClusters.size() < 3)
293  // continue;
294 
295  // // Look at the average RMS of clusters in each view
296  // std::map<int,double> avRMS;
297  // for (std::map<int,std::vector<art::Ptr<recob::Cluster> > >::iterator planeClusterIt = planeClusters.begin(); planeClusterIt != planeClusters.end(); ++planeClusterIt) {
298  // std::cout << "Plane " << planeClusterIt->first << std::endl;
299  // for (std::vector<art::Ptr<recob::Cluster> >::iterator clusterIt = planeClusterIt->second.begin(); clusterIt != planeClusterIt->second.end(); ++clusterIt) {
300  // double rms = ShowerHitRMS(planeClusterHits.at(clusterIt->key()));
301  // std::cout << "Cluster " << clusterIt->key() << " has RMS " << rms << std::endl;
302  // }
303  // }
304  // }
305 
306 
307  // Look at each shower
308  for (std::vector<std::vector<int> >::const_iterator initialShowerIt = initialShowers.begin(); initialShowerIt != initialShowers.end(); ++initialShowerIt) {
309 
310  if (std::distance(initialShowers.begin(),initialShowerIt) > 0)
311  continue;
312 
313  // Map the clusters and cluster hits to each view
314  std::map<int,std::vector<art::Ptr<recob::Cluster> > > planeClusters;
315  std::map<int,std::vector<art::Ptr<recob::Hit> > > planeHits;
316  for (std::vector<int>::const_iterator clusterIt = initialShowerIt->begin(); clusterIt != initialShowerIt->end(); ++clusterIt) {
317  art::Ptr<recob::Cluster> cluster = clusters.at(*clusterIt);
318  std::vector<art::Ptr<recob::Hit> > hits = fmh.at(cluster.key());
319  planeClusters[cluster->Plane().Plane].push_back(cluster);
320  for (std::vector<art::Ptr<recob::Hit> >::iterator hitIt = hits.begin(); hitIt != hits.end(); ++hitIt)
321  planeHits[(*hitIt)->WireID().Plane].push_back(*hitIt);
322  }
323 
324  TFile* outFile = new TFile("chargeDistributions.root","RECREATE");
325  std::map<int,TH1D*> chargeDist;
326  for (std::map<int,std::vector<art::Ptr<recob::Cluster> > >::iterator planeIt = planeClusters.begin(); planeIt != planeClusters.end(); ++planeIt) {
327  for (std::vector<art::Ptr<recob::Cluster> >::iterator clusterIt = planeIt->second.begin(); clusterIt != planeIt->second.end(); ++clusterIt) {
328  chargeDist[planeIt->first] = new TH1D(std::string("chargeDist_Plane"+std::to_string(planeIt->first)+"_Cluster"+std::to_string(clusterIt->key())).c_str(),"",150,0,1000);
329  std::vector<art::Ptr<recob::Hit> > hits = fmh.at(clusterIt->key());
330  for (std::vector<art::Ptr<recob::Hit> >::iterator hitIt = hits.begin(); hitIt != hits.end(); ++hitIt)
331  chargeDist[planeIt->first]->Fill((*hitIt)->Integral());
332  outFile->cd();
333  chargeDist[planeIt->first]->Write();
334  }
335  }
336  outFile->Close();
337  delete outFile;
338 
339  // Can't do much with fewer than three views
340  if (planeClusters.size() < 3)
341  continue;
342 
343  // Look at how many clusters each plane has, and the proportion of hits each one uses
344  std::map<int,std::vector<double> > planeClusterSizes;
345  for (std::map<int,std::vector<art::Ptr<recob::Cluster> > >::iterator planeClustersIt = planeClusters.begin(); planeClustersIt != planeClusters.end(); ++planeClustersIt) {
346  for (std::vector<art::Ptr<recob::Cluster> >::iterator planeClusterIt = planeClustersIt->second.begin(); planeClusterIt != planeClustersIt->second.end(); ++planeClusterIt) {
347  std::vector<art::Ptr<recob::Hit> > hits = fmh.at(planeClusterIt->key());
348  planeClusterSizes[planeClustersIt->first].push_back((double)hits.size()/(double)planeHits.at(planeClustersIt->first).size());
349  }
350  }
351 
352  // Find the average hit fraction across all clusters in the plane
353  std::map<int,double> planeClustersAvSizes;
354  for (std::map<int,std::vector<double> >::iterator planeClusterSizesIt = planeClusterSizes.begin(); planeClusterSizesIt != planeClusterSizes.end(); ++planeClusterSizesIt) {
355  double average = 0;
356  for (std::vector<double>::iterator planeClusterSizeIt = planeClusterSizesIt->second.begin(); planeClusterSizeIt != planeClusterSizesIt->second.end(); ++planeClusterSizeIt)
357  average += *planeClusterSizeIt;
358  average /= planeClusterSizesIt->second.size();
359  planeClustersAvSizes[planeClusterSizesIt->first] = average;
360  }
361 
362  // Now decide if there is one plane which is ruining the reconstruction
363  // If two planes have a low average cluster fraction and one high, this plane likely merges two particle deposits together
364  int badPlane = -1;
365  for (std::map<int,double>::iterator clusterAvSizeIt = planeClustersAvSizes.begin(); clusterAvSizeIt != planeClustersAvSizes.end(); ++clusterAvSizeIt) {
366 
367  // Get averages from other planes and add in quadrature
368  std::vector<double> otherAverages;
369  for (std::map<int,double>::iterator otherClustersAvSizeIt = planeClustersAvSizes.begin(); otherClustersAvSizeIt != planeClustersAvSizes.end(); ++otherClustersAvSizeIt)
370  if (clusterAvSizeIt->first != otherClustersAvSizeIt->first)
371  otherAverages.push_back(otherClustersAvSizeIt->second);
372  double quadOtherPlanes = 0;
373  for (std::vector<double>::iterator otherAvIt = otherAverages.begin(); otherAvIt != otherAverages.end(); ++otherAvIt)
374  quadOtherPlanes += TMath::Power(*otherAvIt,2);
375  quadOtherPlanes = TMath::Sqrt(quadOtherPlanes);
376 
377  // If this plane has an average higher than the quadratic sum of the others, it may be bad
378  if (clusterAvSizeIt->second >= quadOtherPlanes)
379  badPlane = clusterAvSizeIt->first;
380 
381  }
382 
383  if (badPlane != -1) {
384  if (fDebug > 1)
385  std::cout << "Bad plane is " << badPlane << std::endl;
386  for (std::vector<art::Ptr<recob::Cluster> >::iterator clusterIt = planeClusters.at(badPlane).begin(); clusterIt != planeClusters.at(badPlane).end(); ++clusterIt)
387  clustersToIgnore.push_back(clusterIt->key());
388  }
389 
390  }
391 
392  return clustersToIgnore;
393 
394 }
key_type key() const
Definition: Ptr.h:356
intermediate_table::iterator iterator
geo::PlaneID Plane() const
Returns the plane ID this cluster lies on.
Definition: Cluster.h:744
Cluster finding and building.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
void hits()
Definition: readHits.C:15
intermediate_table::const_iterator const_iterator
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:258
std::string to_string(Flag_t< Storage > const flag)
Convert a flag into a stream (shows its index).
Definition: BitMask.h:187
TVector3 shower::EMShowerAlg::Construct3DPoint ( art::Ptr< recob::Hit > const &  hit1,
art::Ptr< recob::Hit > const &  hit2 
)
private

Constructs a 3D point (in [cm]) to represent the hits given in two views.

Definition at line 396 of file EMShowerAlg.cxx.

References detinfo::DetectorProperties::ConvertTicksToX(), fDetProp, fGeom, recob::Hit::PeakTime(), geo::WireID::planeID(), recob::Hit::WireID(), geo::GeometryCore::WireIDsIntersect(), x, geo::WireIDIntersection::y, and geo::WireIDIntersection::z.

Referenced by CheckShowerHits(), ConstructTrack(), and MakeSpacePoints().

396  {
397 
398  // x is average of the two x's
399  double x = (fDetProp->ConvertTicksToX(hit1->PeakTime(), hit1->WireID().planeID()) + fDetProp->ConvertTicksToX(hit2->PeakTime(), hit2->WireID().planeID())) / (double)2;
400 
401  // y and z got from the wire interections
402  geo::WireIDIntersection intersection;
403  fGeom->WireIDsIntersect(hit1->WireID(), hit2->WireID(), intersection);
404 
405  return TVector3(x, intersection.y, intersection.z);
406 
407 }
Float_t x
Definition: compare.C:6
PlaneID const & planeID() const
Definition: geo_types.h:355
double z
z position of intersection
Definition: geo_types.h:494
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
art::ServiceHandle< geo::Geometry > fGeom
Definition: EMShowerAlg.h:234
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
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:219
double y
y position of intersection
Definition: geo_types.h:493
detinfo::DetectorProperties const * fDetProp
Definition: EMShowerAlg.h:235
std::unique_ptr< recob::Track > shower::EMShowerAlg::ConstructTrack ( std::vector< art::Ptr< recob::Hit > > const &  track1,
std::vector< art::Ptr< recob::Hit > > const &  track2,
std::map< int, TVector2 > const &  showerCentreMap 
)

Constructs a recob::Track from sets of hits in two views. Intended to be used to construct the initial first part of a shower. All PMA methods taken from the pma tracking algorithm (R. Sulej and D. Stefan). This implementation also orients the track in the correct direction if a map of shower centres (units [cm]) in each view is provided.

Definition at line 409 of file EMShowerAlg.cxx.

References pma::ProjectionMatchingAlg::buildSegment(), Construct3DPoint(), recob::tracking::convertCollToPoint(), recob::tracking::convertCollToVector(), evd::details::end(), fDebug, fProjectionMatchingAlg, HitCoordinates(), if(), Project3DPointOntoPlane(), track, and lar::dump::vector().

Referenced by ConstructTrack(), and MakeInitialTrack().

411  {
412 
413  std::unique_ptr<recob::Track> track;
414 
415  std::vector<art::Ptr<recob::Hit> > track1, track2;
416 
417  // Check the TPCs
418  if ((*hits1.begin())->WireID().TPC != (*hits2.begin())->WireID().TPC) {
419  mf::LogWarning("EMShowerAlg") << "Warning: attempting to construct a track from two different TPCs. Returning a null track.";
420  return track;
421  }
422 
423  // Check for tracks crossing TPC boundaries
424  std::map<int,int> tpcMap;
425  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hitIt = hits1.begin(); hitIt != hits1.end(); ++hitIt)
426  ++tpcMap[(*hitIt)->WireID().TPC];
427  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hitIt = hits2.begin(); hitIt != hits2.end(); ++hitIt)
428  ++tpcMap[(*hitIt)->WireID().TPC];
429  if (tpcMap.size() > 1) {
430  mf::LogWarning("EMShowerAlg") << "Warning: attempting to construct a track which crosses more than one TPC -- PMTrack can't handle this right now. Returning a track made just from hits in the first TPC it traverses.";
431  unsigned int firstTPC1 = hits1.at(0)->WireID().TPC, firstTPC2 = hits2.at(0)->WireID().TPC;
432  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hitIt = hits1.begin(); hitIt != hits1.end(); ++hitIt)
433  if ((*hitIt)->WireID().TPC == firstTPC1) track1.push_back(*hitIt);
434  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hitIt = hits2.begin(); hitIt != hits2.end(); ++hitIt)
435  if ((*hitIt)->WireID().TPC == firstTPC2) track2.push_back(*hitIt);
436  }
437  else {
438  track1 = hits1;
439  track2 = hits2;
440  }
441 
442  if (fDebug > 1) {
443  std::cout << "About to make a track from these hits:" << std::endl;
444  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hit1 = track1.begin(); hit1 != track1.end(); ++hit1)
445  std::cout << "Hit (" << HitCoordinates(*hit1).X() << ", " << HitCoordinates(*hit1).Y() << ") (real wire " << (*hit1)->WireID().Wire << ") in TPC " << (*hit1)->WireID().TPC << std::endl;
446  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hit2 = track2.begin(); hit2 != track2.end(); ++hit2)
447  std::cout << "Hit (" << HitCoordinates(*hit2).X() << ", " << HitCoordinates(*hit2).Y() << ") (real wire " << (*hit2)->WireID().Wire << ") in TPC " << (*hit2)->WireID().TPC << std::endl;
448  }
449 
450  TVector3 trackStart = Construct3DPoint(track1.at(0), track2.at(0));
451  pma::Track3D* pmatrack = fProjectionMatchingAlg.buildSegment(track1, track2, trackStart);
452 
453  if (!pmatrack) {
454  mf::LogInfo("EMShowerAlg") << "Skipping this event because not enough hits in two views";
455  return track;
456  }
457 
458  std::vector<TVector3> xyz, dircos;
459  // std::vector<std::vector<double> > dEdx; // Right now, not finding the dE/dx for these tracks. Can extend if needed.
460 
461  for (unsigned int i = 0; i < pmatrack->size(); i++) {
462 
463  xyz.push_back((*pmatrack)[i]->Point3D());
464 
465  if (i < pmatrack->size()-1) {
466  size_t j = i+1;
467  double mag = 0.0;
468  TVector3 dc(0., 0., 0.);
469  while ((mag == 0.0) and (j < pmatrack->size())) {
470  dc = (*pmatrack)[j]->Point3D();
471  dc -= (*pmatrack)[i]->Point3D();
472  mag = dc.Mag();
473  ++j;
474  }
475  if (mag > 0.0) dc *= 1.0 / mag;
476  else if (!dircos.empty()) dc = dircos.back();
477  // TVector3 dc((*pmatrack)[i+1]->Point3D());
478  // dc -= (*pmatrack)[i]->Point3D();
479  // dc *= 1.0 / dc.Mag();
480  dircos.push_back(dc);
481  }
482  else dircos.push_back(dircos.back());
483 
484  }
485 
486  // Orient the track correctly
487  std::map<int,double> distanceToVertex, distanceToEnd;
488  TVector3 vertex = *xyz.begin(), end = *xyz.rbegin();
489 
490  // Loop over all the planes and find the distance from the vertex and end projections to the centre in each plane
491  for (std::map<int,TVector2>::const_iterator showerCentreIt = showerCentreMap.begin(); showerCentreIt != showerCentreMap.end(); ++showerCentreIt) {
492 
493  // Project the vertex and the end point onto this plane
494  TVector2 vertexProj = Project3DPointOntoPlane(vertex, showerCentreIt->first);
495  TVector2 endProj = Project3DPointOntoPlane(end, showerCentreIt->first);
496 
497  // Find the distance of each to the centre of the cluster
498  distanceToVertex[showerCentreIt->first] = (vertexProj - showerCentreIt->second).Mod();
499  distanceToEnd[showerCentreIt->first] = (endProj - showerCentreIt->second).Mod();
500 
501  }
502 
503  // Find the average distance to the vertex and the end across the planes
504  double avDistanceToVertex = 0, avDistanceToEnd = 0;
505  for (std::map<int,double>::iterator distanceToVertexIt = distanceToVertex.begin(); distanceToVertexIt != distanceToVertex.end(); ++distanceToVertexIt)
506  avDistanceToVertex += distanceToVertexIt->second;
507  avDistanceToVertex /= distanceToVertex.size();
508 
509  for (std::map<int,double>::iterator distanceToEndIt = distanceToEnd.begin(); distanceToEndIt != distanceToEnd.end(); ++distanceToEndIt)
510  avDistanceToEnd += distanceToEndIt->second;
511  if (distanceToEnd.size() != 0)
512  avDistanceToEnd /= distanceToEnd.size();
513 
514  if (fDebug > 2)
515  std::cout << "Distance to vertex is " << avDistanceToVertex << " and distance to end is " << avDistanceToEnd << std::endl;
516 
517  // Change order if necessary
518  if (avDistanceToEnd > avDistanceToVertex) {
519  std::reverse(xyz.begin(), xyz.end());
520  std::transform(dircos.begin(), dircos.end(), dircos.begin(), [](TVector3 const& vec){return -1*vec;});
521  }
522 
523  if (xyz.size() != dircos.size())
524  mf::LogError("EMShowerAlg") << "Problem converting pma::Track3D to recob::Track";
525 
526  track = std::make_unique<recob::Track>(recob::TrackTrajectory(recob::tracking::convertCollToPoint(xyz),
528  recob::Track::Flags_t(xyz.size()), false),
530 
531  return track;
532 
533 }
intermediate_table::iterator iterator
ROOT::Math::SMatrix< Double32_t, 5, 5, ROOT::Math::MatRepSym< Double32_t, 5 > > SMatrixSym55
Definition: TrackingTypes.h:85
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
std::vector< Vector_t > convertCollToVector(std::vector< Vector > const &coll)
Definition: TrackingTypes.h:58
TVector3 Construct3DPoint(art::Ptr< recob::Hit > const &hit1, art::Ptr< recob::Hit > const &hit2)
Constructs a 3D point (in [cm]) to represent the hits given in two views.
::fhicl::TupleAs< Point(::geo::Length_t,::geo::Length_t,::geo::Length_t)> Point3D
Atom object for reading a 3D point or vector (centimeters).
TVector2 Project3DPointOntoPlane(TVector3 const &point, int plane, int cryostat=0)
TrackTrajectory::Flags_t Flags_t
Definition: Track.h:71
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
if(nlines<=0)
intermediate_table::const_iterator const_iterator
A trajectory in space reconstructed from hits.
pma::Track3D * buildSegment(const std::vector< art::Ptr< recob::Hit > > &hits_1, const std::vector< art::Ptr< recob::Hit > > &hits_2=std::vector< art::Ptr< recob::Hit > >()) const
pma::ProjectionMatchingAlg fProjectionMatchingAlg
Definition: EMShowerAlg.h:241
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
Definition: TrackingTypes.h:55
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
TVector2 HitCoordinates(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in global wire/tick space.
Float_t track
Definition: plot.C:34
vertex reconstruction
std::unique_ptr< recob::Track > shower::EMShowerAlg::ConstructTrack ( std::vector< art::Ptr< recob::Hit > > const &  track1,
std::vector< art::Ptr< recob::Hit > > const &  track2 
)

Constructs a recob::Track from sets of hits in two views. Intended to be used to construct the initial first part of a shower. All methods taken from the pma tracking algorithm (R. Sulej and D. Stefan).

Definition at line 535 of file EMShowerAlg.cxx.

References ConstructTrack().

536  {
537 
538  std::map<int,TVector2> showerCentreMap;
539 
540  return this->ConstructTrack(track1, track2, showerCentreMap);
541 
542 }
std::unique_ptr< recob::Track > ConstructTrack(std::vector< art::Ptr< recob::Hit > > const &track1, std::vector< art::Ptr< recob::Hit > > const &track2, std::map< int, TVector2 > const &showerCentreMap)
double shower::EMShowerAlg::FinddEdx ( std::vector< art::Ptr< recob::Hit > > const &  trackHits,
std::unique_ptr< recob::Track > const &  track 
)
private

Finds dE/dx for the track given a set of hits.

Definition at line 544 of file EMShowerAlg.cxx.

References calo::CalorimetryAlg::dEdx_AREA(), fCalorimetryAlg, fdEdxTrackLength, lar::util::TrackPitchInView(), and lar::dump::vector().

Referenced by MakeShower().

544  {
545 
546  double totalCharge = 0, totalDistance = 0, avHitTime = 0;
547  unsigned int nHits = 0;
548 
549  if (!track)
550  return -999;
551 
552  // size_t trajectory_point = 0;
553  // double wirePitch = fGeom->WirePitch(trackHits.at(0)->View(), 1, 0);
554  // double angleToVert = fGeom->WireAngleToVertical(trackHits.at(0)->View(), 1, 0) - 0.5*::util::pi<>();
555  // const TVector3& dir = track->DirectionAtPoint(trajectory_point);
556  // //(sin(angleToVert),cos(angleToVert)) is the direction perpendicular to wire
557  // double cosgamma = std::abs(std::sin(angleToVert)*dir.Y() +
558  // std::cos(angleToVert)*dir.Z());
559 
560  // if(cosgamma < 1.e-5)
561  // throw cet::exception("Track") << "cosgamma is basically 0, that can't be right\n";
562  // double pitch = wirePitch/cosgamma;
563 
564  // Get the pitch
565  double pitch = 0;
566  try { pitch = lar::util::TrackPitchInView(*track, trackHits.at(0)->View()); }
567  catch(...) { pitch = 0; }
568 
569  // Deal with large pitches
570  if (pitch > fdEdxTrackLength) {
571  double dEdx = fCalorimetryAlg.dEdx_AREA(*trackHits.begin(), pitch);
572  return dEdx;
573  }
574 
575  for (std::vector<art::Ptr<recob::Hit> >::const_iterator trackHitIt = trackHits.begin(); trackHitIt != trackHits.end(); ++trackHitIt) {
576  if (totalDistance + pitch < fdEdxTrackLength) {
577  totalDistance += pitch;
578  totalCharge += (*trackHitIt)->Integral();
579  avHitTime += (*trackHitIt)->PeakTime();
580  ++nHits;
581  }
582  }
583 
584  avHitTime /= (double)nHits;
585 
586  double dQdx = totalCharge / totalDistance;
587  double dEdx = fCalorimetryAlg.dEdx_AREA(dQdx, avHitTime, trackHits.at(0)->WireID().Plane);
588 
589  return dEdx;
590 
591 }
double dEdx_AREA(art::Ptr< recob::Hit > hit, double pitch, double T0=0) const
calo::CalorimetryAlg fCalorimetryAlg
Definition: EMShowerAlg.h:240
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
double TrackPitchInView(recob::Track const &track, geo::View_t view, size_t trajectory_point=0)
Provides projected wire pitch for the view.
Definition: TrackUtils.cxx:76
void shower::EMShowerAlg::FindInitialTrack ( const std::map< int, std::vector< art::Ptr< recob::Hit > > > &  hits,
std::unique_ptr< recob::Track > &  initialTrack,
std::map< int, std::vector< art::Ptr< recob::Hit > > > &  initialTrackHits,
int  plane 
)

Finds the initial track-like part of the shower and the hits in all views associated with it.

Finding the initial track requires three stages: – put the hits in the correct order in each view – find the initial track-like hits in each view – use these to construct a track

Definition at line 593 of file EMShowerAlg.cxx.

References fDebug, FindShowerStart(), HitCoordinates(), MakeInitialTrack(), lar::dump::vector(), recob::Track::Vertex(), and recob::Track::VertexDirection().

Referenced by shower::EMShower::produce().

595  {
596 
601 
602  // // First, order the hits into the correct shower order in each plane
603  // if (fDebug > 1)
604  // std::cout << " ------------------ Ordering shower hits -------------------- " << std::endl;
605  // std::map<int,std::vector<art::Ptr<recob::Hit> > > showerHitsMap = OrderShowerHits(hits, plane);
606  // if (fDebug > 1)
607  // std::cout << " ------------------ End ordering shower hits -------------------- " << std::endl;
608 
609  // Now find the hits belonging to the track
610  if (fDebug > 1)
611  std::cout << " ------------------ Finding initial track hits -------------------- " << std::endl;
612  initialTrackHits = FindShowerStart(showerHitsMap);
613  if (fDebug > 1) {
614  std::cout << "Here are the initial shower hits... " << std::endl;
615  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator initialTrackHitsIt = initialTrackHits.begin(); initialTrackHitsIt != initialTrackHits.end(); ++initialTrackHitsIt) {
616  std::cout << " Plane " << initialTrackHitsIt->first << std::endl;
617  for (std::vector<art::Ptr<recob::Hit> >::iterator initialTrackHitIt = initialTrackHitsIt->second.begin(); initialTrackHitIt != initialTrackHitsIt->second.end(); ++initialTrackHitIt)
618  std::cout << " Hit is (" << HitCoordinates(*initialTrackHitIt).X() << " (real hit " << (*initialTrackHitIt)->WireID() << "), " << HitCoordinates(*initialTrackHitIt).Y() << ")" << std::endl;
619  }
620  }
621  if (fDebug > 1)
622  std::cout << " ------------------ End finding initial track hits -------------------- " << std::endl;
623 
624  // Now we have the track hits -- can make a track!
625  if (fDebug > 1)
626  std::cout << " ------------------ Finding initial track -------------------- " << std::endl;
627  initialTrack = MakeInitialTrack(initialTrackHits, showerHitsMap);
628  if (initialTrack and fDebug > 1) {
629  std::cout << "The track start is (" << initialTrack->Vertex().X() << ", " << initialTrack->Vertex().Y() << ", " << initialTrack->Vertex().Z() << ")" << std::endl;
630  std::cout << "The track direction is (" << initialTrack->VertexDirection().X() << ", " << initialTrack->VertexDirection().Y() << ", " << initialTrack->VertexDirection().Z() << ")" << std::endl;
631  }
632  if (fDebug > 1)
633  std::cout << " ------------------ End finding initial track -------------------- " << std::endl;
634 
635  // // Fill correct or incorrect direction histogram
636  // std::map<int,int> trackHits;
637  // for (art::PtrVector<recob::Hit>::const_iterator hitIt = hits.begin(); hitIt != hits.end(); ++hitIt)
638  // ++trackHits[FindTrackID(*hitIt)];
639  // int trueTrack = -9999;
640  // for (std::map<int,int>::iterator trackHitIt = trackHits.begin(); trackHitIt != trackHits.end(); ++trackHitIt)
641  // if (trackHitIt->second/(double)hits.size() > 0.8)
642  // trueTrack = trackHitIt->first;
643  // if (trueTrack != -9999) {
644  // const simb::MCParticle* trueParticle = backtracker->TrackIDToParticle(trueTrack);
645  // TVector3 trueStart = trueParticle->Position().Vect();
646  // if (initialTrack) {
647  // TVector3 recoStart = initialTrack->Vertex();
648  // if ((recoStart-trueStart).Mag() < 5)
649  // hTrueDirection->Fill(1);
650  // else
651  // hTrueDirection->Fill(0);
652  // }
653  // }
654  // else
655  // hTrueDirection->Fill(0);
656 
657  return;
658 
659 }
std::map< int, std::vector< art::Ptr< recob::Hit > > > FindShowerStart(std::map< int, std::vector< art::Ptr< recob::Hit > > > const &orderedShowerMap)
Vector_t VertexDirection() const
Access to track direction at different points.
Definition: Track.h:135
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
std::unique_ptr< recob::Track > MakeInitialTrack(std::map< int, std::vector< art::Ptr< recob::Hit > > > const &initialHitsMap, std::map< int, std::vector< art::Ptr< recob::Hit > > > const &showerHitsMap)
Takes initial track hits from multiple views and forms a track object which best represents the start...
Point_t const & Vertex() const
Access to track position at different points.
Definition: Track.h:127
TVector2 HitCoordinates(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in global wire/tick space.
void shower::EMShowerAlg::FindInitialTrackHits ( std::vector< art::Ptr< recob::Hit > >const &  showerHits,
art::Ptr< recob::Vertex > const &  vertex,
std::vector< art::Ptr< recob::Hit > > &  trackHits 
)

<Tingjun to="" document>="">

Definition at line 1542 of file EMShowerAlg.cxx.

References geo::vect::coord(), fGeom, geo::GeometryCore::FindTPCAtPosition(), fNfithits, fNfitpass, fToler, HitCoordinates(), geo::CryostatID::isValid, geo::TPCID::TPC, WeightedFit(), and recob::Vertex::XYZ().

Referenced by MakeShower().

1544  {
1545 
1546  // Find TPC for the vertex
1547  //std::cout<<"here"<<std::endl;
1548  double xyz[3];
1549  vertex->XYZ(xyz);
1550  //std::cout<<xyz[0]<<" "<<xyz[1]<<" "<<xyz[2]<<std::endl;
1551  geo::TPCID tpc = fGeom->FindTPCAtPosition(xyz);
1552  //std::cout<<tpc<<std::endl;
1553  //vertex cannot be projected into a TPC, find the TPC that has the most hits
1554  if (!tpc.isValid){
1555  std::map<geo::TPCID, unsigned int> tpcmap;
1556  unsigned maxhits = 0;
1557  for (auto const&hit : showerHits){
1558  ++tpcmap[geo::TPCID(hit->WireID())];
1559  }
1560  for (auto const&t : tpcmap){
1561  if (t.second > maxhits){
1562  maxhits = t.second;
1563  tpc = t.first;
1564  }
1565  }
1566  }
1567  //std::cout<<tpc<<std::endl;
1568  //if (!tpc.isValid&&showerHits.size()) tpc = geo::TPCID(showerHits[0]->WireID());
1569  if (!tpc.isValid) return;
1570  //std::cout<<"here 1"<<std::endl;
1571 
1572  double parm[2];
1573  int fitok = 0;
1574  std::vector<double> wfit;
1575  std::vector<double> tfit;
1576  std::vector<double> cfit;
1577 
1578  for (size_t i = 0; i<fNfitpass; ++i){
1579 
1580  // Fit a straight line through hits
1581  unsigned int nhits = 0;
1582  for (auto &hit: showerHits){
1583  //std::cout<<i<<" "<<hit->WireID()<<" "<<tpc<<std::endl;
1584  if (hit->WireID().TPC==tpc.TPC){
1585  TVector2 coord = HitCoordinates(hit);
1586  //std::cout<<i<<" "<<hit->WireID()<<" "<<hit->PeakTime()<<std::endl;
1587  if (i==0||(std::abs((coord.Y()-(parm[0]+coord.X()*parm[1]))*cos(atan(parm[1])))<fToler[i-1])||fitok==1){
1588  ++nhits;
1589  if (nhits==fNfithits[i]+1) break;
1590  wfit.push_back(coord.X());
1591  tfit.push_back(coord.Y());
1592  //cfit.push_back(hit->Integral());
1593  cfit.push_back(1.);
1594  if (i==fNfitpass-1) {
1595  trackHits.push_back(hit);
1596  }
1597  //std::cout<<*hit<<std::endl;
1598 //
1599 //<<hit->PeakTime()<<" "<<std::abs((coord.Y()-(parm[0]+coord.X()*parm[1]))*cos(atan(parm[1])))<<std::endl;
1600  }
1601  }
1602  }
1603 
1604  if (i<fNfitpass-1&&wfit.size()){
1605  fitok = WeightedFit(wfit.size(), &wfit[0], &tfit[0], &cfit[0], &parm[0]);
1606  }
1607  wfit.clear();
1608  tfit.clear();
1609  cfit.clear();
1610  }
1611 
1612 }
void XYZ(double *xyz) const
Legacy method to access vertex position, preserved to avoid breaking code. Please try to use Vertex::...
Definition: Vertex.cxx:37
std::vector< double > fToler
Definition: EMShowerAlg.h:231
Int_t WeightedFit(const Int_t n, const Double_t *x, const Double_t *y, const Double_t *w, Double_t *parm)
<Tingjun to="" document>="">
auto coord(Vector &v, unsigned int n) noexcept
Returns an object to manage the coordinate n of a vector.
bool isValid
Whether this ID points to a valid element.
Definition: geo_types.h:129
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
unsigned int fNfitpass
Definition: EMShowerAlg.h:229
The data type to uniquely identify a TPC.
Definition: geo_types.h:195
art::ServiceHandle< geo::Geometry > fGeom
Definition: EMShowerAlg.h:234
Detector simulation of raw signals on wires.
TVector2 HitCoordinates(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in global wire/tick space.
std::vector< unsigned int > fNfithits
Definition: EMShowerAlg.h:230
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:203
std::vector< art::Ptr< recob::Hit > > shower::EMShowerAlg::FindOrderOfHits ( std::vector< art::Ptr< recob::Hit > > const &  hits,
bool  perpendicular = false 
)
private

Orders hits along the best fit line through the charge-weighted centre of the hits. Orders along the line perpendicular to the least squares line if perpendicular is set to true.

Definition at line 661 of file EMShowerAlg.cxx.

References fMakeGradientPlot, HitPosition(), hits(), ShowerCentre(), ShowerDirection(), and lar::dump::vector().

Referenced by OrderShowerHits().

661  {
662 
663  // Find the charge-weighted centre (in [cm]) of this shower
664  TVector2 centre = ShowerCentre(hits);
665 
666  // Find a rough shower 'direction'
667  TVector2 direction = ShowerDirection(hits);
668 
669  if (perpendicular)
670  direction = direction.Rotate(TMath::Pi()/2);
671 
672  // Find how far each hit (projected onto this axis) is from the centre
673  TVector2 pos;
674  std::map<double,art::Ptr<recob::Hit> > hitProjection;
675  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hit = hits.begin(); hit != hits.end(); ++hit) {
676  pos = HitPosition(*hit) - centre;
677  hitProjection[direction*pos] = *hit;
678  }
679 
680  // Get a vector of hits in order of the shower
681  std::vector<art::Ptr<recob::Hit> > showerHits;
682  std::transform(hitProjection.begin(), hitProjection.end(), std::back_inserter(showerHits), [](std::pair<double,art::Ptr<recob::Hit> > const& hit) { return hit.second; });
683 
684  // Make gradient plot
685  if (fMakeGradientPlot) {
686  std::map<int,TGraph*> graphs;
687  for (std::vector<art::Ptr<recob::Hit> >::iterator hitIt = showerHits.begin(); hitIt != showerHits.end(); ++hitIt) {
688  int tpc = (*hitIt)->WireID().TPC;
689  if (graphs[tpc] == nullptr)
690  graphs[tpc] = new TGraph();
691  graphs[tpc]->SetPoint(graphs[tpc]->GetN(), HitPosition(*hitIt).X(), HitPosition(*hitIt).Y());
692  //graphs[tpc]->SetPoint(graphs[tpc]->GetN(), HitCoordinates(*hitIt).X(), HitCoordinates(*hitIt).Y());
693  }
694  TMultiGraph* multigraph = new TMultiGraph();
695  for (std::map<int,TGraph*>::iterator graphIt = graphs.begin(); graphIt != graphs.end(); ++graphIt) {
696  graphIt->second->SetMarkerColor(graphIt->first);
697  graphIt->second->SetMarkerStyle(8);
698  graphIt->second->SetMarkerSize(2);
699  multigraph->Add(graphIt->second);
700  }
701  TCanvas* canvas = new TCanvas();
702  multigraph->Draw("AP");
703  TLine line;
704  line.SetLineColor(2);
705  line.DrawLine(centre.X()-1000*direction.X(),centre.Y()-1000*direction.Y(),centre.X()+1000*direction.X(),centre.Y()+1000*direction.Y());
706  canvas->SaveAs("Gradient.png");
707  delete canvas; delete multigraph;
708  }
709 
710  return showerHits;
711 
712 }
intermediate_table::iterator iterator
TVector2 HitPosition(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in units of cm.
TVector2 ShowerDirection(const std::vector< art::Ptr< recob::Hit > > &showerHits)
Returns a rough charge-weighted shower &#39;direction&#39; given the hits in the shower.
TVector2 ShowerCentre(const std::vector< art::Ptr< recob::Hit > > &showerHits)
Returns the charge-weighted shower centre.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
Detector simulation of raw signals on wires.
int shower::EMShowerAlg::FindParticleID ( const art::Ptr< recob::Hit > &  hit)
private

Returns the true track ID associated with this hit (if more than one, returns the one with highest energy)

Definition at line 2330 of file EMShowerAlg.cxx.

2330  {
2331 
2333 
2334  double particleEnergy = 0;
2335  int likelyTrackID = 0;
2336  std::vector<sim::TrackIDE> trackIDs = bt_serv->HitToTrackIDEs(hit);
2337  for (unsigned int idIt = 0; idIt < trackIDs.size(); ++idIt) {
2338  if (trackIDs.at(idIt).energy > particleEnergy) {
2339  particleEnergy = trackIDs.at(idIt).energy;
2340  likelyTrackID = TMath::Abs(trackIDs.at(idIt).trackID);
2341  }
2342  }
2343 
2344  return likelyTrackID;
2345 
2346 }
art::ServiceHandle< cheat::BackTrackerService > bt_serv
Definition: EMShowerAlg.h:249
const std::vector< sim::TrackIDE > HitToTrackIDEs(recob::Hit const &hit)
std::vector< std::vector< int > > shower::EMShowerAlg::FindShowers ( std::map< int, std::vector< int > > const &  trackToClusters)

Makes showers given a map between tracks and all clusters associated with them.

Definition at line 714 of file EMShowerAlg.cxx.

References evd::details::begin(), and evd::details::end().

Referenced by shower::EMShower::produce().

714  {
715 
716  // Showers are vectors of clusters
717  std::vector<std::vector<int> > showers;
718 
719  // Loop over all tracks
720  for (std::map<int,std::vector<int> >::const_iterator trackToClusterIt = trackToClusters.begin(); trackToClusterIt != trackToClusters.end(); ++ trackToClusterIt) {
721 
722  // Find which showers already made are associated with this track
723  std::vector<int> matchingShowers;
724  for (unsigned int shower = 0; shower < showers.size(); ++shower)
725  for (std::vector<int>::const_iterator cluster = trackToClusterIt->second.begin(); cluster != trackToClusterIt->second.end(); ++cluster)
726  if ( (std::find(showers.at(shower).begin(), showers.at(shower).end(), *cluster) != showers.at(shower).end()) and
727  (std::find(matchingShowers.begin(), matchingShowers.end(), shower)) == matchingShowers.end() )
728  matchingShowers.push_back(shower);
729 
730  // THINK THERE PROBABLY CAN BE MORE THAN ONE!
731  // IN FACT, THIS WOULD BE A SUCCESS OF THE SHOWERING METHOD!
732  // // Shouldn't be more than one
733  // if (matchingShowers.size() > 1)
734  // mf::LogInfo("EMShowerAlg") << "Number of showers this track matches is " << matchingShowers.size() << std::endl;
735 
736  // New shower
737  if (matchingShowers.size() < 1)
738  showers.push_back(trackToClusterIt->second);
739 
740  // Add to existing shower
741  else {
742  for (std::vector<int>::const_iterator cluster = trackToClusterIt->second.begin(); cluster != trackToClusterIt->second.end(); ++cluster)
743  if (std::find(showers.at(matchingShowers.at(0)).begin(), showers.at(matchingShowers.at(0)).end(), *cluster) == showers.at(matchingShowers.at(0)).end())
744  showers.at(matchingShowers.at(0)).push_back(*cluster);
745  }
746  }
747 
748  return showers;
749 
750 }
Cluster finding and building.
intermediate_table::const_iterator const_iterator
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
std::map< int, std::vector< art::Ptr< recob::Hit > > > shower::EMShowerAlg::FindShowerStart ( std::map< int, std::vector< art::Ptr< recob::Hit > > > const &  orderedShowerMap)
private

Takes a map of the shower hits on each plane (ordered from what has been decided to be the start) Returns a map of the initial track-like part of the shower on each plane

Definition at line 752 of file EMShowerAlg.cxx.

References fDebug, HitCoordinates(), lar::dump::vector(), X, and Y.

Referenced by FindInitialTrack().

752  {
753 
754  std::map<int,std::vector<art::Ptr<recob::Hit> > > initialHitsMap;
755 
756  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator orderedShowerIt = orderedShowerMap.begin(); orderedShowerIt != orderedShowerMap.end(); ++orderedShowerIt) {
757 
758  std::vector<art::Ptr<recob::Hit> > initialHits;
759  const std::vector<art::Ptr<recob::Hit> > orderedShower = orderedShowerIt->second;
760 
761  // Find if the shower is travelling along ticks or wires
762  bool wireDirection = true;
763  std::vector<int> wires;
764  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hitIt = orderedShower.begin(); hitIt != orderedShower.end(); ++hitIt)
765  wires.push_back(std::round(HitCoordinates(*hitIt).X()));
766  std::sort(wires.begin(), wires.end());
767  if (TMath::Abs(*wires.begin()-std::round(HitCoordinates(*orderedShower.begin()).X())) > 3 and
768  TMath::Abs(*wires.rbegin()-std::round(HitCoordinates(*orderedShower.begin()).X())) > 3)
769  wireDirection = false;
770 
771  // Deal with showers travelling along wires
772  if (wireDirection) {
773  bool increasing = HitCoordinates(*orderedShower.rbegin()).X() > HitCoordinates(*orderedShower.begin()).X();
774  std::map<int,std::vector<art::Ptr<recob::Hit> > > wireHitMap;
775  int multipleWires = 0;
776  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hitIt = orderedShower.begin(); hitIt != orderedShower.end(); ++hitIt)
777  wireHitMap[std::round(HitCoordinates(*hitIt).X())].push_back(*hitIt);
778  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hitIt = orderedShower.begin(); hitIt != orderedShower.end(); ++hitIt) {
779  int wire = std::round(HitCoordinates(*hitIt).X());
780  if (wireHitMap[wire].size() > 1) {
781  ++multipleWires;
782  if (multipleWires > 5) break;
783  continue;
784  }
785  else if ( (increasing and wireHitMap[wire+1].size() > 1 and (wireHitMap[wire+2].size() > 1 or wireHitMap[wire+3].size() > 1)) or
786  (!increasing and wireHitMap[wire-1].size() > 1 and (wireHitMap[wire-2].size() > 1 or wireHitMap[wire-3].size() > 1)) ) {
787  if ( (increasing and (wireHitMap[wire+4].size() < 2 and wireHitMap[wire+5].size() < 2 and wireHitMap[wire+6].size() < 2 and wireHitMap[wire+9].size() > 1)) or
788  (!increasing and (wireHitMap[wire-4].size() < 2 and wireHitMap[wire-5].size() < 2 and wireHitMap[wire-6].size() < 2) and wireHitMap[wire-9].size() > 1) )
789  initialHits.push_back(*hitIt);
790  else
791  break;
792  }
793  else
794  initialHits.push_back(*hitIt);
795  }
796  if (!initialHits.size()) initialHits.push_back(*orderedShower.begin());
797  }
798 
799  // Deal with showers travelling along ticks
800  else {
801  bool increasing = HitCoordinates(*orderedShower.rbegin()).Y() > HitCoordinates(*orderedShower.begin()).Y();
802  std::map<int,std::vector<art::Ptr<recob::Hit> > > tickHitMap;
803  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hitIt = orderedShower.begin(); hitIt != orderedShower.end(); ++hitIt)
804  tickHitMap[std::round(HitCoordinates(*hitIt).Y())].push_back(*hitIt);
805  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hitIt = orderedShower.begin(); hitIt != orderedShower.end(); ++hitIt) {
806  int tick = std::round(HitCoordinates(*hitIt).Y());
807  if ( (increasing and (tickHitMap[tick+1].size() or tickHitMap[tick+2].size() or tickHitMap[tick+3].size() or tickHitMap[tick+4].size() or tickHitMap[tick+5].size())) or
808  (!increasing and (tickHitMap[tick-1].size() or tickHitMap[tick-2].size() or tickHitMap[tick-3].size() or tickHitMap[tick-4].size() or tickHitMap[tick-5].size())) )
809  break;
810  else
811  initialHits.push_back(*hitIt);
812  }
813  if (!initialHits.size()) initialHits.push_back(*orderedShower.begin());
814  }
815 
816  // Need at least two hits to make a track
817  if (initialHits.size() == 1 and orderedShower.size() > 2)
818  initialHits.push_back(orderedShower.at(1));
819 
820  // Quality check -- make sure there isn't a single hit in a different TPC (artefact of tracking failure)
821  std::vector<art::Ptr<recob::Hit> > newInitialHits;
822  std::map<int,int> tpcHitMap;
823  std::vector<int> singleHitTPCs;
824  for (std::vector<art::Ptr<recob::Hit> >::iterator initialHitIt = initialHits.begin(); initialHitIt != initialHits.end(); ++initialHitIt)
825  ++tpcHitMap[(*initialHitIt)->WireID().TPC];
826  for (std::map<int,int>::iterator tpcIt = tpcHitMap.begin(); tpcIt != tpcHitMap.end(); ++tpcIt)
827  if (tpcIt->second == 1) singleHitTPCs.push_back(tpcIt->first);
828  if (singleHitTPCs.size()) {
829  if (fDebug > 2)
830  for (std::vector<int>::iterator tpcIt = singleHitTPCs.begin(); tpcIt != singleHitTPCs.end(); ++tpcIt)
831  std::cout << "Removed hits in TPC " << *tpcIt << std::endl;
832  for (std::vector<art::Ptr<recob::Hit> >::iterator initialHitIt = initialHits.begin(); initialHitIt != initialHits.end(); ++initialHitIt)
833  if (std::find(singleHitTPCs.begin(), singleHitTPCs.end(), (*initialHitIt)->WireID().TPC) == singleHitTPCs.end())
834  newInitialHits.push_back(*initialHitIt);
835  if (!newInitialHits.size()) newInitialHits.push_back(*orderedShower.begin());
836  }
837  else
838  newInitialHits = initialHits;
839 
840  initialHitsMap[orderedShowerIt->first] = newInitialHits;
841 
842  }
843 
844  return initialHitsMap;
845 
846 }
intermediate_table::iterator iterator
Float_t Y
Definition: plot.C:39
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
TVector2 HitCoordinates(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in global wire/tick space.
Float_t X
Definition: plot.C:39
int shower::EMShowerAlg::FindTrueParticle ( const std::vector< art::Ptr< recob::Hit > > &  showerHits)
private

Returns the true particle most likely associated with this shower

Definition at line 2304 of file EMShowerAlg.cxx.

References recob::Hit::Integral(), and lar::dump::vector().

2304  {
2305 
2307 
2308  // Make a map of the tracks which are associated with this shower and the charge each contributes
2309  std::map<int,double> trackMap;
2310  for (std::vector<art::Ptr<recob::Hit> >::const_iterator showerHitIt = showerHits.begin(); showerHitIt != showerHits.end(); ++showerHitIt) {
2311  art::Ptr<recob::Hit> hit = *showerHitIt;
2312  int trackID = FindParticleID(hit);
2313  trackMap[trackID] += hit->Integral();
2314  }
2315 
2316  // Pick the track with the highest charge as the 'true track'
2317  double highestCharge = 0;
2318  int showerTrack = 0;
2319  for (std::map<int,double>::iterator trackIt = trackMap.begin(); trackIt != trackMap.end(); ++trackIt) {
2320  if (trackIt->second > highestCharge) {
2321  highestCharge = trackIt->second;
2322  showerTrack = trackIt->first;
2323  }
2324  }
2325 
2326  return showerTrack;
2327 
2328 }
intermediate_table::iterator iterator
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:225
int FindParticleID(const art::Ptr< recob::Hit > &hit)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
Detector simulation of raw signals on wires.
std::map< int, std::map< int, bool > > shower::EMShowerAlg::GetPlanePermutations ( const std::map< int, std::vector< art::Ptr< recob::Hit > > > &  showerHitsMap)
private

Takes all the shower hits, ready ordered, and returns information to help with the orientation of the shower in each view Returns map of most likely permutations of reorientation Starts at 0,0,0 (i.e. don't need to reorient any plane) and ends with 1,1,1 (i.e. every plane needs reorienting) Every permutation inbetween represent increasing less likely changes to satisfy the correct orientation criteria

Definition at line 848 of file EMShowerAlg.cxx.

References fDebug, for(), if(), RelativeWireWidth(), ShowerHitRMS(), ShowerHitRMSGradient(), and lar::dump::vector().

Referenced by OrderShowerHits().

848  {
849 
850  // The map to return
851  std::map<int,std::map<int,bool> > permutations;
852 
853  // Get the properties of the shower hits across the planes which will be used to
854  // determine the likelihood of a particular reorientation permutation
855  // -- relative width in the wire direction (if showers travel along the wire
856  // direction in a particular plane)
857  // -- the RMS gradients (how likely it is the RMS of the hit positions from
858  // central axis increases along a particular orientation)
859 
860  // Find the RMS, RMS gradient and wire widths
861  std::map<int,double> planeRMSGradients, planeRMS;
862  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt) {
863  planeRMS[showerHitsIt->first] = ShowerHitRMS(showerHitsIt->second);
864  planeRMSGradients[showerHitsIt->first] = ShowerHitRMSGradient(showerHitsIt->second);
865  }
866 
867  // Order these backwards so they can be used to discriminate between planes
868  std::map<double,int> gradientMap;
869  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt)
870  gradientMap[TMath::Abs(planeRMSGradients.at(showerHitsIt->first))] = showerHitsIt->first;
871 
872  std::map<double,int> wireWidthMap = RelativeWireWidth(showerHitsMap);
873 
874  if (fDebug > 1)
875  for (std::map<double,int>::const_iterator wireWidthIt = wireWidthMap.begin(); wireWidthIt != wireWidthMap.end(); ++wireWidthIt)
876  std::cout << "Plane " << wireWidthIt->second << " has relative width in wire of " << wireWidthIt->first << "; and an RMS gradient of " << planeRMSGradients[wireWidthIt->second] << std::endl;
877 
878  // Find the correct permutations
879  int perm = 0;
880  std::vector<std::map<int,bool> > usedPermutations;
881 
882  // Most likely is to not change anything
883  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt)
884  permutations[perm][showerHitsIt->first] = 0;
885  ++perm;
886 
887  // Use properties of the shower to determine the middle cases
888  for (std::map<double,int>::iterator wireWidthIt = wireWidthMap.begin(); wireWidthIt != wireWidthMap.end(); ++wireWidthIt) {
889  std::map<int,bool> permutation;
890  permutation[wireWidthIt->second] = 1;
891  for (std::map<double,int>::iterator wireWidth2It = wireWidthMap.begin(); wireWidth2It != wireWidthMap.end(); ++wireWidth2It)
892  if (wireWidthIt->second != wireWidth2It->second)
893  permutation[wireWidth2It->second] = 0;
894  if (std::find(usedPermutations.begin(), usedPermutations.end(), permutation) == usedPermutations.end()) {
895  permutations[perm] = permutation;
896  usedPermutations.push_back(permutation);
897  ++perm;
898  }
899  }
900  for (std::map<double,int>::reverse_iterator wireWidthIt = wireWidthMap.rbegin(); wireWidthIt != wireWidthMap.rend(); ++wireWidthIt) {
901  std::map<int,bool> permutation;
902  permutation[wireWidthIt->second] = 0;
903  for (std::map<double,int>::iterator wireWidth2It = wireWidthMap.begin(); wireWidth2It != wireWidthMap.end(); ++wireWidth2It)
904  if (wireWidthIt->second != wireWidth2It->second)
905  permutation[wireWidth2It->second] = 1;
906  if (std::find(usedPermutations.begin(), usedPermutations.end(), permutation) == usedPermutations.end()) {
907  permutations[perm] = permutation;
908  usedPermutations.push_back(permutation);
909  ++perm;
910  }
911  }
912 
913  // Least likely is to change everything
914  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt)
915  permutations[perm][showerHitsIt->first] = 1;
916  ++perm;
917 
918  if (fDebug > 1) {
919  std::cout << "Here are the permutations!" << std::endl;
920  for (std::map<int,std::map<int,bool> >::iterator permIt = permutations.begin(); permIt != permutations.end(); ++permIt) {
921  std::cout << "Permutation " << permIt->first << std::endl;
922  for (std::map<int,bool>::iterator planePermIt = permIt->second.begin(); planePermIt != permIt->second.end(); ++planePermIt)
923  std::cout << " Plane " << planePermIt->first << " has value " << planePermIt->second << std::endl;
924  }
925  }
926 
927  return permutations;
928 
929 }
intermediate_table::iterator iterator
for(int i=0;i< 401;i++)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
if(nlines<=0)
intermediate_table::const_iterator const_iterator
double ShowerHitRMS(const std::vector< art::Ptr< recob::Hit > > &showerHits)
Returns the RMS of the hits from the central shower &#39;axis&#39; along the length of the shower...
double ShowerHitRMSGradient(const std::vector< art::Ptr< recob::Hit > > &showerHits, TVector2 trueStart=TVector2(0, 0))
Returns the gradient of the RMS vs shower segment graph.
std::map< double, int > RelativeWireWidth(const std::map< int, std::vector< art::Ptr< recob::Hit > > > &showerHitsMap)
double shower::EMShowerAlg::GlobalWire ( const geo::WireID wireID)
private

Find the global wire position.

Definition at line 1636 of file EMShowerAlg.cxx.

References geo::CryostatID::Cryostat, fDetector, fGeom, geo::WireGeo::GetCenter(), geo::kInduction, geo::GeometryCore::Nwires(), geo::PlaneID::Plane, geo::GeometryCore::SignalType(), geo::TPCID::TPC, geo::WireID::Wire, geo::GeometryCore::WireCoordinate(), and geo::GeometryCore::WireIDToWireGeo().

Referenced by HitCoordinates(), and Project3DPointOntoPlane().

1636  {
1637 
1638  double globalWire = -999;
1639 
1640  // Induction
1641  if (fGeom->SignalType(wireID) == geo::kInduction) {
1642  double wireCentre[3];
1643  fGeom->WireIDToWireGeo(wireID).GetCenter(wireCentre);
1644  if (wireID.TPC % 2 == 0) globalWire = fGeom->WireCoordinate(wireCentre[1], wireCentre[2], wireID.Plane, 0, wireID.Cryostat);
1645  else globalWire = fGeom->WireCoordinate(wireCentre[1], wireCentre[2], wireID.Plane, 1, wireID.Cryostat);
1646  }
1647 
1648  // Collection
1649  else {
1650  // FOR COLLECTION WIRES, HARD CODE THE GEOMETRY FOR GIVEN DETECTORS
1651  // THIS _SHOULD_ BE TEMPORARY. GLOBAL WIRE SUPPORT IS BEING ADDED TO THE LARSOFT GEOMETRY AND SHOULD BE AVAILABLE SOON
1652  if (fDetector == "dune35t") {
1653  unsigned int nwires = fGeom->Nwires(wireID.Plane, 0, wireID.Cryostat);
1654  if (wireID.TPC == 0 or wireID.TPC == 1) globalWire = wireID.Wire;
1655  else if (wireID.TPC == 2 or wireID.TPC == 3 or wireID.TPC == 4 or wireID.TPC == 5) globalWire = nwires + wireID.Wire;
1656  else if (wireID.TPC == 6 or wireID.TPC == 7) globalWire = (2*nwires) + wireID.Wire;
1657  else mf::LogError("BlurredClusterAlg") << "Error when trying to find a global induction plane coordinate for TPC " << wireID.TPC << " (geometry" << fDetector << ")";
1658  }
1659  else if (fDetector == "dune10kt") {
1660  unsigned int nwires = fGeom->Nwires(wireID.Plane, 0, wireID.Cryostat);
1661  // Detector geometry has four TPCs, two on top of each other, repeated along z...
1662  int block = wireID.TPC / 4;
1663  globalWire = (nwires*block) + wireID.Wire;
1664  }
1665  else {
1666  double wireCentre[3];
1667  fGeom->WireIDToWireGeo(wireID).GetCenter(wireCentre);
1668  if (wireID.TPC % 2 == 0) globalWire = fGeom->WireCoordinate(wireCentre[1], wireCentre[2], wireID.Plane, 0, wireID.Cryostat);
1669  else globalWire = fGeom->WireCoordinate(wireCentre[1], wireCentre[2], wireID.Plane, 1, wireID.Cryostat);
1670  }
1671  }
1672 
1673  return globalWire;
1674 
1675 }
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:130
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:313
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
unsigned int Nwires(unsigned int p, unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wires in the specified plane.
Signal from induction planes.
Definition: geo_types.h:92
std::string fDetector
Definition: EMShowerAlg.h:243
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:258
art::ServiceHandle< geo::Geometry > fGeom
Definition: EMShowerAlg.h:234
void GetCenter(double *xyz, double localz=0.0) const
Fills the world coordinate of a point on the wire.
Definition: WireGeo.cxx:68
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:203
WireGeo const & WireIDToWireGeo(geo::WireID const &wireid) const
Returns the specified wire.
TVector2 shower::EMShowerAlg::HitCoordinates ( art::Ptr< recob::Hit > const &  hit)
private

Return the coordinates of this hit in global wire/tick space.

Definition at line 1615 of file EMShowerAlg.cxx.

References GlobalWire(), recob::Hit::PeakTime(), and recob::Hit::WireID().

Referenced by ConstructTrack(), FindInitialTrack(), FindInitialTrackHits(), FindShowerStart(), HitPosition(), OrderShowerHits(), RelativeWireWidth(), and WorstPlane().

1615  {
1616 
1617  return TVector2(GlobalWire(hit->WireID()), hit->PeakTime());
1618 
1619 }
double GlobalWire(const geo::WireID &wireID)
Find the global wire position.
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:219
TVector2 shower::EMShowerAlg::HitPosition ( art::Ptr< recob::Hit > const &  hit)
private

Return the coordinates of this hit in units of cm.

Definition at line 1621 of file EMShowerAlg.cxx.

References HitCoordinates(), geo::WireID::planeID(), and recob::Hit::WireID().

Referenced by CheckShowerHits(), FindOrderOfHits(), MakeSpacePoints(), OrderShowerHits(), Project3DPointOntoPlane(), ShowerCentre(), ShowerDirection(), ShowerHitRMS(), and ShowerHitRMSGradient().

1621  {
1622 
1623  geo::PlaneID planeID = hit->WireID().planeID();
1624 
1625  return HitPosition(HitCoordinates(hit), planeID);
1626 
1627 }
PlaneID const & planeID() const
Definition: geo_types.h:355
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
The data type to uniquely identify a Plane.
Definition: geo_types.h:250
TVector2 HitPosition(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in units of cm.
TVector2 HitCoordinates(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in global wire/tick space.
TVector2 shower::EMShowerAlg::HitPosition ( TVector2 const &  pos,
geo::PlaneID  planeID 
)
private

Return the coordinates of this hit in units of cm.

Definition at line 1629 of file EMShowerAlg.cxx.

References detinfo::DetectorProperties::ConvertTicksToX(), fDetProp, fGeom, and geo::GeometryCore::WirePitch().

1629  {
1630 
1631  return TVector2(pos.X() * fGeom->WirePitch(planeID),
1632  fDetProp->ConvertTicksToX(pos.Y(), planeID));
1633 
1634 }
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
art::ServiceHandle< geo::Geometry > fGeom
Definition: EMShowerAlg.h:234
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
detinfo::DetectorProperties const * fDetProp
Definition: EMShowerAlg.h:235
bool shower::EMShowerAlg::isCleanShower ( std::vector< art::Ptr< recob::Hit > > const &  hits)

<Tingjun to="" document>="">

Definition at line 2202 of file EMShowerAlg.cxx.

References hits().

2202  {
2203 
2204  if (!hits.size()) return false;
2205  if (hits.size()>2000) return true;
2206  if (hits.size()<20) return true;
2207  std::map<int, int> hitmap;
2208  unsigned nhits = 0;
2209  for (auto const&hit : hits){
2210  ++nhits;
2211  if (nhits>2)
2212  ++hitmap[hit->WireID().Wire];
2213  if (nhits==20) break;
2214  }
2215  //std::cout<<hits.size()<<" "<<float(nhits-2)/hitmap.size()<<std::endl;
2216  if (float(nhits-2)/hitmap.size()>1.4) return false;
2217  else return true;
2218 }
Detector simulation of raw signals on wires.
std::unique_ptr< recob::Track > shower::EMShowerAlg::MakeInitialTrack ( std::map< int, std::vector< art::Ptr< recob::Hit > > > const &  initialHitsMap,
std::map< int, std::vector< art::Ptr< recob::Hit > > > const &  showerHitsMap 
)
private

Takes initial track hits from multiple views and forms a track object which best represents the start of the shower.

Definition at line 931 of file EMShowerAlg.cxx.

References CheckShowerHits(), ConstructTrack(), fDebug, lar::dump::vector(), and WorstPlane().

Referenced by FindInitialTrack().

932  {
933 
934  // Can't do much with just one view
935  if (initialHitsMap.size() < 2) {
936  mf::LogInfo("EMShowerAlg") << "Only one useful view for this shower; nothing can be done" << std::endl;
937  return std::unique_ptr<recob::Track>();
938  }
939 
940  std::vector<std::pair<int,int> > initialHitsSize;
941  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator initialHitIt = initialHitsMap.begin(); initialHitIt != initialHitsMap.end(); ++initialHitIt)
942  initialHitsSize.push_back(std::make_pair(initialHitIt->first, initialHitIt->second.size()));
943 
944  // Sort the planes by number of hits
945  std::sort(initialHitsSize.begin(), initialHitsSize.end(), [](std::pair<int,int> const& size1, std::pair<int,int> const& size2) { return size1.second > size2.second; });
946 
947  // Pick the two planes to use to make the track
948  // -- if more than two planes, can choose the two views
949  // more accurately
950  // -- if not, just use the two views available
951 
952  std::vector<int> planes;
953 
954  if (initialHitsSize.size() > 2 and !CheckShowerHits(showerHitsMap)) {
955  int planeToIgnore = WorstPlane(showerHitsMap);
956  if (fDebug > 1)
957  std::cout << "Igoring plane " << planeToIgnore << " in creation of initial track" << std::endl;
958  for (std::vector<std::pair<int,int> >::iterator hitsSizeIt = initialHitsSize.begin(); hitsSizeIt != initialHitsSize.end() and planes.size() < 2; ++hitsSizeIt) {
959  if (hitsSizeIt->first == planeToIgnore)
960  continue;
961  planes.push_back(hitsSizeIt->first);
962  }
963  }
964  else
965  planes = {initialHitsSize.at(0).first, initialHitsSize.at(1).first};
966 
967  return ConstructTrack(initialHitsMap.at(planes.at(0)), initialHitsMap.at(planes.at(1)));
968 
969 }
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
bool CheckShowerHits(std::map< int, std::vector< art::Ptr< recob::Hit > > > const &showerHitsMap)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
int WorstPlane(const std::map< int, std::vector< art::Ptr< recob::Hit > > > &showerHitsMap)
Returns the plane which is determined to be the least likely to be correct.
std::unique_ptr< recob::Track > ConstructTrack(std::vector< art::Ptr< recob::Hit > > const &track1, std::vector< art::Ptr< recob::Hit > > const &track2, std::map< int, TVector2 > const &showerCentreMap)
void shower::EMShowerAlg::MakePicture ( )
private
recob::Shower shower::EMShowerAlg::MakeShower ( art::PtrVector< recob::Hit > const &  hits,
std::unique_ptr< recob::Track > const &  initialTrack,
std::map< int, std::vector< art::Ptr< recob::Hit > > > const &  initialTrackHits 
)

Makes a recob::Shower object given the hits in the shower and the initial track-like part.

Definition at line 971 of file EMShowerAlg.cxx.

References art::PtrVector< T >::begin(), art::PtrVector< T >::end(), fDebug, fGeom, FinddEdx(), fShowerEnergyAlg, geo::GeometryCore::MaxPlanes(), shower::ShowerEnergyAlg::ShowerEnergy(), recob::Track::Vertex(), and recob::Track::VertexDirection().

Referenced by shower::EMShower::produce().

973  {
974 
975  //return recob::Shower();
976 
977  // Find the shower hits on each plane
978  std::map<int,std::vector<art::Ptr<recob::Hit> > > planeHitsMap;
979  for (art::PtrVector<recob::Hit>::const_iterator hit = hits.begin(); hit != hits.end(); ++hit)
980  planeHitsMap[(*hit)->View()].push_back(*hit);
981 
982  int bestPlane = -1;
983  unsigned int highestNumberOfHits = 0;
984  std::vector<double> totalEnergy, totalEnergyError, dEdx, dEdxError;
985 
986  // Look at each of the planes
987  for (unsigned int plane = 0; plane < fGeom->MaxPlanes(); ++plane) {
988 
989  // If there's hits on this plane...
990  if (planeHitsMap.count(plane)) {
991  dEdx.push_back(FinddEdx(initialHitsMap.at(plane), initialTrack));
992  totalEnergy.push_back(fShowerEnergyAlg.ShowerEnergy(planeHitsMap.at(plane), plane));
993  if (planeHitsMap.at(plane).size() > highestNumberOfHits and initialHitsMap.count(plane)) {
994  bestPlane = plane;
995  highestNumberOfHits = planeHitsMap.at(plane).size();
996  }
997  }
998 
999  // If not...
1000  else {
1001  dEdx.push_back(0);
1002  totalEnergy.push_back(0);
1003  }
1004 
1005  }
1006 
1007  TVector3 direction, directionError, showerStart, showerStartError;
1008  if (initialTrack) {
1009  direction = initialTrack->VertexDirection<TVector3>();
1010  showerStart = initialTrack->Vertex<TVector3>();
1011  }
1012 
1013  if (fDebug > 0) {
1014  std::cout << "Best plane is " << bestPlane << std::endl;
1015  std::cout << "dE/dx for each plane is: " << dEdx[0] << ", " << dEdx[1] << " and " << dEdx[2] << std::endl;
1016  std::cout << "Total energy for each plane is: " << totalEnergy[0] << ", " << totalEnergy[1] << " and " << totalEnergy[2] << std::endl;
1017  std::cout << "The shower start is (" << showerStart.X() << ", " << showerStart.Y() << ", " << showerStart.Z() << ")" << std::endl;
1018  std::cout << "The shower direction is (" << direction.X() << ", " << direction.Y() << ", " << direction.Z() << ")" << std::endl;
1019  }
1020 
1021  return recob::Shower(direction, directionError, showerStart, showerStartError, totalEnergy, totalEnergyError, dEdx, dEdxError, bestPlane);
1022 
1023 }
double ShowerEnergy(std::vector< art::Ptr< recob::Hit > > const &hits, int plane)
Finds the total energy deposited by the shower in this view.
iterator begin()
Definition: PtrVector.h:223
Vector_t VertexDirection() const
Access to track direction at different points.
Definition: Track.h:135
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.
Point_t const & Vertex() const
Access to track position at different points.
Definition: Track.h:127
iterator end()
Definition: PtrVector.h:237
shower::ShowerEnergyAlg fShowerEnergyAlg
Definition: EMShowerAlg.h:239
art::ServiceHandle< geo::Geometry > fGeom
Definition: EMShowerAlg.h:234
double FinddEdx(std::vector< art::Ptr< recob::Hit > > const &trackHits, std::unique_ptr< recob::Track > const &track)
Finds dE/dx for the track given a set of hits.
Detector simulation of raw signals on wires.
data_t::const_iterator const_iterator
Definition: PtrVector.h:61
recob::Shower shower::EMShowerAlg::MakeShower ( art::PtrVector< recob::Hit > const &  hits,
art::Ptr< recob::Vertex > const &  vertex,
int &  iok 
)

<Tingjun to="" document>="">

Definition at line 1025 of file EMShowerAlg.cxx.

References art::PtrVector< T >::begin(), pma::ProjectionMatchingAlg::buildSegment(), calo::CalorimetryAlg::dEdx_AREA(), art::PtrVector< T >::end(), fCalorimetryAlg, fDebug, fdEdxTrackLength, fGeom, FindInitialTrackHits(), fProjectionMatchingAlg, fShowerEnergyAlg, geo::GeometryCore::MaxPlanes(), OrderShowerHits(), geo::GeometryCore::Plane(), shower::ShowerEnergyAlg::ShowerEnergy(), pma::Track3D::size(), lar::dump::vector(), geo::PlaneGeo::View(), geo::GeometryCore::WireAngleToVertical(), geo::GeometryCore::WirePitch(), and recob::Vertex::XYZ().

1027  {
1028 
1029  iok = 1;
1030 
1031  // Find the shower hits on each plane
1032  std::map<int,std::vector<art::Ptr<recob::Hit> > > planeHitsMap;
1033  for (art::PtrVector<recob::Hit>::const_iterator hit = hits.begin(); hit != hits.end(); ++hit)
1034  planeHitsMap[(*hit)->WireID().Plane].push_back(*hit);
1035 
1036  std::vector<std::vector<art::Ptr<recob::Hit> > > initialTrackHits(3);
1037 
1038  int pl0 = -1;
1039  int pl1 = -1;
1040  unsigned maxhits0 = 0;
1041  unsigned maxhits1 = 0;
1042 
1043  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator planeHits = planeHitsMap.begin(); planeHits != planeHitsMap.end(); ++planeHits) {
1044 
1045  std::vector<art::Ptr<recob::Hit> > showerHits;
1046  OrderShowerHits(planeHits->second, showerHits, vertex);
1047  //if (!isCleanShower(showerHits)) continue;
1048  FindInitialTrackHits(showerHits, vertex, initialTrackHits[planeHits->first]);
1049  if ((planeHits->second).size()>maxhits0){
1050  if (pl0!=-1){
1051  maxhits1 = maxhits0;
1052  pl1 = pl0;
1053  }
1054  pl0 = planeHits->first;
1055  maxhits0 = (planeHits->second).size();
1056  }
1057  else if ((planeHits->second).size()>maxhits1){
1058  pl1 = planeHits->first;
1059  maxhits1 = (planeHits->second).size();
1060  }
1061 
1062  }
1063  //std::cout<<pl0<<" "<<pl1<<std::endl;
1064 // if (pl0!=-1&&pl1!=-1) {
1065 // pl0 = 1;
1066 // pl1 = 2;
1067 // }
1068  if (pl0!=-1&&pl1!=-1
1069  &&initialTrackHits[pl0].size()>=2
1070  &&initialTrackHits[pl1].size()>=2
1071  &&initialTrackHits[pl0][0]->WireID().TPC==
1072  initialTrackHits[pl1][0]->WireID().TPC){
1073  double xyz[3];
1074  vertex->XYZ(xyz);
1075  TVector3 vtx(xyz);
1076 // std::vector<art::Ptr<recob::Hit>> alltrackhits;
1077 // for (size_t i = 0; i<3; ++i){
1078 // for (auto const&hit : initialTrackHits[i]){
1079 // alltrackhits.push_back(hit);
1080 // }
1081 // }
1082  //std::cout<<"vertex "<<xyz[0]<<" "<<xyz[1]<<" "<<xyz[2]<<std::endl;
1083  //for (auto const&hit : initialTrackHits[pl0]) std::cout<<*hit<<std::endl;
1084  //for (auto const&hit : initialTrackHits[pl1]) std::cout<<*hit<<std::endl;
1085  pma::Track3D* pmatrack = fProjectionMatchingAlg.buildSegment(initialTrackHits[pl0], initialTrackHits[pl1]);
1086  //std::cout<<pmatrack->size()<<std::endl;
1087  //pma::Track3D* pmatrack = fProjectionMatchingAlg.buildSegment(alltrackhits);
1088  std::vector<TVector3> spts;
1089 
1090 // points are shifted now by tracking code, commented out shifts here
1091 // double xshift = pmatrack->GetXShift();
1092 // bool has_shift = (xshift != 0.0);
1093  for (size_t i = 0; i<pmatrack->size(); ++i){
1094  if ((*pmatrack)[i]->IsEnabled()){
1095  TVector3 p3d = (*pmatrack)[i]->Point3D();
1096 // if (has_shift) p3d.SetX(p3d.X() + xshift);
1097  //std::cout<<p3d.X()<<" "<<p3d.Y()<<" "<<p3d.Z()<<std::endl;
1098  spts.push_back(p3d);
1099  }
1100  }
1101  if (spts.size()>=2){ //at least two space points
1102  TVector3 shwxyz, shwxyzerr;
1103  TVector3 shwdir, shwdirerr;
1104  std::vector<double> totalEnergy, totalEnergyError, dEdx, dEdxError;
1105  int bestPlane = pl0;
1106  double minpitch = 1000;
1107  std::vector<TVector3> dirs;
1108  if ((spts[0]-vtx).Mag()<(spts.back()-vtx).Mag()){
1109  shwxyz = spts[0];
1110  size_t i = 5;
1111  if (spts.size()-1<5) i = spts.size()-1;
1112  shwdir = spts[i] - spts[0];
1113  shwdir = shwdir.Unit();
1114  }
1115  else{
1116  shwxyz = spts.back();
1117  size_t i = 0;
1118  if (spts.size()>6) i = spts.size() - 6;
1119  shwdir = spts[i] - spts[spts.size()-1];
1120  shwdir = shwdir.Unit();
1121  }
1122  //std::cout<<shwxyz.X()<<" "<<shwxyz.Y()<<" "<<shwxyz.Z()<<std::endl;
1123  //std::cout<<shwdir.X()<<" "<<shwdir.Y()<<" "<<shwdir.Z()<<std::endl;
1124  for (unsigned int plane = 0; plane < fGeom->MaxPlanes(); ++plane) {
1125  if (planeHitsMap.find(plane)!=planeHitsMap.end()){
1126  totalEnergy.push_back(fShowerEnergyAlg.ShowerEnergy(planeHitsMap[plane], plane));
1127  }
1128  else{
1129  totalEnergy.push_back(0);
1130  }
1131  if (initialTrackHits[plane].size()){
1132  double fdEdx = 0;
1133  double totQ = 0;
1134  double avgT = 0;
1135  double pitch = 0;
1136  double wirepitch = fGeom->WirePitch(initialTrackHits[plane][0]->WireID().planeID());
1137  double angleToVert = fGeom->WireAngleToVertical(fGeom->Plane(plane).View(),initialTrackHits[plane][0]->WireID().planeID()) - 0.5*TMath::Pi();
1138  double cosgamma = std::abs(sin(angleToVert)*shwdir.Y()+
1139  cos(angleToVert)*shwdir.Z());
1140  if (cosgamma>0) pitch = wirepitch/cosgamma;
1141  if (pitch){
1142  if (pitch<minpitch){
1143  minpitch = pitch;
1144  bestPlane = plane;
1145  }
1146  int nhits = 0;
1147  //std::cout<<"pitch = "<<pitch<<std::endl;
1148  std::vector<float> vQ;
1149  for (auto const& hit: initialTrackHits[plane]){
1150  //std::cout<<hit->WireID()<<" "<<hit->PeakTime()<<" "<<std::abs((hit->WireID().Wire-initialTrackHits[plane][0]->WireID().Wire)*pitch)<<" "<<fdEdxTrackLength<<std::endl;
1151  int w1 = hit->WireID().Wire;
1152  int w0 = initialTrackHits[plane][0]->WireID().Wire;
1153  if (std::abs((w1-w0)*pitch)<fdEdxTrackLength){
1154  vQ.push_back(hit->Integral());
1155  totQ += hit->Integral();
1156  avgT+= hit->PeakTime();
1157  ++nhits;
1158  //std::cout<<hit->WireID()<<" "<<hit->PeakTime()<<" "<<hit->Integral()<<" "<<totQ<<" "<<avgT<<std::endl;
1159  }
1160  }
1161  if (totQ) {
1162  //double dQdx = totQ/(nhits*pitch);
1163  //std::sort(vQ.begin(), vQ.end());
1164  //double dQdx = vQ[vQ.size()/2]/pitch;
1165  double dQdx = TMath::Median(vQ.size(), &vQ[0])/pitch;
1166  fdEdx = fCalorimetryAlg.dEdx_AREA(dQdx, avgT/nhits, initialTrackHits[plane][0]->WireID().Plane);
1167  }
1168  }
1169  dEdx.push_back(fdEdx);
1170  }
1171  else{
1172  dEdx.push_back(0);
1173  }
1174  }
1175  iok = 0;
1176  if (fDebug > 1) {
1177  std::cout << "Best plane is " << bestPlane << std::endl;
1178  std::cout << "dE/dx for each plane is: " << dEdx[0] << ", " << dEdx[1] << " and " << dEdx[2] << std::endl;
1179  std::cout << "Total energy for each plane is: " << totalEnergy[0] << ", " << totalEnergy[1] << " and " << totalEnergy[2] << std::endl;
1180  std::cout << "The shower start is (" << shwxyz.X() << ", " << shwxyz.Y() << ", " << shwxyz.Z() << ")" << std::endl;
1181  shwxyz.Print();
1182  }
1183 
1184  return recob::Shower(shwdir, shwdirerr, shwxyz, shwxyzerr, totalEnergy, totalEnergyError, dEdx, dEdxError, bestPlane);
1185  }
1186  }
1187  return recob::Shower();
1188 }
void XYZ(double *xyz) const
Legacy method to access vertex position, preserved to avoid breaking code. Please try to use Vertex::...
Definition: Vertex.cxx:37
double ShowerEnergy(std::vector< art::Ptr< recob::Hit > > const &hits, int plane)
Finds the total energy deposited by the shower in this view.
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
void FindInitialTrackHits(std::vector< art::Ptr< recob::Hit > >const &showerHits, art::Ptr< recob::Vertex > const &vertex, std::vector< art::Ptr< recob::Hit > > &trackHits)
<Tingjun to="" document>="">
double dEdx_AREA(art::Ptr< recob::Hit > hit, double pitch, double T0=0) const
iterator begin()
Definition: PtrVector.h:223
std::map< int, std::vector< art::Ptr< recob::Hit > > > OrderShowerHits(const art::PtrVector< recob::Hit > &shower, int plane)
Takes the hits associated with a shower and orders them so they follow the direction of the shower...
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
calo::CalorimetryAlg fCalorimetryAlg
Definition: EMShowerAlg.h:240
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
View_t View() const
Which coordinate does this plane measure.
Definition: PlaneGeo.h:171
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.
pma::Track3D * buildSegment(const std::vector< art::Ptr< recob::Hit > > &hits_1, const std::vector< art::Ptr< recob::Hit > > &hits_2=std::vector< art::Ptr< recob::Hit > >()) const
iterator end()
Definition: PtrVector.h:237
shower::ShowerEnergyAlg fShowerEnergyAlg
Definition: EMShowerAlg.h:239
pma::ProjectionMatchingAlg fProjectionMatchingAlg
Definition: EMShowerAlg.h:241
art::ServiceHandle< geo::Geometry > fGeom
Definition: EMShowerAlg.h:234
Detector simulation of raw signals on wires.
data_t::const_iterator const_iterator
Definition: PtrVector.h:61
size_t size() const
Definition: PmaTrack3D.h:76
recob::tracking::Plane Plane
Definition: TrackState.h:17
double WireAngleToVertical(geo::View_t view, geo::TPCID const &tpcid) const
Returns the angle of the wires in the specified view from vertical.
std::vector< recob::SpacePoint > shower::EMShowerAlg::MakeSpacePoints ( std::map< int, std::vector< art::Ptr< recob::Hit > > >  hits,
std::vector< std::vector< art::Ptr< recob::Hit > > > &  hitAssns 
)

Makes space points from the shower hits in each plane.

Definition at line 1190 of file EMShowerAlg.cxx.

References Construct3DPoint(), fDebug, fGeom, fSpacePointSize, HitPosition(), geo::GeometryCore::MaxPlanes(), Project3DPointOntoPlane(), and lar::dump::vector().

Referenced by shower::EMShower::produce().

1191  {
1192 
1193  // Space points to return
1194  std::vector<recob::SpacePoint> spacePoints;
1195 
1196  // // Order by charge
1197  // for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator planeIt = showerHits.begin(); planeIt != showerHits.end(); ++planeIt)
1198  // std::sort(planeIt->second.begin(), planeIt->second.end(), [](const art::Ptr<recob::Hit>& h1, const art::Ptr<recob::Hit>& h2) { return h1->Integral() > h2->Integral(); });
1199 
1200  // Make space points
1201  // Use the following procedure:
1202  // -- Consider hits plane by plane
1203  // -- For each hit on the first plane, consider the 3D point made by combining with each hit from the second plane
1204  // -- Project this 3D point back into the two planes
1205  // -- Determine how close to a the original hits this point lies
1206  // -- If close enough, make a 3D space point from this point
1207  // // -- Discard these used hits in future iterations, along with hits in the
1208  // // third plane (if exists) close to the projection of the point into this plane
1209 
1210  // Container to hold used hits
1211  std::vector<int> usedHits;
1212 
1213  // Look through plane by plane
1214  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator showerHitIt = showerHits.begin(); showerHitIt != showerHits.end(); ++showerHitIt) {
1215 
1216  // Find the other planes with hits
1217  std::vector<int> otherPlanes;
1218  for (unsigned int otherPlane = 0; otherPlane < fGeom->MaxPlanes(); ++otherPlane)
1219  if ((int)otherPlane != showerHitIt->first and showerHits.count(otherPlane))
1220  otherPlanes.push_back(otherPlane);
1221 
1222  // Can't make space points if we only have one view
1223  if (otherPlanes.size() == 0)
1224  return spacePoints;
1225 
1226  // Look at all hits on this plane
1227  for (std::vector<art::Ptr<recob::Hit> >::const_iterator planeHitIt = showerHitIt->second.begin(); planeHitIt != showerHitIt->second.end(); ++planeHitIt) {
1228 
1229  if (std::find(usedHits.begin(), usedHits.end(), planeHitIt->key()) != usedHits.end())
1230  continue;
1231 
1232  // Make a 3D point with every hit on the second plane
1233  const std::vector<art::Ptr<recob::Hit> > otherPlaneHits = showerHits.at(otherPlanes.at(0));
1234  for (std::vector<art::Ptr<recob::Hit> >::const_iterator otherPlaneHitIt = otherPlaneHits.begin();
1235  otherPlaneHitIt != otherPlaneHits.end() and std::find(usedHits.begin(), usedHits.end(), planeHitIt->key()) == usedHits.end();
1236  ++otherPlaneHitIt) {
1237 
1238  if ((*otherPlaneHitIt)->WireID().TPC != (*planeHitIt)->WireID().TPC or
1239  std::find(usedHits.begin(), usedHits.end(), otherPlaneHitIt->key()) != usedHits.end())
1240  continue;
1241 
1242  TVector3 point = Construct3DPoint(*planeHitIt, *otherPlaneHitIt);
1243  std::vector<art::Ptr<recob::Hit> > pointHits;
1244  bool truePoint = false;
1245 
1246  if (otherPlanes.size() > 1) {
1247 
1248  TVector2 projThirdPlane = Project3DPointOntoPlane(point, otherPlanes.at(1));
1249  const std::vector<art::Ptr<recob::Hit> > otherOtherPlaneHits = showerHits.at(otherPlanes.at(1));
1250 
1251  for (std::vector<art::Ptr<recob::Hit> >::const_iterator otherOtherPlaneHitIt = otherOtherPlaneHits.begin();
1252  otherOtherPlaneHitIt != otherOtherPlaneHits.end() and !truePoint;
1253  ++otherOtherPlaneHitIt) {
1254 
1255  if ((*otherOtherPlaneHitIt)->WireID().TPC == (*planeHitIt)->WireID().TPC and
1256  (projThirdPlane-HitPosition(*otherOtherPlaneHitIt)).Mod() < fSpacePointSize) {
1257 
1258  truePoint = true;
1259 
1260  // Remove hits used to make the point
1261  usedHits.push_back(planeHitIt->key());
1262  usedHits.push_back(otherPlaneHitIt->key());
1263  usedHits.push_back(otherOtherPlaneHitIt->key());
1264 
1265  pointHits.push_back(*planeHitIt);
1266  pointHits.push_back(*otherPlaneHitIt);
1267  pointHits.push_back(*otherOtherPlaneHitIt);
1268 
1269  }
1270  }
1271  }
1272 
1273  else if ((Project3DPointOntoPlane(point, (*planeHitIt)->WireID().Plane) - HitPosition(*planeHitIt)).Mod() < fSpacePointSize and
1274  (Project3DPointOntoPlane(point, (*otherPlaneHitIt)->WireID().Plane) - HitPosition(*otherPlaneHitIt)).Mod() < fSpacePointSize) {
1275 
1276  truePoint = true;
1277 
1278  usedHits.push_back(planeHitIt->key());
1279  usedHits.push_back(otherPlaneHitIt->key());
1280 
1281  pointHits.push_back(*planeHitIt);
1282  pointHits.push_back(*otherPlaneHitIt);
1283 
1284  }
1285 
1286  // Make space point
1287  if (truePoint) {
1288  double xyz[3] = {point.X(), point.Y(), point.Z()};
1289  double xyzerr[6] = {fSpacePointSize, fSpacePointSize, fSpacePointSize, fSpacePointSize, fSpacePointSize, fSpacePointSize};
1290  double chisq = 0.;
1291  spacePoints.emplace_back(xyz, xyzerr, chisq);
1292  hitAssns.push_back(pointHits);
1293  }
1294 
1295  } // end loop over second plane hits
1296 
1297  } // end loop over first plane hits
1298 
1299  } // end loop over planes
1300 
1301  if (fDebug > 0) {
1302  std::cout << "-------------------- Space points -------------------" << std::endl;
1303  std::cout << "There are " << spacePoints.size() << " space points:" << std::endl;
1304  if (fDebug > 1)
1305  for (std::vector<recob::SpacePoint>::const_iterator spacePointIt = spacePoints.begin(); spacePointIt != spacePoints.end(); ++spacePointIt) {
1306  const double* xyz = spacePointIt->XYZ();
1307  std::cout << " Space point (" << xyz[0] << ", " << xyz[1] << ", " << xyz[2] << ")" << std::endl;
1308  }
1309  }
1310 
1311  return spacePoints;
1312 
1313 }
TVector3 Construct3DPoint(art::Ptr< recob::Hit > const &hit1, art::Ptr< recob::Hit > const &hit2)
Constructs a 3D point (in [cm]) to represent the hits given in two views.
TVector2 Project3DPointOntoPlane(TVector3 const &point, int plane, int cryostat=0)
TVector2 HitPosition(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in units of cm.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.
intermediate_table::const_iterator const_iterator
art::ServiceHandle< geo::Geometry > fGeom
Definition: EMShowerAlg.h:234
std::map< int, std::vector< art::Ptr< recob::Hit > > > shower::EMShowerAlg::OrderShowerHits ( const art::PtrVector< recob::Hit > &  shower,
int  plane 
)

Takes the hits associated with a shower and orders them so they follow the direction of the shower.

Ordering the shower hits requires three stages: – putting all the hits in a given plane in some kind of order – use the properties of the hits in all three planes to check this order – orient the hits correctly using properties of the shower

Definition at line 1315 of file EMShowerAlg.cxx.

References art::PtrVector< T >::begin(), CheckIsolatedHits(), CheckShowerHits(), art::PtrVector< T >::end(), fDebug, fGeom, FindOrderOfHits(), GetPlanePermutations(), HitCoordinates(), HitPosition(), hits(), geo::GeometryCore::MaxPlanes(), n, RelativeWireWidth(), ShowerHitRMS(), ShowerHitRMSGradient(), lar::dump::vector(), X, and Y.

Referenced by MakeShower(), and shower::EMShower::produce().

1315  {
1316 
1321 
1322  // ------------- Put hits in order ------------
1323 
1324  // // Find the true start for reconstruction validation purposes
1325  // std::vector<art::Ptr<recob::Hit> > showerHitsVector;
1326  // std::map<int,int> trueParticleHits;
1327  // for (art::PtrVector<recob::Hit>::const_iterator showerHitIt = shower.begin(); showerHitIt != shower.end(); ++showerHitIt) {
1328  // showerHitsVector.push_back(*showerHitIt);
1329  // ++trueParticleHits[FindParticleID(*showerHitIt)];
1330  // }
1331  // int trueParticleID = FindTrueParticle(showerHitsVector);
1332  // const simb::MCParticle* trueParticle = bt_serv->TrackIDToParticle(trueParticleID);
1333  // TVector3 trueStart3D = trueParticle->Position().Vect();
1334  // double purity = trueParticleHits[trueParticleID]/(double)shower.size();
1335 
1336  // Find the shower hits on each plane
1337  std::map<int,std::vector<art::Ptr<recob::Hit> > > showerHitsMap;
1338  for (art::PtrVector<recob::Hit>::const_iterator hit = shower.begin(); hit != shower.end(); ++hit)
1339  showerHitsMap[(*hit)->WireID().Plane].push_back(*hit);
1340 
1341  // if (purity < 0.9)
1342  // return showerHitsMap;
1343 
1344  // Order the hits, get the RMS and the RMS gradient for the hits in this plane
1345  std::map<int,double> planeRMSGradients, planeRMS;
1346  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt) {
1347  if (plane != showerHitsIt->first and plane != -1)
1348  continue;
1349  std::vector<art::Ptr<recob::Hit> > orderedHits = FindOrderOfHits(showerHitsIt->second);
1350  planeRMS[showerHitsIt->first] = ShowerHitRMS(orderedHits);
1351  //TVector2 trueStart2D = Project3DPointOntoPlane(trueStart3D, showerHitsIt->first);
1352  planeRMSGradients[showerHitsIt->first] = ShowerHitRMSGradient(orderedHits);
1353  showerHitsMap[showerHitsIt->first] = orderedHits;
1354  }
1355 
1356  if (fDebug > 1)
1357  for (std::map<int,double>::iterator planeRMSIt = planeRMS.begin(); planeRMSIt != planeRMS.end(); ++planeRMSIt)
1358  std::cout << "Plane " << planeRMSIt->first << " has RMS " << planeRMSIt->second << " and RMS gradient " << planeRMSGradients.at(planeRMSIt->first) << std::endl;
1359 
1360  if (fDebug > 2) {
1361  std::cout << std::endl << "Hits in order; after ordering, before reversing..." << std::endl;
1362  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt) {
1363  std::cout << " Plane " << showerHitsIt->first << std::endl;
1364  for (std::vector<art::Ptr<recob::Hit> >::iterator hitIt = showerHitsIt->second.begin(); hitIt != showerHitsIt->second.end(); ++hitIt)
1365  std::cout << " Hit at (" << HitCoordinates(*hitIt).X() << ", " << HitCoordinates(*hitIt).Y() << ") -- real wire " << (*hitIt)->WireID() << ", hit position (" << HitPosition(*hitIt).X() << ", " << HitPosition(*hitIt).Y() << ")" << std::endl;
1366  }
1367  }
1368 
1369  // ------------- Check between the views to ensure consistency of ordering -------------
1370 
1371  // Check between the views to make sure there isn't a poorly formed shower in just one view
1372  // First, determine the average RMS and RMS gradient across the other planes
1373  std::map<int,double> planeOtherRMS, planeOtherRMSGradients;
1374  for (std::map<int,double>::iterator planeRMSIt = planeRMS.begin(); planeRMSIt != planeRMS.end(); ++planeRMSIt) {
1375  planeOtherRMS[planeRMSIt->first] = 0;
1376  planeOtherRMSGradients[planeRMSIt->first] = 0;
1377  int nOtherPlanes = 0;
1378  for (int plane = 0; plane < (int)fGeom->MaxPlanes(); ++plane) {
1379  if (plane != planeRMSIt->first and planeRMS.count(plane)) {
1380  planeOtherRMS[planeRMSIt->first] += planeRMS.at(plane);
1381  planeOtherRMSGradients[planeRMSIt->first] += planeRMSGradients.at(plane);
1382  ++nOtherPlanes;
1383  }
1384  }
1385  planeOtherRMS[planeRMSIt->first] /= (double)nOtherPlanes;
1386  planeOtherRMSGradients[planeRMSIt->first] /= (double)nOtherPlanes;
1387  }
1388 
1389  // Look to see if one plane has a particularly high RMS (compared to the others) whilst having a similar gradient
1390  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt) {
1391  if (planeRMS.at(showerHitsIt->first) > planeOtherRMS.at(showerHitsIt->first) * 2) {
1392  //and TMath::Abs(planeRMSGradients.at(showerHitsIt->first) / planeOtherRMSGradients.at(showerHitsIt->first)) < 0.1) {
1393  if (fDebug > 1)
1394  std::cout << "Plane " << showerHitsIt->first << " was perpendicular... recalculating" << std::endl;
1395  std::vector<art::Ptr<recob::Hit> > orderedHits = this->FindOrderOfHits(showerHitsIt->second, true);
1396  showerHitsMap[showerHitsIt->first] = orderedHits;
1397  planeRMSGradients[showerHitsIt->first] = this->ShowerHitRMSGradient(orderedHits);
1398  }
1399  }
1400 
1401  // ------------- Orient the shower correctly ---------------
1402 
1403  if (fDebug > 1) {
1404  std::cout << "Before reversing, here are the start and end points..." << std::endl;
1405  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt)
1406  std::cout << " Plane " << showerHitsIt->first << " has start (" << HitCoordinates(showerHitsIt->second.front()).X() << ", " << HitCoordinates(showerHitsIt->second.front()).Y() << ") (real wire " << showerHitsIt->second.front()->WireID() << ") and end (" << HitCoordinates(showerHitsIt->second.back()).X() << ", " << HitCoordinates(showerHitsIt->second.back()).Y() << ") (real wire " << showerHitsIt->second.back()->WireID() << ")" << std::endl;
1407  }
1408 
1409  // Use the RMS gradient information to get an initial ordering
1410  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt) {
1411  double gradient = planeRMSGradients.at(showerHitsIt->first);
1412  if (gradient < 0)
1413  std::reverse(showerHitsIt->second.begin(), showerHitsIt->second.end());
1414  }
1415 
1416  if (fDebug > 2) {
1417  std::cout << std::endl << "Hits in order; after reversing, before checking isolated hits..." << std::endl;
1418  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt) {
1419  std::cout << " Plane " << showerHitsIt->first << std::endl;
1420  for (std::vector<art::Ptr<recob::Hit> >::iterator hitIt = showerHitsIt->second.begin(); hitIt != showerHitsIt->second.end(); ++hitIt)
1421  std::cout << " Hit at (" << HitCoordinates(*hitIt).X() << ", " << HitCoordinates(*hitIt).Y() << ") -- real wire " << (*hitIt)->WireID() << ", hit position (" << HitPosition(*hitIt).X() << ", " << HitPosition(*hitIt).Y() << ")" << std::endl;
1422  }
1423  }
1424 
1425  CheckIsolatedHits(showerHitsMap);
1426 
1427  if (fDebug > 2) {
1428  std::cout << std::endl << "Hits in order; after checking isolated hits..." << std::endl;
1429  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt) {
1430  std::cout << " Plane " << showerHitsIt->first << std::endl;
1431  for (std::vector<art::Ptr<recob::Hit> >::iterator hitIt = showerHitsIt->second.begin(); hitIt != showerHitsIt->second.end(); ++hitIt)
1432  std::cout << " Hit at (" << HitCoordinates(*hitIt).X() << ", " << HitCoordinates(*hitIt).Y() << ") -- real wire " << (*hitIt)->WireID() << ", hit position (" << HitPosition(*hitIt).X() << ", " << HitPosition(*hitIt).Y() << ")" << std::endl;
1433  }
1434  }
1435 
1436  if (fDebug > 1) {
1437  std::cout << "After reversing and checking isolated hits, here are the start and end points..." << std::endl;
1438  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt)
1439  std::cout << " Plane " << showerHitsIt->first << " has start (" << HitCoordinates(showerHitsIt->second.front()).X() << ", " << HitCoordinates(showerHitsIt->second.front()).Y() << ") (real wire " << showerHitsIt->second.front()->WireID() << ") and end (" << HitCoordinates(showerHitsIt->second.back()).X() << ", " << HitCoordinates(showerHitsIt->second.back()).Y() << ")" << std::endl;
1440  }
1441 
1442  // Check for views in which the shower travels almost along the wire planes
1443  // (shown by a small relative wire width)
1444  std::map<double,int> wireWidths = RelativeWireWidth(showerHitsMap);
1445  std::vector<int> badPlanes;
1446  if (fDebug > 1)
1447  std::cout << "Here are the relative wire widths... " << std::endl;
1448  for (std::map<double,int>::iterator wireWidthIt = wireWidths.begin(); wireWidthIt != wireWidths.end(); ++wireWidthIt) {
1449  if (fDebug > 1)
1450  std::cout << "Plane " << wireWidthIt->second << " has relative wire width " << wireWidthIt->first << std::endl;
1451  if (wireWidthIt->first < 1/(double)wireWidths.size())
1452  badPlanes.push_back(wireWidthIt->second);
1453  }
1454 
1455  std::map<int,std::vector<art::Ptr<recob::Hit> > > ignoredPlanes;
1456  if (badPlanes.size() == 1) {
1457  int badPlane = badPlanes.at(0);
1458  if (fDebug > 1)
1459  std::cout << "Ignoring plane " << badPlane << " when orientating" << std::endl;
1460  ignoredPlanes[badPlane] = showerHitsMap.at(badPlane);
1461  showerHitsMap.erase(showerHitsMap.find(badPlane));
1462  }
1463 
1464  // Consider all possible permutations of planes (0/1, oriented correctly/incorrectly)
1465  std::map<int,std::map<int,bool> > permutations = GetPlanePermutations(showerHitsMap);
1466 
1467  // Go through all permutations until we have a satisfactory orientation
1468  std::map<int,std::vector<art::Ptr<recob::Hit> > > originalShowerHitsMap = showerHitsMap;
1469  int n = 0;
1470  while (!CheckShowerHits(showerHitsMap) and n < TMath::Power(2,(int)showerHitsMap.size())) {
1471  if (fDebug > 1)
1472  std::cout << "Permutation " << n << std::endl;
1473  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt) {
1474  std::vector<art::Ptr<recob::Hit> > hits = originalShowerHitsMap.at(showerHitsIt->first);
1475  if (permutations[n][showerHitsIt->first] == 1) {
1476  std::reverse(hits.begin(), hits.end());
1477  showerHitsMap[showerHitsIt->first] = hits;
1478  }
1479  else
1480  showerHitsMap[showerHitsIt->first] = hits;
1481  }
1482  ++n;
1483  }
1484 
1485  // Go back to original if still no consistency
1486  if (!CheckShowerHits(showerHitsMap))
1487  showerHitsMap = originalShowerHitsMap;
1488 
1489  if (fDebug > 2) {
1490  std::cout << "End of OrderShowerHits: here are the order of hits:" << std::endl;
1491  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator planeHitsIt = showerHitsMap.begin(); planeHitsIt != showerHitsMap.end(); ++planeHitsIt) {
1492  std::cout << " Plane " << planeHitsIt->first << std::endl;
1493  for (std::vector<art::Ptr<recob::Hit> >::iterator hitIt = planeHitsIt->second.begin(); hitIt != planeHitsIt->second.end(); ++hitIt)
1494  std::cout << " Hit (" << HitCoordinates(*hitIt).X() << " (real wire " << (*hitIt)->WireID() << "), " << HitCoordinates(*hitIt).Y() << ") -- pos (" << HitPosition(*hitIt).X() << ", " << HitPosition(*hitIt).Y() << ")" << std::endl;
1495  }
1496  }
1497 
1498  if (ignoredPlanes.size())
1499  showerHitsMap[ignoredPlanes.begin()->first] = ignoredPlanes.begin()->second;
1500 
1501  return showerHitsMap;
1502 
1503 }
intermediate_table::iterator iterator
iterator begin()
Definition: PtrVector.h:223
Float_t Y
Definition: plot.C:39
bool CheckShowerHits(std::map< int, std::vector< art::Ptr< recob::Hit > > > const &showerHitsMap)
TVector2 HitPosition(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in units of cm.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
void hits()
Definition: readHits.C:15
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.
iterator end()
Definition: PtrVector.h:237
std::map< int, std::map< int, bool > > GetPlanePermutations(const std::map< int, std::vector< art::Ptr< recob::Hit > > > &showerHitsMap)
double ShowerHitRMS(const std::vector< art::Ptr< recob::Hit > > &showerHits)
Returns the RMS of the hits from the central shower &#39;axis&#39; along the length of the shower...
art::ServiceHandle< geo::Geometry > fGeom
Definition: EMShowerAlg.h:234
Detector simulation of raw signals on wires.
double ShowerHitRMSGradient(const std::vector< art::Ptr< recob::Hit > > &showerHits, TVector2 trueStart=TVector2(0, 0))
Returns the gradient of the RMS vs shower segment graph.
data_t::const_iterator const_iterator
Definition: PtrVector.h:61
void CheckIsolatedHits(std::map< int, std::vector< art::Ptr< recob::Hit > > > &showerHitsMap)
Checks the hits across the views in a given shower to determine if there is one in the incorrect TPC...
std::vector< art::Ptr< recob::Hit > > FindOrderOfHits(std::vector< art::Ptr< recob::Hit > > const &hits, bool perpendicular=false)
Char_t n[5]
TVector2 HitCoordinates(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in global wire/tick space.
Float_t X
Definition: plot.C:39
std::map< double, int > RelativeWireWidth(const std::map< int, std::vector< art::Ptr< recob::Hit > > > &showerHitsMap)
void shower::EMShowerAlg::OrderShowerHits ( std::vector< art::Ptr< recob::Hit > > const &  shower,
std::vector< art::Ptr< recob::Hit > > &  orderedShower,
art::Ptr< recob::Vertex > const &  vertex 
)
private

Takes the hits associated with a shower and orders then so they follow the direction of the shower.

Definition at line 1505 of file EMShowerAlg.cxx.

References detinfo::DetectorProperties::ConvertXToTicks(), fDetProp, fGeom, FindOrderOfHits(), geo::GeometryCore::FindTPCAtPosition(), art::Ptr< T >::isNull(), geo::CryostatID::isValid, recob::Hit::PeakTime(), geo::WireID::planeID(), geo::TPCID::TPC, geo::WireID::Wire, geo::GeometryCore::WireCoordinate(), recob::Hit::WireID(), and recob::Vertex::XYZ().

1507  {
1508 
1509  showerHits = FindOrderOfHits(shower);
1510 
1511  // Find TPC for the vertex
1512  double xyz[3];
1513  vertex->XYZ(xyz);
1514  geo::TPCID tpc = fGeom->FindTPCAtPosition(xyz);
1515  if (!tpc.isValid&&showerHits.size()) tpc = geo::TPCID(showerHits[0]->WireID());
1516  //std::cout<<tpc<<std::endl;
1517  // Find hits in the same TPC
1518  art::Ptr<recob::Hit> hit0, hit1;
1519  for (auto &hit: showerHits){
1520  if (hit->WireID().TPC==tpc.TPC){
1521  if (hit0.isNull()){
1522  hit0 = hit;
1523  }
1524  hit1 = hit;
1525  }
1526  }
1527  if (hit0.isNull()||hit1.isNull()) return;
1528  TVector2 coord0 = TVector2(hit0->WireID().Wire, hit0->PeakTime());
1529  TVector2 coord1 = TVector2(hit1->WireID().Wire, hit1->PeakTime());
1530  TVector2 coordvtx = TVector2(fGeom->WireCoordinate(xyz[1], xyz[2], hit0->WireID().planeID()),
1531  fDetProp->ConvertXToTicks(xyz[0], hit0->WireID().planeID()));
1532 // std::cout<<coord0.X()<<" "<<coord0.Y()<<std::endl;
1533 // std::cout<<coord1.X()<<" "<<coord1.Y()<<std::endl;
1534 // std::cout<<coordvtx.X()<<" "<<coordvtx.Y()<<std::endl;
1535 // std::cout<<hit0->WireID()<<" "<<hit1->WireID()<<std::endl;
1536  if ((coord1-coordvtx).Mod()<(coord0-coordvtx).Mod()){
1537  std::reverse(showerHits.begin(), showerHits.end());
1538  }
1539  //std::cout<<showerHits[0]->WireID()<<" "<<showerHits.back()->WireID()<<std::endl;
1540 }
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
void XYZ(double *xyz) const
Legacy method to access vertex position, preserved to avoid breaking code. Please try to use Vertex::...
Definition: Vertex.cxx:37
PlaneID const & planeID() const
Definition: geo_types.h:355
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
bool isValid
Whether this ID points to a valid element.
Definition: geo_types.h:129
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:313
virtual double ConvertXToTicks(double X, int p, int t, int c) const =0
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
The data type to uniquely identify a TPC.
Definition: geo_types.h:195
art::ServiceHandle< geo::Geometry > fGeom
Definition: EMShowerAlg.h:234
Detector simulation of raw signals on wires.
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:219
std::vector< art::Ptr< recob::Hit > > FindOrderOfHits(std::vector< art::Ptr< recob::Hit > > const &hits, bool perpendicular=false)
detinfo::DetectorProperties const * fDetProp
Definition: EMShowerAlg.h:235
bool isNull() const
Definition: Ptr.h:328
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:203
TVector2 shower::EMShowerAlg::Project3DPointOntoPlane ( TVector3 const &  point,
int  plane,
int  cryostat = 0 
)
private

Projects a 3D point (units [cm]) onto a 2D plane Returns 2D point (units [cm])

Definition at line 2096 of file EMShowerAlg.cxx.

References detinfo::DetectorProperties::ConvertXToTicks(), e, fDetProp, fGeom, geo::GeometryCore::FindTPCAtPosition(), GlobalWire(), HitPosition(), geo::CryostatID::isValid, geo::GeometryCore::NearestWireID(), geo::InvalidWireError::suggestedWireID(), and geo::TPCID::TPC.

Referenced by CheckShowerHits(), ConstructTrack(), and MakeSpacePoints().

2096  {
2097 
2098  TVector2 wireTickPos = TVector2(-999., -999.);
2099 
2100  double pointPosition[3] = {point.X(), point.Y(), point.Z()};
2101 
2102  geo::TPCID tpcID = fGeom->FindTPCAtPosition(pointPosition);
2103  int tpc = 0;
2104  if (tpcID.isValid)
2105  tpc = tpcID.TPC;
2106  else
2107  return wireTickPos;
2108 
2109  // Construct wire ID for this point projected onto the plane
2110  geo::PlaneID planeID = geo::PlaneID(cryostat, tpc, plane);
2111  geo::WireID wireID;
2112  try{
2113  wireID = fGeom->NearestWireID(point, planeID);
2114  }
2115  catch(geo::InvalidWireError const& e) {
2116  wireID = e.suggestedWireID(); // pick the closest valid wire
2117  }
2118 
2119  wireTickPos = TVector2(GlobalWire(wireID),
2120  fDetProp->ConvertXToTicks(point.X(), planeID));
2121 
2122  // wireTickPos = TVector2(fGeom->WireCoordinate(point.Y(), point.Z(), planeID.Plane, tpc % 2, planeID.Cryostat),
2123  // fDetProp->ConvertXToTicks(point.X(), planeID.Plane, tpc % 2, planeID.Cryostat));
2124 
2125  //return wireTickPos;
2126  return HitPosition(wireTickPos, planeID);
2127 
2128 }
double GlobalWire(const geo::WireID &wireID)
Find the global wire position.
The data type to uniquely identify a Plane.
Definition: geo_types.h:250
bool isValid
Whether this ID points to a valid element.
Definition: geo_types.h:129
TVector2 HitPosition(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in units of cm.
virtual double ConvertXToTicks(double X, int p, int t, int c) const =0
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
The data type to uniquely identify a TPC.
Definition: geo_types.h:195
art::ServiceHandle< geo::Geometry > fGeom
Definition: EMShowerAlg.h:234
detinfo::DetectorProperties const * fDetProp
Definition: EMShowerAlg.h:235
Exception thrown on invalid wire number.
Definition: Exceptions.h:42
geo::WireID NearestWireID(geo::Point_t const &point, geo::PlaneID const &planeid) const
Returns the ID of wire closest to position in the specified TPC.
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:203
Float_t e
Definition: plot.C:34
geo::WireID suggestedWireID() const
Returns a better wire ID.
Definition: Exceptions.h:120
std::map< double, int > shower::EMShowerAlg::RelativeWireWidth ( const std::map< int, std::vector< art::Ptr< recob::Hit > > > &  showerHitsMap)
private

Determines the 'relative wire width', i.e. how spread a shower is across wires of each plane relative to the others If a shower travels along the wire directions in a particular view, it will have a smaller wire width in that view Returns a map relating these widths to each plane

Definition at line 1677 of file EMShowerAlg.cxx.

References fGeom, HitCoordinates(), geo::GeometryCore::MaxPlanes(), lar::dump::vector(), and X.

Referenced by GetPlanePermutations(), and OrderShowerHits().

1677  {
1678 
1679  // Get the wire widths
1680  std::map<int,int> planeWireLength;
1681  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt)
1682  planeWireLength[showerHitsIt->first] = TMath::Abs(HitCoordinates(showerHitsIt->second.front()).X() - HitCoordinates(showerHitsIt->second.back()).X());
1683 
1684  // Find the relative wire width for each plane with respect to the others
1685  std::map<int,double> planeOtherWireLengths;
1686  for (std::map<int,int>::iterator planeWireLengthIt = planeWireLength.begin(); planeWireLengthIt != planeWireLength.end(); ++planeWireLengthIt) {
1687  double quad = 0.;
1688  for (int plane = 0; plane < (int)fGeom->MaxPlanes(); ++plane)
1689  if (plane != planeWireLengthIt->first and planeWireLength.count(plane))
1690  quad += TMath::Power(planeWireLength[plane],2);
1691  quad = TMath::Sqrt(quad);
1692  planeOtherWireLengths[planeWireLengthIt->first] = planeWireLength[planeWireLengthIt->first] / (double)quad;
1693  }
1694 
1695  // Order these backwards
1696  std::map<double,int> wireWidthMap;
1697  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt)
1698  wireWidthMap[planeOtherWireLengths.at(showerHitsIt->first)] = showerHitsIt->first;
1699 
1700  return wireWidthMap;
1701 
1702 }
intermediate_table::iterator iterator
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.
art::ServiceHandle< geo::Geometry > fGeom
Definition: EMShowerAlg.h:234
TVector2 HitCoordinates(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in global wire/tick space.
Float_t X
Definition: plot.C:39
TVector2 shower::EMShowerAlg::ShowerCentre ( const std::vector< art::Ptr< recob::Hit > > &  showerHits)
private

Returns the charge-weighted shower centre.

Definition at line 1729 of file EMShowerAlg.cxx.

References HitPosition(), and lar::dump::vector().

Referenced by FindOrderOfHits(), and ShowerHitRMS().

1729  {
1730 
1731  TVector2 pos, chargePoint = TVector2(0,0);
1732  double totalCharge = 0;
1733  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hit = showerHits.begin(); hit != showerHits.end(); ++hit) {
1734  pos = HitPosition(*hit);
1735  chargePoint += (*hit)->Integral() * pos;
1736  totalCharge += (*hit)->Integral();
1737  }
1738  TVector2 centre = chargePoint / totalCharge;
1739 
1740  return centre;
1741 
1742 }
TVector2 HitPosition(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in units of cm.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
Detector simulation of raw signals on wires.
TVector2 shower::EMShowerAlg::ShowerDirection ( const std::vector< art::Ptr< recob::Hit > > &  showerHits)
private

Returns a rough charge-weighted shower 'direction' given the hits in the shower.

Definition at line 1704 of file EMShowerAlg.cxx.

References HitPosition(), lar::dump::vector(), and weight.

Referenced by FindOrderOfHits(), ShowerHitRMS(), and ShowerHitRMSGradient().

1704  {
1705 
1706  TVector2 pos;
1707  //double weight;
1708  double weight = 1;
1709  //int nhits = 0;
1710  double sumx=0., sumy=0., sumx2=0., sumxy=0., sumweight = 0.;
1711  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hit = showerHits.begin(); hit != showerHits.end(); ++hit) {
1712  //++nhits;
1713  pos = HitPosition(*hit);
1714  weight = TMath::Power((*hit)->Integral(),2);
1715  sumweight += weight;
1716  sumx += weight * pos.X();
1717  sumy += weight * pos.Y();
1718  sumx2 += weight * pos.X() * pos.X();
1719  sumxy += weight * pos.X() * pos.Y();
1720  }
1721  //double gradient = (nhits * sumxy - sumx * sumy) / (nhits * sumx2 - sumx * sumx);
1722  double gradient = (sumweight * sumxy - sumx * sumy) / (sumweight * sumx2 - sumx * sumx);
1723  TVector2 direction = TVector2(1,gradient).Unit();
1724 
1725  return direction;
1726 
1727 }
TVector2 HitPosition(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in units of cm.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
Detector simulation of raw signals on wires.
double weight
Definition: plottest35.C:25
double shower::EMShowerAlg::ShowerHitRMS ( const std::vector< art::Ptr< recob::Hit > > &  showerHits)
private

Returns the RMS of the hits from the central shower 'axis' along the length of the shower.

Definition at line 1744 of file EMShowerAlg.cxx.

References HitPosition(), proj, ShowerCentre(), ShowerDirection(), and lar::dump::vector().

Referenced by GetPlanePermutations(), and OrderShowerHits().

1744  {
1745 
1746  TVector2 direction = ShowerDirection(showerHits);
1747  TVector2 centre = ShowerCentre(showerHits);
1748 
1749  std::vector<double> distanceToAxis;
1750  for (std::vector<art::Ptr<recob::Hit> >::const_iterator showerHitsIt = showerHits.begin(); showerHitsIt != showerHits.end(); ++showerHitsIt) {
1751  TVector2 proj = (HitPosition(*showerHitsIt) - centre).Proj(direction) + centre;
1752  distanceToAxis.push_back((HitPosition(*showerHitsIt) - proj).Mod());
1753  }
1754  double RMS = TMath::RMS(distanceToAxis.begin(), distanceToAxis.end());
1755 
1756  return RMS;
1757 
1758 }
TVector2 HitPosition(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in units of cm.
TVector2 ShowerDirection(const std::vector< art::Ptr< recob::Hit > > &showerHits)
Returns a rough charge-weighted shower &#39;direction&#39; given the hits in the shower.
TVector2 ShowerCentre(const std::vector< art::Ptr< recob::Hit > > &showerHits)
Returns the charge-weighted shower centre.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
Float_t proj
Definition: plot.C:34
double shower::EMShowerAlg::ShowerHitRMSGradient ( const std::vector< art::Ptr< recob::Hit > > &  showerHits,
TVector2  trueStart = TVector2(0,0) 
)
private

Returns the gradient of the RMS vs shower segment graph.

Definition at line 1760 of file EMShowerAlg.cxx.

References fMakeRMSGradientPlot, fNumShowerSegments, HitPosition(), proj, ShowerDirection(), lar::dump::vector(), and weight.

Referenced by GetPlanePermutations(), and OrderShowerHits().

1760  {
1761 
1762  // Don't forget to clean up the header file!
1763 
1764  // Find a rough shower 'direction' and centre
1765  TVector2 direction = ShowerDirection(showerHits);
1766 
1767  //std::cout << std::endl << "Number of hits in this shower: " << showerHits.size() << std::endl;
1768 
1769  // for (int i = 0; i < 100; ++i) {
1770 
1771  // // Bin the hits into discreet chunks
1772  // //int nSegmentHits = fNumSegmentHits;
1773  // int nSegmentHits = i;
1774  // int nShowerSegments = showerHits.size() / (double)nSegmentHits;
1775  // //int nShowerSegments = fNumShowerSegments;
1776  // double lengthOfShower = (HitPosition(showerHits.back()) - HitPosition(showerHits.front())).Mod();
1777  // double lengthOfSegment = lengthOfShower / (double)nShowerSegments;
1778  // std::map<int,std::vector<art::Ptr<recob::Hit> > > showerSegments;
1779  // std::map<int,double> segmentCharge;
1780  // for (std::vector<art::Ptr<recob::Hit> >::const_iterator showerHitsIt = showerHits.begin(); showerHitsIt != showerHits.end(); ++showerHitsIt) {
1781  // showerSegments[(int)(HitPosition(*showerHitsIt)-HitPosition(showerHits.front())).Mod() / lengthOfSegment].push_back(*showerHitsIt);
1782  // segmentCharge[(int)(HitPosition(*showerHitsIt)-HitPosition(showerHits.front())).Mod() / lengthOfSegment] += (*showerHitsIt)->Integral();
1783  // }
1784 
1785  // TGraph* graph = new TGraph();
1786  // std::vector<std::pair<int,double> > binVsRMS;
1787 
1788  // // Loop over the bins to find the distribution of hits as the shower progresses
1789  // for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator showerSegmentIt = showerSegments.begin(); showerSegmentIt != showerSegments.end(); ++showerSegmentIt) {
1790 
1791  // // Get the mean position of the hits in this bin
1792  // TVector2 meanPosition(0,0);
1793  // for (std::vector<art::Ptr<recob::Hit> >::iterator hitInSegmentIt = showerSegmentIt->second.begin(); hitInSegmentIt != showerSegmentIt->second.end(); ++hitInSegmentIt)
1794  // meanPosition += HitPosition(*hitInSegmentIt);
1795  // meanPosition /= (double)showerSegmentIt->second.size();
1796 
1797  // // Get the RMS of this bin
1798  // std::vector<double> distanceToAxisBin;
1799  // for (std::vector<art::Ptr<recob::Hit> >::iterator hitInSegmentIt = showerSegmentIt->second.begin(); hitInSegmentIt != showerSegmentIt->second.end(); ++hitInSegmentIt) {
1800  // TVector2 proj = (HitPosition(*hitInSegmentIt) - meanPosition).Proj(direction) + meanPosition;
1801  // distanceToAxisBin.push_back((HitPosition(*hitInSegmentIt) - proj).Mod());
1802  // }
1803 
1804  // double RMSBin = TMath::RMS(distanceToAxisBin.begin(), distanceToAxisBin.end());
1805  // binVsRMS.push_back(std::make_pair(showerSegmentIt->first, RMSBin));
1806  // if (fMakeRMSGradientPlot)
1807  // graph->SetPoint(graph->GetN(), showerSegmentIt->first, RMSBin);
1808 
1809  // }
1810 
1811  // // Get the gradient of the RMS-bin plot
1812 
1813  // // OLD
1814  // int nhits1 = 0;
1815  // double sumx1=0., sumy1=0., sumx21=0., sumxy1=0.;
1816  // for (std::vector<std::pair<int,double> >::iterator binVsRMSIt = binVsRMS.begin(); binVsRMSIt != binVsRMS.end(); ++binVsRMSIt) {
1817  // ++nhits1;
1818  // sumx1 += binVsRMSIt->first;
1819  // sumy1 += binVsRMSIt->second;
1820  // sumx21 += binVsRMSIt->first * binVsRMSIt->first;
1821  // sumxy1 += binVsRMSIt->first * binVsRMSIt->second;
1822  // }
1823  // double RMSgradient1 = (nhits1 * sumxy1 - sumx1 * sumy1) / (nhits1 * sumx21 - sumx1 * sumx1);
1824 
1825  // // NEW
1826  // double sumx=0., sumy=0., sumx2=0., sumxy=0., sumweight = 0.;
1827  // for (std::vector<std::pair<int,double> >::iterator binVsRMSIt = binVsRMS.begin(); binVsRMSIt != binVsRMS.end(); ++binVsRMSIt) {
1828  // //double weight = showerSegments.at(binVsRMSIt->first).size();
1829  // double weight = TMath::Power(segmentCharge.at(binVsRMSIt->first),2);
1830  // sumweight += weight;
1831  // sumx += weight * binVsRMSIt->first;
1832  // sumy += weight * binVsRMSIt->second;
1833  // sumx2 += weight * binVsRMSIt->first * binVsRMSIt->first;
1834  // sumxy += weight * binVsRMSIt->first * binVsRMSIt->second;
1835  // }
1836  // double RMSgradient = (sumweight * sumxy - sumx * sumy) / (sumweight * sumx2 - sumx * sumx);
1837 
1838  // // PCA
1839  // TPrincipal* pca = new TPrincipal(2,"");
1840  // double point[2];
1841  // for (std::vector<std::pair<int,double> >::iterator binVsRMSIt = binVsRMS.begin(); binVsRMSIt != binVsRMS.end(); ++binVsRMSIt) {
1842  // if (fDebug > 2)
1843  // std::cout << "Number of hits in segment " << binVsRMSIt->first << " is " << showerSegments.at(binVsRMSIt->first).size() << std::endl;
1844  // for (int nhit = 0; nhit < (int)showerSegments.at(binVsRMSIt->first).size(); ++nhit) {
1845  // point[0] = binVsRMSIt->first;
1846  // point[1] = binVsRMSIt->second;
1847  // pca->AddRow(point);
1848  // }
1849  // }
1850  // pca->MakePrincipals();
1851  // TVector2 RMSgradientPCA = TVector2( (*pca->GetEigenVectors())[0][0], (*pca->GetEigenVectors())[1][0] ).Unit();
1852 
1853  // if (fDebug > 1)
1854  // std::cout << "RMS gradient without weighting: " << RMSgradient1 << ", and with weighting: " << RMSgradient << "; PCA with weighting: " << RMSgradientPCA.Y()/RMSgradientPCA.X() << std::endl;
1855 
1856  // if (fMakeRMSGradientPlot) {
1857  // TVector2 direction = TVector2(1,RMSgradient).Unit();
1858  // TVector2 direction1 = TVector2(1,RMSgradient1).Unit();
1859  // TCanvas* canv = new TCanvas();
1860  // graph->Draw();
1861  // TVector2 centre = TVector2(graph->GetMean(1), graph->GetMean(2));
1862  // TLine line, line1, line2;
1863  // line.SetLineColor(3);
1864  // line1.SetLineColor(4);
1865  // line2.SetLineColor(5);
1866  // line.DrawLine(centre.X()-1000*direction.X(),centre.Y()-1000*direction.Y(),centre.X()+1000*direction.X(),centre.Y()+1000*direction.Y());
1867  // line1.DrawLine(centre.X()-1000*direction1.X(),centre.Y()-1000*direction1.Y(),centre.X()+1000*direction1.X(),centre.Y()+1000*direction1.Y());
1868  // line2.DrawLine(centre.X()-1000*RMSgradientPCA.X(),centre.Y()-1000*RMSgradientPCA.Y(),centre.X()+1000*RMSgradientPCA.X(),centre.Y()+1000*RMSgradientPCA.Y());
1869  // canv->SaveAs("RMSGradient.png");
1870  // delete canv;
1871  // }
1872  // delete graph; delete pca;
1873 
1874  // //std::cout << "Number of hits per bin " << i << " gives gradient of " << RMSgradient << std::endl;
1875 
1876  // double distanceFromStart = 0, distanceFromEnd = 0;
1877  // if (RMSgradient > 0) {
1878  // distanceFromStart = (trueStart - HitPosition(showerHits.front())).Mod();
1879  // distanceFromEnd = (trueStart - HitPosition(showerHits.back())).Mod();
1880  // }
1881  // if (RMSgradient < 0) {
1882  // distanceFromStart = (trueStart - HitPosition(showerHits.back())).Mod();
1883  // distanceFromEnd = (trueStart - HitPosition(showerHits.front())).Mod();
1884  // }
1885  // bool correct = distanceFromStart < distanceFromEnd;
1886  // hNumHitsInSegment->Fill(i,correct);
1887 
1888  // }
1889 
1890 
1891 
1892 
1893  // for (int i = 0; i < 100; ++i) {
1894 
1895  // // Bin the hits into discreet chunks
1896  // int nShowerSegments = i;
1897  // double lengthOfShower = (HitPosition(showerHits.back()) - HitPosition(showerHits.front())).Mod();
1898  // double lengthOfSegment = lengthOfShower / (double)nShowerSegments;
1899  // std::map<int,std::vector<art::Ptr<recob::Hit> > > showerSegments;
1900  // std::map<int,double> segmentCharge;
1901  // for (std::vector<art::Ptr<recob::Hit> >::const_iterator showerHitsIt = showerHits.begin(); showerHitsIt != showerHits.end(); ++showerHitsIt) {
1902  // showerSegments[(int)(HitPosition(*showerHitsIt)-HitPosition(showerHits.front())).Mod() / lengthOfSegment].push_back(*showerHitsIt);
1903  // segmentCharge[(int)(HitPosition(*showerHitsIt)-HitPosition(showerHits.front())).Mod() / lengthOfSegment] += (*showerHitsIt)->Integral();
1904  // }
1905 
1906  // TGraph* graph = new TGraph();
1907  // std::vector<std::pair<int,double> > binVsRMS;
1908 
1909  // // Loop over the bins to find the distribution of hits as the shower progresses
1910  // for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator showerSegmentIt = showerSegments.begin(); showerSegmentIt != showerSegments.end(); ++showerSegmentIt) {
1911 
1912  // // Get the mean position of the hits in this bin
1913  // TVector2 meanPosition(0,0);
1914  // for (std::vector<art::Ptr<recob::Hit> >::iterator hitInSegmentIt = showerSegmentIt->second.begin(); hitInSegmentIt != showerSegmentIt->second.end(); ++hitInSegmentIt)
1915  // meanPosition += HitPosition(*hitInSegmentIt);
1916  // meanPosition /= (double)showerSegmentIt->second.size();
1917 
1918  // // Get the RMS of this bin
1919  // std::vector<double> distanceToAxisBin;
1920  // for (std::vector<art::Ptr<recob::Hit> >::iterator hitInSegmentIt = showerSegmentIt->second.begin(); hitInSegmentIt != showerSegmentIt->second.end(); ++hitInSegmentIt) {
1921  // TVector2 proj = (HitPosition(*hitInSegmentIt) - meanPosition).Proj(direction) + meanPosition;
1922  // distanceToAxisBin.push_back((HitPosition(*hitInSegmentIt) - proj).Mod());
1923  // }
1924 
1925  // double RMSBin = TMath::RMS(distanceToAxisBin.begin(), distanceToAxisBin.end());
1926  // binVsRMS.push_back(std::make_pair(showerSegmentIt->first, RMSBin));
1927  // if (fMakeRMSGradientPlot)
1928  // graph->SetPoint(graph->GetN(), showerSegmentIt->first, RMSBin);
1929 
1930  // }
1931 
1932  // // Get the gradient of the RMS-bin plot
1933 
1934  // // OLD
1935  // int nhits1 = 0;
1936  // double sumx1=0., sumy1=0., sumx21=0., sumxy1=0.;
1937  // for (std::vector<std::pair<int,double> >::iterator binVsRMSIt = binVsRMS.begin(); binVsRMSIt != binVsRMS.end(); ++binVsRMSIt) {
1938  // ++nhits1;
1939  // sumx1 += binVsRMSIt->first;
1940  // sumy1 += binVsRMSIt->second;
1941  // sumx21 += binVsRMSIt->first * binVsRMSIt->first;
1942  // sumxy1 += binVsRMSIt->first * binVsRMSIt->second;
1943  // }
1944  // double RMSgradient1 = (nhits1 * sumxy1 - sumx1 * sumy1) / (nhits1 * sumx21 - sumx1 * sumx1);
1945 
1946  // // NEW
1947  // double sumx=0., sumy=0., sumx2=0., sumxy=0., sumweight = 0.;
1948  // for (std::vector<std::pair<int,double> >::iterator binVsRMSIt = binVsRMS.begin(); binVsRMSIt != binVsRMS.end(); ++binVsRMSIt) {
1949  // //double weight = showerSegments.at(binVsRMSIt->first).size();
1950  // double weight = TMath::Power(segmentCharge.at(binVsRMSIt->first),2);
1951  // sumweight += weight;
1952  // sumx += weight * binVsRMSIt->first;
1953  // sumy += weight * binVsRMSIt->second;
1954  // sumx2 += weight * binVsRMSIt->first * binVsRMSIt->first;
1955  // sumxy += weight * binVsRMSIt->first * binVsRMSIt->second;
1956  // }
1957  // double RMSgradient = (sumweight * sumxy - sumx * sumy) / (sumweight * sumx2 - sumx * sumx);
1958 
1959  // // PCA
1960  // TPrincipal* pca = new TPrincipal(2,"");
1961  // double point[2];
1962  // for (std::vector<std::pair<int,double> >::iterator binVsRMSIt = binVsRMS.begin(); binVsRMSIt != binVsRMS.end(); ++binVsRMSIt) {
1963  // if (fDebug > 2)
1964  // std::cout << "Number of hits in segment " << binVsRMSIt->first << " is " << showerSegments.at(binVsRMSIt->first).size() << std::endl;
1965  // for (int nhit = 0; nhit < (int)showerSegments.at(binVsRMSIt->first).size(); ++nhit) {
1966  // point[0] = binVsRMSIt->first;
1967  // point[1] = binVsRMSIt->second;
1968  // pca->AddRow(point);
1969  // }
1970  // }
1971  // pca->MakePrincipals();
1972  // TVector2 RMSgradientPCA = TVector2( (*pca->GetEigenVectors())[0][0], (*pca->GetEigenVectors())[1][0] ).Unit();
1973 
1974  // if (fDebug > 1)
1975  // std::cout << "RMS gradient without weighting: " << RMSgradient1 << ", and with weighting: " << RMSgradient << "; PCA with weighting: " << RMSgradientPCA.Y()/RMSgradientPCA.X() << std::endl;
1976 
1977  // if (fMakeRMSGradientPlot) {
1978  // TVector2 direction = TVector2(1,RMSgradient).Unit();
1979  // TVector2 direction1 = TVector2(1,RMSgradient1).Unit();
1980  // TCanvas* canv = new TCanvas();
1981  // graph->Draw();
1982  // TVector2 centre = TVector2(graph->GetMean(1), graph->GetMean(2));
1983  // TLine line, line1, line2;
1984  // line.SetLineColor(3);
1985  // line1.SetLineColor(4);
1986  // line2.SetLineColor(5);
1987  // line.DrawLine(centre.X()-1000*direction.X(),centre.Y()-1000*direction.Y(),centre.X()+1000*direction.X(),centre.Y()+1000*direction.Y());
1988  // line1.DrawLine(centre.X()-1000*direction1.X(),centre.Y()-1000*direction1.Y(),centre.X()+1000*direction1.X(),centre.Y()+1000*direction1.Y());
1989  // line2.DrawLine(centre.X()-1000*RMSgradientPCA.X(),centre.Y()-1000*RMSgradientPCA.Y(),centre.X()+1000*RMSgradientPCA.X(),centre.Y()+1000*RMSgradientPCA.Y());
1990  // canv->SaveAs("RMSGradient.png");
1991  // delete canv;
1992  // }
1993  // delete graph; delete pca;
1994 
1995  // //std::cout << "Number of hits per bin " << i << " gives gradient of " << RMSgradient << std::endl;
1996 
1997  // double distanceFromStart = 0, distanceFromEnd = 0;
1998  // if (RMSgradient > 0) {
1999  // distanceFromStart = (trueStart - HitPosition(showerHits.front())).Mod();
2000  // distanceFromEnd = (trueStart - HitPosition(showerHits.back())).Mod();
2001  // }
2002  // if (RMSgradient < 0) {
2003  // distanceFromStart = (trueStart - HitPosition(showerHits.back())).Mod();
2004  // distanceFromEnd = (trueStart - HitPosition(showerHits.front())).Mod();
2005  // }
2006  // bool correct = distanceFromStart < distanceFromEnd;
2007  // hNumSegments->Fill(i,correct);
2008 
2009  // }
2010 
2011 
2012 
2013 
2014 
2015 
2016 
2017 
2018 
2019 
2020 
2021 
2022 
2023 
2024 
2025 
2026  // Bin the hits into discreet chunks
2027  int nShowerSegments = fNumShowerSegments;
2028  double lengthOfShower = (HitPosition(showerHits.back()) - HitPosition(showerHits.front())).Mod();
2029  double lengthOfSegment = lengthOfShower / (double)nShowerSegments;
2030  std::map<int,std::vector<art::Ptr<recob::Hit> > > showerSegments;
2031  std::map<int,double> segmentCharge;
2032  for (std::vector<art::Ptr<recob::Hit> >::const_iterator showerHitsIt = showerHits.begin(); showerHitsIt != showerHits.end(); ++showerHitsIt) {
2033  showerSegments[(int)(HitPosition(*showerHitsIt)-HitPosition(showerHits.front())).Mod() / lengthOfSegment].push_back(*showerHitsIt);
2034  segmentCharge[(int)(HitPosition(*showerHitsIt)-HitPosition(showerHits.front())).Mod() / lengthOfSegment] += (*showerHitsIt)->Integral();
2035  }
2036 
2037  TGraph* graph = new TGraph();
2038  std::vector<std::pair<int,double> > binVsRMS;
2039 
2040  // Loop over the bins to find the distribution of hits as the shower progresses
2041  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator showerSegmentIt = showerSegments.begin(); showerSegmentIt != showerSegments.end(); ++showerSegmentIt) {
2042 
2043  // Get the mean position of the hits in this bin
2044  TVector2 meanPosition(0,0);
2045  for (std::vector<art::Ptr<recob::Hit> >::iterator hitInSegmentIt = showerSegmentIt->second.begin(); hitInSegmentIt != showerSegmentIt->second.end(); ++hitInSegmentIt)
2046  meanPosition += HitPosition(*hitInSegmentIt);
2047  meanPosition /= (double)showerSegmentIt->second.size();
2048 
2049  // Get the RMS of this bin
2050  std::vector<double> distanceToAxisBin;
2051  for (std::vector<art::Ptr<recob::Hit> >::iterator hitInSegmentIt = showerSegmentIt->second.begin(); hitInSegmentIt != showerSegmentIt->second.end(); ++hitInSegmentIt) {
2052  TVector2 proj = (HitPosition(*hitInSegmentIt) - meanPosition).Proj(direction) + meanPosition;
2053  distanceToAxisBin.push_back((HitPosition(*hitInSegmentIt) - proj).Mod());
2054  }
2055 
2056  double RMSBin = TMath::RMS(distanceToAxisBin.begin(), distanceToAxisBin.end());
2057  binVsRMS.push_back(std::make_pair(showerSegmentIt->first, RMSBin));
2059  graph->SetPoint(graph->GetN(), showerSegmentIt->first, RMSBin);
2060 
2061  }
2062 
2063  // Get the gradient of the RMS-bin plot
2064  double sumx=0., sumy=0., sumx2=0., sumxy=0., sumweight = 0.;
2065  for (std::vector<std::pair<int,double> >::iterator binVsRMSIt = binVsRMS.begin(); binVsRMSIt != binVsRMS.end(); ++binVsRMSIt) {
2066  //double weight = showerSegments.at(binVsRMSIt->first).size();
2067  //double weight = 1;
2068  double weight = segmentCharge.at(binVsRMSIt->first);
2069  sumweight += weight;
2070  sumx += weight * binVsRMSIt->first;
2071  sumy += weight * binVsRMSIt->second;
2072  sumx2 += weight * binVsRMSIt->first * binVsRMSIt->first;
2073  sumxy += weight * binVsRMSIt->first * binVsRMSIt->second;
2074  }
2075  double RMSgradient = (sumweight * sumxy - sumx * sumy) / (sumweight * sumx2 - sumx * sumx);
2076 
2077  if (fMakeRMSGradientPlot) {
2078  TVector2 direction = TVector2(1,RMSgradient).Unit();
2079  TCanvas* canv = new TCanvas();
2080  graph->Draw();
2081  graph->GetXaxis()->SetTitle("Shower segment");
2082  graph->GetYaxis()->SetTitle("RMS of hit distribution");
2083  TVector2 centre = TVector2(graph->GetMean(1), graph->GetMean(2));
2084  TLine line;
2085  line.SetLineColor(2);
2086  line.DrawLine(centre.X()-1000*direction.X(),centre.Y()-1000*direction.Y(),centre.X()+1000*direction.X(),centre.Y()+1000*direction.Y());
2087  canv->SaveAs("RMSGradient.png");
2088  delete canv;
2089  }
2090  delete graph;
2091 
2092  return RMSgradient;
2093 
2094 }
TVector2 HitPosition(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in units of cm.
TVector2 ShowerDirection(const std::vector< art::Ptr< recob::Hit > > &showerHits)
Returns a rough charge-weighted shower &#39;direction&#39; given the hits in the shower.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
double weight
Definition: plottest35.C:25
Float_t proj
Definition: plot.C:34
Int_t shower::EMShowerAlg::WeightedFit ( const Int_t  n,
const Double_t *  x,
const Double_t *  y,
const Double_t *  w,
Double_t *  parm 
)

<Tingjun to="" document>="">

Definition at line 2160 of file EMShowerAlg.cxx.

References n.

Referenced by FindInitialTrackHits().

2160  {
2161 
2162  Double_t sumx=0.;
2163  Double_t sumx2=0.;
2164  Double_t sumy=0.;
2165  Double_t sumy2=0.;
2166  Double_t sumxy=0.;
2167  Double_t sumw=0.;
2168  Double_t eparm[2];
2169 
2170  parm[0] = 0.;
2171  parm[1] = 0.;
2172  eparm[0] = 0.;
2173  eparm[1] = 0.;
2174 
2175  for (Int_t i=0; i<n; i++) {
2176  sumx += x[i]*w[i];
2177  sumx2 += x[i]*x[i]*w[i];
2178  sumy += y[i]*w[i];
2179  sumy2 += y[i]*y[i]*w[i];
2180  sumxy += x[i]*y[i]*w[i];
2181  sumw += w[i];
2182  }
2183 
2184  if (sumx2*sumw-sumx*sumx==0.) return 1;
2185  if (sumx2-sumx*sumx/sumw==0.) return 1;
2186 
2187  parm[0] = (sumy*sumx2-sumx*sumxy)/(sumx2*sumw-sumx*sumx);
2188  parm[1] = (sumxy-sumx*sumy/sumw)/(sumx2-sumx*sumx/sumw);
2189 
2190  eparm[0] = sumx2*(sumx2*sumw-sumx*sumx);
2191  eparm[1] = (sumx2-sumx*sumx/sumw);
2192 
2193  if (eparm[0]<0. || eparm[1]<0.) return 1;
2194 
2195  eparm[0] = sqrt(eparm[0])/(sumx2*sumw-sumx*sumx);
2196  eparm[1] = sqrt(eparm[1])/(sumx2-sumx*sumx/sumw);
2197 
2198  return 0;
2199 
2200 }
Float_t x
Definition: compare.C:6
Float_t y
Definition: compare.C:6
Char_t n[5]
Float_t w
Definition: plot.C:23
int shower::EMShowerAlg::WorstPlane ( const std::map< int, std::vector< art::Ptr< recob::Hit > > > &  showerHitsMap)
private

Returns the plane which is determined to be the least likely to be correct.

Definition at line 2130 of file EMShowerAlg.cxx.

References fDebug, fGeom, for(), HitCoordinates(), geo::GeometryCore::MaxPlanes(), lar::dump::vector(), and X.

Referenced by MakeInitialTrack().

2130  {
2131 
2132  // Get the width of the shower in wire coordinate
2133  std::map<int,int> planeWireLength;
2134  std::map<int,double> planeOtherWireLengths;
2135  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt)
2136  planeWireLength[showerHitsIt->first] = TMath::Abs(HitCoordinates(showerHitsIt->second.front()).X() - HitCoordinates(showerHitsIt->second.back()).X());
2137  for (std::map<int,int>::iterator planeWireLengthIt = planeWireLength.begin(); planeWireLengthIt != planeWireLength.end(); ++planeWireLengthIt) {
2138  double quad = 0.;
2139  for (int plane = 0; plane < (int)fGeom->MaxPlanes(); ++plane)
2140  if (plane != planeWireLengthIt->first and planeWireLength.count(plane))
2141  quad += TMath::Power(planeWireLength[plane],2);
2142  quad = TMath::Sqrt(quad);
2143  planeOtherWireLengths[planeWireLengthIt->first] = planeWireLength[planeWireLengthIt->first] / (double)quad;
2144  }
2145 
2146  if (fDebug > 1)
2147  for (std::map<int,double>::const_iterator planeOtherWireLengthIt = planeOtherWireLengths.begin(); planeOtherWireLengthIt != planeOtherWireLengths.end(); ++planeOtherWireLengthIt)
2148  std::cout << "Plane " << planeOtherWireLengthIt->first << " has " << planeWireLength[planeOtherWireLengthIt->first] << " wire width and therefore has relative width in wire of " << planeOtherWireLengthIt->second << std::endl;
2149 
2150  std::map<double,int> wireWidthMap;
2151  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt) {
2152  double wireWidth = planeWireLength.at(showerHitsIt->first);
2153  wireWidthMap[wireWidth] = showerHitsIt->first;
2154  }
2155 
2156  return wireWidthMap.begin()->second;
2157 
2158 }
intermediate_table::iterator iterator
for(int i=0;i< 401;i++)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.
intermediate_table::const_iterator const_iterator
art::ServiceHandle< geo::Geometry > fGeom
Definition: EMShowerAlg.h:234
TVector2 HitCoordinates(art::Ptr< recob::Hit > const &hit)
Return the coordinates of this hit in global wire/tick space.
Float_t X
Definition: plot.C:39

Member Data Documentation

art::ServiceHandle<cheat::BackTrackerService> shower::EMShowerAlg::bt_serv
private

Definition at line 249 of file EMShowerAlg.h.

calo::CalorimetryAlg shower::EMShowerAlg::fCalorimetryAlg
private

Definition at line 240 of file EMShowerAlg.h.

Referenced by FinddEdx(), and MakeShower().

double shower::EMShowerAlg::fdEdxTrackLength
private

Definition at line 226 of file EMShowerAlg.h.

Referenced by EMShowerAlg(), FinddEdx(), and MakeShower().

std::string shower::EMShowerAlg::fDetector
private

Definition at line 243 of file EMShowerAlg.h.

Referenced by EMShowerAlg(), and GlobalWire().

bool shower::EMShowerAlg::fMakeGradientPlot
private

Definition at line 253 of file EMShowerAlg.h.

Referenced by EMShowerAlg(), and FindOrderOfHits().

bool shower::EMShowerAlg::fMakeRMSGradientPlot
private

Definition at line 253 of file EMShowerAlg.h.

Referenced by EMShowerAlg(), and ShowerHitRMSGradient().

double shower::EMShowerAlg::fMinTrackLength
private

Definition at line 225 of file EMShowerAlg.h.

Referenced by AssociateClustersAndTracks(), and EMShowerAlg().

std::vector<unsigned int> shower::EMShowerAlg::fNfithits
private

Definition at line 230 of file EMShowerAlg.h.

Referenced by EMShowerAlg(), and FindInitialTrackHits().

unsigned int shower::EMShowerAlg::fNfitpass
private

Definition at line 229 of file EMShowerAlg.h.

Referenced by EMShowerAlg(), and FindInitialTrackHits().

int shower::EMShowerAlg::fNumShowerSegments
private

Definition at line 254 of file EMShowerAlg.h.

Referenced by EMShowerAlg(), and ShowerHitRMSGradient().

pma::ProjectionMatchingAlg shower::EMShowerAlg::fProjectionMatchingAlg
private

Definition at line 241 of file EMShowerAlg.h.

Referenced by ConstructTrack(), and MakeShower().

shower::ShowerEnergyAlg shower::EMShowerAlg::fShowerEnergyAlg
private

Definition at line 239 of file EMShowerAlg.h.

Referenced by MakeShower().

double shower::EMShowerAlg::fSpacePointSize
private

Definition at line 227 of file EMShowerAlg.h.

Referenced by EMShowerAlg(), and MakeSpacePoints().

std::vector<double> shower::EMShowerAlg::fToler
private

Definition at line 231 of file EMShowerAlg.h.

Referenced by EMShowerAlg(), and FindInitialTrackHits().

TProfile* shower::EMShowerAlg::hNumHitsInSegment
private

Definition at line 251 of file EMShowerAlg.h.

Referenced by EMShowerAlg().

TProfile * shower::EMShowerAlg::hNumSegments
private

Definition at line 251 of file EMShowerAlg.h.

Referenced by EMShowerAlg().

TH1I* shower::EMShowerAlg::hTrueDirection
private

Definition at line 250 of file EMShowerAlg.h.

Referenced by EMShowerAlg().

art::ServiceHandle<art::TFileService> shower::EMShowerAlg::tfs
private

Definition at line 236 of file EMShowerAlg.h.

Referenced by EMShowerAlg().


The documentation for this class was generated from the following files: