68 #include "art_root_io/TFileService.h" 81 #include "TLorentzVector.h" 185 Name(
"SimulationLabel"),
186 Comment(
"tag of the input data product with the detector simulation " 191 Comment(
"tag of the input data product with reconstructed hits")};
194 Name(
"ClusterLabel"),
195 Comment(
"tag of the input data product with reconstructed clusters")};
199 Comment(
"particle type (PDG ID) of the primary particle to be selected")};
202 Comment(
"dx [cm] used for the dE/dx calculation")};
335 auto const clock_data =
369 fPDGCodeHist = tfs->make<TH1D>(
"pdgcodes",
";PDG Code;", 5000, -2500, 2500);
370 fMomentumHist = tfs->make<TH1D>(
"mom",
";particle Momentum (GeV);", 100, 0., 10.);
372 tfs->make<TH1D>(
"length",
";particle track length (cm);", 200, 0, detectorLength);
376 fSimulationNtuple = tfs->make<TTree>(
"AnalysisExampleSimulation",
"AnalysisExampleSimulation");
378 tfs->make<TTree>(
"AnalysisExampleReconstruction",
"AnalysisExampleReconstruction");
382 fSimulationNtuple->Branch(
"Event", &
fEvent,
"Event/I");
383 fSimulationNtuple->Branch(
"SubRun", &
fSubRun,
"SubRun/I");
384 fSimulationNtuple->Branch(
"Run", &
fRun,
"Run/I");
385 fSimulationNtuple->Branch(
"TrackID", &
fSimTrackID,
"TrackID/I");
386 fSimulationNtuple->Branch(
"PDG", &
fSimPDG,
"PDG/I");
389 fSimulationNtuple->Branch(
"StartXYZT",
fStartXYZT,
"StartXYZT[4]/D");
390 fSimulationNtuple->Branch(
"EndXYZT",
fEndXYZT,
"EndXYZT[4]/D");
391 fSimulationNtuple->Branch(
"StartPE",
fStartPE,
"StartPE[4]/D");
392 fSimulationNtuple->Branch(
"EndPE",
fEndPE,
"EndPE[4]/D");
394 fSimulationNtuple->Branch(
"NdEdx", &
fSimNdEdxBins,
"NdEdx/I");
400 fReconstructionNtuple->Branch(
"Event", &
fEvent,
"Event/I");
401 fReconstructionNtuple->Branch(
"SubRun", &
fSubRun,
"SubRun/I");
402 fReconstructionNtuple->Branch(
"Run", &
fRun,
"Run/I");
403 fReconstructionNtuple->Branch(
"TrackID", &
fRecoTrackID,
"TrackID/I");
404 fReconstructionNtuple->Branch(
"PDG", &
fRecoPDG,
"PDG/I");
405 fReconstructionNtuple->Branch(
"NdEdx", &
fRecoNdEdxBins,
"NdEdx/I");
424 fEvent =
event.id().event();
453 <<
" No simb::MCParticle objects in this event - " 454 <<
" Line " << __LINE__ <<
" in file " << __FILE__ << std::endl;
465 auto simChannelHandle =
476 std::map<int, const simb::MCParticle*> particleMap;
479 for (
auto const& particle : *particleHandle) {
497 const size_t numberTrajectoryPoints = particle.NumberTrajectoryPoints();
500 const int last = numberTrajectoryPoints - 1;
501 const TLorentzVector& positionStart = particle.Position(0);
502 const TLorentzVector& positionEnd = particle.Position(last);
503 const TLorentzVector& momentumStart = particle.Momentum(0);
504 const TLorentzVector& momentumEnd = particle.Momentum(last);
514 momentumEnd.GetXYZT(
fEndPE);
517 const double trackLength = (positionEnd - positionStart).Rho();
522 MF_LOG_DEBUG(
"AnalysisExample") <<
"Track length: " << trackLength <<
" cm";
529 <<
" cm long, momentum " << momentumStart.P() <<
" GeV/c, has " << numberTrajectoryPoints
530 <<
" trajectory points";
539 for (
auto const& channel : *simChannelHandle) {
543 auto const channelNumber = channel.Channel();
549 if (wireReadoutGeom.SignalType(channelNumber) !=
geo::kCollection)
continue;
554 auto const& timeSlices = channel.TDCIDEMap();
557 for (
auto const& timeSlice : timeSlices) {
560 auto const& energyDeposits = timeSlice.second;
566 for (
auto const& energyDeposit : energyDeposits) {
569 if (energyDeposit.trackID !=
fSimTrackID)
continue;
571 TVector3 location(energyDeposit.x, energyDeposit.y, energyDeposit.z);
574 const double distance = (location - positionStart.Vect()).Mag();
577 const unsigned int bin = (
unsigned int)(distance /
fBinSize);
631 std::map<int, std::vector<double>> dEdxMap;
633 auto const clock_data =
637 for (
auto const&
hit : *hitHandle) {
639 auto hitChannelNumber =
hit.Channel();
643 if (wireReadoutGeom.SignalType(hitChannelNumber) !=
geo::kCollection)
continue;
645 MF_LOG_DEBUG(
"AnalysisExample") <<
"Hit in collection plane" << std::endl;
656 TDC_t start_tdc = clock_data.TPCTick2TDC(
hit.StartTick());
657 TDC_t end_tdc = clock_data.TPCTick2TDC(
hit.EndTick());
658 TDC_t hitStart_tdc = clock_data.TPCTick2TDC(
hit.PeakTime() - 3. *
hit.SigmaPeakTime());
659 TDC_t hitEnd_tdc = clock_data.TPCTick2TDC(
hit.PeakTime() + 3. *
hit.SigmaPeakTime());
661 start_tdc = std::max(start_tdc, hitStart_tdc);
662 end_tdc = std::min(end_tdc, hitEnd_tdc);
668 for (
auto const& channel : *simChannelHandle) {
669 auto simChannelNumber = channel.Channel();
670 if (simChannelNumber != hitChannelNumber)
continue;
672 MF_LOG_DEBUG(
"AnalysisExample") <<
"SimChannel number = " << simChannelNumber << std::endl;
675 auto const& timeSlices = channel.TDCIDEMap();
683 startTime.first = start_tdc;
684 endTime.first = end_tdc;
689 auto const startPointer =
690 std::lower_bound(timeSlices.begin(), timeSlices.end(), startTime, TDCIDETimeCompare);
693 auto const endPointer =
694 std::upper_bound(startPointer, timeSlices.end(), endTime, TDCIDETimeCompare);
697 if (startPointer == timeSlices.end() || startPointer == endPointer)
continue;
699 <<
"Time slice start = " << (*startPointer).first << std::endl;
702 for (
auto slicePointer = startPointer; slicePointer != endPointer; slicePointer++) {
703 auto const timeSlice = *slicePointer;
704 auto time = timeSlice.first;
716 <<
"Hit index = " <<
hit.LocalIndex() <<
" channel number = " << hitChannelNumber
717 <<
" start TDC tick = " <<
hit.StartTick() <<
" end TDC tick = " <<
hit.EndTick()
718 <<
" peak TDC tick = " <<
hit.PeakTime() <<
" sigma peak time = " <<
hit.SigmaPeakTime()
719 <<
" adjusted start TDC tick = " << clock_data.TPCTick2TDC(
hit.StartTick())
720 <<
" adjusted end TDC tick = " << clock_data.TPCTick2TDC(
hit.EndTick())
721 <<
" adjusted peak TDC tick = " << clock_data.TPCTick2TDC(
hit.PeakTime())
722 <<
" adjusted start_tdc = " << start_tdc <<
" adjusted end_tdc = " << end_tdc
723 <<
" time = " << time << std::endl;
726 auto const& energyDeposits = timeSlice.second;
727 for (
auto const& energyDeposit : energyDeposits) {
738 auto search = particleMap.find(energyDeposit.trackID);
744 if (search == particleMap.end())
continue;
747 int trackID = (*search).first;
754 const TLorentzVector& positionStart = particle.
Position(0);
755 TVector3 location(energyDeposit.x, energyDeposit.y, energyDeposit.z);
756 double distance = (location - positionStart.Vect()).Mag();
770 auto& track_dEdX = dEdxMap[trackID];
771 if (track_dEdX.size() < bin + 1) {
773 track_dEdX.resize(bin + 1, 0);
786 for (
const auto& dEdxEntry : dEdxMap) {
795 const std::vector<double>&
dEdx = dEdxEntry.second;
862 if (!findManyTruth.isValid()) {
863 mf::LogError(
"AnalysisExample") <<
"findManyTruth simb::MCTruth for simb::MCParticle failed!";
872 size_t particle_index = 0;
882 auto const& truth = findManyTruth.at(particle_index);
887 <<
"Particle ID=" << particleHandle->at(particle_index).TrackId() <<
" has no primary!";
896 mf::LogInfo(
"AnalysisExample") <<
"Particle ID=" << particleHandle->at(particle_index).TrackId()
897 <<
" primary PDG code=" << truth[0]->GetParticle(0).PdgCode();
919 if (!findManyHits.isValid()) {
920 mf::LogError(
"AnalysisExample") <<
"findManyHits recob::Hit for recob::Cluster failed;" 928 for (
size_t cluster_index = 0; cluster_index != clusterHandle->size(); cluster_index++) {
931 auto const&
hits = findManyHits.at(cluster_index);
936 mf::LogInfo(
"AnalysisExample") <<
"Cluster ID=" << clusterHandle->at(cluster_index).ID()
937 <<
" has " <<
hits.size() <<
" hits";
952 auto const& tpc = geom.
TPC({0, 0});
953 const double length = tpc.
Length();
954 const double width = 2. * tpc.HalfWidth();
955 const double height = 2. * tpc.HalfHeight();
957 return std::hypot(length, width, height);
964 return lhs.first < rhs.first;
Store parameters for running LArG4.
int fSimNdEdxBins
Number of dE/dx bins in a given track.
const TLorentzVector & Position(const int i=0) const
TH1D * fPDGCodeHist
PDG code of all particles.
Utilities related to art service access.
fhicl::Atom< art::InputTag > HitLabel
fhicl::Atom< double > BinSize
fhicl::Atom< art::InputTag > SimulationLabel
int fRecoTrackID
GEANT ID of the particle being processed.
std::pair< unsigned short, std::vector< sim::IDE > > TDCIDE
List of energy deposits at the same time (on this channel)
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
Declaration of signal hit object.
art::InputTag fHitProducerLabel
The name of the producer that created hits.
double fEndXYZT[4]
(x,y,z,t) of the true end of the particle
geo::GeometryCore const * fGeometryService
pointer to Geometry provider
std::vector< double > fSimdEdxBins
The vector that will be used to accumulate dE/dx values as a function of range.
double fStartPE[4]
(Px,Py,Pz,E) at the true start of the particle
AnalysisExample(Parameters const &config)
Constructor: configures the module (see the Config structure above)
int fSimTrackID
GEANT ID of the particle being processed.
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
TTree * fReconstructionNtuple
tuple with reconstructed data
void analyze(const art::Event &event) override
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
EDAnalyzer(fhicl::ParameterSet const &pset)
std::string Process() const
art::InputTag fSimulationProducerLabel
int fRecoNdEdxBins
Number of dE/dx bins in a given track.
double Length() const
Length is associated with z coordinate [cm].
Access the description of the physical detector geometry.
#define DEFINE_ART_MODULE(klass)
fhicl::Atom< art::InputTag > ClusterLabel
void beginRun(const art::Run &run) override
double fStartXYZT[4]
(x,y,z,t) of the true start of the particle
std::vector< double > fRecodEdxBins
The vector that will be used to accumulate dE/dx values as a function of range.
art::InputTag fClusterProducerLabel
Description of the physical geometry of one entire detector.
Declaration of cluster object.
int fRecoPDG
PDG ID of the particle being processed.
Definition of data types for geometry description.
float dEdx(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, TP3D &tp3d)
Detector simulation of raw signals on wires.
fhicl::Atom< int > PDGcode
int fSimPDG
PDG ID of the particle being processed.
int fRun
number of the run being processed
TH1D * fMomentumHist
momentum [GeV] of all selected particles
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
int fEvent
number of the event being processed
object containing MC truth information necessary for making RawDigits and doing back tracking ...
int trigger_offset(DetectorClocksData const &data)
double fEndPE[4]
(Px,Py,Pz,E) at the true end of the particle
TTree * fSimulationNtuple
tuple with simulated data
double fElectronsToGeV
conversion factor
TPCGeo const & TPC(TPCID const &tpcid=details::tpc_zero) const
Returns the specified TPC.
int fTriggerOffset
(units of ticks) time of expected neutrino event
double fBinSize
For dE/dx work: the value of dx.
double GeVToElectrons() const
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
TH1D * fTrackLengthHist
true length [cm] of all selected particles
Event finding and building.
int fSelectedPDG
PDG code of particle we'll focus on.
TDCIDE::first_type StoredTDC_t
Type for TDC tick used in the internal representation.
Signal from collection planes.