ROOT 가이드

히스토그램 클래스 TH1

TH1

ROOT의 TH1 클래스는 여러가지 히스토그램을 위한 기본 클래스다. TH1은 TObject의 파생클래스이며 모든 히스토그램 클래스는 TH1으로 부터 파생된다. 대부분의 히스토그램 클래스 사용방법은 TH1에 정의 되어있다. 따라서 파생 클래스를 이용하면서 궁금한 기능들이 있다면 TH1 클래스 레퍼런스를 먼저 찾아보는 것이 좋다. 아래는 히스토그램 클래스 상속 다이어그램 이다.

그림 1 히스토그램 클래스 다이어그램 (출처: ROOT User's Guide - 3.1 The Histogram Classes)

히스토그램 클래스의 이름은 TH[차원][데이터 타입] 의 형태로 되어 있으며 각 문자/단어는 클래스를 뜻하는 T, Histogram의 H, 히스토그램의 [차원]: (1-3), 그리고 히스토그램에 저장되는 bin content의 [데이터 타입]: (I, D, etc.) 을 의미한다.

 

히스토그램 정의 및 그리기

일차원 히스토그램 TH1D를 기준으로 히스토그램 클래스를 알아보자. TH1D를 정의하는 방법은 다음과 같다.

TH1D (const char* name, const char* title, Int_t nbinsx, Double_t xlow, Double_t xup)

각 변수에 대한 설명은 다음과 같다.

  • name: 히스토그램 이름
  • title: 설명, x축, y축 이름
  • nbinsx: x축 빈 개수
  • xlow, xup: x축 범위

위 생성자대로 다음과 같은 특성을 가진 히스토그램을 그려보자.

  • 이름: name
  • 타이틀: title
  • x축 이름: x
  • y축 이름: n
  • 빈 개수: 10
  • x축 범위: [0,20) ← 0 이상 20 미만

히스토그램을 그릴 때는 Draw() 함수를 사용한다.

void example_histogram() {
    TH1D *hist = new TH1D("name", "title;x;n", 10, 0, 20);
    hist -> Draw();
}

위 정의에서 타이틀, x축 이름, y축 이름이 세미콜론(;)으로 분리되어 쓰임을 알아두자. 이 매크로를 실행하면 다음과 같은 결과를 볼 수 있다.

> root example_histogram.C
root [0]
Processing example_histogram.C...
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1
root [1] 
그림 2

위 출력에서 메세지

Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1

는 히스토그램을 그리는 공간인 TCanvas라는 그림판을 자동으로 생성하는 과정이다. TCanvas는 사용자가 만들지 않는 한 한번 밖에 생성 되지 않으므로 여러개의 그림을 그릴 때 주의해야 한다. 가장 간단하게 그림판을 생성 하는 방법은 다음과 같다.

new TCanvas;

 당연하지만 Draw() 함수를 사용하기 전에 그림판을 만들어야 한다. 이에 대한 내용은 나중에 다시 공부하도록 하자.

 

내용 채우기, 빈넘버

히스토그램에 내용을 채울 때는 Fill() 함수를 사용한다.

Int_t TH1::Fill(Double_t x)
void example_histogram() {
    TH1D *hist = new TH1D("name", "title;x;n", 10, 0, 20);
    hist -> Fill(1);
    hist -> Fill(2);
    hist -> Fill(2);
    hist -> Fill(3);
    hist -> Fill(3);
    hist -> Fill(3);
    hist -> Fill(4);
    hist -> Fill(4);
    hist -> Fill(4);
    hist -> Fill(4);
    hist -> Draw();
}

 

그림 3

Fill() 함수는 주어진 숫자가 들어가는 히스토그램 빈을 찾아서 내용을 1 만큼 채운다. 만약에 어떤 빈에 얼마만큼의 엔트리를 채워야 할지 미리 알고 있다면 SetBinContent() 를 이용할 수 있다.

void TH1::SetBinContent(Int_t bin, Double_t content)

그런데 SetBinContent() 함수를 사용하려면 bin (빈 넘버) 를 알아야 한다. 이미 알고 있다면 상관없지만 그렇지 않은 경우에는 FindBin() 함수를 이용할 수 있다. 예를 들어서 x=5 에 해당하는 빈에 4 만큼의 값을 채우고 싶다면 다음과 같이 쓸 수 있다.

auto bin = hist -> FindBin(5);
hist -> SetBinContent(bin, 4);

참고로 히스토그램의 0번 빈은 언더플로우, 즉 x<0 에 해당한다. 이후에 x 가 증가하는 방향으로 빈넘버가 1 씩 증가한다. 따라서 그림 3 의 경우 x=5 에 해당하는 빈넘버는 3 이다. ROOT의 히스토그램은 값을 채울 때 언더플로우(Underflow) 빈과 오버플로우(Overflow) 빈을 자동으로 생성한다. 언더플로우 빈은 내가 설정한 구간 보다 작은 값이 들어왔을 때 채워지고 오버플로우 빈은 내가 설정한 구간보다 큰 값이 들어왔을 때 채워진다. 앞에서 작성한 코드처럼10개의 빈을 가지는 히스토그램을 생성하면 실제로는 언더플로우와 오버플로우 빈을 합쳐서 12개의 빈을 생성한다. 0번 빈은 언더플로우 12번 빈이 오버플로우 에 해당된다.

 

참고자료

댓글

댓글 본문
버전 관리
ejungwoo
현재 버전
선택 버전
graphittie 자세히 보기