ARTEMISでモンテカルロシミュレーションをする
今回は、ARTEMISにてモンテカルロシミュレーションをする手法についてまとめます。
ARTEMISには一様乱数を発生させて、その値をBranchに詰めるTRandomNumberEventStore
というProcessorがあります。これを用いる利点として、Branchに詰められることから乱数の値にアクセスでき、データとして相関が取れることが挙げられます。このProcessorで発生した乱数の値はTSimpleData
になります。
乱数の作成方法
以下のようなyamlを書くだけです。
Processor:
- name: timer
type: art::TTimerProcessor
- name: ran
type: art::TRandomNumberEventStore
parameter:
Max: 1 # 最大値が1
MaxLoop: 1000 # 1000回発生
Min: -1 # 最小値が-1
OutputCollection: random
OutputTransparency: 0
Verbose: 0
- name: output_tree
type: art::TOutputTreeProcessor
parameter:
FileName: random_tree.root
使い方
これを回したときに作られるrandom
というBranchはTSimpleData
型になっていますので、Drawするときは
tree->Draw("random.fValue");
とすれば良いです。
また、別の作ったProcessorにこれを食わせたい場合もいつものようにやればOKです。ただ、私が普段作っているProcessorはいつもInputがTClonesArray
なのですが、今回はTSimpleData
なのでその辺を工夫します(といっても、TSimpleData**
として受ければ良いだけです)。
例として、乱数に1を足すProcessorを作ります。
ヘッダTAddOneProcessor.h
は
#ifndef TADDONEPROCESSOR_H
#define TADDONEPROCESSOR_H
#include "TProcessor.h"
#include "TSimpleData.h"
namespace art {
class TAddOneProcessor;
}
class art::TAddOneProcessor : public TProcessor {
public:
TAddOneProcessor();
virtual ~TAddOneProcessor();
void Init(TEventCollection*);
void Process();
private:
TSimpleData **fInput;
TClonesArray *fOutput;
TString fInputName;
TString fOutputName;
ClassDef(TAddOneProcessor,1)
};
#endif
ソースTAddOneProcessor.cc
は
#include "TAddOneProcessor.h"
#include "TSimpleData.h"
#include "TClonesArray.h"
using art::TAddOneProcessor;
ClassImp(TAddOneProcessor)
TAddOneProcessor::TAddOneProcessor() : fOutput(NULL)
{
RegisterInputCollection("Input", "name of input collection",
fInputName, TString("random"),
&fInput, TSimpleData::Class_Name());
RegisterOutputCollection("Output", "name of output collection",
fOutputName, TString("random_1"),
&fOutput, TClonesArray::Class_Name(), TSimpleData::Class_Name());
}
TAddOneProcessor::~TAddOneProcessor()
{
delete fOutput;
}
void TAddOneProcessor::Init(TEventCollection *col)
{
}
void TAddOneProcessor::Process()
{
fOutput->Clear("C");
Double_t input_data = (*fInput)->GetValue(); // TSimpleDataの値を取得
TSimpleData *output_data = static_cast<TSimpleData*>(fOutput->ConstructedAt(0));
output_data->SetValue(input_data + 1);
}
となります。
TClonesArray
で入力を受けるときとは違う点は
TSimpleData**
でinput collectionを受けるRegisterInputCollection
での入力型を直接指定- 使うところでcastはいらない
辺りでしょうか。