SimWireDUNE_module.cc
Go to the documentation of this file.
1 // SimWireDUNE_module.cc
2 //
3 // David Adams
4 // December 2015
5 //
6 // SimWireDUNE class designed to simulate signal on a wire in the TPC
7 //
8 // Developed from the now-obsolete SimWireDUNE35t_module.cc. This implementation
9 // follows the TSI model where most of the algorithmic code is moved to
10 // services accessed via service interfaces.
11 //
12 // For configuration parameters, see the "Flags" block in the module class
13 // definition below. Remove the leading "f" to get the parameter name.
14 //
15 // There is no flag for compression because this must always be invoked
16 // to apply zero suppression. Use ReplaceCompressService (prolog cmpreplace)
17 // to effectively skip the compression while retaining the supression.
18 //
19 // The interface names for the accessed services are listed in the "Services"
20 // block in the header below.
21 //
22 // Some useful module and service configurations may be found in
23 // detsimmodules_dune.fcl, e.g. cmpreplace to skip compression.
24 
25 #include <vector>
26 #include <string>
27 #include <sstream>
28 #include <iostream>
29 
35 #include "fhiclcpp/ParameterSet.h"
37 
38 #include "lardataobj/RawData/raw.h"
44 
46 
55 
56 using std::ostringstream;
57 using std::cout;
58 using std::endl;
59 using std::string;
60 
61 //**********************************************************************
62 
63 // Base class for creation of raw signals on wires.
64 class SimWireDUNE : public art::EDProducer {
65 
66 public:
67 
68  explicit SimWireDUNE(fhicl::ParameterSet const& pset);
69  virtual ~SimWireDUNE();
70 
71  // read/write access to event
72  void produce (art::Event& evt);
73  void beginJob();
74  void endJob();
75  void reconfigure(fhicl::ParameterSet const& p);
76 
77 private:
78 
79  std::string fSimChannelLabel; ///< Data product holding the ionization electrons
80 
81  // Flags.
82  bool fNoiseOn; ///< noise turned on or off for debugging; default is on
83  bool fPedestalOn; ///< switch for simulation of nonzero pedestals
84  bool fDistortOn; ///< switch for simulation of stuck bits
85  bool fSuppressOn; ///< switch for simulation of zero suppression
86  bool fKeepEmptyChannels; ///< Write out empty channels iff true.
87  bool fUseRawDigitInput; ///< Use (presumably noise-free) RawDigits for input instead of SimChannels
88  std::string fRawDigitInputLabel; ///< The module label for the RawDigits to read in
89  // Tools.
91 
92 
93  std::unique_ptr<AdcSimulator> m_pads;
94 
95  // Services.
103 
104 }; // class SimWireDUNE
105 
107 
108 //**********************************************************************
109 
110 SimWireDUNE::SimWireDUNE(fhicl::ParameterSet const& pset) : EDProducer{pset} {
111  reconfigure(pset);
112  produces< std::vector<raw::RawDigit> >();
113 }
114 
115 //**********************************************************************
116 
118 
119 //**********************************************************************
120 
122  string myname = "SimWireDUNE::reconfigure: ";
123  string myprefix = myname + " ";
124  fSimChannelLabel = p.get<std::string>("SimChannelLabel");
125  fNoiseOn = p.get<bool>("NoiseOn");
126  fPedestalOn = p.get<bool>("PedestalOn");
127  fDistortOn = p.get<bool>("DistortOn");
128  fSuppressOn = p.get<bool>("SuppressOn");
129  fKeepEmptyChannels = p.get<bool>("KeepEmptyChannels");
130  fUseRawDigitInput = p.get<bool>("UseRawDigitInput", false);
131  fRawDigitInputLabel= p.get<string>("RawDigitInputLabel", "");
132  fAdcSimulatorName = p.get<string>("AdcSimulator");
133 
135  m_pads = pdtm == nullptr ? nullptr : pdtm->getPrivate<AdcSimulator>(fAdcSimulatorName);
136  ostringstream out;
137  out << myname << "Tools:" << endl;
138  out << " AdcSimulator: " << bool(m_pads) << endl;
139  out << myname << "Accessed services:" << endl;
140  out << myname << " SimChannel extraction service:" << endl;
141  m_pscx->print(out, myprefix) << endl;
142  if ( fNoiseOn ) {
143  out << myname << " Channel noise service:" << endl;;
144  m_pcns->print(out, myprefix);
145  } else {
146  out << myname << " Channel noise is off.";
147  }
148  out << endl;
149  if ( fPedestalOn ) {
150  out << myname << " Pedestal addition service:" << endl;;
151  m_ppad->print(out, myprefix);
152  } else {
153  out << myname << " Pedestal addition is off.";
154  }
155  out << endl;
156  if ( fDistortOn ) {
157  out << myname << " ADC distortion service:" << endl;;
158  m_pdis->print(out, myprefix);
159  } else {
160  out << myname << " ADC distortion is off.";
161  }
162  out << endl;
163  if ( fSuppressOn ) {
164  out << myname << " ADC suppression service:" << endl;
165  m_pzs->print(out, myprefix);
166  } else {
167  out << myname << " ADC suppression is off.";
168  }
169  out << endl;
170  out << myname << " Compression service:" << endl;
171  out << endl;
172  m_pcmp->print(out, myprefix);
173  out << myname << " KeepEmptyChannels:" << fKeepEmptyChannels << endl;
174  mf::LogInfo("SimWireDUNE::reconfigure") << out.str();
175 
176  return;
177 }
178 
179 //**********************************************************************
180 
182 
183 //**********************************************************************
184 
186 
187 //**********************************************************************
188 
190  const string myname = "SimWireDUNE::produce: ";
191 
192  // Make a vector of const sim::SimChannel* that has same number
193  // of entries as the number of channels in the detector
194  // and set the entries for the channels that have signal on them
195  // using the chanHandle
196  std::vector<const sim::SimChannel*> chanHandle;
197  std::vector<const sim::SimChannel*> simChannels(m_pgeo->Nchannels(), nullptr);
198  evt.getView(fSimChannelLabel, chanHandle);
199  for ( size_t c=0; c<chanHandle.size(); ++c ) {
200  simChannels[chanHandle[c]->Channel()] = chanHandle[c];
201  }
202 
203  // Do the same as above, but for the RawDigits, so we can map from channel number to digit
204  std::vector<const raw::RawDigit*> inputDigitsHandle;
205  std::vector<const raw::RawDigit*> inputDigits(m_pgeo->Nchannels(), nullptr);
206  if(fUseRawDigitInput){
207  evt.getView(fRawDigitInputLabel, inputDigitsHandle);
208  for ( size_t c=0; c<inputDigitsHandle.size(); ++c ) {
209  const raw::RawDigit* dig=inputDigitsHandle[c];
210  inputDigits[dig->Channel()] = dig;
211  }
212  }
213 
214  // make an unique_ptr of sim::SimDigits that allows ownership of the produced
215  // digits to be transferred to the art::Event after the put statement below
216  std::unique_ptr<std::vector<raw::RawDigit>> digcol(new std::vector<raw::RawDigit>);
217 
218  // Fetch the number of ticks to write out for each channel.
219  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
220  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt, clockData);
221  unsigned int nTickReadout = detProp.ReadOutWindowSize();
222  m_pcns->newEvent();
223  // Loop over channels.
225  for ( unsigned int chan = 0; chan<m_pgeo->Nchannels(); ++chan ) {
226 
227  // Get the SimChannel for this channel
228  const sim::SimChannel* psc = simChannels[chan];
229 
230  // Create vector that holds the floating ADC count for each tick.
231  std::vector<AdcSignal> fChargeWork;
232 
233  if(fUseRawDigitInput){
234  const raw::RawDigit* dig=inputDigits[chan];
235  fChargeWork.insert(fChargeWork.end(), dig->ADCs().begin(), dig->ADCs().end());
236  }
237  else{
238  // Extract the floating ADC count from the SimChannel for each tick in the channel.
239  m_pscx->extract(clockData, psc, fChargeWork);
240  }
241 
242  // Add noise to each tick in the channel.
243  if ( fNoiseOn ) {
244  m_pcns->addNoise(clockData, detProp, chan, fChargeWork);
245  }
246 
247  // Option to display signals before adding pedestals.
248  // E.g. logsig = chan==1000.
249  bool logsig = false;
250  if ( logsig ) {
251  cout << myname << "Signals after noise:" << endl;
252  for ( unsigned int itck=0; itck<fChargeWork.size(); ++itck ) {
253  if(fChargeWork[itck] > 0 )
254  cout << myname << " " << itck << ": chg=" << fChargeWork[itck] << endl;
255  }
256  }
257 
258  // Add pedestal.
259  float pedval = 0.0; // Pedestal to be recorded in RawDigits collection
260  float pedrms = 0.0; // Pedestal RMS to be recorded in RawDigits collection
261  if ( fPedestalOn ) {
262  m_ppad->addPedestal(chan, fChargeWork, pedval, pedrms);
263  }
264 
265  // Convert floating ADC to integral ADC count.
266  std::vector<short> adcvec(fChargeWork.size(), 0);
267  const short adcmax = 4095;
268  for ( unsigned int itck=0; itck<fChargeWork.size(); ++itck ) {
269  AdcSignal adcin = fChargeWork[itck];
270  short adc = 0;
271  bool useOldAdc = false;
272  // New ADC calculation (with tool).
273  if ( m_pads ) {
274  if(adcin > 0)
275  //cout << " adcin " << adcin << endl;
276  adc = m_pads->count(adcin, chan);
277  } else {
278  //cout << myname << "WARNING: AdcSimulator not found." << endl;
279  useOldAdc = true;
280  }
281  // Old ADC calculation.
282  if ( useOldAdc ) {
283  short adc1 = 0;
284  if ( adcin > 0 ) adc1 = (short) (adcin + 0.5);
285  if ( adc1 > adcmax ) adc1 = adcmax;
286  bool show = m_pads && adc1 != adc;
287 
288  static int ndump = 1000;
289  if ( ndump && show ) {
290  cout << myname << " ADC: " << adc1 << " --> " << adc << " (" << adcin << ")" << endl;
291  --ndump;
292  }
293  adc = adc1;
294  }
295  // Record the ADC value.
296  adcvec[itck] = adc;
297  }
298  // Resize to the correct number of time samples, dropping extra samples.
299  adcvec.resize(nTickReadout);
300 
301  // Add stuck bits.
302  if ( fDistortOn ) {
303  m_pdis->modify(chan, adcvec);
304  }
305 
306  // Zero suppress.
307  AdcCountSelection acs(adcvec, chan, pedval);
308  if ( fSuppressOn ) {
309  m_pzs->filter(acs);
310  }
311  int nkeep = 0;
312  for ( bool kept : acs.filter ) if ( kept ) ++nkeep;
313 
314  // If flag is not set and channel is empty, skip it.
315  if ( ! fKeepEmptyChannels && nkeep==0 ) continue;
316 
317  // Compress.
319  m_pcmp->compress(adcvec, acs.filter, pedval, comp);
320 
321  // Create and store raw digit.
322  raw::RawDigit rd(chan, nTickReadout, adcvec, comp);
323  rd.SetPedestal(pedval, pedrms);
324  digcol->push_back(rd); // add this digit to the collection
325 
326  } // end loop over channels
327 
328  evt.put(std::move(digcol));
329 
330 }
intermediate_table::iterator iterator
art::ServiceHandle< PedestalAdditionService > m_ppad
art::ServiceHandle< SimChannelExtractService > m_pscx
bool fKeepEmptyChannels
Write out empty channels iff true.
const ADCvector_t & ADCs() const
Reference to the compressed ADC count vector.
Definition: RawDigit.h:210
enum raw::_compress Compress_t
virtual ~SimWireDUNE()
Collection of charge vs time digitized from a single readout channel.
Definition: RawDigit.h:69
virtual int modify(Channel chan, AdcCountVector &adcvec) const =0
Energy deposited on a readout channel by simulated tracks.
Definition: SimChannel.h:140
art::ServiceHandle< AdcSuppressService > m_pzs
virtual int addNoise(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, Channel chan, AdcSignalVector &sigs) const =0
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
virtual int extract(detinfo::DetectorClocksData const &clockData, const sim::SimChannel *psc, AdcSignalVector &sig) const =0
float AdcSignal
Definition: AdcTypes.h:21
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
bool fNoiseOn
noise turned on or off for debugging; default is on
virtual std::ostream & print(std::ostream &out=std::cout, std::string prefix="") const =0
std::unique_ptr< AdcSimulator > m_pads
ChannelID_t Channel() const
DAQ channel this raw data was read from.
Definition: RawDigit.h:212
int16_t adc
Definition: CRTFragment.hh:202
virtual std::ostream & print(std::ostream &out=std::cout, std::string prefix="") const =0
SimWireDUNE(fhicl::ParameterSet const &pset)
no compression
Definition: RawTypes.h:9
virtual std::ostream & print(std::ostream &out=std::cout, std::string prefix=" ") const =0
art framework interface to geometry description
art::ServiceHandle< geo::Geometry > m_pgeo
art::ServiceHandle< ChannelNoiseService > m_pcns
unsigned int Nchannels() const
Returns the number of TPC readout channels in the detector.
void produce(art::Event &evt)
virtual std::ostream & print(std::ostream &out=std::cout, std::string prefix=" ") const =0
bool fUseRawDigitInput
Use (presumably noise-free) RawDigits for input instead of SimChannels.
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
def move(depos, offset)
Definition: depos.py:107
T get(std::string const &key) const
Definition: ParameterSet.h:271
AdcFilterVector filter
p
Definition: test.py:223
std::string fRawDigitInputLabel
The module label for the RawDigits to read in.
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
bool fPedestalOn
switch for simulation of nonzero pedestals
virtual std::ostream & print(std::ostream &out=std::cout, std::string prefix="") const =0
art::ServiceHandle< AdcDistortionService > m_pdis
void reconfigure(fhicl::ParameterSet const &p)
void SetPedestal(float ped, float sigma=1.)
Set pedestal and its RMS (the latter is 0 by default)
Definition: RawDigit.cxx:68
virtual int addPedestal(Channel chan, AdcSignalVector &sigs, float &ped, float &pedrms) const =0
virtual int filter(const AdcCountVector &sigs, Channel chan, AdcPedestal ped, AdcFilterVector &keep) const =0
std::string fAdcSimulatorName
std::size_t getView(std::string const &moduleLabel, std::string const &productInstanceName, std::string const &processName, std::vector< ELEMENT const * > &result) const
Definition: DataViewImpl.h:500
art::ServiceHandle< AdcCompressService > m_pcmp
Tools and modules for checking out the basics of the Monte Carlo.
TCEvent evt
Definition: DataStructs.cxx:7
std::string fSimChannelLabel
Data product holding the ionization electrons.
virtual int compress(AdcCountVector &sigs, const AdcFilterVector &keep, AdcCount offset, raw::Compress_t &comp) const =0
int bool
Definition: qglobal.h:345
virtual std::ostream & print(std::ostream &out=std::cout, std::string prefix="") const =0
bool fSuppressOn
switch for simulation of zero suppression
static DuneToolManager * instance(std::string fclname="", int dbg=1)
QTextStream & endl(QTextStream &s)
bool fDistortOn
switch for simulation of stuck bits