44 #include "CLHEP/Units/PhysicalConstants.h"
46 #include "CLHEP/Vector/LorentzVector.h"
48 #include <QStringList>
50 #include <QElapsedTimer>
56 static double mag(
const HepMC::FourVector&
v) {
57 return std::sqrt(
v.x()*
v.x() +
v.y()*
v.y() +
v.z()*
v.z() );
61 bool loadHitLists(std::map<SimBarCode,SimHitList> & hitLists);
62 void loadGenParticles( std::map<SimBarCode,HepMC::ConstGenParticlePtr> & genParticles,
64 bool loadGenParticles( std::map<SimBarCode,HepMC::ConstGenParticlePtr> & genParticles,
65 const QString& hepMcCollKey );
67 template <
class collT>
80 std::map<SimBarCode,SimHitList> & outlists,
84 std::list<SimHitHandleBase*>& handleList,
85 const double& massSquared)
const;
121 QStringList keys_siliconhits, keys_trthits, keys_mdthits,
122 keys_rpchits, keys_tgchits, keys_cschits;
135 bool extrainfo = ! ( keys_siliconhits.empty() && keys_trthits.empty()
136 && keys_mdthits.empty() && keys_rpchits.empty()
137 && keys_tgchits.empty() && keys_cschits.empty()
138 && trackrecord_keys.empty() );
140 if (extrainfo&&mcevent_keys.empty()) {
145 for (QString mcevent_key : mcevent_keys) {
205 template <
class collT>
213 const collT * hitColl;
215 theclass->
message(
"Error: Could not retrieve "+QString(
typeid(collT).
name())+
" collection with key = "+
key);
219 typename collT::const_iterator
it,
itE(hitColl->end());
220 int itot(0), iadded(0);
240 itHitList = hitLists.find(trackID);
241 if ( itHitList == hitLists.end() ) {
243 l.push_back(std::pair<double,SimHitHandleBase*>(handle->
hitTime(),handle));
244 hitLists[trackID] =
l;
246 itHitList->second.emplace_back(handle->
hitTime(),handle);
259 addHitCollections<TrackRecordCollection>(hitLists);
263 addHitCollections<TRTUncompressedHitCollection>(hitLists);
266 addHitCollections<SiHitCollection>(hitLists);
269 theclass->messageVerbose(
"Found " +
str( hitLists.size() ) +
" lists of sim. hits.");
273 for (
it = hitLists.begin();
it!=
itE; ++
it) {
274 if (
it->first.unknownPdgCode())
281 for (;itHit!=itHitE;++itHit)
282 itHit->second->setCharge(
charge);
289 for (
it = hitLists.begin();
it!=
itE; ++
it) {
290 sort(
it->second.begin(),
it->second.end());
306 std::map<SimBarCode::ExtBarCode,int>::const_iterator
it =
m_d->
extBarCode2pdg.find(extBarCode);
311 if (isNonUniqueSecondary)
313 std::map<SimBarCode::ExtBarCode,int>::const_iterator
it =
m_d->
extBarCode2pdg.find(extBarCode);
325 for (
const auto&
p: *vtx){
329 const HepMC::GenEvent*
evt =
p->parent_event();
334 genParticles[simBarCode] =
p;
336 extBarCode2pdg[simBarCode.
extBarCode()] =
p->pdg_id();
338 loadGenParticles(genParticles,
p->end_vertex());
344 const QString& hepMcCollKey )
349 theclass->message(
"Error: Could not retrieve "+QString(
typeid(
McEventCollection).
name())+
" collection with key = "+hepMcCollKey);
357 for (;itEvt!=itEvtEnd;++itEvt) {
359 const HepMC::GenEvent *
evt = *itEvt;
363 for(
auto itVtx:
evt->vertices()) loadGenParticles(genParticles,itVtx);
365 HepMC::GenEvent::vertex_const_iterator itVtx(
evt->vertices_begin()), itVtxEnd(
evt->vertices_end());
366 for(;itVtx!=itVtxEnd;++itVtx) {
367 loadGenParticles(genParticles,*itVtx);
382 if (!augmentedonly) {
389 std::map<SimBarCode,HepMC::ConstGenParticlePtr> genParticles;
390 if (!hepmckey.isEmpty())
395 std::map<SimBarCode,SimHitList> hitLists;
400 +
": Found "+
str(hitLists.size())+
" truth particles from simhits");
420 std::map<SimBarCode,SimHitList> secondaryHitLists;
421 messageVerbose(
"Sorting non-unique secondaries into lists of hits likely to originate from the same track.");
423 for (itHitList = hitLists.begin();itHitList!=itHitListEnd;) {
424 if (itHitList->first.isNonUniqueSecondary()) {
426 itHitListTemp = itHitList;
428 hitLists.erase(itHitListTemp);
433 messageVerbose(
"Finished sorting non-unique secondaries into lists. Time spent: "+
str(
timer.elapsed()*0.001)+
" seconds");
435 for (itSecondaryList = secondaryHitLists.begin();itSecondaryList!=itSecondaryListEnd;++itSecondaryList)
436 hitLists[itSecondaryList->first] = itSecondaryList->second;
438 for (itHitList = hitLists.begin();itHitList!=itHitListEnd;++itHitList) {
439 if (itHitList->second.empty()) {
440 message(
"load WARNING: Ignoring empty hit list.");
443 itGenPart = genParticles.find(itHitList->first);
445 if (itGenPart!=itGenPartEnd) {
446 p = itGenPart->second;
447 itGenPart->second = 0;
456 const double minSpacialSeparation = 1.0e-3*
CLHEP::mm;
457 const double minSepSq = minSpacialSeparation*minSpacialSeparation;
458 for (itGenPart=genParticles.begin();itGenPart!=itGenPartEnd;++itGenPart) {
464 if (!
p->production_vertex())
466 if (
p->end_vertex()) {
467 double dx(
p->end_vertex()->position().x()-
p->production_vertex()->position().x());
468 double dy(
p->end_vertex()->position().y()-
p->production_vertex()->position().y());
469 double dz(
p->end_vertex()->position().z()-
p->production_vertex()->position().z());
541 std::map<SimBarCode,SimHitList> & outlists,
545 theclass->message(
"createSecondaryHitLists"
546 " ERROR: Unexpected input");
550 unsigned ntothitinput = origHitList.size();
552 int pdgCode = origSimBarCode.
pdgCode();
558 SimHitList::const_iterator itOrig(origHitList.begin()),itOrigE(origHitList.end());
559 std::list<SimHitHandleBase*> handleList;
560 for(;itOrig!=itOrigE;++itOrig)
561 handleList.push_back(itOrig->second);
567 std::set<std::list<SimHitHandleBase*> > outHandleLists;
572 while (!handleList.empty()) {
573 std::list<SimHitHandleBase*>
list;
577 list.push_back(handle);
579 handleList.erase(itTemp);
581 if (
it==handleList.end())
583 itNext = closestCompatibleHandleItr(handle,
it,handleList,massSquared);
585 if (itNext == handleList.end())
588 list.push_back(handle);
590 handleList.erase(itNext);
591 if (
it == handleList.end())
594 if (
list.size()==1) {
600 outHandleLists.insert(
list);
613 std::set<std::list<SimHitHandleBase*> >
::iterator itOutList(outHandleLists.begin()), itOutListE(outHandleLists.end());
615 for (;itOutList!=itOutListE;++itOutList) {
616 const SimBarCode fakeBarCode(newBarCode--,evtIndex,pdgCode);
618 const unsigned n = itOutList->size();
622 itActualOutList->second.reserve(
n);
624 std::list<SimHitHandleBase*>::const_iterator itHandle(itOutList->begin()),itHandleE(itOutList->end());
625 for (;itHandle!=itHandleE;++itHandle)
626 itActualOutList->second.emplace_back((*itHandle)->hitTime(),*itHandle);
629 sort(itActualOutList->second.begin(),itActualOutList->second.end());
633 theclass->messageVerbose(
"Grouped "+
str(ntothitinput)+
" secondaries with pdgCode = "
634 +
str(pdgCode)+
" into "+
str(outHandleLists.size())
635 +
" tracks ("+
str(ntothitinput-totused)+
" went unused).");
642 std::list<SimHitHandleBase*>& handleList,
643 const double& massSquared)
const {
647 const double momSq =
mom*
mom;
648 const double betaSqMax = ( (
mom < 0 || massSquared<=0 ? 1 : (momSq/(momSq+massSquared)) ));
655 unsigned ichecked(0);
656 unsigned maxchecked(50);
660 double mom2, flightTime;
676 mom2 = (*it)->momentum();
678 if (
mom>=0&&mom2>=0) {
686 const double distSquared = ((*it)->posStart()-
pos).
mag2();
689 if (distSquared>=minDistSq)
692 flightTime = (*it)->hitTime() -
hitTime;
693 if (flightTime<=0||flightTime>100*
CLHEP::ns) {
696 theclass->message(
"closestCompatibleHandleItr WARNING: Should never happen. T1="+
str(
hitTime)+
", T2="+
str((*it)->hitTime()));
699 if (distSquared>flightTime*flightTime*speedSqMax)
705 double mindotproduct = -0.5;
707 mindotproduct = -0.1;
711 mindotproduct = 0.80;
715 if (mindotproduct>-1.0)
732 minDistSq = distSquared;
738 maxchecked = ichecked + 5;
740 maxchecked = ichecked + 15;
743 if (ichecked>maxchecked)
758 static double unknown = -1.0e99;
773 bool sawhitwithoutmominfo(
false);
777 const bool hasinfo =
it->second->momentum()>=0.0;
779 sawhitwithmominfo =
true;
781 sawhitwithoutmominfo =
true;
782 if (sawhitwithoutmominfo&&sawhitwithmominfo)
786 if (!sawhitwithoutmominfo) {
790 if (!sawhitwithmominfo) {
792 theclass->messageDebug(
"Discarding hitlist." );
815 if (hitlist.at(0).second->momentum()<0.0) {
818 if (
it->second->momentum()>=0.0) {
819 hitlist.at(0).second->setFakeMomentum(
it->second->momentum()*1.00001);
823 if (hitlist.at(0).second->momentum()<0.0) {
824 theclass->messageDebug(
"fixMomentumInfoInSimHits ERROR: Should not happen! (1)" );
829 mom = hitlist.at(0).second->momentum();
830 time = hitlist.at(0).second->hitTime();
838 unsigned ilast = hitlist.size()-1;
839 if (hitlist.at(ilast).second->momentum()<0.0) {
840 for (
int iLastWithMom = ilast-1;iLastWithMom>=0;--iLastWithMom) {
841 if (hitlist.at(iLastWithMom).second->momentum()>0.0) {
842 hitlist.at(ilast).second->setFakeMomentum(hitlist.at(iLastWithMom).second->momentum()*0.99999);
846 if (hitlist.at(ilast).second->momentum()<0.0) {
849 theclass->messageDebug(
"fixMomentumInfoInSimHits ERROR: Should not happen! (2)" );
853 hitlist.at(ilast).second->setFakeMomentum(
mom*0.99999);
860 mom = hitlist.at(0).second->momentum();
861 time = hitlist.at(0).second->hitTime();
864 unsigned iNextWithMom(0);
865 for (
unsigned i = 0;
i < hitlist.size(); ++
i) {
866 if (hitlist.at(
i).second->momentum()>=0.0) {
867 mom = hitlist.at(
i).second->momentum();
868 time = hitlist.at(
i).second->hitTime();
871 if (iNextWithMom<=
i) {
872 for (
unsigned j =
i+1;j<hitlist.size();++j) {
873 if (hitlist.at(j).second->momentum()>=0.0) {
878 if (iNextWithMom<=
i) {
879 theclass->messageDebug(
"fixMomentumInfoInSimHits ERROR: Should not happen! (3)" );
885 double time2 = hitlist.at(iNextWithMom).second->hitTime();
886 double mom2 = hitlist.at(iNextWithMom).second->momentum();
887 double t = hitlist.at(
i).second->hitTime();
890 if (t<=time||t>=time2||time2<=
time)
891 theclass->message(
"SUSPICIOUS TIME");
893 theclass->message(
"SUSPICIOUS MOM mom="+
str(
mom)+
", mom2="+
str(mom2));
896 hitlist.at(
i).second->setFakeMomentum(
mom);
965 theclass->message(
"updateVisibleAssociatedObjects");
966 theclass->largeChangesBegin();
967 theclass->trackHandleIterationBegin();
972 theclass->largeChangesEnd();