Skip to content
Snippets Groups Projects
Commit 89ac5a6b authored by Frank Winklmeier's avatar Frank Winklmeier
Browse files

Merge branch 'masterderivationsbphy' into 'master'

Initial migration of BPHY Derivations to master

See merge request atlas/athena!38748
parents e8befe45 d1b9add7
No related branches found
No related tags found
No related merge requests found
Showing
with 3614 additions and 0 deletions
// Dear emacs, this is -*- c++ -*-
/*
Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
*/
/**
* @file BPhysBlindingTool.h
* @author Wolfgang Walkowiak <Wolfgang.Walkowiak@cern.ch>
*
* @brief Dual-use tool for blinding and unblinding certain float values
*/
// $Id: $
#ifndef BPHYSTOOLS_BPHYSBLINDINGTOOL_H
#define BPHYSTOOLS_BPHYSBLINDINGTOOL_H
// Framework includes
#include "AsgTools/AsgTool.h"
// System include(s):
#include <memory>
// Local includes
#include "BPhysTools/IBPhysBlindingTool.h"
#include "BPhysTools/SimpleEncrypter.h"
// EDM includes
#include "xAODTracking/VertexAuxContainer.h"
namespace xAOD {
///
/// @class BPhysBlindingToll
/// @author Wolfgang Walkowiak <Wolfgang.Walkowiak@cern.ch>
///
/// Dual-use tool for blinding and unblinding certain float values
/// provided as variables in a container.
///
/// This tool can be used in two ways:
/// 1. As a tool to blind or unblind arbitrary positive float values
/// using doBlind(float val) or doUnblind(float val).
/// For this mode to work only the corresponding key
/// (JO BlindingKey or UnblindingKey) needs to be set.
/// 2. As a tool to blind a list of variables (VarToBlindNames)
/// for a certain xAOD::VertexContainer's vertices.
/// Since this only works for positive float values,
/// an the values may be scaled by a factor and an
/// offset may be added to the values, specified separately for
/// each variable (BlindingFactors, BlindingOffsets).
/// In addition a negative sign may be added to the resulting blinded
/// value (NegativeSigns) as a convenience.
/// If this tool is used for unblinding the same values for
/// BlindingFactors, BlindingOffsets and NegativeSigns need to be
/// provided.
/// Depending on the mode, the BlindingKey or Unblindingkey need
/// to be set.
///
/// @Note: Key pairs may be produced using the createBlindingKeys
/// utility.
///
/// Job options:
/// - BlindingKey
/// Hex string providing the (public) blinding key.
/// - UnblindingKey
/// Hex string providing the (private) unblinding key.
/// - VertexContainerName
/// Name of the vertex container to be used
/// - BlindingFlag
/// Flag to indicate candidates for blinding ("pass_XXXX")
/// Blind values for all candidates if empty.
/// - VarToBlindNames
/// String with list of float variables to blind (delimiter: .)
/// - BlindingOffsets
/// Offsets applied to values before blinding
/// List must have same length as VarToBlindNames or zero.
/// - BlindingFactors
/// Scale factors applied before blinding
/// List must have same length as VarToBlindNames or zero.
/// - NegativeSigns
/// Flip signs to negative range?
/// List must have same length as VarToBlindNames or zero.
///
///
class BPhysBlindingTool :
public asg::AsgTool, virtual public xAOD::IBPhysBlindingTool {
/// Declare the correct constructor for Athena
ASG_TOOL_CLASS( BPhysBlindingTool, xAOD::IBPhysBlindingTool )
public:
///
/// @brief Regular AsgTool constructor
BPhysBlindingTool(const std::string& name = "BPhysBlindingTool");
///
/// @brief Method initialising the tool
virtual StatusCode initialize() override;
///
/// @brief Method finalizing the tool
virtual StatusCode finalize() override;
///
/// @brief Simply blind one positive float value
///
/// @param[in] val : positive float value to blind.
///
/// @returns Blinded positive float value; same value as input on error.
virtual float doBlind(const float& val) override;
///
/// @name Methods to be called by user classes
/// @{
///
/// @brief Simply unblind one positive float value
///
/// @param[in] val : Blinded positive float value.
///
/// @returns Unblinded positive float value; same value as input on error.
virtual float doUnblind(const float& val) override;
///
/// @brief Simply blind one (positive) float value with corrections
///
/// @param[in] val : float value to blind.
/// @param[in] negativeSign : flip sign after blinding
/// @param[in] offset : before blinding, shift by offset
/// @param[in] factor : before blinding, stretch by factor
///
/// @returns Blinded float value; same value as input on error.
virtual float doBlind(const float& val,
const bool& negativeSign,
const float& offset,
const float& factor) override;
///
/// @name Methods to be called by user classes
/// @{
///
/// @brief Simply unblind one (positive) float value with corrections
///
/// @param[in] val : Blinded float value.
/// @param[in] negativeSign : flip sign before unblinding
/// @param[in] offset : after unblinding, shift by offset
/// @param[in] factor : after unblinding, stretch by factor
///
/// @returns Unblinded positive float value; same value as input on error.
virtual float doUnblind(const float& val,
const bool& negativeSign,
const float& offset,
const float& factor) override;
///
/// @brief Perform blinding of requested variables
virtual StatusCode doBlind() override;
///
/// @brief Perform unblinding of requested variables
virtual StatusCode doUnblind() override;
protected:
///
/// @name Perform blinding or unblinding action
///
virtual StatusCode doBlindingAction(bool unblind=false);
///
/// @name Utility methods
/// @{
///
/// @brief Check whether an element is marked as passing a hypothesis.
///
virtual bool pass(const SG::AuxElement& em, std::string hypo);
///
/// @brief Tokenize a string using certain separators
///
virtual std::vector<std::string> getTokens(std::string input,
std::string seperators);
///
/// @brief Convert vector of floats to string
///
virtual std::string vecToString(const std::vector<float>& v) const;
///
/// @brief Convert vector of bools to string
///
virtual std::string vecToString(const std::vector<bool>& v) const;
///
/// @name Cache current event.
///
virtual StatusCode cacheEvent();
/// @}
protected:
///
/// @name Job options
/// @{
///
/// @brief Vertex container name
std::string m_vertexContainerName;
///
/// @brief List of variables to blind
///
/// (as concatenated string using . as delimiter)
std::string m_varToBlindNames;
///
/// @brief Flag to indicate candidates for blinding
///
/// Left empty: Blind values for all candidates.
std::string m_blindingFlag;
///
/// @brief Offsets applied to values before blinding
///
/// List must have same length as VarToBlindNames or zero.
/// Applied before blinding/after unblinding.
std::vector<float> m_vOffsets;
///
/// @brief Scale factors applied before blinding
///
/// List must have same length as VarToBlindNames or zero.
/// Applied before blinding/after unblinding.
std::vector<float> m_vFactors;
///
/// @brief Flip signs to negative range?
///
/// List must have same length as VarToBlindNames or zero.
/// Applied after blinding/before unblinding.
std::vector<bool> m_vNegSigns;
///
/// @brief Key for blinding
std::string m_blindKey;
///
/// @brief Key for unblinding
std::string m_unblindKey;
/// @}
///
/// @name Containers
/// @{
xAOD::VertexContainer* m_vtxContainer; //!
xAOD::VertexAuxContainer* m_vtxAuxContainer; //!
/// @}
///
/// @name Event caching
/// @{
int m_cachedRun; //!
int m_cachedEvent; //!
/// @}
///
///
/// @name Counters
/// @{
long m_eventsForBlindingSeen; //!
long m_candidatesForBlindingSeen; //!
long m_eventsForUnblindingSeen; //!
long m_candidatesForUnblindingSeen; //!
long m_eventsBlinded; //!
long m_candidatesBlinded; //!
long m_eventsUnblinded; //!
long m_candidatesUnblinded; //!
/// @}
private:
///
/// @brief Vector of variable names
///
std::vector<std::string> m_vVarNames; //!
///
/// @brief Instance of SimpleEncrypter
///
SimpleEncrypter m_senc; //!
}; // class BPhysBlindingTool
} // namespace xAOD
#endif // BPHYSTOOLS_BPHYSBLINDINGTOOL_H
// This file's extension implies that it's C, but it's really -*- C++ -*-.
/*
Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
*/
/**
* @file BPhysTools/BPhysToolsDict.h
* @author Wolfgang Walkowiak <wolfgang.walkowiak@cern.ch>
* @date Mar 2018
* @brief Dictionary header for BPhysTools.
*/
#include "BPhysTools/BPhysBlindingTool.h"
#include "BPhysTools/BPhysTrackVertexMapTool.h"
#include "BPhysTools/SimpleEncrypter.h"
// Dear emacs, this is -*- c++ -*-
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
// $Id: $
#ifndef BPHYSTOOLS_BPHYSTRACKVERTEXMAPTOOL_H
#define BPHYSTOOLS_BPHYSTRACKVERTEXMAPTOOL_H
// Framework includes
#include "BPhysTools/IBPhysTrackVertexMapTool.h"
#include "AsgTools/AsgTool.h"
// System include(s):
#include <memory>
// EDM includes
#include "xAODTracking/TrackParticleAuxContainer.h"
#include "xAODTracking/VertexAuxContainer.h"
namespace xAOD {
///
/// Dual-use tool createing a track-to-vertex map from
/// the vertex-to-track information.
///
/// Job options provided by this class:
/// - VertexContainerName -- name of container for secondary vertices
/// - RefPVContainerName -- name of container for refitted PVs
/// - PVContainerName -- name of container for primary vertices
/// - TrackParticleContainerName -- name of container for TrackParticles
/// - DebugTrkToVtxMaxEvents -- Maximum number of events to produce
/// detailed log output for the
/// track-to-vertex association maps.
/// Set to -1 for infinity.
/// - DumpPrefix -- Line prefix for log dump lines.
/// - HypoName -- Hypothesis name
/// (for picking up inv. mass values)
/// May be a set of hypo names to be
/// tested, delimited by '|'.
///
/// @author Wolfgang Walkowiak <Wolfgang.Walkowiak@cern.ch>
///
/// $Revision:$
/// $Date: $
///
class BPhysTrackVertexMapTool :
public asg::AsgTool, virtual public xAOD::IBPhysTrackVertexMapTool {
/// Declare the correct constructor for Athena
ASG_TOOL_CLASS( BPhysTrackVertexMapTool, xAOD::IBPhysTrackVertexMapTool )
public:
/// Regular AsgTool constructor
BPhysTrackVertexMapTool(const std::string& name =
"BPhysTrackVertexMapTool");
/// Function initialising the tool
virtual StatusCode initialize() override;
/// Function being excuted for each event
virtual StatusCode logEvent() override;
/// Function finalizing the tool
virtual StatusCode finalize() override;
/// Function indicating whether log counter allows logging of current event
virtual bool doLog() const override;
/// convenience method to wrap output lines by a prefix
static std::string wrapLines(std::string lines, std::string prefix);
protected:
/// @name Functions to be called by user classes
/// @{
/// fill cache for current event
virtual StatusCode cacheEvent() override;
/// obtain primary vertices for a given ID track (may return empty vector)
virtual std::vector<const xAOD::Vertex*>
pvsForIDTrack(const xAOD::TrackParticle* track) const override;
/// obtain refitted primary vertices for a given ID track
/// (may return empty vector)
virtual std::vector<const xAOD::Vertex*>
refPVsForIDTrack(const xAOD::TrackParticle* track) const override;
/// obtain secondary vertices for a given ID track (may return empty vector)
virtual std::vector<const xAOD::Vertex*>
svsForIDTrack(const xAOD::TrackParticle* track) const override;
// track-vertex association related
virtual std::string idTrackToString(const xAOD::TrackParticle* track,
unsigned int indent=0,
bool withPV=false,
bool withRefPV=false,
bool withSV=false) override;
virtual std::string pvToString(const xAOD::Vertex* vtx,
unsigned int indent=0,
bool withTracks=false) override;
virtual std::string refPVToString(const xAOD::Vertex* vtx,
unsigned int indent=0,
bool withTracks=false) override;
virtual std::string svToString(const xAOD::Vertex* vtx,
unsigned int indent=0,
bool withTracks=false,
bool withMasses=false) override;
virtual std::string idTracksToString(const xAOD::TrackParticleContainer*
tpc,
unsigned int indent=0,
bool withPV=false,
bool withRefPV=false,
bool withSV=false) override;
virtual std::string pvsToString(const xAOD::VertexContainer* pvc,
unsigned int indent=0,
bool withTracks=false) override;
virtual std::string refPVsToString(const xAOD::VertexContainer* rpvc,
unsigned int indent=0,
bool withTracks=false) override;
virtual std::string svsToString(const xAOD::VertexContainer* svc,
unsigned int indent=0,
bool withTracks=false,
bool withMasses=false) override;
virtual std::string summaryToString(std::string prefix) override;
/// @}
protected:
virtual float getFloat(std::string name, const xAOD::Vertex* b);
virtual std::vector<std::string> getTokens(std::string input,
std::string seperators);
private:
// track-vertex association related
typedef std::map<const xAOD::TrackParticle*,
std::vector<const xAOD::Vertex*> > TrackToVertexMap_t;
virtual void initTrackVertexMaps(const xAOD::TrackParticleContainer* tpc,
const xAOD::VertexContainer* pvc,
const xAOD::VertexContainer* rpvc,
const xAOD::VertexContainer* svc);
virtual void addVertexToTrackVertexMap(TrackToVertexMap_t& map,
const xAOD::TrackParticle* track,
const xAOD::Vertex* vtx);
virtual std::string pvName(const xAOD::Vertex* vtx);
virtual std::string refPVName(const xAOD::Vertex* vtx);
virtual std::string svName(const xAOD::Vertex* vtx);
virtual std::string idTrackName(const xAOD::TrackParticle* vtx);
protected:
// job options
std::string m_vertexContainerName;
std::string m_refPVContainerName;
std::string m_pvContainerName;
std::string m_trackParticleContainerName;
int m_debugTrkToVtxMaxEvents;
std::string m_dumpPrefix;
std::string m_hypoName;
// containers
const xAOD::TrackParticleContainer* m_tracks;
const xAOD::TrackParticleAuxContainer* m_tracksAux;
const xAOD::VertexContainer* m_pvtxContainer;
const xAOD::VertexContainer* m_svtxContainer;
const xAOD::VertexAuxContainer* m_svtxAuxContainer;
const xAOD::VertexContainer* m_refPVContainer;
const xAOD::VertexAuxContainer* m_refPVAuxContainer;
unsigned int m_nEvtsSeen;
int m_cachedRun;
int m_cachedEvent;
private:
// track-vertex association related
typedef std::map<const xAOD::Vertex*, std::string> VertexNameMap_t;
VertexNameMap_t m_pvNameMap;
VertexNameMap_t m_refPVNameMap;
VertexNameMap_t m_svNameMap;
typedef std::map<const xAOD::TrackParticle*, std::string> TrackNameMap_t;
TrackNameMap_t m_idTrackNameMap;
TrackToVertexMap_t m_idTrackToPVMap;
TrackToVertexMap_t m_idTrackToRefPVMap;
TrackToVertexMap_t m_idTrackToSVMap;
}; // class BPhysTrackVertexMapTool
} // namespace xAOD
#endif // BPHYSTOOLS_BPHYSTRACKVERTEXMAPTOOL_H
// Dear emacs, this is -*- c++ -*-
/*
Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
*/
/**
* @file IBPhysBlindingTool.h
* @author Wolfgang Walkowiak <Wolfgang.Walkowiak@cern.ch>
*
* @brief Interface for dual-use tool for (un-)blinding of float values.
*/
#ifndef BPHYSTOOLS_IBPHYSBLINDINGTOOL_H
#define BPHYSTOOLS_IBPHYSBLINDINGTOOL_H
// Framework includes
#include "AsgTools/IAsgTool.h"
// System include(s):
#include <string>
#include <vector>
// EDM includes
#include "xAODTracking/VertexContainer.h"
namespace xAOD {
///
/// Interface for dual-use tool for blinding and unblinding
/// certain float values provided as variables in a container.
///
/// @author Wolfgang Walkowiak <Wolfgang.Walkowiak@cern.ch>
///
///
class IBPhysBlindingTool : virtual public asg::IAsgTool {
public:
/// Declare the correct interface for Athena
ASG_TOOL_INTERFACE( xAOD::IBPhysBlindingTool )
/// @ brief Function finalizing the tool
virtual StatusCode finalize() = 0;
///
/// @name Methods to be called by user classes
/// @{
///
/// @brief Simply blind one positive float value
virtual float doBlind(const float& val) = 0;
///
/// @brief Simply unblind one positive float value
virtual float doUnblind(const float& val) = 0;
///
/// @brief Simply blind one (positive) float value with corretions
virtual float doBlind(const float& val, const bool& negativeSign,
const float& offset, const float& factor) = 0;
///
/// @brief Simply unblind one (positive) float value with corrections
virtual float doUnblind(const float& val, const bool& negativeSign,
const float& offset, const float& factor) = 0;
///
/// @brief Perform blinding of requested variables
virtual StatusCode doBlind() = 0;
///
/// @brief Perform unblinding of requested variables
virtual StatusCode doUnblind() = 0;
/// @}
}; // class IBPhysBlindingTool
} // namespace xAOD
#endif // BPHYSTOOLS_IBPHYSBLINDINGTOOL_H
// Dear emacs, this is -*- c++ -*-
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
// $Id: $
#ifndef BPHYSTOOLS_IBPHYSTRACKVERTEXMAPTOOL_H
#define BPHYSTOOLS_IBPHYSTRACKVERTEXMAPTOOL_H
// Framework includes
#include "AsgTools/IAsgTool.h"
// System include(s):
#include <string>
#include <memory>
#include <vector>
// EDM includes
#include "xAODTracking/TrackParticleContainer.h"
#include "xAODTracking/VertexContainer.h"
namespace xAOD {
///
/// Interface for dual-use tool createing a track-to-vertex map from
/// the vertex-to-track information.
///
/// @author Wolfgang Walkowiak <Wolfgang.Walkowiak@cern.ch>
///
/// $Revision:$
/// $Date: $
///
class IBPhysTrackVertexMapTool : virtual public asg::IAsgTool {
public:
/// Declare the correct interface for Athena
ASG_TOOL_INTERFACE( xAOD::IBPhysTrackVertexMapTool )
/// Function being excuted for each event
virtual StatusCode logEvent() = 0;
/// Function finalizing the tool
virtual StatusCode finalize() = 0;
/// Function indicating whether log counter allows logging of current event
virtual bool doLog() const = 0;
public:
/// @name Functions to be called by user classes
/// @{
/// fill cache for current event
virtual StatusCode cacheEvent() = 0;
/// obtain primary vertices for a given ID track (may return empty vector)
virtual std::vector<const xAOD::Vertex*>
pvsForIDTrack(const xAOD::TrackParticle* track) const = 0;
/// obtain refitted primary vertices for a given ID track
/// (may return empty vector)
virtual std::vector<const xAOD::Vertex*>
refPVsForIDTrack(const xAOD::TrackParticle* track) const = 0;
/// obtain secondary vertices for a given ID track (may return empty vector)
virtual std::vector<const xAOD::Vertex*>
svsForIDTrack(const xAOD::TrackParticle* track) const = 0;
// track-vertex association related
virtual std::string idTrackToString(const xAOD::TrackParticle* track,
unsigned int indent=0,
bool withPV=false,
bool withRefPV=false,
bool withSV=false) = 0;
virtual std::string pvToString(const xAOD::Vertex* vtx,
unsigned int indent=0,
bool withTracks=false) = 0;
virtual std::string refPVToString(const xAOD::Vertex* vtx,
unsigned int indent=0,
bool withTracks=false) = 0;
virtual std::string svToString(const xAOD::Vertex* vtx,
unsigned int indent=0,
bool withTracks=false,
bool withMasses=false) = 0;
virtual std::string idTracksToString(const xAOD::TrackParticleContainer*
tpc,
unsigned int indent=0,
bool withPV=false,
bool withRefPV=false,
bool withSV=false) = 0;
virtual std::string pvsToString(const xAOD::VertexContainer* pvc,
unsigned int indent=0,
bool withTracks=false) = 0;
virtual std::string refPVsToString(const xAOD::VertexContainer* rpvc,
unsigned int indent=0,
bool withTracks=false) =0;
virtual std::string svsToString(const xAOD::VertexContainer* svc,
unsigned int indent=0,
bool withTracks=false,
bool withMasses=false) = 0;
virtual std::string summaryToString(std::string prefix) = 0;
/// @}
}; // class IBPhysTrackVertexMapTool
} // namespace xAOD
#endif // BPHYSTOOLS_IBPHYSTRACKVERTEXMAPTOOL_H
// Dear emacs, this is -*- c++ -*-
/*
Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
*/
/**
* @file SimpleEncrypter.h
* @author Wolfgang Walkowiak <Wolfgang.Walkowiak@cern.ch>
*
* @brief Provide simple asymmetric encryption for blinding of float values.
*/
#ifndef BPHYSTOOLS_SIMPLEENCRYPTER_H
#define BPHYSTOOLS_SIMPLEENCRYPTER_H
// Framework includes
#include "AsgMessaging/AsgMessaging.h"
// System includes
#include <string>
#include <set>
namespace xAOD {
///
/// @class SimpleEncrypter
/// @author Wolfgang Walkowiak <Wolfgang.Walkowiak@cern.ch.>
///
/// @brief Provide simple asymmetric encryption for blinding of float values.
///
/// Provides asymmetric key encryption for blinding of positive float
/// values. Internally it uses a simple RSA encryption of bits in
/// the floating point numbers.
/// This class is used by the BPhysBlindingTool.
///
class SimpleEncrypter : public asg::AsgMessaging {
public:
/// @brief Useful typedefs
typedef long long int LLI_t;
typedef unsigned long long int ULLI_t;
///
/// @brief Main constructor
///
/// @param[in] name of instance
///
SimpleEncrypter(const std::string& name = "SimpleEncrypter");
///
/// @brief Default destructor
///
virtual ~SimpleEncrypter();
///
/// @brief Generate private and public keys
///
/// @returns key pair as string: [private key, public key]
///
virtual std::pair<std::string, std::string> genKeyPair();
///
/// @brief Set private key
///
/// @param[in] hex string with private key
///
virtual void setPrivKey(std::string keystr);
///
/// @brief Set public key
///
/// @param[in] hex string with public key
///
virtual void setPubKey(std::string keystr);
///
/// @brief Get private key
///
/// @returns hex string with private key
///
virtual std::string getPrivKey() const;
///
/// @brief Get public key
///
/// @returns hex string with public key
///
virtual std::string getPubKey() const;
///
/// @brief Encrypt a positive integer value
///
/// @param[in] unsigned integer value to be encrypted
///
/// @returns encrypted unsigned integer value
///
virtual ULLI_t encrypt(ULLI_t x);
///
/// @brief Decrypt a positive integer value
///
/// @param[in] unsigned integer value to be decrypted
///
/// @returns encrypted unsigned integer value
///
virtual ULLI_t decrypt(ULLI_t x);
///
/// @brief Encrypt a positive float value
///
/// @param[in] positive float value to be encrypted
///
/// @returns encrypted float value
///
virtual float encrypt(float x);
///
/// @brief Decrypt a positive float value
///
/// @param[in] positive float value to be decrypted
///
/// @returns encrypted float value
///
virtual float decrypt(float x);
private:
///
/// @name Key generation utilities
/// @{
///
/// @brief Internally generate numeric representation of key pair
///
virtual void genKeyPairInternal();
///
/// @brief Find a prime number
///
virtual ULLI_t genPrime() const;
///
/// @brief Check for being a prime number
///
virtual bool isPrime(ULLI_t n) const;
///
/// @brief Find greatest common denominator
///
virtual ULLI_t greatestCommonDenominator(ULLI_t n1, ULLI_t n2) const;
///
/// @brief Find a coprime number
///
virtual ULLI_t genCoprime(ULLI_t n) const;
///
/// @brief Find decryption exponent
///
virtual ULLI_t genDecryptionExponent(ULLI_t phi, ULLI_t e) const;
///
/// @}
///
/// @name Key conversion utilities
/// @{
///
/// @brief Convert key to hex string
///
virtual std::string keyToString(ULLI_t a, ULLI_t b) const;
///
/// @brief Decode hex string to two integers
///
virtual std::pair<ULLI_t, ULLI_t> decodeKeyString(std::string str) const;
/// @}
///
/// @name float <-> int conversion utilities
/// @{
///
/// @brief Interpret bits of floating point number as integer
///
virtual ULLI_t floatBitsToInt(float val) const;
///
/// @brief Interpret bits of integer as floating point number
///
virtual float intBitsToFloat(ULLI_t val) const;
/// @}
///
/// @name Internal en-/decryption methods
/// @{
///
/// @brief Encrypt using format preserving encryption w.r.t. RSA modulus
///
ULLI_t encryptFPECycle(ULLI_t a) const;
///
/// @brief Decrypt using format preserving encryption w.r.t. RSA modulus
///
ULLI_t decryptFPECycle(ULLI_t a) const;
///
/// @brief Encrypt integer (internal)
///
ULLI_t encryptInternal(ULLI_t x) const;
///
/// @brief Decrypt integer (internal)
///
ULLI_t decryptInternal(ULLI_t x) const;
///
/// @brief Exponentiate a with d observing modulus n
///
ULLI_t powerMod(ULLI_t a, ULLI_t d, ULLI_t n) const;
///
/// @brief Check setup readiness for encryption
///
bool isOkForEnc();
///
/// @brief Check setup readiness for decryption
///
bool isOkForDec();
///
/// @}
private:
///
/// @name Internal static consts
///
/// @brief Approximate range for prime numbers to be generated in
static const ULLI_t m_MAXRANGE;
static const ULLI_t m_MINRANGE;
/// @brief maximum number of hex digits for key parts
static const unsigned int m_MAXHEXDIGITS;
///
/// @name Internal member variables
///
/// RSA modulus: common part of both keys
ULLI_t m_n;
/// encryption exponent: public key part II
ULLI_t m_e;
/// decryption exponent: private key part II
ULLI_t m_d;
/// indicates that keys are set and range checks are ok
bool m_isOkForEnc;
bool m_isOkForDec;
}; // class
} // namespace xAOD
#endif // BPHYSTOOLS_SIMPLEENCRYPTER_H
<!--
Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
-->
<lcgdict>
<!-- BPhysTools -->
<class name="xAOD::BPhysBlindingTool" />
<class name="xAOD::BPhysTrackVertexMapTool" />
<class name="xAOD::SimpleEncrypter" />
</lcgdict>
#
# Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
#
# $Id: CMakeLists.txt 805745 2017-05-31 17:23:48Z wwalko $
#
# Build configuration for the package.
#
#********************************************
set(extra_dep)
if( XAOD_STANDALONE )
set(extra_dep)
else()
set( extra_dep
GaudiKernel
Control/AthenaKernel
)
endif()
#********************************************
set(extra_libs)
if( XAOD_STANDALONE )
set(extra_libs)
else()
set( extra_libs
GaudiKernel
AthenaKernel
)
endif()
#********************************************
# The name of the package:
atlas_subdir( BPhysTools )
# Used external(s):
find_package( ROOT COMPONENTS Core Physics Matrix )
find_package( Boost )
# Build the main library of the package:
atlas_add_library( BPhysToolsLib
BPhysTools/*.h Root/*.cxx src/*.cxx
PUBLIC_HEADERS BPhysTools
INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
PRIVATE_INCLUDE_DIRS ${Boost_INCLUDE_DIRS}
LINK_LIBRARIES ${ROOT_LIBRARIES}
xAODTracking
xAODBPhysLib
AsgTools
${extra_libs}
PRIVATE_LINK_LIBRARIES ${Boost_LIBRARIES}
xAODEventInfo
)
if(NOT XAOD_STANDALONE)
atlas_add_component( BPhysTools
src/components/*.cxx
INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
PRIVATE_INCLUDE_DIRS ${Boost_INCLUDE_DIRS}
LINK_LIBRARIES ${ROOT_LIBRARIES}
xAODTracking
xAODBPhysLib
AsgTools
${extra_libs}
BPhysToolsLib
PRIVATE_LINK_LIBRARIES ${Boost_LIBRARIES}
xAODEventInfo
)
endif()
# Build the dictionary
atlas_add_dictionary( BPhysToolsDict
BPhysTools/BPhysToolsDict.h
BPhysTools/selection.xml
LINK_LIBRARIES BPhysToolsLib
)
# Executables in util subdirectory
file (GLOB util_sources RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/util/*.cxx")
foreach (source ${util_sources})
string (REGEX REPLACE "util/(.*).cxx" "\\1" util ${source})
atlas_add_executable (${util} ${source} LINK_LIBRARIES BPhysToolsLib)
endforeach (source ${util_sources})
/*
Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
*/
// system include:
#include "boost/tokenizer.hpp"
#include <boost/algorithm/string.hpp>
#include <set>
#include <cmath>
// EDM includes:
#include "xAODEventInfo/EventInfo.h"
// ROOT includes
#include "TString.h"
// Local include(s):
#include "BPhysTools/BPhysBlindingTool.h"
namespace xAOD {
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
BPhysBlindingTool::BPhysBlindingTool( const std::string& name )
: asg::AsgTool( name ),
m_vtxContainer(nullptr), m_vtxAuxContainer(nullptr),
m_cachedRun(-1), m_cachedEvent(-1),
m_eventsForBlindingSeen(0),
m_candidatesForBlindingSeen(0),
m_eventsForUnblindingSeen(0),
m_candidatesForUnblindingSeen(0),
m_eventsBlinded(0),
m_candidatesBlinded(0),
m_eventsUnblinded(0),
m_candidatesUnblinded(0) {
#ifdef ASGTOOL_ATHENA
declareInterface< IBPhysBlindingTool >( this );
#endif // ASGTOOL_ATHENA
// Vertex container
declareProperty("VertexContainerName", m_vertexContainerName = "");
// List of variables to blind
// (as concatenated string using . as delimiter)
declareProperty("VarToBlindNames", m_varToBlindNames = "");
// Flag to indicate candidates for blinding
// Left empty: Blind values for all candidates.
declareProperty("BlindingFlag" , m_blindingFlag = "");
// Offsets applied to values before blinding
// List must have same length as VarToBlindNames or zero.
declareProperty("BlindingOffsets", m_vOffsets);
// Scale factors applied before blinding
// List must have same length as VarToBlindNames or zero.
declareProperty("BlindingFactors", m_vFactors);
// Flip signs to negative range?
declareProperty("NegativeSigns" , m_vNegSigns);
// Key for blinding
declareProperty("BlindingKey" , m_blindKey = "");
// Key for unblinding
declareProperty("UnblindingKey" , m_unblindKey = "");
}
//--------------------------------------------------------------------------
StatusCode BPhysBlindingTool::initialize() {
// Greet the user:
ATH_MSG_DEBUG( "Initializing xAOD::BPhysBlindingTool" );
// Setup of variables
if ( m_vertexContainerName == "" ) {
ATH_MSG_INFO("No vertex container name provided.");
}
if ( m_varToBlindNames != "" ) {
m_vVarNames = getTokens(m_varToBlindNames, ".,:;|");
}
// Blinding and unblinding keys
if ( m_blindKey == "" && m_unblindKey == "" ) {
ATH_MSG_ERROR("You must at least set a key for blinding or unblinding!");
} else {
if ( m_blindKey != "" ) {
m_senc.setPubKey(m_blindKey);
ATH_MSG_INFO("Setting blinding key.");
}
if ( m_unblindKey != "" ) {
m_senc.setPrivKey(m_unblindKey);
ATH_MSG_INFO("Setting unblinding key.");
}
}
// make sure offsets vector is of correct length
if ( m_vOffsets.size() < m_vVarNames.size() ) {
for (uint i=m_vOffsets.size(); i<m_vVarNames.size(); ++i) {
m_vOffsets.push_back(0.);
}
ATH_MSG_INFO("Extending BlindingOffsets list ...");
} else if ( m_vOffsets.size() > m_vVarNames.size() ) {
ATH_MSG_WARNING("BlindingOffsets list longer than VarToBlindNames.");
}
// make sure scale factors vector is of correct length
if ( m_vFactors.size() < m_vVarNames.size() ) {
for (uint i=m_vFactors.size(); i<m_vVarNames.size(); ++i) {
m_vFactors.push_back(1.);
}
ATH_MSG_INFO("Extending BlindingOffsets list ...");
} else if ( m_vFactors.size() > m_vVarNames.size() ) {
ATH_MSG_WARNING("BlindingFactors list longer than VarToBlindNames.");
}
// make sure negative signs vector is of correct length
if ( m_vNegSigns.size() < m_vVarNames.size() ) {
for (uint i=m_vNegSigns.size(); i<m_vVarNames.size(); ++i) {
m_vNegSigns.push_back(1.);
}
ATH_MSG_INFO("Extending NegativeSigns list ...");
} else if ( m_vNegSigns.size() > m_vVarNames.size() ) {
ATH_MSG_WARNING("NegativeSigns list longer than VarToBlindNames.");
}
// some info for the job log
ATH_MSG_INFO("VertexContainerName : " << m_vertexContainerName);
ATH_MSG_INFO("BlindingFlag : " << m_blindingFlag);
ATH_MSG_INFO("VarToBlindNames : " << m_varToBlindNames);
ATH_MSG_INFO("BlindingOffsets : " << vecToString(m_vOffsets));
ATH_MSG_INFO("BlindingFactors : " << vecToString(m_vFactors));
ATH_MSG_INFO("NegativeSigns : " << vecToString(m_vNegSigns));
ATH_MSG_INFO("BlindingKey : " << m_blindKey);
ATH_MSG_INFO("UnblindingKey : " << m_unblindKey);
// Return gracefully:
return StatusCode::SUCCESS;
}
//--------------------------------------------------------------------------
StatusCode BPhysBlindingTool::finalize() {
ATH_MSG_DEBUG( "Finalizing xAOD::BPhysBlindingTool" );
ATH_MSG_INFO("Statistics for " << name() << ":");
ATH_MSG_INFO(Form("N_eventsForBlindingSeen : %10ld",
m_eventsForBlindingSeen));
ATH_MSG_INFO(Form("N_eventsBlinded : %10ld",
m_eventsBlinded));
ATH_MSG_INFO(Form("N_eventsForUnblindingSeen : %10ld",
m_eventsForUnblindingSeen));
ATH_MSG_INFO(Form("N_eventsUnblinded : %10ld",
m_eventsUnblinded));
ATH_MSG_INFO(Form("N_candidatesForBlindingSeen : %10ld",
m_candidatesForBlindingSeen));
ATH_MSG_INFO(Form("N_candidatesBlinded : %10ld",
m_candidatesBlinded));
ATH_MSG_INFO(Form("N_candidatesForUnblindingSeen : %10ld",
m_candidatesForUnblindingSeen));
ATH_MSG_INFO(Form("N_candidatesUnblinded : %10ld",
m_candidatesUnblinded));
// Return gracefully:
return StatusCode::SUCCESS;
}
//--------------------------------------------------------------------------
// Simply blind one positive float value
//--------------------------------------------------------------------------
float BPhysBlindingTool::doBlind(const float& val) {
return m_senc.encrypt(val);
}
//--------------------------------------------------------------------------
// Simply unblind one positive float value
//--------------------------------------------------------------------------
float BPhysBlindingTool::doUnblind(const float& val) {
return m_senc.decrypt(val);
}
//--------------------------------------------------------------------------
// Simply blind one (positive) float value
//--------------------------------------------------------------------------
float BPhysBlindingTool::doBlind(const float& val,
const bool& negativeSign,
const float& offset,
const float& factor) {
// adjustment if requested
float bval(val);
float cval = val*factor + offset;
if ( cval > 0. ) {
// perform actual blinding
bval = m_senc.encrypt(cval);
if (negativeSign) bval *= -1.;
} else {
ATH_MSG_WARNING("Blinding: Corrected value not positive: "
<< val << Form(" (%a) -> ", val)
<< cval << Form(" (%a)", cval));
} // if cval > 0
return bval;
}
//--------------------------------------------------------------------------
// Simply unblind one (positive) float value
//--------------------------------------------------------------------------
float BPhysBlindingTool::doUnblind(const float& val,
const bool& negativeSign,
const float& offset,
const float& factor) {
float bval(val), cval(val);
if (negativeSign) bval *= -1.;
// if ( bval > 0. || isnan(bval) ) {
if ( bval > 0. || !std::isnormal(bval) ) {
// perform actual unblinding
cval = m_senc.decrypt(bval);
if ( factor != 0. ) {
cval = (cval - offset)/factor;
} else {
ATH_MSG_WARNING("Unblinding: BlindingFactor == 0!: "
<< val << Form(" (%a)", val));
} // if m_vFactors[ivtx] != 0
} else {
ATH_MSG_WARNING("Unblinding: Corrected value not positive: "
<< val << Form(" (%a) -> ", val)
<< bval << Form(" (%a)", bval));
} // if bval > 0
return cval;
}
//--------------------------------------------------------------------------
// Perform blinding of requested variables
//--------------------------------------------------------------------------
StatusCode BPhysBlindingTool::doBlind() {
if ( m_blindKey == "" ) {
ATH_MSG_WARNING("Can not blind without blinding key!");
} else {
ATH_CHECK( doBlindingAction(false) );
}
// Return gracefully:
return StatusCode::SUCCESS;
}
//--------------------------------------------------------------------------
// Perform unblinding of requested variables
//--------------------------------------------------------------------------
StatusCode BPhysBlindingTool::doUnblind() {
if ( m_unblindKey == "" ) {
ATH_MSG_WARNING("Can not unblind without unblinding key!");
} else {
ATH_CHECK( doBlindingAction(true) );
}
// Return gracefully:
return StatusCode::SUCCESS;
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Protected methods
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Perform blinding or unblinding action
//--------------------------------------------------------------------------
StatusCode BPhysBlindingTool::doBlindingAction(bool unblind) {
ATH_CHECK(cacheEvent());
// counters
if ( unblind ) {
++m_eventsForUnblindingSeen;
} else {
++m_eventsForBlindingSeen;
}
if ( m_vVarNames.size() > 0 ) {
long candidatesBlinded(0);
long candidatesUnblinded(0);
// loop over vertices
// int ivtx(0);
for (xAOD::VertexContainer::const_iterator
vtxItr = m_vtxContainer->begin();
vtxItr != m_vtxContainer->end(); ++vtxItr) {
// counters
if ( unblind ) {
++m_candidatesForUnblindingSeen;
} else {
++m_candidatesForBlindingSeen;
}
const xAOD::Vertex* vtx = *vtxItr;
// check whether to apply (un-)blinding to this candidate
if ( m_blindingFlag == "" || pass(*vtx, m_blindingFlag) ) {
// counters
if ( unblind ) {
++candidatesUnblinded;
} else {
++candidatesBlinded;
}
// loop over variable names
for (size_t iv=0; iv<m_vVarNames.size(); ++iv) {
SG::AuxElement::Decorator<float> floatDec(m_vVarNames[iv]);
// check for variable
if ( floatDec.isAvailable(*vtx) ) {
float val = floatDec(*vtx);
if ( unblind ) {
// unblinding
floatDec(*vtx) = doUnblind(val, m_vNegSigns[iv],
m_vOffsets[iv], m_vFactors[iv]);
ATH_MSG_DEBUG("Unblind: " << val << Form(" (%a) -> ", val)
<< floatDec(*vtx)
<< Form(" (%a)", floatDec(*vtx)));
} else {
// blinding
floatDec(*vtx) = doBlind(val, m_vNegSigns[iv],
m_vOffsets[iv], m_vFactors[iv]);
ATH_MSG_DEBUG("Blind: " << val << Form(" (%a) -> ", val)
<< floatDec(*vtx)
<< Form(" (%a)", floatDec(*vtx)));
} // if unblind
} else {
ATH_MSG_WARNING("Missing variable " << m_vVarNames[iv]);
} // if isAvailable
} // for m_vVarNames
} // if blinding
} // for iv
// counters
if ( unblind ) {
m_candidatesUnblinded += candidatesUnblinded;
if ( candidatesUnblinded > 0 ) ++m_eventsUnblinded;
} else {
m_candidatesBlinded += candidatesBlinded;
if ( candidatesBlinded > 0 ) ++m_eventsBlinded;
}
} // if m_vVarNames.size()
// Return gracefully:
return StatusCode::SUCCESS;
}
//--------------------------------------------------------------------------
// Cache current event.
//
// Call this once per event.
// Repeated calls for the same run/event are not updating the cache again.
//--------------------------------------------------------------------------
StatusCode BPhysBlindingTool::cacheEvent() {
ATH_MSG_DEBUG("BPhysBlindingTool::cacheEvent -- begin");
const xAOD::EventInfo* eventInfo = NULL;
ATH_CHECK(evtStore()->retrieve(eventInfo, "EventInfo"));
if ( m_cachedRun != (int)eventInfo->runNumber() ||
m_cachedEvent != (int)eventInfo->eventNumber() ) {
// note update
m_cachedRun = eventInfo->runNumber();
m_cachedEvent = eventInfo->eventNumber();
ATH_MSG_DEBUG("BPhysBlindingTool::cacheEvent: caching now: "
<< "run " << m_cachedRun << " event " << m_cachedEvent);
// retrieve vertices container
m_vtxContainer = nullptr;
m_vtxAuxContainer = nullptr;
if ( evtStore()->transientContains<xAOD::VertexContainer>(m_vertexContainerName) ) {
ATH_MSG_DEBUG("In transient store: " << m_vertexContainerName);
ATH_CHECK(evtStore()->retrieve(m_vtxContainer,
m_vertexContainerName));
ATH_CHECK(evtStore()->retrieve(m_vtxAuxContainer,
m_vertexContainerName+"Aux."));
} else {
ATH_MSG_DEBUG("Not in transient store: " << m_vertexContainerName);
const xAOD::VertexContainer* constVtxContainer = nullptr;
const xAOD::VertexAuxContainer* constVtxAuxContainer = nullptr;
ATH_CHECK(evtStore()->retrieve(constVtxContainer,
m_vertexContainerName));
ATH_CHECK(evtStore()->retrieve(constVtxAuxContainer,
m_vertexContainerName+"Aux."));
// create a copy
m_vtxContainer = new xAOD::VertexContainer();
m_vtxAuxContainer = new xAOD::VertexAuxContainer();
m_vtxContainer->setStore(m_vtxAuxContainer);
for (const xAOD::Vertex* constVtx : *constVtxContainer) {
xAOD::Vertex* vtx = new xAOD::Vertex();
m_vtxContainer->push_back(vtx);
*vtx = *constVtx;
}
ATH_CHECK(evtStore()->record(m_vtxContainer,
m_vertexContainerName));
ATH_CHECK(evtStore()->record(m_vtxAuxContainer,
m_vertexContainerName+"Aux."));
}
ATH_MSG_DEBUG("Found vertex collection with key "
<< m_vertexContainerName);
} // if new run/event
ATH_MSG_DEBUG("BPhysBlindingTool::cacheEvent -- end");
// Return gracefully:
return StatusCode::SUCCESS;
}
//--------------------------------------------------------------------------
// Helper to check whether an element is marked as passing a specific
// hypothesis.
//--------------------------------------------------------------------------
bool BPhysBlindingTool::pass(const SG::AuxElement& em, std::string hypo) {
if ( !boost::algorithm::starts_with(hypo, "passed_") )
hypo = "passed_" + hypo;
SG::AuxElement::Accessor<Char_t> flagAcc(hypo);
return flagAcc.isAvailable(em) && flagAcc(em) != 0;
}
//--------------------------------------------------------------------------
// Tokenize a string using certain separators
//--------------------------------------------------------------------------
std::vector<std::string>
BPhysBlindingTool::getTokens(std::string input, std::string seperators) {
std::vector<std::string> tokens;
boost::char_separator<char> sep(seperators.c_str());
typedef boost::tokenizer<boost::char_separator<char> > Tokenizer_t;
Tokenizer_t tokenizer(input, sep);
for (auto& token : tokenizer) {
tokens.push_back(token);
}
return tokens;
}
//--------------------------------------------------------------------------
// Format vector of floats as string
//--------------------------------------------------------------------------
std::string BPhysBlindingTool::vecToString(const std::vector<float>& v)
const {
std::string str("[");
for (unsigned int i=0; i<v.size(); ++i) {
str += std::to_string(v[i]);
if ( i < v.size()-1 ) str += ",";
}
str += "]";
return str;
}
//--------------------------------------------------------------------------
// Format vector of bools as string
//--------------------------------------------------------------------------
std::string BPhysBlindingTool::vecToString(const std::vector<bool>& v)
const {
std::string str("[");
for (unsigned int i=0; i<v.size(); ++i) {
str += std::to_string(v[i]);
if ( i < v.size()-1 ) str += ",";
}
str += "]";
return str;
}
//--------------------------------------------------------------------------
} // namespace xAOD
This diff is collapsed.
/*
Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
*/
// system include:
#include <climits>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <cmath>
// ROOT includes
#include <TString.h>
// Local include(s):
#include "BPhysTools/SimpleEncrypter.h"
namespace xAOD {
//--------------------------------------------------------------------------
// Private static constants
//--------------------------------------------------------------------------
const SimpleEncrypter::ULLI_t SimpleEncrypter::m_MAXRANGE =
(SimpleEncrypter::ULLI_t)pow(std::numeric_limits<ULLI_t>::max(), 0.25);
const SimpleEncrypter::ULLI_t SimpleEncrypter::m_MINRANGE =
(SimpleEncrypter::ULLI_t)SimpleEncrypter::m_MAXRANGE/10;
const unsigned int SimpleEncrypter::m_MAXHEXDIGITS =
(unsigned int)(log(pow(SimpleEncrypter::m_MAXRANGE,2))/log(16.))+3;
//--------------------------------------------------------------------------
// Public methods
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
SimpleEncrypter::SimpleEncrypter(const std::string& name) :
asg::AsgMessaging(name), m_n(0), m_e(0), m_d(0),
m_isOkForEnc(false), m_isOkForDec(false) {
// initialize random number generator
srand(static_cast<unsigned>(time(0)));
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
SimpleEncrypter::~SimpleEncrypter() {
}
//--------------------------------------------------------------------------
// Generation of key pair as pair of hex strings
//--------------------------------------------------------------------------
std::pair<std::string, std::string> SimpleEncrypter::genKeyPair() {
// default preset
std::pair<std::string, std::string> keys =
std::make_pair("__NO_PRIV_KEY__", "__NO_PUB_KEY__");
// generate keys
genKeyPairInternal();
if ( isOkForEnc() && isOkForDec() ) {
keys = std::make_pair(getPrivKey(), getPubKey());
}
return keys;
}
//--------------------------------------------------------------------------
// Set private key
//--------------------------------------------------------------------------
void SimpleEncrypter::setPrivKey(std::string keystr) {
std::pair<ULLI_t, ULLI_t> keys = decodeKeyString(keystr);
if ( m_n > 0 && m_n != keys.first ) {
ATH_MSG_WARNING("RSA module already set!");
}
m_n = keys.first;
m_d = keys.second;
m_isOkForDec = false;
}
//--------------------------------------------------------------------------
// Set public key
//--------------------------------------------------------------------------
void SimpleEncrypter::setPubKey(std::string keystr) {
std::pair<ULLI_t, ULLI_t> keys = decodeKeyString(keystr);
if ( m_n > 0 && m_n != keys.second ) {
ATH_MSG_WARNING("RSA module already set!");
}
m_e = keys.first;
m_n = keys.second;
m_isOkForEnc = false;
}
//--------------------------------------------------------------------------
// Get private key
//--------------------------------------------------------------------------
std::string SimpleEncrypter::getPrivKey() const {
return keyToString(m_n, m_d);
}
//--------------------------------------------------------------------------
// Get public key
//--------------------------------------------------------------------------
std::string SimpleEncrypter::getPubKey() const {
return keyToString(m_e, m_n);
}
//--------------------------------------------------------------------------
// Encrypt unsigned integer value
//--------------------------------------------------------------------------
SimpleEncrypter::ULLI_t SimpleEncrypter::encrypt(ULLI_t a) {
ULLI_t b = a;
if ( isOkForEnc() ) {
b = encryptFPECycle(a);
}
return b;
}
//--------------------------------------------------------------------------
// Decrypt unsigned integer value
//--------------------------------------------------------------------------
SimpleEncrypter::ULLI_t SimpleEncrypter::decrypt(ULLI_t a) {
ULLI_t b = a;
if ( isOkForDec() ) {
b = decryptFPECycle(a);
}
return b;
}
//--------------------------------------------------------------------------
// Encrypt positive float value
//--------------------------------------------------------------------------
float SimpleEncrypter::encrypt(float a) {
float b = a;
if ( a > 0. ) {
if ( isOkForEnc() ) {
ULLI_t ia = floatBitsToInt(a);
ULLI_t ib = encryptFPECycle(ia);
b = intBitsToFloat(ib);
}
} else {
ATH_MSG_WARNING("Encrypt: Float value not positive: "
<< a << Form(" (%a) !", a));
} // if a > 0
return b;
}
//--------------------------------------------------------------------------
// Decrypt positive float value
//--------------------------------------------------------------------------
float SimpleEncrypter::decrypt(float a) {
float b = a;
// As nan is a valid encrypted value, decrypt it as well.
if ( a > 0. || std::isnan(a) ) {
if ( isOkForDec() ) {
ULLI_t ia = floatBitsToInt(a);
ULLI_t ib = decryptFPECycle(ia);
b = intBitsToFloat(ib);
}
} else {
ATH_MSG_WARNING("Decrypt: Float value not positive: "
<< a << Form(" (%a) !", a));
} // if a > 0
return b;
}
//--------------------------------------------------------------------------
// Private methods
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Generate numeric representation of the keys
//--------------------------------------------------------------------------
void SimpleEncrypter::genKeyPairInternal() {
// Generate prime numbers p != q
ULLI_t p(1);
ULLI_t q(1);
// Euler's phi function
ULLI_t phi(1);
// reset encryption and decryption exponent
m_e = 0;
m_d = 0;
while ( p == q || m_e < 2 || m_e >= phi || m_d < 2
|| m_e*m_d % phi != 1 ) {
double dlog2 = 0.;
while ( p == q || dlog2 < 0.1 || dlog2 > 30. ) {
p = genPrime();
q = genPrime();
dlog2 = fabs(log2(p)-log2(q));
} // inner while loop
phi = (p-1)*(q-1);
m_n = p*q;
m_e = genCoprime(phi);
m_d = genDecryptionExponent(phi, m_e);
} // outer while loop
m_isOkForDec = false;
m_isOkForEnc = false;
}
//--------------------------------------------------------------------------
// Find a prime number
//--------------------------------------------------------------------------
SimpleEncrypter::ULLI_t SimpleEncrypter::genPrime() const {
ULLI_t t = (m_MINRANGE + rand()) % (m_MAXRANGE-1);
do {
t++;
} while ( !isPrime(t) || t < m_MINRANGE );
return t;
}
//--------------------------------------------------------------------------
// Test for being a prime number
//--------------------------------------------------------------------------
bool SimpleEncrypter::isPrime(ULLI_t n) const {
bool isPrime = true;
if (n != 2) {
for (LLI_t i = 2; i < (LLI_t)sqrt(n) + 1; ++i) {
if (n % i == 0) {
isPrime = false;
break;
}
}
}
return isPrime;
}
//--------------------------------------------------------------------------
// Greatest common denominator
//--------------------------------------------------------------------------
SimpleEncrypter::ULLI_t
SimpleEncrypter::greatestCommonDenominator(ULLI_t n1, ULLI_t n2) const {
std::vector<LLI_t> r;
LLI_t i = 1;
r.push_back(std::max(n1, n2));
r.push_back(std::min(n1, n2));
while (r[i] != 0) {
++i;
r.push_back(r[i-2] % r[i-1]);
}
return r[i-1];
}
//--------------------------------------------------------------------------
// Find coprime number
//--------------------------------------------------------------------------
SimpleEncrypter::ULLI_t SimpleEncrypter::genCoprime(ULLI_t n) const {
// make sure coprime is larger than 5th Fermat number (2^16+1 = 65537)
ULLI_t i = (65537 + rand()) % (m_MAXRANGE -1);
do {
++i;
} while (greatestCommonDenominator(n, i) != 1);
return i;
}
//--------------------------------------------------------------------------
// Find decryption exponent
//--------------------------------------------------------------------------
SimpleEncrypter::ULLI_t
SimpleEncrypter::genDecryptionExponent(ULLI_t phi, ULLI_t e) const {
for (ULLI_t i=1; i<m_MAXRANGE; ++i) {
if ( ((phi * i + 1) % e) == 0 ) {
return (ULLI_t)((phi * i + 1) / e);
}
}
return 0;
}
//--------------------------------------------------------------------------
// Convert key to a hex string
//--------------------------------------------------------------------------
std::string SimpleEncrypter::keyToString(ULLI_t a, ULLI_t b) const {
// length of keys w.r.t. hex digits
unsigned int ra = (unsigned int)(log(a)/log(16.))+1;
unsigned int rb = (unsigned int)(log(b)/log(16.))+1;
// random numbers for padding
unsigned int r1 = rand() & ((1 << 4*(m_MAXHEXDIGITS-ra))-1);
unsigned int r2 = rand() & ((1 << 4*(m_MAXHEXDIGITS-rb))-1);
// format string
TString tstr = Form("%02x%02x%02x%0*x%0*llx%0*x%0*llx",
m_MAXHEXDIGITS, ra, rb,
m_MAXHEXDIGITS-ra, r1, ra, a,
m_MAXHEXDIGITS-rb, r2, rb, b);
return std::string(tstr.Data());
}
//--------------------------------------------------------------------------
// Convert hex string to two integers
//--------------------------------------------------------------------------
std::pair<SimpleEncrypter::ULLI_t, SimpleEncrypter::ULLI_t>
SimpleEncrypter::decodeKeyString(std::string hstr) const {
std::pair<ULLI_t, ULLI_t> keys(0,0);
TString str(hstr);
if (str.IsHex() && str.Length() > 3) {
str.ToLower();
unsigned int ndigits = strtoul(TString(str(0,2)).Data(), nullptr, 16);
unsigned int ra = strtoul(TString(str(2,2)).Data(), nullptr, 16);
unsigned int rb = strtoul(TString(str(4,2)).Data(), nullptr, 16);
if ( str.Length() == (int)(2*ndigits + 6) ) {
keys.first = strtoll(TString(str(ndigits+6-ra, ra)).Data(),
nullptr, 16);
keys.second = strtoll(TString(str(2*ndigits+6-rb, rb)).Data(),
nullptr, 16);
} else {
ATH_MSG_ERROR("Private/public key must be a hex string of " <<
2*m_MAXHEXDIGITS+6 << " digits!");
} // if Length()
} else {
ATH_MSG_ERROR("Private/public key must be a hex string of " <<
2*m_MAXHEXDIGITS+6 << " digits!");
} // if IsHex() ...
return keys;
}
//--------------------------------------------------------------------------
// Interpret bits of positive floating point number as integer
//--------------------------------------------------------------------------
SimpleEncrypter::ULLI_t SimpleEncrypter::floatBitsToInt(float val) const {
ULLI_t res(0);
if ( val < 0. ) {
ATH_MSG_ERROR("Float value needs to be positive!");
} else {
// convert floating point number to ULLI_t if size fits
if ( sizeof(float) <= sizeof(ULLI_t) ) {
// check whether a quick conversion is possible
if ( sizeof(float) == sizeof(int) ) {
int* p = reinterpret_cast<int*>(&val);
res = *p;
} else {
// do a slow conversion
char* pval = reinterpret_cast<char*>(&val);
// loop over bytes
for (unsigned int i=0; i<sizeof(float); ++i) {
// loop over bits
for (unsigned int j=0; j<CHAR_BIT; ++j) {
unsigned int n = i*CHAR_BIT + j;
unsigned int bit = (*(pval+i) >> j) & 1;
if ( bit > 0 ) res |= 1 << n;
} // for bits
} // for bytes
} // if sizeof
} else {
ATH_MSG_ERROR("sizeof(float) > sizeof(ULLI_t): "
<< sizeof(float) << " > " << sizeof(LLI_t));
} // if sizeof
} // if val < 0.
return res;
}
//--------------------------------------------------------------------------
// Interpret bits of positive integer as floating point number
//--------------------------------------------------------------------------
float SimpleEncrypter::intBitsToFloat(ULLI_t val) const {
float res(0.);
// number of bits needed
unsigned int r = (int)(std::log2(val))+1;
// convert ULLI_t to floating point number if size fits
if ( sizeof(float)*CHAR_BIT >= r ) {
// check whether a quick conversion is possible
if ( sizeof(float) == sizeof(int) ) {
float* p = reinterpret_cast<float*>(&val);
res = *p;
} else {
// do a slow conversion
char* pres = reinterpret_cast<char*>(&res);
// loop over bytes
for (unsigned int i=0; i<sizeof(float); ++i) {
// loop over bits
for (unsigned int j=0; j<CHAR_BIT; ++j) {
unsigned int n = i*CHAR_BIT + j;
unsigned int bit = (val >> n) & 1;
if ( bit > 0 ) *(pres+i) |= 1 << j;
} // for bits
} // for bytes
} // if sizeof
} else {
ATH_MSG_WARNING("sizeof(float)*CHAR_BIT < r: "
<< sizeof(float)*CHAR_BIT << " < " << r);
} // if sizeof
return res;
}
//--------------------------------------------------------------------------
// Encrypt using format preserving encryption w.r.t. RSA modulus
// via cycling
//--------------------------------------------------------------------------
SimpleEncrypter::ULLI_t SimpleEncrypter::encryptFPECycle(ULLI_t a) const {
ULLI_t enc = 0;
if ( a > 0 ) {
ULLI_t r = (int)(std::log2(m_n));
ULLI_t rmask = pow(2,r)-1;
ULLI_t c = a & rmask;
ULLI_t b = a - c;
do {
c = encryptInternal(c);
} while ( c > rmask );
enc = b + c;
} // if
return enc;
}
//--------------------------------------------------------------------------
// Decrypt using format preserving encryption w.r.t. RSA modulus
// via cycling
//--------------------------------------------------------------------------
SimpleEncrypter::ULLI_t SimpleEncrypter::decryptFPECycle(ULLI_t enc) const {
ULLI_t dec = 0;
if ( enc > 0 ) {
ULLI_t r = (int)(std::log2(m_n));
ULLI_t rmask = pow(2,r)-1;
ULLI_t d = enc & rmask;
ULLI_t b = enc - d;
do {
d = decryptInternal(d);
} while ( d > rmask );
dec = d + b;
} // if
return dec;
}
//--------------------------------------------------------------------------
// Encrypt integer
//--------------------------------------------------------------------------
SimpleEncrypter::ULLI_t SimpleEncrypter::encryptInternal(ULLI_t x) const {
return powerMod(x, m_e, m_n);
}
//--------------------------------------------------------------------------
// Decrypt integer
//--------------------------------------------------------------------------
SimpleEncrypter::ULLI_t SimpleEncrypter::decryptInternal(ULLI_t x) const {
return powerMod(x, m_d, m_n);
}
//--------------------------------------------------------------------------
// Exponentiate a with d observing modulus n
//--------------------------------------------------------------------------
SimpleEncrypter::ULLI_t
SimpleEncrypter::powerMod(ULLI_t a, ULLI_t d, ULLI_t n) const {
int bin[sizeof(ULLI_t)*CHAR_BIT];
ULLI_t dec[sizeof(ULLI_t)*CHAR_BIT];
ULLI_t r = (ULLI_t)(std::log2(d))+1;
ULLI_t tmp = d;
// decompose exponent into binary number (reverse order!)
for (ULLI_t i=0; i < r; ++i) {
bin[r-i-1] = tmp % 2;
tmp = (LLI_t)(tmp/2);
} // for i
// perform the exponentiation taking modulus into account
dec[0] = a;
for (ULLI_t i=1; i < r; ++i) {
ULLI_t d2 = dec[i-1]*dec[i-1] % n;
if ( bin[i] > 0 ) d2 *= a;
dec[i] = d2 % n;
} // for i
return dec[r-1];
}
//--------------------------------------------------------------------------
// Check setup readiness for encryption
//--------------------------------------------------------------------------
bool SimpleEncrypter::isOkForEnc() {
if ( !m_isOkForEnc ) {
if ( m_n > 0 && m_e > 1 && m_e < m_n ) {
m_isOkForEnc = true;
} else {
ATH_MSG_ERROR("Setup not OK for encryption: public key set?");
}
} // if ! m_isOkForEnc
return m_isOkForEnc;
}
//--------------------------------------------------------------------------
// Check setup readiness for decryption
//--------------------------------------------------------------------------
bool SimpleEncrypter::isOkForDec() {
if ( !m_isOkForDec ) {
if ( m_n > 0 && m_d > 1 && m_d < m_n ) {
m_isOkForDec = true;
} else {
ATH_MSG_ERROR("Setup not OK for decryption: private key set?");
}
} // if ! m_isOkForDec
return m_isOkForDec;
}
//--------------------------------------------------------------------------
} // namespace xAOD
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
/**
* @file creteBlindingKeys.cxx
* @author Wolfgang Walkowiak <Wolfgang.Walkowiak@cern.ch>
*
* @brief Utility to create a set of blinding keys
*
* @param[in] option: -c : perform a quick encoding/decoding check
*/
// system includes:
#include <iostream>
#include <iomanip>
#include <set>
#include <string>
#include <cstdlib>
#include <ctime>
// Local include(s):
#include "BPhysTools/SimpleEncrypter.h"
int main(int argc, char* argv[]) {
// Enable check (-c flag)
bool doCheck(false);
int nChecks(1);
if ( argc > 1 ) {
std::string arg(argv[1]);
if ( arg == "-c" ) doCheck = true;
}
if ( argc > 2 ) {
nChecks = atoi(argv[2]);
}
// Helper object
xAOD::SimpleEncrypter senc;
// Create key pair
std::pair<std::string, std::string> keys = senc.genKeyPair();
std::cout << std::endl;
std::cout << "Blinding keys generated:" << std::endl;
std::cout << " Private key: " << keys.first << std::endl;
std::cout << " Public key: " << keys.second << std::endl;
std::cout << std::endl;
// check that encryption works
if ( doCheck ) {
srand(static_cast<unsigned>(time(0)));
std::cout << "Encryption test:" << std::endl;
int nOK(0);
for (int i=0; i<nChecks; ++i) {
float val = 10000.*
static_cast <float>(rand())/(static_cast <float> (RAND_MAX));
// float val = 5267.23;
float enc = senc.encrypt(val);
float dec = senc.decrypt(enc);
if ( dec == val ) ++nOK;
if ( i == 0 || dec != val ) {
std::cout << " Test # " << i << std::endl;
std::cout << " val = " << val << std::endl;
std::cout << " enc = " << enc << std::endl;
std::cout << " dec = " << dec << std::endl;
if ( dec == val ) {
std::cout << " => worked!" << std::endl;
} else {
std::cout << " => FAILED!" << std::endl;
}
} // if
} // for
std::cout << std::endl;
std::cout << "Summary:" << std::endl;
std::cout << " nChecks: " << std::setw(12) << nChecks << std::endl;
std::cout << " nOK : " << std::setw(12) << nOK << std::endl;
std::cout << " nFailed: " << std::setw(12) << nChecks - nOK << std::endl;
} // if
exit(0);
}
# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
################################################################################
# Package: DerivationFrameworkBPhys
################################################################################
# Declare the package name:
atlas_subdir( DerivationFrameworkBPhys )
find_package( ROOT COMPONENTS Core MathCore )
# Component(s) in the package:
atlas_add_component( DerivationFrameworkBPhys
DerivationFrameworkBPhys/*.h src/*.cxx src/components/*.cxx
INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
LINK_LIBRARIES xAODMuon AthenaBaseComps JpsiUpsilonToolsLib
MuonSelectorToolsLib ${ROOT_LIBRARIES}
xAODTracking xAODBPhysLib AthenaKernel RecoToolInterfaces EventPrimitives
DerivationFrameworkInterfaces BPhysToolsLib TrackVertexAssociationToolLib
xAODBase xAODMetaData AsgTools CaloInterfaceLib TrackToCaloLib
xAODEventInfo AthenaPoolUtilities xAODPrimitives TrigDecisionToolLib
BeamSpotConditionsData TrkVertexAnalysisUtilsLib ITrackToVertex
InDetTrackSelectionToolLib InDetV0FinderLib)
# Install files from the package:
atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8})
atlas_install_joboptions( share/*.py )
/*
Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
*/
/**
* @file AugOriginalCounts.h
*
* @brief Augmentation with primary vertex counts (before thinning)
*/
#ifndef DERIVATIONFRAMEWORKBPHYS_AUGORIGINALCOUNTS_H
#define DERIVATIONFRAMEWORKBPHYS_AUGORIGINALCOUNTS_H
#include "DerivationFrameworkInterfaces/IAugmentationTool.h"
#include "AthenaBaseComps/AthAlgTool.h"
#include "StoreGate/WriteDecorHandleKey.h"
#include "xAODTracking/TrackParticleContainer.h"
#include "xAODTracking/VertexContainer.h"
#include "xAODEventInfo/EventInfo.h"
#include <string>
#include "AthenaBaseComps/AthAlgTool.h"
#include "DerivationFrameworkInterfaces/IAugmentationTool.h"
#include "xAODTracking/TrackParticleContainer.h"
#include "xAODTracking/VertexContainer.h"
#include <string>
#include "xAODEventInfo/EventInfo.h"
#include <StoreGate/WriteDecorHandleKey.h>
namespace DerivationFramework {
///
/// @class AugOriginalCounts
///
/// @brief Augmentation with primary vertex counts (before thinning)
///
/// This tool adds primary vertex counts and track counts
/// to the EventInfo container in order to preserve them in
/// case the primary vertex or track collections are thinned.
///
/// ### Job options
/// <table border="0">
/// <tr><th align="left">Name</td>
/// <th align="left">Description</th></tr>
/// <tr><td>TrackContainer</td>
/// <td>name of the TrackParticle container to be used</td>
/// </tr>
/// <tr><td>VertexContainer</td>
/// <td>name of the Vertex container to be used</td>
/// </tr>
/// <tr><td>AddPVCountsByType</td>
/// <td>add PV counts by PV type (default: false)</td>
/// </td>
/// </table>
///
class AugOriginalCounts : public AthAlgTool, public IAugmentationTool {
public:
/// @brief Main constructor
AugOriginalCounts(const std::string& t, const std::string& n,
const IInterface* p);
/// @brief Main method called for each event
virtual StatusCode addBranches() const override;
virtual StatusCode initialize() override;
private:
///
/// @name job options
/// @{
SG::WriteDecorHandleKey<xAOD::EventInfo> m_OrigPVNTracks{this, "DO_NOT_SET1", "", "internal property"};
SG::WriteDecorHandleKey<xAOD::EventInfo> m_OrigNTracksKeys{this, "DO_NOT_SET2", "", "internal property"};
SG::WriteDecorHandleKey<xAOD::EventInfo> m_OrigNtype0{this, "DO_NOT_SET3", "", "internal property"};
SG::WriteDecorHandleKey<xAOD::EventInfo> m_OrigNtype1{this, "DO_NOT_SET4", "", "internal property"};
SG::WriteDecorHandleKey<xAOD::EventInfo> m_OrigNtype2{this, "DO_NOT_SET5", "", "internal property"};
SG::WriteDecorHandleKey<xAOD::EventInfo> m_OrigNtype3{this, "DO_NOT_SET6", "", "internal property"};
SG::WriteDecorHandleKey<xAOD::EventInfo> m_OrigNtypeUnknown{this, "DO_NOT_SET7", "", "internal property"};
SG::WriteDecorHandleKey<xAOD::VertexContainer> m_OrigSqrtPt2Sum{this, "DO_NOT_SET8", "", "internal property"};
SG::WriteDecorHandleKey<xAOD::VertexContainer> m_d_nPVTracks{this, "DO_NOT_SET9", "", "internal property"};
SG::ReadHandleKey<xAOD::TrackParticleContainer> m_TrackContainername;
SG::ReadHandleKey<xAOD::VertexContainer> m_PVContainername;
bool m_addPVCountsByType;
bool m_addNTracksToPVs;
bool m_addSqrtPt2SumToPVs;
/// @}
};
}
#endif // DERIVATIONFRAMEWORKBPHYS_AUGORIGINALCOUNTS_H
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
//============================================================================
// BMuonTrackIsoTool.h
//============================================================================
//
// Author : Wolfgang Walkowiak <Wolfgang.Walkowiak@cern.ch.>
// Changes:
//
// Add muon track isolation information for different configurations,
// different track selections and different PV-to-SV association methods.
//
// For an usage example see BPHY8.py .
//
//============================================================================
//
#ifndef DERIVATIONFRAMEWORK_BMuonTrackIsoTool_H
#define DERIVATIONFRAMEWORK_BMuonTrackIsoTool_H
#include "DerivationFrameworkBPhys/BPhysVertexTrackBase.h"
#include "xAODMuon/MuonContainer.h"
#include "boost/multi_array.hpp"
namespace InDet {
class IInDetTrackSelectionTool;
}
namespace DerivationFramework {
class BMuonTrackIsoTool : virtual public BPhysVertexTrackBase {
private:
typedef BPhysVertexTrackBase super;
//
// internal helper class
//
protected:
class MuIsoItem : public BaseItem {
public:
MuIsoItem(std::string Name="_none_", std::string Bname="muiso",
std::string Prefix="");
virtual ~MuIsoItem();
virtual void resetVals();
virtual void copyVals(const BaseItem& item);
virtual void copyVals(const MuIsoItem& item);
virtual void fill(double isoValue=-2., int nTracks=-1,
const xAOD::Muon* muon=NULL);
virtual std::string muIsoName();
virtual std::string nTracksName();
virtual std::string muLinkName();
public:
mutable std::vector<float> vIsoValues;
mutable std::vector<int> vNTracks;
mutable MuonBag vMuons;
}; // MuIsoItem
public:
BMuonTrackIsoTool(const std::string& t, const std::string& n,
const IInterface* p);
protected:
// Hook methods
virtual StatusCode initializeHook();
virtual StatusCode finalizeHook();
virtual StatusCode addBranchesVCSetupHook(size_t ivc) const;
virtual StatusCode addBranchesSVLoopHook(const xAOD::Vertex* vtx) const;
virtual StatusCode calcValuesHook(const xAOD::Vertex* vtx,
const unsigned int ipv,
const unsigned int its,
const unsigned int itt) const;
virtual bool fastFillHook(const xAOD::Vertex* vtx,
const int ipv) const;
private:
virtual StatusCode saveIsolation(const xAOD::Vertex* vtx) const;
virtual void initResults();
virtual void setResultsPrefix(std::string prefix) const;
virtual std::string buildBranchName(unsigned int ic,
unsigned int its,
unsigned int ipv,
unsigned int itt) const;
private:
// job options
std::string m_muonContainerName;
std::vector<double> m_isoConeSizes;
std::vector<double> m_isoTrkImpLogChi2Max;
std::vector<int> m_isoDoTrkImpLogChi2Cut;
// containers
mutable const xAOD::MuonContainer* m_muons;
// results array
typedef boost::multi_array<MuIsoItem, 4> MuIsoItem4_t;
mutable MuIsoItem4_t m_results;
}; // BMuonTrackIsoTool
} // namespace
#endif // DERIVATIONFRAMEWORK_BMuonTrackIsoTool_H
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
/**
* @file BPhysAddMuonBasedInvMass.h
* @author Wolfgang Walkowiak <wolfgang.walkowiak@cern.ch>
*
* @brief Augmentation with muon-information based invariant mass.
*
*/
//
#ifndef DERIVATIONFRAMEWORK_BPhysAddMuonBasedInvMass_H
#define DERIVATIONFRAMEWORK_BPhysAddMuonBasedInvMass_H
#include <string>
#include <vector>
#include <set>
#include <map>
#include "AthenaBaseComps/AthAlgTool.h"
#include "DerivationFrameworkInterfaces/IAugmentationTool.h"
#include "GaudiKernel/ToolHandle.h"
#include "xAODBPhys/BPhysHelper.h"
#include "EventPrimitives/EventPrimitives.h"
#include "ITrackToVertex/ITrackToVertex.h"
namespace DerivationFramework {
//
// typedefs -- to abbreviate long lines
//
typedef std::vector<const xAOD::TrackParticle*> TrackBag;
typedef std::vector<const xAOD::Muon*> MuonBag;
///
/// @class BPhysAddMuonBasedInvMass
/// @author Wolfgang Walkowiak <wolfgang.walkowiak@cern.ch>
///
/// @brief Augment secondary vertices with muon-information-based mass.
///
/// Add muon-information based invarient mass to secondary vertices using
/// a four vector sum. Optionally, it also calculates the minimum
/// chi2 for all muon tracks of the secondary vertex candidate w.r.t.
/// any primary vertex matching the selection criteria.
///
/// ### Job options provided by this class:
/// <table border="0">
/// <tr><th align="left">Name</th>
/// <th align="left">Description</th>
/// </tr>
/// <tr><td>BranchPrefix</td>
/// <td>assign the prefix of added branches
/// (possibly the derivation format's name)</td>
/// </tr>
/// <tr><td>VertexContainerName</td>
/// <td>name of container for vertices</td>
/// </tr>
/// <tr><td>TrkMasses</td>
/// <td>ordered list of track masses
/// (Important to keep proper order: J/psi muons go first!)</td>
/// </tr>
/// <tr><td>TrackToVertexTool</td>
/// <td>ToolHandle for track-to-vertex tool</td>
/// </tr>
/// <tr><td>AdjustToMuonKinematics</td>
/// <td>Adjust the primary track particle's kinematics to the one of
/// the muon.</td>
/// </tr>
/// <tr><td valign="top">AddMinChi2ToAnyPVMode</td>
/// <td>mode of minLogChi2ToAnyPV calculation: (default: 0)
/// <table border="0">
/// <tr><th align="left">Value</th>
/// <th align="left">Explanation<th></tr>
/// <tr><td> 0 </td><td>no such calculation</td></tr>
/// <tr><td> 1 </td><td>use all PVs of requested
/// type(s)</td></tr>
/// <tr><td> 2 </td><td>exclude PVs associated to SVs</td></tr>
/// <tr><td> 3 </td><td>replace PVs associated to SVs by
/// corresponding refitted PVs</td></tr>
/// </table></td>
/// </tr>
/// <tr><td>PrimaryVertexContainerName</td>
/// <td>name of container for primary vertices</td>
/// </tr>
/// <tr><td>MinNTracksInPV</td>
/// <td>minimum number of tracks in PV
/// for PV to be considered in calculation
/// of minChi2MuToAnyPV variable.</td>
/// </tr>
/// <tr><td>PVTypesToConsider</td>
/// <td>list of primary vertex types to consider
/// (default: {1, 3})</td>
/// </tr>
/// <tr><td>DoVertexType</td>
/// <td>PV-to-SV association types to be considered (bitwise variable,
/// see xAODBPhys::BPhysHelper)<br>
/// Note: only needed for AddMinChi2ToAnyPVMode > 1</td>
/// </tr>
/// </table>
///
/// @note
///
/// For a usage example see BPHY8.py .
///
class BPhysAddMuonBasedInvMass : virtual public AthAlgTool,
virtual public IAugmentationTool {
public:
///
/// @brief Main contructor
///
BPhysAddMuonBasedInvMass(const std::string& t, const std::string& n,
const IInterface* p);
/// @brief Initialize augmentation tool.
virtual StatusCode initialize();
/// @brief Finalize augmentation tool.
virtual StatusCode finalize();
/// @brief Main method called for each event.
virtual StatusCode addBranches() const;
protected:
///
/// @name Internal protected methods
/// @{
///
/// @brief Calculate muon-information based mass values if available.
///
/// @param[in] vtx secondary vertex
/// @param[in] trkMasses ordered vector of track mass values
/// @param[in] nMuRequested number of muons requested
/// @returns muon-information based invariant mass for secondary
/// vertex and the corresponding uncertainty
///
std::pair<double, double> getMuCalcMass(xAOD::BPhysHelper& vtx,
std::vector<double>
trkMasses,
int nMuRequested) const;
///
/// @brief Obtain a set of tracks with muon track information if available
///
/// @param[in] vtx secondary vertex
/// @returns container of muon tracks, number of muons found
///
std::pair<TrackBag, int> getTracksWithMuons(xAOD::BPhysHelper& vtx) const;
///
/// @brief Calculate invariant mass and uncertainty from a set of tracks.
///
/// Returns invariant mass and mass error given
/// a set of tracks, their mass hypotheses and a reference position.
/// Each track must have a separate mass hypothesis in
/// the vector, and they must be in the same order as the tracks in the
/// track vector. Otherwise it will go horribly wrong.
///
/// @param[in] trksIn container with tracks to be considered
/// @param[in] massHypoTheses vector of mass hypotheses in the same
/// order as the tracks
/// @param[in] pos position of the vertex
/// @returns invariant mass value and uncertainty
///
std::pair<double,double>
getInvariantMassWithError(TrackBag trksIn,
std::vector<double> massHypotheses,
const Amg::Vector3D& pos) const;
///
/// @brief Determine minimum log chi2 of signal muon tracks w.r.t.
// any primary vertex.
///
/// Find minimum log chi2 distance of signal muons w.r.t any primary
/// vertex of required types and with a minimum number of tracks cut.
/// It also depends on the mode w.r.t. the treatment of the associated
/// primary vertex and the type of PV-to-SV association.
/// Returns this minimum chi2.
///
/// @param[in] vtx secondary vertex
/// @param[in] pvContainer container of primary vertices
/// @parma[in] pvtypes vector of primary vertex types to be considered
/// @param[in] minNTracksInPV minimum number of tracks in primary
/// vertex for it to be considered
/// @param[in] mode mode of operation (possible values: 0, 1, 2 ,3)
/// @param[in] pv_type type of PV-to-SV association
/// @returns minimum log chi2 = log(d0^2/d0e^+z0^2/z0e^2) w.r.t.
/// any primary vertex
///
double getMinChi2ToAnyPV(xAOD::BPhysHelper& vtx,
const xAOD::VertexContainer* pvContainer,
const std::vector<int>& pvtypes,
const int minNTracksInPV,
const int mode,
const xAOD::BPhysHelper::pv_type&
pvAssocType) const;
///
/// @brief Calculate log chi2 value of a track w.r.t. a position.
///
/// Calculate the log chi2 ( = log((d0/d0e)^2+(z0/z0e)^2) contribution
/// of a track at the position closest to the given PV.
///
/// @param[in] track track considered
/// @param[in] pos position considered
/// @returns log chi2 value
///
double getTrackPVChi2(const xAOD::TrackParticle& track,
const Amg::Vector3D& pos) const;
///
/// @brief Extract 3x3 momentum covariance matrix from a TrackParticle.
///
/// Extract the 3x3 momentum covariance matrix in (x,y,z) notation
/// from the (phi, theta, qoverp) notation from a TrackParticle.
///
/// @param[in] track TrackParticle considered
/// @returns 3x3 momentum covariance matrix
///
AmgSymMatrix(3) getMomentumCov(const xAOD::TrackParticle* track) const;
///
/// @brief Extract 3x3 momentum covariance matrix from a Perigee.
///
/// Extract the 3x3 momentum covariance matrix in (x,y,z) notation
/// from the (phi, theta, qoverp) notation from a Perigee.
///
/// @param[in] perigee Trk::Perigee considered
/// @returns 3x3 momentum covariance matrix
///
AmgSymMatrix(3) getMomentumCov(const Trk::Perigee* perigee) const;
///
/// @brief Extract 3x3 momentum covariance matrix from a track parameter
/// vector and 5x5 covariance matrix.
///
/// Extract the 3x3 momentum covariance matrix in (x,y,z) notation
/// from the (phi, theta, qoverp) notation from a vector of
/// track parameters and the 5x5 error matrix.
///
/// @param[in] pars 5-vector of track parameters
/// @param[in] cov 5x5 covariance matrix of track parameters
/// @returns 3x3 momentum covariance matrix
///
AmgSymMatrix(3) getMomentumCov(const AmgVector(5)& pars,
const AmgSymMatrix(5)& cov) const;
///
/// @brief Find all muons associated to secondary vertex.
///
/// Returns a vector of xAOD::Muon objects found
/// in this vertex and subsequent decay vertices.
/// Recursively calls itself if necessary.
///
/// @param[in] vtx secondary vertex
/// @returns container of muons found
///
MuonBag findAllMuonsInDecay(xAOD::BPhysHelper& vtx) const;
///
/// @brief Obtain a set of ID tracks for a set of muons.
///
/// @param[in] muons container of muon objects
/// @returns container of associated ID tracks
///
TrackBag getIdTracksForMuons(MuonBag& muons) const;
///
/// @brief Extract TrackParticle for Muon and adjust kinematics.
///
/// Extract primary track particle from muon;
/// if configured adjust pt, eta and phi of it before returning
/// a pointer to it.
///
/// @param[in] muon pointer to muon
/// @returns TrackParticle pointer
///
const xAOD::TrackParticle* adjustTrackParticle(const xAOD::Muon* muon)
const;
///
/// @brief Initialize PV-to-SV association type vector.
///
void initPvAssocTypeVec();
///
/// @brief Clear the cache of adjusted TrackParticles.
///
void clearAdjTpCache() const;
/// @}
private:
/// @name job options
/// @{
std::string m_branchPrefix;
std::string m_vertexContainerName;
std::vector<double> m_trkMasses;
ToolHandle<Reco::ITrackToVertex> m_trackToVertexTool;
bool m_adjustToMuonKinematics;
int m_addMinChi2ToAnyPVMode;
std::string m_pvContainerName;
int m_minNTracksInPV;
std::vector<int> m_pvTypesToConsider;
int m_doVertexType;
/// @}
///
/// map original -> adjusted track particles
typedef std::map<const xAOD::TrackParticle*, const xAOD::TrackParticle*>
TpMap_t;
/// map of adjusted track particles as cache
mutable TpMap_t m_adjTpCache;
/// cache for individual vertex types
std::vector<xAOD::BPhysHelper::pv_type> m_pvAssocTypes;
}; // class
} // namespace
#endif // DERIVATIONFRAMEWORK_BPhysAddMuonBasedInvMass_H
/*
Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
*/
///////////////////////////////////////////////////////////////////
// BPhysConversionFinder.h, (c) ATLAS Detector software
///////////////////////////////////////////////////////////////////
// Author: A. Chisholm <andrew.chisholm@cern.ch>
#ifndef DERIVATIONFRAMEWORK_BPHYSCONVERSIONFINDER_H
#define DERIVATIONFRAMEWORK_BPHYSCONVERSIONFINDER_H
#include <string>
#include "AthenaBaseComps/AthAlgTool.h"
#include "GaudiKernel/ToolHandle.h"
#include "DerivationFrameworkInterfaces/IAugmentationTool.h"
#include "InDetConversionFinderTools/VertexPointEstimator.h"
#include "InDetConversionFinderTools/ConversionPostSelector.h"
#include "TrkVertexSeedFinderUtils/ITrkDistanceFinder.h"
#include "TLorentzVector.h"
namespace Trk
{
class V0Tools;
class IVertexFitter;
class TrkVKalVrtFitter;
}
namespace InDet
{
class VertexPointEstimator;
class TrackPairsSelector;
class ConversionPostSelector;
}
namespace DerivationFramework {
class BPhysConversionFinder : public AthAlgTool, public IAugmentationTool {
public:
BPhysConversionFinder(const std::string& t, const std::string& n, const IInterface* p);
StatusCode initialize() override;
StatusCode finalize() override;
virtual StatusCode addBranches() const override;
private:
StatusCode doCascadeFit(const xAOD::Vertex * diMuonVertex, const xAOD::Vertex * convVertex, const double diMuonMassConstraint, TLorentzVector & fitMom, float & chiSq) const;
std::string m_diMuonCollectionToCheck;
std::vector<std::string> m_passFlagsToCheck;
ToolHandle <Trk::V0Tools> m_v0Tools;
ToolHandle <Trk::IVertexFitter> m_vertexFitter;
ToolHandle <InDet::VertexPointEstimator> m_vertexEstimator;
ToolHandle <Trk::ITrkDistanceFinder> m_distanceTool;
ToolHandle <InDet::ConversionPostSelector> m_postSelector;
ToolHandle <Trk::TrkVKalVrtFitter > m_cascadeFitter;
std::string m_inputTrackParticleContainerName;
std::string m_conversionContainerName;
float m_maxDistBetweenTracks;
float m_maxDeltaCotTheta;
bool m_requireDeltaM;
float m_maxDeltaM;
};
}
#endif // DERIVATIONFRAMEWORK_BPhysConversionFinder_H
/*
Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
*/
//============================================================================
// BPhysMetadataBase.h
//============================================================================
//
// Author : Wolfgang Walkowiak <Wolfgang.Walkowiak@cern.ch.>
// Changes:
// - w.w., 2017-01-22: Added use of BPhysMetaDataTool.
// - w.w., 2019-12-05: Added long and vector<long> types
//
// Store JO metadata in the output file.
//
// It uses the BPhysMetaDataTool (default) or the IOVDbMetaDataTool to
// store job option information as metadata in a specific branch whose
// name needs to prefixed by the deriviation format name.
// Note: Metadata stored by the IOVDbMetaDataTool is not readable on
// 'RootCore' level.
//
// This is a base class. Inherit from it to add the job options you want
// to store. For a usage example, see
// Bmumu_metadata.h / Bmumu_metadata.cxx
// and
// BPHY8.py .
//
//============================================================================
//
#ifndef DERIVATIONFRAMEWORK_BPhysMetadataBase_H
#define DERIVATIONFRAMEWORK_BPhysMetadataBase_H
#include <string>
#include <map>
#include <vector>
#include "AthenaBaseComps/AthAlgTool.h"
#include "DerivationFrameworkInterfaces/IAugmentationTool.h"
#include "GaudiKernel/ToolHandle.h"
namespace DerivationFramework {
class BPhysMetadataBase : virtual public AthAlgTool,
virtual public IAugmentationTool {
public:
BPhysMetadataBase(const std::string& t, const std::string& n,
const IInterface* p);
virtual StatusCode initialize();
virtual StatusCode finalize();
virtual StatusCode addBranches() const;
protected:
virtual void recordPropertyI(const std::string& name, int val);
virtual void recordPropertyL(const std::string& name, long val);
virtual void recordPropertyD(const std::string& name, double val);
virtual void recordPropertyB(const std::string& name, bool val);
virtual void recordPropertyS(const std::string& name, const std::string& val);
virtual void recordPropertyVI(const std::string& name, const std::vector<int>& val);
virtual void recordPropertyVL(const std::string& name, const std::vector<long>& val);
virtual void recordPropertyVD(const std::string& name, const std::vector<double>& val);
virtual void recordPropertyVB(const std::string& name, const std::vector<bool>& val);
virtual void recordPropertyVS(const std::string& name,
const std::vector<std::string>& val);
private:
virtual StatusCode saveMetaDataBPhys() const;
virtual std::string buildFolderName(const std::string& fname="") const;
virtual std::string vecToString(const std::vector<int>& v) const;
virtual std::string vecToString(const std::vector<long>& v) const;
virtual std::string vecToString(const std::vector<double>& v) const;
virtual std::string vecToString(const std::vector<bool>& v) const;
virtual std::string vecToString(const std::vector<std::string>& v) const;
private:
/// Object accessing the output metadata store
mutable ServiceHandle< StoreGateSvc > m_outputMetaStore;
// job options
std::string m_derivationName;
std::string m_mdFolderName;
std::string m_prefix;
// maps for different types of JOs
std::map<std::string, int> m_propInt;
std::map<std::string, long> m_propLong;
std::map<std::string, double> m_propDouble;
std::map<std::string, bool> m_propBool;
std::map<std::string, std::string> m_propString;
std::map<std::string, std::vector<int> > m_propVInt;
std::map<std::string, std::vector<long> > m_propVLong;
std::map<std::string, std::vector<double> > m_propVDouble;
std::map<std::string, std::vector<bool> > m_propVBool;
std::map<std::string, std::vector<std::string> > m_propVString;
}; // class
} // namespace
#endif // DERIVATIONFRAMEWORK_BPhysMetadataBase_H
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef DERIVATIONFRAMEWORK_PVCASCADETOOLS_H
#define DERIVATIONFRAMEWORK_PVCASCADETOOLS_H
#include "GaudiKernel/ToolHandle.h"
#include "xAODBPhys/BPhysHypoHelper.h"
#include "DerivationFrameworkBPhys/CascadeTools.h"
#include "EventKernel/PdtPdg.h"
#include <vector>
// Authors: Adam Barton <abarton@SPAMMENOTTtttcern.ch>
// Eva Bouhova <bouhova@SPAMMENOTTtttcern.ch>
//class CascadeTools;
namespace Trk {
class V0Tools;
class VxCascadeInfo;
}
namespace Analysis{
class PrimaryVertexRefitter;
}
namespace InDet{
class BeamSpotData;
}
namespace HepPDT{
class ParticleDataTable;
}
namespace DerivationFramework {
class BPhysPVCascadeTools {
typedef ElementLink<xAOD::VertexContainer> VertexLink;
typedef std::vector<VertexLink> VertexLinkVector;
private:
const Trk::V0Tools *m_v0Tools;
const CascadeTools *m_cascadeTools;
const InDet::BeamSpotData *m_beamSpotData;
/// minimum number of tracks required in PVs considered
size_t m_PV_minNTracks;
public:
bool m_copyAllVertices;
BPhysPVCascadeTools(const CascadeTools *cascadeTools);
BPhysPVCascadeTools(const CascadeTools *cascadeTools,
const InDet::BeamSpotData*);
void ProcessVertex(const std::vector<TLorentzVector> &mom, Amg::MatrixX cov, xAOD::BPhysHypoHelper &vtx, xAOD::BPhysHelper::pv_type pvtype, double mass) const;
static void FillBPhysHelperNULL(xAOD::BPhysHelper &vtx, const xAOD::VertexContainer* PvContainer,
xAOD::BPhysHelper::pv_type pvtype);
///Fills the BPhysHelper object with the standard parameters
void FillBPhysHelper(const std::vector<TLorentzVector> &mom, Amg::MatrixX cov, xAOD::BPhysHelper &vtx, const xAOD::Vertex* refPV,const xAOD::VertexContainer* refPvContainer,
xAOD::BPhysHelper::pv_type pvtype, int) const;
///Returns the index integer of the vertex with the lowest Z in relation to the given vertex
size_t FindLowZIndex(const std::vector<TLorentzVector> &mom, const xAOD::BPhysHelper &Obj,
const std::vector<const xAOD::Vertex*> &PVlist,
const size_t PV_minNTracks=0) const;
///Returns the index integer of the vertex with the lowest A0 in relation to the given vertex
size_t FindLowA0Index(const std::vector<TLorentzVector> &mom, const xAOD::BPhysHelper &Obj,
const std::vector<const xAOD::Vertex*> &PVlist,
const size_t PV_minNTracks=0) const;
static size_t FindHighPtIndex(const std::vector<const xAOD::Vertex*> &PVlist);
template< size_t NTracks> //NTracks = number of tracks in this type of vertex, if this is not known do not use this method
static bool VerticesMatchTracks(const xAOD::Vertex* v1, const xAOD::Vertex* v2);
template< size_t NTracks>
static const xAOD::Vertex* FindVertex(const xAOD::VertexContainer* c, const xAOD::Vertex* v);
/// Static method call with
/// DerivationFramework::BPhysDerHelpers::GetGoodPV
/// Returns a std::vector containing only PVs of type 1 and 3 - HighPt
/// and Pileup, which have at least PV_minNTracks tracks.
static std::vector<const xAOD::Vertex*> GetGoodPV(const xAOD::VertexContainer* pvContainer);
/// Set the minimum number of tracks required for primary vertices to be
/// considered for primary vertex association to a secondary vertex.
/// Note that this requirement will not be applied for finding
/// the vertex with the highest pT sum (FindHighPtIndex()) since
/// it would possibly exclude this vertex which has been marked
/// earlier in the tool chain.
void SetMinNTracksInPV(size_t PV_minNTracks);
/// Get the current beamspot position either from cache or from
/// BeamCondSvc.
/// Before processing a new event, make sure to call
/// GetBeamSpot();
[[nodiscard]] const Amg::Vector3D& GetBeamSpot() const noexcept;
/// Find the index for the PV with the lowest distance in z of
/// the SV's DOCA point w.r.t. the beamline and the PV.
size_t FindLowZ0BAIndex(const std::vector<TLorentzVector> &mom, const xAOD::BPhysHelper &obj,
const std::vector<const xAOD::Vertex*> &PVlist,
const size_t PV_minNTracks=0) const;
/// Calculate the distance along z axis between the PV and
/// SV's DOCA point w.r.t. the beamline.
double DistInZtoDOCA(const std::vector<TLorentzVector> &mom, const xAOD::BPhysHelper &obj,
const xAOD::Vertex* vertex) const;
/// Point of DOCA w.r.t. the beamline backward extrapolated
/// along the B candidate's momentum direction.
Amg::Vector3D DocaExtrapToBeamSpot(const std::vector<TLorentzVector> &mom, const xAOD::BPhysHelper &obj) const;
static void PrepareVertexLinks(Trk::VxCascadeInfo *result, const xAOD::TrackParticleContainer* importedTrackCollection);
StatusCode FillCandwithRefittedVertices( bool refitPV,
const xAOD::VertexContainer* pvContainer, xAOD::VertexContainer* refPvContainer,
const Analysis::PrimaryVertexRefitter *pvRefitter, size_t in_PV_max, int DoVertexType,
Trk::VxCascadeInfo* casc, int index,
double mass, xAOD::BPhysHypoHelper &vtx);
static std::vector<const xAOD::TrackParticle*> CollectAllChargedTracks(const std::vector<xAOD::Vertex*> &cascadeVertices);
static void SetVectorInfo(xAOD::BPhysHelper &, const Trk::VxCascadeInfo*);
static bool uniqueCollection(const std::vector<const xAOD::TrackParticle*>&);
static bool uniqueCollection(const std::vector<const xAOD::TrackParticle*>&, const std::vector<const xAOD::TrackParticle*>&);
static bool LinkVertices(SG::AuxElement::Decorator<VertexLinkVector> &decor, const std::vector<const xAOD::Vertex*>& vertices,
const xAOD::VertexContainer* vertexContainer, const xAOD::Vertex* vert);
static double getParticleMass(const HepPDT::ParticleDataTable* pdt, int pdg);
}; // class BPhysPVCascadeTools
} // namespace DerivationFramework
//added by ab
template< size_t NTracks>
bool DerivationFramework::BPhysPVCascadeTools::VerticesMatchTracks(const xAOD::Vertex* v1, const xAOD::Vertex* v2)
{
if(v1->nTrackParticles() != v2->nTrackParticles()) return false;
assert(v1->nTrackParticles() == NTracks);
std::array<const xAOD::TrackParticle*, NTracks> a1;
std::array<const xAOD::TrackParticle*, NTracks> a2;
for(size_t i=0;i<NTracks;i++){
a1[i] = v1->trackParticle(i);
a2[i] = v2->trackParticle(i);
}
std::sort(a1.begin(), a1.end());
std::sort(a2.begin(), a2.end());
return a1 == a2;
}
template< size_t NTracks>
const xAOD::Vertex* DerivationFramework::BPhysPVCascadeTools::FindVertex(const xAOD::VertexContainer* c, const xAOD::Vertex* v){
for (const xAOD::Vertex* a : *c){
if(VerticesMatchTracks<NTracks>(a,v)) return a;
}
return nullptr;
}
#endif // DERIVATIONFRAMEWORK_PVCASCADETOOLS_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment