10 #include "art/Utilities/ToolMacros.h"
24 #include "TPrincipal.h"
26 namespace ShowerRecoTools {
40 const art::Event& Event,
41 std::vector<art::Ptr<recob::SpacePoint>>
const& sps,
42 const art::FindManyP<recob::Hit>& fmh);
45 std::vector<art::Ptr<recob::SpacePoint>>
const& initial_track);
51 size_t num_sps_to_take);
59 const art::FindManyP<recob::Hit>& fmh,
60 double current_residual);
65 const art::FindManyP<recob::Hit>& fmh);
70 const art::FindManyP<recob::Hit>& fmh,
71 int& max_residual_point);
77 std::vector<art::Ptr<recob::SpacePoint>>& reduced_sps_pool,
78 const art::FindManyP<recob::Hit>& fmh,
79 double current_residual);
87 IsResidualOK(
double new_residual,
double current_residual,
size_t no_sps)
99 TVector3& PCAEigenvector,
100 TVector3& TrackPosition);
103 TVector3& PCAEigenvector,
104 TVector3& TrackPosition,
105 int& max_residual_point);
112 const std::vector<art::Ptr<recob::SpacePoint>>& sps,
113 const art::FindManyP<recob::Hit>& fmh);
116 TVector3 start_direction);
117 std::vector<art::Ptr<recob::SpacePoint>>
CreateFakeSPLine(TVector3 start_position,
118 TVector3 start_direction,
121 const art::FindManyP<recob::Hit>& dud_fmh);
126 const art::FindManyP<recob::Hit>& fmh);
151 , fPFParticleLabel(pset.
get<art::InputTag>(
"PFParticleLabel"))
152 , fVerbose(pset.
get<int>(
"Verbose"))
153 , fUseShowerDirection(pset.
get<
bool>(
"UseShowerDirection"))
154 , fChargeWeighted(pset.
get<
bool>(
"ChargeWeighted"))
155 , fForwardHitsOnly(pset.
get<
bool>(
"ForwardHitsOnly"))
156 , fMaxResidualDiff(pset.
get<float>(
"MaxResidualDiff"))
157 , fMaxAverageResidual(pset.
get<float>(
"MaxAverageResidual"))
158 , fStartFitSize(pset.
get<int>(
"StartFitSize"))
159 , fNMissPoints(pset.
get<int>(
"NMissPoints"))
160 , fTrackMaxAdjacentSPDistance(pset.
get<float>(
"TrackMaxAdjacentSPDistance"))
162 , fMakeTrackSeed(pset.
get<
bool>(
"MakeTrackSeed"))
163 , fStartDistanceCut(pset.
get<float>(
"StartDistanceCut"))
164 , fDistanceCut(pset.
get<float>(
"DistanceCut"))
165 , fShowerStartPositionInputLabel(pset.
get<
std::string>(
"ShowerStartPositionInputLabel"))
166 , fShowerDirectionInputLabel(pset.
get<
std::string>(
"ShowerDirectionInputLabel"))
169 fInitialTrackHitsOutputLabel(pset.
get<
std::string>(
"InitialTrackHitsOutputLabel"))
170 , fInitialTrackSpacePointsOutputLabel(
171 pset.
get<
std::string>(
"InitialTrackSpacePointsOutputLabel"))
174 throw cet::exception(
"ShowerIncrementalTrackHitFinder")
175 <<
"We cannot make a track if you don't gives us at leats one hit. Change fStartFitSize "
176 "please to something sensible";
182 const art::Ptr<recob::PFParticle>& pfparticle,
190 mf::LogError(
"ShowerIncrementalTrackHitFinder")
191 <<
"Start position not set, returning " << std::endl;
196 auto const pfpHandle = Event.getValidHandle<std::vector<recob::PFParticle>>(
fPFParticleLabel);
199 const art::FindManyP<recob::SpacePoint>& fmspp =
203 auto const spHandle = Event.getValidHandle<std::vector<recob::SpacePoint>>(
fPFParticleLabel);
206 const art::FindManyP<recob::Hit>& fmh =
210 std::vector<art::Ptr<recob::SpacePoint>> spacePoints = fmspp.at(pfparticle.key());
213 if (spacePoints.empty()) {
215 mf::LogError(
"ShowerIncrementalTrackHitFinder")
216 <<
"No space points, returning " << std::endl;
220 TVector3 ShowerStartPosition = {-999, -999, -999};
228 mf::LogError(
"ShowerIncrementalTrackHitFinder")
229 <<
"Direction not set, returning " << std::endl;
233 TVector3 ShowerDirection = {-999, -999, -999};
238 spacePoints, ShowerStartPosition, ShowerDirection);
242 for (
auto spacePoint : spacePoints) {
244 spacePoint, ShowerStartPosition, ShowerDirection);
245 if (proj < 0) { ++back_sps; }
246 if (proj > 0) {
break; }
248 spacePoints.erase(spacePoints.begin(), spacePoints.begin() + back_sps);
254 ShowerStartPosition);
259 for (
auto spacePoint : spacePoints) {
266 spacePoints.erase(spacePoints.begin(), spacePoints.begin() + frontsp);
270 for (
auto spacePoint : spacePoints) {
277 spacePoints.erase(spacePoints.begin() + sp_iter, spacePoints.end());
279 if (spacePoints.size() < 3) {
281 mf::LogError(
"ShowerIncrementalTrackHitFinder")
282 <<
"Not enough spacepoints bailing" << std::endl;
290 std::vector<art::Ptr<recob::SpacePoint>> track_sps =
294 std::vector<art::Ptr<recob::Hit>> trackHits;
295 for (
auto const& spacePoint : track_sps) {
296 std::vector<art::Ptr<recob::Hit>> hits = fmh.at(spacePoint.key());
297 for (
auto const&
hit : hits) {
298 trackHits.push_back(
hit);
314 TPrincipal* pca =
new TPrincipal(3,
"");
317 for (
auto& sp : sps) {
322 sp_coord[0] = sp_position.X();
323 sp_coord[1] = sp_position.Y();
324 sp_coord[2] = sp_position.Z();
327 pca->AddRow(sp_coord);
331 pca->MakePrincipals();
334 const TMatrixD* Eigenvectors = pca->GetEigenVectors();
336 TVector3 Eigenvector = {(*Eigenvectors)[0][0], (*Eigenvectors)[1][0], (*Eigenvectors)[2][0]};
348 const std::vector<art::Ptr<recob::SpacePoint>>& sps,
349 const art::FindManyP<recob::Hit>& fmh)
353 TPrincipal* pca =
new TPrincipal(3,
"");
355 float TotalCharge = 0;
358 for (
auto& sp : sps) {
378 wht *= std::sqrt(Charge / TotalCharge);
382 sp_coord[0] = sp_position.X() * wht;
383 sp_coord[1] = sp_position.Y() * wht;
384 sp_coord[2] = sp_position.Z() * wht;
387 pca->AddRow(sp_coord);
391 pca->MakePrincipals();
394 const TMatrixD* Eigenvectors = pca->GetEigenVectors();
396 TVector3 Eigenvector = {(*Eigenvectors)[0][0], (*Eigenvectors)[1][0], (*Eigenvectors)[2][0]};
409 const art::FindManyP<recob::Hit>& fmh)
414 int maxresidual_point = 0;
424 while (!ok && segment.size() != 1) {
427 for (
auto sp = segment.begin(); sp != segment.end(); ++sp) {
428 if (sp->key() == (unsigned)maxresidual_point) {
443 std::vector<art::Ptr<recob::SpacePoint>>
445 const art::Event& Event,
446 std::vector<art::Ptr<recob::SpacePoint>>
const& sps,
447 const art::FindManyP<recob::Hit>& fmh)
450 auto const clockData =
451 art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(Event);
453 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(Event, clockData);
456 std::vector<art::Ptr<recob::SpacePoint>> sps_pool = sps;
457 std::vector<art::Ptr<recob::SpacePoint>> initial_track;
458 std::vector<art::Ptr<recob::SpacePoint>> track_segment_copy;
460 while (sps_pool.size() > 0) {
463 std::vector<art::Ptr<recob::SpacePoint>> track_segment;
474 if (track_segment.empty())
break;
476 track_segment_copy = track_segment;
483 sps_pool.insert(sps_pool.begin(), track_segment.back());
484 track_segment.pop_back();
485 double current_residual = 0;
486 size_t initial_segment_size = track_segment.size();
491 if (initial_segment_size == track_segment.size()) {
505 if (
fMakeTrackSeed && initial_track.empty()) initial_track = track_segment_copy;
510 return initial_track;
515 std::vector<art::Ptr<recob::SpacePoint>>& sps_pool,
516 std::vector<art::Ptr<recob::SpacePoint>>
const& initial_track)
520 if (initial_track.empty())
return;
522 initial_track.back(), sps_pool.front());
523 while (distance > 1 && sps_pool.size() > 0) {
524 sps_pool.erase(sps_pool.begin());
526 initial_track.back(), sps_pool.front());
533 std::vector<art::Ptr<recob::SpacePoint>>& initial_track)
536 if (initial_track.empty())
return;
537 std::vector<art::Ptr<recob::SpacePoint>>::iterator sps_it = initial_track.begin();
538 while (sps_it != std::next(initial_track.end(), -1)) {
539 std::vector<art::Ptr<recob::SpacePoint>>::iterator next_sps_it = std::next(sps_it, 1);
553 std::vector<art::Ptr<recob::SpacePoint>>& sps_pool,
554 size_t num_sps_to_take)
556 size_t new_segment_size = segment.size() + num_sps_to_take;
557 while (segment.size() < new_segment_size && sps_pool.size() > 0) {
558 segment.push_back(sps_pool[0]);
559 sps_pool.erase(sps_pool.begin());
566 std::vector<art::Ptr<recob::SpacePoint>>
const& segment)
579 std::vector<art::Ptr<recob::SpacePoint>>& sps_pool,
580 const art::FindManyP<recob::Hit>& fmh,
581 double current_residual)
586 if (sps_pool.empty())
return !ok;
594 ok =
IsResidualOK(residual, current_residual, segment.size());
597 std::vector<art::Ptr<recob::SpacePoint>> sub_sps_pool;
601 std::vector<art::Ptr<recob::SpacePoint>> sub_sps_pool_cache = sub_sps_pool;
605 sub_sps_pool_cache.insert(sub_sps_pool_cache.begin(), segment.back());
607 clockData, detProp, segment, sub_sps_pool, fmh, current_residual);
612 while (sub_sps_pool.size() > 0) {
613 sps_pool.insert(sps_pool.begin(), sub_sps_pool.back());
614 sub_sps_pool.pop_back();
623 while (sub_sps_pool_cache.size() > 0) {
624 sps_pool.insert(sps_pool.begin(), sub_sps_pool_cache.back());
625 sub_sps_pool_cache.pop_back();
634 current_residual = residual;
646 const art::FindManyP<recob::Hit>& fmh)
649 TVector3 primary_axis;
655 TVector3 segment_centre;
672 const art::FindManyP<recob::Hit>& fmh,
673 int& max_residual_point)
676 TVector3 primary_axis;
682 TVector3 segment_centre;
689 double residual =
CalculateResidual(segment, primary_axis, segment_centre, max_residual_point);
699 std::vector<art::Ptr<recob::SpacePoint>>& reduced_sps_pool,
700 const art::FindManyP<recob::Hit>& fmh,
701 double current_residual)
706 if (reduced_sps_pool.empty())
return !ok;
713 ok =
IsResidualOK(residual, current_residual, segment.size());
717 clockData, detProp, segment, reduced_sps_pool, fmh, current_residual);
722 TVector3& PCAEigenvector,
723 TVector3& TrackPosition)
728 for (
auto const& sp : sps) {
734 double len = pos.Dot(PCAEigenvector);
735 double perp = (pos - len * PCAEigenvector).Mag();
744 TVector3& PCAEigenvector,
745 TVector3& TrackPosition,
746 int& max_residual_point)
750 double max_residual = -999;
752 for (
auto const& sp : sps) {
758 double len = pos.Dot(PCAEigenvector);
759 double perp = (pos - len * PCAEigenvector).Mag();
763 if (perp > max_residual) {
765 max_residual_point = sp.key();
771 std::vector<art::Ptr<recob::SpacePoint>>
773 TVector3 start_direction)
775 std::vector<art::Ptr<recob::SpacePoint>> fake_sps;
776 std::vector<art::Ptr<recob::SpacePoint>> segment_a =
781 TVector3 sp_position =
783 TVector3 direction = start_direction;
784 direction.RotateX(10. * 3.142 / 180.);
785 std::vector<art::Ptr<recob::SpacePoint>> segment_b =
790 TVector3 branching_position =
793 TVector3 direction_branch_a = direction;
794 direction_branch_a.RotateZ(15. * 3.142 / 180.);
795 std::vector<art::Ptr<recob::SpacePoint>> branch_a =
799 TVector3 direction_branch_b = direction;
800 direction_branch_b.RotateY(20. * 3.142 / 180.);
801 std::vector<art::Ptr<recob::SpacePoint>> branch_b =
805 TVector3 direction_branch_c = direction;
806 direction_branch_c.RotateX(3. * 3.142 / 180.);
807 std::vector<art::Ptr<recob::SpacePoint>> branch_c =
814 std::vector<art::Ptr<recob::SpacePoint>>
816 TVector3 start_direction,
819 std::vector<art::Ptr<recob::SpacePoint>> fake_sps;
820 art::ProductID prod_id(std::string(
"totally_genuine"));
821 size_t current_id = 500000;
823 double step_length = 0.2;
824 for (
double i_point = 0; i_point < npoints; i_point++) {
825 TVector3 new_position = start_position + i_point * step_length * start_direction;
826 Double32_t xyz[3] = {new_position.X(), new_position.Y(), new_position.Z()};
827 Double32_t
err[3] = {0., 0., 0.};
829 fake_sps.emplace_back(art::Ptr<recob::SpacePoint>(prod_id, sp, current_id++));
836 const art::Event& Event,
837 const art::FindManyP<recob::Hit>& dud_fmh)
839 TVector3 start_position(50, 50, 50);
840 TVector3 start_direction(0, 0, 1);
841 std::vector<art::Ptr<recob::SpacePoint>> fake_sps =
846 std::vector<art::Ptr<recob::SpacePoint>> track_sps =
850 for (
size_t i_sp = 0; i_sp < fake_sps.size(); i_sp++) {
851 graph_sps.SetPoint(graph_sps.GetN(),
852 fake_sps[i_sp]->XYZ()[0],
853 fake_sps[i_sp]->XYZ()[1],
854 fake_sps[i_sp]->XYZ()[2]);
856 TGraph2D graph_track_sps;
857 for (
size_t i_sp = 0; i_sp < track_sps.size(); i_sp++) {
858 graph_track_sps.SetPoint(graph_track_sps.GetN(),
859 track_sps[i_sp]->XYZ()[0],
860 track_sps[i_sp]->XYZ()[1],
861 track_sps[i_sp]->XYZ()[2]);
864 art::ServiceHandle<art::TFileService>
tfs;
866 TCanvas* canvas = tfs->make<TCanvas>(
"test_inc_can",
"test_inc_can");
867 canvas->SetName(
"test_inc_can");
868 graph_sps.SetMarkerStyle(8);
869 graph_sps.SetMarkerColor(1);
870 graph_sps.SetFillColor(1);
873 graph_track_sps.SetMarkerStyle(8);
874 graph_track_sps.SetMarkerColor(2);
875 graph_track_sps.SetFillColor(2);
876 graph_track_sps.Draw(
"samep");
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
double DistanceBetweenSpacePoints(art::Ptr< recob::SpacePoint > const &sp_a, art::Ptr< recob::SpacePoint > const &sp_b) const
void OrderShowerSpacePoints(std::vector< art::Ptr< recob::SpacePoint >> &showersps, TVector3 const &vertex, TVector3 const &direction) const
Declaration of signal hit object.
EResult err(const char *call)
void SetElement(T &dataproduct, const std::string &Name, bool checktag=false)
double ElectronLifetime() const
const art::FindManyP< T1 > & GetFindManyP(const art::ValidHandle< std::vector< T2 > > &handle, const art::Event &evt, const art::InputTag &moduleTag)
double SpacePointTime(art::Ptr< recob::SpacePoint > const &sp, art::FindManyP< recob::Hit > const &fmh) const
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
auto end(FixedBins< T, C > const &) noexcept
bool CheckElement(const std::string &Name) const
double SpacePointProjection(art::Ptr< recob::SpacePoint > const &sp, TVector3 const &vertex, TVector3 const &direction) const
int GetElement(const std::string &Name, T &Element) const
auto begin(FixedBins< T, C > const &) noexcept
double SpacePointCharge(art::Ptr< recob::SpacePoint > const &sp, art::FindManyP< recob::Hit > const &fmh) const
Contains all timing reference information for the detector.
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
TVector3 ShowerCentre(std::vector< art::Ptr< recob::SpacePoint >> const &showersps) const
2D representation of charge deposited in the TDC/wire plane
art::ServiceHandle< art::TFileService > tfs
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
TVector3 SpacePointPosition(art::Ptr< recob::SpacePoint > const &sp) const