44#include "CLHEP/Units/PhysicalConstants.h"
46#include "CLHEP/Vector/LorentzVector.h"
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,
83 const std::list<SimHitHandleBase*>::iterator& itFirst,
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 (
const QString& mcevent_key : mcevent_keys) {
164 m_d->theclass =
this;
165 m_d->updateGUICounter = 0;
166 m_d->cut_fromIROnly =
true;
167 m_d->cut_excludeBarcodeZero =
true;
168 m_d->cut_excludeNeutrals =
true;
169 m_d->displayAscObjs =
false;
181 connect(controller,SIGNAL(cutTruthFromIROnlyChanged(
bool)),
this,SLOT(
setCutFromIROnly(
bool)));
187 connect(controller,SIGNAL(cutTruthExcludeNeutralsChanged(
bool)),
this,SLOT(
setCutExcludeNeutrals(
bool)));
190 connect(controller,SIGNAL(showTruthAscObjsChanged(
bool)),
this,SLOT(
setShowAscObjs(
bool)));
197 if (
m_d->displayAscObjs==b)
199 m_d->displayAscObjs=b;
201 m_d->updateVisibleAssociatedObjects();
205template <
class collT>
208 std::map<SimBarCode,SimHitList>::iterator itHitList;
213 const collT * hitColl;
214 if (!sgaccess.
retrieve(hitColl, key)) {
215 theclass->message(
"Error: Could not retrieve "+QString(
typeid(collT).
name())+
" collection with key = "+key);
218 theclass->messageVerbose(
"Retrieved hit collection of type "+QString(
typeid(collT).
name())+
" with key = "+key);
219 typename collT::const_iterator it, itE(hitColl->end());
220 int itot(0), iadded(0);
221 for (it=hitColl->begin();it!=itE;++it) {
233 if (absmom>=0&&absmom<1.0*CLHEP::MeV) {
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);
250 theclass->messageVerbose(
" => used "+
str(iadded)+
" of "+
str(itot)+
" hits");
269 theclass->messageVerbose(
"Found " +
str( hitLists.size() ) +
" lists of sim. hits.");
272 std::map<SimBarCode,SimHitList>::iterator it, itE(hitLists.end());
273 for (it = hitLists.begin(); it!=itE; ++it) {
274 if (it->first.unknownPdgCode())
280 SimHitList::iterator itHit(it->second.begin()), itHitE(it->second.end());
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);
307 if ( !isNonUniqueSecondary && it==
m_d->extBarCode2pdg.end())
308 m_d->extBarCode2pdg[extBarCode] = pdgfromsimhit;
311 if (isNonUniqueSecondary)
313 std::map<SimBarCode::ExtBarCode,int>::const_iterator it =
m_d->extBarCode2pdg.find(extBarCode);
314 if (it!=
m_d->extBarCode2pdg.end()) {
315 handle->
setPDG(it->second);
325 for (
const auto& p: *vtx){
329 const HepMC::GenEvent* evt = p->parent_event();
334 genParticles[simBarCode] = p;
344 const QString& hepMcCollKey )
357 for (;itEvt!=itEvtEnd;++itEvt) {
359 const HepMC::GenEvent * evt = *itEvt;
365 HepMC::GenEvent::vertex_const_iterator itVtx(evt->vertices_begin()), itVtxEnd(evt->vertices_end());
366 for(;itVtx!=itVtxEnd;++itVtx) {
382 if (!augmentedonly) {
389 std::map<SimBarCode,HepMC::ConstGenParticlePtr> genParticles;
390 if (!hepmckey.isEmpty())
391 if (!
m_d->loadGenParticles(genParticles,hepmckey))
395 std::map<SimBarCode,SimHitList> hitLists;
397 if (!
m_d->loadHitLists(hitLists))
400 +
": Found "+
str(hitLists.size())+
" truth particles from simhits");
413 std::map<SimBarCode,HepMC::ConstGenParticlePtr>::iterator itGenPart, itGenPartEnd(genParticles.end());
414 std::map<SimBarCode,SimHitList>::iterator itHitList, itHitListEnd(hitLists.end()), itHitListTemp;
420 std::map<SimBarCode,SimHitList> secondaryHitLists;
421 messageVerbose(
"Sorting non-unique secondaries into lists of hits likely to originate from the same track.");
422 QElapsedTimer timer;timer.start();
423 for (itHitList = hitLists.begin();itHitList!=itHitListEnd;) {
424 if (itHitList->first.isNonUniqueSecondary()) {
425 m_d->createSecondaryHitLists(itHitList->first,itHitList->second,secondaryHitLists,newBarCode);
426 itHitListTemp = itHitList;
428 hitLists.erase(itHitListTemp);
433 messageVerbose(
"Finished sorting non-unique secondaries into lists. Time spent: "+
str(timer.elapsed()*0.001)+
" seconds");
434 std::map<SimBarCode,SimHitList>::iterator itSecondaryList,itSecondaryListEnd(secondaryHitLists.end());
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;
450 m_d->possiblyUpdateGUI();
452 if (
m_d->fixMomentumInfoInSimHits(p,itHitList->second))
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());
470 if ( dx*dx+dy*dy+dz*dz < minSepSq )
473 m_d->possiblyUpdateGUI();
478 m_d->updateVisibleAssociatedObjects();
496 if (
m_d->cut_fromIROnly && ! truthhandle->
hasVertexAtIR(2.8*CLHEP::cm*2.8*CLHEP::cm,50*CLHEP::cm))
505 if (
m_d->cut_fromIROnly == b)
507 m_d->cut_fromIROnly = b;
517 if (
m_d->cut_excludeBarcodeZero==b)
519 m_d->cut_excludeBarcodeZero=b;
529 if (
m_d->cut_excludeNeutrals==b)
531 m_d->cut_excludeNeutrals=b;
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;
571 double massSquared( (ok&&mass>=0) ? mass*mass : -1);
572 while (!handleList.empty()) {
573 std::list<SimHitHandleBase*> list;
574 std::list<SimHitHandleBase*>::iterator it(handleList.begin()), itNext, itTemp;
577 list.push_back(handle);
579 handleList.erase(itTemp);
581 if (it==handleList.end())
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();
621 std::map<SimBarCode,SimHitList>::iterator itActualOutList = outlists.find(fakeBarCode);
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).");
641 const std::list<SimHitHandleBase*>::iterator& itFirst,
642 std::list<SimHitHandleBase*>& handleList,
643 const double& massSquared)
const {
646 const double mom = handle->
momentum();
647 const double momSq = mom*mom;
648 const double betaSqMax = ( (mom < 0 || massSquared<=0 ? 1 : (momSq/(momSq+massSquared)) ));
649 const double speedSqMax = 4.0* CLHEP::c_squared * betaSqMax;
655 unsigned ichecked(0);
656 unsigned maxchecked(50);
660 double mom2, flightTime;
661 std::list<SimHitHandleBase*>::iterator it(itFirst), itE(handleList.end());
662 std::list<SimHitHandleBase*>::iterator itMinDist(itE);
663 double minDistSq(100*CLHEP::cm*100*CLHEP::cm);
665 if (mom<500*CLHEP::MeV) {
666 minDistSq = 20*CLHEP::cm*20*CLHEP::cm;
667 if (mom<100*CLHEP::MeV) {
668 minDistSq = 10*CLHEP::cm*10*CLHEP::cm;
669 if (mom<10*CLHEP::MeV)
670 minDistSq = 5*CLHEP::cm*5*CLHEP::cm;
674 for (;it!=itE;++it) {
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;
706 if (mom>10.0*CLHEP::MeV) {
707 mindotproduct = -0.1;
708 if (mom>1000.0*CLHEP::MeV) {
710 if (mom>10000.0*CLHEP::MeV) {
711 mindotproduct = 0.80;
715 if (mindotproduct>-1.0)
732 minDistSq = distSquared;
735 if (distSquared<15*15*CLHEP::cm*CLHEP::cm) {
737 if (distSquared<5*5*CLHEP::cm*CLHEP::cm)
738 maxchecked = ichecked + 5;
740 maxchecked = ichecked + 15;
743 if (ichecked>maxchecked)
758 static double unknown = -1.0e99;
759 double mom(unknown), time(unknown);
763 mom =
mag(p->momentum());
764 time = v->position().t()/CLHEP::c_light;
773 bool sawhitwithoutmominfo(
false);
774 bool sawhitwithmominfo(mom!=unknown);
775 SimHitList::iterator it(hitlist.begin()), itE(hitlist.end());
776 for (;it!=itE;++it) {
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." );
793 SimHitList::iterator it(hitlist.begin()), itE(hitlist.end());
815 if (hitlist.at(0).second->momentum()<0.0) {
816 SimHitList::iterator it(hitlist.begin()), itE(hitlist.end());
817 for (;it!=itE;++it) {
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);
858 if (mom==unknown||time==unknown) {
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));
894 mom += (mom2-mom)*(t-time)/(time2-time);
896 hitlist.at(i).second->setFakeMomentum(mom);
965 theclass->message(
"updateVisibleAssociatedObjects");
967 theclass->trackHandleIterationBegin();
float hitTime(const AFP_SIDSimHit &hit)
Scalar mag() const
mag method
double charge(const T &p)
AtlasHitsVector< CSCSimHit > CSCSimHitCollection
AtlasHitsVector< MDTSimHit > MDTSimHitCollection
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
AtlasHitsVector< RPCSimHit > RPCSimHitCollection
AtlasHitsVector< SiHit > SiHitCollection
std::vector< std::pair< double, SimHitHandleBase * > > SimHitList
AtlasHitsVector< TGCSimHit > TGCSimHitCollection
AtlasHitsVector< TRTUncompressedHit > TRTUncompressedHitCollection
AtlasHitsVector< TrackRecord > TrackRecordCollection
Header file for AthHistogramAlgorithm.
DataModel_detail::const_iterator< DataVector > const_iterator
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
std::pair< int, HepMcParticleLink::index_type > ExtBarCode
ExtBarCode extBarCode() const
static const int unknownPDG
bool isNonUniqueSecondary() const
HepMcParticleLink::index_type evtIndex() const
virtual double hitTime() const =0
virtual Amg::Vector3D posStart() const =0
virtual Amg::Vector3D momentumDirection() const =0
virtual int actualPDGCodeFromSimHit() const
SimBarCode simBarCode() const
void recheckCutStatusOfAllVisibleHandles()
const QString & name() const
virtual bool cut(TrackHandleBase *)
void addTrackHandle(TrackHandleBase *)
TrackCollHandleBase(TrackSysCommonData *, const QString &name, TrackType::Type)
void recheckCutStatusOfAllNotVisibleHandles()
static SimHitHandleBase * createHitHandle(const TRTUncompressedHit &h)
void addHitCollections(std::map< SimBarCode, SimHitList > &hitLists)
void updateVisibleAssociatedObjects() const
std::map< SimBarCode::ExtBarCode, int > extBarCode2pdg
static const int maxPdgCode
bool fixMomentumInfoInSimHits(HepMC::ConstGenParticlePtr p, SimHitList &hitlist) const
static QString nameAugmentedOnly
bool loadHitLists(std::map< SimBarCode, SimHitList > &hitLists)
std::list< SimHitHandleBase * >::iterator closestCompatibleHandleItr(SimHitHandleBase *handle, const std::list< SimHitHandleBase * >::iterator &itFirst, std::list< SimHitHandleBase * > &handleList, const double &massSquared) const
static SimHitHandleBase * createHitHandle(const TrackRecord &h)
void createSecondaryHitLists(const SimBarCode &origSimBarCode, const SimHitList &origHitList, std::map< SimBarCode, SimHitList > &outlists, int &newBarCode)
static double mag(const HepMC::FourVector &v)
TrackCollHandle_TruthTracks * theclass
bool cut_excludeBarcodeZero
static SimHitHandleBase * createHitHandle(const SiHit &h)
void loadGenParticles(std::map< SimBarCode, HepMC::ConstGenParticlePtr > &genParticles, const HepMC::ConstGenVertexPtr &vtx)
static QString nameHepMCAugmentedEnd
static QStringList availableCollections(IVP1System *)
virtual bool cut(TrackHandleBase *)
void setShowAscObjs(bool)
TrackCollHandle_TruthTracks(TrackSysCommonData *, const QString &name)
virtual void setupSettingsFromControllerSpecific(TrackSystemController *)
void setCutExcludeBarcodeZero(bool)
virtual ~TrackCollHandle_TruthTracks()
void fixPDGCode(SimHitHandleBase *) const
void setCutFromIROnly(bool)
void setCutExcludeNeutrals(bool)
void setAscObjsVisible(bool)
bool hasBarCodeZero() const
bool hasVertexAtIR(const double &rmaxsq, const double &zmax) const
bool cutTruthFromIROnly() const
bool showTruthAscObjs() const
bool cutTruthExcludeNeutrals() const
bool cutExcludeBarcodeZero() const
void messageVerbose(const QString &) const
void message(const QString &) const
void setHelperClassName(const QString &n)
static bool hasTRTGeometry()
static bool hasPixelGeometry()
static bool hasSCTGeometry()
static bool hasMuonGeometry()
static double particleMass(const int &pdgcode, bool &ok)
static double particleCharge(const int &pdgcode, bool &ok)
bool retrieve(const T *&, const QString &key) const
QStringList getKeys() const
int count(std::string s, const std::string ®x)
count how many occurances of a regx are in a string
Eigen::Matrix< double, 3, 1 > Vector3D
const GenParticle * ConstGenParticlePtr
const HepMC::GenVertex * ConstGenVertexPtr