All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SimTestPulse_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: SimTestPulse
3 // Module Type: producer
4 // File: SimTestPulse_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 
22 #include "fhiclcpp/ParameterSet.h"
24 #include <memory>
25 
31 
32 #include "ParamHolder.h"
33 
34 #include <TTree.h>
35 #include <TFile.h>
36 
37 class SimTestPulse;
38 
39 class SimTestPulse : public art::EDProducer
40 {
41 public:
42  explicit SimTestPulse(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  SimTestPulse(SimTestPulse const &) = delete;
48  SimTestPulse(SimTestPulse &&) = delete;
49 
50  SimTestPulse & operator = (SimTestPulse const &) = delete;
51  SimTestPulse & operator = (SimTestPulse &&) = 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  //
65  // Parameters to be configured
66  //
67  double fTriggerTime; ///< Trigger timing in electronics clock [us]
68  std::vector<double> fSimTime_v; ///< Charge timing in electronics clock [us]
69  std::vector<double> fY_v; ///< Charge Y position in detector coordinate [cm]
70  std::vector<double> fZ_v; ///< Charge Z position in detector coordinate [cm]
71  std::vector<double> fNumElectrons_v; ///< Charge amount in electron count
72 
73  //
74  // Parameters to be calculated
75  //
76  std::vector<int> fTick_v; ///< Corresponding tick
77  std::vector<int> fPlane0Channel_v; ///< Resulting plane 0 channel number where charge is deposited
78  std::vector<int> fPlane1Channel_v; ///< Resulting plane 1 channel number where charge is deposited
79  std::vector<int> fPlane2Channel_v; ///< Resulting plane 2 channel number where charge is deposited
80 
81  std::vector<int> fPlane0Wire_v; ///< Resulting plane 0 wire number where charge is deposited
82  std::vector<int> fPlane1Wire_v; ///< Resulting plane 1 wire number where charge is deposited
83  std::vector<int> fPlane2Wire_v; ///< Resulting plane 2 wire number where charge is deposited
84 
86 
87  TTree* fTupleTree; ///< output analysis tree
88 };
89 
90 SimTestPulse::SimTestPulse(fhicl::ParameterSet const & p)
91  : EDProducer{p}
92 // Initialize member data here.
93 {
94  produces< std::vector<sim::SimChannel> >();
95  produces< std::vector<sim::SimEnergyDeposit> >();
96  produces< std::vector<raw::Trigger> >();
97  produces< sumdata::RunData, art::InRun >();
98 
99  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
100  fTriggerTime = clockData.TriggerTime();
101 
102 // fTriggerTime = p.get< double> ("TriggerTime_us");
103  fSimTime_v = p.get< std::vector<double> >("SimTimeArray_us");
104  fY_v = p.get< std::vector<double> >("YArray_cm");
105  fZ_v = p.get< std::vector<double> >("ZArray_cm");
106  fNumElectrons_v = p.get< std::vector<double> >("NumElectronsArray");
107  fVerbose = p.get< bool> ("Verbose",false);
108 
109  assert( fSimTime_v.size() == fY_v.size() &&
110  fSimTime_v.size() == fZ_v.size() &&
111  fSimTime_v.size() == fNumElectrons_v.size() );
112 }
113 
115 {
116  art::ServiceHandle<art::TFileService> tfs;
117 
118  fTupleTree = tfs->make<TTree>("simTestPulse", "Tree by SimTestPulse_module");
119  fTupleTree->Branch("run",&_run,"run/I");
120  fTupleTree->Branch("subrun",&_subrun,"subrun/I");
121  fTupleTree->Branch("event",&_event,"event/I");
122  fTupleTree->Branch("trigger_time",&fTriggerTime,"trigger_time/D");
123  fTupleTree->Branch("charge_time_v","std::vector<double>",&fSimTime_v);
124  fTupleTree->Branch("tick_v","std::vector<int>",&fTick_v);
125  fTupleTree->Branch("y_v","std::vector<double>",&fY_v);
126  fTupleTree->Branch("z_v","std::vector<double>",&fZ_v);
127  fTupleTree->Branch("e_v","std::vector<double>",&fNumElectrons_v);
128 
129  fTupleTree->Branch("ch_plane0","std::vector<int>",&fPlane0Channel_v);
130  fTupleTree->Branch("ch_plane1","std::vector<int>",&fPlane1Channel_v);
131  fTupleTree->Branch("ch_plane2","std::vector<int>",&fPlane2Channel_v);
132 
133  fTupleTree->Branch("wire_plane0","std::vector<int>",&fPlane0Wire_v);
134  fTupleTree->Branch("wire_plane1","std::vector<int>",&fPlane1Wire_v);
135  fTupleTree->Branch("wire_plane2","std::vector<int>",&fPlane2Wire_v);
136 }
137 
139 {
141 }
142 
143 void SimTestPulse::beginRun(art::Run& run)
144 {
145  // grab the geometry object to see what geometry we are using
146  art::ServiceHandle<geo::Geometry> geo;
147 
148  std::unique_ptr<sumdata::RunData> runData(new sumdata::RunData(geo->DetectorName()));
149 
150  run.put(std::move(runData));
151 
152  return;
153 }
154 
155 void SimTestPulse::produce(art::Event & e)
156 {
157  std::unique_ptr<std::vector<raw::Trigger> > trigger_v(new std::vector<raw::Trigger> );
158  trigger_v->push_back(raw::Trigger(0,fTriggerTime,fTriggerTime,1));
159 
160  std::unique_ptr<std::vector<sim::SimChannel> > simch_v(new std::vector<sim::SimChannel> );
161 
162  std::unique_ptr<std::vector<sim::SimEnergyDeposit>> simDep_v(new std::vector<sim::SimEnergyDeposit>);
163 
164  geo::Point_t chargeDepCoords = {0., 0., 0.};
165 
166  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
167  art::ServiceHandle<geo::Geometry> geo;
168 
169  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob(clockData);
170 
171  fPlane0Channel_v.clear();
172  fPlane1Channel_v.clear();
173  fPlane2Channel_v.clear();
174  fPlane0Wire_v.clear();
175  fPlane1Wire_v.clear();
176  fPlane2Wire_v.clear();
177  fTick_v.clear();
178 
179  auto& pholder = alternative::ParamHolder::get();
180  pholder.Clear();
181 
182  for(size_t index=0; index < fSimTime_v.size(); ++index) {
183 
184  int tdc = fSimTime_v[index] / clockData.TPCClock().TickPeriod();
185  fTick_v.push_back(clockData.TPCTDC2Tick(tdc));
186 
187  if(fVerbose)
188  std::cout << "[BUFFOON!] Charge injection id " << index << " @ TDC=" << tdc
189  << " @ Y=" << fY_v[index] << " @ Z=" << fZ_v[index]
190  << " with " << fNumElectrons_v[index] << " electrons " << std::endl;
191 
192  if(tdc<0) {
193  std::cerr << "\033[93m[WARNING BUFFOON!]\033[00m ignoring fSimTime " << fSimTime_v[index]
194  << " as it results in negative TDC (invalid)" << std::endl;
195  continue;
196  }
197 
198  const geo::PlaneGeo& planeGeo = geo->Plane(geo::PlaneID(0,0,0)); // Get the coordinates of the first wire plane
199 
200  TVector3 planeCoords = planeGeo.GetCenter();
201  TVector3 planeNormal = planeGeo.GetNormalDirection();
202 
203  // Assume C=0, T=1
204  chargeDepCoords = geo::Point_t(planeCoords[0] + 1. * planeNormal[0],fY_v[index],fZ_v[index]);
205 
206  alternative::TruthHit pulse_record;
207  pulse_record.tdc = tdc;
208  pulse_record.num_electrons = fNumElectrons_v[index];
209  pulse_record.tick = clockData.TPCTDC2Tick(tdc);
210 
211  double nElecADC = detProp.ElectronsToADC() * fNumElectrons_v[index];
212  double eDeposit = 23.6 * fNumElectrons_v[index] / 1000.; // This is a guesstimate for now but hopefully not far off, note we assume wirecell will handle recombination
213 
214  std::cout << "==> x position of plane 0: " << planeCoords[0] << ", normal: " << planeNormal[0] << ", nElec: " << fNumElectrons_v[index] << ", nElecADC: " << nElecADC << ", edep: " << eDeposit << std::endl;
215  std::cout << " x position of charge deposit: " << chargeDepCoords.X() << std::endl;
216 
217  simDep_v->emplace_back(0,
218  fNumElectrons_v[index],
219  0.,
220  eDeposit,
221  geo::Point_t(chargeDepCoords.X(),chargeDepCoords.Y()+0.001,chargeDepCoords.Z()+0.001),
222  geo::Point_t(chargeDepCoords.X(),chargeDepCoords.Y()-0.001,chargeDepCoords.Z()-0.001));
223 
224  geo::PlaneID collectionPlaneID(0,0,2);
225 
226  for(size_t plane=0; plane<3; ++plane) {
227  geo::PlaneID planeID(0,0,plane);
228  double xyz[3] = {chargeDepCoords.X(),chargeDepCoords.Y(),chargeDepCoords.Z()};
229 
230  std::cout << "++ Searching for nearest wire id for planeID: " << planeID << ", xyz: " << xyz[0] << "," << xyz[1] << "," << xyz[2] << std::endl;
231  geo::WireID nearestID = geo->NearestWireID(xyz,plane);
232  std::cout << " WireID: " << nearestID << std::endl;
233  std::cout << "** Searching for nearest channel with plane: " << plane << ", xyz: " << xyz[0] << "," << xyz[1] << "," << xyz[2] << std::endl;
234  auto channel = geo->NearestChannel(xyz,plane);
235  std::cout << " Returned with channel: " << channel << std::endl;
236  auto wire = geo->ChannelToWire(channel).front().Wire;
237  std::cout << " which gives wire: " << wire << std::endl;
238  if(fVerbose) std::cout << "[BUFFOON!] plane " << plane << " channel "
239  << channel << " ... wire " << wire << std::endl;
240  pulse_record.channel_list[plane] = channel;
241  switch(plane) {
242  case 0: fPlane0Channel_v.push_back(channel); fPlane0Wire_v.push_back(wire); break;
243  case 1: fPlane1Channel_v.push_back(channel); fPlane1Wire_v.push_back(wire); break;
244  case 2: fPlane2Channel_v.push_back(channel); fPlane2Wire_v.push_back(wire); break;
245  default:
246  std::cerr << "[BUFFOON!] unexpected plane! " << plane << std::endl;
247  throw std::exception();
248  }
249  sim::SimChannel sch(channel);
250  unsigned planeTDC = clockData.TPCTick2TDC(pulse_record.tick + detProp.GetXTicksOffset(planeID) - detProp.GetXTicksOffset(collectionPlaneID));
251  sch.AddIonizationElectrons(1, /// track id, keep 0 = invalid
252  (unsigned int)planeTDC,
253  fNumElectrons_v[index],
254  xyz,
255  100.); /// energy, keep -1 = invalid
256  simch_v->emplace_back(std::move(sch));
257  }
258  pholder.Register(std::move(pulse_record));
259  }
260 
261  _run = e.id().run();
262  _subrun = e.id().subRun();
263  _event = e.id().event();
264 
265  fTupleTree->Fill();
266  e.put(std::move(simch_v));
267  e.put(std::move(simDep_v));
268  e.put(std::move(trigger_v));
269 
270  return;
271 }
272 
273 DEFINE_ART_MODULE(SimTestPulse)
std::vector< int > fPlane1Channel_v
Resulting plane 1 channel number where charge is deposited.
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
SimTestPulse(fhicl::ParameterSet const &p)
SimTestPulse & operator=(SimTestPulse const &)=delete
unsigned int tdc
Definition: ParamHolder.h:12
TTree * fTupleTree
output analysis tree
std::vector< double > fSimTime_v
Charge timing in electronics clock [us].
pdgs p
Definition: selectors.fcl:22
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
void produce(art::Event &e) override
std::vector< double > fNumElectrons_v
Charge amount in electron count.
std::vector< int > fPlane2Wire_v
Resulting plane 2 wire number where charge is deposited.
Vector GetNormalDirection() const
Returns the direction normal to the plane.
Definition: PlaneGeo.h:442
Access the description of detector geometry.
std::vector< int > fPlane0Channel_v
Resulting plane 0 channel number where charge is deposited.
std::vector< int > fPlane2Channel_v
Resulting plane 2 channel number where charge is deposited.
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< int > fPlane0Wire_v
Resulting plane 0 wire number where charge is deposited.
void beginJob() override
std::vector< int > fTick_v
Corresponding tick.
std::array< int, 3 > channel_list
Definition: ParamHolder.h:11
double fTriggerTime
Trigger timing in electronics clock [us].
static void destroy()
Definition: ParamHolder.h:28
void beginRun(art::Run &run) override
contains information for a single step in the detector simulation
std::vector< double > fY_v
Charge Y position in detector coordinate [cm].
object containing MC truth information necessary for making RawDigits and doing back tracking ...
std::vector< int > fPlane1Wire_v
Resulting plane 1 wire number where charge is deposited.
do i e
art::ServiceHandle< art::TFileService > tfs
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 endJob() override
std::vector< double > fZ_v
Charge Z position in detector coordinate [cm].
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
bool fVerbose
verbosity