79 #include "cetlib/pow.h" 87 #include "TLorentzVector.h" 211 Name(
"SimulationLabel"),
212 Comment(
"tag of the input data product with the detector simulation information")
217 Comment(
"tag of the input data product with reconstructed hits")
221 Name(
"ClusterLabel"),
222 Comment(
"tag of the input data product with reconstructed clusters")
227 Comment(
"particle type (PDG ID) of the primary particle to be selected")
232 Comment(
"dx [cm] used for the dE/dx calculation")
394 fTimeService = lar::providerFrom<detinfo::DetectorClocksService>();
432 fMomentumHist = tfs->
make<TH1D>(
"mom",
";particle Momentum (GeV);", 100, 0., 10.);
433 fTrackLengthHist = tfs->
make<TH1D>(
"length",
";particle track length (cm);", 200, 0, detectorLength);
443 fSimulationNtuple->Branch(
"Event", &
fEvent,
"Event/I");
444 fSimulationNtuple->Branch(
"SubRun", &
fSubRun,
"SubRun/I");
445 fSimulationNtuple->Branch(
"Run", &
fRun,
"Run/I");
446 fSimulationNtuple->Branch(
"TrackID", &
fSimTrackID,
"TrackID/I");
447 fSimulationNtuple->Branch(
"PDG", &
fSimPDG,
"PDG/I");
450 fSimulationNtuple->Branch(
"StartXYZT",
fStartXYZT,
"StartXYZT[4]/D");
451 fSimulationNtuple->Branch(
"EndXYZT",
fEndXYZT,
"EndXYZT[4]/D");
452 fSimulationNtuple->Branch(
"StartPE",
fStartPE,
"StartPE[4]/D");
453 fSimulationNtuple->Branch(
"EndPE",
fEndPE,
"EndPE[4]/D");
455 fSimulationNtuple->Branch(
"NdEdx", &
fSimNdEdxBins,
"NdEdx/I");
461 fReconstructionNtuple->Branch(
"Event", &
fEvent,
"Event/I");
462 fReconstructionNtuple->Branch(
"SubRun", &
fSubRun,
"SubRun/I");
463 fReconstructionNtuple->Branch(
"Run", &
fRun,
"Run/I");
464 fReconstructionNtuple->Branch(
"TrackID", &
fRecoTrackID,
"TrackID/I");
465 fReconstructionNtuple->Branch(
"PDG", &
fRecoPDG,
"PDG/I");
466 fReconstructionNtuple->Branch(
"NdEdx", &
fRecoNdEdxBins,
"NdEdx/I");
492 fEvent =
event.id().event();
525 <<
" No simb::MCParticle objects in this event - " 526 <<
" Line " << __LINE__ <<
" in file " << __FILE__ << std::endl;
544 auto simChannelHandle =
556 std::map< int, const simb::MCParticle* > particleMap;
588 for (
auto const& particle : (*particleHandle) )
610 const size_t numberTrajectoryPoints = particle.NumberTrajectoryPoints();
614 const int last = numberTrajectoryPoints - 1;
615 const TLorentzVector& positionStart = particle.Position(0);
616 const TLorentzVector& positionEnd = particle.Position(last);
617 const TLorentzVector& momentumStart = particle.Momentum(0);
618 const TLorentzVector& momentumEnd = particle.Momentum(last);
629 momentumEnd.GetXYZT(
fEndPE );
633 const double trackLength = ( positionEnd - positionStart ).Rho();
640 <<
"Track length: " << trackLength <<
" cm";
647 <<
" (PDG ID: " <<
fSimPDG <<
") " 648 << trackLength <<
" cm long, momentum " 649 << momentumStart.P() <<
" GeV/c, has " 650 << numberTrajectoryPoints <<
" trajectory points";
659 for (
auto const& channel : (*simChannelHandle) )
665 auto const channelNumber = channel.Channel();
680 auto const& timeSlices = channel.TDCIDEMap();
683 for (
auto const& timeSlice : timeSlices )
688 auto const& energyDeposits = timeSlice.second;
697 for (
auto const& energyDeposit : energyDeposits )
701 if ( energyDeposit.trackID !=
fSimTrackID )
continue;
703 TVector3 location( energyDeposit.x,
708 const double distance = ( location - positionStart.Vect() ).Mag();
711 const unsigned int bin = (
unsigned int)( distance /
fBinSize );
773 std::map< int, std::vector<double> > dEdxMap;
776 for (
auto const&
hit : (*hitHandle) )
779 auto hitChannelNumber =
hit.Channel();
787 <<
"Hit in collection plane" 809 start_tdc =
std::max(start_tdc, hitStart_tdc);
810 end_tdc =
std::min(end_tdc, hitEnd_tdc );
817 for (
auto const& channel : (*simChannelHandle) )
819 auto simChannelNumber = channel.Channel();
820 if ( simChannelNumber != hitChannelNumber )
continue;
823 <<
"SimChannel number = " << simChannelNumber
827 auto const& timeSlices = channel.TDCIDEMap();
847 startTime.first = start_tdc;
848 endTime.first = end_tdc;
853 auto const startPointer
854 = std::lower_bound( timeSlices.begin(), timeSlices.end(), startTime, TDCIDETimeCompare);
857 auto const endPointer
858 = std::upper_bound( startPointer, timeSlices.end(), endTime, TDCIDETimeCompare);
861 if ( startPointer == timeSlices.end() || startPointer == endPointer )
continue;
863 <<
"Time slice start = " << (*startPointer).first
868 for (
auto slicePointer = startPointer; slicePointer != endPointer; slicePointer++)
870 auto const timeSlice = *slicePointer;
871 auto time = timeSlice.first;
885 <<
"Hit index = " <<
hit.LocalIndex()
886 <<
" channel number = " << hitChannelNumber
887 <<
" start TDC tick = " <<
hit.StartTick()
888 <<
" end TDC tick = " <<
hit.EndTick()
889 <<
" peak TDC tick = " <<
hit.PeakTime()
890 <<
" sigma peak time = " <<
hit.SigmaPeakTime()
894 <<
" adjusted start_tdc = " << start_tdc
895 <<
" adjusted end_tdc = " << end_tdc
896 <<
" time = " << time
900 auto const& energyDeposits = timeSlice.second;
901 for (
auto const& energyDeposit : energyDeposits )
918 auto search = particleMap.find( energyDeposit.trackID );
926 if ( search == particleMap.end() )
continue;
929 int trackID = (*search).first;
934 if ( particle.
Process() !=
"primary" 939 const TLorentzVector& positionStart = particle.
Position(0);
940 TVector3 location( energyDeposit.x,
943 double distance = ( location - positionStart.Vect() ).Mag();
963 auto& track_dEdX = dEdxMap[trackID];
964 if ( track_dEdX.size() < bin+1 )
968 track_dEdX.resize( bin+1, 0 );
981 for (
const auto& dEdxEntry : dEdxMap )
992 const std::vector<double>& dEdx = dEdxEntry.second;
1066 if ( ! findManyTruth.isValid() )
1069 <<
"findManyTruth simb::MCTruth for simb::MCParticle failed!";
1079 size_t particle_index = 0;
1091 auto const& truth = findManyTruth.at( particle_index );
1094 if ( truth.empty() )
1097 <<
"Particle ID=" << particleHandle->at( particle_index ).TrackId()
1098 <<
" has no primary!";
1109 <<
"Particle ID=" << particleHandle->at( particle_index ).TrackId()
1110 <<
" primary PDG code=" << truth[0]->GetParticle(0).PdgCode();
1136 if ( ! findManyHits.isValid() )
1139 <<
"findManyHits recob::Hit for recob::Cluster failed;" 1148 for (
size_t cluster_index = 0; cluster_index != clusterHandle->size(); cluster_index++ )
1153 auto const&
hits = findManyHits.at( cluster_index );
1160 <<
"Cluster ID=" << clusterHandle->at( cluster_index ).ID()
1161 <<
" has " <<
hits.size() <<
" hits";
1184 return std::sqrt(cet::sum_of_squares(length, width, height));
1191 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.
fhicl::Atom< art::InputTag > HitLabel
geo::Length_t DetHalfWidth(geo::TPCID const &tpcid) const
Returns the half width of the active volume of the specified TPC.
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.
TTree * fReconstructionNtuple
tuple with reconstructed data
virtual void analyze(const art::Event &event) override
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
std::string Process() const
art::InputTag fSimulationProducerLabel
The name of the producer that tracked simulated particles through the detector.
int fRecoNdEdxBins
Number of dE/dx bins in a given track.
Access the description of detector geometry.
geo::Length_t DetHalfHeight(geo::TPCID const &tpcid) const
Returns the half height of the active volume of the specified TPC.
#define DEFINE_ART_MODULE(klass)
fhicl::Atom< art::InputTag > ClusterLabel
virtual 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.
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
detinfo::DetectorClocks const * fTimeService
pointer to detector clock time service provider
art::InputTag fClusterProducerLabel
The name of the producer that created clusters.
EDAnalyzer(Table< Config > const &config)
Description of 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.
Detector simulation of raw signals on wires.
fhicl::Atom< int > PDGcode
Conversion of times between different formats and references.
int fSimPDG
PDG ID of the particle being processed.
int fRun
number of the run being processed
T * make(ARGS...args) const
virtual double TPCTick2TDC(double tick) const =0
Converts a TPC time tick into a electronics time tick.
TH1D * fMomentumHist
momentum [GeV] of all selected particles
LArSoft-specific namespace.
int fEvent
number of the event being processed
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
object containing MC truth information necessary for making RawDigits and doing back tracking ...
double fEndPE[4]
(Px,Py,Pz,E) at the true end of the particle
virtual void beginJob() override
TTree * fSimulationNtuple
tuple with simulated data
double fElectronsToGeV
conversion factor
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.