Ryan Reece's Sandbox
Athena Notes
Here you will find notes from my experiences computing in ATLAS. You can find
some more notes on ROOT, python, pyROOT, and makefiles at my website:
http://www.hep.upenn.edu/~rreece/computing.html
.
Other places to find athena help are:
These notes document the use of Athena release 13, specifically release 13.0.40.
Back to top
Using Athena at BNL
You will need a computing account at BNL and you will have to
create a register a public key
.
Then you can login to BNL:
>> ssh -X user@atlasgw.bnl.gov
You will be prompted for password for your security key.
Once inside the gateway, do:
>> rterm -i
You will be prompted for you BNL account password.
Following the advice of the
USATLAS TWiki
, my
cmthome/requirements
file at BNL is
#---------------------------------------------------------------------
set CMTSITE STANDALONE
macro PROJ_RELEASE "latest" \
12.0.6 "12.0.6" \
13.0.30 "13.0.30" \
13.0.40 "13.0.40" \
13.1.0 "13.1.0" \
13.2.0 "13.2.0"
macro PROJ_BASE_RELEASE "$(PROJ_RELEASE)" \
13.0.25.2 "13.0.25"
macro PROJ_SUBDIR "$(PROJ_BASE_RELEASE)" \
bugfix "bugfix/$(PROJ_BASE_RELEASE)" \
dev "dev/$(PROJ_BASE_RELEASE)"
set SITEROOT /opt/usatlas/kit_rel/${PROJ_SUBDIR}
macro ATLAS_DIST_AREA ${SITEROOT}
macro ATLAS_TEST_AREA ${HOME}/testarea/${PROJ_BASE_RELEASE}
#macro ATLAS_GROUP_AREA "/afs/cern.ch/atlas/groups/PAT/Tutorial/EventViewGroupArea/EVTags-13.0.30.1"
apply_tag oneTest
apply_tag setupCMT
apply_tag setup
apply_tag noCVSROOT
apply_tag 32
use AtlasLogin AtlasLogin-* $(ATLAS_DIST_AREA)
set PATHENA_GRID_SETUP_SH /afs/usatlas.bnl.gov/lcg/current/etc/profile.d/grid_env.sh
macro setup_slc3compat "" \
gcc323 "/opt/usatlas/kit_rel/SLC3/setup_slc3compat"
setup_script $(setup_slc3compat)
#---------------------------------------------------------------------
I have added the
ATLAS_GROUP_AREA
line in order to use
EventView in release 13.0.30, but for release 13.0.40, the Group Area is not needed and I have commented it out. You should also set the CVSROOT in your
.bashrc
file so that you can check out packages.
export CVSROOT=/afs/usatlas.bnl.gov/software/cvs
echo "CVSROOT set for BNL to " $CVSROOT
I find it convenient when setting up athena and running jobs, to define the following functions in my
.bashrc
file:
function setup {
source ${HOME}/cmthome/setup.sh -tag=$*
shift
}
function makeit {
cmt config
source ./setup.sh
gmake
}
function run {
nohup athena.py $* &> $1.log &
tail -f $1.log
}
Using the above to set up athena, all I have to do is run
setup
follow by the comma separated tags,
e.g.
>> setup 13.0.30,groupArea
or
>> setup 13.0.40
makeit
, explained
below, is used to compile a package.
And to run an athena job, all I do is
>> run example_jobOptions.py
This creates a log file of the athena ouput,
example_jobOptions.py.log
and prints it to the screen real time using
tail -f
.
In general, refer to the
Computing Workbook for learning how to setup and run athena.
Back to top
Checking Out a Package
After setting up athena, go to the appropriate place to check out packages, your
testarea
.
>> cd $TestArea
>> pwd
/usatlas/u/rreece/testarea/13.0.30
First, you must find which package tag is appropriate for your version of Athena.
>> cmt show versions PhysicsAnalysis/AnalysisCommon/UserAnalysis
PhysicsAnalysis/AnalysisCommon/UserAnalysis UserAnalysis-00-10-12 /opt/usatlas/kit_rel/13.0.30/AtlasAnalysis/13.0.30
Alternatively, you can see a list of all the possible tags for the package by running:
>> get_tag PhysicsAnalysis/AnalysisCommon/UserAnalysis
To checkout the package with this tag do:
>> cmt co -r UserAnalysis-00-10-12 PhysicsAnalysis/AnalysisCommon/UserAnalysis
After checkout, go inside the package and see what's there.
>> cd PhysicsAnalysis/AnalysisCommon/UserAnalysis/
>> ls
cmt/ CVS/ doc/ python/ Root/ run/ share/ src/ UserAnalysis/
Every pacakge has the following directories:
- cmt - where you configure and build the package
- share - contains python job options
- src - contains the C++ sources
- PackageName - contains the C++ headers
- run - directory for you to run jobs. a place to hold your job options and data.
To configure and make the package do
>> cd cmt
>> cmt config
>> source setup.sh
>> gmake
This can be abbreviated using my bash function,
makeit
, explained
above.
>> cd cmt
>> makeit
Back to top
Using DQ2 to Get Datasets
You can browse for datasets on the web at the
DQ2 Browser
.
The following describes how to setup DQ2 at BNL. This requires that you have a
grid certificate. Create the file
dq2_setup.sh
containing:
source /afs/usatlas.bnl.gov/lcg/current/etc/profile.d/grid_env.sh
grid-proxy-init
source /afs/usatlas.bnl.gov/Grid/Don-Quijote/dq2_user_client/setup.sh.BNL
Now source this script:
>> source dq2_setup.sh
This will prompt you for the password for your grid certificate. Now you can use the DQ2 commmands. For example:
>> dq2_ls trig1_misal1_mc12.005144.PythiaZee.recon.AOD.*
trig1_misal1_mc12.005144.PythiaZee.recon.AOD.v12000602
trig1_misal1_mc12.005144.PythiaZee.recon.AOD.v12000603
trig1_misal1_mc12.005144.PythiaZee.recon.AOD.v12000604
trig1_misal1_mc12.005144.PythiaZee.recon.AOD.v12000604_tid008230
trig1_misal1_mc12.005144.PythiaZee.recon.AOD.v12000604_tid008231
trig1_misal1_mc12.005144.PythiaZee.recon.AOD.v12000604_tid008232
trig1_misal1_mc12.005144.PythiaZee.recon.AOD.v12000605
To copy locally all the files in one of these data sets, do:
>> dq2_get trig1_misal1_mc12.005144.PythiaZee.recon.AOD.v12000604_tid008230
Back to top
Grid Submission
In order to submit athena jobs to the computing grid, you need to checkout
pathena
:
>> cd $TestArea
>> cmt co PhysicsAnalysis/DistributedAnalysis/PandaTools
>> cd PhysicsAnalysis/DistributedAnalysis/PandaTools/cmt
>> cmt config
>> source setup.sh
>> gmake
To submit a job, do:
>> pathena ZeeZmmOnAODExample_jobOptions.py
--outDS user.RyanDReece.005144.AnalysisExampleZee.01
--inDS trig1_misal1_mc12.005144.PythiaZee.recon.AOD.v12000604_tid008230
-
ZeeZmmOnAODExample_jobOptions.py
is some job option file.
-
--outDS
precedes your specified output dataset that your job will create. Its name must have the format of user..
.
-
--inDS
is optional. It specifies the input dataset to use for your job. If given, it overides any EventSelector.InputCollections
in your job option file.
Following this command, you will be prompted for the password for your
grid certificate. Then your job's IDs will be printed.
There are two ways to monitor the status of your jobs. First, you can run
pathen_util
:
>> pathena_util
>>> show()
will print a list of the jobs you have submitted. You can specify a specific job ID to get more information:
>>> show(3)
======================================
JobID : 3
time : 2007-11-19 16:14:23
inDS : trig1_misal1_mc12.005144.PythiaZee.recon.AOD.v12000604_tid008230
outDS : user.RyanDReece.005144.AnalysisExampleZee.01
libDS : user.RyanDReece.acas0003_5.lib._000003
build : 4668038
run : 4668039
jobO : ZeeZmmOnAODExample_jobOptions.py
site : ANALY_BNL_ATLAS_1
----------------------
buildJob : ----
----------------------
runAthena :
total : 1
succeeded : 0
failed : 0
running : 1
unknown : 0
----------------------
To quit
pathena_util
, type
CTRL-D
.
Second, you can visit your user page on the
Panda Monitor website
.
You will receive an email you notifying you when your job has finished. Then you can use DQ2 to retrieve the dataset your job created:
>> dq2_get -rv user.RyanDReece.005144.AnalysisExampleZee.01
Back to top
Writing Your Own Athena Algorithms
In writing your own athena algorithm, you must write a C++ class that inherits from the
algorithm
class. Like all C++ classes, it will need a header file with a declaration and a source file with implementation of the algorithm. They should be named
MyAlg.h
and
MyAlg.cxx
, where
MyAlg
is whatever you want to name your algorithm. The header file goes in the
PackageName/PackageName/
directory and the source file goes in the
PackageName/src/
directory.
The Header File
The following is a template for the header file:
#ifndef MYALG_H
#define MYALG_H
#include "GaudiKernel/ToolHandle.h"
#include "GaudiKernel/Algorithm.h"
#include "GaudiKernel/ObjectVector.h"
#include "GaudiKernel/ITHistSvc.h"
#include "CLHEP/Units/SystemOfUnits.h"
#include "StoreGate/StoreGateSvc.h"
#include "AnalysisTools/AnalysisTools.h"
#include "egammaEvent/ElectronContainer.h"
#include "egammaEvent/Electron.h"
#include <string>
#include "TTree.h"
class MyAlg : public Algorithm
{
public:
MyAlg(const std::string& name, ISvcLocator* pSvcLocator);
~MyAlg();
StatusCode initialize();
StatusCode finalize();
StatusCode execute();
private:
// methods
//------------------------------------------------------------------------
bool selectElectron(const Analysis::Electron& elect) const;
// data members
//------------------------------------------------------------------------
ToolHandle<AnalysisTools> m_analysisTools;
StoreGateSvc* m_storeGate;
ITHistSvc * m_histSvc;
TTree* m_tree;
int m_numEvents;
float m_electron_Et;
// configurable data members
//------------------------------------------------------------------------
float m_electron_Et_min_cut;
float m_electron_abs_eta_cut;
};
#endif // MYALG_H
The first group of includes should be in every algorithm. The
egammaEvent
includes are examples of what you might need to read the data in an AOD. Every athena algorithm has to have a constructor of the form
MyAlg(const std::string& name, ISvcLocator* pSvcLocator)
and
initialize()
,
finalize()
, and
execute()
methods.
selectElectron
is an example of a custom method you can write yourself. The following data members are just examples of things an algorithm might use, but are not necessary. We will see what makes
m_electron_Et_min_cut
and
m_electron_abs_eta_cut
"configurable" in the source file.
Back to top
The Source File
The following is a template for the source file:
#include "GaudiKernel/MsgStream.h"
#include "GaudiKernel/AlgFactory.h"
#include "GaudiKernel/IToolSvc.h"
#include "StoreGate/StoreGateSvc.h"
#include "StoreGate/DataHandle.h"
#include "egammaEvent/Electron.h" // the Electron
#include "Navigation/NavigationToken.h" // Constituent navigation
#include "ParticleEvent/ParticleBaseContainer.h" // common implementation of all particles
// #include "CompositeParticleEvent/CompositeParticle.h" // the composite particle
#include "AnalysisUtils/AnalysisCombination.h" // analysis tools
#include "PackageName/MyAlg.h"// the header file
#include <stdint.h>
#include <algorithm>
#include <math.h>
using namespace Analysis;
//////////////////////////////////////////////////////////////////////////////////////
/// Constructor
MyAlg::MyAlg(const std::string& name,
ISvcLocator* pSvcLocator) : Algorithm(name, pSvcLocator),
m_analysisTools( "AnalysisTools", this )
{
m_storeGate = NULL;
m_histSvc = NULL;
m_tree = NULL;
m_numEvents = 0;
m_numEventsPassed = 0;
m_electron_Et = 0.0;
declareProperty("electron_Et_min_cut", m_electron_Et_min_cut = 20*GeV);
declareProperty("electron_abs_eta_cut", m_electron_abs_eta_cut = 2.0);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Destructor
MyAlg::~MyAlg() {}
////////////////////////////////////////////////////////////////////////////////////
/// Initialize
StatusCode MyAlg::initialize()
{
MsgStream mLog( messageService(), name() );
mLog << MSG::DEBUG << "Initializing MyAlg" << endreq;
// Get handle StoreGate
StatusCode sc = service("StoreGateSvc", m_storeGate);
if(sc.isFailure())
{
mLog << MSG::ERROR
<< "Unable to retrieve pointer to StoreGate service."
<< endreq;
}
// Get a handle on the NTuple and histogramming service
sc = service("THistSvc", m_histSvc);
if(sc.isFailure())
{
mLog << MSG::ERROR
<< "Unable to retrieve pointer to THistSvc"
<< endreq;
return sc;
}
// Create TTree and register it to THistSvc
m_tree = new TTree("MyTree" , "MyTree");
std::string fullTreeName = "/AANT/MyTree" ;
sc = m_histSvc->regTree(fullTreeName, m_tree);
if(sc.isFailure())
{
mLog << MSG::ERROR << "Unable to register TTree : " << fullTreeName << endreq;
return sc;
}
// Create TTree branches.
m_tree->Branch("electron_Et", &m_electron_Et, "electron_Et/F");
return StatusCode::SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////////
/// Finalize
StatusCode MyAlg::finalize()
{ }
//////////////////////////////////////////////////////////////////////////////////
/// Execute - called by the event loop on event by event
StatusCode MyAlg::execute()
{
[Code called event by event here]
return StatusCode::SUCCESS;
}
Notice the calls of the
declareProperty("electron_Et_min_cut", m_electron_Et_min_cut = 20*GeV)
in the constructor. This makes the C++
m_electron_Et_min_cut
variable configurable from the Python job options. The first argument is a string containing the Python name of the variable. The second is the C++ variable with an optional equals-sign followed by a default value. Configuration from Python will be explained more later when we get to the job options.
This also shows how to use the Message Service to print to the screen and how to create TTrees in a root file. All that is missing is the assignment of variables in branches and calling
Fill()
in the
execute()
function.
Back to top
The ALGORITHM_FACTORY
In order to make your algorithm configurable in Python job options, there is one last thing to do. Every package has a
PackageName/src/components/PackageName_entries.cxx
file. In it, there is some code that tells
cmt
to create the appropriate Python modules for the algorithms in the package when you make the package.
#include "PackageName/MyAlg.h"
#include "PackageName/AnotherAlg.h"
DECLARE_ALGORITHM_FACTORY( MyAlg )
DECLARE_ALGORITHM_FACTORY( AnotherAlg )
DECLARE_FACTORY_ENTRIES( PackageName ) {
DECLARE_ALGORITHM( MyAlg )
DECLARE_ALGORITHM( AnotherAlg )
}
For each algorithm in your package, you need to include the header file, add a
DECLARE_ALGORITHM_FACTORY
line, and add a
DECLARE_ALGORITHM
line like above.
After editing this file, you can now compile your code. Go to the
PackageName/cmt/
directory and run
>> cmt config
>> source setup.sh
>> gmake
Back to top
The Job Options
Here are some example Python job options needed to run a job with your new algorithm.
from AthenaCommon.Constants import *
from AthenaCommon.AppMgr import theApp
from AthenaCommon.AppMgr import ServiceMgr
import AthenaPoolCnvSvc.ReadAthenaPool
#-------------------------------------------------------------------------
# Input Dataset
#-------------------------------------------------------------------------
ServiceMgr.EventSelector.InputCollections = [
"/usatlas/u/rreece/workarea/data/13/Zee/AOD.016450._00017.pool.root.2",
"/usatlas/u/rreece/workarea/data/13/Zee/AOD.016450._00293.pool.root.4"
]
theApp.EvtMax = -1 # -1 means all events
#-------------------------------------------------------------------------
# Message Service
#-------------------------------------------------------------------------
# Set output level threshold (2=DEBUG, 3=INFO, 4=WARNING, 5=ERROR, 6=FATAL )
ServiceMgr.MessageSvc.OutputLevel = WARNING
#-------------------------------------------------------------------------
# Algorithms
#-------------------------------------------------------------------------
from AthenaCommon.AlgSequence import AlgSequence
theJob = AlgSequence()
from PackageName.PackageNameConf import MyAlg
theJob += MyAlg(OutputLevel = INFO)
#-------------------------------------------------------------------------
# Histogram and Tree Service
#-------------------------------------------------------------------------
THistSvc = Service ( "THistSvc" )
THistSvc.Output = ["AANT DATAFILE='MyAlg.AAN.root' OPT='RECREATE'"]
THistSvc.OutputLevel = INFO
print theJob
Notice the following lines. One gets a handle on the top algorithm sequence by
from AthenaCommon.AlgSequence import AlgSequence
theJob = AlgSequence()
Then one adds algorithms to the sequence by
from PackageName.PackageNameConf import MyAlg
theJob += MyAlg(OutputLevel = INFO)
Now, using the bash function I defined
above, you can run your athena job by
>> run example_jobOptions.py
Back to top
Services
In my notes
above on writing your own athena algorithms, the example code shows the use of the Message Service to print to the terminal and the
THistSvc to make a TTree saved in a ROOT file. In the next sections, I explain how to use of these services in more detail.
The Message Service
You can use the Message Service to print text in the terminal. In the C++ code for your algorithm, you must
#include "GaudiKernel/MsgStream.h"
.
Then define an instance of the
MsgStream
by
MsgStream mLog( msgSvc(), name() );
Now you can use it to print to the terminal by
mLog << MSG::INFO << "Hello World!" << endreq;
where
INFO
specifies the Output Level of the message. It can be one of the following
2=DEBUG
,
3=INFO
,
4=WARNING
,
5=ERROR
, or
6=FATAL
.
If the message's Output Level is not above the Output Level specified in the job options, then the message will be suppressed.
Now in your job options, you must have the line
from AthenaCommon.AppMgr import ServiceMgr
To specify the global Output Level in job options, do
ServiceMgr.MessageSvc.OutputLevel = WARNING
This will suppress output of all message with output level
INFO
or lower.
(Note the difference in syntax between
msgSvc()
in the C++ code and
MessageSvc
in the Python job options.)
One can specify that a specific algorithm have an Output Level differing from the global Output Level by setting the
OutputLevel
member variable of that algorithm.
someAlg.OutputLevel = INFO
Alternatively, one can set the Output Level when declaring an instance of the algorithm, as is done in the job options
above.
theJob += MyAlg(OutputLevel = INFO)
Back to top
TODO
Back to top
The
THistSvc allows you to create ROOT TTree's and save them to ROOT files in your athena algorithms. The first thing to do is to add pointers to the
THistSvc and to your TTree in the class for your algorithm. In
MyAlg.h
include the
THistSvc andTTree headers.
#include "GaudiKernel/ITHistSvc.h"
#include "TTree.h"
And add the pointers as private member variables. Also add variables that you want to put in the tree.
class MyAlg : public Algorithm
{
...
private:
ITHistSvc * m_histSvc;
TTree* m_tree;
float m_someVariable;
}
Then, in the
initialize()
function in
MyAlg.cxx
, create a TTree, register it to the
THistSvc, and add branches to the TTree.
StatusCode MyAlg::initialize()
{
...
// Create TTree and register it to THistSvc
m_tree = new TTree("MyTree" , "MyTree");
std::string fullTreeName = "/AANT/MyTree" ;
sc = m_histSvc->regTree(fullTreeName, m_tree);
if(sc.isFailure())
{
mLog << MSG::ERROR << "Unable to register TTree : " << fullTreeName << endreq;
return sc;
}
// Create TTree branches.
m_tree->Branch("someVariable", &m_someVariable, "someVariable/F");
...
}
Where
AANT
is the output file stream specified in your job options. This will be explained below.
Now you need to calculate your variables for each event in the
execute()
function and then call
Fill()
for the TTree.
StatusCode MyAlg::execute()
{
...
m_someVariable = something;
m_tree->Fill();
...
}
Now you can compile your code. Lastly, you need to setup your job options to use the
THistSvc by adding the following lines
THistSvc = Service ( "THistSvc" )
THistSvc.Output = ["AANT DATAFILE='filename.root' OPT='RECREATE'"]
THistSvc.OutputLevel = INFO
where
filename.root
specifies the name of the ROOT file to which the TTree will be saved.
Back to top
EventView is an analysis framework within Athena that does a lot of handy things like
overlap removal,
cuts,
particle combination,
dumping NTuples... A lot of
tools have already been written and you can do a pretty complicated analysis just by stitching these tools together in your job options, without having to compile any code.
Besides overlap removal, the best thing about the
EventView Framework is that it encourages a modular design to your analysis and the reusability of code. To know more about the philosophy and organization of
EventView Framework, I recommend that you read the
EventView ATLAS Note
.
One confusing thing, is that
EventView can refer to the entire
EventView Framework or the
EventView class. In theses notes, I try to include the word "Framework" when appropriate. An
EventView (EV) is a class that holds pointers to particles that represent a "view" of what an event was. The particle objects actually remain in the AOD containers held in
StoreGate, but EV gives you a way to organize which particles pass your selection cuts and allows you to label them.
Back to top
To use the
EventView Framework in Athena release 13.0.40 in the
UserAnalysis Package, you have to make some changes to the
UserAnalysis/cmt/requirements
file, although there is no need for a Group Area. Add the following lines to the 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
The Start of EV Job Options
A Job Option using the EV Framework, should start with:
#-------------------------------------------------------------------------
# Athena imports
#-------------------------------------------------------------------------
from AthenaCommon.Constants import *
from AthenaCommon.AppMgr import theApp
from AthenaCommon.AppMgr import ServiceMgr
import AthenaPoolCnvSvc.ReadAthenaPool
from AthenaCommon.AlgSequence import AlgSequence
theJob = AlgSequence()
#-------------------------------------------------------------------------
# EventView imports
#-------------------------------------------------------------------------
from EventViewBuilderAlgs.EventViewBuilderAlgsConf import *
from EventViewInserters.EventViewInsertersConf import *
from EventViewUserData.EventViewUserDataConf import *
from EventViewDumpers.EventViewDumpersConf import *
from EventViewCombiners.EventViewCombinersConf import *
from EventViewConfiguration.DefaultModules import * # for AANtupleFromUserData
#-------------------------------------------------------------------------
# Message Service
#-------------------------------------------------------------------------
# Set output level threshold (2=DEBUG, 3=INFO, 4=WARNING, 5=ERROR, 6=FATAL )
ServiceMgr.MessageSvc.OutputLevel = WARNING
#-------------------------------------------------------------------------
# Input Datasets
#-------------------------------------------------------------------------
ServiceMgr.EventSelector.InputCollections = [
'/usatlas/u/rreece/workarea/data/13/Zee/AOD.016450._00017.pool.root.2',
'/usatlas/u/rreece/workarea/data/13/Zee/AOD.016450._00293.pool.root.4']
theApp.EvtMax = 20 # -1 means all events
This sets up Athena, imports things for the EV Framework, sets the Output Level of the Message Service, and specifies the input datasets.
Back to top
Next, you should add an EV Tool Looper to the job.
The EV Tool Looper is the main algorithm of the EV Framework that you add to the Athena algorithm sequence of a job.
It holds the collection of EVs created for a single event and runs the list of EV tools added to it. An EV tool is like a small algorithm that runs and does something to the EV, like inserting particles into the EV or combining particles to make inferred particles.
You add an EV Tool Looper by:
#-------------------------------------------------------------------------
# Algorithms
#-------------------------------------------------------------------------
theJob += EVMultipleOutputToolLooper('theToolLooper',
EventViewCollectionOutputName = 'myEventViewCollection',
OutputLevel = WARNING)
Back to top
Inserting Particles
You add tools to the
EVMultipleOutputToolLooper
by using +=, just like adding algorithms to
theJob
. Your first tool should probably be one that inserts particles into the EV. For example, to insert electrons, use the
EVElectronInserter
tool:
#-------------------------------------------------------------------------
# EventView Tools
#-------------------------------------------------------------------------
theToolLooper = theJob.theToolLooper
theToolLooper += EVElectronInserter('theElectronInserter',
SelectedLabels = ['Electron'],
etCut = 15*GeV,
EtaMaxCut = 2.0,
makeEtaCuts = True )
This makes some selection cuts on the electrons in the AOD. Those that pass are labeled with the the labels specified by
selectedLabels
and then those that do not overlap with anything already inserted in the EV (in our case nothing) get inserted into the
Final State (FS) particles of the EV. Labels are handy because we will use them later to refer to these particles in other tools.
In the terminal output, aftering running the job, you should see a cut flow table summarizing the particle insertion.
theToolLooper.t... INFO
CUT RESULTS: ElectronAODCollection
==============================================================================
= Cut Num Passed Cut Effic. Cut Flow Eff. =
=----------------------------------------------------------------------------=
= All 4403 1 1 =
= EtaMaxCut 3722 0.845 0.845 =
= EtaMinCut 3722 1 0.845 =
= ptCut 3722 1 0.845 =
= etCut 2296 0.617 0.521 =
= eCut 2296 1 0.521 =
= authorCut 2296 1 0.521 =
= isolationCut 2296 1 0.521 =
= caloCut 2228 0.97 0.506 =
= track Quality Cut 2188 0.982 0.497 =
= All_Preselection 2188 1 0.497 =
= Overlap 2162 0.988 0.491 =
= Inserted 2162 1 0.491 =
==============================================================================
Back to top
EV Screen Dump
After inserting particles into your EV, you may want to check to see that they are there. You can dump the EV information to the screen by adding the following to your job option and running it in Athena.
theToolLooper += EVScreenDumper('theScreenDumper')
Back to top
Athena Aware Ntuple (AAN) Dumping
You can dump data from EVs into a TTree in a ROOT file, but first, you have to save that data as
User Data (UD) in the EVs. For that you need to schedule an
EVUDFinalStateLooper
to the
EVMultipleOutputToolLooper
, a looper within a looper. The
EVMultipleOutputToolLooper
loops over each event creating EVs and running the scheduled tools over them. The
EVUDFinalStateLooper
is one of those tools. It loops over the FS particles in a single EV and runs the tools schedules on it. You can schedule the
EVUDKinCalc
tool to the
EVUDFinalStateLooper
, and it will dump the the FS particles' kinetic variables like energy, momentum, eta... into UD. This is done by adding the following to your job options.
DumpLooper = EVUDFinalStateLooper('myDumpLooper',
Prefix = 'Electron_',
RequireLabels = ['Electron'] )
DumpLooper += EVUDKinCalc('myEVUDKinCalc')
theToolLooper +=DumpLooper
I like to generalize this by defining the following function in my job options:
def DumpFSKin(ToolLooper, PrefixArg,
LabelsArg=[], RequireLabelsArg=[], RejectLabelsArg=[]):
DumpLooper = EVUDFinalStateLooper(PrefixArg + 'DumpLooper',
Prefix = PrefixArg,
Labels = LabelsArg,
RequireLabels = RequireLabelsArg,
RejectLabels = RejectLabelsArg )
DumpLooper += EVUDKinCalc(PrefixArg + 'EVUDKinCalc')
ToolLooper += DumpLooper
And then calling it by:
DumpFSKin(theToolLooper, 'Electron_', RequireLabelsArg=['Electron'])
Similarly, one can loop over Inferred Objects, explained
below, and dump their kinematics into UD:
def DumpIOKin(ToolLooper, PrefixArg,
LabelsArg=[], RequireLabelsArg=[], RejectLabelsArg=[]):
DumpLooper = EVUDInferredObjectLooper(PrefixArg + 'DumpLooper',
Prefix = PrefixArg,
Labels = LabelsArg,
RequireLabels = RequireLabelsArg,
RejectLabels = RejectLabelsArg )
DumpLooper += EVUDKinCalc(PrefixArg + 'EVUDKinCalc')
ToolLooper += DumpLooper
And call it by:
DumpIOKin(theToolLooper, 'Z_', RequireLabelsArg=['Z'])
Now that the variables are in UD, you can add code to the job options to dump the UD into an AAN:
theToolLooper += AANtupleFromUserData('theNtupleDumper',
filename='Zee.AAN.root', sequencer=theJob, EventTree=True,
CandTree=False)
Athena release 13.0.40 uses
ROOT version 5.14, but that version of ROOT has trouble with
vector<double>
being in branches of a TTree. Using
ROOT version 5.17 avoids this problem. Changing your ROOT version in the same terminal that you run Athena, could cause troubles for Athena. It is recommended that you change your ROOT version in a different terminal, and do ROOT work there. I setup ROOT by using the following
.bashrc
function.
function setup_root {
export ROOTSYS=/afs/usatlas.bnl.gov/cernsw/lcg/external/root/5.17.08/slc4_ia32_gcc34/root
export PATH=$ROOTSYS/bin/:$PATH
export LD_LIBRARY_PATH=${ROOTSYS}/lib:$LD_LIBRARY_PATH
export PYTHONPATH=${ROOTSYS}/lib:$PYTHONPATH
}
Back to top
Combining Particles
You can use the EV Framework Combiner Tools to combine particles in an EV into
Inferred Objects (IO), from which they decayed. For example, you can combine an electron and positron to make a Z boson. This is done by adding the following tool to the
EVMultipleOutputToolLooper
.
theToolLooper += EVSimpleCombo('ZeeCombo',
Labels = ['Electron'],
OutputLabel = 'Z',
DaughterLabel = 'ZDaughter',
LowMass = 0*GeV,
HighMass = 10000*GeV,
NDaughters = 2,
CheckCharge = True,
Charge = 0,
SortParticles = True,
PassOnNoCombo = True )
This combines every pair of electrons (specified by
Labels = ['Electron']
and
NDaughters = 2
) that have opposite charge (
CheckCharge = True, Charge = 0
). The IO particle is labeled by
OutputLabel = 'Z'
. The electrons that were combined are labeled by
DaughterLabel = 'ZDaughter'
. If there is more than one possible pairing, each pairing is done in separate EVs for the same event, named EV0, EV1, EV2... Upon dumping into an AAN, the different EVs will be stored in separate trees.
Back to top
Example Analysis: Z -> ee
Putting together all the tools discussed above, one can do a Z -> ee analysis using EV Tools with the following job option, without having to write your own tools or compile any code.
#-------------------------------------------------------------------------
# Athena imports
#-------------------------------------------------------------------------
from AthenaCommon.Constants import *
from AthenaCommon.AppMgr import theApp
from AthenaCommon.AppMgr import ServiceMgr
import AthenaPoolCnvSvc.ReadAthenaPool
from AthenaCommon.AlgSequence import AlgSequence
theJob = AlgSequence()
#-------------------------------------------------------------------------
# EventView imports
#-------------------------------------------------------------------------
from EventViewBuilderAlgs.EventViewBuilderAlgsConf import *
from EventViewInserters.EventViewInsertersConf import *
from EventViewUserData.EventViewUserDataConf import *
from EventViewDumpers.EventViewDumpersConf import *
from EventViewCombiners.EventViewCombinersConf import *
from EventViewConfiguration.DefaultModules import * # for AANtupleFromUserData
#-------------------------------------------------------------------------
# Message Service
#-------------------------------------------------------------------------
# Set output level threshold (2=DEBUG, 3=INFO, 4=WARNING, 5=ERROR, 6=FATAL )
ServiceMgr.MessageSvc.OutputLevel = WARNING
#-------------------------------------------------------------------------
# Input Datasets
#-------------------------------------------------------------------------
ServiceMgr.EventSelector.InputCollections = [
'/usatlas/u/rreece/workarea/data/13/Zee/AOD.016450._00017.pool.root.2',
'/usatlas/u/rreece/workarea/data/13/Zee/AOD.016450._00293.pool.root.4']
theApp.EvtMax = -1 # -1 means all events
#-------------------------------------------------------------------------
# Algorithms
#-------------------------------------------------------------------------
theJob += EVMultipleOutputToolLooper('theToolLooper',
EventViewCollectionOutputName = 'myEventViewCollection',
OutputLevel = WARNING)
#-------------------------------------------------------------------------
# EventView Tools
#-------------------------------------------------------------------------
theToolLooper = theJob.theToolLooper
theToolLooper += EVElectronInserter('theElectronInserter',
SelectedLabels = ['Electron'],
etCut = 15*GeV,
EtaMaxCut = 2.0,
makeEtaCuts = True )
theToolLooper += EVSimpleCombo('ZeeCombo',
Labels = ['Electron'],
OutputLabel = 'Z',
DaughterLabel = 'ZDaughter',
LowMass = 0*GeV,
HighMass = 10000*GeV,
NDaughters = 2,
CheckCharge = True,
Charge = 0,
SortParticles = True,
PassOnNoCombo = True )
#-------------------------------------------------------------------------
# EventView Dumping
#-------------------------------------------------------------------------
def DumpFSKin(ToolLooper, PrefixArg,
LabelsArg=[], RequireLabelsArg=[], RejectLabelsArg=[]):
DumpLooper = EVUDFinalStateLooper(PrefixArg + 'DumpLooper',
Prefix = PrefixArg,
Labels = LabelsArg,
RequireLabels = RequireLabelsArg,
RejectLabels = RejectLabelsArg )
DumpLooper += EVUDKinCalc(PrefixArg + 'EVUDKinCalc')
ToolLooper += DumpLooper
def DumpIOKin(ToolLooper, PrefixArg,
LabelsArg=[], RequireLabelsArg=[], RejectLabelsArg=[]):
DumpLooper = EVUDInferredObjectLooper(PrefixArg + 'DumpLooper',
Prefix = PrefixArg,
Labels = LabelsArg,
RequireLabels = RequireLabelsArg,
RejectLabels = RejectLabelsArg )
DumpLooper += EVUDKinCalc(PrefixArg + 'EVUDKinCalc')
ToolLooper += DumpLooper
DumpFSKin(theToolLooper, 'Electron_', RequireLabelsArg=['Electron', 'ZDaughter'])
DumpIOKin(theToolLooper, 'Z_', RequireLabelsArg=['Z'])
#theToolLooper += EVScreenDumper('theScreenDumper')
theToolLooper += AANtupleFromUserData('theNtupleDumper',
filename='Zee.AAN.root', sequencer=theJob, EventTree=True,
CandTree=False)
print theJob
Back to top
Writing Your Own EventView Tool
TODO
Back to top
Latex
Here I test out using
LaTeX in a TWiki.
Back to top
Major updates:
--
RyanReece - 21 Dec 2007
--
RyanReece - 05 Jan 2008
--
RyanReece - 10 Jan 2008
Latex rendering error!! dvi file was not created.