17 : fIndexCorrelation(nullptr), fIndexMapSize(0), fFolded(kFALSE), fGrouped(kFALSE)
43 Bool_t group = kFALSE)
48 Int_t energy1axis = 0;
49 Int_t energy2axis = 0;
50 std::array<Double_t, 3> xmin;
51 std::array<Double_t, 3> xmax;
52 for(
int i = 0; i < 3; i++) {
53 xmin[i] = hst->GetAxis(i)->GetXmin();
54 xmax[i] = hst->GetAxis(i)->GetXmax();
56 if(xmin[0] == xmin[1] && xmax[0] == xmax[1]) {
60 }
else if(xmin[1] == xmin[2] && xmax[1] == xmax[2]) {
64 }
else if(xmin[2] == xmin[0] && xmax[2] == xmax[0]) {
69 std::cout <<
"Can't identify energy axes. Assuming index axis is axis 0." << std::endl;
76 hst->GetAxis(energy1axis)->SetRangeUser(min, max);
77 TH2D* tempslice = hst->Projection(indexaxis, energy2axis,
"eo");
78 tempslice->SetName(Form(
"%s_proj_%i", hst->GetName(),
static_cast<Int_t
>((max + min) / 2)));
79 tempslice->SetTitle(Form(
"%s: %i keV", hst->GetTitle(),
static_cast<Int_t
>((max + min) / 2)));
102 Bool_t group = kFALSE)
107 Bool_t sparse = kFALSE;
108 Bool_t hst2d = kFALSE;
109 TIter next(hstarray);
110 TObject* obj =
nullptr;
111 while((obj = next()) !=
nullptr) {
113 if(obj->InheritsFrom(
"TH2")) {
118 std::cout <<
"found both THnSparse and TH2 in array." << std::endl;
119 std::cout <<
"currently, Create2DSlice only deals with one." << std::endl;
120 std::cout <<
"Bailing out." << std::endl;
123 }
else if(obj->InheritsFrom(
"THnSparse")) {
128 std::cout <<
"found both THnSparse and TH2 in array." << std::endl;
129 std::cout <<
"currently, Create2DSlice only deals with one." << std::endl;
130 std::cout <<
"Bailing out." << std::endl;
134 std::cout <<
"Element is neither THnSparse or TH2." << std::endl;
135 std::cout <<
"Bailing." << std::endl;
140 if(!sparse && !hst2d) {
141 std::cout <<
"Can't identify the type of object in the array." << std::endl;
142 std::cout <<
"Returning without slicing." << std::endl;
147 Int_t elements = hstarray->GetEntries();
151 const Char_t* name =
nullptr;
152 const Char_t* title =
nullptr;
154 auto* firsthst =
static_cast<THnSparse*
>(hstarray->At(0));
155 bins = firsthst->GetAxis(0)->GetNbins();
156 xmin = firsthst->GetAxis(0)->GetBinLowEdge(1);
157 xmax = firsthst->GetAxis(0)->GetBinUpEdge(bins);
158 name = firsthst->GetName();
159 title = firsthst->GetTitle();
161 auto* firsthst =
static_cast<TH2*
>(hstarray->At(0));
162 bins = firsthst->GetXaxis()->GetNbins();
163 xmin = firsthst->GetXaxis()->GetBinLowEdge(1);
164 xmax = firsthst->GetXaxis()->GetBinUpEdge(bins);
165 name = firsthst->GetName();
166 title = firsthst->GetTitle();
168 Int_t ybins = elements;
171 TH2D* newslice =
nullptr;
172 if(gFile->Get(Form(
"%s_%i_%i", name,
static_cast<Int_t
>(min),
static_cast<Int_t
>(max))) ==
nullptr) {
173 newslice =
new TH2D(Form(
"%s_%i_%i", name,
static_cast<Int_t
>(min),
static_cast<Int_t
>(max)),
174 Form(
"%s, E_{#gamma 1}=[%.1f,%.1f)", title, min, max), bins, xmin, xmax, ybins, 0, ybins);
176 while(iteration < 10) {
177 if(gFile->Get(Form(
"%s_%i_%i_%i", name,
static_cast<Int_t
>(min),
static_cast<Int_t
>(max), iteration)) ==
nullptr) {
182 newslice =
new TH2D(Form(
"%s_%i_%i_%i", name,
static_cast<Int_t
>(min),
static_cast<Int_t
>(max), iteration),
183 Form(
"%s, E_{#gamma 1}=[%.1f,%.1f)", title, min, max), bins, xmin, xmax, ybins, 0, ybins);
187 for(Int_t i = 0; i < elements; i++) {
189 TH1D* tempslice =
nullptr;
192 auto* thishst =
static_cast<THnSparse*
>(hstarray->At(i));
193 thishst->GetAxis(0)->SetRangeUser(min, max);
194 tempslice = thishst->Projection(
197 auto* thishst =
static_cast<TH2*
>(hstarray->At(i));
198 thishst->GetXaxis()->SetRangeUser(min, max);
199 tempslice = thishst->ProjectionY();
204 for(Int_t j = 1; j <= bins; j++) {
205 Double_t x = tempslice->GetBinCenter(j);
206 Int_t bin = newslice->FindBin(x, y);
207 Double_t newcontent = tempslice->GetBinContent(j);
208 Double_t oldcontent = newslice->GetBinContent(bin);
209 Double_t newerror = tempslice->GetBinError(j);
210 Double_t olderror = newslice->GetBinError(bin);
211 newslice->SetBinContent(bin, oldcontent + newcontent);
212 newslice->SetBinError(bin, sqrt(pow(newerror, 2) + pow(olderror, 2)));
229 if(!fold && !group) {
230 std::cout <<
"No folding or grouping selected." << std::endl;
231 std::cout <<
"Returning unmodified 2D slice." << std::endl;
232 return static_cast<TH2D*
>(hst);
245 Int_t group_numbers =
fGroups.size();
249 if(angle_numbers == 0) {
250 std::cout <<
"Angle Map has not been defined yet." << std::endl;
251 std::cout <<
"Need Angle Map to assign groups." << std::endl;
252 std::cout <<
"Bailing out." << std::endl;
256 if(group_numbers == 0) {
257 std::cout <<
"Groups have not been assigned yet." << std::endl;
258 std::cout <<
"Cannot group Angular Indexes." << std::endl;
259 std::cout <<
"Bailing out." << std::endl;
263 if(group_numbers != angle_numbers) {
264 if(group_numbers < angle_numbers) {
265 std::cout <<
"Not all angular indexes have been assigned a group." << std::endl;
266 std::cout <<
"Bailing out." << std::endl;
269 if(group_numbers > angle_numbers) {
270 std::cout <<
"Too many groups have been assigned, not enough angular indexes." << std::endl;
271 std::cout <<
"Bailing out." << std::endl;
278 Int_t bins = hst->GetNbinsX();
279 Double_t xmin = hst->GetXaxis()->GetBinLowEdge(1);
280 Double_t xmax = hst->GetXaxis()->GetBinUpEdge(bins);
283 const Char_t* hst2dname = hst->GetName();
284 const Char_t* hst2dtitle = hst->GetTitle();
287 Int_t ybins = hst->GetNbinsY();
291 TH2D* modified_slice =
nullptr;
292 if(
static_cast<int>(
static_cast<int>((group)) &
static_cast<int>(!fold)) != 0) {
293 modified_slice =
new TH2D(Form(
"%s_grouped", hst2dname), Form(
"%s_grouped", hst2dtitle), bins, xmin, xmax,
294 newybins, 0, newybins);
295 }
else if(
static_cast<int>(
static_cast<int>((fold)) &
static_cast<int>(!group)) != 0) {
296 modified_slice =
new TH2D(Form(
"%s_folded", hst2dname), Form(
"%s_folded", hst2dtitle), bins, xmin, xmax, newybins,
298 }
else if(fold && group) {
299 modified_slice =
new TH2D(Form(
"%s_grouped_folded", hst2dname), Form(
"%s_grouped_folded", hst2dtitle), bins, xmin,
300 xmax, newybins, 0, newybins);
302 modified_slice =
new TH2D(Form(
"%s_unknown", hst2dname), Form(
"%s_unknown", hst2dtitle), bins, xmin, xmax,
303 newybins, 0, newybins);
307 for(Int_t i = 0; i < ybins; i++) {
308 TH1D* tempslice =
nullptr;
309 tempslice = hst->ProjectionX(
"", i + 1, i + 1);
314 for(Int_t j = 1; j <= bins; j++) {
315 Double_t x = tempslice->GetBinCenter(j);
316 Int_t bin = modified_slice->FindBin(x, y);
318 Double_t newcontent = tempslice->GetBinContent(j);
319 Double_t newerror = tempslice->GetBinError(j);
321 Double_t oldcontent = modified_slice->GetBinContent(bin);
322 Double_t olderror = modified_slice->GetBinError(bin);
324 modified_slice->SetBinContent(bin, oldcontent + newcontent);
325 modified_slice->SetBinError(bin, sqrt(pow(newerror, 2) + pow(olderror, 2)));
333 return modified_slice;
349 hst->GetXaxis()->SetRangeUser(min, max);
379 auto indexmin =
static_cast<Int_t
>(hst->GetYaxis()->GetXmin());
380 auto indexmax =
static_cast<Int_t
>(hst->GetYaxis()->GetXmax());
381 const Int_t indexbins = indexmax - indexmin;
384 const Char_t* hst2dname = hst->GetName();
385 const Char_t* hst2dtitle = hst->GetTitle();
386 const Char_t* hst1dname = Form(
"%s_%ikeV", hst2dname,
static_cast<Int_t
>(peak->
GetCentroid()));
387 const Char_t* hst1dtitle = Form(
"%s-%ikeV", hst2dtitle,
static_cast<Int_t
>(peak->
GetCentroid()));
390 auto* newhst =
new TH1D(hst1dname, Form(
"%s;Angular index;Counts", hst1dtitle), indexbins, indexmin, indexmax);
398 Double_t minenergy = 0.;
399 Double_t maxenergy = 0.;
400 peak->GetRange(minenergy, maxenergy);
401 Double_t difference = maxenergy - minenergy;
402 minenergy = minenergy - 0.5 * difference;
403 maxenergy = maxenergy + 0.5 * difference;
404 hst->GetXaxis()->SetRangeUser(minenergy, maxenergy);
405 Double_t AvgFWHM = 0;
410 std::vector<TCanvas*> c;
412 TH1D* totalProjection =
413 hst->ProjectionX(Form(
"total_%sproj", hst2dname), hst->GetYaxis()->GetFirst(), hst->GetYaxis()->GetLast());
417 peak->SetParameter(
"centroid", peak->
GetCentroid());
419 std::cout <<
"initial parameters:" << std::endl;
420 for(
int i = 0; i < peak->GetNpar(); i++) {
423 peak->GetParLimits(i, min, max);
424 std::cout << i <<
": " << peak->GetParameter(i) <<
"; " << min <<
" - " << max << std::endl;
426 std::cout <<
"===========================" << std::endl;
427 peak->SetParameter(0, totalProjection->GetMaximum() / 2.);
428 peak->SetParLimits(0, 0., 2. * totalProjection->GetMaximum());
433 peak->SetParLimits(7, -0.1, 0.1);
434 peak->FixParameter(8, 0.);
437 std::cout <<
"Our parameters:" << std::endl;
438 for(
int i = 0; i < peak->GetNpar(); i++) {
441 peak->GetParLimits(i, min, max);
442 std::cout << i <<
": " << peak->GetParameter(i) <<
"; " << min <<
" - " << max << std::endl;
444 std::cout <<
"==========================" << std::endl;
447 std::cout <<
"Final parameters:" << std::endl;
448 for(
int i = 0; i < peak->GetNpar(); i++) {
451 peak->GetParLimits(i, min, max);
452 std::cout << i <<
": " << peak->GetParameter(i) <<
"; " << min <<
" - " << max << std::endl;
454 std::cout <<
"==========================" << std::endl;
455 std::cout <<
"Peak area = " << peak->
GetArea() <<
" +/- " << peak->
GetAreaErr() << std::endl;
456 double peakCentroid = peak->GetParameter(1);
457 double sigma = peak->GetParameter(2);
458 std::cout <<
"Fixing the centroid to " << peakCentroid <<
", and sigma to " << sigma <<
" (FWHM = " << 2.355 * sigma
461 auto* file =
new TFile(
"Fit_singles.root",
"recreate");
462 for(Int_t i = 1; i <= indexmax - indexmin; i++) {
463 auto index =
static_cast<Int_t
>(hst->GetYaxis()->GetBinLowEdge(i));
466 Int_t canvas = (i - 1) / 16;
467 Int_t pad = (i - 1) % 16;
469 auto* temp =
new TCanvas(Form(
"c%i", canvas), Form(
"c%i", canvas), 800, 800);
474 c[canvas]->cd(pad + 1);
478 TH1D* temphst = hst->ProjectionX(Form(
"%s_proj%i", hst2dname, index), i, i);
479 temphst->SetStats(
false);
480 temphst->SetTitle(Form(
"%s: angular index %i", hst->GetTitle(), index));
489 if(temphst->Integral() < 50) {
494 peak->SetName(Form(
"%s_proj%i_peak", hst2dname, index));
498 peak->SetParameter(0, temphst->GetMaximum());
499 peak->FixParameter(1, peakCentroid);
500 peak->FixParameter(2, sigma);
501 peak->SetParLimits(7, -0.1, 0.1);
502 peak->FixParameter(8, 0.);
503 peak->SetParameter(9, peakCentroid);
504 peak->SetParLimits(9, peakCentroid - 2., peakCentroid + 2.);
507 peak->
Fit(temphst,
"LL");
513 bool fitresult =
false;
515 fitresult = peak->
Fit(temphst,
"Q");
517 fitresult = peak->
Fit(temphst,
"Q0");
523 static_cast<TPeak*
>(temphst->GetListOfFunctions()->Last())->
Background()->Draw(
"same");
526 Double_t FullWidthHM = peak->GetParameter(2);
527 AvgFWHM = AvgFWHM + FullWidthHM;
529 SetPeak(index,
static_cast<TPeak*
>(temphst->GetFunction(Form(
"%s_proj%i_peak", hst2dname, index))));
532 Double_t area =
static_cast<TPeak*
>(
GetPeak(index))->GetArea();
533 Double_t area_err =
static_cast<TPeak*
>(
GetPeak(index))->GetAreaErr();
534 Double_t chi2 = peak->GetChisquare();
535 Double_t ndf = peak->GetNDF();
536 Double_t scale = TMath::Max(1.0, TMath::Sqrt(chi2 / ndf));
537 if(area_err < scale * TMath::Sqrt(area)) {
538 std::cout <<
"Area error was less than the scaled square root of the area." << std::endl;
539 std::cout <<
"This means something is wrong; using scaled square root of area for area error." << std::endl;
540 area_err = TMath::Sqrt(area) * scale;
544 newhst->SetBinContent(i, area);
545 newhst->SetBinError(i, area_err);
548 Double_t TrueFWHM = AvgFWHM / (indexmax - indexmin);
549 std::cout <<
"True sigma = " << TrueFWHM << std::endl;
556 new TCanvas(Form(
"c_diag_%i",
static_cast<Int_t
>(peak->
GetCentroid())),
557 Form(
"Diagnostics for fitting %i keV peak",
static_cast<Int_t
>(peak->
GetCentroid())), 800, 800);
560 hst2dname = hst->GetName();
561 hst1dname = Form(
"%s_%ikeV", hst2dname,
static_cast<Int_t
>(peak->
GetCentroid()));
563 new TH1D(Form(
"%s_chi2", hst1dname), Form(
"%s: #chi^{2};Angular index;#chi^{2}/NDF value", newhst->GetTitle()),
564 indexbins, indexmin, indexmax);
565 auto* centroidhst =
new TH1D(Form(
"%s_centroid", hst1dname),
566 Form(
"%s: Peak centroid;Angular index;Peak centroid (keV)", newhst->GetTitle()),
567 indexbins, indexmin, indexmax);
568 auto* fwhmhst =
new TH1D(Form(
"%s_fwhm", hst1dname), Form(
"%s: FWHM;Angular index;FWHM (keV)", newhst->GetTitle()),
569 indexbins, indexmin, indexmax);
599 if(!fold && !group) {
602 std::cout <<
"Angles have not been assigned." << std::endl;
603 std::cout <<
"Therefore cannot create graph." << std::endl;
616 std::cout <<
"Modified angles have not been assigned." << std::endl;
617 std::cout <<
"Therefore cannot create graph." << std::endl;
628 auto* graph =
new TGraphAsymmErrors();
629 Int_t n = hst->GetNbinsX();
631 for(Int_t i = 1; i <= n; i++) {
634 auto index =
static_cast<Int_t
>(hst->GetXaxis()->GetBinLowEdge(i));
638 if(!fold && !group) {
645 Double_t y = hst->GetBinContent(i);
649 Double_t yerr = hst->GetBinError(i);
652 Int_t graphn = graph->GetN();
653 graph->SetPoint(graphn, TMath::Cos(angle), y);
654 graph->SetPointError(graphn, 0, 0, yerr, yerr);
658 graph->SetTitle(Form(
"%s;cos(#theta);Counts", hst->GetTitle()));
672 if(arraynum1 == 0 || arraynum2 == 0) {
673 std::cout <<
"Array numbers usually begin at 1 - unless you have programmed" << std::endl;
674 std::cout <<
"it differently explicitly, don't trust this output." << std::endl;
677 std::cout <<
"Error: array number " << arraynum1 <<
" is not present in the index map." << std::endl;
680 if(
fIndexMap[arraynum1].count(arraynum2) == 0) {
681 std::cout <<
"Error: element [" << arraynum1 <<
"][" << arraynum2 <<
"] is not present in the index map." << std::endl;
695 Bool_t result = kTRUE;
696 if(!fold && !group) {
698 std::cout <<
"fAngleMap and fWeights do not have the same size." << std::endl;
699 std::cout <<
"fAngleMap size is: " <<
static_cast<Int_t
>(
fAngleMap.size()) << std::endl;
700 std::cout <<
"fWeights size is: " <<
static_cast<Int_t
>(
fWeights.size()) << std::endl;
705 std::cout <<
"fModifiedAngles and fModifiedWeights do not have the same size." << std::endl;
706 std::cout <<
"fModifiedAngles size is: " <<
static_cast<Int_t
>(
fModifiedAngles.size()) << std::endl;
707 std::cout <<
"fModifiedWeights size is: " <<
static_cast<Int_t
>(
fModifiedWeights.size()) << std::endl;
722 std::cout <<
"Indexes have not been assigned yet." << std::endl;
723 std::cout <<
"Therefore cannot print map." << std::endl;
727 for(Int_t i = 1; i <= size; i++) {
728 std::cout <<
"-----------------------------------------------------" << std::endl;
729 std::cout <<
"|| Array number 1 | Array number 2 | Angular index ||" << std::endl;
730 std::cout <<
"-----------------------------------------------------" << std::endl;
731 for(Int_t j = 1; j <= size; j++) {
735 std::cout << std::left <<
"|| " << std::setw(14) << i <<
" | " << std::setw(14) << j <<
" | " << std::setw(13) <<
GetAngularIndex(i, j) <<
" ||" << std::right << std::endl;
738 std::cout <<
"-----------------------------------------------------" << std::endl;
748 Int_t weight_size =
fWeights.size();
750 std::cout <<
"The angle map hasn't been created yet." << std::endl;
751 std::cout <<
"Therefore, can't print." << std::endl;
755 if(weight_size == 0) {
756 std::cout <<
"The weights haven't been calculated yet." << std::endl;
757 std::cout <<
"Therefore, can't print." << std::endl;
761 std::cout <<
"--------------------------------------------------------" << std::endl;
762 std::cout <<
"|| Angular index | Opening angle (rad) | Weight ||" << std::endl;
763 std::cout <<
"--------------------------------------------------------" << std::endl;
764 for(Int_t i = 0; i < size; i++) {
765 std::cout << std::left <<
"|| " << std::setw(13) << i <<
" | " << std::setw(19) <<
GetAngleFromIndex(i) <<
" | " << std::setw(6) <<
GetWeightFromIndex(i) <<
" ||" << std::right << std::endl;
767 std::cout <<
"--------------------------------------------------------" << std::endl;
776 Int_t group_size =
fGroups.size();
778 std::cout <<
"The angle map hasn't been created yet." << std::endl;
779 std::cout <<
"Therefore, can't print." << std::endl;
782 if(group_size == 0) {
783 std::cout <<
"The groups haven't been assigned yet." << std::endl;
784 std::cout <<
"Therefore, can't print." << std::endl;
788 std::cout <<
"-------------------------------------" << std::endl;
789 std::cout <<
"|| Angular index | Group index ||" << std::endl;
790 std::cout <<
"-------------------------------------" << std::endl;
791 for(Int_t i = 0; i < size; i++) {
792 std::cout <<
"|| " << std::setw(13) << i <<
" | " << std::setw(11) <<
GetGroupFromIndex(i) <<
" ||" << std::endl;
794 std::cout <<
"-------------------------------------" << std::endl;
806 std::cout <<
"The number of groups haven't been determined yet." << std::endl;
807 std::cout <<
"Therefore, can't print." << std::endl;
810 if(angle_size == 0) {
811 std::cout <<
"The angles haven't been assigned yet." << std::endl;
812 std::cout <<
"Therefore, can't print." << std::endl;
815 std::cout <<
"-----------------------------------" << std::endl;
816 std::cout <<
"|| Group index | Angle (rad) ||" << std::endl;
817 std::cout <<
"-----------------------------------" << std::endl;
818 for(Int_t i = 0; i < size; i++) {
819 std::cout <<
"|| " << std::setw(11) << i <<
" | " << std::setw(12) <<
GetGroupAngleFromIndex(i) <<
" ||" << std::endl;
821 std::cout <<
"-----------------------------------" << std::endl;
832 std::cout <<
"Folded angles have not been assigned yet." << std::endl;
833 std::cout <<
"Therefore cannot print map." << std::endl;
837 std::cout <<
"---------------------------------------------" << std::endl;
838 std::cout <<
"|| Angular index | Opening angle (rad) ||" << std::endl;
839 std::cout <<
"---------------------------------------------" << std::endl;
840 for(Int_t i = 0; i < size; i++) {
841 std::cout << std::left <<
"|| " << std::setw(13) << i <<
" | " << std::setw(19) <<
GetAngleFromIndex(i) <<
" ||" << std::right << std::endl;
843 std::cout <<
"---------------------------------------------" << std::endl;
855 std::cout <<
"Folded angles have not been assigned yet." << std::endl;
856 std::cout <<
"Therefore cannot print map." << std::endl;
860 std::cout <<
"--------------------------------------" << std::endl;
861 std::cout <<
"|| Modified index | Angle (rad) ||" << std::endl;
862 std::cout <<
"--------------------------------------" << std::endl;
863 for(Int_t i = 0; i < size; i++) {
864 std::cout <<
"|| " << std::setw(14) << i <<
" | " << std::setw(11) <<
GetModifiedAngleFromIndex(i) <<
" ||" << std::endl;
866 std::cout <<
"--------------------------------------" << std::endl;
879 std::cout <<
"Modified angles have not been assigned yet." << std::endl;
880 std::cout <<
"Therefore cannot print map." << std::endl;
883 if(weight_size == 0) {
884 std::cout <<
"Modified weights have not been generated yet." << std::endl;
885 std::cout <<
"Therefore cannot print map." << std::endl;
889 std::cout <<
"-------------------------------------------------" << std::endl;
890 std::cout <<
"|| Modified index | Angle (rad) | Weight ||" << std::endl;
891 std::cout <<
"-------------------------------------------------" << std::endl;
892 for(Int_t i = 0; i < size; i++) {
895 std::cout <<
"-------------------------------------------------" << std::endl;
905 std::cout <<
"Modified indices have not been assigned yet." << std::endl;
906 std::cout <<
"Therefore cannot print map." << std::endl;
910 std::cout <<
"----------------------------------------" << std::endl;
911 std::cout <<
"|| Angular index | Modified index ||" << std::endl;
912 std::cout <<
"----------------------------------------" << std::endl;
913 for(Int_t i = 0; i < size; i++) {
914 std::cout <<
"|| " << std::setw(13) << i <<
" | " << std::setw(14) <<
GetModifiedIndex(i) <<
" ||" << std::endl;
916 std::cout <<
"----------------------------------------" << std::endl;
927 std::vector<Int_t>& distances)
930 std::vector<Double_t> map;
933 const Int_t size = arraynumbers.size();
934 if(size !=
static_cast<Int_t
>(distances.size())) {
935 std::cout <<
"Lengths of array number and distance vectors are inconsistent." << std::endl;
936 std::cout <<
"Array number vector size: " << size << std::endl;
937 std::cout <<
"Distance vector size: " << distances.size() << std::endl;
941 for(Int_t i = 0; i < size; i++) {
943 Int_t detector1 = (arraynumbers[i] - 1) / 4 + 1;
944 Int_t crystal1 = (arraynumbers[i] - 1) % 4;
947 for(Int_t j = i; j < size; j++) {
949 Int_t detector2 = (arraynumbers[j] - 1) / 4 + 1;
950 Int_t crystal2 = (arraynumbers[j] - 1) % 4;
951 TVector3 positionone =
953 TVector3 positiontwo =
955 Double_t angle = positionone.Angle(positiontwo);
956 Bool_t alreadyclaimed = kFALSE;
957 for(
double m : map) {
958 if(TMath::Abs(angle - m) < 0.00005) {
959 alreadyclaimed = kTRUE;
963 if(!alreadyclaimed) {
964 map.push_back(angle);
970 std::sort(map.begin(), map.end());
988 std::map<Int_t, std::map<Int_t, Int_t>>& indexmap)
990 std::vector<Int_t> weights;
993 Int_t size = arraynumbers.size();
997 for(Int_t i = 0; i < size; i++) {
998 for(Int_t j = 0; j < size; j++) {
999 if(indexmap[i][j] > max) {
1000 max = indexmap[i][j];
1006 for(Int_t i = 0; i <= max; i++) {
1007 weights.push_back(0);
1011 for(Int_t i = 0; i < size; i++) {
1012 if(arraynumbers[i] < 1 || arraynumbers[i] > 64) {
1013 std::cout << arraynumbers[i] <<
" is not a good array number." << std::endl;
1014 std::cout <<
"Skipping... you'll probably get some errors." << std::endl;
1018 for(Int_t j = 0; j < size; j++) {
1019 Int_t index = indexmap[arraynumbers[i]][arraynumbers[j]];
1020 Int_t old_weight = weights[index];
1021 Int_t new_weight = old_weight + 1;
1022 weights[index] = new_weight;
1038 std::vector<Int_t>& weights)
1040 std::vector<Int_t> modifiedweights;
1043 Int_t size = weights.size();
1047 for(Int_t i = 0; i < size; i++) {
1048 if(modindices[i] > max) {
1049 max = modindices[i];
1054 for(Int_t i = 0; i <= max; i++) {
1055 modifiedweights.push_back(0);
1059 for(Int_t i = 0; i < size; i++) {
1060 Int_t thisIndex = modindices[i];
1061 modifiedweights[thisIndex] = modifiedweights[thisIndex] + weights[i];
1064 return modifiedweights;
1077 std::vector<Int_t>& distances,
1078 std::vector<Double_t>& anglemap)
1081 std::map<Int_t, std::map<Int_t, Int_t>> indexmap;
1084 Int_t size = arraynumbers.size();
1087 Int_t mapsize = anglemap.size();
1090 for(Int_t i = 0; i < size; i++) {
1091 if(arraynumbers[i] < 1 || arraynumbers[i] > 64) {
1092 std::cout << arraynumbers[i] <<
" is not a good array number." << std::endl;
1093 std::cout <<
"Skipping... you'll probably get some errors." << std::endl;
1098 Int_t detector1 = (arraynumbers[i] - 1) / 4 + 1;
1099 Int_t crystal1 = (arraynumbers[i] - 1) % 4;
1100 TVector3 positionone =
1104 for(Int_t j = 0; j < size; j++) {
1106 Int_t detector2 = (arraynumbers[j] - 1) / 4 + 1;
1107 Int_t crystal2 = (arraynumbers[j] - 1) % 4;
1108 TVector3 positiontwo =
1110 Double_t angle = positionone.Angle(positiontwo);
1111 for(Int_t m = 0; m < mapsize; m++) {
1112 if(TMath::Abs(angle - anglemap[m]) < 0.00005) {
1113 Int_t index1 = arraynumbers[i];
1114 Int_t index2 = arraynumbers[j];
1115 if(index1 == 0 || index2 == 0) {
1116 std::cout <<
"found array number of zero?" << std::endl;
1118 indexmap[index1][index2] = m;
1140 Int_t size = group.size();
1144 std::cout <<
"The group list is inconsistent with the number of angular indices." << std::endl;
1145 std::cout <<
"Number of groups: " << size << std::endl;
1146 std::cout <<
"Number of angular indices: " <<
fNumIndices << std::endl;
1176 if(fModifiedIndice > max) {
1177 max = fModifiedIndice;
1193 std::vector<Double_t> groupangle;
1196 Int_t size = groupangles.size();
1200 if(size != numgroups) {
1201 std::cout <<
"Not all groups have been assigned an angle." << std::endl;
1219 std::vector<Double_t> folds;
1222 Int_t size = anglemap.size();
1226 std::cout <<
"Angles have not been assigned yet. " << std::endl;
1227 std::cout <<
"Therefore cannot fold indexes. " << std::endl;
1232 std::vector<Double_t> foldArray(size);
1235 for(Int_t i = 0; i < size; i++) {
1236 foldArray[i] = anglemap[i];
1240 for(Int_t i = 0; i < size; i++) {
1241 Double_t fold_angle = foldArray[i];
1242 Bool_t alreadyclaimed = kFALSE;
1244 for(
double fold : folds) {
1245 if(TMath::Abs(TMath::Sin(fold_angle) - TMath::Sin(fold)) <
1247 alreadyclaimed = kTRUE;
1251 if(!alreadyclaimed) {
1252 folds.push_back(fold_angle);
1256 std::sort(folds.begin(), folds.end());
1271 std::vector<Double_t>& anglemap)
1273 std::vector<Int_t> fold_indexes;
1276 Int_t fold_size = folds.size();
1277 Int_t angle_size = anglemap.size();
1280 for(Int_t i = 0; i < angle_size; i++) {
1281 Double_t angle = anglemap[i];
1282 Double_t sin_angle = TMath::Sin(angle);
1285 for(Int_t j = 0; j < fold_size; j++) {
1286 Double_t rad_angle = folds[j];
1287 Double_t fold_angle = TMath::Sin(rad_angle);
1288 if(TMath::Abs(fold_angle - sin_angle) < 0.000005) {
1289 fold_indexes.push_back(j);
1295 return fold_indexes;
1307 const Int_t size = arraynumbers.size();
1308 if(size !=
static_cast<Int_t
>(distances.size())) {
1309 std::cout <<
"Lengths of array number and distance vectors are inconsistent." << std::endl;
1310 std::cout <<
"Array number vector size: " << size << std::endl;
1311 std::cout <<
"Distance vector size: " << distances.size() << std::endl;
1319 for(Int_t i = 0; i < size; i++) {
1344 std::cout <<
"The groups are not set up properly." << std::endl;
1345 std::cout <<
"Cannot create grouped maps." << std::endl;
1346 std::cout <<
"Please use AssignGroupMaps first." << std::endl;
1368 std::vector<Int_t>& group, std::vector<Double_t>& groupangles)
1371 const Int_t size = arraynumbers.size();
1372 if(size !=
static_cast<Int_t
>(distances.size())) {
1373 std::cout <<
"Lengths of array number and distance vectors are inconsistent." << std::endl;
1374 std::cout <<
"Array number vector size: " << size << std::endl;
1375 std::cout <<
"Distance vector size: " << distances.size() << std::endl;
1383 for(Int_t i = 0; i < size; i++) {
1439 std::vector<Int_t> array_numbers;
1440 std::vector<Int_t> distances;
1442 if(detectors == 16) {
1443 std::cout <<
"Generating maps for full array setup." << std::endl;
1444 for(Int_t i = 1; i <= 64; i++) {
1445 array_numbers.push_back(i);
1446 distances.push_back(distance);
1448 }
else if(detectors == 15) {
1449 std::cout <<
"Generating maps for full array setup, less detector 13." << std::endl;
1450 for(Int_t i = 1; i <= 64; i++) {
1451 if(i >= 49 && i <= 52) {
1454 array_numbers.push_back(i);
1455 distances.push_back(distance);
1457 }
else if(detectors == 12) {
1458 std::cout <<
"Generating maps for detectors 5-16." << std::endl;
1459 for(Int_t i = 17; i <= 64; i++) {
1460 array_numbers.push_back(i);
1461 distances.push_back(distance);
1463 }
else if(detectors == 11) {
1464 std::cout <<
"Generating maps for detectors 5-16, less detector 13." << std::endl;
1465 for(Int_t i = 17; i <= 64; i++) {
1466 if(i >= 49 && i <= 52) {
1469 array_numbers.push_back(i);
1470 distances.push_back(distance);
1472 }
else if(detectors == 8) {
1473 std::cout <<
"Generating maps for the corona only, detectors 5-12." << std::endl;
1474 for(Int_t i = 17; i <= 48; i++) {
1475 array_numbers.push_back(i);
1476 distances.push_back(distance);
1479 std::cout <<
"This option isn't coded. Please use the more general GenerateMap(std::vector<Int_t> &arraynumbers, std::vector<Int_t> &distances)function." << std::endl;
1496 std::vector<Int_t> modindices;
1499 std::cout <<
"You haven't set any angular indices yet." << std::endl;
1500 std::cout <<
"Returning empty vector from GenerateModifiedIndices." << std::endl;
1505 std::cout <<
"Please call GenerateModifiedAngles before calling GenerateModifiedIndices." << std::endl;
1506 std::cout <<
"Returning empty vector from GenerateModifiedIndices." << std::endl;
1512 std::cout <<
"The groups are not set up properly." << std::endl;
1513 std::cout <<
"Returning empty vector from GenerateModifiedIndices." << std::endl;
1518 if(!group && (!fold)) {
1521 }
else if(!fold && group) {
1523 }
else if(fold && group) {
1526 std::vector<Double_t> groupedangles;
1530 groupedangles.push_back(thisangle);
1559 std::vector<Double_t> modangles;
1563 std::cout <<
"You haven't set any angular indices yet." << std::endl;
1564 std::cout <<
"Aborting." << std::endl;
1570 std::cout <<
"The groups are not set up properly." << std::endl;
1571 std::cout <<
"Returning empty vector from GenerateModifiedAngles." << std::endl;
1577 std::cout <<
"Group angles aren't set up properly." << std::endl;
1578 std::cout <<
"Returning empty vector from GenerateModifiedAngles." << std::endl;
1583 std::cout <<
"Changing modification conditions to:" << std::endl;
1585 std::cout <<
"Folded: yes" << std::endl;
1587 std::cout <<
"Folded: no" << std::endl;
1590 std::cout <<
"Grouped: yes" << std::endl;
1592 std::cout <<
"Grouped: no" << std::endl;
1597 if(!group && (!fold)) {
1600 }
else if(!fold && group) {
1602 }
else if(
static_cast<int>(
static_cast<int>((fold)) &
static_cast<int>(!group)) != 0) {
1604 }
else if(fold && group) {
1618 for(
auto& fPeak :
fPeaks) {
1619 Int_t index = fPeak.first;
1624 if(peak ==
nullptr) {
1627 Double_t area = peak->
GetArea();
1628 Double_t area_err = peak->GetAreaErr();
1629 Double_t chi2 = peak->GetChisquare();
1630 Double_t ndf = peak->GetNDF();
1631 Double_t scale = TMath::Max(1.0, TMath::Sqrt(chi2 / ndf));
1632 if(area_err < scale * TMath::Sqrt(area)) {
1633 std::cout <<
"Area error was less than the scaled square root of the area." << std::endl;
1634 std::cout <<
"This means something is wrong; using scaled square root of area for area error." << std::endl;
1635 area_err = TMath::Sqrt(area) * scale;
1652 Double_t old_value = hst->GetBinContent(index + 1);
1653 Double_t old_error = hst->GetBinError(index + 1);
1656 Double_t new_value = old_value * factor;
1657 std::cout <<
"old value is " << old_value <<
" multiplied by " << factor <<
" is " << new_value << std::endl;
1658 Double_t new_area_err = old_error * factor;
1661 hst->SetBinContent(index + 1, new_value);
1662 hst->SetBinError(index + 1, new_area_err);
1671 for(
auto& fPeak :
fPeaks) {
1672 Int_t index = fPeak.first;
1677 if(peak ==
nullptr) {
1680 Double_t chi2 = peak->GetChisquare();
1681 auto NDF =
static_cast<Double_t
>(peak->GetNDF());
1683 Double_t centroid_err = peak->GetCentroidErr();
1684 Double_t fwhm = peak->GetFWHM();
1685 Double_t fwhm_err = peak->GetFWHMErr();
1688 static_cast<TH1D*
>(
GetChi2Hst())->SetBinContent(bin, chi2 / NDF);
1689 static_cast<TH1D*
>(
GetCentroidHst())->SetBinContent(bin, centroid);
1690 static_cast<TH1D*
>(
GetCentroidHst())->SetBinError(bin, centroid_err);
1691 static_cast<TH1D*
>(
GetFWHMHst())->SetBinContent(bin, fwhm);
1692 static_cast<TH1D*
>(
GetFWHMHst())->SetBinError(bin, fwhm_err);
1708 new TCanvas(Form(
"peak%iupdate", index), Form(
"Peak %i update", index), 400, 400);
1714 Double_t minenergy = 0.;
1715 Double_t maxenergy = 0.;
1716 peak->GetRange(minenergy, maxenergy);
1717 Double_t difference = maxenergy - minenergy;
1718 minenergy = minenergy - 0.5 * difference;
1719 maxenergy = maxenergy + 0.5 * difference;
1720 temphst->GetXaxis()->SetRangeUser(minenergy, maxenergy);
1725 auto* hstpeak =
static_cast<TPeak*
>(temphst->GetListOfFunctions()->Last());
1741 if(
fPeaks[index] ==
nullptr) {
1742 std::cout <<
"No peak exists for index " << index <<
". Returning nullptr." << std::endl;
1755 Int_t hstbins = hst->GetNbinsX();
1758 if(hstbins != modindices) {
1759 std::cout <<
"The histogram " << hst->GetName() <<
" does not have the same number of bins as the current settings." << std::endl;
1760 std::cout <<
"Bins in the histogram: " << hstbins << std::endl;
1761 std::cout <<
"Number of modified indices: " << modindices << std::endl;
1774 std::cout <<
"Current modification conditions:" << std::endl;
1776 std::cout <<
"Folded: yes" << std::endl;
1778 std::cout <<
"Folded: no" << std::endl;
1781 std::cout <<
"Grouped: yes" << std::endl;
1783 std::cout <<
"Grouped: no" << std::endl;
1798 if(!fold && !group) {
1803 std::cout <<
"You haven't created the weights yet. Please use the GenerateMaps function to do so." << std::endl;
1806 if(size != hst->GetNbinsX()) {
1807 std::cout <<
"Warning: size of weights array is different than number of bins in " << hst->GetName() << std::endl;
1810 for(Int_t i = 1; i <= hst->GetNbinsX(); i++) {
1811 auto index =
static_cast<Int_t
>(hst->GetXaxis()->GetBinLowEdge(i));
1813 std::cout <<
"Indices in histogram " << hst->GetName() <<
" go beyond size of weights array. Aborting." << std::endl;
1835 std::cout <<
"Weights array size is not the same as the number of bins." << std::endl;
1836 std::cout <<
"Returning from DivideByWeights without dividing." << std::endl;
1842 for(Int_t i = 1; i <= hst->GetNbinsX(); i++) {
1843 std::cout <<
"\t" << i << std::endl;
1844 auto index =
static_cast<Int_t
>(hst->GetXaxis()->GetBinLowEdge(i));
1845 Double_t found_weight = 0;
1846 if(!fold && !group) {
1851 Double_t content = hst->GetBinContent(i);
1852 Double_t error = hst->GetBinError(i);
1853 Double_t weight = found_weight;
1854 Double_t newcontent = content / weight;
1855 Double_t newerror = error / weight;
1856 hst->SetBinContent(i, newcontent);
1857 hst->SetBinError(i, newerror);
1860 return static_cast<TH1D*
>(hst);
1865 if(c_diag ==
nullptr) {
1866 c_diag =
new TCanvas(Form(
"c_diag_%s", GetName()), Form(
"Diagnostics from %s", GetName()), 800, 800);
1870 c_diag->Divide(2, 2);
1878 for(
int i = 0; i < 52; i++) {
1879 std::cout << chi2hst->GetBinContent(i) << std::endl;
1883 indexhst->SetStats(
false);
1884 chi2hst->SetStats(
false);
1885 centroidhst->SetStats(
false);
1886 fwhmhst->SetStats(
false);
1887 chi2hst->SetMarkerStyle(4);
1895 centroidhst->Draw();
std::vector< Double_t > fGroupAngles
array correlating angular index with group assignment
TGraphAsymmErrors * CreateGraphFromHst()
void Set1DSlice(Int_t index, TH1D *slice)
Double_t GetWeightFromIndex(Int_t index)
Int_t GetAngularIndex(Int_t arraynum1, Int_t arraynum2)
TH1D * GetIndexCorrelation()
TPeak * GetPeak(Int_t index)
TH1D * DivideByWeights(TH1 *hst, Bool_t fold, Bool_t group)
void PrintGroupAngleMap()
Bool_t CheckModifiedHistogram(TH1 *hst) const
std::vector< Double_t > fAngleMap
size of fIndexMap
Int_t GetModifiedWeight(Int_t modindex)
Int_t AssignGroupMaps(std::vector< Int_t > &group, std::vector< Double_t > &groupangles)
std::vector< Int_t > fGroups
array correlating angular index with weight (number of detector pairs at that index)
~TAngularCorrelation() override
static std::vector< Int_t > GenerateFoldedIndices(std::vector< Double_t > &folds, std::vector< Double_t > &anglemap)
Bool_t CheckGroups(std::vector< Int_t > &group) const
std::vector< Double_t > GenerateModifiedAngles(Bool_t fold, Bool_t group)
Int_t GetGroupFromIndex(Int_t index)
TH2D * Create2DSlice(THnSparse *hst, Double_t min, Double_t max, Bool_t fold, Bool_t group)
std::vector< Int_t > GenerateModifiedWeights(std::vector< Int_t > &modindices, std::vector< Int_t > &weights)
Bool_t fGrouped
switch to indicate a folded correlation
void PrintModifiedIndexMap()
Prints map of angular index vs. Folded Index.
Int_t fIndexMapSize
number of angular indices
TH1D * fFWHM
1D plot of centroid vs. angular index
TH1D * IntegralSlices(TH2 *hst, Double_t min, Double_t max)
Bool_t CheckGroupAngles(std::vector< Double_t > &groupangles) const
static std::vector< Double_t > GenerateAngleMap(std::vector< Int_t > &arraynumbers, std::vector< Int_t > &distances)
std::vector< Int_t > fModifiedWeights
TH1D * FitSlices(TH2 *hst, TPeak *peak, Bool_t visualization)
Int_t GetNumModIndices() const
static std::vector< Int_t > GenerateWeights(std::vector< Int_t > &arraynumbers, std::vector< Int_t > &distances, std::map< Int_t, std::map< Int_t, Int_t > > &indexmap)
Bool_t fFolded
array correlating group assignment with their average angles
void ScaleSingleIndex(TH1 *hst, Int_t index, Double_t factor)
void UpdateIndexCorrelation()
Int_t GenerateGroupMaps(std::vector< Int_t > &arraynumbers, std::vector< Int_t > &distances, std::vector< Int_t > &group, std::vector< Double_t > &groupangles)
static std::map< Int_t, std::map< Int_t, Int_t > > GenerateIndexMap(std::vector< Int_t > &arraynumbers, std::vector< Int_t > &distances, std::vector< Double_t > &anglemap)
std::vector< Int_t > GenerateModifiedIndices(Bool_t fold, Bool_t group)
void SetPeak(Int_t index, TPeak *peak)
void UpdatePeak(Int_t index, TPeak *peak)
TH1D * fChi2
1D plot of counts vs. angular index
Double_t GetGroupAngleFromIndex(Int_t gindex)
Int_t fNumIndices
2D square array correlating array number pairs with angular index
Int_t GenerateMaps(std::vector< Int_t > &arraynumbers, std::vector< Int_t > &distances)
TH1D * Get1DSlice(Int_t index)
void PrintModifiedConditions() const
Double_t GetModifiedAngleFromIndex(Int_t modindex)
static std::vector< Double_t > GenerateFoldedAngles(std::vector< Double_t > &anglemap)
std::vector< Int_t > fWeights
array correlating angular index with opening angle
std::map< Int_t, TPeak * > fPeaks
1D plot of FWHM vs. angular index
void DisplayDiagnostics(TCanvas *c_diag)
Bool_t CheckMaps(Bool_t fold, Bool_t group)
Int_t GetNumGroups() const
std::vector< Int_t > fModifiedIndices
switch to indicate a grouped correlation
Int_t GetModifiedIndex(Int_t index)
std::vector< Double_t > fModifiedAngles
Int_t GetWeightsSize() const
void PrintModifiedAngleMap()
Int_t GenerateModifiedMaps(Bool_t fold, Bool_t group)
std::map< Int_t, std::map< Int_t, Int_t > > fIndexMap
array of 1D histograms used to create fIndexCorrelations
TH1D * fCentroid
1D plot of chi^2 vs. angular index
void PrintGroupIndexMap()
Double_t GetAngleFromIndex(Int_t index)
TH2D * Modify2DSlice(TH2 *hst, Bool_t fold, Bool_t group)
void PrintModifiedWeights()
static TVector3 GetPosition(int DetNbr, int CryNbr=5, double dist=110.0)
!
Bool_t Fit(TH1 *fitHist, Option_t *opt="")
Double_t GetAreaErr() const
static void SetLogLikelihoodFlag(Bool_t flag=true)
Bool_t InitParams(TH1 *fitHist=nullptr) override
Double_t GetCentroid() const