ROOTPWA
isobarDecayVertex.cc
Go to the documentation of this file.
1 
2 //
3 // Copyright 2010
4 //
5 // This file is part of rootpwa
6 //
7 // rootpwa is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation, either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // rootpwa is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with rootpwa. If not, see <http://www.gnu.org/licenses/>.
19 //
21 //-------------------------------------------------------------------------
22 // File and Version Information:
23 // $Rev:: $: revision of last commit
24 // $Author:: $: author of last commit
25 // $Date:: $: date of last commit
26 //
27 // Description:
28 // class that describes decay vertex of isobar into two particles
29 // the isobar -> particle1 + particle 2 vertex has exactly one
30 // incoming parent and two outgoing daughter particle
31 //
32 //
33 // Author List:
34 // Boris Grube TUM (original author)
35 //
36 //
37 //-------------------------------------------------------------------------
38 
39 
40 #include <sstream>
41 
42 #include "reportingUtilsRoot.hpp"
43 #include "spinUtils.hpp"
44 #include "isobarDecayVertex.h"
45 
46 
47 using namespace std;
48 using namespace rpwa;
49 
50 
51 bool isobarDecayVertex::_debug = false;
52 
53 
54 isobarDecayVertex::isobarDecayVertex(const particlePtr& parent,
55  const particlePtr& daughter1,
56  const particlePtr& daughter2,
57  const unsigned int L,
58  const unsigned int S,
61  _L (L),
62  _S (S),
63  _massDep (massDep)
64 {
65  if (not parent) {
66  printErr << "null pointer to parent particle. aborting." << endl;
67  throw;
68  }
69  if (not daughter1) {
70  printErr << "null pointer to daughter 1 particle. aborting." << endl;
71  throw;
72  }
73  if (not daughter2) {
74  printErr << "null pointer to daughter 2 particle. aborting." << endl;
75  throw;
76  }
80  if (not _massDep) {
81  _massDep = createFlatMassDependence();
82  if (_debug)
83  printWarn << "null pointer to mass dependence. setting " << *_massDep << endl;
84  }
85  if (_debug)
86  printDebug << "constructed " << *this << endl;
87 }
88 
89 
91 {
92  *this = vert;
93 }
94 
95 
97 { }
98 
99 
102 {
103  if (this != &vert) {
105  _L = vert._L;
106  _S = vert._S;
107  _massDep = vert._massDep;
108  }
109  return *this;
110 }
111 
112 
114 isobarDecayVertex::doClone(const bool cloneInParticles,
115  const bool cloneOutParticles) const
116 {
117  isobarDecayVertex* vertexClone = new isobarDecayVertex(*this);
118  if (cloneInParticles)
119  vertexClone->cloneInParticles();
120  if (cloneOutParticles)
121  vertexClone->cloneOutParticles();
122  if (_debug)
123  printDebug << "cloned " << *this << "; " << this << " -> " << vertexClone << " "
124  << ((cloneInParticles ) ? "in" : "ex") << "cluding incoming particles, "
125  << ((cloneOutParticles) ? "in" : "ex") << "cluding outgoing particles" << std::endl;
126  return vertexClone;
127 }
128 
129 
130 bool
132 {
133  const isobarDecayVertex* isoVert = dynamic_cast<const isobarDecayVertex*>(&vert);
134  if (not isoVert)
135  return false;
136  if (not interactionVertex::isEqualTo(vert))
137  return false;
138  if ( (L() != isoVert->L())
139  or (S() != isoVert->S())
140  or (*(massDependence()) != *(isoVert->massDependence())))
141  return false;
142  return true;
143 }
144 
145 
146 bool
148 {
149  if (_debug)
150  printWarn << "cannot add incoming particle to " << *this << endl;
151  return false;
152 }
153 
154 
155 bool
157 {
158  if (_debug)
159  printWarn << "cannot add outgoing particle to " << *this << endl;
160  return false;
161 }
162 
163 
164 const TLorentzVector&
166 {
167  if (_debug)
168  printDebug << "calculating Lorentz-vector of parent particle " << parent()->name()
169  << " before = " << parent()->lzVec() << " GeV, " << flush;
170  parent()->setLzVec(daughter1()->lzVec() + daughter2()->lzVec());
171  if (_debug)
172  cout << "after = " << parent()->lzVec() << " GeV" << endl;
173  return parent()->lzVec();
174 }
175 
176 
177 int
179 {
180  if (_debug)
181  printDebug << "calculating charge of parent particle " << parent()->name()
182  << " before = " << parent()->charge() << ", " << flush;
183  parent()->setCharge(daughter1()->charge() + daughter2()->charge());
184  if (_debug)
185  cout << "after = " << parent()->charge() << endl;
186  return parent()->charge();
187 }
188 
189 
190 int
192 {
193  if (_debug)
194  printDebug << "calculating baryon number of parent particle " << parent()->name()
195  << " before = " << parent()->baryonNmb() << ", " << flush;
196  parent()->setBaryonNmb(daughter1()->baryonNmb() + daughter2()->baryonNmb());
197  if (_debug)
198  cout << "after = " << parent()->baryonNmb() << endl;
199  return parent()->baryonNmb();
200 }
201 
202 
203 bool
205  const int d1Qn,
206  const int d2Qn,
207  const string& qnName)
208 {
209  if (mQn == d1Qn * d2Qn) {
210  if (_debug)
211  printDebug << "success: " << *this << ": "
212  << ((qnName == "") ? "multiplicative quantum number" : qnName)
213  << " is consistent" << endl;
214  return true;
215  } else {
216  printWarn << ((qnName == "") ? "multiplicative quantum number" : qnName) << " mismatch: "
217  << parent()->name() << " = " << mQn << " != " << d1Qn * d2Qn << " = "
218  << "(" << daughter1()->name() << " = " << d1Qn << ") * "
219  << "(" << daughter2()->name() << " = " << d2Qn << ")" << endl;
220  return false;
221  }
222 }
223 
224 
225 bool
227  const int d1Qn,
228  const int d2Qn,
229  const string& qnName)
230 {
231  if (mQn == d1Qn + d2Qn) {
232  if (_debug)
233  printDebug << "success: " << *this << ": "
234  << ((qnName == "") ? "additive quantum number" : qnName)
235  << " is consistent" << endl;
236  return true;
237  } else {
238  printWarn << ((qnName == "") ? "additive quantum number" : qnName) << " mismatch: "
239  << parent()->name() << " = " << mQn << " != " << d1Qn + d2Qn << " = "
240  << "(" << daughter1()->name() << " = " << d1Qn << ") + "
241  << "(" << daughter2()->name() << " = " << d2Qn << ")" << endl;
242  return false;
243  }
244 }
245 
246 
247 bool
249 {
250  bool vertexConsistent = true;
251  // check multiplicative quantum numbers
252  // G-parity
253  if (not checkMultiplicativeQn(parent()->G(), daughter1()->G(), daughter2()->G(), "G-parity"))
254  vertexConsistent = false;
255  // parity
256  const int angMomParity = (_L % 4 == 0) ? 1 : -1; // modulo 4 because L is in units of hbar / 2
257  if (parent()->P() != daughter1()->P() * daughter2()->P() * angMomParity) {
258  printWarn << "parity mismatch: "
259  << parent()->name() << " = " << parent()->P() << " != "
260  << daughter1()->P() * daughter2()->P() * angMomParity << " = "
261  << "(" << daughter1()->name() << " = " << daughter1()->P() << ") * "
262  << "(" << daughter2()->name() << " = " << daughter2()->P() << ") * "
263  << "(ang. momentum = " << angMomParity << ")" << endl;
264  vertexConsistent = false;
265  } else if (_debug)
266  printDebug << "success: " << *this << ": parity is consistent" << endl;
267  // check additive quantum numbers
268  // charge
269  if (not checkAdditiveQn(parent()->charge(), daughter1()->charge(),
270  daughter2()->charge(), "charge"))
271  vertexConsistent = false;
272  // baryon number
273  if (not checkAdditiveQn(parent()->baryonNmb(), daughter1()->baryonNmb(),
274  daughter2()->baryonNmb(), "baryonNmb"))
275  vertexConsistent = false;
276  // strangeness
277  if (not checkAdditiveQn(parent()->strangeness(), daughter1()->strangeness(),
278  daughter2()->strangeness(), "strangeness"))
279  vertexConsistent = false;
280  // charm
281  if (not checkAdditiveQn(parent()->charm(), daughter1()->charm(),
282  daughter2()->charm(), "charm"))
283  vertexConsistent = false;
284  // beauty
285  if (not checkAdditiveQn(parent()->beauty(), daughter1()->beauty(),
286  daughter2()->beauty(), "beauty"))
287  vertexConsistent = false;
288  // check orbital angular momentum
289  if (not isEven(_L)) {
290  printWarn << "relative orbital angular momentum L = " << spinQn(_L)
291  << " is not an integer" << endl;
292  vertexConsistent = false;
293  } else if (_debug)
294  printDebug << "success: " << *this
295  << ": relative orbital angular momentum L = " << spinQn(_L) << " is integer" << endl;
296  // spin coupling: S in {|s1 - s2|, ..., s1 + s2}
297  if (not spinStatesCanCouple(daughter1()->J(), daughter2()->J(), _S)) {
298  printWarn << "spins "
299  << "(" << daughter1()->name() << " J = " << spinQn(daughter1()->J()) << ") and "
300  << "(" << daughter2()->name() << " J = " << spinQn(daughter2()->J()) << ") "
301  << "cannot couple to total spin S = " << spinQn(_S) << endl;
302  vertexConsistent = false;
303  } else if (_debug)
304  printDebug << "success: " << *this << ": spin-spin coupling is consistent" << endl;
305  // L-S coupling: J in {|L - S|, ..., L + S}
306  if (not spinStatesCanCouple(_L, _S, parent()->J())) {
307  printWarn << "orbital angular momentum L = " << spinQn(_L) << " and spin S = " << spinQn(_S)
308  << " cannot couple to angular momentum J = " << spinQn(parent()->J()) << endl;
309  vertexConsistent = false;
310  } else if (_debug)
311  printDebug << "success: " << *this << ": L-S coupling is consistent" << endl;
312  // check, whether isospins can couple
313  if (not spinStatesCanCouple(daughter1()->isospin(), daughter1()->isospinProj(),
314  daughter2()->isospin(), daughter2()->isospinProj(),
315  parent ()->isospin(), parent ()->isospinProj())) {
316  printWarn << "isospin Clebsch-Gordan "
317  << "(" << spinQn(daughter1()->isospin()) << ", " << spinQn(daughter1()->isospinProj())
318  << "; " << spinQn(daughter2()->isospin()) << ", " << spinQn(daughter2()->isospinProj())
319  << " | " << spinQn(parent ()->isospin()) << ", " << spinQn(parent ()->isospinProj())
320  << ") == 0" << endl;
321  vertexConsistent = false;
322  } else if (_debug)
323  printDebug << *this << ": isospin Clebsch-Gordan is not zero" << endl;
324  // check consistency of C-, G-parity, and isospin
325  if ( ( (daughter1()->charge() == 0)
326  and (daughter1()->C() != daughter1()->G() * (daughter1()->isospin() % 4 == 0 ? 1 : -1)))
327  or ( (daughter1()->charge() != 0)
328  and (daughter1()->C() != 0))
329  or ( (daughter2()->charge() == 0)
330  and (daughter2()->C() != daughter2()->G() * (daughter2()->isospin() % 4 == 0 ? 1 : -1)))
331  or ( (daughter2()->charge() != 0)
332  and (daughter2()->C() != 0))
333  or ( (parent ()->charge() == 0)
334  and (parent ()->C() != parent ()->G() * (parent ()->isospin() % 4 == 0 ? 1 : -1)))
335  or ( (parent ()->charge() != 0)
336  and (parent ()->C() != 0))) {
337  printWarn << "C-, G-parity, and isospin are inconsistent "
338  << daughter1()->qnSummary() << ", " << daughter2()->qnSummary() << ", "
339  << parent ()->qnSummary() << endl;
340  vertexConsistent = false;
341  } else if (_debug)
342  printDebug << *this << ": C-, G-parity, and isospin are consistent" << endl;
343 
345  if (vertexConsistent) {
346  if (_debug)
347  printDebug << "data for " << *this << " are consistent: " << endl;
348  } else
349  printWarn << "data for " << *this << " are inconsistent (see warnings above)" << endl;
350  return vertexConsistent;
351 }
352 
353 
354 ostream&
355 isobarDecayVertex::print(ostream& out) const
356 {
357  out << name() << ": "
358  << parent()->qnSummary() << " --{" << *_massDep << "}--> "
359  << daughter1()->qnSummary()
360  << " [L = " << spinQn(_L) << ", S = " << spinQn(_S) << "] "
361  << daughter2()->qnSummary();
362  return out;
363 }
364 
365 
366 ostream&
367 isobarDecayVertex::dump(ostream& out) const
368 {
369  out << name() << ":" << endl
370  << " parent: " << *parent() << endl
371  << " daughter 1: " << *daughter1() << endl
372  << " daughter 2: " << *daughter2() << endl
373  << " L = " << spinQn(_L) << ", S = " << spinQn(_S) << endl
374  << " " << *_massDep << endl;
375  return out;
376 }
377 
378 
379 ostream&
381 {
382  out << name() << " " << this << ": "
383  << "parent particle: " << parent() << "; "
384  << "daughter 1 particle: " << daughter1() << "; "
385  << "daughter 2 particle: " << daughter2() << endl;
386  return out;
387 }