ShowerDirectionCheater_tool.cc
Go to the documentation of this file.
1 //############################################################################
2 //### Name: ShowerDirectionCheater ###
3 //### Author: Ed Tyley ###
4 //### Date: 16.07.19 ###
5 //### Description: Cheating tool using truth for shower direction ###
6 //############################################################################
7 
8 //Framework Includes
10 
11 //LArSoft Includes
15 
16 namespace ShowerRecoTools {
17 
19 
20  public:
22 
23  //Generic Direction Finder
24  int CalculateElement(const art::Ptr<recob::PFParticle>& pfparticle,
26  reco::shower::ShowerElementHolder& ShowerEleHolder) override;
27 
28  private:
29  //Algorithm functions
31 
32  //Services
34 
35  //fcl
37  const unsigned int
38  fNSegments; //Number of segement to split the shower into the perforam the RMSFlip.
39  const bool fRMSFlip; //Flip the direction by considering the rms.
40  const bool
41  fVertexFlip; //Flip the direction by considering the vertex position relative to the center position.
42 
43  //TTree Branch variables
44  TTree* Tree;
46  float rmsGradient;
47 
51  };
52 
54  : IShowerTool(pset.get<fhicl::ParameterSet>("BaseTools"))
55  , fLArPandoraShowerCheatingAlg(pset.get<fhicl::ParameterSet>("LArPandoraShowerCheatingAlg"))
56  , fPFParticleLabel(pset.get<art::InputTag>("PFParticleLabel"))
57  , fNSegments(pset.get<unsigned int>("NSegments"))
58  , fRMSFlip(pset.get<bool>("RMSFlip"))
59  , fVertexFlip(pset.get<bool>("VertexFlip"))
60  , fShowerStartPositionInputLabel(pset.get<std::string>("ShowerStartPositionInputLabel"))
61  , fTrueParticleInputLabel(pset.get<std::string>("TrueParticleInputLabel"))
62  , fShowerDirectionOutputLabel(pset.get<std::string>("ShowerDirectionOutputLabel"))
63  {
64  if (fVertexFlip || fRMSFlip) {
65  Tree = tfs->make<TTree>("DebugTreeDirCheater", "DebugTree from shower direction cheater");
66  if (fVertexFlip) Tree->Branch("vertexDotProduct", &vertexDotProduct);
67  if (fRMSFlip) Tree->Branch("rmsGradient", &rmsGradient);
68  }
69  }
70 
71  int
73  art::Event& Event,
74  reco::shower::ShowerElementHolder& ShowerEleHolder)
75  {
76 
77  const simb::MCParticle* trueParticle;
78 
79  //Get the hits from the shower:
80  auto const pfpHandle = Event.getValidHandle<std::vector<recob::PFParticle>>(fPFParticleLabel);
81 
82  auto const clockData =
84  auto const detProp =
86 
87  if (ShowerEleHolder.CheckElement(fTrueParticleInputLabel)) {
88  ShowerEleHolder.GetElement(fTrueParticleInputLabel, trueParticle);
89  }
90  else {
91 
92  //Could store these in the shower element holder and just calculate once?
93  std::map<int, const simb::MCParticle*> trueParticles =
95  std::map<int, std::vector<int>> showersMothers =
97 
98  //Get the clusters
99  auto const clusHandle = Event.getValidHandle<std::vector<recob::Cluster>>(fPFParticleLabel);
100  art::FindManyP<recob::Cluster> fmc(pfpHandle, Event, fPFParticleLabel);
101  std::vector<art::Ptr<recob::Cluster>> clusters = fmc.at(pfparticle.key());
102 
103  //Get the hit association
104  art::FindManyP<recob::Hit> fmhc(clusHandle, Event, fPFParticleLabel);
105 
106  std::vector<art::Ptr<recob::Hit>> showerHits;
107  for (auto const& cluster : clusters) {
108  //Get the hits
109  std::vector<art::Ptr<recob::Hit>> hits = fmhc.at(cluster.key());
110  showerHits.insert(showerHits.end(), hits.begin(), hits.end());
111  }
112 
113  //Get the true particle from the shower
114  std::pair<int, double> ShowerTrackInfo =
116  clockData, showersMothers, showerHits, 2);
117 
118  if (ShowerTrackInfo.first == -99999) {
119  mf::LogError("ShowerDirectionCheater") << "True shower not found, returning";
120  return 1;
121  }
122  trueParticle = trueParticles[ShowerTrackInfo.first];
123  ShowerEleHolder.SetElement(trueParticle, fTrueParticleInputLabel);
124  }
125 
126  if (!trueParticle) {
127  mf::LogError("ShowerDirectionCheater") << "True shower not found, returning";
128  return 1;
129  }
130 
131  TVector3 trueDir = TVector3{trueParticle->Px(), trueParticle->Py(), trueParticle->Pz()}.Unit();
132 
133  TVector3 trueDirErr = {-999, -999, -999};
134  ShowerEleHolder.SetElement(trueDir, trueDirErr, fShowerDirectionOutputLabel);
135 
136  if (fRMSFlip || fVertexFlip) {
137 
138  // Reset the tree values to defaults
139  rmsGradient = std::numeric_limits<float>::lowest();
140  vertexDotProduct = std::numeric_limits<float>::lowest();
141 
142  //Get the SpacePoints and hits
143  art::FindManyP<recob::SpacePoint> fmspp(pfpHandle, Event, fPFParticleLabel);
144 
145  if (!fmspp.isValid()) {
146  throw cet::exception("ShowerDirectionCheater")
147  << "Trying to get the spacepoint and failed. Something is not configured correctly. "
148  "Stopping ";
149  }
150 
151  auto const spHandle = Event.getValidHandle<std::vector<recob::SpacePoint>>(fPFParticleLabel);
152  art::FindManyP<recob::Hit> fmh(spHandle, Event, fPFParticleLabel);
153  if (!fmh.isValid()) {
154  throw cet::exception("ShowerDirectionCheater")
155  << "Spacepoint and hit association not valid. Stopping.";
156  }
157  std::vector<art::Ptr<recob::SpacePoint>> spacePoints = fmspp.at(pfparticle.key());
158 
159  if (spacePoints.size() < 3) {
160  mf::LogWarning("ShowerDirectionCheater")
161  << spacePoints.size() << " spacepoints in shower, not calculating direction" << std::endl;
162  return 1;
163  }
164 
165  //Get Shower Centre
166  float TotalCharge;
167 
168  const TVector3 ShowerCentre = IShowerTool::GetLArPandoraShowerAlg().ShowerCentre(
169  clockData, detProp, spacePoints, fmh, TotalCharge);
170 
171  //Check if we are pointing the correct direction or not, First try the start position
172  if (ShowerEleHolder.CheckElement(fShowerStartPositionInputLabel) && fVertexFlip) {
173 
174  //Get the General direction as the vector between the start position and the centre
175  TVector3 StartPositionVec = {-999, -999, -999};
176  ShowerEleHolder.GetElement(fShowerStartPositionInputLabel, StartPositionVec);
177 
178  TVector3 GeneralDir = (ShowerCentre - StartPositionVec).Unit();
179 
180  //Dot product
181  vertexDotProduct = trueDir.Dot(GeneralDir);
182  }
183 
184  if (fRMSFlip) {
185  //Otherwise Check against the RMS of the shower. Method adapated from EMShower Thanks Mike.
187  spacePoints, ShowerCentre, trueDir, fNSegments);
188  }
189  Tree->Fill();
190  }
191 
192  return 0;
193  }
194 }
195 
art::ServiceHandle< art::TFileService > tfs
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
double Py(const int i=0) const
Definition: MCParticle.h:231
std::string string
Definition: nybbler.cc:12
std::map< int, const simb::MCParticle * > GetTrueParticleMap() const
double Px(const int i=0) const
Definition: MCParticle.h:230
void SetElement(T &dataproduct, const std::string &Name, bool checktag=false)
STL namespace.
double RMSShowerGradient(std::vector< art::Ptr< recob::SpacePoint >> &sps, const TVector3 &ShowerCentre, const TVector3 &Direction, const unsigned int nSegments) const
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
Cluster finding and building.
int CalculateElement(const art::Ptr< recob::PFParticle > &pfparticle, art::Event &Event, reco::shower::ShowerElementHolder &ShowerEleHolder) override
key_type key() const noexcept
Definition: Ptr.h:216
std::map< int, std::vector< int > > GetTrueChain(std::map< int, const simb::MCParticle * > &trueParticles) const
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
bool CheckElement(const std::string &Name) const
int GetElement(const std::string &Name, T &Element) const
shower::LArPandoraShowerCheatingAlg fLArPandoraShowerCheatingAlg
const shower::LArPandoraShowerAlg & GetLArPandoraShowerAlg() const
Definition: IShowerTool.h:87
std::pair< int, double > TrueParticleIDFromTrueChain(detinfo::DetectorClocksData const &clockData, std::map< int, std::vector< int >> const &ShowersMothers, std::vector< art::Ptr< recob::Hit >> const &hits, int planeid) const
Definition: types.h:32
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
double Pz(const int i=0) const
Definition: MCParticle.h:232
TVector3 ShowerCentre(std::vector< art::Ptr< recob::SpacePoint >> const &showersps) const
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
int bool
Definition: qglobal.h:345
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
ShowerDirectionCheater(const fhicl::ParameterSet &pset)