All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SimTestPulseWire_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: SimTestPulseWire
3 // Module Type: producer
4 // File: SimTestPulseWire_module.cc
5 //
6 // Imported to ICARUS on October 21, 2018
7 //
8 // Generated at Sat Feb 11 04:35:44 2017 by Kazuhiro Terao using artmod
9 // from cetpkgsupport v1_11_00.
10 ////////////////////////////////////////////////////////////////////////
11 
12 #include "art/Framework/Core/EDProducer.h"
13 #include "art/Framework/Core/ModuleMacros.h"
14 #include "art/Framework/Principal/Event.h"
15 #include "art/Framework/Principal/Handle.h"
16 #include "art/Framework/Principal/Run.h"
17 #include "art/Framework/Principal/SubRun.h"
18 #include "art_root_io/TFileService.h"
19 
23 #include "fhiclcpp/ParameterSet.h"
25 #include <memory>
26 
31 
32 #include "ParamHolder.h"
33 
34 #include <TTree.h>
35 #include <TFile.h>
36 
37 class SimTestPulseWire;
38 
39 class SimTestPulseWire : public art::EDProducer
40 {
41 public:
42  explicit SimTestPulseWire(fhicl::ParameterSet const & p);
43  // The destructor generated by the compiler is fine for classes
44  // without bare pointers or other resource use.
45 
46  // Plugins should not be copied or assigned.
47  SimTestPulseWire(SimTestPulseWire const &) = delete;
49 
50  SimTestPulseWire & operator = (SimTestPulseWire const &) = delete;
52 
53  // Required functions.
54  void produce(art::Event & e) override;
55  void beginRun(art::Run& run) override;
56 
57  void beginJob() override;
58  void endJob() override;
59 
60 private:
61 
62  bool fVerbose; ///< verbosity
63 
64  using WireVec = std::vector<int>;
65  using WireVecVec = std::vector<WireVec>;
66 
67  using Position = std::vector<double>;
68  using PositionVec = std::vector<Position>;
69  using PositionVecVec = std::vector<PositionVec>;
70 
71  //
72  // Parameters to be configured
73  //
74  double fTriggerTime; ///< Trigger timing in electronics clock [us]
75  unsigned int fCryostat; ///< Cryostat to consider
76  unsigned int fTPC; ///< TPC in that cryostat (0-3 for split wire)
77  std::vector<double> fSimTime_v; ///< Charge timing in electronics clock [us]
78  WireVecVec fWiresByPlaneVec; ///< For each plane the wires to deposit charge on
79  std::vector<double> fNumElectrons_v; ///< Charge amount in electron count
80 
81  //
82  // Parameters to be calculated
83  //
84  WireVec fTick_v; ///< Corresponding tick
85  WireVecVec fPlaneChannelVec; ///< Keep track of wires for each plane
86 
87  PositionVecVec fPlanePositionVecVec; ///< Keep track of positions for each wire on each plane
88 
90 
91  TTree* fTupleTree; ///< output analysis tree
92 };
93 
94 SimTestPulseWire::SimTestPulseWire(fhicl::ParameterSet const & p)
95  : EDProducer{p}
96 // Initialize member data here.
97 {
98  produces< std::vector<sim::SimChannel> >();
99  produces< std::vector<sim::SimEnergyDeposit> >();
100  produces< std::vector<raw::Trigger> >();
101  produces< sumdata::RunData, art::InRun >();
102 
103  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService>()->DataForJob();
104  fTriggerTime = clockData.TriggerTime();
105 
106  // Assume 3 planes
107  fWiresByPlaneVec.resize(3);
108  fPlaneChannelVec.resize(3);
109  fPlanePositionVecVec.resize(3);
110 
111 // fTriggerTime = p.get< double> ("TriggerTime_us");
112  fSimTime_v = p.get< std::vector<double> >("SimTimeArray_us");
113  fCryostat = p.get< unsigned int >("Cryostat");
114  fTPC = p.get< unsigned int >("TPC");
115  fWiresByPlaneVec[0] = p.get< WireVec >("Plane0Wires");
116  fWiresByPlaneVec[1] = p.get< WireVec >("Plane1Wires");
117  fWiresByPlaneVec[2] = p.get< WireVec >("Plane2Wires");
118  fNumElectrons_v = p.get< std::vector<double> >("NumElectronsArray");
119  fVerbose = p.get< bool> ("Verbose",false);
120 
121  assert( fSimTime_v.size() == fWiresByPlaneVec[0].size() &&
122  fSimTime_v.size() == fWiresByPlaneVec[1].size() &&
123  fSimTime_v.size() == fWiresByPlaneVec[2].size() &&
124  fSimTime_v.size() == fNumElectrons_v.size() );
125 }
126 
128 {
129  art::ServiceHandle<art::TFileService> tfs;
130 
131  fTupleTree = tfs->make<TTree>("SimTestPulseWire", "Tree by SimTestPulseWire_module");
132  fTupleTree->Branch("run",&_run,"run/I");
133  fTupleTree->Branch("subrun",&_subrun,"subrun/I");
134  fTupleTree->Branch("event",&_event,"event/I");
135  fTupleTree->Branch("trigger_time",&fTriggerTime,"trigger_time/D");
136  fTupleTree->Branch("charge_time_v","std::vector<double>",&fSimTime_v);
137  fTupleTree->Branch("tick_v","std::vector<int>",&fTick_v);
138 // fTupleTree->Branch("y_v","std::vector<double>",&fY_v);
139 // fTupleTree->Branch("z_v","std::vector<double>",&fZ_v);
140  fTupleTree->Branch("e_v","std::vector<double>",&fNumElectrons_v);
141 
142  fTupleTree->Branch("ch_plane0","std::vector<int>",&fPlaneChannelVec[0]);
143  fTupleTree->Branch("ch_plane1","std::vector<int>",&fPlaneChannelVec[1]);
144  fTupleTree->Branch("ch_plane2","std::vector<int>",&fPlaneChannelVec[2]);
145 
146  fTupleTree->Branch("wire_plane0","std::vector<int>",&fWiresByPlaneVec[0]);
147  fTupleTree->Branch("wire_plane1","std::vector<int>",&fWiresByPlaneVec[1]);
148  fTupleTree->Branch("wire_plane2","std::vector<int>",&fWiresByPlaneVec[2]);
149 }
150 
152 {
154 }
155 
156 void SimTestPulseWire::beginRun(art::Run& run)
157 {
158  // grab the geometry object to see what geometry we are using
159  art::ServiceHandle<geo::Geometry> geo;
160 
161  std::unique_ptr<sumdata::RunData> runData(new sumdata::RunData(geo->DetectorName()));
162 
163  run.put(std::move(runData));
164 
165  return;
166 }
167 
168 void SimTestPulseWire::produce(art::Event & e)
169 {
170  std::unique_ptr<std::vector<raw::Trigger> > trigger_v(new std::vector<raw::Trigger> );
171  trigger_v->push_back(raw::Trigger(0,fTriggerTime,fTriggerTime,1));
172 
173  std::unique_ptr<std::vector<sim::SimChannel> > simch_v(new std::vector<sim::SimChannel> );
174 
175  std::unique_ptr<std::vector<sim::SimEnergyDeposit>> simDep_v(new std::vector<sim::SimEnergyDeposit>);
176 
177  geo::Point_t chargeDepCoords = {0., 0., 0.};
178 
179  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService>()->DataFor(e);
180  art::ServiceHandle<geo::Geometry> geo;
181 
182  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob(clockData);
183 
184  for(size_t idx = 0; idx < fPlaneChannelVec.size(); idx++)
185  {
186  fPlaneChannelVec[idx].clear();
187  fPlanePositionVecVec[idx].clear();
188  }
189 
190  fTick_v.clear();
191 
192  auto& pholder = alternative::ParamHolder::get();
193  pholder.Clear();
194 
195  for(size_t index=0; index < fSimTime_v.size(); ++index) {
196 
197  int tdc = fSimTime_v[index] / clockData.TPCClock().TickPeriod();
198  fTick_v.push_back(clockData.TPCTDC2Tick(tdc));
199 
200  if(fVerbose)
201  std::cout << "[BUFFOON!] Charge injection id " << index << " @ TDC=" << tdc
202 // << " @ Y=" << fY_v[index] << " @ Z=" << fZ_v[index]
203  << " with " << fNumElectrons_v[index] << " electrons " << std::endl;
204 
205  if(tdc<0) {
206  std::cerr << "\033[93m[WARNING BUFFOON!]\033[00m ignoring fSimTime " << fSimTime_v[index]
207  << " as it results in negative TDC (invalid)" << std::endl;
208  continue;
209  }
210 
211  const geo::PlaneGeo& planeGeo = geo->Plane(geo::PlaneID(fCryostat,fTPC,0)); // Get the coordinates of the first wire plane
212 
213  TVector3 planeCoords = planeGeo.GetCenter();
214  TVector3 planeNormal = planeGeo.GetNormalDirection();
215 
216  // Assume C=0, T=1
217  chargeDepCoords = geo::Point_t(planeCoords[0] + 1. * planeNormal[0],planeCoords[1],planeCoords[2]);
218 
219  alternative::TruthHit pulse_record;
220  pulse_record.tdc = tdc;
221  pulse_record.num_electrons = fNumElectrons_v[index];
222  pulse_record.tick = clockData.TPCTDC2Tick(tdc);
223 
224  double nElecADC = detProp.ElectronsToADC() * fNumElectrons_v[index];
225 
226  std::cout << "==> x position of plane 0: " << planeCoords[0] << ", normal: " << planeNormal[0] << ", nElec: " << fNumElectrons_v[index] << ", nElecADC: " << nElecADC << std::endl;
227 
228  simDep_v->emplace_back(0,fNumElectrons_v[index],0.,nElecADC,chargeDepCoords,chargeDepCoords);
229 
230  for(size_t plane=0; plane<3; ++plane)
231  {
232  int wire = fWiresByPlaneVec[plane][index];
233 
234  geo::WireID wireID(fCryostat,fTPC,plane,wire);
235 
236  raw::ChannelID_t channel = geo->PlaneWireToChannel(wireID);
237 
238  fPlaneChannelVec[plane].emplace_back(channel);
239 
240  // Let's go backwards...
241  std::vector<geo::WireID> wireIDVec = geo->ChannelToWire(channel);
242 
243  std::cout << ">>Channel " << channel << ", C/T/P/W: " << wireID.Cryostat << "/" << wireID.TPC << "/" << wireID.Plane << "/" << wireID.Wire
244  << " returns " << wireIDVec.size() << " IDs, C/T/P/W: " << wireIDVec.front().Cryostat << "/" << wireIDVec.front().TPC << "/" << wireIDVec.front().Plane << "/" << wireIDVec.front().Wire << std::endl;
245 
246  // Recover the positions
247  const geo::WireGeo& wireGeo = geo->Wire(wireID);
248 
249  double xyz[3];
250 
251  wireGeo.GetCenter(xyz);
252 
253  xyz[0] = chargeDepCoords.X();
254 
255  Position position = {xyz[0],xyz[1],xyz[2]};
256 
257  fPlanePositionVecVec[plane].emplace_back(position);
258 
259  if(fVerbose) std::cout << "[BUFFOON!] plane " << plane << " channel " << channel << " ... wire " << wire << std::endl;
260 
261  pulse_record.channel_list[plane] = channel;
262 
263  sim::SimChannel sch(channel);
264 
265  sch.AddIonizationElectrons(1, /// track id, keep 0 = invalid
266  (unsigned int)tdc,
267  fNumElectrons_v[index],
268  xyz,
269  100.); /// energy, keep -1 = invalid
270  simch_v->emplace_back(std::move(sch));
271  }
272 
273  pholder.Register(std::move(pulse_record));
274  }
275 
276  _run = e.id().run();
277  _subrun = e.id().subRun();
278  _event = e.id().event();
279 
280  fTupleTree->Fill();
281  e.put(std::move(simch_v));
282  e.put(std::move(simDep_v));
283  e.put(std::move(trigger_v));
284 
285  return;
286 }
287 
288 DEFINE_ART_MODULE(SimTestPulseWire)
WireVecVec fWiresByPlaneVec
For each plane the wires to deposit charge on.
std::vector< PositionVec > PositionVecVec
Geometry description of a TPC wireThe wire is a single straight segment on a wire plane...
Definition: WireGeo.h:65
unsigned int tick
Definition: ParamHolder.h:13
static ParamHolder & get()
Definition: ParamHolder.h:23
Energy deposited on a readout channel by simulated tracks.
Definition: SimChannel.h:145
BEGIN_PROLOG could also be cerr
unsigned int fTPC
TPC in that cryostat (0-3 for split wire)
unsigned int tdc
Definition: ParamHolder.h:12
pdgs p
Definition: selectors.fcl:22
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:212
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:580
Vector GetNormalDirection() const
Returns the direction normal to the plane.
Definition: PlaneGeo.h:442
WireVec fTick_v
Corresponding tick.
Access the description of detector geometry.
std::vector< WireVec > WireVecVec
void produce(art::Event &e) override
std::vector< int > WireVec
PositionVecVec fPlanePositionVecVec
Keep track of positions for each wire on each plane.
SimTestPulseWire & operator=(SimTestPulseWire const &)=delete
SimTestPulseWire(fhicl::ParameterSet const &p)
Point GetCenter() const
Returns the centre of the wire plane in world coordinates [cm].
Definition: PlaneGeo.h:479
Geometry information for a single wire plane.The plane is represented in the geometry by a solid whic...
Definition: PlaneGeo.h:82
std::vector< Position > PositionVec
WireVecVec fPlaneChannelVec
Keep track of wires for each plane.
void beginRun(art::Run &run) override
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:493
std::array< int, 3 > channel_list
Definition: ParamHolder.h:11
std::vector< double > Position
unsigned int fCryostat
Cryostat to consider.
static void destroy()
Definition: ParamHolder.h:28
contains information for a single step in the detector simulation
object containing MC truth information necessary for making RawDigits and doing back tracking ...
do i e
art::ServiceHandle< art::TFileService > tfs
double fTriggerTime
Trigger timing in electronics clock [us].
void AddIonizationElectrons(TrackID_t trackID, TDC_t tdc, double numberElectrons, double const *xyz, double energy, TrackID_t origTrackID=util::kBogusI)
Add ionization electrons and energy to this channel.
Definition: SimChannel.cxx:55
void GetCenter(double *xyz, double localz=0.0) const
Fills the world coordinate of a point on the wire.
Definition: WireGeo.cxx:73
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
TTree * fTupleTree
output analysis tree
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:184
art framework interface to geometry description
BEGIN_PROLOG could also be cout
auto const detProp
std::vector< double > fNumElectrons_v
Charge amount in electron count.
std::vector< double > fSimTime_v
Charge timing in electronics clock [us].