LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
CreateHybridLibrary_module.cc
Go to the documentation of this file.
1 // Chris Backhouse, UCL, Nov 2017
4 
9 
13 
14 #include "TBranch.h"
15 #include "TCanvas.h"
16 #include "TF1.h"
17 #include "TFile.h"
18 #include "TGraph.h"
19 #include "TH1.h"
20 #include "TStyle.h"
21 #include "TTree.h"
22 #include "TVectorD.h"
23 
24 #include <iostream>
25 
26 #define PI 3.14159265
27 
28 namespace fhicl {
29  class ParameterSet;
30 }
31 
32 namespace phot {
34  public:
35  explicit CreateHybridLibrary(const fhicl::ParameterSet& p);
36 
37  // Plugins should not be copied or assigned.
40  CreateHybridLibrary& operator=(const CreateHybridLibrary&) = delete;
41  CreateHybridLibrary& operator=(CreateHybridLibrary&&) = delete;
42 
43  void analyze(const art::Event& e) override;
44  };
45 
46  //--------------------------------------------------------------------
47  CreateHybridLibrary::CreateHybridLibrary(const fhicl::ParameterSet& p) : EDAnalyzer(p)
48  {
49 
51 
53  sim::PhotonVoxelDef voxdef = pvs->GetVoxelDef();
54 
55  TFile* fout_full = new TFile("full.root", "RECREATE");
56  TFile* fout_fit = new TFile("fit.root", "RECREATE");
57 
58  std::cout << voxdef.GetNVoxels() << " voxels for each of " << geom->NOpDets() << " OpDets"
59  << std::endl;
60  std::cout << std::endl;
61 
62  //EP = Exception points: the parameterization is not a good description of the visibility and the value of the Photon Library is kept.
63  long totExceptions = 0;
64  long totPts = 0;
65 
66  for (unsigned int opdetIdx = 0; opdetIdx < geom->NOpDets(); ++opdetIdx) {
67  std::cout << opdetIdx << " / " << geom->NOpDets() << std::endl;
68 
69  TDirectory* d_full = fout_full->mkdir(TString::Format("opdet_%d", opdetIdx).Data());
70  TDirectory* d_fit = fout_fit->mkdir(TString::Format("opdet_%d", opdetIdx).Data());
71 
72  d_full->cd();
73  TTree* tr_full = new TTree("tr", "tr");
74  int vox, taken;
75  float dist, vis, psi, theta, xpos;
76  tr_full->Branch("vox", &vox);
77  tr_full->Branch("dist", &dist);
78  tr_full->Branch("vis", &vis);
79  tr_full->Branch("taken", &taken);
80  tr_full->Branch("psi",
81  &psi); //not needed to parameterize the visibilities, useful for tests in SP
82  tr_full->Branch("theta",
83  &theta); //not needed to parameterize the visibilities, useful for tests in SP
84  tr_full->Branch("xpos",
85  &xpos); //not needed to parameterize the visibilities, useful for tests in SP
86 
87  const geo::OpDetGeo& opdet = geom->OpDetGeoFromOpDet(opdetIdx);
88  auto const opdetCenter = opdet.GetCenter();
89  //std::cout << "OpDet position " << opdetIdx << ": " << opdetCenter << std::endl;
90 
91  struct Visibility {
92  Visibility(int vx, int t, float d, float v, float p, float th, float xp)
93  : vox(vx), taken(t), dist(d), vis(v), psi(p), theta(th), xpos(xp)
94  {}
95  int vox;
96  int taken;
97  float dist;
98  float vis;
99  float psi;
100  float theta;
101  float xpos;
102  };
103  TCanvas* c1 = new TCanvas("c1", "c1");
104  //c1->SetCanvasSize(1500, 1500);
105  c1->SetWindowSize(600, 600);
106  //c1->Divide(1,2);
107  TGraph g;
108  TGraph g2;
109 
110  std::vector<Visibility> viss;
111  viss.reserve(voxdef.GetNVoxels());
112 
113  for (unsigned int voxIdx = 0U; voxIdx < voxdef.GetNVoxels(); ++voxIdx) {
114 
115  const auto voxvec = voxdef.GetPhotonVoxel(voxIdx).GetCenter();
116  const double xyzvox[] = {voxvec.X(), voxvec.Y(), voxvec.Z()};
117  const double fc_y =
118  600; //624cm is below the center of the first voxel outside the Field Cage
119  const double fc_z = 1394;
120  const double fc_x = 350;
121  taken = 0;
122  //DP does not need variable "taken" because all voxels are inside the Field Cage for the Photon Library created in LightSim.
123  //DP taken = 1;
124  dist = opdet.DistanceToPoint(voxvec);
125  vis = pvs->GetVisibility(xyzvox, opdetIdx); // TODO use Point_t when available
126  // all voxels outside the Field Cage would be assigned these values of psi and theta
127  psi = 100;
128  theta = 200;
129  xpos = voxvec.X();
130 
131  if ((voxvec.X() - opdetCenter.X()) < 0) {
132  psi = atan((voxvec.Y() - opdetCenter.Y()) / (-voxvec.X() + opdetCenter.X()));
133  }
134 
135  if (voxvec.X() < fc_x && voxvec.X() > -fc_x && voxvec.Y() < fc_y && voxvec.Y() > -fc_y &&
136  voxvec.Z() > -9 && voxvec.Z() < fc_z) {
137  g.SetPoint(g.GetN(), dist, vis * dist * dist);
138  taken = 1;
139  psi = atan((voxvec.Y() - opdetCenter.Y()) / (voxvec.X() - opdetCenter.X())) * 180.0 /
140  PI; // psi takes values within (-PI/2, PI/2)
141  theta = acos((voxvec.Z() - opdetCenter.Z()) / dist) * 180.0 /
142  PI; // theta takes values within (0 (beam direction, z), PI (-beam direction, -z))
143 
144  if ((voxvec.X() - opdetCenter.X()) < 0) {
145  psi = atan((voxvec.Y() - opdetCenter.Y()) / (-voxvec.X() + opdetCenter.X()));
146  }
147  }
148  tr_full->Fill();
149  viss.emplace_back(voxIdx, taken, dist, vis, psi, theta, xpos);
150  } // end for voxIdx
151 
152  d_full->cd();
153  tr_full->Write();
154  delete tr_full;
155 
156  g.SetMarkerStyle(7);
157  c1->cd();
158  g.Draw("ap");
159  g.GetXaxis()->SetTitle("Distance (cm)");
160  g.GetYaxis()->SetTitle("Visibility #times r^{2}");
161  g.Fit("expo");
162  TF1* fit = g.GetFunction("expo");
163 
164  d_fit->cd();
165  TVectorD fitres(2);
166  fitres[0] = fit->GetParameter(0);
167  fitres[1] = fit->GetParameter(1);
168  fitres.Write("fit");
169 
170  gPad->SetLogy();
171 
172  TH1F h("", "", 200, 0, 20);
173 
174  d_fit->cd();
175  TTree* tr_fit = new TTree("tr", "tr");
176  tr_fit->Branch("vox", &vox);
177  tr_fit->Branch("dist", &dist);
178  tr_fit->Branch("vis", &vis);
179  tr_fit->Branch("taken", &taken);
180  tr_fit->Branch("psi", &psi);
181  tr_fit->Branch("theta", &theta);
182  tr_fit->Branch("xpos", &xpos);
183 
184  for (const Visibility& v : viss) {
185  // 2e-5 is the magic scaling factor to get back to integer photon
186  // counts. TODO this will differ for new libraries, should work out a
187  // way to communicate it or derive it.
188  const double obs = v.vis / 2e-5; //taken from the Photon Library
189  const double pred =
190  fit->Eval(v.dist) / (v.dist * v.dist) / 2e-5; //calculated with parameterization
191 
192  //DP const double obs = v.vis / 1e-7; //magic scaling factor for DP library created in LightSim
193  //Minimal amount of detected photons is 50, bc of Landau dustribution
194  //Those voxels with detected photons < 50 were set to 0
195  //DP const double pred = fit->Eval(v.dist) / (v.dist*v.dist) / 1e-7; //calculated with parametrisation
196  //std::cout << "observed = "<<obs<<" predicted (by parametrization) = "<<pred <<std::endl;
197 
198  // Log-likelihood ratio for poisson statistics
199  double chisq = 2 * (pred - obs);
200  if (obs) chisq += 2 * obs * log(obs / pred);
201 
202  vox = v.vox;
203  dist = v.dist;
204  vis = pred * 2e-5;
205  psi = v.psi;
206  theta = v.theta;
207  xpos = v.xpos;
208  //DP vis = pred *1e-7;
209 
210  if (v.taken == 1) { h.Fill(chisq); }
211 
212  if (
213  chisq >
214  9) { //equivalent to more than 9 chisquare = 3 sigma //maybe play around with this cutoff
215  g2.SetPoint(g2.GetN(), v.dist, v.vis * v.dist * v.dist);
216  vis = obs * 2e-5;
217  //DP vis = obs *1e-7;
218  tr_fit->Fill();
219  }
220  }
221 
222  d_fit->cd();
223  tr_fit->Write();
224  delete tr_fit;
225  g2.SetMarkerSize(1);
226  g2.SetLineWidth(3);
227  g2.SetMarkerStyle(7);
228  g2.SetMarkerColor(kRed);
229  gStyle->SetLabelSize(.04, "XY");
230  gStyle->SetTitleSize(.04, "XY");
231  c1->cd();
232  g2.Draw("p same");
233  c1->SaveAs(TString::Format("plots/Chris_vis_vs_dist_%d.png", opdetIdx).Data());
234 
235  h.GetXaxis()->SetTitle("#chi^{2}");
236  h.GetYaxis()->SetTitle("Counts");
237  gStyle->SetLabelSize(.04, "XY");
238  gStyle->SetTitleSize(.04, "XY");
239  h.Draw("hist");
240  std::cout << "Integral(90,-1)/Integral(all) = " << h.Integral(90, -1) / h.Integral(0, -1)
241  << std::endl;
242  std::cout << "*****************************" << std::endl;
243  totExceptions += h.Integral(90, -1);
244  totPts += h.Integral(0, -1);
245  gPad->Print(TString::Format("plots/chisq_opdet_%d.eps", opdetIdx).Data());
246 
247  delete c1;
248  } // end for opdetIdx
249 
250  std::cout << totExceptions << " exceptions from " << totPts
251  << " points = " << (100. * totExceptions) / totPts << "%" << std::endl;
252 
253  delete fout_full;
254  delete fout_fit;
255  exit(0); // We're done :)
256  }
257 
258  //--------------------------------------------------------------------
260 
262 } // namespace
Definitions of voxel data structures.
OpDetGeo const & OpDetGeoFromOpDet(unsigned int OpDet) const
Returns the geo::OpDetGeo object for the given detector number.
Float_t vox
Definition: plot.C:38
Representation of a region of space diced into voxels.
Definition: PhotonVoxels.h:58
void analyze(const art::Event &e) override
TCanvas * c1
Definition: plotHisto.C:7
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
parameter set interface
Float_t d
Definition: plot.C:235
unsigned int NOpDets() const
Number of OpDets in the whole detector.
Encapsulate the geometry of an optical detector.
geo::Point_t const & GetCenter() const
Definition: OpDetGeo.h:72
const sim::PhotonVoxelDef & GetVoxelDef() const
double DistanceToPoint(geo::Point_t const &point) const
Returns the distance of the specified point from detector center [cm].
Definition: OpDetGeo.cxx:98
General LArSoft Utilities.
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
Point GetCenter() const
Returns the center of the voxel (type Point).
Definition: PhotonVoxels.h:186
unsigned int GetNVoxels() const
Returns the total number of voxels in the volume.
Float_t e
Definition: plot.C:35
float GetVisibility(Point const &p, unsigned int OpChannel, bool wantReflected=false) const
art framework interface to geometry description
PhotonVoxel GetPhotonVoxel(int ID) const