00001
00002
00003
00004 #include <vector>
00005
00006
00007 #include "TClonesArray.h"
00008
00009
00010 #include "Conventions/BeamType.h"
00011 #include "DataUtil/infid.h"
00012 #include "MCNtuple/NtpMCStdHep.h"
00013 #include "MCNtuple/NtpMCTruth.h"
00014 #include "MCReweight/NeugenWeightCalculator.h"
00015 #include "MCReweight/ReweightHelpers.h"
00016 #include "MessageService/MsgService.h"
00017 #include "MinosObjectMap/MomNavigator.h"
00018 #include "StandardNtuple/NtpStRecord.h"
00019 #include "TruthHelperNtuple/NtpTHEvent.h"
00020 #include "TruthHelperNtuple/NtpTHShower.h"
00021 #include "TruthHelperNtuple/NtpTHTrack.h"
00022
00023
00024 #include "PhysicsNtuple/Default.h"
00025 #include "PhysicsNtuple/Factory.h"
00026 #include "FillTruth.h"
00027
00028 REGISTER_ANP_OBJECT(AlgStore,FillTruth)
00029
00030 CVSID("$Id: FillTruth.cxx,v 1.18 2008/03/10 19:58:06 rustem Exp $");
00031
00032 using namespace std;
00033
00034
00035 Anp::FillTruth::FillTruth()
00036 :fStdHep(true),
00037 fCheck(true),
00038 fHepKey(-1),
00039 fNTruth(0),
00040 fNStHep(0),
00041 fNRecoEvent(0),
00042 fNRecoTrack(0),
00043 fNRecoShower(0)
00044 {
00045 }
00046
00047
00048 Anp::FillTruth::~FillTruth()
00049 {
00050 cout << " Number of truths " << fNTruth << endl
00051 << " Number of stdheps " << fNStHep << endl
00052 << " Number of event truths " << fNRecoEvent << endl
00053 << " Number of track truths " << fNRecoTrack << endl
00054 << " Number of shower truths " << fNRecoShower << endl;
00055 }
00056
00057
00058 bool Anp::FillTruth::Run(Record &record, TObject *ptr)
00059 {
00060
00061
00062
00063
00064 NtpStRecord *ntprec = dynamic_cast<NtpStRecord *>(ptr);
00065 if(!ntprec)
00066 {
00067 const MomNavigator *mom = dynamic_cast<const MomNavigator *> (ptr);
00068 if(mom)
00069 {
00070 ntprec = dynamic_cast<NtpStRecord *>(mom -> GetFragment("NtpStRecord"));
00071 }
00072 else
00073 {
00074 MSG("FillAlg", Msg::kError) << "Failed to find MomNavigator pointer" << endl;
00075 return false;
00076 }
00077 }
00078
00079 if(!ntprec)
00080 {
00081 MSG("FillAlg", Msg::kError) << "Failed to find NtpStRecord pointer" << endl;
00082 return false;
00083 }
00084
00085
00086
00087
00088 if(ntprec -> GetVldContext() -> GetSimFlag() != SimFlag::kMC)
00089 {
00090 return true;
00091 }
00092
00093 const TClonesArray *stdhep_array = ntprec -> stdhep;
00094 if(!stdhep_array)
00095 {
00096 MSG("FillAlg", Msg::kWarning) << "TClonesArray of NtpMCStdHep doesn't exist" << endl;
00097 return true;
00098 }
00099
00100
00101
00102
00103 if(fStdHep)
00104 {
00105 FillStdHep(record, *stdhep_array);
00106 }
00107
00108 const TClonesArray *mc_array = ntprec -> mc;
00109 if(!mc_array)
00110 {
00111 MSG("FillAlg", Msg::kError) << "TClonesArray of NtpMCTruth doesn't exist" << endl;
00112 return false;
00113 }
00114
00115 if(!ntprec -> thevt || !ntprec -> thtrk || !ntprec -> thshw)
00116 {
00117 MSG("FillAlg", Msg::kError) << "One or more TClonesArray of NtpTH doesn't exist" << endl;
00118 return false;
00119 }
00120
00121 const vector<const NtpTHEvent *> thevt_vec = Anp::FillRecoTruth<NtpTHEvent> (ntprec -> thevt);
00122 const vector<const NtpTHTrack *> thtrk_vec = Anp::FillRecoTruth<NtpTHTrack> (ntprec -> thtrk);
00123 const vector<const NtpTHShower *> thshw_vec = Anp::FillRecoTruth<NtpTHShower>(ntprec -> thshw);
00124
00125 MSG("FillAlg", Msg::kDebug)
00126 << endl
00127 << " size of NtpMCTruth array = " << mc_array -> GetEntries() << endl
00128 << " size of NtpTHEvent array = " << thevt_vec.size() << endl
00129 << " size of NtpTHTrack array = " << thtrk_vec.size() << endl
00130 << " size of NtpMCStdHep array = " << stdhep_array -> GetEntries() << endl
00131 << " size of NtpTHShower array = " << thshw_vec.size() << endl;
00132
00133 const int nentries = mc_array -> GetEntries();
00134 for(int index = 0; index < nentries; ++index)
00135 {
00136 const NtpMCTruth *truth_ptr = dynamic_cast<const NtpMCTruth *>(mc_array -> At(index));
00137 if(!truth_ptr)
00138 {
00139 MSG("FillAlg", Msg::kWarning) << "No mc truth at " << index << endl;
00140 continue;
00141 }
00142 if(index != truth_ptr -> index)
00143 {
00144 MSG("FillAlg", Msg::kWarning) << "Wrong array index" << endl;
00145 continue;
00146 }
00147
00148 Truth truth = FillTruth::Fill(*truth_ptr);
00149
00150 FillTruth::Fill(truth, thevt_vec);
00151 FillTruth::Fill(truth, thtrk_vec);
00152 FillTruth::Fill(truth, thshw_vec);
00153
00154
00155
00156
00157 MCEventInfo mcinfo;
00158 ReweightHelpers::MCEventInfoFilla(&mcinfo, ntprec, truth.TruthIndex());
00159
00160 truth.init_state = mcinfo.initial_state;
00161 truth.nucleus = mcinfo.nucleus;
00162 truth.had_fs = mcinfo.had_fs;
00163
00164
00165
00166
00167 truth.isfid = infid(ntprec -> GetVldContext() -> GetDetector(), SimFlag::kMC,
00168 truth.VtxX(), truth.VtxY(), truth.VtxZ());
00169
00170 record.Add(truth);
00171 }
00172
00173 MSG("FillAlg", Msg::kDebug)
00174 << endl
00175 << " size of Truth vector = " << record.GetNTruths() << endl
00176 << " size of StdHep vector = " << record.GetNStdHeps() << endl;
00177
00178 if(fCheck && !IsConsistent(record))
00179 {
00180 return false;
00181 }
00182
00183
00184
00185
00186 if(fHepKey >= 0)
00187 {
00188 for(TrackIterator itrack = record.TrackBegIterator(); itrack != record.TrackEndIterator(); ++itrack)
00189 {
00190 StdHepIter ihep = record.FindStdHep(*itrack);
00191 if(ihep != record.StdHepEnd())
00192 {
00193 itrack -> Add(fHepKey, ihep -> GetIdHEP());
00194 }
00195 else
00196 {
00197 MSG("FillAlg", Msg::kWarning) << "Failed to find StdHep block" << endl;
00198 }
00199 }
00200 }
00201
00202 return true;
00203 }
00204
00205
00206 void Anp::FillTruth::Config(const Registry ®)
00207 {
00208 Anp::Read(reg, "FillTruthCheck", fCheck);
00209 Anp::Read(reg, "FillTruthStdHep", fStdHep);
00210
00211 if(reg.KeyExists("PrintConfig"))
00212 {
00213 cout << "FillTruth::Config" << endl
00214 << " StdHep = " << fStdHep << endl
00215 << " Check = " << fCheck << endl
00216 << " HepKey = " << fHepKey << endl;
00217 }
00218 }
00219
00220
00221 const Anp::Truth Anp::FillTruth::Fill(const NtpMCTruth &ntpmc) const
00222 {
00223
00224
00225
00226
00227
00228 Truth truth;
00229
00230 truth.index = ntpmc.index;
00231 truth.stdhep[0] = ntpmc.stdhep[0];
00232 truth.stdhep[1] = ntpmc.stdhep[1];
00233 truth.inu = ntpmc.inu;
00234 truth.inunoosc = ntpmc.inunoosc;
00235 truth.itg = ntpmc.itg;
00236 truth.iboson = ntpmc.iboson;
00237 truth.iresonance = ntpmc.iresonance;
00238 truth.iaction = ntpmc.iaction;
00239 truth.istruckq = ntpmc.istruckq;
00240 truth.iflags = ntpmc.iflags;
00241 truth.ndigu = ntpmc.ndigu;
00242 truth.ndigv = ntpmc.ndigv;
00243 truth.tphu = ntpmc.tphu;
00244 truth.tphv = ntpmc.tphv;
00245 truth.a = ntpmc.a;
00246 truth.z = ntpmc.z;
00247 truth.sigma = ntpmc.sigma;
00248 truth.sigmadiff = ntpmc.sigmadiff;
00249 truth.x = ntpmc.x;
00250 truth.y = ntpmc.y;
00251 truth.q2 = ntpmc.q2;
00252 truth.w2 = ntpmc.w2;
00253 truth.emfrac = ntpmc.emfrac;
00254 truth.vtxx = ntpmc.vtxx;
00255 truth.vtxy = ntpmc.vtxy;
00256 truth.vtxz = ntpmc.vtxz;
00257
00258 for(short i = 0; i < 4; ++i)
00259 {
00260 truth.p4neu[i] = ntpmc.p4neu[i];
00261 truth.p4neunoosc[i] = ntpmc.p4neunoosc[i];
00262 truth.p4shw[i] = ntpmc.p4shw[i];
00263 truth.p4tgt[i] = ntpmc.p4tgt[i];
00264 }
00265
00266 truth.flux.fluxrun = ntpmc.flux.fluxrun;
00267 truth.flux.fluxevtno = ntpmc.flux.fluxevtno;
00268 truth.flux.ndecay = ntpmc.flux.ndecay;
00269 truth.flux.ntype = ntpmc.flux.ntype;
00270 truth.flux.ptype = ntpmc.flux.ptype;
00271 truth.flux.tptype = ntpmc.flux.tptype;
00272 truth.flux.tgen = ntpmc.flux.tgen;
00273
00274 truth.flux.ndxdznear = ntpmc.flux.ndxdznear;
00275 truth.flux.ndydznear = ntpmc.flux.ndydznear;
00276 truth.flux.nenergynear = ntpmc.flux.nenergynear;
00277 truth.flux.nwtnear = ntpmc.flux.nwtnear;
00278 truth.flux.ndxdzfar = ntpmc.flux.ndxdzfar;
00279 truth.flux.ndydzfar = ntpmc.flux.ndydzfar;
00280 truth.flux.nenergyfar = ntpmc.flux.nenergyfar;
00281 truth.flux.nwtfar = ntpmc.flux.nwtfar;
00282 truth.flux.vx = ntpmc.flux.vx;
00283 truth.flux.vy = ntpmc.flux.vy;
00284 truth.flux.vz = ntpmc.flux.vz;
00285 truth.flux.pdpx = ntpmc.flux.pdpx;
00286 truth.flux.pdpy = ntpmc.flux.pdpy;
00287 truth.flux.pdpz = ntpmc.flux.pdpz;
00288 truth.flux.ppdxdz = ntpmc.flux.ppdxdz;
00289 truth.flux.ppdydz = ntpmc.flux.ppdydz;
00290 truth.flux.pppz = ntpmc.flux.pppz;
00291 truth.flux.ppenergy = ntpmc.flux.ppenergy;
00292 truth.flux.ppvx = ntpmc.flux.ppvx;
00293 truth.flux.ppvy = ntpmc.flux.ppvy;
00294 truth.flux.ppvz = ntpmc.flux.ppvz;
00295 truth.flux.necm = ntpmc.flux.necm;
00296 truth.flux.nimpwt = ntpmc.flux.nimpwt;
00297 truth.flux.tvx = ntpmc.flux.tvx;
00298 truth.flux.tvy = ntpmc.flux.tvy;
00299 truth.flux.tvz = ntpmc.flux.tvz;
00300 truth.flux.tpx = ntpmc.flux.tpx;
00301 truth.flux.tpy = ntpmc.flux.tpy;
00302 truth.flux.tpz = ntpmc.flux.tpz;
00303
00304 ++fNTruth;
00305
00306 return truth;
00307 }
00308
00309 void Anp::FillTruth::FillStdHep(Record &record, const TClonesArray &array) const
00310 {
00311
00312
00313
00314
00315 const int nstdhep = array.GetEntries();
00316
00317
00318
00319 std::vector<Anp::StdHep> &svec = record.GetStdHep();
00320 svec.clear();
00321
00322
00323 svec.insert(svec.begin(), nstdhep, Anp::StdHep());
00324
00325 for(int index = 0; index < nstdhep; ++index)
00326 {
00327 const NtpMCStdHep *stdhep_ptr = dynamic_cast<const NtpMCStdHep *>(array.At(index));
00328 if(!stdhep_ptr)
00329 {
00330 MSG("FillAlg", Msg::kError) << "No stdhep at " << index << " out of " << nstdhep << endl;
00331 continue;
00332 }
00333
00334 if(int(stdhep_ptr -> index) != index)
00335 {
00336 MSG("FillAlg", Msg::kError) << "Wrong StdHep index" << endl;
00337 continue;
00338 }
00339
00340 StdHep &stdhep = svec[index];
00341
00342 stdhep.index = stdhep_ptr -> index;
00343 stdhep.mc_index = stdhep_ptr -> mc;
00344 stdhep.parent[0] = stdhep_ptr -> parent[0];
00345 stdhep.parent[1] = stdhep_ptr -> parent[1];
00346 stdhep.child[0] = stdhep_ptr -> child[0];
00347 stdhep.child[1] = stdhep_ptr -> child[1];
00348 stdhep.IstHEP = stdhep_ptr -> IstHEP;
00349 stdhep.IdHEP = stdhep_ptr -> IdHEP;
00350 stdhep.mass = stdhep_ptr -> mass;
00351
00352 stdhep.p4[0] = stdhep_ptr -> p4[0];
00353 stdhep.p4[1] = stdhep_ptr -> p4[1];
00354 stdhep.p4[2] = stdhep_ptr -> p4[2];
00355 stdhep.p4[3] = stdhep_ptr -> p4[3];
00356
00357 stdhep.vtx[0] = stdhep_ptr -> vtx[0];
00358 stdhep.vtx[1] = stdhep_ptr -> vtx[1];
00359 stdhep.vtx[2] = stdhep_ptr -> vtx[2];
00360 stdhep.vtx[3] = stdhep_ptr -> vtx[3];
00361
00362 ++fNStHep;
00363 }
00364 }
00365
00366
00367 void Anp::FillTruth::Fill(Truth &truth, const vector<const NtpTHEvent *> &vec)
00368 {
00369
00370
00371
00372
00373 unsigned int count = 0;
00374
00375 for(vector<const NtpTHEvent *>::const_iterator it = vec.begin(); it != vec.end(); ++it)
00376 {
00377 const NtpTHEvent *th_event = *it;
00378
00379 if(th_event -> neumc != truth.TruthIndex() && !truth.IsChild(th_event -> neustdhep))
00380 {
00381 continue;
00382 }
00383
00384 const TruthReco truth_reco(TruthReco::kEvent,
00385 th_event -> index,
00386 th_event -> neumc,
00387 th_event -> neustdhep,
00388 th_event -> purity,
00389 th_event -> completeall,
00390 th_event -> completeslc);
00391
00392
00393
00394
00395 truth.fReco.push_back(truth_reco);
00396
00397 ++count;
00398 }
00399
00400 fNRecoEvent += count;
00401
00402 MSG("FillAlg", Msg::kDebug) << "MC truth record with index " << truth.TruthIndex()
00403 << " matches "<< count << " reconstructed events" << endl;
00404 }
00405
00406
00407 void Anp::FillTruth::Fill(Truth &truth, const vector<const NtpTHTrack *> &vec)
00408 {
00409
00410
00411
00412
00413 unsigned int count = 0;
00414
00415 for(vector<const NtpTHTrack *>::const_iterator it = vec.begin(); it != vec.end(); ++it)
00416 {
00417 const NtpTHTrack *th_track = *it;
00418
00419 if(th_track -> neumc != truth.TruthIndex() &&
00420 !truth.IsChild(th_track -> neustdhep) &&
00421 !truth.IsChild(th_track -> trkstdhep))
00422 {
00423 continue;
00424 }
00425
00426 const TruthReco truth_reco(TruthReco::kTrack,
00427 th_track -> index,
00428 th_track -> neumc,
00429 th_track -> trkstdhep,
00430 th_track -> purity,
00431 th_track -> completeall,
00432 th_track -> completeslc);
00433
00434
00435
00436
00437 truth.fReco.push_back(truth_reco);
00438
00439 ++count;
00440 }
00441
00442 fNRecoTrack += count;
00443
00444 MSG("FillAlg", Msg::kDebug) << "MC truth record with index " << truth.TruthIndex()
00445 << " matches "<< count << " reconstructed tracks" << endl;
00446 }
00447
00448
00449 void Anp::FillTruth::Fill(Truth &truth, const vector<const NtpTHShower *> &vec)
00450 {
00451
00452
00453
00454
00455 unsigned int count = 0;
00456
00457 for(vector<const NtpTHShower *>::const_iterator it = vec.begin(); it != vec.end(); ++it)
00458 {
00459 const NtpTHShower *th_shower = *it;
00460
00461 if(th_shower -> neumc != truth.TruthIndex() && !truth.IsChild(th_shower -> neustdhep))
00462 {
00463 continue;
00464 }
00465
00466 const TruthReco truth_reco(TruthReco::kShower,
00467 th_shower -> index,
00468 th_shower -> neumc,
00469 th_shower -> neustdhep,
00470 th_shower -> purity,
00471 th_shower -> completeall,
00472 th_shower -> completeslc);
00473
00474
00475
00476
00477 truth.fReco.push_back(truth_reco);
00478
00479 ++count;
00480 }
00481
00482 fNRecoShower += count;
00483
00484 MSG("FillAlg", Msg::kDebug) << "MC truth record with index " << truth.TruthIndex()
00485 << " matches "<< count << " reconstructed showers" << endl;
00486 }
00487
00488
00489 bool Anp::FillTruth::IsConsistent(const Record &record) const
00490 {
00491
00492
00493
00494
00495
00496
00497 for(TruthIter truth = record.TruthBeg(); truth != record.TruthEnd(); ++truth)
00498 {
00499 for(TruthRecoIter reco = truth -> RecoBeg(); reco != truth -> RecoEnd(); ++reco)
00500 {
00501 short found = 0;
00502
00503 if(record.StdHepBeg() != record.StdHepEnd())
00504 {
00505 for(StdHepIter hep = record.StdHepBeg(); hep != record.StdHepEnd(); ++hep)
00506 {
00507 if(reco -> StdHepIndex() == hep -> StdHepIndex())
00508 {
00509 ++found;
00510 }
00511 }
00512
00513 if(found != 1)
00514 {
00515 MSG("FillAlg", Msg::kError) << "Failed to match StdHep to TruthReco" << endl;
00516 reco -> Print();
00517 return false;
00518 }
00519 }
00520
00521 found = std::count(record.EventBeg(), record.EventEnd(), *reco);
00522 if(reco -> IsEvent() && record.EventBeg() != record.EventEnd() && found != 1)
00523 {
00524 MSG("FillAlg", Msg::kError) << "No match for event to TruthReco: found = " << found << endl;
00525 reco -> Print();
00526 return false;
00527 }
00528
00529 found = std::count(record.TrackBeg(), record.TrackEnd(), *reco);
00530 if(reco -> IsTrack() && record.TrackBeg() != record.TrackEnd() && found != 1)
00531 {
00532 MSG("FillAlg", Msg::kError) << "Failed to match track to TruthReco" << endl;
00533 reco -> Print();
00534 return false;
00535 }
00536 }
00537 }
00538
00539
00540
00541
00542
00543
00544
00545 for(EventIter event = record.EventBeg(); event != record.EventEnd(); ++event)
00546 {
00547 short found = 0;
00548 for(TruthIter truth = record.TruthBeg(); truth != record.TruthEnd(); ++truth)
00549 {
00550
00551
00552
00553 found += std::count(truth -> RecoBeg(), truth -> RecoEnd(), *event);
00554 }
00555
00556
00557
00558
00559 if(found != 1)
00560 {
00561 MSG("FillAlg", Msg::kError) << "Failed to find truth info for a reco event" << endl;
00562 return false;
00563 }
00564 }
00565
00566 for(TrackIter track = record.TrackBeg(); track != record.TrackEnd(); ++track)
00567 {
00568 short found = 0;
00569 for(TruthIter truth = record.TruthBeg(); truth != record.TruthEnd(); ++truth)
00570 {
00571
00572
00573
00574 found += std::count(truth -> RecoBeg(), truth -> RecoEnd(), *track);
00575 }
00576
00577
00578
00579
00580 if(found != 1)
00581 {
00582 MSG("FillAlg", Msg::kError) << "Found " << found <<" truth records for reco track" << endl;
00583 return false;
00584 }
00585 }
00586
00587 for(ShowerIter shower = record.ShowerBeg(); shower != record.ShowerEnd(); ++shower)
00588 {
00589 short found = 0;
00590 for(TruthIter truth = record.TruthBeg(); truth != record.TruthEnd(); ++truth)
00591 {
00592
00593
00594
00595 found += std::count(truth -> RecoBeg(), truth -> RecoEnd(), *shower);
00596 }
00597
00598
00599
00600
00601 if(found != 1)
00602 {
00603 MSG("FillAlg", Msg::kError) << "Found " << found <<" truth records for reco shower" << endl;
00604 return false;
00605 }
00606 }
00607
00608 return true;
00609 }
00610
00611
00612 template<class T>
00613 vector<const T *> Anp::FillRecoTruth(const TClonesArray *array)
00614 {
00615
00616
00617
00618
00619 vector<const T *> tvec;
00620
00621 if(!array)
00622 {
00623 cerr << "FillRecoTruth<T> - TClonesArray of reco-to-truth records does not exist" << endl;
00624 return tvec;
00625 }
00626
00627 const int nentries = array -> GetEntries();
00628 for(int index = 0; index < nentries; ++index)
00629 {
00630 const T *treco = dynamic_cast<const T *>(array -> At(index));
00631 if(!treco)
00632 {
00633 cerr << "FillRecoTruth<T> - dynamic_cast failed at index: "<< index << endl;
00634 continue;
00635 }
00636
00637 if(treco -> index != index)
00638 {
00639 cerr << "FillRecoTruth<T> - wrong index at index: "<< index << endl;
00640 continue;
00641 }
00642
00643 tvec.push_back(treco);
00644 }
00645
00646 return tvec;
00647 }