SignalShapingServiceDUNE35t_service.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file SignalShapingServiceDUNE35t_service.cc
3 /// \author H. Greenlee
4 ////////////////////////////////////////////////////////////////////////
5 
10 #include "cetlib_except/exception.h"
17 #include "TFile.h"
18 #include <fstream>
19 
20 //----------------------------------------------------------------------
21 // Constructor.
23  art::ActivityRegistry& /* reg */)
24  : fInit(false)
25 {
26  // This class is deprecated. See https://cdcvs.fnal.gov/redmine/issues/11777.
27  mf::LogInfo("SignalShapingServiceDUNE10kt") << "Deprecated: Consider using SignalShapingServiceDUNE";
28  reconfigure(pset);
29 }
30 
31 
32 //----------------------------------------------------------------------
33 // Destructor.
35 {}
36 
37 
38 //----------------------------------------------------------------------
39 // Reconfigure method.
41 {
42  // Reset initialization flag.
43 
44  fInit = false;
45 
46  // Reset kernels.
47 
51 
52  // Fetch fcl parameters.
53 
54  fNFieldBins = pset.get<int>("FieldBins");
55  fCol3DCorrection = pset.get<double>("Col3DCorrection");
56  fInd3DCorrection = pset.get<double>("Ind3DCorrection");
57  fColFieldRespAmp = pset.get<double>("ColFieldRespAmp");
58  fIndUFieldRespAmp = pset.get<double>("IndUFieldRespAmp");
59  fIndVFieldRespAmp = pset.get<double>("IndVFieldRespAmp");
60 
61  fDeconNorm = pset.get<double>("DeconNorm");
62  fADCPerPCAtLowestASICGain = pset.get<double>("ADCPerPCAtLowestASICGain");
63  fASICGainInMVPerFC = pset.get<std::vector<double> >("ASICGainInMVPerFC");
64  fShapeTimeConst = pset.get<std::vector<double> >("ShapeTimeConst");
65  fNoiseFactVec = pset.get<std::vector<DoubleVec> >("NoiseFactVec");
66 
67  fInputFieldRespSamplingPeriod = pset.get<double>("InputFieldRespSamplingPeriod");
68 
69  fFieldResponseTOffset = pset.get<std::vector<double> >("FieldResponseTOffset");
70  fCalibResponseTOffset = pset.get<std::vector<double> >("CalibResponseTOffset");
71 
72  fUseFunctionFieldShape= pset.get<bool>("UseFunctionFieldShape");
73  fUseHistogramFieldShape = pset.get<bool>("UseHistogramFieldShape");
74 
75  fGetFilterFromHisto= pset.get<bool>("GetFilterFromHisto");
76 
77  fDebugFieldShape = pset.get<bool>("DebugFieldShape",false);
78 
79  // Construct parameterized collection filter function.
80  if(!fGetFilterFromHisto)
81  {
82  mf::LogInfo("SignalShapingServiceDUNE35t") << "Getting Filter from .fcl file" ;
83  std::string colFilt = pset.get<std::string>("ColFilter");
84  std::vector<double> colFiltParams =
85  pset.get<std::vector<double> >("ColFilterParams");
86  fColFilterFunc = new TF1("colFilter", colFilt.c_str());
87  for(unsigned int i=0; i<colFiltParams.size(); ++i)
88  fColFilterFunc->SetParameter(i, colFiltParams[i]);
89 
90  // Construct parameterized induction filter function.
91 
92  std::string indUFilt = pset.get<std::string>("IndUFilter");
93  std::vector<double> indUFiltParams = pset.get<std::vector<double> >("IndUFilterParams");
94  fIndUFilterFunc = new TF1("indUFilter", indUFilt.c_str());
95  for(unsigned int i=0; i<indUFiltParams.size(); ++i)
96  fIndUFilterFunc->SetParameter(i, indUFiltParams[i]);
97 
98  std::string indVFilt = pset.get<std::string>("IndVFilter");
99  std::vector<double> indVFiltParams = pset.get<std::vector<double> >("IndVFilterParams");
100  fIndVFilterFunc = new TF1("indVFilter", indVFilt.c_str());
101  for(unsigned int i=0; i<indVFiltParams.size(); ++i)
102  fIndVFilterFunc->SetParameter(i, indVFiltParams[i]);
103 
104  }
105  else
106  {
107  std::string histoname = pset.get<std::string>("FilterHistoName");
108  mf::LogInfo("SignalShapingServiceDUNE35t") << " using filter from .root file " ;
109  int fNPlanes=3;
110 
111  // constructor decides if initialized value is a path or an environment variable
113  cet::search_path sp("FW_SEARCH_PATH");
114  sp.find_file(pset.get<std::string>("FilterFunctionFname"), fname);
115 
116  TFile * in=new TFile(fname.c_str(),"READ");
117  for(int i=0;i<fNPlanes;i++){
118  TH1D * temp=(TH1D *)in->Get(Form(histoname.c_str(),i));
119  fFilterHist[i]=new TH1D(Form(histoname.c_str(),i),Form(histoname.c_str(),i),temp->GetNbinsX(),0,temp->GetNbinsX());
120  temp->Copy(*fFilterHist[i]);
121  }
122 
123  in->Close();
124 
125  }
126 
127  /////////////////////////////////////
128  if(fUseFunctionFieldShape)
129  {
130  std::string colField = pset.get<std::string>("ColFieldShape");
131  std::vector<double> colFieldParams =
132  pset.get<std::vector<double> >("ColFieldParams");
133  fColFieldFunc = new TF1("colField", colField.c_str());
134  for(unsigned int i=0; i<colFieldParams.size(); ++i)
135  fColFieldFunc->SetParameter(i, colFieldParams[i]);
136 
137  // Construct parameterized induction filter function.
138 
139  std::string indUField = pset.get<std::string>("IndUFieldShape");
140  std::vector<double> indUFieldParams = pset.get<std::vector<double> >("IndUFieldParams");
141  fIndUFieldFunc = new TF1("indUField", indUField.c_str());
142  for(unsigned int i=0; i<indUFieldParams.size(); ++i)
143  fIndUFieldFunc->SetParameter(i, indUFieldParams[i]);
144  // Warning, last parameter needs to be multiplied by the FFTSize, in current version of the code,
145 
146  std::string indVField = pset.get<std::string>("IndVFieldShape");
147  std::vector<double> indVFieldParams = pset.get<std::vector<double> >("IndVFieldParams");
148  fIndVFieldFunc = new TF1("indVField", indVField.c_str());
149  for(unsigned int i=0; i<indVFieldParams.size(); ++i)
150  fIndVFieldFunc->SetParameter(i, indVFieldParams[i]);
151  // Warning, last parameter needs to be multiplied by the FFTSize, in current version of the code,
152 
153  } else if ( fUseHistogramFieldShape ) {
154  mf::LogInfo("SignalShapingServiceDUNE35t") << " using the field response provided from a .root file " ;
155  int fNPlanes = 3;
156 
157  // constructor decides if initialized value is a path or an environment variable
159  cet::search_path sp("FW_SEARCH_PATH");
160  sp.find_file( pset.get<std::string>("FieldResponseFname"), fname );
161  std::string histoname = pset.get<std::string>("FieldResponseHistoName");
162 
163  std::unique_ptr<TFile> fin(new TFile(fname.c_str(), "READ"));
164  if ( !fin->IsOpen() ) throw art::Exception( art::errors::NotFound ) << "Could not find the field response file " << fname << "!" << std::endl;
165 
166  std::string iPlane[3] = { "U", "V", "Y" };
167 
168  for ( int i = 0; i < fNPlanes; i++ ) {
169  TString iHistoName = Form( "%s_%s", histoname.c_str(), iPlane[i].c_str());
170  TH1F *temp = (TH1F*) fin->Get( iHistoName );
171  if ( !temp ) throw art::Exception( art::errors::NotFound ) << "Could not find the field response histogram " << iHistoName << std::endl;
172  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;
173 
174  fFieldResponseHist[i] = new TH1F( iHistoName, iHistoName, temp->GetNbinsX(), temp->GetBinLowEdge(1), temp->GetBinLowEdge( temp->GetNbinsX() + 1) );
175  temp->Copy(*fFieldResponseHist[i]);
176  }
177 
178  fin->Close();
179  }
180 }
181 
182 
183 //----------------------------------------------------------------------
184 // Accessor for single-plane signal shaper.
185 const util::SignalShaping&
187 {
188  if(!fInit)
189  init();
190 
191  // Figure out plane type.
192 
194  //geo::SigType_t sigtype = geom->SignalType(channel);
195 
196  // we need to distinguis between the U and V planes
197  geo::View_t view = geom->View(channel);
198 
199  // Return appropriate shaper.
200 
201  if(view == geo::kU)
202  return fIndUSignalShaping;
203  else if (view == geo::kV)
204  return fIndVSignalShaping;
205  else if(view == geo::kZ)
206  return fColSignalShaping;
207  else
208  throw cet::exception("SignalShapingServiceDUNE35t")<< "can't determine"
209  << " View\n";
210 
211 return fColSignalShaping;
212 }
213 
214 //-----Give Gain Settings to SimWire-----//jyoti
216 {
218 
219  //geo::SigType_t sigtype = geom->SignalType(channel);
220 
221  // we need to distinguis between the U and V planes
222  geo::View_t view = geom->View(channel);
223 
224  double gain = 0;
225  if(view == geo::kU)
226  gain = fASICGainInMVPerFC.at(0);
227  else if(view == geo::kV)
228  gain = fASICGainInMVPerFC.at(1);
229  else if(view == geo::kZ)
230  gain = fASICGainInMVPerFC.at(2);
231  else
232  throw cet::exception("SignalShapingServiceDUNE35t")<< "can't determine"
233  << " View\n";
234  return gain;
235 }
236 
237 
238 //-----Give Shaping time to SimWire-----//jyoti
240 {
242  //geo::SigType_t sigtype = geom->SignalType(channel);
243 
244  // we need to distinguis between the U and V planes
245  geo::View_t view = geom->View(channel);
246 
247  double shaping_time = 0;
248 
249  if(view == geo::kU)
250  shaping_time = fShapeTimeConst.at(0);
251  else if(view == geo::kV)
252  shaping_time = fShapeTimeConst.at(1);
253  else if(view == geo::kZ)
254  shaping_time = fShapeTimeConst.at(2);
255  else
256  throw cet::exception("SignalShapingServiceDUNE35t")<< "can't determine"
257  << " View\n";
258  return shaping_time;
259 }
260 
262 {
263  unsigned int plane;
265  //geo::SigType_t sigtype = geom->SignalType(channel);
266 
267  // we need to distinguis between the U and V planes
268  geo::View_t view = geom->View(channel);
269 
270  if(view == geo::kU)
271  plane = 0;
272  else if(view == geo::kV)
273  plane = 1;
274  else if(view == geo::kZ)
275  plane = 2;
276  else
277  throw cet::exception("SignalShapingServiceDUNE35t")<< "can't determine"
278  << " View\n";
279 
280  double shapingtime = fShapeTimeConst.at(plane);
281  double gain = fASICGainInMVPerFC.at(plane);
282  int temp;
283  if (shapingtime == 0.5){
284  temp = 0;
285  }else if (shapingtime == 1.0){
286  temp = 1;
287  }else if (shapingtime == 2.0){
288  temp = 2;
289  }else{
290  temp = 3;
291  }
292  double rawNoise;
293 
294  auto tempNoise = fNoiseFactVec.at(plane);
295  rawNoise = tempNoise.at(temp);
296 
297  rawNoise *= gain/4.7;
298  return rawNoise;
299 }
300 
302 {
303  unsigned int plane;
305  //geo::SigType_t sigtype = geom->SignalType(channel);
306 
307  // we need to distinguis between the U and V planes
308  geo::View_t view = geom->View(channel);
309 
310  if(view == geo::kU)
311  plane = 0;
312  else if(view == geo::kV)
313  plane = 1;
314  else if(view == geo::kZ)
315  plane = 2;
316  else
317  throw cet::exception("SignalShapingServiceDUNE35t")<< "can't determine"
318  << " View\n";
319 
320  double shapingtime = fShapeTimeConst.at(plane);
321  int temp;
322  if (shapingtime == 0.5){
323  temp = 0;
324  }else if (shapingtime == 1.0){
325  temp = 1;
326  }else if (shapingtime == 2.0){
327  temp = 2;
328  }else{
329  temp = 3;
330  }
331  auto tempNoise = fNoiseFactVec.at(plane);
332  double deconNoise = tempNoise.at(temp);
333 
334  deconNoise = deconNoise /4096.*2000./4.7 *6.241*1000/fDeconNorm;
335  return deconNoise;
336 }
337 
338 //----------------------------------------------------------------------
339 // Initialization method.
340 // Here we do initialization that can't be done in the constructor.
341 // All public methods should ensure that this method is called as necessary.
343 {
344  if(!fInit) {
345  fInit = true;
346 
347  // Do microboone-specific configuration of SignalShaping by providing
348  // microboone response and filter functions.
349 
350  // Calculate field and electronics response functions.
351 
352  // Lazy evaluation in a multi-threaded environment is problematic.
353  // The best we can do here is to use the global data available
354  // through detector-properties service.
355  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
356  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob(clockData);
357  SetFieldResponse(clockData, detProp);
359 
360  // Configure convolution kernels.
361 
366  //fColSignalShaping.SetPeakResponseTime(0.);
367 
369 
374  //fIndSignalShaping.SetPeakResponseTime(0.);
375 
377 
382  //fIndSignalShaping.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*(fabs(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  // Collection plane
492  for ( int ibin = 1; ibin <= fFieldResponseHist[2]->GetNbinsX(); ibin++ )
493  fColFieldResponse[ibin-1] = fColFieldRespAmp*fFieldResponseHist[2]->GetBinContent( ibin )/integral;
494  } else
495  {
496  //////////////////////////////////////////////////
497  mf::LogInfo("SignalShapingServiceDUNE35t") << " using the old field shape " ;
498  double integral = 0.;
499  for(int i = 1; i < nbinc; ++i){
500  fColFieldResponse[i] = fColFieldResponse[i-1] + 1.0;
501  integral += fColFieldResponse[i];
502  }
503 
504  for(int i = 0; i < nbinc; ++i){
506  }
507 
508  // now the induction plane
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 //----------------------------------------------------------------------
527 // Calculate microboone field response.
528 void util::SignalShapingServiceDUNE35t::SetElectResponse(double shapingtime, double gain)
529 {
530  // Get services.
531 
534 
535  MF_LOG_DEBUG("SignalShapingDUNE35t") << "Setting DUNE35t electronics response function...";
536 
537  int nticks = fft->FFTSize();
538  fElectResponse.resize(nticks, 0.);
539  std::vector<double> time(nticks,0.);
540 
541  //Gain and shaping time variables from fcl file:
542  double Ao = 1.0;
543  double To = shapingtime; //peaking time
544 
545  // this is actually sampling time, in ns
546  // mf::LogInfo("SignalShapingDUNE35t") << "Check sampling intervals: "
547  // << fSampleRate << " ns"
548  // << "Check number of samples: " << fNTicks;
549 
550  // The following sets the microboone electronics response function in
551  // time-space. Function comes from BNL SPICE simulation of DUNE35t
552  // electronics. SPICE gives the electronics transfer function in
553  // frequency-space. The inverse laplace transform of that function
554  // (in time-space) was calculated in Mathematica and is what is being
555  // used below. Parameters Ao and To are cumulative gain/timing parameters
556  // from the full (ASIC->Intermediate amp->Receiver->ADC) electronics chain.
557  // They have been adjusted to make the SPICE simulation to match the
558  // actual electronics response. Default params are Ao=1.4, To=0.5us.
559  double max = 0;
560 
561  for(size_t i = 0; i < fElectResponse.size(); ++i){
562 
563  //convert time to microseconds, to match fElectResponse[i] definition
564  time[i] = (1.*i)*fInputFieldRespSamplingPeriod *1e-3;
565  fElectResponse[i] =
566  4.31054*exp(-2.94809*time[i]/To)*Ao - 2.6202*exp(-2.82833*time[i]/To)*cos(1.19361*time[i]/To)*Ao
567  -2.6202*exp(-2.82833*time[i]/To)*cos(1.19361*time[i]/To)*cos(2.38722*time[i]/To)*Ao
568  +0.464924*exp(-2.40318*time[i]/To)*cos(2.5928*time[i]/To)*Ao
569  +0.464924*exp(-2.40318*time[i]/To)*cos(2.5928*time[i]/To)*cos(5.18561*time[i]/To)*Ao
570  +0.762456*exp(-2.82833*time[i]/To)*sin(1.19361*time[i]/To)*Ao
571  -0.762456*exp(-2.82833*time[i]/To)*cos(2.38722*time[i]/To)*sin(1.19361*time[i]/To)*Ao
572  +0.762456*exp(-2.82833*time[i]/To)*cos(1.19361*time[i]/To)*sin(2.38722*time[i]/To)*Ao
573  -2.6202*exp(-2.82833*time[i]/To)*sin(1.19361*time[i]/To)*sin(2.38722*time[i]/To)*Ao
574  -0.327684*exp(-2.40318*time[i]/To)*sin(2.5928*time[i]/To)*Ao +
575  +0.327684*exp(-2.40318*time[i]/To)*cos(5.18561*time[i]/To)*sin(2.5928*time[i]/To)*Ao
576  -0.327684*exp(-2.40318*time[i]/To)*cos(2.5928*time[i]/To)*sin(5.18561*time[i]/To)*Ao
577  +0.464924*exp(-2.40318*time[i]/To)*sin(2.5928*time[i]/To)*sin(5.18561*time[i]/To)*Ao;
578 
579  if(fElectResponse[i] > max) max = fElectResponse[i];
580 
581  }// end loop over time buckets
582 
583 
584  MF_LOG_DEBUG("SignalShapingDUNE35t") << " Done.";
585 
586  //normalize fElectResponse[i], before the convolution
587 
588  for(auto& element : fElectResponse){
589  element /= max;
590  element *= fADCPerPCAtLowestASICGain * 1.60217657e-7;
591  element *= gain / 4.7;
592  }
593 
594  return;
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 
630  fIndUFilterFunc->SetRange(0, double(n));
631 
632  for(int i=0; i<=n; ++i) {
633  double freq = 500. * i / (ts * n); // Cycles / microsecond.
634  double f = fIndUFilterFunc->Eval(freq);
635  fIndUFilter[i] = TComplex(f, 0.);
636  }
637 
638  fIndVFilterFunc->SetRange(0, double(n));
639 
640  for(int i=0; i<=n; ++i) {
641  double freq = 500. * i / (ts * n); // Cycles / microsecond.
642  double f = fIndVFilterFunc->Eval(freq);
643  fIndVFilter[i] = TComplex(f, 0.);
644  }
645 
646  }
647  else
648  {
649 
650  for(int i=0; i<=n; ++i) {
651  double f = fFilterHist[2]->GetBinContent(i); // hardcoded plane numbers. Bad. To change later.
652  fColFilter[i] = TComplex(f, 0.);
653  double g = fFilterHist[1]->GetBinContent(i);
654  fIndVFilter[i] = TComplex(g, 0.);
655  double h = fFilterHist[0]->GetBinContent(i);
656  fIndUFilter[i] = TComplex(h, 0.);
657  }
658  }
659 
660  // fIndUSignalShaping.AddFilterFunction(fIndUFilter);
661  // fIndVSignalShaping.AddFilterFunction(fIndVFilter);
662  // fColSignalShaping.AddFilterFunction(fColFilter);
663 
664 }
665 
666 
667 //----------------------------------------------------------------------
668 // Sample microboone response (the convoluted field and electronic
669 // response), will probably add the filter later
671 {
672  // Get services
675 
676  // Operation permitted only if output of rebinning has a larger bin size
678  throw cet::exception(__FUNCTION__) << "\033[93m"
679  << "Invalid operation: cannot rebin to a more finely binned vector!"
680  << "\033[00m" << std::endl;
681 
682  int nticks = fft->FFTSize();
683  std::vector<double> SamplingTime( nticks, 0. );
684  for ( int itime = 0; itime < nticks; itime++ ) {
685  SamplingTime[itime] = (1.*itime) * sampling_rate(clockData);
686  /// VELOCITY-OUT ... comment out kDVel usage here
687  //SamplingTime[itime] = (1.*itime) * sampling_rate(clockData) / kDVel;
688  }
689 
690  // Sampling
691  for ( int iplane = 0; iplane < 3; iplane++ ) {
692  const std::vector<double>* pResp;
693  switch ( iplane ) {
694  case 0: pResp = &(fIndUSignalShaping.Response_save()); break;
695  case 1: pResp = &(fIndVSignalShaping.Response_save()); break;
696  default: pResp = &(fColSignalShaping.Response_save()); break;
697  }
698 
699  std::vector<double> SamplingResp(nticks , 0. );
700 
701 
702  int nticks_input = pResp->size();
703  std::vector<double> InputTime(nticks_input, 0. );
704  for ( int itime = 0; itime < nticks_input; itime++ ) {
705  InputTime[itime] = (1.*itime) * fInputFieldRespSamplingPeriod;
706  }
707 
708 
709  /*
710  Much more sophisticated approach using a linear (trapezoidal) interpolation
711  Current default!
712  */
713  int SamplingCount = 0;
714  for ( int itime = 0; itime < nticks; itime++ ) {
715  int low = -1, up = -1;
716  for ( int jtime = 0; jtime < nticks_input; jtime++ ) {
717  if ( InputTime[jtime] == SamplingTime[itime] ) {
718  SamplingResp[itime] = (*pResp)[jtime];
719  /// VELOCITY-OUT ... comment out kDVel usage here
720  //SamplingResp[itime] = kDVel * (*pResp)[jtime];
721  SamplingCount++;
722  break;
723  } else if ( InputTime[jtime] > SamplingTime[itime] ) {
724  low = jtime - 1;
725  up = jtime;
726  SamplingResp[itime] = (*pResp)[low] + ( SamplingTime[itime] - InputTime[low] ) * ( (*pResp)[up] - (*pResp)[low] ) / ( InputTime[up] - InputTime[low] );
727  /// VELOCITY-OUT ... comment out kDVel usage here
728  //SamplingResp[itime] *= kDVel;
729  SamplingCount++;
730  break;
731  } else {
732  SamplingResp[itime] = 0.;
733  }
734  } // for ( int jtime = 0; jtime < nticks; jtime++ )
735  } // for ( int itime = 0; itime < nticks; itime++ )
736  SamplingResp.resize( SamplingCount, 0.);
737 
738 
739 
740 
741  switch ( iplane ) {
742  case 0: fIndUSignalShaping.AddResponseFunction( SamplingResp, true ); break;
743  case 1: fIndVSignalShaping.AddResponseFunction( SamplingResp, true ); break;
744  default: fColSignalShaping.AddResponseFunction( SamplingResp, true ); break;
745  }
746 
747  if (fDebugFieldShape){
748  if (iplane == 0){
749  std::ofstream outfile("resutest.txt");
750  for (size_t i = 0; i<SamplingResp.size(); ++i){
751  outfile<<i<<" "<<SamplingResp[i]<<std::endl;
752  }
753  outfile.close();
754  }
755  else if (iplane==1){
756  std::ofstream outfile("resvtest.txt");
757  for (size_t i = 0; i<SamplingResp.size(); ++i){
758  outfile<<i<<" "<<SamplingResp[i]<<std::endl;
759  }
760  outfile.close();
761  }
762  else if (iplane==2){
763  std::ofstream outfile("resztest.txt");
764  for (size_t i = 0; i<SamplingResp.size(); ++i){
765  outfile<<i<<" "<<SamplingResp[i]<<std::endl;
766  }
767  outfile.close();
768  }
769  }
770 
771  } // for ( int iplane = 0; iplane < fNPlanes; iplane++ )
772 
773  return;
774 }
775 
776 
777 
779  unsigned int const channel) const
780 {
782  //geo::SigType_t sigtype = geom->SignalType(channel);
783 
784  // we need to distinguis between the U and V planes
785  geo::View_t view = geom->View(channel);
786 
787  double time_offset = 0;
788 
789  if(view == geo::kU)
790  time_offset = fFieldResponseTOffset.at(0) + fCalibResponseTOffset.at(0);
791  else if(view == geo::kV)
792  time_offset = fFieldResponseTOffset.at(1) + fCalibResponseTOffset.at(1);
793  else if(view == geo::kZ)
794  time_offset = fFieldResponseTOffset.at(2) + fCalibResponseTOffset.at(2);
795  else
796  throw cet::exception("SignalShapingServiceDUNE35t")<< "can't determine"
797  << " View\n";
798 
799  return clockData.TPCClock().Ticks(time_offset/1.e3);
800 
801 }
802 
803 
804 namespace util {
805 
807 
808 }
TF1 * fIndUFilterFunc
Parameterized induction filter function.
void set_normflag(bool flag)
const std::vector< double > & Response_save() const
Definition: SignalShaping.h:78
TF1 * fIndVFieldFunc
Parameterized induction field shape function.
int FieldResponseTOffset(detinfo::DetectorClocksData const &clockData, unsigned int const channel) const
Namespace for general, non-LArSoft-specific utilities.
TF1 * fColFieldFunc
Parameterized collection field shape function.
double GetShapingTime(unsigned int const channel) const
void SetFieldResponse(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp)
void reconfigure(const fhicl::ParameterSet &pset)
std::vector< double > fShapeTimeConst
time constants for exponential shaping
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
static constexpr double g
Definition: Units.h:144
void ShiftData(std::vector< TComplex > &input, double shift)
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
Service to provide microboone-specific signal shaping for simulation (convolution) and reconstruction...
TH1F * fFieldResponseHist[3]
Histogram used to hold the field response, hardcoded for the time being.
void SetElectResponse(double shapingtime, double gain)
TF1 * fColFilterFunc
Parameterized collection filter function.
double GetRawNoise(unsigned int const channel) const
void SetFilters(detinfo::DetectorClocksData const &clockData)
void AddResponseFunction(const std::vector< double > &resp, bool ResetResponse=false)
Planes which measure Z direction.
Definition: geo_types.h:132
bool fDebugFieldShape
Save field response shape to a text file.
bool fUseFunctionFieldShape
Flag that allows to use a parameterized field response instead of the hardcoded version.
uint8_t channel
Definition: CRTFragment.hh:201
double fColFieldRespAmp
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
bool fGetFilterFromHisto
Flag that allows to use a filter function from a histogram instead of the functional dependency...
Planes which measure U.
Definition: geo_types.h:129
int FFTSize() const
Definition: LArFFT.h:69
const double e
void CalculateDeconvKernel() const
std::void_t< T > n
T get(std::string const &key) const
Definition: ParameterSet.h:271
TF1 * fIndUFieldFunc
Parameterized induction field shape function.
double fIndVFieldRespAmp
amplitude of response to field
ElecClock const & TPCClock() const noexcept
Borrow a const TPC clock with time set to Trigger time [us].
double GetASICGain(unsigned int const channel) const
double GetDeconNoise(unsigned int const channel) const
void SetResponseSampling(detinfo::DetectorClocksData const &clockData)
bool fUseHistogramFieldShape
Flag that turns on field response shapes from histograms.
static int max(int a, int b)
double DriftVelocity(double efield=0., double temperature=0.) const
cm/us
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
std::vector< double > fFieldResponseTOffset
Time offset for field response in ns.
const util::SignalShaping & SignalShaping(unsigned int channel) const
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
#define DEFINE_ART_SERVICE(svc)
TF1 * fIndVFilterFunc
Parameterized induction filter function.
Encapsulate the construction of a single detector plane.
Contains all timing reference information for the detector.
double fADCPerPCAtLowestASICGain
Pulse amplitude gain for a 1 pc charge impulse after convoluting it the with field and electronics re...
#define MF_LOG_DEBUG(id)
std::string find_file(std::string const &filename) const
Definition: search_path.cc:96
double fIndUFieldRespAmp
amplitude of response to field
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
double fInputFieldRespSamplingPeriod
Sampling period in the input field response.
LArSoft geometry interface.
Definition: ChannelGeo.h:16
SignalShapingServiceDUNE35t(const fhicl::ParameterSet &pset, art::ActivityRegistry &reg)
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
int fNFieldBins
number of bins for field response
QTextStream & endl(QTextStream &s)
Encapsulate the construction of a single detector plane.
TH1D * fFilterHist[3]
Histogram used to hold the collection filter, hardcoded for the time being.