WCSim
read_OD.C
Go to the documentation of this file.
1 // C++ Includes
2 #include <iostream>
3 //#include <algorithm>
4 //#include <iomanip>
5 #include <cmath>
6 
7 // ROOT Includes
8 #include "TH1F.h"
9 #include "TH2F.h"
10 #include "TFile.h"
11 //#include "TApplication.h"
12 
13 
14 // WCSim Includes
15 #include "WCSimRootEvent.hh"
16 #include "WCSimRootGeom.hh"
17 
18 // Defines
19 #define PI 3.141592654
20 
21 /*
22 *How to run:
23 *
24 * enter in the terminal $WCSIMDIR/rootwc/rootwc -l 'read_OD.C("WCSim.root","outputFile.root",false)' to run the code
25 * where you replace WCSim.root with your file name and outputfile with the name you wish to save it under
26 */
27 
28 // A function to easily format the histograms
29 void format_histogram(TH1D* h, std::string title ,std::string xtitle, std::string ytitle){
30  h->SetTitle( title.c_str() );
31  h->GetXaxis()->SetTitle( xtitle.c_str() );
32  h->GetYaxis()->SetTitle( ytitle.c_str() );
33  h->SetLineColor(kRed);
34  h->SetLineWidth(2);
35 }
36 // An (overloaded) function to easily format the histograms
37 void format_histogram(TH2D* h, std::string title ,std::string xtitle, std::string ytitle){
38  h->SetTitle( title.c_str() );
39  h->GetXaxis()->SetTitle( xtitle.c_str() );
40  h->GetYaxis()->SetTitle( ytitle.c_str() );
41 }
42 
43 void read_OD(std::string inFileName, std::string outFileName, bool verbosity){
44 
45 
46  // Some nicely formatted text options
47  std::cout << std::scientific; // This causes all numbers to be displayed in scientific notation.
48  std::cout << std::setprecision(2); // Sets the decimal precision (no more than two decimal places)
49  std::cout << std::left; // Sets the text justification to left
50  const int txtW = 20; // Width of "box" holding text
51  const int numW = 10; // Width of "box" holding numbers
52 
53 
54  // Open the WCSim file
55  TFile *inFile = new TFile(inFileName.c_str(), "READ");
56  if ( !inFile->IsOpen() ){
57  std::cout << "Error: could not open input file \"" << inFileName << "\"." <<std::endl;
58 
59  } else if (verbosity) {
60  std::cout << "Input file: " << inFileName << std::endl;
61  }
62 
63 
64 
65  // Get a pointer to the tree from the input file
66  TTree *wcsimTree = (TTree*) inFile->Get("wcsimT");
67 
68  // Get the number of events in the tree
69  long int nEvent = wcsimTree->GetEntries();
70  if (verbosity) { std::cout << "Number of events: "<< nEvent << std::endl;}
71 
72  // Create a WCSimRootEvent to put stuff from the tree in
73  WCSimRootEvent *wcsimRootID = new WCSimRootEvent();
74  WCSimRootEvent *wcsimRootOD = new WCSimRootEvent();
75 
76  // Set the branch address for reading from the tree
77  TBranch *branch = wcsimTree->GetBranch("wcsimrootevent");
78  TBranch *branchOD = wcsimTree->GetBranch("wcsimrootevent_OD");
79  branch->SetAddress(&wcsimRootID);
80  branchOD->SetAddress(&wcsimRootOD);
81 
82  // Force deletion to prevent memory leak
83  wcsimTree->GetBranch("wcsimrootevent")->SetAutoDelete(kTRUE);
84  wcsimTree->GetBranch("wcsimrootevent_OD")->SetAutoDelete(kTRUE);
85 
86  // Load the geometry tree (only 1 "event")
87  TTree *geoTree = (TTree*) inFile->Get("wcsimGeoT");
89  TBranch *branchG = geoTree->GetBranch("wcsimrootgeom");
90  branchG->SetAddress(&geo);
91 
92  if (verbosity) {std::cout << "Geotree has " << geoTree->GetEntries() << " entries." << std::endl;}
93 
94  geoTree->GetEntry(0);
95 
96  // Start with the main trigger as it always exists and contains most of the info
97  WCSimRootTrigger *wcsimTriggerID;
98  WCSimRootTrigger *wcsimTriggerOD;
99  // Create an output file
100  TFile *outFile = new TFile(outFileName.c_str(), "RECREATE");
101  TTree *outBranch = new TTree("simulation", "simulation");
102 
103 
104  // Detector geometry details
105  int MAXPMT = geo->GetWCNumPMT(); // Get the maximum number of PMTs in the ID
106  int MAXPMTA = geo->GetODWCNumPMT(); // Get the maximum number of PMTs in the OD
107 
108  // Variables to read in from the root file ID
109  float vtxX, vtxY, vtxZ; // vertex coordinate
110  float dirX, dirY, dirZ; // particle momentum direction
111  float energy; // particle energy
112  float rawHitsID; // number of raw pmt hits
113  float digiHitsID; // number of pmt digitised hits
114  int numPMTsHitID; // Number of PMTs hit
115  int numPMTsDigiHitID; // Number of PMTs with digihits
116  // Variables to read in from the root file OD
117  float vtxXOD, vtxYOD, vtxZOD; // vertex coordinate
118  float dirXOD, dirYOD, dirZOD; // particle momentum direction
119  float energyOD; // particle energy
120  float rawHitsOD; // number of raw pmt hits
121  float digiHitsOD; // number of pmt digitised hits
122  int numPMTsHitOD; // Number of PMTs hit
123  int numPMTsDigiHitOD; // Number of PMTs with digihits
124 
125  // other variables
126  int event, trigger;
127  float phi, theta;
128 
129  // Set the branches to be saved.
130  outBranch->Branch("event", &event, "event/I");
131  outBranch->Branch("trigger", &trigger, "trigger/I");
132  outBranch->Branch("vtxX", &vtxX, "vtxX/F");
133  outBranch->Branch("vtxY", &vtxY, "vtxY/F");
134  outBranch->Branch("vtxZ", &vtxZ, "vtxZ/F");
135  outBranch->Branch("dirX", &dirX, "dirX/F");
136  outBranch->Branch("dirY", &dirY, "dirY/F");
137  outBranch->Branch("dirZ", &dirZ, "dirZ/F");
138  outBranch->Branch("phi", &phi, "phi/F");
139  outBranch->Branch("theta", &theta, "theta/F");
140  outBranch->Branch("energy", &energy, "energy/F");
141  outBranch->Branch("rawHitsID", &rawHitsID, "rawHitsID/F");
142  outBranch->Branch("digiHitsID", &digiHitsID, "digiHitsID/F");
143  outBranch->Branch("rawHitsOD", &rawHitsOD, "rawHitsOD/F");
144  outBranch->Branch("digiHitsOD", &digiHitsOD, "digiHitsOD/F");
145  outBranch->Branch("numPMTsHitID", &numPMTsHitID, "numPMTsHitID/I");
146  outBranch->Branch("numPMTsDigiHitID", &numPMTsDigiHitID, "numPMTsDigiHitID/I");
147  outBranch->Branch("numPMTsHitOD", &numPMTsHitOD, "numPMTsHitOD/I");
148  outBranch->Branch("numPMTsDigiHitOD", &numPMTsDigiHitOD, "numPMTsDigiHitOD/I");
149 
150 
151  // Declare histograms
152  // number of hit PMTs
153  TH1D *numRawHitPMTsIDHist = new TH1D("numRawHitPMTsIDHist","numRawHitPMTsIDHist",200, 0, 1000);
154  TH1D *numRawHitPMTsODHist = new TH1D("numRawHitPMTsODHist","numRawHitPMTsODHist",200, 0, 1000);
155  TH1D *numDigiHitPMTsIDHist = new TH1D("numDigiHitPMTsIDHist","numDigiHitPMTsIDHist",200, 0, 1000);
156  TH1D *numDigiHitPMTsODHist = new TH1D("numDigiHitPMTsODHist","numDigiHitPMTsODHist",200, 0, 1000);
157  // number of hits (pe)
158  TH1D *numRawHitsIDHist = new TH1D("numRawHitsIDHist","numRawHitsIDHist",200, 0, 1000);
159  TH1D *numRawHitsODHist = new TH1D("numRawHitsODHist","numRawHitsODHist",200, 0, 1000);
160  TH1D *numDigiHitsIDHist = new TH1D("numDigiHitsIDHist","numDigiHitsIDHist",200, 0, 1000);
161  TH1D *numDigiHitsODHist = new TH1D("numDigiHitsODHist","numDigiHitsODHist",200, 0, 1000);
162  // Simulated particles
163  TH2D *thetaVsPhi = new TH2D("thetaVsPhi", "thetaVsPhi", 60, -PI, PI, 60, -PI, PI );
164 
165  // Format histograms ( hist, title, x_title, y_title)
166  format_histogram(numRawHitPMTsIDHist, "" , "Number of hit ID PMTs [raw]", "");
167  format_histogram(numRawHitPMTsODHist, "" , "Number of hit OD PMTs [raw]", "");
168  format_histogram(numDigiHitPMTsIDHist, "" , "Number of hit ID PMTs [digi]", "");
169  format_histogram(numDigiHitPMTsODHist, "" , "Number of hit OD PMTs [digi]", "");
170 
171  format_histogram(numRawHitsIDHist, "" , "Number of ID hits [pe]", "");
172  format_histogram(numRawHitsODHist, "" , "Number of OD hits [pe]", "");
173  format_histogram(numDigiHitsIDHist, "" , "Number of ID hits [pe]", "");
174  format_histogram(numDigiHitsODHist, "" , "Number of OD hits [pe]", "");
175 
176  format_histogram(thetaVsPhi, "" , "Particle direction #theta", "Particle direction #phi");
177 
178  // Event Analysis
179  for (int ev = 0; ev < nEvent; ev++){ // Loop over events
180 
181  std::string command;
182  wcsimTree->GetEntry(ev);
183  wcsimTriggerID = wcsimRootID->GetTrigger(0);
184  int numTriggersID = wcsimRootID->GetNumberOfEvents();
185  int numSubTriggersID = wcsimRootID->GetNumberOfSubEvents();
186 
187  wcsimTriggerOD = wcsimRootOD->GetTrigger(0);
188  int numTriggersOD = wcsimRootOD->GetNumberOfEvents();
189  int numSubTriggersOD = wcsimRootOD->GetNumberOfSubEvents();
190 
191  event = ev;
192 
193  for (int nTrig = 0; nTrig < numTriggersID; nTrig++){
194 
195  trigger = nTrig;
196 
197  // ID
198  wcsimTriggerID = wcsimRootID->GetTrigger(nTrig);
199  int numTracksID = wcsimTriggerID->GetNtrack();
200  WCSimRootTrack * trackID = (WCSimRootTrack*) wcsimTriggerID->GetTracks()->At(0);
201 
202  vtxX = wcsimTriggerID->GetVtx(0);
203  vtxY = wcsimTriggerID->GetVtx(1);
204  vtxZ = wcsimTriggerID->GetVtx(2);
205  dirX = trackID->GetDir(0);
206  dirY = trackID->GetDir(1);
207  dirZ = trackID->GetDir(2);
208  energy = trackID->GetE();
209 
210  theta = atan2( dirX, dirZ );
211  phi = atan2( dirY, dirX );
212  thetaVsPhi->Fill(theta, phi);
213 
214  rawHitsID = 0;
215  digiHitsID = 0;
216 
217  numPMTsHitID = wcsimTriggerID->GetNcherenkovhits(); //Returns the number of PMTs with a true hit (photon or dark noise) (QE applied)
218  numPMTsDigiHitID = wcsimTriggerID->GetNcherenkovdigihits(); //Returns the number of PMTs with a true hit (photon or dark noise) (QE applied)
219  // END OF ID
220 
221  // ID
222  wcsimTriggerOD = wcsimRootOD->GetTrigger(nTrig);
223  int numTracksOD = wcsimTriggerOD->GetNtrack();
224  WCSimRootTrack * trackOD = (WCSimRootTrack*) wcsimTriggerOD->GetTracks()->At(0);
225 
226  vtxXOD = wcsimTriggerOD->GetVtx(0);
227  vtxYOD = wcsimTriggerOD->GetVtx(1);
228  vtxZOD = wcsimTriggerOD->GetVtx(2);
229  dirXOD = trackOD->GetDir(0);
230  dirYOD = trackOD->GetDir(1);
231  dirZOD = trackOD->GetDir(2);
232  energyOD = trackOD->GetE();
233  rawHitsOD = 0;
234  digiHitsOD = 0;
235 
236  numPMTsHitOD = wcsimTriggerOD->GetNcherenkovhits(); //Returns the number of PMTs with a true hit (photon or dark noise) (QE applied)
237  numPMTsDigiHitOD = wcsimTriggerOD->GetNcherenkovdigihits(); //Returns the number of PMTs with a true hit (photon or dark noise) (QE applied)
238  // END OF ID
239 
240 
241  // Work out the number of photons that hit the PMTs
242  for (int i = 0; i < numPMTsHitID; i++){
243  WCSimRootCherenkovHit *cherenkovHitID = (WCSimRootCherenkovHit*) wcsimTriggerID->GetCherenkovHits()->At(i);
244  float tmpRawHitsID = cherenkovHitID->GetTotalPe(1);
245  rawHitsID += tmpRawHitsID;
246  } // End of for loop working out number of photons in PMTs
247 
248  // Work out the number of photons that hit the PMTs
249  for (int i = 0; i < numPMTsHitOD; i++){
250  WCSimRootCherenkovHit *cherenkovHitOD = (WCSimRootCherenkovHit*) wcsimTriggerOD->GetCherenkovHits()->At(i);
251  float tmpRawHitsOD = cherenkovHitOD->GetTotalPe(1);
252  rawHitsOD += tmpRawHitsOD;
253  } // End of for loop working out number of photons in PMTs
254 
255  // Work out the number of digitised hits in the PMTs
256  for (int i = 0; i < numPMTsDigiHitID; i++){
257  WCSimRootCherenkovDigiHit *cherenkovDigiHitID = (WCSimRootCherenkovDigiHit*) wcsimTriggerID->GetCherenkovDigiHits()->At(i);
258  float tmpDigiHitsID = cherenkovDigiHitID->GetQ();
259 
260  digiHitsID += tmpDigiHitsID;
261  int tubeID = cherenkovDigiHitID->GetTubeId() -1;
262  } // End of for loop working out number of digitized hits in PMTs
263 
264  // Work out the number of digitised hits in the PMTs
265  for (int i = 0; i < numPMTsDigiHitOD; i++){
266  WCSimRootCherenkovDigiHit *cherenkovDigiHitOD = (WCSimRootCherenkovDigiHit*) wcsimTriggerOD->GetCherenkovDigiHits()->At(i);
267  float tmpDigiHitsOD = cherenkovDigiHitOD->GetQ();
268 
269  digiHitsOD += tmpDigiHitsOD;
270  // Find the tube and work out its position
271  int tubeOD = MAXPMT + cherenkovDigiHitOD->GetTubeId() -1;
272  } // End of for loop working out number of digitized hits in PMTs
273 
274 
275  if (verbosity){
276  std::cout << "====================================================" << std::endl;
277  std::cout << "Event\t" << ev << std::endl;
278  std::cout << "Trigger\t" << nTrig << std::endl;
279  std::cout << "vtx\t" << vtxXOD << " " << vtxYOD << " " << vtxZOD << std::endl;
280  std::cout << "dir\t" << dirXOD << " " << dirYOD << " " << dirZOD << std::endl;
281  std::cout << "ene\t" << energyOD << std::endl;
282  std::cout << "rawhitsOD\t" << rawHitsOD << std::endl;
283  std::cout << "digihitsOD\t" << digiHitsOD << std::endl;
284  std::cout << "rawhitsID\t" << rawHitsID << std::endl;
285  std::cout << "digihitsID\t" << digiHitsID << std::endl;
286  std::cout << "numPMTsHitOD\t" << numPMTsHitOD << std::endl;
287  std::cout << "numPMTsDigiHitOD\t" << numPMTsDigiHitOD << std::endl;
288  std::cout << "numPMTsHitID\t" << numPMTsHitID << std::endl;
289  std::cout << "numPMTsDigiHitID\t" << numPMTsDigiHitID << std::endl;
290  }
291 
292  numRawHitsIDHist->Fill(rawHitsID);
293  numDigiHitsIDHist->Fill(digiHitsID);
294  numRawHitsODHist->Fill(rawHitsOD);
295  numDigiHitsODHist->Fill(digiHitsOD);
296 
297  numRawHitPMTsIDHist->Fill(numPMTsHitID);
298  numRawHitPMTsODHist->Fill(numPMTsHitOD);
299  numDigiHitPMTsIDHist->Fill(numPMTsDigiHitID);
300  numDigiHitPMTsODHist->Fill(numPMTsDigiHitOD);
301 
302  outBranch->Fill(); // fill the tree with events
303 
304  } // End of loop over triggers
305 
306 
307  } // End of loop over events
308 
309 
310 
311  outFile->Write(); // Write all of objects to the output file.
312  outFile->Close(); // Close the output file.
313 
314 }
315 
316 
317 
318 
Int_t GetODWCNumPMT() const
Detector geometry information (also containing PMT information arrays)
Int_t GetNumberOfSubEvents() const
Class holding digitised hit (aka digit or digi) information (after PMT & electronics simulation + tri...
void format_histogram(TH1D *h, std::string title, std::string xtitle, std::string ytitle)
Definition: read_OD.C:29
TClonesArray * GetTracks() const
Int_t GetNcherenkovhits() const
Float_t GetDir(Int_t i=0) const
Float_t GetVtx(Int_t i=0)
Int_t GetWCNumPMT(bool hybridsecondtype=false) const
TClonesArray * GetCherenkovHits() const
Int_t GetNcherenkovdigihits() const
Class storing trigger information.
#define PI
Definition: read_OD.C:19
Int_t GetTotalPe(int i) const
Float_t GetE() const
WCSimRootTrigger * GetTrigger(int number)
Int_t GetNumberOfEvents() const
Class containing event information.
WCSimRootGeom * geo
void read_OD(std::string inFileName, std::string outFileName, bool verbosity)
Definition: read_OD.C:43
Int_t GetNtrack() const
Class holding true (Cherenkov photon + dark noise) hit information.
TClonesArray * GetCherenkovDigiHits() const
Class holding true track information.