LArSoft  v06_85_00
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(), 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>(xyz, dircos, dEdx);
527 
528  return track;
529 
530 }
intermediate_table::iterator iterator
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
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)
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
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
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 532 of file EMShowerAlg.cxx.

References ConstructTrack().

533  {
534 
535  std::map<int,TVector2> showerCentreMap;
536 
537  return this->ConstructTrack(track1, track2, showerCentreMap);
538 
539 }
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 541 of file EMShowerAlg.cxx.

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

Referenced by MakeShower().

541  {
542 
543  double totalCharge = 0, totalDistance = 0, avHitTime = 0;
544  unsigned int nHits = 0;
545 
546  if (!track)
547  return -999;
548 
549  // size_t trajectory_point = 0;
550  // double wirePitch = fGeom->WirePitch(trackHits.at(0)->View(), 1, 0);
551  // double angleToVert = fGeom->WireAngleToVertical(trackHits.at(0)->View(), 1, 0) - 0.5*::util::pi<>();
552  // const TVector3& dir = track->DirectionAtPoint(trajectory_point);
553  // //(sin(angleToVert),cos(angleToVert)) is the direction perpendicular to wire
554  // double cosgamma = std::abs(std::sin(angleToVert)*dir.Y() +
555  // std::cos(angleToVert)*dir.Z());
556 
557  // if(cosgamma < 1.e-5)
558  // throw cet::exception("Track") << "cosgamma is basically 0, that can't be right\n";
559  // double pitch = wirePitch/cosgamma;
560 
561  // Get the pitch
562  double pitch = 0;
563  try { pitch = lar::util::TrackPitchInView(*track, trackHits.at(0)->View()); }
564  catch(...) { pitch = 0; }
565 
566  // Deal with large pitches
567  if (pitch > fdEdxTrackLength) {
568  double dEdx = fCalorimetryAlg.dEdx_AREA(*trackHits.begin(), pitch);
569  return dEdx;
570  }
571 
572  for (std::vector<art::Ptr<recob::Hit> >::const_iterator trackHitIt = trackHits.begin(); trackHitIt != trackHits.end(); ++trackHitIt) {
573  if (totalDistance + pitch < fdEdxTrackLength) {
574  totalDistance += pitch;
575  totalCharge += (*trackHitIt)->Integral();
576  avHitTime += (*trackHitIt)->PeakTime();
577  ++nHits;
578  }
579  }
580 
581  avHitTime /= (double)nHits;
582 
583  double dQdx = totalCharge / totalDistance;
584  double dEdx = fCalorimetryAlg.dEdx_AREA(dQdx, avHitTime, trackHits.at(0)->WireID().Plane);
585 
586  return dEdx;
587 
588 }
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 590 of file EMShowerAlg.cxx.

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

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

592  {
593 
598 
599  // // First, order the hits into the correct shower order in each plane
600  // if (fDebug > 1)
601  // std::cout << " ------------------ Ordering shower hits -------------------- " << std::endl;
602  // std::map<int,std::vector<art::Ptr<recob::Hit> > > showerHitsMap = OrderShowerHits(hits, plane);
603  // if (fDebug > 1)
604  // std::cout << " ------------------ End ordering shower hits -------------------- " << std::endl;
605 
606  // Now find the hits belonging to the track
607  if (fDebug > 1)
608  std::cout << " ------------------ Finding initial track hits -------------------- " << std::endl;
609  initialTrackHits = FindShowerStart(showerHitsMap);
610  if (fDebug > 1) {
611  std::cout << "Here are the initial shower hits... " << std::endl;
612  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator initialTrackHitsIt = initialTrackHits.begin(); initialTrackHitsIt != initialTrackHits.end(); ++initialTrackHitsIt) {
613  std::cout << " Plane " << initialTrackHitsIt->first << std::endl;
614  for (std::vector<art::Ptr<recob::Hit> >::iterator initialTrackHitIt = initialTrackHitsIt->second.begin(); initialTrackHitIt != initialTrackHitsIt->second.end(); ++initialTrackHitIt)
615  std::cout << " Hit is (" << HitCoordinates(*initialTrackHitIt).X() << " (real hit " << (*initialTrackHitIt)->WireID() << "), " << HitCoordinates(*initialTrackHitIt).Y() << ")" << std::endl;
616  }
617  }
618  if (fDebug > 1)
619  std::cout << " ------------------ End finding initial track hits -------------------- " << std::endl;
620 
621  // Now we have the track hits -- can make a track!
622  if (fDebug > 1)
623  std::cout << " ------------------ Finding initial track -------------------- " << std::endl;
624  initialTrack = MakeInitialTrack(initialTrackHits, showerHitsMap);
625  if (initialTrack and fDebug > 1) {
626  std::cout << "The track start is (" << initialTrack->Vertex().X() << ", " << initialTrack->Vertex().Y() << ", " << initialTrack->Vertex().Z() << ")" << std::endl;
627  std::cout << "The track direction is (" << initialTrack->VertexDirection().X() << ", " << initialTrack->VertexDirection().Y() << ", " << initialTrack->VertexDirection().Z() << ")" << std::endl;
628  }
629  if (fDebug > 1)
630  std::cout << " ------------------ End finding initial track -------------------- " << std::endl;
631 
632  // // Fill correct or incorrect direction histogram
633  // std::map<int,int> trackHits;
634  // for (art::PtrVector<recob::Hit>::const_iterator hitIt = hits.begin(); hitIt != hits.end(); ++hitIt)
635  // ++trackHits[FindTrackID(*hitIt)];
636  // int trueTrack = -9999;
637  // for (std::map<int,int>::iterator trackHitIt = trackHits.begin(); trackHitIt != trackHits.end(); ++trackHitIt)
638  // if (trackHitIt->second/(double)hits.size() > 0.8)
639  // trueTrack = trackHitIt->first;
640  // if (trueTrack != -9999) {
641  // const simb::MCParticle* trueParticle = backtracker->TrackIDToParticle(trueTrack);
642  // TVector3 trueStart = trueParticle->Position().Vect();
643  // if (initialTrack) {
644  // TVector3 recoStart = initialTrack->Vertex();
645  // if ((recoStart-trueStart).Mag() < 5)
646  // hTrueDirection->Fill(1);
647  // else
648  // hTrueDirection->Fill(0);
649  // }
650  // }
651  // else
652  // hTrueDirection->Fill(0);
653 
654  return;
655 
656 }
TVector3 VertexDirection() const
Covariance matrices are either set or not.
Definition: Track.h:247
std::map< int, std::vector< art::Ptr< recob::Hit > > > FindShowerStart(std::map< int, std::vector< art::Ptr< recob::Hit > > > const &orderedShowerMap)
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...
TVector3 Vertex() const
Covariance matrices are either set or not.
Definition: Track.h:245
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 1539 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().

1541  {
1542 
1543  // Find TPC for the vertex
1544  //std::cout<<"here"<<std::endl;
1545  double xyz[3];
1546  vertex->XYZ(xyz);
1547  //std::cout<<xyz[0]<<" "<<xyz[1]<<" "<<xyz[2]<<std::endl;
1548  geo::TPCID tpc = fGeom->FindTPCAtPosition(xyz);
1549  //std::cout<<tpc<<std::endl;
1550  //vertex cannot be projected into a TPC, find the TPC that has the most hits
1551  if (!tpc.isValid){
1552  std::map<geo::TPCID, unsigned int> tpcmap;
1553  unsigned maxhits = 0;
1554  for (auto const&hit : showerHits){
1555  ++tpcmap[geo::TPCID(hit->WireID())];
1556  }
1557  for (auto const&t : tpcmap){
1558  if (t.second > maxhits){
1559  maxhits = t.second;
1560  tpc = t.first;
1561  }
1562  }
1563  }
1564  //std::cout<<tpc<<std::endl;
1565  //if (!tpc.isValid&&showerHits.size()) tpc = geo::TPCID(showerHits[0]->WireID());
1566  if (!tpc.isValid) return;
1567  //std::cout<<"here 1"<<std::endl;
1568 
1569  double parm[2];
1570  int fitok = 0;
1571  std::vector<double> wfit;
1572  std::vector<double> tfit;
1573  std::vector<double> cfit;
1574 
1575  for (size_t i = 0; i<fNfitpass; ++i){
1576 
1577  // Fit a straight line through hits
1578  unsigned int nhits = 0;
1579  for (auto &hit: showerHits){
1580  //std::cout<<i<<" "<<hit->WireID()<<" "<<tpc<<std::endl;
1581  if (hit->WireID().TPC==tpc.TPC){
1582  TVector2 coord = HitCoordinates(hit);
1583  //std::cout<<i<<" "<<hit->WireID()<<" "<<hit->PeakTime()<<std::endl;
1584  if (i==0||(std::abs((coord.Y()-(parm[0]+coord.X()*parm[1]))*cos(atan(parm[1])))<fToler[i-1])||fitok==1){
1585  ++nhits;
1586  if (nhits==fNfithits[i]+1) break;
1587  wfit.push_back(coord.X());
1588  tfit.push_back(coord.Y());
1589  //cfit.push_back(hit->Integral());
1590  cfit.push_back(1.);
1591  if (i==fNfitpass-1) {
1592  trackHits.push_back(hit);
1593  }
1594  //std::cout<<*hit<<std::endl;
1595 //
1596 //<<hit->PeakTime()<<" "<<std::abs((coord.Y()-(parm[0]+coord.X()*parm[1]))*cos(atan(parm[1])))<<std::endl;
1597  }
1598  }
1599  }
1600 
1601  if (i<fNfitpass-1&&wfit.size()){
1602  fitok = WeightedFit(wfit.size(), &wfit[0], &tfit[0], &cfit[0], &parm[0]);
1603  }
1604  wfit.clear();
1605  tfit.clear();
1606  cfit.clear();
1607  }
1608 
1609 }
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 658 of file EMShowerAlg.cxx.

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

Referenced by OrderShowerHits().

658  {
659 
660  // Find the charge-weighted centre (in [cm]) of this shower
661  TVector2 centre = ShowerCentre(hits);
662 
663  // Find a rough shower 'direction'
664  TVector2 direction = ShowerDirection(hits);
665 
666  if (perpendicular)
667  direction = direction.Rotate(TMath::Pi()/2);
668 
669  // Find how far each hit (projected onto this axis) is from the centre
670  TVector2 pos;
671  std::map<double,art::Ptr<recob::Hit> > hitProjection;
672  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hit = hits.begin(); hit != hits.end(); ++hit) {
673  pos = HitPosition(*hit) - centre;
674  hitProjection[direction*pos] = *hit;
675  }
676 
677  // Get a vector of hits in order of the shower
678  std::vector<art::Ptr<recob::Hit> > showerHits;
679  std::transform(hitProjection.begin(), hitProjection.end(), std::back_inserter(showerHits), [](std::pair<double,art::Ptr<recob::Hit> > const& hit) { return hit.second; });
680 
681  // Make gradient plot
682  if (fMakeGradientPlot) {
683  std::map<int,TGraph*> graphs;
684  for (std::vector<art::Ptr<recob::Hit> >::iterator hitIt = showerHits.begin(); hitIt != showerHits.end(); ++hitIt) {
685  int tpc = (*hitIt)->WireID().TPC;
686  if (graphs[tpc] == nullptr)
687  graphs[tpc] = new TGraph();
688  graphs[tpc]->SetPoint(graphs[tpc]->GetN(), HitPosition(*hitIt).X(), HitPosition(*hitIt).Y());
689  //graphs[tpc]->SetPoint(graphs[tpc]->GetN(), HitCoordinates(*hitIt).X(), HitCoordinates(*hitIt).Y());
690  }
691  TMultiGraph* multigraph = new TMultiGraph();
692  for (std::map<int,TGraph*>::iterator graphIt = graphs.begin(); graphIt != graphs.end(); ++graphIt) {
693  graphIt->second->SetMarkerColor(graphIt->first);
694  graphIt->second->SetMarkerStyle(8);
695  graphIt->second->SetMarkerSize(2);
696  multigraph->Add(graphIt->second);
697  }
698  TCanvas* canvas = new TCanvas();
699  multigraph->Draw("AP");
700  TLine line;
701  line.SetLineColor(2);
702  line.DrawLine(centre.X()-1000*direction.X(),centre.Y()-1000*direction.Y(),centre.X()+1000*direction.X(),centre.Y()+1000*direction.Y());
703  canvas->SaveAs("Gradient.png");
704  delete canvas; delete multigraph;
705  }
706 
707  return showerHits;
708 
709 }
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 2327 of file EMShowerAlg.cxx.

2327  {
2328 
2330 
2331  double particleEnergy = 0;
2332  int likelyTrackID = 0;
2333  std::vector<sim::TrackIDE> trackIDs = bt_serv->HitToTrackIDEs(hit);
2334  for (unsigned int idIt = 0; idIt < trackIDs.size(); ++idIt) {
2335  if (trackIDs.at(idIt).energy > particleEnergy) {
2336  particleEnergy = trackIDs.at(idIt).energy;
2337  likelyTrackID = TMath::Abs(trackIDs.at(idIt).trackID);
2338  }
2339  }
2340 
2341  return likelyTrackID;
2342 
2343 }
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 711 of file EMShowerAlg.cxx.

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

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

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

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

Referenced by FindInitialTrack().

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

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

2301  {
2302 
2304 
2305  // Make a map of the tracks which are associated with this shower and the charge each contributes
2306  std::map<int,double> trackMap;
2307  for (std::vector<art::Ptr<recob::Hit> >::const_iterator showerHitIt = showerHits.begin(); showerHitIt != showerHits.end(); ++showerHitIt) {
2308  art::Ptr<recob::Hit> hit = *showerHitIt;
2309  int trackID = FindParticleID(hit);
2310  trackMap[trackID] += hit->Integral();
2311  }
2312 
2313  // Pick the track with the highest charge as the 'true track'
2314  double highestCharge = 0;
2315  int showerTrack = 0;
2316  for (std::map<int,double>::iterator trackIt = trackMap.begin(); trackIt != trackMap.end(); ++trackIt) {
2317  if (trackIt->second > highestCharge) {
2318  highestCharge = trackIt->second;
2319  showerTrack = trackIt->first;
2320  }
2321  }
2322 
2323  return showerTrack;
2324 
2325 }
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 845 of file EMShowerAlg.cxx.

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

Referenced by OrderShowerHits().

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

1633  {
1634 
1635  double globalWire = -999;
1636 
1637  // Induction
1638  if (fGeom->SignalType(wireID) == geo::kInduction) {
1639  double wireCentre[3];
1640  fGeom->WireIDToWireGeo(wireID).GetCenter(wireCentre);
1641  if (wireID.TPC % 2 == 0) globalWire = fGeom->WireCoordinate(wireCentre[1], wireCentre[2], wireID.Plane, 0, wireID.Cryostat);
1642  else globalWire = fGeom->WireCoordinate(wireCentre[1], wireCentre[2], wireID.Plane, 1, wireID.Cryostat);
1643  }
1644 
1645  // Collection
1646  else {
1647  // FOR COLLECTION WIRES, HARD CODE THE GEOMETRY FOR GIVEN DETECTORS
1648  // THIS _SHOULD_ BE TEMPORARY. GLOBAL WIRE SUPPORT IS BEING ADDED TO THE LARSOFT GEOMETRY AND SHOULD BE AVAILABLE SOON
1649  if (fDetector == "dune35t") {
1650  unsigned int nwires = fGeom->Nwires(wireID.Plane, 0, wireID.Cryostat);
1651  if (wireID.TPC == 0 or wireID.TPC == 1) globalWire = wireID.Wire;
1652  else if (wireID.TPC == 2 or wireID.TPC == 3 or wireID.TPC == 4 or wireID.TPC == 5) globalWire = nwires + wireID.Wire;
1653  else if (wireID.TPC == 6 or wireID.TPC == 7) globalWire = (2*nwires) + wireID.Wire;
1654  else mf::LogError("BlurredClusterAlg") << "Error when trying to find a global induction plane coordinate for TPC " << wireID.TPC << " (geometry" << fDetector << ")";
1655  }
1656  else if (fDetector == "dune10kt") {
1657  unsigned int nwires = fGeom->Nwires(wireID.Plane, 0, wireID.Cryostat);
1658  // Detector geometry has four TPCs, two on top of each other, repeated along z...
1659  int block = wireID.TPC / 4;
1660  globalWire = (nwires*block) + wireID.Wire;
1661  }
1662  else {
1663  double wireCentre[3];
1664  fGeom->WireIDToWireGeo(wireID).GetCenter(wireCentre);
1665  if (wireID.TPC % 2 == 0) globalWire = fGeom->WireCoordinate(wireCentre[1], wireCentre[2], wireID.Plane, 0, wireID.Cryostat);
1666  else globalWire = fGeom->WireCoordinate(wireCentre[1], wireCentre[2], wireID.Plane, 1, wireID.Cryostat);
1667  }
1668  }
1669 
1670  return globalWire;
1671 
1672 }
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 1612 of file EMShowerAlg.cxx.

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

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

1612  {
1613 
1614  return TVector2(GlobalWire(hit->WireID()), hit->PeakTime());
1615 
1616 }
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 1618 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().

1618  {
1619 
1620  geo::PlaneID planeID = hit->WireID().planeID();
1621 
1622  return HitPosition(HitCoordinates(hit), planeID);
1623 
1624 }
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 1626 of file EMShowerAlg.cxx.

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

1626  {
1627 
1628  return TVector2(pos.X() * fGeom->WirePitch(planeID),
1629  fDetProp->ConvertTicksToX(pos.Y(), planeID));
1630 
1631 }
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 2199 of file EMShowerAlg.cxx.

References hits().

2199  {
2200 
2201  if (!hits.size()) return false;
2202  if (hits.size()>2000) return true;
2203  if (hits.size()<20) return true;
2204  std::map<int, int> hitmap;
2205  unsigned nhits = 0;
2206  for (auto const&hit : hits){
2207  ++nhits;
2208  if (nhits>2)
2209  ++hitmap[hit->WireID().Wire];
2210  if (nhits==20) break;
2211  }
2212  //std::cout<<hits.size()<<" "<<float(nhits-2)/hitmap.size()<<std::endl;
2213  if (float(nhits-2)/hitmap.size()>1.4) return false;
2214  else return true;
2215 }
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 928 of file EMShowerAlg.cxx.

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

Referenced by FindInitialTrack().

929  {
930 
931  // Can't do much with just one view
932  if (initialHitsMap.size() < 2) {
933  mf::LogInfo("EMShowerAlg") << "Only one useful view for this shower; nothing can be done" << std::endl;
934  return std::unique_ptr<recob::Track>();
935  }
936 
937  std::vector<std::pair<int,int> > initialHitsSize;
938  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator initialHitIt = initialHitsMap.begin(); initialHitIt != initialHitsMap.end(); ++initialHitIt)
939  initialHitsSize.push_back(std::make_pair(initialHitIt->first, initialHitIt->second.size()));
940 
941  // Sort the planes by number of hits
942  std::sort(initialHitsSize.begin(), initialHitsSize.end(), [](std::pair<int,int> const& size1, std::pair<int,int> const& size2) { return size1.second > size2.second; });
943 
944  // Pick the two planes to use to make the track
945  // -- if more than two planes, can choose the two views
946  // more accurately
947  // -- if not, just use the two views available
948 
949  std::vector<int> planes;
950 
951  if (initialHitsSize.size() > 2 and !CheckShowerHits(showerHitsMap)) {
952  int planeToIgnore = WorstPlane(showerHitsMap);
953  if (fDebug > 1)
954  std::cout << "Igoring plane " << planeToIgnore << " in creation of initial track" << std::endl;
955  for (std::vector<std::pair<int,int> >::iterator hitsSizeIt = initialHitsSize.begin(); hitsSizeIt != initialHitsSize.end() and planes.size() < 2; ++hitsSizeIt) {
956  if (hitsSizeIt->first == planeToIgnore)
957  continue;
958  planes.push_back(hitsSizeIt->first);
959  }
960  }
961  else
962  planes = {initialHitsSize.at(0).first, initialHitsSize.at(1).first};
963 
964  return ConstructTrack(initialHitsMap.at(planes.at(0)), initialHitsMap.at(planes.at(1)));
965 
966 }
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 968 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().

970  {
971 
972  //return recob::Shower();
973 
974  // Find the shower hits on each plane
975  std::map<int,std::vector<art::Ptr<recob::Hit> > > planeHitsMap;
976  for (art::PtrVector<recob::Hit>::const_iterator hit = hits.begin(); hit != hits.end(); ++hit)
977  planeHitsMap[(*hit)->View()].push_back(*hit);
978 
979  int bestPlane = -1;
980  unsigned int highestNumberOfHits = 0;
981  std::vector<double> totalEnergy, totalEnergyError, dEdx, dEdxError;
982 
983  // Look at each of the planes
984  for (unsigned int plane = 0; plane < fGeom->MaxPlanes(); ++plane) {
985 
986  // If there's hits on this plane...
987  if (planeHitsMap.count(plane)) {
988  dEdx.push_back(FinddEdx(initialHitsMap.at(plane), initialTrack));
989  totalEnergy.push_back(fShowerEnergyAlg.ShowerEnergy(planeHitsMap.at(plane), plane));
990  if (planeHitsMap.at(plane).size() > highestNumberOfHits and initialHitsMap.count(plane)) {
991  bestPlane = plane;
992  highestNumberOfHits = planeHitsMap.at(plane).size();
993  }
994  }
995 
996  // If not...
997  else {
998  dEdx.push_back(0);
999  totalEnergy.push_back(0);
1000  }
1001 
1002  }
1003 
1004  TVector3 direction, directionError, showerStart, showerStartError;
1005  if (initialTrack) {
1006  direction = initialTrack->VertexDirection();
1007  showerStart = initialTrack->Vertex();
1008  }
1009 
1010  if (fDebug > 0) {
1011  std::cout << "Best plane is " << bestPlane << std::endl;
1012  std::cout << "dE/dx for each plane is: " << dEdx[0] << ", " << dEdx[1] << " and " << dEdx[2] << std::endl;
1013  std::cout << "Total energy for each plane is: " << totalEnergy[0] << ", " << totalEnergy[1] << " and " << totalEnergy[2] << std::endl;
1014  std::cout << "The shower start is (" << showerStart.X() << ", " << showerStart.Y() << ", " << showerStart.Z() << ")" << std::endl;
1015  std::cout << "The shower direction is (" << direction.X() << ", " << direction.Y() << ", " << direction.Z() << ")" << std::endl;
1016  }
1017 
1018  return recob::Shower(direction, directionError, showerStart, showerStartError, totalEnergy, totalEnergyError, dEdx, dEdxError, bestPlane);
1019 
1020 }
double ShowerEnergy(std::vector< art::Ptr< recob::Hit > > const &hits, int plane)
Finds the total energy deposited by the shower in this view.
TVector3 VertexDirection() const
Covariance matrices are either set or not.
Definition: Track.h:247
iterator begin()
Definition: PtrVector.h:223
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.
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
TVector3 Vertex() const
Covariance matrices are either set or not.
Definition: Track.h:245
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 1022 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().

1024  {
1025 
1026  iok = 1;
1027 
1028  // Find the shower hits on each plane
1029  std::map<int,std::vector<art::Ptr<recob::Hit> > > planeHitsMap;
1030  for (art::PtrVector<recob::Hit>::const_iterator hit = hits.begin(); hit != hits.end(); ++hit)
1031  planeHitsMap[(*hit)->WireID().Plane].push_back(*hit);
1032 
1033  std::vector<std::vector<art::Ptr<recob::Hit> > > initialTrackHits(3);
1034 
1035  int pl0 = -1;
1036  int pl1 = -1;
1037  unsigned maxhits0 = 0;
1038  unsigned maxhits1 = 0;
1039 
1040  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::iterator planeHits = planeHitsMap.begin(); planeHits != planeHitsMap.end(); ++planeHits) {
1041 
1042  std::vector<art::Ptr<recob::Hit> > showerHits;
1043  OrderShowerHits(planeHits->second, showerHits, vertex);
1044  //if (!isCleanShower(showerHits)) continue;
1045  FindInitialTrackHits(showerHits, vertex, initialTrackHits[planeHits->first]);
1046  if ((planeHits->second).size()>maxhits0){
1047  if (pl0!=-1){
1048  maxhits1 = maxhits0;
1049  pl1 = pl0;
1050  }
1051  pl0 = planeHits->first;
1052  maxhits0 = (planeHits->second).size();
1053  }
1054  else if ((planeHits->second).size()>maxhits1){
1055  pl1 = planeHits->first;
1056  maxhits1 = (planeHits->second).size();
1057  }
1058 
1059  }
1060  //std::cout<<pl0<<" "<<pl1<<std::endl;
1061 // if (pl0!=-1&&pl1!=-1) {
1062 // pl0 = 1;
1063 // pl1 = 2;
1064 // }
1065  if (pl0!=-1&&pl1!=-1
1066  &&initialTrackHits[pl0].size()>=2
1067  &&initialTrackHits[pl1].size()>=2
1068  &&initialTrackHits[pl0][0]->WireID().TPC==
1069  initialTrackHits[pl1][0]->WireID().TPC){
1070  double xyz[3];
1071  vertex->XYZ(xyz);
1072  TVector3 vtx(xyz);
1073 // std::vector<art::Ptr<recob::Hit>> alltrackhits;
1074 // for (size_t i = 0; i<3; ++i){
1075 // for (auto const&hit : initialTrackHits[i]){
1076 // alltrackhits.push_back(hit);
1077 // }
1078 // }
1079  //std::cout<<"vertex "<<xyz[0]<<" "<<xyz[1]<<" "<<xyz[2]<<std::endl;
1080  //for (auto const&hit : initialTrackHits[pl0]) std::cout<<*hit<<std::endl;
1081  //for (auto const&hit : initialTrackHits[pl1]) std::cout<<*hit<<std::endl;
1082  pma::Track3D* pmatrack = fProjectionMatchingAlg.buildSegment(initialTrackHits[pl0], initialTrackHits[pl1]);
1083  //std::cout<<pmatrack->size()<<std::endl;
1084  //pma::Track3D* pmatrack = fProjectionMatchingAlg.buildSegment(alltrackhits);
1085  std::vector<TVector3> spts;
1086 
1087 // points are shifted now by tracking code, commented out shifts here
1088 // double xshift = pmatrack->GetXShift();
1089 // bool has_shift = (xshift != 0.0);
1090  for (size_t i = 0; i<pmatrack->size(); ++i){
1091  if ((*pmatrack)[i]->IsEnabled()){
1092  TVector3 p3d = (*pmatrack)[i]->Point3D();
1093 // if (has_shift) p3d.SetX(p3d.X() + xshift);
1094  //std::cout<<p3d.X()<<" "<<p3d.Y()<<" "<<p3d.Z()<<std::endl;
1095  spts.push_back(p3d);
1096  }
1097  }
1098  if (spts.size()>=2){ //at least two space points
1099  TVector3 shwxyz, shwxyzerr;
1100  TVector3 shwdir, shwdirerr;
1101  std::vector<double> totalEnergy, totalEnergyError, dEdx, dEdxError;
1102  int bestPlane = pl0;
1103  double minpitch = 1000;
1104  std::vector<TVector3> dirs;
1105  if ((spts[0]-vtx).Mag()<(spts.back()-vtx).Mag()){
1106  shwxyz = spts[0];
1107  size_t i = 5;
1108  if (spts.size()-1<5) i = spts.size()-1;
1109  shwdir = spts[i] - spts[0];
1110  shwdir = shwdir.Unit();
1111  }
1112  else{
1113  shwxyz = spts.back();
1114  size_t i = 0;
1115  if (spts.size()>6) i = spts.size() - 6;
1116  shwdir = spts[i] - spts[spts.size()-1];
1117  shwdir = shwdir.Unit();
1118  }
1119  //std::cout<<shwxyz.X()<<" "<<shwxyz.Y()<<" "<<shwxyz.Z()<<std::endl;
1120  //std::cout<<shwdir.X()<<" "<<shwdir.Y()<<" "<<shwdir.Z()<<std::endl;
1121  for (unsigned int plane = 0; plane < fGeom->MaxPlanes(); ++plane) {
1122  if (planeHitsMap.find(plane)!=planeHitsMap.end()){
1123  totalEnergy.push_back(fShowerEnergyAlg.ShowerEnergy(planeHitsMap[plane], plane));
1124  }
1125  else{
1126  totalEnergy.push_back(0);
1127  }
1128  if (initialTrackHits[plane].size()){
1129  double fdEdx = 0;
1130  double totQ = 0;
1131  double avgT = 0;
1132  double pitch = 0;
1133  double wirepitch = fGeom->WirePitch(initialTrackHits[plane][0]->WireID().planeID());
1134  double angleToVert = fGeom->WireAngleToVertical(fGeom->Plane(plane).View(),initialTrackHits[plane][0]->WireID().planeID()) - 0.5*TMath::Pi();
1135  double cosgamma = std::abs(sin(angleToVert)*shwdir.Y()+
1136  cos(angleToVert)*shwdir.Z());
1137  if (cosgamma>0) pitch = wirepitch/cosgamma;
1138  if (pitch){
1139  if (pitch<minpitch){
1140  minpitch = pitch;
1141  bestPlane = plane;
1142  }
1143  int nhits = 0;
1144  //std::cout<<"pitch = "<<pitch<<std::endl;
1145  std::vector<float> vQ;
1146  for (auto const& hit: initialTrackHits[plane]){
1147  //std::cout<<hit->WireID()<<" "<<hit->PeakTime()<<" "<<std::abs((hit->WireID().Wire-initialTrackHits[plane][0]->WireID().Wire)*pitch)<<" "<<fdEdxTrackLength<<std::endl;
1148  int w1 = hit->WireID().Wire;
1149  int w0 = initialTrackHits[plane][0]->WireID().Wire;
1150  if (std::abs((w1-w0)*pitch)<fdEdxTrackLength){
1151  vQ.push_back(hit->Integral());
1152  totQ += hit->Integral();
1153  avgT+= hit->PeakTime();
1154  ++nhits;
1155  //std::cout<<hit->WireID()<<" "<<hit->PeakTime()<<" "<<hit->Integral()<<" "<<totQ<<" "<<avgT<<std::endl;
1156  }
1157  }
1158  if (totQ) {
1159  //double dQdx = totQ/(nhits*pitch);
1160  //std::sort(vQ.begin(), vQ.end());
1161  //double dQdx = vQ[vQ.size()/2]/pitch;
1162  double dQdx = TMath::Median(vQ.size(), &vQ[0])/pitch;
1163  fdEdx = fCalorimetryAlg.dEdx_AREA(dQdx, avgT/nhits, initialTrackHits[plane][0]->WireID().Plane);
1164  }
1165  }
1166  dEdx.push_back(fdEdx);
1167  }
1168  else{
1169  dEdx.push_back(0);
1170  }
1171  }
1172  iok = 0;
1173  if (fDebug > 1) {
1174  std::cout << "Best plane is " << bestPlane << std::endl;
1175  std::cout << "dE/dx for each plane is: " << dEdx[0] << ", " << dEdx[1] << " and " << dEdx[2] << std::endl;
1176  std::cout << "Total energy for each plane is: " << totalEnergy[0] << ", " << totalEnergy[1] << " and " << totalEnergy[2] << std::endl;
1177  std::cout << "The shower start is (" << shwxyz.X() << ", " << shwxyz.Y() << ", " << shwxyz.Z() << ")" << std::endl;
1178  shwxyz.Print();
1179  }
1180 
1181  return recob::Shower(shwdir, shwdirerr, shwxyz, shwxyzerr, totalEnergy, totalEnergyError, dEdx, dEdxError, bestPlane);
1182  }
1183  }
1184  return recob::Shower();
1185 }
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 1187 of file EMShowerAlg.cxx.

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

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

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

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

1504  {
1505 
1506  showerHits = FindOrderOfHits(shower);
1507 
1508  // Find TPC for the vertex
1509  double xyz[3];
1510  vertex->XYZ(xyz);
1511  geo::TPCID tpc = fGeom->FindTPCAtPosition(xyz);
1512  if (!tpc.isValid&&showerHits.size()) tpc = geo::TPCID(showerHits[0]->WireID());
1513  //std::cout<<tpc<<std::endl;
1514  // Find hits in the same TPC
1515  art::Ptr<recob::Hit> hit0, hit1;
1516  for (auto &hit: showerHits){
1517  if (hit->WireID().TPC==tpc.TPC){
1518  if (hit0.isNull()){
1519  hit0 = hit;
1520  }
1521  hit1 = hit;
1522  }
1523  }
1524  if (hit0.isNull()||hit1.isNull()) return;
1525  TVector2 coord0 = TVector2(hit0->WireID().Wire, hit0->PeakTime());
1526  TVector2 coord1 = TVector2(hit1->WireID().Wire, hit1->PeakTime());
1527  TVector2 coordvtx = TVector2(fGeom->WireCoordinate(xyz[1], xyz[2], hit0->WireID().planeID()),
1528  fDetProp->ConvertXToTicks(xyz[0], hit0->WireID().planeID()));
1529 // std::cout<<coord0.X()<<" "<<coord0.Y()<<std::endl;
1530 // std::cout<<coord1.X()<<" "<<coord1.Y()<<std::endl;
1531 // std::cout<<coordvtx.X()<<" "<<coordvtx.Y()<<std::endl;
1532 // std::cout<<hit0->WireID()<<" "<<hit1->WireID()<<std::endl;
1533  if ((coord1-coordvtx).Mod()<(coord0-coordvtx).Mod()){
1534  std::reverse(showerHits.begin(), showerHits.end());
1535  }
1536  //std::cout<<showerHits[0]->WireID()<<" "<<showerHits.back()->WireID()<<std::endl;
1537 }
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 2093 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().

2093  {
2094 
2095  TVector2 wireTickPos = TVector2(-999., -999.);
2096 
2097  double pointPosition[3] = {point.X(), point.Y(), point.Z()};
2098 
2099  geo::TPCID tpcID = fGeom->FindTPCAtPosition(pointPosition);
2100  int tpc = 0;
2101  if (tpcID.isValid)
2102  tpc = tpcID.TPC;
2103  else
2104  return wireTickPos;
2105 
2106  // Construct wire ID for this point projected onto the plane
2107  geo::PlaneID planeID = geo::PlaneID(cryostat, tpc, plane);
2108  geo::WireID wireID;
2109  try{
2110  wireID = fGeom->NearestWireID(point, planeID);
2111  }
2112  catch(geo::InvalidWireError const& e) {
2113  wireID = e.suggestedWireID(); // pick the closest valid wire
2114  }
2115 
2116  wireTickPos = TVector2(GlobalWire(wireID),
2117  fDetProp->ConvertXToTicks(point.X(), planeID));
2118 
2119  // wireTickPos = TVector2(fGeom->WireCoordinate(point.Y(), point.Z(), planeID.Plane, tpc % 2, planeID.Cryostat),
2120  // fDetProp->ConvertXToTicks(point.X(), planeID.Plane, tpc % 2, planeID.Cryostat));
2121 
2122  //return wireTickPos;
2123  return HitPosition(wireTickPos, planeID);
2124 
2125 }
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 1674 of file EMShowerAlg.cxx.

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

Referenced by GetPlanePermutations(), and OrderShowerHits().

1674  {
1675 
1676  // Get the wire widths
1677  std::map<int,int> planeWireLength;
1678  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt)
1679  planeWireLength[showerHitsIt->first] = TMath::Abs(HitCoordinates(showerHitsIt->second.front()).X() - HitCoordinates(showerHitsIt->second.back()).X());
1680 
1681  // Find the relative wire width for each plane with respect to the others
1682  std::map<int,double> planeOtherWireLengths;
1683  for (std::map<int,int>::iterator planeWireLengthIt = planeWireLength.begin(); planeWireLengthIt != planeWireLength.end(); ++planeWireLengthIt) {
1684  double quad = 0.;
1685  for (int plane = 0; plane < (int)fGeom->MaxPlanes(); ++plane)
1686  if (plane != planeWireLengthIt->first and planeWireLength.count(plane))
1687  quad += TMath::Power(planeWireLength[plane],2);
1688  quad = TMath::Sqrt(quad);
1689  planeOtherWireLengths[planeWireLengthIt->first] = planeWireLength[planeWireLengthIt->first] / (double)quad;
1690  }
1691 
1692  // Order these backwards
1693  std::map<double,int> wireWidthMap;
1694  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt)
1695  wireWidthMap[planeOtherWireLengths.at(showerHitsIt->first)] = showerHitsIt->first;
1696 
1697  return wireWidthMap;
1698 
1699 }
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 1726 of file EMShowerAlg.cxx.

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

Referenced by FindOrderOfHits(), and ShowerHitRMS().

1726  {
1727 
1728  TVector2 pos, chargePoint = TVector2(0,0);
1729  double totalCharge = 0;
1730  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hit = showerHits.begin(); hit != showerHits.end(); ++hit) {
1731  pos = HitPosition(*hit);
1732  chargePoint += (*hit)->Integral() * pos;
1733  totalCharge += (*hit)->Integral();
1734  }
1735  TVector2 centre = chargePoint / totalCharge;
1736 
1737  return centre;
1738 
1739 }
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 1701 of file EMShowerAlg.cxx.

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

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

1701  {
1702 
1703  TVector2 pos;
1704  //double weight;
1705  double weight = 1;
1706  //int nhits = 0;
1707  double sumx=0., sumy=0., sumx2=0., sumxy=0., sumweight = 0.;
1708  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hit = showerHits.begin(); hit != showerHits.end(); ++hit) {
1709  //++nhits;
1710  pos = HitPosition(*hit);
1711  weight = TMath::Power((*hit)->Integral(),2);
1712  sumweight += weight;
1713  sumx += weight * pos.X();
1714  sumy += weight * pos.Y();
1715  sumx2 += weight * pos.X() * pos.X();
1716  sumxy += weight * pos.X() * pos.Y();
1717  }
1718  //double gradient = (nhits * sumxy - sumx * sumy) / (nhits * sumx2 - sumx * sumx);
1719  double gradient = (sumweight * sumxy - sumx * sumy) / (sumweight * sumx2 - sumx * sumx);
1720  TVector2 direction = TVector2(1,gradient).Unit();
1721 
1722  return direction;
1723 
1724 }
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 1741 of file EMShowerAlg.cxx.

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

Referenced by GetPlanePermutations(), and OrderShowerHits().

1741  {
1742 
1743  TVector2 direction = ShowerDirection(showerHits);
1744  TVector2 centre = ShowerCentre(showerHits);
1745 
1746  std::vector<double> distanceToAxis;
1747  for (std::vector<art::Ptr<recob::Hit> >::const_iterator showerHitsIt = showerHits.begin(); showerHitsIt != showerHits.end(); ++showerHitsIt) {
1748  TVector2 proj = (HitPosition(*showerHitsIt) - centre).Proj(direction) + centre;
1749  distanceToAxis.push_back((HitPosition(*showerHitsIt) - proj).Mod());
1750  }
1751  double RMS = TMath::RMS(distanceToAxis.begin(), distanceToAxis.end());
1752 
1753  return RMS;
1754 
1755 }
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 1757 of file EMShowerAlg.cxx.

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

Referenced by GetPlanePermutations(), and OrderShowerHits().

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

References n.

Referenced by FindInitialTrackHits().

2157  {
2158 
2159  Double_t sumx=0.;
2160  Double_t sumx2=0.;
2161  Double_t sumy=0.;
2162  Double_t sumy2=0.;
2163  Double_t sumxy=0.;
2164  Double_t sumw=0.;
2165  Double_t eparm[2];
2166 
2167  parm[0] = 0.;
2168  parm[1] = 0.;
2169  eparm[0] = 0.;
2170  eparm[1] = 0.;
2171 
2172  for (Int_t i=0; i<n; i++) {
2173  sumx += x[i]*w[i];
2174  sumx2 += x[i]*x[i]*w[i];
2175  sumy += y[i]*w[i];
2176  sumy2 += y[i]*y[i]*w[i];
2177  sumxy += x[i]*y[i]*w[i];
2178  sumw += w[i];
2179  }
2180 
2181  if (sumx2*sumw-sumx*sumx==0.) return 1;
2182  if (sumx2-sumx*sumx/sumw==0.) return 1;
2183 
2184  parm[0] = (sumy*sumx2-sumx*sumxy)/(sumx2*sumw-sumx*sumx);
2185  parm[1] = (sumxy-sumx*sumy/sumw)/(sumx2-sumx*sumx/sumw);
2186 
2187  eparm[0] = sumx2*(sumx2*sumw-sumx*sumx);
2188  eparm[1] = (sumx2-sumx*sumx/sumw);
2189 
2190  if (eparm[0]<0. || eparm[1]<0.) return 1;
2191 
2192  eparm[0] = sqrt(eparm[0])/(sumx2*sumw-sumx*sumx);
2193  eparm[1] = sqrt(eparm[1])/(sumx2-sumx*sumx/sumw);
2194 
2195  return 0;
2196 
2197 }
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 2127 of file EMShowerAlg.cxx.

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

Referenced by MakeInitialTrack().

2127  {
2128 
2129  // Get the width of the shower in wire coordinate
2130  std::map<int,int> planeWireLength;
2131  std::map<int,double> planeOtherWireLengths;
2132  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt)
2133  planeWireLength[showerHitsIt->first] = TMath::Abs(HitCoordinates(showerHitsIt->second.front()).X() - HitCoordinates(showerHitsIt->second.back()).X());
2134  for (std::map<int,int>::iterator planeWireLengthIt = planeWireLength.begin(); planeWireLengthIt != planeWireLength.end(); ++planeWireLengthIt) {
2135  double quad = 0.;
2136  for (int plane = 0; plane < (int)fGeom->MaxPlanes(); ++plane)
2137  if (plane != planeWireLengthIt->first and planeWireLength.count(plane))
2138  quad += TMath::Power(planeWireLength[plane],2);
2139  quad = TMath::Sqrt(quad);
2140  planeOtherWireLengths[planeWireLengthIt->first] = planeWireLength[planeWireLengthIt->first] / (double)quad;
2141  }
2142 
2143  if (fDebug > 1)
2144  for (std::map<int,double>::const_iterator planeOtherWireLengthIt = planeOtherWireLengths.begin(); planeOtherWireLengthIt != planeOtherWireLengths.end(); ++planeOtherWireLengthIt)
2145  std::cout << "Plane " << planeOtherWireLengthIt->first << " has " << planeWireLength[planeOtherWireLengthIt->first] << " wire width and therefore has relative width in wire of " << planeOtherWireLengthIt->second << std::endl;
2146 
2147  std::map<double,int> wireWidthMap;
2148  for (std::map<int,std::vector<art::Ptr<recob::Hit> > >::const_iterator showerHitsIt = showerHitsMap.begin(); showerHitsIt != showerHitsMap.end(); ++showerHitsIt) {
2149  double wireWidth = planeWireLength.at(showerHitsIt->first);
2150  wireWidthMap[wireWidth] = showerHitsIt->first;
2151  }
2152 
2153  return wireWidthMap.begin()->second;
2154 
2155 }
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: