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.