00001 #include "GaudiKernel/IDataProviderSvc.h"
00002 #include "GaudiKernel/MsgStream.h"
00003 #include "GaudiKernel/SmartDataPtr.h"
00004 #include "EventModel/EventModel.h"
00005 #include "EvtRecEvent/EvtRecEvent.h"
00006 #include "EventModel/EventHeader.h"
00007 #include "SimplePIDSvc/SimplePIDSvc.h"
00008
00009 #include "DstEvent/TofHitStatus.h"
00010 #include "TMath.h"
00011 #include "TFile.h"
00012 #include "TMatrixD.h"
00013 #include "TArray.h"
00014 #include <fstream>
00015 #include <iostream>
00016 #include <cstdlib>
00017 #include <cmath>
00018 using namespace std;
00019
00020 SimplePIDSvc::SimplePIDSvc(const std::string& name, ISvcLocator* svcLoc) : Service(name, svcLoc)
00021 {
00022 declareProperty("DedxChiCut", m_dedx_chi_cut = 4);
00023 declareProperty("TofChiCut", m_tof_chi_cut = 4);
00024 declareProperty("IsTofCorr", m_tof_corr = true);
00025 declareProperty("IsDedxCorr", m_dedx_corr = true);
00026 declareProperty("EidRatio", m_eid_ratio = 0.80);
00027 }
00028
00029 SimplePIDSvc::~SimplePIDSvc() {;}
00030
00031 StatusCode SimplePIDSvc::initialize()
00032 {
00033 MsgStream log(messageService(), name());
00034 log << MSG::INFO << "in SimplePIDSvc initialize()" << endreq;
00035
00036 StatusCode sc = Service::initialize();
00037
00038 sc = serviceLocator()->service("EventDataSvc", eventSvc_, true);
00039
00040 loadHistogram();
00041
00042 return sc;
00043 }
00044
00045 StatusCode SimplePIDSvc::finalize()
00046 {
00047 MsgStream log(messageService(), name());
00048 log << MSG::INFO << "in SimplePIDSvc finalize()" << endreq;
00049
00050 StatusCode sc = Service::finalize();
00051
00052 for (unsigned int i = 0; i < 2; i++)
00053 {
00054 for (unsigned int j = 0; j < 4; j++)
00055 {
00056 f_dedx[i][j]->Close();
00057 f_tof_q[i][j]->Close();
00058 f_tof_bgcost[i][j]->Close();
00059 f_tof_wgt[i][j]->Close();
00060 f_tof_final[i][j]->Close();
00061 f_tofec_q[i][j]->Close();
00062 f_tofec_bg[i][j]->Close();
00063 f_tofec_cost[i][j]->Close();
00064 }
00065 }
00066 for (unsigned int i = 0; i < 3; i++)
00067 {
00068 for (unsigned int j = 0; j < 4; j++)
00069 {
00070 f_emc[i][j]->Close();
00071 }
00072 }
00073
00074 return sc;
00075 }
00076
00077 StatusCode SimplePIDSvc::queryInterface(const InterfaceID& riid, void** ppvIF)
00078 {
00079 if (ISimplePIDSvc::interfaceID().versionMatch(riid))
00080 {
00081 *ppvIF = dynamic_cast<ISimplePIDSvc*>(this);
00082 }
00083 else
00084 {
00085 return Service::queryInterface(riid, ppvIF);
00086 }
00087 addRef();
00088 return StatusCode::SUCCESS;
00089 }
00090
00091 void SimplePIDSvc::preparePID(EvtRecTrack* track)
00092 {
00093
00094 SmartDataPtr<Event::EventHeader> eventHeaderpid(eventSvc_, "/Event/EventHeader");
00095 m_run = eventHeaderpid->runNumber();
00096
00097 if (track->isMdcKalTrackValid())
00098 {
00099 RecMdcKalTrack *mdckalTrk = track->mdcKalTrack();
00100 RecMdcKalTrack::PidType trk_type[5] = {
00101 RecMdcKalTrack::electron,
00102 RecMdcKalTrack::muon,
00103 RecMdcKalTrack::pion,
00104 RecMdcKalTrack::kaon,
00105 RecMdcKalTrack::proton,
00106 };
00107 double mass[5] = {
00108 0.000511,
00109 0.105658,
00110 0.13957,
00111 0.493677,
00112 0.938272,
00113 };
00114 for(unsigned int pid = 0; pid < 5; pid++)
00115 {
00116 mdckalTrk->setPidType(trk_type[pid]);
00117 m_p[pid] = mdckalTrk->p();
00118 m_betagamma[pid] = m_p[pid] / mass[pid];
00119 m_charge[pid] = mdckalTrk->charge();
00120 m_cost[pid] = cos(mdckalTrk->theta());
00121 }
00122 }
00123 else
00124 {
00125 for(unsigned int i = 0; i < 5; i++)
00126 {
00127 m_p[i] = -99;
00128 m_betagamma[i] = -99;
00129 m_cost[i] = -99;
00130 m_charge[i] = 0;
00131 }
00132
00133 }
00134
00135
00136 loadDedxInfo(track);
00137 if (m_dedx_corr)
00138 {
00139 dedxCorrection();
00140 }
00141
00142 loadTOFInfo(track);
00143 if (m_tof_corr)
00144 {
00145 if (m_tof_barrel == 1)
00146 {
00147 tofBarrelCorrection();
00148 }
00149 else if (m_tof_barrel == 0)
00150 tofEndcapCorrection();
00151 }
00152
00153 loadEMCInfo(track);
00154
00155 calprob();
00156 }
00157
00158 void SimplePIDSvc::calprob()
00159 {
00160 bool usededx = false;
00161 bool usetof = false;
00162
00163 for (unsigned int i = 0; i < 5 ;i++)
00164 {
00165 if (!usededx && fabs(m_dedx_chi[i]) < m_dedx_chi_cut)
00166 usededx = true;
00167 if (!usetof && fabs(m_tof_chi[i]) < m_tof_chi_cut)
00168 usetof = true;
00169
00170 m_dedx_only[i] = false;
00171 }
00172 if (!usededx)
00173 {
00174 for(unsigned int i = 0; i < 5; i++)
00175 m_dedx_chi[i] = -99;
00176 }
00177 if (!usetof)
00178 {
00179 for(unsigned int i = 0; i < 5; i++)
00180 m_tof_chi[i] = -99;
00181 }
00182
00183 for (unsigned int i = 0; i < 5; i++)
00184 {
00185 m_prob[i] = -99;
00186 double chi2 = 0;
00187 int ndf = 0;
00188
00189 if (usededx && usetof)
00190 {
00191 chi2 = pow(m_dedx_chi[i], 2) + pow(m_tof_chi[i], 2);
00192 ndf = 2;
00193 }
00194 else if (usededx && !usetof)
00195 {
00196 chi2 = pow(m_dedx_chi[i], 2);
00197 ndf = 1;
00198 m_dedx_only[i] = true;
00199 }
00200 else if (!usededx && usetof)
00201 {
00202 chi2 = pow(m_tof_chi[i],2);
00203 ndf = 1;
00204 }
00205 if (ndf > 0 && chi2 > 0)
00206 m_prob[i] = TMath::Prob(chi2, ndf);
00207 }
00208 }
00209
00210
00211
00212 int SimplePIDSvc::getRunIdx(int run_no)
00213 {
00214
00215
00216
00217
00218
00219 const int RUN_BEGIN_DATA_10 = 11414;
00220 const int RUN_END_DATA_10 = 14604;
00221 const int RUN_BEGIN_MC_10 = -14604;
00222 const int RUN_END_MC_10 = -11414;
00223 const int RUN_BEGIN_DATA_11 = 20448;
00224 const int RUN_END_DATA_11 = 23454;
00225 const int RUN_BEGIN_MC_11 = -23454;
00226 const int RUN_END_MC_11 = -20448;
00227 if (run_no >= RUN_BEGIN_DATA_10 && run_no <= RUN_END_DATA_10)
00228 return 0;
00229 else if (run_no >= RUN_BEGIN_DATA_11 && run_no <= RUN_END_DATA_11)
00230 return 1;
00231 else if (run_no >= RUN_BEGIN_MC_10 && run_no <= RUN_END_MC_10)
00232 return 2;
00233 else if (run_no >= RUN_BEGIN_MC_11 && run_no <= RUN_END_MC_11)
00234 return 3;
00235 else
00236 return -1;
00237 }
00238
00239 void SimplePIDSvc::loadTOFInfo(EvtRecTrack *track)
00240 {
00241
00242 for (unsigned int i = 0; i < 8; i++)
00243 {
00244 for (unsigned int j = 0; j < 5; j++)
00245 m_tof_dt[i][j] = -99.;
00246 m_tof_ph[i] = -99.;
00247 }
00248 for (unsigned int i = 0; i < 2; i++)
00249 {
00250 m_tof_zr[i] = -9999.;
00251 m_tof_counter[i] = -1;
00252 }
00253 for (unsigned int i = 0; i < 5; i++)
00254 {
00255 m_tof_chi[i] = -99.;
00256 }
00257 m_tof_barrel = -1;
00258
00259 if (!track->isExtTrackValid() || !track->isTofTrackValid()) return;
00260
00261 SmartRefVector<RecTofTrack> tofTrk = track->tofTrack();
00262 SmartRefVector<RecTofTrack>::iterator it;
00263 RecExtTrack* extTrk = track->extTrack();
00264 double zrhit[2];
00265 zrhit[0] = extTrk->tof1Position().z();
00266 zrhit[1] = extTrk->tof2Position().z();
00267
00268 TofHitStatus *hitst = new TofHitStatus;
00269
00270 for (it = tofTrk.begin(); it != tofTrk.end(); it++)
00271 {
00272 unsigned int st = (*it)->status();
00273 hitst->setStatus(st);
00274 if (hitst->is_raw()) continue;
00275 bool barrel = hitst->is_barrel();
00276 bool readout = hitst->is_readout();
00277 bool counter = hitst->is_counter();
00278 bool cluster = hitst->is_cluster();
00279 int layer = hitst->layer();
00280 double tof = (*it)->tof();
00281 double ph = (*it)->ph();
00282 m_tof_counter[layer-1] = (*it)->tofID();
00283
00284 if (barrel)
00285 {
00286 m_tof_barrel = 1;
00287 }
00288 else
00289 {
00290 m_tof_barrel = 0;
00291 zrhit[0] = extTrk->tof1Position().rho();
00292 }
00293 m_tof_zr[0] = zrhit[0];
00294 m_tof_zr[1] = zrhit[1];
00295
00296 int idx = -1;
00297 if (readout)
00298 {
00299 if (barrel)
00300 idx = ((st & 0xC0) >> 5) + (((st ^ 0x20) & 0x20) >> 5) - 2;
00301 else
00302 idx = 7;
00303 }
00304 else if (counter)
00305 {
00306 idx = layer + 3;
00307 }
00308 else if (cluster)
00309 {
00310 idx = 6;
00311 }
00312 if (idx == -1) continue;
00313 m_tof_ph[idx] = ph;
00314 for (unsigned int i = 0; i < 5; i++)
00315 {
00316 double offset = (*it)->toffset(i);
00317 double texp = (*it)->texp(i);
00318 if (texp < 0.0) continue;
00319 double dt = tof - offset - texp;
00320 m_tof_dt[idx][i] = dt;
00321 }
00322
00323
00324
00325 }
00326 delete hitst;
00327 }
00328
00329 void SimplePIDSvc::tofBarrelCorrection()
00330 {
00331 const double EPS = 1e-4;
00332 const double BG_LOW = 0.20;
00333 const double BG_UP = 7.40;
00334 const double COST_LOW = -0.81;
00335 const double COST_UP = 0.81;
00336 const double Q_LOW = 0.;
00337 const double Q_UP = 9000.;
00338 const double P_LOW = 0.2;
00339 const double P_UP = 1.3;
00340 const int BIN_BG = 15;
00341 const int BIN_COST = 15;
00342 const int BIN_P = 15;
00343 double BG[BIN_BG + 1] = {0.20, 0.87, 1.11, 1.35, 1.55, 1.72, 1.91, 2.17, 2.63, 3.05, 3.47, 3.93, 4.50, 5.27, 6.00, 7.40};
00344 double COST[BIN_COST + 1] = {-0.81, -0.64, -0.53, -0.43, -0.33, -0.23, -0.13, -0.04, 0.05, 0.14, 0.24, 0.34, 0.44, 0.54, 0.65, 0.81};
00345 double P[BIN_P + 1] = {0.20, 0.47, 0.56, 0.65, 0.72, 0.79, 0.86, 0.92, 0.98, 1.03, 1.08, 1.13, 1.17, 1.22, 1.26, 1.30};
00346 int idx = getRunIdx(m_run);
00347
00348 if (idx != -1)
00349 {
00350 for (unsigned int i = 0; i < 4; i++)
00351 {
00352 double bg;
00353 int bin_bg, bin_cost, bin_wgt;
00354 int pid;
00355 if (i == 0)
00356 {
00357 bg = max(P_LOW+EPS, min(P_UP-EPS, m_p[i]));
00358 bin_bg = findBin(P, BIN_P, bg);
00359 pid = 0;
00360 }
00361 else if (i == 2 || i == 3)
00362 {
00363 bg = max(BG_LOW+EPS, min(BG_UP-EPS, m_betagamma[i]));
00364 bin_bg = findBin(BG, BIN_BG, bg);
00365 pid = 1;
00366 }
00367 else
00368 {
00369 continue;
00370 }
00371 double cost = m_cost[i];
00372 int charge = m_charge[i];
00373 double t[5], q;
00374 double offset, sigma;
00375 double offset_q, offset_bgcost;
00376 int flag[4] = {0, 0, 0, 0, };
00377 cost = max(COST_LOW+EPS, min(COST_UP-EPS, cost));
00378 bin_cost = findBin(COST, BIN_COST, cost);
00379 if (bin_bg == -1 || bin_cost == -1) continue;
00380
00381
00382 for (unsigned int j = 0; j < 4; j++)
00383 {
00384 t[j] = m_tof_dt[j][i];
00385 if (fabs(t[j] + 99.) < EPS)
00386 flag[j] = 0;
00387 else
00388 flag[j] = 1;
00389 q = m_tof_ph[j];
00390 q = max(Q_LOW+EPS, min(Q_UP-EPS, q));
00391 if (charge == 1)
00392 {
00393 offset_q = h_tof_p_q_offset[pid][idx][j]->Interpolate( q );
00394 offset_bgcost = h_tof_p_bgcost_offset[pid][idx][j]->Interpolate( bg, cost );
00395 t[j] = t[j] - offset_q - offset_bgcost;
00396 }
00397 else
00398 {
00399 offset_q = h_tof_m_q_offset[pid][idx][j]->Interpolate( q );
00400 offset_bgcost = h_tof_m_bgcost_offset[pid][idx][j]->Interpolate( bg, cost );
00401 t[j] = t[j] - offset_q - offset_bgcost;
00402 }
00403 }
00404 bin_wgt = flag[0]*8 + flag[1]*4 + flag[2]*2 + flag[3] - 1;
00405 if (bin_wgt == -1) continue;
00406 t[4] = 0;
00407 for (unsigned int j = 0; j < 4; j++)
00408 {
00409 if (charge == 1)
00410 t[4] += t[j] * h_tof_p_wgt[pid][idx][bin_wgt][j]->GetBinContent( bin_bg+1, bin_cost+1 );
00411 else
00412 t[4] += t[j] * h_tof_m_wgt[pid][idx][bin_wgt][j]->GetBinContent( bin_bg+1, bin_cost+1 );
00413 }
00414 if (charge == 1)
00415 {
00416 t[4] /= h_tof_p_wgt[pid][idx][bin_wgt][4]->GetBinContent( bin_bg+1, bin_cost+1 );
00417 offset = h_tof_p_final_offset[pid][idx][bin_wgt]->Interpolate( bg, cost );
00418 sigma = h_tof_p_final_sigma[pid][idx][bin_wgt]-> Interpolate( bg, cost );
00419 m_tof_chi[i] = (t[4] - offset) / sigma;
00420 }
00421 else
00422 {
00423 t[4] /= h_tof_m_wgt[pid][idx][bin_wgt][4]->GetBinContent( bin_bg+1, bin_cost+1 );
00424 offset = h_tof_m_final_offset[pid][idx][bin_wgt]->Interpolate( bg, cost );
00425 sigma = h_tof_m_final_sigma[pid][idx][bin_wgt]-> Interpolate( bg, cost );
00426 m_tof_chi[i] = (t[4] - offset) / sigma;
00427 }
00428 }
00429 }
00430 }
00431
00432 void SimplePIDSvc::tofEndcapCorrection()
00433 {
00434 const double EPS = 1e-4;
00435 const double BG_LOW = 0.30;
00436 const double BG_UP = 7.40;
00437 const double Q_LOW = 0.;
00438 const double Q_UP = 6000.;
00439 const double COST_EAST_LOW = 0.720;
00440 const double COST_EAST_UP = 0.930;
00441 const double COST_WEST_LOW = -0.930;
00442 const double COST_WEST_UP = -0.720;
00443 const double P_LOW = 0.2;
00444 const double P_UP = 1.3;
00445
00446 int idx = getRunIdx(m_run);
00447
00448 if (idx != -1)
00449 {
00450 for (unsigned int i = 0; i < 4; i++)
00451 {
00452 int pid;
00453 double bg;
00454 if (i == 0)
00455 {
00456 bg = max(P_LOW+EPS, min(P_UP-EPS, m_p[i]));
00457 pid = 0;
00458 }
00459 else if (i == 2 || i == 3)
00460 {
00461 bg = max(BG_LOW+EPS, min(BG_UP-EPS, m_betagamma[i]));
00462 pid = 1;
00463 }
00464 else
00465 {
00466 continue;
00467 }
00468
00469 int flag;
00470 double cost = m_cost[i];
00471 int charge = m_charge[i];
00472 double t = m_tof_dt[7][i];
00473 double q = m_tof_ph[7];
00474 double off_q, off_bg, off_cost;
00475 double sg_q, sg_bg, sg_cost;
00476 if (cost > 0)
00477 {
00478 flag = 0;
00479 cost = max(COST_EAST_LOW+EPS, min(COST_EAST_UP-EPS, cost));
00480 }
00481 else
00482 {
00483 flag = 1;
00484 cost = max(COST_WEST_LOW+EPS, min(COST_WEST_UP-EPS, cost));
00485 }
00486 q = max(Q_LOW+EPS, min(Q_UP-EPS, q));
00487
00488
00489 if (charge == 1)
00490 {
00491 off_q = h_tofec_p_q_offset[pid][idx][flag] ->Interpolate( q );
00492 sg_q = h_tofec_p_q_sigma[pid][idx][flag] ->Interpolate( q );
00493 off_bg = h_tofec_p_bg_offset[pid][idx][flag] ->Interpolate( bg );
00494 sg_bg = h_tofec_p_bg_sigma[pid][idx][flag] ->Interpolate( bg );
00495 off_cost = h_tofec_p_cost_offset[pid][idx][flag]->Interpolate( cost );
00496 sg_cost = h_tofec_p_cost_sigma[pid][idx][flag] ->Interpolate( cost );
00497 m_tof_chi[i] = (((t - off_q) / sg_q - off_bg) / sg_bg - off_cost) / sg_cost;
00498 }
00499 else
00500 {
00501 off_q = h_tofec_m_q_offset[pid][idx][flag] ->Interpolate( q );
00502 sg_q = h_tofec_m_q_sigma[pid][idx][flag] ->Interpolate( q );
00503 off_bg = h_tofec_m_bg_offset[pid][idx][flag] ->Interpolate( bg );
00504 sg_bg = h_tofec_m_bg_sigma[pid][idx][flag] ->Interpolate( bg );
00505 off_cost = h_tofec_m_cost_offset[pid][idx][flag]->Interpolate( cost );
00506 sg_cost = h_tofec_m_cost_sigma[pid][idx][flag] ->Interpolate( cost );
00507 m_tof_chi[i] = (((t - off_q) / sg_q - off_bg) / sg_bg - off_cost) / sg_cost;
00508 }
00509 }
00510 }
00511 }
00512
00513 void SimplePIDSvc::loadDedxInfo(EvtRecTrack *track)
00514 {
00515 if (track->isMdcDedxValid())
00516 {
00517 RecMdcDedx* dedx_trk = track->mdcDedx();
00518 for (unsigned int i = 0; i < 5; i++)
00519 m_dedx_chi[i] = dedx_trk->chi(i);
00520 }
00521 else
00522 {
00523 for (unsigned int i = 0; i < 5; i++)
00524 m_dedx_chi[i] = -99;
00525 }
00526 }
00527
00528 void SimplePIDSvc::dedxCorrection()
00529 {
00530 int idx = getRunIdx(m_run);
00531 const double EPS = 1e-4;
00532 const double BG_LOW = 0.20;
00533 const double BG_UP = 7.40;
00534 const double COST_LOW = -0.93;
00535 const double COST_UP = 0.93;
00536 const double P_LOW = 0.2;
00537 const double P_UP = 1.3;
00538 if (idx != -1)
00539 {
00540 double offset, sigma;
00541 for (unsigned int i = 0; i < 4; i++)
00542 {
00543 double bg;
00544 int pid;
00545 if (i == 0)
00546 {
00547 bg = max(P_LOW+EPS, min(P_UP-EPS, m_p[i]));
00548 pid = 0;
00549 }
00550 else if (i == 2 || i == 3)
00551 {
00552 bg = max(BG_LOW+EPS, min(BG_UP-EPS, m_betagamma[i]));
00553 pid = 1;
00554 }
00555 else
00556 {
00557 continue;
00558 }
00559 double cost = m_cost[i];
00560 double charge = m_charge[i];
00561 cost = max(COST_LOW+EPS, min(COST_UP-EPS, cost));
00562 if (charge == 1)
00563 {
00564 offset = h_dedx_p_offset[pid][idx]->Interpolate( bg, cost );
00565 sigma = h_dedx_p_sigma[pid][idx] ->Interpolate( bg, cost );
00566 m_dedx_chi[i] = (m_dedx_chi[i] - offset) / sigma;
00567 }
00568 else
00569 {
00570 offset = h_dedx_m_offset[pid][idx]->Interpolate( bg, cost );
00571 sigma = h_dedx_m_sigma[pid][idx] ->Interpolate( bg, cost );
00572 m_dedx_chi[i] = (m_dedx_chi[i] - offset) / sigma;
00573 }
00574 }
00575 }
00576 }
00577
00578 void SimplePIDSvc::loadHistogram()
00579 {
00580 string path = getenv("SIMPLEPIDSVCROOT");
00581 vector<string> filename;
00582 for (unsigned int idx = 0; idx < 2; idx++)
00583 {
00584 const char *dir;
00585 if (idx == 0)
00586 dir = "electron";
00587 else if (idx == 1)
00588 dir = "kpi";
00589 else
00590 {
00591 cout << "Boundary Error! " << endl;
00592 exit(1);
00593 }
00594
00595
00596 filename.clear();
00597 filename.push_back( path + Form("/share/%s/dedx/dedx_d10.root", dir) );
00598 filename.push_back( path + Form("/share/%s/dedx/dedx_d11.root", dir) );
00599 filename.push_back( path + Form("/share/%s/dedx/dedx_m10.root", dir) );
00600 filename.push_back( path + Form("/share/%s/dedx/dedx_m11.root", dir) );
00601 for (unsigned int i = 0; i < filename.size(); i++)
00602 {
00603 f_dedx[idx][i] = new TFile(filename[i].c_str(), "READ");
00604 const char *name;
00605 if (i == 0)
00606 name = "d10";
00607 else if (i == 1)
00608 name = "d11";
00609 else if (i == 2)
00610 name = "m10";
00611 else if (i == 3)
00612 name = "m11";
00613 else
00614 {
00615 cout << "Boundary Error! " << endl;
00616 exit(1);
00617 }
00618 h_dedx_p_offset[idx][i] = (TH2D*)f_dedx[idx][i]->Get( Form("h_dedx_p_offset_%s", name) );
00619 h_dedx_p_sigma[idx][i] = (TH2D*)f_dedx[idx][i]->Get( Form("h_dedx_p_sigma_%s" , name) );
00620 h_dedx_m_offset[idx][i] = (TH2D*)f_dedx[idx][i]->Get( Form("h_dedx_m_offset_%s", name) );
00621 h_dedx_m_sigma[idx][i] = (TH2D*)f_dedx[idx][i]->Get( Form("h_dedx_m_sigma_%s" , name) );
00622 }
00623
00624 filename.clear();
00625 filename.push_back( path + Form("/share/%s/tof_barrel/tof_q_d10.root", dir) );
00626 filename.push_back( path + Form("/share/%s/tof_barrel/tof_q_d11.root", dir) );
00627 filename.push_back( path + Form("/share/%s/tof_barrel/tof_q_m10.root", dir) );
00628 filename.push_back( path + Form("/share/%s/tof_barrel/tof_q_m11.root", dir) );
00629 for (unsigned int i = 0; i < filename.size(); i++)
00630 {
00631 f_tof_q[idx][i] = new TFile(filename[i].c_str(), "READ");
00632 const char *name;
00633 if (i == 0)
00634 name = "d10";
00635 else if (i == 1)
00636 name = "d11";
00637 else if (i == 2)
00638 name = "m10";
00639 else if (i == 3)
00640 name = "m11";
00641 else
00642 {
00643 cout << "Boundary Error! " << endl;
00644 exit(1);
00645 }
00646 for (unsigned int j = 0; j < 4; j++)
00647 {
00648 h_tof_p_q_offset[idx][i][j] = (TH1D*)f_tof_q[idx][i]->Get( Form("h_tof_p_q_offset_%s_%d", name, j) );
00649 h_tof_m_q_offset[idx][i][j] = (TH1D*)f_tof_q[idx][i]->Get( Form("h_tof_m_q_offset_%s_%d", name, j) );
00650 h_tof_p_q_sigma[idx][i][j] = (TH1D*)f_tof_q[idx][i]->Get( Form("h_tof_p_q_sigma_%s_%d" , name, j) );
00651 h_tof_m_q_sigma[idx][i][j] = (TH1D*)f_tof_q[idx][i]->Get( Form("h_tof_m_q_sigma_%s_%d" , name, j) );
00652 }
00653 }
00654
00655 filename.clear();
00656 filename.push_back( path + Form("/share/%s/tof_barrel/tof_bg_cost_d10.root", dir) );
00657 filename.push_back( path + Form("/share/%s/tof_barrel/tof_bg_cost_d11.root", dir) );
00658 filename.push_back( path + Form("/share/%s/tof_barrel/tof_bg_cost_m10.root", dir) );
00659 filename.push_back( path + Form("/share/%s/tof_barrel/tof_bg_cost_m11.root", dir) );
00660 for (unsigned int i = 0; i < filename.size(); i++)
00661 {
00662 f_tof_bgcost[idx][i] = new TFile(filename[i].c_str(), "READ");
00663 const char *name;
00664 if (i == 0)
00665 name = "d10";
00666 else if (i == 1)
00667 name = "d11";
00668 else if (i == 2)
00669 name = "m10";
00670 else if (i == 3)
00671 name = "m11";
00672 else
00673 {
00674 cout << "Boundary Error! " << endl;
00675 exit(1);
00676 }
00677 for (unsigned int j = 0; j < 4; j++)
00678 {
00679 h_tof_p_bgcost_offset[idx][i][j] = (TH2D*)f_tof_bgcost[idx][i]->Get( Form("h_tof_p_bgcost_offset_%s_%d", name, j) );
00680 h_tof_m_bgcost_offset[idx][i][j] = (TH2D*)f_tof_bgcost[idx][i]->Get( Form("h_tof_m_bgcost_offset_%s_%d", name, j) );
00681 h_tof_p_bgcost_sigma[idx][i][j] = (TH2D*)f_tof_bgcost[idx][i]->Get( Form("h_tof_p_bgcost_sigma_%s_%d" , name, j) );
00682 h_tof_m_bgcost_sigma[idx][i][j] = (TH2D*)f_tof_bgcost[idx][i]->Get( Form("h_tof_m_bgcost_sigma_%s_%d" , name, j) );
00683 }
00684 }
00685
00686 filename.clear();
00687 filename.push_back( path + Form("/share/%s/tof_barrel/tof_wgt_d10.root", dir) );
00688 filename.push_back( path + Form("/share/%s/tof_barrel/tof_wgt_d11.root", dir) );
00689 filename.push_back( path + Form("/share/%s/tof_barrel/tof_wgt_m10.root", dir) );
00690 filename.push_back( path + Form("/share/%s/tof_barrel/tof_wgt_m11.root", dir) );
00691 for (unsigned int i = 0; i < filename.size(); i++)
00692 {
00693 f_tof_wgt[idx][i] = new TFile(filename[i].c_str(), "READ");
00694 const char *name;
00695 if (i == 0)
00696 name = "d10";
00697 else if (i == 1)
00698 name = "d11";
00699 else if (i == 2)
00700 name = "m10";
00701 else if (i == 3)
00702 name = "m11";
00703 else
00704 {
00705 cout << "Boundary Error! " << endl;
00706 exit(1);
00707 }
00708 for (unsigned int j = 0; j < 15; j++)
00709 {
00710 for (unsigned int k = 0; k < 5; k++)
00711 {
00712 h_tof_p_wgt[idx][i][j][k] = (TH2D*)f_tof_wgt[idx][i]->Get( Form("h_tof_p_wgt_%s_%d_%d", name, j, k) );
00713 h_tof_m_wgt[idx][i][j][k] = (TH2D*)f_tof_wgt[idx][i]->Get( Form("h_tof_m_wgt_%s_%d_%d", name, j, k) );
00714 }
00715 }
00716 }
00717
00718 filename.clear();
00719 filename.push_back( path + Form("/share/%s/tof_barrel/tof_final_d10.root", dir) );
00720 filename.push_back( path + Form("/share/%s/tof_barrel/tof_final_d11.root", dir) );
00721 filename.push_back( path + Form("/share/%s/tof_barrel/tof_final_m10.root", dir) );
00722 filename.push_back( path + Form("/share/%s/tof_barrel/tof_final_m11.root", dir) );
00723 for (unsigned int i = 0; i < filename.size(); i++)
00724 {
00725 f_tof_final[idx][i] = new TFile(filename[i].c_str(), "READ");
00726 const char *name;
00727 if (i == 0)
00728 name = "d10";
00729 else if (i == 1)
00730 name = "d11";
00731 else if (i == 2)
00732 name = "m10";
00733 else if (i == 3)
00734 name = "m11";
00735 else
00736 {
00737 cout << "Boundary Error! " << endl;
00738 exit(1);
00739 }
00740 for (unsigned int j = 0; j < 15; j++)
00741 {
00742 h_tof_p_final_offset[idx][i][j] = (TH2D*)f_tof_final[idx][i]->Get( Form("h_tof_p_final_offset_%s_%d", name, j) );
00743 h_tof_m_final_offset[idx][i][j] = (TH2D*)f_tof_final[idx][i]->Get( Form("h_tof_m_final_offset_%s_%d", name, j) );
00744 h_tof_p_final_sigma[idx][i][j] = (TH2D*)f_tof_final[idx][i]->Get( Form("h_tof_p_final_sigma_%s_%d" , name, j) );
00745 h_tof_m_final_sigma[idx][i][j] = (TH2D*)f_tof_final[idx][i]->Get( Form("h_tof_m_final_sigma_%s_%d" , name, j) );
00746 }
00747 }
00748
00749 filename.clear();
00750 filename.push_back( path + Form("/share/%s/tof_endcap/tofec_q_d10.root", dir) );
00751 filename.push_back( path + Form("/share/%s/tof_endcap/tofec_q_d11.root", dir) );
00752 filename.push_back( path + Form("/share/%s/tof_endcap/tofec_q_m10.root", dir) );
00753 filename.push_back( path + Form("/share/%s/tof_endcap/tofec_q_m11.root", dir) );
00754 for (unsigned int i = 0; i < filename.size(); i++)
00755 {
00756 f_tofec_q[idx][i] = new TFile(filename[i].c_str(), "READ");
00757 const char *name;
00758 if (i == 0)
00759 name = "d10";
00760 else if (i == 1)
00761 name = "d11";
00762 else if (i == 2)
00763 name = "m10";
00764 else if (i == 3)
00765 name = "m11";
00766 else
00767 {
00768 cout << "Boundary Error! " << endl;
00769 exit(1);
00770 }
00771 for (unsigned int j = 0; j < 2; j++)
00772 {
00773 h_tofec_p_q_offset[idx][i][j] = (TH1D*)f_tofec_q[idx][i]->Get( Form("h_tofec_p_q_offset_%s_%d", name, j) );
00774 h_tofec_m_q_offset[idx][i][j] = (TH1D*)f_tofec_q[idx][i]->Get( Form("h_tofec_m_q_offset_%s_%d", name, j) );
00775 h_tofec_p_q_sigma[idx][i][j] = (TH1D*)f_tofec_q[idx][i]->Get( Form("h_tofec_p_q_sigma_%s_%d" , name, j) );
00776 h_tofec_m_q_sigma[idx][i][j] = (TH1D*)f_tofec_q[idx][i]->Get( Form("h_tofec_m_q_sigma_%s_%d" , name, j) );
00777 }
00778 }
00779
00780 filename.clear();
00781 filename.push_back( path + Form("/share/%s/tof_endcap/tofec_bg_d10.root", dir) );
00782 filename.push_back( path + Form("/share/%s/tof_endcap/tofec_bg_d11.root", dir) );
00783 filename.push_back( path + Form("/share/%s/tof_endcap/tofec_bg_m10.root", dir) );
00784 filename.push_back( path + Form("/share/%s/tof_endcap/tofec_bg_m11.root", dir) );
00785 for (unsigned int i = 0; i < filename.size(); i++)
00786 {
00787 f_tofec_bg[idx][i] = new TFile(filename[i].c_str(), "READ");
00788 const char *name;
00789 if (i == 0)
00790 name = "d10";
00791 else if (i == 1)
00792 name = "d11";
00793 else if (i == 2)
00794 name = "m10";
00795 else if (i == 3)
00796 name = "m11";
00797 else
00798 {
00799 cout << "Boundary Error! " << endl;
00800 exit(1);
00801 }
00802 for (unsigned int j = 0; j < 2; j++)
00803 {
00804 h_tofec_p_bg_offset[idx][i][j] = (TH1D*)f_tofec_bg[idx][i]->Get( Form("h_tofec_p_bg_offset_%s_%d", name, j) );
00805 h_tofec_m_bg_offset[idx][i][j] = (TH1D*)f_tofec_bg[idx][i]->Get( Form("h_tofec_m_bg_offset_%s_%d", name, j) );
00806 h_tofec_p_bg_sigma[idx][i][j] = (TH1D*)f_tofec_bg[idx][i]->Get( Form("h_tofec_p_bg_sigma_%s_%d" , name, j) );
00807 h_tofec_m_bg_sigma[idx][i][j] = (TH1D*)f_tofec_bg[idx][i]->Get( Form("h_tofec_m_bg_sigma_%s_%d" , name, j) );
00808 }
00809 }
00810
00811 filename.clear();
00812 filename.push_back( path + Form("/share/%s/tof_endcap/tofec_cost_d10.root", dir) );
00813 filename.push_back( path + Form("/share/%s/tof_endcap/tofec_cost_d11.root", dir) );
00814 filename.push_back( path + Form("/share/%s/tof_endcap/tofec_cost_m10.root", dir) );
00815 filename.push_back( path + Form("/share/%s/tof_endcap/tofec_cost_m11.root", dir) );
00816 for (unsigned int i = 0; i < filename.size(); i++)
00817 {
00818 f_tofec_cost[idx][i] = new TFile(filename[i].c_str(), "READ");
00819 const char *name;
00820 if (i == 0)
00821 name = "d10";
00822 else if (i == 1)
00823 name = "d11";
00824 else if (i == 2)
00825 name = "m10";
00826 else if (i == 3)
00827 name = "m11";
00828 else
00829 {
00830 cout << "Boundary Error! " << endl;
00831 exit(1);
00832 }
00833 for (unsigned int j = 0; j < 2; j++)
00834 {
00835 h_tofec_p_cost_offset[idx][i][j] = (TH1D*)f_tofec_cost[idx][i]->Get( Form("h_tofec_p_cost_offset_%s_%d", name, j) );
00836 h_tofec_m_cost_offset[idx][i][j] = (TH1D*)f_tofec_cost[idx][i]->Get( Form("h_tofec_m_cost_offset_%s_%d", name, j) );
00837 h_tofec_p_cost_sigma[idx][i][j] = (TH1D*)f_tofec_cost[idx][i]->Get( Form("h_tofec_p_cost_sigma_%s_%d" , name, j) );
00838 h_tofec_m_cost_sigma[idx][i][j] = (TH1D*)f_tofec_cost[idx][i]->Get( Form("h_tofec_m_cost_sigma_%s_%d" , name, j) );
00839 }
00840 }
00841 }
00842 for (unsigned int idx = 0; idx < 3; idx++)
00843 {
00844 const char *dir;
00845 if (idx == 0)
00846 dir = "electron/emc";
00847 else if (idx == 1)
00848 dir = "kpi/emc_pion";
00849 else if (idx == 2)
00850 dir = "kpi/emc_kaon";
00851 else
00852 {
00853 cout << "Boundary Error! " << endl;
00854 exit(1);
00855 }
00856
00857 filename.clear();
00858 filename.push_back( path + Form("/share/%s/emc_d10.root", dir) );
00859 filename.push_back( path + Form("/share/%s/emc_d11.root", dir) );
00860 filename.push_back( path + Form("/share/%s/emc_m10.root", dir) );
00861 filename.push_back( path + Form("/share/%s/emc_m11.root", dir) );
00862 for (unsigned int i = 0; i < filename.size(); i++)
00863 {
00864 f_emc[idx][i] = new TFile(filename[i].c_str(), "READ");
00865 const char *name;
00866 if (i == 0)
00867 name = "d10";
00868 else if (i == 1)
00869 name = "d11";
00870 else if (i == 2)
00871 name = "m10";
00872 else if (i == 3)
00873 name = "m11";
00874 else
00875 {
00876 cout << "Boundary Error! " << endl;
00877 exit(1);
00878 }
00879 for (unsigned int j = 0; j < 15; j++)
00880 {
00881 for (unsigned int k = 0; k < 25; k++)
00882 {
00883 h_emc_ep[idx][i][j][k] = (TH1D*)f_emc[idx][i]->Get( Form("h_ep_%s_%d_%d", name, j, k) );
00884 h_emc_e35[idx][i][j][k] = (TH1D*)f_emc[idx][i]->Get( Form("h_e35_%s_%d_%d", name, j, k) );
00885 }
00886 }
00887 }
00888 }
00889 cout << "Successfully Return from Loading Initializations by package SimplePIDSvc ... " << endl;
00890 }
00891
00892 int SimplePIDSvc::findBin(double *a, int length, double value)
00893 {
00894 for (int i = 0; i < length; i++)
00895 {
00896 if (value > a[i] && value <= a[i+1])
00897 {
00898 return i;
00899 }
00900 }
00901 if (value < a[0])
00902 {
00903 return 0;
00904 }
00905 else
00906 {
00907 return length;
00908 }
00909 }
00910
00911 double SimplePIDSvc::getChi2(int i)
00912 {
00913 return pow(m_dedx_chi[i], 2) + pow(m_tof_chi[i], 2);
00914 }
00915
00916 void SimplePIDSvc::loadEMCInfo(EvtRecTrack *track)
00917 {
00918
00919 for (unsigned int i = 0; i < 5; i++)
00920 {
00921 m_emc_eop[i] = -99.;
00922 m_emc_likelihood[i] = -99.;
00923 }
00924 m_emc_e = -99.;
00925 m_emc_e13 = -99.;
00926 m_emc_e35 = -99.;
00927 m_emc_sec = -99.;
00928 m_emc_lat = -99.;
00929 m_lh_electron = -99.;
00930
00931 if (!track->isEmcShowerValid()) return;
00932
00933 RecEmcShower* emc_trk = track->emcShower();
00934 m_emc_e = emc_trk->energy();
00935 for (unsigned int i = 0; i < 5; i++)
00936 {
00937 m_emc_eop[i] = m_emc_e / fabs(m_p[i]);
00938 }
00939 double eseed = emc_trk->eSeed();
00940 double e3 = emc_trk->e3x3();
00941 double e5 = emc_trk->e5x5();
00942 m_emc_sec = emc_trk->secondMoment() / 1000.;
00943 m_emc_lat = emc_trk->latMoment();
00944 if (e3 != 0)
00945 {
00946 m_emc_e13 = eseed / e3;
00947 }
00948 if (e5 != 0)
00949 {
00950 m_emc_e35 = e3 / e5;
00951 }
00952 }
00953
00954 bool SimplePIDSvc::calEMCLikelihood()
00955 {
00956 if (m_emc_eop[0] < 0)
00957 return false;
00958
00959 int idx = getRunIdx(m_run);
00960 const Int_t BIN_P = 15;
00961 const Int_t BIN_COST = 25;
00962 const Int_t BIN_PID = 3;
00963 const double EPS = 1e-4;
00964
00965 double P[BIN_PID][BIN_P + 1] = {
00966 {0.20, 0.47, 0.56, 0.65, 0.72, 0.79, 0.86, 0.92, 0.98, 1.03, 1.08, 1.13, 1.17, 1.22, 1.26, 1.30},
00967 {0.20, 0.26, 0.31, 0.35, 0.39, 0.42, 0.46, 0.49, 0.53, 0.57, 0.62, 0.67, 0.73, 0.80, 0.88, 1.05},
00968 {0.20, 0.33, 0.39, 0.43, 0.48, 0.52, 0.56, 0.61, 0.67, 0.73, 0.76, 0.81, 0.85, 0.90, 0.96, 1.05}, };
00969 double COST[BIN_PID][BIN_COST + 1] = {
00970 {-0.930, -0.910, -0.905, -0.897, -0.890, -0.881, -0.871, -0.858, -0.775, -0.732, -0.669, -0.561, -0.330, 0.199, 0.515, 0.645, 0.718, 0.766, 0.804, 0.870, 0.882, 0.891, 0.898, 0.906, 0.913, 0.930},
00971 {-0.930, -0.810, -0.728, -0.648, -0.574, -0.501, -0.431, -0.364, -0.295, -0.228, -0.161, -0.096, -0.031, 0.035, 0.100, 0.167, 0.234, 0.301, 0.370, 0.439, 0.510, 0.580, 0.655, 0.733, 0.813, 0.930},
00972 {-0.930, -0.804, -0.721, -0.643, -0.568, -0.497, -0.429, -0.362, -0.293, -0.228, -0.161, -0.096, -0.029, 0.035, 0.100, 0.166, 0.233, 0.298, 0.365, 0.432, 0.500, 0.571, 0.644, 0.722, 0.805, 0.930}, };
00973
00974 double vp, vcost;
00975 int pid;
00976 int bin_p, bin_cost;
00977 for (unsigned int i = 0; i < 4; i++)
00978 {
00979
00980 if (i == 0)
00981 pid = 0;
00982 else if (i == 2)
00983 pid = 1;
00984 else if (i == 3)
00985 pid = 2;
00986 else
00987 continue;
00988
00989 vp = max(P[pid][0]+EPS, min(P[pid][BIN_P]-EPS, m_p[i]));
00990 vcost = max(COST[pid][0]+EPS, min(COST[pid][BIN_COST]-EPS, m_cost[i]));
00991 bin_p = findBin(P[pid], BIN_P, vp);
00992 bin_cost = findBin(COST[pid], BIN_COST, vcost);
00993
00994 m_emc_likelihood[i] = h_emc_ep[pid][idx][bin_p][bin_cost]->Interpolate(m_emc_eop[i]) * h_emc_e35[pid][idx][bin_p][bin_cost]->Interpolate(m_emc_e35);
00995 }
00996 double a = m_prob[0] > 0 ? m_prob[0] : 0;
00997 double b = m_prob[2] > 0 ? m_prob[2] : 0;
00998 double c = m_prob[3] > 0 ? m_prob[3] : 0;
00999 double sum = a * m_emc_likelihood[0] + b * m_emc_likelihood[2] + c * m_emc_likelihood[3];
01000
01001 if (sum > 0 && m_prob[0] > 0)
01002 {
01003 m_lh_electron = m_prob[0] * m_emc_likelihood[0] / sum;
01004 return true;
01005 }
01006 else
01007 {
01008 return false;
01009 }
01010 }
01011
01012 bool SimplePIDSvc::ispion()
01013 {
01014 if (m_prob[2] > 0.00 && m_prob[2] > m_prob[3])
01015 return true;
01016 else
01017 return false;
01018 }
01019
01020 bool SimplePIDSvc::iskaon()
01021 {
01022 if (m_prob[3] > 0.00 && m_prob[3] > m_prob[2])
01023 return true;
01024 else
01025 return false;
01026 }
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047 bool SimplePIDSvc::iselectron(bool emc)
01048 {
01049 if (!emc)
01050 {
01051 if (m_prob[0] > 0 && m_prob[0] > m_prob[2] && m_prob[0] > m_prob[3])
01052 return true;
01053 else
01054 return false;
01055 }
01056 else
01057 {
01058 if (calEMCLikelihood())
01059 {
01060 if (m_lh_electron > m_eid_ratio)
01061 return true;
01062 else
01063 return false;
01064 }
01065 else
01066 {
01067 if (m_prob[0] > 0 && m_prob[0] > m_prob[2] && m_prob[0] > m_prob[3])
01068 return true;
01069 else
01070 return false;
01071 }
01072 }
01073 }