44#include "CLHEP/Units/PhysicalConstants.h"
46#include "CLHEP/Vector/LorentzVector.h"
50#include <QElapsedTimer>
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) {
225 handle->cacheMomentum();
232 double absmom = handle->momentum();
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());
300 int pdgfromsimhit =handle->actualPDGCodeFromSimHit();
301 bool isNonUniqueSecondary = handle->simBarCode().isNonUniqueSecondary();
305 handle->setPDG(handle->actualPDGCodeFromSimHit());
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){
334 genParticles[simBarCode] = p;
344 const QString& hepMcCollKey )
357 for (;itEvt!=itEvtEnd;++itEvt) {
375 if (!augmentedonly) {
382 std::map<SimBarCode,HepMC::ConstGenParticlePtr> genParticles;
383 if (!hepmckey.isEmpty())
384 if (!
m_d->loadGenParticles(genParticles,hepmckey))
388 std::map<SimBarCode,SimHitList> hitLists;
390 if (!
m_d->loadHitLists(hitLists))
393 +
": Found "+
str(hitLists.size())+
" truth particles from simhits");
406 std::map<SimBarCode,HepMC::ConstGenParticlePtr>::iterator itGenPart, itGenPartEnd(genParticles.end());
407 std::map<SimBarCode,SimHitList>::iterator itHitList, itHitListEnd(hitLists.end()), itHitListTemp;
413 std::map<SimBarCode,SimHitList> secondaryHitLists;
414 messageVerbose(
"Sorting non-unique secondaries into lists of hits likely to originate from the same track.");
415 QElapsedTimer timer;timer.start();
416 for (itHitList = hitLists.begin();itHitList!=itHitListEnd;) {
417 if (itHitList->first.isNonUniqueSecondary()) {
418 m_d->createSecondaryHitLists(itHitList->first,itHitList->second,secondaryHitLists,newBarCode);
419 itHitListTemp = itHitList;
421 hitLists.erase(itHitListTemp);
426 messageVerbose(
"Finished sorting non-unique secondaries into lists. Time spent: "+
str(timer.elapsed()*0.001)+
" seconds");
427 std::map<SimBarCode,SimHitList>::iterator itSecondaryList,itSecondaryListEnd(secondaryHitLists.end());
428 for (itSecondaryList = secondaryHitLists.begin();itSecondaryList!=itSecondaryListEnd;++itSecondaryList)
429 hitLists[itSecondaryList->first] = itSecondaryList->second;
431 for (itHitList = hitLists.begin();itHitList!=itHitListEnd;++itHitList) {
432 if (itHitList->second.empty()) {
433 message(
"load WARNING: Ignoring empty hit list.");
436 itGenPart = genParticles.find(itHitList->first);
438 if (itGenPart!=itGenPartEnd) {
439 p = itGenPart->second;
440 itGenPart->second = 0;
443 m_d->possiblyUpdateGUI();
445 if (
m_d->fixMomentumInfoInSimHits(p,itHitList->second))
449 const double minSpacialSeparation = 1.0e-3*CLHEP::mm;
450 const double minSepSq = minSpacialSeparation*minSpacialSeparation;
451 for (itGenPart=genParticles.begin();itGenPart!=itGenPartEnd;++itGenPart) {
457 if (!p->production_vertex())
459 if (p->end_vertex()) {
460 double dx(p->end_vertex()->position().x()-p->production_vertex()->position().x());
461 double dy(p->end_vertex()->position().y()-p->production_vertex()->position().y());
462 double dz(p->end_vertex()->position().z()-p->production_vertex()->position().z());
463 if ( dx*dx+dy*dy+dz*dz < minSepSq )
466 m_d->possiblyUpdateGUI();
471 m_d->updateVisibleAssociatedObjects();
482 if (
m_d->cut_excludeNeutrals && handle->hasCharge() && handle->charge()==0.0)
489 if (
m_d->cut_fromIROnly && ! truthhandle->
hasVertexAtIR(2.8*CLHEP::cm*2.8*CLHEP::cm,50*CLHEP::cm))
498 if (
m_d->cut_fromIROnly == b)
500 m_d->cut_fromIROnly = b;
510 if (
m_d->cut_excludeBarcodeZero==b)
512 m_d->cut_excludeBarcodeZero=b;
522 if (
m_d->cut_excludeNeutrals==b)
524 m_d->cut_excludeNeutrals=b;
534 std::map<SimBarCode,SimHitList> & outlists,
538 theclass->message(
"createSecondaryHitLists"
539 " ERROR: Unexpected input");
543 unsigned ntothitinput = origHitList.size();
545 int pdgCode = origSimBarCode.
pdgCode();
551 SimHitList::const_iterator itOrig(origHitList.begin()),itOrigE(origHitList.end());
552 std::list<SimHitHandleBase*> handleList;
553 for(;itOrig!=itOrigE;++itOrig)
554 handleList.push_back(itOrig->second);
560 std::set<std::list<SimHitHandleBase*> > outHandleLists;
564 double massSquared( (ok&&mass>=0) ? mass*mass : -1);
565 while (!handleList.empty()) {
566 std::list<SimHitHandleBase*> list;
567 std::list<SimHitHandleBase*>::iterator it(handleList.begin()), itNext, itTemp;
570 list.push_back(handle);
572 handleList.erase(itTemp);
574 if (it==handleList.end())
578 if (itNext == handleList.end())
581 list.push_back(handle);
583 handleList.erase(itNext);
584 if (it == handleList.end())
587 if (list.size()==1) {
593 outHandleLists.insert(list);
606 std::set<std::list<SimHitHandleBase*> >
::iterator itOutList(outHandleLists.begin()), itOutListE(outHandleLists.end());
608 for (;itOutList!=itOutListE;++itOutList) {
609 const SimBarCode fakeBarCode(newBarCode--,evtIndex,pdgCode);
611 const unsigned n = itOutList->size();
614 std::map<SimBarCode,SimHitList>::iterator itActualOutList = outlists.find(fakeBarCode);
615 itActualOutList->second.reserve(n);
617 std::list<SimHitHandleBase*>::const_iterator itHandle(itOutList->begin()),itHandleE(itOutList->end());
618 for (;itHandle!=itHandleE;++itHandle)
619 itActualOutList->second.emplace_back((*itHandle)->hitTime(),*itHandle);
622 sort(itActualOutList->second.begin(),itActualOutList->second.end());
626 theclass->messageVerbose(
"Grouped "+
str(ntothitinput)+
" secondaries with pdgCode = "
627 +
str(pdgCode)+
" into "+
str(outHandleLists.size())
628 +
" tracks ("+
str(ntothitinput-totused)+
" went unused).");
634 const std::list<SimHitHandleBase*>::iterator& itFirst,
635 std::list<SimHitHandleBase*>& handleList,
636 const double& massSquared)
const {
639 const double mom = handle->momentum();
640 const double momSq = mom*mom;
641 const double betaSqMax = ( (mom < 0 || massSquared<=0 ? 1 : (momSq/(momSq+massSquared)) ));
642 const double speedSqMax = 4.0* CLHEP::c_squared * betaSqMax;
648 unsigned ichecked(0);
649 unsigned maxchecked(50);
651 const double hitTime = handle->hitTime();
653 double mom2, flightTime;
654 std::list<SimHitHandleBase*>::iterator it(itFirst), itE(handleList.end());
655 std::list<SimHitHandleBase*>::iterator itMinDist(itE);
656 double minDistSq(100*CLHEP::cm*100*CLHEP::cm);
658 if (mom<500*CLHEP::MeV) {
659 minDistSq = 20*CLHEP::cm*20*CLHEP::cm;
660 if (mom<100*CLHEP::MeV) {
661 minDistSq = 10*CLHEP::cm*10*CLHEP::cm;
662 if (mom<10*CLHEP::MeV)
663 minDistSq = 5*CLHEP::cm*5*CLHEP::cm;
667 for (;it!=itE;++it) {
669 mom2 = (*it)->momentum();
671 if (mom>=0&&mom2>=0) {
679 const double distSquared = ((*it)->posStart()-pos).mag2();
682 if (distSquared>=minDistSq)
685 flightTime = (*it)->hitTime() -
hitTime;
686 if (flightTime<=0||flightTime>100*CLHEP::ns) {
689 theclass->message(
"closestCompatibleHandleItr WARNING: Should never happen. T1="+
str(
hitTime)+
", T2="+
str((*it)->hitTime()));
692 if (distSquared>flightTime*flightTime*speedSqMax)
698 double mindotproduct = -0.5;
699 if (mom>10.0*CLHEP::MeV) {
700 mindotproduct = -0.1;
701 if (mom>1000.0*CLHEP::MeV) {
703 if (mom>10000.0*CLHEP::MeV) {
704 mindotproduct = 0.80;
708 if (mindotproduct>-1.0)
709 if (handle->momentumDirection().dot((*it)->momentumDirection())<mindotproduct)
725 minDistSq = distSquared;
728 if (distSquared<15*15*CLHEP::cm*CLHEP::cm) {
730 if (distSquared<5*5*CLHEP::cm*CLHEP::cm)
731 maxchecked = ichecked + 5;
733 maxchecked = ichecked + 15;
736 if (ichecked>maxchecked)
751 static double unknown = -1.0e99;
752 double mom(unknown), time(unknown);
756 mom =
mag(p->momentum());
757 time = v->position().t()/CLHEP::c_light;
766 bool sawhitwithoutmominfo(
false);
767 bool sawhitwithmominfo(mom!=unknown);
768 SimHitList::iterator it(hitlist.begin()), itE(hitlist.end());
769 for (;it!=itE;++it) {
770 const bool hasinfo = it->second->momentum()>=0.0;
772 sawhitwithmominfo =
true;
774 sawhitwithoutmominfo =
true;
775 if (sawhitwithoutmominfo&&sawhitwithmominfo)
779 if (!sawhitwithoutmominfo) {
783 if (!sawhitwithmominfo) {
785 theclass->messageDebug(
"Discarding hitlist." );
786 SimHitList::iterator it(hitlist.begin()), itE(hitlist.end());
808 if (hitlist.at(0).second->momentum()<0.0) {
809 SimHitList::iterator it(hitlist.begin()), itE(hitlist.end());
810 for (;it!=itE;++it) {
811 if (it->second->momentum()>=0.0) {
812 hitlist.at(0).second->setFakeMomentum(it->second->momentum()*1.00001);
816 if (hitlist.at(0).second->momentum()<0.0) {
817 theclass->messageDebug(
"fixMomentumInfoInSimHits ERROR: Should not happen! (1)" );
822 mom = hitlist.at(0).second->momentum();
823 time = hitlist.at(0).second->hitTime();
831 unsigned ilast = hitlist.size()-1;
832 if (hitlist.at(ilast).second->momentum()<0.0) {
833 for (
int iLastWithMom = ilast-1;iLastWithMom>=0;--iLastWithMom) {
834 if (hitlist.at(iLastWithMom).second->momentum()>0.0) {
835 hitlist.at(ilast).second->setFakeMomentum(hitlist.at(iLastWithMom).second->momentum()*0.99999);
839 if (hitlist.at(ilast).second->momentum()<0.0) {
842 theclass->messageDebug(
"fixMomentumInfoInSimHits ERROR: Should not happen! (2)" );
846 hitlist.at(ilast).second->setFakeMomentum(mom*0.99999);
851 if (mom==unknown||time==unknown) {
853 mom = hitlist.at(0).second->momentum();
854 time = hitlist.at(0).second->hitTime();
857 unsigned iNextWithMom(0);
858 for (
unsigned i = 0; i < hitlist.size(); ++i) {
859 if (hitlist.at(i).second->momentum()>=0.0) {
860 mom = hitlist.at(i).second->momentum();
861 time = hitlist.at(i).second->hitTime();
864 if (iNextWithMom<=i) {
865 for (
unsigned j = i+1;j<hitlist.size();++j) {
866 if (hitlist.at(j).second->momentum()>=0.0) {
871 if (iNextWithMom<=i) {
872 theclass->messageDebug(
"fixMomentumInfoInSimHits ERROR: Should not happen! (3)" );
878 double time2 = hitlist.at(iNextWithMom).second->hitTime();
879 double mom2 = hitlist.at(iNextWithMom).second->momentum();
880 double t = hitlist.at(i).second->hitTime();
883 if (t<=time||t>=time2||time2<=time)
884 theclass->message(
"SUSPICIOUS TIME");
886 theclass->message(
"SUSPICIOUS MOM mom="+
str(mom)+
", mom2="+
str(mom2));
887 mom += (mom2-mom)*(t-time)/(time2-time);
889 hitlist.at(i).second->setFakeMomentum(mom);
958 theclass->message(
"updateVisibleAssociatedObjects");
960 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
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)
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::FourVector FourVector
HepMC3::ConstGenParticlePtr ConstGenParticlePtr
HepMC3::ConstGenVertexPtr ConstGenVertexPtr
HepMC3::GenEvent GenEvent