15 #include <sys/types.h> 58 #include "cetlib/search_path.h" 59 #include "cetlib_except/exception.h" 64 #include "CLHEP/Random/RandFlat.h" 65 #include "CLHEP/Random/RandGaussQ.h" 72 namespace geo {
class Geometry; }
94 void ConvoluteResponseFunctions();
96 void SetFieldResponse();
97 void SetElectResponse();
99 void GenNoise(std::vector<float>&
array);
113 double fInd3DCorrection;
115 double fColFieldRespAmp;
128 std::vector< std::vector<float> >
fNoise;
146 this->reconfigure(pset);
148 produces< std::vector<raw::RawDigit> >();
151 std::string compression(pset.
get< std::string >(
"CompressionType"));
152 if(compression.compare(
"Huffman") == 0) fCompression =
raw::kHuffman;
157 ->createEngine(*
this, pset,
"Seed");
161 SimWireT962::~SimWireT962()
163 fColFieldResponse.clear();
164 fIndFieldResponse.clear();
168 fElectResponse.clear();
170 for(
unsigned int i = 0; i < fNoise.size(); ++i) fNoise[i].
clear();
178 fResponseSet =
false;
179 cet::search_path sp(
"FW_SEARCH_PATH");
180 if( !sp.find_file(p.
get<std::string>(
"ResponseFile"), fResponseFile) )
181 throw cet::exception(
"SimWireT962") <<
"Unable to find electronics response file in\n" 183 <<
"\n bailing ungracefully.\n";
185 fDriftEModuleLabel= p.
get< std::string >(
"DriftEModuleLabel");
186 fNoiseFact = p.
get<
double >(
"NoiseFact");
187 fNoiseWidth = p.
get<
double >(
"NoiseWidth");
188 fLowCutoff = p.
get<
double >(
"LowCutoff");
189 fNFieldBins = p.
get<
int >(
"FieldBins");
190 fCol3DCorrection = p.
get<
double >(
"Col3DCorrection");
191 fInd3DCorrection = p.
get<
double >(
"Ind3DCorrection");
192 fColFieldRespAmp = p.
get<
double >(
"ColFieldRespAmp");
193 fIndFieldRespAmp = p.
get<
double >(
"IndFieldRespAmp");
194 fShapeTimeConst = p.
get< std::vector<double> >(
"ShapeTimeConst");
198 fSampleRate = detprop->SamplingRate();
199 fTriggerOffset = detprop->TriggerOffset();
210 fNoiseDist = tfs->
make<TH1D>(
"Noise",
";Noise (ADC);", 1000, -10., 10.);
214 fChargeWork.resize(fNTicks, 0.);
221 for(
unsigned int p = 0; p < geo->
Nchannels(); ++p){
224 for(
int i = 0; i < fNTicks; ++i){
225 fNoiseDist->Fill(fNoise[p][i]);
243 ConvoluteResponseFunctions();
248 void SimWireT962::endJob()
260 unsigned int signalSize = fNTicks/2;
262 std::vector<short> adcvec(signalSize, 0);
264 std::vector<const sim::SimChannel*> chanHandle;
265 evt.
getView(fDriftEModuleLabel,chanHandle);
271 std::vector<const sim::SimChannel*> channels(geo->Nchannels());
272 for(
size_t c = 0; c < chanHandle.size(); ++c){
273 channels[chanHandle[c]->Channel()] = chanHandle[c];
278 std::unique_ptr< std::vector<raw::RawDigit> > digcol(
new std::vector<raw::RawDigit>);
280 unsigned int chan = 0;
282 fChargeWork.resize(fNTicks, 0.);
288 CLHEP::HepRandomEngine &engine = rng->
getEngine();
289 CLHEP::RandFlat flat(engine);
292 for(chan = 0; chan < geo->Nchannels(); chan++) {
295 fChargeWork.resize(fNTicks, 0.);
297 if( channels[chan] ){
302 for(
size_t t = 0; t < fChargeWork.size(); ++t){
304 if (tdc < 0)
continue;
305 if (tdc >=
int(fChargeWork.size()))
continue;
306 fChargeWork[t] = sc->
Charge(tdc);
312 else fFFT->
Convolute(fChargeWork,fColShape);
319 int noisechan = TMath::Nint(flat.fire()*(1.*(fNoise.size()-1)+0.1));
320 for(
unsigned int i = 0; i < signalSize; ++i){
321 adcvec[i] = (short)TMath::Nint(fNoise[noisechan][i] + fChargeWork[i]);
334 adcvec.resize(signalSize,0.0);
336 digcol->push_back(rd);
339 evt.
put(std::move(digcol));
345 void SimWireT962::ConvoluteResponseFunctions()
347 std::vector<double>
col(fNTicks, 0.);
348 std::vector<double> ind(fNTicks, 0.);
350 unsigned int mxbin = TMath::Min(fNTicks, (
int)fNElectResp + fNFieldBins);
355 for(
unsigned int i = 1; i < mxbin; ++i){
358 for(
unsigned int j = 0; j < (
unsigned int)fNFieldBins; ++j){
359 unsigned int k = i - j;
361 sumCol += fElectResponse[k]*fColFieldResponse[j];
362 sumInd += fElectResponse[k]*fIndFieldResponse[j];
370 ind.resize(fNTicks, 0.);
371 col.resize(fNTicks, 0.);
375 fColTimeShape = tfs->
make<TH1D>(
"ConvolutedCollection",
";ticks; Electronics#timesCollection",fNTicks,0,fNTicks);
376 fIndTimeShape = tfs->
make<TH1D>(
"ConvolutedInduction",
";ticks; Electronics#timesInduction",fNTicks,0,fNTicks);
378 fIndShape.resize(fNTicks/2+1);
379 fColShape.resize(fNTicks/2+1);
382 std::vector<double> delta(fNTicks);
384 delta[fNTicks-1]=1.0;
389 fFFT->
DoFFT(ind, fIndShape);
390 fFFT->
DoFFT(col, fColShape);
393 for(
unsigned int i = 0; i < ind.size(); ++i){
394 fColTimeShape->Fill(i, col[i]);
395 fIndTimeShape->Fill(i, ind[i]);
398 fColTimeShape->Write();
399 fIndTimeShape->Write();
406 void SimWireT962::GenNoise(std::vector<float>&
noise)
409 CLHEP::HepRandomEngine &engine = rng->
getEngine();
410 CLHEP::RandFlat flat(engine);
413 noise.resize(fNTicks, 0.);
414 std::vector<TComplex> noiseFrequency(fNTicks/2+1, 0.);
417 double lofilter = 0.;
419 double rnd[2] = {0.};
422 double binWidth = 1.0/(fNTicks*fSampleRate*1.0e-6);
423 for(
int i=0; i< fNTicks/2+1; ++i){
425 pval = fNoiseFact*exp(-(
double)i*binWidth/fNoiseWidth);
427 lofilter = 1.0/(1.0+exp(-(i-fLowCutoff/binWidth)/0.5));
429 flat.fireArray(2,rnd,0,1);
430 pval *= lofilter*(0.9+0.2*rnd[0]);
432 phase = rnd[1]*2.*TMath::Pi();
434 TComplex tc(pval*cos(phase),pval*sin(phase));
435 noiseFrequency[i] += tc;
440 fFFT->
DoInvFFT(noiseFrequency, noise);
442 noiseFrequency.clear();
447 for(
unsigned int i = 0; i < noise.size(); ++i) noise[i] *= 1.*fNTicks;
453 void SimWireT962::SetFieldResponse()
458 double xyz1[3] = {0.};
459 double xyz2[3] = {0.};
460 double xyzl[3] = {0.};
467 double pitch = xyz2[0] - xyz1[0];
469 fColFieldResponse.resize(fNFieldBins, 0.);
470 fIndFieldResponse.resize(fNFieldBins, 0.);
478 fIndFieldResp = tfs->
make<TH1D>(
"InductionFieldResponse",
";t (ns);Induction Response",fNTicks,0,fNTicks);
479 fColFieldResp = tfs->
make<TH1D>(
"CollectionFieldResponse",
";t (ns);Collection Response",fNTicks,0,fNTicks);
481 double driftvelocity=detprop->
DriftVelocity(detprop->Efield(),detprop->Temperature())/1000.;
482 int nbinc = TMath::Nint(fCol3DCorrection*(std::abs(pitch))/(driftvelocity*fSampleRate));
484 double integral = 0.;
485 for(
int i = 1; i < nbinc; ++i){
486 fColFieldResponse[i] = fColFieldResponse[i-1] + 1.0;
487 integral += fColFieldResponse[i];
490 for(
int i = 0; i < nbinc; ++i){
491 fColFieldResponse[i] *= fColFieldRespAmp/integral;
492 fColFieldResp->Fill(i, fColFieldResponse[i]);
497 int nbini = TMath::Nint(fInd3DCorrection*(std::abs(pitch))/(driftvelocity*fSampleRate));
498 for(
int i = 0; i < nbini; ++i){
499 fIndFieldResponse[i] = fIndFieldRespAmp/(1.*nbini);
500 fIndFieldResponse[nbini+i] = -fIndFieldRespAmp/(1.*nbini);
502 fIndFieldResp->Fill(i, fIndFieldResponse[i]);
503 fIndFieldResp->Fill(nbini+i, fIndFieldResponse[nbini+i]);
507 fColFieldResp->Write();
508 fIndFieldResp->Write();
514 void SimWireT962::SetElectResponse()
519 fElectResponse.resize(fNTicks, 0.);
520 std::vector<double> time(fNTicks,0.);
522 TFile inFile(fResponseFile.c_str(),
"READ");
523 if(inFile.IsZombie()){
524 throw cet::exception(
"SimWireT962") <<
"Cannot open response file" << fResponseFile <<
"\n";
527 TH1D * shape = (TH1D*)inFile.Get(
"shape");
529 double integral = 0.;
532 while(ctr < fNTicks){
533 holder = shape->GetBinContent(ctr+1);
534 fElectResponse[ctr] = holder;
535 time[ctr] = ctr*fSampleRate;
543 for(
unsigned int i = 0; i < fElectResponse.size(); ++i)
544 fElectResponse[i] /= integral;
546 fNElectResp = fElectResponse.size();
550 fElectResp = tfs->
make<TH1D>(
"ElectronicsResponse",
";t (ns);Electronics Response",fNElectResp,0,fNElectResp);
551 for(
unsigned int i = 0; i < fNElectResp; ++i){
552 fElectResp->Fill(i, fElectResponse[i]);
568 #endif // SIMWIRET962_H
unsigned int fNElectResp
number of entries from response to use
double fSampleRate
sampling rate in ns
TH1D * fIndFieldResp
response function for the field @ induction plane
enum raw::_compress Compress_t
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
Collection of charge vs time digitized from a single readout channel.
Energy deposited on a readout channel by simulated tracks.
std::vector< double > fColFieldResponse
response function for the field @ collection plane
Encapsulate the construction of a single cyostat.
std::vector< TComplex > fColShape
response function for the field @ collection plane
TH1D * fNoiseDist
distribution of noise counts
Detector simulation of raw signals on wires.
std::vector< std::vector< float > > fNoise
noise on each channel for each time
Definition of basic raw digits.
void DoFFT(std::vector< T > &input, std::vector< TComplex > &output)
raw::Compress_t fCompression
compression type to use
void DoInvFFT(std::vector< TComplex > &input, std::vector< T > &output)
unsigned int Nchannels() const
Returns the number of TPC readout channels in the detector.
ProductID put(std::unique_ptr< PROD > &&product)
int fTriggerOffset
(units of ticks) time of expected neutrino event
std::size_t getView(std::string const &moduleLabel, std::string const &productInstanceName, std::vector< ELEMENT const * > &result) const
base_engine_t & getEngine() const
std::string fResponseFile
response file for induction planes
std::vector< double > fShapeTimeConst
time constants for exponential shaping
auto array(Array const &a)
Returns a manipulator which will print the specified array.
#define DEFINE_ART_MODULE(klass)
int fNTicks
number of ticks of the clock
Signal from induction planes.
std::string fDriftEModuleLabel
module making the ionization electrons
double Charge(TDC_t tdc) const
Returns the total number of ionization electrons on this channel in the specified TDC...
int fNFieldBins
number of bins for field response
std::vector< TComplex > fIndShape
response function for the field @ induction plane
Collect all the RawData header files together.
T get(std::string const &key) const
std::vector< double > fElectResponse
response function for the electronics
double fIndFieldRespAmp
amplitude of response to field
void Convolute(std::vector< T > &input, std::vector< T > &respFunc)
bool fResponseSet
flag of whether to set the response functions or not
An art service to assist in the distribution of guaranteed unique seeds to all engines within an art ...
double fLowCutoff
low frequency filter cutoff (kHz)
Conversion of times between different formats and references.
TH1D * fColTimeShape
convoluted shape for field x electronics @ col plane
T * make(ARGS...args) const
std::vector< double > fChargeWork
virtual double TPCTick2TDC(double tick) const =0
Converts a TPC time tick into a electronics time tick.
Encapsulate the construction of a single detector plane.
TH1D * fColFieldResp
response function for the field @ collection plane
void AlignedSum(std::vector< T > &input, std::vector< T > &output, bool add=true)
virtual double DriftVelocity(double efield=0., double temperature=0.) const =0
std::vector< double > fIndFieldResponse
response function for the field @ induction plane
object containing MC truth information necessary for making RawDigits and doing back tracking ...
void Compress(std::vector< short > &adc, raw::Compress_t compress)
Compresses a raw data buffer.
TH1D * fIndTimeShape
convoluted shape for field x electronics @ ind plane
Namespace collecting geometry-related classes utilities.
Tools and modules for checking out the basics of the Monte Carlo.
double fNoiseWidth
exponential noise width (kHz)
void LocalToWorld(const double *plane, double *world) const
Transform point from local plane frame to world frame.
double fNoiseFact
noise scale factor
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
Encapsulate the construction of a single detector plane.
TH1D * fElectResp
response function for the electronics