WCSim
plot_pmts.C
Go to the documentation of this file.
1 #include <iostream>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <algorithm>
5 
6 #include "TTree.h"
7 #include "TGraph.h"
8 #include "TEllipse.h"
9 #include "TH1F.h"
10 #include "THStack.h"
11 #include "TH1D.h"
12 #include "TStyle.h"
13 #include "TROOT.h"
14 #include "TSystem.h"
15 #include "TCanvas.h"
16 #include "TFile.h"
17 
18 #include "WCSimRootOptions.hh"
19 #include "WCSimRootGeom.hh"
20 #include "WCSimRootEvent.hh"
21 
22 /*
23  Produces X-Y and R-Z displays for each PMT type
24  - In the X-Y displays, the detector edge is shown as a circle
25  - Note that both top & bottom cap PMTs are displayed on this plot
26  By construction in WCSim, PMTs are placed in the same location on each end cap
27  - In the R-Z displays, the detector edge is the edge of the image
28 
29 Output
30 - display_geo.pdf has the 2D plots
31  - There is one page per PMT type (20" / OD / mPMT)
32 - display_geo.root has
33  - The TGraph's used to create the 2D plots
34  - Additionally two THStack's (one for R, one for Z), that contain the 1D information
35 
36 Running
37 From the command line, something like
38 root -b -q $WCSIMDIR/sample-root-scripts/plot_pmts.C+g'(1,"wcsim.root")'
39 or however you prefer to run your root macros
40 */
41 
42 int display(int verbose, //how verbose should the printout be? 0 = lowest, higher number = more
43  const char *filename); //WCSim file. Should work for all geometries
44 
45 TGraph * MakeGraph(vector<pair<double, double> > v, int col, int style, const float size=1.5)
46 {
47  cout << "Making graph from vector of size " << v.size() << endl;
48  TGraph * g = new TGraph(v.size());
49  for(size_t i = 0; i < v.size(); i++) {
50  auto pair = v.at(i);
51  g->SetPoint(i, pair.first, pair.second);
52  //cout << pair.first << "\t" << pair.second << endl;
53  }
54  g->SetMarkerColor(col);
55  g->SetMarkerStyle(style);
56  g->SetMarkerSize(size);
57  return g;
58 }
59 
60 double GetAzimuth(double x, double y)
61 {
62  double t = TMath::ATan(y / x);
63  if(x < 0) {
64  if(y < 0)
65  t -= TMath::Pi();
66  else
67  t += TMath::Pi();
68  }
69  t = TMath::ATan2(y, x);
70  return t;
71 }
72 
73 void PrintPMT(const WCSimRootPMT * tube, const int ipmt)
74 {
75  double x, y, z, r, t;
76  x = tube->GetPosition(0);
77  y = tube->GetPosition(1);
78  z = tube->GetPosition(2);
79  r = TMath::Sqrt(x*x + y*y);
80  t = GetAzimuth(x, y);
81  cout << std::setw(6) << ipmt
82  << " " << std::setw(8) << tube->GetTubeNo()
83  << " " << std::setw(8) << tube->GetmPMTNo()
84  << " " << std::setw(3) << tube->GetmPMT_PMTNo()
85  << " " << std::setw(9) << x
86  << " " << std::setw(9) << y
87  << " " << std::setw(9) << z
88  << " " << std::setw(9) << r
89  << " " << std::setw(9) << t
90  << " " << std::setw(2) << tube->GetCylLoc()
91  << endl;
92 }
93 
94 std::string CycLocs[9] = {"ID top cap",
95  "ID barrel",
96  "ID bottom cap",
97  "OD bottom cap",
98  "OD barrel",
99  "OD top cap",
100  "mPMT top cap",
101  "mPMT barrel",
102  "mPMT bottom cap"};
103 
105  TCanvas * c,
106  int verbose)
107 {
108  const float detR = geo->GetWCCylRadius();
109  const float detZ = geo->GetWCCylLength() / 2;
110 
111  TClonesArray * pmts = geo->GetPMTs();
112  cout << "N 20\" PMTs in TClonesArray: " << pmts->GetEntries() << endl
113  << "N 20\" PMTs from rootgeom : " << geo->GetWCNumPMT() << endl;
114  TClonesArray * pmts2 = geo->GetPMTs(true);
115  cout << "N mPMTs in TClonesArray: " << pmts2->GetEntries() << endl
116  << "N mPMTs from rootgeom : " << geo->GetWCNumPMT(true) << endl;
117  TClonesArray * pmtsod = geo->GetODPMTs();
118  cout << "N OD PMTs in TClonesArray: " << pmtsod->GetEntries() << endl;
119  cout << "N OD PMTs from rootgeom : " << geo->GetODWCNumPMT() << endl;
120 
121  const int narrays = 9;
122  vector<pair<double, double> > pos[narrays];
123  TH1D * Rs[narrays], * Zs[narrays];
124  vector<double> Rsv[narrays], Zsv[narrays];
125  THStack * stackR = new THStack("stackR", ";R (cm);Number in bin");
126  THStack * stackZ = new THStack("stackZ", ";Z (cm);Number in bin");
127  for(int i = 0; i < narrays; i++) {
128  Rs[i] = new TH1D(TString::Format("R%d", i), ";R (cm);Number in bin", TMath::Ceil(detR*8), 0, detR);
129  Zs[i] = new TH1D(TString::Format("Z%d", i), ";Z (cm);Number in bin", TMath::Ceil(detZ*8), -detZ, +detZ);
130  stackR->Add(Rs[i]);
131  stackZ->Add(Zs[i]);
132  }
133  double x, y, z, r, t;
134 
135  //Get the 20" PMT information
136  if(verbose > 1)
137  cout << endl << "20\" PMT list" << endl;
138  for(int ipmt = 0; ipmt < pmts->GetEntries() - 1; ipmt++) {
139  const WCSimRootPMT * tube = geo->GetPMTPtr(ipmt);
140  //get the tube position. Depends on cycloc
141  x = tube->GetPosition(0);
142  y = tube->GetPosition(1);
143  z = tube->GetPosition(2);
144  r = TMath::Sqrt(x*x + y*y);
145  t = GetAzimuth(x, y);
146  const int loc = tube->GetCylLoc();
147  switch(loc) {
148  //endcap
149  case 0:
150  case 2:
151  pos[loc].push_back(std::make_pair(x, y));
152  break;
153  //wall
154  case 1:
155  pos[loc].push_back(std::make_pair(t, z));
156  break;
157  default:
158  cout << "Unknown case " << tube->GetCylLoc() << endl;
159  break;
160  }
161  Rs[loc]->Fill(r);
162  Zs[loc]->Fill(z);
163  Rsv[loc].push_back(r);
164  Zsv[loc].push_back(z);
165  if(verbose > 1)
166  PrintPMT(tube, ipmt);
167  }//20" PMTs
168 
169  //and for OD pmts
170  if(verbose > 1)
171  cout << endl << "OD PMT list" << endl;
172  for(int ipmt = 0; ipmt < pmtsod->GetEntries() - 1; ipmt++) {
173  const WCSimRootPMT * tube = geo->GetODPMTPtr(ipmt);
174  //get the tube position. Depends on cycloc
175  x = tube->GetPosition(0);
176  y = tube->GetPosition(1);
177  z = tube->GetPosition(2);
178  r = TMath::Sqrt(x*x + y*y);
179  t = GetAzimuth(x, y);
180  const int loc = tube->GetCylLoc();
181  switch(loc) {
182  //endcap
183  case 3:
184  case 5:
185  pos[loc].push_back(std::make_pair(x, y));
186  break;
187  //wall
188  case 4:
189  pos[loc].push_back(std::make_pair(t, z));
190  break;
191  default:
192  cout << "Unknown case " << tube->GetCylLoc() << endl;
193  break;
194  }
195  Rs[loc]->Fill(r);
196  Zs[loc]->Fill(z);
197  Rsv[loc].push_back(r);
198  Zsv[loc].push_back(z);
199  if(verbose > 1)
200  PrintPMT(tube, ipmt);
201  }//OD PMTs
202 
203  //and for mPMTs
204  if(verbose > 1)
205  cout << endl << "mPMT list" << endl;
206  for(int ipmt = 0; ipmt < pmts2->GetEntries() - 1; ipmt++) {
207  const WCSimRootPMT * tube = geo->GetPMTPtr(ipmt, true);
208  //get the tube position. Depends on cycloc
209  x = tube->GetPosition(0);
210  y = tube->GetPosition(1);
211  z = tube->GetPosition(2);
212  r = TMath::Sqrt(x*x + y*y);
213  t = GetAzimuth(x, y);
214  const int loc = tube->GetCylLoc();
215  switch(loc) {
216  //endcap
217  case 6:
218  case 8:
219  pos[loc].push_back(std::make_pair(x, y));
220  break;
221  //wall
222  case 7:
223  pos[loc].push_back(std::make_pair(t, z));
224  break;
225  default:
226  cout << "Unknown case " << tube->GetCylLoc() << endl;
227  break;
228  }
229  Rs[loc]->Fill(r);
230  Zs[loc]->Fill(z);
231  Rsv[loc].push_back(r);
232  Zsv[loc].push_back(z);
233  if(verbose > 1)
234  PrintPMT(tube, ipmt);
235  }//mPMTs
236 
237  //now setup the plotting
238  c->SaveAs("display_geo.pdf[");
239  TGraph * g[narrays];
240  Color_t cols[narrays] = {kBlack, kBlue, kRed,
241  kBlack, kBlue, kRed,
242  kBlack, kBlue, kRed};
243  Style_t styles[narrays] = {29, 29, 29,
244  20, 20, 20,
245  21, 21, 21};
246  for(int i = 0; i < narrays; i++) {
247  cout << "Vector " << i << " (" << CycLocs[i]
248  << ") contains " << pos[i].size() << " entries" << endl;
249  g[i] = MakeGraph(pos[i], cols[i], styles[i], 0.2);
250  }
251 
252  TEllipse circle(0, 0, detR);
253  for(int i = 0; i < narrays; i+=3) {
254  c->cd(1)->DrawFrame(-detR,-detR,+detR,+detR,";X (cm);Y (cm)")->GetYaxis()->SetTitleOffset(1);
255  circle.Draw();
256  if(g[i]->GetN())
257  g[i]->Draw("P");
258  if(g[i+2]->GetN())
259  g[i+2]->Draw("P");
260  c->cd(2)->DrawFrame(-TMath::Pi(),-detZ,+TMath::Pi(),+detZ,";Azimuthal angle;Z (cm)")->GetYaxis()->SetTitleOffset(1);
261  if(g[i+1]->GetN())
262  g[i+1]->Draw("P");
263  c->SaveAs("display_geo.pdf");
264  }
265  c->SaveAs("display_geo.pdf]");
266 
267  TFile fout("display_geo.root", "RECREATE");
268  for(int i = 0; i < narrays; i++)
269  g[i]->Write(TString::Format("graph%d", i));
270  stackR->Write();
271  stackZ->Write();
272  fout.Close();
273 
274  for(int i = 0; i < narrays; i++) {
275  cout << i << " " << CycLocs[i] << endl;
276  if(!Rsv[i].size()) {
277  cout << " No PMTs in this cycloc" << endl;
278  continue;
279  }
280  cout << " MIN R: " << *std::min_element(Rsv[i].begin(), Rsv[i].end())
281  << "\t MAX R: " << *std::max_element(Rsv[i].begin(), Rsv[i].end()) << endl;
282  cout << " MIN Z: " << *std::min_element(Zsv[i].begin(), Zsv[i].end())
283  << "\t MAX Z: " << *std::max_element(Zsv[i].begin(), Zsv[i].end()) << endl;
284  }
285  cout << "Detector half z: " << detZ << endl
286  << "Detector radius: " << detR << endl;
287 }
288 
289 
290 
292 int plot_pmts(int verbose=0,
293  const char *filename="wcsim.root")
294 {
295  // Clear global scope
296  //gROOT->Reset();
297 
298  // Open the file
299  TFile * file = new TFile(filename,"read");
300  if (!file->IsOpen()){
301  cout << "Error, could not open input file: " << filename << endl;
302  return -1;
303  }
304 
305  // Geometry tree - only need 1 "event"
306  TTree *geotree = (TTree*)file->Get("wcsimGeoT");
307  WCSimRootGeom *geo = 0;
308  geotree->SetBranchAddress("wcsimrootgeom", &geo);
309  if(verbose) std::cout << "Geotree has: " << geotree->GetEntries() << " entries (1 expected)" << std::endl;
310  if (geotree->GetEntries() == 0) {
311  exit(9);
312  }
313  geotree->GetEntry(0);
314 
315  // Options tree - only need 1 "event"
316  TTree *opttree = (TTree*)file->Get("wcsimRootOptionsT");
317  WCSimRootOptions *opt = 0;
318  opttree->SetBranchAddress("wcsimrootoptions", &opt);
319  if(verbose) std::cout << "Options tree has: " << opttree->GetEntries() << " entries (1 expected)" << std::endl;
320  if (opttree->GetEntries() == 0) {
321  exit(9);
322  }
323  opttree->GetEntry(0);
324  opt->Print();
325 
326  float win_scale = 0.75;
327  int n_wide(2);
328  int n_high(2);
329  TCanvas* c1 = new TCanvas("c1", "First canvas", 1000*n_wide*win_scale, 500*n_high*win_scale);
330  c1->Divide(2,1);
331 
332  DumpGeoTree(geo, c1, verbose);
333 
334  return 0;
335 }
Int_t GetCylLoc() const
Int_t GetODWCNumPMT() const
Detector geometry information (also containing PMT information arrays)
TGraph * MakeGraph(vector< pair< double, double > > v, int col, int style, const float size=1.5)
Definition: plot_pmts.C:45
Float_t GetWCCylLength() const
void PrintPMT(const WCSimRootPMT *tube, const int ipmt)
Definition: plot_pmts.C:73
void Print(Option_t *option="") const
std::string CycLocs[9]
Definition: plot_pmts.C:94
Float_t GetWCCylRadius() const
void DumpGeoTree(WCSimRootGeom *geo, TCanvas *c, int verbose)
Definition: plot_pmts.C:104
int display(int verbose, const char *filename)
int plot_pmts(int verbose=0, const char *filename="wcsim.root")
Definition: plot_pmts.C:292
const WCSimRootPMT * GetODPMTPtr(Int_t i) const
PMT geometry information.
Int_t GetWCNumPMT(bool hybridsecondtype=false) const
const WCSimRootPMT * GetPMTPtr(Int_t i, bool hybridsecondtype=false) const
string filename
Definition: MakeKin.py:235
List of WCSim running options.
Int_t GetTubeNo() const
WCSimRootGeom * geo
TClonesArray * GetPMTs(bool hybridsecondtype=false)
TClonesArray * GetODPMTs()
Int_t GetmPMTNo() const
double GetAzimuth(double x, double y)
Definition: plot_pmts.C:60
Int_t GetmPMT_PMTNo() const
Float_t GetPosition(Int_t i=0) const