HepPDT Reference Documentation

HepPDT

ParticleIDMethods.cc

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

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