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