![]() |
HepPDT Reference DocumentationHepPDT |
00001 // ---------------------------------------------------------------------- 00002 // 00003 // ParticleID.cc 00004 // 00005 // ---------------------------------------------------------------------- 00006 00007 #include <stdlib.h> 00008 #include <cmath> // for pow() 00009 00010 #include "HepPDT/defs.h" 00011 #include "HepPDT/ParticleID.hh" 00012 00013 namespace HepPDT { 00014 00015 00016 ParticleID::ParticleID( int pid ) 00017 : itsPID ( pid ) 00018 { ; } 00019 00020 ParticleID::ParticleID( const ParticleID & orig ) 00021 : itsPID ( orig.itsPID ) 00022 { ; } 00023 00024 ParticleID& ParticleID::operator=( const ParticleID & rhs ) 00025 { 00026 ParticleID temp( rhs ); 00027 swap( temp ); 00028 return *this; 00029 } 00030 00031 void ParticleID::swap( ParticleID & other ) 00032 { 00033 std::swap( itsPID, other.itsPID ); 00034 } 00035 00036 bool ParticleID::operator < ( ParticleID const & other ) const 00037 { 00038 return itsPID < other.itsPID; 00039 } 00040 00041 bool ParticleID::operator == ( ParticleID const & other ) const 00042 { 00043 return itsPID == other.itsPID; 00044 } 00045 00046 int ParticleID::abspid( ) const 00047 { 00049 return (itsPID < 0) ? -itsPID : itsPID; 00050 } 00051 00052 // split the PID into constituent integers 00053 unsigned short ParticleID::digit( location loc ) const 00054 { 00055 // PID digits (base 10) are: n nr nl nq1 nq2 nq3 nj 00056 // the location enum provides a convenient index into the PID 00057 int numerator = (int) std::pow(10.0,(loc-1)); 00058 return (abspid()/numerator)%10; 00059 } 00060 00061 // returns everything beyond the 7th digit (e.g. outside the numbering scheme) 00062 int ParticleID::extraBits( ) const 00063 { 00064 return abspid()/10000000; 00065 } 00066 00067 // return the first two digits if this is a "fundamental" particle 00068 // ID = 100 is a special case (internal generator ID's are 81-100) 00069 // also, 101 and 102 are now used (by HepPID) for geantinos 00070 int ParticleID::fundamentalID( ) const 00071 { 00072 if( ( digit(n10) == 1 ) && ( digit(n9) == 0 ) ) { return 0; } 00073 if( digit(nq2) == 0 && digit(nq1) == 0) { 00074 return abspid()%10000; 00075 } else if( abspid() <= 102 ) { 00076 return abspid(); 00077 } else { 00078 return 0; 00079 } 00080 } 00081 00082 bool ParticleID::hasUp( ) const 00083 { 00084 if( extraBits() > 0 ) { return false; } 00085 if( abspid() <= 100 ) { return false; } 00086 if( fundamentalID() <= 100 && fundamentalID() > 0 ) { return false; } 00087 if( digit(nq3) == 2 || digit(nq2) == 2 || digit(nq1) == 2 ) { return true; } 00088 return false; 00089 } 00090 00091 bool ParticleID::hasDown( ) const 00092 { 00093 if( extraBits() > 0 ) { return false; } 00094 if( abspid() <= 100 ) { return false; } 00095 if( fundamentalID() <= 100 && fundamentalID() > 0 ) { return false; } 00096 if( digit(nq3) == 1 || digit(nq2) == 1 || digit(nq1) == 1 ) { return true; } 00097 return false; 00098 } 00099 00100 bool ParticleID::hasStrange( ) const 00101 { 00102 if( extraBits() > 0 ) { return false; } 00103 if( abspid() <= 100 ) { return false; } 00104 if( fundamentalID() <= 100 && fundamentalID() > 0 ) { return false; } 00105 if( digit(nq3) == 3 || digit(nq2) == 3 || digit(nq1) == 3 ) { return true; } 00106 return false; 00107 } 00108 00109 bool ParticleID::hasCharm( ) const 00110 { 00111 if( extraBits() > 0 ) { return false; } 00112 if( abspid() <= 100 ) { return false; } 00113 if( fundamentalID() <= 100 && fundamentalID() > 0 ) { return false; } 00114 if( digit(nq3) == 4 || digit(nq2) == 4 || digit(nq1) == 4 ) { return true; } 00115 return false; 00116 } 00117 00118 bool ParticleID::hasBottom( ) const 00119 { 00120 if( extraBits() > 0 ) { return false; } 00121 if( abspid() <= 100 ) { return false; } 00122 if( fundamentalID() <= 100 && fundamentalID() > 0 ) { return false; } 00123 if( digit(nq3) == 5 || digit(nq2) == 5 || digit(nq1) == 5 ) { return true; } 00124 return false; 00125 } 00126 00127 bool ParticleID::hasTop( ) const 00128 { 00129 if( extraBits() > 0 ) { return false; } 00130 if( abspid() <= 100 ) { return false; } 00131 if( fundamentalID() <= 100 && fundamentalID() > 0 ) { return false; } 00132 if( digit(nq3) == 6 || digit(nq2) == 6 || digit(nq1) == 6 ) { return true; } 00133 return false; 00134 } 00135 00136 // check to see if this is a valid PID 00137 bool ParticleID::isValid( ) const 00138 { 00139 if( extraBits() > 0 ) { 00140 if( isNucleus() ) { return true; } 00141 return false; 00142 } 00143 // SUSY signature 00144 if( isSUSY() ) { return true; } 00145 // R-hadron signature 00146 if( isRhadron() ) { return true; } 00147 // Meson signature 00148 if( isMeson() ) { return true; } 00149 // Baryon signature 00150 if( isBaryon() ) { return true; } 00151 // DiQuark signature 00152 if( isDiQuark() ) { return true; } 00153 // fundamental particle 00154 if( fundamentalID() > 0 ) { return true; } 00155 // pentaquark 00156 if( isPentaquark() ) { return true; } 00157 // don't recognize this number 00158 return false; 00159 } 00160 00161 // check to see if this is a valid pentaquark 00162 bool ParticleID::isPentaquark( ) const 00163 { 00164 // a pentaquark is of the form 9abcdej, 00165 // where j is the spin and a, b, c, d, and e are quarks 00166 if( extraBits() > 0 ) { return false; } 00167 if( digit(n) != 9 ) { return false; } 00168 if( digit(nr) == 9 || digit(nr) == 0 ) { return false; } 00169 if( digit(nj) == 9 || digit(nl) == 0 ) { return false; } 00170 if( digit(nq1) == 0 ) { return false; } 00171 if( digit(nq2) == 0 ) { return false; } 00172 if( digit(nq3) == 0 ) { return false; } 00173 if( digit(nj) == 0 ) { return false; } 00174 // check ordering 00175 if( digit(nq2) > digit(nq1) ) { return false; } 00176 if( digit(nq1) > digit(nl) ) { return false; } 00177 if( digit(nl) > digit(nr) ) { return false; } 00178 return true; 00179 } 00180 00181 // is this an R-hadron? 00182 bool ParticleID::isRhadron( ) const 00183 { 00184 // an R-hadron is of the form 10abcdj, 00185 // where j is the spin and a, b, c, and d are quarks or gluons 00186 if( extraBits() > 0 ) { return false; } 00187 if( digit(n) != 1 ) { return false; } 00188 if( digit(nr) != 0 ) { return false; } 00189 // make sure this isn't a SUSY particle 00190 if( isSUSY() ) { return false; } 00191 // All R-hadrons have at least 3 core digits 00192 if( digit(nq2) == 0 ) { return false; } 00193 if( digit(nq3) == 0 ) { return false; } 00194 if( digit(nj) == 0 ) { return false; } 00195 return true; 00196 } 00197 00198 // is this a SUSY? 00199 bool ParticleID::isSUSY( ) const 00200 { 00201 // fundamental SUSY particles have n = 1 or 2 00202 if( extraBits() > 0 ) { return false; } 00203 if( digit(n) != 1 && digit(n) != 2 ) { return false; } 00204 if( digit(nr) != 0 ) { return false; } 00205 // check fundamental part 00206 if( fundamentalID() == 0 ) { return false; } 00207 return true; 00208 } 00209 00210 // This implements the 2006 Monte Carlo nuclear code scheme. 00211 // Ion numbers are +/- 10LZZZAAAI. 00212 // AAA is A - total baryon number 00213 // ZZZ is Z - total charge 00214 // L is the total number of strange quarks. 00215 // I is the isomer number, with I=0 corresponding to the ground state. 00216 bool ParticleID::isNucleus( ) const 00217 { 00218 // a proton can also be a Hydrogen nucleus 00219 if( abspid() == 2212 ) { return true; } 00220 // new standard: +/- 10LZZZAAAI 00221 if( ( digit(n10) == 1 ) && ( digit(n9) == 0 ) ) { 00222 // charge should always be less than or equal to baryon number 00223 if( A() >= Z() ) { return true; } 00224 } 00225 return false; 00226 } 00227 00228 // return A if this is a nucleus 00229 int ParticleID::A( ) const 00230 { 00231 // a proton can also be a Hydrogen nucleus 00232 if( abspid() == 2212 ) { return 1; } 00233 if( ( digit(n10) != 1 ) || ( digit(n9) != 0 ) ) { return 0; } 00234 return (abspid()/10)%1000; 00235 } 00236 00237 // return Z if this is a nucleus 00238 int ParticleID::Z( ) const 00239 { 00240 // a proton can also be a Hydrogen nucleus 00241 if( abspid() == 2212 ) { return 1; } 00242 if( ( digit(n10) != 1 ) || ( digit(n9) != 0 ) ) { return 0; } 00243 return (abspid()/10000)%1000; 00244 } 00245 00246 // return nLambda if this is a nucleus 00247 int ParticleID::lambda( ) const 00248 { 00249 if( ! isNucleus() ) { return 0; } 00250 // a proton can also be a Hydrogen nucleus 00251 if( abspid() == 2212 ) { return 0; } 00252 return digit(n8); 00253 } 00254 00255 // check to see if this is a valid meson 00256 bool ParticleID::isMeson( ) const 00257 { 00258 if( extraBits() > 0 ) { return false; } 00259 if( abspid() <= 100 ) { return false; } 00260 if( fundamentalID() <= 100 && fundamentalID() > 0 ) { return false; } 00261 int aid = abspid(); 00262 int id = pid(); 00263 if( aid == 130 || aid == 310 || aid == 210 ) { return true; } 00264 // EvtGen uses some odd numbers 00265 if( aid == 150 || aid == 350 || aid == 510 || aid == 530 ) { return true; } 00266 // pomeron, etc. 00267 if( id == 110 || id == 990 || id == 9990 ) { return true; } 00268 if( digit(nj) > 0 && digit(nq3) > 0 && digit(nq2) > 0 && digit(nq1) == 0 ) { 00269 // check for illegal antiparticles 00270 if( digit(nq3) == digit(nq2) && pid() < 0 ) { 00271 return false; 00272 } else { 00273 return true; 00274 } 00275 } 00276 return false; 00277 } 00278 00279 // check to see if this is a valid meson 00280 bool ParticleID::isLepton( ) const 00281 { 00282 if( extraBits() > 0 ) { return false; } 00283 if( fundamentalID() >= 11 && fundamentalID() <= 18 ) { return true; } 00284 return false; 00285 } 00286 00287 // check to see if this is a valid hadron 00288 bool ParticleID::isHadron( ) const 00289 { 00290 if( extraBits() > 0 ) { return false; } 00291 if( isMeson() ) { return true; } 00292 if( isBaryon() ) { return true; } 00293 if( isPentaquark() ) { return true; } 00294 return false; 00295 } 00296 00297 // check to see if this is a valid diquark 00298 bool ParticleID::isDiQuark( ) const 00299 { 00300 if( extraBits() > 0 ) { return false; } 00301 if( abspid() <= 100 ) { return false; } 00302 if( fundamentalID() <= 100 && fundamentalID() > 0 ) { return false; } 00303 if( digit(nj) > 0 && digit(nq3) == 0 && digit(nq2) > 0 && digit(nq1) > 0 ) { // diquark signature 00304 // EvtGen uses the diquarks for quark pairs, so, for instance, 00305 // 5501 is a valid "diquark" for EvtGen 00306 //if( digit(nj) == 1 && digit(nq2) == digit(nq1) ) { // illegal 00307 // return false; 00308 //} else { 00309 return true; 00310 //} 00311 } 00312 return false; 00313 } 00314 00315 // check to see if this is a valid baryon 00316 bool ParticleID::isBaryon( ) const 00317 { 00318 if( extraBits() > 0 ) { return false; } 00319 if( abspid() <= 100 ) { return false; } 00320 if( fundamentalID() <= 100 && fundamentalID() > 0 ) { return false; } 00321 if( abspid() == 2110 || abspid() == 2210 ) { return true; } 00322 if( digit(nj) > 0 && digit(nq3) > 0 && digit(nq2) > 0 && digit(nq1) > 0 ) { return true; } 00323 return false; 00324 } 00325 00326 // return the total spin as 2J+1 00327 int ParticleID::jSpin( ) const 00328 { 00329 if( fundamentalID() > 0 && fundamentalID() <= 100 ) { 00330 // some of these are known 00331 int fund = fundamentalID(); 00332 if( fund > 0 && fund < 7 ) return 2; 00333 if( fund == 9 ) return 3; 00334 if( fund > 10 && fund < 17 ) return 2; 00335 if( fund > 20 && fund < 25 ) return 3; 00336 return 0; 00337 } else if( extraBits() > 0 ) { 00338 return 0; 00339 } 00340 return abspid()%10; 00341 } 00342 00343 // return the orbital angular momentum - valid for mesons only 00344 int ParticleID::lSpin( ) const 00345 { 00346 int nl, tent, js; 00347 if( !isMeson() ) { return 0; } 00348 nl = (abspid()/10000)%10; 00349 tent = (abspid()/1000000)%10; 00350 js = abspid()%10; 00351 if( tent == 9 ) { return 0; } // tentative assignment 00352 if( nl == 0 && js == 3 ) { 00353 return 0; 00354 } else if( nl == 0 && js == 5 ) { 00355 return 1; 00356 } else if( nl == 0 && js == 7 ) { 00357 return 2; 00358 } else if( nl == 0 && js == 9 ) { 00359 return 3; 00360 } else if( nl == 0 && js == 1 ) { 00361 return 0; 00362 } else if( nl == 1 && js == 3 ) { 00363 return 1; 00364 } else if( nl == 1 && js == 5 ) { 00365 return 2; 00366 } else if( nl == 1 && js == 7 ) { 00367 return 3; 00368 } else if( nl == 1 && js == 9 ) { 00369 return 4; 00370 } else if( nl == 2 && js == 3 ) { 00371 return 1; 00372 } else if( nl == 2 && js == 5 ) { 00373 return 2; 00374 } else if( nl == 2 && js == 7 ) { 00375 return 3; 00376 } else if( nl == 2 && js == 9 ) { 00377 return 4; 00378 } else if( nl == 1 && js == 1 ) { 00379 return 1; 00380 } else if( nl == 3 && js == 3 ) { 00381 return 2; 00382 } else if( nl == 3 && js == 5 ) { 00383 return 3; 00384 } else if( nl == 3 && js == 7 ) { 00385 return 4; 00386 } else if( nl == 3 && js == 9 ) { 00387 return 5; 00388 } 00389 // default to zero 00390 return 0; 00391 } 00392 00393 // return the spin - valid for mesons only 00394 int ParticleID::sSpin( ) const 00395 { 00396 int nl, tent, js; 00397 if( !isMeson() ) { return 0; } 00398 nl = (abspid()/10000)%10; 00399 tent = (abspid()/1000000)%10; 00400 js = abspid()%10; 00401 if( tent == 9 ) { return 0; } // tentative assignment 00402 if( nl == 0 && js >= 3 ) { 00403 return 1; 00404 } else if( nl == 0 && js == 1 ) { 00405 return 0; 00406 } else if( nl == 1 && js >= 3 ) { 00407 return 0; 00408 } else if( nl == 2 && js >= 3 ) { 00409 return 1; 00410 } else if( nl == 1 && js == 1 ) { 00411 return 1; 00412 } else if( nl == 3 && js >= 3 ) { 00413 return 1; 00414 } 00415 // default to zero 00416 return 0; 00417 } 00418 00419 int ParticleID::threeCharge( ) const 00420 { 00421 int charge=0; 00422 int ida, sid; 00423 unsigned short q1, q2, q3; 00424 static int ch100[100] = { -1, 2,-1, 2,-1, 2,-1, 2, 0, 0, 00425 -3, 0,-3, 0,-3, 0,-3, 0, 0, 0, 00426 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 00427 0, 0, 0, 3, 0, 0, 3, 0, 0, 0, 00428 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 00429 0, 6, 3, 6, 0, 0, 0, 0, 0, 0, 00430 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00431 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00432 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00433 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 00434 q1 = digit(nq1); 00435 q2 = digit(nq2); 00436 q3 = digit(nq3); 00437 ida = abspid(); 00438 sid = fundamentalID(); 00439 if( ida == 0 ) { // illegal 00440 return 0; 00441 } else if( extraBits() > 0 ) { 00442 if( isNucleus() ) { // ion 00443 return 3*Z(); 00444 } else { // not an ion 00445 return 0; 00446 } 00447 } else if( sid > 0 && sid <= 100 ) { // use table 00448 charge = ch100[sid-1]; 00449 if(ida==1000017 || ida==1000018) { charge = 0; } 00450 if(ida==1000034 || ida==1000052) { charge = 0; } 00451 if(ida==1000053 || ida==1000054) { charge = 0; } 00452 if(ida==5100061 || ida==5100062) { charge = 6; } 00453 } else if( digit(nj) == 0 ) { // KL, Ks, or undefined 00454 return 0; 00455 } else if( q1 == 0 ) { // mesons 00456 if( q2 == 3 || q2 == 5 ) { 00457 charge = ch100[q3-1] - ch100[q2-1]; 00458 } else { 00459 charge = ch100[q2-1] - ch100[q3-1]; 00460 } 00461 } else if( q3 == 0 ) { // diquarks 00462 charge = ch100[q2-1] + ch100[q1-1]; 00463 } else { // baryons 00464 charge = ch100[q3-1] + ch100[q2-1] + ch100[q1-1]; 00465 } 00466 if( charge == 0 ) { 00467 return 0; 00468 } else if( pid() < 0 ) { 00469 charge = -charge; 00470 } 00471 return charge; 00472 } 00473 00474 } // HepPDT