All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SimWireSBND_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // $Id: SimWireSBND.cxx,v 1.22 2010/04/23 20:30:53 seligman Exp $
3 //
4 // SimWireSBND class designed to simulate signal on a wire in the TPC
5 //
6 // katori@fnal.gov
7 //
8 // - Revised to use sim::RawDigit instead of rawdata::RawDigit, and to
9 // - save the electron clusters associated with each digit.
10 // - ported from the MicroBooNE class by A.Szlec
11 ////////////////////////////////////////////////////////////////////////
12 #include <vector>
13 #include <string>
14 #include <algorithm>
15 #include <sstream>
16 #include <fstream>
17 #include <bitset>
18 
19 extern "C" {
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 }
23 
24 #include "canvas/Utilities/Exception.h"
25 #include "art/Framework/Core/ModuleMacros.h"
26 #include "art/Framework/Core/EDProducer.h"
27 #include "art/Framework/Principal/Event.h"
28 #include "art/Framework/Principal/Handle.h"
29 #include "art/Framework/Services/Registry/ServiceHandle.h"
30 #include "art_root_io/TFileService.h"
31 #include "art_root_io/TFileDirectory.h"
32 #include "fhiclcpp/ParameterSet.h"
33 #include "messagefacility/MessageLogger/MessageLogger.h"
34 
35 // art extensions
36 #include "nurandom/RandomUtils/NuRandomService.h"
37 
38 
41 #include "lardataobj/RawData/raw.h"
51 
52 #include "TMath.h"
53 #include "TComplex.h"
54 #include "TString.h"
55 #include "TH2.h"
56 #include "TH1D.h"
57 #include "TFile.h"
58 #include "TRandom.h"
59 
60 #include "CLHEP/Random/RandFlat.h"
61 #include "CLHEP/Random/RandGaussQ.h"
62 
64 
65 ///Detector simulation of raw signals on wires
66 namespace detsim {
67 
68 // Base class for creation of raw signals on wires.
69 class SimWireSBND : public art::EDProducer {
70 
71 public:
72 
73  explicit SimWireSBND(fhicl::ParameterSet const& pset);
74  virtual ~SimWireSBND();
75 
76  // read/write access to event
77  void produce (art::Event& evt);
78  void beginJob();
79  void endJob();
80  void reconfigure(fhicl::ParameterSet const& p);
81 
82 private:
83 
84  std::string fDriftEModuleLabel;///< module making the ionization electrons
85  raw::Compress_t fCompression; ///< compression type to use
86 
87  size_t fNTicks; ///< number of ticks of the clock
88  unsigned int fNTimeSamples; ///< number of ADC readout samples in all readout frames (per event)
89  float fCollectionPed; ///< ADC value of baseline for collection plane
90  float fInductionPed; ///< ADC value of baseline for induction plane
91  float fCollectionSat; ///< ADC value of pre-amp saturation for collection plane
92  float fInductionSat; ///< ADC value of pre-amp saturation for induction plane
93  float fBaselineRMS; ///< ADC value of baseline RMS within each channel
94  TH1D* fNoiseDist; ///< distribution of noise counts
95  bool fGenNoise; ///< if True -> Gen Noise. if False -> Skip noise generation entierly
96 
97  art::ServiceHandle<ChannelNoiseService> noiseserv;
98 
99  std::string fTrigModName; ///< Trigger data product producer name
100  //define max ADC value - if one wishes this can
101  //be made a fcl parameter but not likely to ever change
102  static constexpr float adcsaturation{4095};
103 
104  //CLHEP::HepRandomEngine& fNoiseEngine;
105  CLHEP::HepRandomEngine& fPedestalEngine;
106 
107 }; // class SimWireSBND
108 
109 DEFINE_ART_MODULE(SimWireSBND)
110 
111 //-------------------------------------------------
112 SimWireSBND::SimWireSBND(fhicl::ParameterSet const& pset)
113  : EDProducer{pset}
114  // create a default random engine; obtain the random seed from NuRandomService,
115  // unless overridden in configuration with key "Seed" and "SeedPedestal"
116  // , fNoiseEngine(art::ServiceHandle<rndm::NuRandomService>{}->createEngine(*this, "HepJamesRandom", "noise", pset, "Seed"))
117  , fPedestalEngine(art::ServiceHandle<rndm::NuRandomService>{}->createEngine(*this, "HepJamesRandom", "pedestal", pset, "SeedPedestal"))
118 {
119  this->reconfigure(pset);
120 
121  produces< std::vector<raw::RawDigit> >();
122 
124  TString compression(pset.get< std::string >("CompressionType"));
125  if (compression.Contains("Huffman", TString::kIgnoreCase)) fCompression = raw::kHuffman;
126 }
127 
128 //-------------------------------------------------
130 {
131 }
132 
133 //-------------------------------------------------
134 void SimWireSBND::reconfigure(fhicl::ParameterSet const& p)
135 {
136  fDriftEModuleLabel = p.get< std::string >("DriftEModuleLabel");
137  fGenNoise = p.get< bool >("GenNoise");
138  fCollectionPed = p.get< float >("CollectionPed",690.);
139  fInductionPed = p.get< float >("InductionPed",2100.);
140  fCollectionSat = p.get< float >("CollectionSat",2922.);
141  fInductionSat = p.get< float >("InductionSat",1247.);
142  fBaselineRMS = p.get< float >("BaselineRMS");
143  fTrigModName = p.get< std::string >("TrigModName");
144 
145  //Map the Shaping times to the entry position for the noise ADC
146  //level in fNoiseFactInd and fNoiseFactColl
147  //fShapingTimeOrder = { {0.5, 0 }, {1.0, 1}, {2.0, 2}, {3.0, 3} };
148 
149  //if (fGetNoiseFromHisto)
150  //{
151  // fNoiseHistoName = p.get< std::string >("NoiseHistoName");
152 
153  // cet::search_path sp("FW_SEARCH_PATH");
154  // sp.find_file(p.get<std::string>("NoiseFileFname"), fNoiseFileFname);
155 
156  // TFile in(fNoiseFileFname.c_str(), "READ");
157  // if (!in.IsOpen()) {
158  // throw art::Exception(art::errors::FileOpenError)
159  // << "Could not find Root file '" << fNoiseHistoName
160  // << "' for noise histogram\n";
161  // }
162  // fNoiseHist = (TH1D*) in.Get(fNoiseHistoName.c_str());
163 
164  // if (!fNoiseHist) {
165  // throw art::Exception(art::errors::NotFound)
166  // << "Could not find noise histogram '" << fNoiseHistoName
167  // << "' in Root file '" << in.GetPath() << "'\n";
168  // }
169  // // release the histogram from its file; now we own it
170  // fNoiseHist->SetDirectory(nullptr);
171  // in.Close();
172  //}
173 
174  //detector properties information
175  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob();
176  fNTimeSamples = detProp.NumberTimeSamples();
177 
178  noiseserv->InitialiseProducerDeps(this, p);
179 
180 
181  return;
182 }
183 
184 //-------------------------------------------------
186 {
187 
188  // get access to the TFile service
189  art::ServiceHandle<art::TFileService> tfs;
190 
191  fNoiseDist = tfs->make<TH1D>("Noise", ";Noise (ADC);", 1000, -10., 10.);
192 
193  art::ServiceHandle<util::LArFFT> fFFT;
194  fNTicks = fFFT->FFTSize();
195 
196  if ( fNTicks % 2 != 0 )
197  MF_LOG_DEBUG("SimWireSBND") << "Warning: FFTSize not a power of 2. "
198  << "May cause issues in (de)convolution.\n";
199 
200  if ( fNTimeSamples > fNTicks )
201  mf::LogError("SimWireSBND") << "Cannot have number of readout samples "
202  << "greater than FFTSize!";
203 
204  return;
205 
206 }
207 
208 //-------------------------------------------------
210 {}
211 
212 void SimWireSBND::produce(art::Event& evt)
213 {
214  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
215 
216  //Generate gaussian and coherent noise if doing uBooNE noise model. For other models it does nothing.
217  noiseserv->generateNoise(clockData);
218 
219  // get the geometry to be able to figure out signal types and chan -> plane mappings
220  art::ServiceHandle<geo::Geometry> geo;
221  //unsigned int signalSize = fNTicks;
222  //
223  //Get the channels status
224  lariov::ChannelStatusProvider const& channelStatus(art::ServiceHandle<lariov::ChannelStatusService const>()->GetProvider());
225 
226  std::vector<const sim::SimChannel*> chanHandle;
227  evt.getView(fDriftEModuleLabel, chanHandle);
228 
229  //Get fIndShape and fColShape from SignalShapingService, on the fly
230  art::ServiceHandle<util::SignalShapingServiceSBND> sss;
231 
232  // make a vector of const sim::SimChannel* that has same number
233  // of entries as the number of channels in the detector
234  // and set the entries for the channels that have signal on them
235  // using the chanHandle
236  std::vector<const sim::SimChannel*> channels(geo->Nchannels(), nullptr);
237  for (size_t c = 0; c < chanHandle.size(); ++c) {
238  channels.at(chanHandle.at(c)->Channel()) = chanHandle.at(c);
239  }
240 
241  const auto NChannels = geo->Nchannels();
242 
243  // vectors for working
244  std::vector<short> adcvec(fNTimeSamples, 0);
245  std::vector<double> chargeWork(fNTicks, 0.);
246 
247 
248 
249  // make a unique_ptr of sim::SimDigits that allows ownership of the produced
250  // digits to be transferred to the art::Event after the put statement below
251  std::unique_ptr< std::vector<raw::RawDigit>> digcol(new std::vector<raw::RawDigit>);
252  digcol->reserve(NChannels);
253 
254  unsigned int chan = 0;
255  art::ServiceHandle<util::LArFFT> fFFT;
256 
257  //LOOP OVER ALL CHANNELS
258  std::map<int, double>::iterator mapIter;
259  for (chan = 0; chan < geo->Nchannels(); chan++) {
260 
261  if (channelStatus.IsBad(chan)) continue;
262 
263  // get the sim::SimChannel for this channel
264  const sim::SimChannel* sc = channels.at(chan);
265  std::fill(chargeWork.begin(), chargeWork.end(), 0.);
266  if ( sc ) {
267 
268  // loop over the tdcs and grab the number of electrons for each
269  for (int t = 0; t < (int)(chargeWork.size()); ++t) {
270 
271  int tdc = clockData.TPCTick2TDC(t);
272 
273  // continue if tdc < 0
274  if ( tdc < 0 ) continue;
275 
276  chargeWork.at(t) = sc->Charge(tdc);
277 
278  }
279 
280  // Convolve charge with appropriate response function
281  sss->Convolute(clockData, chan, chargeWork);
282 
283  }
284  std::vector<float> noisetmp(fNTicks, 0.);
285 
286  // Add noise to channel.
287  if( fGenNoise ) noiseserv->addNoise(clockData, chan,noisetmp);
288 
289  //Pedestal determination
290  float ped_mean = fCollectionPed;
291  float preamp_sat=fCollectionSat;
292  geo::SigType_t sigtype = geo->SignalType(chan);
293  if (sigtype == geo::kInduction) {
294  ped_mean = fInductionPed;
295  preamp_sat = fInductionSat;
296  }
297  //slight variation on ped on order of RMS of baseline variation
298  // (skip this if BaselineRMS = 0 in fhicl)
299  if( fBaselineRMS ) {
300  CLHEP::RandGaussQ rGaussPed(fPedestalEngine, 0.0, fBaselineRMS);
301  ped_mean += rGaussPed.fire();
302  }
303 
304  for (unsigned int i = 0; i < fNTimeSamples; ++i) {
305 
306  float chargecontrib = chargeWork.at(i);
307  if (chargecontrib>preamp_sat) chargecontrib=preamp_sat;
308 
309  float adcval = noisetmp.at(i) + chargecontrib + ped_mean;
310 
311  //Add Noise to NoiseDist Histogram
312  if (i % 100 == 0)
313  fNoiseDist->Fill(noisetmp.at(i));
314 
315  //allow for ADC saturation
316  if ( adcval > adcsaturation )
317  adcval = adcsaturation;
318  //don't allow for "negative" saturation
319  if ( adcval < 0 )
320  adcval = 0;
321 
322  adcvec.at(i) = (unsigned short)(adcval+0.5);
323 
324  }// end loop over signal size
325 
326  // resize the adcvec to be the correct number of time samples,
327  // just drop the extra samples
328  //adcvec.resize(fNTimeSamples);
329 
330  // compress the adc vector using the desired compression scheme,
331  // if raw::kNone is selected nothing happens to adcvec
332  // This shrinks adcvec, if fCompression is not kNone.
333  raw::Compress(adcvec, fCompression);
334 
335  // add this digit to the collection
336  raw::RawDigit rd(chan, fNTimeSamples, adcvec, fCompression);
337  rd.SetPedestal(ped_mean);
338  digcol->push_back(rd);
339 
340  }// end loop over channels
341 
342  evt.put(std::move(digcol));
343 
344 }//produce()
345 
346 
347 
348 }//namespace detsim
Huffman Encoding.
Definition: RawTypes.h:10
TString compression(pset.get< std::string >("CompressionType"))
enum raw::_compress Compress_t
Collection of charge vs time digitized from a single readout channel.
Definition: RawDigit.h:69
float fInductionSat
ADC value of pre-amp saturation for induction plane.
Energy deposited on a readout channel by simulated tracks.
Definition: SimChannel.h:145
virtual bool IsBad(raw::ChannelID_t channel) const =0
Returns whether the specified channel is bad in the current run.
std::string fDriftEModuleLabel
module making the ionization electrons
float fCollectionSat
ADC value of pre-amp saturation for collection plane.
pdgs p
Definition: selectors.fcl:22
Definition of basic raw digits.
bool fGenNoise
if True -&gt; Gen Noise. if False -&gt; Skip noise generation entierly
no compression
Definition: RawTypes.h:9
float fInductionPed
ADC value of baseline for induction plane.
art::ServiceHandle< ChannelNoiseService > noiseserv
createEngine this this reconfigure(pset)
static constexpr float adcsaturation
Service to provide microboone-specific signal shaping for simulation (convolution) and reconstruction...
Signal from induction planes.
Definition: geo_types.h:145
double Charge(TDC_t tdc) const
Returns the total number of ionization electrons on this channel in the specified TDC...
Definition: SimChannel.cxx:138
enum geo::_plane_sigtype SigType_t
Collect all the RawData header files together.
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
Class providing information about the quality of channels.
size_t fNTicks
number of ticks of the clock
unsigned int fNTimeSamples
number of ADC readout samples in all readout frames (per event)
float fBaselineRMS
ADC value of baseline RMS within each channel.
CLHEP::HepRandomEngine & fPedestalEngine
void reconfigure(fhicl::ParameterSet const &p)
void produce(art::Event &evt)
TH1D * fNoiseDist
distribution of noise counts
void SetPedestal(float ped, float sigma=1.)
Set pedestal and its RMS (the latter is 0 by default)
Definition: RawDigit.cxx:68
object containing MC truth information necessary for making RawDigits and doing back tracking ...
Interface for experiment-specific channel quality info provider.
void Compress(std::vector< short > &adc, raw::Compress_t compress)
Compresses a raw data buffer.
Definition: raw.cxx:19
art::ServiceHandle< art::TFileService > tfs
TCEvent evt
Definition: DataStructs.cxx:8
Interface for experiment-specific service for channel quality info.
SimWireSBND(fhicl::ParameterSet const &pset)
raw::Compress_t fCompression
compression type to use
std::string fTrigModName
Trigger data product producer name.
Tools and modules for checking out the basics of the Monte Carlo.
art framework interface to geometry description
auto const detProp
float fCollectionPed
ADC value of baseline for collection plane.