text: #!/usr/bin/env python
  #
  # GAMBIT: Global and Modular BSM Inference Tool
  #*********************************************
  # \file
  #
  #  Particle harvesting script.
  #  Generates particle_database.hpp
  #
  #  This script parses the particle_database.yaml 
  #  file and adds the correct particle macros to 
  #  the particle database .cpp file.
  #
  #*********************************************
  #
  #  Authors (add name and date if you modify):
  #
  #  \author Sanjay Bloor
  #          (sanjay.bloor12@imperial.ac.uk)
  #    \date 2017 Aug
  #
  #  \author Ben Farmer
  #          (b.farmer@imperial.ac.uk)
  #  \date 2018 Oct
  #
  #*********************************************
  import os
  import yaml
  import itertools
  
  toolsfile="./Utils/scripts/harvesting_tools.py"
  exec(compile(open(toolsfile, "rb").read(), toolsfile, 'exec')) # Python 2/3 compatible version of 'execfile'
  
  def create_entry(macro, particle_list):
  
    '''Create the correct entry to add to particle_database.cpp. The 
    argument "macro" should be one of the macros in particle_macros.hpp.'''
    
    # Output to add to the particle database. 
    output = "\n      "
    
    for i in range(0, len(particle_list)):
    
      entry = particle_list[i]
      
      # If there's a comment -> just post it without the rest of the stuff
      if 'comment' in entry:
        output += "\n      // " + entry['comment'] + "\n      "
      
      else:
        PDG = entry['PDG_context']
        
        # Count how many particles appear in the PDG_context lists.
        numlists = sum(1 for x in PDG if isinstance(x, list))
        
        # Add description (C++ comment) if it exists
        if 'description' in entry:
          output += "\n      // " + str(entry['description']) + "\n      "
          
        # Add the macro plus the particle name, plus the PDG-context pair. 
        output += macro + '("' + str(entry['name']) + '", ' + str(entry['PDG_context']).replace("]",")").replace("[","(") + ")\n      " 
      
        # If the YAML file says there is a conjugate particle, add the name of it and the negative PDG-context pair
        if 'conjugate' in entry: 
          output += macro + '("' + str(entry['conjugate']) + '", ('
          
          # If it is not a particle set.
          if numlists == 0:
            output += str(-PDG[0]) + ", " + str(PDG[1])
            
          # If it is a particle set. 
          else:  
            for i in range(0, numlists):
              output += '(' + str(-PDG[i][0]) + ", " + str(PDG[i][1]) + ')'
              # Comma separate all but the last one
              if i < numlists-1: 
                output += ', '
                
          output += "))\n      "
          
    return output
  
  def main(argv):
      
    with open("./config/particle_database.yaml", "r") as f:
  
      try:
        data = yaml.load(f)
      except yaml.YAMLerror as exc:
        print (exc)
        
      # These correspond to the five macros in particle_macros.hpp.
      SM_particles = data['StandardModel']['Particles']   # add_SM_particle
      SM_sets = data['StandardModel']['Sets']             # add_SM_partcle_set
      BSM_particles = data['OtherModels']['Particles']    # add_particle
      BSM_sets = data['OtherModels']['Sets']              # add_particle_set
      Generic = data['OtherModels']['Generic']            # add_generic_particle
      
    towrite = "\
  //   GAMBIT: Global and Modular BSM Inference Tool\n\
  //   *********************************************\n\
  ///  \\file                                       \n\
  ///                                               \n\
  ///  Compile-time generation of particle          \n\
  ///  database.                                    \n\
  ///                                               \n\
  ///  This file was automatically generated by     \n\
  ///  particle_harvester.py. Do not modify.        \n\
  ///                                               \n\
  ///  Do not add to this if you want to add new    \n\
  ///  particles -- just add the particles to the   \n\
  ///  include/gambit/Models/particle_database.yaml \n\
  ///  file, and be confident that the particle     \n\
  ///  harvester will add it to the database.       \n\
  ///                                               \n\
  ///  *********************************************\n\
  ///                                               \n\
  ///  Authors (add name and date if you modify):   \n\
  ///                                               \n\
  ///  \\author The GAMBIT Collaboration            \n\
  ///  \date "+datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y")+"\n\
  ///                                               \n\
  ///  *********************************************\n\
                                                    \n\
  // Automatically-generated particle database.     \n\
                                                    \n\
                                                    \n\
  #include \"gambit/Models/partmap.hpp\"            \n\
  #include \"gambit/Models/particle_macros.hpp\"    \n\
                                                    \n\
  namespace Gambit                                  \n\
  {                                                 \n\
                                                    \n\
    namespace Models                                \n\
    {                                               \n\
                                                    \n\
      void define_particles(partmap* particles)     \n\
      {                                             \n"
    towrite+= create_entry("add_SM_particle", SM_particles)  
      
    towrite+= create_entry("add_SM_particle_set", SM_sets)
    
    towrite+= create_entry("add_particle", BSM_particles)
    
    towrite+= create_entry("add_particle_set", BSM_sets)
  
    towrite+= create_entry("add_generic_particle", Generic)
    
    towrite+="                                      \n\
      }                                             \n\
                                                    \n\
    }                                               \n\
                                                    \n\
  }                                                 \n"
  
  
    with open("./Models/src/particle_database.cpp","w") as f:
      f.write(towrite)
  
  # Handle command line arguments (verbosity)
  if __name__ == "__main__":
     main(sys.argv[1:])
  