FilterAnalyzerRunList_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: FilterAnalyzerRunList
3 // Module Type: analyser
4 // File: FilterAnalyzerRunList_module.cc
5 // Author: Karl Warburton (k.warburton@sheffield.ac.uk), April 2016
6 //
7 // A quick analysis module for looking at the filter.
8 //
9 // Runs over an artdaq-formatted file and produces a tree or histogram,
10 // filled for each channel combination and the respective correlation.
11 ////////////////////////////////////////////////////////////////////////
12 
13 // framework
20 #include "art_root_io/TFileService.h"
21 #include "art_root_io/TFileDirectory.h"
23 #include "fhiclcpp/ParameterSet.h"
25 
26 // lbne-artdaq
27 #include "lbne-raw-data/Overlays/TpcMilliSliceFragment.hh"
28 #include "artdaq-core/Data/Fragment.hh"
29 
30 // larsoft
32 #include "lardataobj/RawData/raw.h"
34 #include "tpcFragmentToRawDigits.h"
41 #include "cetlib/getenv.h"
42 
43 // c++
44 #include <memory>
45 #include <array>
46 #include <iostream>
47 #include <fstream>
48 #include <sstream>
49 
50 // ROOT
51 #include "TMath.h"
52 #include "TTree.h"
53 #include "TF1.h"
54 #include "TH1.h"
55 #include "TH2.h"
56 #include "TVirtualFFT.h"
57 #include "TStyle.h"
58 
59 namespace DAQToOffline {
60  class FilterAnalyzerRunList;
61 }
62 
64 public:
65 
66  explicit FilterAnalyzerRunList(fhicl::ParameterSet const & pset);
67  // The destructor generated by the compiler is fine for classes
68  // without bare pointers or other resource use.
69 
70  // Plugins should not be copied or assigned.
75 
76  void analyze(art::Event const& evt) override;
77  void reconfigure(const fhicl::ParameterSet &pset);
78 
79 private:
80 
83 
84  TF1* fColFilterFunc; ///< Parameterized collection filter function.
85  TF1* fIndUFilterFunc; ///< Parameterized induction filter function.
86  TF1* fIndVFilterFunc; ///< Parameterized induction filter function.
87 
88  const lariov::DetPedestalProvider& fPedestalRetrievalAlg = *(lar::providerFrom<lariov::DetPedestalService>());
89 
90  int ThisRunSeq = 0;
91  std::vector<int> MyUsefulChans;
92 
95  TH2F* RawFFT_APAs;
96  TH2F* FixFFT_APAs;
97 
98  TH2F* FFTRaw[36];
99  TH2F* FFTFix[36];
100 
101  int NumRuns = 119;
102 };
103 
105 
106  this->reconfigure(pset);
107  gStyle->SetOptStat(0);
108 
109  MyUsefulChans.push_back(10); MyUsefulChans.push_back(70); MyUsefulChans.push_back(110);
110  MyUsefulChans.push_back(160); MyUsefulChans.push_back(205); MyUsefulChans.push_back(260);
111  MyUsefulChans.push_back(300); MyUsefulChans.push_back(410); MyUsefulChans.push_back(500);
112 
113  MyUsefulChans.push_back(525); MyUsefulChans.push_back(585); MyUsefulChans.push_back(625);
114  MyUsefulChans.push_back(675); MyUsefulChans.push_back(720); MyUsefulChans.push_back(775);
115  MyUsefulChans.push_back(815); MyUsefulChans.push_back(915); MyUsefulChans.push_back(1015);
116 
117  MyUsefulChans.push_back(1040); MyUsefulChans.push_back(1095); MyUsefulChans.push_back(1135);
118  MyUsefulChans.push_back(1185); MyUsefulChans.push_back(1230); MyUsefulChans.push_back(1285);
119  MyUsefulChans.push_back(1325); MyUsefulChans.push_back(1435); MyUsefulChans.push_back(1525);
120 
121  MyUsefulChans.push_back(1545); MyUsefulChans.push_back(1605); MyUsefulChans.push_back(1645);
122  MyUsefulChans.push_back(1695); MyUsefulChans.push_back(1740); MyUsefulChans.push_back(1795);
123  MyUsefulChans.push_back(1835); MyUsefulChans.push_back(1945); MyUsefulChans.push_back(2035);
124 
125  std::cout << "I have made my useful channel vector. It has size " << MyUsefulChans.size() << ". It's elements are as follows." << std::endl;
126  for (size_t xx=0; xx<MyUsefulChans.size(); ++xx) {
127  std::cout << "MyUsefulChans["<<xx<<"] " << MyUsefulChans[xx] << std::endl;
128  }
129 
131 
132  RawFFT_Planes = tfs->make<TH2F>("RawFFT_Planes", "Raw FFT for all channels grouped by plane; Channel Number; Frequency (KHz)", 36, 0, 36, 1000, 0, 1000 );
133  FixFFT_Planes = tfs->make<TH2F>("FixFFT_Planes", "Raw FFT for all channels grouped by plane; Channel Number; Frequency (KHz)", 36, 0, 36, 1000, 0, 1000 );
134 
135  RawFFT_APAs = tfs->make<TH2F>("RawFFT_APAs", "Raw FFT for all channels grouped by plane; Channel Number; Frequency (KHz)", 36, 0, 36, 1000, 0, 1000 );
136  FixFFT_APAs = tfs->make<TH2F>("FixFFT_APAs", "Raw FFT for all channels grouped by plane; Channel Number; Frequency (KHz)", 36, 0, 36, 1000, 0, 1000 );
137 
138  for (int XBin=0; XBin<36; ++XBin) {
139  std::stringstream oss;
140  oss<<"Chan_"<<MyUsefulChans[XBin];
141  int WhAPA = XBin/9;
142  int WhPla = (XBin/3)%3;
143  int PlaIn = XBin%3;
144  RawFFT_Planes->GetXaxis()->SetBinLabel((WhAPA*3)+(WhPla*12)+PlaIn+1, oss.str().c_str());
145  FixFFT_Planes->GetXaxis()->SetBinLabel((WhAPA*3)+(WhPla*12)+PlaIn+1, oss.str().c_str());
146 
147  RawFFT_APAs->GetXaxis()->SetBinLabel(XBin+1, oss.str().c_str());
148  FixFFT_APAs->GetXaxis()->SetBinLabel(XBin+1, oss.str().c_str());
149  }
150 
151  for (size_t HistoChan=0; HistoChan<MyUsefulChans.size(); HistoChan++) {
152  std::stringstream oss1a, oss1b;
153  oss1a << "RawFFT_"<<HistoChan;
154  oss1b << "Raw FFT for Channel "<<MyUsefulChans[HistoChan]<<"; Run Number; Frequency (KHz)";
155  FFTRaw[HistoChan] = tfs->make<TH2F>(oss1a.str().c_str(), oss1b.str().c_str(), NumRuns, 0, NumRuns, 1000, 0, 1000);
156 
157  std::stringstream oss2a, oss2b;
158  oss2a << "FixFFT_"<<HistoChan;
159  oss2b << "Fix FFT for Channel "<<MyUsefulChans[HistoChan]<<"; Run Number; Frequency (KHz)";
160  FFTFix[HistoChan] = tfs->make<TH2F>(oss2a.str().c_str(), oss2b.str().c_str(), NumRuns, 0, NumRuns, 1000, 0, 1000);
161  }
162 
163 
164 }
165 
167  fDigitModuleLabel = pset.get<std::string>("DigitModuleLabel");
168  fDigitModuleInstance = pset.get<std::string>("DigitModuleInstance");
169 
170  // Make the filter functions.
171  std::string colFilt = pset.get<std::string>("ColFilter");
172  std::vector<double> colFiltParams = pset.get<std::vector<double> >("ColFilterParams");
173  fColFilterFunc = new TF1("colFilter", colFilt.c_str());
174  for(unsigned int i=0; i<colFiltParams.size(); ++i)
175  fColFilterFunc->SetParameter(i, colFiltParams[i]);
176 
177  std::string indUFilt = pset.get<std::string>("IndUFilter");
178  std::vector<double> indUFiltParams = pset.get<std::vector<double> >("IndUFilterParams");
179  fIndUFilterFunc = new TF1("indUFilter", indUFilt.c_str());
180  for(unsigned int i=0; i<indUFiltParams.size(); ++i)
181  fIndUFilterFunc->SetParameter(i, indUFiltParams[i]);
182 
183  std::string indVFilt = pset.get<std::string>("IndVFilter");
184  std::vector<double> indVFiltParams = pset.get<std::vector<double> >("IndVFilterParams");
185  fIndVFilterFunc = new TF1("indVFilter", indVFilt.c_str());
186  for(unsigned int i=0; i<indVFiltParams.size(); ++i)
187  fIndVFilterFunc->SetParameter(i, indVFiltParams[i]);
188 }
189 
191  if (evt.event() != 1) return;
192 
193  ++ThisRunSeq;
194  std::cout << "\n\n\n\nThis Run sequence is " << ThisRunSeq << "\n\n\n" << std::endl;
195  for (size_t HistoChan=0; HistoChan<MyUsefulChans.size(); HistoChan++) {
196  std::stringstream oss;
197  oss<<"Run "<<(int)evt.run();
198  FFTRaw[HistoChan]->GetXaxis()->SetBinLabel(ThisRunSeq, oss.str().c_str());
199  FFTFix[HistoChan]->GetXaxis()->SetBinLabel(ThisRunSeq, oss.str().c_str());
200  }
201 
203 
205  evt.getByLabel(fDigitModuleLabel, fDigitModuleInstance, rawDigitHandle);
206  std::vector<raw::RawDigit> const& rawDigitVector(*rawDigitHandle);
207 
208 
209  std::vector< std::pair<int,int> > ZeroFreq;
210  //ZeroFreq.push_back( std::make_pair(276 , 285 ) );
211  //ZeroFreq.push_back( std::make_pair(558 , 568 ) );
212  //ZeroFreq.push_back( std::make_pair(837 , 849 ) );
213  //ZeroFreq.push_back( std::make_pair(1116, 1127) );
214  //ZeroFreq.push_back( std::make_pair(4340, 5205) );
215 
216  for (size_t DigLoop=0; DigLoop < rawDigitVector.size(); ++DigLoop) {
217  int Channel = rawDigitVector[DigLoop].Channel();
218  size_t NADC = rawDigitVector[DigLoop].NADC();
219  double Pedestal = rawDigitVector[DigLoop].GetPedestal();
220  const geo::View_t view = geo->View(Channel);
221  // Check if this channel is one of the ones I want.
222  for (size_t GotChan=0; GotChan<MyUsefulChans.size(); ++GotChan) {
223  if (MyUsefulChans[GotChan] != Channel) continue;
224 
225  int WhAPA = GotChan/9;
226  int WhPla = (GotChan/3)%3;
227  int PlaIn = GotChan%3;
228  //std::cout << "Looking at Chan " << Channel << ", GotChan " << GotChan << ". I am going to fill bin " << (WhAPA*3)+(WhPla*12)+PlaIn+0.5 << std::endl;
229 
230  //std::cout << "Looking at rawDigitVector["<<DigLoop<<"] it was on channel " << rawDigitVector[DigLoop].Channel() << "("<<Channel<<") it is in View " << view
231  // << ", NADC is " << rawDigitVector[DigLoop].NADC() << " ("<<NADC<<")"
232  // << ", pedestal is " << rawDigitVector[DigLoop].GetPedestal() << " ("<<Pedestal<<")"
233  // << std::endl;
234 
235  // Fill the RawDigit histogram for this histogram.
236  TH1F* hRawDigit = new TH1F("hRawDigit","",NADC,0,NADC/2);
237  TH1F* hRawFFT = new TH1F("hRawFFT" ,"",NADC,0,NADC);
238  for (size_t ADCs=0; ADCs < NADC; ++ADCs) {
239  hRawDigit -> SetBinContent( ADCs+1, rawDigitVector[DigLoop].ADC(ADCs)-Pedestal );
240  }
241  for (size_t ww=NADC; ww<NADC; ++ww)
242  hRawFFT -> SetBinContent( ww, 0 );
243  // Make the FFT for this channel.
244  hRawDigit -> FFT( hRawFFT ,"MAG");
245  for (size_t bin = 0; bin < NADC; ++bin) {
246  double BinVal = hRawFFT->GetBinContent(bin+1);
247  double freq = 2000. * bin / (double)NADC;
248  if (freq < 1000 && BinVal < 1e5) {
249  FFTRaw[GotChan] -> Fill( (ThisRunSeq-0.5) , freq, BinVal );
250  RawFFT_Planes -> Fill( (WhAPA*3)+(WhPla*12)+PlaIn+0.5, freq, BinVal );
251  RawFFT_APAs -> Fill( GotChan+0.5, freq, BinVal );
252  }
253  }
254 
255  // I want to do an inverse FFT, so need to convert the tranformed FFT into an array....
256  //double Re[NADC], Im[NADC];
257  std::unique_ptr<double[]> Re( new double[NADC]);
258  std::unique_ptr<double[]> Im( new double[NADC]);
259  TVirtualFFT *fft = TVirtualFFT::GetCurrentTransform();
260  fft->GetPointsComplex(Re.get(),Im.get());
261 
262  // Set the noisy frequency range bins to an average value.
263  for (size_t aa=0; aa<ZeroFreq.size(); ++aa) {
264  for (int bb=ZeroFreq[aa].first; bb<ZeroFreq[aa].second; ++bb) {
265  double ReMeanVal=0;
266  double ImMeanVal=0;
267  int Range = 50;
268  for (int cc=0; cc<Range; ++cc) {
269  ReMeanVal += Re[ZeroFreq[aa].first-cc] + Re[ZeroFreq[aa].second+cc];
270  ImMeanVal += Im[ZeroFreq[aa].first-cc] + Im[ZeroFreq[aa].second+cc];
271  }
272  ReMeanVal = ReMeanVal / Range;
273  Re[bb] = Re[1500-bb] = ReMeanVal;
274  ImMeanVal = ImMeanVal / Range;
275  Im[bb] = Im[1500-bb] = ImMeanVal;
276  }
277  }
278  Re[0] = Re[1];
279  Im[0] = Im[1];
280 
281  // Apply the filter...
282  for (size_t bin = 0; bin < NADC; ++bin) {
283  double freq = 2000. * bin / NADC;
284  if (view == geo::kU) { // U plane
285  Re[bin] = Re[bin]*fIndUFilterFunc->Eval(freq);
286  Im[bin] = Im[bin]*fIndUFilterFunc->Eval(freq);
287  } else if ( view == geo::kV) { // V plane
288  Re[bin] = Re[bin]*fIndVFilterFunc->Eval(freq);
289  Im[bin] = Im[bin]*fIndVFilterFunc->Eval(freq);
290  } else if ( view == geo::kZ) { // Collection plane
291  Re[bin] = Re[bin]*fColFilterFunc->Eval(freq);
292  Im[bin] = Im[bin]*fColFilterFunc->Eval(freq);
293  }
294  double MagVal = pow ( Re[bin]*Re[bin] + Im[bin]*Im[bin], 0.5);
295  if (TMath::IsNaN(MagVal)) MagVal = 0;
296 
297  // Now do the big histograms...
298  if (freq < 1000 && MagVal < 1e5) {
299  FFTFix[GotChan] -> Fill( (ThisRunSeq-0.5) , freq, MagVal );
300  FixFFT_Planes -> Fill( (WhAPA*3)+(WhPla*12)+PlaIn+0.5, freq, MagVal );
301  FixFFT_APAs -> Fill( GotChan+0.5, freq, MagVal );
302  }
303  }
304  } // Checking if one of my chosen useful channels
305  } // RawDigit Loop
306  return;
307 }
308 
void reconfigure(const fhicl::ParameterSet &pset)
EventNumber_t event() const
Definition: DataViewImpl.cc:96
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
std::string string
Definition: nybbler.cc:12
Planes which measure V.
Definition: geo_types.h:126
constexpr T pow(T x)
Definition: pow.h:72
Definition of basic raw digits.
Planes which measure Z direction.
Definition: geo_types.h:128
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:27
FilterAnalyzerRunList(fhicl::ParameterSet const &pset)
TF1 * fIndUFilterFunc
Parameterized induction filter function.
Planes which measure U.
Definition: geo_types.h:125
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Definition: DataViewImpl.h:446
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:69
Collect all the RawData header files together.
T get(std::string const &key) const
Definition: ParameterSet.h:231
TF1 * fIndVFilterFunc
Parameterized induction filter function.
FilterAnalyzerRunList & operator=(FilterAnalyzerRunList const &)=delete
TF1 * fColFilterFunc
Parameterized collection filter function.
RunNumber_t run() const
Definition: DataViewImpl.cc:82
void analyze(art::Event const &evt) override
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
const lariov::DetPedestalProvider & fPedestalRetrievalAlg
ChannelMappingService::Channel Channel
QTextStream & bin(QTextStream &s)
Interface for experiment-specific channel quality info provider.
TCEvent evt
Definition: DataStructs.cxx:7
Interface for experiment-specific service for channel quality info.
Namespace collecting geometry-related classes utilities.
QTextStream & endl(QTextStream &s)