test_perchanresp.cxx
Go to the documentation of this file.
1 #include "WireCellUtil/Units.h"
2 #include "WireCellUtil/Testing.h"
4 
5 /// needed to pretend like we are doing WCT internals
11 
12 
13 #include "TCanvas.h"
14 #include "TStyle.h"
15 #include "TH2F.h"
16 #include "TAxis.h"
17 #include "TFile.h"
18 
19 #include <vector>
20 #include <string>
21 #include <algorithm>
22 #include <iostream>
23 
24 #include "anode_loader.h" // do not use this
25 
26 using namespace WireCell;
30 
31 using namespace std;
32 
33 int main(int argc, char* argv[])
34 {
35  std::string detector = "uboone";
36  if (argc > 1) {
37  detector = argv[1];
38  }
39  auto anode_tns = anode_loader(detector);
40 
41 
42  // Real component code would get this info from its
43  // configuration.
44  const std::string cr_tn = "PerChannelResponse";
45  const std::string ap_tn = anode_tns[0];
46  const std::string pcr_filename = "microboone-channel-responses-v1.json.bz2";
47 
48 
49  { // User code should never do this.
50  auto icfg = Factory::lookup<IConfigurable>(cr_tn);
51  auto cfg = icfg->default_configuration();
52  cfg["filename"] = pcr_filename;
53  icfg->configure(cfg);
54  }
55 
56 
57  /// Finally, we now pretend to be real component code.
58  auto cr = Factory::find_tn<IChannelResponse>(cr_tn);
59  auto ap = Factory::find_tn<IAnodePlane>(ap_tn);
60 
61  auto bins = cr->channel_response_binning();
62  cerr << "PerChannelResponse with binning: " << bins.nbins() << " bins "
63  << " with sample period " << bins.binsize()/units::us << " us and bounds:"
64  << "[" << bins.min()/units::us << "," << bins.max()/units::us << "]us\n";
65 
66  std::vector<int> planechans[3]; // fixme: will break with DUNE
67  for (auto ch : ap->channels()) {
68  auto wpid = ap->resolve(ch);
69  planechans[wpid.index()].push_back(ch);
70  }
71 
72  auto outfile = TFile::Open(Form("%s.root", argv[0]), "RECREATE");
73 
74  gStyle->SetOptStat(0);
75  TCanvas c("c","c",500,500);
76  c.Divide(3,1);
77 
78  // Desired gain units for showing in the plot
79  const double GU = units::mV/units::fC;
80 
81  for (int iplane=0; iplane<3; ++iplane) {
82  auto& channels = planechans[iplane];
83  std::sort(channels.begin(), channels.end());
84 
85  /// assume all responses in a plane are the same size.
86  const int nsamps = bins.nbins();
87  const double mintus = bins.min()/units::us;
88  const double maxtus = bins.max()/units::us;
89  const int nchans = channels.size();
90 
91  Assert(nsamps>0);
92  Assert(nchans>0);
93 
94 
95  TH2F* hist = new TH2F(Form("hist%d", iplane),
96  Form("Per Channel Response Plane %d [mV/fC]", iplane),
97  nsamps, mintus, maxtus,
98  nchans, 0, nchans
99  );
100  hist->GetXaxis()->SetTitle("sample time (us)");
101  hist->GetYaxis()->SetTitle("channel indices");
102 
103  for (int ich=0; ich<nchans; ++ich) {
104  const auto& resp = cr->channel_response(channels[ich]);
105  for (int isamp=0; isamp<nsamps; ++isamp) {
106  const double Tus = bins.center(isamp)/units::us;
107  hist->Fill(Tus, ich+0.5, resp[isamp]/GU);
108  }
109  }
110 
111  c.cd(iplane+1);
112  hist->Draw("colz");
113  hist->Write();
114  }
115 
116  cerr << "Now ROOT makes the PDF" << endl;
117  c.Print(Form("%s.pdf", argv[0]), "pdf");
118 
119  outfile->Close();
120 
121  return 0;
122 }
std::string string
Definition: nybbler.cc:12
STL namespace.
static const double mV
Definition: Units.h:180
cfg
Definition: dbjson.py:29
std::vector< std::string > anode_loader(std::string detector)
Definition: anode_loader.h:35
#define Assert
Definition: Testing.h:7
static const double fC
Definition: Units.h:113
Definition: Main.h:22
static const double us
Definition: Units.h:105
int main(int argc, char *argv[])
QTextStream & endl(QTextStream &s)