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はいらない

辺りでしょうか。

Shoichiro Masuoka

CNS, the Univ. of Tokyo. Dcotoral student

関連項目