SignalShapingServiceDUNE10kt_service.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file SignalShapingServiceDUNE10kt_service.cc
3 /// \author H. Greenlee
4 ////////////////////////////////////////////////////////////////////////
5 
10 #include "cetlib_except/exception.h"
17 #include "TFile.h"
18 
19 //----------------------------------------------------------------------
20 // Constructor.
22  art::ActivityRegistry& /* reg */)
23  : fInit(false)
24 {
25  // This class is deprecated. See https://cdcvs.fnal.gov/redmine/issues/11777.
26  mf::LogInfo("SignalShapingServiceDUNE10kt") << "Deprecated: Consider using SignalShapingServiceDUNE";
27  reconfigure(pset);
28 }
29 
30 
31 //----------------------------------------------------------------------
32 // Destructor.
34 {}
35 
36 
37 //----------------------------------------------------------------------
38 // Reconfigure method.
40 {
41  // Reset initialization flag.
42 
43  fInit = false;
44 
45  // Reset kernels.
46 
50 
51  // Fetch fcl parameters.
52 
53  fNFieldBins = pset.get<int>("FieldBins");
54  fCol3DCorrection = pset.get<double>("Col3DCorrection");
55  fInd3DCorrection = pset.get<double>("Ind3DCorrection");
56  fColFieldRespAmp = pset.get<double>("ColFieldRespAmp");
57  fIndUFieldRespAmp = pset.get<double>("IndUFieldRespAmp");
58  fIndVFieldRespAmp = pset.get<double>("IndVFieldRespAmp");
59 
60  fDeconNorm = pset.get<double>("DeconNorm");
61  fADCPerPCAtLowestASICGain = pset.get<double>("ADCPerPCAtLowestASICGain");
62  fASICGainInMVPerFC = pset.get<std::vector<double> >("ASICGainInMVPerFC");
63  fShapeTimeConst = pset.get<std::vector<double> >("ShapeTimeConst");
64  fNoiseFactVec = pset.get<std::vector<DoubleVec> >("NoiseFactVec");
65 
66  fInputFieldRespSamplingPeriod = pset.get<double>("InputFieldRespSamplingPeriod");
67 
68  fFieldResponseTOffset = pset.get<std::vector<double> >("FieldResponseTOffset");
69  fCalibResponseTOffset = pset.get<std::vector<double> >("CalibResponseTOffset");
70 
71  fUseFunctionFieldShape= pset.get<bool>("UseFunctionFieldShape");
72  fUseHistogramFieldShape = pset.get<bool>("UseHistogramFieldShape");
73 
74  fGetFilterFromHisto= pset.get<bool>("GetFilterFromHisto");
75 
76  // Construct parameterized collection filter function.
77  if(!fGetFilterFromHisto)
78  {
79  mf::LogInfo("SignalShapingServiceDUNE10kt") << "Getting Filter from .fcl file";
80  std::string colFilt = pset.get<std::string>("ColFilter");
81  std::vector<double> colFiltParams =
82  pset.get<std::vector<double> >("ColFilterParams");
83  fColFilterFunc = new TF1("colFilter", colFilt.c_str());
84  for(unsigned int i=0; i<colFiltParams.size(); ++i)
85  fColFilterFunc->SetParameter(i, colFiltParams[i]);
86 
87  // Construct parameterized induction filter function.
88 
89  std::string indUFilt = pset.get<std::string>("IndUFilter");
90  std::vector<double> indUFiltParams = pset.get<std::vector<double> >("IndUFilterParams");
91  fIndUFilterFunc = new TF1("indUFilter", indUFilt.c_str());
92  for(unsigned int i=0; i<indUFiltParams.size(); ++i)
93  fIndUFilterFunc->SetParameter(i, indUFiltParams[i]);
94 
95  std::string indVFilt = pset.get<std::string>("IndVFilter");
96  std::vector<double> indVFiltParams = pset.get<std::vector<double> >("IndVFilterParams");
97  fIndVFilterFunc = new TF1("indVFilter", indVFilt.c_str());
98  for(unsigned int i=0; i<indVFiltParams.size(); ++i)
99  fIndVFilterFunc->SetParameter(i, indVFiltParams[i]);
100 
101  }
102  else
103  {
104 
105  std::string histoname = pset.get<std::string>("FilterHistoName");
106  mf::LogInfo("SignalShapingServiceDUNE10kt") << " using filter from .root file ";
107  int fNPlanes=3;
108 
109  // constructor decides if initialized value is a path or an environment variable
111  cet::search_path sp("FW_SEARCH_PATH");
112  sp.find_file(pset.get<std::string>("FilterFunctionFname"), fname);
113 
114  TFile * in=new TFile(fname.c_str(),"READ");
115  for(int i=0;i<fNPlanes;i++){
116  TH1D * temp=(TH1D *)in->Get(Form(histoname.c_str(),i));
117  fFilterHist[i]=new TH1D(Form(histoname.c_str(),i),Form(histoname.c_str(),i),temp->GetNbinsX(),0,temp->GetNbinsX());
118  temp->Copy(*fFilterHist[i]);
119  }
120 
121  in->Close();
122 
123  }
124 
125  /////////////////////////////////////
126  if(fUseFunctionFieldShape)
127  {
128  std::string colField = pset.get<std::string>("ColFieldShape");
129  std::vector<double> colFieldParams =
130  pset.get<std::vector<double> >("ColFieldParams");
131  fColFieldFunc = new TF1("colField", colField.c_str());
132  for(unsigned int i=0; i<colFieldParams.size(); ++i)
133  fColFieldFunc->SetParameter(i, colFieldParams[i]);
134 
135  // Construct parameterized induction filter function.
136 
137  std::string indUField = pset.get<std::string>("IndUFieldShape");
138  std::vector<double> indUFieldParams = pset.get<std::vector<double> >("IndUFieldParams");
139  fIndUFieldFunc = new TF1("indUField", indUField.c_str());
140  for(unsigned int i=0; i<indUFieldParams.size(); ++i)
141  fIndUFieldFunc->SetParameter(i, indUFieldParams[i]);
142  // Warning, last parameter needs to be multiplied by the FFTSize, in current version of the code,
143 
144  std::string indVField = pset.get<std::string>("IndVFieldShape");
145  std::vector<double> indVFieldParams = pset.get<std::vector<double> >("IndVFieldParams");
146  fIndVFieldFunc = new TF1("indVField", indVField.c_str());
147  for(unsigned int i=0; i<indVFieldParams.size(); ++i)
148  fIndVFieldFunc->SetParameter(i, indVFieldParams[i]);
149  // Warning, last parameter needs to be multiplied by the FFTSize, in current version of the code,
150 
151  } else if ( fUseHistogramFieldShape ) {
152  mf::LogInfo("SignalShapingServiceDUNE35t") << " using the field response provided from a .root file " ;
153  int fNPlanes = 3;
154 
155  // constructor decides if initialized value is a path or an environment variable
157  cet::search_path sp("FW_SEARCH_PATH");
158  sp.find_file( pset.get<std::string>("FieldResponseFname"), fname );
159  std::string histoname = pset.get<std::string>("FieldResponseHistoName");
160 
161  std::unique_ptr<TFile> fin(new TFile(fname.c_str(), "READ"));
162  if ( !fin->IsOpen() ) throw art::Exception( art::errors::NotFound ) << "Could not find the field response file " << fname << "!" << std::endl;
163 
164  std::string iPlane[3] = { "U", "V", "Y" };
165 
166  for ( int i = 0; i < fNPlanes; i++ ) {
167  TString iHistoName = Form( "%s_%s", histoname.c_str(), iPlane[i].c_str());
168  TH1F *temp = (TH1F*) fin->Get( iHistoName );
169  if ( !temp ) throw art::Exception( art::errors::NotFound ) << "Could not find the field response histogram " << iHistoName << std::endl;
170  if ( temp->GetNbinsX() > fNFieldBins ) throw art::Exception( art::errors::InvalidNumber ) << "FieldBins should always be larger than or equal to the number of the bins in the input histogram!" << std::endl;
171 
172  fFieldResponseHist[i] = new TH1F( iHistoName, iHistoName, temp->GetNbinsX(), temp->GetBinLowEdge(1), temp->GetBinLowEdge( temp->GetNbinsX() + 1) );
173  temp->Copy(*fFieldResponseHist[i]);
174  }
175 
176  fin->Close();
177  }
178 }
179 
180 
181 //----------------------------------------------------------------------
182 // Accessor for single-plane signal shaper.
183 const util::SignalShaping&
185 {
186  if(!fInit)
187  init();
188 
189  // Figure out plane type.
190 
192  //geo::SigType_t sigtype = geom->SignalType(channel);
193 
194  // we need to distinguis between the U and V planes
195  geo::View_t view = geom->View(channel);
196 
197  // Return appropriate shaper.
198 
199  if(view == geo::kU)
200  return fIndUSignalShaping;
201  else if (view == geo::kV)
202  return fIndVSignalShaping;
203  else if(view == geo::kZ)
204  return fColSignalShaping;
205  else
206  throw cet::exception("SignalShapingServiceDUNE35t")<< "can't determine"
207  << " View\n";
208 
209 return fColSignalShaping;
210 }
211 
212 //-----Give Gain Settings to SimWire-----//jyoti
214 {
216  //geo::SigType_t sigtype = geom->SignalType(channel);
217 
218  // we need to distinguis between the U and V planes
219  geo::View_t view = geom->View(channel);
220 
221  double gain = 0;
222  if(view == geo::kU)
223  gain = fASICGainInMVPerFC.at(0);
224  else if(view == geo::kV)
225  gain = fASICGainInMVPerFC.at(1);
226  else if(view == geo::kZ)
227  gain = fASICGainInMVPerFC.at(2);
228  else
229  throw cet::exception("SignalShapingServiceDUNE35t")<< "can't determine"
230  << " View\n";
231  return gain;
232 }
233 
234 
235 //-----Give Shaping time to SimWire-----//jyoti
237 {
239  //geo::SigType_t sigtype = geom->SignalType(channel);
240 
241  // we need to distinguis between the U and V planes
242  geo::View_t view = geom->View(channel);
243 
244  double shaping_time = 0;
245 
246  if(view == geo::kU)
247  shaping_time = fShapeTimeConst.at(0);
248  else if(view == geo::kV)
249  shaping_time = fShapeTimeConst.at(1);
250  else if(view == geo::kZ)
251  shaping_time = fShapeTimeConst.at(2);
252  else
253  throw cet::exception("SignalShapingServiceDUNE35t")<< "can't determine"
254  << " View\n";
255  return shaping_time;
256 }
257 
259 {
260  unsigned int plane;
262  //geo::SigType_t sigtype = geom->SignalType(channel);
263 
264  // we need to distinguis between the U and V planes
265  geo::View_t view = geom->View(channel);
266 
267  if(view == geo::kU)
268  plane = 0;
269  else if(view == geo::kV)
270  plane = 1;
271  else if(view == geo::kZ)
272  plane = 2;
273  else
274  throw cet::exception("SignalShapingServiceDUNE35t")<< "can't determine"
275  << " View\n";
276 
277  double shapingtime = fShapeTimeConst.at(plane);
278  double gain = fASICGainInMVPerFC.at(plane);
279  int temp;
280  if (shapingtime == 0.5){
281  temp = 0;
282  }else if (shapingtime == 1.0){
283  temp = 1;
284  }else if (shapingtime == 2.0){
285  temp = 2;
286  }else{
287  temp = 3;
288  }
289  double rawNoise;
290 
291  auto tempNoise = fNoiseFactVec.at(plane);
292  rawNoise = tempNoise.at(temp);
293 
294  rawNoise *= gain/4.7;
295  return rawNoise;
296 }
297 
299 {
300  unsigned int plane;
302  //geo::SigType_t sigtype = geom->SignalType(channel);
303 
304  // we need to distinguis between the U and V planes
305  geo::View_t view = geom->View(channel);
306 
307  if(view == geo::kU)
308  plane = 0;
309  else if(view == geo::kV)
310  plane = 1;
311  else if(view == geo::kZ)
312  plane = 2;
313  else
314  throw cet::exception("SignalShapingServiceDUNE35t")<< "can't determine"
315  << " View\n";
316 
317  double shapingtime = fShapeTimeConst.at(plane);
318  int temp;
319  if (shapingtime == 0.5){
320  temp = 0;
321  }else if (shapingtime == 1.0){
322  temp = 1;
323  }else if (shapingtime == 2.0){
324  temp = 2;
325  }else{
326  temp = 3;
327  }
328  auto tempNoise = fNoiseFactVec.at(plane);
329  double deconNoise = tempNoise.at(temp);
330 
331  deconNoise = deconNoise /4096.*2000./4.7 *6.241*1000/fDeconNorm;
332  return deconNoise;
333 }
334 
335 
336 //----------------------------------------------------------------------
337 // Initialization method.
338 // Here we do initialization that can't be done in the constructor.
339 // All public methods should ensure that this method is called as necessary.
341 {
342  if(!fInit) {
343  fInit = true;
344 
345  // Do microboone-specific configuration of SignalShaping by providing
346  // microboone response and filter functions.
347 
348  // Calculate field and electronics response functions.
349 
350  // Lazy initialization is problematic in the context of
351  // multi-threading. In this case, the best we can do is use the
352  // global data provided by the detector-clocks/properties
353  // services.
354  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
355  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob(clockData);
356 
357  SetFieldResponse(clockData, detProp);
359 
360  // Configure convolution kernels.
361 
366  //fColSignalShaping.SetPeakResponseTime(0.);
367 
369 
374  //fIndUSignalShaping.SetPeakResponseTime(0.);
375 
377 
382  //fIndVSignalShaping.SetPeakResponseTime(0.);
383 
384 
385  SetResponseSampling(clockData);
386 
387  // Calculate filter functions.
388 
389  SetFilters(clockData);
390 
391  // Configure deconvolution kernels.
392 
395 
398 
401  }
402 }
403 
404 
405 //----------------------------------------------------------------------
406 // Calculate microboone field response.
408  detinfo::DetectorPropertiesData const& detProp)
409 {
410  // Get services.
411 
413 
414  // Get plane pitch.
415 
416  double xyz1[3] = {0.};
417  double xyz2[3] = {0.};
418  double xyzl[3] = {0.};
419  // should always have at least 2 planes
420  geo->Plane(0).LocalToWorld(xyzl, xyz1);
421  geo->Plane(1).LocalToWorld(xyzl, xyz2);
422 
423  // this assumes all planes are equidistant from each other,
424  // probably not a bad assumption
425  double pitch = xyz2[0] - xyz1[0]; ///in cm
426 
427  fColFieldResponse.resize(fNFieldBins, 0.);
428  fIndUFieldResponse.resize(fNFieldBins, 0.);
429  fIndVFieldResponse.resize(fNFieldBins, 0.);
430 
431  // set the response for the collection plane first
432  // the first entry is 0
433 
434  double driftvelocity=detProp.DriftVelocity()/1000.;
435  int nbinc = TMath::Nint(fCol3DCorrection*(std::abs(pitch))/(driftvelocity*sampling_rate(clockData))); ///number of bins //KP
436  double integral = 0;
437  ////////////////////////////////////////////////////
439  {
441  int signalSize = fft->FFTSize();
442  std::vector<double> ramp(signalSize);
443  // TComplex kernBin;
444  // int size = signalSize/2;
445  // int bin=0;
446  //std::vector<TComplex> freqSig(size+1);
447  std::vector<double> bipolar(signalSize);
448 
449 
450  fColFieldResponse.resize(signalSize, 0.);
451  fIndUFieldResponse.resize(signalSize, 0.);
452  fIndVFieldResponse.resize(signalSize, 0.);
453 
454  // Hardcoding. Bad. Temporary hopefully.
455  fIndUFieldFunc->SetParameter(4,fIndUFieldFunc->GetParameter(4)*signalSize);
456  fIndVFieldFunc->SetParameter(4,fIndVFieldFunc->GetParameter(4)*signalSize);
457 
458  //double integral = 0.;
459  for(int i = 0; i < signalSize; i++) {
460  ramp[i]=fColFieldFunc->Eval(i);
461  fColFieldResponse[i]=ramp[i];
462  integral += fColFieldResponse[i];
463  // rampc->Fill(i,ramp[i]);
464  bipolar[i]=fIndUFieldFunc->Eval(i);
465  fIndUFieldResponse[i]=bipolar[i];
466  bipolar[i]=fIndVFieldFunc->Eval(i);
467  fIndVFieldResponse[i]=bipolar[i];
468  // bipol->Fill(i,bipolar[i]);
469  }
470 
471  for(int i = 0; i < signalSize; ++i){
473  }
474 
475  //this might be not necessary if the function definition is not defined in the middle of the signal range
476  fft->ShiftData(fIndUFieldResponse,signalSize/2.0);
477  } else if ( fUseHistogramFieldShape ) {
478 
479  // Ticks in nanosecond
480  // Calculate the normalization of the collection plane
481  for ( int ibin = 1; ibin <= fFieldResponseHist[2]->GetNbinsX(); ibin++ )
482  integral += fFieldResponseHist[2]->GetBinContent( ibin );
483 
484  // Induction plane
485  for ( int ibin = 1; ibin <= fFieldResponseHist[0]->GetNbinsX(); ibin++ )
486  fIndUFieldResponse[ibin-1] = fIndUFieldRespAmp*fFieldResponseHist[0]->GetBinContent( ibin )/integral;
487 
488  for ( int ibin = 1; ibin <= fFieldResponseHist[1]->GetNbinsX(); ibin++ )
489  fIndVFieldResponse[ibin-1] = fIndVFieldRespAmp*fFieldResponseHist[1]->GetBinContent( ibin )/integral;
490 
491  for ( int ibin = 1; ibin <= fFieldResponseHist[2]->GetNbinsX(); ibin++ )
492  fColFieldResponse[ibin-1] = fColFieldRespAmp*fFieldResponseHist[2]->GetBinContent( ibin )/integral;
493  }else
494  {
495  //////////////////////////////////////////////////
496  mf::LogInfo("SignalShapingServiceDUNE10kt") << " using the old field shape ";
497  double integral = 0.;
498  for(int i = 1; i < nbinc; ++i){
499  fColFieldResponse[i] = fColFieldResponse[i-1] + 1.0;
500  integral += fColFieldResponse[i];
501  }
502 
503  for(int i = 0; i < nbinc; ++i){
505  }
506 
507  // now the induction plane
508 
509 
510  int nbini = TMath::Nint(fInd3DCorrection*(fabs(pitch))/(driftvelocity*sampling_rate(clockData)));//KP
511  for(int i = 0; i < nbini; ++i){
512  fIndUFieldResponse[i] = fIndUFieldRespAmp/(1.*nbini);
513  fIndUFieldResponse[nbini+i] = -fIndUFieldRespAmp/(1.*nbini);
514  }
515 
516  for(int i = 0; i < nbini; ++i){
517  fIndVFieldResponse[i] = fIndVFieldRespAmp/(1.*nbini);
518  fIndVFieldResponse[nbini+i] = -fIndVFieldRespAmp/(1.*nbini);
519  }
520 
521  }
522 
523  return;
524 }
525 
526 void util::SignalShapingServiceDUNE10kt::SetElectResponse(double shapingtime, double gain)
527 {
528  // Get services.
529 
532 
533  MF_LOG_DEBUG("SignalShapingDUNE10kt") << "Setting DUNE10kt electronics response function...";
534 
535  int nticks = fft->FFTSize();
536  fElectResponse.resize(nticks, 0.);
537  std::vector<double> time(nticks,0.);
538 
539  //Gain and shaping time variables from fcl file:
540  double Ao = 1.0;
541  double To = shapingtime; //peaking time
542 
543  // this is actually sampling time, in ns
544  // mf::LogInfo("SignalShapingDUNE35t") << "Check sampling intervals: "
545  // << fSampleRate << " ns"
546  // << "Check number of samples: " << fNTicks;
547 
548  // The following sets the microboone electronics response function in
549  // time-space. Function comes from BNL SPICE simulation of DUNE35t
550  // electronics. SPICE gives the electronics transfer function in
551  // frequency-space. The inverse laplace transform of that function
552  // (in time-space) was calculated in Mathematica and is what is being
553  // used below. Parameters Ao and To are cumulative gain/timing parameters
554  // from the full (ASIC->Intermediate amp->Receiver->ADC) electronics chain.
555  // They have been adjusted to make the SPICE simulation to match the
556  // actual electronics response. Default params are Ao=1.4, To=0.5us.
557  double max = 0;
558 
559  for(size_t i = 0; i < fElectResponse.size(); ++i){
560 
561  //convert time to microseconds, to match fElectResponse[i] definition
562  time[i] = (1.*i)*fInputFieldRespSamplingPeriod *1e-3;
563  fElectResponse[i] =
564  4.31054*exp(-2.94809*time[i]/To)*Ao - 2.6202*exp(-2.82833*time[i]/To)*cos(1.19361*time[i]/To)*Ao
565  -2.6202*exp(-2.82833*time[i]/To)*cos(1.19361*time[i]/To)*cos(2.38722*time[i]/To)*Ao
566  +0.464924*exp(-2.40318*time[i]/To)*cos(2.5928*time[i]/To)*Ao
567  +0.464924*exp(-2.40318*time[i]/To)*cos(2.5928*time[i]/To)*cos(5.18561*time[i]/To)*Ao
568  +0.762456*exp(-2.82833*time[i]/To)*sin(1.19361*time[i]/To)*Ao
569  -0.762456*exp(-2.82833*time[i]/To)*cos(2.38722*time[i]/To)*sin(1.19361*time[i]/To)*Ao
570  +0.762456*exp(-2.82833*time[i]/To)*cos(1.19361*time[i]/To)*sin(2.38722*time[i]/To)*Ao
571  -2.6202*exp(-2.82833*time[i]/To)*sin(1.19361*time[i]/To)*sin(2.38722*time[i]/To)*Ao
572  -0.327684*exp(-2.40318*time[i]/To)*sin(2.5928*time[i]/To)*Ao +
573  +0.327684*exp(-2.40318*time[i]/To)*cos(5.18561*time[i]/To)*sin(2.5928*time[i]/To)*Ao
574  -0.327684*exp(-2.40318*time[i]/To)*cos(2.5928*time[i]/To)*sin(5.18561*time[i]/To)*Ao
575  +0.464924*exp(-2.40318*time[i]/To)*sin(2.5928*time[i]/To)*sin(5.18561*time[i]/To)*Ao;
576 
577  if(fElectResponse[i] > max) max = fElectResponse[i];
578 
579  }// end loop over time buckets
580 
581 
582  MF_LOG_DEBUG("SignalShapingDUNE10kt") << " Done.";
583 
584  //normalize fElectResponse[i], before the convolution
585 
586  for(auto& element : fElectResponse){
587  element /= max;
588  element *= fADCPerPCAtLowestASICGain * 1.60217657e-7;
589  element *= gain / 4.7;
590  }
591 
592  return;
593 
594 }
595 
596 
597 
598 
599 //----------------------------------------------------------------------
600 // Calculate microboone filter functions.
602 {
603  // Get services.
604 
606 
607  double ts = sampling_rate(clockData);
608  int n = fft->FFTSize() / 2;
609 
610  // Calculate collection filter.
611 
612  fColFilter.resize(n+1);
613  fIndUFilter.resize(n+1);
614  fIndVFilter.resize(n+1);
615 
617  {
618  fColFilterFunc->SetRange(0, double(n));
619 
620  for(int i=0; i<=n; ++i) {
621  double freq = 500. * i / (ts * n); // Cycles / microsecond.
622  double f = fColFilterFunc->Eval(freq);
623  fColFilter[i] = TComplex(f, 0.);
624  }
625 
626 
627  // Calculate induction filter.
628 
629  fIndUFilterFunc->SetRange(0, double(n));
630 
631  for(int i=0; i<=n; ++i) {
632  double freq = 500. * i / (ts * n); // Cycles / microsecond.
633  double f = fIndUFilterFunc->Eval(freq);
634  fIndUFilter[i] = TComplex(f, 0.);
635  }
636 
637  fIndVFilterFunc->SetRange(0, double(n));
638 
639  for(int i=0; i<=n; ++i) {
640  double freq = 500. * i / (ts * n); // Cycles / microsecond.
641  double f = fIndVFilterFunc->Eval(freq);
642  fIndVFilter[i] = TComplex(f, 0.);
643  }
644 
645  }
646  else
647  {
648 
649  for(int i=0; i<=n; ++i) {
650  double f = fFilterHist[2]->GetBinContent(i); // hardcoded plane numbers. Bad. To change later.
651  fColFilter[i] = TComplex(f, 0.);
652  double g = fFilterHist[1]->GetBinContent(i);
653  fIndVFilter[i] = TComplex(g, 0.);
654  double h = fFilterHist[0]->GetBinContent(i);
655  fIndUFilter[i] = TComplex(h, 0.);
656  }
657  }
658 
659  //fIndUSignalShaping.AddFilterFunction(fIndFilter);
660  //fIndVSignalShaping.AddFilterFunction(fIndVFilter);
661  //fColSignalShaping.AddFilterFunction(fColFilter);
662 
663 }
664 
665 //----------------------------------------------------------------------
666 // Sample microboone response (the convoluted field and electronic
667 // response), will probably add the filter later
669 {
670  // Get services
673 
674  // Operation permitted only if output of rebinning has a larger bin size
676  throw cet::exception(__FUNCTION__) << "\033[93m"
677  << "Invalid operation: cannot rebin to a more finely binned vector!"
678  << "\033[00m" << std::endl;
679 
680  int nticks = fft->FFTSize();
681  std::vector<double> SamplingTime( nticks, 0. );
682  for ( int itime = 0; itime < nticks; itime++ ) {
683  SamplingTime[itime] = (1.*itime) * sampling_rate(clockData);
684  /// VELOCITY-OUT ... comment out kDVel usage here
685  //SamplingTime[itime] = (1.*itime) * sampling_rate(clockData) / kDVel;
686  }
687 
688  // Sampling
689  for ( int iplane = 0; iplane < 3; iplane++ ) {
690  const std::vector<double>* pResp;
691  switch ( iplane ) {
692  case 0: pResp = &(fIndUSignalShaping.Response_save()); break;
693  case 1: pResp = &(fIndVSignalShaping.Response_save()); break;
694  default: pResp = &(fColSignalShaping.Response_save()); break;
695  }
696 
697  std::vector<double> SamplingResp(nticks , 0. );
698 
699 
700  int nticks_input = pResp->size();
701  std::vector<double> InputTime(nticks_input, 0. );
702  for ( int itime = 0; itime < nticks_input; itime++ ) {
703  InputTime[itime] = (1.*itime) * fInputFieldRespSamplingPeriod;
704  }
705 
706 
707  /*
708  Much more sophisticated approach using a linear (trapezoidal) interpolation
709  Current default!
710  */
711  int SamplingCount = 0;
712  for ( int itime = 0; itime < nticks; itime++ ) {
713  int low = -1, up = -1;
714  for ( int jtime = 0; jtime < nticks_input; jtime++ ) {
715  if ( InputTime[jtime] == SamplingTime[itime] ) {
716  SamplingResp[itime] = (*pResp)[jtime];
717  /// VELOCITY-OUT ... comment out kDVel usage here
718  //SamplingResp[itime] = kDVel * (*pResp)[jtime];
719  SamplingCount++;
720  break;
721  } else if ( InputTime[jtime] > SamplingTime[itime] ) {
722  low = jtime - 1;
723  up = jtime;
724  SamplingResp[itime] = (*pResp)[low] + ( SamplingTime[itime] - InputTime[low] ) * ( (*pResp)[up] - (*pResp)[low] ) / ( InputTime[up] - InputTime[low] );
725  /// VELOCITY-OUT ... comment out kDVel usage here
726  //SamplingResp[itime] *= kDVel;
727  SamplingCount++;
728  break;
729  } else {
730  SamplingResp[itime] = 0.;
731  }
732  } // for ( int jtime = 0; jtime < nticks; jtime++ )
733  } // for ( int itime = 0; itime < nticks; itime++ )
734  SamplingResp.resize( SamplingCount, 0.);
735 
736 
737 
738 
739  switch ( iplane ) {
740  case 0: fIndUSignalShaping.AddResponseFunction( SamplingResp, true ); break;
741  case 1: fIndVSignalShaping.AddResponseFunction( SamplingResp, true ); break;
742  default: fColSignalShaping.AddResponseFunction( SamplingResp, true ); break;
743  }
744 
745 
746 
747  } // for ( int iplane = 0; iplane < fNPlanes; iplane++ )
748 
749  return;
750 }
751 
752 
753 
755  unsigned int const channel) const
756 {
758  //geo::SigType_t sigtype = geom->SignalType(channel);
759 
760  // we need to distinguis between the U and V planes
761  geo::View_t view = geom->View(channel);
762 
763  double time_offset = 0;
764 
765  if(view == geo::kU)
766  time_offset = fFieldResponseTOffset.at(0) + fCalibResponseTOffset.at(0);
767  else if(view == geo::kV)
768  time_offset = fFieldResponseTOffset.at(1) + fCalibResponseTOffset.at(1);
769  else if(view == geo::kZ)
770  time_offset = fFieldResponseTOffset.at(2) + fCalibResponseTOffset.at(2);
771  else
772  throw cet::exception("SignalShapingServiceDUNE35t")<< "can't determine"
773  << " View\n";
774 
775  return clockData.TPCClock().Ticks(time_offset/1.e3);
776 
777 }
778 
779 
780 namespace util {
781 
783 
784 }
void set_normflag(bool flag)
const std::vector< double > & Response_save() const
Definition: SignalShaping.h:78
TF1 * fIndUFieldFunc
Parameterized induction field shape function.
Namespace for general, non-LArSoft-specific utilities.
Service to provide microboone-specific signal shaping for simulation (convolution) and reconstruction...
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
TF1 * fIndUFilterFunc
Parameterized induction filter function.
void SetFilters(detinfo::DetectorClocksData const &clockData)
static constexpr double g
Definition: Units.h:144
void ShiftData(std::vector< TComplex > &input, double shift)
void SetElectResponse(double shapingtime, double gain)
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
Planes which measure V.
Definition: geo_types.h:130
double GetShapingTime(unsigned int const channel) const
double GetASICGain(unsigned int const channel) const
void AddResponseFunction(const std::vector< double > &resp, bool ResetResponse=false)
Planes which measure Z direction.
Definition: geo_types.h:132
SignalShapingServiceDUNE10kt(const fhicl::ParameterSet &pset, art::ActivityRegistry &reg)
uint8_t channel
Definition: CRTFragment.hh:201
std::vector< double > fShapeTimeConst
time constants for exponential shaping
int FieldResponseTOffset(detinfo::DetectorClocksData const &clockData, unsigned int const channel) const
double fIndVFieldRespAmp
amplitude of response to field
constexpr int Ticks() const noexcept
Current clock tick (that is, the number of tick Time() falls in).
Definition: ElecClock.h:205
art framework interface to geometry description
double fIndUFieldRespAmp
amplitude of response to field
T abs(T value)
Planes which measure U.
Definition: geo_types.h:129
int FFTSize() const
Definition: LArFFT.h:69
const double e
bool fGetFilterFromHisto
Flag that allows to use a filter function from a histogram instead of the functional dependency...
void CalculateDeconvKernel() const
TF1 * fIndVFilterFunc
Parameterized induction filter function.
void reconfigure(const fhicl::ParameterSet &pset)
std::void_t< T > n
T get(std::string const &key) const
Definition: ParameterSet.h:271
TH1D * fFilterHist[3]
Histogram used to hold the collection filter, hardcoded for the time being.
ElecClock const & TPCClock() const noexcept
Borrow a const TPC clock with time set to Trigger time [us].
double fADCPerPCAtLowestASICGain
Pulse amplitude gain for a 1 pc charge impulse after convoluting it the with field and electronics re...
static int max(int a, int b)
double DriftVelocity(double efield=0., double temperature=0.) const
cm/us
bool fUseFunctionFieldShape
Flag that allows to use a parameterized field response instead of the hardcoded version.
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
void SetFieldResponse(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp)
TF1 * fColFilterFunc
Parameterized collection filter function.
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
TH1F * fFieldResponseHist[3]
Histogram used to hold the field response, hardcoded for the time being.
#define DEFINE_ART_SERVICE(svc)
const util::SignalShaping & SignalShaping(unsigned int channel) const
Encapsulate the construction of a single detector plane.
Contains all timing reference information for the detector.
double GetDeconNoise(unsigned int const channel) const
TF1 * fIndVFieldFunc
Parameterized induction field shape function.
double fColFieldRespAmp
amplitude of response to field
#define MF_LOG_DEBUG(id)
std::vector< double > fFieldResponseTOffset
Time offset for field response in ns.
std::string find_file(std::string const &filename) const
Definition: search_path.cc:96
double fInputFieldRespSamplingPeriod
Sampling period in the input field response.
void SetResponseSampling(detinfo::DetectorClocksData const &clockData)
double GetRawNoise(unsigned int const channel) const
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
LArSoft geometry interface.
Definition: ChannelGeo.h:16
int fNFieldBins
number of bins for field response
TF1 * fColFieldFunc
Parameterized collection field shape function.
void AddFilterFunction(const std::vector< TComplex > &filt)
void LocalToWorld(const double *plane, double *world) const
Transform point from local plane frame to world frame.
Definition: PlaneGeo.h:1343
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
bool fUseHistogramFieldShape
Flag that turns on field response shapes from histograms.
QTextStream & endl(QTextStream &s)
Encapsulate the construction of a single detector plane.