26 #include "nusimdata/SimulationBase/MCParticle.h"
30 #include "art/Framework/Core/EDAnalyzer.h"
31 #include "art/Framework/Principal/Event.h"
32 #include "art/Framework/Principal/Handle.h"
33 #include "art/Framework/Services/Registry/ServiceHandle.h"
34 #include "art_root_io/TFileService.h"
35 #include "art/Framework/Core/ModuleMacros.h"
36 #include "canvas/Persistency/Common/FindManyP.h"
37 #include "canvas/Utilities/Exception.h"
43 #include "messagefacility/MessageLogger/MessageLogger.h"
44 #include "fhiclcpp/ParameterSet.h"
45 #include "fhiclcpp/types/Table.h"
46 #include "fhiclcpp/types/Atom.h"
47 #include "cetlib/pow.h"
72 virtual void analyze(
const art::Event& event)
override;
75 virtual void endJob()
override;
101 std::map<std::string, TH1D*>
hDCA;
105 std::map<std::string, TH1D*>
hDoL;
109 std::map<std::string, TH1D*>
hT0;
139 , t0Alg(
p.get<fhicl::ParameterSet>(
"t0Alg"))
141 , bt(
p.get<fhicl::ParameterSet>(
"CRTBackTrack"))
145 fGeometryService = lar::providerFrom<geo::Geometry>();
155 fCRTHitLabel = p.get<art::InputTag> (
"CRTHitLabel",
"crthit");
156 fTPCTrackLabel = p.get< std::vector<art::InputTag> >(
"TPCTrackLabel", {
""});
157 fTriggerLabel = p.get<art::InputTag>(
"TriggerLabel",
"daqTrigger");
166 art::ServiceHandle<art::TFileService>
tfs;
167 for(
int i = 30; i < 50 + 1; i++){
168 std::string
tagger =
"All";
169 if (i > 34 && i < 40)
continue;
170 if (i==48 || i==49)
continue;
173 std::cout <<
"tagger: " << tagger.c_str() << std::endl;
174 hDCA[tagger] = tfs->make<TH1D>(Form(
"DCA_%s", tagger.c_str()),
"", 50, 0, 100);
175 hMatchDCA[tagger] = tfs->make<TH1D>(Form(
"MatchDCA_%s", tagger.c_str()),
"", 50, 0, 100);
176 hNoMatchDCA[tagger] = tfs->make<TH1D>(Form(
"NoMatchDCA_%s", tagger.c_str()),
"", 50, 0, 100);
178 hDoL[tagger] = tfs->make<TH1D>(Form(
"DoL_%s", tagger.c_str()),
"", 100, 0, 0.25);
179 hMatchDoL[tagger] = tfs->make<TH1D>(Form(
"MatchDoL_%s", tagger.c_str()),
"", 100, 0, 0.25);
180 hNoMatchDoL[tagger] = tfs->make<TH1D>(Form(
"NoMatchDoL_%s", tagger.c_str()),
"", 100, 0, 0.25);
182 hT0[tagger] = tfs->make<TH1D>(Form(
"T0_%s", tagger.c_str()),
"", 600, -3000, 3000);
183 hMatchT0[tagger] = tfs->make<TH1D>(Form(
"MatchT0_%s", tagger.c_str()),
"", 600, -3000, 3000);
184 hNoMatchT0[tagger] = tfs->make<TH1D>(Form(
"NoMatchT0_%s", tagger.c_str()),
"", 600, -3000, 3000);
186 hEffDCATotal[tagger] = tfs->make<TH1D>(Form(
"EffDCATotal_%s", tagger.c_str()),
"", 50, 0, 100);
187 hEffDCAReco[tagger] = tfs->make<TH1D>(Form(
"EffDCAReco_%s", tagger.c_str()),
"", 50, 0, 100);
188 hEffDoLTotal[tagger] = tfs->make<TH1D>(Form(
"EffDoLTotal_%s", tagger.c_str()),
"", 100, 0, 0.25);
189 hEffDoLReco[tagger] = tfs->make<TH1D>(Form(
"EffDoLReco_%s", tagger.c_str()),
"", 100, 0, 0.25);
190 hEffLengthTotal[tagger] = tfs->make<TH1D>(Form(
"EffLengthTotal_%s", tagger.c_str()),
"", 20, 0, 600);
191 hEffLengthReco[tagger] = tfs->make<TH1D>(Form(
"EffLengthReco_%s", tagger.c_str()),
"", 20, 0, 600);
193 hPurityDCATotal[tagger] = tfs->make<TH1D>(Form(
"PurityDCATotal_%s", tagger.c_str()),
"", 50, 0, 100);
194 hPurityDCAReco[tagger] = tfs->make<TH1D>(Form(
"PurityDCAReco_%s", tagger.c_str()),
"", 50, 0, 100);
195 hPurityDoLTotal[tagger] = tfs->make<TH1D>(Form(
"PurityDoLTotal_%s", tagger.c_str()),
"", 100, 0, 0.25);
196 hPurityDoLReco[tagger] = tfs->make<TH1D>(Form(
"PurityDoLReco_%s", tagger.c_str()),
"", 100, 0, 0.25);
197 hPurityLengthTotal[tagger] = tfs->make<TH1D>(Form(
"PurityLengthTotal_%s", tagger.c_str()),
"", 20, 0, 600);
198 hPurityLengthReco[tagger] = tfs->make<TH1D>(Form(
"PurityLengthReco_%s", tagger.c_str()),
"", 20, 0, 600);
202 if(
fVerbose)
std::cout<<
"----------------- CRT T0 Matching Ana Module -------------------"<<std::endl;
212 std::cout<<
"============================================"<<std::endl
213 <<
"Run = "<<
event.run()<<
", SubRun = "<<
event.subRun()<<
", Event = "<<
event.id().event()<<std::endl
214 <<
"============================================"<<std::endl;
224 art::Handle<sbn::ExtraTriggerInfo> trigger_handle;
226 if( trigger_handle.isValid() ) {
232 m_trigger_gate_diff = trigger_handle->triggerTimestamp - trigger_handle->beamGateTimestamp;
236 mf::LogError(
"CRTT0MatchingAna:") <<
"No raw::Trigger associated to label: " <<
fTriggerLabel.label() <<
"\n" ;
240 mf::LogError(
"CRTT0MatchingAna:") <<
"Trigger Data product " <<
fTriggerLabel.label() <<
" not found!\n" ;
244 art::ServiceHandle<cheat::ParticleInventoryService> pi_serv;
245 auto particleHandle =
event.getValidHandle<std::vector<simb::MCParticle>>(
fSimModuleLabel);
248 art::Handle< std::vector<sbn::crt::CRTHit>> crtHitHandle;
249 std::vector<art::Ptr<sbn::crt::CRTHit> > crtHitList;
251 art::fill_ptr_vector(crtHitList, crtHitHandle);
263 std::map<int, simb::MCParticle> particles;
265 for (
auto const& particle: (*particleHandle)){
268 int partID = particle.TrackId();
269 particles[partID] = particle;
273 if(
fVerbose)
std::cout<<
"----------------- truth matching -------------------"<<std::endl;
274 std::map<int, std::vector<std::string>> crtTaggerMap;
275 std::vector<sbn::crt::CRTHit> crtHits;
277 double minHitTime = 99999;
278 double maxHitTime = -99999;
280 for(
auto const&
hit : (*crtHitHandle)){
282 if(hitTime<-0.5e6) hitTime+=1e6;
283 else if(hitTime>0.5e6) hitTime-=1e6;
285 // double hitTime = (double)(int)hit.ts1_ns * 1e-3;
286 if(hitTime < minHitTime) minHitTime = hitTime;
287 if(hitTime > maxHitTime) maxHitTime = hitTime;
289 crtHits.push_back(hit);
290 int trueId = bt.TrueIdFromHitId(event, hit_i);
292 if(trueId == -99999) continue;
293 if(crtTaggerMap.find(trueId) == crtTaggerMap.end()){
294 crtTaggerMap[trueId].push_back(hit.tagger);
296 else if(std::find(crtTaggerMap[trueId].begin(), crtTaggerMap[trueId].end(), hit.tagger) == crtTaggerMap[trueId].end()){
297 crtTaggerMap[trueId].push_back(hit.tagger);
301 // std::cout << " New event" << std::endl;
302 //----------------------------------------------------------------------------------------------------------
303 // DISTANCE OF CLOSEST APPROACH ANALYSIS
304 //----------------------------------------------------------------------------------------------------------
306 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(event);
307 auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(event, clockData);
309 // if(fVerbose) std::cout<<"----------------- DCA Analysis -------------------"<<std::endl;
310 for(const auto& trackLabel : fTPCTrackLabel)
312 auto tpcTrackHandle = event.getValidHandle<std::vector<recob::Track>>(trackLabel);
313 if (!tpcTrackHandle.isValid()) continue;
315 art::FindManyP<recob::Hit> findManyHits(tpcTrackHandle, event, trackLabel);
317 // Loop over reconstructed tracks
318 for (auto const& tpcTrack : (*tpcTrackHandle)){
319 // std::cout<<"----------------- why only 4 times -------------------" <<std::endl;
320 // if(fVerbose) std::cout<<"----------------- # track -------------------" << (*tpcTrackHandle).size()<<std::endl;
321 // Get the associated hits
322 std::vector<art::Ptr<recob::Hit>> hits = findManyHits.at(tpcTrack.ID());
323 int trackTrueID = RecoUtils::TrueParticleIDFromTotalRecoHits(clockData, hits, false);
324 if(particles.find(trackTrueID) == particles.end()) continue;
325 // Only consider primary muons
326 if(!(std::abs(particles[trackTrueID].PdgCode()) == 13 && particles[trackTrueID].Mother() == 0)) continue;
328 // Only consider particles inside the reco hit time window
329 double trueTime = particles[trackTrueID].T() * 1e-3;
330 if(trueTime < minHitTime || trueTime > maxHitTime) continue;
331 //if(fVerbose) std::cout<<"----------------- line 315 -------------------"<<std::endl;
332 std::cout << "new track " << trueTime << std::endl;
333 // Calculate t0 from CRT Hit matching
334 matchCand closest = t0Alg.GetClosestCRTHit(detProp, tpcTrack, hits, crtHits, m_gate_start_timestamp);
335 // matchCand closest = t0Alg.GetClosestCRTHit(detProp, tpcTrack, crtHits, event);
336 //std::vector <matchCand> closestvec = t0Alg.GetClosestCRTHit(detProp, tpcTrack, crtHits, event);
337 //matchCand closest = closestvec.back();
338 //std::cout << "closest match " << closest.t0 << std::endl;
339 //std::cout << "closest dca " << closest.dca << " ,tagger: "<< closest.thishit.tagger << " , sin angele: \t" << closest.dca/closest.extrapLen << std::endl;
340 double sin_angle = -99999;
341 if(closest.dca != -99999){
342 hDCA[closest.thishit.tagger]->Fill(closest.dca);
343 //hDCA["All"]->Fill(closest.dca);
344 sin_angle = closest.dca/closest.extrapLen;
345 hDoL[closest.thishit.tagger]->Fill(sin_angle);
346 // hDoL["All"]->Fill(sin_angle);
347 hT0[closest.thishit.tagger]->Fill(closest.t0);
348 //hT0["All"]->Fill(closest.t0);
349 //std::cout<< "tagger: "<< closest.thishit.tagger << " , sin angele: \t" << sin_angle << std::endl;
351 // Is hit matched to that track
352 int hitTrueID = bt.TrueIdFromTotalEnergy(event, closest.thishit);
353 if(hitTrueID == trackTrueID && hitTrueID != -99999){
354 hMatchDCA[closest.thishit.tagger]->Fill(closest.dca);
355 //hMatchDCA["All"]->Fill(closest.dca);
356 hMatchDoL[closest.thishit.tagger]->Fill(sin_angle);
357 //hMatchDoL["All"]->Fill(sin_angle);
358 hMatchT0[closest.thishit.tagger]->Fill(closest.t0);
359 //hMatchT0["All"]->Fill(closest.t0);
362 hNoMatchDCA[closest.thishit.tagger]->Fill(closest.dca);
363 //hNoMatchDCA["All"]->Fill(closest.dca);
364 hNoMatchDoL[closest.thishit.tagger]->Fill(sin_angle);
365 // hNoMatchDoL["All"]->Fill(sin_angle);
366 hNoMatchT0[closest.thishit.tagger]->Fill(closest.t0);
367 // hNoMatchT0["All"]->Fill(closest.t0);
369 //std::cout<< "---------> 2nd line tagger: "<< closest.thishit.tagger << " , sin angele: \t" << sin_angle << std::endl;
371 //if(fVerbose) std::cout<<"----------------- line 350 -------------------"<<std::endl;
372 int nbins = hEffDCATotal.begin()->second->GetNbinsX();
373 for(int i = 0; i < nbins; i++){
374 double DCAcut = hEffDCATotal.begin()->second->GetBinCenter(i);
376 // Fill total efficiency histogram with each cut if track matches any hits
377 if(crtTaggerMap.find(trackTrueID) != crtTaggerMap.end()){
378 for(auto const& tagger : crtTaggerMap[trackTrueID]){
379 hEffDCATotal[tagger]->Fill(DCAcut);
381 // If closest hit is below limit and track matches any hits then fill efficiency
382 if(closest.dca < DCAcut && closest.dca != -99999){
383 hEffDCAReco[tagger]->Fill(DCAcut);
386 // Fill total efficiency histograms
387 // hEffDCATotal["All"]->Fill(DCAcut);
388 if(closest.dca < DCAcut && closest.dca != -99999){
389 // hEffDCAReco["All"]->Fill(DCAcut);
393 // Fill total purity histogram with each cut if closest hit is below limit
394 if(closest.dca < DCAcut && closest.dca != -99999){
395 hPurityDCATotal[closest.thishit.tagger]->Fill(DCAcut);
396 // hPurityDCATotal["All"]->Fill(DCAcut);
398 // If closest hit is below limit and matched time is correct then fill purity
399 double hitTime = closest.thishit.ts1_ns * 1e-3;
400 if(particles.find(trackTrueID) != particles.end()){
401 if(std::abs(hitTime - trueTime) < 2.){
402 hPurityDCAReco[closest.thishit.tagger]->Fill(DCAcut);
403 // hPurityDCAReco["All"]->Fill(DCAcut);
410 nbins = hEffDoLTotal.begin()->second->GetNbinsX();
411 //if(fVerbose) std::cout<<"----------------- line 390 -------------------"<<std::endl;
412 for(int i = 0; i < nbins; i++){
413 double DCAcut = hEffDoLTotal.begin()->second->GetBinCenter(i);
415 // Fill total efficiency histogram with each cut if track matches any hits
416 if(crtTaggerMap.find(trackTrueID) != crtTaggerMap.end()){
417 for(auto const& tagger : crtTaggerMap[trackTrueID]){
418 hEffDoLTotal[tagger]->Fill(DCAcut);
420 // If closest hit is below limit and track matches any hits then fill efficiency
421 if(sin_angle < DCAcut && closest.dca != -99999){
422 hEffDoLReco[tagger]->Fill(DCAcut);
425 // Fill total efficiency histograms
426 // hEffDoLTotal["All"]->Fill(DCAcut);
427 if(sin_angle < DCAcut && closest.dca != -99999){
428 // hEffDoLReco["All"]->Fill(DCAcut);
432 // Fill total purity histogram with each cut if closest hit is below limit
433 if(sin_angle < DCAcut && closest.dca != -99999){
434 hPurityDoLTotal[closest.thishit.tagger]->Fill(DCAcut);
435 // hPurityDoLTotal["All"]->Fill(DCAcut);
437 // If closest hit is below limit and matched time is correct then fill purity
438 double hitTime = closest.thishit.ts1_ns * 1e-3;
439 if(particles.find(trackTrueID) != particles.end()){
440 if(std::abs(hitTime - trueTime) < 2.){
441 hPurityDoLReco[closest.thishit.tagger]->Fill(DCAcut);
442 // hPurityDoLReco["All"]->Fill(DCAcut);
449 double fixedCut = 30.;
451 // Fill total efficiency histogram with each cut if track matches any hits
452 if(crtTaggerMap.find(trackTrueID) != crtTaggerMap.end()){
453 for(auto const& tagger : crtTaggerMap[trackTrueID]){
454 hEffLengthTotal[tagger]->Fill(tpcTrack.Length());
456 // If closest hit is below limit and track matches any hits then fill efficiency
457 if(closest.dca < fixedCut && closest.dca >=0 ){
458 hEffLengthReco[tagger]->Fill(tpcTrack.Length());
461 // Fill total efficiency histograms
462 // hEffLengthTotal["All"]->Fill(tpcTrack.Length());
463 if(closest.dca < fixedCut && closest.dca >=0){
464 //hEffLengthReco["All"]->Fill(tpcTrack.Length());
468 // Fill total purity histogram with each cut if closest hit is below limit
469 if(closest.dca < fixedCut && closest.dca >= 0){
470 hPurityLengthTotal[closest.thishit.tagger]->Fill(tpcTrack.Length());
471 // hPurityLengthTotal["All"]->Fill(tpcTrack.Length());
473 // If closest hit is below limit and matched time is correct then fill purity
474 double hitTime = closest.thishit.ts1_ns * 1e-3;
475 if(particles.find(trackTrueID) != particles.end()){
476 double trueTime = particles[trackTrueID].T() * 1e-3;
477 if(std::abs(hitTime - trueTime) < 2.){
478 hPurityLengthReco[closest.thishit.tagger]->Fill(tpcTrack.Length());
479 // hPurityLengthReco["All"]->Fill(tpcTrack.Length());
484 // if(fVerbose) std::cout<<"----------------- line 463 -------------------"<<std::endl;
487 // if(fVerbose) std::cout<<"----------------- line 466 -------------------"<<std::endl;
489 } // CRTT0MatchingAna::analyze()
492 void CRTT0MatchingAna::endJob(){
495 } // CRTT0MatchingAna::endJob()
498 DEFINE_ART_MODULE(CRTT0MatchingAna)
499 } // namespace icarus
Functions to help with numbers.
bool fVerbose
print information about what's going on
Utilities related to art service access.
std::map< std::string, TH1D * > hNoMatchDCA
std::map< std::string, TH1D * > hDoL
std::map< std::string, TH1D * > hPurityDoLReco
Declaration of signal hit object.
art::InputTag fTriggerLabel
labels for trigger
std::map< std::string, TH1D * > hNoMatchT0
std::map< std::string, TH1D * > hEffDoLReco
uint64_t m_gate_start_timestamp
std::map< std::string, TH1D * > hEffDCAReco
std::map< std::string, TH1D * > hPurityLengthReco
std::map< std::string, TH1D * > hPurityDCATotal
std::map< std::string, TH1D * > hMatchDCA
std::string bitName(triggerSource bit)
Returns a mnemonic short name of the beam type.
std::map< std::string, TH1D * > hPurityDCAReco
std::map< std::string, TH1D * > hNoMatchDoL
std::map< std::string, TH1D * > hT0
std::map< std::string, TH1D * > hEffDoLTotal
icarus::crt::CRTBackTracker bt
uint64_t m_trigger_timestamp
string GetRegionNameFromNum(int num)
art::InputTag fCRTHitLabel
name of CRT producer
art::InputTag fSimModuleLabel
name of detsim producer
virtual void analyze(const art::Event &event) override
std::map< std::string, TH1D * > hEffLengthReco
virtual void beginJob() override
std::map< std::string, TH1D * > hPurityLengthTotal
void reconfigure(fhicl::ParameterSet const &p)
virtual void endJob() override
std::map< std::string, TH1D * > hEffDCATotal
Description of geometry of one entire detector.
Definition of data types for geometry description.
CRTT0MatchingAna(fhicl::ParameterSet const &p)
std::map< std::string, TH1D * > hMatchDoL
Provides recob::Track data product.
std::map< std::string, TH1D * > hDCA
std::map< std::string, TH1D * > hPurityDoLTotal
double DistToCrtHit(TVector3 trackPos, sbn::crt::CRTHit crtHit)
object containing MC truth information necessary for making RawDigits and doing back tracking ...
std::vector< art::InputTag > fTPCTrackLabel
name of CRT producer
triggerSource
Type of beam or beam gate or other trigger source.
std::map< std::string, TH1D * > hEffLengthTotal
art::ServiceHandle< art::TFileService > tfs
icarus::crt::CRTCommonUtils * fCrtutils
std::map< std::string, TH1D * > hMatchT0
BEGIN_PROLOG could also be cout
uint64_t m_trigger_gate_diff
geo::GeometryCore const * fGeometryService
pointer to Geometry provider