All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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
9 #include "art/Utilities/ToolMacros.h"
10 
11 //LArSoft Includes
18 
19 //ROOT Includes
20 #include "TTree.h"
21 
22 namespace ShowerRecoTools {
23 
25 
26  public:
27  ShowerDirectionCheater(const fhicl::ParameterSet& pset);
28 
29  //Generic Direction Finder
30  int CalculateElement(const art::Ptr<recob::PFParticle>& pfparticle,
31  art::Event& Event,
32  reco::shower::ShowerElementHolder& ShowerEleHolder) override;
33 
34  private:
35  //Algorithm functions
37 
38  //Services
39  art::ServiceHandle<art::TFileService> tfs;
40 
41  //fcl
42  const art::InputTag fPFParticleLabel;
43  const unsigned int
44  fNSegments; //Number of segement to split the shower into the perforam the RMSFlip.
45  const bool fRMSFlip; //Flip the direction by considering the rms.
46  const bool
47  fVertexFlip; //Flip the direction by considering the vertex position relative to the center position.
48 
49  //TTree Branch variables
50  TTree* Tree;
52  float rmsGradient;
53 
54  const std::string fShowerStartPositionInputLabel;
55  const std::string fTrueParticleInputLabel;
56  const std::string fShowerDirectionOutputLabel;
57  };
58 
59  ShowerDirectionCheater::ShowerDirectionCheater(const fhicl::ParameterSet& pset)
60  : IShowerTool(pset.get<fhicl::ParameterSet>("BaseTools"))
61  , fLArPandoraShowerCheatingAlg(pset.get<fhicl::ParameterSet>("LArPandoraShowerCheatingAlg"))
62  , fPFParticleLabel(pset.get<art::InputTag>("PFParticleLabel"))
63  , fNSegments(pset.get<unsigned int>("NSegments"))
64  , fRMSFlip(pset.get<bool>("RMSFlip"))
65  , fVertexFlip(pset.get<bool>("VertexFlip"))
66  , fShowerStartPositionInputLabel(pset.get<std::string>("ShowerStartPositionInputLabel"))
67  , fTrueParticleInputLabel(pset.get<std::string>("TrueParticleInputLabel"))
68  , fShowerDirectionOutputLabel(pset.get<std::string>("ShowerDirectionOutputLabel"))
69  {
70  if (fVertexFlip || fRMSFlip) {
71  Tree = tfs->make<TTree>("DebugTreeDirCheater", "DebugTree from shower direction cheater");
72  if (fVertexFlip) Tree->Branch("vertexDotProduct", &vertexDotProduct);
73  if (fRMSFlip) Tree->Branch("rmsGradient", &rmsGradient);
74  }
75  }
76 
77  int
78  ShowerDirectionCheater::CalculateElement(const art::Ptr<recob::PFParticle>& pfparticle,
79  art::Event& Event,
80  reco::shower::ShowerElementHolder& ShowerEleHolder)
81  {
82 
83  const simb::MCParticle* trueParticle;
84 
85  //Get the hits from the shower:
86  auto const pfpHandle = Event.getValidHandle<std::vector<recob::PFParticle>>(fPFParticleLabel);
87 
88  auto const clockData =
89  art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(Event);
90  auto const detProp =
91  art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(Event, clockData);
92 
93  if (ShowerEleHolder.CheckElement(fTrueParticleInputLabel)) {
94  ShowerEleHolder.GetElement(fTrueParticleInputLabel, trueParticle);
95  }
96  else {
97 
98  //Could store these in the shower element holder and just calculate once?
99  std::map<int, const simb::MCParticle*> trueParticles =
101  std::map<int, std::vector<int>> showersMothers =
103 
104  //Get the clusters
105  auto const clusHandle = Event.getValidHandle<std::vector<recob::Cluster>>(fPFParticleLabel);
106  art::FindManyP<recob::Cluster> fmc(pfpHandle, Event, fPFParticleLabel);
107  std::vector<art::Ptr<recob::Cluster>> clusters = fmc.at(pfparticle.key());
108 
109  //Get the hit association
110  art::FindManyP<recob::Hit> fmhc(clusHandle, Event, fPFParticleLabel);
111 
112  std::vector<art::Ptr<recob::Hit>> showerHits;
113  for (auto const& cluster : clusters) {
114  //Get the hits
115  std::vector<art::Ptr<recob::Hit>> hits = fmhc.at(cluster.key());
116  showerHits.insert(showerHits.end(), hits.begin(), hits.end());
117  }
118 
119  //Get the true particle from the shower
120  std::pair<int, double> ShowerTrackInfo =
122  clockData, showersMothers, showerHits, 2);
123 
124  if (ShowerTrackInfo.first == -99999) {
125  mf::LogError("ShowerDirectionCheater") << "True shower not found, returning";
126  return 1;
127  }
128  trueParticle = trueParticles[ShowerTrackInfo.first];
129  ShowerEleHolder.SetElement(trueParticle, fTrueParticleInputLabel);
130  }
131 
132  if (!trueParticle) {
133  mf::LogError("ShowerDirectionCheater") << "True shower not found, returning";
134  return 1;
135  }
136 
137  TVector3 trueDir = TVector3{trueParticle->Px(), trueParticle->Py(), trueParticle->Pz()}.Unit();
138 
139  TVector3 trueDirErr = {-999, -999, -999};
140  ShowerEleHolder.SetElement(trueDir, trueDirErr, fShowerDirectionOutputLabel);
141 
142  if (fRMSFlip || fVertexFlip) {
143 
144  // Reset the tree values to defaults
145  rmsGradient = std::numeric_limits<float>::lowest();
146  vertexDotProduct = std::numeric_limits<float>::lowest();
147 
148  //Get the SpacePoints and hits
149  art::FindManyP<recob::SpacePoint> fmspp(pfpHandle, Event, fPFParticleLabel);
150 
151  if (!fmspp.isValid()) {
152  throw cet::exception("ShowerDirectionCheater")
153  << "Trying to get the spacepoint and failed. Something is not configured correctly. "
154  "Stopping ";
155  }
156 
157  auto const spHandle = Event.getValidHandle<std::vector<recob::SpacePoint>>(fPFParticleLabel);
158  art::FindManyP<recob::Hit> fmh(spHandle, Event, fPFParticleLabel);
159  if (!fmh.isValid()) {
160  throw cet::exception("ShowerDirectionCheater")
161  << "Spacepoint and hit association not valid. Stopping.";
162  }
163  std::vector<art::Ptr<recob::SpacePoint>> spacePoints = fmspp.at(pfparticle.key());
164 
165  if (spacePoints.size() < 3) {
166  mf::LogWarning("ShowerDirectionCheater")
167  << spacePoints.size() << " spacepoints in shower, not calculating direction" << std::endl;
168  return 1;
169  }
170 
171  //Get Shower Centre
172  float TotalCharge;
173 
174  const TVector3 ShowerCentre = IShowerTool::GetLArPandoraShowerAlg().ShowerCentre(
175  clockData, detProp, spacePoints, fmh, TotalCharge);
176 
177  //Check if we are pointing the correct direction or not, First try the start position
178  if (ShowerEleHolder.CheckElement(fShowerStartPositionInputLabel) && fVertexFlip) {
179 
180  //Get the General direction as the vector between the start position and the centre
181  TVector3 StartPositionVec = {-999, -999, -999};
182  ShowerEleHolder.GetElement(fShowerStartPositionInputLabel, StartPositionVec);
183 
184  TVector3 GeneralDir = (ShowerCentre - StartPositionVec).Unit();
185 
186  //Dot product
187  vertexDotProduct = trueDir.Dot(GeneralDir);
188  }
189 
190  if (fRMSFlip) {
191  //Otherwise Check against the RMS of the shower. Method adapated from EMShower Thanks Mike.
193  spacePoints, ShowerCentre, trueDir, fNSegments);
194  }
195  Tree->Fill();
196  }
197 
198  return 0;
199  }
200 }
201 
202 DEFINE_ART_CLASS_TOOL(ShowerRecoTools::ShowerDirectionCheater)
art::ServiceHandle< art::TFileService > tfs
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
Definition: UtilFunc.cxx:42
process_name cluster
Definition: cheaterreco.fcl:51
std::map< int, const simb::MCParticle * > GetTrueParticleMap() const
void SetElement(T &dataproduct, const std::string &Name, bool checktag=false)
static constexpr bool
double RMSShowerGradient(std::vector< art::Ptr< recob::SpacePoint >> &sps, const TVector3 &ShowerCentre, const TVector3 &Direction, const unsigned int nSegments) const
int CalculateElement(const art::Ptr< recob::PFParticle > &pfparticle, art::Event &Event, reco::shower::ShowerElementHolder &ShowerEleHolder) override
std::map< int, std::vector< int > > GetTrueChain(std::map< int, const simb::MCParticle * > &trueParticles) const
bool CheckElement(const std::string &Name) const
int GetElement(const std::string &Name, T &Element) const
Declaration of cluster object.
shower::LArPandoraShowerCheatingAlg fLArPandoraShowerCheatingAlg
const shower::LArPandoraShowerAlg & GetLArPandoraShowerAlg() const
Definition: IShowerTool.h:88
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
TVector3 ShowerCentre(std::vector< art::Ptr< recob::SpacePoint >> const &showersps) const
auto const detProp
ShowerDirectionCheater(const fhicl::ParameterSet &pset)