44#include "CLHEP/Units/PhysicalConstants.h"
46#include "CLHEP/Vector/LorentzVector.h"
50#include <QElapsedTimer>
58 bool loadHitLists(std::map<SimBarCode,SimHitList> & hitLists);
59 void loadGenParticles( std::map<SimBarCode,HepMC::ConstGenParticlePtr> & genParticles,
61 bool loadGenParticles( std::map<SimBarCode,HepMC::ConstGenParticlePtr> & genParticles,
62 const QString& hepMcCollKey );
64 template <
class collT>
77 std::map<SimBarCode,SimHitList> & outlists,
80 const std::list<SimHitHandleBase*>::iterator& itFirst,
81 std::list<SimHitHandleBase*>& handleList,
82 const double& massSquared)
const;
118 QStringList keys_siliconhits, keys_trthits, keys_mdthits,
119 keys_rpchits, keys_tgchits, keys_cschits;
132 bool extrainfo = ! ( keys_siliconhits.empty() && keys_trthits.empty()
133 && keys_mdthits.empty() && keys_rpchits.empty()
134 && keys_tgchits.empty() && keys_cschits.empty()
135 && trackrecord_keys.empty() );
137 if (extrainfo&&mcevent_keys.empty()) {
142 for (
const QString& mcevent_key : mcevent_keys) {
161 m_d->theclass =
this;
162 m_d->updateGUICounter = 0;
163 m_d->cut_fromIROnly =
true;
164 m_d->cut_excludeBarcodeZero =
true;
165 m_d->cut_excludeNeutrals =
true;
166 m_d->displayAscObjs =
false;
178 connect(controller,SIGNAL(cutTruthFromIROnlyChanged(
bool)),
this,SLOT(
setCutFromIROnly(
bool)));
184 connect(controller,SIGNAL(cutTruthExcludeNeutralsChanged(
bool)),
this,SLOT(
setCutExcludeNeutrals(
bool)));
187 connect(controller,SIGNAL(showTruthAscObjsChanged(
bool)),
this,SLOT(
setShowAscObjs(
bool)));
194 if (
m_d->displayAscObjs==b)
196 m_d->displayAscObjs=b;
198 m_d->updateVisibleAssociatedObjects();
202template <
class collT>
205 std::map<SimBarCode,SimHitList>::iterator itHitList;
210 const collT * hitColl;
211 if (!sgaccess.
retrieve(hitColl, key)) {
212 theclass->message(
"Error: Could not retrieve "+QString(
typeid(collT).
name())+
" collection with key = "+key);
215 theclass->messageVerbose(
"Retrieved hit collection of type "+QString(
typeid(collT).
name())+
" with key = "+key);
216 typename collT::const_iterator it, itE(hitColl->end());
217 int itot(0), iadded(0);
218 for (it=hitColl->begin();it!=itE;++it) {
222 handle->cacheMomentum();
229 double absmom = handle->momentum();
230 if (absmom>=0&&absmom<1.0*CLHEP::MeV) {
237 itHitList = hitLists.find(trackID);
238 if ( itHitList == hitLists.end() ) {
240 l.push_back(std::pair<double,SimHitHandleBase*>(handle->hitTime(),handle));
241 hitLists[trackID] = l;
243 itHitList->second.emplace_back(handle->hitTime(),handle);
247 theclass->messageVerbose(
" => used "+
str(iadded)+
" of "+
str(itot)+
" hits");
266 theclass->messageVerbose(
"Found " +
str( hitLists.size() ) +
" lists of sim. hits.");
269 std::map<SimBarCode,SimHitList>::iterator it, itE(hitLists.end());
270 for (it = hitLists.begin(); it!=itE; ++it) {
271 if (it->first.unknownPdgCode())
277 SimHitList::iterator itHit(it->second.begin()), itHitE(it->second.end());
278 for (;itHit!=itHitE;++itHit)
279 itHit->second->setCharge(
charge);
286 for (it = hitLists.begin(); it!=itE; ++it) {
287 sort(it->second.begin(),it->second.end());
297 int pdgfromsimhit =handle->actualPDGCodeFromSimHit();
298 bool isNonUniqueSecondary = handle->simBarCode().isNonUniqueSecondary();
302 handle->setPDG(handle->actualPDGCodeFromSimHit());
303 std::map<SimBarCode::ExtBarCode,int>::const_iterator it =
m_d->extBarCode2pdg.find(extBarCode);
304 if ( !isNonUniqueSecondary && it==
m_d->extBarCode2pdg.end())
305 m_d->extBarCode2pdg[extBarCode] = pdgfromsimhit;
308 if (isNonUniqueSecondary)
310 std::map<SimBarCode::ExtBarCode,int>::const_iterator it =
m_d->extBarCode2pdg.find(extBarCode);
311 if (it!=
m_d->extBarCode2pdg.end()) {
312 handle->setPDG(it->second);
322 for (
const auto& p: *vtx){
331 genParticles[simBarCode] = p;
341 const QString& hepMcCollKey )
354 for (;itEvt!=itEvtEnd;++itEvt) {
372 if (!augmentedonly) {
379 std::map<SimBarCode,HepMC::ConstGenParticlePtr> genParticles;
380 if (!hepmckey.isEmpty())
381 if (!
m_d->loadGenParticles(genParticles,hepmckey))
385 std::map<SimBarCode,SimHitList> hitLists;
387 if (!
m_d->loadHitLists(hitLists))
390 +
": Found "+
str(hitLists.size())+
" truth particles from simhits");
403 std::map<SimBarCode,HepMC::ConstGenParticlePtr>::iterator itGenPart, itGenPartEnd(genParticles.end());
404 std::map<SimBarCode,SimHitList>::iterator itHitList, itHitListEnd(hitLists.end()), itHitListTemp;
410 std::map<SimBarCode,SimHitList> secondaryHitLists;
411 messageVerbose(
"Sorting non-unique secondaries into lists of hits likely to originate from the same track.");
412 QElapsedTimer timer;timer.start();
413 for (itHitList = hitLists.begin();itHitList!=itHitListEnd;) {
414 if (itHitList->first.isNonUniqueSecondary()) {
415 m_d->createSecondaryHitLists(itHitList->first,itHitList->second,secondaryHitLists,newBarCode);
416 itHitListTemp = itHitList;
418 hitLists.erase(itHitListTemp);
423 messageVerbose(
"Finished sorting non-unique secondaries into lists. Time spent: "+
str(timer.elapsed()*0.001)+
" seconds");
424 std::map<SimBarCode,SimHitList>::iterator itSecondaryList,itSecondaryListEnd(secondaryHitLists.end());
425 for (itSecondaryList = secondaryHitLists.begin();itSecondaryList!=itSecondaryListEnd;++itSecondaryList)
426 hitLists[itSecondaryList->first] = itSecondaryList->second;
428 for (itHitList = hitLists.begin();itHitList!=itHitListEnd;++itHitList) {
429 if (itHitList->second.empty()) {
430 message(
"load WARNING: Ignoring empty hit list.");
433 itGenPart = genParticles.find(itHitList->first);
435 if (itGenPart!=itGenPartEnd) {
436 p = itGenPart->second;
437 itGenPart->second = 0;
440 m_d->possiblyUpdateGUI();
442 if (
m_d->fixMomentumInfoInSimHits(p,itHitList->second))
446 const double minSpacialSeparation = 1.0e-3*CLHEP::mm;
447 const double minSepSq = minSpacialSeparation*minSpacialSeparation;
448 for (itGenPart=genParticles.begin();itGenPart!=itGenPartEnd;++itGenPart) {
454 if (!p->production_vertex())
456 if (p->end_vertex()) {
457 double dx(p->end_vertex()->position().x()-p->production_vertex()->position().x());
458 double dy(p->end_vertex()->position().y()-p->production_vertex()->position().y());
459 double dz(p->end_vertex()->position().z()-p->production_vertex()->position().z());
460 if ( dx*dx+dy*dy+dz*dz < minSepSq )
463 m_d->possiblyUpdateGUI();
468 m_d->updateVisibleAssociatedObjects();
479 if (
m_d->cut_excludeNeutrals && handle->hasCharge() && handle->charge()==0.0)
486 if (
m_d->cut_fromIROnly && ! truthhandle->
hasVertexAtIR(2.8*CLHEP::cm*2.8*CLHEP::cm,50*CLHEP::cm))
495 if (
m_d->cut_fromIROnly == b)
497 m_d->cut_fromIROnly = b;
507 if (
m_d->cut_excludeBarcodeZero==b)
509 m_d->cut_excludeBarcodeZero=b;
519 if (
m_d->cut_excludeNeutrals==b)
521 m_d->cut_excludeNeutrals=b;
531 std::map<SimBarCode,SimHitList> & outlists,
535 theclass->message(
"createSecondaryHitLists"
536 " ERROR: Unexpected input");
540 unsigned ntothitinput = origHitList.size();
542 int pdgCode = origSimBarCode.
pdgCode();
548 SimHitList::const_iterator itOrig(origHitList.begin()),itOrigE(origHitList.end());
549 std::list<SimHitHandleBase*> handleList;
550 for(;itOrig!=itOrigE;++itOrig)
551 handleList.push_back(itOrig->second);
557 std::set<std::list<SimHitHandleBase*> > outHandleLists;
561 double massSquared( (ok&&mass>=0) ? mass*mass : -1);
562 while (!handleList.empty()) {
563 std::list<SimHitHandleBase*> list;
564 std::list<SimHitHandleBase*>::iterator it(handleList.begin()), itNext, itTemp;
567 list.push_back(handle);
569 handleList.erase(itTemp);
571 if (it==handleList.end())
575 if (itNext == handleList.end())
578 list.push_back(handle);
580 handleList.erase(itNext);
581 if (it == handleList.end())
584 if (list.size()==1) {
590 outHandleLists.insert(list);
603 std::set<std::list<SimHitHandleBase*> >
::iterator itOutList(outHandleLists.begin()), itOutListE(outHandleLists.end());
605 for (;itOutList!=itOutListE;++itOutList) {
606 const SimBarCode fakeBarCode(newBarCode--,evtIndex,pdgCode);
608 const unsigned n = itOutList->size();
611 std::map<SimBarCode,SimHitList>::iterator itActualOutList = outlists.find(fakeBarCode);
612 itActualOutList->second.reserve(n);
614 std::list<SimHitHandleBase*>::const_iterator itHandle(itOutList->begin()),itHandleE(itOutList->end());
615 for (;itHandle!=itHandleE;++itHandle)
616 itActualOutList->second.emplace_back((*itHandle)->hitTime(),*itHandle);
619 sort(itActualOutList->second.begin(),itActualOutList->second.end());
623 theclass->messageVerbose(
"Grouped "+
str(ntothitinput)+
" secondaries with pdgCode = "
624 +
str(pdgCode)+
" into "+
str(outHandleLists.size())
625 +
" tracks ("+
str(ntothitinput-totused)+
" went unused).");
631 const std::list<SimHitHandleBase*>::iterator& itFirst,
632 std::list<SimHitHandleBase*>& handleList,
633 const double& massSquared)
const {
636 const double mom = handle->momentum();
637 const double momSq = mom*mom;
638 const double betaSqMax = ( (mom < 0 || massSquared<=0 ? 1 : (momSq/(momSq+massSquared)) ));
639 const double speedSqMax = 4.0* CLHEP::c_squared * betaSqMax;
645 unsigned ichecked(0);
646 unsigned maxchecked(50);
648 const double hitTime = handle->hitTime();
650 double mom2, flightTime;
651 std::list<SimHitHandleBase*>::iterator it(itFirst), itE(handleList.end());
652 std::list<SimHitHandleBase*>::iterator itMinDist(itE);
653 double minDistSq(100*CLHEP::cm*100*CLHEP::cm);
655 if (mom<500*CLHEP::MeV) {
656 minDistSq = 20*CLHEP::cm*20*CLHEP::cm;
657 if (mom<100*CLHEP::MeV) {
658 minDistSq = 10*CLHEP::cm*10*CLHEP::cm;
659 if (mom<10*CLHEP::MeV)
660 minDistSq = 5*CLHEP::cm*5*CLHEP::cm;
664 for (;it!=itE;++it) {
666 mom2 = (*it)->momentum();
668 if (mom>=0&&mom2>=0) {
676 const double distSquared = ((*it)->posStart()-pos).mag2();
679 if (distSquared>=minDistSq)
682 flightTime = (*it)->hitTime() -
hitTime;
683 if (flightTime<=0||flightTime>100*CLHEP::ns) {
686 theclass->message(
"closestCompatibleHandleItr WARNING: Should never happen. T1="+
str(
hitTime)+
", T2="+
str((*it)->hitTime()));
689 if (distSquared>flightTime*flightTime*speedSqMax)
695 double mindotproduct = -0.5;
696 if (mom>10.0*CLHEP::MeV) {
697 mindotproduct = -0.1;
698 if (mom>1000.0*CLHEP::MeV) {
700 if (mom>10000.0*CLHEP::MeV) {
701 mindotproduct = 0.80;
705 if (mindotproduct>-1.0)
706 if (handle->momentumDirection().dot((*it)->momentumDirection())<mindotproduct)
722 minDistSq = distSquared;
725 if (distSquared<15*15*CLHEP::cm*CLHEP::cm) {
727 if (distSquared<5*5*CLHEP::cm*CLHEP::cm)
728 maxchecked = ichecked + 5;
730 maxchecked = ichecked + 15;
733 if (ichecked>maxchecked)
748 static double unknown = -1.0e99;
749 double mom(unknown), time(unknown);
753 mom = p->momentum().length();
754 time = v->position().t()/CLHEP::c_light;
763 bool sawhitwithoutmominfo(
false);
764 bool sawhitwithmominfo(mom!=unknown);
765 SimHitList::iterator it(hitlist.begin()), itE(hitlist.end());
766 for (;it!=itE;++it) {
767 const bool hasinfo = it->second->momentum()>=0.0;
769 sawhitwithmominfo =
true;
771 sawhitwithoutmominfo =
true;
772 if (sawhitwithoutmominfo&&sawhitwithmominfo)
776 if (!sawhitwithoutmominfo) {
780 if (!sawhitwithmominfo) {
782 theclass->messageDebug(
"Discarding hitlist." );
783 SimHitList::iterator it(hitlist.begin()), itE(hitlist.end());
805 if (hitlist.at(0).second->momentum()<0.0) {
806 SimHitList::iterator it(hitlist.begin()), itE(hitlist.end());
807 for (;it!=itE;++it) {
808 if (it->second->momentum()>=0.0) {
809 hitlist.at(0).second->setFakeMomentum(it->second->momentum()*1.00001);
813 if (hitlist.at(0).second->momentum()<0.0) {
814 theclass->messageDebug(
"fixMomentumInfoInSimHits ERROR: Should not happen! (1)" );
819 mom = hitlist.at(0).second->momentum();
820 time = hitlist.at(0).second->hitTime();
828 unsigned ilast = hitlist.size()-1;
829 if (hitlist.at(ilast).second->momentum()<0.0) {
830 for (
int iLastWithMom = ilast-1;iLastWithMom>=0;--iLastWithMom) {
831 if (hitlist.at(iLastWithMom).second->momentum()>0.0) {
832 hitlist.at(ilast).second->setFakeMomentum(hitlist.at(iLastWithMom).second->momentum()*0.99999);
836 if (hitlist.at(ilast).second->momentum()<0.0) {
839 theclass->messageDebug(
"fixMomentumInfoInSimHits ERROR: Should not happen! (2)" );
843 hitlist.at(ilast).second->setFakeMomentum(mom*0.99999);
848 if (mom==unknown||time==unknown) {
850 mom = hitlist.at(0).second->momentum();
851 time = hitlist.at(0).second->hitTime();
854 unsigned iNextWithMom(0);
855 for (
unsigned i = 0; i < hitlist.size(); ++i) {
856 if (hitlist.at(i).second->momentum()>=0.0) {
857 mom = hitlist.at(i).second->momentum();
858 time = hitlist.at(i).second->hitTime();
861 if (iNextWithMom<=i) {
862 for (
unsigned j = i+1;j<hitlist.size();++j) {
863 if (hitlist.at(j).second->momentum()>=0.0) {
868 if (iNextWithMom<=i) {
869 theclass->messageDebug(
"fixMomentumInfoInSimHits ERROR: Should not happen! (3)" );
875 double time2 = hitlist.at(iNextWithMom).second->hitTime();
876 double mom2 = hitlist.at(iNextWithMom).second->momentum();
877 double t = hitlist.at(i).second->hitTime();
880 if (t<=time||t>=time2||time2<=time)
881 theclass->message(
"SUSPICIOUS TIME");
883 theclass->message(
"SUSPICIOUS MOM mom="+
str(mom)+
", mom2="+
str(mom2));
884 mom += (mom2-mom)*(t-time)/(time2-time);
886 hitlist.at(i).second->setFakeMomentum(mom);
955 theclass->message(
"updateVisibleAssociatedObjects");
957 theclass->trackHandleIterationBegin();
float hitTime(const AFP_SIDSimHit &hit)
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
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)
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)
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
HepMC3::ConstGenParticlePtr ConstGenParticlePtr
HepMC3::ConstGenVertexPtr ConstGenVertexPtr
HepMC3::GenEvent GenEvent