//-------------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // Matt.Dobbs@Cern.CH, January 2000 // Reads a particle data table from file supplied in PDG format // For the most recent table see: http://pdg.lbl.gov/computer_read.html ////////////////////////////////////////////////////////////////////////// #include // for isspace() etc. #include #include #include // needed for abort() #include // for strlen() #include "IO_PDG_ParticleDataTable.h" namespace HepMC { IO_PDG_ParticleDataTable::IO_PDG_ParticleDataTable( const char* filename ) : m_filename(filename), m_file(filename) { std::cout << "-------------------------------------------------------" << std::endl; std::cout << "Use of HepMC/IO_PDG_ParticleDataTable is deprecated" << std::endl; std::cout << "Use of HepMC/ParticleDataTable is deprecated" << std::endl; std::cout << "-------------------------------------------------------" << std::endl; } IO_PDG_ParticleDataTable::~IO_PDG_ParticleDataTable() { m_file.close(); } bool IO_PDG_ParticleDataTable::fill_particle_data_table( ParticleDataTable* pdt) { // // test that pdt pointer is not null if ( !pdt ) { std::cerr << "IO_Ascii::fill_particle_data_table - passed null table." << std::endl; return false; } // // test the file is good and advance to keyword if (!m_file ) { // return false; std::cerr << "IO_PDG_ParticleDataTable::fill_particle_data_table " << " ERROR, file " << m_filename << " does not exist, " << " ABORT." << std::endl; abort(); } m_file.seekg( 0 ); if ( !search_for_key_end(m_file,"\nM") ) { std::cerr << "IO_PDG_ParticleDataTable: " << "Error advancing to first entry." << std::endl; return false; } // set description std::string description = "Read from " + m_filename + " by IO_PDG_ParticleDataTable"; pdt->set_description( description ); m_file.putback('M'); // read in each entry one by one while ( m_file.rdstate() == 0 ) { read_entry( pdt ); } return true; } void IO_PDG_ParticleDataTable::read_entry( ParticleDataTable* pdt ) { int position = m_file.tellg(); // variables for input char code; int id[4] = { 0,0,0,0 }; int charge[4] = { 999, 999, 999, 999 }; double value; std::string name; code = m_file.get(); if ( code == EOF ) { m_file.clear( std::ios::eofbit ); return; } if ( code == '\n' ) return; // ignore empty lines. if ( code!='M' && code!='W' ) { std::cerr << "IO_PDG_ParticleDataTable::read_entry cannot " << "understand syntax, setting badbit." << std::endl; m_file.putback( code ); m_file.clear( std::ios::badbit ); return; } // read the particle ID's -- here I assume there is atleast one // white space b/t the 4 id columns. for ( int id_i1 = 0; id_i1 < 4; ++id_i1 ) { m_file.seekg( position+1+(id_i1*8) ); for ( int i = 0; i < 8; ++i ) { if ( !isspace(m_file.peek()) ) { //m_file.width(8-i); // has no effect // how do I limit to reading only 8-i characters? // setw(8-i) has no effect either. m_file >> id[id_i1]; break; } m_file.ignore(); } } //m_file.width(0); m_file.seekg(position+33); m_file >> value; m_file.seekg(position+66); m_file >> name; // loop over all remaining columns of the name section, where the // charge is stored --- until \n is reached // Here I assume there is atleast one white space between the name // and the charge. This is true for the 1998 PDG table, and I expect // it will always be true. int id_i2 = 0; while ( m_file.rdstate() == 0 ) { char c = m_file.get(); if ( c == '\n' || c == EOF ) break; if ( isspace(c) || c==',' ) { } else if ( c=='-' ) { charge[id_i2] = -1; ++id_i2; } else if ( c=='0' ) { charge[id_i2] = 0; ++id_i2; } else if ( c=='+' ) { charge[id_i2] = 1; if ( m_file.peek() == '+' ) { charge[id_i2] = 2; m_file.ignore(); } ++id_i2; } } // add the new information to the particle data table. for ( int id_i3 = 0; id_i3 < 4; ++id_i3 ) { if ( id[id_i3] == 0 ) continue; std::string scharge; if ( charge[id_i3] == -1 ) { scharge = "-"; } else if ( charge[id_i3] == 1 ) { scharge = "+"; } else if ( charge[id_i3] == 2 ) { scharge = "++"; } ParticleData* pdata = pdt->find( id[id_i3] ); if ( pdata ) { if ( code == 'M' ) { pdata->set_mass( value ); } else if ( code == 'W' ) { pdata->set_clifetime( clifetime_from_width(value) ); } } else if ( code == 'M' ) { pdata = new ParticleData( name+scharge, id[id_i3], (double)charge[id_i3], value ); pdt->insert(pdata); } else if ( code == 'W' ) { pdata = new ParticleData( name+scharge, id[id_i3], (double)charge[id_i3], 0, clifetime_from_width(value) ); pdt->insert(pdata); } } } void IO_PDG_ParticleDataTable::add_quarks_to_table( ParticleDataTable& pdt ) { /// since quarks aren't included in PDG table, this method adds them // in std::vector name(6); name[0] = "d"; name[1] = "u"; name[2] = "s"; name[3] = "c"; name[4] = "b"; name[5] = "t"; int id[6] = { 1, 2, 3, 4, 5, 6 }; double charge[6] = { -1./3., 2./3., -1./3., 2./3., -1./3., 2./3. }; // take central values from PDG July 1998 for masses double mass[6] = { 0.006, 0.00325, 0.115, 1.25, 4.25, 173.8 }; for ( int i = 0; i<6; ++i ) { // build the particle ParticleData* pdata = pdt.find(id[i]); if ( pdata ) { mass[i] = pdata->mass(); pdt.erase(pdata); delete pdata; } pdata = new ParticleData( name[i], id[i], charge[i], mass[i], -1., .5 ); pdt.insert(pdata); // build the antiparticle pdata = pdt.find(-1*id[i]); if ( pdata ) { pdt.erase(pdata); delete pdata; } pdata = new ParticleData( name[i]+"~", -1*id[i], -1*charge[i], mass[i], -1., .5 ); pdt.insert(pdata); } } bool IO_PDG_ParticleDataTable::search_for_key_end( std::istream& in, const char* key ) { /// (this method borrowed from IO_Ascii class) /// reads characters from in until the string of characters matching /// key is found (success) or EOF is reached (failure). /// It stops immediately thereafter. Returns T/F for success/fail // char c[1]; unsigned int index = 0; while ( in.get(c[0]) ) { if ( c[0] == key[index] ) { ++index; } else { index = 0; } if ( index == strlen(key) ) return true; } return false; } } // HepMC