LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
SvmVertexSelectionAlgorithm.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
17 
23 
25 
27 
28 #include <random>
29 
30 using namespace pandora;
31 
32 namespace lar_content
33 {
34 SvmVertexSelectionAlgorithm::SvmVertexSelectionAlgorithm() :
36  m_filePathEnvironmentVariable("FW_SEARCH_PATH"),
37  m_trainingSetMode(false),
38  m_allowClassifyDuringTraining(false),
39  m_mcVertexXCorrection(0.f),
40  m_minClusterCaloHits(12),
41  m_slidingFitWindow(100),
42  m_minShowerSpineLength(15.f),
43  m_beamDeweightingConstant(0.4),
44  m_localAsymmetryConstant(3.f),
45  m_globalAsymmetryConstant(1.f),
46  m_showerAsymmetryConstant(1.f),
47  m_energyKickConstant(0.06),
48  m_showerClusteringDistance(3.f),
49  m_minShowerClusterHits(1),
50  m_useShowerClusteringApproximation(false),
51  m_regionRadius(10.f),
52  m_rPhiFineTuningRadius(2.f),
53  m_maxTrueVertexRadius(1.f),
54  m_useRPhiFeatureForRegion(false),
55  m_dropFailedRPhiFastScoreCandidates(true)
56 {
57 }
58 
59 //------------------------------------------------------------------------------------------------------------------------------------------
60 
61 void SvmVertexSelectionAlgorithm::GetVertexScoreList(const VertexVector &vertexVector, const BeamConstants &beamConstants,
62  HitKDTree2D &kdTreeU, HitKDTree2D &kdTreeV, HitKDTree2D &kdTreeW, VertexScoreList &vertexScoreList) const
63 {
64  ClusterList clustersU, clustersV, clustersW;
65  this->GetClusterLists(m_inputClusterListNames, clustersU, clustersV, clustersW);
66 
67  SlidingFitDataList slidingFitDataListU, slidingFitDataListV, slidingFitDataListW;
68  this->CalculateClusterSlidingFits(clustersU, m_minClusterCaloHits, m_slidingFitWindow, slidingFitDataListU);
69  this->CalculateClusterSlidingFits(clustersV, m_minClusterCaloHits, m_slidingFitWindow, slidingFitDataListV);
70  this->CalculateClusterSlidingFits(clustersW, m_minClusterCaloHits, m_slidingFitWindow, slidingFitDataListW);
71 
72  ShowerClusterList showerClusterListU, showerClusterListV, showerClusterListW;
73  this->CalculateShowerClusterList(clustersU, showerClusterListU);
74  this->CalculateShowerClusterList(clustersV, showerClusterListV);
75  this->CalculateShowerClusterList(clustersW, showerClusterListW);
76 
77  // Create maps from hit types to objects for passing to feature tools.
78  const ClusterListMap clusterListMap{{TPC_VIEW_U, clustersU},
79  {TPC_VIEW_V, clustersV},
80  {TPC_VIEW_W, clustersV}};
81 
82  const SlidingFitDataListMap slidingFitDataListMap{{TPC_VIEW_U, slidingFitDataListU},
83  {TPC_VIEW_V, slidingFitDataListV},
84  {TPC_VIEW_W, slidingFitDataListW}};
85 
86  const ShowerClusterListMap showerClusterListMap{{TPC_VIEW_U, showerClusterListU},
87  {TPC_VIEW_V, showerClusterListV},
88  {TPC_VIEW_W, showerClusterListW}};
89 
90  const KDTreeMap kdTreeMap{{TPC_VIEW_U, kdTreeU},
91  {TPC_VIEW_V, kdTreeV},
92  {TPC_VIEW_W, kdTreeW}};
93 
94  // Calculate the event feature list and the vertex feature map.
95  EventFeatureInfo eventFeatureInfo(this->CalculateEventFeatures(clustersU, clustersV, clustersW, vertexVector));
96 
97  LArMvaHelper::MvaFeatureVector eventFeatureList;
98  this->AddEventFeaturesToVector(eventFeatureInfo, eventFeatureList);
99 
100  VertexFeatureInfoMap vertexFeatureInfoMap;
101  for (const Vertex *const pVertex : vertexVector)
102  {
103  this->PopulateVertexFeatureInfoMap(beamConstants, clusterListMap, slidingFitDataListMap, showerClusterListMap, kdTreeMap, pVertex,
104  vertexFeatureInfoMap);
105  }
106 
107  // Use a simple score to get the list of vertices representing good regions.
108  VertexScoreList initialScoreList;
109  for (const Vertex *const pVertex : vertexVector)
110  PopulateInitialScoreList(vertexFeatureInfoMap, pVertex, initialScoreList);
111 
112  VertexVector bestRegionVertices;
113  this->GetBestRegionVertices(initialScoreList, bestRegionVertices);
114 
115  if (m_trainingSetMode)
116  this->ProduceTrainingSets(vertexVector, bestRegionVertices, vertexFeatureInfoMap, eventFeatureList, kdTreeMap);
117 
118  if ((!m_trainingSetMode || m_allowClassifyDuringTraining) && !bestRegionVertices.empty())
119  {
120  // Use svm to choose the region.
121  const Vertex *const pBestRegionVertex(this->CompareVertices(bestRegionVertices, vertexFeatureInfoMap, eventFeatureList, m_svMachineRegion,
123 
124  // Get all the vertices in the best region.
125  VertexVector regionalVertices{pBestRegionVertex};
126  for (const Vertex *const pVertex : vertexVector)
127  {
128  if (pVertex == pBestRegionVertex)
129  continue;
130 
131  if ((pBestRegionVertex->GetPosition() - pVertex->GetPosition()).GetMagnitude() < m_regionRadius)
132  regionalVertices.push_back(pVertex);
133  }
134 
135  this->CalculateRPhiScores(regionalVertices, vertexFeatureInfoMap, kdTreeMap);
136 
137  if (!regionalVertices.empty())
138  {
139  // Use svm to choose the vertex and then fine-tune using the RPhi score.
140  const Vertex *const pBestVertex(this->CompareVertices(regionalVertices, vertexFeatureInfoMap, eventFeatureList, m_svMachineVertex, true));
141  this->PopulateFinalVertexScoreList(vertexFeatureInfoMap, pBestVertex, vertexVector, vertexScoreList);
142  }
143  }
144 }
145 
146 //------------------------------------------------------------------------------------------------------------------------------------------
147 
148 void SvmVertexSelectionAlgorithm::CalculateShowerClusterList(const ClusterList &inputClusterList, ShowerClusterList &showerClusterList) const
149 {
150  ClusterEndPointsMap clusterEndPointsMap;
151  ClusterList showerLikeClusters;
152  this->GetShowerLikeClusterEndPoints(inputClusterList, showerLikeClusters, clusterEndPointsMap);
153 
154  const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
155  ClusterList availableShowerLikeClusters(showerLikeClusters.begin(), showerLikeClusters.end());
156 
157  HitKDTree2D kdTree;
158  HitToClusterMap hitToClusterMap;
159 
161  this->PopulateKdTree(availableShowerLikeClusters, kdTree, hitToClusterMap);
162 
163  while (!availableShowerLikeClusters.empty())
164  {
165  ClusterList showerCluster;
166  showerCluster.push_back(availableShowerLikeClusters.back());
167  availableShowerLikeClusters.pop_back();
168 
169  bool addedCluster(true);
170  while (addedCluster && !availableShowerLikeClusters.empty())
171  {
172  addedCluster = false;
173  for (const Cluster *const pCluster : showerCluster)
174  {
176  {
177  addedCluster = this->AddClusterToShower(kdTree, hitToClusterMap, availableShowerLikeClusters, pCluster, showerCluster);
178  }
179  else
180  {
181  addedCluster = this->AddClusterToShower(clusterEndPointsMap, availableShowerLikeClusters, pCluster, showerCluster);
182  }
183 
184  if (addedCluster)
185  break;
186  }
187  }
188 
189  unsigned int totHits(0);
190  for (const Cluster *const pCluster : showerCluster)
191  totHits += pCluster->GetNCaloHits();
192 
193  if (totHits < m_minClusterCaloHits)
194  continue;
195 
196  showerClusterList.emplace_back(showerCluster, slidingFitPitch, m_slidingFitWindow);
197  }
198 }
199 
200 //------------------------------------------------------------------------------------------------------------------------------------------
201 
202 void SvmVertexSelectionAlgorithm::GetShowerLikeClusterEndPoints(const ClusterList &clusterList, ClusterList &showerLikeClusters,
203  ClusterEndPointsMap &clusterEndPointsMap) const
204 {
205  for (const Cluster *const pCluster : clusterList)
206  {
207  if (pCluster->GetNCaloHits() < m_minShowerClusterHits)
208  continue;
209 
210  if (this->IsClusterShowerLike(pCluster))
211  showerLikeClusters.push_back(pCluster);
212 
213  CaloHitList clusterCaloHitList;
214  pCluster->GetOrderedCaloHitList().FillCaloHitList(clusterCaloHitList);
215 
216  CaloHitVector clusterCaloHitVector(clusterCaloHitList.begin(), clusterCaloHitList.end());
217  std::sort(clusterCaloHitVector.begin(), clusterCaloHitVector.end(), LArClusterHelper::SortHitsByPosition);
218 
219  if (clusterCaloHitVector.empty())
220  continue;
221 
222  ClusterEndPoints clusterEndPoints(clusterCaloHitVector.front()->GetPositionVector(), clusterCaloHitVector.back()->GetPositionVector());
223  clusterEndPointsMap.emplace(pCluster, clusterEndPoints);
224  }
225 }
226 
227 //------------------------------------------------------------------------------------------------------------------------------------------
228 
229 void SvmVertexSelectionAlgorithm::PopulateKdTree(const ClusterList &clusterList, HitKDTree2D &kdTree, HitToClusterMap &hitToClusterMap) const
230 {
231  CaloHitList allCaloHits;
232 
233  for (const Cluster *const pCluster : clusterList)
234  {
235  CaloHitList daughterHits;
236  pCluster->GetOrderedCaloHitList().FillCaloHitList(daughterHits);
237  allCaloHits.insert(allCaloHits.end(), daughterHits.begin(), daughterHits.end());
238 
239  for (const CaloHit *const pCaloHit : daughterHits)
240  (void) hitToClusterMap.insert(HitToClusterMap::value_type(pCaloHit, pCluster));
241  }
242 
243  HitKDNode2DList hitKDNode2DList;
244  KDTreeBox hitsBoundingRegion2D(fill_and_bound_2d_kd_tree(allCaloHits, hitKDNode2DList));
245  kdTree.build(hitKDNode2DList, hitsBoundingRegion2D);
246 }
247 
248 //------------------------------------------------------------------------------------------------------------------------------------------
249 
250 bool SvmVertexSelectionAlgorithm::AddClusterToShower(const ClusterEndPointsMap &clusterEndPointsMap, ClusterList &availableShowerLikeClusters,
251  const Cluster *const pCluster, ClusterList &showerCluster) const
252 {
253  const auto existingEndPointsIter(clusterEndPointsMap.find(pCluster));
254  if (existingEndPointsIter == clusterEndPointsMap.end())
255  return false;
256 
257  const ClusterEndPoints &existingClusterEndPoints(existingEndPointsIter->second);
258 
259  for (auto iter = availableShowerLikeClusters.begin(); iter != availableShowerLikeClusters.end(); ++iter)
260  {
261  const Cluster *const pAvailableShowerLikeCluster(*iter);
262  const auto &newEndPointsIter(clusterEndPointsMap.find(pAvailableShowerLikeCluster));
263 
264  if (newEndPointsIter == clusterEndPointsMap.end())
265  continue;
266 
267  const ClusterEndPoints &newClusterEndPoints(newEndPointsIter->second);
268  const float startStartDistance((newClusterEndPoints.first - existingClusterEndPoints.first).GetMagnitude());
269  const float startEndDistance((newClusterEndPoints.first - existingClusterEndPoints.second).GetMagnitude());
270  const float endStartDistance((newClusterEndPoints.second - existingClusterEndPoints.first).GetMagnitude());
271  const float endEndDistance((newClusterEndPoints.second - existingClusterEndPoints.second).GetMagnitude());
272 
273  const float smallestDistance(std::min(std::min(startStartDistance, startEndDistance), std::min(endStartDistance, endEndDistance)));
274 
275  if (smallestDistance < m_showerClusteringDistance)
276  {
277  showerCluster.push_back(pAvailableShowerLikeCluster);
278  availableShowerLikeClusters.erase(iter); // Now must return, after invalidating current iterator
279  return true;
280  }
281  }
282 
283  return false;
284 }
285 
286 //------------------------------------------------------------------------------------------------------------------------------------------
287 
289  ClusterList &availableShowerLikeClusters, const Cluster *const pCluster, ClusterList &showerCluster) const
290 {
291  ClusterSet nearbyClusters;
292  CaloHitList daughterHits;
293  pCluster->GetOrderedCaloHitList().FillCaloHitList(daughterHits);
294 
295  for (const CaloHit *const pCaloHit : daughterHits)
296  {
298 
299  HitKDNode2DList found;
300  kdTree.search(searchRegionHits, found);
301 
302  for (const auto &hit : found)
303  (void) nearbyClusters.insert(hitToClusterMap.at(hit.data));
304  }
305 
306  for (auto iter = availableShowerLikeClusters.begin(); iter != availableShowerLikeClusters.end(); ++iter)
307  {
308  const Cluster *const pAvailableShowerLikeCluster(*iter);
309 
310  if ((pAvailableShowerLikeCluster != pCluster) && nearbyClusters.count(pAvailableShowerLikeCluster))
311  {
312  showerCluster.push_back(pAvailableShowerLikeCluster);
313  availableShowerLikeClusters.erase(iter); // Now must return, after invalidating current iterator
314  return true;
315  }
316  }
317 
318  return false;
319 }
320 
321 //------------------------------------------------------------------------------------------------------------------------------------------
322 
324  const ClusterList &clusterListV, const ClusterList &clusterListW, const VertexVector &vertexVector) const
325 {
326  float eventEnergy(0.f);
327  unsigned int nShoweryHits(0), nHits(0);
328 
329  this->IncrementShoweryParameters(clusterListU, nShoweryHits, nHits, eventEnergy);
330  this->IncrementShoweryParameters(clusterListV, nShoweryHits, nHits, eventEnergy);
331  this->IncrementShoweryParameters(clusterListW, nShoweryHits, nHits, eventEnergy);
332 
333  const unsigned int nClusters(clusterListU.size() + clusterListV.size() + clusterListW.size());
334  const float eventShoweryness((nHits > 0) ? static_cast<float>(nShoweryHits) / static_cast<float>(nHits) : 0.f);
335 
336  ClusterList allClusters(clusterListU);
337  allClusters.insert(allClusters.end(), clusterListV.begin(), clusterListV.end());
338  allClusters.insert(allClusters.end(), clusterListW.begin(), clusterListW.end());
339 
340  float eventVolume(0.f), longitudinality(0.f);
341  this->GetEventShapeFeatures(allClusters, eventVolume, longitudinality);
342 
343  return EventFeatureInfo(eventShoweryness, eventEnergy, eventVolume, longitudinality, nHits, nClusters, vertexVector.size());
344 }
345 
346 //------------------------------------------------------------------------------------------------------------------------------------------
347 
348 void SvmVertexSelectionAlgorithm::IncrementShoweryParameters(const ClusterList &clusterList, unsigned int &nShoweryHits, unsigned int &nHits,
349  float &eventEnergy) const
350 {
351  for (const Cluster *const pCluster : clusterList)
352  {
353  if (this->IsClusterShowerLike(pCluster))
354  nShoweryHits += pCluster->GetNCaloHits();
355 
356  eventEnergy += pCluster->GetElectromagneticEnergy();
357  nHits += pCluster->GetNCaloHits();
358  }
359 }
360 
361 //------------------------------------------------------------------------------------------------------------------------------------------
362 
363 inline bool SvmVertexSelectionAlgorithm::IsClusterShowerLike(const Cluster *const pCluster) const
364 {
365  return (pCluster->GetParticleId() == E_MINUS && LArClusterHelper::GetLength(pCluster) < m_minShowerSpineLength);
366 }
367 
368 //------------------------------------------------------------------------------------------------------------------------------------------
369 
370 void SvmVertexSelectionAlgorithm::GetEventShapeFeatures(const ClusterList &clusterList, float &eventVolume, float &longitudinality) const
371 {
372  InputFloat xMin, yMin, zMin, xMax, yMax, zMax;
373 
374  for (const Cluster *const pCluster : clusterList)
375  {
376  CartesianVector minPosition(0.f, 0.f, 0.f), maxPosition(0.f, 0.f, 0.f);
377  LArClusterHelper::GetClusterBoundingBox(pCluster, minPosition, maxPosition);
378 
379  this->UpdateSpanCoordinate(minPosition.GetX(), maxPosition.GetX(), xMin, xMax);
380  this->UpdateSpanCoordinate(minPosition.GetY(), maxPosition.GetY(), yMin, yMax);
381  this->UpdateSpanCoordinate(minPosition.GetZ(), maxPosition.GetZ(), zMin, zMax);
382  }
383 
384  const float xSpan(this->GetCoordinateSpan(xMax, xMin));
385  const float ySpan(this->GetCoordinateSpan(yMax, zMin));
386  const float zSpan(this->GetCoordinateSpan(yMax, zMin));
387 
388  // Calculate the volume and longitudinality of the event (ySpan often 0 - to be investigated).
389  if ((xSpan > std::numeric_limits<float>::epsilon()) && (ySpan > std::numeric_limits<float>::epsilon()))
390  {
391  eventVolume = xSpan * ySpan * zSpan;
392  longitudinality = zSpan / (xSpan + ySpan);
393  }
394 
395  else if (ySpan > std::numeric_limits<float>::epsilon())
396  {
397  eventVolume = ySpan * ySpan * zSpan;
398  longitudinality = zSpan / (ySpan + ySpan);
399  }
400 
401  else if (xSpan > std::numeric_limits<float>::epsilon())
402  {
403  eventVolume = xSpan * xSpan * zSpan;
404  longitudinality = zSpan / (xSpan + xSpan);
405  }
406 }
407 
408 //------------------------------------------------------------------------------------------------------------------------------------------
409 
410 inline void SvmVertexSelectionAlgorithm::UpdateSpanCoordinate(const float minPositionCoord, const float maxPositionCoord, InputFloat &minCoord,
411  InputFloat &maxCoord) const
412 {
413  if (!minCoord.IsInitialized() || minPositionCoord < minCoord.Get())
414  minCoord = minPositionCoord;
415 
416  if (!maxCoord.IsInitialized() || maxPositionCoord > maxCoord.Get())
417  maxCoord = maxPositionCoord;
418 }
419 
420 //------------------------------------------------------------------------------------------------------------------------------------------
421 
422 inline float SvmVertexSelectionAlgorithm::GetCoordinateSpan(const InputFloat &minCoord, const InputFloat &maxCoord) const
423 {
424  if (minCoord.IsInitialized() && maxCoord.IsInitialized())
425  return std::fabs(maxCoord.Get() - minCoord.Get());
426 
427  return 0.f;
428 }
429 
430 //------------------------------------------------------------------------------------------------------------------------------------------
431 
433  LArMvaHelper::MvaFeatureVector &featureVector) const
434 {
435  featureVector.push_back(static_cast<double>(eventFeatureInfo.m_eventShoweryness));
436  featureVector.push_back(static_cast<double>(eventFeatureInfo.m_eventEnergy));
437  featureVector.push_back(static_cast<double>(eventFeatureInfo.m_eventVolume));
438  featureVector.push_back(static_cast<double>(eventFeatureInfo.m_longitudinality));
439  featureVector.push_back(static_cast<double>(eventFeatureInfo.m_nHits));
440  featureVector.push_back(static_cast<double>(eventFeatureInfo.m_nClusters));
441  featureVector.push_back(static_cast<double>(eventFeatureInfo.m_nCandidates));
442 }
443 
444 //------------------------------------------------------------------------------------------------------------------------------------------
445 
447  const SlidingFitDataListMap &slidingFitDataListMap, const ShowerClusterListMap &showerClusterListMap, const KDTreeMap &kdTreeMap,
448  const Vertex *const pVertex, VertexFeatureInfoMap &vertexFeatureInfoMap) const
449 {
450  float bestFastScore(-std::numeric_limits<float>::max()); // not actually used - artefact of toolizing RPhi score and still using performance trick
451 
452  const double beamDeweighting(this->GetBeamDeweightingScore(beamConstants, pVertex));
453 
454  const double energyKick(LArMvaHelper::CalculateFeaturesOfType<EnergyKickFeatureTool>(m_featureToolVector, this, pVertex,
455  slidingFitDataListMap, clusterListMap, kdTreeMap, showerClusterListMap, beamDeweighting, bestFastScore).at(0).Get());
456 
457  const double localAsymmetry(LArMvaHelper::CalculateFeaturesOfType<LocalAsymmetryFeatureTool>(m_featureToolVector, this, pVertex,
458  slidingFitDataListMap, clusterListMap, kdTreeMap, showerClusterListMap, beamDeweighting, bestFastScore).at(0).Get());
459 
460  const double globalAsymmetry(LArMvaHelper::CalculateFeaturesOfType<GlobalAsymmetryFeatureTool>(m_featureToolVector, this, pVertex,
461  slidingFitDataListMap, clusterListMap, kdTreeMap, showerClusterListMap, beamDeweighting, bestFastScore).at(0).Get());
462 
463  const double showerAsymmetry(LArMvaHelper::CalculateFeaturesOfType<ShowerAsymmetryFeatureTool>(m_featureToolVector, this, pVertex,
464  slidingFitDataListMap, clusterListMap, kdTreeMap, showerClusterListMap, beamDeweighting, bestFastScore).at(0).Get());
465 
466  //const double rPhiFeature(LArMvaHelper::CalculateFeaturesOfType<RPhiFeatureTool>(m_featureToolVector, this, pVertex,
467  // slidingFitDataListMap, clusterListMap, kdTreeMap, showerClusterListMap, beamDeweighting, bestFastScore).at(0).Get());
468 
469  VertexFeatureInfo vertexFeatureInfo(beamDeweighting, 0.f, energyKick, localAsymmetry, globalAsymmetry, showerAsymmetry);
470  vertexFeatureInfoMap.emplace(pVertex, vertexFeatureInfo);
471 }
472 
473 //------------------------------------------------------------------------------------------------------------------------------------------
474 
475 void SvmVertexSelectionAlgorithm::PopulateInitialScoreList(VertexFeatureInfoMap &vertexFeatureInfoMap, const Vertex *const pVertex,
476  VertexScoreList &initialScoreList) const
477 {
478  VertexFeatureInfo vertexFeatureInfo = vertexFeatureInfoMap.at(pVertex);
479 
480  const float beamDeweightingScore(vertexFeatureInfo.m_beamDeweighting / m_beamDeweightingConstant);
481  const float energyKickScore(-vertexFeatureInfo.m_energyKick / m_energyKickConstant);
482  const float localAsymmetryScore(vertexFeatureInfo.m_localAsymmetry / m_localAsymmetryConstant);
483  const float globalAsymmetryScore(vertexFeatureInfo.m_globalAsymmetry / m_globalAsymmetryConstant);
484  const float showerAsymmetryScore(vertexFeatureInfo.m_showerAsymmetry / m_showerAsymmetryConstant);
485 
486  initialScoreList.emplace_back(pVertex, beamDeweightingScore + energyKickScore + localAsymmetryScore + globalAsymmetryScore + showerAsymmetryScore);
487 }
488 
489 //------------------------------------------------------------------------------------------------------------------------------------------
490 
491 void SvmVertexSelectionAlgorithm::GetBestRegionVertices(VertexScoreList &initialScoreList, VertexVector &bestRegionVertices) const
492 {
493  std::sort(initialScoreList.begin(), initialScoreList.end());
494 
495  for (const VertexScore &vertexScore : initialScoreList)
496  {
497  const Vertex *const pVertex(vertexScore.GetVertex());
498  bool farEnoughAway(true);
499 
500  for (const Vertex *const pRegionVertex: bestRegionVertices)
501  {
502  if (pRegionVertex == pVertex)
503  {
504  farEnoughAway = false;
505  break;
506  }
507 
508  const float distance = (pRegionVertex->GetPosition() - pVertex->GetPosition()).GetMagnitude();
509 
510  if (distance <= m_regionRadius)
511  {
512  farEnoughAway = false;
513  break;
514  }
515  }
516 
517  if (farEnoughAway)
518  bestRegionVertices.push_back(pVertex);
519  }
520 }
521 
522 //------------------------------------------------------------------------------------------------------------------------------------------
523 
524 void SvmVertexSelectionAlgorithm::ProduceTrainingSets(const VertexVector &vertexVector, const VertexVector &bestRegionVertices,
525  VertexFeatureInfoMap &vertexFeatureInfoMap, const LArMvaHelper::MvaFeatureVector &eventFeatureList, const KDTreeMap &kdTreeMap) const
526 {
527  if (vertexVector.empty())
528  return;
529 
530  // Create a distribution for random coin flips.
531  std::random_device device;
532  std::mt19937 generator(device());
533  std::bernoulli_distribution coinFlip(0.5);
534 
535  const std::string interactionType(this->GetInteractionType());
536 
537  // Produce training examples for the vertices representing regions.
538  const Vertex *const pBestRegionVertex(this->ProduceTrainingExamples(bestRegionVertices, vertexFeatureInfoMap, coinFlip, generator,
539  interactionType, m_trainingOutputFileRegion, eventFeatureList, m_regionRadius, m_useRPhiFeatureForRegion));
540 
541  // Get all the vertices in the best region.
542  VertexVector regionalVertices{pBestRegionVertex};
543  for (const Vertex *const pVertex : vertexVector)
544  {
545  if (pVertex == pBestRegionVertex)
546  continue;
547 
548  if ((pBestRegionVertex->GetPosition() - pVertex->GetPosition()).GetMagnitude() < m_regionRadius)
549  regionalVertices.push_back(pVertex);
550  }
551 
552  this->CalculateRPhiScores(regionalVertices, vertexFeatureInfoMap, kdTreeMap);
553 
554  // Produce training examples for the final vertices within the best region.
555  if (!regionalVertices.empty())
556  {
557  this->ProduceTrainingExamples(regionalVertices, vertexFeatureInfoMap, coinFlip, generator, interactionType, m_trainingOutputFileVertex,
558  eventFeatureList, m_maxTrueVertexRadius, true);
559  }
560 }
561 
562 //------------------------------------------------------------------------------------------------------------------------------------------
563 
565  const KDTreeMap &kdTreeMap) const
566 {
567  float bestFastScore(-std::numeric_limits<float>::max());
568 
569  for (auto iter = vertexVector.begin(); iter != vertexVector.end(); /* no increment */)
570  {
571  VertexFeatureInfo &vertexFeatureInfo = vertexFeatureInfoMap.at(*iter);
572  vertexFeatureInfo.m_rPhiFeature = static_cast<float>(LArMvaHelper::CalculateFeaturesOfType<RPhiFeatureTool>(m_featureToolVector, this, *iter,
573  SlidingFitDataListMap(), ClusterListMap(), kdTreeMap, ShowerClusterListMap(), vertexFeatureInfo.m_beamDeweighting,
574  bestFastScore).at(0).Get());
575 
576  if (m_dropFailedRPhiFastScoreCandidates && (vertexFeatureInfo.m_rPhiFeature <= std::numeric_limits<float>::epsilon()))
577  iter = vertexVector.erase(iter);
578 
579  else
580  ++iter;
581  }
582 }
583 
584 //------------------------------------------------------------------------------------------------------------------------------------------
585 
587 {
588  // Extract input collections
589  const MCParticleList *pMCParticleList(nullptr);
590  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_mcParticleListName, pMCParticleList));
591 
592  const CaloHitList *pCaloHitList(nullptr);
593  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_caloHitListName, pCaloHitList));
594 
595  // ATTN Assumes single neutrino is parent of all neutrino-induced mc particles
596  LArMCParticleHelper::MCContributionMap nuMCParticlesToGoodHitsMap;
598  LArMCParticleHelper::IsBeamNeutrinoFinalState, nuMCParticlesToGoodHitsMap);
599 
600  MCParticleList mcPrimaryList;
601  for (const auto &mapEntry : nuMCParticlesToGoodHitsMap) mcPrimaryList.push_back(mapEntry.first);
602  mcPrimaryList.sort(LArMCParticleHelper::SortByMomentum);
603 
605  return LArInteractionTypeHelper::ToString(interactionType);
606 }
607 
608 //------------------------------------------------------------------------------------------------------------------------------------------
609 
610 const pandora::Vertex * SvmVertexSelectionAlgorithm::ProduceTrainingExamples(const VertexVector &vertexVector,
611  const VertexFeatureInfoMap &vertexFeatureInfoMap, std::bernoulli_distribution &coinFlip, std::mt19937 &generator,
612  const std::string &interactionType, const std::string &trainingOutputFile, const LArMvaHelper::MvaFeatureVector &eventFeatureList,
613  const float maxRadius, const bool useRPhi) const
614 {
615  const Vertex *pBestVertex(nullptr);
616  float bestVertexDr(std::numeric_limits<float>::max());
617 
618  LArMvaHelper::MvaFeatureVector bestVertexFeatureList;
619  this->GetBestVertex(vertexVector, pBestVertex, bestVertexDr);
620 
621  VertexFeatureInfo bestVertexFeatureInfo(vertexFeatureInfoMap.at(pBestVertex));
622  this->AddVertexFeaturesToVector(bestVertexFeatureInfo, bestVertexFeatureList, useRPhi);
623 
624  for (const Vertex *const pVertex : vertexVector)
625  {
626  if (pVertex == pBestVertex)
627  continue;
628 
629  LArMvaHelper::MvaFeatureVector featureList;
630  VertexFeatureInfo vertexFeatureInfo(vertexFeatureInfoMap.at(pVertex));
631  this->AddVertexFeaturesToVector(vertexFeatureInfo, featureList, useRPhi);
632 
633  if (pBestVertex && (bestVertexDr < maxRadius))
634  {
635  if (coinFlip(generator))
636  {
637  LArMvaHelper::ProduceTrainingExample(trainingOutputFile + "_" + interactionType + ".txt", true, eventFeatureList,
638  bestVertexFeatureList, featureList);
639  }
640 
641  else
642  {
643  LArMvaHelper::ProduceTrainingExample(trainingOutputFile + "_" + interactionType + ".txt", false, eventFeatureList, featureList,
644  bestVertexFeatureList);
645  }
646  }
647  }
648 
649  return pBestVertex;
650 }
651 
652 //------------------------------------------------------------------------------------------------------------------------------------------
653 
654 void SvmVertexSelectionAlgorithm::GetBestVertex(const VertexVector &vertexVector, const Vertex *&pBestVertex, float &bestVertexDr) const
655 {
656  // Extract input collections
657  const MCParticleList *pMCParticleList(nullptr);
658  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_mcParticleListName, pMCParticleList));
659 
660  // Obtain vector: true neutrinos
661  MCParticleVector mcNeutrinoVector;
662  LArMCParticleHelper::GetTrueNeutrinos(pMCParticleList, mcNeutrinoVector);
663 
664  for (const Vertex *const pVertex : vertexVector)
665  {
666  float mcVertexDr(std::numeric_limits<float>::max());
667  for (const MCParticle *const pMCNeutrino : mcNeutrinoVector)
668  {
669  const CartesianVector mcNeutrinoPosition(pMCNeutrino->GetEndpoint().GetX() + m_mcVertexXCorrection, pMCNeutrino->GetEndpoint().GetY(),
670  pMCNeutrino->GetEndpoint().GetZ());
671 
672  const float dr = (mcNeutrinoPosition - pVertex->GetPosition()).GetMagnitude();
673  if (dr < mcVertexDr)
674  mcVertexDr = dr;
675  }
676 
677  if (mcVertexDr < bestVertexDr)
678  {
679  bestVertexDr = mcVertexDr;
680  pBestVertex = pVertex;
681  }
682  }
683 }
684 
685 //------------------------------------------------------------------------------------------------------------------------------------------
686 
688  LArMvaHelper::MvaFeatureVector &featureVector, const bool useRPhi) const
689 {
690  featureVector.push_back(static_cast<double>(vertexFeatureInfo.m_beamDeweighting));
691  featureVector.push_back(static_cast<double>(vertexFeatureInfo.m_energyKick));
692  featureVector.push_back(static_cast<double>(vertexFeatureInfo.m_globalAsymmetry));
693  featureVector.push_back(static_cast<double>(vertexFeatureInfo.m_localAsymmetry));
694  featureVector.push_back(static_cast<double>(vertexFeatureInfo.m_showerAsymmetry));
695 
696  if (useRPhi)
697  featureVector.push_back(static_cast<double>(vertexFeatureInfo.m_rPhiFeature));
698 }
699 
700 //------------------------------------------------------------------------------------------------------------------------------------------
701 
702 const pandora::Vertex * SvmVertexSelectionAlgorithm::CompareVertices(const VertexVector &vertexVector, const VertexFeatureInfoMap &vertexFeatureInfoMap,
703  const LArMvaHelper::MvaFeatureVector &eventFeatureList, const SupportVectorMachine &supportVectorMachine, const bool useRPhi) const
704 {
705  const Vertex *pBestVertex(vertexVector.front());
706  LArMvaHelper::MvaFeatureVector chosenFeatureList;
707 
708  VertexFeatureInfo chosenVertexFeatureInfo(vertexFeatureInfoMap.at(pBestVertex));
709  this->AddVertexFeaturesToVector(chosenVertexFeatureInfo, chosenFeatureList, useRPhi);
710 
711  for (const Vertex *const pVertex : vertexVector)
712  {
713  if (pVertex == pBestVertex)
714  continue;
715 
716  LArMvaHelper::MvaFeatureVector featureList;
717  VertexFeatureInfo vertexFeatureInfo(vertexFeatureInfoMap.at(pVertex));
718  this->AddVertexFeaturesToVector(vertexFeatureInfo, featureList, useRPhi);
719 
720  if (LArMvaHelper::Classify(supportVectorMachine, eventFeatureList, featureList, chosenFeatureList))
721  {
722  pBestVertex = pVertex;
723  chosenFeatureList = featureList;
724  }
725  }
726 
727  return pBestVertex;
728 }
729 
730 //------------------------------------------------------------------------------------------------------------------------------------------
731 
732 void SvmVertexSelectionAlgorithm::PopulateFinalVertexScoreList(const VertexFeatureInfoMap &vertexFeatureInfoMap, const Vertex *const pFavouriteVertex,
733  const VertexVector &vertexVector, VertexScoreList &finalVertexScoreList) const
734 {
735  if (pFavouriteVertex)
736  {
737  const CartesianVector vertexPosition(pFavouriteVertex->GetPosition());
738 
739  for (const Vertex *const pVertex : vertexVector)
740  {
741  if ((pVertex->GetPosition() - vertexPosition).GetMagnitude() < m_rPhiFineTuningRadius)
742  {
743  const float rPhiScore(vertexFeatureInfoMap.at(pVertex).m_rPhiFeature);
744  finalVertexScoreList.emplace_back(pVertex, rPhiScore);
745  }
746  }
747  }
748 }
749 
750 //------------------------------------------------------------------------------------------------------------------------------------------
751 //------------------------------------------------------------------------------------------------------------------------------------------
752 
753 StatusCode SvmVertexSelectionAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
754 {
755  AlgorithmToolVector algorithmToolVector;
756  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*this, xmlHandle, "FeatureTools", algorithmToolVector));
757 
758  for (AlgorithmTool *const pAlgorithmTool : algorithmToolVector)
759  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, LArMvaHelper::AddFeatureToolToVector(pAlgorithmTool, m_featureToolVector));
760 
761  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
762  "FilePathEnvironmentVariable", m_filePathEnvironmentVariable));
763 
764  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
765  "SvmFileName", m_svmFileName));
766 
767  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
768  "RegionSvmName", m_regionSvmName));
769 
770  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
771  "VertexSvmName", m_vertexSvmName));
772 
773  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
774  "TrainingSetMode", m_trainingSetMode));
775 
776  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
777  "AllowClassifyDuringTraining", m_allowClassifyDuringTraining));
778 
780  {
781  if (m_svmFileName.empty() || m_regionSvmName.empty() || m_vertexSvmName.empty())
782  {
783  std::cout << "SvmVertexSelectionAlgorithm: SvmFileName, RegionSvmName and VertexSvmName must be set if training set mode is" <<
784  "off or we allow classification during training" << std::endl;
785  return STATUS_CODE_INVALID_PARAMETER;
786  }
787 
789  m_svMachineRegion.Initialize(fullSvmFileName, m_regionSvmName);
790  m_svMachineVertex.Initialize(fullSvmFileName, m_vertexSvmName);
791  }
792 
793 
794  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
795  "MCVertexXCorrection", m_mcVertexXCorrection));
796 
797  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
798  "TrainingOutputFileRegion", m_trainingOutputFileRegion));
799 
800  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
801  "TrainingOutputFileVertex", m_trainingOutputFileVertex));
802 
804  {
805  std::cout << "SvmVertexSelectionAlgorithm: TrainingOutputFileRegion and TrainingOutputFileVertex are required for training set " <<
806  "mode" << std::endl;
807  return STATUS_CODE_INVALID_PARAMETER;
808  }
809 
810  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
811  "MCParticleListName", m_mcParticleListName));
812 
813  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
814  "CaloHitListName", m_caloHitListName));
815 
816  if (m_trainingSetMode && (m_mcParticleListName.empty() || m_caloHitListName.empty()))
817  {
818  std::cout << "SvmVertexSelectionAlgorithm: MCParticleListName and CaloHitListName are required for training set mode" << std::endl;
819  return STATUS_CODE_INVALID_PARAMETER;
820  }
821 
822  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadVectorOfValues(xmlHandle,
823  "InputClusterListNames", m_inputClusterListNames));
824 
825  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
826  "MinClusterCaloHits", m_minClusterCaloHits));
827 
828  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
829  "SlidingFitWindow", m_slidingFitWindow));
830 
831  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
832  "MinShowerSpineLength", m_minShowerSpineLength));
833 
834  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
835  "BeamDeweightingConstant", m_beamDeweightingConstant));
836 
837  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
838  "LocalAsymmetryConstant", m_localAsymmetryConstant));
839 
840  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
841  "GlobalAsymmetryConstant", m_globalAsymmetryConstant));
842 
843  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
844  "ShowerAsymmetryConstant", m_showerAsymmetryConstant));
845 
846  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
847  "EnergyKickConstant", m_energyKickConstant));
848 
849  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
850  "ShowerClusteringDistance", m_showerClusteringDistance));
851 
852  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
853  "MinShowerClusterHits", m_minShowerClusterHits));
854 
855  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
856  "UseShowerClusteringApproximation", m_useShowerClusteringApproximation));
857 
858  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
859  "RegionRadius", m_regionRadius));
860 
861  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
862  "RPhiFineTuningRadius", m_rPhiFineTuningRadius));
863 
864  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
865  "MaxTrueVertexRadius", m_maxTrueVertexRadius));
866 
867  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
868  "UseRPhiFeatureForRegion", m_useRPhiFeatureForRegion));
869 
870  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
871  "DropFailedRPhiFastScoreCandidates", m_dropFailedRPhiFastScoreCandidates));
872 
874 }
875 
876 } // namespace lar_content
std::string m_vertexSvmName
The name of the vertex Svm to find.
std::map< const pandora::Vertex *const, VertexFeatureInfo > VertexFeatureInfoMap
Header file for the kd tree linker algo template class.
void PopulateFinalVertexScoreList(const VertexFeatureInfoMap &vertexFeatureInfoMap, const pandora::Vertex *const pFavouriteVertex, const pandora::VertexVector &vertexVector, VertexScoreList &finalVertexScoreList) const
Populate the final vertex score list using the r/phi score to find the best vertex in the vicinity...
void GetBestRegionVertices(VertexScoreList &initialScoreList, pandora::VertexVector &bestRegionVertices) const
Get the list of top-N separated vertices.
MvaTypes::MvaFeatureVector MvaFeatureVector
Definition: LArMvaHelper.h:58
unsigned int m_nCandidates
The total number of vertex candidates.
void IncrementShoweryParameters(const pandora::ClusterList &clusterList, unsigned int &nShoweryHits, unsigned int &nHits, float &eventEnergy) const
Increment the showery hit parameters for a cluster list.
Header file for the interaction type helper class.
unsigned int m_minShowerClusterHits
The minimum number of shower cluster hits.
float m_globalAsymmetryConstant
The global asymmetry constant for the initial region score list.
void GetClusterLists(const pandora::StringVector &inputClusterListNames, pandora::ClusterList &clusterListU, pandora::ClusterList &clusterListV, pandora::ClusterList &clusterListW) const
Get the cluster lists.
Class that implements the KDTree partition of 2D space and a closest point search algorithm...
void CalculateClusterSlidingFits(const pandora::ClusterList &inputClusterList, const unsigned int minClusterCaloHits, const unsigned int slidingFitWindow, SlidingFitDataList &slidingFitDataList) const
Calculate the cluster sliding fits.
Box structure used to define 2D field. It&#39;s used in KDTree building step to divide the detector space...
void CalculateRPhiScores(pandora::VertexVector &vertexVector, VertexFeatureInfoMap &vertexFeatureInfoMap, const KDTreeMap &kdTreeMap) const
Calculate the r/phi scores for the vertices in a vector, possibly erasing those that fail the fast sc...
std::unordered_map< const pandora::CaloHit *, const pandora::Cluster * > HitToClusterMap
const pandora::Vertex * ProduceTrainingExamples(const pandora::VertexVector &vertexVector, const VertexFeatureInfoMap &vertexFeatureInfoMap, std::bernoulli_distribution &coinFlip, std::mt19937 &generator, const std::string &interactionType, const std::string &trainingOutputFile, const LArMvaHelper::MvaFeatureVector &eventFeatureList, const float maxRadius, const bool useRPhi) const
Produce a set of training examples for a binary classifier.
void GetVertexScoreList(const pandora::VertexVector &vertexVector, const BeamConstants &beamConstants, HitKDTree2D &kdTreeU, HitKDTree2D &kdTreeV, HitKDTree2D &kdTreeW, VertexScoreList &vertexScoreList) const
Get the vertex score list.
bool m_dropFailedRPhiFastScoreCandidates
Whether to drop candidates that fail the r/phi fast score test.
static bool Classify(const MvaInterface &classifier, TLISTS &&...featureLists)
Use the trained classifier to predict the boolean class of an example.
Definition: LArMvaHelper.h:220
float GetCoordinateSpan(const pandora::InputFloat &minCoord, const pandora::InputFloat &maxCoord) const
Get the coordinate span.
float m_maxTrueVertexRadius
The maximum distance at which a vertex candidate can be considered the &#39;true&#39; vertex.
float m_showerAsymmetryConstant
The shower asymmetry constant for the initial region score list.
bool m_allowClassifyDuringTraining
Whether classification is allowed during training.
std::vector< art::Ptr< simb::MCParticle > > MCParticleVector
static InteractionType GetInteractionType(const pandora::MCParticleList &mcPrimaryList)
Get the interaction type of an event.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
Definition: AddMC.C:8
bool IsClusterShowerLike(const pandora::Cluster *const pCluster) const
Find whether a cluster is shower-like.
TFile f
Definition: plotHisto.C:6
float m_localAsymmetryConstant
The local asymmetry constant for the initial region score list.
void ProduceTrainingSets(const pandora::VertexVector &vertexVector, const pandora::VertexVector &bestRegionVertices, VertexFeatureInfoMap &vertexFeatureInfoMap, const LArMvaHelper::MvaFeatureVector &eventFeatureList, const KDTreeMap &kdTreeMap) const
Produce the region and vertex training sets.
Header file for the geometry helper class.
static bool SortByMomentum(const pandora::MCParticle *const pLhs, const pandora::MCParticle *const pRhs)
Sort mc particles by their momentum.
float m_regionRadius
The radius for a vertex region.
static void GetClusterBoundingBox(const pandora::Cluster *const pCluster, pandora::CartesianVector &minimumCoordinate, pandora::CartesianVector &maximumCoordinate)
Get minimum and maximum X, Y and Z positions of the calo hits in a cluster.
std::map< const pandora::Cluster *const, ClusterEndPoints > ClusterEndPointsMap
std::string GetInteractionType() const
Get the interaction type string.
Int_t max
Definition: plot.C:27
static void SelectReconstructableMCParticles(const pandora::MCParticleList *pMCParticleList, const pandora::CaloHitList *pCaloHitList, const PrimaryParameters &parameters, std::function< bool(const pandora::MCParticle *const)> fCriteria, MCContributionMap &selectedMCParticlesToHitsMap)
Select primary, reconstructable mc particles that match given criteria.
void search(const KDTreeBoxT< DIM > &searchBox, std::vector< KDTreeNodeInfoT< DATA, DIM > > &resRecHitList)
Search in the KDTree for all points that would be contained in the given searchbox The founded points...
static pandora::StatusCode ProduceTrainingExample(const std::string &trainingOutputFile, const bool result, TLISTS &&...featureLists)
Produce a training example with the given features and result.
Definition: LArMvaHelper.h:197
std::pair< pandora::CartesianVector, pandora::CartesianVector > ClusterEndPoints
unsigned int m_slidingFitWindow
The layer window for the sliding linear fits.
std::map< pandora::HitType, const ShowerClusterList > ShowerClusterListMap
Map of shower cluster lists for passing to tools.
std::unordered_map< const pandora::MCParticle *, pandora::CaloHitList > MCContributionMap
void GetEventShapeFeatures(const pandora::ClusterList &clusterList, float &eventVolume, float &longitudinality) const
Get the event shape features.
Header file for the lar monte carlo particle helper helper class.
static bool SortHitsByPosition(const pandora::CaloHit *const pLhs, const pandora::CaloHit *const pRhs)
Sort calo hits by their position (use Z, followed by X, followed by Y)
Header file for the cluster helper class.
bool m_useRPhiFeatureForRegion
Whether to use the r/phi feature for the region vertex.
static std::string ToString(const InteractionType interactionType)
Get a string representation of an interaction type.
SupportVectorMachine m_svMachineVertex
The vertex support vector machine.
std::map< pandora::HitType, const pandora::ClusterList & > ClusterListMap
Map array of cluster lists for passing to tools.
SupportVectorMachine m_svMachineRegion
The region support vector machine.
float m_minShowerSpineLength
The minimum length at which all are considered to be tracks.
std::string m_mcParticleListName
The MC particle list for creating training examples.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static float GetLength(const pandora::Cluster *const pCluster)
Get length of cluster.
static pandora::StatusCode AddFeatureToolToVector(pandora::AlgorithmTool *const pFeatureTool, MvaFeatureToolVector< Ts... > &featureToolVector)
Add a feature tool to a vector of feature tools.
Definition: LArMvaHelper.h:274
Header file for the local asymmetry feature tool class.
static std::string FindFileInPath(const std::string &unqualifiedFileName, const std::string &environmentVariable, const std::string &delimiter=":")
Find the fully-qualified file name by searching through a list of delimiter-separated paths in a name...
Header file for the file helper class.
float m_mcVertexXCorrection
The correction to the x-coordinate of the MC vertex position.
float m_energyKickConstant
The energy kick constant for the initial region score list.
void PopulateInitialScoreList(VertexFeatureInfoMap &vertexFeatureInfoMap, const pandora::Vertex *const pVertex, VertexScoreList &initialScoreList) const
Populate the initial vertex score list for a given vertex.
std::string m_filePathEnvironmentVariable
The environment variable providing a list of paths to svm files.
void PopulateVertexFeatureInfoMap(const BeamConstants &beamConstants, const ClusterListMap &clusterListMap, const SlidingFitDataListMap &slidingFitDataListMap, const ShowerClusterListMap &showerClusterListMap, const KDTreeMap &kdTreeMap, const pandora::Vertex *const pVertex, VertexFeatureInfoMap &vertexFeatureInfoMap) const
Populate the vertex feature info map for a given vertex.
void AddEventFeaturesToVector(const EventFeatureInfo &eventFeatureInfo, LArMvaHelper::MvaFeatureVector &featureVector) const
Add the event features to a vector in the correct order.
Detector simulation of raw signals on wires.
std::string m_caloHitListName
The 2D CaloHit list name.
Header file for the svm vertex selection algorithm class.
float m_showerClusteringDistance
The shower clustering distance.
void AddVertexFeaturesToVector(const VertexFeatureInfo &vertexFeatureInfo, LArMvaHelper::MvaFeatureVector &featureVector, const bool useRPhi) const
Add the vertex features to a vector in the correct order.
std::string m_trainingOutputFileVertex
The training output file for the vertex Svm.
void GetBestVertex(const pandora::VertexVector &vertexVector, const pandora::Vertex *&pBestVertex, float &bestVertexDr) const
Use the MC information to get the best vertex from a list.
pandora::StatusCode Initialize(const std::string &parameterLocation, const std::string &svmName)
Initialize the svm using a serialized model.
bool m_useShowerClusteringApproximation
Whether to use the shower clustering distance approximation.
float m_beamDeweightingConstant
The beam deweighting constant for the initial region score list.
const pandora::Vertex * CompareVertices(const pandora::VertexVector &vertexVector, const VertexFeatureInfoMap &vertexFeatureInfoMap, const LArMvaHelper::MvaFeatureVector &eventFeatureList, const SupportVectorMachine &supportVectorMachine, const bool useRPhi) const
Used a binary classifier to compare a set of vertices and pick the best one.
static void GetTrueNeutrinos(const pandora::MCParticleList *const pMCParticleList, pandora::MCParticleVector &trueNeutrinos)
Get neutrino MC particles from an input MC particle list.
bool AddClusterToShower(const ClusterEndPointsMap &clusterEndPointsMap, pandora::ClusterList &availableShowerLikeClusters, const pandora::Cluster *const pCluster, pandora::ClusterList &showerCluster) const
Try to add an available cluster to a given shower cluster, using shower clustering approximation...
std::map< pandora::HitType, const SlidingFitDataList > SlidingFitDataListMap
Map of sliding fit data lists for passing to tools.
Int_t min
Definition: plot.C:26
void PopulateKdTree(const pandora::ClusterList &clusterList, HitKDTree2D &kdTree, HitToClusterMap &hitToClusterMap) const
Populate kd tree with information about hits in a provided list of clusters.
std::string m_trainingOutputFileRegion
The training output file for the region Svm.
KDTreeBox fill_and_bound_2d_kd_tree(const MANAGED_CONTAINER< const T * > &points, std::vector< KDTreeNodeInfoT< const T *, 2 > > &nodes)
fill_and_bound_2d_kd_tree
void UpdateSpanCoordinate(const float minPositionCoord, const float maxPositionCoord, pandora::InputFloat &minCoord, pandora::InputFloat &maxCoord) const
Update the min/max coordinate spans.
Header file for the shower asymmetry feature tool class.
std::string m_regionSvmName
The name of the region Svm to find.
std::map< pandora::HitType, const std::reference_wrapper< HitKDTree2D > > KDTreeMap
Map array of hit kd trees for passing to tools.
VertexFeatureTool::FeatureToolVector m_featureToolVector
The feature tool vector.
float GetBeamDeweightingScore(const BeamConstants &beamConstants, const pandora::Vertex *const pVertex) const
Get the beam deweighting score for a vertex.
Header file for the energy kick feature tool class.
void CalculateShowerClusterList(const pandora::ClusterList &inputClusterList, ShowerClusterList &showerClusterList) const
Calculate the shower cluster map for a cluster list.
EventFeatureInfo CalculateEventFeatures(const pandora::ClusterList &clusterListU, const pandora::ClusterList &clusterListV, const pandora::ClusterList &clusterListW, const pandora::VertexVector &vertexVector) const
Calculate the event parameters.
unsigned int m_minClusterCaloHits
The min number of hits parameter in the energy score.
void GetShowerLikeClusterEndPoints(const pandora::ClusterList &clusterList, pandora::ClusterList &showerLikeClusters, ClusterEndPointsMap &clusterEndPointsMap) const
Add the endpoints of any shower-like clusters to the map.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static bool IsBeamNeutrinoFinalState(const pandora::MCParticle *const pMCParticle)
Returns true if passed a primary neutrino final state MCParticle.
KDTreeBox build_2d_kd_search_region(const pandora::CaloHit *const point, const float x_span, const float z_span)
build_2d_kd_search_region
unsigned int m_nClusters
The number of clusters in the event.
float m_rPhiFineTuningRadius
The maximum distance the r/phi tune can move a vertex.
Header file for the r/phi feature tool class.
void build(std::vector< KDTreeNodeInfoT< DATA, DIM > > &eltList, const KDTreeBoxT< DIM > &region)
Build the KD tree from the "eltList" in the space define by "region".
Header file for the global asymmetry feature tool class.
std::vector< art::Ptr< recob::Vertex > > VertexVector
pandora::StringVector m_inputClusterListNames
The list of cluster list names.