29 #include "nusimdata/SimulationBase/MCParticle.h"
30 #include "nusimdata/SimulationBase/MCTruth.h"
33 #include "art/Framework/Core/EDAnalyzer.h"
34 #include "art/Framework/Principal/Event.h"
35 #include "art/Framework/Principal/Handle.h"
36 #include "art/Framework/Services/Registry/ServiceHandle.h"
37 #include "art_root_io/TFileService.h"
38 #include "art/Framework/Core/ModuleMacros.h"
39 #include "canvas/Persistency/Common/FindManyP.h"
40 #include "canvas/Utilities/Exception.h"
45 #include "messagefacility/MessageLogger/MessageLogger.h"
46 #include "fhiclcpp/ParameterSet.h"
47 #include "fhiclcpp/types/Table.h"
48 #include "fhiclcpp/types/Atom.h"
72 std::map<std::string, std::vector<sbn::crt::CRTHit>>
crtHits;
89 Name(
"SimModuleLabel"),
90 Comment(
"tag of detector simulation data product")
95 Comment(
"tag of CRT simulation data product")
100 Comment(
"tag of CRT simulation data product")
104 Name(
"CRTTrackLabel"),
105 Comment(
"tag of CRT simulation data product")
109 Name(
"TPCTrackLabel"),
110 Comment(
"tag of TPC track data product")
115 Comment(
"Print information about what's going on")
127 Name(
"CrtBackTrack"),
141 virtual void analyze(
const art::Event& event)
override;
144 virtual void endJob()
override;
160 std::vector<std::string>
stage{
"CRTHit",
"CRTTrack",
"HitT0",
"TrackT0"};
161 std::vector<std::string>
category{
"PossMatch",
"ShouldMatch",
"CRTVol",
"TPCVol",
"CRTCross",
"TPCCross"};
162 std::vector<std::string>
level{
"Total",
"Matched"};
167 std::vector<std::string>
trackType{
"Complete",
"Incomplete",
"Both"};
173 std::vector<std::string>
t0Type{
"HitT0",
"TrackT0"};
174 std::vector<std::string>
purity{
"Matched",
"Correct"};
192 , fSimModuleLabel (config().SimModuleLabel())
193 , fCRTSimLabel (config().CRTSimLabel())
194 , fCRTHitLabel (config().CRTHitLabel())
195 , fCRTTrackLabel (config().CRTTrackLabel())
197 , fVerbose (config().
Verbose())
198 , crtT0Alg (config().CRTT0Alg())
199 , crtTrackAlg (config().CRTTrackAlg())
200 , fCrtBackTrack (config().CrtBackTrack())
207 art::ServiceHandle<art::TFileService>
tfs;
209 hCRTHitTimes = tfs->make<TH1D>(
"CRTHitTimes",
"",100, -5000, 5000);
213 TString histName = Form(
"%s_resolution", taggerName.c_str());
214 hTaggerXYZResolution[taggerName] = tfs->make<TH3D>(histName,
"", 50, -25, 25, 50, -25, 25, 50, -25, 25);
217 for(
size_t si = 0; si <
stage.size(); si++){
218 for(
size_t ci = 0; ci <
category.size(); ci++){
219 for(
size_t li = 0; li <
level.size(); li++){
220 TString momName = Form(
"MuMom%s_%s_%s",
stage[si].c_str(),
category[ci].c_str(),
level[li].c_str());
221 hEffMom[si][ci][li] = tfs->make<TH1D>(momName,
"", 20, 0, 10);
222 TString thetaName = Form(
"MuTheta%s_%s_%s",
stage[si].c_str(),
category[ci].c_str(),
level[li].c_str());
223 hEffTheta[si][ci][li] = tfs->make<TH1D>(thetaName,
"", 20, 0, 3.2);
224 TString phiName = Form(
"MuPhi%s_%s_%s",
stage[si].c_str(),
category[ci].c_str(),
level[li].c_str());
225 hEffPhi[si][ci][li] = tfs->make<TH1D>(phiName,
"", 20, -3.2, 3.2);
230 for(
size_t ti = 0; ti <
trackType.size(); ti++){
231 TString thetaDiffName = Form(
"TrackThetaDiff%s",
trackType[ti].c_str());
232 hTrackThetaDiff[ti] = tfs->make<TH1D>(thetaDiffName,
"", 50, -0.2, 0.2);
233 TString phiDiffName = Form(
"TrackPhiDiff%s",
trackType[ti].c_str());
234 hTrackPhiDiff[ti] = tfs->make<TH1D>(phiDiffName,
"", 50, -0.2, 0.2);
235 TString thetaName = Form(
"TrackTheta%s",
trackType[ti].c_str());
236 hTrackTheta[ti] = tfs->make<TH2D>(thetaName,
"", 20, 0, 3.2, 20, 0, 3.2);
237 TString phiName = Form(
"TrackPhi%s",
trackType[ti].c_str());
238 hTrackPhi[ti] = tfs->make<TH2D>(phiName,
"", 20, -3.2, 0, 20, -3.2, 0);
241 for(
size_t ti = 0; ti <
t0Type.size(); ti++){
243 TString momName = Form(
"PurityMom%s_%s",
t0Type[ti].c_str(),
purity[
pi].c_str());
244 hPurityMom[ti][
pi] = tfs->make<TH1D>(momName,
"", 20, 0, 10);
245 TString thetaName = Form(
"PurityTheta%s_%s",
t0Type[ti].c_str(),
purity[
pi].c_str());
246 hPurityTheta[ti][
pi] = tfs->make<TH1D>(thetaName,
"", 20, 0, 3.2);
247 TString phiName = Form(
"PurityPhi%s_%s",
t0Type[ti].c_str(),
purity[
pi].c_str());
248 hPurityPhi[ti][
pi] = tfs->make<TH1D>(phiName,
"", 20, -3.2, 3.2);
253 std::cout<<
"----------------- Full CRT Reconstruction Analysis Module -------------------"<<std::endl;
262 std::cout<<
"============================================"<<std::endl
263 <<
"Run = "<<
event.run()<<
", SubRun = "<<
event.subRun()<<
", Event = "<<
event.id().event()<<std::endl
264 <<
"============================================"<<std::endl;
273 art::ServiceHandle<cheat::ParticleInventoryService> pi_serv;
274 auto particleHandle =
event.getValidHandle<std::vector<simb::MCParticle>>(
fSimModuleLabel);
277 art::Handle< std::vector<sbn::crt::CRTHit>> crtHitHandle;
278 std::vector<art::Ptr<sbn::crt::CRTHit> > crtHitList;
280 art::fill_ptr_vector(crtHitList, crtHitHandle);
283 art::Handle< std::vector<sbn::crt::CRTTrack>> crtTrackHandle;
284 std::vector<art::Ptr<sbn::crt::CRTTrack> > crtTrackList;
286 art::fill_ptr_vector(crtTrackList, crtTrackHandle);
287 art::FindManyP<sbn::crt::CRTHit> findManyCrtHits(crtTrackHandle, event,
fCRTTrackLabel);
290 auto tpcTrackHandle =
event.getValidHandle<std::vector<recob::Track>>(
fTPCTrackLabel);
291 art::FindManyP<recob::Hit> findManyHits(tpcTrackHandle, event,
fTPCTrackLabel);
300 double minHitTime = 99999;
301 double maxHitTime = -99999;
302 for(
auto const&
hit : (*crtHitHandle)){
303 double hitTime = (double)(
int)
hit.ts1_ns * 1
e-3;
304 if(hitTime < minHitTime) minHitTime = hitTime;
305 if(hitTime > maxHitTime) maxHitTime = hitTime;
308 std::map<int, simb::MCParticle> particles;
309 std::map<int, CRTTruthMatch> truthMatching;
311 for (
auto const& particle: (*particleHandle)){
315 int partID = particle.TrackId();
316 particles[partID] = particle;
319 if(!(
std::abs(particle.PdgCode()) == 13 && particle.Mother()==0))
continue;
321 double time = particle.T() * 1
e-3;
322 if(time < minHitTime || time > maxHitTime)
continue;
324 truthMatch.
partID = partID;
334 if(trueCP.X() != -99999){
341 truthMatching[partID] = truthMatch;
348 std::vector<sbn::crt::CRTHit> crtHits;
350 for (
auto const& crtHit: (*crtHitHandle)){
351 crtHits.push_back(crtHit);
353 std::string taggerName = crtHit.tagger;
360 if(truthMatching.find(partID) == truthMatching.end())
continue;
362 truthMatching[partID].crtHits[taggerName].push_back(crtHit);
368 std::vector<sbn::crt::CRTTrack> crtTracks;
370 for (
auto const& crtTrack : (*crtTrackHandle)){
371 crtTracks.push_back(crtTrack);
376 if(truthMatching.find(partID) == truthMatching.end())
continue;
378 truthMatching[partID].crtTracks.push_back(crtTrack);
384 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(event);
385 auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(event, clockData);
388 for (
auto const& tpcTrack : (*tpcTrackHandle)){
390 std::vector<art::Ptr<recob::Hit>> hits = findManyHits.at(tpcTrack.ID());
392 if(truthMatching.find(partID) == truthMatching.end())
continue;
393 truthMatching[partID].hasTpcTrack =
true;
398 if(hitT0 != -99999) truthMatching[partID].hitT0s.push_back(hitT0);
402 if(trackT0 != -99999) truthMatching[partID].trackT0s.push_back(trackT0);
410 for(
auto const& truthMatch : truthMatching){
412 int partID = match.
partID;
414 double momentum = particles[partID].P();
415 TVector3 start(particles[partID].Vx(), particles[partID].Vy(), particles[partID].Vz());
416 TVector3
end(particles[partID].EndX(), particles[partID].EndY(), particles[partID].EndZ());
417 double theta = (end-start).Theta();
418 double phi = (end-start).Phi();
424 std::string taggerName = trueCross.first;
427 double minDist = 99999;
430 if(match.
crtHits.find(taggerName) == match.
crtHits.end())
continue;
431 for(
auto const& crtHit : match.
crtHits[taggerName]){
432 double dist = pow(crtHit.x_pos-trueCP.X(), 2) + pow(crtHit.y_pos-trueCP.Y(), 2) + pow(crtHit.z_pos-trueCP.Z(), 2);
440 if(minDist != 99999){
448 double minThetaDiff = 99999;
449 double minPhiDiff = 99999;
450 double minTheta = 99999;
451 double minPhi = 99999;
452 bool complete =
true;
454 simb::MCParticle particle = particles[match.
partID];
455 TVector3 trueStart(particle.Vx(), particle.Vy(), particle.Vz());
456 TVector3 trueEnd(particle.EndX(), particle.EndY(), particle.EndZ());
457 if(trueEnd.Y() > trueStart.Y()) std::swap(trueStart, trueEnd);
458 double trueTheta = (trueEnd - trueStart).Theta();
459 double truePhi = (trueEnd - trueStart).Phi();
461 for(
auto const& crtTrack : match.
crtTracks){
463 TVector3 recoStart(crtTrack.x1_pos, crtTrack.y1_pos, crtTrack.z1_pos);
464 TVector3 recoEnd(crtTrack.x2_pos, crtTrack.y2_pos, crtTrack.z2_pos);
465 if(recoEnd.Y() > recoStart.Y()) std::swap(recoStart, recoEnd);
466 double recoTheta = (recoEnd - recoStart).Theta();
467 double recoPhi = (recoEnd - recoStart).Phi();
468 double thetaDiff = TMath::ATan2(TMath::Sin(recoTheta-trueTheta), TMath::Cos(recoTheta-trueTheta));
469 double phiDiff = TMath::ATan2(TMath::Sin(recoPhi-truePhi), TMath::Cos(recoPhi-truePhi));
470 if(thetaDiff < minThetaDiff){
471 minThetaDiff = thetaDiff;
472 minPhiDiff = phiDiff;
473 minTheta = recoTheta;
475 complete = crtTrack.complete;
479 if(minThetaDiff != 99999){
503 double bestHitT0Diff = 99999;
504 for(
auto const& hitT0 : match.
hitT0s){
506 if(hitT0Diff < bestHitT0Diff) bestHitT0Diff = hitT0Diff;
508 if(bestHitT0Diff != 99999){
513 if(bestHitT0Diff < 2){
523 double bestTrackT0Diff = 99999;
524 for(
auto const& trackT0 : match.
trackT0s){
526 if(trackT0Diff < bestTrackT0Diff) bestTrackT0Diff = trackT0Diff;
528 if(bestTrackT0Diff != 99999){
533 if(bestTrackT0Diff < 2){
541 bool matchesCRTHit = (match.
crtHits.size() > 0);
542 bool matchesCRTTrack = (match.
crtTracks.size() > 0);
543 bool matchesHitT0 = (match.
hitT0s.size() > 0);
544 bool matchesTrackT0 = (match.
trackT0s.size() > 0);
545 std::vector<bool> matches{matchesCRTHit, matchesCRTTrack, matchesHitT0, matchesTrackT0};
547 std::vector<bool> crtHitCategories;
548 std::vector<bool> crtTrackCategories;
549 std::vector<bool> hitT0Categories;
550 std::vector<bool> trackT0Categories;
553 crtHitCategories.push_back((match.
trueCrosses.size() > 0));
554 crtTrackCategories.push_back((match.
trueCrosses.size() > 1));
560 bool validHit =
false;
562 if(valid.second) validHit =
true;
564 crtHitCategories.push_back(validHit);
565 crtTrackCategories.push_back(match.
crtHits.size() > 1);
571 crtHitCategories.push_back(entersCRT);
572 crtTrackCategories.push_back(entersCRT);
573 hitT0Categories.push_back((entersCRT && match.
hasTpcTrack));
574 trackT0Categories.push_back((entersCRT && match.
hasTpcTrack));
578 crtHitCategories.push_back(entersTPC);
579 crtTrackCategories.push_back(entersTPC);
580 hitT0Categories.push_back((entersTPC && match.
hasTpcTrack));
581 trackT0Categories.push_back((entersTPC && match.
hasTpcTrack));
585 crtHitCategories.push_back(crossesCRT);
586 crtTrackCategories.push_back(crossesCRT);
587 hitT0Categories.push_back((crossesCRT && match.
hasTpcTrack));
588 trackT0Categories.push_back((crossesCRT && match.
hasTpcTrack));
592 crtHitCategories.push_back(crossesTPC);
593 crtTrackCategories.push_back(crossesTPC);
594 hitT0Categories.push_back((crossesTPC && match.
hasTpcTrack));
595 trackT0Categories.push_back((crossesTPC && match.
hasTpcTrack));
597 std::vector<std::vector<bool>> matchCategories{crtHitCategories, crtTrackCategories, hitT0Categories, trackT0Categories};
599 for(
size_t si = 0; si <
stage.size(); si++){
600 for(
size_t ci = 0; ci <
category.size(); ci++){
601 if(!matchCategories[si][ci])
continue;
602 hEffMom[si][ci][0]->Fill(momentum);
606 if(!matches[si])
continue;
607 hEffMom[si][ci][1]->Fill(momentum);
CRTFullRecoAna(Parameters const &config)
fhicl::Atom< art::InputTag > CRTSimLabel
int TrueIdFromTrackId(const art::Event &event, int track_i)
TH1D * hEffTheta[4][6][2]
std::vector< std::string > level
bool CrossesVolume(const simb::MCParticle &particle)
std::map< std::string, geo::Point_t > trueCrosses
virtual void analyze(const art::Event &event) override
CRTTaggerGeo GetTagger(std::string taggerName) const
fhicl::Atom< art::InputTag > SimModuleLabel
virtual void beginJob() override
Declaration of signal hit object.
fhicl::Atom< bool > Verbose
bool fVerbose
print information about what's going on
std::map< std::string, TH3D * > hTaggerXYZResolution
fhicl::Table< CRTBackTracker::Config > CrtBackTrack
int TrueIdFromHitId(const art::Event &event, int hit_i)
float z_pos
position in z-direction (cm).
Access the description of detector geometry.
void Initialize(const art::Event &event)
TH1D * hPurityTheta[2][2]
auto end(FixedBins< T, C > const &) noexcept
TH1D * hTrackThetaDiff[3]
bool EntersVolume(const simb::MCParticle &particle)
BEGIN_PROLOG vertical distance to the surface Name
int TrueParticleIDFromTotalRecoHits(detinfo::DetectorClocksData const &clockData, const std::vector< art::Ptr< recob::Hit > > &hits, bool rollup_unsaved_ids=1)
size_t NumTaggers() const
BEGIN_PROLOG don t mess with this TPCTrackLabel
std::vector< std::string > trackType
Definition of data types for geometry description.
art::InputTag fTPCTrackLabel
name of CRT producer
Provides recob::Track data product.
art::InputTag fCRTTrackLabel
name of CRT producer
float y_pos
position in y-direction (cm).
double T0FromCRTHits(detinfo::DetectorPropertiesData const &detProp, recob::Track tpcTrack, std::vector< sbn::crt::CRTHit > crtHits, const art::Event &event)
art::InputTag fCRTSimLabel
name of CRT producer
std::vector< std::string > stage
std::vector< std::string > purity
std::vector< double > trackT0s
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
geo::Point_t TaggerCrossingPoint(std::string taggerName, const simb::MCParticle &particle)
float x_pos
position in x-direction (cm).
fhicl::Table< CRTTrackMatchAlg::Config > CRTTrackAlg
std::vector< std::string > category
fhicl::Atom< art::InputTag > CRTTrackLabel
CRTBackTracker fCrtBackTrack
std::map< std::string, std::vector< sbn::crt::CRTHit > > crtHits
virtual void endJob() override
art::InputTag fSimModuleLabel
name of detsim producer
bool EntersVolume(const simb::MCParticle &particle)
stream1 can override from command line with o or output services user sbnd
fhicl::Atom< art::InputTag > CRTHitLabel
std::vector< double > hitT0s
double T0FromCRTTracks(detinfo::DetectorPropertiesData const &detProp, recob::Track tpcTrack, std::vector< sbn::crt::CRTTrack > crtTracks, const art::Event &event)
art::ServiceHandle< art::TFileService > tfs
std::vector< std::string > t0Type
std::map< std::string, bool > validCrosses
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
art::InputTag fCRTHitLabel
name of CRT producer
fhicl::Atom< art::InputTag > TPCTrackLabel
bool ValidCrossingPoint(std::string taggerName, const simb::MCParticle &particle)
fhicl::Table< CRTT0MatchAlg::Config > CRTT0Alg
art framework interface to geometry description
BEGIN_PROLOG could also be cout
art::EDAnalyzer::Table< Config > Parameters
bool CrossesVolume(const simb::MCParticle &particle)
std::vector< sbn::crt::CRTTrack > crtTracks
CRTTrackMatchAlg crtTrackAlg