diff --git a/FixedOrderGen/configFO.yml b/FixedOrderGen/configFO.yml
index cebbb11..f14188c 100644
--- a/FixedOrderGen/configFO.yml
+++ b/FixedOrderGen/configFO.yml
@@ -1,64 +1,68 @@
 # number of generated events
 events: 200
 
 jets:
   min pt: 20
   peak pt: 30
   algorithm: antikt
   R: 0.4
   max rapidity: 5
 
 beam:
   energy: 6500
   particles: [p, p]
 
 pdf: 230000
 
 process: p p => h 4j
 
 # fraction of events with two extremal emissions in one direction
 # that contain an subleading emission e.g. unordered emission
 subleading fraction: 0.05
+# Allow different subleading configurations
+# By default all implemented processes are allowed
+#
+# subleading channels: unordered
 
 scales: max jet pperp
 
 event output:
   - HEJFO.lhe
 #  - HEJ.lhe
 #  - HEJ_events.hepmc
 
 particle properties:
   Higgs:
     mass: 125
     width: 0.004165
     decays: {into: [photon, photon], branching ratio: 0.0023568762400521404}
 
 random generator:
   name: mixmax
 
 # unweighting parameters
 # remove to obtain weighted events
 unweight:
   sample size: 200  # should be similar to "events:", but not more than ~10000
   max deviation: 0
 
 # to use a rivet analysis
 #
 # analysis:
 #   rivet: MC_XS # rivet analysis name
 #   output: HEJ # name of the yoda files, ".yoda" and scale suffix will be added
 #
 # to use a custom analysis
 #
 # analysis:
 #   plugin: /path/to/libmyanalysis.so
 #   my analysis parameter: some value
 
 # parameters for Higgs-gluon couplings
 # this requires compilation with qcdloop
 #
 # Higgs coupling:
 #   use impact factors: false
 #   mt: 174
 #   include bottom: true
 #   mb: 4.7
diff --git a/FixedOrderGen/include/EventGenerator.hh b/FixedOrderGen/include/EventGenerator.hh
index 8fe376a..a039144 100644
--- a/FixedOrderGen/include/EventGenerator.hh
+++ b/FixedOrderGen/include/EventGenerator.hh
@@ -1,54 +1,56 @@
 #pragma once
 
 #include "HEJ/PDF.hh"
 #include "HEJ/MatrixElement.hh"
 #include "HEJ/RNG.hh"
 
 #include "JetParameters.hh"
 #include "Process.hh"
 #include "Beam.hh"
 #include "Status.hh"
 #include "ParticleProperties.hh"
 
 namespace HEJ{
   class Event;
   class HiggsCouplingSettings;
   class ScaleGenerator;
 }
 
 //! Namespace for HEJ Fixed Order Generator
 namespace HEJFOG{
   class EventGenerator{
   public:
     EventGenerator(
         Process process,
         Beam beam,
         HEJ::ScaleGenerator scale_gen,
         JetParameters jets,
         int pdf_id,
         double subl_change,
+        unsigned int subl_channels,
         ParticlesPropMap particles_properties,
         HEJ::HiggsCouplingSettings Higgs_coupling,
         HEJ::RNG & ran
     );
 
     HEJ::Event gen_event();
 
     Status status() const {
       return status_;
     }
 
   private:
     HEJ::PDF pdf_;
     HEJ::MatrixElement ME_;
     HEJ::ScaleGenerator scale_gen_;
     Process process_;
     JetParameters jets_;
     Beam beam_;
     Status status_;
     double subl_change_;
+    unsigned int subl_channels_;
     ParticlesPropMap particles_properties_;
     std::reference_wrapper<HEJ::RNG> ran_;
   };
 
 }
diff --git a/FixedOrderGen/include/PhaseSpacePoint.hh b/FixedOrderGen/include/PhaseSpacePoint.hh
index da36093..2645b40 100644
--- a/FixedOrderGen/include/PhaseSpacePoint.hh
+++ b/FixedOrderGen/include/PhaseSpacePoint.hh
@@ -1,184 +1,187 @@
 /** \file PhaseSpacePoint.hh
  *  \brief Contains the PhaseSpacePoint Class
  */
 
 #pragma once
 
 #include <vector>
 
 #include "HEJ/utility.hh"
 #include "HEJ/Event.hh"
 #include "HEJ/PDG_codes.hh"
 #include "HEJ/PDF.hh"
 #include "HEJ/RNG.hh"
 
 #include "Status.hh"
 #include "JetParameters.hh"
 #include "ParticleProperties.hh"
 
 namespace HEJFOG{
   class Process;
 
   using HEJ::Particle;
   //! A point in resummation phase space
   class PhaseSpacePoint{
   public:
     //! Default PhaseSpacePoint Constructor
     PhaseSpacePoint() = default;
 
     //! PhaseSpacePoint Constructor
     /**
      * @param proc                  The process to generate
      * @param jet_properties        Jet defintion & cuts
      * @param pdf                   The pdf set (used for sampling)
      * @param E_beam                Energie of the beam
      * @param subl_chance           Chance to turn a potentially unordered
      *                              emission into an actual one
+     * @param subl_channels         Possible subleading channels.
+     *                              see HEJFOG::Subleading
      * @param particle_properties   Properties of producted boson
      *
      * Initially, only FKL phase space points are generated. If the most
      * extremal emission in any direction is a quark or anti-quark and the
      * next emission is a gluon, subl_chance is the chance to turn this into
      * an unordered emission event by swapping the two flavours. At most one
      * unordered emission will be generated in this way.
      */
     PhaseSpacePoint(
       Process const & proc,
       JetParameters const & jet_properties,
       HEJ::PDF & pdf, double E_beam,
       double subl_chance,
+      unsigned int subl_channels,
       ParticlesPropMap const & particles_properties,
       HEJ::RNG & ran
     );
 
     //! Get Weight Function
     /**
      * @returns        Weight of Event
      */
     double weight() const{
       return weight_;
     }
 
     Status status() const{
       return status_;
     }
 
     //! Get Incoming Function
     /**
      * @returns        Incoming Particles
      */
     std::array<Particle, 2> const & incoming() const{
       return incoming_;
     }
 
     //! Get Outgoing Function
     /**
      * @returns        Outgoing Particles
      */
     std::vector<Particle> const & outgoing() const{
       return outgoing_;
     }
 
     std::unordered_map<size_t, std::vector<Particle>> const & decays() const{
       return decays_;
     }
 
     private:
     /**
      * \internal
      * \brief Generate LO parton momentum
      *
      * @param count             Number of partons to generate
      * @param is_pure_jets      If true ensures momentum conservation in x and y
      * @param jet_param         Jet properties to fulfil
      * @param max_pt            max allowed pt for a parton (typically E_CMS)
      * @param ran               Random Number Generator
      *
      * @returns                 Momentum of partons
      *
      * Ensures that each parton is in its own jet.
      * Generation is independent of parton flavour. Output is sorted in rapidity.
      */
     std::vector<fastjet::PseudoJet> gen_LO_partons(
         int count, bool is_pure_jets,
         JetParameters const & jet_param,
         double max_pt,
         HEJ::RNG & ran
     );
     Particle gen_boson(
         HEJ::ParticleID bosonid, double mass, double width,
         HEJ::RNG & ran
     );
     template<class ParticleMomenta>
     fastjet::PseudoJet gen_last_momentum(
         ParticleMomenta const & other_momenta,
         double mass_square, double y
     ) const;
 
     bool jets_ok(
         std::vector<fastjet::PseudoJet> const & Born_jets,
         std::vector<fastjet::PseudoJet> const & partons
     ) const;
     /**
      * \internal
      * \brief Generate incoming partons according to the PDF
      *
      * @param uf                Scale used in the PDF
      */
     void reconstruct_incoming(
         std::array<HEJ::ParticleID, 2> const & ids,
         HEJ::PDF & pdf, double E_beam,
         double uf,
         HEJ::RNG & ran
     );
     HEJ::ParticleID generate_incoming_id(
         size_t beam_idx, double x, double uf, HEJ::PDF & pdf,
         HEJ::RNG & ran
     );
 
     bool momentum_conserved(double ep) const;
 
     HEJ::Particle const & most_backward_FKL(
         std::vector<HEJ::Particle> const & partons
     ) const;
     HEJ::Particle const & most_forward_FKL(
         std::vector<HEJ::Particle> const & partons
     ) const;
     HEJ::Particle & most_backward_FKL(std::vector<HEJ::Particle> & partons) const;
     HEJ::Particle & most_forward_FKL(std::vector<HEJ::Particle> & partons) const;
     bool extremal_FKL_ok(
         std::vector<fastjet::PseudoJet> const & partons
     ) const;
     double random_normal(double stddev, HEJ::RNG & ran);
     void maybe_turn_to_uno(double chance, HEJ::RNG & ran);
     std::vector<Particle> decay_boson(
         HEJ::Particle const & parent,
         std::vector<Decay> const & decays,
         HEJ::RNG & ran
     );
     Decay select_decay_channel(
         std::vector<Decay> const & decays,
         HEJ::RNG & ran
     );
     double gen_hard_pt(
         int np, double ptmin, double ptmax, double y,
         HEJ::RNG & ran
     );
     double gen_soft_pt(int np, double ptmax, HEJ::RNG & ran);
     double gen_parton_pt(
         int count, JetParameters const & jet_param, double ptmax, double y,
         HEJ::RNG & ran
     );
 
 
     double weight_;
 
     Status status_;
 
     std::array<Particle, 2> incoming_;
     std::vector<Particle> outgoing_;
     //! Particle decays in the format {outgoing index, decay products}
     std::unordered_map<size_t, std::vector<Particle>> decays_;
   };
   HEJ::UnclusteredEvent to_UnclusteredEvent(PhaseSpacePoint const & psp);
 }
diff --git a/FixedOrderGen/include/Subleading.hh b/FixedOrderGen/include/Subleading.hh
new file mode 100644
index 0000000..0edc565
--- /dev/null
+++ b/FixedOrderGen/include/Subleading.hh
@@ -0,0 +1,14 @@
+#pragma once
+
+namespace HEJFOG{
+  /**
+   * Bit position of different subleading channels
+   * e.g. (unsigned int) 1 => only unordered
+   */
+  enum Subleading: unsigned {
+    none = 0u,
+    all = ~0u,
+    uno = 1u,
+    unordered = uno
+  };
+}
diff --git a/FixedOrderGen/include/config.hh b/FixedOrderGen/include/config.hh
index d98f9e1..e34b2ec 100644
--- a/FixedOrderGen/include/config.hh
+++ b/FixedOrderGen/include/config.hh
@@ -1,37 +1,38 @@
 #pragma once
 
 #include "yaml-cpp/yaml.h"
 
 #include "HEJ/HiggsCouplingSettings.hh"
 #include "HEJ/optional.hh"
 #include "HEJ/config.hh"
 #include "HEJ/output_formats.hh"
 #include "HEJ/exceptions.hh"
 
 #include "Process.hh"
 #include "JetParameters.hh"
 #include "Beam.hh"
 #include "ParticleProperties.hh"
 #include "UnweightSettings.hh"
 
 namespace HEJFOG{
 
   struct Config{
     Process process;
     int events;
     JetParameters jets;
     Beam beam;
     int pdf_id;
     double subleading_fraction;
+    unsigned int subleading_channels; //! < see HEJFOG::Subleading
     ParticlesPropMap particles_properties;
     YAML::Node analysis_parameters;
     HEJ::ScaleConfig scales;
     std::vector<HEJ::OutputFile> output;
     HEJ::RNGConfig rng;
     HEJ::HiggsCouplingSettings Higgs_coupling;
     HEJ::optional<UnweightSettings> unweight;
   };
 
   Config load_config(std::string const & config_file);
 
 }
diff --git a/FixedOrderGen/src/EventGenerator.cc b/FixedOrderGen/src/EventGenerator.cc
index 90c80af..8cfa609 100644
--- a/FixedOrderGen/src/EventGenerator.cc
+++ b/FixedOrderGen/src/EventGenerator.cc
@@ -1,78 +1,80 @@
 #include "EventGenerator.hh"
 
 #include "Process.hh"
 #include "Beam.hh"
 #include "JetParameters.hh"
 #include "PhaseSpacePoint.hh"
 
 #include "HEJ/Event.hh"
 #include "HEJ/config.hh"
 
 namespace HEJFOG{
   EventGenerator::EventGenerator(
       Process process,
       Beam beam,
       HEJ::ScaleGenerator scale_gen,
       JetParameters jets,
       int pdf_id,
       double subl_change,
+      unsigned int subl_channels,
       ParticlesPropMap particles_properties,
       HEJ::HiggsCouplingSettings Higgs_coupling,
       HEJ::RNG & ran
   ):
     pdf_{pdf_id, beam.particles[0], beam.particles[1]},
     ME_{
       [this](double mu){ return pdf_.Halphas(mu); },
       HEJ::MatrixElementConfig{
         false,
         std::move(Higgs_coupling)
       }
     },
     scale_gen_{std::move(scale_gen)},
     process_{std::move(process)},
     jets_{std::move(jets)},
     beam_{std::move(beam)},
     subl_change_{subl_change},
+    subl_channels_{subl_channels},
     particles_properties_{std::move(particles_properties)},
     ran_{ran}
   {
   }
 
   HEJ::Event EventGenerator::gen_event(){
     HEJFOG::PhaseSpacePoint psp{
       process_,
       jets_,
       pdf_, beam_.energy,
-      subl_change_,
+      subl_change_, subl_channels_,
       particles_properties_,
       ran_
     };
     status_ = psp.status();
     if(status_ != good) return {};
 
     HEJ::Event ev = scale_gen_(
         HEJ::Event{
           to_UnclusteredEvent(std::move(psp)),
           jets_.def, jets_.min_pt
         }
     );
 
     const double shat = HEJ::shat(ev);
     const double xa = (ev.incoming()[0].E()-ev.incoming()[0].pz())/(2.*beam_.energy);
     const double xb = (ev.incoming()[1].E()+ev.incoming()[1].pz())/(2.*beam_.energy);
 
     // evaluate matrix element on this point
     const auto ME_weights = ME_.tree(ev, false);
     ev.central().weight *= ME_weights.central/(shat*shat);
     ev.central().weight *= pdf_.pdfpt(0,xa,ev.central().muf, ev.incoming()[0].type);
     ev.central().weight *= pdf_.pdfpt(0,xb,ev.central().muf, ev.incoming()[1].type);
     for(size_t i = 0; i < ev.variations().size(); ++i){
       auto & var = ev.variations(i);
       var.weight *= ME_weights.variations[i]/(shat*shat);
       var.weight *= pdf_.pdfpt(0,xa,var.muf, ev.incoming()[0].type);
       var.weight *= pdf_.pdfpt(0,xb,var.muf, ev.incoming()[1].type);
     }
     return ev;
   }
 
 }
diff --git a/FixedOrderGen/src/PhaseSpacePoint.cc b/FixedOrderGen/src/PhaseSpacePoint.cc
index 740a910..4182985 100644
--- a/FixedOrderGen/src/PhaseSpacePoint.cc
+++ b/FixedOrderGen/src/PhaseSpacePoint.cc
@@ -1,457 +1,459 @@
 #include "PhaseSpacePoint.hh"
 
 #include <random>
 
 #include "HEJ/kinematics.hh"
 #include "HEJ/utility.hh"
 #include "HEJ/exceptions.hh"
 
 #include "Process.hh"
+#include "Subleading.hh"
 
 #include <CLHEP/Random/Randomize.h>
 #include <CLHEP/Random/RanluxEngine.h>
 
 using namespace HEJ;
 
 namespace HEJFOG{
 
   static_assert(
       std::numeric_limits<double>::has_quiet_NaN,
       "no quiet NaN for double"
   );
   constexpr double NaN = std::numeric_limits<double>::quiet_NaN();
   HEJ::UnclusteredEvent to_UnclusteredEvent(PhaseSpacePoint const & psp){
     HEJ::UnclusteredEvent result;
     result.incoming = psp.incoming();
     std::sort(
         begin(result.incoming), end(result.incoming),
         [](Particle o1, Particle o2){return o1.p.pz()<o2.p.pz();}
     );
     assert(result.incoming.size() == 2);
     result.outgoing = psp.outgoing();
     assert(
         std::is_sorted(
             begin(result.outgoing), end(result.outgoing),
             HEJ::rapidity_less{}
         )
     );
     assert(result.outgoing.size() >= 2);
     result.decays = psp.decays();
     result.central.mur = NaN;
     result.central.muf = NaN;
     result.central.weight = psp.weight();
     return result;
   }
 
   namespace{
     bool can_swap_to_uno(
         HEJ::Particle const & p1, HEJ::Particle const & p2
     ){
       return is_parton(p1)
         && p1.type != HEJ::pid::gluon
         && p2.type == HEJ::pid::gluon;
     }
   }
 
   void PhaseSpacePoint::maybe_turn_to_uno(
       double chance,
       HEJ::RNG & ran
   ){
     assert(outgoing_.size() >= 2);
     const size_t nout = outgoing_.size();
     const bool can_be_uno_backward = can_swap_to_uno(
         outgoing_[0], outgoing_[1]
     );
     const bool can_be_uno_forward = can_swap_to_uno(
         outgoing_[nout-1], outgoing_[nout-2]
     );
     if(!can_be_uno_backward && !can_be_uno_forward) return;
     if(ran.flat() < chance){
       weight_ /= chance;
       if(can_be_uno_backward && can_be_uno_forward){
         if(ran.flat() < 0.5){
           std::swap(outgoing_[0].type, outgoing_[1].type);
         }
         else{
           std::swap(outgoing_[nout-1].type, outgoing_[nout-2].type);
         }
         weight_ *= 2.;
       }
       else if(can_be_uno_backward){
         std::swap(outgoing_[0].type, outgoing_[1].type);
       }
       else{
         assert(can_be_uno_forward);
         std::swap(outgoing_[nout-1].type, outgoing_[nout-2].type);
       }
     }
     else weight_ /= 1 - chance;
   }
 
   template<class ParticleMomenta>
   fastjet::PseudoJet PhaseSpacePoint::gen_last_momentum(
       ParticleMomenta const & other_momenta,
       const double mass_square, const double y
   ) const {
     std::array<double,2> pt{0.,0.};
     for (auto const & p: other_momenta) {
       pt[0]-= p.px();
       pt[1]-= p.py();
     }
 
     const double mperp = sqrt(pt[0]*pt[0]+pt[1]*pt[1]+mass_square);
     const double pz=mperp*sinh(y);
     const double E=mperp*cosh(y);
 
     return {pt[0], pt[1], pz, E};
   }
 
   PhaseSpacePoint::PhaseSpacePoint(
     Process const & proc,
     JetParameters const & jet_param,
     HEJ::PDF & pdf, double E_beam,
     double subl_change,
+    unsigned int subl_channels,
     ParticlesPropMap const & particles_properties,
     HEJ::RNG & ran
   )
   {
     assert(proc.njets >= 2);
     if(proc.boson
       && particles_properties.find(*(proc.boson))
         == particles_properties.end())
       throw HEJ::missing_option("Boson "
         +std::to_string(*(proc.boson))+" can't be generated: missing properties");
     status_ = good;
     weight_ = 1;
 
     const int nout = proc.njets + (proc.boson?1:0);
     outgoing_.reserve(nout);
 
     const bool is_pure_jets = !proc.boson;
     auto partons = gen_LO_partons(
         proc.njets, is_pure_jets, jet_param, E_beam, ran
     );
     for(auto&& p_out: partons) {
       outgoing_.emplace_back(Particle{pid::gluon, std::move(p_out)});
     }
     if(status_ != good) return;
 
     // create boson
     if(proc.boson){
       const auto & boson_prop = particles_properties.at(*proc.boson);
       auto boson(gen_boson(*proc.boson, boson_prop.mass, boson_prop.width, ran));
       const auto pos = std::upper_bound(
           begin(outgoing_),end(outgoing_),boson,rapidity_less{}
       );
       outgoing_.insert(pos, std::move(boson));
       if(! boson_prop.decays.empty()){
         const size_t boson_idx = std::distance(begin(outgoing_), pos);
         decays_.emplace(
             boson_idx,
             decay_boson(outgoing_[boson_idx], boson_prop.decays, ran)
         );
       }
     }
     // normalisation of momentum-conserving delta function
     weight_ *= pow(2*M_PI, 4);
 
     reconstruct_incoming(proc.incoming, pdf, E_beam, jet_param.min_pt, ran);
     if(status_ != good) return;
     // set outgoing states
     most_backward_FKL(outgoing_).type = incoming_[0].type;
     most_forward_FKL(outgoing_).type = incoming_[1].type;
 
-    if(proc.njets > 2) maybe_turn_to_uno(subl_change, ran);
+    if(proc.njets > 2 && subl_channels & Subleading::uno) maybe_turn_to_uno(subl_change, ran);
   }
 
   double PhaseSpacePoint::gen_hard_pt(
       int np , double ptmin, double ptmax, double y,
       HEJ::RNG & ran
   ) {
     // heuristic parameters for pt sampling
     const double ptpar = ptmin + np/5.;
     const double arg_small_y = atan((ptmax - ptmin)/ptpar);
     const double y_cut = 3.;
 
     const double r1 = ran.flat();
     if(y < y_cut){
       const double pt = ptmin + ptpar*tan(r1*arg_small_y);
       const double temp = cos(r1*arg_small_y);
       weight_ *= pt*ptpar*arg_small_y/(temp*temp);
       return pt;
     }
 
     const double ptpar2 = ptpar/(1 + 5*(y-y_cut));
     const double temp = 1. - std::exp((ptmin-ptmax)/ptpar2);
     const double pt = ptmin - ptpar2*std::log(1-r1*temp);
     weight_ *= pt*ptpar2*temp/(1-r1*temp);
     return pt;
   }
 
   double PhaseSpacePoint::gen_soft_pt(int np, double max_pt, HEJ::RNG & ran) {
     constexpr double ptpar = 4.;
 
     const double r = ran.flat();
     const double pt = max_pt + ptpar/np*std::log(r);
     weight_ *= pt*ptpar/(np*r);
     return pt;
   }
 
   double PhaseSpacePoint::gen_parton_pt(
       int count, JetParameters const & jet_param, double max_pt, double y,
       HEJ::RNG & ran
   ) {
     constexpr double p_small_pt = 0.02;
 
     if(! jet_param.peak_pt) {
        return gen_hard_pt(count, jet_param.min_pt, max_pt, y, ran);
     }
     const double r = ran.flat();
     if(r > p_small_pt) {
       weight_ /= 1. - p_small_pt;
       return gen_hard_pt(count, *jet_param.peak_pt, max_pt, y, ran);
     }
     weight_ /= p_small_pt;
     const double pt =  gen_soft_pt(count, *jet_param.peak_pt, ran);
     if(pt < jet_param.min_pt) {
       weight_=0.0;
       status_ = not_enough_jets;
       return jet_param.min_pt;
     }
     return pt;
   }
 
   std::vector<fastjet::PseudoJet> PhaseSpacePoint::gen_LO_partons(
       int np, bool is_pure_jets,
       JetParameters const & jet_param,
       double max_pt,
       HEJ::RNG & ran
   ){
     if (np<2) throw std::invalid_argument{"Not enough partons in gen_LO_partons"};
 
     weight_ /= pow(16.*pow(M_PI,3),np);
     weight_ /= std::tgamma(np+1); //remove rapidity ordering
     std::vector<fastjet::PseudoJet> partons;
     partons.reserve(np);
     for(int i = 0; i < np; ++i){
       const double y = -jet_param.max_y + 2*jet_param.max_y*ran.flat();
       weight_ *= 2*jet_param.max_y;
 
       const bool is_last_parton = i+1 == np;
       if(is_pure_jets && is_last_parton) {
         constexpr double parton_mass_sq = 0.;
         partons.emplace_back(gen_last_momentum(partons, parton_mass_sq, y));
         break;
       }
 
       const double phi = 2*M_PI*ran.flat();
       weight_ *= 2.0*M_PI;
 
       const double pt = gen_parton_pt(np, jet_param, max_pt, y, ran);
       if(weight_ == 0.0) return {};
 
       partons.emplace_back(fastjet::PtYPhiM(pt, y, phi));
       assert(jet_param.min_pt <= partons[i].pt());
       assert(partons[i].pt() <= max_pt+1e-5);
     }
     // Need to check that at LO, the number of jets = number of partons;
     fastjet::ClusterSequence cs(partons, jet_param.def);
     auto cluster_jets=cs.inclusive_jets(jet_param.min_pt);
     if (cluster_jets.size()!=unsigned(np)){
       weight_=0.0;
       status_ = not_enough_jets;
       return {};
     }
 
     std::sort(begin(partons), end(partons), rapidity_less{});
 
     return partons;
   }
 
   Particle PhaseSpacePoint::gen_boson(
       HEJ::ParticleID bosonid, double mass, double width,
       HEJ::RNG & ran
   ){
     if(bosonid != HEJ::pid::Higgs)
       throw HEJ::not_implemented("Production of boson "+std::to_string(bosonid)
         +" not implemented yet.");
     // Usual phase space measure
     weight_ /= 16.*pow(M_PI, 3);
 
     // Generate a y Gaussian distributed around 0
     // TODO: magic number only for Higgs
     const double y = random_normal(1.6, ran);
     const double r1 = ran.flat();
     const double sH = mass*(
         mass + width*tan(M_PI/2.*r1 + (r1-1.)*atan(mass/width))
     );
 
     auto p = gen_last_momentum(outgoing_, sH, y);
 
     return Particle{bosonid, std::move(p)};
   }
 
   Particle const & PhaseSpacePoint::most_backward_FKL(
       std::vector<Particle> const & partons
   ) const{
     if(!HEJ::is_parton(partons[0])) return partons[1];
     return partons[0];
   }
 
   Particle const & PhaseSpacePoint::most_forward_FKL(
       std::vector<Particle> const & partons
   ) const{
     const size_t last_idx = partons.size() - 1;
     if(!HEJ::is_parton(partons[last_idx])) return partons[last_idx-1];
     return partons[last_idx];
   }
 
   Particle & PhaseSpacePoint::most_backward_FKL(
       std::vector<Particle> & partons
   ) const{
     if(!HEJ::is_parton(partons[0])) return partons[1];
     return partons[0];
   }
 
   Particle & PhaseSpacePoint::most_forward_FKL(
       std::vector<Particle> & partons
   ) const{
     const size_t last_idx = partons.size() - 1;
     if(!HEJ::is_parton(partons[last_idx])) return partons[last_idx-1];
     return partons[last_idx];
   }
 
   void PhaseSpacePoint::reconstruct_incoming(
       std::array<HEJ::ParticleID, 2> const & ids,
       HEJ::PDF & pdf, double E_beam,
       double uf,
       HEJ::RNG & ran
   ){
     std::tie(incoming_[0].p, incoming_[1].p) = incoming_momenta(outgoing_);
     // calculate xa, xb
     const double sqrts=2*E_beam;
     const double xa=(incoming_[0].p.e()-incoming_[0].p.pz())/sqrts;
     const double xb=(incoming_[1].p.e()+incoming_[1].p.pz())/sqrts;
     // abort if phase space point is outside of collider energy reach
     if (xa>1. || xb>1.){
       weight_=0;
       status_ = too_much_energy;
       return;
     }
     // pick pdfs
     /** @TODO:
      *  ufa, ufb don't correspond to our final scale choice.
      *  The HEJ scale generators currently expect a full event as input,
      *  so fixing this is not completely trivial
      */
     for(size_t i = 0; i < 2; ++i){
       if(ids[i] == pid::proton || ids[i] == pid::p_bar){
         incoming_[i].type = generate_incoming_id(i, i?xb:xa, uf, pdf, ran);
       }
       else {
         incoming_[i].type = ids[i];
       }
     }
     assert(momentum_conserved(1e-7));
   }
 
   namespace {
     /// particles are ordered, odd = anti
     ParticleID index_to_pid(size_t i){
       if(!i) return pid::gluon;
       return static_cast<ParticleID>(i%2?(i+1)/2:-i/2);
     }
   }
 
   HEJ::ParticleID PhaseSpacePoint::generate_incoming_id(
       size_t const beam_idx, double const x, double const uf,
       HEJ::PDF & pdf, HEJ::RNG & ran
   ){
     std::array<double,11> pdf_wt;
     pdf_wt[0] = fabs(pdf.pdfpt(beam_idx,x,uf,pid::gluon));
     double pdftot = pdf_wt[0];
       for(size_t i = 1; i < pdf_wt.size(); ++i){
       pdf_wt[i] = 4./9.*fabs(pdf.pdfpt(beam_idx,x,uf,index_to_pid(i)));
       pdftot += pdf_wt[i];
     }
     const double r1 = pdftot * ran.flat();
     double sum = 0;
     for(size_t i=0; i < pdf_wt.size(); ++i){
       if (r1 < (sum+=pdf_wt[i])){
         weight_*= pdftot/pdf_wt[i];
         return index_to_pid(i);
       }
     }
     std::cerr << "Error in choosing incoming parton: "<<x<<" "<<uf<<" "
       <<sum<<" "<<pdftot<<" "<<r1<<std::endl;
     throw std::logic_error{"Failed to choose parton flavour"};
   }
 
   double PhaseSpacePoint::random_normal(
       double stddev,
       HEJ::RNG & ran
   ){
     const double r1 = ran.flat();
     const double r2 = ran.flat();
     const double lninvr1 = -log(r1);
     const double result = stddev*sqrt(2.*lninvr1)*cos(2.*M_PI*r2);
     weight_ *= exp(result*result/(2*stddev*stddev))*sqrt(2.*M_PI)*stddev;
     return result;
   }
 
   bool PhaseSpacePoint::momentum_conserved(double ep) const{
     fastjet::PseudoJet diff;
     for(auto const & in: incoming()) diff += in.p;
     for(auto const & out: outgoing()) diff -= out.p;
     return nearby_ep(diff, fastjet::PseudoJet{}, ep);
   }
 
   Decay PhaseSpacePoint::select_decay_channel(
       std::vector<Decay> const & decays,
       HEJ::RNG & ran
   ){
     double br_total = 0.;
     for(auto const & decay: decays) br_total += decay.branching_ratio;
     // adjust weight
     // this is given by (channel branching ratio)/(chance to pick channel)
     // where (chance to pick channel) =
     //       (channel branching ratio)/(total branching ratio)
     weight_ *= br_total;
     const double r1 = br_total*ran.flat();
     double br_sum = 0.;
     for(auto const & decay: decays){
       br_sum += decay.branching_ratio;
       if(r1 < br_sum) return decay;
     }
     throw std::logic_error{"unreachable"};
   }
 
   std::vector<Particle> PhaseSpacePoint::decay_boson(
       HEJ::Particle const & parent,
       std::vector<Decay> const & decays,
       HEJ::RNG & ran
   ){
     const auto channel = select_decay_channel(decays, ran);
     if(channel.products.size() != 2){
       throw HEJ::not_implemented{
         "only decays into two particles are implemented"
       };
     }
     std::vector<Particle> decay_products(channel.products.size());
     for(size_t i = 0; i < channel.products.size(); ++i){
       decay_products[i].type = channel.products[i];
     }
     // choose polar and azimuth angle in parent rest frame
     const double E = parent.m()/2;
     const double theta = 2.*M_PI*ran.flat();
     const double cos_phi = 2.*ran.flat()-1.;
     const double sin_phi = sqrt(1. - cos_phi*cos_phi);  // Know 0 < phi < pi
     const double px = E*cos(theta)*sin_phi;
     const double py = E*sin(theta)*sin_phi;
     const double pz = E*cos_phi;
     decay_products[0].p.reset(px, py, pz, E);
     decay_products[1].p.reset(-px, -py, -pz, E);
     for(auto & particle: decay_products) particle.p.boost(parent.p);
     return decay_products;
   }
 }
diff --git a/FixedOrderGen/src/config.cc b/FixedOrderGen/src/config.cc
index 652df13..7fdca38 100644
--- a/FixedOrderGen/src/config.cc
+++ b/FixedOrderGen/src/config.cc
@@ -1,309 +1,358 @@
 #include "config.hh"
 
 #include <cctype>
 
+#include "Subleading.hh"
+
 #include "HEJ/config.hh"
 #include "HEJ/YAMLreader.hh"
 
 namespace HEJFOG{
   using HEJ::set_from_yaml;
   using HEJ::set_from_yaml_if_defined;
 
   namespace{
     //! Get YAML tree of supported options
     /**
      * The configuration file is checked against this tree of options
      * in assert_all_options_known.
      */
     YAML::Node const & get_supported_options(){
       const static YAML::Node supported = [](){
         YAML::Node supported;
         static const auto opts = {
-          "process", "events", "subleading fraction", "scales", "scale factors",
-          "max scale ratio", "pdf", "event output", "analysis", "import scales"
+          "process", "events", "subleading fraction","subleading channels",
+          "scales", "scale factors", "max scale ratio", "pdf",
+          "event output", "analysis", "import scales"
         };
         // add subnodes to "supported" - the assigned value is irrelevant
         for(auto && opt: opts) supported[opt] = "";
         for(auto && jet_opt: {"min pt", "peak pt", "algorithm", "R", "max rapidity"}){
           supported["jets"][jet_opt] = "";
         }
         for(auto && particle_type: {"Higgs", "Wp", "Wm", "Z"}){
           for(auto && particle_opt: {"mass", "width"}){
             supported["particle properties"][particle_type][particle_opt] = "";
           }
           supported["particle properties"][particle_type]["decays"]["into"] = "";
           supported["particle properties"][particle_type]["decays"]["branching ratio"] = "";
         }
         for(auto && opt: {"mt", "use impact factors", "include bottom", "mb"}){
           supported["Higgs coupling"][opt] = "";
         }
         for(auto && beam_opt: {"energy", "particles"}){
           supported["beam"][beam_opt] = "";
         }
         for(auto && unweight_opt: {"sample size", "max deviation"}){
           supported["unweight"][unweight_opt] = "";
         }
         for(auto && opt: {"name", "seed"}){
           supported["random generator"][opt] = "";
         }
         return supported;
       }();
       return supported;
     }
 
     JetParameters get_jet_parameters(
         YAML::Node const & node, std::string const & entry
     ){
       const auto p = HEJ::get_jet_parameters(node, entry);
       JetParameters result;
       result.def = p.def;
       result.min_pt = p.min_pt;
       set_from_yaml(result.max_y, node, entry, "max rapidity");
       set_from_yaml_if_defined(result.peak_pt, node, entry, "peak pt");
       return result;
     }
 
     Beam get_Beam(
         YAML::Node const & node, std::string const & entry
     ){
       Beam beam;
       std::vector<HEJ::ParticleID> particles;
       set_from_yaml(beam.energy, node, entry, "energy");
       set_from_yaml_if_defined(particles, node, entry, "particles");
       if(! particles.empty()){
         for(HEJ::ParticleID particle: particles){
           if(particle != HEJ::pid::p && particle != HEJ::pid::p_bar){
             throw std::invalid_argument{
               "Unsupported value in option " + entry + ": particles:"
               " only proton ('p') and antiproton ('p_bar') beams are supported"
             };
           }
         }
         if(particles.size() != 2){
           throw std::invalid_argument{"Not exactly two beam particles"};
         }
         beam.particles.front() = particles.front();
         beam.particles.back() = particles.back();
       }
       return beam;
     }
 
     std::vector<std::string> split(
         std::string const & str, std::string const & delims
     ){
       std::vector<std::string> result;
       for(size_t begin, end = 0; end != str.npos;){
         begin = str.find_first_not_of(delims, end);
         if(begin == str.npos) break;
         end = str.find_first_of(delims, begin + 1);
         result.emplace_back(str.substr(begin, end - begin));
       }
       return result;
     }
 
     std::invalid_argument invalid_incoming(std::string const & what){
       return std::invalid_argument{
         "Incoming particle type " + what + " not supported,"
         " incoming particles have to be 'p', 'p_bar' or partons"
       };
     }
 
     std::invalid_argument invalid_outgoing(std::string const & what){
       return std::invalid_argument{
         "Outgoing particle type " + what + " not supported,"
         " outgoing particles have to be 'j', 'photon', 'W+', 'W-', 'Z', 'H'"
       };
     }
 
     Process get_process(
         YAML::Node const & node, std::string const & entry
     ){
       Process result;
 
       std::string process_string;
       set_from_yaml(process_string, node, entry);
       assert(! process_string.empty());
       const auto particles = split(process_string, " \n\t\v=>");
       if(particles.size() < 3){
         throw std::invalid_argument{
           "Bad format in option process: '" + process_string
           + "', expected format is 'in1 in2 => out1 ...'"
         };
       }
       result.incoming.front() = HEJ::to_ParticleID(particles[0]);
       result.incoming.back() = HEJ::to_ParticleID(particles[1]);
 
       for(size_t i = 0; i < result.incoming.size(); ++i){
         const HEJ::ParticleID in = result.incoming[i];
         if(
             in != HEJ::pid::proton && in != HEJ::pid::p_bar
             && !HEJ::is_parton(in)
         ){
           throw invalid_incoming(particles[i]);
         }
       }
       result.njets = 0;
       for(size_t i = result.incoming.size(); i < particles.size(); ++i){
         assert(! particles[i].empty());
         if(particles[i] == "j") ++result.njets;
         else if(std::isdigit(particles[i].front())
             && particles[i].back() == 'j')
           result.njets += std::stoi(particles[i]);
         else{
           const auto pid = HEJ::to_ParticleID(particles[i]);
           if(!HEJ::is_AWZH_boson(pid)){
             throw invalid_outgoing(particles[i]);
           }
           if(result.boson){
             throw std::invalid_argument{
               "More than one outgoing boson is not supported"
             };
           }
           result.boson = pid;
         }
       }
       if(result.njets < 2){
         throw std::invalid_argument{
           "Process has to include at least two jets ('j')"
         };
       }
       return result;
     }
 
+    HEJFOG::Subleading to_subleading_channel(YAML::Node const & yaml){
+      std::string name;
+      using HEJFOG::Subleading;
+      set_from_yaml(name, yaml);
+      if(name == "none")
+        return none;
+      if(name == "all")
+        return all;
+      if(name == "unordered" || name == "uno")
+        return uno;
+      throw HEJ::unknown_option("Unknown subleading channel '"+name+"'");
+
+    }
+
+    unsigned int get_subleading_channels(YAML::Node const & node){
+      using YAML::NodeType;
+      using HEJFOG::Subleading;
+      // all channels allowed by default
+      if(!node) return all;
+      switch(node.Type()){
+      case NodeType::Undefined:
+        return  all;
+      case NodeType::Null:
+        return none;
+      case NodeType::Scalar:
+        return to_subleading_channel(node);
+      case NodeType::Map:
+        throw HEJ::invalid_type{"map is not a valid option for subleading channels"};
+      case NodeType::Sequence:
+        unsigned int channels = HEJFOG::Subleading::none;
+        for(auto && channel_node: node){
+          channels |= get_subleading_channels(channel_node);
+        }
+        return channels;
+      }
+      throw std::logic_error{"unreachable"};
+    }
+
     Decay get_decay(YAML::Node const & node){
       Decay decay;
       set_from_yaml(decay.products, node, "into");
       set_from_yaml(decay.branching_ratio, node, "branching ratio");
       return decay;
     }
 
     std::vector<Decay> get_decays(YAML::Node const & node){
       using YAML::NodeType;
       if(!node) return {};
       switch(node.Type()){
       case NodeType::Null:
       case NodeType::Undefined:
         return {};
       case NodeType::Scalar:
         throw HEJ::invalid_type{"value is not a list of decays"};
       case NodeType::Map:
         return {get_decay(node)};
       case NodeType::Sequence:
         std::vector<Decay> result;
         for(auto && decay_str: node){
           result.emplace_back();
           set_from_yaml(result.back().products, decay_str, "into");
           set_from_yaml(result.back().branching_ratio, decay_str, "branching ratio");
         }
         return result;
       }
       throw std::logic_error{"unreachable"};
     }
 
     ParticleProperties get_particle_properties(
         YAML::Node const & node, std::string const & entry
     ){
       ParticleProperties result;
       set_from_yaml(result.mass, node, entry, "mass");
       set_from_yaml(result.width, node, entry, "width");
       try{
         result.decays = get_decays(node[entry]["decays"]);
       }
       catch(HEJ::missing_option const & ex){
         throw HEJ::missing_option{entry + ": decays: " + ex.what()};
       }
       catch(HEJ::invalid_type const & ex){
         throw HEJ::invalid_type{entry + ": decays: " + ex.what()};
       }
       return result;
     }
 
     ParticlesPropMap get_all_particles_properties(YAML::Node const & node){
       ParticlesPropMap result;
       using namespace HEJ;
       // @TODO allow more synonyms
       if(node["Higgs"])
         result[pid::Higgs] = get_particle_properties(node,"Higgs");
       if(node["Wp"])
         result[pid::Wp] = get_particle_properties(node,"Wp");
       if(node["Wm"])
         result[pid::Wm] = get_particle_properties(node,"Wm");
       if(node["Z"])
         result[pid::Z] = get_particle_properties(node,"Z");
       return result;
     }
 
     UnweightSettings get_unweight(
         YAML::Node const & node, std::string const & entry
     ){
       UnweightSettings result;
       set_from_yaml(result.sample_size, node, entry, "sample size");
       if(result.sample_size <= 0){
         throw std::invalid_argument{
           "negative sample size " + std::to_string(result.sample_size)
         };
       }
       set_from_yaml(result.max_dev, node, entry, "max deviation");
       return result;
     }
 
     Config to_Config(YAML::Node const & yaml){
       try{
         HEJ::assert_all_options_known(yaml, get_supported_options());
       }
       catch(HEJ::unknown_option const & ex){
         throw HEJ::unknown_option{std::string{"Unknown option '"} + ex.what() + "'"};
       }
 
       Config config;
       config.process = get_process(yaml, "process");
       set_from_yaml(config.events, yaml, "events");
       config.jets = get_jet_parameters(yaml, "jets");
       config.beam = get_Beam(yaml, "beam");
       for(size_t i = 0; i < config.process.incoming.size(); ++i){
         const auto & in = config.process.incoming[i];
         using namespace HEJ::pid;
         if( (in == p || in == p_bar) && in != config.beam.particles[i]){
           throw std::invalid_argument{
             "Particle type of beam " + std::to_string(i+1) + " incompatible"
             + " with type of incoming particle " + std::to_string(i+1)
           };
         }
       }
       set_from_yaml(config.pdf_id, yaml, "pdf");
+
       set_from_yaml(config.subleading_fraction, yaml, "subleading fraction");
       if(config.subleading_fraction < 0 || config.subleading_fraction > 1){
         throw std::invalid_argument{
           "subleading fraction has to be between 0 and 1"
         };
       }
+      if(config.subleading_fraction == 0)
+        config.subleading_channels = Subleading::none;
+      else
+        config.subleading_channels = get_subleading_channels(yaml["subleading channels"]);
+      if(!config.process.boson && config.subleading_channels != Subleading::none)
+        throw HEJ::not_implemented("Subleading processes for pure Jet production not implemented yet");
+
       if(yaml["particle properties"]){
         config.particles_properties = get_all_particles_properties(
           yaml["particle properties"]);
       }
       if(config.process.boson
         && config.particles_properties.find(*(config.process.boson))
           == config.particles_properties.end())
         throw HEJ::missing_option("Process wants to generate boson "
           +std::to_string(*(config.process.boson))+", but boson properties are missing");
       set_from_yaml_if_defined(config.analysis_parameters, yaml, "analysis");
       config.scales = HEJ::to_ScaleConfig(yaml);
       set_from_yaml_if_defined(config.output, yaml, "event output");
       config.rng = HEJ::to_RNGConfig(yaml, "random generator");
       config.Higgs_coupling = HEJ::get_Higgs_coupling(yaml, "Higgs coupling");
       if(yaml["unweight"]) config.unweight = get_unweight(yaml, "unweight");
       return config;
     }
 
   } // namespace anonymous
 
   Config load_config(std::string const & config_file){
     try{
       return to_Config(YAML::LoadFile(config_file));
     }
     catch(...){
       std::cerr << "Error reading " << config_file << ":\n  ";
       throw;
     }
   }
 }
diff --git a/FixedOrderGen/src/main.cc b/FixedOrderGen/src/main.cc
index be850fa..3cbd54b 100644
--- a/FixedOrderGen/src/main.cc
+++ b/FixedOrderGen/src/main.cc
@@ -1,247 +1,248 @@
 /**
  * Name: main.cc
  * Authors: Jeppe R. Andersen
  */
 
 #include <fstream>
 #include <algorithm>
 #include <memory>
 #include <chrono>
 #include <iostream>
 #include <map>
 
 #include "yaml-cpp/yaml.h"
 
 #include "config.hh"
 
 #include "LHEF/LHEF.h"
 #include "HEJ/CombinedEventWriter.hh"
 #include "HEJ/get_analysis.hh"
 #include "HEJ/utility.hh"
 //#include "HEJ/EventReweighter.hh"
 #include "HEJ/stream.hh"
 #include "HEJ/LesHouchesWriter.hh"
 #include "HEJ/ProgressBar.hh"
 #include "HEJ/make_RNG.hh"
 
 #include "EventGenerator.hh"
 #include "PhaseSpacePoint.hh"
 #include "Unweighter.hh"
 #include "CrossSectionAccumulator.hh"
 #include "Version.hh"
 
 namespace{
   constexpr auto banner =
     "     __  ___       __       ______                                   __     __                               \n"
     "    / / / (_)___ _/ /_     / ____/___  ___  _________ ___  __       / /__  / /______                         \n"
     "   / /_/ / / __ `/ __ \\   / __/ / __ \\/ _ \\/ ___/ __ `/ / / /  __  / / _ \\/ __/ ___/                         \n"
     "  / __  / / /_/ / / / /  / /___/ / / /  __/ /  / /_/ / /_/ /  / /_/ /  __/ /_(__  )                          \n"
     " /_/ /_/_/\\__, /_/ /_/  /_____/_/ /_/\\___/_/   \\__, /\\__, /   \\____/\\___/\\__/____/                           \n"
     "     ____///__/            __   ____          ///__//____/    ______                           __            \n"
     "    / ____(_)  _____  ____/ /  / __ \\_________/ /__  _____   / ____/__  ____  ___  _________ _/ /_____  _____\n"
     "   / /_  / / |/_/ _ \\/ __  /  / / / / ___/ __  / _ \\/ ___/  / / __/ _ \\/ __ \\/ _ \\/ ___/ __ `/ __/ __ \\/ ___/\n"
     "  / __/ / />  </  __/ /_/ /  / /_/ / /  / /_/ /  __/ /     / /_/ /  __/ / / /  __/ /  / /_/ / /_/ /_/ / /    \n"
     " /_/   /_/_/|_|\\___/\\__,_/   \\____/_/   \\__,_/\\___/_/      \\____/\\___/_/ /_/\\___/_/   \\__,_/\\__/\\____/_/     \n"
     ;
 
   constexpr double invGeV2_to_pb = 389379292.;
   constexpr long long max_warmup_events = 10000;
 }
 
 HEJFOG::Config load_config(char const * filename){
   try{
     return HEJFOG::load_config(filename);
   }
   catch(std::exception const & exc){
     std::cerr << "Error: " << exc.what() << '\n';
     std::exit(EXIT_FAILURE);
   }
 }
 
 std::unique_ptr<HEJ::Analysis> get_analysis(
     YAML::Node const & parameters
 ){
   try{
     return HEJ::get_analysis(parameters);
   }
   catch(std::exception const & exc){
     std::cerr << "Failed to load analysis: " << exc.what() << '\n';
     std::exit(EXIT_FAILURE);
   }
 }
 
 void rescale_weights(HEJ::Event & ev, double factor) {
     ev.central().weight *= factor;
     for(auto & var: ev.variations()){
       var.weight *= factor;
     }
 }
 
 int main(int argn, char** argv) {
   using namespace std::string_literals;
   if (argn < 2) {
     std::cerr << "\n# Usage:\n.FOgen config_file\n";
     return EXIT_FAILURE;
   }
   std::cout << banner;
   std::cout << "Version " << HEJFOG::Version::String()
              << ", revision " << HEJFOG::Version::revision() << std::endl;
   fastjet::ClusterSequence::print_banner();
   using clock = std::chrono::system_clock;
 
   const auto start_time = clock::now();
 
   // read configuration
   auto config = load_config(argv[1]);
 
   std::unique_ptr<HEJ::Analysis> analysis = get_analysis(
       config.analysis_parameters
   );
   assert(analysis != nullptr);
 
   auto ran = HEJ::make_RNG(config.rng.name, config.rng.seed);
   assert(ran != nullptr);
 
   HEJ::ScaleGenerator scale_gen{
     config.scales.base,
     config.scales.factors,
     config.scales.max_ratio
   };
 
   HEJFOG::EventGenerator generator{
     config.process,
     config.beam,
     std::move(scale_gen),
     config.jets,
     config.pdf_id,
     config.subleading_fraction,
+    config.subleading_channels,
     config.particles_properties,
     config.Higgs_coupling,
     *ran
   };
 
   LHEF::HEPRUP heprup;
   heprup.IDBMUP=std::pair<long,long>(config.beam.particles[0], config.beam.particles[1]);
   heprup.EBMUP=std::make_pair(config.beam.energy, config.beam.energy);
   heprup.PDFGUP=std::make_pair(0,0);
   heprup.PDFSUP=std::make_pair(config.pdf_id,config.pdf_id);
   heprup.NPRUP=1;
   heprup.XSECUP=std::vector<double>(1.);
   heprup.XERRUP=std::vector<double>(1.);
   heprup.LPRUP=std::vector<int>{1};
   heprup.generators.emplace_back(LHEF::XMLTag{});
   heprup.generators.back().name = HEJFOG::Version::package_name();
   heprup.generators.back().version = HEJFOG::Version::String();
 
   HEJ::CombinedEventWriter writer{config.output, heprup};
 
   HEJ::optional<HEJFOG::Unweighter> unweighter{};
   std::map<HEJFOG::Status, int> status_counter;
 
   std::vector<HEJ::Event> events;
   int trials = 0;
   // warm-up phase to train unweighter
   if(config.unweight) {
     std::cout << "Calibrating unweighting ...\n";
     const auto warmup_start = clock::now();
     const size_t warmup_events = config.unweight->sample_size;
     HEJ::ProgressBar<size_t> warmup_progress{std::cout, warmup_events};
     for(; events.size() < warmup_events; ++trials){
       auto ev = generator.gen_event();
       ++status_counter[generator.status()];
       if(generator.status() == HEJFOG::good && analysis->pass_cuts(ev, ev)) {
         events.emplace_back(std::move(ev));
         ++warmup_progress;
       }
     }
     std::cout << std::endl;
     unweighter = HEJFOG::Unweighter{
       begin(events), end(events), config.unweight->max_dev, *ran,
       config.jets.peak_pt?(*config.jets.peak_pt):0.
     };
     std::vector<HEJ::Event> unweighted_events;
     for(auto && ev: events) {
       auto unweighted = unweighter->unweight(std::move(ev));
       if(unweighted) {
         unweighted_events.emplace_back(std::move(*unweighted));
       }
     }
     events = std::move(unweighted_events);
     if(events.empty()) {
       std::cerr <<
         "Failed to generate events. Please increase \"unweight: sample size\""
         " or reduce \"unweight: max deviation\"\n";
       return EXIT_FAILURE;
     }
     const auto warmup_end = clock::now();
     const double completion = static_cast<double>(events.size())/config.events;
     const std::chrono::duration<double> remaining_time =
       (warmup_end- warmup_start)*(1./completion - 1);
     const auto finish = clock::to_time_t(
         std::chrono::time_point_cast<std::chrono::seconds>(warmup_end + remaining_time)
     );
     std::cout
       << "Generated " << events.size() << "/" << config.events << " events ("
       << static_cast<int>(std::round(100*completion)) << "%)\n"
       << "Estimated remaining generation time: "
       << remaining_time.count() << " seconds ("
       << std::put_time(std::localtime(&finish), "%c") << ")\n\n";
   }
 
   HEJ::ProgressBar<long long> progress{std::cout, config.events};
   progress.increment(events.size());
   events.reserve(config.events);
   for(; events.size() < static_cast<size_t>(config.events); ++trials){
     auto ev = generator.gen_event();
     ++status_counter[generator.status()];
     if(generator.status() == HEJFOG::good && analysis->pass_cuts(ev, ev)) {
       if(unweighter) {
         auto unweighted = unweighter->unweight(std::move(ev));
         if(! unweighted) continue;
         ev = std::move(*unweighted);
       }
       events.emplace_back(std::move(ev));
       ++progress;
     }
   }
   std::cout << std::endl;
 
   HEJFOG::CrossSectionAccumulator xs;
   for(auto & ev: events){
     rescale_weights(ev, invGeV2_to_pb/trials);
     analysis->fill(ev, ev);
     writer.write(ev);
     xs.fill(ev);
   }
   analysis->finalise();
 
   const std::chrono::duration<double> run_time = (clock::now() - start_time);
   std::cout << "\nTask Runtime: " << run_time.count() << " seconds.\n\n";
 
   std::cout.precision(10);
   std::cout.setf(std::ios::fixed);
   std::cout
     << "   " << std::left << std::setw(20)
     << "Cross section: " << xs.total().value
     << " +- " << std::sqrt(xs.total().error) << " (pb)\n";
   for(auto const & xs_type: xs) {
     std::cout
        << "   " << std::left << std::setw(20)
       << (HEJ::event_type::names[xs_type.first] + ": "s)
       << xs_type.second.value << " +- "
       << std::sqrt(xs_type.second.error) << " (pb)\n";
   }
 
   std::cout << '\n';
   for(auto && entry: status_counter){
     const double fraction = static_cast<double>(entry.second)/trials;
     const int percent = std::round(100*fraction);
     std::cout << "status "
               << std::left << std::setw(16) << (to_string(entry.first) + ":")
               << " [";
     for(int i = 0; i < percent/2; ++i) std::cout << '#';
     for(int i = percent/2; i < 50; ++i) std::cout << ' ';
     std::cout << "] " << percent << "%\n";
   }
 
 }
diff --git a/FixedOrderGen/t/2j.cc b/FixedOrderGen/t/2j.cc
index 01c3682..8eabfc4 100644
--- a/FixedOrderGen/t/2j.cc
+++ b/FixedOrderGen/t/2j.cc
@@ -1,57 +1,58 @@
 #ifdef NDEBUG
 #undef NDEBUG
 #endif
 
 #include <algorithm>
 #include <cmath>
 #include <cassert>
 #include <iostream>
 
 #include "config.hh"
 #include "EventGenerator.hh"
 #include "HEJ/Mixmax.hh"
 
 #include "HEJ/PDF.hh"
 #include "HEJ/MatrixElement.hh"
 
 using namespace HEJFOG;
 
 int main(){
   constexpr double invGeV2_to_pb = 389379292.;
   constexpr double xs_ref = 86.42031848*1e6; //calculated with "combined" HEJ svn r3480
 
   auto config = load_config("config_2j.yml");
 
   HEJ::Mixmax ran{};
   HEJFOG::EventGenerator generator{
     config.process,
     config.beam,
     HEJ::ScaleGenerator{
       config.scales.base,
       config.scales.factors,
       config.scales.max_ratio
     },
     config.jets,
     config.pdf_id,
     config.subleading_fraction,
+    config.subleading_channels,
     config.particles_properties,
     config.Higgs_coupling,
     ran
   };
 
   double xs = 0., xs_err = 0.;
   for (int trials = 0; trials < config.events; ++trials){
     auto ev = generator.gen_event();
     if(generator.status() != good) continue;
     ev.central().weight *= invGeV2_to_pb;
     ev.central().weight /= config.events;
 
     xs += ev.central().weight;
     xs_err += ev.central().weight*ev.central().weight;
   }
   xs_err = std::sqrt(xs_err);
   std::cout << xs_ref << " ~ " << xs << " +- " << xs_err << '\n';
 
   assert(std::abs(xs - xs_ref) < 3*xs_err);
   assert(xs_err < 0.01*xs);
 }
diff --git a/FixedOrderGen/t/4j.cc b/FixedOrderGen/t/4j.cc
index 9bfaaed..b459200 100644
--- a/FixedOrderGen/t/4j.cc
+++ b/FixedOrderGen/t/4j.cc
@@ -1,58 +1,59 @@
 #ifdef NDEBUG
 #undef NDEBUG
 #endif
 
 #include <algorithm>
 #include <cmath>
 #include <cassert>
 #include <iostream>
 
 #include "config.hh"
 #include "EventGenerator.hh"
 #include "HEJ/Mixmax.hh"
 
 #include "HEJ/PDF.hh"
 #include "HEJ/MatrixElement.hh"
 
 using namespace HEJFOG;
 
 int main(){
   constexpr double invGeV2_to_pb = 389379292.;
   constexpr double xs_ref = 0.81063619*1e6; //calculated with "combined" HEJ svn r3480
 
   auto config = load_config("config_2j.yml");
   config.process.njets = 4;
 
   HEJ::Mixmax ran{};
   HEJFOG::EventGenerator generator{
     config.process,
     config.beam,
     HEJ::ScaleGenerator{
       config.scales.base,
       config.scales.factors,
       config.scales.max_ratio
     },
     config.jets,
     config.pdf_id,
     config.subleading_fraction,
+    config.subleading_channels,
     config.particles_properties,
     config.Higgs_coupling,
     ran
   };
 
   double xs = 0., xs_err = 0.;
   for (int trials = 0; trials < config.events; ++trials){
     auto ev = generator.gen_event();
     if(generator.status() != good) continue;
     ev.central().weight *= invGeV2_to_pb;
     ev.central().weight /= config.events;
 
     xs += ev.central().weight;
     xs_err += ev.central().weight*ev.central().weight;
   }
   xs_err = std::sqrt(xs_err);
   std::cout << xs_ref << " ~ " << xs << " +- " << xs_err << '\n';
 
   assert(std::abs(xs - xs_ref) < 3*xs_err);
   assert(xs_err < 0.03*xs);
 }
diff --git a/FixedOrderGen/t/config_2j.yml b/FixedOrderGen/t/config_2j.yml
index 504fab2..4431412 100644
--- a/FixedOrderGen/t/config_2j.yml
+++ b/FixedOrderGen/t/config_2j.yml
@@ -1,27 +1,28 @@
 events: 100000
 
 jets:
   min pt: 30
   R: 0.4
   algorithm: antikt
   max rapidity: 5
 
 beam:
   energy: 6500
   particles: [p, p]
 
 pdf: 11000
 
 process: p p => 2j
 
-subleading fraction: 0
+subleading fraction: 0.1
+subleading channels: none
 
 scales: 125
 
 random generator:
   name: mixmax
 
 particle properties:
   Higgs:
     mass: 125
     width: 0
diff --git a/FixedOrderGen/t/config_h_2j.yml b/FixedOrderGen/t/config_h_2j.yml
index bdc7bc8..b5a4ff9 100644
--- a/FixedOrderGen/t/config_h_2j.yml
+++ b/FixedOrderGen/t/config_h_2j.yml
@@ -1,27 +1,28 @@
 events: 200000
 
 jets:
   min pt: 30
   R: 0.4
   algorithm: antikt
   max rapidity: 5
 
 beam:
   energy: 6500
   particles: [p, p]
 
 pdf: 11000
 
 process: p p => h 2j
 
-subleading fraction: 0
+subleading fraction: 0.37
+subleading channels: none
 
 scales: 125
 
 particle properties:
   Higgs:
     mass: 125
     width: 0
 
 random generator:
   name: mixmax
diff --git a/FixedOrderGen/t/h_2j.cc b/FixedOrderGen/t/h_2j.cc
index c6d4cfb..26d91c5 100644
--- a/FixedOrderGen/t/h_2j.cc
+++ b/FixedOrderGen/t/h_2j.cc
@@ -1,65 +1,66 @@
 #ifdef NDEBUG
 #undef NDEBUG
 #endif
 
 #include <algorithm>
 #include <cmath>
 #include <cassert>
 #include <iostream>
 
 #include "config.hh"
 #include "EventGenerator.hh"
 #include "HEJ/Ranlux64.hh"
 
 #include "HEJ/PDF.hh"
 #include "HEJ/MatrixElement.hh"
 
 using namespace HEJFOG;
 
 int main(){
   constexpr double invGeV2_to_pb = 389379292.;
   constexpr double xs_ref = 2.04928; // +- 0.00377252
   //calculated with HEJ revision 9570e3809613272ac4b8bf3236279ba23cf64d20
 
   auto config = load_config("config_h_2j.yml");
 
   HEJ::Ranlux64 ran{};
   HEJFOG::EventGenerator generator{
     config.process,
     config.beam,
     HEJ::ScaleGenerator{
       config.scales.base,
       config.scales.factors,
       config.scales.max_ratio
     },
     config.jets,
     config.pdf_id,
     config.subleading_fraction,
+    config.subleading_channels,
     config.particles_properties,
     config.Higgs_coupling,
     ran
   };
 
   double xs = 0., xs_err = 0.;
   for (int trials = 0; trials < config.events; ++trials){
     auto ev = generator.gen_event();
     if(generator.status() != good) continue;
     ev.central().weight *= invGeV2_to_pb;
     ev.central().weight /= config.events;
 
     const auto the_Higgs = std::find_if(
         begin(ev.outgoing()), end(ev.outgoing()),
         [](HEJ::Particle const & p){ return p.type == HEJ::ParticleID::h; }
     );
     assert(the_Higgs != end(ev.outgoing()));
     if(std::abs(the_Higgs->rapidity()) > 5.) continue;
 
     xs += ev.central().weight;
     xs_err += ev.central().weight*ev.central().weight;
   }
   xs_err = std::sqrt(xs_err);
   std::cout << xs_ref << " ~ " << xs << " +- " << xs_err << std::endl;
 
   assert(std::abs(xs - xs_ref) < 3*xs_err);
   assert(xs_err < 0.01*xs);
 }
diff --git a/FixedOrderGen/t/h_2j_decay.cc b/FixedOrderGen/t/h_2j_decay.cc
index 9fdded5..6ecc37c 100644
--- a/FixedOrderGen/t/h_2j_decay.cc
+++ b/FixedOrderGen/t/h_2j_decay.cc
@@ -1,83 +1,84 @@
 #ifdef NDEBUG
 #undef NDEBUG
 #endif
 
 #include <algorithm>
 #include <cmath>
 #include <cassert>
 #include <iostream>
 
 #include "config.hh"
 #include "EventGenerator.hh"
 #include "HEJ/Ranlux64.hh"
 
 #include "HEJ/PDF.hh"
 #include "HEJ/MatrixElement.hh"
 #include "HEJ/utility.hh"
 
 using namespace HEJFOG;
 
 bool pass_dR_cut(
     std::vector<fastjet::PseudoJet> const & jets,
     std::vector<HEJ::Particle> const & photons
 ){
   constexpr double delta_R_min = 0.7;
   for(auto const & jet: jets){
     for(auto const & photon: photons){
       if(jet.delta_R(photon.p) < delta_R_min) return false;
     }
   }
   return true;
 }
 
 int main(){
   constexpr double invGeV2_to_pb = 389379292.;
   constexpr double xs_ref = 0.00429198; // +- 1.0488e-05
   //calculated with HEJ revision 9570e3809613272ac4b8bf3236279ba23cf64d20
 
   auto config = load_config("config_h_2j_decay.yml");
 
   HEJ::Ranlux64 ran{};
   HEJFOG::EventGenerator generator{
     config.process,
     config.beam,
     HEJ::ScaleGenerator{
       config.scales.base,
       config.scales.factors,
       config.scales.max_ratio
     },
     config.jets,
     config.pdf_id,
     config.subleading_fraction,
+    config.subleading_channels,
     config.particles_properties,
     config.Higgs_coupling,
     ran
   };
 
   double xs = 0., xs_err = 0.;
   for (int trials = 0; trials < config.events; ++trials){
     auto ev = generator.gen_event();
     if(generator.status() != good) continue;
     assert(ev.decays().size() == 1);
     const auto decay = begin(ev.decays());
     assert(ev.outgoing().size() > decay->first);
     const auto & the_Higgs = ev.outgoing()[decay->first];
     assert(the_Higgs.type == HEJ::pid::Higgs);
     assert(decay->second.size() == 2);
     auto const & gamma = decay->second;
     assert(gamma[0].type == HEJ::pid::photon);
     assert(gamma[1].type == HEJ::pid::photon);
     assert(HEJ::nearby_ep(gamma[0].p + gamma[1].p, the_Higgs.p, 1e-6));
     if(!pass_dR_cut(ev.jets(), gamma)) continue;
     ev.central().weight *= invGeV2_to_pb;
     ev.central().weight /= config.events;
 
     xs += ev.central().weight;
     xs_err += ev.central().weight*ev.central().weight;
   }
   xs_err = std::sqrt(xs_err);
   std::cout << xs_ref << " ~ " << xs << " +- " << xs_err << std::endl;
 
   assert(std::abs(xs - xs_ref) < 3*xs_err);
   assert(xs_err < 0.012*xs);
 }
diff --git a/FixedOrderGen/t/h_3j.cc b/FixedOrderGen/t/h_3j.cc
index e3edaf8..540be9a 100644
--- a/FixedOrderGen/t/h_3j.cc
+++ b/FixedOrderGen/t/h_3j.cc
@@ -1,66 +1,67 @@
 #ifdef NDEBUG
 #undef NDEBUG
 #endif
 
 #include <algorithm>
 #include <cmath>
 #include <cassert>
 #include <iostream>
 
 #include "config.hh"
 #include "EventGenerator.hh"
 #include "HEJ/Ranlux64.hh"
 
 #include "HEJ/PDF.hh"
 #include "HEJ/MatrixElement.hh"
 
 using namespace HEJFOG;
 
 int main(){
   constexpr double invGeV2_to_pb = 389379292.;
   constexpr double xs_ref = 1.07807; // +- 0.0071
   //calculated with HEJ revision 93efdc851b02a907a6fcc63956387f9f4c1111c2 +1
 
   auto config = load_config("config_h_2j.yml");
   config.process.njets = 3;
 
   HEJ::Ranlux64 ran{};
   HEJFOG::EventGenerator generator{
     config.process,
     config.beam,
     HEJ::ScaleGenerator{
       config.scales.base,
       config.scales.factors,
       config.scales.max_ratio
     },
     config.jets,
     config.pdf_id,
     config.subleading_fraction,
+    config.subleading_channels,
     config.particles_properties,
     config.Higgs_coupling,
     ran
   };
 
   double xs = 0., xs_err = 0.;
   for (int trials = 0; trials < config.events; ++trials){
     auto ev = generator.gen_event();
     if(generator.status() != good) continue;
     ev.central().weight *= invGeV2_to_pb;
     ev.central().weight /= config.events;
 
     const auto the_Higgs = std::find_if(
         begin(ev.outgoing()), end(ev.outgoing()),
         [](HEJ::Particle const & p){ return p.type == HEJ::ParticleID::h; }
     );
     assert(the_Higgs != end(ev.outgoing()));
     if(std::abs(the_Higgs->rapidity()) > 5.) continue;
 
     xs += ev.central().weight;
     xs_err += ev.central().weight*ev.central().weight;
   }
   xs_err = std::sqrt(xs_err);
   std::cout << xs_ref << " ~ " << xs << " +- " << xs_err << std::endl;
 
   assert(std::abs(xs - xs_ref) < 3*xs_err);
   assert(xs_err < 0.02*xs);
 }
diff --git a/FixedOrderGen/t/h_3j_uno1.cc b/FixedOrderGen/t/h_3j_uno1.cc
index b1339fe..ee60d97 100644
--- a/FixedOrderGen/t/h_3j_uno1.cc
+++ b/FixedOrderGen/t/h_3j_uno1.cc
@@ -1,69 +1,71 @@
 #ifdef NDEBUG
 #undef NDEBUG
 #endif
 
 // check that adding uno emissions doesn't change the FKL cross section
 
 #include <algorithm>
 #include <cmath>
 #include <cassert>
 #include <iostream>
 
 #include "config.hh"
 #include "EventGenerator.hh"
+#include "Subleading.hh"
 #include "HEJ/Ranlux64.hh"
 
 #include "HEJ/PDF.hh"
 #include "HEJ/MatrixElement.hh"
 
 using namespace HEJFOG;
 
 int main(){
   constexpr double invGeV2_to_pb = 389379292.;
   constexpr double xs_ref = 0.0243548; // +- 0.000119862
   //calculated with HEJ revision 9570e3809613272ac4b8bf3236279ba23cf64d20
 
   auto config = load_config("config_h_2j.yml");
   config.process.njets = 3;
   config.process.incoming = {HEJ::pid::u, HEJ::pid::u};
-  config.subleading_fraction = 0.37;
+  config.subleading_channels = HEJFOG::Subleading::uno;
 
   HEJ::Ranlux64 ran{};
   HEJFOG::EventGenerator generator{
     config.process,
     config.beam,
     HEJ::ScaleGenerator{
       config.scales.base,
       config.scales.factors,
       config.scales.max_ratio
     },
     config.jets,
     config.pdf_id,
     config.subleading_fraction,
+    config.subleading_channels,
     config.particles_properties,
     config.Higgs_coupling,
     ran
   };
 
   double xs = 0., xs_err = 0.;
   int uno_found = 0;
   for (int trials = 0; trials < config.events; ++trials){
     auto ev = generator.gen_event();
     if(generator.status() != good) continue;
     if(ev.type() != HEJ::event_type::FKL){
       ++uno_found;
       continue;
     }
     ev.central().weight *= invGeV2_to_pb;
     ev.central().weight /= config.events;
 
     xs += ev.central().weight;
     xs_err += ev.central().weight*ev.central().weight;
   }
   xs_err = std::sqrt(xs_err);
   std::cout << xs_ref << " ~ " << xs << " +- " << xs_err << '\n';
   std::cout << uno_found << " events with unordered emission" << std::endl;
   assert(uno_found > 0);
   assert(std::abs(xs - xs_ref) < 3*xs_err);
   assert(xs_err < 0.05*xs);
 }
diff --git a/FixedOrderGen/t/h_3j_uno2.cc b/FixedOrderGen/t/h_3j_uno2.cc
index b4ea06a..cf28f57 100644
--- a/FixedOrderGen/t/h_3j_uno2.cc
+++ b/FixedOrderGen/t/h_3j_uno2.cc
@@ -1,63 +1,66 @@
 #ifdef NDEBUG
 #undef NDEBUG
 #endif
 
 // check uno cross section
 
 #include <algorithm>
 #include <cmath>
 #include <cassert>
 #include <iostream>
 
 #include "config.hh"
 #include "EventGenerator.hh"
+#include "Subleading.hh"
 #include "HEJ/Ranlux64.hh"
 
 #include "HEJ/PDF.hh"
 #include "HEJ/MatrixElement.hh"
 
 using namespace HEJFOG;
 
 int main(){
   constexpr double invGeV2_to_pb = 389379292.;
   constexpr double xs_ref = 0.00347538; // +- 3.85875e-05
   //calculated with HEJ revision 9570e3809613272ac4b8bf3236279ba23cf64d20
 
   auto config = load_config("config_h_2j.yml");
   config.process.njets = 3;
   config.process.incoming = {HEJ::pid::u, HEJ::pid::u};
   config.subleading_fraction = 1.;
+  config.subleading_channels = HEJFOG::Subleading::uno;
 
   HEJ::Ranlux64 ran{};
   HEJFOG::EventGenerator generator{
     config.process,
     config.beam,
     HEJ::ScaleGenerator{
       config.scales.base,
       config.scales.factors,
       config.scales.max_ratio
     },
     config.jets,
     config.pdf_id,
     config.subleading_fraction,
+    config.subleading_channels,
     config.particles_properties,
     config.Higgs_coupling,
     ran
   };
 
   double xs = 0., xs_err = 0.;
   for (int trials = 0; trials < config.events; ++trials){
     auto ev = generator.gen_event();
     if(ev.type() == HEJ::event_type::FKL) continue;
     if(generator.status() != good) continue;
     ev.central().weight *= invGeV2_to_pb;
     ev.central().weight /= config.events;
 
     xs += ev.central().weight;
     xs_err += ev.central().weight*ev.central().weight;
   }
   xs_err = std::sqrt(xs_err);
   std::cout << xs_ref << " ~ " << xs << " +- " << xs_err << std::endl;
   assert(std::abs(xs - xs_ref) < 3*xs_err);
   assert(xs_err < 0.05*xs);
 }
diff --git a/FixedOrderGen/t/h_5j.cc b/FixedOrderGen/t/h_5j.cc
index 0112ee2..6bd9e41 100644
--- a/FixedOrderGen/t/h_5j.cc
+++ b/FixedOrderGen/t/h_5j.cc
@@ -1,61 +1,62 @@
 #ifdef NDEBUG
 #undef NDEBUG
 #endif
 // This is a regression test
 // the reference cross section has not been checked against any other program
 
 #include <algorithm>
 #include <cmath>
 #include <cassert>
 #include <iostream>
 
 #include "config.hh"
 #include "EventGenerator.hh"
 #include "HEJ/Ranlux64.hh"
 
 #include "HEJ/PDF.hh"
 #include "HEJ/MatrixElement.hh"
 
 using namespace HEJFOG;
 
 int main(){
   constexpr double invGeV2_to_pb = 389379292.;
   constexpr double xs_ref = 0.252273; // +- 0.00657742
   //calculated with HEJ revision 9570e3809613272ac4b8bf3236279ba23cf64d20
 
   auto config = load_config("config_h_2j.yml");
   config.process.njets = 5;
 
   HEJ::Ranlux64 ran{};
   HEJFOG::EventGenerator generator{
     config.process,
     config.beam,
     HEJ::ScaleGenerator{
       config.scales.base,
       config.scales.factors,
       config.scales.max_ratio
     },
     config.jets,
     config.pdf_id,
     config.subleading_fraction,
+    config.subleading_channels,
     config.particles_properties,
     config.Higgs_coupling,
     ran
   };
 
   double xs = 0., xs_err = 0.;
   for (int trials = 0; trials < config.events; ++trials){
     auto ev = generator.gen_event();
     if(generator.status() != good) continue;
     ev.central().weight *= invGeV2_to_pb;
     ev.central().weight /= config.events;
 
     xs += ev.central().weight;
     xs_err += ev.central().weight*ev.central().weight;
   }
   xs_err = std::sqrt(xs_err);
   std::cout << xs_ref << " ~ " << xs << " +- " << xs_err << std::endl;
 
   assert(std::abs(xs - xs_ref) < 3*xs_err);
   assert(xs_err < 0.06*xs);
 }
diff --git a/doc/sphinx/HEJFOG.rst b/doc/sphinx/HEJFOG.rst
index a197a2e..42c8af6 100644
--- a/doc/sphinx/HEJFOG.rst
+++ b/doc/sphinx/HEJFOG.rst
@@ -1,269 +1,281 @@
 The HEJ Fixed Order Generator
 =============================
 
 For high jet multiplicities event generation with standard fixed-order
 generators becomes increasingly cumbersome. For example, the
 leading-order production of a Higgs Boson with five or more jets is
 computationally prohibitively expensive.
 
 To this end, HEJ 2 provides the ``HEJFOG`` fixed-order generator
 that allows to generate events with high jet multiplicities. To
 facilitate the computation the limit of Multi-Regge Kinematics with
 large invariant masses between all outgoing particles is assumed in the
 matrix elements. The typical use of the ``HEJFOG`` is to supplement
 low-multiplicity events from standard generators with high-multiplicity
 events before using the HEJ 2 program to add high-energy
 resummation.
 
 Installation
 ------------
 
 The ``HEJFOG`` comes bundled together with HEJ 2 and the
 installation is very similar. After downloading HEJ 2 and
 installing the prerequisites as described in :ref:`Installation` the
 ``HEJFOG`` can be installed with::
 
   cmake /path/to/FixedOrderGen -DCMAKE_INSTALL_PREFIX=target/directory -DCMAKE_BUILD_TYPE=Release
   make install
 
 where :file:`/path/to/FixedOrderGen` refers to the :file:`FixedOrderGen`
 subdirectory in the HEJ 2 directory. If HEJ 2 was
 installed to a non-standard location, it may be necessary to specify the
 directory containing :file:`HEJ-config.cmake`. If the base installation
 directory is :file:`/path/to/HEJ`, :file:`HEJ-config.cmake` should be
 found in :file:`/path/to/HEJ/lib/cmake/HEJ` and the commands for
 installing the ``HEJFOG`` would read::
 
   cmake /path/to/FixedOrderGen -DHEJ_DIR=/path/to/HEJ/lib/cmake/HEJ -DCMAKE_INSTALL_PREFIX=target/directory -DCMAKE_BUILD_TYPE=Release
   make install
 
 The installation can be tested with::
 
   make test
 
 provided that the NNPDF 3.0 PDF set is installed.
 
 Running the fixed-order generator
 ---------------------------------
 
 After installing the ``HEJFOG`` you can modify the provided
 configuration file :file:`configFO.yml` and run the generator with::
 
   HEJFOG configFO.yml
 
 The resulting event file, by default named :file:`HEJFO.lhe`, can then be
 fed into HEJ 2 like any event file generated from a standard
 fixed-order generator, see :ref:`Running HEJ 2`.
 
 Settings
 --------
 
 Similar to HEJ 2, the ``HEJFOG`` uses a `YAML
 <http://yaml.org/>`_ configuration file. The settings are
 
 .. _`process`:
 
 **process**
    The scattering process for which events are being generated. The
    format is
 
    :code:`in1 in2 => out1 out2 ...`
 
    The incoming particles, :code:`in1`, :code:`in2` can be
 
    - quarks: :code:`u`, :code:`d`, :code:`u_bar`, and so on
    - gluons: :code:`g`
    - protons :code:`p` or antiprotons :code:`p_bar`
 
    At most one of the outgoing particles can be a boson, the rest has to be
    partonic. At the moment only the Higgs boson :code:`h` is supported. All
    other outgoing particles are jets. Multiple jets can be grouped together, so
    :code:`p p => h j j` is the same as :code:`p p => h 2j`. There have to be at
    least two jets. Further decays of the boson can be added through the
    :ref:`particle properties<particle properties: particle: decays>`.
 
 .. _`events`:
 
 **events**
    Specifies the number of events to generate.
 
 .. _`jets`:
 
 **jets**
    Defines the properties of the generated jets.
 
    .. _`jets: min pt`:
 
    **min pt**
       Minimum jet transverse momentum in GeV.
 
    .. _`jets: peak pt`:
 
    **peak pt**
       Optional setting to specify the dominant jet transverse momentum
       in GeV. If the generated events are used as input for HEJ
       resummation, this should be set to the minimum transverse momentum
       of the resummation jets. The effect is that only a small fraction
       of jets will be generated with a transverse momentum below the
       value of this setting.
 
    .. _`jets: algorithm`:
 
    **algorithm**
       The algorithm used to define jets. Allowed settings are
       :code:`kt`, :code:`cambridge`, :code:`antikt`,
       :code:`cambridge for passive`. See the `FastJet
       <http://fastjet.fr/>`_ documentation for a description of these
       algorithms.
 
    .. _`jets: R`:
 
    **R**
       The R parameter used in the jet algorithm.
 
    .. _`jets: max rapidity`:
 
    **max rapidity**
       Maximum absolute value of the jet rapidity.
 
 .. _`beam`:
 
 **beam**
    Defines various properties of the collider beam.
 
    .. _`beam: energy`:
 
    **energy**
       The beam energy in GeV. For example, the 13
       TeV LHC corresponds to a value of 6500.
 
    .. _`beam: particles`:
 
    **particles**
       A list :code:`[p1, p2]` of two beam particles. The only supported
       entries are protons :code:`p` and antiprotons :code:`p_bar`.
 
 .. _`pdf`:
 
 **pdf**
    The `LHAPDF number <https://lhapdf.hepforge.org/pdfsets>`_ of the PDF set.
    For example, 230000 corresponds to an NNPDF 2.3 NLO PDF set.
 
 .. _`subleading fraction`:
 
 **subleading fraction**
    This setting is related to the fraction of events, that are not a FKL
    configuration. Currently only unordered emissions are implemented, and only
    for Higgs plus multijet processes.
-
-   Unordered emission are any rapidity ordering, where exactly one gluon is
-   emitted outside the rapidity ordering required in FKL events. More
-   precisely, if at least one of the incoming particles is a quark or
-   antiquark and there are more than two jets in the final state,
-   this states the probability that the flavours of the outgoing particles
-   are assigned in such a way that an unordered configuration arises.
    Typically, this value should be between 0.01 and 0.1.
 
+.. _`subleading channels`:
+
+**subleading channels**
+   Optional parameters to select a specific unordered process, multiple
+   channels can be selected at once. Only matters if :code:`subleading fraction`
+   is non-zero. Currently three values are allowed:
+
+   - :code:`all`: All channels allowed, default if nothing else set
+   - :code:`none`:  No subleading contribution, only FKL allowed
+      Equivalent to :code:`subleading fraction: 0`
+   - :code:`unordered`: Unordered emission allowed
+      Unordered emission are any rapidity ordering, where exactly one gluon is
+      emitted outside the rapidity ordering required in FKL events. More
+      precisely, if at least one of the incoming particles is a quark or
+      antiquark and there are more than two jets in the final state,
+      :code:`subleading fraction` states the probability that the flavours
+      of the outgoing particles are assigned in such a way that an unordered
+      configuration arises.
+
 .. _`unweight`:
 
 **unweight**
    This setting defines the parameters for the partial unweighting of
    events. You can disable unweighting by removing this entry from the
    configuration file.
 
 .. _`unweight: sample size`:
 
    **sample size**
       The number of weighted events used to calibrate the unweighting.
       A good default is to set this to the number of target
       `events`_. If the number of `events`_ is large this can
       lead to significant memory consumption and a lower value should be
       chosen. Contrarily, for large multiplicities the unweighting
       efficiency becomes worse and the sample size should be increased.
 
 .. _`unweight: max deviation`:
 
    **max deviation**
      Controls the range of events to which unweighting is applied. A
      larger value means that a larger fraction of events are unweighted.
      Typical values are between -1 and 1.
 
 .. _`particle properties`:
 
 **particle properties**
    Specifies various properties of the different particles (Higgs, W or Z).
    This is only relevant if the chosen `process`_ is the production of the
    corresponding particles with jets. E.g. for the `process`_
    :code:`p p => h 2j` the :code:`mass`, :code:`width` and (optionally)
    :code:`decays` of the :code:`Higgs` boson are required, while all other
    particle properties will be ignored.
 
 .. _`particle properties: particle`:
 
    **Higgs, Wp, Wm or Z**
       Name of the boson. Can be any of the once above.
 
    .. _`particle properties: particle: mass`:
 
       **mass**
          The mass of the particle in GeV.
 
    .. _`particle properties: particle: width`:
 
       **width**
          The total decay width of the particle in GeV.
 
    .. _`particle properties: particle: decays`:
 
       **decays**
          Optional setting specifying the decays of the particle. Only the decay
          into two particles is implemented. Each decay has the form
 
          :code:`{into: [p1,p2], branching ratio: r}`
 
          where :code:`p1` and :code:`p2` are the particle names of the
          decay product (e.g. :code:`photon`) and :code:`r` is the branching
          ratio.
 
          Decays of a Higgs boson are treated as the production and subsequent
          decay of an on-shell Higgs boson, so decays into e.g. Z bosons are not
          supported.
 
 .. _`scales`:
 
 **scales**
    Specifies the renormalisation and factorisation scales for the output
    events. For details, see the corresponding entry in the HEJ 2
    :ref:`HEJ 2 settings`. Note that this should usually be a
    single value, as the weights resulting from additional scale choices
    will simply be ignored by HEJ 2.
 
 .. _`event output`:
 
 **event output**
    Specifies the name of a single event output file or a list of such
    files. See the corresponding entry in the HEJ 2
    :ref:`HEJ 2 settings` for details.
 
 .. _`RanLux init`:
 
 .. _`random generator`:
 
 **random generator**
    Sets parameters for random number generation. See the HEJ 2
    :ref:`HEJ 2 settings` for details.
 
 .. _`analysis`:
 
 **analysis**
    Specifies the name and settings for a custom analysis library. This
    can be useful to specify cuts at the fixed-order level. See the
    corresponding entry in the HEJ 2 :ref:`HEJ 2 settings`
    for details.
 
 .. _`Higgs coupling`:
 
 **Higgs coupling**
    This collects a number of settings concerning the effective coupling
    of the Higgs boson to gluons. See the corresponding entry in the
    HEJ 2 :ref:`HEJ 2 settings` for details.
diff --git a/include/HEJ/YAMLreader.hh b/include/HEJ/YAMLreader.hh
index 8740f14..03a5597 100644
--- a/include/HEJ/YAMLreader.hh
+++ b/include/HEJ/YAMLreader.hh
@@ -1,241 +1,241 @@
 /** \file
  *  \brief The file which handles the configuration file parameters
  *
  *  The configuration files parameters are read and then stored
  *  within this objects.
  */
 
 #pragma once
 
 #include "yaml-cpp/yaml.h"
 
 #include "HEJ/config.hh"
 #include "HEJ/exceptions.hh"
-
+#include "HEJ/utility.hh"
 
 namespace HEJ{
   //! Load configuration from file
   /**
    *  @param config_file   Name of the YAML configuration file
    *  @returns             The HEJ 2 configuration
    */
   Config load_config(std::string const & config_file);
 
   //! Set option using the corresponding YAML entry
   /**
    *  @param setting      Option variable to be set
    *  @param yaml         Root of the YAML configuration
    *  @param names        Name of the entry
    *
    *  If the entry does not exist or has the wrong type or format
    *  an exception is thrown.
    *
    *  For example
    *  @code
    *  set_from_yaml(foobar, yaml, "foo", "bar")
    *  @endcode
    *  is equivalent to
    *  @code
    *  foobar = yaml["foo"]["bar"].as<decltype(foobar)>()
    *  @endcode
    *  with improved diagnostics on errors.
    *
    * @see set_from_yaml_if_defined
    */
   template<typename T, typename... YamlNames>
   void set_from_yaml(
       T & setting,
       YAML::Node const & yaml, YamlNames const & ... names
   );
 
   //! Set option using the corresponding YAML entry, if present
   /**
    *  @param setting      Option variable to be set
    *  @param yaml         Root of the YAML configuration
    *  @param names        Name of the entry
    *
    *  This function works similar to set_from_yaml, but does not
    *  throw any exception if the requested YAML entry does not exist.
    *
    *  @see set_from_yaml
    */
   template<typename T, typename... YamlNames>
   void set_from_yaml_if_defined(
       T & setting,
       YAML::Node const & yaml, YamlNames const & ... names
   );
 
   //! Extract jet parameters from YAML configuration
   JetParameters get_jet_parameters(
       YAML::Node const & node, std::string const & entry
   );
 
   //! Extract Higgs coupling settings from YAML configuration
   HiggsCouplingSettings get_Higgs_coupling(
       YAML::Node const & node, std::string const & entry
   );
 
   //! Extract scale setting parameters from YAML configuration
   ScaleConfig to_ScaleConfig(YAML::Node const & yaml);
 
   //! Extract random number generator settings from YAML configuration
   RNGConfig to_RNGConfig(YAML::Node const & node, std::string const & entry);
 
   //! Check whether all options in configuration are supported
   /**
    *  @param conf       Configuration to be checked
    *  @param supported  Tree of supported options
    *
    *  If conf contains an entry that does not appear in supported
    *  an unknown_option exception is thrown. Sub-entries of "analysis"
    *  (if present) are not checked.
    *
    *  @see unknown_option
    */
   void assert_all_options_known(
       YAML::Node const & conf, YAML::Node const & supported
   );
 
   namespace detail{
     void set_from_yaml(fastjet::JetAlgorithm & setting, YAML::Node const & yaml);
     void set_from_yaml(EventTreatment & setting, YAML::Node const & yaml);
     void set_from_yaml(ParticleID & setting, YAML::Node const & yaml);
     void set_from_yaml(OutputFile & setting, YAML::Node const & yaml);
 
     inline
     void set_from_yaml(YAML::Node & setting, YAML::Node const & yaml){
       setting = yaml;
     }
 
     template<typename Scalar>
     void set_from_yaml(Scalar & setting, YAML::Node const & yaml){
       assert(yaml);
       if(!yaml.IsScalar()){
         throw invalid_type{"value is not a scalar"};
       }
       try{
         setting = yaml.as<Scalar>();
       }
       catch(...){
         throw invalid_type{
           "value " + yaml.as<std::string>()
           + " cannot be converted to a " + type_string(setting)
         };
       }
     }
 
     template<typename T>
     void set_from_yaml(optional<T> & setting, YAML::Node const & yaml){
       T tmp;
       set_from_yaml(tmp, yaml);
       setting = tmp;
     }
 
     template<typename T>
     void set_from_yaml(std::vector<T> & setting, YAML::Node const & yaml){
       assert(yaml);
       // special case: treat a single value like a vector with one element
       if(yaml.IsScalar()){
         setting.resize(1);
         return set_from_yaml(setting.front(), yaml);
       }
       if(yaml.IsSequence()){
         setting.resize(yaml.size());
         for(size_t i = 0; i < setting.size(); ++i){
           set_from_yaml(setting[i], yaml[i]);
         }
         return;
       }
       throw invalid_type{""};
     }
 
     template<typename T, typename FirstName, typename... YamlNames>
     void set_from_yaml(
         T & setting,
         YAML::Node const & yaml, FirstName const & name,
         YamlNames && ... names
     ){
       if(!yaml[name]) throw missing_option{""};
       set_from_yaml(
           setting,
           yaml[name], std::forward<YamlNames>(names)...
       );
     }
 
     template<typename T>
     void set_from_yaml_if_defined(T & setting, YAML::Node const & yaml){
       return set_from_yaml(setting, yaml);
     }
 
     template<typename T, typename FirstName, typename... YamlNames>
     void set_from_yaml_if_defined(
         T & setting,
         YAML::Node const & yaml, FirstName const & name,
         YamlNames && ... names
     ){
       if(!yaml[name]) return;
       set_from_yaml_if_defined(
           setting,
           yaml[name], std::forward<YamlNames>(names)...
       );
     }
   }
 
   template<typename T, typename... YamlNames>
   void set_from_yaml(
       T & setting,
       YAML::Node const & yaml, YamlNames const & ... names
   ){
     try{
       detail::set_from_yaml(setting, yaml, names...);
     }
     catch(invalid_type const & ex){
       throw invalid_type{
         "In option " + join(": ", names...) + ": " + ex.what()
       };
     }
     catch(missing_option const &){
       throw missing_option{
         "No entry for mandatory option " + join(": ", names...)
       };
     }
     catch(std::invalid_argument const & ex){
       throw missing_option{
         "In option " + join(": ", names...) + ":"
           " invalid value " + ex.what()
       };
     }
   }
 
   template<typename T, typename... YamlNames>
   void set_from_yaml_if_defined(
       T & setting,
       YAML::Node const & yaml, YamlNames const & ... names
   ){
     try{
       detail::set_from_yaml_if_defined(setting, yaml, names...);
     }
     catch(invalid_type const & ex){
       throw invalid_type{
         "In option " + join(": ", names...) + ": " + ex.what()
       };
     }
     catch(std::invalid_argument const & ex){
       throw missing_option{
         "In option " + join(": ", names...) + ":"
           " invalid value " + ex.what()
       };
     }
   }
 
 }
 
 
 namespace YAML {
 
   template<>
   struct convert<HEJ::OutputFile> {
     static Node encode(HEJ::OutputFile const & outfile);
     static bool decode(Node const & node, HEJ::OutputFile & out);
   };
 }
diff --git a/include/HEJ/utility.hh b/include/HEJ/utility.hh
index f66b810..f7b1262 100644
--- a/include/HEJ/utility.hh
+++ b/include/HEJ/utility.hh
@@ -1,198 +1,206 @@
 /**
  * \file
  * \brief Contains various utilities
  */
 
 #pragma once
 
 #include <algorithm>
 #include <cassert>
 
 #include <boost/core/demangle.hpp>
 
 // FastJet Includes
 #include "fastjet/PseudoJet.hh"
 #include "fastjet/ClusterSequence.hh"
 
 #include "HEJ/PDG_codes.hh"
 
 namespace HEJ{
   //! Class representing a particle
   struct Particle {
     //! particle type
     ParticleID type;
     //! particle momentum
     fastjet::PseudoJet p;
 
     //! get rapidity
     double rapidity() const{
       return p.rapidity();
     }
     //! get transverse momentum
     double perp() const{
       return p.perp();
     }
     //! get momentum in x direction
     double px() const{
       return p.px();
     }
     //! get momentum in y direction
     double py() const{
       return p.py();
     }
     //! get momentum in z direction
     double pz() const{
       return p.pz();
     }
     //! get energy
     double E() const{
       return p.E();
     }
     //! get mass
     double m() const{
       return p.m();
     }
   };
 
   //! Functor to compare rapidities
   /**
    *  This can be used whenever a rapidity comparison function is needed,
    *  for example in many standard library functions.
    *
    *  @see pz_less
    */
   struct rapidity_less{
     template<class FourVector>
     bool operator()(FourVector const & p1, FourVector const & p2){
       return p1.rapidity() < p2.rapidity();
     }
   };
 
   //! Functor to compare momenta in z direction
   /**
    *  This can be used whenever a pz comparison function is needed,
    *  for example in many standard library functions.
    *
    *  @see rapidity_less
    */
   struct pz_less{
     template<class FourVector>
     bool operator()(FourVector const & p1, FourVector const & p2){
       return p1.pz() < p2.pz();
     }
   };
 
 
   //! Convert a vector of Particles to a vector of particle momenta
   inline
   std::vector<fastjet::PseudoJet> to_PseudoJet(
       std::vector<Particle> const & v
   ){
     std::vector<fastjet::PseudoJet> result;
     for(auto && sp: v) result.emplace_back(sp.p);
     return result;
   }
 
   //! Check if a particle is a parton, i.e. quark, antiquark, or gluon
   inline
   bool is_parton(Particle const & p){
     return is_parton(p.type);
   }
 
   //! Check if a particle is a photon, W, Z, or Higgs boson
   inline bool is_AWZH_boson(Particle const & particle){
     return is_AWZH_boson(particle.type);
   }
 
   //! Extract all partons from a vector of particles
   inline
   std::vector<Particle> filter_partons(
       std::vector<Particle> const & v
   ){
     std::vector<Particle> result;
     result.reserve(v.size());
     std::copy_if(
         begin(v), end(v), std::back_inserter(result),
         [](Particle const & p){ return is_parton(p); }
     );
     return result;
   }
 
   //! Create a std::unique_ptr to a T object
   /**
    *  For non-array types this works like std::make_unique,
    *  which is not available under C++11
    */
   template<class T, class... Args>
   std::unique_ptr<T> make_unique(Args&&... a){
     return std::unique_ptr<T>{new T{std::forward<Args>(a)...}};
   }
 
   //! Create an array containing the passed arguments
   template<typename T, typename... U>
   constexpr
   std::array<T, 1 + sizeof...(U)> make_array(T t, U&&... rest){
     return {{t, std::forward<U>(rest)...}};
   }
 
+
+  inline
+  std::string join(
+      std::string const & /* delim */
+  ){
+    return "";
+  }
+
   inline
   std::string join(
       std::string const & /* delim */, std::string const & str
   ){
     return str;
   }
 
   //! Join strings with a delimiter
   /**
    *   @param delim      Delimiter to be put between consecutive strings
    *   @param first      First string
    *   @param second     Second string
    *   @param rest       Remaining strings
    */
   template<typename... Strings>
   std::string join(
       std::string const & delim,
       std::string const & first, std::string const & second,
       Strings&&... rest
   ){
     return join(delim, first + delim + second, std::forward<Strings>(rest)...);
   }
 
   //! Return the name of the argument's type
   template<typename T>
   std::string type_string(T&&){
     return boost::core::demangle(typeid(T).name());
   }
 
   //! Eliminate compiler warnings for unused variables
   template<typename... T>
   constexpr void ignore(T&&...) {}
 
   //! Check whether two doubles are closer than ep > 0 to each other
   inline
   bool nearby_ep(double a, double b, double ep){
     assert(ep > 0);
     return std::abs(a-b) < ep;
   }
 
   //! Check whether all components of two PseudoJets are closer than ep to each other
   inline
   bool nearby_ep(
       fastjet::PseudoJet const & pa, fastjet::PseudoJet const & pb,
       double ep
   ){
     assert(ep > 0);
     for(size_t i = 0; i < 4; ++i){
       if(!nearby_ep(pa[i], pb[i], ep)) return false;
     }
     return true;
   }
 
   inline
   bool nearby(
       fastjet::PseudoJet const & pa, fastjet::PseudoJet const & pb, double const norm = 1.
   ){
     return nearby_ep(pa, pb, 1e-7*norm);
   }
 
 }