71 #include "art_root_io/TFileService.h" 72 #include "canvas/Persistency/Common/FindManyP.h" 85 #include "TLorentzVector.h" 204 Name(
"SimulationLabel"),
205 Comment(
"tag of the input data product with the detector simulation " 210 Comment(
"tag of the input data product with reconstructed hits")};
213 Name(
"ClusterLabel"),
214 Comment(
"tag of the input data product with reconstructed clusters")};
218 Comment(
"particle type (PDG ID) of the primary particle to be selected")};
221 Comment(
"dx [cm] used for the dE/dx calculation")};
384 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");
486 fEvent =
event.id().event();
518 <<
" No simb::MCParticle objects in this event - " 519 <<
" Line " << __LINE__ <<
" in file " << __FILE__ <<
std::endl;
537 auto simChannelHandle =
549 std::map<int, const simb::MCParticle*> particleMap;
581 for (
auto const& particle : (*particleHandle)) {
601 const size_t numberTrajectoryPoints = particle.NumberTrajectoryPoints();
605 const int last = numberTrajectoryPoints - 1;
606 const TLorentzVector& positionStart = particle.Position(0);
607 const TLorentzVector& positionEnd = particle.Position(last);
608 const TLorentzVector& momentumStart = particle.Momentum(0);
609 const TLorentzVector& momentumEnd = particle.Momentum(last);
620 momentumEnd.GetXYZT(
fEndPE);
624 const double trackLength = (positionEnd - positionStart).
Rho();
630 MF_LOG_DEBUG(
"AnalysisExample") <<
"Track length: " << trackLength <<
" cm";
637 <<
" cm long, momentum " << momentumStart.P() <<
" GeV/c, has " << numberTrajectoryPoints
638 <<
" trajectory points";
647 for (
auto const&
channel : (*simChannelHandle)) {
652 auto const channelNumber =
channel.Channel();
666 auto const& timeSlices =
channel.TDCIDEMap();
669 for (
auto const& timeSlice : timeSlices) {
673 auto const& energyDeposits = timeSlice.second;
682 for (
auto const& energyDeposit : energyDeposits) {
685 if (energyDeposit.trackID !=
fSimTrackID)
continue;
687 TVector3 location(energyDeposit.x, energyDeposit.y, energyDeposit.z);
690 const double distance = (location - positionStart.Vect()).Mag();
754 std::map<int, std::vector<double>> dEdxMap;
756 auto const clock_data =
760 for (
auto const&
hit : (*hitHandle)) {
762 auto hitChannelNumber =
hit.Channel();
784 TDC_t start_tdc = clock_data.TPCTick2TDC(
hit.StartTick());
785 TDC_t end_tdc = clock_data.TPCTick2TDC(
hit.EndTick());
786 TDC_t hitStart_tdc = clock_data.TPCTick2TDC(
hit.PeakTime() - 3. *
hit.SigmaPeakTime());
787 TDC_t hitEnd_tdc = clock_data.TPCTick2TDC(
hit.PeakTime() + 3. *
hit.SigmaPeakTime());
789 start_tdc =
std::max(start_tdc, hitStart_tdc);
790 end_tdc =
std::min(end_tdc, hitEnd_tdc);
797 for (
auto const&
channel : (*simChannelHandle)) {
798 auto simChannelNumber =
channel.Channel();
799 if (simChannelNumber != hitChannelNumber)
continue;
802 <<
"SimChannel number = " << simChannelNumber <<
std::endl;
805 auto const& timeSlices =
channel.TDCIDEMap();
825 startTime.first = start_tdc;
826 endTime.first = end_tdc;
831 auto const startPointer =
832 std::lower_bound(timeSlices.begin(), timeSlices.end(), startTime, TDCIDETimeCompare);
835 auto const endPointer =
836 std::upper_bound(startPointer, timeSlices.end(), endTime, TDCIDETimeCompare);
839 if (startPointer == timeSlices.end() || startPointer == endPointer)
continue;
841 <<
"Time slice start = " << (*startPointer).first <<
std::endl;
845 for (
auto slicePointer = startPointer; slicePointer != endPointer; slicePointer++) {
846 auto const timeSlice = *slicePointer;
847 auto time = timeSlice.first;
861 <<
"Hit index = " <<
hit.LocalIndex() <<
" channel number = " << hitChannelNumber
862 <<
" start TDC tick = " <<
hit.StartTick() <<
" end TDC tick = " <<
hit.EndTick()
863 <<
" peak TDC tick = " <<
hit.PeakTime()
864 <<
" sigma peak time = " <<
hit.SigmaPeakTime()
865 <<
" adjusted start TDC tick = " << clock_data.TPCTick2TDC(
hit.StartTick())
866 <<
" adjusted end TDC tick = " << clock_data.TPCTick2TDC(
hit.EndTick())
867 <<
" adjusted peak TDC tick = " << clock_data.TPCTick2TDC(
hit.PeakTime())
868 <<
" adjusted start_tdc = " << start_tdc <<
" adjusted end_tdc = " << end_tdc
869 <<
" time = " <<
time << std::endl;
872 auto const& energyDeposits = timeSlice.second;
873 for (
auto const& energyDeposit : energyDeposits) {
889 auto search = particleMap.find(energyDeposit.trackID);
897 if (
search == particleMap.end())
continue;
900 int trackID = (*search).first;
908 const TLorentzVector& positionStart = particle.
Position(0);
909 TVector3 location(energyDeposit.x, energyDeposit.y, energyDeposit.z);
910 double distance = (location - positionStart.Vect()).Mag();
930 auto& track_dEdX = dEdxMap[trackID];
931 if (track_dEdX.size() < bin + 1) {
934 track_dEdX.resize(bin + 1, 0);
947 for (
const auto& dEdxEntry : dEdxMap) {
957 const std::vector<double>&
dEdx = dEdxEntry.second;
1015 const art::FindManyP<simb::MCTruth> findManyTruth(
1032 if (!findManyTruth.isValid()) {
1034 <<
"findManyTruth simb::MCTruth for simb::MCParticle failed!";
1044 size_t particle_index = 0;
1056 auto const& truth = findManyTruth.at(particle_index);
1059 if (truth.empty()) {
1061 <<
"Particle ID=" << particleHandle->at(particle_index).TrackId() <<
" has no primary!";
1072 <<
"Particle ID=" << particleHandle->at(particle_index).TrackId()
1073 <<
" primary PDG code=" << truth[0]->GetParticle(0).PdgCode();
1099 if (!findManyHits.isValid()) {
1100 mf::LogError(
"AnalysisExample") <<
"findManyHits recob::Hit for recob::Cluster failed;" 1109 for (
size_t cluster_index = 0; cluster_index != clusterHandle->size(); cluster_index++) {
1113 auto const& hits = findManyHits.at(cluster_index);
1119 mf::LogInfo(
"AnalysisExample") <<
"Cluster ID=" << clusterHandle->at(cluster_index).ID()
1120 <<
" has " << hits.size() <<
" hits";
1151 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
constexpr T sum_of_squares(T x, T y)
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
double fStartPE[4]
(Px,Py,Pz,E) at the true start of the particle
ChannelGroupService::Name Name
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
EDAnalyzer(fhicl::ParameterSet const &pset)
std::string Process() const
art::InputTag fSimulationProducerLabel
art framework interface to geometry description
int fRecoNdEdxBins
Number of dE/dx bins in a given track.
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
double dEdx(float dqdx, float Efield)
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
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
art::InputTag fClusterProducerLabel
static int max(int a, int b)
Description of geometry of one entire detector.
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
int fSimPDG
PDG ID of the particle being processed.
int fRun
number of the run being processed
Declaration of signal hit object.
TH1D * fMomentumHist
momentum [GeV] of all selected particles
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
LArSoft-specific namespace.
int fEvent
number of the event being processed
QTextStream & bin(QTextStream &s)
int trigger_offset(DetectorClocksData const &data)
double fEndPE[4]
(Px,Py,Pz,E) at the true end of the particle
virtual void beginJob() override
Access the description of detector geometry.
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
cet::coded_exception< error, detail::translate > exception
TH1D * fTrackLengthHist
true length [cm] of all selected particles
QTextStream & endl(QTextStream &s)
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.