Belle II Software  release-06-01-15
PhotosHEPEVTParticle.cc
1 #include "PhotosHEPEVTParticle.h"
2 #include "Log.h"
3 
4 namespace Photospp {
5 
7  {
8  // Cleanup particles that do not belong to event
9  for (unsigned int i = 0; i < cache.size(); i++)
10  if (cache[i]->m_barcode < 0)
11  delete cache[i];
12  }
13 
14  PhotosHEPEVTParticle::PhotosHEPEVTParticle(int pdgid, int status, double px, double py, double pz, double e, double m, int ms,
15  int me, int ds, int de)
16  {
17  m_px = px;
18  m_py = py;
19  m_pz = pz;
20  m_e = e;
21  m_generated_mass = m;
22 
23  m_pdgid = pdgid;
24  m_status = status;
25 
26  m_first_mother = ms;
27  m_second_mother = me;
28  m_daughter_start = ds;
29  m_daughter_end = de;
30 
31  m_barcode = -1;
32  m_event = NULL;
33  }
34 
37  {
38  if (!m_event) Log::Fatal("PhotosHEPEVTParticle::addDaughter - particle not in event record");
39 
40  std::vector<PhotosParticle*> mothers = daughter->getMothers();
41 
42  mothers.push_back((PhotosParticle*)this);
43 
44  daughter->setMothers(mothers);
45 
46  int bc = daughter->getBarcode();
47 
48  if (m_daughter_end < 0) {
49  m_daughter_start = bc;
50  m_daughter_end = bc;
51  }
52  // if it's in the middle of the event record
53  else if (m_daughter_end != bc - 1) {
55 
56  // Move all particles one spot down the list, to make place for new particle
57  for (int i = bc - 1; i > m_daughter_end; i--) {
59  move->setBarcode(i + 1);
60  m_event->setParticle(i + 1, move);
61  }
62 
63  m_daughter_end++;
64  newPart->setBarcode(m_daughter_end);
65  m_event->setParticle(m_daughter_end, newPart);
66 
67  // Now: correct all daughter pointers that point after new particle
68  for (int i = 0; i < m_event->getParticleCount(); i++) {
70  int m = check->getDaughterRangeEnd();
71  if (m != -1 && m > m_daughter_end) {
72  check->setDaughterRangeEnd(m + 1);
73  check->setDaughterRangeStart(check->getDaughterRangeStart() + 1);
74  }
75  }
76 
77  // Then: correct all mother pointers for particles after new particle
78  for (int i = m_daughter_end + 1; i < m_event->getParticleCount(); i++) {
80 
81  int m1 = check->m_first_mother;
82  int m2 = check->m_second_mother;
83 
84  if (m1 > m_daughter_end) {
85  ++check->m_first_mother;
86  }
87  if (m2 > m_daughter_end) {
88  ++check->m_second_mother;
89  }
90  }
91 
92  } else m_daughter_end = bc;
93  }
94 
95  void PhotosHEPEVTParticle::setMothers(vector<PhotosParticle*> mothers)
96  {
97 
98  // If this particle has not yet been added to the event record
99  // then add it to the mothers' event record
100  if (m_barcode < 0 && mothers.size() > 0) {
101  PhotosHEPEVTEvent* evt = ((PhotosHEPEVTParticle*)mothers[0])->m_event;
102  evt->addParticle(this);
103  }
104 
105  if (mothers.size() > 2) Log::Fatal("PhotosHEPEVTParticle::setMothers: HEPEVT does not allow more than two mothers!");
106 
107  if (mothers.size() > 0) m_first_mother = mothers[0]->getBarcode();
108  if (mothers.size() > 1) m_second_mother = mothers[1]->getBarcode();
109  }
110 
111  void PhotosHEPEVTParticle::setDaughters(vector<PhotosParticle*> daughters)
112  {
113 
114  // This particle must be inside some event record to be able to add daughters
115  if (m_event == NULL) Log::Fatal("PhotosHEPEVTParticle::setDaughters: particle not inside event record.");
116 
117  int beg = 65535, end = -1;
118 
119  for (unsigned int i = 0; i < daughters.size(); i++) {
120  int bc = daughters[i]->getBarcode();
121  if (bc < 0) Log::Fatal("PhotosHEPEVTParticle::setDaughters: all daughters has to be in event record first");
122  if (bc < beg) beg = bc;
123  if (bc > end) end = bc;
124  }
125  if (end == -1) beg = -1;
126 
127  m_daughter_start = beg;
128  m_daughter_end = end;
129  }
130 
131  std::vector<PhotosParticle*> PhotosHEPEVTParticle::getMothers()
132  {
133 
134  std::vector<PhotosParticle*> mothers;
135 
136  PhotosParticle* p1 = NULL;
137  PhotosParticle* p2 = NULL;
138 
139  // 21.XI.2013: Some generators set same mother ID in both indices if there is only one mother
140  if (m_first_mother == m_second_mother) m_second_mother = -1;
141 
143  if (m_second_mother >= 0) p2 = m_event->getParticle(m_second_mother);
144 
145  if (p1) mothers.push_back(p1);
146  if (p2) mothers.push_back(p2);
147 
148  return mothers;
149  }
150 
151 // WARNING: this method also corrects daughter indices
152 // if such were not defined
153  std::vector<PhotosParticle*> PhotosHEPEVTParticle::getDaughters()
154  {
155 
156  std::vector<PhotosParticle*> daughters;
157 
158  if (!m_event) return daughters;
159 
160  // Check if m_daughter_start and m_daughter_end are set
161  // If not - try to get list of daughters from event
162  if (m_daughter_end < 0) {
163  int min_d = 65535, max_d = -1;
164  for (int i = 0; i < m_event->getParticleCount(); i++) {
165  if (m_event->getParticle(i)->isDaughterOf(this)) {
166  if (i < min_d) min_d = i;
167  if (i > max_d) max_d = i;
168  }
169  }
170  if (max_d >= 0) {
171  m_daughter_start = min_d;
172  m_daughter_end = max_d;
173  m_status = 2;
174  }
175  }
176 
177  // If m_daughter_end is still not set - there are no daughters
178  // Otherwsie - get daughters
179  if (m_daughter_end >= 0) {
180  for (int i = m_daughter_start; i <= m_daughter_end; i++) {
182  if (p == NULL) {
183  Log::Warning() << "PhotosHEPEVTParticle::getDaughters(): No particle with index " << i << endl;
184  return daughters;
185  }
186 
187  daughters.push_back(p);
188  }
189  }
190 
191  return daughters;
192  }
193 
194  std::vector<PhotosParticle*> PhotosHEPEVTParticle::getAllDecayProducts()
195  {
196  std::vector<PhotosParticle*> list;
197 
198  if (!hasDaughters()) // if this particle has no daughters
199  return list;
200 
201  std::vector<PhotosParticle*> daughters = getDaughters();
202 
203  // copy daughters to list of all decay products
204  list.insert(list.end(), daughters.begin(), daughters.end());
205 
206  // Now, get all daughters recursively, without duplicates.
207  // That is, for each daughter:
208  // 1) get list of her daughters
209  // 2) for each particle on this list:
210  // a) check if it is already on the list
211  // b) if it's not, add her to the end of the list
212  for (unsigned int i = 0; i < list.size(); i++) {
213  std::vector<PhotosParticle*> daughters2 = list[i]->getDaughters();
214 
215  if (!list[i]->hasDaughters()) continue;
216  for (unsigned int j = 0; j < daughters2.size(); j++) {
217  bool add = true;
218  for (unsigned int k = 0; k < list.size(); k++)
219  if (daughters2[j]->getBarcode() == list[k]->getBarcode()) {
220  add = false;
221  break;
222  }
223 
224  if (add) list.push_back(daughters2[j]);
225  }
226  }
227 
228  return list;
229  }
230 
232  {
233 
234  if (!m_event) return true;
235  if (m_daughter_end < 0) return true;
236 
238 
239  int first_mother_idx = buf->getFirstMotherIndex();
240  int second_mother_idx = buf->getSecondMotherIndex();
241 
242  double px = 0.0, py = 0.0, pz = 0.0, e = 0.0;
243  double px2 = 0.0, py2 = 0.0, pz2 = 0.0, e2 = 0.0;
244 
245  for (int i = m_daughter_start; i <= m_daughter_end; i++) {
246  buf = m_event->getParticle(i);
247  px += buf->getPx();
248  py += buf->getPy();
249  pz += buf->getPz();
250  e += buf->getE();
251  }
252 
253  if (first_mother_idx >= 0) {
254  buf = m_event->getParticle(first_mother_idx);
255  px2 += buf->getPx();
256  py2 += buf->getPy();
257  pz2 += buf->getPz();
258  e2 += buf->getE();
259  }
260 
261  if (second_mother_idx >= 0) {
262  buf = m_event->getParticle(second_mother_idx);
263  px2 += buf->getPx();
264  py2 += buf->getPy();
265  pz2 += buf->getPz();
266  e2 += buf->getE();
267  }
268  // 3-momentum // test HepMC style
269  double dp = sqrt((px - px2) * (px - px2) + (py - py2) * (py - py2) + (pz - pz2) * (pz - pz2));
270  // virtuality test as well.
271  double m1 = sqrt(fabs(e * e - px * px - py * py - pz * pz));
272  double m2 = sqrt(fabs(e2 * e2 - px2 * px2 - py2 * py2 - pz2 * pz2));
273 
274  if (fabs(m1 - m2) > 0.0001 || dp > 0.0001 * (e + e2)) {
275  Log::RedirectOutput(Log::Warning() << "Momentum not conserved in vertex: ");
276  if (first_mother_idx >= 0) m_event->getParticle(first_mother_idx) ->print();
277  if (second_mother_idx >= 0) m_event->getParticle(second_mother_idx)->print();
278  cout << " TO: " << endl;
279  for (int i = m_daughter_start; i <= m_daughter_end; i++) m_event->getParticle(i)->print();
281  return false;
282  }
283 
284  return true;
285  }
286 
288  int pdg_id, int status, double mass,
289  double px, double py, double pz, double e)
290  {
291 
292  // New particles created using this method are added to cache
293  // They will be deleted when this particle will be deleted
294 
295  cache.push_back(new PhotosHEPEVTParticle(pdg_id, status, px, py, pz, e, mass, -1, -1, -1, -1));
296  return cache.back();
297  }
298 
300  {
301  Log::Warning() << "PhotosParticle::createHistoryEntry() not implemented for HEPEVT." << endl;
302  }
303 
305  {
306  Log::Warning() << "PhotosHEPEVTParticle::createSelfDecayVertex() not implemented for HEPEVT." << endl;
307  }
308 
310  {
311  int bc = p->getBarcode();
312  if (bc == m_first_mother || bc == m_second_mother) return true;
313 
314  return false;
315  }
316 
318  {
319  int bc = p->getBarcode();
320  if (bc >= m_daughter_start && bc <= m_daughter_end) return true;
321 
322  return false;
323  }
324 
326  {
327  char buf[256];
328  sprintf(buf, "P: (%2i) %6i %2i | %11.4e %11.4e %11.4e %11.4e | %11.4e | M: %2i %2i | D: %2i %2i\n",
329  m_barcode, m_pdgid, m_status, m_px, m_py, m_pz, m_e, m_generated_mass,
330  m_first_mother, m_second_mother, m_daughter_start, m_daughter_end);
331 
332  cout << buf;
333  }
334 
335  /******** Getter and Setter methods: ***********************/
336 
338  {
339  m_pdgid = pdg_id;
340  }
341 
343  {
344  m_status = status;
345  }
346 
348  {
349  m_generated_mass = mass;
350  }
351 
353  {
354  return m_pdgid;
355  }
356 
358  {
359  return m_status;
360  }
361 
363  {
364  return m_generated_mass;
365  }
366 
368  {
369  return m_px;
370  }
371 
373  {
374  return m_py;
375  }
376 
378  {
379  return m_pz;
380  }
381 
383  {
384  return m_e;
385  }
386 
388  {
389  m_px = px;
390  }
391 
393  {
394  m_py = py;
395  }
396 
397 
399  {
400  m_pz = pz;
401  }
402 
404  {
405  m_e = e;
406  }
407 
409  {
410  return m_barcode;
411  }
412 
414  {
415  m_barcode = barcode;
416  }
417 
419  {
420  m_event = event;
421  }
422 
424  {
425  return m_first_mother;
426  }
427 
429  {
430  return m_second_mother;
431  }
432 
434  {
435  return m_daughter_start;
436  }
437 
439  {
440  return m_daughter_end;
441  }
442 
443 } // namespace Photospp
static void RedirectOutput(void(*func)(), ostream &where= *out)
Redirects output to log.
Definition: Log.cc:90
static void Fatal(string text, unsigned short int code=0)
Terminates the program with added default message or 'text'.
static void RevertOutput()
WARNING! If You're redirecting more than one function, do not forget to use RevertOutput() afterwards...
Definition: Log.h:89
void addParticle(PhotosHEPEVTParticle *p)
Add particle at the end of event record.
int getParticleCount()
Get higher-most index of the particles in event (nhep)
PhotosHEPEVTParticle * getParticle(int i)
Get particle at index 'i'.
void setParticle(int i, PhotosHEPEVTParticle *p)
Set particle at index 'i'.
int m_first_mother
Indexes of mothers (-1 if do not have mothers)
double getPx()
Returns the px component of the four vector.
void setMothers(std::vector< PhotosParticle * > mothers)
Set the mothers of this particle via a vector of PhotosParticle.
void setE(double e)
Set the energy component of the four vector.
void setDaughters(std::vector< PhotosParticle * > daughters)
Set the daughters of this particle via a vector of PhotosParticle.
bool checkMomentumConservation()
Check that the 4 momentum in conserved in the decay of this particle.
bool isMotherOf(PhotosHEPEVTParticle *p)
Check if particle 'p' is mother of this particle.
void setStatus(int statu)
Set the status of this particle.
int getDaughterRangeStart()
Get index of first daughter.
int getBarcode()
Get the barcode (position in list) of this particle.
PhotosHEPEVTParticle(int pdgid, int status, double px, double py, double pz, double e, double m, int ms, int me, int ds, int de)
Default constructor.
double getPy()
Returns the py component of the four vector.
void print()
Print information on this particle into standard output.
int getFirstMotherIndex()
Get index of first mother.
std::vector< PhotosParticle * > getAllDecayProducts()
Returns all particles in the decay tree of this particle via a vector of PhotosParticle.
void setEvent(PhotosHEPEVTEvent *event)
Set event of this particle.
double getMass()
Get the mass stored (i.e.
void setPy(double py)
Set the px component of the four vector.
PhotosHEPEVTEvent * m_event
Event from which this particle is taken.
int m_daughter_start
Range of indexes of daughters (-1 if do not have daughters)
double getPz()
Returns the pz component of the four vector.
std::vector< PhotosParticle * > getDaughters()
Returns the daughters of this particle via a vector of PhotosParticle.
void createSelfDecayVertex(PhotosParticle *out)
Create a self-decay vertex for this particle with 'out' being the outgoing particle in new vertex.
vector< PhotosHEPEVTParticle * > cache
List of created particles - if they are not in the event, they will be deleted when no longer needed.
void addDaughter(PhotosParticle *daughter)
Add a new daughter to this particle.
void setBarcode(int barcode)
Set barcode (position in list) of this particle.
int getSecondMotherIndex()
Get index of second mother.
double getE()
Returns the energy component of the four vector.
bool isDaughterOf(PhotosHEPEVTParticle *p)
Check if particle 'p' is daughter of this particle.
void setPx(double px)
Set the px component of the four vector.
int getDaughterRangeEnd()
Get index of last daughter.
int m_status
Status (stable, decayed)
void setMass(double mass)
Set the mass of this particle.
int m_barcode
Position in the event record.
void createHistoryEntry()
Creating history entries not implemented in HEPEVT.
int getPdgID()
Get the PDG ID code of this particle.
double m_generated_mass
Mass saved at generation step.
void setPz(double pz)
Set the pz component of the four vector.
PhotosHEPEVTParticle * createNewParticle(int pdg_id, int status, double mass, double px, double py, double pz, double e)
Creates a new particle of type PhotosHEPEVTParticle, with the given properties.
int getStatus()
Get the status of this particle.
~PhotosHEPEVTParticle()
Default destructor.
std::vector< PhotosParticle * > getMothers()
Returns the mothers of this particle via a vector of PhotosParticle.
void setPdgID(int pdg_id)
Set the PDG ID code of this particle.
bool hasDaughters()
Return whether the particle has any chidren.