File indexing completed on 2025-01-18 10:17:17
0001
0002 #define _DETECTOR_ "DRICH"
0003
0004
0005
0006 #define _NPE_REFERENCE_ 321
0007
0008
0009 #define _TSIZE_ 0.07
0010 #define _LSIZE_ 0.05
0011
0012 void evaluation(const char *ifname, const char *ofname = 0)
0013 {
0014 const unsigned gdim = 11, qdim = 40;
0015 double thmin = 36.0, thstep = 0.1;
0016 unsigned thstat[2][qdim]; memset(thstat, 0x00, sizeof(thstat));
0017
0018
0019 auto ifdata = new TFile(ifname);
0020 if (!ifdata) {
0021 printf("input file '%s' does not exist\n", ifname);
0022 exit(0);
0023 }
0024 TTree *it = dynamic_cast<TTree*>(ifdata->Get("events"));
0025 if (!it) {
0026 printf("input file '%s' does not have \"events\" tree\n", ifname);
0027 exit(0);
0028 }
0029
0030 std::vector<double> thvector, npvector;
0031
0032 auto np = new TH1D("np", "Photon count", 50, 0, 50);
0033 #ifdef _AEROGEL_
0034 unsigned id = 0;
0035 auto th = new TH1D("th", "Cherenkov theta", 50, 180, 200);
0036 auto ri = new TH1D("ri", "Refractive Index - 1.0", 50, 0.018, 0.020);
0037 auto dt = new TH1D("dt", "Cherenkov theta diff", 50, -10, 10);
0038
0039 #else
0040 unsigned id = 1;
0041 auto th = new TH1D("th", "", 50, 35, 41);
0042 auto tq = new TH1D("tq", "", 50, 35, 41);
0043 auto ri = new TH1D("ri", "Refractive Index - 1.0", 50, 0.00075, 0.00077);
0044 auto dt = new TH1D("dt", "Cherenkov theta diff", 50, -2, 3);
0045
0046 #endif
0047
0048
0049 auto mctracks = new std::vector<dd4pod::Geant4ParticleData>();
0050 auto rctracks = new std::vector<edm4eic::ReconstructedParticleData>();
0051 auto cherenkov = new std::vector<edm4eic::CherenkovParticleIDData>();
0052 it->SetBranchAddress("mcparticles", &mctracks);
0053
0054
0055 #ifdef _USE_RECONSTRUCTED_TRACKS_
0056 it->SetBranchAddress("rcparticles", &rctracks);
0057 #endif
0058 it->SetBranchAddress((TString(_DETECTOR_) + "PID").Data(), &cherenkov);
0059 auto options = new std::vector<edm4eic::CherenkovPdgHypothesis>();
0060 it->SetBranchAddress((TString(_DETECTOR_) + "PID_0").Data(), &options);
0061 auto angles = new std::vector<edm4eic::CherenkovThetaAngleMeasurement>();
0062 it->SetBranchAddress((TString(_DETECTOR_) + "PID_1").Data(), &angles);
0063
0064
0065 unsigned false_assignment_stat[2] = {0};
0066 for(int ev=0; ev<it->GetEntries(); ev++) {
0067 it->GetEntry(ev);
0068
0069 #ifdef _USE_RECONSTRUCTED_TRACKS_
0070
0071 std::map<eic::Index, const edm4eic::ReconstructedParticleData*> mc2rc;
0072 for(const auto &rctrack: *rctracks)
0073 mc2rc[rctrack.mcID] = &rctrack;
0074 #endif
0075
0076
0077
0078 std::map<eic::Index, const edm4eic::CherenkovParticleIDData*> rc2cherenkov;
0079 for(const auto &pid: *cherenkov)
0080 rc2cherenkov[pid.recID] = &pid;
0081
0082
0083
0084 for(auto mctrack: *mctracks) {
0085
0086 if (mctrack.g4Parent) continue;
0087
0088 #ifdef _USE_RECONSTRUCTED_TRACKS_
0089
0090 auto rctrack = mc2rc.find(mctrack.ID) == mc2rc.end() ? 0 : mc2rc[mctrack.ID];
0091 if (!rctrack) continue;
0092
0093
0094 auto cherenkov = rc2cherenkov.find(rctrack.ID) == rc2cherenkov.end() ? 0 : rc2cherenkov[rctrack.ID];
0095 #else
0096 auto cherenkov = rc2cherenkov.find(mctrack.ID) == rc2cherenkov.end() ? 0 : rc2cherenkov[mctrack.ID];
0097 #endif
0098 if (!cherenkov) continue;
0099
0100
0101
0102
0103 double pp = mctrack.ps.mag(), m = 0.493677;
0104
0105
0106
0107
0108 printf("%f %f (%4d) \n", mctrack.mass, mctrack.ps.mag(), mctrack.pdgID);
0109
0110
0111 {
0112 const edm4eic::CherenkovPdgHypothesis *best = 0;
0113
0114 for(unsigned iq=cherenkov->options_begin; iq<cherenkov->options_end; iq++) {
0115 const auto &option = (*options)[iq];
0116
0117 if (option.radiator != id) continue;
0118
0119
0120 if (abs(option.pdg) == 11) continue;
0121
0122 if (abs(option.pdg) == _NPE_REFERENCE_) {
0123 np->Fill(option.npe);
0124
0125 if (ofname) npvector.push_back(option.npe);
0126 }
0127
0128 if (!best || option.weight > best->weight) best = &option;
0129 printf("radiator %3d (pdg %5d): weight %7.2f, npe %7.2f\n",
0130 option.radiator, option.pdg, option.weight, option.npe);
0131 }
0132 printf("\n");
0133
0134
0135
0136 if (!best || best->pdg != mctrack.pdgID) {
0137
0138 false_assignment_stat[best->npe >= 0 ? 0 : 1]++;
0139 }
0140
0141
0142
0143
0144 double rindex = (*angles)[id].rindex, theta = (*angles)[id].theta;
0145 double argument = sqrt(pp*pp + m*m)/(rindex*pp);
0146 double thp = fabs(argument) <= 1.0 ? acos(argument) : theta;
0147
0148
0149 if (best->npe > 15) (mctrack.pdgID == 321 ? th : tq)->Fill(1000* theta);
0150
0151 if (mctrack.pdgID == 321) dt->Fill(1000* (theta - thp));
0152 ri->Fill(rindex - 1.0);
0153 printf("<n> ~ %8.6f, <th> = %7.2f [mrad]\n", rindex - 1.0, 1000*thp);
0154
0155 {
0156 int thbin = (int)floor((1000*theta - thmin)/thstep);
0157 thstat[mctrack.pdgID == 321 ? 0 : 1][thbin]++;
0158 }
0159
0160 if (ofname) thvector.push_back(theta - thp);
0161 }
0162 }
0163 }
0164
0165 printf("%3d (%3d) false out of %lld\n", false_assignment_stat[0],
0166 false_assignment_stat[1], it->GetEntries());
0167
0168 if (ofname) {
0169 ifdata->Close();
0170
0171 auto *ofdata = new TFile(ofname, "RECREATE");
0172
0173 if (!ofdata) {
0174 printf("was not able to create output file '%s'\n", ofname);
0175 exit(0);
0176 }
0177 auto *ot = new TTree("t", "My tree");
0178
0179 double thbff, npbff;
0180 ot->Branch("th", &thbff, "th/D");
0181 ot->Branch("np", &npbff, "np/D");
0182
0183 for(unsigned iq=0; iq<thvector.size(); iq++) {
0184
0185 thbff = thvector[iq];
0186 npbff = npvector[iq];
0187
0188 ot->Fill();
0189 }
0190
0191 ot->Write();
0192 ofdata->Close();
0193 exit(0);
0194 } else {
0195 gROOT->Reset();
0196
0197 gStyle->SetTextSize(0.02);
0198 gStyle->SetLabelSize(0.04,"xy");
0199 gStyle->SetFrameFillColor(0);
0200 gStyle->SetOptStat(0);
0201 gStyle->SetOptFit(0);
0202
0203 gStyle->SetPadBottomMargin(0.15);
0204 gStyle->SetPadTopMargin(0.04);
0205 gStyle->SetPadRightMargin(0.05);
0206 gStyle->SetPadLeftMargin(0.12);
0207
0208
0209
0210
0211 gStyle->SetStatBorderSize(0);
0212 gStyle->SetStatColor(kWhite);
0213 gStyle->SetStatFontSize(0.03);
0214 gStyle->SetStatFont(52);
0215 gStyle->SetStatW(.13);
0216 gStyle->SetFitFormat("5.2f");
0217
0218
0219
0220
0221 TCanvas *cv = new TCanvas("cv", "", 0, 0, 800, 1000);
0222 cv->UseCurrentStyle();
0223 cv->SetBorderMode(0);
0224 cv->SetFrameBorderMode(0);
0225 cv->SetFrameLineColor(kWhite);
0226 cv->SetFillColor(kWhite);
0227
0228
0229 cv->Divide(1, 2);
0230 th->SetLineWidth(2); tq->SetLineWidth(2);
0231
0232 tq->GetXaxis()->SetLabelFont(52);
0233 tq->GetYaxis()->SetLabelFont(52);
0234 tq->GetXaxis()->SetTitleFont(52);
0235 tq->GetYaxis()->SetTitleFont(52);
0236
0237 tq->GetXaxis()->SetTitle("Reconstructed Cherenkov angle, [mrad]");
0238 tq->GetXaxis()->SetTitleSize(_TSIZE_);
0239 tq->GetXaxis()->SetLabelSize(_LSIZE_);
0240 tq->GetYaxis()->SetTitle("Number of Events");
0241 tq->GetYaxis()->SetTitleSize(_TSIZE_);
0242 tq->GetYaxis()->SetLabelSize(_LSIZE_);
0243 tq->GetXaxis()->SetTitleOffset(0.90);
0244 tq->GetYaxis()->SetTitleOffset(0.90);
0245
0246 tq->GetXaxis()->SetNdivisions(408);
0247 tq->GetYaxis()->SetNdivisions(808);
0248
0249 cv->cd(1);
0250 gPad->SetGrid();
0251 tq->Draw(); tq->Fit("gaus");
0252 th->Draw("SAME"); th->Fit("gaus");
0253
0254 {
0255
0256
0257
0258
0259 unsigned kstat = 0, pistat = 0, offset = 16;
0260 for(unsigned iq=0; iq<qdim; iq++) {
0261 kstat += thstat[0][iq];
0262 pistat += thstat[1][iq];
0263 }
0264
0265 unsigned kaccu [qdim]; memset( kaccu, 0x00, sizeof( kaccu));
0266 unsigned piaccu[qdim]; memset(piaccu, 0x00, sizeof(piaccu));
0267 for(unsigned iq=0; iq<qdim; iq++) {
0268 kaccu [iq] = (iq ? kaccu [iq-1] : 0) + thstat[0][iq];
0269 piaccu[iq] = (iq ? piaccu[iq-1] : 0) + thstat[1][iq];
0270 }
0271 for(unsigned iq=0; iq<qdim; iq++)
0272 printf("%2d: %4d -> %5.3f %4d -> %5.3f\n",
0273 iq, kaccu[iq], 1.*kaccu[iq]/kstat, piaccu[iq], 1.*piaccu[iq]/pistat);
0274
0275
0276
0277 float eff[gdim];
0278 float ctm[gdim];
0279 for(unsigned ig=0; ig<gdim; ig++) {
0280 unsigned ibin = ig + offset;
0281 eff[ig] = 1.* kaccu[ibin]/kstat;
0282 ctm[ig] = 1.*piaccu[ibin]/(kaccu[ibin] + piaccu[ibin]);
0283 }
0284 float eeff[gdim] = { .001, .001, .001, .001, .001, .001, .001, .001, .001, .001, .001};
0285 float ectm[gdim] = { .001, .001, .001, .001, .001, .001, .001, .001, .001, .001, .001};
0286
0287 auto greff = new TGraphErrors(gdim, eff, ctm, eeff, ectm);
0288 greff->SetMarkerSize(1.3);
0289 greff->SetMarkerStyle(21);
0290 greff->SetMarkerColor(kBlue);
0291
0292 auto hdum = new TH1D("hdum", "", 10, 0.50, 1.00);
0293
0294 hdum->GetXaxis()->SetLabelFont(52);
0295 hdum->GetYaxis()->SetLabelFont(52);
0296 hdum->GetXaxis()->SetTitleFont(52);
0297 hdum->GetYaxis()->SetTitleFont(52);
0298
0299 hdum->GetXaxis()->SetTitle("Kaon detection efficiency, [0..1]");
0300 hdum->GetXaxis()->SetTitleSize(_TSIZE_);
0301 hdum->GetXaxis()->SetLabelSize(_LSIZE_);
0302 hdum->GetYaxis()->SetTitle("Pion contamination, [0..1]");
0303 hdum->GetYaxis()->SetTitleSize(_TSIZE_);
0304 hdum->GetYaxis()->SetLabelSize(_LSIZE_);
0305 hdum->GetXaxis()->SetTitleOffset(0.90);
0306 hdum->GetYaxis()->SetTitleOffset(0.90);
0307 hdum->SetMinimum( 0.00);
0308 hdum->SetMaximum( 0.25);
0309
0310 hdum->GetXaxis()->SetNdivisions(408);
0311 hdum->GetYaxis()->SetNdivisions(808);
0312
0313 cv->cd(2);
0314 gPad->SetGrid();
0315 hdum->Draw();
0316 greff->Draw("PC");
0317
0318 }
0319
0320 #if 0
0321 auto cv = new TCanvas("cv", "", 1500, 500);
0322 cv->Divide(4, 1);
0323 cv->cd(1); np->Draw(); np->Fit("gaus");
0324 cv->cd(2); tq->Draw(); tq->Fit("gaus");
0325 th->Draw("SAME"); th->Fit("gaus");
0326 cv->cd(3); ri->Draw(); ri->Fit("gaus");
0327 cv->cd(4); dt->Draw();
0328 #endif
0329 }
0330 }