GRSISort "v4.0.0.5"
An extension of the ROOT analysis Framework
Loading...
Searching...
No Matches
ComptonPolarimetryHelper.cxx
Go to the documentation of this file.
2
4{
5 // set up the queue for event mixing by filling it with empty events
6 // we chose 10 here as a reasonable compromise between statistics and computing power/memory needed
7 for(int i = 0; i < 10; ++i) {
8 fGriffinDeque[slot].emplace_back(new TGriffin);
9 }
10
11 fH2[slot]["xiThetaDetCount"] = new TH2D("xiThetaDetCount",
12 "Possible #xi Angles in GRIFFIN Array for coincidence angle #theta (measured from clover faces);Experimental Angle #xi (#circ);Coincidence Angle #theta (#circ);Counts",
13 fXiBins, 0., 180.000001, fThetaBins, 0., 180.000001);
14 fH2[slot]["xiThetaDet"] = new TH2D("xiThetaDet",
15 "Measured #xi Angles in GRIFFIN Array for coincidence angle #theta (measured from clover faces);Experimental Angle #xi (#circ);Coincidence Angle #theta (#circ);Counts",
16 fXiBins, 0., 180.000001, fThetaBins, 0., 180.000001);
17 fH2[slot]["xiThetaDetMixed"] = new TH2D("xiThetaDetMixed",
18 "Measured #xi Angles in GRIFFIN Array for mixed angle #theta (measured from clover faces);Experimental Angle #xi (#circ);Coincidence Angle #theta (#circ);Counts",
19 fXiBins, 0., 180.000001, fThetaBins, 0., 180.000001);
20 fH2[slot]["xiThetaCryCount"] = new TH2D("xiThetaCryCount",
21 "Possible #xi Angles in GRIFFIN Array for coincidence angle #theta (measured from crystal positions);Experimental Angle #xi (#circ);Coincidence Angle #theta (#circ);Counts",
22 fXiBins, 0., 180.000001, fThetaBins, 0., 180.000001);
23 fH2[slot]["xiThetaCry"] = new TH2D("xiThetaCry",
24 "Measured #xi Angles in GRIFFIN Array for coincidence angle #theta (measured from crystal positions);Experimental Angle #xi (#circ);Coincidence Angle #theta (#circ);Counts",
25 fXiBins, 0., 180.000001, fThetaBins, 0., 180.000001);
26 fH2[slot]["xiThetaCryMixed"] = new TH2D("xiThetaCryMixed",
27 "Measured #xi Angles in GRIFFIN Array for mixed angle #theta (measured from crystal positions);Experimental Angle #xi (#circ);Coincidence Angle #theta (#circ);Counts",
28 fXiBins, 0., 180.000001, fThetaBins, 0., 180.000001);
29
30 fH1[slot]["gammaSingles"] = new TH1D("gammaSingles", "#gamma singles (All Events);Energy [keV]", fBins, fMinEnergy, fMaxEnergy);
31 fH2[slot]["gammagamma"] = new TH2D("gammagamma", "#gamma - #gamma (All Events);Energy [keV];Energy [keV]", fBins,
33 fH2[slot]["gammaCrystal"] = new TH2D("gammaCrystal", "#gamma Crystal (All Events);Energy [keV];Crystal Number",
34 fBins, fMinEnergy, fMaxEnergy, 64, 0, 64);
35 fH2[slot]["xiCrystalCount"] = new TH2D("xiCrystalCount", "Possible #xi Crystal (All Events);#xi;Crystal Number",
36 fXiBins, 0.0, 180.000001, 64, 0, 64);
37 fH2[slot]["thetaCrystalCount"] =
38 new TH2D("thetaCrystalCount", "Possible #theta Crystal (All Events);#theta;Crystal Number", fThetaBins, 0.0,
39 180.000001, 64, 0, 64);
40 fH2[slot]["xiCrystal"] =
41 new TH2D("xiCrystal", "#xi Crystal (All Events);#xi;Crystal Number", fXiBins, 0.0, 180.000001, 64, 0, 64);
42 fH2[slot]["thetaCrystal"] = new TH2D("thetaCrystal", "#theta Crystal (All Events);#theta;Crystal Number", fThetaBins,
43 0.0, 180.000001, 64, 0, 64);
44 fH2[slot]["gammaXi_g1"] =
45 new TH2D("gammaXi_g1", "#xi - #gamma (Only #gamma_{1} from Triple Coincidence);#xi;Energy [keV]", fXiBins, 0.0,
46 180.000001, fBins, fMinEnergy, fMaxEnergy);
47 fH2[slot]["gammaXi_g2"] =
48 new TH2D("gammaXi_g2", "#xi - #gamma (Only #gamma_{2} from Triple Coincidence);#xi;Energy [keV]", fXiBins, 0.0,
49 180.000001, fBins, fMinEnergy, fMaxEnergy);
50 fH1[slot]["gammaSingles_g1"] =
51 new TH1D("gammaSingles_g1", "#gamma singles (Only #gamma_{1} from Triple Coincidence);Energy [keV]", fBins,
53 fH1[slot]["gammaSingles_g2"] =
54 new TH1D("gammaSingles_g2", "#gamma singles (Only #gamma_{2} from Triple Coincidence);Energy [keV]", fBins,
56 fH1[slot]["gammaSingles_g3"] =
57 new TH1D("gammaSingles_g3", "#gamma singles (Only #gamma_{3} from Triple Coincidence);Energy [keV]", fBins,
59 fH1[slot]["ggTimeDiff_g1g2"] = new TH1D("ggTimeDiff_g1g2", "#gamma_{1}-#gamma_{2} time difference", 300, 0, 300);
60 fH1[slot]["ggTimeDiff_g1g3"] = new TH1D("ggTimeDiff_g1g3", "#gamma_{1}-#gamma_{3} time difference", 300, 0, 300);
61 fH1[slot]["ggTimeDiff_g2g3"] = new TH1D("ggTimeDiff_g2g3", "#gamma_{2}-#gamma_{3} time difference", 300, 0, 300);
62
63 // fill histograms with counts of occurance of angles (only once for the first slot)
64 if(slot == 0) {
65 //TODO rewrite as detector and crystal loops
66 for(int one = 0; one < 64; ++one) {
67 // loop over each crystal
68 if(ExcludeDetector(one / 4 + 1) || ExcludeCrystal(one)) { continue; }
69 TVector3 v1 = TGriffin::GetPosition(one / 4 + 1, one % 4, fGriffinDistance);
70 TVector3 d1 = TGriffin::GetPosition(one / 4 + 1, 5, fGriffinDistance);
71 for(int two = (one / 4) * 4; two < (one / 4 + 1) * 4; ++two) {
72 // loop over the other crystals in the same detector as one
73 if(one == two) { continue; }
74 TVector3 v2 = TGriffin::GetPosition(two / 4 + 1, two % 4, fGriffinDistance);
75 for(int three = 0; three < 64; ++three) {
76 // loop over all crystals not in the same detector as one
77 if(three / 4 == one / 4) { continue; }
78 if(ExcludeDetector(three / 4 + 1) || ExcludeCrystal(three)) { continue; }
79 TVector3 v3 = TGriffin::GetPosition(three / 4 + 1, three % 4, fGriffinDistance);
80 TVector3 d3 = TGriffin::GetPosition(three / 4 + 1, 5, fGriffinDistance);
81
82 TVector3 n1 = v3.Cross(v1);
83 TVector3 n2 = v1.Cross(v2);
84 double xi = n1.Angle(n2) * TMath::RadToDeg();
85 double theta = v3.Angle(v1) * TMath::RadToDeg();
86
87 std::cout << one << ", " << two << ", " << three << ": " << xi << ", "
88 << d1.Angle(d3) * TMath::RadToDeg() << ", " << theta << std::endl;
89 fH2[slot]["xiThetaDetCount"]->Fill(xi, d1.Angle(d3) * TMath::RadToDeg());
90 fH2[slot]["xiThetaCryCount"]->Fill(xi, theta);
91 fH2[slot]["xiCrystalCount"]->Fill(xi, one);
92 fH2[slot]["thetaCrystalCount"]->Fill(theta, one);
93 }
94 }
95 }
96 }
97}
98
99void ComptonPolarimetryHelper::Exec(unsigned int slot, TGriffin& fGriffin, TGriffinBgo& fGriffinBgo)
100{
101 for(auto g1 = 0; g1 < fGriffin.GetMultiplicity(); ++g1) {
102 auto grif1 = fGriffin.GetGriffinHit(g1);
103 if(ExcludeDetector(grif1->GetDetector()) || ExcludeCrystal(grif1->GetArrayNumber())) { continue; }
104
105 fH1[slot].at("gammaSingles")->Fill(grif1->GetEnergy());
106 fH2[slot].at("gammaCrystal")->Fill(grif1->GetEnergy(), grif1->GetArrayNumber() - 1);
107 for(auto g2 = 0; g2 < fGriffin.GetMultiplicity(); ++g2) {
108 if(g1 == g2) { continue; }
109 auto grif2 = fGriffin.GetGriffinHit(g2);
110 if(ExcludeDetector(grif2->GetDetector()) || ExcludeCrystal(grif2->GetArrayNumber())) { continue; }
111
112 fH2[slot].at("gammagamma")->Fill(grif1->GetEnergy(), grif2->GetEnergy());
113
114 // skip hits not in the same detector, in the same crystal, or the wrong order of energies (the reverse will be
115 // looped over again), or not coincident
116 if(grif1->GetDetector() != grif2->GetDetector() || grif1->GetCrystal() == grif2->GetCrystal() ||
117 grif1->GetEnergy() < grif2->GetEnergy() || !Coincident(grif1, grif2)) {
118 continue;
119 }
120
121 // check that the sum energy of the two hits matches one of our gamma gates
122 int index = CheckEnergy(grif1->GetEnergy() + grif2->GetEnergy());
123 if(index < 0) { continue; }
124
125 TVector3 v1 = grif1->GetPosition(fGriffinDistance);
126 TVector3 v2 = grif2->GetPosition(fGriffinDistance);
127 TVector3 d1 = TGriffin::GetPosition(grif1->GetDetector(), 5, fGriffinDistance);
128
129 for(auto g3 = 0; g3 < fGriffin.GetMultiplicity(); ++g3) {
130 if(g1 == g3 || g2 == g3) { continue; }
131 auto grif3 = fGriffin.GetGriffinHit(g3);
132 if(ExcludeDetector(grif3->GetDetector()) || ExcludeCrystal(grif3->GetArrayNumber())) { continue; }
133 // skip hits in the same detector as hits 1 and 2
134 if(grif1->GetDetector() == grif3->GetDetector()) { continue; }
135 // check that the energy of this gamma ray matches the other gamma gate
136 if(CheckEnergy(grif3->GetEnergy(), 1 - index) < 0) { continue; }
137 // fill time histograms
138 // check that 1 and 3 are coincident
139 fH1[slot].at("ggTimeDiff_g1g2")->Fill(TimeDiff(grif1, grif2));
140 fH1[slot].at("ggTimeDiff_g1g3")->Fill(TimeDiff(grif1, grif3));
141 fH1[slot].at("ggTimeDiff_g2g3")->Fill(TimeDiff(grif2, grif3));
142 if(!Coincident(grif1, grif3)) { continue; }
143
144 TVector3 v3 = grif3->GetPosition(fGriffinDistance);
145 TVector3 d3 = TGriffin::GetPosition(grif3->GetDetector(), 5, fGriffinDistance);
146
147 TVector3 n1 = v3.Cross(v1);
148 TVector3 n2 = v1.Cross(v2);
149
150 double xi = n1.Angle(n2) * TMath::RadToDeg();
151 double theta = v3.Angle(v1) * TMath::RadToDeg();
152
153 fH2[slot].at("xiThetaCry")->Fill(xi, theta);
154 fH2[slot].at("xiThetaDet")->Fill(xi, d1.Angle(d3) * TMath::RadToDeg());
155 fH2[slot].at("xiCrystal")->Fill(xi, grif1->GetArrayNumber() - 1);
156 fH2[slot].at("thetaCrystal")->Fill(theta, grif1->GetArrayNumber() - 1);
157
158 fH2[slot].at("gammaXi_g1")->Fill(xi, grif1->GetEnergy());
159 fH2[slot].at("gammaXi_g2")->Fill(xi, grif2->GetEnergy());
160 fH1[slot].at("gammaSingles_g1")->Fill(grif1->GetEnergy());
161 fH1[slot].at("gammaSingles_g2")->Fill(grif2->GetEnergy());
162 fH1[slot].at("gammaSingles_g3")->Fill(grif3->GetEnergy());
163 } // for g3
164
165 // Event mixing: loop over all stored events for this thread/slot and use them as the "third" gamma ray
166 for(auto l = 0; l < fGriffinDeque[slot].size(); ++l) {
167 auto fLastGriffin = fGriffinDeque[slot][l];
168 for(auto g3 = 0; g3 < fLastGriffin->GetMultiplicity(); ++g3) {
169 if(g1 == g3 || g2 == g3) { continue; }
170 auto grif3 = fLastGriffin->GetGriffinHit(g3);
171 if(ExcludeDetector(grif3->GetDetector()) || ExcludeCrystal(grif3->GetArrayNumber())) { continue; }
172 // skip hits in the same detector as hits 1 and 2
173 if(grif1->GetDetector() == grif3->GetDetector()) { continue; }
174 // check that the energy of this gamma ray matches the other gamma gate
175 if(CheckEnergy(grif3->GetEnergy(), 1 - index) < 0) { continue; }
176
177 TVector3 v3 = grif3->GetPosition(fGriffinDistance);
178 TVector3 d3 = TGriffin::GetPosition(grif3->GetDetector(), 5, fGriffinDistance);
179
180 TVector3 n1 = v3.Cross(v1);
181 TVector3 n2 = v1.Cross(v2);
182
183 double xi = n1.Angle(n2) * TMath::RadToDeg();
184 double theta = v3.Angle(v1) * TMath::RadToDeg();
185
186 fH2[slot].at("xiThetaCryMixed")->Fill(xi, theta);
187 fH2[slot].at("xiThetaDetMixed")->Fill(xi, d1.Angle(d3) * TMath::RadToDeg());
188 }
189 }
190 } // for g2
191 } // for g1
192
193 // Add the current event to the queue, delete the oldest event in the queue, and pop the pointer from the queue.
194 fGriffinDeque[slot].emplace_back(new TGriffin(fGriffin));
195
196 delete fGriffinDeque[slot].front();
197
198 fGriffinDeque[slot].pop_front();
199}
double TimeDiff(TGriffinHit *grif1, TGriffinHit *grif2) const
bool Coincident(TGriffinHit *grif1, TGriffinHit *grif2) const
void Exec(unsigned int slot, TGriffin &fGriffin, TGriffinBgo &fGriffinBgo)
void CreateHistograms(unsigned int slot) override
Virtual helper function that the user uses to create their histograms.
bool ExcludeCrystal(int arraynumber) const
bool ExcludeDetector(int detector) const
std::map< unsigned int, std::deque< TGriffin * > > fGriffinDeque
int CheckEnergy(double energy, int index=-1) const
std::vector< TGRSIMap< std::string, TH2 * > > fH2
Definition TGRSIHelper.h:49
std::vector< TGRSIMap< std::string, TH1 * > > fH1
Definition TGRSIHelper.h:48
static TVector3 GetPosition(int DetNbr, int CryNbr=5, double dist=110.0)
!
Definition TGriffin.cxx:501
Short_t GetMultiplicity() const override
Definition TGriffin.h:52
TGriffinHit * GetGriffinHit(const int &i)
!
Definition TGriffin.h:47