CMS 3D CMS Logo

SimTrackManager.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Application
4 // Class : SimTrackManager
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author:
10 // Created: Fri Nov 25 17:44:19 EST 2005
11 //
12 
13 // system include files
14 #include <iostream>
15 
16 // user include files
21 
23 
24 #include "G4VProcess.hh"
25 
26 //#define DebugLog
27 
28 SimTrackManager::SimTrackManager(bool iCollapsePrimaryVertices)
29  : m_trksForThisEvent(nullptr),
30  m_nVertices(0),
31  m_collapsePrimaryVertices(iCollapsePrimaryVertices),
32  lastTrack(0),
33  lastHist(0),
34  theLHCTlink(nullptr) {}
35 
37  if (m_trksForThisEvent != nullptr)
38  deleteTracks();
39 }
40 
41 //
42 // member functions
43 //
45  if (m_trksForThisEvent == nullptr) {
47  } else {
48  for (unsigned int i = 0; i < m_trksForThisEvent->size(); i++) {
49  delete (*m_trksForThisEvent)[i];
50  }
51  delete m_trksForThisEvent;
53  }
56  std::vector<std::pair<int, int> >().swap(idsave);
57  ancestorList.clear();
58  lastTrack = 0;
59  lastHist = 0;
60 }
61 
63  for (unsigned int i = 0; i < m_trksForThisEvent->size(); ++i) {
64  delete (*m_trksForThisEvent)[i];
65  }
66  delete m_trksForThisEvent;
67  m_trksForThisEvent = nullptr;
68 }
69 
72  using namespace std;
73  TrackWithHistory* trkH = trkWHist;
74  if (trkH == nullptr) {
75  edm::LogError("SimTrackManager") << " SimTrackManager::saveTrackAndItsBranch got 0 pointer ";
76  throw cms::Exception("SimTrackManager::saveTrackAndItsBranch") << " cannot handle hits for tracking";
77  }
78  trkH->save();
79  unsigned int parent = trkH->parentID();
80 
81  TrackContainer::const_iterator tk_itr = std::lower_bound(
82  (*m_trksForThisEvent).begin(), (*m_trksForThisEvent).end(), parent, SimTrackManager::StrictWeakOrdering());
83 
84  if (tk_itr != m_trksForThisEvent->end() && (*tk_itr)->trackID() == parent) {
85  saveTrackAndItsBranch(*tk_itr);
86  }
87 }
88 
91 
92  // fill the map with the final mother-daughter relationship
93  idsave.swap(ancestorList);
94  stable_sort(idsave.begin(), idsave.end());
95 
96  std::vector<std::pair<int, int> >().swap(ancestorList);
97 
98  // to get a backward compatible order
99  stable_sort(m_trksForThisEvent->begin(), m_trksForThisEvent->end(), trkIDLess());
100 
101  // to reset the GenParticle ID of a SimTrack to its pre-LHCTransport value
102  resetGenID();
103 
104  reallyStoreTracks(simEvent);
105 }
106 
108  // loop over the (now ordered) vector and really save the tracks
109 #ifdef DebugLog
110  LogDebug("SimTrackManager") << "Inside the reallyStoreTracks method object to be stored = "
111  << m_trksForThisEvent->size();
112 #endif
113 
114  for (auto& trkH : *m_trksForThisEvent) {
115  // at this stage there is one vertex per track,
116  // so the vertex id of track N is also N
117  int ivertex = -1;
118  int ig;
119 
120  math::XYZVectorD pm(0., 0., 0.);
121  unsigned int iParentID = trkH->parentID();
122  for (auto& trk : *m_trksForThisEvent) {
123  if (trk->trackID() == iParentID) {
124  pm = trk->momentum();
125  break;
126  }
127  }
128  ig = trkH->genParticleID();
129  ivertex = getOrCreateVertex(trkH, iParentID, simEvent);
130  std::map<uint32_t, std::pair<math::XYZVectorD, math::XYZTLorentzVectorD> >::const_iterator cit =
131  mapTkCaloStateInfo.find(trkH->trackID());
132  std::pair<math::XYZVectorD, math::XYZTLorentzVectorD> tcinfo;
133  if (cit != mapTkCaloStateInfo.end()) {
134  tcinfo = cit->second;
135  }
136  G4SimTrack* g4simtrack = new G4SimTrack(trkH->trackID(),
137  trkH->particleID(),
138  trkH->momentum(),
139  trkH->totalEnergy(),
140  ivertex,
141  ig,
142  pm,
143  tcinfo.first,
144  tcinfo.second);
145  g4simtrack->copyCrossedBoundaryVars(trkH);
146  simEvent->add(g4simtrack);
147  }
148 }
149 
150 int SimTrackManager::getOrCreateVertex(TrackWithHistory* trkH, int iParentID, G4SimEvent* simEvent) {
151  int parent = -1;
152  for (auto& trk : *m_trksForThisEvent) {
153  int id = trk->trackID();
154  if (id == iParentID) {
155  parent = id;
156  break;
157  }
158  }
159 
160  VertexMap::const_iterator iterator = m_vertexMap.find(parent);
161  if (iterator != m_vertexMap.end()) {
162  // loop over saved vertices
163  for (auto& xx : m_vertexMap[parent]) {
164  if ((trkH->vertexPosition() - xx.second).Mag2() < 1.e-6) {
165  return xx.first;
166  }
167  }
168  }
169 
170  unsigned int ptype = 0;
171  const G4VProcess* pr = trkH->creatorProcess();
172  if (nullptr != pr) {
173  ptype = pr->GetProcessSubType();
174  }
175  simEvent->add(new G4SimVertex(trkH->vertexPosition(), trkH->globalTime(), parent, ptype));
177  ++m_nVertices;
178  return (m_nVertices - 1);
179 }
180 
182  m_vertexMap.clear();
184  m_nVertices = 0;
185 }
186 
188  mapTkCaloStateInfo.clear();
189  std::map<uint32_t, std::pair<math::XYZVectorD, math::XYZTLorentzVectorD> >().swap(mapTkCaloStateInfo);
190 }
191 
192 int SimTrackManager::idSavedTrack(int id) const {
193  int idMother = id;
194  if (id > 0) {
195  unsigned int n = idsave.size();
196  if (0 < n) {
197  int jmax = n - 1;
198  int j, id1;
199 
200  // first loop forward
201  bool notFound = true;
202  for (j = 0; j <= jmax; ++j) {
203  if ((idsave[j]).first == idMother) {
204  id1 = (idsave[j]).second;
205  if (0 == id1 || id1 == idMother) {
206  return id1;
207  }
208  jmax = j - 1;
209  idMother = id1;
210  notFound = false;
211  break;
212  }
213  }
214  if (notFound) {
215  return 0;
216  }
217 
218  // recursive loop
219  do {
220  notFound = true;
221  // search ID scan backward
222  for (j = jmax; j >= 0; --j) {
223  if ((idsave[j]).first == idMother) {
224  id1 = (idsave[j]).second;
225  if (0 == id1 || id1 == idMother) {
226  return id1;
227  }
228  jmax = j - 1;
229  idMother = id1;
230  notFound = false;
231  break;
232  }
233  }
234  if (notFound) {
235  // ID not in the list of saved track - look into ancestors
236  jmax = ancestorList.size() - 1;
237  for (j = jmax; j >= 0; --j) {
238  if ((ancestorList[j]).first == idMother) {
239  idMother = (ancestorList[j]).second;
240  return idMother;
241  }
242  }
243  return 0;
244  }
245  } while (!notFound);
246  }
247  }
248  return idMother;
249 }
250 
252  if (!ancestorList.empty() && lastHist > ancestorList.size()) {
253  lastHist = ancestorList.size();
254  edm::LogError("SimTrackManager") << " SimTrackManager::fillMotherList track index corrupted";
255  }
256  /*
257  edm::LogVerbatim("SimTrackManager") << "### SimTrackManager::fillMotherList: "
258  << idsave.size() << " saved; ancestor: " << lastHist
259  << " " << ancestorList.size() << std::endl;
260  for (unsigned int i = 0; i< idsave.size(); ++i) {
261  edm::LogVerbatim("SimTrackManager") << " ISV: Track ID = " << (idsave[i]).first
262  << " Mother ID = " << (idsave[i]).second << std::endl;
263  }
264  */
265  for (unsigned int n = lastHist; n < ancestorList.size(); ++n) {
266  int theMotherId = idSavedTrack((ancestorList[n]).first);
267  ancestorList[n].second = theMotherId;
268  /*
269  std::cout << " ANC: Track ID = " << (ancestorList[n]).first
270  << " Mother ID = " << (ancestorList[n]).second << std::endl;
271  */
272 #ifdef DebugLog
273  LogDebug("SimTrackManager") << "Track ID = " << (ancestorList[n]).first
274  << " Mother ID = " << (ancestorList[n]).second;
275 #endif
276  }
277 
278  lastHist = ancestorList.size();
279 
280  idsave.clear();
281 }
282 
284  if ((*m_trksForThisEvent).empty() && idsave.empty()) {
285  return;
286  }
287 
288 #ifdef DebugLog
289  LogDebug("SimTrackManager") << "SimTrackManager::cleanTracksWithHistory has " << idsave.size()
290  << " mother-daughter relationships stored with lastTrack = " << lastTrack;
291 #endif
292 
293  if (lastTrack > 0 && lastTrack >= (*m_trksForThisEvent).size()) {
294  lastTrack = 0;
295  edm::LogError("SimTrackManager") << " SimTrackManager::cleanTracksWithHistory track index corrupted";
296  }
297 
298  stable_sort(m_trksForThisEvent->begin() + lastTrack, m_trksForThisEvent->end(), trkIDLess());
299 
300  stable_sort(idsave.begin(), idsave.end());
301 
302 #ifdef DebugLog
303  LogDebug("SimTrackManager") << " SimTrackManager::cleanTracksWithHistory knows " << m_trksForThisEvent->size()
304  << " tracks with history before branching";
305  for (unsigned int it = 0; it < (*m_trksForThisEvent).size(); it++) {
306  LogDebug("SimTrackManager") << " 1 - Track in position " << it << " G4 track number "
307  << (*m_trksForThisEvent)[it]->trackID() << " mother "
308  << (*m_trksForThisEvent)[it]->parentID() << " status "
309  << (*m_trksForThisEvent)[it]->saved();
310  }
311 #endif
312 
313  for (auto& t : *m_trksForThisEvent) {
314  if (t->saved()) {
316  }
317  }
318  unsigned int num = lastTrack;
319  for (unsigned int it = lastTrack; it < m_trksForThisEvent->size(); ++it) {
320  TrackWithHistory* t = (*m_trksForThisEvent)[it];
321  int g4ID = t->trackID();
322  if (t->saved() == true) {
323  if (it > num)
324  (*m_trksForThisEvent)[num] = t;
325  ++num;
326  for (auto& xx : idsave) {
327  if (xx.first == g4ID) {
328  xx.second = g4ID;
329  break;
330  }
331  }
332  } else {
333  delete t;
334  }
335  }
336 
337  m_trksForThisEvent->resize(num);
338 
339 #ifdef DebugLog
340  LogDebug("SimTrackManager") << " AFTER CLEANING, I GET " << (*m_trksForThisEvent).size()
341  << " tracks to be saved persistently";
342  for (unsigned int it < (*m_trksForThisEvent).size(); ++it) {
343  LogDebug("SimTrackManager") << " Track in position " << it << " G4 track number "
344  << (*m_trksForThisEvent)[it]->trackID() << " mother "
345  << (*m_trksForThisEvent)[it]->parentID() << " Status "
346  << (*m_trksForThisEvent)[it]->saved() << " id "
347  << (*m_trksForThisEvent)[it]->particleID()
348  << " E(MeV)= " << (*m_trksForThisEvent)[it]->totalEnergy();
349  }
350 #endif
351 
352  fillMotherList();
353 
354  lastTrack = (*m_trksForThisEvent).size();
355 }
356 
358  if (theLHCTlink == nullptr)
359  return;
360 
361  for (auto& trkH : *m_trksForThisEvent) {
362  int genParticleID = trkH->genParticleID();
363  if (genParticleID == -1) {
364  continue;
365  } else {
366  for (auto& xx : *theLHCTlink) {
367  if (xx.afterHector() == genParticleID) {
368  trkH->setGenParticleID(xx.beforeHector());
369  continue;
370  }
371  }
372  }
373  }
374 
375  theLHCTlink = nullptr;
376 }
void copyCrossedBoundaryVars(const TrackWithHistory *track)
Definition: G4SimTrack.h:76
double globalTime() const
int getOrCreateVertex(TrackWithHistory *, int, G4SimEvent *simEvent)
int parentID() const
std::map< int, MapVertexPositionVector > MotherParticleToVertexMap
SimTrackManager(bool iCollapsePrimaryVertices=false)
const math::XYZVectorD & vertexPosition() const
Log< level::Error, false > LogError
void cleanTkCaloStateInfoMap()
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:117
unsigned int lastHist
virtual ~SimTrackManager()
TrackContainer * m_trksForThisEvent
U second(std::pair< T, U > const &p)
void add(G4SimTrack *t)
Definition: G4SimEvent.h:33
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > XYZVectorD
spatial vector with cartesian internal representation
Definition: Vector3D.h:8
std::vector< TrackWithHistory * > TrackContainer
Definition: TrackContainer.h:8
void cleanTracksWithHistory()
MotherParticleToVertexMap m_vertexMap
void storeTracks(G4SimEvent *simEvent)
std::vector< std::pair< int, int > > idsave
std::map< uint32_t, std::pair< math::XYZVectorD, math::XYZTLorentzVectorD > > mapTkCaloStateInfo
std::pair< int, math::XYZVectorD > MapVertexPosition
this map contains association between vertex number and position
void saveTrackAndItsBranch(TrackWithHistory *)
this saves a track and all its parents looping over the non ordered vector
unsigned int lastTrack
static const GlobalPoint notFound(0, 0, 0)
const edm::LHCTransportLinkContainer * theLHCTlink
void reallyStoreTracks(G4SimEvent *simEvent)
int idSavedTrack(int) const
std::vector< std::pair< int, int > > ancestorList
const G4VProcess * creatorProcess() const
#define LogDebug(id)