Skip to content

Commit 19e8412

Browse files
authored
Merge pull request #46979 from AuroraPerego/g4TracksInfo
Add additional information to the `SimTrack`s
2 parents 15c5f5f + 26b0572 commit 19e8412

File tree

9 files changed

+106
-23
lines changed

9 files changed

+106
-23
lines changed

SimDataFormats/Track/interface/SimTrack.h

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ class SimTrack : public CoreSimTrack {
3434
bool noVertex() const { return ivert == -1; }
3535

3636
/// index of the corresponding Generator particle in the Event container (-1 if no Genpart)
37-
int genpartIndex() const { return igenpart; }
38-
bool noGenpart() const { return igenpart == -1; }
37+
bool isPrimary() const { return (trackInfo_ >> 1) & 1; }
38+
int genpartIndex() const { return isPrimary() ? igenpart : -1; }
39+
bool noGenpart() const { return isPrimary() ? igenpart == -1 : true; }
3940

4041
const math::XYZVectorD& trackerSurfacePosition() const { return tkposition; }
4142

@@ -51,27 +52,40 @@ class SimTrack : public CoreSimTrack {
5152
int idAtBoundary,
5253
math::XYZTLorentzVectorF positionAtBoundary,
5354
math::XYZTLorentzVectorF momentumAtBoundary) {
54-
crossedBoundary_ = crossedBoundary;
55+
if (crossedBoundary)
56+
trackInfo_ |= (1 << 2);
5557
idAtBoundary_ = idAtBoundary;
5658
positionAtBoundary_ = positionAtBoundary;
5759
momentumAtBoundary_ = momentumAtBoundary;
5860
}
59-
bool crossedBoundary() const { return crossedBoundary_; }
61+
bool crossedBoundary() const { return (trackInfo_ >> 2) & 1; }
6062
const math::XYZTLorentzVectorF& getPositionAtBoundary() const { return positionAtBoundary_; }
6163
const math::XYZTLorentzVectorF& getMomentumAtBoundary() const { return momentumAtBoundary_; }
6264
int getIDAtBoundary() const { return idAtBoundary_; }
6365

66+
bool isFromBackScattering() const { return trackInfo_ & 1; }
67+
void setFromBackScattering() { trackInfo_ |= 1; }
68+
69+
void setIsPrimary() { trackInfo_ |= (1 << 1); }
70+
void setGenParticleID(const int idx) { igenpart = idx; }
71+
int getPrimaryID() const { return igenpart; }
72+
uint8_t getTrackInfo() const { return trackInfo_; }
73+
6474
private:
6575
int ivert;
6676
int igenpart;
6777

6878
math::XYZVectorD tkposition;
6979
math::XYZTLorentzVectorD tkmomentum;
7080

71-
bool crossedBoundary_;
7281
int idAtBoundary_;
7382
math::XYZTLorentzVectorF positionAtBoundary_;
7483
math::XYZTLorentzVectorF momentumAtBoundary_;
84+
uint8_t trackInfo_;
85+
// explanation of trackInfo bits:
86+
// 00000001 = simTrack is from backscattering
87+
// 00000010 = simTrack is of a primary particle
88+
// 00000100 = simTrack crossed the boundary
7589
};
7690

7791
#include <iosfwd>

SimDataFormats/Track/src/SimTrack.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
#include "SimDataFormats/Track/interface/SimTrack.h"
22

3-
SimTrack::SimTrack() : ivert(-1), igenpart(-1), crossedBoundary_(false) {}
3+
SimTrack::SimTrack() : ivert(-1), igenpart(-1), trackInfo_(0) {}
44

55
SimTrack::SimTrack(int ipart, const math::XYZTLorentzVectorD& p)
6-
: Core(ipart, p), ivert(-1), igenpart(-1), crossedBoundary_(false) {}
6+
: Core(ipart, p), ivert(-1), igenpart(-1), trackInfo_(0) {}
77

88
SimTrack::SimTrack(int ipart, const math::XYZTLorentzVectorD& p, int iv, int ig)
9-
: Core(ipart, p), ivert(iv), igenpart(ig), crossedBoundary_(false) {}
9+
: Core(ipart, p), ivert(iv), igenpart(ig), trackInfo_(0) {}
1010

1111
SimTrack::SimTrack(int ipart,
1212
const math::XYZTLorentzVectorD& p,
1313
int iv,
1414
int ig,
1515
const math::XYZVectorD& tkp,
1616
const math::XYZTLorentzVectorD& tkm)
17-
: Core(ipart, p), ivert(iv), igenpart(ig), tkposition(tkp), tkmomentum(tkm), crossedBoundary_(false) {}
17+
: Core(ipart, p), ivert(iv), igenpart(ig), tkposition(tkp), tkmomentum(tkm), trackInfo_(0) {}
1818

19-
SimTrack::SimTrack(const CoreSimTrack& t, int iv, int ig) : Core(t), ivert(iv), igenpart(ig), crossedBoundary_(false) {}
19+
SimTrack::SimTrack(const CoreSimTrack& t, int iv, int ig) : Core(t), ivert(iv), igenpart(ig), trackInfo_(0) {}
2020

2121
std::ostream& operator<<(std::ostream& o, const SimTrack& t) {
2222
return o << (SimTrack::Core)(t) << ", " << t.vertIndex() << ", " << t.genpartIndex();

SimDataFormats/Track/src/classes_def.xml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,27 @@
44
<class name="CoreSimTrack" ClassVersion="10">
55
<version ClassVersion="10" checksum="3936841839"/>
66
</class>
7-
<class name="SimTrack" ClassVersion="12">
7+
<class name="SimTrack" ClassVersion="13">
8+
<version ClassVersion="13" checksum="1912247222"/>
89
<version ClassVersion="12" checksum="3470347245"/>
910
<version ClassVersion="11" checksum="1785575744"/>
1011
<version ClassVersion="10" checksum="1430205451"/>
12+
<ioread sourceClass = "SimTrack" version="[-12]" targetClass="SimTrack" source="" target="">
13+
<![CDATA[
14+
SimTrack tmp(newObj->type(), newObj->momentum(), newObj->vertIndex(), newObj->genpartIndex(), newObj->trackerSurfacePosition(), newObj->trackerSurfaceMomentum());
15+
tmp.setTrackId(newObj->trackId());
16+
tmp.setEventId(newObj->eventId());
17+
tmp.setCrossedBoundaryVars(
18+
newObj->crossedBoundary(), newObj->getIDAtBoundary(), newObj->getPositionAtBoundary(), newObj->getMomentumAtBoundary());
19+
if (newObj->isFromBackScattering()) {
20+
tmp.setFromBackScattering();
21+
}
22+
if (newObj->genpartIndex() != -1) {
23+
tmp.setIsPrimary();
24+
}
25+
*newObj=tmp;
26+
]]>
27+
</ioread>
1128
</class>
1229
<class name="edm::Wrapper<std::vector<SimTrack> >" />
1330
<class name="edm::RefProd<std::vector<SimTrack> >"/>

SimG4Core/Application/plugins/OscarMTProducer.cc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ void OscarMTProducer::produce(edm::Event& e, const edm::EventSetup& es) {
251251

252252
if (0 < m_verbose) {
253253
edm::LogVerbatim("SimG4CoreApplication")
254-
<< "Produced " << p2->size() << " SimVertecies: position(cm), time(s), parentID, vertexID, processType";
254+
<< "Produced " << p2->size() << " SimVertices: position(cm), time(s), parentID, vertexID, processType";
255255
if (1 < m_verbose) {
256256
int nn = p2->size();
257257
for (int i = 0; i < nn; ++i) {
@@ -260,12 +260,15 @@ void OscarMTProducer::produce(edm::Event& e, const edm::EventSetup& es) {
260260
}
261261
edm::LogVerbatim("SimG4CoreApplication")
262262
<< "Produced " << p1->size()
263-
<< " SimTracks: pdg, 4-momentum(GeV), vertexID, mcTruthID, flagBoundary, trackID at boundary";
263+
<< " SimTracks: G4 Id, pdg, 4-momentum(GeV), vertexID, mcTruthID, crossedBoundary -> trackID at boundary, from "
264+
"backscattering, isPrimary -> getPrimary";
264265
if (1 < m_verbose) {
265266
int nn = p1->size();
266267
for (int i = 0; i < nn; ++i) {
267-
edm::LogVerbatim("Track") << " " << i << ". " << (*p1)[i] << " " << (*p1)[i].crossedBoundary() << " "
268-
<< (*p1)[i].getIDAtBoundary();
268+
edm::LogVerbatim("Track") << " " << i << ". " << (*p1)[i].trackId() << ", " << (*p1)[i] << ", "
269+
<< (*p1)[i].crossedBoundary() << "-> " << (*p1)[i].getIDAtBoundary() << ", "
270+
<< (*p1)[i].isFromBackScattering() << ", " << (*p1)[i].isPrimary() << "-> "
271+
<< (*p1)[i].getPrimaryID();
269272
}
270273
}
271274
}

SimG4Core/Notification/interface/TmpSimTrack.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class TmpSimTrack {
4040
const math::XYZVectorD& momentum() const { return ip_; }
4141
double energy() const { return ie_; }
4242
int ivert() const { return ivert_; }
43-
int igenpart() const { return igenpart_; }
43+
int igenpart() const { return isPrimary_ ? igenpart_ : -1; }
4444
// parent momentum at interaction
4545
const math::XYZVectorD& parentMomentum() const { return parentMomentum_; }
4646
// Information at level of tracker surface
@@ -62,6 +62,12 @@ class TmpSimTrack {
6262
const math::XYZTLorentzVectorF& getPositionAtBoundary() const { return positionAtBoundary_; }
6363
const math::XYZTLorentzVectorF& getMomentumAtBoundary() const { return momentumAtBoundary_; }
6464
int getIDAtBoundary() const { return idAtBoundary_; }
65+
bool isFromBackScattering() const { return isFromBackScattering_; }
66+
void setFromBackScattering() { isFromBackScattering_ = true; }
67+
void setGenParticleID(int i) { igenpart_ = i; }
68+
bool isPrimary() const { return isPrimary_; }
69+
void setIsPrimary() { isPrimary_ = true; }
70+
int getPrimaryID() const { return igenpart_; }
6571

6672
private:
6773
int id_;
@@ -74,7 +80,9 @@ class TmpSimTrack {
7480
math::XYZVectorD parentMomentum_{math::XYZVectorD(0., 0., 0.)};
7581
math::XYZVectorD tkSurfacePosition_{math::XYZVectorD(0., 0., 0.)};
7682
math::XYZTLorentzVectorD tkSurfaceMomentum_{math::XYZTLorentzVectorD(0., 0., 0., 0.)};
83+
bool isFromBackScattering_{false};
7784
bool crossedBoundary_{false};
85+
bool isPrimary_{false};
7886
int idAtBoundary_{-1};
7987
math::XYZTLorentzVectorF positionAtBoundary_{math::XYZTLorentzVectorF(0.f, 0.f, 0.f, 0.f)};
8088
math::XYZTLorentzVectorF momentumAtBoundary_{math::XYZTLorentzVectorF(0.f, 0.f, 0.f, 0.f)};

SimG4Core/Notification/interface/TrackWithHistory.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class G4PrimaryParticle;
1414

1515
class TrackWithHistory {
1616
public:
17-
/** The constructor is called at time,
17+
/** The constructor is called at time,
1818
* when some of the information may not available yet.
1919
*/
2020
TrackWithHistory(const G4Track *g4track, int pID);
@@ -27,7 +27,7 @@ class TrackWithHistory {
2727
int trackID() const { return trackID_; }
2828
int particleID() const { return pdgID_; }
2929
int parentID() const { return parentID_; }
30-
int genParticleID() const { return genParticleID_; }
30+
int genParticleID() const { return isPrimary_ ? genParticleID_ : -1; }
3131
int vertexID() const { return vertexID_; }
3232
int processType() const { return procType_; }
3333
int getIDAtBoundary() const { return idAtBoundary_; }
@@ -67,6 +67,11 @@ class TrackWithHistory {
6767
tkSurfacePosition_ = pos;
6868
tkSurfaceMomentum_ = mom;
6969
}
70+
bool isFromBackScattering() const { return isFromBackScattering_; }
71+
void setFromBackScattering() { isFromBackScattering_ = true; }
72+
bool isPrimary() const { return isPrimary_; }
73+
void setIsPrimary() { isPrimary_ = true; }
74+
int getPrimaryID() const { return genParticleID_; }
7075

7176
private:
7277
int trackID_;
@@ -88,6 +93,8 @@ class TrackWithHistory {
8893
bool storeTrack_{false};
8994
bool saved_{false};
9095
bool crossedBoundary_{false};
96+
bool isFromBackScattering_{false};
97+
bool isPrimary_{false};
9198
};
9299

93100
extern G4ThreadLocal G4Allocator<TrackWithHistory> *fpTrackWithHistoryAllocator;

SimG4Core/Notification/src/SimTrackManager.cc

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ void SimTrackManager::addTrack(TrackWithHistory* iTrack, const G4Track* track, b
7373
std::pair<int, int> thePair(iTrack->trackID(), iTrack->parentID());
7474
idsave.push_back(thePair);
7575
if (inHistory) {
76+
auto info = static_cast<const TrackInformation*>(track->GetUserInformation());
77+
if (info->isInTrkFromBackscattering())
78+
iTrack->setFromBackScattering();
79+
// set there for the *non-primary* tracks the genParticle ID associated with the G4Track
80+
// for the primaries this is done in the TrackWithHistory constructor.
81+
// In the constructor of TrackWithHistory the info isPrimary is saved and used
82+
// to give -1 if the track is not a primary.
83+
if (not iTrack->isPrimary())
84+
iTrack->setGenParticleID(info->mcTruthID());
7685
m_trackContainer.push_back(iTrack);
7786
const auto& v = track->GetStep()->GetPostStepPoint()->GetPosition();
7887
std::pair<int, math::XYZVectorD> p(iTrack->trackID(),
@@ -124,15 +133,18 @@ void SimTrackManager::storeTracks() {
124133
void SimTrackManager::reallyStoreTracks() {
125134
// loop over the (now ordered) vector and really save the tracks
126135
#ifdef DebugLog
127-
edm::LogVerbatim("SimTrackManager") << "reallyStoreTracks() NtracksWithHistory= " << m_trackContainer->size();
136+
edm::LogVerbatim("SimTrackManager") << "reallyStoreTracks() NtracksWithHistory= " << m_trackContainer.size();
128137
#endif
129138

130139
int nn = m_endPoints.size();
131140
for (auto& trkH : m_trackContainer) {
132141
// at this stage there is one vertex per track,
133142
// so the vertex id of track N is also N
134143
int iParentID = trkH->parentID();
135-
int ig = trkH->genParticleID();
144+
int ig = trkH->genParticleID(); // filled only for primary tracks
145+
bool isBackScatter = trkH->isFromBackScattering();
146+
bool isPrimary = trkH->isPrimary();
147+
int primaryGenPartId = trkH->getPrimaryID(); // filled if the G4Track had this info
136148
int ivertex = getOrCreateVertex(trkH, iParentID);
137149

138150
auto ptr = trkH;
@@ -170,6 +182,11 @@ void SimTrackManager::reallyStoreTracks() {
170182
TmpSimTrack* g4simtrack =
171183
new TmpSimTrack(id, trkH->particleID(), trkH->momentum(), trkH->totalEnergy(), ivertex, ig, pm, spos, smom);
172184
g4simtrack->copyCrossedBoundaryVars(trkH);
185+
if (isBackScatter)
186+
g4simtrack->setFromBackScattering();
187+
if (isPrimary)
188+
g4simtrack->setIsPrimary();
189+
g4simtrack->setGenParticleID(primaryGenPartId);
173190
m_simEvent->addTrack(g4simtrack);
174191
}
175192
}
@@ -304,7 +321,7 @@ void SimTrackManager::cleanTracksWithHistory() {
304321
std::stable_sort(idsave.begin(), idsave.end());
305322

306323
#ifdef DebugLog
307-
LogDebug("SimTrackManager") << " SimTrackManager::cleanTracksWithHistory knows " << m_trksForThisEvent->size()
324+
LogDebug("SimTrackManager") << " SimTrackManager::cleanTracksWithHistory knows " << m_trackContainer.size()
308325
<< " tracks with history before branching";
309326
for (unsigned int it = 0; it < m_trackContainer.size(); it++) {
310327
LogDebug("SimTrackManager") << " 1 - Track in position " << it << " G4 track number "

SimG4Core/Notification/src/TmpSimEvent.cc

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,26 @@ void TmpSimEvent::load(edm::SimTrackContainer& c) const {
3535
int iv = trk->ivert();
3636
int ig = trk->igenpart();
3737
int id = trk->id();
38+
bool isBackScatter = trk->isFromBackScattering();
39+
bool isPrimary = trk->isPrimary();
40+
int primaryGenPartId = trk->getPrimaryID(); // filled if the G4Track had this info
3841
// ip = particle ID as PDG
39-
// pp = 4-momentum in GeV
42+
// p = 4-momentum in GeV
4043
// iv = corresponding TmpSimVertex index
41-
// ig = corresponding GenParticle index
44+
// ig = corresponding GenParticle index only if is a primary, otherwise is -1
45+
// primaryGenPartId = corresponding GenParticle index also if not primary
46+
// id = corresponding g4Track Id
4247
SimTrack t = SimTrack(ip, p, iv, ig, trk->trackerSurfacePosition(), trk->trackerSurfaceMomentum());
4348
t.setTrackId(id);
4449
t.setEventId(EncodedEventId(0));
4550
t.setCrossedBoundaryVars(
4651
trk->crossedBoundary(), trk->getIDAtBoundary(), trk->getPositionAtBoundary(), trk->getMomentumAtBoundary());
52+
if (isBackScatter)
53+
t.setFromBackScattering();
54+
if (isPrimary)
55+
t.setIsPrimary();
56+
else
57+
t.setGenParticleID(primaryGenPartId);
4758
c.push_back(t);
4859
}
4960
std::stable_sort(c.begin(), c.end(), IdSort());

SimG4Core/Notification/src/TrackWithHistory.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,15 @@ TrackWithHistory::TrackWithHistory(const G4Track* g4trk, int pID) {
2929
TrackInformation* trkinfo = static_cast<TrackInformation*>(g4trk->GetUserInformation());
3030
storeTrack_ = trkinfo->storeTrack();
3131
auto vgprimary = g4trk->GetDynamicParticle()->GetPrimaryParticle();
32+
// GetPrimaryParticle() returns the pointer to the corresponding G4PrimaryParticle object
33+
// if this particle is a primary particle OR is defined as a
34+
// pre-assigned decay product. Otherwise return nullptr.
35+
// Therefore here the genParticleID_ is -1 for not primary particles
3236
if (vgprimary != nullptr) {
3337
auto priminfo = static_cast<GenParticleInfo*>(vgprimary->GetUserInformation());
3438
if (nullptr != priminfo) {
3539
genParticleID_ = priminfo->id();
40+
isPrimary_ = true;
3641
}
3742
}
3843
// V.I. weight is computed in the same way as before
@@ -53,6 +58,7 @@ TrackWithHistory::TrackWithHistory(const G4PrimaryParticle* ptr, int trackID, co
5358
auto priminfo = static_cast<GenParticleInfo*>(ptr->GetUserInformation());
5459
if (nullptr != priminfo) {
5560
genParticleID_ = priminfo->id();
61+
isPrimary_ = true;
5662
}
5763
weight_ = 10000. * genParticleID_;
5864
}

0 commit comments

Comments
 (0)