Commit b6ef6acd authored by CI Runner's avatar CI Runner
Browse files

Merge branch 'master' into mramospe-neutrals

parents c5b85380 d34d58fa
Pipeline #3206501 passed with stage
in 17 seconds
......@@ -11,7 +11,7 @@
cmake_minimum_required(VERSION 3.15)
project(Phys VERSION 33.2
project(Phys VERSION 33.3
LANGUAGES CXX)
# Enable testing with CTest/CDash
......
......@@ -49,7 +49,6 @@
#include "Kernel/IParticleStuffer.h"
#include "Kernel/IParticleTisTos.h"
#include "Kernel/IParticleTransporter.h"
#include "Kernel/IParticleTupleTool.h"
#include "Kernel/IParticleValue.h"
#include "Kernel/IParticleVeto.h"
#include "Kernel/IPlotTool.h"
......
......@@ -36,7 +36,6 @@
<class name = "IParticleStuffer"/>
<class name = "IParticleTransporter"/>
<class name = "IParticleTisTos"/>
<class name = "IParticleTupleTool"/>
<class name = "IParticleValue"/>
<class name = "IPlotTool"/>
<class name = "IProtoParticleFilter"/>
......
/*****************************************************************************\
* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration *
* *
* This software is distributed under the terms of the GNU General Public *
* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". *
* *
* In applying this licence, CERN does not waive the privileges and immunities *
* granted to it by virtue of its status as an Intergovernmental Organization *
* or submit itself to any jurisdiction. *
\*****************************************************************************/
#pragma once
#include "GaudiKernel/IAlgTool.h"
#include <string>
struct IGeometryInfo;
namespace Tuples {
class Tuple;
}
namespace LHCb {
class Particle;
}
/**
* Fill some particle related variables into a tuple.
*
* \sa IEventTupleTool
*
* @author Jeremie Borel
* @date November 2007
*/
struct GAUDI_API IParticleTupleTool : extend_interfaces<IAlgTool> {
DeclareInterfaceID( IParticleTupleTool, 3, 0 );
//! Fill the tuple.
//! - \b top : may be used to provide additional information about \b part, like the top particle of the decay.
//! - \b part : the particle about which some info are filled.
//! - \b head : prefix for the tuple column name.
//! - \b tuple: the tuple to fill
virtual StatusCode fill( LHCb::Particle const* top, LHCb::Particle const* part, std::string const& head,
Tuples::Tuple& tuple, IGeometryInfo const& geometry ) = 0;
};
......@@ -28,7 +28,6 @@
#include "Kernel/IFilterMCParticles.h"
#include "Kernel/IMC2Collision.h"
#include "Kernel/IMCParticleArrayFilter.h"
#include "Kernel/IMCParticleTupleTool.h"
#include "Kernel/IPV2MC.h"
#include "Kernel/IParticle2MCAssociator.h"
#include "Kernel/IParticle2MCWeightedAssociator.h"
......
......@@ -17,7 +17,6 @@
<class name = "IDaVinciAssociatorsWrapper"/>
<class name = "IFilterMCParticles"/>
<class name = "IMCParticleArrayFilter"/>
<class name = "IMCParticleTupleTool"/>
<class name = "IMC2Collision"/>
<class name = "IParticle2MCAssociator"/>
<class name = "IParticle2MCWeightedAssociator"/>
......
/*****************************************************************************\
* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration *
* *
* This software is distributed under the terms of the GNU General Public *
* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". *
* *
* In applying this licence, CERN does not waive the privileges and immunities *
* granted to it by virtue of its status as an Intergovernmental Organization *
* or submit itself to any jurisdiction. *
\*****************************************************************************/
// ============================================================================
#ifndef DECAYTUPLE_IMCPARTICLETUPLETOOL_H
#define DECAYTUPLE_IMCPARTICLETUPLETOOL_H 1
// ============================================================================
// Include files
// from STL
#include <string>
// from Gaudi
#include "GaudiKernel/IAlgTool.h"
static const InterfaceID IID_IMCParticleTupleTool( "IMCParticleTupleTool", 1, 0 );
namespace Tuples {
class Tuple;
}
namespace LHCb {
class MCParticle;
}
/** @class IMCParticleTupleTool
*
* Fill some mc-particle related variables into a tuple.
*
* \sa IEventTupleTool
* \sa IParticleTupleTool
*
* @author patrick.koppenburg@cern.ch
* @date 19 January 2009
*/
class IMCParticleTupleTool : virtual public IAlgTool {
public:
virtual ~IMCParticleTupleTool(){};
// Return the interface ID
static const InterfaceID& interfaceID() { return IID_IMCParticleTupleTool; }
//! Fill the tuple.
//! - \b top : may be used to provide additional information about \b part, like the top particle of the decay.
//! - \b part : the particle about which some info are filled.
//! - \b head : prefix for the tuple column name.
//! - \b tuple: the tuple to fill
virtual StatusCode fill( const LHCb::MCParticle* top, const LHCb::MCParticle* part, const std::string& head,
Tuples::Tuple& tuple ) = 0;
};
#endif // DECAYTUPLE_IMCPARTICLETUPLETOOL_H
......@@ -27,6 +27,21 @@
// Declaration of the Tool Factory
DECLARE_COMPONENT( CheckOverlap )
namespace detail {
template <typename... Particles>
bool find_overlap_in_basics( Particles const*... particles ) {
static_assert( ( std::is_same_v<Particles, LHCb::ProtoParticle> && ... ),
"All Particles must be LHCb::ProtoParticle" );
std::array ps{particles...};
for ( auto i = 0u; i < ps.size(); ++i ) {
for ( auto j = i + 1; j < ps.size(); ++j ) {
if ( ps[i] == ps[j] || ( ps[i]->track() != nullptr && ps[i]->track() == ps[j]->track() ) ) { return true; }
}
}
return false;
}
} // namespace detail
//=============================================================================
// Standard constructor, initializes variables
//=============================================================================
......@@ -99,6 +114,9 @@ bool CheckOverlap::foundOverlap( const LHCb::Particle* particle1 ) const {
bool CheckOverlap::foundOverlap( const LHCb::Particle* particle1, const LHCb::Particle* particle2 ) const {
if ( msgLevel( MSG::VERBOSE ) ) verbose() << "foundOverlap(2)" << endmsg;
if ( !particle1 || !particle2 ) Exception( "Null pointer" );
if ( particle1->proto() != nullptr && particle2->proto() != nullptr ) {
return detail::find_overlap_in_basics( particle1->proto(), particle2->proto() );
}
LHCb::Particle::ConstVector parts( 2 );
parts[0] = particle1;
parts[1] = particle2;
......@@ -111,6 +129,9 @@ bool CheckOverlap::foundOverlap( const LHCb::Particle* particle1, const LHCb::Pa
const LHCb::Particle* particle3 ) const {
if ( msgLevel( MSG::VERBOSE ) ) verbose() << "foundOverlap(3)" << endmsg;
if ( !particle1 || !particle2 || !particle3 ) Exception( "Null pointer" );
if ( particle1->proto() != nullptr && particle2->proto() != nullptr && particle3->proto() != nullptr ) {
return detail::find_overlap_in_basics( particle1->proto(), particle2->proto(), particle3->proto() );
}
LHCb::Particle::ConstVector parts( 3 );
parts[0] = particle1;
parts[1] = particle2;
......@@ -124,6 +145,11 @@ bool CheckOverlap::foundOverlap( const LHCb::Particle* particle1, const LHCb::Pa
const LHCb::Particle* particle3, const LHCb::Particle* particle4 ) const {
if ( msgLevel( MSG::VERBOSE ) ) verbose() << "foundOverlap(4)" << endmsg;
if ( !particle1 || !particle2 || !particle3 || !particle4 ) Exception( "Null pointer" );
if ( particle1->proto() != nullptr && particle2->proto() != nullptr && particle3->proto() != nullptr &&
particle4->proto() != nullptr ) {
return detail::find_overlap_in_basics( particle1->proto(), particle2->proto(), particle3->proto(),
particle4->proto() );
}
LHCb::Particle::ConstVector parts( 4 );
parts[0] = particle1;
parts[1] = particle2;
......
......@@ -22,6 +22,7 @@ gaudi_add_header_only_library(FlavourTaggingLib
gaudi_add_module(FlavourTagging
SOURCES
src/GetFlavourTaggingParticles.cpp
src/BTagging.cpp
src/BTaggingTool.cpp
src/Classification/TaggingClassifierTMVA.cpp
......
/*****************************************************************************\
* (c) Copyright 2000-2021 CERN for the benefit of the LHCb Collaboration *
* *
* This software is distributed under the terms of the GNU General Public *
* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". *
* *
* In applying this licence, CERN does not waive the privileges and immunities *
* granted to it by virtue of its status as an Intergovernmental Organization *
* or submit itself to any jurisdiction. *
\*****************************************************************************/
#include "GetFlavourTaggingParticles.h"
// Declaration of the Algorithm Factory
DECLARE_COMPONENT( GetFlavourTaggingParticles )
LHCb::Particle::Selection GetFlavourTaggingParticles::operator()( const LHCb::Particles& bCandidates,
const LHCb::Particle::Range& taggingParticles,
const LHCb::RecVertices& primaryVertices,
const DetectorElement& lhcbDetector ) const {
auto& geometry = *lhcbDetector.geometry();
LHCb::Particle::Selection selectedParticles;
for ( const auto& particle : taggingParticles ) {
const LHCb::VertexBase* bestParticlePV = m_relatedPVTool->relatedPV( particle, primaryVertices );
for ( const auto& bCand : bCandidates ) {
const LHCb::VertexBase* bestbCandPV = m_relatedPVTool->relatedPV( bCand, primaryVertices );
if ( bestbCandPV == bestParticlePV ) {
selectedParticles.insert( particle );
break;
}
auto minIpChi2 = calcMinIpChi2( *particle, primaryVertices, geometry );
if ( minIpChi2.has_value() ) {
if ( minIpChi2.value() > m_minIpChi2 ) {
selectedParticles.insert( particle );
break;
}
}
}
}
m_inCount += taggingParticles.size();
m_outCount += selectedParticles.size();
return selectedParticles;
}
std::optional<double> GetFlavourTaggingParticles::calcMinIpChi2( const LHCb::Particle& part,
const LHCb::RecVertices& vertices,
const IGeometryInfo& geometry ) const {
double minIpChi2 = std::numeric_limits<double>::max();
for ( auto const* vertex : vertices ) {
auto tempIpChi2 = calcIpChi2( part, *vertex, geometry );
if ( tempIpChi2.has_value() ) {
if ( tempIpChi2.value() < minIpChi2 ) { minIpChi2 = tempIpChi2.value(); }
}
}
if ( minIpChi2 < std::numeric_limits<double>::max() ) return minIpChi2;
return std::nullopt;
}
std::optional<double> GetFlavourTaggingParticles::calcIpChi2( const LHCb::Particle& part,
const LHCb::VertexBase& vertex,
const IGeometryInfo& geometry ) const {
double ip = -100.0;
double ipChi2 = 0;
StatusCode sc = m_distCalcTool->distance( &part, &vertex, ip, ipChi2, geometry );
if ( sc ) return ipChi2;
return std::nullopt;
}
\ No newline at end of file
/*****************************************************************************\
* (c) Copyright 2000-2021 CERN for the benefit of the LHCb Collaboration *
* *
* This software is distributed under the terms of the GNU General Public *
* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". *
* *
* In applying this licence, CERN does not waive the privileges and immunities *
* granted to it by virtue of its status as an Intergovernmental Organization *
* or submit itself to any jurisdiction. *
\*****************************************************************************/
#pragma once
// from Gaudi
#include "GaudiAlg/Transformer.h"
// from LHCb
#include "DetDesc/DetectorElement.h"
#include "DetDesc/GenericConditionAccessorHolder.h"
#include "Event/Particle.h"
#include "Event/RecVertex.h"
#include "Kernel/IDistanceCalculator.h"
#include "Kernel/IRelatedPVFinder.h"
class GetFlavourTaggingParticles
: public Gaudi::Functional::Transformer<LHCb::Particle::Selection(
const LHCb::Particles&, const LHCb::Particle::Range&,
const LHCb::RecVertices&, const DetectorElement& ),
LHCb::DetDesc::usesConditions<DetectorElement>> {
public:
/// Standard constructor
GetFlavourTaggingParticles( const std::string& name, ISvcLocator* pSvcLocator )
: Transformer( name, pSvcLocator,
{KeyValue{"BCandidates", ""}, KeyValue{"TaggingParticles", ""}, KeyValue{"PrimaryVertices", ""},
KeyValue{"StandardGeometry", "/dd/Structure/LHCb"}},
KeyValue{"FlavourTaggingParticles", ""} ) {}
LHCb::Particle::Selection operator()( const LHCb::Particles& bCandidates,
const LHCb::Particle::Range& taggingParticles,
const LHCb::RecVertices& primaryVertices,
const DetectorElement& ) const override;
private:
Gaudi::Property<double> m_minIpChi2{this, "MinIpChi2", 6.,
"Tagging particle requirement: Minimum IPChi2 wrt to all PVs"};
std::optional<double> calcMinIpChi2( const LHCb::Particle& part, const LHCb::RecVertices& vertices,
const IGeometryInfo& geometry ) const;
std::optional<double> calcIpChi2( const LHCb::Particle& part, const LHCb::VertexBase& vertex,
const IGeometryInfo& geometry ) const;
ToolHandle<IRelatedPVFinder> m_relatedPVTool{
this, "RelatedPVFinderTool", "GenericParticle2PVRelator__p2PVWithIPChi2_OnlineDistanceCalculatorName_"};
ToolHandle<IDistanceCalculator> m_distCalcTool{this, "DistanceCalculatorTool", "LoKi::TrgDistanceCalculator"};
mutable Gaudi::Accumulators::SummingCounter<> m_inCount{this, "#InputParticles"};
mutable Gaudi::Accumulators::SummingCounter<> m_outCount{this, "#OutputParticles"};
};
......@@ -40,11 +40,9 @@ gaudi_add_library(LoKiArrayFunctorsLib
gaudi_add_module(LoKiArrayFunctors
SOURCES
src/Components/ArrayTupleTool.cpp
src/Components/CheckOverlap.cpp
src/Components/DTFDict.cpp
src/Components/Dict2tuple.cpp
src/Components/DictOfFunctors.cpp
src/Components/DictOfFunctors.cpp
src/Components/DictValue.cpp
src/Components/DummyTransform.cpp
src/Components/HybridFilterCriterion.cpp
......@@ -56,7 +54,6 @@ gaudi_add_module(LoKiArrayFunctors
src/Components/PrintDecay.cpp
src/Components/PrintTool.cpp
src/Components/TestValue.cpp
src/Components/TupleTool.cpp
LINK
AIDA::aida
Boost::headers
......
/*****************************************************************************\
* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration *
* *
* This software is distributed under the terms of the GNU General Public *
* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". *
* *
* In applying this licence, CERN does not waive the privileges and immunities *
* granted to it by virtue of its status as an Intergovernmental Organization *
* or submit itself to any jurisdiction. *
\*****************************************************************************/
#include "TupleTool.h"
#include "LoKi/Operators.h"
#include "LoKi/Particles11.h"
#include "LoKi/Particles8.h"
#include "LoKi/Particles9.h"
#include <algorithm>
#include <utility>
namespace LoKi {
namespace Hybrid {
/** @class ArrayTupleTool
* "Specific" tuple tool to fill infomation about "other" particles
*
* @code
* xxx.Source = "SOURCE('Phys/StdLoosePions/Particles', PT>1*GeV )"
* xxx. Variables = { "var1" : "PT" , "var2" : "ETA" }
* xxx.AVariables = { "doca" : "ADOCA(1,2)" , "docachi2" : "ACHI2DOCA(1,2)"}
* @endcode
* - "Other" particles are required to be different from the signal particle
* and its top-particle: there is requirement of no common paricles,
* protoparticles and tracks
* - For "A"-variables, temporary array of two elemements:
* (signal particle and one "other" particle from the list)
* is constructed and each "A"-functor is applied to this array.
*
* @see Tuples::TupleObj
* @see LoKi::ATypes::Combination
* @see LoKi::ATypes::AFun
*
* @author Vanya BELYAEV Ivan.Belyaev@itep.ru
* @date 2016-03-19
*/
class ArrayTupleTool : public LoKi::Hybrid::TupleTool {
public:
/** helper class to keep the N-tuple items
* it is needed due to absence of the default constructor for
* the class LoKi::PhysTypes::Fun
* @author Vanya BELYAEV Ivan.Belyaev@itep.ru
* @date 2016-06-05
*/
struct AItem {
/// the default constructor
AItem( const LHCb::Particle* p = nullptr )
: m_name(), m_particle( p ), m_fun( LoKi::BasicFunctors<LoKi::ATypes::Combination>::Constant( -1.e+10 ) ) {}
double operator()( const LHCb::Particle* p ) const {
const LHCb::Particle::ConstVector vct{{m_particle, p}};
return m_fun.fun( LoKi::ATypes::Combination( vct ) );
}
/// the variable name
std::string m_name; // the variable name
/// the particle
const LHCb::Particle* m_particle; /// the paticle
/// the functor
LoKi::ATypes::AFun m_fun; /// the functor
};
/** Fill the tuple.
* @see IParticleTupelTool
* @param top the top particle of the decay.
* @param particle the particle about which some info are filled.
* @param head prefix for the tuple column name.
* @param tuple the tuple to fill
* @return status code
*/
StatusCode fill( LHCb::Particle const* top, LHCb::Particle const* particle, std::string const& head,
Tuples::Tuple& tuple, IGeometryInfo const& geometry ) override;
protected:
/// initialization of the tool
StatusCode initVariables() override {
// get varibales
StatusCode sc = LoKi::Hybrid::TupleTool::initVariables();
if ( sc.isFailure() ) { return Error( "Can't decode varibales", sc ); }
// get the factory
IHybridFactory* the_factory = tool<IHybridFactory>( factory(), this );
sc = the_factory->get( m_source_code, m_source, preambulo() );
if ( sc.isFailure() ) { return Error( "Unable to decode ``source'' code:" + m_source_code, sc ); }
debug() << "The decoded ``source code'' is " << m_source << endmsg;
m_aitems.clear();
m_aitems.reserve( m_avars.size() );
for ( Map::const_iterator ivar = m_avars.begin(); m_avars.end() != ivar; ++ivar ) {
AItem item;
StatusCode sc = the_factory->get( ivar->second, item.m_fun, preambulo() );
if ( sc.isFailure() ) { return Error( "Unable to decode " + ivar->first + " : " + ivar->second, sc ); }
item.m_name = ivar->first;
m_aitems.push_back( std::make_pair( ivar->first, item ) );
debug() << "The decoded 'A'-variable name is '" << m_aitems.back().first << "'\t, the functor : '"
<< m_aitems.back().second.m_fun << "'" << endmsg;
}
release( the_factory ).ignore(); // we do not need the factory anymore
return StatusCode::SUCCESS;
}
public:
/// the update handler
void propHandler( Gaudi::Details::PropertyBase& p ) { return LoKi::Hybrid::TupleTool::propHandler( p ); }
ArrayTupleTool( const std::string& type, const std::string& name, const IInterface* parent );
private:
/// the source of ``other'' particles (code)
std::string m_source_code; //
/// the source itself
LoKi::Types::Source m_source; // { "name":"functor"} map
/// "A"-variables
Map m_avars;
/// the actual type of containter of items
typedef std::vector<std::pair<std::string, AItem>> AItems;
/// "A"-items
AItems m_aitems;
mutable Gaudi::Accumulators::StatCounter<> m_nFiltered1{this, "#filtered1"};
mutable Gaudi::Accumulators::StatCounter<> m_nFiltered2{this, "#filtered2"};
};
} // namespace Hybrid
} // end of namespace LoKi
namespace {
/// empty source
class EmptySource : public LoKi::Types::Sources {
EmptySource* clone() const override { return new EmptySource( *this ); }
result_type operator()() const override {
Error( "Empty source is invoked" ).ignore();
return LHCb::Particle::ConstVector();
}
};
} // namespace
LoKi::Hybrid::ArrayTupleTool::ArrayTupleTool( const std::string& type, const std::string& name,
const IInterface* parent )
: LoKi::Hybrid::TupleTool( type, name, parent ), m_source_code(), m_source( EmptySource() ) {
declareProperty( "Source", m_source_code, "The source of ``other'' particles" )
->declareUpdateHandler( &LoKi::Hybrid::ArrayTupleTool::propHandler, this );
declareProperty( "AVariables", m_avars, "The {'name':'functor'}-map of A-columns for N-tuple " )
->declareUpdateHandler( &LoKi::Hybrid::ArrayTupleTool::propHandler, this );
}
/* Fill the tuple.
* @see IParticleTupleTool
* @param top the top particle of the decay.
* @param particle the particle about which some info are filled.
* @param head prefix for the tuple column name.
* @param tuple the tuple to fill
* @return status code
*/
StatusCode LoKi::Hybrid::ArrayTupleTool::fill( const LHCb::Particle* top, const LHCb::Particle* particle,
const std::string& head, Tuples::Tuple& tuple, IGeometryInfo const& ) {
if ( 0 == top ) { Warning( "LHCb::Particle* 'Top' points to NULL" ).ignore(); }
if ( 0 == particle ) { Warning( "LHCb::Particle* points to NULL" ).ignore(); }
if ( !tuple.valid() ) { return Error( "Invalid tuple " ); }
std::string head_ = head + "_";
// get ``other'' particles
LHCb::Particle::ConstVector input1 = m_source();
LHCb::Particle::ConstVector input2;
input2.reserve( input1.size() );
LoKi::Types::Cut cuts = LoKi::Particles::IsAParticleInTree( particle ) ||
LoKi::Particles::HasProtosInTree( particle ) || LoKi::Particles::HasTracksInTree( particle );
if ( top ) {
cuts = cuts || LoKi::Particles::HasTracksInTree( top ) || LoKi::Particles::IsAParticleInTree( top ) ||
LoKi::Particles::HasProtosInTree( top );
}
cuts = !cuts;
std::copy_if( input1.begin(), input1.end(), std::back_inserter( input2 ), std::cref( cuts ) );
m_nFiltered1 += input1.size();
m_nFiltered2 += input2.size();
tuple->farray( items(), input2.begin(), input2.end(), head_ + "len", 1000 ).ignore();
/// activate 'A'-variables
for ( AItems::iterator item = m_aitems.begin(); m_aitems.end() != item; ++item ) {
item->second.m_particle = particle;
}
tuple->farray( m_aitems, input2.begin(), input2.end(), head_ + "len", 1000 ).ignore();
return StatusCode::SUCCESS;
}
DECLARE_COMPONENT( LoKi::Hybrid::ArrayTupleTool )
/*****************************************************************************\
* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration *
* *
* This software is distributed under the terms of the GNU General Public *
* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". *
* *
* In applying this licence, CERN does not waive the privileges and immunities *
* granted to it by virtue of its status as an Intergovernmental Organization *
* or submit itself to any jurisdiction. *
\*****************************************************************************/
#include "Kernel/IParticleDictTool.h"
#include "Kernel/IParticleTupleTool.h" // Interface
#include "LoKi/IHybridFactory.h"