ROOTPWA
particleProperties.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 // container class for particle properties
29 //
30 //
31 // Author List:
32 // Boris Grube TUM (original author)
33 //
34 //
35 //-------------------------------------------------------------------------
36 
37 
38 #include <cstdlib>
39 #include <iterator>
40 
41 #include <boost/lexical_cast.hpp>
42 #include <boost/algorithm/string.hpp>
43 
44 #include "spinUtils.hpp"
45 #include "conversionUtils.hpp"
46 #include "particleDataTable.h"
47 #include "particleProperties.h"
48 
49 
50 using namespace std;
51 using namespace rpwa;
52 using namespace boost;
53 
54 
55 bool particleProperties::_debug = false;
56 
57 
58 particleProperties::decayMode::decayMode(const multiset<string>& daughters,
59  const int L,
60  const int S)
61  : _daughters(daughters),
62  _L (L),
63  _S (S)
64 { }
65 
66 
68 { }
69 
70 
71 bool
73 {
74  if (_daughters != rhsDecay._daughters)
75  return false;
76  // compare L and S only if they are defined in left- and right-hand side
77  if ((_L != -1) and (rhsDecay._L != -1) and (_L != rhsDecay._L))
78  return false;
79  if ((_S != -1) and (rhsDecay._S != -1) and (_S != rhsDecay._S))
80  return false;
81  return true;
82 }
83 
84 
85 ostream&
87 {
88  copy(_daughters.begin(), _daughters.end(), ostream_iterator<string>(out, " "));
89  if (_L != -1)
90  out << "[L = " << spinQn(_L);
91  if (_S != -1) {
92  if (_L != -1)
93  out << ", ";
94  else
95  out << "[";
96  out << "S = " << spinQn(_S) << "]";
97  } else if (_L != -1)
98  out << "]";
99  return out;
100 }
101 
102 
104  : _name (""),
105  _antiPartName(""),
106  _charge (0),
107  _mass (0),
108  _mass2 (0),
109  _width (0),
110  _baryonNmb (0),
111  _isospin (0),
112  _strangeness (0),
113  _charm (0),
114  _beauty (0),
115  _G (0),
116  _J (0),
117  _P (0),
118  _C (0),
119  _decayModes ()
120 { }
121 
122 
124 {
125  *this = partProp;
126 }
127 
128 
129 particleProperties::particleProperties(const std::string& partName,
130  const int isospin,
131  const int G,
132  const int J,
133  const int P,
134  const int C)
135  : _antiPartName(""),
136  _mass (0),
137  _mass2 (0),
138  _width (0),
139  _baryonNmb (0),
140  _strangeness (0),
141  _charm (0),
142  _beauty (0),
143  _decayModes ()
144 {
145  setName (partName);
146  setIsospin(isospin);
147  setG (G);
148  setJ (J);
149  setP (P);
150  setC (C);
151 }
152 
153 
155 { }
156 
157 
160 {
161  if (this != &partProp) {
162  _name = partProp._name;
163  _antiPartName = partProp._antiPartName;
164  _charge = partProp._charge;
165  _mass = partProp._mass;
166  _mass2 = partProp._mass2;
167  _width = partProp._width;
168  _baryonNmb = partProp._baryonNmb;
169  _isospin = partProp._isospin;
170  _strangeness = partProp._strangeness;
171  _charm = partProp._charm;
172  _beauty = partProp._beauty;
173  _G = partProp._G;
174  _J = partProp._J;
175  _P = partProp._P;
176  _C = partProp._C;
177  _decayModes = partProp._decayModes;
178  }
179  return *this;
180 }
181 
182 
183 namespace rpwa {
184 
185  // selector string can contain any of the following:
186  // I, G, J, P, C, strangeness, charm, beauty, baryonNmb, or allQn
187  bool
189  const pair<particleProperties, string>& rhsPropSel)
190  {
191  const particleProperties& rhsProp = rhsPropSel.first;
192  const string& selector = rhsPropSel.second;
193  const bool checkAllQn = (selector.find("allQn") != string::npos);
194  return ( ( ((selector.find("charge") == string::npos) and not checkAllQn)
195  or (lhsProp.charge() == rhsProp.charge()))
196  and ( ((selector.find("baryonNmb") == string::npos) and not checkAllQn)
197  or (lhsProp.baryonNmb() == rhsProp.baryonNmb()))
198  and ( ((selector.find("I") == string::npos) and not checkAllQn)
199  or (lhsProp.isospin() == rhsProp.isospin()))
200  and ( ((selector.find("strangeness") == string::npos) and not checkAllQn)
201  or (lhsProp.strangeness() == rhsProp.strangeness()))
202  and ( ((selector.find("charm") == string::npos) and not checkAllQn)
203  or (lhsProp.charm() == rhsProp.charm()))
204  and ( ((selector.find("beauty") == string::npos) and not checkAllQn)
205  or (lhsProp.beauty() == rhsProp.beauty()))
206  and ( ((selector.find("G") == string::npos) and not checkAllQn)
207  or (lhsProp.G() == rhsProp.G()))
208  and ( ((selector.find("J") == string::npos) and not checkAllQn)
209  or (lhsProp.J() == rhsProp.J()))
210  and ( ((selector.find("P") == string::npos) and not checkAllQn)
211  or (lhsProp.P() == rhsProp.P()))
212  and ( ((selector.find("C") == string::npos) and not checkAllQn)
213  or (lhsProp.C() == rhsProp.C())));
214  }
215 
216 }
217 
218 
219 unsigned int
221 {
223 }
224 
225 
226 bool
228 {
229  return (isMeson() and igjpIsExotic(isospin(), G(), J(), P()));
230 }
231 
232 
233 bool
235 {
236  return find(_decayModes.begin(), _decayModes.end(), decay) != _decayModes.end();
237 }
238 
239 
240 bool
242  const bool warnIfNotExistent)
243 {
244  string name = partName;
245  if (not particleDataTable::instance().isInTable(partName)
246  and (partName == stripChargeFromName(partName)))
247  // if no charge is given in the name assume charge 0
248  name += '0';
249  const particleProperties* partProp = particleDataTable::instance().entry(name, warnIfNotExistent);
250  if (not partProp) {
251  if (warnIfNotExistent)
252  printWarn << "trying to fill particle properties for '"
253  << partName << "' from non-existing table entry" << endl;
254  return false;
255  } else {
256  *this = *partProp;
257  if (_debug)
258  printDebug << "succesfully filled particle properties for '" << partName << "': "
259  << *this << endl;
260  return true;
261  }
262 }
263 
264 
265 void
266 particleProperties::setSCB(const int strangeness,
267  const int charm,
268  const int beauty)
269 {
270  setStrangeness(strangeness);
271  setCharm (charm);
272  setBeauty (beauty);
273 }
274 
275 
276 void
278  const int G,
279  const int J,
280  const int P,
281  const int C)
282 {
283  setIsospin(isospin);
284  setG (G);
285  setJ (J);
286  setP (P);
287  setC (C);
288 }
289 
290 
292 particleProperties::antiPartProperties(const bool convertDecaysModes) const
293 {
294  particleProperties antiPartProp;
295  if (isItsOwnAntiPart()) {
296  if (convertDecaysModes)
297  return *this;
298  else {
299  antiPartProp = *this;
300  antiPartProp.deleteDecayModes();
301  }
302  } else {
303  antiPartProp.setName (_antiPartName);
304  antiPartProp.setAntiPartName(_name );
305  antiPartProp.setCharge (-_charge );
306  antiPartProp.setMass (_mass );
307  antiPartProp.setWidth (_width );
308  antiPartProp.setBaryonNmb (-_baryonNmb );
309  antiPartProp.setIsospin (_isospin );
310  antiPartProp.setStrangeness (-_strangeness);
311  antiPartProp.setCharm (-_charm );
312  antiPartProp.setBeauty (-_beauty );
313  antiPartProp.setG (_G );
314  antiPartProp.setJ (_J );
315  antiPartProp.setP (_P );
316  antiPartProp.setC (_C );
317  // convert decay modes to antiparticles
318  if (convertDecaysModes)
319  for (size_t i = 0 ; i < nmbDecays(); ++i) {
320  multiset<string> antiDaughters;
322  // !NOTE! for associative containers with value type == key type iterator is const_iterator
323  for (multiset<string>::const_iterator it = decay._daughters.begin();
324  it != decay._daughters.end(); ++it) {
325  particleProperties daughterProp;
326  daughterProp.fillFromDataTable(*it);
327  antiDaughters.insert(daughterProp.antiPartName());
328  }
329  decay._daughters = antiDaughters;
330  antiPartProp.addDecayMode(decay);
331  }
332  }
333  return antiPartProp;
334 }
335 
336 
337 string
339 {
340  // split name into mass and symbol parts
341  // const string name = bareName();
342  // typename boost::iterator_range<std::string> startPos;
343  // find_first(name, "(");
344  // iterator_range<string> endPos = find_last (name, ")");
345  // iterator_range<string> range = make_iterator_range(startPos, endPos);
346  // const string mass = copy_range(range);
347  // printDebug << "!!!HERE " << name << ": " << mass << "; " << range << endl;
348  // // handle antiparticle
349  // if ()
350  // // handle * particles
351 
352  // // setup particle-name dictionary
353  // map<string, string> partNameDict;
354  // isobars["gamma" ] = "\\gamma";
355  // isobars["mu" ] = "\\mu";
356  // isobars["pi" ] = "\\pi";
357  // isobars["eta" ] = "\\eta";
358  // isobars["sigma" ] = "\\sigma";
359  // isobars["rho" ] = "\\rho";
360  // isobars["omega" ] = "\\omega";
361  // isobars["phi" ] = "\\phi";
362  // isobars["kappa" ] = "\\kappa";
363  // isobars["nucleon"] = "N";
364  // isobars["Delta" ] = "\\Delta";
365  // isobars["Lambda" ] = "\\Lambda";
366 
367 
368  // vector<iterator_range<string::iterator> > foundPos;
369  // find_all(foundPos, name, "(");
370  // if (foundPos.size() > 1) {
371  // printErr << "particle name '" << name << "' contains more than one '('. "
372  // << "cannot construct LaTeX name" << endl;
373  // return "";
374  // }
375  return "";
376 }
377 
378 
379 
380 string
382 {
383  ostringstream out;
384  out << name() << "[" << spinQn(isospin()) << parityQn(G())
385  << "(" << spinQn(J()) << parityQn(P()) << parityQn(C()) << ")]";
386  return out.str();
387 }
388 
389 
390 ostream&
391 particleProperties::print(ostream& out) const
392 {
393  out << "particle '" << name() << "': "
394  << "mass = " << mass() << " GeV/c^2, "
395  << "width = " << width() << " GeV/c^2, "
396  << "baryon # = " << baryonNmb() << ", "
397  << "I" << ((G() != 0) ? "^G" : "") << " J";
398  if (P() != 0)
399  out << "^P" << ((C() != 0) ? "C" : "") << " = ";
400  else
401  out << ((C() != 0) ? "^C" : "") << " = ";
402  out << spinQn(isospin());
403  if (G() != 0)
404  out << "^" << sign(G());
405  out << " " << spinQn(J());
406  if (P() != 0)
407  out << "^" << sign(P()) << parityQn(C());
408  else
409  if (C() != 0)
410  out << "^" << sign(C());
411  out << ", "
412  << "strangeness = " << strangeness() << ", "
413  << "charm = " << charm() << ", "
414  << "beauty = " << beauty() << ", "
415  << "is meson = " << yesNo(isMeson()) << ", ";
416  if (isMeson())
417  out << "is spin-exotic = " << yesNo(isSpinExotic()) << ", ";
418  out << "is baryon = " << yesNo(isBaryon()) << ", "
419  << "is lepton = " << yesNo(isLepton()) << ", "
420  << "is photon = " << yesNo(isPhoton()) << ", "
421  << "antiparticle '" << antiPartName() << "', "
422  << "is its own antiparticle = " << yesNo(isItsOwnAntiPart());
423  // decay products
424  const unsigned int nmbDecays = this->nmbDecays();
425  if (nmbDecays > 0) {
426  out << endl << " decay modes:" << endl;
427  for (unsigned int i = 0; i < nmbDecays; ++i) {
428  out << " -> " << _decayModes[i];
429  if (i < nmbDecays - 1)
430  out << endl;
431  }
432  }
433 
434  return out;
435 }
436 
437 
438 ostream&
439 particleProperties::dump(ostream& out) const
440 {
441  out << name () << "\t"
442  << antiPartName() << "\t"
443  << mass () << "\t"
444  << mass2 () << "\t"
445  << width () << "\t"
446  << baryonNmb () << "\t"
447  << isospin () << "\t"
448  << strangeness () << "\t"
449  << charm () << "\t"
450  << beauty () << "\t"
451  << G () << "\t"
452  << J () << "\t"
453  << P () << "\t"
454  << C ();
455  return out;
456 }
457 
458 
459 bool
460 particleProperties::read(istringstream& line)
461 {
462  if (_debug)
463  printDebug << "trying to read particle properties from line '" << line.str() << "' ... " << flush;
464  std::string name = "", antiPartName = "";
465  double mass = 0, width = 0;
466  int baryonNmb = 0, isospin = 0, strangeness = 0, charm = 0, beauty = 0;
467  int G = 0, J = 0, P = 0, C = 0;
468  if (line >> name
469  >> antiPartName
470  >> mass
471  >> width
472  >> baryonNmb
473  >> isospin
474  >> strangeness
475  >> charm
476  >> beauty
477  >> G
478  >> J
479  >> P
480  >> C) {
481  setName (name );
483  setMass (mass );
484  setWidth (width );
485  setBaryonNmb (baryonNmb );
486  setIsospin (isospin );
488  setCharm (charm );
489  setBeauty (beauty );
490  setG (G );
491  setJ (J );
492  setP (P );
493  setC (C );
494  if (_debug) {
495  cout << "success" << endl;
496  printDebug << "read "<< *this << endl;
497  }
498  return true;
499  } else {
500  printWarn << "problems reading particle data from line '" << line.str() << "'" << endl;
501  return false;
502  }
503 }
504 
505 
506 string
507 particleProperties::nameWithCharge(const string& bareName,
508  const int charge)
509 {
510  string name = bareName;
511  if (bareName != "") {
512  if (abs(charge) > 1) {
513  string q = "";
514  try {
515  q = lexical_cast<char>(abs(charge));
516  } catch (bad_lexical_cast&) { }
517  name += q;
518  }
519  name += sign(charge);
520  }
521  return name;
522 }
523 
524 
525 string
526 particleProperties::chargeFromName(const string& partName,
527  int& charge)
528 {
529  // naming scheme: <bare name>XY
530  //
531  // for singly charged particles the charge is designated by the last
532  // character Y in the particle name (e.g. 'pi0', 'rho-', 'p+'). If Y
533  // is neither of '-', '0', or '+', the particle charge is set to 0.
534  //
535  // for multiply charged particles the absolute value of the charge
536  // is defined by the second-to-last character X, the sign by the
537  // lats character Y (e.g. 'Delta(1232)2+').
538  //
539  // !NOTE! <bare name> should not end on a digit, as this would be
540  // interpreted as the absolute value of the charge, so instead of
541  // e.g. 'pi2+' one should use 'pi2(1670)+'
542  charge = 0;
543  string strippedName = partName;
544  const char last = partName[partName.length() - 1];
545  if ((last == '+') or (last == '0') or (last == '-')) {
546  charge = sign(last);
547  strippedName.erase(strippedName.length() - 1);
548  int chargeVal = 0;
549  try {
550  chargeVal = lexical_cast<int>(partName[partName.length() - 2]);
551  } catch (bad_lexical_cast&) { }
552  if (chargeVal != 0) {
553  charge *= chargeVal;
554  strippedName.erase(strippedName.length() - 1);
555  }
556  }
557  return strippedName;
558 }
559 
560 
561 string
563 {
564  int dummy;
565  return chargeFromName(partName, dummy);
566 }
567 
568 
569 bool
571 {
572  return ( (name () == rhsProp.name ())
573  and (antiPartName() == rhsProp.antiPartName())
574  and (charge () == rhsProp.charge ())
575  and (mass () == rhsProp.mass ())
576  and (width () == rhsProp.width ())
577  and (baryonNmb () == rhsProp.baryonNmb ())
578  and (isospin () == rhsProp.isospin ())
579  and (strangeness () == rhsProp.strangeness ())
580  and (charm () == rhsProp.charm ())
581  and (beauty () == rhsProp.beauty ())
582  and (G () == rhsProp.G ())
583  and (J () == rhsProp.J ())
584  and (P () == rhsProp.P ())
585  and (C () == rhsProp.C ()));
586 }