LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
NoiseWaveformDump_module.cc
Go to the documentation of this file.
1 //
3 // Module to dump noise waveforms for 1DCNN
4 // training
5 //
6 // mwang@fnal.gov
7 //
9 
10 #include <random>
11 
12 // Framework includes
22 #include "fhiclcpp/ParameterSet.h"
24 
25 // LArSoft libraries
28 #include "larcoreobj/SimpleTypesAndConstants/RawTypes.h" // raw::ChannelID_t
32 #include "lardataobj/RawData/raw.h"
34 
35 #include "CLHEP/Random/RandFlat.h"
36 #include "c2numpy.h"
38 
39 using std::cout;
40 using std::endl;
41 using std::ofstream;
42 using std::string;
43 
44 namespace nnet {
45  class NoiseWaveformDump;
46 }
47 
49 
50 public:
51  explicit NoiseWaveformDump(fhicl::ParameterSet const& p);
52 
53  // Plugins should not be copied or assigned.
54  NoiseWaveformDump(NoiseWaveformDump const&) = delete;
58 
59  // Required functions.
60  void analyze(art::Event const& e) override;
61 
62  //void reconfigure(fhicl::ParameterSet const & p);
63 
64  void beginJob() override;
65  void endJob() override;
66 
67 private:
69 
71  std::string fSimChannelLabel;
72  std::string fDigitModuleLabel;
74  unsigned int fShortWaveformSize;
75 
76  std::string fPlaneToDump;
79 
80  CLHEP::RandFlat fRandFlat;
81 
83 };
84 
85 // Create the random number generator
86 namespace {
87  std::string const instanceName = "NoiseWaveformDump";
88 }
89 
90 //-----------------------------------------------------------------------
92  : EDAnalyzer{p}
93  , fDumpWaveformsFileName(p.get<std::string>("DumpWaveformsFileName", "dumpwaveforms"))
94  , fSimulationProducerLabel(p.get<std::string>("SimulationProducerLabel", "larg4Main"))
95  , fSimChannelLabel(p.get<std::string>("SimChannelLabel", "elecDrift"))
96  , fDigitModuleLabel(p.get<std::string>("DigitModuleLabel", "simWire"))
97  , fUseFullWaveform(p.get<bool>("UseFullWaveform", true))
98  , fShortWaveformSize(p.get<unsigned int>("ShortWaveformSize"))
99  , fPlaneToDump(p.get<std::string>("PlaneToDump"))
100  , fMaxNoiseChannelsPerEvent(p.get<int>("MaxNoiseChannelsPerEvent"))
103  -> declareEngine(instanceName, p, "SeedForNoiseWaveformDump"),
104  "HepJamesRandom",
105  instanceName)}
106 {
107  if (std::getenv("CLUSTER") && std::getenv("PROCESS")) {
109  string(std::getenv("CLUSTER")) + "-" + string(std::getenv("PROCESS")) + "-";
110  }
111 
112  if (fDigitModuleLabel.empty()) {
113  throw cet::exception("NoiseWaveformDump") << "DigitModuleLabel is empty";
114  }
115 }
116 
117 //-----------------------------------------------------------------------
119 {
120  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob();
121 
127 
128  for (unsigned int i = 0; i < 5; i++) {
129  std::ostringstream name;
130 
131  name.str("");
132  name << "tid" << i;
133  c2numpy_addcolumn(&npywriter, name.str().c_str(), C2NUMPY_INT32);
134 
135  name.str("");
136  name << "pdg" << i;
137  c2numpy_addcolumn(&npywriter, name.str().c_str(), C2NUMPY_INT32);
138 
139  name.str("");
140  name << "gen" << i;
141  c2numpy_addcolumn(&npywriter, name.str().c_str(), (c2numpy_type)((int)C2NUMPY_STRING + 6));
142 
143  name.str("");
144  name << "pid" << i;
145  c2numpy_addcolumn(&npywriter, name.str().c_str(), (c2numpy_type)((int)C2NUMPY_STRING + 7));
146 
147  name.str("");
148  name << "edp" << i;
149  c2numpy_addcolumn(&npywriter, name.str().c_str(), C2NUMPY_FLOAT32);
150 
151  name.str("");
152  name << "nel" << i;
153  c2numpy_addcolumn(&npywriter, name.str().c_str(), C2NUMPY_UINT32);
154 
155  name.str("");
156  name << "sti" << i;
157  c2numpy_addcolumn(&npywriter, name.str().c_str(), C2NUMPY_UINT16);
158 
159  name.str("");
160  name << "stf" << i;
161  c2numpy_addcolumn(&npywriter, name.str().c_str(), C2NUMPY_UINT16);
162  }
163 
164  for (unsigned int i = 0;
165  i < (fUseFullWaveform ? detProp.ReadOutWindowSize() : fShortWaveformSize);
166  i++) {
167  std::ostringstream name;
168  name << "tck_" << i;
169  c2numpy_addcolumn(&npywriter, name.str().c_str(), C2NUMPY_INT16);
170  }
171 }
172 
173 //-----------------------------------------------------------------------
175 {
177 }
178 
179 //-----------------------------------------------------------------------
181 {
182  cout << "Event " << evt.id().run() << " " << evt.id().subRun() << " " << evt.id().event() << endl;
183 
184  // ... Read in the digit List object(s).
185  auto digitVecHandle = evt.getValidHandle<std::vector<raw::RawDigit>>(fDigitModuleLabel);
186 
187  std::cout << " !!!!! Size of digitVecHandle: " << digitVecHandle->size() << std::endl;
188  if (!digitVecHandle->size()) return;
189 
190  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
191  auto const detProp =
193 
194  // ... Use the handle to get a particular (0th) element of collection.
195  std::vector<raw::RawDigit> const& rawDigits = *digitVecHandle;
196  raw::RawDigit const& digitVec0 = rawDigits[0];
197  unsigned int dataSize = digitVec0.Samples(); //size of raw data vectors
198  if (dataSize != detProp.ReadOutWindowSize()) {
199  throw cet::exception("NoiseWaveformDumpNoiseWaveformDump") << "Bad dataSize: " << dataSize;
200  }
201 
202  // ... Build a map from channel number -> rawdigitVec
203  std::map<raw::ChannelID_t, raw::RawDigit const*> rawdigitMap;
204  raw::ChannelID_t chnum = raw::InvalidChannelID; // channel number
205  for (size_t rdIter = 0; rdIter < rawDigits.size(); ++rdIter) {
206  chnum = rawDigits[rdIter].Channel();
207  if (chnum == raw::InvalidChannelID) continue;
208  if (geo::PlaneGeo::ViewName(fgeom->View(chnum)) != fPlaneToDump[0]) continue;
209  rawdigitMap[chnum] = &rawDigits[rdIter];
210  }
211 
212  // ... Read in sim channel list
213  auto simChannelHandle = evt.getValidHandle<std::vector<sim::SimChannel>>(fSimChannelLabel);
214  std::cout << " !!!!! Size of simChannelHandle: " << simChannelHandle->size() << std::endl;
215 
216  if (simChannelHandle->size() > 0) {
217 
218  // ... Loop over simChannels to find all signal channels and erase them
219  // from the rawdigitMap
220  for (auto const& channel : (*simChannelHandle)) {
221 
222  // .. get simChannel channel number
223  const raw::ChannelID_t ch1 = channel.Channel();
224  if (ch1 == raw::InvalidChannelID) continue;
225  if (geo::PlaneGeo::ViewName(fgeom->View(ch1)) != fPlaneToDump[0]) continue;
226 
227  bool hasEnergyDeposit = false;
228 
229  // ... Loop over all ticks with ionization energy deposited
230  auto const& timeSlices = channel.TDCIDEMap();
231  for (auto const& [tpctime, energyDeposits] : timeSlices) {
232 
233  unsigned int tdctick = static_cast<unsigned int>(clockData.TPCTDC2Tick(double(tpctime)));
234  if (tdctick < 0 || tdctick > (dataSize - 1)) continue;
235 
236  // ... Loop over all energy depositions in this tick
237  for (auto const& energyDeposit : energyDeposits) {
238  if ((energyDeposit.energy > 0) || (energyDeposit.numElectrons > 0)) {
239  hasEnergyDeposit = true;
240  break;
241  }
242  }
243  if (hasEnergyDeposit) break;
244  }
245  if (hasEnergyDeposit) rawdigitMap.erase(ch1);
246 
247  } // loop over SimChannels
248  }
249 
250  // .. Now construct noise channel vector from updated rawdigitMap
251  std::vector<raw::ChannelID_t> noisechannels;
252  for (std::map<raw::ChannelID_t, raw::RawDigit const*>::iterator iter = rawdigitMap.begin();
253  iter != rawdigitMap.end();
254  ++iter) {
255  noisechannels.push_back(iter->first);
256  }
257 
258  std::cout << " !!!!! size of noisechannels: " << noisechannels.size() << std::endl;
259  if (!noisechannels.size()) return;
260 
261  //save noise
262  int noisechancount = 0;
263 
264  // .. create a vector for shuffling the wire channel indices
265  auto seed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
266  std::vector<size_t> randigitmap;
267  for (size_t i = 0; i < noisechannels.size(); ++i)
268  randigitmap.push_back(i);
269  std::shuffle(randigitmap.begin(), randigitmap.end(), std::mt19937(seed));
270 
271  std::string dummystr6 = "none ";
272  std::string dummystr7 = "none ";
273 
274  for (size_t rdIter = 0; rdIter < noisechannels.size(); ++rdIter) {
275 
276  if (noisechancount == fMaxNoiseChannelsPerEvent) break;
277 
278  size_t ranIdx = randigitmap[rdIter];
279  auto digitVec = rawdigitMap[noisechannels[ranIdx]];
280 
281  std::vector<short> rawadc(dataSize); // vector to hold uncompressed adc values later
282  std::vector<short> adcvec(dataSize); // vector to pedestal-subtracted adc values
283  raw::Uncompress(digitVec->ADCs(), rawadc, digitVec->GetPedestal(), digitVec->Compression());
284  for (size_t j = 0; j < rawadc.size(); ++j) {
285  adcvec[j] = rawadc[j] - digitVec->GetPedestal();
286  }
287  c2numpy_uint32(&npywriter, evt.id().event());
288  c2numpy_uint32(&npywriter, digitVec->Channel());
289  c2numpy_string(&npywriter, geo::PlaneGeo::ViewName(fgeom->View(digitVec->Channel())).c_str());
290 
291  c2numpy_uint16(&npywriter, 0); //number of peaks
292  for (unsigned int i = 0; i < 5; ++i) {
295  c2numpy_string(&npywriter, dummystr6.c_str());
296  c2numpy_string(&npywriter, dummystr7.c_str());
301  }
302 
303  if (fUseFullWaveform) {
304  for (unsigned int itck = 0; itck < dataSize; ++itck) {
305  c2numpy_int16(&npywriter, adcvec[itck]);
306  }
307  }
308  else {
309  int start_tick = int((dataSize - fShortWaveformSize) * fRandFlat.fire(0, 1));
310  for (unsigned int itck = start_tick; itck < (start_tick + fShortWaveformSize); ++itck) {
311  c2numpy_int16(&npywriter, adcvec[itck]);
312  }
313  }
314 
315  ++noisechancount;
316  }
317  std::cout << "Total number of noise channels " << noisechancount << std::endl;
318 }
int c2numpy_init(c2numpy_writer *writer, const std::string outputFilePrefix, int32_t numRowsPerFile)
Definition: c2numpy.h:140
intermediate_table::iterator iterator
base_engine_t & createEngine(seed_t seed)
int c2numpy_int32(c2numpy_writer *writer, int32_t data)
Definition: c2numpy.h:298
static std::string ViewName(geo::View_t view)
Returns the name of the specified view.
Definition: PlaneGeo.cxx:682
ULong64_t Samples() const
Number of samples in the uncompressed ADC data.
Definition: RawDigit.h:217
Collection of charge vs time digitized from a single readout channel.
Definition: RawDigit.h:68
c2numpy_type
Definition: c2numpy.h:29
Definition of basic raw digits.
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.cc:6
RunNumber_t run() const
Definition: EventID.h:98
int c2numpy_close(c2numpy_writer *writer)
Definition: c2numpy.h:425
NoiseWaveformDump & operator=(NoiseWaveformDump const &)=delete
constexpr ChannelID_t InvalidChannelID
ID of an invalid channel.
Definition: RawTypes.h:31
int c2numpy_addcolumn(c2numpy_writer *writer, const std::string name, c2numpy_type type)
Definition: c2numpy.h:157
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
long seed
Definition: chem4.cc:67
Collect all the RawData header files together.
Definition: EmTrack.h:40
int c2numpy_uint32(c2numpy_writer *writer, uint32_t data)
Definition: c2numpy.h:334
An art service to assist in the distribution of guaranteed unique seeds to all engines within an art ...
int c2numpy_float32(c2numpy_writer *writer, float data)
Definition: c2numpy.h:369
void analyze(art::Event const &e) override
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
NoiseWaveformDump(fhicl::ParameterSet const &p)
std::string fSimulationProducerLabel
producer that tracked simulated part. through detector
Encapsulate the construction of a single detector plane.
art::ServiceHandle< geo::Geometry > fgeom
View_t View(PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
int c2numpy_uint16(c2numpy_writer *writer, uint16_t data)
Definition: c2numpy.h:325
std::string fSimChannelLabel
module that made simchannels
object containing MC truth information necessary for making RawDigits and doing back tracking ...
int c2numpy_int16(c2numpy_writer *writer, int16_t data)
Definition: c2numpy.h:289
EventNumber_t event() const
Definition: EventID.h:116
TCEvent evt
Definition: DataStructs.cxx:8
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
std::string fDigitModuleLabel
module that made digits
void Uncompress(const std::vector< short > &adc, std::vector< short > &uncompressed, raw::Compress_t compress)
Uncompresses a raw data buffer.
Definition: raw.cxx:744
Float_t e
Definition: plot.C:35
SubRunNumber_t subRun() const
Definition: EventID.h:110
int c2numpy_string(c2numpy_writer *writer, const char *data)
Definition: c2numpy.h:411
EventID id() const
Definition: Event.cc:23
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33