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