31double*
CrossTalkFix(
int det,
double energy, TFile* inputFile,
int minimumCounts)
34 static double largestCorrection = 0.0;
37 for(
int i = 0; i < 4; ++i) {
40 std::cout <<
DRED <<
"Couldn't find a channel for "
47 static int largestDet = -1;
48 static int largestCrystal1 = -1;
49 static int largestCrystal2 = -1;
51 std::string namebase = Form(
"det_%d", det);
54 double lowCut = energy - 15;
55 double highCut = energy + 15;
58 std::array<double, 5> xpts = {lowCut, 0, 0, highCut, lowCut};
59 std::array<double, 5> ypts = {0, lowCut, highCut, 0, 0};
60 TCutG cut(
"cut", 5, xpts.data(), ypts.data());
62 auto* d =
new double[16];
63 auto* eD =
new double[16];
65 for(
int crystal1 = 0; crystal1 < 4; crystal1++) {
66 for(
int crystal2 = crystal1 + 1; crystal2 < 4; crystal2++) {
68 std::string name = Form(
"%s_%d_%d", namebase.c_str(), crystal1, crystal2);
69 TH2*
mat =
dynamic_cast<TH2*
>(inputFile->Get(name.c_str()));
71 std::cout <<
"can not find: " << name << std::endl;
74 std::cout <<
mat->GetName() << std::endl;
75 int xbins =
mat->GetNbinsX();
76 int ybins =
mat->GetNbinsY();
78 TH2* cmat =
dynamic_cast<TH2*
>(
mat->Clone(Form(
"%s_clone",
mat->GetName())));
82 auto* fitGraph =
new TGraphErrors;
83 fitGraph->SetNameTitle(Form(
"%s_graph",
mat->GetName()),
"Graph");
87 for(
int i = 1; i <= xbins; i++) {
88 bool insideYet =
false;
89 for(
int j = 1; j <= ybins; j++) {
90 double xc =
mat->GetXaxis()->GetBinCenter(i);
91 double yc =
mat->GetYaxis()->GetBinCenter(j);
92 if(cut.IsInside(xc, yc) != 0) {
96 cmat->Fill(xc, yc,
mat->GetBinContent(i, j));
99 cmat->GetXaxis()->SetRange(i, i);
104 if(cmat->Integral() > minimumCounts) {
105 fitGraph->SetPoint(fitGraph->GetN(), cmat->GetYaxis()->GetBinCenter(i), cmat->GetMean(2));
106 fitGraph->SetPointError(fitGraph->GetN() - 1, cmat->GetXaxis()->GetBinWidth(i), cmat->GetMeanError(2));
112 cmat->GetXaxis()->SetRange(1, cmat->GetXaxis()->GetNbins());
115 if(rejectedBins > 0) {
116 std::cout << name <<
": rejected " << rejectedBins <<
" bins out of " << xbins <<
" bins, because the number of counts in the projection of this bin is less than " << minimumCounts << std::endl;
119 if(fitGraph->GetN() <= 0) {
120 std::cout << name <<
": graph doesn't have any data points (" << fitGraph->GetN() <<
"), going to skip fitting it" << std::endl;
125 auto* fpx =
new TF1(Form(
"pxfit_%i_%i_%i", det, crystal1, crystal2),
CrossTalkFit, 6, 1167, 3);
126 fpx->SetParameter(0, 0.0001);
127 fpx->SetParameter(1, 0.0001);
128 fpx->SetParameter(2, energy);
129 fpx->FixParameter(2, energy);
135 TProfile* px = cmat->ProfileX();
138 TH1* residualPlot =
new TH1D(Form(
"%s_resid", fpx->GetName()),
"residuals", 2000, 0, 2000);
139 for(
int i = 0; i < residualPlot->GetNbinsX(); ++i) {
140 if(px->GetBinContent(i) != 0) {
141 residualPlot->SetBinContent(i, px->GetBinContent(i) - fpx->Eval(residualPlot->GetBinCenter(i)));
143 residualPlot->SetBinError(i, px->GetBinError(i));
145 residualPlot->Write();
152 std::cout <<
"=====================" << std::endl;
153 std::cout <<
mat->GetName() << std::endl;
154 std::cout <<
"d" << crystal1 << crystal2 <<
" at zero " << (fpx->Eval(energy)) / energy << std::endl;
155 std::cout <<
"=====================" << std::endl;
158 d[crystal2 * 4 + crystal1] = fpx->GetParameter(0);
159 d[crystal1 * 4 + crystal2] = fpx->GetParameter(1);
160 eD[crystal2 * 4 + crystal1] = fpx->GetParError(0);
161 eD[crystal1 * 4 + crystal2] = fpx->GetParError(1);
165 if(fpx->GetParameter(0) > largestCorrection) {
166 largestCorrection = fpx->GetParameter(0);
168 largestCrystal2 = crystal2;
169 largestCrystal1 = crystal1;
171 if(fpx->GetParameter(1) > largestCorrection) {
172 largestCorrection = fpx->GetParameter(1);
174 largestCrystal2 = crystal2;
175 largestCrystal1 = crystal1;
180 std::cout <<
" -------------------- " << std::endl;
181 std::cout <<
" -------------------- " << std::endl;
182 std::cout << std::endl;
186 std::streamsize prec = std::cout.precision();
187 std::cout.precision(10);
188 std::cout.setf(std::ios::fixed, std::ios::floatfield);
189 for(
int i = 0; i < 4; i++) {
190 for(
int j = 0; j < 4; j++) {
192 d[i * 4 + j] = 0.0000;
193 eD[i * 4 + j] = 0.0000;
196 std::cout << d[j * 4 + i] <<
"\t";
200 if(chan ==
nullptr) {
201 std::cout <<
DRED <<
"Couldn't find a channel for "
208 std::cout << std::endl;
211 std::cout.precision(prec);
212 std::cout.unsetf(std::ios::floatfield);
214 std::cout << std::endl;
215 std::cout <<
"Largest correction = " << largestCorrection <<
" Shift = " << largestCorrection * energy << std::endl;
216 std::cout <<
"Largest combo, det = " << largestDet <<
" Crystals = " << largestCrystal1 <<
", " << largestCrystal2 << std::endl;
217 std::cout <<
" -------------------- " << std::endl;
218 std::cout <<
" -------------------- " << std::endl;
239 if(argc != 3 && argc != 4) {
240 std::cout <<
"Usage: " << argv[0] <<
" <matrix file> <cal file> <user settings (optional)>" << std::endl;
241 std::cout <<
"User settings available: CrossTalkEnergy (double), MinimumCounts (int), and ExcludedDetectors (int vector, 1-16)" << std::endl;
247 std::cout <<
"Aborting" << std::endl;
251 auto* inputFile =
new TFile(argv[1]);
252 if(inputFile ==
nullptr || !inputFile->IsOpen()) {
253 std::cout <<
"Failed to open file '" << argv[1] <<
"'!" << std::endl;
259 userSettings->ReadSettings(argv[3]);
263 std::string outputFileName = argv[1];
264 auto lastSlash = outputFileName.find_last_of(
'/');
265 if(lastSlash != std::string::npos) {
266 outputFileName = std::string(
"ct_") + outputFileName.substr(lastSlash + 1);
268 outputFileName = std::string(
"ct_") + std::string(argv[1]);
271 auto* outputFile =
new TFile(outputFileName.c_str(),
"recreate");
273 std::vector<int> excludedDetectors;
275 excludedDetectors = userSettings->GetIntVector(
"ExcludedDetectors",
true);
276 }
catch(std::out_of_range& e) {
279 FixAll(inputFile, userSettings->GetDouble(
"CrossTalkEnergy", 1332.), userSettings->GetInt(
"MinimumCounts", 10), excludedDetectors);