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
23 
26 
27 #include "G4VProcess.hh"
28 #include "G4Track.hh"
29 #include "G4ThreeVector.hh"
30 #include "G4SystemOfUnits.hh"
31 
32 //#define DebugLog
33 namespace {
34  const double invcm = 1.0 / CLHEP::cm;
35  const double r_limit2 = 1.e-6; // 10 micron in CMS units
36 } // namespace
37 
39  idsave.reserve(1000);
40  ancestorList.reserve(1000);
41  m_trackContainer.reserve(1000);
42  m_endPoints.reserve(1000);
43 }
44 
46 
48  deleteTracks();
50  idsave.clear();
51  ancestorList.clear();
52  lastTrack = 0;
53  lastHist = 0;
54 }
55 
57  if (!m_trackContainer.empty()) {
58  for (auto const& ptr : m_trackContainer) {
59  delete ptr;
60  }
61  m_trackContainer.clear();
62  m_endPoints.clear();
63  }
64 }
65 
67  m_vertexMap.clear();
69  m_nVertices = 0;
70 }
71 
72 void SimTrackManager::addTrack(TrackWithHistory* iTrack, const G4Track* track, bool inHistory, bool withAncestor) {
73  std::pair<int, int> thePair(iTrack->trackID(), iTrack->parentID());
74  idsave.push_back(thePair);
75  if (inHistory) {
76  m_trackContainer.push_back(iTrack);
77  const auto& v = track->GetStep()->GetPostStepPoint()->GetPosition();
78  std::pair<int, math::XYZVectorD> p(iTrack->trackID(),
79  math::XYZVectorD(v.x() * invcm, v.y() * invcm, v.z() * invcm));
80  m_endPoints.push_back(p);
81  }
82  if (withAncestor) {
83  std::pair<int, int> thisPair(iTrack->trackID(), 0);
84  ancestorList.push_back(thisPair);
85  }
86 }
87 
90  TrackWithHistory* trkH = trkWHist;
91  if (trkH == nullptr) {
92  edm::LogError("SimTrackManager") << " SimTrackManager::saveTrackAndItsBranch got 0 pointer ";
93  throw cms::Exception("SimTrackManager::saveTrackAndItsBranch") << " cannot handle hits for tracking";
94  }
95  trkH->setToBeSaved();
96  int parent = trkH->parentID();
97 
98  auto tk_itr =
100 
101  if (tk_itr != m_trackContainer.end() && (*tk_itr)->trackID() == parent) {
102  saveTrackAndItsBranch(*tk_itr);
103  }
104 }
105 
108 
109  // fill the map with the final mother-daughter relationship
110  idsave.swap(ancestorList);
111  std::stable_sort(idsave.begin(), idsave.end());
112 
113  std::vector<std::pair<int, int> >().swap(ancestorList);
114 
115  // to get a backward compatible order
116  std::stable_sort(m_trackContainer.begin(), m_trackContainer.end(), trkIDLess());
117 
118  // to reset the GenParticle ID of a SimTrack to its pre-LHCTransport value
119  resetGenID();
120 
122 }
123 
125  // loop over the (now ordered) vector and really save the tracks
126 #ifdef DebugLog
127  edm::LogVerbatim("SimTrackManager") << "reallyStoreTracks() NtracksWithHistory= " << m_trackContainer->size();
128 #endif
129 
130  int nn = m_endPoints.size();
131  for (auto& trkH : m_trackContainer) {
132  // at this stage there is one vertex per track,
133  // so the vertex id of track N is also N
134  int iParentID = trkH->parentID();
135  int ig = trkH->genParticleID();
136  int ivertex = getOrCreateVertex(trkH, iParentID);
137 
138  auto ptr = trkH;
139  if (0 < iParentID) {
140  for (auto& trk : m_trackContainer) {
141  if (trk->trackID() == iParentID) {
142  ptr = trk;
143  break;
144  }
145  }
146  }
147  // Track at surface is the track at intersection point between tracker and calo
148  // envelops if exist. If not exist the momentum is zero, position is the end of
149  // the track
150  const math::XYZVectorD& pm = ptr->momentum();
151  math::XYZVectorD spos(0., 0., 0.);
152  math::XYZTLorentzVectorD smom(0., 0., 0., 0.);
153  int id = trkH->trackID();
154  if (trkH->crossedBoundary()) {
155  spos = trkH->getPositionAtBoundary();
156  smom = trkH->getMomentumAtBoundary();
157  } else {
158  for (int i = 0; i < nn; ++i) {
159  if (id == m_endPoints[i].first) {
160  spos = m_endPoints[i].second;
161  break;
162  }
163  }
164  }
165 
166  if (id >= static_cast<int>(PSimHit::k_tidOffset)) {
167  throw cms::Exception("SimTrackManager::reallyStoreTracks")
168  << " SimTrack ID " << id << " exceeds maximum allowed by PSimHit identifier" << PSimHit::k_tidOffset;
169  }
170  TmpSimTrack* g4simtrack =
171  new TmpSimTrack(id, trkH->particleID(), trkH->momentum(), trkH->totalEnergy(), ivertex, ig, pm, spos, smom);
172  g4simtrack->copyCrossedBoundaryVars(trkH);
173  m_simEvent->add(g4simtrack);
174  }
175 }
176 
178  int parent = -1;
179  for (auto const& trk : m_trackContainer) {
180  int id = trk->trackID();
181  if (id == iParentID) {
182  parent = id;
183  break;
184  }
185  }
186 
187  VertexMap::const_iterator iterator = m_vertexMap.find(parent);
188  if (iterator != m_vertexMap.end()) {
189  // loop over saved vertices
190  for (auto const& xx : m_vertexMap[parent]) {
191  if ((trkH->vertexPosition() - xx.second).Mag2() < r_limit2) {
192  return xx.first;
193  }
194  }
195  }
196 
197  m_simEvent->add(new TmpSimVertex(trkH->vertexPosition(), trkH->time(), parent, trkH->processType()));
199  ++m_nVertices;
200  return (m_nVertices - 1);
201 }
202 
203 int SimTrackManager::idSavedTrack(int id) const {
204  int idMother = id;
205  if (id > 0) {
206  unsigned int n = idsave.size();
207  if (0 < n) {
208  int jmax = n - 1;
209  int j, id1;
210 
211  // first loop forward
212  bool notFound = true;
213  for (j = 0; j <= jmax; ++j) {
214  if ((idsave[j]).first == idMother) {
215  id1 = (idsave[j]).second;
216  if (0 == id1 || id1 == idMother) {
217  return id1;
218  }
219  jmax = j - 1;
220  idMother = id1;
221  notFound = false;
222  break;
223  }
224  }
225  if (notFound) {
226  return 0;
227  }
228 
229  // recursive loop
230  do {
231  notFound = true;
232  // search ID scan backward
233  for (j = jmax; j >= 0; --j) {
234  if ((idsave[j]).first == idMother) {
235  id1 = (idsave[j]).second;
236  if (0 == id1 || id1 == idMother) {
237  return id1;
238  }
239  jmax = j - 1;
240  idMother = id1;
241  notFound = false;
242  break;
243  }
244  }
245  if (notFound) {
246  // ID not in the list of saved track - look into ancestors
247  jmax = ancestorList.size() - 1;
248  for (j = jmax; j >= 0; --j) {
249  if ((ancestorList[j]).first == idMother) {
250  idMother = (ancestorList[j]).second;
251  return idMother;
252  }
253  }
254  return 0;
255  }
256  } while (!notFound);
257  }
258  }
259  return idMother;
260 }
261 
263  if (!ancestorList.empty() && lastHist > ancestorList.size()) {
264  lastHist = ancestorList.size();
265  edm::LogError("SimTrackManager") << " SimTrackManager::fillMotherList track index corrupted";
266  }
267 #ifdef DebugLog
268  edm::LogVerbatim("SimTrackManager") << "### SimTrackManager::fillMotherList: " << idsave.size()
269  << " saved; ancestor: " << lastHist << " " << ancestorList.size();
270  for (unsigned int i = 0; i < idsave.size(); ++i) {
271  edm::LogVerbatim("SimTrackManager") << " ISV: Track ID = " << (idsave[i]).first
272  << " Mother ID = " << (idsave[i]).second;
273  }
274 #endif
275  for (unsigned int n = lastHist; n < ancestorList.size(); ++n) {
276  int theMotherId = idSavedTrack((ancestorList[n]).first);
277  ancestorList[n].second = theMotherId;
278 #ifdef DebugLog
279  LogDebug("SimTrackManager") << "Track ID = " << (ancestorList[n]).first
280  << " Mother ID = " << (ancestorList[n]).second;
281 #endif
282  }
283 
284  lastHist = ancestorList.size();
285  idsave.clear();
286 }
287 
289  if (m_trackContainer.empty() && idsave.empty()) {
290  return;
291  }
292 
293 #ifdef DebugLog
294  LogDebug("SimTrackManager") << "SimTrackManager::cleanTracksWithHistory has " << idsave.size()
295  << " mother-daughter relationships stored with lastTrack = " << lastTrack;
296 #endif
297 
298  if (lastTrack > 0 && lastTrack >= m_trackContainer.size()) {
299  lastTrack = 0;
300  edm::LogError("SimTrackManager") << " SimTrackManager::cleanTracksWithHistory track index corrupted";
301  }
302 
303  std::stable_sort(m_trackContainer.begin() + lastTrack, m_trackContainer.end(), trkIDLess());
304  std::stable_sort(idsave.begin(), idsave.end());
305 
306 #ifdef DebugLog
307  LogDebug("SimTrackManager") << " SimTrackManager::cleanTracksWithHistory knows " << m_trksForThisEvent->size()
308  << " tracks with history before branching";
309  for (unsigned int it = 0; it < m_trackContainer.size(); it++) {
310  LogDebug("SimTrackManager") << " 1 - Track in position " << it << " G4 track number "
311  << m_trackContainer[it]->trackID() << " mother " << m_trackContainer[it]->parentID()
312  << " status " << m_trackContainer[it]->saved();
313  }
314 #endif
315 
316  for (auto const& t : m_trackContainer) {
317  if (t->saved()) {
319  }
320  }
321  unsigned int num = lastTrack;
322  for (unsigned int it = lastTrack; it < m_trackContainer.size(); ++it) {
323  auto t = m_trackContainer[it];
324  int g4ID = m_trackContainer[it]->trackID();
325  if (t->saved()) {
326  if (it > num) {
328  }
329  ++num;
330  for (auto& xx : idsave) {
331  if (xx.first == g4ID) {
332  xx.second = g4ID;
333  break;
334  }
335  }
336  } else {
337  delete t;
338  }
339  }
340 
341  m_trackContainer.resize(num);
342 
343 #ifdef DebugLog
344  LogDebug("SimTrackManager") << " AFTER CLEANING, I GET " << m_trackContainer.size()
345  << " tracks to be saved persistently";
346  for (unsigned int it = 0; it < m_trackContainer.size(); ++it) {
347  LogDebug("SimTrackManager") << " Track in position " << it << " G4 track number " << m_trackContainer[it]->trackID()
348  << " mother " << m_trackContainer[it]->parentID() << " Status "
349  << m_trackContainer[it]->saved() << " id " << m_trackContainer[it]->particleID()
350  << " E(MeV)= " << m_trackContainer[it]->totalEnergy();
351  }
352 #endif
353 
354  fillMotherList();
355  lastTrack = m_trackContainer.size();
356 }
357 
359  if (theLHCTlink == nullptr)
360  return;
361 
362  for (auto const& trkH : m_trackContainer) {
363  int genParticleID = trkH->genParticleID();
364  if (genParticleID == -1) {
365  continue;
366  } else {
367  for (auto const& xx : *theLHCTlink) {
368  if (xx.afterHector() == genParticleID) {
369  trkH->setGenParticleID(xx.beforeHector());
370  continue;
371  }
372  }
373  }
374  }
375 
376  theLHCTlink = nullptr;
377 }
378 
379 void SimTrackManager::ReportException(unsigned int id) const {
380  throw cms::Exception("Unknown", "SimTrackManager::getTrackByID")
381  << "Fail to get track " << id << " from SimTrackManager, container size= " << m_trackContainer.size();
382 }
Log< level::Info, true > LogVerbatim
std::vector< TrackWithHistory * > m_trackContainer
VertexMap m_vertexMap
SimTrackManager(TmpSimEvent *)
int parentID() const
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > XYZTLorentzVectorD
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:14
std::pair< int, math::XYZVectorD > VertexPosition
const math::XYZVectorD & vertexPosition() const
void copyCrossedBoundaryVars(const TrackWithHistory *track)
Definition: TmpSimTrack.h:53
double time() const
Log< level::Error, false > LogError
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:112
unsigned int lastHist
TmpSimEvent * m_simEvent
U second(std::pair< T, U > const &p)
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > XYZVectorD
spatial vector with cartesian internal representation
Definition: Vector3D.h:8
static constexpr unsigned int k_tidOffset
Definition: PSimHit.h:17
void add(TmpSimTrack *t)
Definition: TmpSimEvent.h:33
void cleanTracksWithHistory()
void addTrack(TrackWithHistory *iTrack, const G4Track *track, bool inHistory, bool withAncestor)
std::vector< std::pair< int, int > > idsave
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)
int processType() const
int trackID() const
const edm::LHCTransportLinkContainer * theLHCTlink
int idSavedTrack(int) const
int getOrCreateVertex(TrackWithHistory *, int)
std::vector< std::pair< int, int > > ancestorList
void ReportException(unsigned int id) const
#define LogDebug(id)
std::vector< std::pair< int, math::XYZVectorD > > m_endPoints