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( 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

Generated on Fri Oct 24 13:41:36 2008 for HepPDT by  doxygen 1.5.1-3