Project

General

Profile

Beam Optimization

Running the optimization

  • The optimization typically runs via a cron command that looks like this:
    #57 * * * * /usr/krb5/bin/kcron source ~/OptimizationCron2.sh >> /dune/data2/users/ljf26/CP_run31.log 2>&1
    

    In principle, this should just keep running continually without stopping, but grid problems, etc will eventually make it stop. Debugging why it stops is about 80% of the effort involved in running optimizations.
  • OptimizationCron2.sh sets up a g4lbnf release, then changes to the BeamSimStudies/GeneticOptimization folder of that release and runs the optimization python script. Here is what it does specifically:
    source $HOME/setup_g4lbnf.sh v3r4p3
    export PATH=$PATH:/usr/krb5/bin
    echo PATH
    cd BeamSimStudies/GeneticOptimization
    python DoOptimization.py CP_run31 -b
    
  • Here is the content of the g4lbnf setup script that OptimizationCron2.sh assumes is in your home directory:
    #!/bin/sh
    
    if [ $# -ne 1 ]
    then
      echo "Usage: `basename $0` version" 
      return
    fi
    
    source /dune/app/users/ljf26/lbne-beamsim/g4lbne/$1/setups/setup_g4lbne_fnal.sh
    
    export EDITOR="emacs -nw " 
    
    cd /dune/app/users/ljf26/lbne-beamsim/g4lbne/$1/
    
  • DoOptimization.py does the following:
    • Instantiates an object of Optimizations, a class definied in Optimizations.py, given a tag input by the user (CP_run31 in the above example)
    • Looks for output files already created for that optimization & merges if necessary
    • If no files are found (start of an optimization) or if a complete set of output files (allowing a few failures) is found, a new round of optimization is executed

Setting up a new round of optimization

  • To setup a new optimization, you need to modify Optimizations.py:
    • Add a new Optimization name to the vector at the top of the file. If it starts with "CP_", then CP sensitivity will automatically be optimized . "LE_" or "HE_" will optimize low or high energy flux
    • Set a list of parameter names, upper and lower limits, and macro commands using one of the existing optimizations as a template
    • The default macro template is macros/NoSnout.mac; if you want a different one, you should modify populateMacros() accordingly
  • Some modifications to OptimizationUtils.py may also necessary:
    • The "makeMacro" method needs to be modified to write the correct macro commands if you have any parameters that can't be changed with a simple macro command (for example, if you want to change the target with and proton energy simultaneously)
    • If there are particular combinations of parameters that you want to throw out, you should modify the ParametersOkay() method to check for those combinations (for example, if two horns run into each other)
      h3. Making Plots of Results
  • A bunch of plots are made by makePlots.py:
    makePlots.py <optimization_name> <max_iteration>
    
  • Fluxes for the best beams can be plotted with bestFitnesses.py:
    bestFitnesses.py <optimization_name> <max_iteration>
    

How to possibly speed things up

  • Implement particle swarm or other algorithm instead of genetic algorithm
  • If merging is dominating the time per generation, it might be better to run one job per beam configuration with more protons on target
  • Reduce number of protons per generation (have to balance against number of generations required)
  • The optimization currently checks each optimized macro to make sure it will run successfully before sending it to the grid. This takes a long time. It would be faster to configure parameters such that they never create geometry overlaps (which are the main reason why jobs don't run successfully)
  • Currently, the optimization does output merging, fitness calculation, generation of new beams, and grid submission in serial. It would be faster to do these in parallel -- e.g. to have a cron constantly checking for newly finished jobs, then merging and calculating sensitivity. Then a separate cron would look for cases where sensitivities are calculated for a full generation, then generate new beams