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 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,
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 char detectorName[3][40] = {
"BarrelAndEndcap",
"BarrelOnly",
"EndcapOnly" };
137 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 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 sprintf(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 sprintf(label,
"LayerHitU-layer%02d-outcome%d", layer, outcome);
291 sprintf(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 sprintf(label,
"LayerHitV-layer%02d-outcome%d", layer, outcome);
295 sprintf(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 sprintf(label,
"LayerHitW-layer%02d-outcome%d", layer, outcome);
299 sprintf(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 sprintf(label,
"ReducedChiSquaredA-%02ddof-detector%d", 2 * halfNdof, detector);
308 sprintf(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 sprintf(label,
"ReducedChiSquaredB-%02ddof-detector%d", 2 * halfNdof, detector);
312 sprintf(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 = (TChainElement*)next())) {
325 TFile file(chEl->GetTitle());
326 TTree* tree = (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)
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) {
537 if ((outcome >= MuidElementNumbers::c_CrossBarrelStopInForwardMin)
538 && (outcome <= MuidElementNumbers::c_CrossBarrelStopInForwardMax)
540 if ((outcome >= MuidElementNumbers::c_CrossBarrelStopInBackwardMin)
541 && (outcome <= MuidElementNumbers::c_CrossBarrelStopInBackwardMax)
543 if ((outcome >= MuidElementNumbers::c_CrossBarrelExitForwardMin) && (outcome <= MuidElementNumbers::c_CrossBarrelExitForwardMax)
545 if ((outcome >= MuidElementNumbers::c_CrossBarrelExitBackwardMin) && (outcome <= MuidElementNumbers::c_CrossBarrelExitBackwardMax)
549 int blayer = outcome - 7;
551 if (outcome >= MuidElementNumbers::c_CrossBarrelStopInBackwardMin) { outcomeRef = MuidElementNumbers::c_StopInBackwardEndcap; blayer = outcome - MuidElementNumbers::c_CrossBarrelStopInBackwardMin; }
552 if (outcome >= MuidElementNumbers::c_CrossBarrelExitForwardMin) { outcomeRef = MuidElementNumbers::c_ExitForwardEndcap; blayer = outcome - MuidElementNumbers::c_CrossBarrelExitForwardMin; }
553 if (outcome >= MuidElementNumbers::c_CrossBarrelExitBackwardMin) { outcomeRef = MuidElementNumbers::c_ExitBackwardEndcap; blayer = outcome - MuidElementNumbers::c_CrossBarrelExitBackwardMin; }
556 double wSumRef = 0.0;
557 double vSumRef = 0.0;
558 for (
int bin = 1; bin <= blayer + 1; ++bin) {
559 wSum += layerHitW[layer][outcome]->GetBinContent(bin);
560 vSum += layerHitV[layer][outcome]->GetBinContent(bin);
561 wSumRef += layerHitW[blayer][3]->GetBinContent(bin);
562 vSumRef += layerHitV[blayer][3]->GetBinContent(bin);
566 if (vSum == 0.0) vSum = wSum;
568 double factor = (wSum / vSum) / (wSumRef / vSumRef);
569 for (
int bin = 1; bin <= blayer + 1; ++bin) {
570 double w = layerHitW[layer][outcome]->GetBinContent(bin);
571 double v = layerHitV[layer][outcome]->GetBinContent(bin);
572 double v1 = TMath::Max(v, 1.0);
573 double wRef = layerHitW[blayer][3]->GetBinContent(bin);
574 double vRef = layerHitV[blayer][3]->GetBinContent(bin);
575 double wRef1 = TMath::Max(wRef, 1.0);
576 double wNew = wRef * factor * (
v1 / vRef);
577 wNew = TMath::Min((isMuon ? 0.95 : 0.6667) * v1, wNew);
578 double e = (w == 0.0) ? 1.0 : w;
579 double eNew = factor * factor * wRef1 *
v1 * (
v1 * (vRef - wRef) + wRef * vRef) / (vRef * vRef * vRef);
580 wNew = (w / e + wNew / eNew) / (1.0 / e + 1.0 / eNew);
581 if (!isMuon && (bin > 1)) {
582 wNew = TMath::Min(wNew, layerHitW[layer][outcome]->GetBinContent(bin - 1));
585 layerHitW[layer][outcome]->SetBinContent(bin, wNew);
587 printf(
"%d,%d,%d,%d,%g,%g,%g,%g,%g,%g,%g\n", outcome, layer, blayer, bin, factor, w, v, wRef, vRef, wNew,
588 TMath::Sq(w - wNew) / (e + eNew));
594 for (
int bin = 1; bin <= elayer + 1; ++bin) {
595 wSum += layerHitW[layer][outcome]->GetBinContent(bin + 15);
596 vSum += layerHitV[layer][outcome]->GetBinContent(bin + 15);
597 wSumRef += layerHitW[layer][outcomeRef]->GetBinContent(bin + 15);
598 vSumRef += layerHitV[layer][outcomeRef]->GetBinContent(bin + 15);
601 factor *= (layerHitW[blayer][3]->GetBinContent(blayer + 1) / layerHitV[blayer][3]->GetBinContent(blayer + 1))
602 / (layerHitW[layer][outcomeRef]->GetBinContent(1 + 15) / layerHitV[layer][outcomeRef]->GetBinContent(1 + 15));
604 factor = (wSum / vSum) / (wSumRef / vSumRef);
606 for (
int bin = 1; bin <= elayer + 1; ++bin) {
607 double w = layerHitW[layer][outcome]->GetBinContent(bin + 15);
608 double v = layerHitV[layer][outcome]->GetBinContent(bin + 15);
609 double v1 = TMath::Max(v, 1.0);
610 double wRef = layerHitW[layer][outcomeRef]->GetBinContent(bin + 15);
611 double vRef = layerHitV[layer][outcomeRef]->GetBinContent(bin + 15);
612 double wRef1 = TMath::Max(wRef, 1.0);
613 double wNew = wRef * factor * (
v1 / vRef);
614 wNew = TMath::Min((isMuon ? 0.95 : 0.6667) * v1, wNew);
615 double e = (w == 0.0) ? 1.0 : w;
616 double eNew = factor * factor * wRef1 *
v1 * (
v1 * (vRef - wRef) + wRef * vRef) / (vRef * vRef * vRef);
617 wNew = (w / e + wNew / eNew) / (1.0 / e + 1.0 / eNew);
618 if (!isMuon && (bin > 1)) {
619 wNew = TMath::Min(wNew, layerHitW[layer][outcome]->GetBinContent(bin + 15 - 1));
622 layerHitW[layer][outcome]->SetBinContent(bin + 15, wNew);
624 printf(
"%d,%d,%d,%d,%g,%g,%g,%g,%g,%g,%g\n", outcome, layer, blayer, bin, factor, w, v, wRef, vRef, wNew,
625 TMath::Sq(w - wNew) / (e + eNew));
629 fprintf(output,
" <LayerProfile>\n");
630 for (
int outcome = 1; outcome < NOUTCOME; ++outcome) {
631 fprintf(output,
" <!-- %s -->\n", outcomeComment[outcome]);
632 fprintf(output,
" <Outcome outcome=\"%d\">\n", outcome);
635 if ((outcome == MuidElementNumbers::c_StopInForwardEndcap)
639 if ((outcome == MuidElementNumbers::c_StopInBackwardEndcap)
641 if ((outcome == MuidElementNumbers::c_ExitBackwardEndcap)
643 if ((outcome >= MuidElementNumbers::c_CrossBarrelStopInForwardMin)
644 && (outcome <= MuidElementNumbers::c_CrossBarrelStopInForwardMax)
646 if ((outcome >= MuidElementNumbers::c_CrossBarrelStopInBackwardMin)
647 && (outcome <= MuidElementNumbers::c_CrossBarrelStopInBackwardMax)
649 if ((outcome >= MuidElementNumbers::c_CrossBarrelExitForwardMin) && (outcome <= MuidElementNumbers::c_CrossBarrelExitForwardMax)
651 if ((outcome >= MuidElementNumbers::c_CrossBarrelExitBackwardMin) && (outcome <= MuidElementNumbers::c_CrossBarrelExitBackwardMax)
653 int lastBin = layer + 1;
654 if ((outcome != MuidElementNumbers::c_StopInBarrel)
656 if (layerHitV[layer][outcome]->GetEntries() > 0.0) {
657 if (outcome >= MuidElementNumbers::c_CrossBarrelStopInForwardMin) layerHitU[layer][outcome]->Divide(layerHitV[layer][outcome]);
658 layerHitW[layer][outcome]->Divide(layerHitV[layer][outcome]);
660 fprintf(output,
" <LastLayer layer=\"%d\">\n ", layer);
661 for (
int bin = 1; bin <= lastBin; ++bin) {
662 fprintf(output,
"%16.8E", layerHitW[layer][outcome]->GetBinContent(bin));
663 if ((bin % 8 == 0) && (bin != lastBin)) fprintf(output,
"\n ");
665 fprintf(output,
"\n </LastLayer>\n");
667 fprintf(output,
" </Outcome>\n");
669 fprintf(output,
" </LayerProfile>\n");
673 int nBins = rchisqA[0][1]->GetNbinsX();
674 double binWidth = rchisqA[0][1]->GetBinWidth(1);
675 double lowEdge = rchisqA[0][1]->GetBinLowEdge(1);
676 fprintf(output,
" <TransversePDF>\n");
677 for (
int detector = 0; detector <= 2; ++detector) {
678 fprintf(output,
" <%s>\n", detectorName[detector]);
680 for (
int halfNdof = 1; halfNdof <= 18; ++halfNdof) {
683 fprintf(output,
" <DegreesOfFreedom ndof=\"%d\">\n", 2 * halfNdof);
684 double entries = rchisqA[halfNdof][detector]->GetEntries();
685 double p0 = entries * binWidth;
691 double p2 = (double)(halfNdof);
692 rchisqFunc->SetParameters(p0, p1, p2);
693 rchisqFunc->ReleaseParameter(0);
694 rchisqFunc->ReleaseParameter(1);
695 rchisqFunc->FixParameter(2, p2);
696 int peakBin = rchisqA[halfNdof][detector]->GetMaximumBin();
698 double xMax = lowEdge + binWidth * (peakBin + 10);
701 if ((halfNdof > 1) && (entries > 0)) {
702 rchisqA[halfNdof][detector]->Fit(
"rchisqFunc",
"WL",
"", xMin, xMax);
703 p0Left = rchisqFunc->GetParameter(0);
704 p1Left = rchisqFunc->GetParameter(1);
707 if (!isMuon) p0 = entries * (isElec ? 1.0 : 10.0);
711 if ((entries > 500.0) && (halfNdof <= 15)) {
712 double peak = rchisqA[halfNdof][detector]->GetBinContent(peakBin);
714 int binLow = peakBin;
715 double threshold = ((isMuon || isPion || isKaon) ? 0.1 : 0.2) * peak;
716 if (halfNdof >= 10) { threshold *= 2.0; }
717 for (
int bin = peakBin; bin <= nBins; ++bin) {
718 if (rchisqA[halfNdof][detector]->GetBinContent(bin) < threshold)
break;
720 if (binLow < 1) { binLow = 1; }
722 xMin = lowEdge + binWidth * binLow;
733 for (
int bin = rchisqA[halfNdof][detector]->GetNbinsX(); bin > 0; --bin) {
734 if (rchisqA[halfNdof][detector]->GetBinContent(bin) > 0.0) {
735 int bin2 = bin - (33 - 3 * halfNdof);
736 if (bin2 > bin - 2) { bin2 = bin - 2; }
737 if (bin2 < peakBin) {
740 double xMin2 = lowEdge + binWidth * bin2;
749 if (halfNdof == 1) { xMin = 6.4; }
751 if (halfNdof == 1) { xMin = 8.0; }
752 if (halfNdof == 2) { xMin = (isElec ? 3.8 : 4.6); }
753 if (halfNdof == 3) { xMin = (isElec ? 2.4 : 4.0); }
754 if (halfNdof == 4) { xMin = (isElec ? 0.0 : 3.4); }
764 if (entries < 50.0) {
765 rchisqFunc->FixParameter(1, p1);
767 if ((entries > 0) && (int((xMax - xMin) / binWidth + 0.5) >= rchisqFunc->GetNumberFreeParameters())) {
768 rchisqA[halfNdof][detector]->Fit(
"rchisqFunc",
"WL",
"", xMin, xMax);
769 p0 = rchisqFunc->GetParameter(0);
771 p1 = rchisqFunc->GetParameter(1);
776 if ((entries > 0.0) && (rchisqA[halfNdof][detector]->GetEntries() > 0.0)) {
777 yNorm = rchisqA[halfNdof][detector]->GetEntries() / entries;
779 double yScaleLeft = yNorm * p0Left * p2 / TMath::Gamma(p2);
780 double yScale = yNorm * p0 * p2 / TMath::Gamma(p2);
781 for (
int bin = 1; bin <= nBins; ++bin) {
782 double x = lowEdge + (bin - 0.5) * binWidth;
783 double y = rchisqA[halfNdof][detector]->GetBinContent(bin) * yNorm;
784 if ((rchisqA[halfNdof][detector]->GetBinContent(bin) == 0.0) || (x > xMin)) {
785 if ((bin < peakBin) && (xMin > 0.0)) {
787 y = yScaleLeft * std::pow(x, p2 - 1.0) * std::exp(-x);
790 y = yScale * std::pow(x, p2 - 1.0) * std::exp(-x);
793 rchisqB[halfNdof][detector]->SetBinContent(bin, y);
795 for (
int bin = nBins + 1; bin <= 100; ++bin) {
796 double x = (lowEdge + (bin - 0.5) * binWidth) * p1 * p2;
797 double y = yScale * std::pow(x, p2 - 1.0) * std::exp(-x);
798 rchisqB[halfNdof][detector]->SetBinContent(bin, y);
801 for (
int bin = 100; bin > 0; --bin) {
802 sum += rchisqB[halfNdof][detector]->GetBinContent(bin);
805 fprintf(output,
" <Tail>\n");
806 fprintf(output,
" <Threshold>%16.7E</Threshold>\n", xMin);
807 fprintf(output,
" <ScaleY>%16.7E</ScaleY>\n", yScale / sum);
808 fprintf(output,
" <ScaleX>%16.7E</ScaleX>\n", p1);
809 fprintf(output,
" </Tail>\n");
810 fprintf(output,
" <Histogram>\n");
811 for (
int bin = 1; bin <= nBins; bin += 10) {
812 fprintf(output,
" %16.7E%16.7E%16.7E%16.7E%16.7E%16.7E%16.7E%16.7E%16.7E%16.7E\n",
813 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin) / sum),
814 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 1) / sum),
815 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 2) / sum),
816 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 3) / sum),
817 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 4) / sum),
818 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 5) / sum),
819 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 6) / sum),
820 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 7) / sum),
821 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 8) / sum),
822 std::log(rchisqB[halfNdof][detector]->GetBinContent(bin + 9) / sum));
824 fprintf(output,
" </Histogram>\n");
825 fprintf(output,
" </DegreesOfFreedom>\n");
827 fprintf(output,
" </%s>\n", detectorName[detector]);
829 fprintf(output,
" </TransversePDF>\n");
830 fprintf(output,
" </%s>\n", xmllabel);
834 TCanvas* canvas =
new TCanvas(
"tree", label, 900, 900);
836 gStyle->SetOptStat(10);
837 gStyle->SetOptFit(0);
838 canvas->GetPad(0)->SetLogy(0);
839 canvas->GetPad(0)->SetGrid(1, 1);
841 canvas->Divide(1, 1);
842 canvas->GetPad(1)->SetLogy(1);
843 sprintf(label,
"Muid-%s.pdf[", xmllabel);
844 canvas->SaveAs(label);
845 sprintf(label,
"Muid-%s.pdf", xmllabel);
847 discardA->Divide(discardB);
848 discardA->SetLineColor(kRed);
850 canvas->SaveAs(label);
851 for (
int outcome = 1; outcome < NOUTCOME; ++outcome) {
854 layerHitU[layer][outcome]->SetMaximum(2.0);
855 layerHitU[layer][outcome]->SetMinimum(1.0E-4);
856 if (isProt or isDeut) layerHitU[layer][outcome]->SetMinimum(1.0E-6);
857 if (isElec) layerHitU[layer][outcome]->SetMinimum(1.0E-10);
858 layerHitU[layer][outcome]->GetXaxis()->SetTitle(
"KLM Layer");
859 layerHitU[layer][outcome]->GetYaxis()->SetTitle(
"Frequency");
860 layerHitU[layer][outcome]->Draw(
"E1");
861 layerHitW[layer][outcome]->SetLineColor(kMagenta);
862 layerHitW[layer][outcome]->Draw(
"HIST,SAME");
863 layerHitU[layer][outcome]->Draw(
"E1,SAME");
864 canvas->SaveAs(label);
869 canvas->Divide(1, 2);
870 canvas->GetPad(1)->SetLogy(1);
871 canvas->GetPad(2)->SetLogy(1);
872 gStyle->SetOptStat(110);
873 gStyle->SetOptFit(2);
874 for (
int detector = 0; detector <= 2; ++detector) {
875 for (
int halfNdof = 1; halfNdof <= 18; ++halfNdof) {
876 int padNo = (halfNdof - 1) % 2 + 1;
879 rchisqA[halfNdof][detector]->SetMinimum(0.001);
880 if (rchisqA[halfNdof][detector]->GetEntries() == 0.0) { rchisqA[halfNdof][detector]->SetMaximum(2.0); }
881 rchisqA[halfNdof][detector]->GetXaxis()->SetTitle(
"#chi^{2}/ndf");
882 rchisqA[halfNdof][detector]->GetYaxis()->SetTitle(
"Frequency");
883 rchisqA[halfNdof][detector]->Draw(
"");
884 rchisqB[halfNdof][detector]->SetLineColor(kMagenta);
885 rchisqB[halfNdof][detector]->Draw(
"SAME");
886 rchisqA[halfNdof][detector]->Draw(
"SAME,E1");
888 canvas->SaveAs(label);
893 sprintf(label,
"Muid-%s.pdf]", xmllabel);
894 canvas->SaveAs(label);
900int main(
int argc,
char** argv)
908 output = std::fopen(argv[2],
"a");
909 makeprob(chain, output, argv[3]);
916 "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.
const std::vector< double > v1
MATLAB generated random vector.