HepPDT Reference Documentation

HepPDT

ParticleID.cc

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

Generated on Fri Dec 4 14:05:23 2009 for HepPDT by  doxygen 1.4.7