Writing Your Own Sandbox.EventView Tools
Setting Up Your Package for Sandbox.EventView
In order to write your own Sandbox.EventView tools, you need a packaged in which to develop your code. See
this page in the Computing Workbook to learn how to create your own package. You will need to add the following Sandbox.EventView related lines to your package's requirements file.
use EventViewBuilderUtils EventViewBuilderUtils-* PhysicsAnalysis/EventViewBuilder
private
macro genconfig_configurableModuleName "EventViewConfiguration.EventViewConfCore.EventViewToolLoopers"
macro genconfig_configurableAlgTool "GenericEventViewTool"
macro genconfig_configurableAlgorithm "EVToolLooperBase"
end_private
Back to top
Writing Your Own Event-level Sandbox.EventView Tool (EVTool)
After setting up Athena you should have the command
newEVTool
in your path. Change directories such that your current working directory is the root of your package (e.g
MyPackge/
), such that when you list the contents of the directory you get.
cmt/ MyPackage/ src/
Your package should also have a
src/components/MyPackage_entires.cxx
file.
Then one can call
newEVTool
by running
>> newEVTool EVMyTool
This command creates skeleton header and source files for your new tool,
MyPackage/EVMyTool.h
and
src/EVMyTool.cxx
. It is customary to prefix the name of your EV tools with
EV
. In the source file, you will see a constructor, a destructor,
initialize
,
finalize
, and
execute
methods, just like any other Athena algorithm. You should use the
execute(Sandbox.EventView* ev)
method that takes passes a pointer to the current Sandbox.EventView. In the constructor, you should put a
declareProperty
line for each configurable the user should control from the job options. For example, we will write a tool,
EVScaleMET
, that scales the missing transverse energy by some factor, configured by the user.
EVScaleMET::EVScaleMET(const std::string& type,
const std::string& name,
const IInterface* parent):
EventViewBaseTool(type, name, parent)
{
declareProperty("ScaleFactor", m_ScaleFactor=1.0); // double
declareProperty("MissingEx", m_MissingEx="MET_RefFinal_ex"); // std::string
declareProperty("MissingEy", m_MissingEy="MET_RefFinal_ey"); // std::string
declareProperty("MissingEt", m_MissingEt="MET_RefFinal_et"); // std::string
}
Next, you should write any code you want to tool do during initialization and finalization, and what to execute on each event. For this example, we only need to write the execute method. One can use the
ev
pointer to get access to anything in the current Sandbox.EventView. Here are some examples of the kinds of methods one can use:
-
ev->doubleUserData(a_label);
- gets a double with label a_label
from UD
-
ev->setDoubleUserData(a_label, a_double);
- stores a double with label a_label
in UD
-
std::vector<const INavigable4Momentum*>* particles = ev->finalStateObjects();
- gets a vector of pointers to all the final state objects in the Sandbox.EventView.
The Sandbox.EventView class provides several other methods for getting and storing UD, for accessing particles, and for checking a particle's labels. See the
Sandbox.EventView class definition
for more methods.
For our example, code to get the MET (which needs to have previously been put UD), scale it, and store it in UD, would look like:
StatusCode EVScaleMET::execute(Sandbox.EventView* ev)
{
double MEx = ev->doubleUserData(m_MissingEx);
double MEy = ev->doubleUserData(m_MissingEy);
double MEt = ev->doubleUserData(m_MissingEt);
double MEx_scaled = MEx*m_ScaleFactor;
double MEy_scaled = MEy*m_ScaleFactor;
double MEt_scaled = std::sqrt(MEx_scaled*MEx_scaled + MEy_scaled*MEy_scaled);
CheckSC(ev->setDoubleUserData(m_MissingEx + "_scaled", MEx_scaled));
CheckSC(ev->setDoubleUserData(m_MissingEy + "_scaled", MEy_scaled));
CheckSC(ev->setDoubleUserData(m_MissingEt + "_scaled", MEt_scaled));
return StatusCode::SUCCESS;
}
Note that you will have to
#include <cmath>
to use
std::sqrt
.
Then, after you have declared the tool's private data like
m_ScaleFactor
in the header file, you are ready to compile by going to the package's
cmt
directory and running
gmake
. Compiling will automatically create the necessary python code to so that your tool can be imported and configured in job options. Tools created with
newEVTool
should be scheduled to an
EVMultipleOutputToolLooper
to be run
event-by-event, if you want to create a tool to run within a tool looper over particles, you should create
EVUDObjTool
, described in the next section.
To schedule and configure your tool in your python job options, you should do something like:
from MyPackage.MyPackageConf import EVScaleMET
theEVMOToolLooper += EVScaleMET('theEVScaleMET', ScaleFactor=1.2)
Back to top
Writing Your Own Particle-level Sandbox.EventView Tool (EVUDObjTool)
An
EVUDObjTool
is a tool to be run on each of some set of particles in an event, usually to calculate some UD for each of those particles. It should be scheduled to a looper like an
EVUDFinalStateLooper
that loops over the particles for the tool to run on.
For example, we will write a tool called
EVUDTransMassCalculator
, that calculates the transverse mass between a given particle and the missing transverse energy. In our python job options, we can configure this tool to calculated the transverse mass for every particle with the label 'Muon' by writing the following.
FSLooper = EVUDFinalStateLooper('MuonFSLooper',
Labels = ['Muon'],
Prefix = 'Muon_',
OutputLevel = WARNING)
FSLooper += EVUDTransMassCalculator('TransMassCalc',
MissingEt = 'MET_RefFinal_et',
MissingEx = 'MET_RefFinal_ex',
MissingEy = 'MET_RefFinal_ey')
theEVMOToolLooper += FSLooper
Similar to the discussion in the above section, in the root directory of the package in which you will develop your tool, you can use the
newEVUDObjTool
command to create skeleton header and source files.
>> newEVUDObjTool EVUDTransMassCalculator INavigable4Momentum
The second argument is the type of particle looped over by the
EVUDFinalStateLooper
, to which
EVUDTransMassCalculator
will be scheduled. We use
INavigable4Momentum
to make this tool's application general. Every EDM particle type inherits from
INavigable4Momentum
. Unless your tool will use something specific to a particle type's EDM, you should write the tool for use with
INavigable4Momentum
.
EVUDObjTools
have two execute methods,
executeObj
and
executeDummy
. The
executeObj
method is the code to be run
particle-by-particle for each particle looped over by the final state looper. The
executeObj
method passes
const INavigable4Momentum *part
parameter that points to the particle currently being considered by the final state looper to which this
EVUDObjTool
was scheduled. The
ev
pointer parameter is for setting/accessing event-level UD and accessing particles inserted to the current Sandbox.EventView. The
UD
pointer parameter is for setting/accessing the particle-level UD of
part
.
The
executeDummy
is for filling dummy values to UD when the final state looper didn't have a particle to loop over, but needs a dummy value such that data can be aggregated when dumping UD to a ROOT TTree.
EVUDTransMassCalculator::EVUDTransMassCalculator(const std::string& type,
const std::string& name,
const IInterface* parent):
EVUDObjCalcBaseT<INavigable4Momentum>(type, name, parent)
{
declareProperty("MissingEx", m_MissingEx="MET_RefFinal_ex"); // std::string
declareProperty("MissingEy", m_MissingEy="MET_RefFinal_ey"); // std::string
declareProperty("MissingEt", m_MissingEt="MET_RefFinal_et"); // std::string
}
EVUDTransMassCalculator::~EVUDTransMassCalculator()
{ }
StatusCode EVUDTransMassCalculator::executeObj(Sandbox.EventView* ev, UserDataBlock *UD, const INavigable4Momentum *part,
std::string prefix, std::string postfix)
{
double MEx = ev->doubleUserData(m_MissingEx);
double MEy = ev->doubleUserData(m_MissingEy);
double MEt = ev->doubleUserData(m_MissingEt);
double NuPhi = atan2(MEy, MEx);
double TMass = sqrt(2.*( part->et() * MEt ) * ( 1.-cos(NuPhi-part->phi()) ));
CheckSC(UD->put<double>(prefix+"TransM"+postfix,TMass));
return StatusCode::SUCCESS;
}
StatusCode EVUDTransMassCalculator::executeDummy(Sandbox.EventView* ev, UserDataBlock *UD,
std::string prefix, std::string postfix)
{
CheckSC(UD->put<double>(prefix+"TransM"+postfix,0.));
return StatusCode::SUCCESS;
}
As with the
EVTool
example, after you have declared the tool's private data like
m_MissingEx
in the header file, you are ready to compile by going to the package's
cmt
directory and running
gmake
. Compiling will automatically create the necessary python code to so that your tool can be imported and configured in job options.
A job that uses this
EVUDTransMassCalculator
tool and later uses
AANtupleFromUserData
to dump the UD to a ntuple will create an ntuple with a variable called
Muon_TransM
for every particle inserted into the EV with the label 'Muon'.
Back to top
--
RyanReece - 07 Oct 2008