72 #include "art_root_io/TFileService.h" 77 #include "cetlib/pow.h" 86 #include "TLorentzVector.h" 205 Name(
"SimulationLabel"),
206 Comment(
"tag of the input data product with the detector simulation " 211 Comment(
"tag of the input data product with reconstructed hits")};
214 Name(
"ClusterLabel"),
215 Comment(
"tag of the input data product with reconstructed clusters")};
219 Comment(
"particle type (PDG ID) of the primary particle to be selected")};
222 Comment(
"dx [cm] used for the dE/dx calculation")};
385 auto const clock_data =
420 fPDGCodeHist = tfs->make<TH1D>(
"pdgcodes",
";PDG Code;", 5000, -2500, 2500);
421 fMomentumHist = tfs->make<TH1D>(
"mom",
";particle Momentum (GeV);", 100, 0., 10.);
423 tfs->make<TH1D>(
"length",
";particle track length (cm);", 200, 0, detectorLength);
428 tfs->make<TTree>(
"AnalysisExampleSimulation",
"AnalysisExampleSimulation");
430 tfs->make<TTree>(
"AnalysisExampleReconstruction",
"AnalysisExampleReconstruction");
435 fSimulationNtuple->Branch(
"Event", &
fEvent,
"Event/I");
436 fSimulationNtuple->Branch(
"SubRun", &
fSubRun,
"SubRun/I");
437 fSimulationNtuple->Branch(
"Run", &
fRun,
"Run/I");
438 fSimulationNtuple->Branch(
"TrackID", &
fSimTrackID,
"TrackID/I");
439 fSimulationNtuple->Branch(
"PDG", &
fSimPDG,
"PDG/I");
442 fSimulationNtuple->Branch(
"StartXYZT",
fStartXYZT,
"StartXYZT[4]/D");
443 fSimulationNtuple->Branch(
"EndXYZT",
fEndXYZT,
"EndXYZT[4]/D");
444 fSimulationNtuple->Branch(
"StartPE",
fStartPE,
"StartPE[4]/D");
445 fSimulationNtuple->Branch(
"EndPE",
fEndPE,
"EndPE[4]/D");
447 fSimulationNtuple->Branch(
"NdEdx", &
fSimNdEdxBins,
"NdEdx/I");
453 fReconstructionNtuple->Branch(
"Event", &
fEvent,
"Event/I");
454 fReconstructionNtuple->Branch(
"SubRun", &
fSubRun,
"SubRun/I");
455 fReconstructionNtuple->Branch(
"Run", &
fRun,
"Run/I");
456 fReconstructionNtuple->Branch(
"TrackID", &
fRecoTrackID,
"TrackID/I");
457 fReconstructionNtuple->Branch(
"PDG", &
fRecoPDG,
"PDG/I");
458 fReconstructionNtuple->Branch(
"NdEdx", &
fRecoNdEdxBins,
"NdEdx/I");
484 fEvent =
event.id().event();
516 <<
" No simb::MCParticle objects in this event - " 517 <<
" Line " << __LINE__ <<
" in file " << __FILE__ << std::endl;
535 auto simChannelHandle =
547 std::map<int, const simb::MCParticle*> particleMap;
579 for (
auto const& particle : (*particleHandle)) {
599 const size_t numberTrajectoryPoints = particle.NumberTrajectoryPoints();
603 const int last = numberTrajectoryPoints - 1;
604 const TLorentzVector& positionStart = particle.Position(0);
605 const TLorentzVector& positionEnd = particle.Position(last);
606 const TLorentzVector& momentumStart = particle.Momentum(0);
607 const TLorentzVector& momentumEnd = particle.Momentum(last);
618 momentumEnd.GetXYZT(
fEndPE);
622 const double trackLength = (positionEnd - positionStart).Rho();
628 MF_LOG_DEBUG(
"AnalysisExample") <<
"Track length: " << trackLength <<
" cm";
635 <<
" cm long, momentum " << momentumStart.P() <<
" GeV/c, has " << numberTrajectoryPoints
636 <<
" trajectory points";
645 for (
auto const& channel : (*simChannelHandle)) {
650 auto const channelNumber = channel.Channel();
664 auto const& timeSlices = channel.TDCIDEMap();
667 for (
auto const& timeSlice : timeSlices) {
671 auto const& energyDeposits = timeSlice.second;
680 for (
auto const& energyDeposit : energyDeposits) {
683 if (energyDeposit.trackID !=
fSimTrackID)
continue;
685 TVector3 location(energyDeposit.x, energyDeposit.y, energyDeposit.z);
688 const double distance = (location - positionStart.Vect()).Mag();
691 const unsigned int bin = (
unsigned int)(distance /
fBinSize);
752 std::map<int, std::vector<double>> dEdxMap;
754 auto const clock_data =
758 for (
auto const&
hit : (*hitHandle)) {
760 auto hitChannelNumber =
hit.Channel();
766 MF_LOG_DEBUG(
"AnalysisExample") <<
"Hit in collection plane" << std::endl;
782 TDC_t start_tdc = clock_data.TPCTick2TDC(
hit.StartTick());
783 TDC_t end_tdc = clock_data.TPCTick2TDC(
hit.EndTick());
784 TDC_t hitStart_tdc = clock_data.TPCTick2TDC(
hit.PeakTime() - 3. *
hit.SigmaPeakTime());
785 TDC_t hitEnd_tdc = clock_data.TPCTick2TDC(
hit.PeakTime() + 3. *
hit.SigmaPeakTime());
787 start_tdc = std::max(start_tdc, hitStart_tdc);
788 end_tdc = std::min(end_tdc, hitEnd_tdc);
795 for (
auto const& channel : (*simChannelHandle)) {
796 auto simChannelNumber = channel.Channel();
797 if (simChannelNumber != hitChannelNumber)
continue;
800 <<
"SimChannel number = " << simChannelNumber << std::endl;
803 auto const& timeSlices = channel.TDCIDEMap();
823 startTime.first = start_tdc;
824 endTime.first = end_tdc;
829 auto const startPointer =
830 std::lower_bound(timeSlices.begin(), timeSlices.end(), startTime, TDCIDETimeCompare);
833 auto const endPointer =
834 std::upper_bound(startPointer, timeSlices.end(), endTime, TDCIDETimeCompare);
837 if (startPointer == timeSlices.end() || startPointer == endPointer)
continue;
839 <<
"Time slice start = " << (*startPointer).first << std::endl;
843 for (
auto slicePointer = startPointer; slicePointer != endPointer; slicePointer++) {
844 auto const timeSlice = *slicePointer;
845 auto time = timeSlice.first;
859 <<
"Hit index = " <<
hit.LocalIndex() <<
" channel number = " << hitChannelNumber
860 <<
" start TDC tick = " <<
hit.StartTick() <<
" end TDC tick = " <<
hit.EndTick()
861 <<
" peak TDC tick = " <<
hit.PeakTime()
862 <<
" sigma peak time = " <<
hit.SigmaPeakTime()
863 <<
" adjusted start TDC tick = " << clock_data.TPCTick2TDC(
hit.StartTick())
864 <<
" adjusted end TDC tick = " << clock_data.TPCTick2TDC(
hit.EndTick())
865 <<
" adjusted peak TDC tick = " << clock_data.TPCTick2TDC(
hit.PeakTime())
866 <<
" adjusted start_tdc = " << start_tdc <<
" adjusted end_tdc = " << end_tdc
867 <<
" time = " << time << std::endl;
870 auto const& energyDeposits = timeSlice.second;
871 for (
auto const& energyDeposit : energyDeposits) {
887 auto search = particleMap.find(energyDeposit.trackID);
895 if (search == particleMap.end())
continue;
898 int trackID = (*search).first;
906 const TLorentzVector& positionStart = particle.
Position(0);
907 TVector3 location(energyDeposit.x, energyDeposit.y, energyDeposit.z);
908 double distance = (location - positionStart.Vect()).Mag();
928 auto& track_dEdX = dEdxMap[trackID];
929 if (track_dEdX.size() < bin + 1) {
932 track_dEdX.resize(bin + 1, 0);
945 for (
const auto& dEdxEntry : dEdxMap) {
955 const std::vector<double>&
dEdx = dEdxEntry.second;
1030 if (!findManyTruth.isValid()) {
1032 <<
"findManyTruth simb::MCTruth for simb::MCParticle failed!";
1042 size_t particle_index = 0;
1054 auto const& truth = findManyTruth.at(particle_index);
1057 if (truth.empty()) {
1059 <<
"Particle ID=" << particleHandle->at(particle_index).TrackId() <<
" has no primary!";
1070 <<
"Particle ID=" << particleHandle->at(particle_index).TrackId()
1071 <<
" primary PDG code=" << truth[0]->GetParticle(0).PdgCode();
1097 if (!findManyHits.isValid()) {
1098 mf::LogError(
"AnalysisExample") <<
"findManyHits recob::Hit for recob::Cluster failed;" 1107 for (
size_t cluster_index = 0; cluster_index != clusterHandle->size(); cluster_index++) {
1111 auto const&
hits = findManyHits.at(cluster_index);
1117 mf::LogInfo(
"AnalysisExample") <<
"Cluster ID=" << clusterHandle->at(cluster_index).ID()
1118 <<
" has " <<
hits.size() <<
" hits";
1140 return std::sqrt(cet::sum_of_squares(length, width, height));
1147 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.
Length_t DetHalfWidth(TPCID const &tpcid=tpc_zero) const
Returns the half width of the active volume of the specified TPC.
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
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
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
EDAnalyzer(fhicl::ParameterSet const &pset)
std::string Process() const
Length_t DetLength(TPCID const &tpcid=tpc_zero) const
Returns the length of the active volume of the specified TPC.
art::InputTag fSimulationProducerLabel
int fRecoNdEdxBins
Number of dE/dx bins in a given track.
Access the description of detector geometry.
#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
art::InputTag fClusterProducerLabel
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.
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
SigType_t SignalType(PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
TH1D * fMomentumHist
momentum [GeV] of all selected particles
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
LArSoft-specific namespace.
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
virtual void beginJob() override
Length_t DetHalfHeight(TPCID const &tpcid=tpc_zero) const
Returns the half height of the active volume of the specified TPC.
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.