自分の作業ディレクトリに移動してパッケージを作ります。
$ rc make_skeleton MyNewPackage
これでほぼ空っぽの MyNewPackage が作られました。
$ ls MyNewPackage
MyNewPackage Root cmt
RootCore で提供されている EvenrLoop パッケージを使ってアルゴリズムクラスを作成します。
$ $ROOTCOREBIN/user_scripts/EventLoop/make_skeleton MyNewPackage MyAnalysisAlg
以下のファイルが作成されました。
MyNewPackage /MyNewPackage/MyAnalysisAlg.h
MyNewPackage /Root/MyAnalysisAlg.cxx
EventLoopは文字通りevent loopをサポートするツールです。中身を見てみるとinitialize(),finalize(),execute()などが定義されており、用途が推測できます。1イベントに1回execute()が呼ばれるわけです。
このMyNewPackage をコンパイルします。
$ rc find_packages
$ rc compile
MyNewPackage が認識されてコンパイルされました。それではこれらのファイルを編集していきましょう。 xAODRootAccess というパッケージを介して、xAODにアクセスします。 MyAnalysisAlg.cxxを編集していきます。まずヘッダーファイルを追加します。
// Infrastructure include(s):
#include "xAODRootAccess/Init.h"
#include "xAODRootAccess/TEvent.h"
// ASG status code check
#include <AsgTools/MessageCheck.h>
次に、setupJob(EL::Job& job)に以下を追加します:
job.useXAOD ();
ANA_CHECK(xAOD::Init());
次にinitialize()に以下を追加します。
xAOD::TEvent* event = wk()->xaodEvent();
Info("initialize()", "Number of events = %lli", event->getEntries() );
TEventはxAODの各イベント情報を管理するツールです。
最後にMywPackage /cmt/Makefile.RootCoreに依存するパッケージをリストします:
PACKAGE_DEP = EventLoop xAODRootAccess AsgTools
コンパイルします。
$ rc find_packages
$ rc compile
作ったアルゴリズムを走らせるための実行コードを作成します。
$ mkdir MyNewPackage/util
$ touch MyNewPackage/util/testRun.cxx
testRun.cxxの中身は以下のように書きます。
#include "xAODRootAccess/Init.h"
#include "SampleHandler/SampleHandler.h"
#include "SampleHandler/ScanDir.h"
#include "SampleHandler/ToolsDiscovery.h"
#include "EventLoop/Job.h"
#include "EventLoop/DirectDriver.h"
#include "SampleHandler/DiskListLocal.h"
#include "MyNewPackage/MyAnalysisAlg.h"
#include <TSystem.h>
int main( int argc, char* argv[] ) {
// Take the submit directory from the input if provided:
std::string submitDir = "submitDir"; if( argc > 1 ) submitDir = argv[ 1 ];
// Set up the job for xAOD access:
xAOD::Init().ignore();
// Construct the samples to run on:
SH::SampleHandler sh;
// use SampleHandler to scan all of the subdirectories of a directory for particular MC single file:
const char* inputFilePath = gSystem->ExpandPathName ("/gpfs/fs2001/nobe/data2086b/sample_forTutorial2016/data16_13TeV.00310247.physics_Main.merge.DAOD_HIGG2D4.f755_m1699_p2880/");
SH::ScanDir().filePattern("*pool.root*").scan(sh,inputFilePath);
// Set the name of the input TTree. It's always "CollectionTree" // for xAOD files.
sh.setMetaString( "nc_tree", "CollectionTree" );
// Print what we found:
sh.print();
// Create an EventLoop job:
EL::Job job; job.sampleHandler( sh );
job.options()->setDouble (EL::Job::optMaxEvents, 500); // maximum number of events to be analyzed. If you want to see all events, please set it to -1
// Add our analysis to the job:
MyAnalysisAlg* alg = new MyAnalysisAlg (); job.algsAdd( alg );
// Run the job using the local/direct driver:
EL::DirectDriver driver; driver.submit( job, submitDir );
return 0;
}
だいたい分かるように、
を指定しています。
コンパイルします。
$ rc find_packages
$ rc compile
以下のコマンドでtestRunというプログラムを走らせることができます。
$ testRun submitDir
submitDirはアウトプットファイルが出来る場所で、既にあるディレクトリ名を指定するとジョブは走りません。
このままだとEventLoopで何もしないで最初の500eventsを読み込むだけのコードです。
inputFilePathやoptMaxEventsも、submitDirと同様にconfigurableにしておいたほうが何かと便利かもしれません。