Commit 25cbd296 authored by Attila Krasznahorkay's avatar Attila Krasznahorkay Committed by Graeme Stewart
Browse files

Fixing the compilation of SystematicsTool.cxx on MacOS X (PATInterfaces-00-00-11)

parent cd68522d
In the first iteration the base class just deals with section 5 of the
recommendation, i.e. how to configure tools for different systematics
configurations. It also doesn't yet implement the dual-use tool
recommendations and only compiles in RootCore (so far).
* I decided to give a little bit of structure to the names of
systematics, they now have the format of "basename__subvariation".
In this format "basename" identifies the actual nuisance parameter
involved, and subvariation contains the description of what level
of variation it is (i.e. the number of sigmas). Such a scheme
allows some generic processing of the systematics without diving
much into the interpretation of the systematics.
* I decided on a fixed scheme to indicate the number of sigmas of the
systematic variation. "1up" equals +1, "2down" equals -2,
"2down35" equals -2.35, etc. Among other things this allows to
have a seamless migration from discrete to continuous systematics.
It also allows to extract the numeric parameter value from the
systematics value automatically.
* The systematics are represented by the class SystematicVariation.
This allows to construct systematics in various ways, as well as
inspecting it in multiple ways as well. In particular it makes it
easy to pick a particular systematic from the list of systematics
and then ask for the nuisance parameter value.
* I moved a lot of the systematics handling into the actual tool base
class. Tools now register their affecting systematics with the
base class and the base class then takes the list of systematics
the user requests and filters it so that the tool has only to deal
with the list of systematics affecting it. This has a couple of
advantages:
* It is a lot easier for the tool to check for unsupported
combinations of affecting systematics. In the simplest case it
can just report UNSUPPORTED when there is more than one element
is in the list.
* It allows to move a lot of systematics handling code into the
base class, which allows to add more functionality as well. Most
significantly it maintains a list of all applied and affecting
systematics, which can be used for debugging purposes, e.g. in
the bookkeeping suggested in section 3.
* It allows the base class to perform a number of sanity checks on
the systematics before passing them on to the tool. See below
for the actual checks.
* As part of moving the generic systematics handling into the base
class by having the applySystematics method the user calls, and a
virtual sysApplySystematics method the tool defines. This allows
the applySystematics method to perform the systematics filtering
and checking mentioned above and then pass the filtered list to the
actual tool implementation.
* Besides the list of default systematics (which is defined but not
filled yet), I also defined a list of all known systematics that gets
automatically filled as tools register their affecting systematics.
This is mostly for sanity checks (see below).
* The base class now performs a number of sanity checks on the
systematics in applySystematics():
* It reports an error if the user requests multiple systematics
with the same basename. This is the canonical example of
requesting both the up and down variation simultaneously.
* It reports an error if the user requests a systematic that is not
registered as affecting, but the tool is affected by a tool with
the same basename as the systematic in question. This is to
catch the otherwise fairly hard to debug case that a tool only
implements +/-1 sigma variations, but the user requests +/-2
sigma variations.
* If a requested systematic is not in the global list of systematic
it is considered an error. This is to detect typos. Should the
user want to request systematics that no tool supports he will
have to add them to the global list manually.
* For the time being SystematicCode is simply a renamed copy of
StatusCode from EventLoop which is in turn derived from StatusCode
in Athena.
// Dear emacs, this is -*- c++ -*-
// $Id: CorrectionCode.h 600738 2014-06-07 14:34:05Z krasznaa $
#ifndef PATINTERFACES_CORRECTIONCODE_H
#define PATINTERFACES_CORRECTIONCODE_H
// Copyright Nils Krumnack 2012.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Please feel free to contact me (krumnack@iastate.edu) for bug
// reports, feature suggestions, praise and complaints.
namespace CP {
/// Return value from object correction CP tools
///
/// This class needs to be used in CP tools implementing object corrections
/// when they implement the interface described in:
/// https://cds.cern.ch/record/1667206
/// In short, all such CP tools should implement the two following functions:
///
/// <code>
/// CorrectionCode Tool::applyCorrection( xAODObjectType& inputObject );<br/>
/// CorrectionCode Tool::correctedCopy( const xAODObjectType& inputObject,<br/>
/// xAODObjectType*& outputObject );
/// </code>
///
/// @author Nils Krumnack <krumnack@iastate.edu>
/// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
///
/// $Revision: 600738 $
/// $Date: 2014-06-07 16:34:05 +0200 (Sat, 07 Jun 2014) $
///
class CorrectionCode {
public:
/// Possible values for the correction code
enum ErrorCode {
Error = 0, ///< Some error happened during the object correction
OutOfValidityRange = 1, ///< Input object is out of validity range
Ok = 2 ///< The correction was done successfully
};
/// Constructor with a correction code
CorrectionCode( ErrorCode code = Ok );
/// Copy constructor
CorrectionCode( const CorrectionCode& parent );
/// Destructor
~CorrectionCode();
/// Assignment operator
CorrectionCode& operator= ( const CorrectionCode& rhs );
/// The code stored internally
ErrorCode code() const;
/// Automatic conversion to the enumeration value
operator ErrorCode() const { return code(); }
/// Ordering operator. To make it possible to use this type as an
/// STL container key
bool operator < ( const CorrectionCode& rhs ) const {
return m_code < rhs.m_code;
}
/// Mark the correction code as checked, ignoring its value
void setChecked() const { m_checked = true; }
/// Ignore the correction code, marking it as checked
void ignore() const { setChecked(); }
/// Enable failure (with a backtrace) on an unchecked correction code
static void enableFailure();
/// Disable failure (no backtrace) on an unchecked correction code
static void disableFailure();
private:
ErrorCode m_code; ///< The stored correction code
mutable bool m_checked; ///< Checked status of the object
}; // class CorrectionCode
} // namespace CP
#endif // not PATINTERFACES_CORRECTIONCODE_H
// Dear emacs, this is -*- c++ -*-
// $Id: CorrectionTool.h 600738 2014-06-07 14:34:05Z krasznaa $
#ifndef PATINTERFACES_CORRECTIONTOOL_H
#define PATINTERFACES_CORRECTIONTOOL_H
// Copyright Iowa State University 2014.
// Author: Nils Krumnack
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Please feel free to contact me (nils.erik.krumnack@cern.ch) for bug
// reports, feature suggestions, praise and complaints.
// Local include(s):
#include "PATInterfaces/CorrectionCode.h"
namespace CP {
/// Helper base class for "correction tools"
///
/// This class is provided to make the coding of CP tools that apply some
/// modification to objects a little easier. The tool needs to provide a
/// separate, proper interface class. This class will just provide the
/// implementation of the functions defined in that interface. So the CP
/// tool itself will look like:
///
/// <code>
/// class MySmearingTool : public virtual IMySmearingTool,<br/>
/// public virtual CP::CorrectionTool< MyContainerType >,<br/>
/// public asg::AsgTool {<br/>
/// ...<br/>
/// };
/// </code>
///
/// The idea is that the user only needs to implement one function in the
/// final tool in order to implement the interface outlined in
/// https://cds.cern.ch/record/1667206
///
/// @author Nils Krumnack <krumnack@iastate.edu>
/// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
///
/// $Revision: 600738 $
/// $Date: 2014-06-07 16:34:05 +0200 (Sat, 07 Jun 2014) $
///
template< class T >
class CorrectionTool {
public:
/// description: the type of xAOD container used
typedef T xAODContainerType;
/// description: the type of xAOD object used
typedef typename xAODContainerType::base_value_type xAODObjectType;
/// effects: standard destructor
/// rationale: virtual destruct for base class
virtual ~CorrectionTool() {}
/// effects: apply the correction and store the output in the object
/// returns: success
virtual CorrectionCode
applyCorrection( xAODObjectType& inputObject ) = 0;
/// effects: make a clone of the input object, apply the
/// correction to it and store the output in the object
/// returns: success
/// rationale: the interface class provides a default
/// implementation in terms of applyCorrection, that the derived
/// classes can override for efficiency
CorrectionCode
correctedCopy( const xAODObjectType& inputObject,
xAODObjectType*& outputObject );
/// effects: apply the correction to all the members of the
/// container
/// returns: overall success
/// rationale: this will apply the correction to every single
/// member (even if some members fail)
/// rationale: the interface class provides a default
/// implementation in terms of applyCorrection, that the derived
/// classes can override for efficiency
CorrectionCode
applyContainerCorrection( xAODContainerType& inputContainer );
}; // class CorrectionTool
} // namespace CP
// Include the implementation:
#include "PATInterfaces/CorrectionTool.icc"
#endif // PATINTERFACES_CORRECTIONTOOL_H
// Dear emacs, this is -*- c++ -*-
// $Id: CorrectionTool.icc 600738 2014-06-07 14:34:05Z krasznaa $
#ifndef PATINTERFACES_CORRECTIONTOOL_ICC
#define PATINTERFACES_CORRECTIONTOOL_ICC
// Copyright Iowa State University 2014.
// Author: Nils Krumnack
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Please feel free to contact me (nils.erik.krumnack@cern.ch) for bug
// reports, feature suggestions, praise and complaints.
// System include(s):
#include <memory>
namespace CP {
template< class T >
CorrectionCode CorrectionTool< T >::
correctedCopy( const xAODObjectType& inputObject,
xAODObjectType*& outputObject ) {
// Choose a smart pointer type according to the standard used:
#if __cplusplus < 201100
std::auto_ptr< xAODObjectType > myobject( new xAODObjectType );
#else
std::unique_ptr< xAODObjectType > myobject( new xAODObjectType );
#endif // C++11
// Make a deep copy of the input object:
myobject->makePrivateStore( inputObject );
// Call the function implemented in the concrete tool:
CorrectionCode result = applyCorrection( *myobject );
if( result != CorrectionCode::Error ) {
outputObject = myobject.release();
}
return result;
}
template< class T >
CorrectionCode CorrectionTool< T >::
applyContainerCorrection( xAODContainerType& inputContainer ) {
// Loop over the container:
typename xAODContainerType::iterator itr = inputContainer.begin();
typename xAODContainerType::iterator end = inputContainer.end();
for( ; itr != end; ++itr ) {
// Apply the correction for this object:
CorrectionCode subresult = applyCorrection( **itr );
if( subresult == CorrectionCode::Error ) {
return subresult;
}
}
// We were successful:
return CorrectionCode::Ok;
}
} // namespace CP
#endif // PATINTERFACES_CORRECTIONTOOL_ICC
#ifndef PATINTERFACES_GLOBAL_H
#define PATINTERFACES_GLOBAL_H
// Copyright Iowa State University 2014.
// Author: Nils Krumnack
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Please feel free to contact me (nils.erik.krumnack@cern.ch) for bug
// reports, feature suggestions, praise and complaints.
// This module still needs to be documented. The interface provided
// in this module is intended for experts only. The module is
// considered to be in the pre-alpha stage.
namespace CP
{
class CorrectionCode;
template<class T> class ICorrectionTool;
class ISystematicsTool;
class SystematicCode;
class SystematicVariation;
class SystematicSet;
class SystematicsTool;
}
#endif
// Dear emacs, this is -*- c++ -*-
// $Id: ISystematicsTool.h 602616 2014-06-19 11:43:22Z krumnack $
#ifndef PATINTERFACES_ISYSTEMATICSTOOL_H
#define PATINTERFACES_ISYSTEMATICSTOOL_H
// Copyright Iowa State University 2014.
// Author: Nils Krumnack
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// System include(s):
// Framework include(s):
#include "AsgTools/IAsgTool.h"
// Local include(s):
#include "PATInterfaces/SystematicCode.h"
#include "PATInterfaces/SystematicVariation.h"
#include "PATInterfaces/SystematicSet.h"
namespace CP {
/// Interface for all CP tools supporting systematic variations
///
/// This interface is meant to be used by the systematics handling
/// system to configure different CP tools to change their behaviour
/// at runtime.
///
/// @author Nils Krumnack <nils.erik.krumnack@cern.ch>
/// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
///
/// $Revision: 602616 $
/// $Date: 2014-06-19 13:43:22 +0200 (Thu, 19 Jun 2014) $
///
class ISystematicsTool : public virtual asg::IAsgTool {
/// Declare the interface that this class provides
ASG_TOOL_INTERFACE( CP::ISystematicsTool )
public:
/// returns: whether this tool is affected by the given systematis
virtual bool
isAffectedBySystematic( const SystematicVariation& systematic ) const = 0;
/// returns: the list of all systematics this tool can be affected by
virtual SystematicSet
affectingSystematics() const = 0;
/// returns: the list of all systematics this tool recommends to use
virtual SystematicSet
recommendedSystematics() const = 0;
/// effects: configure this tool for the given list of systematic
/// variations. any requested systematics that are not
/// affecting this tool will be silently ignored (unless they
/// cause other errors).
/// failures: systematic unknown
/// failures: requesting multiple variations on the same
/// systematic (e.g. up & down)
/// failures: requesting an unsupported variation on an otherwise
/// supported systematic (e.g. a 2 sigma variation and the tool
/// only supports 1 sigma variations)
/// failures: unsupported combination of supported systematic
/// failures: other tool specific errors
///
virtual SystematicCode applySystematicVariation
( const SystematicSet& systConfig ) = 0;
}; // class ISystematicsTool
} // namespace CP
#endif // PATINTERFACES_ISYSTEMATICSTOOL_H
// Dear emacs, this is -*- c++ -*-
// $Id: SystematicCode.h 600738 2014-06-07 14:34:05Z krasznaa $
#ifndef PATINTERFACES_SYSTEMATICCODE_H
#define PATINTERFACES_SYSTEMATICCODE_H
// Copyright Nils Krumnack 2012.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Please feel free to contact me (krumnack@iastate.edu) for bug
// reports, feature suggestions, praise and complaints.
namespace CP {
/// Return value from CP tools supporting systematic variations
///
/// This class needs to be used in CP tools that support systematic
/// variations, and implement the interface described in:
/// https://cds.cern.ch/record/1667206
/// In short, all such CP tools should implement the two following functions:
///
/// <code>
/// SystematicCode Tool::applySystematicVariation(<br/>
/// const std::set< SystematicVariation >& systConfig );<br/>
/// bool Tool::isAffectedBySystematic( const SystematicVariation& s ) const;<br/>
/// std::set< SystematicVariation > Tool::affectingSystematics(<br/>
/// const std::set< SystematicVariation >& inputSystList ) const;
/// </code>
///
/// @author Nils Krumnack <krumnack@iastate.edu>
/// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
///
/// $Revision: 600738 $
/// $Date: 2014-06-07 16:34:05 +0200 (Sat, 07 Jun 2014) $
///
class SystematicCode {
public:
/// Possible values for the systematic code
enum ESysCode {
Unsupported = 0, ///< The requested systematic is not supported
Ok = 1 ///< The requested systematic will be applied
};
/// Constructor with the systematic code
SystematicCode( ESysCode code );
/// Copy constructor
SystematicCode( const SystematicCode& parent );
/// Destructor
~SystematicCode();
/// Assignment operator
SystematicCode& operator= ( const SystematicCode& rhs );
/// The code stored internally
ESysCode code() const;
/// Automatic conversion to the enumeration value
operator ESysCode() const { return code(); }
/// Ordering operator. To make it possible to use this type as an
/// STL container key
bool operator < ( const SystematicCode& rhs ) const {
return m_code < rhs.m_code;
}
/// Mark the correction code as checked, ignoring its value
void setChecked() const { m_checked = true; }
/// Ignore the correction code, marking it as checked
void ignore() const { setChecked(); }
/// Enable failure (with a backtrace) on an unchecked systematic code
static void enableFailure();
/// Disable failure (no backtrace) on an unchecked systematic code
static void disableFailure();
private:
ESysCode m_code; ///< The stored systematic code
mutable bool m_checked; ///< Checked status of the object
}; // class SystematicCode
} // namespace CP
#endif // PATINTERFACES_SYSTEMATICCODE_H
#ifndef PATINTERFACES_SYSTEMATIC_LIST_H
#define PATINTERFACES_SYSTEMATIC_LIST_H
// Copyright Iowa State University 2014.
// Author: Nils Krumnack
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Please feel free to contact me (nils.erik.krumnack@cern.ch) for bug
// reports, feature suggestions, praise and complaints.
// This module provides the global lists of systematics as well as
// some tools for working with lists of systematics. The interface
// provided in this module is intended for the general user. The
// module is considered to be in the pre-alpha stage.
#include <PATInterfaces/Global.h>
#include <PATInterfaces/SystematicVariation.h>
#include <set>
namespace CP
{
/// description: the list of all known systematics
typedef std::set<SystematicVariation> systematics_list_type;
systematics_list_type& systematics_list();
/// description: the list of all systematics that should be applied
/// by default
systematics_list_type& default_systematics();
/// returns: the given systematics configuration joined into a single string
/// guarantee: strong
/// failures: out of memory II
std::string
joinSystematicList (const std::set<SystematicVariation>& systConfig);
/// returns: the given systematics string split into individual
/// systematics
/// guarantee: strong
/// failures: out of memory II
std::set<SystematicVariation>
splitSystematicList (const std::string& systematics);
/// effects: filter the systematics for the affected systematics
/// returns: success
/// guarantee: strong
/// failures: out of memory II
/// failures: requesting a systematic that's not on the global list
/// failures: requesting multiple variations on the same systematic
/// (e.g. up & down)
/// failures: requesting an unsupported variation on an otherwise
/// supported systematic (e.g. a 2 sigma variation and the tool
/// only supports 1 sigma variations)
SystematicCode filterForAffectingSystematics
(const std::set<SystematicVariation>& systConfig,
const std::set<SystematicVariation>& affectingSystematics,
std::set<SystematicVariation>& filteredSystematics);
}
#endif