diff --git a/Phys/ParticleCombiners/include/CombKernel/ParticleCombiner.h b/Phys/ParticleCombiners/include/CombKernel/ParticleCombiner.h index fda074e62a437abbee7ffb1e834f293cd01c5c16..c27a1012baba69fdd46ad7eadeea6ddc010fbc49 100644 --- a/Phys/ParticleCombiners/include/CombKernel/ParticleCombiner.h +++ b/Phys/ParticleCombiners/include/CombKernel/ParticleCombiner.h @@ -555,13 +555,17 @@ private: // identical inputs (mild EWWW :() if constexpr ( std::is_same_v<std::tuple_element_t<IInput - 1, IterableInputTuple>, std::tuple_element_t<IInput, IterableInputTuple>> ) { - if ( decay.children()[IInput].pid() == decay.children()[IInput - 1].pid() ) { + if ( decay.children()[IInput].pid() == decay.children()[IInput - 1].pid() && !m_allow_different_inputs ) { // Yes, in this case we should insist that the `IInput`th and // `IInput-1`th inputs were, in fact, the same... + // There are some cases in which we don't want to enforce this (for example + // when long-lived particles are involved). This can be swtiched-off via + // the flag m_allow_different_inputs if ( !( std::get<IInput>( inputs ) == std::get<IInput - 1>( inputs ) ) ) { - throw GaudiException{"Got contiguous children with the same PIDs, but the corresponding algorithm inputs " - "were not the same. This is unsupported.", - "NBodyCombiner<name>", StatusCode::FAILURE}; + throw GaudiException{ + "Got contiguous children with the same PIDs, but the corresponding algorithm inputs " + "were not the same. If this is intentional, please set AllowDiffInputsForSameIDChildren = True. ", + "NBodyCombiner<name>", StatusCode::FAILURE}; } // In this case there is no need to come up with a new list of // indices, we will make a "triangular" (need a better name) loop @@ -624,6 +628,8 @@ private: ServiceHandle<LHCb::IParticlePropertySvc> m_particlePropSvc{this, "ParticlePropertySvc", "LHCb::ParticlePropertySvc"}; Gaudi::Property<std::string> m_decay_descriptor{this, "DecayDescriptor", {}, "The decay topology to reconstruct."}; + // By defalut, don't allow contiguous children with the same PID to have different algorithm inputs + Gaudi::Property<bool> m_allow_different_inputs{this, "AllowDiffInputsForSameIDChildren", false}; /// Store decay objects parsed from the descriptor (this will be a maximum of /// two, in the case of a `[]cc` decay descriptor) std::vector<Decays::Decay> m_decays; diff --git a/Phys/ParticleCombiners/include/CombKernel/ThOrCombiner.h b/Phys/ParticleCombiners/include/CombKernel/ThOrCombiner.h index 3586ce7aa9474ad19d47f382aa8d36040eb6e8bf..57be0d258cee0af694b6756b477606f8c282b7a2 100644 --- a/Phys/ParticleCombiners/include/CombKernel/ThOrCombiner.h +++ b/Phys/ParticleCombiners/include/CombKernel/ThOrCombiner.h @@ -570,13 +570,17 @@ namespace ThOr { // identical inputs (mild EWWW :() if constexpr ( std::is_same_v<std::tuple_element_t<IInput - 1, IterableInputTuple>, std::tuple_element_t<IInput, IterableInputTuple>> ) { - if ( decay.children()[IInput].pid() == decay.children()[IInput - 1].pid() ) { + if ( decay.children()[IInput].pid() == decay.children()[IInput - 1].pid() && !m_allow_different_inputs ) { // Yes, in this case we should insist that the `IInput`th and // `IInput-1`th inputs were, in fact, the same... - if ( std::get<IInput>( inputs ) != std::get<IInput - 1>( inputs ) ) { - throw GaudiException{"Got contiguous children with the same PIDs, but the corresponding algorithm inputs " - "were not the same. This is unsupported.", - "ThOr::{name}Combiner", StatusCode::FAILURE}; + // There are some cases in which we don't want to enforce this (for example + // when long-lived particles are involved). This can be swtiched-off via + // the flag m_allow_different_inputs + if ( !( std::get<IInput>( inputs ) == std::get<IInput - 1>( inputs ) ) ) { + throw GaudiException{ + "Got contiguous children with the same PIDs, but the corresponding algorithm inputs " + "were not the same. If this is intentional, please set AllowDiffInputsForSameIDChildren = True.", + "ThOr::{name}Combiner", StatusCode::FAILURE}; } // In this case there is no need to come up with a new list of // indices, we will make a "triangular" (need a better name) loop @@ -1123,6 +1127,9 @@ namespace ThOr { // descriptors Gaudi::Property<std::string> m_decaydescriptor{this, "DecayDescriptor", "PleaseConfigureMe!", "Please provide a decay descriptor!"}; + // By defalut, don't allow contiguous children with the same PID to have different algorithm inputs + Gaudi::Property<bool> m_allow_different_inputs{this, "AllowDiffInputsForSameIDChildren", false}; + // vertex fitter VertexFitter m_vertex_fitter{this}; };