GRSISort "v4.0.0.5"
An extension of the ROOT analysis Framework
Loading...
Searching...
No Matches
LeanComptonMatrices.cxx
Go to the documentation of this file.
1/*
2This script is a derivative of the ComptonMatrices.c file. It is called lean because I have taken out
3many of the portions that were simply for comparing different methods. As I have essentially settled
4on one method, these additional steps are just bloating. Part of this fact means that I no longer
5do any weighting other that event mixing, and I also no longer include the metzger Nparallel/Nperpendicular
6method of Compton polarimetry. This script only includes the portions that I believe would be useful for
7actual implementation of this code. To use this you should only need to ensure the output directory/name
8is appropriate, you will need to make sure the max entries is set, and you need to ensure everything is as
9expected in the Parameter Setup section.
10
11Compile:
12g++ LeanComptonMatrices.c -std=c++0x -I$GRSISYS/include -L$GRSISYS/libraries `grsi-config --cflags --all-libs` `root-config --cflags --libs` -lTreePlayer -lMathMore -lSpectrum -o MakeComptonMatrices
13Run:
14Run with selected filename and no max entries:
15./MakeComptonMatrices /pathtotree/AnalysisTree.root
16
17This script is designed to create just the histograms required for producing the Compton polarimetry
18plots. These histograms can the be combined for multiple subruns using the hadd function. The summed
19file can be analysed using the AnalyzeComptonMatrices.c. To run on multiple runs/subruns at once simply
20put multiple parameters or use the * character to select multiple files.
21i.e.
22./MakeComptonMatrices /pathtotrees/analysis*.root
23
24______________________________________________________________________________________________
25*/
26
27#include <cstdio>
28#include <cstdlib>
29#include <cmath>
30#include <vector>
31#include <algorithm>
32#include <fstream>
33#include <Globals.h>
34#include <string>
35#include <iostream>
36#include <iomanip>
37#include <list>
38
39#include "TTree.h"
40#include "TTreeIndex.h"
41#include "TVirtualIndex.h"
42#include "TFile.h"
43#include "TList.h"
44#include "TFragment.h"
45#include "TChannel.h"
46#include "TApplication.h"
47#include "TROOT.h"
48#include "TChain.h"
49#include "TMath.h"
50#include "TF1.h"
51#include "TH1F.h"
52#include "TH2F.h"
53#include "TH3F.h"
54#include "TVector.h"
55#include "TVector3.h"
56#include "TCanvas.h"
57#include "TLatex.h"
58#include "TStyle.h"
59#include "TStopwatch.h"
60#include "TSpectrum.h"
61#include "TGraph.h"
62#include "TMultiGraph.h"
63#include "TGraphErrors.h"
64
65#include "TRunInfo.h"
66#include "TGRSISortInfo.h"
67#include "TGriffin.h"
68
69//Set to 0 for all entries.
70constexpr int MaxEntries = 0;
71
72TList* ComptonHists(TTree* tree, int64_t maxEntries, TStopwatch* w);
73
74int main(int argc, char** argv)
75{
76 if(argc < 2) {
77 std::cout << "usage: " << argv[0] << " <analysis tree files>" << std::endl;
78 return 0;
79 }
80 //We use a stopwatch so that we can watch progress
81 TStopwatch w;
82 w.Start();
83
84 TFile* file = nullptr;
85 TFile* outfile = nullptr;
86 TList* outlist = nullptr;
87 for(int f = 0; f < argc - 1; ++f) {
88 file = new TFile(argv[f + 1]); //maybe should be new?
89
90 if(file == nullptr || !file->IsOpen()) {
91 std::cout << "Failed to open file '" << argv[f + 1] << "'!" << std::endl;
92 continue;
93 }
94
95 std::cout << "Analyzing file: " << DBLUE << file->GetName() << RESET_COLOR << std::endl;
96
97 //Opening AnalysisTree and getting run info.
98 auto* tree = static_cast<TTree*>(file->Get("AnalysisTree"));
99 if(tree == nullptr) {
100 printf("Failed to find analysis tree in file '%s'!\n", argv[f + 1]);
101 return 1;
102 }
104
105 auto* runInfo = static_cast<TRunInfo*>(file->Get("RunInfo"));
106 std::string inputname = argv[f + 1];
107 std::string outputname;
108 if(runInfo == nullptr) {
109 std::cout << "Failed to find run information in file '" << argv[f + 1] << "'!" << std::endl
110 << "Trying to accomodate filenames" << std::endl;
111 for(int pop = 0; pop < 5; pop++) { inputname.pop_back(); }
112 while(inputname.size() > 9) { inputname.erase(inputname.begin()); }
113 outputname = Form("test_%s.root", inputname.c_str());
114 } else {
115 int runnumber = TRunInfo::RunNumber();
116 int subrunnumber = TRunInfo::SubRunNumber();
117 printf("Run number = %d and subrun number = %d\n", runnumber, subrunnumber);
118 outputname = Form("CompHists_%05d_%03d.root", runnumber, subrunnumber);
119 }
120
121 outfile = new TFile(outputname.c_str(), "recreate");
122 std::cout << argv[0] << ": starting Analysis on " << argv[f + 1] << " after " << w.RealTime() << " seconds" << std::endl;
123 w.Continue();
124
125 outlist = ComptonHists(tree, MaxEntries, &w);
126 if(outlist == nullptr) {
127 std::cout << "ComptonHists returned TList* nullptr!" << std::endl;
128 continue;
129 }
130 outlist->Write();
131 outfile->Close();
132 std::cout << argv[f + 1] << " done after " << w.RealTime() << " seconds" << std::endl;
133 w.Continue();
134 }
135 return 0;
136}
137
138// ****************************************************************** //
139// ********************* FUNCTION DEFINITIONS *********************** //
140// ****************************************************************** //
141
142TList* ComptonHists(TTree* tree, int64_t maxEntries, TStopwatch* w)
143{
144 if(w == nullptr) {
145 w = new TStopwatch;
146 w->Start();
147 }
148
149 ////////////////////////////////////////////////////////////////////////////////////
150 //---------------------------- Parameter Setup -----------------------------------//
151 ////////////////////////////////////////////////////////////////////////////////////
152 //Energy Spectrum Paramaters
153 Double_t low = 0.;
154 Double_t high = 5000.;
155 Int_t nofBins = 10000;
156 //Coincidence Parameters
157 bool usetimestamps = true; // Will use timestamps instead of time.
158 Double_t ggTlow = 0.0; //Ensure the units here match with the units of GetTimeStamps, or if
159 Double_t ggThigh = 20.0; //false ensure that they are the same as GetTime
160
161 //These are the time values for each gamma. (Used in Section 2 for coincidence gating)
162 int tg1 = 0;
163 int tg2 = 0;
164 int tg3 = 0;
165 //These are the indices of the two hits being compared. (Used in both Section 1 and Section 2)
166 int one = 0;
167 int two = 0;
168 int three = 0;
169 //Experimental Angles to be calculated: (Used in both Section 1 and Section 2)
170 double Xi = 0.;
171 double CoTheta = 0.;
172 //Vectors (Used in both Section 1 and Section 2)
173 TVector3 v1;
174 TVector3 v2;
175 TVector3 v3;
176 TVector3 n1;
177 TVector3 n2;
178 TVector3 d1;
179 TVector3 d2;
180
181 int ThetaBins = 180; // Binsize = 180deg / bins
182 int XiBins = 180;
183
184 std::array<double, 2> gEnergy = {1332.5, 1173.2};
185 double gEnergyErr = 5.0; //Energies within this on eithr side of gEnergy will be considered a good interaction
186 double gEnergySumErr = gEnergyErr; //If the energy of the two scattering gamma rays sum to within this from either side of gEnergy then they are considered a good interaction.
187
188 bool ForceG1 = true; //If true it will make gEnergy[0] the energy of the scattered gamma ray in the cascade.
189
190 int gEnergyIndex1 = 0; //The index for gEnergy of gamma 1. Set within the code.
191 //These parameters could potentially be automated but right now my attempts were unsuccesful
192 std::vector<int> MissingClovers = {}; // = {1,2,3,4};//13 //Put Missing Detectors in vector below. Any detector combinations including these detectors will be ignored. Detectors are 1 through 16.
193 double DetectorHeight = 145.0; //This should be found from runinfo->HPGeArrayPosition();, however this may not have been actively set for the experiment. For
194 //for run02397 it seems that this returned the default of 110mm, but the calculated crystal position magnitudes were 58.112mm,
195 // lists in which to store the array numbers, energies, and entry numbers of earlier events used for
196 // event mixing.
197 std::list<int> NonCo_CryNums;
198 std::list<double> NonCo_Energies;
199 std::list<int> NonCo_Entries;
200
201 ////////////////////////////////////////////////////////////////////////////////////
202 //--------------------- Setting up output histograms -----------------------------//
203 ////////////////////////////////////////////////////////////////////////////////////
204
205 auto* list = new TList; //Output list
206
207 auto* XiHist2DGeo_DetDet = new TH2D("XiHist2D_DetDetCoincidenceTheta_Geo", "Possible #xi Angles in GRIFFIN Array for Coincidence Angle #theta (Measured from Clover Faces)", XiBins, 0.0, 180.000001, ThetaBins, 0.0, 180.000001);
208 list->Add(XiHist2DGeo_DetDet);
209 auto* XiHist2DGeo_CryCry = new TH2D("XiHist2D_CryCryCoincidenceTheta_Geo", "Possible #xi Angles in GRIFFIN Array for Coincidence Angle #theta (Measured from Crystal Positions)", XiBins, 0.0, 180.000001, ThetaBins, 0.0, 180.000001);
210 list->Add(XiHist2DGeo_CryCry);
211
212 auto* XiHist2D_DetDet = new TH2D("XiHist2D_DetDetCoincidenceTheta", "Measured #xi Angles for Coincidence Angle #theta (Measured from Clover Faces)", XiBins, 0.0, 180.000001, ThetaBins, 0.0, 180.000001);
213 list->Add(XiHist2D_DetDet);
214 auto* XiHist2D_CryCry = new TH2D("XiHist2D_CryCryCoincidenceTheta", "Measured #xi Angles for Coincidence Angle #theta (Measured from Crystal Positions)", XiBins, 0.0, 180.000001, ThetaBins, 0.0, 180.000001);
215 list->Add(XiHist2D_CryCry);
216
217 auto* XiHist2DNonCo_DetDet = new TH2D("XiHist2D_DetDetCoincidenceTheta_NonCo", "Measured #xi Angles for Non-Coincidenct #gamma_{1} and #gamma_{2} at Angle #theta (Measured from Clover Faces)", XiBins, 0.0, 180.000001, ThetaBins, 0.0, 180.000001);
218 list->Add(XiHist2DNonCo_DetDet);
219 auto* XiHist2DNonCo_CryCry = new TH2D("XiHist2D_CryCryCoincidenceTheta_NonCo", "Measured #xi Angles for Non-Coincidenct #gamma_{1} and #gamma_{2} at Angle #theta (Measured from Crystal Positions)", XiBins, 0.0, 180.000001, ThetaBins, 0.0, 180.000001);
220 list->Add(XiHist2DNonCo_CryCry);
221
222 auto* gammaSinglesAll = new TH1D("gammaSingles", "#gamma singles (All Events);Energy [keV]", nofBins, low, high);
223 list->Add(gammaSinglesAll);
224 auto* gammagammaAll = new TH2D("gammagamma", "#gamma - #gamma (All Events);Energy [keV];Energy [keV]", nofBins, low, high, nofBins, low, high);
225 list->Add(gammagammaAll);
226 auto* gammaCrystalAll = new TH2D("gammaCrystal", "#gamma Crystal (All Events);Energy [keV];Crystal Number", nofBins, low, high, 64, 0, 64);
227 list->Add(gammaCrystalAll);
228 auto* XiCrystalGeo = new TH2D("XiCrystalGeo", "Possible #xi Crystal (All Events);#xi;Crystal Number", XiBins, 0.0, 180.000001, 64, 0, 64);
229 list->Add(XiCrystalGeo);
230 auto* thetaCrystalGeo = new TH2D("thetaCrystalGeo", "Possible #theta Crystal (All Events);#theta;Crystal Number", ThetaBins, 0.0, 180.000001, 64, 0, 64);
231 list->Add(thetaCrystalGeo);
232 auto* XiCrystalAll = new TH2D("XiCrystal", "#xi Crystal (All Events);#xi;Crystal Number", XiBins, 0.0, 180.000001, 64, 0, 64);
233 list->Add(XiCrystalAll);
234 auto* thetaCrystalAll = new TH2D("thetaCrystal", "#theta Crystal (All Events);#theta;Crystal Number", ThetaBins, 0.0, 180.000001, 64, 0, 64);
235 list->Add(thetaCrystalAll);
236 auto* gammaXi_g1 = new TH2D("gammaXi_g1", "#xi - #gamma (Only #gamma_{1} from Triple Coincidence);#xi;Energy [keV]", XiBins, 0.0, 180.000001, nofBins, low, high);
237 list->Add(gammaXi_g1);
238 auto* gammaXi_g2 = new TH2D("gammaXi_g2", "#xi - #gamma (Only #gamma_{2} from Triple Coincidence);#xi;Energy [keV]", XiBins, 0.0, 180.000001, nofBins, low, high);
239 list->Add(gammaXi_g2);
240 auto* gammaSingles_g1 = new TH1D("gammaSingles_g1", "#gamma singles (Only #gamma_{1} from Triple Coincidence);Energy [keV]", nofBins, low, high);
241 list->Add(gammaSingles_g1);
242 auto* gammaSingles_g2 = new TH1D("gammaSingles_g2", "#gamma singles (Only #gamma_{2} from Triple Coincidence);Energy [keV]", nofBins, low, high);
243 list->Add(gammaSingles_g2);
244 auto* gammaSingles_g3 = new TH1D("gammaSingles_g3", "#gamma singles (Only #gamma_{3} from Triple Coincidence);Energy [keV]", nofBins, low, high);
245 list->Add(gammaSingles_g3);
246 auto* ggTimeDiff_g1g2 = new TH1D("ggTimeDiff_g1g2", "#gamma_{1}-#gamma_{2} time difference", 300, 0, 300);
247 list->Add(ggTimeDiff_g1g2);
248 auto* ggTimeDiff_g1g3 = new TH1D("ggTimeDiff_g1g3", "#gamma_{1}-#gamma_{3} time difference", 300, 0, 300);
249 list->Add(ggTimeDiff_g1g3);
250 auto* ggTimeDiff_g2g3 = new TH1D("ggTimeDiff_g2g3", "#gamma_{2}-#gamma_{3} time difference", 300, 0, 300);
251 list->Add(ggTimeDiff_g2g3);
252
253 ////////////////////////////////////////////////////////////////////////////////////
254 //------------------------------- Entry Setup ------------------------------------//
255 ////////////////////////////////////////////////////////////////////////////////////
256
257 if(maxEntries == 0 || maxEntries > tree->GetEntries()) {
258 maxEntries = tree->GetEntries();
259 }
260 TGriffin* grif = nullptr;
261 tree->SetBranchAddress("TGriffin", &grif);
262
263 ////////////////////////////////////////////////////////////////////////////////////
264 //---------------------------- Main Section 1 ------------------------------------//
265 ////////////////////////////////////////////////////////////////////////////////////
266
267 //This section produces the hists which provide the number of occurances of a particular
268 //Xi/theta combination in the array. This is useful to ensure the proper angles are being produced
269 //in the main code.
270 for(one = 0; one < 64; one++) {
271 if(std::binary_search(MissingClovers.begin(), MissingClovers.end(), one / 4 + 1)) { continue; }
272 v1 = TGriffin::GetPosition(one / 4 + 1, one % 4, DetectorHeight);
273 d1 = TGriffin::GetPosition(one / 4 + 1, 5, DetectorHeight);
274 for(two = (one / 4) * 4; two < (one / 4 + 1) * 4; two++) {
275 if(one == two) { continue; }
276 v2 = TGriffin::GetPosition(two / 4 + 1, two % 4, DetectorHeight);
277 for(three = 0; three < 64; three++) {
278 if(three / 4 == one / 4) { continue; }
279 if(std::binary_search(MissingClovers.begin(), MissingClovers.end(), three / 4 + 1)) { continue; }
280 v3 = TGriffin::GetPosition(three / 4 + 1, three % 4, DetectorHeight);
281 d2 = TGriffin::GetPosition(three / 4 + 1, 5, DetectorHeight);
282
283 n1 = v3.Cross(v1);
284 n2 = v1.Cross(v2);
285 Xi = n1.Angle(n2) * TMath::RadToDeg();
286 CoTheta = v3.Angle(v1) * TMath::RadToDeg();
287
288 std::cout << one << ", " << two << ", " << three << ": " << Xi << ", " << d1.Angle(d2) * TMath::RadToDeg() << ", " << CoTheta << std::endl;
289 XiHist2DGeo_DetDet->Fill(Xi, TMath::RadToDeg() * d1.Angle(d2));
290 XiHist2DGeo_CryCry->Fill(Xi, CoTheta);
291 XiCrystalGeo->Fill(Xi, one);
292 thetaCrystalGeo->Fill(CoTheta, one);
293 //printf("%d %d %d %f %f\n",one,two,three,CoTheta,Xi);
294 }
295 }
296 }
297
298 ////////////////////////////////////////////////////////////////////////////////////
299 //---------------------------- Main Section 2 ------------------------------------//
300 ////////////////////////////////////////////////////////////////////////////////////
301
302 //This section is the main work horse. Below each entry is iterated over, and those which meet
303 //the required gates (i.e. a proper scatter, energy/coincidence gates) are use to calculate Xi and
304 //CoTheta. This region also produces unpolarized counts for normalization purposes.
305 //This is done by through event mixing (internally referred to as NonCo, for NonCorrelated).
306
307 std::cout << "Starting event analysis (Section 2) after " << w->RealTime() << " seconds" << std::endl;
308 w->Continue();
309
310 // int curloopval = 0;
311 int PrintRate = 1000;
312 while(PrintRate >= maxEntries) {
313 //This section just adapts the print rate for absurdly small # of entry runs (# entries < PrintRate)
314 PrintRate /= 10;
315 if(PrintRate < 10) {
316 PrintRate = 1;
317 break;
318 }
319 }
320
321 for(int entry = 1; entry < maxEntries; ++entry) {
322 if(entry == 1 || entry == maxEntries - 1 || entry % (maxEntries / PrintRate) == 0) {
323 std::cout << "\r\t\t\t\t\t\t\t\t "
324 << "\rOn entry: " << std::setw(10) << std::right << entry + 1 << "/" << std::setw(10) << std::left << maxEntries << " (" << std::setw(3) << std::right << static_cast<int>(static_cast<double>(100 * (entry + 1)) / static_cast<double>(maxEntries)) << "%)";
325 }
326 tree->GetEntry(entry);
327 grif->ResetAddback();
328 for(one = 0; one < static_cast<int>(grif->GetMultiplicity()); ++one) {
329 //if(std::binary_search(MissingClovers.begin(),MissingClovers.end(), grif->GetGriffinHit(one)->GetDetector() )) continue; //These could be added to gate out clovers.
330 gammaSinglesAll->Fill(grif->GetGriffinHit(one)->GetEnergy());
331 gammaCrystalAll->Fill(grif->GetGriffinHit(one)->GetEnergy(), 4 * (grif->GetGriffinHit(one)->GetDetector() - 1) + grif->GetGriffinHit(one)->GetCrystal());
332
333 //------------------------------------Beginning of list maintenance------------------------------------//
334 //This updates the last utilized for event mixing.
335
336 NonCo_Entries.push_back(entry);
337 NonCo_CryNums.push_back(4 * (grif->GetGriffinHit(one)->GetDetector() - 1) + grif->GetGriffinHit(one)->GetCrystal()); // 0 -> 63
338 NonCo_Energies.push_back(grif->GetGriffinHit(one)->GetEnergy());
339
340 if(one == 0) { //only needs to be done once per entry, as it doesn't depend on current entries multiplicity.
341 // eliminate parts of lists that are too old
342 int counter = 0;
343 for(int NonCo_Entry : NonCo_Entries) {
344 // the number subtracted from entry in the next line determines how far back the BG loop looks for coincidences
345 // it should be one more than the number of entries you want to compare
346 // i.e. if you want to compare ten entries, this number should be eleven
347 if(NonCo_Entry < entry - 11) { counter++; }
348 }
349 for(int i = 0; i < counter; i++) {
350 NonCo_Entries.pop_front();
351 NonCo_Energies.pop_front();
352 NonCo_CryNums.pop_front();
353 }
354 }
355 //---------------------------------------End of list maintenance---------------------------------------//
356
357 //one will be the first gamma ray of the scatter event
358 if(usetimestamps) {
359 tg1 = grif->GetGriffinHit(one)->GetTimeStamp();
360 } else {
361 tg1 = static_cast<int>(grif->GetGriffinHit(one)->GetTime());
362 }
363
364 for(two = 0; two < static_cast<int>(grif->GetMultiplicity()); ++two) {
365 //if(std::binary_search(MissingClovers.begin(),MissingClovers.end(), grif->GetGriffinHit(two)->GetDetector() )) continue; //These could be added to gate out clovers.
366 if(two == one) { continue; }
367 //Two will be the second event in the scatter. It must have lower energy and sum with g1 to
368 //have energy within range of an expected gamma ray. It must also be in true coincidence with
369 //gamma 1. Further restrictions may be made.
370 if(usetimestamps) {
371 tg2 = grif->GetGriffinHit(two)->GetTimeStamp();
372 } else {
373 tg2 = static_cast<int>(grif->GetGriffinHit(two)->GetTime());
374 }
375
376 if(ggTlow > TMath::Abs(tg2 - tg1) || TMath::Abs(tg2 - tg1) > ggThigh) { continue; }
377
378 gammagammaAll->Fill(grif->GetGriffinHit(one)->GetEnergy(), grif->GetGriffinHit(two)->GetEnergy());
379
380 if(grif->GetGriffinHit(one)->GetDetector() != grif->GetGriffinHit(two)->GetDetector()) { continue; }
381 if(grif->GetGriffinHit(one)->GetCrystal() == grif->GetGriffinHit(two)->GetCrystal()) { continue; }
382 if(grif->GetGriffinHit(one)->GetEnergy() < grif->GetGriffinHit(two)->GetEnergy()) { continue; }
383 if(TMath::Abs(gEnergy[0] - (grif->GetGriffinHit(one)->GetEnergy() + grif->GetGriffinHit(two)->GetEnergy())) < gEnergySumErr) {
384 gEnergyIndex1 = 0;
385 } else if((TMath::Abs(gEnergy[1] - (grif->GetGriffinHit(one)->GetEnergy() + grif->GetGriffinHit(two)->GetEnergy())) < gEnergySumErr)) {
386 gEnergyIndex1 = 1;
387 } else {
388 continue;
389 }
390 if(ForceG1 && gEnergyIndex1 != 0) { continue; } //This gives the option of forcing which gamma is the scatter one.
391
392 //----------------------------------------------------------------------------------------//
393
394 //At this stage we have g1 and g2 being two coincident gammas which enter different crystals
395 //in the same detector, and g1 has higher energy than g2. Togetehr they sum to one of the
396 //expected gamma energies.
397
398 //Polarized Work - Use a third coincident gamma ray to provide orientation axis.
399 v1 = grif->GetGriffinHit(one)->GetPosition(DetectorHeight);
400 v2 = grif->GetGriffinHit(two)->GetPosition(DetectorHeight);
401 d1 = TGriffin::GetPosition(grif->GetGriffinHit(one)->GetDetector(), 5, DetectorHeight);
402
403 for(three = 0; three < static_cast<int>(grif->GetMultiplicity()); ++three) {
404 //if(std::binary_search(MissingClovers.begin(),MissingClovers.end(), grif->GetGriffinHit(three)->GetDetector() )) continue; //These could be added to gate out clovers.
405
406 if(one == three || two == three) { continue; }
407 if(grif->GetGriffinHit(three)->GetDetector() == grif->GetGriffinHit(one)->GetDetector()) { continue; }
408 if(TMath::Abs(gEnergy[1 - gEnergyIndex1] - grif->GetGriffinHit(three)->GetEnergy()) > gEnergyErr) { continue; }
409 if(usetimestamps) {
410 tg3 = grif->GetGriffinHit(three)->GetTimeStamp();
411 } else {
412 tg3 = static_cast<int>(grif->GetGriffinHit(three)->GetTime());
413 }
414
415 bool TimeCoincident = ggTlow < TMath::Abs(tg3 - tg1) && TMath::Abs(tg3 - tg1) < ggThigh && ggTlow < TMath::Abs(tg3 - tg2) && TMath::Abs(tg3 - tg2) < ggThigh;
416 ggTimeDiff_g1g2->Fill(TMath::Abs(tg2 - tg1));
417 ggTimeDiff_g1g3->Fill(TMath::Abs(tg3 - tg1));
418 ggTimeDiff_g2g3->Fill(TMath::Abs(tg3 - tg2));
419
420 //Begin Polarized Assymetry Determinations
421 v3 = grif->GetGriffinHit(three)->GetPosition(DetectorHeight);
422 d2 = TGriffin::GetPosition(grif->GetGriffinHit(three)->GetDetector(), 5, DetectorHeight);
423
424 n1 = v3.Cross(v1);
425 n2 = v1.Cross(v2);
426
427 Xi = n1.Angle(n2) * TMath::RadToDeg();
428 CoTheta = v3.Angle(v1) * TMath::RadToDeg();
429
430 if(TimeCoincident) {
431 XiHist2D_DetDet->Fill(Xi, TMath::RadToDeg() * d1.Angle(d2));
432 XiHist2D_CryCry->Fill(Xi, CoTheta);
433 XiCrystalAll->Fill(Xi, 4 * (grif->GetGriffinHit(one)->GetDetector() - 1) + grif->GetGriffinHit(one)->GetCrystal());
434 thetaCrystalAll->Fill(CoTheta, 4 * (grif->GetGriffinHit(one)->GetDetector() - 1) + grif->GetGriffinHit(one)->GetCrystal());
435
436 gammaXi_g1->Fill(Xi, grif->GetGriffinHit(one)->GetEnergy());
437 gammaXi_g2->Fill(Xi, grif->GetGriffinHit(two)->GetEnergy());
438 gammaSingles_g1->Fill(grif->GetGriffinHit(one)->GetEnergy());
439 gammaSingles_g2->Fill(grif->GetGriffinHit(two)->GetEnergy());
440 gammaSingles_g3->Fill(grif->GetGriffinHit(three)->GetEnergy());
441 }
442 } //end of real event 3
443
444 //----------------------------------------------------------------------------------------//
445
446 //Unpolarized Work - Third gamma chosen from uncorrelated (in time) events. This is used
447 //for event mixing weighting of triplets.
448
449 auto it_Energy = NonCo_Energies.begin();
450 auto it_CryNum = NonCo_CryNums.begin();
451 for(int NonCo_Entry : NonCo_Entries) {
452 if(NonCo_Entry <= entry - 2) { // if the second entry is more than two behind... (this gives a sufficient time window to ensure no time correlation)
453 double Energy3 = *it_Energy;
454 int CrystalNum = *it_CryNum;
455 if((grif->GetGriffinHit(one)->GetDetector() != CrystalNum / 4 + 1) && (TMath::Abs(gEnergy[1 - gEnergyIndex1] - Energy3) < gEnergyErr)) {
456 d2 = TGriffin::GetPosition((CrystalNum / 4) + 1, 5, DetectorHeight);
457 v3 = TGriffin::GetPosition((CrystalNum / 4) + 1, CrystalNum % 4, DetectorHeight);
458 n1 = v3.Cross(v1);
459 n2 = v1.Cross(v2);
460
461 Xi = n1.Angle(n2) * TMath::RadToDeg();
462 CoTheta = v3.Angle(v1) * TMath::RadToDeg();
463
464 XiHist2DNonCo_DetDet->Fill(Xi, TMath::RadToDeg() * d1.Angle(d2));
465 XiHist2DNonCo_CryCry->Fill(Xi, CoTheta);
466 }
467 }
468 ++it_Energy;
469 ++it_CryNum;
470 } // End of event mixing (NonCo) work.
471 }
472 }
473 }
474
475 ////////////////////////////////////////////////////////////////////////////////////
476 //---------------------------- Main Section e ------------------------------------//
477 ////////////////////////////////////////////////////////////////////////////////////
478
479 //Make things pretty (or at least understandable)
480
481 XiHist2DGeo_DetDet->GetXaxis()->SetTitle("Experimental Angle #xi (#circ)");
482 XiHist2DGeo_DetDet->GetXaxis()->CenterTitle();
483 XiHist2DGeo_DetDet->GetYaxis()->SetTitle("Coincidence Angle #theta (#circ)");
484 XiHist2DGeo_DetDet->GetYaxis()->CenterTitle();
485 XiHist2DGeo_DetDet->GetZaxis()->SetTitle("Counts");
486 XiHist2DGeo_DetDet->GetZaxis()->CenterTitle();
487 XiHist2DGeo_DetDet->SetMarkerStyle(24);
488 XiHist2DGeo_DetDet->SetMarkerColor(kRed);
489 XiHist2DGeo_DetDet->SetMarkerSize(0.5);
490
491 XiHist2DGeo_CryCry->GetXaxis()->SetTitle("Experimental Angle #xi (#circ)");
492 XiHist2DGeo_CryCry->GetXaxis()->CenterTitle();
493 XiHist2DGeo_CryCry->GetYaxis()->SetTitle("Coincidence Angle #theta (#circ)");
494 XiHist2DGeo_CryCry->GetYaxis()->CenterTitle();
495 XiHist2DGeo_CryCry->GetZaxis()->SetTitle("Counts");
496 XiHist2DGeo_CryCry->GetZaxis()->CenterTitle();
497 XiHist2DGeo_CryCry->SetMarkerStyle(24);
498 XiHist2DGeo_CryCry->SetMarkerColor(kRed);
499 XiHist2DGeo_CryCry->SetMarkerSize(0.5);
500
501 XiHist2DNonCo_DetDet->GetXaxis()->SetTitle("Experimental Angle #xi (#circ)");
502 XiHist2DNonCo_DetDet->GetXaxis()->CenterTitle();
503 XiHist2DNonCo_DetDet->GetYaxis()->SetTitle("Coincidence Angle #theta (#circ)");
504 XiHist2DNonCo_DetDet->GetYaxis()->CenterTitle();
505 XiHist2DNonCo_DetDet->GetZaxis()->SetTitle("Counts");
506 XiHist2DNonCo_DetDet->GetZaxis()->CenterTitle();
507 XiHist2DNonCo_DetDet->SetMarkerStyle(24);
508 XiHist2DNonCo_DetDet->SetMarkerColor(kRed);
509 XiHist2DNonCo_DetDet->SetMarkerSize(0.5);
510
511 XiHist2DNonCo_CryCry->GetXaxis()->SetTitle("Experimental Angle #xi (#circ)");
512 XiHist2DNonCo_CryCry->GetXaxis()->CenterTitle();
513 XiHist2DNonCo_CryCry->GetYaxis()->SetTitle("Coincidence Angle #theta (#circ)");
514 XiHist2DNonCo_CryCry->GetYaxis()->CenterTitle();
515 XiHist2DNonCo_CryCry->GetZaxis()->SetTitle("Counts");
516 XiHist2DNonCo_CryCry->GetZaxis()->CenterTitle();
517 XiHist2DNonCo_CryCry->SetMarkerStyle(24);
518 XiHist2DNonCo_CryCry->SetMarkerColor(kRed);
519 XiHist2DNonCo_CryCry->SetMarkerSize(0.5);
520
521 XiHist2D_DetDet->GetXaxis()->SetTitle("Experimental Angle #xi (#circ)");
522 XiHist2D_DetDet->GetXaxis()->CenterTitle();
523 XiHist2D_DetDet->GetYaxis()->SetTitle("Coincidence Angle #theta (#circ)");
524 XiHist2D_DetDet->GetYaxis()->CenterTitle();
525 XiHist2D_DetDet->GetZaxis()->SetTitle("Counts");
526 XiHist2D_DetDet->GetZaxis()->CenterTitle();
527 XiHist2D_DetDet->SetMarkerSize(0.5);
528 XiHist2D_DetDet->SetMarkerStyle(20);
529
530 XiHist2D_CryCry->GetXaxis()->SetTitle("Experimental Angle #xi (#circ)");
531 XiHist2D_CryCry->GetXaxis()->CenterTitle();
532 XiHist2D_CryCry->GetYaxis()->SetTitle("Coincidence Angle #theta (#circ)");
533 XiHist2D_CryCry->GetYaxis()->CenterTitle();
534 XiHist2D_CryCry->GetZaxis()->SetTitle("Counts");
535 XiHist2D_CryCry->GetZaxis()->CenterTitle();
536 XiHist2D_CryCry->SetMarkerSize(0.5);
537 XiHist2D_CryCry->SetMarkerStyle(20);
538
539 std::cout << std::endl;
540 return list;
541}
#define DBLUE
Definition Globals.h:15
#define RESET_COLOR
Definition Globals.h:5
TList * ComptonHists(TTree *tree, int64_t maxEntries, TStopwatch *w)
int main(int argc, char **argv)
constexpr int MaxEntries
static Int_t ReadCalFromTree(TTree *, Option_t *opt="overwrite")
virtual Long64_t GetTimeStamp(Option_t *="") const
virtual double GetEnergy(Option_t *opt="") const
virtual Int_t GetCrystal() const
!
virtual Int_t GetDetector() const
!
TVector3 GetPosition(double dist) const override
!
static TVector3 GetPosition(int DetNbr, int CryNbr=5, double dist=110.0)
!
Definition TGriffin.cxx:501
void ResetAddback()
!
Definition TGriffin.h:91
Short_t GetMultiplicity() const override
Definition TGriffin.h:52
TGriffinHit * GetGriffinHit(const int &i)
!
Definition TGriffin.h:47
static int SubRunNumber()
Definition TRunInfo.h:202
static int RunNumber()
Definition TRunInfo.h:201