48 #include "TTimeStamp.h" 49 #include "TLorentzVector.h" 55 #include "TEfficiency.h" 82 void AddHitPreClustering (
TrackID id);
83 void AddSignalHitPostClustering(
ClusterID id);
84 void AddNoiseHitPostClustering (
ClusterID id);
88 double GetEfficiency (
TrackID id);
91 int GetNumberHitsFromTrack (
TrackID id);
92 int GetNumberHitsInCluster (
ClusterID id);
93 int GetNumberHitsInPlane ();
94 std::vector<std::pair<TrackID,ClusterIDs> > GetPhotons ();
148 std::vector<std::pair<TrackID,ClusterIDs> > photonVector;
149 for (
unsigned int track = 0;
track < GetListOfTrackIDs().size(); ++
track)
150 if (!IsNoise(GetListOfTrackIDs().at(
track)) && pi_serv->TrackIdToParticle_P((
int)GetListOfTrackIDs().at(
track))->PdgCode() == 22)
151 photonVector.push_back(std::pair<TrackID,ClusterIDs>(GetListOfTrackIDs().at(
track),trackToClusterIDs.at(GetListOfTrackIDs().at(
track))));
162 if (GetPhotons().size() > 2 || GetPhotons().size() == 0)
return false;
164 for (
unsigned int photon = 0; photon < GetPhotons().size(); ++photon)
166 if (GetCompleteness(GetPhotons().at(photon).second.at(
cluster)) > 0.5) goodPhotons.push_back(GetPhotons().at(photon).first);
167 if ( (GetPhotons().size() == 2 && goodPhotons.size() > 2) || (GetPhotons().size() == 1 && goodPhotons.size() > 1) ) std::cout <<
"More than 2 with >50%?!" << std::endl;
168 bool pass = ( (GetPhotons().size() == 2 && goodPhotons.size() == 2) || (GetPhotons().size() == 1 && goodPhotons.size() == 1) );
181 double FindPhotonAngle();
184 TObjArray GetHistograms();
185 void MakeHistograms();
195 TH1 *hPi0Angle, *hPi0Energy, *hPi0ConversionDistance, *hPi0ConversionSeparation, *hPi0AngleCut, *
hPi0EnergyCut, *hPi0ConversionDistanceCut, *hPi0ConversionSeparationCut;
197 TProfile *
hCompletenessEnergy, *hCompletenessAngle, *hCompletenessConversionDistance, *hCompletenessConversionSeparation;
198 TProfile *
hCleanlinessEnergy, *hCleanlinessAngle, *hCleanlinessConversionDistance, *hCleanlinessConversionSeparation;
199 TProfile *
hComplCleanlEnergy, *hComplCleanlAngle, *hComplCleanlConversionDistance, *hComplCleanlConversionSeparation;
200 TEfficiency *hEfficiencyAngle, *
hEfficiencyEnergy, *hEfficiencyConversionDistance, *hEfficiencyConversionSeparation;
203 std::map<unsigned int,std::map<unsigned int,std::unique_ptr<ClusterCounter> > >
clusterMap;
215 fClusterLabel = clusterLabel;
218 hCompleteness =
new TH1D(
"Completeness",
";Completeness;",101,0,1.01);
219 hCompletenessEnergy =
new TProfile(
"CompletenessEnergy",
";True Energy (GeV);Completeness",100,0,2);
220 hCompletenessAngle =
new TProfile(
"CompletenessAngle",
";True Angle (deg);Completeness;",100,0,180);
221 hCompletenessConversionDistance =
new TProfile(
"CompletenessConversionDistance",
";True Distance from Vertex (cm);Completeness",100,0,200);
222 hCompletenessConversionSeparation =
new TProfile(
"CompletenessConversionSeparation",
";True Conversion Separation (cm);Completeness",100,0,200);
223 hCleanliness =
new TH1D(
"Cleanliness",
";Cleanliness;",101,0,1.01);
224 hCleanlinessEnergy =
new TProfile(
"CleanlinessEnergy",
";True Energy (GeV);Cleanliness",100,0,2);
225 hCleanlinessAngle =
new TProfile(
"CleanlinessAngle",
";True Angle (deg);Cleanliness;",100,0,180);
226 hCleanlinessConversionDistance =
new TProfile(
"CleanlinessConversionDistance",
";True Distance from Vertex (cm);Cleanliness",100,0,200);
227 hCleanlinessConversionSeparation =
new TProfile(
"CleanlinessConversionSeparation",
";True Conversion Separation (cm);Cleanliness",100,0,200);
228 hComplCleanl =
new TH1D(
"CompletenessCleanliness",
";Completeness * Cleanliness;",101,0,1.01);
229 hComplCleanlEnergy =
new TProfile(
"CompletenessCleanlinessEnergy",
";True Energy (GeV);Completeness * Cleanliness",100,0,2);
230 hComplCleanlAngle =
new TProfile(
"CompletenessCleanlinessAngle",
";True Angle (deg);Completeness * Cleanliness;",100,0,180);
231 hComplCleanlConversionDistance =
new TProfile(
"CompletenessCleanlinessConversionDistance",
";True Distance from Vertex (cm);Completeness * Cleanliness",100,0,200);
232 hComplCleanlConversionSeparation =
new TProfile(
"CompletenessCleanlinessConversionSeparation",
";True Conversion Separation (cm);Completeness * Cleanliness",100,0,200);
233 hPi0Energy =
new TH1D(
"Pi0EnergyCut",
";True Energy (GeV);",25,0,2); hPi0Energy ->Sumw2();
234 hPi0Angle =
new TH1D(
"Pi0AngleCut",
";True Angle (deg);",25,0,180); hPi0Angle ->Sumw2();
235 hPi0ConversionDistance =
new TH1D(
"Pi0ConversionDistanceCut",
";True Distance from Vertex (cm);",25,0,200); hPi0ConversionDistance ->Sumw2();
236 hPi0ConversionSeparation =
new TH1D(
"Pi0ConversionSeparationCut",
";True Separation from Vertex (cm);",25,0,200); hPi0ConversionSeparation ->Sumw2();
237 hPi0EnergyCut =
new TH1D(
"Pi0EnergyCut",
";True Energy (GeV);Efficiency",25,0,2); hPi0EnergyCut ->Sumw2();
238 hPi0AngleCut =
new TH1D(
"Pi0AngleCut",
";True Angle (deg);Efficiency",25,0,180); hPi0AngleCut ->Sumw2();
239 hPi0ConversionDistanceCut =
new TH1D(
"Pi0ConversionDistanceCut",
";True Distance from Vertex (cm);Efficiency",25,0,200); hPi0ConversionDistanceCut ->Sumw2();
240 hPi0ConversionSeparationCut =
new TH1D(
"Pi0ConversionSeparationCut",
";True Separation from Vertex (cm);Efficiency",25,0,200); hPi0ConversionSeparationCut->Sumw2();
241 hNumHitsCompleteness =
new TH2D(
"NumHitsCompleteness",
";Completeness;Size of Cluster",101,0,1.01,100,0,100);
242 hNumHitsEnergy =
new TH2D(
"NumHitsEnergy",
";True Energy (GeV);Size of Cluster",100,0,2,100,0,100);
249 for (
unsigned int tpc = 0; tpc < geometry->NTPC(0); ++tpc) {
250 for (
unsigned int plane = 0; plane < geometry->Nplanes(tpc,0); ++plane) {
251 clusterMap[tpc][plane] = (std::unique_ptr<ClusterCounter>)
new ClusterCounter(tpc, plane);
256 for (
size_t hitIt = 0; hitIt <
hits.size(); ++hitIt) {
258 TrackID trackID = FindTrackID(hit);
263 trueParticles.clear();
271 for (
size_t clusIt = 0; clusIt < clusters.size(); ++clusIt) {
274 unsigned int tpc = clusters.at(clusIt)->Plane().TPC%2;
275 unsigned int plane = clusters.at(clusIt)->Plane().Plane;
279 if (clusterMap[tpc][plane]->GetNumberHitsInPlane() < minHits)
continue;
282 std::vector<art::Ptr<recob::Hit> > clusterHits = fmh.at(clusIt);
284 if (clusterHits.size() < 10)
continue;
287 TrackID trueTrackID = FindTrueTrack(clusterHits);
290 clusterMap[tpc][plane]->AssociateClusterAndTrack(
id, trueTrackID);
293 TrackID trackID = FindTrackID(hit);
294 if (trackID == trueTrackID) clusterMap[tpc][plane]->AddSignalHitPostClustering(
id);
295 else clusterMap[tpc][plane]->AddNoiseHitPostClustering (
id);
299 this->MakeHistograms();
304 double particleEnergy = 0;
306 std::vector<sim::TrackIDE> trackIDs = bt_serv->HitToTrackIDEs(hit);
307 for (
unsigned int idIt = 0; idIt < trackIDs.size(); ++idIt) {
308 if (trackIDs.at(idIt).energy > particleEnergy) {
309 particleEnergy = trackIDs.at(idIt).energy;
310 likelyTrackID = (
TrackID)TMath::Abs(trackIDs.at(idIt).trackID);
313 return likelyTrackID;
317 std::map<TrackID,double> trackMap;
320 TrackID trackID = FindTrackID(hit);
321 trackMap[trackID] += hit->
Integral();
324 double highestCharge = 0;
327 if (trackIt->second > highestCharge) {
328 highestCharge = trackIt->second;
329 clusterTrack = trackIt->first;
337 double angle = (trueParticles.at((
TrackID)pi0->
Daughter(0))->Momentum().Angle(trueParticles.at((
TrackID)pi0->
Daughter(1))->Momentum().Vect()) * (180/TMath::Pi()));
344 if (particleIt->second->PdgCode() == 111)
345 pi0 = particleIt->second;
350 return TMath::Sqrt(TMath::Power(trueParticles.at(id1)->EndPosition().X() - trueParticles.at(id2)->EndPosition().X(),2)+
351 TMath::Power(trueParticles.at(id1)->EndPosition().Y() - trueParticles.at(id2)->EndPosition().Y(),2)+
352 TMath::Power(trueParticles.at(id1)->EndPosition().Z() - trueParticles.at(id2)->EndPosition().Z(),2));
358 hEfficiencyEnergy =
new TEfficiency(*hPi0EnergyCut,*hPi0Energy);
359 hEfficiencyAngle =
new TEfficiency(*hPi0AngleCut,*hPi0Angle);
360 hEfficiencyConversionDistance =
new TEfficiency(*hPi0ConversionDistanceCut,*hPi0ConversionDistance);
361 hEfficiencyConversionSeparation =
new TEfficiency(*hPi0ConversionSeparationCut,*hPi0ConversionSeparation);
363 hEfficiencyEnergy ->SetName(
"EfficiencyEnergy");
364 hEfficiencyAngle ->SetName(
"EnergyAngle");
365 hEfficiencyConversionDistance ->SetName(
"EfficiencyConversionDistance");
366 hEfficiencyConversionSeparation->SetName(
"EfficiencyConversionSeparation");
369 fHistArray.Add(hCompleteness); fHistArray.Add(hCompletenessEnergy); fHistArray.Add(hCompletenessAngle); fHistArray.Add(hCompletenessConversionDistance); fHistArray.Add(hCompletenessConversionSeparation);
370 fHistArray.Add(hCleanliness); fHistArray.Add(hCleanlinessEnergy); fHistArray.Add(hCleanlinessAngle); fHistArray.Add(hCleanlinessConversionDistance); fHistArray.Add(hCleanlinessConversionSeparation);
371 fHistArray.Add(hComplCleanl); fHistArray.Add(hComplCleanlEnergy); fHistArray.Add(hComplCleanlAngle); fHistArray.Add(hComplCleanlConversionDistance); fHistArray.Add(hComplCleanlConversionSeparation);
372 fHistArray.Add(hEfficiencyEnergy); fHistArray.Add(hEfficiencyAngle); fHistArray.Add(hEfficiencyConversionDistance); fHistArray.Add(hEfficiencyConversionSeparation);
373 fHistArray.Add(hNumHitsCompleteness); fHistArray.Add(hNumHitsEnergy);
381 for (
unsigned int tpc = 0; tpc < geometry->NTPC(0); ++tpc) {
382 for (
unsigned int plane = 0; plane < geometry->Nplanes(tpc,0); ++plane) {
384 ClusterIDs clusterIDs = clusterMap[tpc][plane]->GetListOfClusterIDs();
387 if (clusterMap[tpc][plane]->GetPhotons().size() == 2) {
388 hPi0Angle ->Fill(FindPhotonAngle());
389 hPi0Energy ->Fill(GetPi0()->Momentum().
E());
390 hPi0ConversionDistance ->Fill(
std::min(GetEndTrackDistance(clusterMap[tpc][plane]->GetPhotons().at(0).first, (
TrackID)GetPi0()->TrackId()),
391 GetEndTrackDistance(clusterMap[tpc][plane]->GetPhotons().at(1).first, (
TrackID)GetPi0()->TrackId())));
392 hPi0ConversionSeparation->Fill(GetEndTrackDistance(clusterMap[tpc][plane]->GetPhotons().at(0).first, clusterMap[tpc][plane]->GetPhotons().at(1).first));
393 if (clusterMap[tpc][plane]->PassesCut()) {
394 hPi0AngleCut ->Fill(FindPhotonAngle());
395 hPi0EnergyCut ->Fill(GetPi0()->Momentum().
E());
396 hPi0ConversionDistanceCut ->Fill(
std::min(GetEndTrackDistance(clusterMap[tpc][plane]->GetPhotons().at(0).first, (
TrackID)GetPi0()->TrackId()),
397 GetEndTrackDistance(clusterMap[tpc][plane]->GetPhotons().at(1).first, (
TrackID)GetPi0()->TrackId())));
398 hPi0ConversionSeparationCut->Fill(GetEndTrackDistance(clusterMap[tpc][plane]->GetPhotons().at(0).first, clusterMap[tpc][plane]->GetPhotons().at(1).first));
401 std::cout <<
"TPC " << tpc <<
", Plane " << plane <<
" fails the cut" << std::endl;
408 double completeness = clusterMap[tpc][plane]->GetCompleteness(clusID);
409 double cleanliness = clusterMap[tpc][plane]->GetCleanliness(clusID);
410 int numClusterHits = clusterMap[tpc][plane]->GetNumberHitsInCluster(clusID);
413 hCompleteness ->Fill(completeness, numClusterHits);
414 hCleanliness ->Fill(cleanliness, numClusterHits);
415 hComplCleanl ->Fill(completeness*cleanliness, numClusterHits);
416 hNumHitsCompleteness ->Fill(completeness, numClusterHits);
419 if (clusterMap[tpc][plane]->IsNoise(clusID))
continue;
421 double pi0Energy = GetPi0()->Momentum().E();
422 double pi0DecayAngle = FindPhotonAngle();
423 double conversionDistance = GetEndTrackDistance(clusterMap[tpc][plane]->GetTrack(clusID), (
TrackID)GetPi0()->TrackId());
425 hCompletenessEnergy ->Fill(pi0Energy, completeness, numClusterHits);
426 hCompletenessAngle ->Fill(pi0DecayAngle, completeness, numClusterHits);
427 hCompletenessConversionDistance->Fill(conversionDistance, completeness, numClusterHits);
428 hCleanlinessEnergy ->Fill(pi0Energy, cleanliness, numClusterHits);
429 hCleanlinessAngle ->Fill(pi0DecayAngle, cleanliness, numClusterHits);
430 hCleanlinessConversionDistance ->Fill(conversionDistance, cleanliness, numClusterHits);
431 hComplCleanlEnergy ->Fill(pi0Energy, cleanliness * completeness, numClusterHits);
432 hComplCleanlAngle ->Fill(pi0DecayAngle, cleanliness * completeness, numClusterHits);
433 hComplCleanlConversionDistance ->Fill(conversionDistance, cleanliness * completeness, numClusterHits);
434 hNumHitsEnergy ->Fill(pi0Energy, numClusterHits);
437 if (clusterMap[tpc][plane]->GetPhotons().size() != 2)
continue;
439 double conversionSeparation = GetEndTrackDistance(clusterMap[tpc][plane]->GetPhotons().at(0).first, clusterMap[tpc][plane]->GetPhotons().at(1).first);
441 hCompletenessConversionSeparation->Fill(conversionSeparation, completeness, numClusterHits);
442 hCleanlinessConversionSeparation ->Fill(conversionSeparation, cleanliness, numClusterHits);
453 double avCompleteness = hCompleteness->GetMean();
454 double avCleanliness = hCleanliness ->GetMean();
457 std::ofstream outFile(
"effpur");
458 outFile << avCompleteness <<
" " << avCleanliness;
493 this->reconfigure(pset);
494 fCanvas =
new TCanvas(
"fCanvas",
"",800,600);
495 gStyle->SetOptStat(0);
499 fMinHitsInPlane = p.
get<
int> (
"MinHitsInPlane");
500 fClusterModuleLabels = p.
get<std::vector<std::string> >(
"ClusterModuleLabels");
501 fHitsModuleLabel = p.
get<std::string> (
"HitsModuleLabel");
508 std::vector<art::Ptr<recob::Hit> >
hits;
509 if (evt.
getByLabel(fHitsModuleLabel,hitHandle))
514 for (
auto clustering : fClusterModuleLabels) {
518 std::vector<art::Ptr<recob::Cluster> > clusters;
526 clusterAnalysis.at(clustering)->Analyse(hits, clusters, fmh, fMinHitsInPlane);
535 for (
auto clustering : fClusterModuleLabels)
536 clusterAnalysis[clustering] = (std::unique_ptr<ClusterAnalyser>)
new ClusterAnalyser(clustering);
543 std::map<std::string,TObjArray> allHistograms;
544 for (
auto clustering : fClusterModuleLabels)
545 allHistograms[clustering] = clusterAnalysis.at(clustering)->GetHistograms();
548 TFile *
file = TFile::Open(
"validationHistograms.root",
"RECREATE");
549 for (
auto clustering : fClusterModuleLabels) {
551 file->mkdir(clustering.c_str());
552 file->cd(clustering.c_str());
553 for (
int histIt = 0; histIt < allHistograms.begin()->second.GetEntriesFast(); ++histIt)
554 allHistograms.at(clustering).At(histIt)->Write();
558 for (
int histIt = 0; histIt < allHistograms.begin()->second.GetEntriesFast(); ++histIt) {
561 const char *name = allHistograms.begin()->second.At(histIt)->GetName();
562 TLegend *l =
new TLegend(0.6,0.8,0.8,0.9,name,
"brNDC");
565 TH1* h = (TH1*)allHistograms.at(clusteringIt->first).At(histIt);
566 h->SetLineColor(clusterings);
567 h->SetMarkerColor(clusterings);
568 if (clusterings == 1) h->Draw();
569 else h->Draw(
"same");
570 l->AddEntry(h,clusteringIt->first.c_str(),
"lp");
575 fCanvas->Write(name);
581 if (clusterAnalysis.find(
"blurredclusteringdc") != clusterAnalysis.end())
582 clusterAnalysis.at(
"blurredclusteringdc")->WriteFile();
void AddHitPreClustering(TrackID id)
int GetNumberHitsFromTrack(TrackID id)
bool IsNoise(ClusterID id)
double GetCompleteness(ClusterID id)
TProfile * hComplCleanlEnergy
std::string fClusterLabel
art::ServiceHandle< cheat::BackTrackerService > bt_serv
ClusteringValidation(fhicl::ParameterSet const &p)
std::vector< TrackID > TrackIDs
geo::WireID WireID() const
Initial tdc tick for hit.
Declaration of signal hit object.
list_type::const_iterator const_iterator
std::map< TrackID, const simb::MCParticle * > trueParticles
double GetEndTrackDistance(TrackID id1, TrackID id2)
std::map< ClusterID, int > numNoiseHitsPostClustering
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
double GetEfficiency(TrackID id)
std::string fHitsModuleLabel
Cluster finding and building.
std::map< TrackID, simb::MCParticle > trueParticles
void Analyse(std::vector< art::Ptr< recob::Hit > > &hits, std::vector< art::Ptr< recob::Cluster > > &clusters, const art::FindManyP< recob::Hit > &fmh, int numHits)
TrackIDs GetListOfTrackIDs()
int NumberDaughters() const
ClusterAnalyser(std::string &label)
ClusterCounter(unsigned int &tpc, unsigned int &plane)
int Daughter(const int i) const
art::ServiceHandle< geo::Geometry > geometry
std::map< unsigned int, std::map< unsigned int, std::unique_ptr< ClusterCounter > > > clusterMap
int GetNumberHitsInPlane()
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
void AddNoiseHitPostClustering(ClusterID id)
#define DEFINE_ART_MODULE(klass)
Provides recob::Track data product.
std::map< TrackID, ClusterIDs > trackToClusterIDs
std::vector< std::pair< TrackID, ClusterIDs > > GetPhotons()
T get(std::string const &key) const
art::ServiceHandle< cheat::BackTrackerService > bt_serv
std::map< ClusterID, int > numSignalHitsPostClustering
std::map< TrackID, std::map< std::string, double > > particleProperties
std::vector< ClusterID > ClusterIDs
void AddSignalHitPostClustering(ClusterID id)
PlaneID_t Plane
Index of the plane within its TPC.
Declaration of cluster object.
TEfficiency * hEfficiencyEnergy
Detector simulation of raw signals on wires.
Encapsulate the geometry of a wire.
art::ServiceHandle< geo::Geometry > geometry
TProfile * hCleanlinessEnergy
std::vector< std::string > fClusterModuleLabels
TProfile * hCompletenessEnergy
double GetCleanliness(ClusterID id)
TrackID FindTrackID(art::Ptr< recob::Hit > &hit)
const simb::MCParticle * GetPi0()
Utility object to perform functions of association.
Encapsulate the construction of a single detector plane.
TrackID GetTrack(ClusterID id)
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
std::map< TrackID, int > numHitsPreClustering
void AssociateClusterAndTrack(ClusterID clusID, TrackID trackID)
TObjArray GetHistograms()
std::map< ClusterID, TrackID > clusterToTrackID
void reconfigure(fhicl::ParameterSet const &p)
void analyze(art::Event const &evt)
TrackID FindTrueTrack(std::vector< art::Ptr< recob::Hit > > &clusterHits)
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
TPCID_t TPC
Index of the TPC within its cryostat.
std::map< std::string, std::unique_ptr< ClusterAnalyser > > clusterAnalysis
ClusterIDs GetListOfClusterIDs()
art framework interface to geometry description
art::ServiceHandle< cheat::ParticleInventoryService > pi_serv
int GetNumberHitsInCluster(ClusterID id)
art::ServiceHandle< cheat::ParticleInventoryService > pi_serv