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  TrackWithHistory* tempTk = *tk_itr;
85 
86  if (tk_itr != m_trksForThisEvent->end() && (*tk_itr)->trackID() == parent) {
87  saveTrackAndItsBranch(tempTk);
88  }
89 }
90 
93 
94  // fill the map with the final mother-daughter relationship
95  idsave.swap(ancestorList);
96  stable_sort(idsave.begin(), idsave.end());
97 
98  std::vector<std::pair<int, int> >().swap(ancestorList);
99 
100  // to get a backward compatible order
101  stable_sort(m_trksForThisEvent->begin(), m_trksForThisEvent->end(), trkIDLess());
102 
103  // to reset the GenParticle ID of a SimTrack to its pre-LHCTransport value
104  resetGenID();
105 
106  reallyStoreTracks(simEvent);
107 }
108 
110  // loop over the (now ordered) vector and really save the tracks
111 #ifdef DebugLog
112  LogDebug("SimTrackManager") << "Inside the reallyStoreTracks method object to be stored = "
113  << m_trksForThisEvent->size();
114 #endif
115 
116  for (unsigned int it = 0; it < m_trksForThisEvent->size(); it++) {
117  TrackWithHistory* trkH = (*m_trksForThisEvent)[it];
118  // at this stage there is one vertex per track,
119  // so the vertex id of track N is also N
120  int ivertex = -1;
121  int ig;
122 
123  math::XYZVectorD pm(0., 0., 0.);
124  unsigned int iParentID = trkH->parentID();
125  for (unsigned int iit = 0; iit < m_trksForThisEvent->size(); ++iit) {
126  if ((*m_trksForThisEvent)[iit]->trackID() == iParentID) {
127  pm = (*m_trksForThisEvent)[iit]->momentum();
128  break;
129  }
130  }
131  ig = trkH->genParticleID();
132  ivertex = getOrCreateVertex(trkH, iParentID, simEvent);
133  std::map<uint32_t, std::pair<math::XYZVectorD, math::XYZTLorentzVectorD> >::const_iterator cit =
134  mapTkCaloStateInfo.find(trkH->trackID());
135  std::pair<math::XYZVectorD, math::XYZTLorentzVectorD> tcinfo;
136  if (cit != mapTkCaloStateInfo.end()) {
137  tcinfo = cit->second;
138  }
139  G4SimTrack* g4simtrack = new G4SimTrack(trkH->trackID(),
140  trkH->particleID(),
141  trkH->momentum(),
142  trkH->totalEnergy(),
143  ivertex,
144  ig,
145  pm,
146  tcinfo.first,
147  tcinfo.second);
148  g4simtrack->copyCrossedBoundaryVars(trkH);
149  simEvent->add(g4simtrack);
150  }
151 }
152 
153 int SimTrackManager::getOrCreateVertex(TrackWithHistory* trkH, int iParentID, G4SimEvent* simEvent) {
154  int parent = iParentID;
155  int check = -1;
156 
157  for (std::vector<TrackWithHistory*>::const_iterator it = (*m_trksForThisEvent).begin();
158  it != (*m_trksForThisEvent).end();
159  it++) {
160  if ((*it)->trackID() == uint32_t(parent)) {
161  check = 0;
162  break;
163  }
164  }
165 
166  if (check == -1) {
167  parent = -1;
168  }
169 
170  VertexMap::const_iterator iterator = m_vertexMap.find(parent);
171  if (iterator != m_vertexMap.end()) {
172  // loop over saved vertices
173  for (unsigned int k = 0; k < m_vertexMap[parent].size(); k++) {
174  if (sqrt((trkH->vertexPosition() - (((m_vertexMap[parent])[k]).second)).Mag2()) < 0.001) {
175  return (((m_vertexMap[parent])[k]).first);
176  }
177  }
178  }
179 
180  unsigned int ptype = 0;
181  const G4VProcess* pr = trkH->creatorProcess();
182  if (pr) {
183  ptype = pr->GetProcessSubType();
184  }
185  simEvent->add(new G4SimVertex(trkH->vertexPosition(), trkH->globalTime(), parent, ptype));
187  m_nVertices++;
188  return (m_nVertices - 1);
189 }
190 
192  m_vertexMap.clear();
194  m_nVertices = 0;
195 }
196 
198  mapTkCaloStateInfo.clear();
199  std::map<uint32_t, std::pair<math::XYZVectorD, math::XYZTLorentzVectorD> >().swap(mapTkCaloStateInfo);
200 }
201 
202 int SimTrackManager::idSavedTrack(int id) const {
203  int idMother = id;
204  if (id > 0) {
205  unsigned int n = idsave.size();
206  if (0 < n) {
207  int jmax = n - 1;
208  int j, id1;
209 
210  // first loop forward
211  bool notFound = true;
212  for (j = 0; j <= jmax; ++j) {
213  if ((idsave[j]).first == idMother) {
214  id1 = (idsave[j]).second;
215  if (0 == id1 || id1 == idMother) {
216  return id1;
217  }
218  jmax = j - 1;
219  idMother = id1;
220  notFound = false;
221  break;
222  }
223  }
224  if (notFound) {
225  return 0;
226  }
227 
228  // recursive loop
229  do {
230  notFound = true;
231  // search ID scan backward
232  for (j = jmax; j >= 0; --j) {
233  if ((idsave[j]).first == idMother) {
234  id1 = (idsave[j]).second;
235  if (0 == id1 || id1 == idMother) {
236  return id1;
237  }
238  jmax = j - 1;
239  idMother = id1;
240  notFound = false;
241  break;
242  }
243  }
244  if (notFound) {
245  // ID not in the list of saved track - look into ancestors
246  jmax = ancestorList.size() - 1;
247  for (j = jmax; j >= 0; --j) {
248  if ((ancestorList[j]).first == idMother) {
249  idMother = (ancestorList[j]).second;
250  return idMother;
251  }
252  }
253  return 0;
254  }
255  } while (!notFound);
256  }
257  }
258  return idMother;
259 }
260 
262  if (!ancestorList.empty() && lastHist > ancestorList.size()) {
263  lastHist = ancestorList.size();
264  edm::LogError("SimTrackManager") << " SimTrackManager::fillMotherList track index corrupted";
265  }
266  /*
267  std::cout << "### SimTrackManager::fillMotherList: "
268  << idsave.size() << " saved; ancestor: " << lastHist
269  << " " << ancestorList.size() << std::endl;
270  for (unsigned int i = 0; i< idsave.size(); ++i) {
271  std::cout << " ISV: Track ID = " << (idsave[i]).first
272  << " Mother ID = " << (idsave[i]).second << std::endl;
273  }
274  */
275  for (unsigned int n = lastHist; n < ancestorList.size(); n++) {
276  int theMotherId = idSavedTrack((ancestorList[n]).first);
277  ancestorList[n].second = theMotherId;
278  /*
279  std::cout << " ANC: Track ID = " << (ancestorList[n]).first
280  << " Mother ID = " << (ancestorList[n]).second << std::endl;
281  */
282 #ifdef DebugLog
283  LogDebug("SimTrackManager") << "Track ID = " << (ancestorList[n]).first
284  << " Mother ID = " << (ancestorList[n]).second;
285 #endif
286  }
287 
288  lastHist = ancestorList.size();
289 
290  idsave.clear();
291 }
292 
294  if ((*m_trksForThisEvent).empty() && idsave.empty()) {
295  return;
296  }
297 
298 #ifdef DebugLog
299  LogDebug("SimTrackManager") << "SimTrackManager::cleanTracksWithHistory has " << idsave.size()
300  << " mother-daughter relationships stored with lastTrack = " << lastTrack;
301 #endif
302 
303  if (lastTrack > 0 && lastTrack >= (*m_trksForThisEvent).size()) {
304  lastTrack = 0;
305  edm::LogError("SimTrackManager") << " SimTrackManager::cleanTracksWithHistory track index corrupted";
306  }
307 
308  stable_sort(m_trksForThisEvent->begin() + lastTrack, m_trksForThisEvent->end(), trkIDLess());
309 
310  stable_sort(idsave.begin(), idsave.end());
311 
312 #ifdef DebugLog
313  LogDebug("SimTrackManager") << " SimTrackManager::cleanTracksWithHistory knows " << m_trksForThisEvent->size()
314  << " tracks with history before branching";
315  for (unsigned int it = 0; it < (*m_trksForThisEvent).size(); it++) {
316  LogDebug("SimTrackManager") << " 1 - Track in position " << it << " G4 track number "
317  << (*m_trksForThisEvent)[it]->trackID() << " mother "
318  << (*m_trksForThisEvent)[it]->parentID() << " status "
319  << (*m_trksForThisEvent)[it]->saved();
320  }
321 #endif
322 
323  for (unsigned int it = lastTrack; it < m_trksForThisEvent->size(); it++) {
324  TrackWithHistory* t = (*m_trksForThisEvent)[it];
325  if (t->saved()) {
327  }
328  }
329  unsigned int num = lastTrack;
330  for (unsigned int it = lastTrack; it < m_trksForThisEvent->size(); it++) {
331  TrackWithHistory* t = (*m_trksForThisEvent)[it];
332  int g4ID = t->trackID();
333  if (t->saved() == true) {
334  if (it > num)
335  (*m_trksForThisEvent)[num] = t;
336  num++;
337  for (unsigned int itr = 0; itr < idsave.size(); itr++) {
338  if ((idsave[itr]).first == g4ID) {
339  (idsave[itr]).second = g4ID;
340  break;
341  }
342  }
343  } else {
344  delete t;
345  }
346  }
347 
348  (*m_trksForThisEvent).resize(num);
349 
350 #ifdef DebugLog
351  LogDebug("SimTrackManager") << " AFTER CLEANING, I GET " << (*m_trksForThisEvent).size()
352  << " tracks to be saved persistently";
353  for (unsigned int it = 0; it < (*m_trksForThisEvent).size(); it++) {
354  LogDebug("SimTrackManager") << " Track in position " << it << " G4 track number "
355  << (*m_trksForThisEvent)[it]->trackID() << " mother "
356  << (*m_trksForThisEvent)[it]->parentID() << " Status "
357  << (*m_trksForThisEvent)[it]->saved() << " id "
358  << (*m_trksForThisEvent)[it]->particleID()
359  << " E(MeV)= " << (*m_trksForThisEvent)[it]->totalEnergy();
360  }
361 #endif
362 
363  fillMotherList();
364 
365  lastTrack = (*m_trksForThisEvent).size();
366 }
367 
369  if (theLHCTlink == nullptr)
370  return;
371 
372  for (unsigned int it = 0; it < m_trksForThisEvent->size(); it++) {
373  TrackWithHistory* trkH = (*m_trksForThisEvent)[it];
374  int genParticleID_ = trkH->genParticleID();
375  if (genParticleID_ == -1) {
376  continue;
377  } else {
378  for (unsigned int itrlink = 0; itrlink < (*theLHCTlink).size(); itrlink++) {
379  if ((*theLHCTlink)[itrlink].afterHector() == genParticleID_) {
380  trkH->setGenParticleID((*theLHCTlink)[itrlink].beforeHector());
381  continue;
382  }
383  }
384  }
385  }
386 
387  theLHCTlink = nullptr;
388 }
void copyCrossedBoundaryVars(const TrackWithHistory *track)
Definition: G4SimTrack.h:77
double globalTime() const
int getOrCreateVertex(TrackWithHistory *, int, G4SimEvent *simEvent)
int parentID() const
const math::XYZVectorD & momentum() const
std::map< int, MapVertexPositionVector > MotherParticleToVertexMap
SimTrackManager(bool iCollapsePrimaryVertices=false)
const math::XYZVectorD & vertexPosition() const
double totalEnergy() const
void setGenParticleID(int i)
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)
int genParticleID() const
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
T sqrt(T t)
Definition: SSEVec.h:19
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
int particleID() const
unsigned int trackID() const
#define LogDebug(id)