10#include <klm/dataobjects/KLMMuidLikelihood.h>
11#include <klm/muid/MuidElementNumbers.h>
14#include <analysis/dataobjects/Particle.h>
15#include <analysis/variables/AcceptanceVariables.h>
16#include <mdst/dataobjects/MCParticle.h>
19#include <Math/Vector4D.h>
22#include <TChainElement.h>
41 TStyle* belle2Style =
new TStyle(
"BELLE2",
"Belle2 style");
45 belle2Style->SetFrameBorderMode(icol);
46 belle2Style->SetFrameFillColor(icol);
47 belle2Style->SetCanvasBorderMode(icol);
48 belle2Style->SetCanvasColor(icol);
49 belle2Style->SetPadBorderMode(icol);
50 belle2Style->SetPadColor(icol);
51 belle2Style->SetStatColor(icol);
55 belle2Style->SetPaperSize(20, 26);
58 belle2Style->SetPadTopMargin(0.05);
59 belle2Style->SetPadRightMargin(0.05);
60 belle2Style->SetPadBottomMargin(0.16);
61 belle2Style->SetPadLeftMargin(0.16);
64 belle2Style->SetTitleXOffset(1.4);
65 belle2Style->SetTitleYOffset(1.4);
70 Double_t tsize = 0.05;
71 belle2Style->SetTextFont(font);
73 belle2Style->SetTextSize(tsize);
74 belle2Style->SetLabelFont(font,
"x");
75 belle2Style->SetTitleFont(font,
"x");
76 belle2Style->SetLabelFont(font,
"y");
77 belle2Style->SetTitleFont(font,
"y");
78 belle2Style->SetLabelFont(font,
"z");
79 belle2Style->SetTitleFont(font,
"z");
81 belle2Style->SetLabelSize(tsize,
"x");
82 belle2Style->SetTitleSize(tsize,
"x");
83 belle2Style->SetLabelSize(tsize,
"y");
84 belle2Style->SetTitleSize(tsize,
"y");
85 belle2Style->SetLabelSize(tsize,
"z");
86 belle2Style->SetTitleSize(tsize,
"z");
89 belle2Style->SetMarkerStyle(20);
90 belle2Style->SetMarkerSize(1.2);
91 belle2Style->SetHistLineWidth(2.);
92 belle2Style->SetLineStyleString(2,
"[12 12]");
97 belle2Style->SetEndErrorSize(0.);
100 belle2Style->SetOptTitle(0);
102 belle2Style->SetOptStat(0);
104 belle2Style->SetOptFit(0);
107 belle2Style->SetPadTickX(1);
108 belle2Style->SetPadTickY(1);
116 const static TStyle* belle2Style = 0;
117 std::cout <<
"\nApplying BELLE2 style settings...\n" << std::endl ;
118 if (belle2Style == 0) belle2Style = Belle2Style();
119 gROOT->SetStyle(
"BELLE2");
123void makeprob(TChain* chain, FILE* output,
const char* xmllabel)
127 bool isMuon = (strncmp(xmllabel,
"Mu", 2) == 0);
128 bool isPion = (strncmp(xmllabel,
"Pi", 2) == 0);
129 bool isKaon = (strncmp(xmllabel,
"Ka", 2) == 0);
130 bool isElec = (strncmp(xmllabel,
"El", 2) == 0) || (strncmp(xmllabel,
"Po", 2) == 0);
131 bool isProt = (strncmp(xmllabel,
"Pr", 2) == 0) || (strncmp(xmllabel,
"An", 2) == 0);
132 bool isDeut = (strncmp(xmllabel,
"De", 2) == 0);
134 char label[80], title[80];
135 const char detectorName[3][40] = {
"BarrelAndEndcap",
"BarrelOnly",
"EndcapOnly" };
137 const char outcomeName[NOUTCOME][40] = {
"",
144 "Fwd Endcap stop B0+E",
145 "Fwd Endcap stop B1+E",
146 "Fwd Endcap stop B2+E",
147 "Fwd Endcap stop B3+E",
148 "Fwd Endcap stop B4+E",
149 "Fwd Endcap stop B5+E",
150 "Fwd Endcap stop B6+E",
151 "Fwd Endcap stop B7+E",
152 "Fwd Endcap stop B8+E",
153 "Fwd Endcap stop B9+E",
154 "Fwd Endcap stop B10+E",
155 "Fwd Endcap stop B11+E",
156 "Fwd Endcap stop B12+E",
157 "Fwd Endcap stop B13+E",
158 "Fwd Endcap stop B14+E",
159 "Bwd Endcap stop B0+E",
160 "Bwd Endcap stop B1+E",
161 "Bwd Endcap stop B2+E",
162 "Bwd Endcap stop B3+E",
163 "Bwd Endcap stop B4+E",
164 "Bwd Endcap stop B5+E",
165 "Bwd Endcap stop B6+E",
166 "Bwd Endcap stop B7+E",
167 "Bwd Endcap stop B8+E",
168 "Bwd Endcap stop B9+E",
169 "Bwd Endcap stop B10+E",
170 "Bwd Endcap stop B11+E",
171 "Bwd Endcap stop B12+E",
172 "Bwd Endcap stop B13+E",
173 "Bwd Endcap stop B14+E",
174 "Fwd Endcap exit B0+E",
175 "Fwd Endcap exit B1+E",
176 "Fwd Endcap exit B2+E",
177 "Fwd Endcap exit B3+E",
178 "Fwd Endcap exit B4+E",
179 "Fwd Endcap exit B5+E",
180 "Fwd Endcap exit B6+E",
181 "Fwd Endcap exit B7+E",
182 "Fwd Endcap exit B8+E",
183 "Fwd Endcap exit B9+E",
184 "Fwd Endcap exit B10+E",
185 "Fwd Endcap exit B11+E",
186 "Fwd Endcap exit B12+E",
187 "Fwd Endcap exit B13+E",
188 "Fwd Endcap exit B14+E",
189 "Bwd Endcap exit B0+E",
190 "Bwd Endcap exit B1+E",
191 "Bwd Endcap exit B2+E",
192 "Bwd Endcap exit B3+E",
193 "Bwd Endcap exit B4+E",
194 "Bwd Endcap exit B5+E",
195 "Bwd Endcap exit B6+E",
196 "Bwd Endcap exit B7+E",
197 "Bwd Endcap exit B8+E",
198 "Bwd Endcap exit B9+E",
199 "Bwd Endcap exit B10+E",
200 "Bwd Endcap exit B11+E",
201 "Bwd Endcap exit B12+E",
202 "Bwd Endcap exit B13+E",
203 "Bwd Endcap exit B14+E"
205 const char outcomeComment[NOUTCOME][100] = {
"",
206 "soft tracks that range out (stop) within the barrel KLM",
207 "soft tracks that range out (stop) within the forward endcap KLM (no barrel hits)",
208 "hard tracks that escape from the barrel KLM",
209 "hard tracks that escape from the forward endcap KLM (no barrel hits)",
210 "soft tracks that range out (stop) within the backward endcap KLM (no barrel hits)",
211 "hard tracks that escape from the backward endcap KLM (no barrel hits)",
212 "soft tracks that range out (stop) within the forward endcap KLM with B0 hit(s)",
213 "soft tracks that range out (stop) within the forward endcap KLM with B1 hit(s)",
214 "soft tracks that range out (stop) within the forward endcap KLM with B2 hit(s)",
215 "soft tracks that range out (stop) within the forward endcap KLM with B3 hit(s)",
216 "soft tracks that range out (stop) within the forward endcap KLM with B4 hit(s)",
217 "soft tracks that range out (stop) within the forward endcap KLM with B5 hit(s)",
218 "soft tracks that range out (stop) within the forward endcap KLM with B6 hit(s)",
219 "soft tracks that range out (stop) within the forward endcap KLM with B7 hit(s)",
220 "soft tracks that range out (stop) within the forward endcap KLM with B8 hit(s)",
221 "soft tracks that range out (stop) within the forward endcap KLM with B9 hit(s)",
222 "soft tracks that range out (stop) within the forward endcap KLM with B10 hit(s)",
223 "soft tracks that range out (stop) within the forward endcap KLM with B11 hit(s)",
224 "soft tracks that range out (stop) within the forward endcap KLM with B12 hit(s)",
225 "soft tracks that range out (stop) within the forward endcap KLM with B13 hit(s)",
226 "soft tracks that range out (stop) within the forward endcap KLM with B14 hit(s)",
227 "soft tracks that range out (stop) within the backward endcap KLM with B0 hit(s)",
228 "soft tracks that range out (stop) within the backward endcap KLM with B1 hit(s)",
229 "soft tracks that range out (stop) within the backward endcap KLM with B2 hit(s)",
230 "soft tracks that range out (stop) within the backward endcap KLM with B3 hit(s)",
231 "soft tracks that range out (stop) within the backward endcap KLM with B4 hit(s)",
232 "soft tracks that range out (stop) within the backward endcap KLM with B5 hit(s)",
233 "soft tracks that range out (stop) within the backward endcap KLM with B6 hit(s)",
234 "soft tracks that range out (stop) within the backward endcap KLM with B7 hit(s)",
235 "soft tracks that range out (stop) within the backward endcap KLM with B8 hit(s)",
236 "soft tracks that range out (stop) within the backward endcap KLM with B9 hit(s)",
237 "soft tracks that range out (stop) within the backward endcap KLM with B10 hit(s)",
238 "soft tracks that range out (stop) within the backward endcap KLM with B11 hit(s)",
239 "soft tracks that range out (stop) within the backward endcap KLM with B12 hit(s)",
240 "soft tracks that range out (stop) within the backward endcap KLM with B13 hit(s)",
241 "soft tracks that range out (stop) within the backward endcap KLM with B14 hit(s)",
242 "hard tracks that escape from the forward endcap KLM with B0 hit(s)",
243 "hard tracks that escape from the forward endcap KLM with B1 hit(s)",
244 "hard tracks that escape from the forward endcap KLM with B2 hit(s)",
245 "hard tracks that escape from the forward endcap KLM with B3 hit(s)",
246 "hard tracks that escape from the forward endcap KLM with B4 hit(s)",
247 "hard tracks that escape from the forward endcap KLM with B5 hit(s)",
248 "hard tracks that escape from the forward endcap KLM with B6 hit(s)",
249 "hard tracks that escape from the forward endcap KLM with B7 hit(s)",
250 "hard tracks that escape from the forward endcap KLM with B8 hit(s)",
251 "hard tracks that escape from the forward endcap KLM with B9 hit(s)",
252 "hard tracks that escape from the forward endcap KLM with B10 hit(s)",
253 "hard tracks that escape from the forward endcap KLM with B11 hit(s)",
254 "hard tracks that escape from the forward endcap KLM with B12 hit(s)",
255 "hard tracks that escape from the forward endcap KLM with B13 hit(s)",
256 "hard tracks that escape from the forward endcap KLM with B14 hit(s)",
257 "hard tracks that escape from the backward endcap KLM with B0 hit(s)",
258 "hard tracks that escape from the backward endcap KLM with B1 hit(s)",
259 "hard tracks that escape from the backward endcap KLM with B2 hit(s)",
260 "hard tracks that escape from the backward endcap KLM with B3 hit(s)",
261 "hard tracks that escape from the backward endcap KLM with B4 hit(s)",
262 "hard tracks that escape from the backward endcap KLM with B5 hit(s)",
263 "hard tracks that escape from the backward endcap KLM with B6 hit(s)",
264 "hard tracks that escape from the backward endcap KLM with B7 hit(s)",
265 "hard tracks that escape from the backward endcap KLM with B8 hit(s)",
266 "hard tracks that escape from the backward endcap KLM with B9 hit(s)",
267 "hard tracks that escape from the backward endcap KLM with B10 hit(s)",
268 "hard tracks that escape from the backward endcap KLM with B11 hit(s)",
269 "hard tracks that escape from the backward endcap KLM with B12 hit(s)",
270 "hard tracks that escape from the backward endcap KLM with B13 hit(s)",
271 "hard tracks that escape from the backward endcap KLM with B14 hit(s)"
273 snprintf(label,
sizeof(label),
"Muon ID PDFs for %s", xmllabel);
276 TH1D* layerHitU[15][NOUTCOME];
277 TH1D* layerHitV[15][NOUTCOME];
278 TH1D* layerHitW[15][NOUTCOME];
279 TH1D* rchisqA[21][3];
280 TH1D* rchisqB[21][3];
286 discardA =
new TH1D(
"discardA",
"discard fraction", 70, -0.5, 69.5);
287 discardB =
new TH1D(
"discardB",
"discard denominator", 70, -0.5, 69.5);
288 for (
int outcome = 1; outcome < NOUTCOME; ++outcome) {
289 for (
int layer = 0; layer < 15; ++layer) {
290 snprintf(label,
sizeof(label),
"LayerHitU-layer%02d-outcome%d", layer, outcome);
291 snprintf(title,
sizeof(title),
"LayerHitU for %s: layer %02d (%s)", xmllabel, layer, outcomeName[outcome]);
292 layerHitU[layer][outcome] =
new TH1D(label, title, 32, -0.5, 31.5);
293 layerHitU[layer][outcome]->Sumw2(
true);
294 snprintf(label,
sizeof(label),
"LayerHitV-layer%02d-outcome%d", layer, outcome);
295 snprintf(title,
sizeof(title),
"LayerHitV for %s: layer %02d (%s)", xmllabel, layer, outcomeName[outcome]);
296 layerHitV[layer][outcome] =
new TH1D(label, title, 32, -0.5, 31.5);
297 layerHitV[layer][outcome]->Sumw2(
true);
298 snprintf(label,
sizeof(label),
"LayerHitW-layer%02d-outcome%d", layer, outcome);
299 snprintf(title,
sizeof(title),
"LayerHitW for %s: layer %02d (%s)", xmllabel, layer, outcomeName[outcome]);
300 layerHitW[layer][outcome] =
new TH1D(label, title, 32, -0.5, 31.5);
301 layerHitW[layer][outcome]->Sumw2(
true);
305 for (
int detector = 0; detector <= 2; ++detector) {
306 for (
int halfNdof = 0; halfNdof <= 20; ++halfNdof) {
307 snprintf(label,
sizeof(label),
"ReducedChiSquaredA-%02ddof-detector%d", 2 * halfNdof, detector);
308 snprintf(title,
sizeof(title),
"Reduced Chi-squared for %s: %02d dof (%s)", xmllabel, 2 * halfNdof, detectorName[detector]);
309 rchisqA[halfNdof][detector] =
new TH1D(label, title, 100, 0.0, 10.0);
310 rchisqA[halfNdof][detector]->Sumw2(
true);
311 snprintf(label,
sizeof(label),
"ReducedChiSquaredB-%02ddof-detector%d", 2 * halfNdof, detector);
312 snprintf(title,
sizeof(title),
"Reduced Chi-squared for %s: %02d dof (%s)", xmllabel, 2 * halfNdof, detectorName[detector]);
313 rchisqB[halfNdof][detector] =
new TH1D(label, title, 1000, 0.0, 100.0);
314 rchisqB[halfNdof][detector]->Sumw2(
true);
318 printf(
"Finished defining histograms\n");
320 TObjArray* fileElements = chain->GetListOfFiles();
321 TIter next(fileElements);
322 TChainElement* chEl = 0;
323 while ((chEl =
static_cast<TChainElement*
>(next()))) {
325 TFile file(chEl->GetTitle());
326 TTree* tree =
static_cast<TTree*
>(file.Get(
"tree"));
327 tree->SetBranchStatus(
"*", 0);
328 tree->SetBranchStatus(
"MCParticles*", 1);
329 tree->SetBranchStatus(
"KLMMuidLikelihoods*", 1);
330 TClonesArray* mcParticles = 0;
331 tree->SetBranchAddress(
"MCParticles", &mcParticles);
332 TClonesArray* muids = 0;
333 tree->SetBranchAddress(
"KLMMuidLikelihoods", &muids);
335 printf(
"Number of events: %lld in file %s\n", tree->GetEntriesFast(), chEl->GetTitle());
336 ROOT::Math::PxPyPzEVector decayMomentum(0.0, 0.0, 0.0, 0.0);
338 for (
int event = 0;
event < tree->GetEntriesFast(); ++event) {
339 tree->GetEntry(event);
340 if (mcParticles->GetEntriesFast() == 0)
continue;
346 decayMomentum.SetPxPyPzE(0.0, 0.0, 0.0, 0.0);
349 for (
int d = firstDaughter - 1; d < lastDaughter; ++d) {
351 int dPDG = abs(daughter->getPDG());
352 if ((dPDG != 11) && (dPDG != 12) && (dPDG != 14) && (dPDG != 22))
continue;
355 ROOT::Math::XYZVector p3 = daughter->getMomentum();
356 decayMomentum.SetPx(decayMomentum.Px() + p3.X());
357 decayMomentum.SetPy(decayMomentum.Py() + p3.Y());
358 decayMomentum.SetPz(decayMomentum.Pz() + p3.Z());
360 if (decayMomentum.P() > 0.05) {
369 double mcMomentumZ = 1000.0 * mcp->
getMomentum().Z();
371 double mcTheta = mcp->
getMomentum().Theta() * 180.0 / TMath::Pi();
375 if (Variable::thetaInECLAcceptance(particle) == 0)
continue;
376 double mcPhi = mcp->
getMomentum().Phi() * 180.0 / TMath::Pi();
377 if ((mcTheta > 110.0) && (mcTheta < 125.0) && (mcPhi > 60.0) && (mcPhi < 120.0))
continue;
378 for (
int m = 0; m < muids->GetEntriesFast(); ++m) {
382 int outcome = muid->getOutcome();
383 if (outcome <= 0)
continue;
384 unsigned int extLayerPattern = muid->getExtLayerPattern();
385 unsigned int hitLayerPattern = muid->getHitLayerPattern();
386 int blayer = muid->getBarrelExtLayer();
387 int elayer = muid->getEndcapExtLayer();
389 if (outcome == MuidElementNumbers::c_StopInForwardEndcap) {
392 outcome =
isForward ? MuidElementNumbers::c_StopInForwardEndcap :
393 MuidElementNumbers::c_StopInBackwardEndcap;
395 outcome = (
isForward ? MuidElementNumbers::c_CrossBarrelStopInForwardMin : MuidElementNumbers::c_CrossBarrelStopInBackwardMin) +
398 }
else if (outcome == MuidElementNumbers::c_ExitForwardEndcap) {
401 outcome =
isForward ? MuidElementNumbers::c_ExitForwardEndcap :
402 MuidElementNumbers::c_ExitBackwardEndcap;
404 outcome = (
isForward ? MuidElementNumbers::c_CrossBarrelExitForwardMin : MuidElementNumbers::c_CrossBarrelExitBackwardMin) +
408 int ndof = muid->getDegreesOfFreedom();
409 double rchisq = (ndof > 0 ? muid->getChiSquared() / ndof : -1.0);
410 if (ndof >= 40)
continue;
414 }
else if (blayer < 0) {
417 rchisqA[ndof / 2][detector]->Fill(rchisq);
418 unsigned int testbit = 1;
419 unsigned int mask = 0;
420 for (
int bit = 0; bit <= blayer; ++bit) {
426 for (
int bit = 0; bit <= elayer; ++bit) {
430 discardB->Fill(outcome);
431 if (extLayerPattern == mask) {
433 for (
int bit = 0; bit < 32; ++bit) {
434 if ((testbit & extLayerPattern) != 0) {
435 double xLyr = (double)(bit);
436 layerHitV[layer][outcome]->Fill(xLyr);
437 if ((testbit & hitLayerPattern) != 0) {
438 layerHitU[layer][outcome]->Fill(xLyr);
439 layerHitW[layer][outcome]->Fill(xLyr);
445 discardA->Fill(outcome);
453 TF1* rchisqFunc =
new TF1(
"rchisqFunc",
"[0]*[2]*std::pow(x*[1]*[2],[2]-1)/TMath::Gamma([2])*std::exp(-x*[1]*[2])", 0.0, 10.0);
454 TF1* layerHitFunc =
new TF1(
"layerHitFunc",
"[0]*std::exp(-[1]*(x-[2]))", -0.5, 28.5);
455 fprintf(output,
" <%s>\n", xmllabel);
456 for (
int outcome = 1; outcome <= 6; ++outcome) {
459 if ((outcome == MuidElementNumbers::c_StopInForwardEndcap)
463 if ((outcome == MuidElementNumbers::c_StopInBackwardEndcap)
465 if ((outcome == MuidElementNumbers::c_ExitBackwardEndcap)
467 int bin0 = ((outcome == MuidElementNumbers::c_StopInBarrel)
468 || (outcome == MuidElementNumbers::c_ExitBarrel)) ? 0 :
MuidElementNumbers::getMaximalBarrelLayer() + 1;
469 if (layerHitV[layer][outcome]->GetEntries() > 0.0) {
470 layerHitU[layer][outcome]->Divide(layerHitV[layer][outcome]);
472 printf(
"Fitting spectrum for outcome %d layer %d bin0 %d ...\n", outcome, layer, bin0);
479 double xMin = bin0 + 0.5;
480 if ((outcome == MuidElementNumbers::c_StopInBarrel) || (outcome == MuidElementNumbers::c_ExitBarrel)) xMin = bin0 + 1.5;
481 double xMax = bin0 - 0.5 + layer;
483 p0 = 0.97; p0Min = 0.9; p0Max = 1.0; p1 = 0.005; p1Min = 0.0; p1Max = 0.02;
485 p0 = 0.29; p0Min = 0.02; p0Max = 0.5; p1 = 0.30; p1Min = 0.2; p1Max = 0.5;
487 p0 = 0.33; p0Min = 0.02; p0Max = 0.5; p1 = 0.23; p1Min = 0.17; p1Max = 0.6;
489 p0 = 0.05; p0Min = 0.001; p0Max = 0.4; p1 = 0.36; p1Min = 0.3; p1Max = 0.7;
490 if ((outcome == MuidElementNumbers::c_StopInBarrel) && (layer >= 12)) xMin = bin0 + 3.5;
491 if ((outcome == MuidElementNumbers::c_StopInForwardEndcap) && (layer >= 8)) xMin = bin0 + 1.5;
492 if ((outcome == MuidElementNumbers::c_StopInForwardEndcap) && (layer >= 10)) xMin = bin0 + 2.5;
493 if ((outcome == MuidElementNumbers::c_StopInBackwardEndcap) && (layer >= 8)) xMin = bin0 + 1.5;
494 if ((outcome == MuidElementNumbers::c_StopInBackwardEndcap) && (layer >= 10)) xMin = bin0 + 2.5;
496 p0 = 0.20; p0Min = 0.0002; p0Max = 0.26; p1 = 0.45; p1Min = 0.40; p1Max = 0.50;
497 if ((outcome == MuidElementNumbers::c_StopInBarrel) && (layer <= 4)) { p0 = 0.00076; p1 = 0.745; }
498 if ((outcome == MuidElementNumbers::c_StopInForwardEndcap) && (layer <= 5)) { p0 = 0.00027; p1 = 0.202; }
499 if ((outcome == MuidElementNumbers::c_ExitForwardEndcap) && (layer <= 4)) { p0 = 0.03; p1 = 0.83; }
500 if ((outcome == MuidElementNumbers::c_StopInBackwardEndcap) && (layer <= 4)) { p0 = 0.00021; p1 = 0.26; }
502 p0 = 0.035; p0Min = 0.005; p0Max = 0.25; p1 = 1.65; p1Min = 1.5; p1Max = 2.5;
503 if ((outcome == MuidElementNumbers::c_ExitForwardEndcap) && (layer >= 11)) xMin = bin0 + 1.5;
504 if ((outcome == MuidElementNumbers::c_ExitForwardEndcap) && (layer <= 10)) { p0 = 0.012; p1 = 1.186; }
505 if ((outcome == MuidElementNumbers::c_StopInBackwardEndcap) && (layer <= 10)) { p0 = 0.010; p1 = 2.33; }
506 if ((outcome == MuidElementNumbers::c_ExitBackwardEndcap) && (layer <= 10)) { p0 = 0.008; p1 = 1.94; }
510 printf(
",B,%d,%d,%g,%g,%g,%g\n", outcome, layer, p0, 0.0, p1, 0.0);
511 layerHitFunc->SetParameters(p0, p1, (
double)bin0);
512 layerHitFunc->SetParLimits(0, p0Min, p0Max);
513 layerHitFunc->SetParLimits(1, p1Min, p1Max);
514 layerHitFunc->FixParameter(2, (
double)bin0);
515 layerHitFunc->ReleaseParameter(1);
516 if (
int(xMax - xMin + 0.5) < layerHitFunc->GetNumberFreeParameters()) layerHitFunc->FixParameter(1, p1);
517 if (
int(xMax - xMin + 0.5) >= layerHitFunc->GetNumberFreeParameters()) {
518 layerHitU[layer][outcome]->Fit(
"layerHitFunc",
"WL",
"", xMin, xMax);
519 p0 = layerHitFunc->GetParameter(0);
520 p1 = layerHitFunc->GetParameter(1);
521 e0 = layerHitFunc->GetParError(0);
522 e1 = layerHitFunc->GetParError(1);
523 printf(
",A,%d,%d,%g,%g,%g,%g\n", outcome, layer, p0, e0, p1, e1);
525 for (
int bin = bin0 + 1; bin <= bin0 + 15; ++bin) {
526 double y = layerHitU[layer][outcome]->GetBinContent(bin) * layerHitV[layer][outcome]->GetBinContent(bin);
527 double yFit = p0 * std::exp(-p1 * (bin - 1 - bin0)) * layerHitV[layer][outcome]->GetBinContent(bin);
528 if ((TMath::Sq(y - yFit) < 9.0 * (yFit + TMath::Max(1.0, y))) || (y <= 2.0)) {
529 layerHitW[layer][outcome]->SetBinContent(bin, yFit);
530 layerHitW[layer][outcome]->SetBinError(bin, yFit * TMath::Sqrt(TMath::Sq(e0 / p1) + TMath::Sq((bin - 1 - bin0)*e1)));
535 for (
int outcome = MuidElementNumbers::c_CrossBarrelStopInForwardMin; outcome < NOUTCOME; ++outcome) {
539 if ((outcome >= MuidElementNumbers::c_CrossBarrelStopInForwardMin)
540 && (outcome <= MuidElementNumbers::c_CrossBarrelStopInForwardMax)
542 if ((outcome >= MuidElementNumbers::c_CrossBarrelStopInBackwardMin)
543 && (outcome <= MuidElementNumbers::c_CrossBarrelStopInBackwardMax)
545 if ((outcome >= MuidElementNumbers::c_CrossBarrelExitForwardMin) && (outcome <= MuidElementNumbers::c_CrossBarrelExitForwardMax)
547 if ((outcome >= MuidElementNumbers::c_CrossBarrelExitBackwardMin) && (outcome <= MuidElementNumbers::c_CrossBarrelExitBackwardMax)
551 int blayer = outcome - 7;
553 if (outcome >= MuidElementNumbers::c_CrossBarrelStopInBackwardMin) { outcomeRef = MuidElementNumbers::c_StopInBackwardEndcap; blayer = outcome - MuidElementNumbers::c_CrossBarrelStopInBackwardMin; }
554 if (outcome >= MuidElementNumbers::c_CrossBarrelExitForwardMin) { outcomeRef = MuidElementNumbers::c_ExitForwardEndcap; blayer = outcome - MuidElementNumbers::c_CrossBarrelExitForwardMin; }
555 if (outcome >= MuidElementNumbers::c_CrossBarrelExitBackwardMin) { outcomeRef = MuidElementNumbers::c_ExitBackwardEndcap; blayer = outcome - MuidElementNumbers::c_CrossBarrelExitBackwardMin; }
558 double wSumRef = 0.0;
559 double vSumRef = 0.0;
560 for (
int bin = 1; bin <= blayer + 1; ++bin) {
561 wSum += layerHitW[layer][outcome]->GetBinContent(bin);
562 vSum += layerHitV[layer][outcome]->GetBinContent(bin);
566 wSumRef += layerHitW[blayer][3]->GetBinContent(bin);
568 vSumRef += layerHitV[blayer][3]->GetBinContent(bin);
572 if (vSum == 0.0) vSum = wSum;
574 double factor = (wSum / vSum) / (wSumRef / vSumRef);
575 for (
int bin = 1; bin <= blayer + 1; ++bin) {
576 double w = layerHitW[layer][outcome]->GetBinContent(bin);
577 double v = layerHitV[layer][outcome]->GetBinContent(bin);
578 double v1 = TMath::Max(v, 1.0);
579 double wRef = layerHitW[blayer][3]->GetBinContent(bin);
580 double vRef = layerHitV[blayer][3]->GetBinContent(bin);
581 double wRef1 = TMath::Max(wRef, 1.0);
582 double wNew = wRef * factor * (v1 / vRef);
583 wNew = TMath::Min((isMuon ? 0.95 : 0.6667) * v1, wNew);
584 double e = (w == 0.0) ? 1.0 : w;
585 double eNew = factor * factor * wRef1 * v1 * (v1 * (vRef - wRef) + wRef * vRef) / (vRef * vRef * vRef);
586 wNew = (w / e + wNew / eNew) / (1.0 / e + 1.0 / eNew);
587 if (!isMuon && (bin > 1)) {
588 wNew = TMath::Min(wNew, layerHitW[layer][outcome]->GetBinContent(bin - 1));
591 layerHitW[layer][outcome]->SetBinContent(bin, wNew);
593 printf(
"%d,%d,%d,%d,%g,%g,%g,%g,%g,%g,%g\n", outcome, layer, blayer, bin, factor, w, v, wRef, vRef, wNew,
594 TMath::Sq(w - wNew) / (e + eNew));
600 for (
int bin = 1; bin <= elayer + 1; ++bin) {
601 wSum += layerHitW[layer][outcome]->GetBinContent(bin + 15);
602 vSum += layerHitV[layer][outcome]->GetBinContent(bin + 15);
603 wSumRef += layerHitW[layer][outcomeRef]->GetBinContent(bin + 15);
604 vSumRef += layerHitV[layer][outcomeRef]->GetBinContent(bin + 15);
607 factor *= (layerHitW[blayer][3]->GetBinContent(blayer + 1) / layerHitV[blayer][3]->GetBinContent(blayer + 1))
608 / (layerHitW[layer][outcomeRef]->GetBinContent(1 + 15) / layerHitV[layer][outcomeRef]->GetBinContent(1 + 15));
610 factor = (wSum / vSum) / (wSumRef / vSumRef);
612 for (
int bin = 1; bin <= elayer + 1; ++bin) {
613 double w = layerHitW[layer][outcome]->GetBinContent(bin + 15);
614 double v = layerHitV[layer][outcome]->GetBinContent(bin + 15);
615 double v1 = TMath::Max(v, 1.0);
616 double wRef = layerHitW[layer][outcomeRef]->GetBinContent(bin + 15);
617 double vRef = layerHitV[layer][outcomeRef]->GetBinContent(bin + 15);
618 double wRef1 = TMath::Max(wRef, 1.0);
619 double wNew = wRef * factor * (v1 / vRef);
620 wNew = TMath::Min((isMuon ? 0.95 : 0.6667) * v1, wNew);
621 double e = (w == 0.0) ? 1.0 : w;
622 double eNew = factor * factor * wRef1 * v1 * (v1 * (vRef - wRef) + wRef * vRef) / (vRef * vRef * vRef);
623 wNew = (w / e + wNew / eNew) / (1.0 / e + 1.0 / eNew);
624 if (!isMuon && (bin > 1)) {
625 wNew = TMath::Min(wNew, layerHitW[layer][outcome]->GetBinContent(bin + 15 - 1));
628 layerHitW[layer][outcome]->SetBinContent(bin + 15, wNew);
630 printf(
"%d,%d,%d,%d,%g,%g,%g,%g,%g,%g,%g\n", outcome, layer, blayer, bin, factor, w, v, wRef, vRef, wNew,
631 TMath::Sq(w - wNew) / (e + eNew));
635 fprintf(output,
" <LayerProfile>\n");
636 for (
int outcome = 1; outcome < NOUTCOME; ++outcome) {
637 fprintf(output,
" <!-- %s -->\n", outcomeComment[outcome]);
638 fprintf(output,
" <Outcome outcome=\"%d\">\n", outcome);
641 if ((outcome == MuidElementNumbers::c_StopInForwardEndcap)
645 if ((outcome == MuidElementNumbers::c_StopInBackwardEndcap)
647 if ((outcome == MuidElementNumbers::c_ExitBackwardEndcap)
649 if ((outcome >= MuidElementNumbers::c_CrossBarrelStopInForwardMin)
650 && (outcome <= MuidElementNumbers::c_CrossBarrelStopInForwardMax)
652 if ((outcome >= MuidElementNumbers::c_CrossBarrelStopInBackwardMin)
653 && (outcome <= MuidElementNumbers::c_CrossBarrelStopInBackwardMax)
655 if ((outcome >= MuidElementNumbers::c_CrossBarrelExitForwardMin) && (outcome <= MuidElementNumbers::c_CrossBarrelExitForwardMax)
657 if ((outcome >= MuidElementNumbers::c_CrossBarrelExitBackwardMin) && (outcome <= MuidElementNumbers::c_CrossBarrelExitBackwardMax)
659 int lastBin = layer + 1;
660 if ((outcome != MuidElementNumbers::c_StopInBarrel)
664 if (layerHitV[layer][outcome]->GetEntries() > 0.0) {
665 if (outcome >= MuidElementNumbers::c_CrossBarrelStopInForwardMin) layerHitU[layer][outcome]->Divide(layerHitV[layer][outcome]);
666 layerHitW[layer][outcome]->Divide(layerHitV[layer][outcome]);
668 fprintf(output,
" <LastLayer layer=\"%d\">\n ", layer);
669 for (
int bin = 1; bin <= lastBin; ++bin) {
670 fprintf(output,
"%16.8E", layerHitW[layer][outcome]->GetBinContent(bin));
671 if ((bin % 8 == 0) && (bin != lastBin)) fprintf(output,
"\n ");
673 fprintf(output,
"\n </LastLayer>\n");
675 fprintf(output,
" </Outcome>\n");
677 fprintf(output,
" </LayerProfile>\n");
681 int nBins = rchisqA[0][1]->GetNbinsX();
682 double binWidth = rchisqA[0][1]->GetBinWidth(1);
683 double lowEdge = rchisqA[0][1]->GetBinLowEdge(1);
684 fprintf(output,
" <TransversePDF>\n");
685 for (
int detector = 0; detector <= 2; ++detector) {
686 fprintf(output,
" <%s>\n", detectorName[detector]);
688 for (
int halfNdof = 1; halfNdof <= 18; ++halfNdof) {
691 fprintf(output,
" <DegreesOfFreedom ndof=\"%d\">\n", 2 * halfNdof);
692 double entries = rchisqA[halfNdof][detector]->GetEntries();
693 double p0 = entries * binWidth;
699 double p2 = (double)(halfNdof);
700 rchisqFunc->SetParameters(p0, p1, p2);
701 rchisqFunc->ReleaseParameter(0);
702 rchisqFunc->ReleaseParameter(1);
703 rchisqFunc->FixParameter(2, p2);
704 int peakBin = rchisqA[halfNdof][detector]->GetMaximumBin();
706 double xMax = lowEdge + binWidth * (peakBin + 10);
709 if ((halfNdof > 1) && (entries > 0)) {
710 rchisqA[halfNdof][detector]->Fit(
"rchisqFunc",
"WL",
"", xMin, xMax);
711 p0Left = rchisqFunc->GetParameter(0);
712 p1Left = rchisqFunc->GetParameter(1);
715 if (!isMuon) p0 = entries * (isElec ? 1.0 : 10.0);
719 if ((entries > 500.0) && (halfNdof <= 15)) {
720 double peak = rchisqA[halfNdof][detector]->GetBinContent(peakBin);
722 int binLow = peakBin;
723 double threshold = ((isMuon || isPion || isKaon) ? 0.1 : 0.2) * peak;
724 if (halfNdof >= 10) { threshold *= 2.0; }
725 for (
int bin = peakBin; bin <= nBins; ++bin) {
726 if (rchisqA[halfNdof][detector]->GetBinContent(bin) < threshold)
break;
728 if (binLow < 1) { binLow = 1; }
730 xMin = lowEdge + binWidth * binLow;
741 for (
int bin = rchisqA[halfNdof][detector]->GetNbinsX(); bin > 0; --bin) {
742 if (rchisqA[halfNdof][detector]->GetBinContent(bin) > 0.0) {
743 int bin2 = bin - (33 - 3 * halfNdof);
744 if (bin2 > bin - 2) { bin2 = bin - 2; }
745 if (bin2 < peakBin) {
748 double xMin2 = lowEdge + binWidth * bin2;
757 if (halfNdof == 1) { xMin = 6.4; }
759 if (halfNdof == 1) { xMin = 8.0; }
760 if (halfNdof == 2) { xMin = (isElec ? 3.8 : 4.6); }
761 if (halfNdof == 3) { xMin = (isElec ? 2.4 : 4.0); }
762 if (halfNdof == 4) { xMin = (isElec ? 0.0 : 3.4); }
772 if (entries < 50.0) {
773 rchisqFunc->FixParameter(1, p1);
775 if ((entries > 0) && (
int((xMax - xMin) / binWidth + 0.5) >= rchisqFunc->GetNumberFreeParameters())) {
776 rchisqA[halfNdof][detector]->Fit(
"rchisqFunc",
"WL",
"", xMin, xMax);
777 p0 = rchisqFunc->GetParameter(0);
779 p1 = rchisqFunc->GetParameter(1);
784 if ((entries > 0.0) && (rchisqA[halfNdof][detector]->GetEntries() > 0.0)) {
785 yNorm = rchisqA[halfNdof][detector]->GetEntries() / entries;
787 double yScaleLeft = yNorm * p0Left * p2 / TMath::Gamma(p2);
788 double yScale = yNorm * p0 * p2 / TMath::Gamma(p2);
789 for (
int bin = 1; bin <= nBins; ++bin) {
790 double x = lowEdge + (bin - 0.5) * binWidth;
791 double y = rchisqA[halfNdof][detector]->GetBinContent(bin) * yNorm;
792 if ((rchisqA[halfNdof][detector]->GetBinContent(bin) == 0.0) || (x > xMin)) {
793 if ((bin < peakBin) && (xMin > 0.0)) {
795 y = yScaleLeft * std::pow(x, p2 - 1.0) * std::exp(-x);
798 y = yScale * std::pow(x, p2 - 1.0) * std::exp(-x);
801 rchisqB[halfNdof][detector]->SetBinContent(bin, y);
803 for (
int bin = nBins + 1; bin <= 100; ++bin) {
804 double x = (lowEdge + (bin - 0.5) * binWidth) * p1 * p2;
805 double y = yScale * std::pow(x, p2 - 1.0) * std::exp(-x);
806 rchisqB[halfNdof][detector]->SetBinContent(bin, y);
809 for (
int bin = 100; bin > 0; --bin) {
810 sum += rchisqB[halfNdof][detector]->GetBinContent(bin);
813 fprintf(output,
" <Tail>\n");
814 fprintf(output,
" <Threshold>%16.7E</Threshold>\n", xMin);
815 fprintf(output,
" <ScaleY>%16.7E</ScaleY>\n", yScale / sum);
816 fprintf(output,
" <ScaleX>%16.7E</ScaleX>\n", p1);
817 fprintf(output,
" </Tail>\n");
818 fprintf(output,
" <Histogram>\n");
819 for (
int bin = 1; bin <= nBins; bin += 10) {
820 fprintf(output,
" %16.7E%16.7E%16.7E%16.7E%16.7E%16.7E%16.7E%16.7E%16.7E%16.7E\n",
821 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin) / sum),
822 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 1) / sum),
823 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 2) / sum),
824 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 3) / sum),
825 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 4) / sum),
826 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 5) / sum),
827 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 6) / sum),
828 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 7) / sum),
829 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 8) / sum),
830 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 9) / sum));
832 fprintf(output,
" </Histogram>\n");
833 fprintf(output,
" </DegreesOfFreedom>\n");
835 fprintf(output,
" </%s>\n", detectorName[detector]);
837 fprintf(output,
" </TransversePDF>\n");
838 fprintf(output,
" </%s>\n", xmllabel);
842 TCanvas* canvas =
new TCanvas(
"tree", label, 900, 900);
844 gStyle->SetOptStat(10);
845 gStyle->SetOptFit(0);
846 canvas->GetPad(0)->SetLogy(0);
847 canvas->GetPad(0)->SetGrid(1, 1);
849 canvas->Divide(1, 1);
850 canvas->GetPad(1)->SetLogy(1);
851 snprintf(label,
sizeof(label),
"Muid-%s.pdf[", xmllabel);
852 canvas->SaveAs(label);
853 snprintf(label,
sizeof(label),
"Muid-%s.pdf", xmllabel);
855 discardA->Divide(discardB);
856 discardA->SetLineColor(kRed);
858 canvas->SaveAs(label);
859 for (
int outcome = 1; outcome < NOUTCOME; ++outcome) {
862 layerHitU[layer][outcome]->SetMaximum(2.0);
863 layerHitU[layer][outcome]->SetMinimum(1.0E-4);
864 if (isProt or isDeut) layerHitU[layer][outcome]->SetMinimum(1.0E-6);
865 if (isElec) layerHitU[layer][outcome]->SetMinimum(1.0E-10);
866 layerHitU[layer][outcome]->GetXaxis()->SetTitle(
"KLM Layer");
867 layerHitU[layer][outcome]->GetYaxis()->SetTitle(
"Frequency");
868 layerHitU[layer][outcome]->Draw(
"E1");
869 layerHitW[layer][outcome]->SetLineColor(kMagenta);
870 layerHitW[layer][outcome]->Draw(
"HIST,SAME");
871 layerHitU[layer][outcome]->Draw(
"E1,SAME");
872 canvas->SaveAs(label);
877 canvas->Divide(1, 2);
878 canvas->GetPad(1)->SetLogy(1);
879 canvas->GetPad(2)->SetLogy(1);
880 gStyle->SetOptStat(110);
881 gStyle->SetOptFit(2);
882 for (
int detector = 0; detector <= 2; ++detector) {
883 for (
int halfNdof = 1; halfNdof <= 18; ++halfNdof) {
884 int padNo = (halfNdof - 1) % 2 + 1;
887 rchisqA[halfNdof][detector]->SetMinimum(0.001);
888 if (rchisqA[halfNdof][detector]->GetEntries() == 0.0) { rchisqA[halfNdof][detector]->SetMaximum(2.0); }
889 rchisqA[halfNdof][detector]->GetXaxis()->SetTitle(
"#chi^{2}/ndf");
890 rchisqA[halfNdof][detector]->GetYaxis()->SetTitle(
"Frequency");
891 rchisqA[halfNdof][detector]->Draw(
"");
892 rchisqB[halfNdof][detector]->SetLineColor(kMagenta);
893 rchisqB[halfNdof][detector]->Draw(
"SAME");
894 rchisqA[halfNdof][detector]->Draw(
"SAME,E1");
896 canvas->SaveAs(label);
901 snprintf(label,
sizeof(label),
"Muid-%s.pdf]", xmllabel);
902 canvas->SaveAs(label);
908int main(
int argc,
char** argv)
916 output = std::fopen(argv[2],
"a");
917 if (output ==
nullptr) {
918 std::printf(
"Cannot open output file %s\n", argv[2]);
922 makeprob(chain, output, argv[3]);
929 "b2klm-likelihood-parameters input_file output_file xml_label\n");
Class to store the likelihoods from KLM with additional information related to the extrapolation.
A Class to store the Monte Carlo particle information.
int getNDaughters() const
Return number of daughter MCParticles.
int getLastDaughter() const
Get 1-based index of last daughter, 0 if no daughters.
ROOT::Math::XYZVector getMomentum() const
Return momentum.
int getFirstDaughter() const
Get 1-based index of first daughter, 0 if no daughters.
static constexpr int getMaximalEndcapForwardLayer()
Get maximal endcap-forward layer number (0-based).
static constexpr int getMaximalEndcapBackwardLayer()
Get maximal endcap-forward layer number (0-based).
static constexpr int getMaximalBarrelLayer()
Get maximal barrel layer number (0-based).
Class to store reconstructed particles.
bool isForward(int cellId)
Check whether the crystal is in forward ECL.
Abstract base class for different kinds of events.