All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LArSimChannelAna_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // \file LArSimChannelAna_module.cc
4 //
5 // \author dmckee@phys.ksu.edu
6 //
7 // \brief Build some histograms based on the som::SimChannels created
8 // \brief by LArVoxelReadout
9 ////////////////////////////////////////////////////////////////////////
10 // C++ std library includes
11 #include <string>
12 
13 // Framework includes
14 #include "art/Framework/Core/EDAnalyzer.h"
15 #include "art/Framework/Core/ModuleMacros.h"
16 #include "art/Framework/Principal/Event.h"
17 #include "art/Framework/Principal/Handle.h"
18 #include "art/Framework/Services/Registry/ServiceHandle.h"
19 #include "art_root_io/TFileService.h"
20 #include "fhiclcpp/ParameterSet.h"
21 
22 // Root Includes
23 #include "TH1.h"
24 
25 // LArSoft includes
30 
31 ///Detector simulation of raw signals on wires
32 namespace larg {
33 
34  /// Base class for creation of raw signals on wires.
35  class LArSimChannelAna : public art::EDAnalyzer {
36  public:
37  explicit LArSimChannelAna(fhicl::ParameterSet const& pset);
38 
39  private:
40  void analyze(const art::Event& evt) override;
41 
42  // initialize the histograms
43  //
44  // Can't be done in Begin job because I want to use LArProperties
45  // which used the database, so I test and run on each
46  // event. Wasteful and silly, but at least it *works*.
47  void ensureHists(unsigned int const nTimeSamples);
48 
49  std::string fLArG4ModuleLabel;
50 
51  // Flag for initialization done, because we set up histograms the
52  // first time through beginRun() so that we can use the
53  // database...
54  bool initDone;
55 
56  TH1D* fChargeXpos; ///< position of the MC Truth charge deposition
57  TH1D* fChargeYpos; ///< position of the MC Truth charge deposition
58  TH1D* fChargeZpos; ///< position of the MC Truth charge deposition
59 
60  TH1D* fTDC; ///< Which TDCs have activity
61 
62  TH1D* fTDCsPerChannel; ///< Number of TDCs with activity
64 
65  TH1D* fElectrons; ///< Electrons in the whole channel entry
66  TH1D* fEnergy; ///< Energy in the whole channel entry
67 
70 
73 
74  }; // class LArSimChannelAna
75 
76  //-------------------------------------------------
77  LArSimChannelAna::LArSimChannelAna(fhicl::ParameterSet const& pset)
78  : EDAnalyzer(pset)
79  , fLArG4ModuleLabel{pset.get<std::string>("LArGeantModuleLabel")}
80  , initDone(false)
81  , fChargeXpos()
82  , fChargeYpos()
83  , fChargeZpos()
84  , fTDC()
85  , fTDCsPerChannel()
86  , fIDEsPerChannel()
87  , fElectrons()
88  , fEnergy()
90  , fEnergyPerTDC()
92  , fEnergyPerIDE()
93  {}
94 
95  //-------------------------------------------------
96  void
97  LArSimChannelAna::ensureHists(unsigned int const nTimeSamples)
98  {
99  if (initDone) return; // Bail if we've already done this.
100  initDone = true; // Insure that we bail later on
101 
102  // get access to the TFile service
103  art::ServiceHandle<art::TFileService const> tfs;
104  // geometry data.
105  art::ServiceHandle<geo::Geometry const> geom;
106 
107  // assumes all TPCs are the same
108  double width = 2 * geom->TPC(0).HalfWidth();
109  double halfHeight = geom->TPC(0).HalfHeight();
110  double length = geom->TPC(0).Length();
111 
112  // Assumes microboone dimensions. Ideally we'd fix this later...
113  fChargeXpos =
114  tfs->make<TH1D>("hChargeXpos", "X charge depositions;X (cm);Events", 101, 0.0, width);
115  fChargeYpos = tfs->make<TH1D>(
116  "hChargeYpos", "Y charge depositions;Y (cm);Events", 101, -halfHeight, halfHeight);
117  fChargeZpos =
118  tfs->make<TH1D>("hChargeZpos", "Z charge depositions;Z (cm);Events", 101, 0.0, length);
119  fTDC = tfs->make<TH1D>("hTDC", "Active TDC;TDCs;Events;", nTimeSamples, 0, nTimeSamples);
120  fTDCsPerChannel = tfs->make<TH1D>(
121  "hTDCsPerChannel", "TDCs per channel entry;# TDCs;Events", 128, 0, nTimeSamples);
123  tfs->make<TH1D>("hIDEsPerChannel", "IDE per channel entry;# IDEs;Events", 100, 0, 20000);
124  fElectrons =
125  tfs->make<TH1D>("hElectrons", "Electrons per channel;Electrons;Events", 100, 0, 2e7);
126  fEnergy = tfs->make<TH1D>("hEnergy", "Energy per channel;energy;Events", 100, 0, 2500);
128  tfs->make<TH1D>("hElectronsPerIDE", "Electrons per IDE;Electrons;Events", 100, 0, 10000);
129  fEnergyPerIDE = tfs->make<TH1D>("hEnergyPerIDE", "Energy per IDE;energy;Events", 100, 0, 50);
131  tfs->make<TH1D>("hElectronsPerTDC", "Electrons per TDC;Electrons;Events", 100, 0, 10000);
132  fEnergyPerTDC = tfs->make<TH1D>("hEnergyPerTDC", "Energy per YDC;energy;Events", 100, 0, 50);
133  }
134 
135  //-------------------------------------------------
136  void
137  LArSimChannelAna::analyze(const art::Event& evt)
138  {
139  if (evt.isRealData()) {
140  throw cet::exception("LArSimChannelAna") << "Not for use on Data yet...\n";
141  }
142 
143  auto const detProp =
144  art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt);
145  ensureHists(detProp.NumberTimeSamples());
146 
147  art::ServiceHandle<geo::Geometry const> geom;
148 
149  auto const& scVec = *evt.getValidHandle<std::vector<sim::SimChannel>>(fLArG4ModuleLabel);
150 
151  //++++++++++
152  // Loop over the Chnnels and fill histograms
153  //++++++++++
154  unsigned int totalIDEs = 0;
155  double totalElectrons = 0;
156  double totalEnergy = 0;
157  for (const auto& sc : scVec) {
158  const auto& tdcidemap = sc.TDCIDEMap();
159  fTDCsPerChannel->Fill(tdcidemap.size());
160 
161  for (auto const& [tdc, ideVec] : tdcidemap) {
162  totalIDEs += ideVec.size();
163  double tdcElectrons = 0;
164  double tdcEnergy = 0;
165 
166  fTDC->Fill(tdc);
167 
168  for (const auto& ide : ideVec) {
169  totalElectrons += ide.numElectrons;
170  totalEnergy += ide.energy;
171  tdcElectrons += ide.numElectrons;
172  tdcEnergy += ide.energy;
173 
174  fChargeXpos->Fill(ide.x);
175  fChargeYpos->Fill(ide.y);
176  fChargeZpos->Fill(ide.z);
177  fElectronsPerIDE->Fill(ide.numElectrons);
178  fEnergyPerIDE->Fill(ide.energy);
179  }
180  fElectronsPerTDC->Fill(tdcElectrons);
181  fEnergyPerTDC->Fill(tdcEnergy);
182  }
183  }
184  fIDEsPerChannel->Fill(totalIDEs);
185  fElectrons->Fill(totalElectrons);
186  fEnergy->Fill(totalEnergy);
187  } //end analyze method
188 
189  DEFINE_ART_MODULE(LArSimChannelAna)
190 
191 } // end of hit namespace
TH1D * fTDCsPerChannel
Number of TDCs with activity.
TH1D * fElectrons
Electrons in the whole channel entry.
TH1D * fChargeXpos
position of the MC Truth charge deposition
void ensureHists(unsigned int const nTimeSamples)
LArSimChannelAna(fhicl::ParameterSet const &pset)
void analyze(const art::Event &evt) override
TH1D * fChargeYpos
position of the MC Truth charge deposition
Base class for creation of raw signals on wires.
TH1D * fEnergy
Energy in the whole channel entry.
TH1D * fChargeZpos
position of the MC Truth charge deposition
object containing MC truth information necessary for making RawDigits and doing back tracking ...
art::ServiceHandle< art::TFileService > tfs
TCEvent evt
Definition: DataStructs.cxx:8
TH1D * fTDC
Which TDCs have activity.
art framework interface to geometry description
auto const detProp
Encapsulate the construction of a single detector plane.