00001
00002
00003
00004
00005
00006
00008 #include <iostream>
00009 using namespace std;
00010 #include <cassert>
00011
00012 #include "TClonesArray.h"
00013
00014 #include "MessageService/MsgService.h"
00015 #include "JobControl/JobCModuleRegistry.h"
00016 #include "JobControl/JobCommand.h"
00017 #include "MinosObjectMap/MomNavigator.h"
00018 #include "Record/SimSnarlRecord.h"
00019 #include "Record/SimSnarlHeader.h"
00020 #include "CandData/CandRecord.h"
00021 #include "RecoBase/CandStripListHandle.h"
00022 #include "RecoBase/CandStripHandle.h"
00023 #include "RecoBase/CandSliceListHandle.h"
00024 #include "RecoBase/CandSliceHandle.h"
00025 #include "RecoBase/CandShowerListHandle.h"
00026 #include "RecoBase/CandShowerHandle.h"
00027 #include "RecoBase/CandTrackListHandle.h"
00028 #include "RecoBase/CandTrackHandle.h"
00029 #include "RecoBase/CandFitTrackListHandle.h"
00030 #include "RecoBase/CandFitTrackHandle.h"
00031 #include "RecoBase/CandEventListHandle.h"
00032 #include "RecoBase/CandEventHandle.h"
00033 #include "DataUtil/TruthHelper.h"
00034 #include "DataUtil/Truthifier.h"
00035 #include "TruthHelperNtuple/Module/NtpTHModule.h"
00036 #include "TruthHelperNtuple/NtpTHRecord.h"
00037 #include "TruthHelperNtuple/NtpTHStrip.h"
00038 #include "TruthHelperNtuple/NtpTHSlice.h"
00039 #include "TruthHelperNtuple/NtpTHShower.h"
00040 #include "TruthHelperNtuple/NtpTHTrack.h"
00041 #include "TruthHelperNtuple/NtpTHEvent.h"
00042 #include "StandardNtuple/NtpStRecord.h"
00043 #include "Digitization/DigiSignal.h"
00044
00045 ClassImp(NtpTHModule)
00046
00047
00048
00049
00050 CVSID("$Id: NtpTHModule.cxx,v 1.17 2008/11/05 17:45:13 rodriges Exp $");
00051 JOBMODULE(NtpTHModule, "NtpTHModule",
00052 "A module for filling truth helper ntuple records.");
00053
00054
00055 namespace NtpTH
00056 {
00057 struct Fraction
00058 {
00059 Fraction() : stdhep(0), adc(0.0), frac(0.0) {}
00060 int stdhep;
00061 double adc;
00062 double frac;
00063 };
00064
00065 typedef std::vector<Fraction> FVec;
00066 typedef FVec::iterator FIter;
00067
00068 struct ByFrac : public std::binary_function<Fraction, Fraction, bool>
00069 {
00070 bool operator()(const Fraction &lhs, const Fraction &rhs)
00071 {
00072 return (lhs.frac < rhs.frac);
00073 }
00074 };
00075
00076 struct ById : public std::binary_function<Fraction, Fraction, bool>
00077 {
00078 bool operator()(const Fraction &lhs, const Fraction &rhs)
00079 {
00080 return (lhs.stdhep < rhs.stdhep);
00081 }
00082 };
00083 }
00084
00085
00086
00087
00088
00089
00090
00091 const Registry& NtpTHModule::DefaultConfig() const {
00092
00093
00094
00095
00096
00097
00098
00099
00100 MSG("NtpTH",Msg::kDebug) << "NtpTHModule::DefaultConfig" << endl;
00101
00102 static Registry r;
00103 std::string name = this->JobCModule::GetName();
00104 name += ".config.default";
00105 r.SetName(name.c_str());
00106
00107 r.UnLockValues();
00108 r.Set("WriteStrip",1);
00109 r.Set("UseStandard",0);
00110 r.Set("CandRecordName","PrimaryCandidateRecord");
00111 r.Set("SimSnarlRecordName","");
00112 r.Set("RecordName","Primary");
00113 r.Set("RecordTitle","Created by NtpTHModule");
00114 r.LockValues();
00115
00116 return r;
00117 }
00118
00119
00120
00121 void NtpTHModule::Config(const Registry& r) {
00122
00123
00124
00125
00126
00127
00128
00129
00130 MSG("NtpTH",Msg::kDebug) << "NtpTHModule::Config" << endl;
00131
00132 Int_t tmpi;
00133
00134 const Char_t* tmps;
00135 if (r.Get("WriteStrip",tmpi)) fWriteStrip = tmpi;
00136 if (r.Get("UseStandard",tmpi)) fUseStandard = tmpi;
00137 if ( r.Get("CandRecordName",tmps) ) fCandRecordName = tmps;
00138 if ( r.Get("SimSnarlRecordName",tmps) ) fSimSnarlRecordName = tmps;
00139 if ( r.Get("RecordName", tmps) ) fRecordName = tmps;
00140 if ( r.Get("RecordTitle", tmps) ) fRecordTitle = tmps;
00141
00142 }
00143
00144
00145
00146 JobCResult NtpTHModule::Reco(MomNavigator *mom) {
00147
00148
00149
00150
00151
00152
00153
00154
00155 JobCResult result(JobCResult::kPassed);
00156 MSG("NtpTH",Msg::kDebug) << "NtpTHModule::Reco" << endl;
00157
00158
00159 assert(mom);
00160
00161 SimSnarlRecord* simrec = dynamic_cast<SimSnarlRecord*>
00162 (mom->GetFragment("SimSnarlRecord",fSimSnarlRecordName.c_str()));
00163 CandRecord* cndrec = dynamic_cast<CandRecord*>
00164 (mom->GetFragment("CandRecord",fCandRecordName.c_str()));
00165 if ( !simrec ) {
00166 MSG("NtpTH",Msg::kWarning) << " No SimSnarlRecord of name "
00167 << fSimSnarlRecordName.c_str() << endl;
00168 result.SetWarning().SetFailed();
00169 return result;
00170 }
00171
00172 const SimSnarlHeader* simhdr = simrec->GetSimSnarlHeader();
00173
00174 TClonesArray* ntpthstp_arrptr = 0;
00175 TClonesArray* ntpthslc_arrptr = 0;
00176 TClonesArray* ntpthshw_arrptr = 0;
00177 TClonesArray* ntpthtrk_arrptr = 0;
00178 TClonesArray* ntpthevt_arrptr = 0;
00179
00180 NtpStRecord* ntpstrec = 0;
00181 NtpTHRecord* ntpthrec = 0;
00182 if ( fUseStandard ) {
00183 ntpstrec = dynamic_cast<NtpStRecord*>(mom->GetFragment("NtpStRecord",
00184 fRecordName.c_str()));
00185 if (!ntpstrec) {
00186 MSG("NtpSt",Msg::kWarning) << "No NtpStRecord in Mom and UseStandard."
00187 << "\nMust call NtpStModule::Get() first." << endl;
00188 result.SetWarning().SetFailed();
00189 return result;
00190 }
00191 ntpthstp_arrptr = ntpstrec->thstp;
00192 ntpthslc_arrptr = ntpstrec->thslc;
00193 ntpthshw_arrptr = ntpstrec->thshw;
00194 ntpthtrk_arrptr = ntpstrec->thtrk;
00195 ntpthevt_arrptr = ntpstrec->thevt;
00196 }
00197 else {
00198
00199 RecCandHeader ntphdr(simhdr->GetVldContext(),simhdr->GetRun(),
00200 simhdr->GetSubRun(),simhdr->GetRunType(),simhdr->GetErrorCode(),
00201 simhdr->GetSnarl(),simhdr->GetTrigSrc(),simhdr->GetTimeFrame(),
00202 simhdr->GetRemoteSpillType(),-1);
00203 ntpthrec = new NtpTHRecord(ntphdr);
00204
00205 RecJobHistory& jobhist
00206 = const_cast<RecJobHistory&>(ntpthrec->GetJobHistory());
00207 jobhist.Append(simrec->GetJobHistory());
00208 if ( cndrec ) jobhist.Append(cndrec->GetJobHistory());
00209 jobhist.CreateJobRecord(RecJobHistory::kNtpTH);
00210
00211 ntpthrec->SetName(fRecordName.c_str());
00212 ntpthrec->SetTitle(fRecordTitle.c_str());
00213 ntpthstp_arrptr = ntpthrec->thstp;
00214 ntpthslc_arrptr = ntpthrec->thslc;
00215 ntpthshw_arrptr = ntpthrec->thshw;
00216 ntpthtrk_arrptr = ntpthrec->thtrk;
00217 ntpthevt_arrptr = ntpthrec->thevt;
00218 }
00219
00220 if ( cndrec ) {
00221
00222 TClonesArray& ntpthstp_array = *(ntpthstp_arrptr);
00223 TClonesArray& ntpthslc_array = *(ntpthslc_arrptr);
00224 TClonesArray& ntpthshw_array = *(ntpthshw_arrptr);
00225 TClonesArray& ntpthtrk_array = *(ntpthtrk_arrptr);
00226 TClonesArray& ntpthevt_array = *(ntpthevt_arrptr);
00227
00228 TruthHelper* helper = new TruthHelper(mom);
00229 if ( fWriteStrip ) {
00230 const Truthifier& truth = Truthifier::Instance(mom);
00231 this -> FillNtpTHStrip(ntpthstp_array,cndrec,truth,helper);
00232 }
00233 this -> FillNtpTHSlice(ntpthslc_array,cndrec,helper);
00234 this -> FillNtpTHShower(ntpthshw_array,cndrec,helper);
00235 this -> FillNtpTHTrack(ntpthtrk_array,cndrec,helper);
00236 this -> FillNtpTHEvent(ntpthevt_array,cndrec,helper);
00237 if ( helper ) delete helper; helper = 0;
00238 }
00239
00240
00241 if ( !fUseStandard ) mom -> AdoptFragment(ntpthrec);
00242
00243 return result;
00244
00245 }
00246
00247 void NtpTHModule::FillNtpTHStrip(TClonesArray& ntpstriparray,
00248 const CandRecord* cndrec,
00249 const Truthifier& truth, TruthHelper* helper) {
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 MSG("NtpTH",Msg::kDebug) << "NtpTHModule::FillNtpTHStrip" << endl;
00260
00261 const CandStripListHandle* striplisthandle
00262 = dynamic_cast < const CandStripListHandle* >
00263 (cndrec -> FindCandHandle("CandStripListHandle"));
00264 if ( !striplisthandle ) return;
00265
00266 Int_t nstrip = 0;
00267 TIter stripItr(striplisthandle->GetDaughterIterator());
00268 while(CandStripHandle* strip = dynamic_cast<CandStripHandle*>(stripItr())){
00269 NtpTHStrip* ntpstrip = new(ntpstriparray[nstrip++])NtpTHStrip();
00270 Int_t neuId = helper -> GetStripNeuIndex(strip);
00271 ntpstrip -> index = nstrip - 1;
00272 ntpstrip -> neumc = helper -> GetNeuKinIndex(neuId);
00273 ntpstrip -> nneu = (Short_t)helper -> StripPurity(strip);
00274
00275 double strip_adc = 0.0;
00276 NtpTH::FVec svec;
00277
00278 TIter digitItr(strip -> GetDaughterIterator());
00279 while (CandDigitHandle* digit=dynamic_cast<CandDigitHandle*>(digitItr()))
00280 {
00281 Int_t truth_flags = (Int_t)truth.GetSignalTruthFlags(*digit);
00282 ntpstrip -> sigflg |= truth_flags;
00283
00284
00285 const double adc = digit -> GetCharge(CalDigitType::kNone);
00286
00287 strip_adc += adc;
00288
00289
00290 const DigiSignal *signal = truth.GetSignal(*digit);
00291 if(!signal)
00292 {
00293 continue;
00294 }
00295
00296
00297 NtpTH::FVec dvec;
00298
00299
00300 double weight_sum = 0;
00301
00302 for(unsigned int ihit = 0; ihit < signal -> GetNumberOfHits(); ++ihit)
00303 {
00304 const DigiScintHit* dhit = signal -> GetHit(ihit);
00305 if(!dhit)
00306 {
00307 continue;
00308 }
00309
00310 const double weight = signal -> GetHitWeight(ihit);
00311 if(!(weight > 0.0))
00312 {
00313 continue;
00314 }
00315
00316 NtpTH::Fraction frac;
00317 frac.stdhep = dhit -> TrackId();
00318 frac.adc = adc;
00319 frac.frac = weight;
00320
00321 dvec.push_back(frac);
00322
00323 weight_sum += weight;
00324 }
00325
00326
00327 if(!(weight_sum > 0.0))
00328 {
00329 continue;
00330 }
00331
00332
00333
00334
00335
00336 const double total_weight = signal -> GetTotalHitWeight();
00337 if(total_weight > weight_sum)
00338 {
00339 weight_sum = total_weight;
00340 }
00341
00342
00343 for(NtpTH::FIter fit = dvec.begin(); fit != dvec.end(); ++fit)
00344 {
00345 fit -> frac /= weight_sum;
00346 }
00347
00348
00349 svec.insert(svec.begin(), dvec.begin(), dvec.end());
00350
00351 }
00352
00353
00354 if(!(strip_adc > 0.0))
00355 {
00356 continue;
00357 }
00358
00359
00360 std::sort(svec.begin(), svec.end(), NtpTH::ById());
00361
00362
00363 NtpTH::FVec frac_vec;
00364
00365
00366
00367 NtpTH::FIter frac_it = svec.begin();
00368 while(frac_it != svec.end())
00369 {
00370
00371 const pair<NtpTH::FIter, NtpTH::FIter> prange =
00372 std::equal_range(frac_it, svec.end(), *frac_it, NtpTH::ById());
00373
00374
00375 if(prange.first == prange.second)
00376 {
00377 break;
00378 }
00379
00380 NtpTH::Fraction frac_all;
00381 for(NtpTH::FIter fit = prange.first; fit != prange.second; ++fit)
00382 {
00383 if(fit == prange.first)
00384 {
00385 frac_all.stdhep = fit -> stdhep;
00386 }
00387 else if(frac_all.stdhep != fit -> stdhep)
00388 {
00389 MSG("NtpTH",Msg::kError) << "Mismatched stdhep index..." << endl;
00390 continue;
00391 }
00392
00393 frac_all.adc += (fit -> frac) * (fit -> adc);
00394 }
00395
00396 frac_all.frac = frac_all.adc/strip_adc;
00397
00398 frac_vec.push_back(frac_all);
00399
00400 frac_it = prange.second;
00401 }
00402
00403
00404 std::sort(frac_vec.begin(), frac_vec.end(), NtpTH::ByFrac());
00405
00406
00407 for(vector<NtpTH::Fraction>::reverse_iterator rit = frac_vec.rbegin();
00408 rit != frac_vec.rend(); ++rit)
00409 {
00410 const unsigned int idist = std::distance(frac_vec.rbegin(), rit);
00411
00412 if(idist > 2)
00413 {
00414 break;
00415 }
00416
00417 ntpstrip -> stdhep[idist] = rit -> stdhep;
00418 ntpstrip -> phfrac[idist] = static_cast<float> (rit -> frac);
00419
00420 MSG("NtpTH",Msg::kVerbose) << idist
00421 << ": stdhep = " << rit -> stdhep
00422 << ", frac = " << rit -> frac << endl;
00423 }
00424
00425 MSG("NtpTH",Msg::kVerbose) << *(ntpstrip) << endl;
00426
00427 }
00428
00429 return;
00430
00431 }
00432
00433 void NtpTHModule::FillNtpTHSlice(TClonesArray& ntpslicearray,
00434 const CandRecord* cndrec, TruthHelper* helper ) {
00435
00436
00437
00438
00439
00440
00441
00442
00443 MSG("NtpTH",Msg::kDebug) << "NtpTHModule::FillNtpTHSlice" << endl;
00444
00445 const CandSliceListHandle* slicelisthandle
00446 = dynamic_cast < const CandSliceListHandle* >
00447 (cndrec -> FindCandHandle("CandSliceListHandle"));
00448 if ( !slicelisthandle ) return;
00449
00450 Int_t nslice = 0;
00451 TIter sliceItr(slicelisthandle->GetDaughterIterator());
00452 while(CandSliceHandle* slc = dynamic_cast<CandSliceHandle*>(sliceItr())){
00453 NtpTHSlice* ntpslice = new(ntpslicearray[nslice++])NtpTHSlice();
00454 Int_t neuId = helper -> GetBestSliceNeuMatch(*slc);
00455 ntpslice -> index = nslice - 1;
00456 ntpslice -> neumc = helper -> GetNeuKinIndex(neuId);
00457 ntpslice -> neustdhep = neuId;
00458 ntpslice -> nneu = helper -> NumNeu(*slc);
00459 ntpslice -> purity = helper -> SlicePurity(*slc);
00460 ntpslice -> secondpurity = helper -> secondNEU(*slc);
00461 ntpslice -> complete = helper -> SliceCompleteness(*slc);
00462 MSG("NtpTH",Msg::kDebug) << *(ntpslice) << endl;
00463 }
00464
00465 return;
00466
00467 }
00468
00469 void NtpTHModule::FillNtpTHShower(TClonesArray& ntpshowerarray,
00470 const CandRecord* cndrec, TruthHelper* helper ) {
00471
00472
00473
00474
00475
00476
00477
00478
00479 MSG("NtpTH",Msg::kDebug) << "NtpTHModule::FillNtpTHShower" << endl;
00480
00481 const CandShowerListHandle* showerlisthandle
00482 = dynamic_cast < const CandShowerListHandle* >
00483 (cndrec -> FindCandHandle("CandShowerListHandle"));
00484 if ( !showerlisthandle ) return;
00485
00486 Int_t nshower = 0;
00487 TIter showerItr(showerlisthandle->GetDaughterIterator());
00488 while(CandShowerHandle* shw = dynamic_cast<CandShowerHandle*>(showerItr())){
00489 NtpTHShower* ntpshower = new(ntpshowerarray[nshower++])NtpTHShower();
00490 Int_t neuId = helper -> GetBestShowerNeuMatch(*shw);
00491 ntpshower -> index = nshower - 1;
00492 ntpshower -> neumc = helper -> GetNeuKinIndex(neuId);
00493 ntpshower -> neustdhep = neuId;
00494 ntpshower -> purity = helper -> ShowerPurity(*shw,neuId);
00495 ntpshower -> completeall = helper -> ShowerCompleteness(*shw);
00496 ntpshower -> completeallnopecut = helper -> ShowerCompletenessAllStrips(*shw);
00497
00498 CandSliceHandle* slch = const_cast<CandSliceHandle*>(shw -> GetCandSlice());
00499 if ( slch ) {
00500 ntpshower -> completeslc = helper -> ShowerCompleteness(*shw,*slch);
00501 ntpshower -> completeslcnopecut = helper -> ShowerCompletenessAllStrips(*shw,*slch);
00502 }
00503
00504 MSG("NtpTH",Msg::kDebug) << *(ntpshower) << endl;
00505 }
00506
00507 return;
00508
00509 }
00510
00511 void NtpTHModule::FillNtpTHTrack(TClonesArray& ntptrackarray,
00512 const CandRecord* cndrec, TruthHelper* helper ) {
00513
00514
00515
00516
00517
00518
00519
00520
00521 MSG("NtpTH",Msg::kDebug) << "NtpTHModule::FillNtpTHTrack" << endl;
00522
00523 const CandTrackListHandle* tracklisthandle
00524 = dynamic_cast < const CandTrackListHandle* >
00525 (cndrec -> FindCandHandle("CandTrackListHandle"));
00526 if ( !tracklisthandle ) return;
00527
00528 Int_t ntrack = 0;
00529 TIter trackItr(tracklisthandle->GetDaughterIterator());
00530 while(CandTrackHandle* trk = dynamic_cast<CandTrackHandle*>(trackItr())){
00531 if(trk->GetNDaughters()==0 &&
00532 trk->InheritsFrom("CandFitTrackHandle") &&
00533 dynamic_cast<CandFitTrackHandle*>(trk)->GetFinderTrack())
00534 trk=dynamic_cast<CandFitTrackHandle*>(trk)->GetFinderTrack();
00535
00536 NtpTHTrack* ntptrack = new(ntptrackarray[ntrack++])NtpTHTrack();
00537 Int_t bestTrack = helper -> GetBestTrackIdMatch(*trk);
00538 ntptrack -> index = ntrack - 1;
00539 ntptrack -> neumc = helper -> GetNeuKinIndex(bestTrack);
00540 ntptrack -> trkstdhep = bestTrack;
00541 ntptrack -> neustdhep = helper -> GetNeuId(bestTrack);
00542 ntptrack -> completeall = helper -> TrackCompleteness(*trk);
00543 ntptrack -> purity = helper -> TrackPurity(*trk,bestTrack);
00544 CandSliceHandle* slch = const_cast<CandSliceHandle*>(trk -> GetCandSlice());
00545 if ( slch ) {
00546 ntptrack -> completeslc = helper -> TrackCompleteness(*trk,*slch);
00547 }
00548 MSG("NtpTH",Msg::kDebug) << *(ntptrack) << endl;
00549 }
00550
00551 return;
00552
00553 }
00554
00555 void NtpTHModule::FillNtpTHEvent(TClonesArray& ntpeventarray,
00556 const CandRecord* cndrec, TruthHelper* helper ) {
00557
00558
00559
00560
00561
00562
00563
00564
00565 MSG("NtpTH",Msg::kDebug) << "NtpTHModule::FillNtpTHEvent" << endl;
00566
00567 const CandEventListHandle* eventlisthandle
00568 = dynamic_cast < const CandEventListHandle* >
00569 (cndrec -> FindCandHandle("CandEventListHandle"));
00570 if ( !eventlisthandle ) return;
00571
00572 Int_t nevent = 0;
00573 TIter eventItr(eventlisthandle->GetDaughterIterator());
00574
00575 while(CandEventHandle* evt = dynamic_cast<CandEventHandle*>(eventItr())){
00576 NtpTHEvent* ntpevent = new(ntpeventarray[nevent++])NtpTHEvent();
00577 Int_t bestEvent = helper -> GetBestEventNeuMatch(*evt);
00578 ntpevent -> index = nevent - 1;
00579 ntpevent -> neumc = helper -> GetNeuKinIndex(bestEvent);
00580 ntpevent -> neustdhep = bestEvent;
00581 ntpevent -> purity = helper -> EventPurity(*evt,bestEvent);
00582 ntpevent -> completeall = helper -> EventCompleteness(*evt);
00583 ntpevent -> completeallnopecut = helper -> EventCompletenessAllStrips(*evt);
00584 CandSliceHandle* slch = const_cast<CandSliceHandle*>(evt -> GetCandSlice());
00585 if ( slch ) {
00586 ntpevent -> completeslc = helper -> EventCompleteness(*evt,*slch);
00587 ntpevent -> completeslcnopecut = helper -> EventCompletenessAllStrips(*evt,*slch);
00588 }
00589 MSG("NtpTH",Msg::kDebug) << *(ntpevent) << endl;
00590 }
00591
00592 return;
00593
00594 }
00595