diff --git a/src/YAMLreader.cc b/src/YAMLreader.cc
index 1d30a58..282c5ef 100644
--- a/src/YAMLreader.cc
+++ b/src/YAMLreader.cc
@@ -1,474 +1,474 @@
 /**
  *  \authors   The HEJ collaboration (see AUTHORS for details)
  *  \date      2019
  *  \copyright GPLv2 or later
  */
 #include "HEJ/YAMLreader.hh"
 
 #include <algorithm>
 #include <iostream>
 #include <limits>
 #include <map>
 #include <string>
 #include <unordered_map>
 #include <vector>
 
 #include <dlfcn.h>
 
 #include "HEJ/ScaleFunction.hh"
 #include "HEJ/event_types.hh"
 #include "HEJ/output_formats.hh"
 #include "HEJ/Constants.hh"
 
 namespace HEJ{
   class Event;
 
   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 = {
           "trials", "min extparton pt", "max ext soft pt fraction",
           "FKL", "unordered", "extremal qqx", "central qqx", "non-HEJ",
           "scales", "scale factors", "max scale ratio", "import scales",
           "log correction", "event output", "analysis", "regulator parameter"
         };
         // add subnodes to "supported" - the assigned value is irrelevant
         for(auto && opt: opts) supported[opt] = "";
         for(auto && jet_opt: {"min pt", "algorithm", "R"}){
           supported["resummation jets"][jet_opt] = "";
           supported["fixed order jets"][jet_opt] = "";
         }
         for(auto && opt: {"mt", "use impact factors", "include bottom", "mb"}){
           supported["Higgs coupling"][opt] = "";
         }
         for(auto && opt: {"name", "seed"}){
           supported["random generator"][opt] = "";
         }
         return supported;
       }();
       return supported;
     }
 
     fastjet::JetAlgorithm to_JetAlgorithm(std::string const & algo){
       using namespace fastjet;
       static const std::map<std::string, fastjet::JetAlgorithm> known = {
         {"kt", kt_algorithm},
         {"cambridge", cambridge_algorithm},
         {"antikt", antikt_algorithm},
         {"cambridge for passive", cambridge_for_passive_algorithm},
         {"plugin", plugin_algorithm}
       };
       const auto res = known.find(algo);
       if(res == known.end()){
         throw std::invalid_argument("Unknown jet algorithm " + algo);
       }
       return res->second;
     }
 
     EventTreatment to_EventTreatment(std::string const & name){
       static const std::map<std::string, EventTreatment> known = {
         {"reweight", EventTreatment::reweight},
         {"keep", EventTreatment::keep},
         {"discard", EventTreatment::discard}
       };
       const auto res = known.find(name);
       if(res == known.end()){
         throw std::invalid_argument("Unknown event treatment " + name);
       }
       return res->second;
     }
 
   } // namespace anonymous
 
   namespace detail{
     void set_from_yaml(fastjet::JetAlgorithm & setting, YAML::Node const & yaml){
       setting = to_JetAlgorithm(yaml.as<std::string>());
     }
 
     void set_from_yaml(EventTreatment & setting, YAML::Node const & yaml){
       setting = to_EventTreatment(yaml.as<std::string>());
     }
 
     void set_from_yaml(ParticleID & setting, YAML::Node const & yaml){
       setting = to_ParticleID(yaml.as<std::string>());
     }
   } // namespace detail
 
   JetParameters get_jet_parameters(
       YAML::Node const & node,
       std::string const & entry
   ){
     assert(node);
     JetParameters result;
     fastjet::JetAlgorithm jet_algo = fastjet::antikt_algorithm;
     double R;
     set_from_yaml_if_defined(jet_algo, node, entry, "algorithm");
     set_from_yaml(R, node, entry, "R");
     result.def = fastjet::JetDefinition{jet_algo, R};
     set_from_yaml(result.min_pt, node, entry, "min pt");
     return result;
   }
 
   RNGConfig to_RNGConfig(
       YAML::Node const & node,
       std::string const & entry
   ){
     assert(node);
     RNGConfig result;
     set_from_yaml(result.name, node, entry, "name");
     set_from_yaml_if_defined(result.seed, node, entry, "seed");
     return result;
   }
 
   HiggsCouplingSettings get_Higgs_coupling(
       YAML::Node const & node,
       std::string const & entry
   ){
     assert(node);
     static constexpr double mt_max = 2e4;
 #ifndef HEJ_BUILD_WITH_QCDLOOP
     if(node[entry]){
       throw std::invalid_argument{
         "Higgs coupling settings require building HEJ 2 "
           "with QCDloop support"
           };
     }
 #endif
     HiggsCouplingSettings settings;
     set_from_yaml_if_defined(settings.mt, node, entry, "mt");
     set_from_yaml_if_defined(settings.mb, node, entry, "mb");
     set_from_yaml_if_defined(settings.include_bottom, node, entry, "include bottom");
     set_from_yaml_if_defined(settings.use_impact_factors, node, entry, "use impact factors");
     if(settings.use_impact_factors){
       if(settings.mt != std::numeric_limits<double>::infinity()){
         throw std::invalid_argument{
           "Conflicting settings: "
             "impact factors may only be used in the infinite top mass limit"
             };
       }
     }
     else{
       // huge values of the top mass are numerically unstable
       settings.mt = std::min(settings.mt, mt_max);
     }
     return settings;
   }
 
   FileFormat to_FileFormat(std::string const & name){
     static const std::map<std::string, FileFormat> known = {
       {"Les Houches", FileFormat::Les_Houches},
       {"HepMC", FileFormat::HepMC}
     };
     const auto res = known.find(name);
     if(res == known.end()){
       throw std::invalid_argument("Unknown file format " + name);
     }
     return res->second;
   }
 
   std::string extract_suffix(std::string const & filename){
     size_t separator = filename.rfind('.');
     if(separator == filename.npos) return {};
     return filename.substr(separator + 1);
   }
 
   FileFormat format_from_suffix(std::string const & filename){
     const std::string suffix = extract_suffix(filename);
     if(suffix == "lhe") return FileFormat::Les_Houches;
     if(suffix == "hepmc") return FileFormat::HepMC;
     throw std::invalid_argument{
       "Can't determine format for output file " + filename
     };
   }
 
   void assert_all_options_known(
       YAML::Node const & conf, YAML::Node const & supported
   ){
     if(!conf.IsMap()) return;
     if(!supported.IsMap()) throw invalid_type{"must not have sub-entries"};
     for(auto const & entry: conf){
       const auto name = entry.first.as<std::string>();
       if(! supported[name]) throw unknown_option{name};
       /* check sub-options, e.g. 'resummation jets: min pt'
        * we don't check analysis sub-options
        * those depend on the analysis being used and should be checked there
        * similar for "import scales"
        */
       if(name != "analysis" && name != "import scales"){
         try{
           assert_all_options_known(conf[name], supported[name]);
         }
         catch(unknown_option const & ex){
           throw unknown_option{name + ": " + ex.what()};
         }
         catch(invalid_type const & ex){
           throw invalid_type{name + ": " + ex.what()};
         }
       }
     }
   }
 
 } // namespace HEJ
 
 namespace YAML {
 
   Node convert<HEJ::OutputFile>::encode(HEJ::OutputFile const & outfile) {
     Node node;
     node[to_string(outfile.format)] = outfile.name;
     return node;
   };
 
   bool convert<HEJ::OutputFile>::decode(Node const & node, HEJ::OutputFile & out) {
     switch(node.Type()){
     case NodeType::Map: {
       YAML::const_iterator it = node.begin();
       out.format = HEJ::to_FileFormat(it->first.as<std::string>());
       out.name = it->second.as<std::string>();
       return true;
     }
     case NodeType::Scalar:
       out.name = node.as<std::string>();
       out.format = HEJ::format_from_suffix(out.name);
       return true;
     default:
       return false;
     }
   }
 } // namespace YAML
 
 namespace HEJ{
 
   namespace detail{
     void set_from_yaml(OutputFile & setting, YAML::Node const & yaml){
       setting = yaml.as<OutputFile>();
     }
   }
 
   namespace{
     void update_fixed_order_jet_parameters(
         JetParameters & fixed_order_jets, YAML::Node const & yaml
     ){
       if(!yaml["fixed order jets"]) return;
       set_from_yaml_if_defined(
           fixed_order_jets.min_pt, yaml, "fixed order jets", "min pt"
       );
       fastjet::JetAlgorithm algo = fixed_order_jets.def.jet_algorithm();
       set_from_yaml_if_defined(algo, yaml, "fixed order jets", "algorithm");
       double R = fixed_order_jets.def.R();
       set_from_yaml_if_defined(R, yaml, "fixed order jets", "R");
       fixed_order_jets.def = fastjet::JetDefinition{algo, R};
     }
 
     // like std::stod, but throw if not the whole string can be converted
     double to_double(std::string const & str){
       std::size_t pos;
       const double result = std::stod(str, &pos);
       if(pos < str.size()){
         throw std::invalid_argument(str + " is not a valid double value");
       }
       return result;
     }
 
     using EventScale = double (*)(Event const &);
 
     void import_scale_functions(
         std::string const & file,
         std::vector<std::string> const & scale_names,
         std::unordered_map<std::string, EventScale> & known
     ) {
       auto handle = dlopen(file.c_str(), RTLD_NOW);
       char * error = dlerror();
       if(error != nullptr) throw std::runtime_error{error};
 
       for(auto const & scale: scale_names) {
         void * sym = dlsym(handle, scale.c_str());
         error = dlerror();
         if(error != nullptr) throw std::runtime_error{error};
         known.emplace(scale, reinterpret_cast<EventScale>(sym));
       }
     }
 
     auto get_scale_map(
         YAML::Node const & yaml
     ) {
       std::unordered_map<std::string, EventScale> scale_map;
       scale_map.emplace("H_T", H_T);
       scale_map.emplace("max jet pperp", max_jet_pt);
       scale_map.emplace("jet invariant mass", jet_invariant_mass);
       scale_map.emplace("m_j1j2", m_j1j2);
       if(yaml["import scales"]) {
         if(! yaml["import scales"].IsMap()) {
           throw invalid_type{"Entry 'import scales' is not a map"};
         }
         for(auto const & import: yaml["import scales"]) {
           const auto file = import.first.as<std::string>();
           const auto scale_names =
             import.second.IsSequence()
             ?import.second.as<std::vector<std::string>>()
             :std::vector<std::string>{import.second.as<std::string>()};
           import_scale_functions(file, scale_names, scale_map);
         }
       }
       return scale_map;
     }
 
     // simple (as in non-composite) scale functions
     /**
      * An example for a simple scale function would be H_T,
      * H_T/2 is then composite (take H_T and then divide by 2)
      */
     ScaleFunction parse_simple_ScaleFunction(
         std::string const & scale_fun,
         std::unordered_map<std::string, EventScale> const & known
     ) {
       assert(
           scale_fun.empty() ||
           (!std::isspace(scale_fun.front()) && !std::isspace(scale_fun.back()))
       );
       const auto it = known.find(scale_fun);
       if(it != end(known)) return {it->first, it->second};
       try{
         const double scale = to_double(scale_fun);
         return {scale_fun, FixedScale{scale}};
       } catch(std::invalid_argument const &){}
       throw std::invalid_argument{"Unknown scale choice: " + scale_fun};
     }
 
     std::string trim_front(std::string const & str){
       const auto new_begin = std::find_if(
           begin(str), end(str), [](char c){ return ! std::isspace(c); }
       );
       return std::string(new_begin, end(str));
     }
 
     std::string trim_back(std::string str){
       size_t pos = str.size() - 1;
       // use guaranteed wrap-around behaviour to check whether we have
       // traversed the whole string
       for(; pos < str.size() && std::isspace(str[pos]); --pos) {}
       str.resize(pos + 1); // note that pos + 1 can be 0
       return str;
     }
 
     ScaleFunction parse_ScaleFunction(
         std::string const & scale_fun,
         std::unordered_map<std::string, EventScale> const & known
     ){
       assert(
           scale_fun.empty() ||
           (!std::isspace(scale_fun.front()) && !std::isspace(scale_fun.back()))
       );
       // parse from right to left => a/b/c gives (a/b)/c
       const size_t delim = scale_fun.find_last_of("*/");
       if(delim == scale_fun.npos){
         return parse_simple_ScaleFunction(scale_fun, known);
       }
       const std::string first = trim_back(std::string{scale_fun, 0, delim});
       const std::string second = trim_front(std::string{scale_fun, delim+1});
       if(scale_fun[delim] == '/'){
         return parse_ScaleFunction(first, known)
           / parse_ScaleFunction(second, known);
       }
       else{
         assert(scale_fun[delim] == '*');
         return parse_ScaleFunction(first, known)
           * parse_ScaleFunction(second, known);
       }
     }
 
     EventTreatMap get_event_treatment(
         YAML::Node const & yaml
     ){
       using namespace event_type;
       EventTreatMap treat {
         {no_2_jets, EventTreatment::discard},
         {bad_final_state, EventTreatment::discard},
         {FKL, EventTreatment::reweight},
         {unob, EventTreatment::keep},
         {unof, EventTreatment::keep},
         {qqxexb, EventTreatment::keep},
         {qqxexf, EventTreatment::keep},
         {qqxmid, EventTreatment::keep},
         {FixedOrder, EventTreatment::keep}
       };
       set_from_yaml(treat.at(FKL), yaml, "FKL");
       set_from_yaml(treat.at(unob), yaml, "unordered");
       treat.at(unof) = treat.at(unob);
       set_from_yaml(treat.at(qqxexb), yaml, "extremal qqx");
       set_from_yaml(treat.at(qqxexf), yaml, "extremal qqx");
       set_from_yaml(treat.at(qqxmid), yaml, "central qqx");
       set_from_yaml(treat.at(FixedOrder), yaml, "non-HEJ");
       if(treat[FixedOrder] == EventTreatment::reweight){
         throw std::invalid_argument{"Cannot reweight Fixed Order events"};
       }
       return treat;
     }
 
     Config to_Config(YAML::Node const & yaml){
       try{
         assert_all_options_known(yaml, get_supported_options());
       }
       catch(unknown_option const & ex){
         throw unknown_option{std::string{"Unknown option '"} + ex.what() + "'"};
       }
 
       Config config;
       config.resummation_jets = get_jet_parameters(yaml, "resummation jets");
       config.fixed_order_jets = config.resummation_jets;
       update_fixed_order_jet_parameters(config.fixed_order_jets, yaml);
       set_from_yaml(config.min_extparton_pt, yaml, "min extparton pt");
       // Sets the standard value, then changes this if defined
       config.regulator_lambda=CLAMBDA;
       set_from_yaml_if_defined(config.regulator_lambda, yaml, "regulator parameter");
-      config.max_ext_soft_pt_fraction = std::numeric_limits<double>::infinity();
+      config.max_ext_soft_pt_fraction = 0.1;
       set_from_yaml_if_defined(
           config.max_ext_soft_pt_fraction, yaml, "max ext soft pt fraction"
       );
       set_from_yaml(config.trials, yaml, "trials");
       set_from_yaml(config.log_correction, yaml, "log correction");
       config.treat = get_event_treatment(yaml);
       set_from_yaml_if_defined(config.output, yaml, "event output");
       config.rng = to_RNGConfig(yaml, "random generator");
       set_from_yaml_if_defined(config.analysis_parameters, yaml, "analysis");
       config.scales = to_ScaleConfig(yaml);
       config.Higgs_coupling = get_Higgs_coupling(yaml, "Higgs coupling");
       return config;
     }
 
   } // namespace anonymous
 
   ScaleConfig to_ScaleConfig(YAML::Node const & yaml){
     ScaleConfig config;
     auto scale_funs = get_scale_map(yaml);
     std::vector<std::string> scales;
     set_from_yaml(scales, yaml, "scales");
     config.base.reserve(scales.size());
     std::transform(
         begin(scales), end(scales), std::back_inserter(config.base),
         [scale_funs](auto const & entry){
           return parse_ScaleFunction(entry, scale_funs);
         }
     );
     set_from_yaml_if_defined(config.factors, yaml, "scale factors");
     config.max_ratio = std::numeric_limits<double>::infinity();
     set_from_yaml_if_defined(config.max_ratio, yaml, "max scale ratio");
     return config;
   }
 
   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;
     }
   }
 
 } // namespace HEJ
diff --git a/t/check_res.cc b/t/check_res.cc
index e7535a7..895be3a 100644
--- a/t/check_res.cc
+++ b/t/check_res.cc
@@ -1,164 +1,163 @@
 /**
  *  \authors   The HEJ collaboration (see AUTHORS for details)
  *  \date      2019
  *  \copyright GPLv2 or later
  */
 #include <iostream>
 
 #include "LHEF/LHEF.h"
 
 #include "HEJ/Event.hh"
 #include "HEJ/EventReweighter.hh"
 #include "HEJ/Mixmax.hh"
 #include "HEJ/stream.hh"
 
 #define ASSERT(x) if(!(x)) { \
     std::cerr << "Assertion '" #x "' failed.\n"; \
     return EXIT_FAILURE; \
   }
 
 namespace{
   const fastjet::JetDefinition jet_def{fastjet::kt_algorithm, 0.4};
   const fastjet::JetDefinition Born_jet_def{jet_def};
   constexpr double Born_jetptmin = 30;
   constexpr double extpartonptmin = 30;
-  constexpr double max_ext_soft_pt_fraction =
-    std::numeric_limits<double>::infinity();
+  constexpr double max_ext_soft_pt_fraction = 0.1;
   constexpr double jetptmin = 35;
   constexpr bool log_corr = false;
   using EventTreatment = HEJ::EventTreatment;
   using namespace HEJ::event_type;
   HEJ::EventTreatMap treat{
     {no_2_jets, EventTreatment::discard},
     {bad_final_state, EventTreatment::discard},
     {FixedOrder, EventTreatment::discard},
     {unof, EventTreatment::discard},
     {unob, EventTreatment::discard},
     {qqxexb, EventTreatment::discard},
     {qqxexf, EventTreatment::discard},
     {qqxmid, EventTreatment::discard},
     {FKL, EventTreatment::reweight}
   };
 
   /// true if colour is allowed for particle
   bool correct_colour(HEJ::Particle const & part){
     if(HEJ::is_AWZH_boson(part) && !part.colour) return true;
     if(!part.colour) return false;
     int const colour = part.colour->first;
     int const anti_colour = part.colour->second;
     if(part.type == HEJ::ParticleID::gluon)
       return colour != anti_colour && colour > 0 && anti_colour > 0;
     if(HEJ::is_quark(part))
       return anti_colour == 0 && colour > 0;
     return colour == 0 && anti_colour > 0;
   }
   bool correct_colour(HEJ::Event const & ev){
     if(!HEJ::event_type::is_HEJ(ev.type()))
       return true;
     for(auto const & part: ev.incoming()){
       if(!correct_colour(part))
         return false;
     }
     for(auto const & part: ev.outgoing()){
       if(!correct_colour(part))
         return false;
     }
     return true;
   }
 };
 
 int main(int argn, char** argv) {
   if(argn == 5 && std::string(argv[4]) == "unof"){
     --argn;
     treat[unof] = EventTreatment::reweight;
     treat[unob] = EventTreatment::discard;
     treat[FKL] = EventTreatment::discard;
   }
   if(argn == 5 && std::string(argv[4]) == "unob"){
     --argn;
     treat[unof] = EventTreatment::discard;
     treat[unob] = EventTreatment::reweight;
     treat[FKL] = EventTreatment::discard;
   }
   else if(argn == 5 && std::string(argv[4]) == "splitf"){
     --argn;
     treat[qqxexb] = EventTreatment::discard;
     treat[qqxexf] = EventTreatment::reweight;
     treat[FKL] = EventTreatment::discard;
   }
   else if(argn == 5 && std::string(argv[4]) == "splitb"){
     --argn;
     treat[qqxexb] = EventTreatment::reweight;
     treat[qqxexf] = EventTreatment::discard;
     treat[FKL] = EventTreatment::discard;
   }
   else if(argn == 5 && std::string(argv[4]) == "qqxmid"){
     --argn;
     treat[qqxmid] = EventTreatment::reweight;
     treat[FKL] = EventTreatment::discard;
   }
   if(argn != 4){
     std::cerr << "Usage: check_res eventfile xsection tolerance [uno]";
     return EXIT_FAILURE;
   }
 
   const double xsec_ref = std::stod(argv[2]);
   const double tolerance = std::stod(argv[3]);
 
   HEJ::istream in{argv[1]};
   LHEF::Reader reader{in};
 
   HEJ::PhaseSpacePointConfig psp_conf;
   psp_conf.jet_param = HEJ::JetParameters{jet_def, jetptmin};
   psp_conf.min_extparton_pt = extpartonptmin;
   psp_conf.max_ext_soft_pt_fraction = max_ext_soft_pt_fraction;
   HEJ::MatrixElementConfig ME_conf;
   ME_conf.log_correction = log_corr;
   ME_conf.Higgs_coupling = HEJ::HiggsCouplingSettings{};
   HEJ::EventReweighterConfig conf;
   conf.psp_config = std::move(psp_conf);
   conf.ME_config = std::move(ME_conf);
   conf.jet_param = psp_conf.jet_param;
   conf.treat = treat;
 
   reader.readEvent();
   const bool has_Higgs = std::find(
       begin(reader.hepeup.IDUP),
       end(reader.hepeup.IDUP),
       25
   ) != end(reader.hepeup.IDUP);
   const double mu = has_Higgs?125.:91.188;
   HEJ::ScaleGenerator scale_gen{
     {{std::to_string(mu), HEJ::FixedScale{mu}}}, {}, 1.
   };
   HEJ::Mixmax ran{};
   HEJ::EventReweighter hej{reader.heprup, std::move(scale_gen), conf, ran};
 
   double xsec = 0.;
   double xsec_err = 0.;
   do{
     auto ev_data = HEJ::Event::EventData{reader.hepeup};
     ev_data.reconstruct_intermediate();
     HEJ::Event ev{
       ev_data.cluster(
         Born_jet_def, Born_jetptmin
       )
     };
     auto resummed_events = hej.reweight(ev, 100);
     for(auto const & ev: resummed_events) {
       ASSERT(correct_colour(ev));
       xsec += ev.central().weight;
       xsec_err +=  ev.central().weight*ev.central().weight;
     }
   } while(reader.readEvent());
   xsec_err = std::sqrt(xsec_err);
   const double significance =
     std::abs(xsec - xsec_ref) / std::sqrt( xsec_err*xsec_err + tolerance*tolerance );
   std::cout << xsec_ref << " +/- " << tolerance << " ~ "
     << xsec << " +- " << xsec_err << " => " << significance << " sigma\n";
 
   if(significance > 3.){
     std::cerr << "Cross section is off by over 3 sigma!\n";
     return EXIT_FAILURE;
   }
 }