Hướng dẫn download file txt trong heej ddieeuf hanhf aix năm 2024

1 Giới thiệu về ROOT 1.1 Giới thiệu . . . . . . . . . . . . . . . . . . . 1.2 Lịch sử hình thành . . . . . . . . . . . . . . 1.3 Một số tính năng cơ bản của ROOT . . . . 1.4 Cấu trúc của ROOT . . . . . . . . . . . . . 1.5 Các lớp của ROOT . . . . . . . . . . . . . . 1.6 Cách thức cài đặt và thực thi ROOT . . . . 1.6.1 Cách cài đặt . . . . . . . . . . . . . . 1.6.2 Cách chạy chương trình trong ROOT 1.7 Một số chú ý khi sử dụng ROOT . . . . . . 1.7.1 Quy ước . . . . . . . . . . . . . . . . 1.7.2 Một số biến toàn cục quan trọng . . 1.8 CINT . . . . . . . . . . . . . . . . . . . . . 1.9 ACLiC . . . . . . . . . . . . . . . . . . . . . 1.10 Cách biên dịch macro . . . . . . . . . . . . . 2 Kiến thức C++ căn bản cho ROOT 2.1 Các lệnh xuất nhập . . . . . . . . . . . 2.2 Khai báo biến . . . . . . . . . . . . . . 2.3 Viết nhiều dòng lệnh một lúc . . . . . 2.4 Các phép toán . . . . . . . . . . . . . . 2.5 Một số cấu trúc điều khiển . . . . . . . 2.5.1 Cấu trúc điều khiển if...else... . 2.5.2 Cấu trúc lặp for . . . . . . . . 2.5.3 Cấu trúc lặp while . . . . . . . 2.5.4 Các lệnh cho vòng lặp: continue 2.6 Các lệnh dành cho file . . . . . . . . . 2.7 Mảng (Array & Vector) . . . . . . . . . 2.8 Hàm . . . . . . . . . . . . . . . . . . . 2.9 Con trỏ . . . . . . . . . . . . . . . . . 2.10 Lớp . . . . . . . . . . . . . . . . . . . . 1

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . và break . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

5 5 5 6 7 9 9 9 10 12 12 12 13 13 14

. . . . . . . . . . . . . .

15 15 15 16 16 17 17 17 18 18 18 19 20 20 21

MỤC LỤC

Đặng Nguyên Phương

2.11 Bài tập . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3 Histogram 3.1 Khai báo histogram . . . . . . . . . 3.2 Một số thao tác với histogram . . . 3.3 Chồng histogram (histogram stack) 3.4 Histogram 2 chiều và 3 chiều . . . . 3.5 Profile histogram . . . . . . . . . . 3.6 Bài tập . . . . . . . . . . . . . . . . 4 Hàm 4.1 Khai báo hàm . . . . . . . . . . 4.2 Khai báo hàm có chứa tham số 4.3 Làm khớp histogram theo hàm . 4.4 TMinuit . . . . . . . . . . . . . 4.5 Bài tập . . . . . . . . . . . . . . 5 Đồ 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9

thị Canvas và pad . . . . . . . . . Bảng chú giải . . . . . . . . . Graph . . . . . . . . . . . . . GraphError . . . . . . . . . . MultiGraph . . . . . . . . . . Các tùy chỉnh vẽ đồ thị . . . . Cách tạo văn bản và biểu thức Graphics Editor . . . . . . . . Bài tập . . . . . . . . . . . . .

6 Các 6.1 6.2 6.3 6.4 6.5 6.6

thư viện toán học Các hàm toán học . . Số ngẫu nhiên . . . . Ma trận . . . . . . . Vector . . . . . . . . Lorentz Vector . . . Bài tập . . . . . . . .

7 File 7.1 Khai báo file . . 7.2 Tree . . . . . . 7.2.1 TNtuple 7.2.2 TTree .

. . . .

. . . .

. . . .

. . . . . .

. . . .

. . . . . .

. . . .

. . . . . .

. . . .

. . . . . .

. . . .

. . . . . .

. . . .

. . . . .

. . . . .

. . . . . . . . . . . . . . . . . . toán . . . . . .

. . . . . .

. . . .

. . . . . .

. . . .

. . . . . .

. . . . 2

. . . . . .

. . . . .

. . . . . .

. . . . .

. . . . . .

. . . . .

. . . . . . . . . . . . . . . . . . học . . . . . .

. . . . . .

. . . .

. . . . . .

. . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

. . . . .

. . . . . . . . .

. . . . . .

. . . .

. . . . . .

25 25 25 29 30 31 34

. . . . .

35 35 36 38 41 44

. . . . . . . . .

46 46 49 51 52 53 54 57 59 59

. . . . . .

62 62 63 64 67 69 70

. . . .

72 72 73 74 75

MỤC LỤC

7.3

7.4 7.5

Đặng Nguyên Phương

7.2.3 Cấu trúc của tree . . . . . . . . . Cách tạo và truy xuất dữ liệu từ file root 7.3.1 Cách tạo file root . . . . . . . . . 7.3.2 Cách truy xuất file root . . . . . Xử lý số liệu có cấu trúc dạng tree . . . Bài tập . . . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

76 77 77 78 80 84

Lời kết

85

Tài liệu tham khảo

86

A Cách cài đặt ROOT cho HĐH Linux

87

B Bảng kí hiệu màu và marker

89

C Kí hiệu LATEX trong ROOT

90

3

Lời nói đầu Tập tài liệu Hướng dẫn sử dụng ROOT cho hệ điều hành Windows được biên soạn nhằm mục đích giới thiệu cho các bạn trong nhóm NMTP về gói phần mềm mã nguồn mở ROOT, một trong những công cụ xử lý số liệu phổ biến nhất hiện nay trong ngành Vật lý Hạt nhân và Năng lượng cao. Mặc dù đây là một công cụ khá thông dụng, đã và đang được sử dụng trong hầu hết các thí nghiệm lớn trên thế giới, tuy nhiên lại khá lạ lẫm với các bạn sinh viên chuyên ngành Vật lý Hạt nhân tại Việt Nam. Do đó qua tập tài liệu này, tôi hi vọng sẽ giới thiệu đến các bạn thêm một công cụ xử lý số liệu hữu ích nữa bên cạnh các công cụ mà các bạn đang sử dụng như Origin, Matlab,... Nội dung của tài liệu tập trung vào những vấn đề cơ bản, cốt lõi nhất của ROOT, các kiến thức được trình bày ngắn gọn và đi kèm các ví dụ minh họa nhằm làm sáng tỏ thêm vấn đề. Các chủ đề được lựa chọn trình bày trong tài liệu này là các vấn đề cơ bản cần nắm vững mà tác giả đã đúc kết được sau một thời gian sử dụng ROOT. Ngoài ra, cuối mỗi phần đều có các bài tập để các bạn có thể luyện tập với các kiến thức đã thu nhận. Tập tài liệu được biên soạn nhằm mục đích trình bày sơ lược cho các bạn những kiến thức và kĩ năng cơ bản nhất trong việc sử dụng ROOT cho công việc của mình. Do đó, nội dung của bài viết khá cô đọng và không đi quá sâu vào chi tiết. Để có thể tìm hiểu về ROOT một cách trọn vẹn hơn, các bạn có thể vào trang web của ROOT tại http://root.cern.ch/drupal/; hoặc tham gia trao đổi, thảo luận với các chuyên gia tại http://root.cern.ch/drupal/content/roottalk-digest.

Đặng Nguyên Phương

4

Chương 1 Giới thiệu về ROOT 1.1

Giới thiệu

ROOT là một framework (thư viện chứa các mã lệnh) dùng cho việc phân tích và xử lý số liệu, chủ yếu cho ngành Vật lý Hạt nhân và Hạt cơ bản (Vật lý Năng lượng cao). Chương trình này được xây dựng dựa trên ngôn ngữ lập trình C++ với khả năng lập trình hướng đối tượng (object-oriented programing). ROOT được phát triển đầu tiên bởi René Brun và Fons Rademakers vào giữa những năm 1990 tại Tổ chức Nghiên cứu Nguyên tử Châu Âu (CERN), và đến khoảng những năm đầu thế kỉ 21 nó đã thay thế hoàn toàn cho các framework được xây dựng bằng ngôn ngữ Fortran trước đó tại tổ chức này. Một điểm đặc trưng dễ nhận thấy nhất của ROOT đó là việc tổ chức, sắp xếp dữ liệu dưới dạng cây (tree) nhằm giúp cho việc lưu trữ và xử lý một lượng lớn dữ liệu được hiệu quả hơn. Hiện nay, chương trình này đang được sử dụng trong các thí nghiệm tại Large Hadron Collider (LHC) và tại hầu hết các thí nghiệm vật lý năng lượng cao trên thế giới.

1.2

Lịch sử hình thành

ROOT được phát triển trong dự án thí nghiệm NA49 tại trung tâm Nghiên cứu Nguyên tử Châu Âu (CERN). Thí nghiệm này đòi hỏi phải xử lý một lượng dữ liệu rất lớn, khoảng 10 Terabytes/run, do đó đòi hỏi phải phát triển một thế hệ công cụ xử lý dữ liệu mới để thay thế cho công cụ hiện đang có. Vào giữa những năm 1990, René Brun và Fons Rademakers sau nhiều năm phát triển các công cụ xử lý và mô phỏng cho các thí nghiệm vật lý năng lượng cao như PAW, PIAF, GEANT đã nhận ra rằng các thư viện ngôn ngữ lập trình Fortran dường như đã đạt tới giới hạn của nó. Dù cho vẫn còn rất thông dụng, các công cụ này cần phải được nâng cấp để có thể tương thích cho lượng dữ liệu khổng lồ của các thí nghiệm trong tương lai, đặc 5

CHƯƠNG 1. GIỚI THIỆU VỀ ROOT

Đặng Nguyên Phương

biệt là các thí nghiệm tại Large Hadron Collider (LHC). Cùng lúc đó, sự phát triển của khoa học máy tính đặc biệt là kĩ thuật lập trình hướng đối tượng đã tạo tiền đề để họ xây dựng một công cụ dựa trên nền tảng kĩ thuật này. Sự phát triển của ROOT phần lớn là nhờ vào sự tương tác của những người dùng và người phát triển. Vì đây là mã nguồn mở cho nên bản thân người dùng cũng có thể trở thành người phát triển bằng cách xây dựng và tích hợp các mã nguồn của mình vào trong ROOT. Từ năm 1995 đến nay, đã có rất nhiều phiên bản ROOT được ra đời: • 11/1995: phiên bản đầu tiên ROOT 0.5 được công bố • 1996: sử dụng CINT cho ROOT • 1997: phiên bản ROOT 1.0 • 1998: phiên bản ROOT 2.0 • 2001: phiên bản ROOT 3.0 • 2004: phiên bản ROOT 4.0 • 2005: phiên bản ROOT 5.0 • 2011: phiên bản ROOT 5.32 • 2013: phiên bản ROOT 5.34

1.3

Một số tính năng cơ bản của ROOT

• Lưu trữ dữ liệu: chúng ta có thể lưu trữ các dữ liệu (thô hoặc đã qua xử lý) và thậm chí là các đối tượng C++ vào trong các file nén dạng .root. Các dữ liệu được lưu lại dưới dạng cấu trúc cây (tree) giúp cho tốc độ truy xuất dữ liệu được tăng lên nhanh chóng so với việc truy xuất các dữ liệu dạng thông thường. • Truy xuất dữ liệu: dữ liệu được lưu trữ trong các file root có thể được truy xuất từ máy tính hoặc thông qua mạng internet. Với các dữ liệu có kích thước lớn, ta có thể lưu trữ trên mạng grid. Các dữ liệu có thể được chia nhỏ ra nhiều file root khác nhau và được liên kết lại trong quá trình xử lý. • Xử lý dữ liệu: ROOT là một thư viện lớn tập hợp rất nhiều các công cụ toán học và thống kê giúp chúng ta có thể xử lý dữ liệu một cách tốt nhất. ROOT cũng hỗ trợ các xử lý theo hướng lập trình hướng đối tượng hoặc lập trình song song.

6

CHƯƠNG 1. GIỚI THIỆU VỀ ROOT

Đặng Nguyên Phương

• Trình bày kết quả: các kết quả có thể được trình bày theo rất nhiều dạng khác nhau (histogram, chấm điểm, đường,...) và có thể được hiệu chỉnh trực tiếp trên hình vẽ. Các hình vẽ trong ROOT có thể được xuất ra theo nhiều định dạng khác nhau (pdf, eps, png,...). • Mô phỏng: ROOT có khả năng mô tả các hình học không gian phức tạp, việc mô phỏng trong ROOT được thực hiện thông qua các gói mô tả hình học, tracker và Monte Carlo ảo.

1.4

Cấu trúc của ROOT

Hình 1.1 trình bày cấu trúc của ROOT. Các thư mục chính của ROOT gồm có: bin, lib, include, tutorials và test.

Hình 1.1: Cấu trúc của ROOT

bin chứa các file thực thi (executable). Một số file quan trọng trong thư mục bin: • root.exe: chạy root • rootcint: cung cấp thư viện các lớp cho CINT • rmkdepend: phiên bản của makedepend cho ROOT 7

CHƯƠNG 1. GIỚI THIỆU VỀ ROOT

Đặng Nguyên Phương

• root-config: script xác định các flag và thư viện cho việc biên dịch chương trình có sử dụng ROOT • cint: chạy trình thông dịch C++ • makecint: xác định các flag và thư viện của rootcint • proofd: chương trình daemon tạo user cho quá trình tính toán song song bằng ROOT (PROOF) • proofserv: thực hiện tính toán PROOF • rootd: chương trình daemon dùng để điều khiển việc truy xuất các file lib chứa thư viện chia sẻ (shared object) của các lớp được định nghĩa trong ROOT, người dùng có thể liên kết các thư viện này với chương trình của mình. Hình 1.2 trình bày sự phụ thuộc giữa các thư viện với nhau.

include chứa các file header mô tả định nghĩa của các lớp.

tutorials chứa các file ví dụ giúp người dùng nắm rõ thêm về các khái niệm, kĩ thuật trong ROOT.

test chứa các file ví dụ để test framework. Khi một phiên bản mới của framework được xây dựng, các ví dụ trong thư mục này sẽ được biên dịch và thực thi để test khả năng của phiên bản mới.

Hình 1.2: Sự phụ thuộc của các thư viện trong ROOT

8

CHƯƠNG 1. GIỚI THIỆU VỀ ROOT

1.5

Đặng Nguyên Phương

Các lớp của ROOT

Trong ROOT hiện có khoảng hơn 250 lớp (class) được chia thành 11 loại: • Các lớp cơ bản: bao gồm các lớp ở tầng thấp nhất trong cấu trúc lớp của ROOT, làm nền tảng để xây dựng nên các lớp khác. VD: TObject, TClass,... • Các lớp lưu trữ: bao gồm các lớp tạo cấu trúc dữ liệu (array, list, set,...) • Các lớp histogram:bao gồm các lớp histogram 1D, 2D, 3D, các lớp làm khớp dữ liệu, hàm. • Các lớp ntuple: bao gồm các lớp như TTree, TNtuple,... • Các lớp đồ họa 2D: bao gồm các đồ họa 2D cơ bản (đường thẳng, hình hộp, ellipse,...) • Các lớp đồ họa 3D: bao gồm có khối hình học 3D và các hình học detector. • Các lớp giao diện người dùng MOTIF: chứa các thành phần giao diện tương tự như các công cụ khác như cửa sổ, nút bấm, menu,... • Các lớp giao diện tương tác: chứa các ứng dụng tương tác, trình thông dịch C++. • Các lớp tương tác với hệ điều hành: các lớp tương tác với hệ điều hành thông qua TSystem (TUnixSystem, TWinNTSystem, TMacSystem). • Các lớp mạng (network): các ứng dụng xây dựng hệ thống mạng. • Các lớp tài liệu: cho phép tạo các tài liệu (dạng HTML), file header và source C++,...

1.6 1.6.1

Cách thức cài đặt và thực thi ROOT Cách cài đặt

ROOT là gói phần mềm mã nguồn mở miễn phí, có thể được download tại trang web http: //root.cern.ch/drupal/, thích hợp cho rất nhiều hệ điều hành như Linux, Windows, Mac OS,... Trong phần này tác giả chỉ trình bày cách thức cài đặt ROOT cho hệ điều hành Windows, còn cách cài đặt cho hệ điều hành Linux được trình bày trong phần Phụ lục A. Đối với cho hệ điều hành Windows, cách thức đơn giản nhất để cài đặt ROOT là cài đặt thẳng file binary của chương trình này, các bước tiến hành như sau:

9

CHƯƠNG 1. GIỚI THIỆU VỀ ROOT

Đặng Nguyên Phương

• Download ROOT tại: http://root.cern.ch/drupal/content/downloading-root, nhấp chọn version cần download (Hình 1.3). • Ứng với mỗi version sẽ có nhiều file source khác nhau cho mỗi hệ điều hành, chọn file có đuôi .msi cho hệ điều hành Windows (Hình 1.4). • Double click vào file đã download và cài đặt như những chương trình bình thường.

Hình 1.3: Các phiên bản của ROOT

Hình 1.4: File download

1.6.2

Cách chạy chương trình trong ROOT

Để khởi động ROOT, ta có thể thực hiện 1 trong 2 cách sau: • Cách 1: double click vào biểu tượng ROOT được tạo ra sau khi cài đặt. • Cách 2: mở cửa sổ Command Prompt, gõ lệnh root hoặc root -l. • Gõ lệnh .q để thoát ra khỏi ROOT. Để thực thi các lệnh, ta có thể gõ các lệnh này trực tiếp tại dấu nhắc lệnh của ROOT hoặc tạo một file macro và chạy file này tại dấu nhắc lệnh của ROOT. Thông thường các 10

CHƯƠNG 1. GIỚI THIỆU VỀ ROOT

Đặng Nguyên Phương

Hình 1.5: Giao diện khi khởi động của ROOT file macro được sử dụng trong ROOT là các file C++, cho nên thường có đuôi dạng như .c, .cpp hoặc .cxx. Các lệnh trong file macro được bao lại bởi một cặp ngoặc nhọn {}. Ví dụ: tạo một file macro ten.cxx yêu cầu người dùng nhập vào tên của mình: { Char_t ten [ 1 0 0 ] ; cout Draw ( " i s o " ) ; }

3.5

Profile histogram

Profile histogram nhằm giúp cho người dùng thấy được sự tương quan giữa các biến với nhau trong cùng một histogram (2 chiều hoặc 3 chiều). Trong một số trường hợp, các profile có thể được xem là sự biểu diễn thay thế cho các đồ thị histogram nhiều chiều. 31

CHƯƠNG 3. HISTOGRAM

Đặng Nguyên Phương

Hình 3.5: Ví dụ histogram 3 chiều Nhiệm vụ của profile là biểu diễn giá trị trung bình và sai số của một biến theo từng bin của biến kia. Ví dụ: Profile 1 chiều (xem Hình 3.6) { TProfile ∗ hprof = new TProfile ( " h p r o f " , " P r o f i l e o f pz v e r s u s px" ,100 , −4 ,4 ,0 ,20) ; Float_t px , py , pz ; f o r ( Int_t i=0; i Rannor ( px , py ) ; pz = px∗px + py∗py ; hprof−>Fill ( px , pz , 1 ) ; } hprof−>Draw ( ) ; }

Ví dụ: Profile 2 chiều (xem Hình 3.7) { TProfile2D ∗ hprof2d

\= new TProfile2D ( " h p r o f 2 d " , " P r o f i l e o f pz

v e r s u s px and py" , 4 0 , − 4 , 4 , 4 0 , − 4 , 4 , 0 , 2 0 ) ; Float_t px , py , pz ; f o r ( Int_t i=0; i Rannor ( px , py ) ; pz = px∗px + py∗py ; hprof2d−>Fill ( px , py , pz , 1 ) ;

32

CHƯƠNG 3. HISTOGRAM

Đặng Nguyên Phương

Hình 3.6: Ví dụ profile 1 chiều } hprof2d−>Draw ( ) ; }

Hình 3.7: Ví dụ profile 2 chiều

33

CHƯƠNG 3. HISTOGRAM

3.6

Đặng Nguyên Phương

Bài tập

1. Một nguồn phóng xạ A có hoạt độ phóng xạ năm 2000 là 1.2 mCi, vẽ đồ thị biểu diễn hoạt độ của nguồn này theo từng năm trong khoảng thời gian từ năm 2000 đến 2020, biết chu kì bán rã của nguồn này là 8 năm. 2. Một sinh viên tiến hành thí nghiệm đo số đếm ghi nhận được theo khoảng cách từ vị trí đứng đến nguồn. Số đếm ghi nhận được theo khoảng cách được trình bày trong Bảng 3.1, vẽ đồ thị phân bố số đếm theo khoảng cách và ước lượng số đếm ghi nhận được tại khoảng cách d = 1.8m. Bảng 3.1: Số đếm theo khoảng cách Khoảng cách (m) 1 1.2 1.5 2 2.5 Số đếm 541 353 169 42 8

3. Sử dụng file phổ phóng xạ đo được tại http://nmtp.wikispaces.com/file/detail/ pho_do.tka và phông nền tại http://nmtp.wikispaces.com/file/detail/phong_ nen.tka, ghi các số đếm của hai phổ này vào các histogram tương ứng. • Xác định vị trí kênh có số đếm lớn nhất, nhỏ nhất của phổ đo. • Vẽ các histogram của phổ đo, phông nền và phổ đo đã trừ cho phông nền trên cùng 1 đồ thị. Gợi ý: để vẽ một histogram trên cùng đồ thị với histogram đã được vẽ trước đó, ta thêm option same vào trong lệnh vẽ − Draw("same") • Tính diện tích đỉnh sau khi đã trừ phông.

34

Chương 4 Hàm Trong ROOT, lớp hàm (function) được kí hiệu là TFd, với d là số chiều của của hàm. Ví dụ TF1 là lớp hàm 1 chiều, TF2 là lớp hàm 2 chiều,...

4.1

Khai báo hàm

Cú pháp chung cho việc khai báo một hàm là: * = new ("", "", , ); Ta có thể khai báo công thức của một hàm theo 1 trong 3 cách sau: Cách 1: tạo trực tiếp một hàm dựa vào các công thức C++ có sẵn Ví dụ: Khai báo hàm sin(x)/x (xem Hình 4.1) root [ 0 ] TF1 ∗f = new TF1 ( " f " , " s i n ( x ) /x" , 0 , 1 0 0 ) root [ 1 ] f−>Draw ( )

Cách 2: tạo trực tiếp một hàm dựa vào lớp TMath Ví dụ: Khai báo hàm Gaussian có x¯ = 50 và σ = 5.3 (xem Hình 4.2) root [ 0 ] TF1 ∗f = new TF1 ( " f " , " [ 0 ] ∗ TMath : : Gaus ( x , 5 0 , 5 . 3 ) " , 0 , 2 0 0 ) root [ 1 ] f−>Draw ( )

Cách 3: tự định nghĩa hàm riêng Ví dụ: Khai báo hàm x2 + x + 1 = 0 (xem Hình 4.3) Double_t my_func ( Double_t x ) { r e t u r n ( x∗x+x+1) ; } root [ 0 ] TF1 ∗f = new TF1 ( " f " , "my_func ( x ) " , 0 , 1 0 0 )

35

CHƯƠNG 4. HÀM

Đặng Nguyên Phương

Hình 4.1: Đồ thị của hàm sin(x)/x

Hình 4.2: Đồ thị của hàm Gauss(50,5.3) root [ 1 ] f−>Draw ( )

4.2

Khai báo hàm có chứa tham số

Trong trường hợp khai báo các hàm có tham số, kí hiệu của các tham số được đặt trong cặp ngoặc vuông []. Giá trị của các tham số có thể được gán thông qua hàm SetParameter() 36

CHƯƠNG 4. HÀM

Đặng Nguyên Phương

Hình 4.3: Đồ thị của hàm my_func(x) cho từng tham số hoặc SetParameters() cho nhiều tham số cùng lúc. Ví dụ: Khai báo hàm a cos(x) + b (xem Hình 4.4) root [ 0 ] TF1 ∗f = new TF1 ( " f " , " [ 0 ] ∗ c o s ( x ) + [ 1 ] " , −10, 1 0 ) root [ 1 ] f−>SetParameter ( 0 , 5 )

// a = 5

root [ 2 ] f−>SetParameter ( 1 , 3 )

// b = 3

root [ 3 ] f−>Draw ( )

Hình 4.4: Đồ thị của hàm a cos(x) + b

37

CHƯƠNG 4. HÀM

4.3

Đặng Nguyên Phương

Làm khớp histogram theo hàm

Để làm khớp histogram, ta có thể dùng lệnh Fit() (xem thêm tại http://root.cern. ch/root/HowtoFit.html và http://root.cern.ch/root/html/TH1.html

TH1:Fit) với cú pháp sau: −>Fit(, ,... ) Đối với một số hàm đặc biệt, ta chỉ cần khai báo từ khóa mà không cần phải khai báo hàm: • gaus: hàm Gaussian với 3 tham số, f(x) = [0]*exp(-0.5*((x-[1])/[2])**2) • expo: hàm e mũ với 2 tham số, f(x) = exp([0]+[1]*x) • polN: hàm đa thức bậc N, f(x) = [0] + [1]*x + [2]*x**2 + ... Một số option thường được sử dụng khi làm khớp: • W: chuyển tất cả trọng số của các bin khác 0 về 1. • WW: chuyển tất cả trọng số của các bin về 1. • L: sử dụng phương pháp log likelihood. • U: sử dụng phương pháp làm khớp do người dùng tự định nghĩa. • V: sử dụng verbose mode. • E: sử dụng kĩ thuật Minos trong ước lượng sai số. • 0: không vẽ kết quả làm khớp. Ví dụ: Gieo số ngẫu nhiên phân bố dạng Gauss và làm khớp lại theo dạng này (xem Hình 4.5) { TH1F ∗h = new TH1F ( "h" , " Gaussian " , 1 0 0 , 0 , 2 0 0 ) ; Float_t mean = 1 0 0 , sigma = 2 0 ; f o r ( Int_t i = 0 ; i < 1 0 0 0 ; i++) {

// g i e o ngau n h i e n 1000 l a n

h−>Fill ( gRandom−>Gaus ( mean , sigma ) ) ;

// g i e o ngau n h i e n t h e o

phan bo Gauss } TF1 ∗f = new TF1 ( " f " , " [ 0 ] ∗ TMath : : Gaus ( x , [ 1 ] , [ 2 ] ) " , 0 , 2 0 0 ) ; f−>SetParameters ( 1 0 , 1 0 , 1 0 ) ; h−>Fit ( " f " ) ; h−>Draw ( ) ;

// t a co t h e su dung f −>F i t ( " gaus " ) thay t h e // ve h i s t o g r a m h

38

CHƯƠNG 4. HÀM

Đặng Nguyên Phương

f−>Draw ( "same" ) ;

// ve ham lam khop f t r e n cung do t h i

}

Kết quả làm khớp như sau: FCN =65.1586 FROM MIGRAD STATUS=CONVERGED 358 CALLS 359 TOTAL EDM =4.68058 e−009 STRATEGY= 1 ERROR MATRIX ACCURATE EXT NO . 1 2 3

PARAMETER NAME p0 p1 p2

VALUE 3 . 6 3 1 3 2 e+001 1 . 0 0 2 6 2 e+002 2 . 0 6 8 2 6 e+001

ERROR 1 . 5 2 6 2 3 e+000 6 . 9 4 9 9 8 e−001 5 . 7 6 0 7 8 e−001

STEP FIRST SIZE DERIVATIVE 4 . 7 1 7 0 9 e−003 6 . 1 4 7 8 9 e−005 2 . 7 6 0 1 3 e−003 −9.82112e−007 1 . 7 8 0 3 6 e−003 2 . 1 2 4 7 0 e−004

Hình 4.5: Đồ thị làm khớp hàm dạng Gauss Trong trường hợp muốn cố định 1 tham số trong quá trình làm khớp, ta có thể sử dụng lệnh FixParameter, ví dụ f−>FixParameter ( 0 , 1 . ) ;

Ngoài ra ta cũng có thể xác định khoảng làm khớp h−>Fit ( " f " , " " , " " , 4 0 , 1 6 0 ) ;

Các tham số làm khớp có thể được truy xuất qua các lệnh sau: • GetFunction("f"): lấy hàm đã được làm khớp 39

CHƯƠNG 4. HÀM

Đặng Nguyên Phương

• GetChisquare(): giá trị χ2 của việc làm khớp • GetParameter(i): giá trị của tham số thứ i • GetParError(i): sai số của tham số thứ i Ví dụ: root [ 1 ] f−>GetChisquare ( ) ( c o n s t Double_t ) 6 . 5 1 5 8 5 9 7 6 9 2 8 2 9 4 1 7 0 e+001 root [ 2 ] f−>GetParameter ( 1 ) ( c o n s t Double_t ) 1 . 0 0 2 6 1 6 3 4 2 8 3 0 9 2 4 5 0 e+002 root [ 3 ] f−>GetParError ( 1 ) ( c o n s t Double_t ) 6 . 9 4 9 9 7 6 4 1 7 1 9 1 0 3 6 1 0 e−001

Ví dụ: Làm khớp số liệu với đỉnh Gaussian và phông nền đa thức bậc 2 (xem Hình 4.6) // Ham mo t a phong nen dang da thuc bac 2 Double_t background ( Double_t ∗x , Double_t ∗ par ) { r e t u r n par [ 0 ] + par [ 1 ] ∗ x [ 0 ] + par [ 2 ] ∗ x [ 0 ] ∗ x [ 0 ] ; } // Ham mo t a dinh dang Gaussian Double_t Gaussian ( Double_t ∗x , Double_t ∗ par ) { r e t u r n ( par [ 0 ] ∗ TMath : : Gaus ( x [ 0 ] , par [ 1 ] , par [ 2 ] ) ) ; } // Ham lam khop bang tong cua ham dinh Gaussian va phong nen Double_t function ( Double_t ∗x , Double_t ∗ par ) { r e t u r n background ( x , par ) + Gaussian ( x,& par [ 3 ] ) ; } // Thuc h i e n v i e c lam khop v o i d fitting ( ) { c o n s t i n t nBins = 5 0 ; Double_t data [ nBins ] = { 1 5 , 2 2 , 2 5 , 1 8 , 2 2 , 2 2 , 1 6 , 2 1 , 1 9 , 20 ,34 ,41 ,45 ,49 ,72 ,77 ,91 ,89 , 90 ,94 ,96 ,94 ,84 ,80 ,64 ,61 ,52 , 38 ,39 ,31 ,32 ,24 ,25 ,25 ,30 ,20 , 27 ,20 ,20 ,14 ,16 ,18 ,12 ,23 , 8 ,22 ,17 ,12 ,23 ,12}; TH1F ∗h = new TH1F ( "h" , " Gaussian + background " , 5 0 , 0 , nBins ) ; f o r ( i n t i=0; i < nBins ;

i++) {

40

CHƯƠNG 4. HÀM

Đặng Nguyên Phương

h−>SetBinContent ( i+1, data [ i ] ) ; } h−>Sumw2 ( ) ; // t a o ham TF1 tu 0 den nBins , co 6 tham s o ( 3 cho phong nen , 3 cho dinh ) TF1 ∗f = new TF1 ( " f " , function , 0 , nBins , 6 ) ; // dua tham s o dau vao f−>SetParameter ( 4 , 2 0 ) ;

// uoc l u o n g v i t r i dinh

f−>SetParameter ( 5 , 1 0 ) ;

// uoc l u o n g be rong dinh

h−>Fit ( " f " ) ; // khao bao ham r i e n g cho phong nen va dinh TF1 ∗ bkg = new TF1 ( " bkg " , background , 0 , 5 0 , 3 ) ; bkg−>SetLineColor ( 3 ) ; TF1 ∗ peak = new TF1 ( " peak " , Gaussian , 0 , 5 0 , 3 ) ; peak−>SetLineColor ( 4 ) ; Double_t par [ 6 ] ; // dua c a c tham s o vao ham phong nen va dinh sau do ve c a c ham nay f−>GetParameters ( par ) ; bkg−>SetParameters ( par ) ; bkg−>Draw ( "same" ) ; peak−>SetParameters(&par [ 3 ] ) ; peak−>Draw ( "same" ) ; }

4.4

TMinuit

Minuit là một gói làm khớp bằng phương pháp cực tiểu hóa hàm mục tiêu (objective function) nằm trong PACKLIB, được viết đầu tiên bằng ngôn ngữ lập trình Fortran bởi Fred James và được chuyển sang lớp TMinuit bằng ngôn ngữ C++ bởi Réne Brun. Chi về lớp này có thể được xem tại http://root.cern.ch/root/html/TMinuit.html. Các bước tiến hành làm khớp sử dụng lớp TMinuit • Xây dựng hàm để cực tiểu hóa "FCN" (chi square, likelihood,...). • Khai báo dữ liệu để làm khớp.

41

CHƯƠNG 4. HÀM

Đặng Nguyên Phương

Hình 4.6: Làm khớp số liệu với dạng đỉnh Gaussian và phông nền đa thức bậc 2 • Khai báo đối tượng thuộc lớp TMinuit để làm khớp, các tham số và khoảng làm khớp, cùng với các kiều làm khớp – SIMPLEX: tìm cực tiểu địa phương, ưu điểm của phương pháp này là tốc độ nhanh, tuy nhiên độ chính xác không cao lắm. – MIGRAD: làm khớp hàm địa phương sử dụng phương pháp Davidson-FletcherPowell cải tiến. – HESSE: tính ma trận đạo hàm bậc hai của hàm FCN sử dụng phương pháp vi phân hữu hạn (finite difference method ), thường được sử dụng để tối ưu kết quả thu được từ MIGRAD. – MINOS: phân tích sai số (bất đối xứng), thông thường ta hay sử dụng ít nhất hai phương pháp (HESSE được sử dụng ngay sau MIGRAD). Còn MINOS được sử dụng để tối ưu sai số của các giá trị làm khớp. • Trả về kết quả làm khớp (cùng với các kiểm tra thống kê). Ví dụ: Float_t z [ 5 ] , x [ 5 ] , y [ 5 ] , errorz [ 5 ] ; //_________________________________________________________________ v o i d fcn ( Int_t &npar , Double_t ∗gin , Double_t &f , Double_t ∗par , Int_t iflag ) { c o n s t Int_t nbins = 5 ; Int_t i ;

42

CHƯƠNG 4. HÀM

Đặng Nguyên Phương

// Tinh c h i s q u a r e Double_t chisq = 0 ; Double_t delta ; f o r ( i=0;iSetFCN ( fcn ) ; Double_t arglist [ 1 0 ] ; Int_t ierflg = 0 ; arglist [ 0 ] = 1 ; gMinuit−>mnexcm ( "SET ERR" , arglist , 1 , ierflg ) ; // Khai bao c a c g i a t r i ban dau va buoc nhay cua c a c tham s o s t a t i c Double_t vstart [ 4 ] = { 3 , 1 , 0 . 1 , 0 . 0 1 } ; s t a t i c Double_t step [ 4 ] = { 0 . 1 , 0 . 1 , 0 . 0 1 , 0 . 0 0 1 } ; gMinuit−>mnparm ( 0 , " a1 " , vstart [ 0 ] , step [ 0 ] , 0 , 0 , ierflg ) ; gMinuit−>mnparm ( 1 , " a2 " , vstart [ 1 ] , step [ 1 ] , 0 , 0 , ierflg ) ; gMinuit−>mnparm ( 2 , " a3 " , vstart [ 2 ] , step [ 2 ] , 0 , 0 , ierflg ) ; gMinuit−>mnparm ( 3 , " a4 " , vstart [ 3 ] , step [ 3 ] , 0 , 0 , ierflg ) ; // Thuc h i e n buoc tim cuc t i e u arglist [ 0 ] = 5 0 0 ; arglist [ 1 ] = 1 . ; gMinuit−>mnexcm ( "MIGRAD" , arglist , 2 , ierflg ) ; // In k e t qua Double_t amin , edm , errdef ; Int_t nvpar , nparx , icstat ; gMinuit−>mnstat ( amin , edm , errdef , nvpar , nparx , icstat ) ; gMinuit−>mnprin ( 3 , amin ) ; }

4.5

Bài tập

1. Vẽ đồ thị các hàm: - |x| - ln(x2 −x + 1)

44

CHƯƠNG 4. HÀM

Đặng Nguyên Phương

- Bessel - Mexican hat 2. Làm khớp bộ số liệu được cho trong Bảng 4.1 theo dạng hàm tuyến tính. Bảng x 0.2 y 1.0 ∆y 0.4

4.1: Bảng số liệu (x,y) 2.0 3.3 4.1 6.2 7.0 1.5 1.9 2.5 2.7 3.7 0.2 0.5 0.3 0.9 0.5

3. Download file số liệu tại http://nmtp.wikispaces.com/file/detail/2gaus.txt. Làm khớp số liệu thu được với hai hàm Gaussian. 4. Download file số liệu tại http://nmtp.wikispaces.com/file/detail/gaus%2Bpoly. txt. Làm khớp số liệu thu được với hai hàm Gaussian và đa thức bậc 2. So sánh kết quả thu được khi có cho tham số đầu vào và khi không cho tham số. Nhận xét?

45

Chương 5 Đồ thị 5.1

Canvas và pad

Canvas là một cửa sổ mà hình ảnh có thể được hiển thị trên đó. Một canvas có thể được chia thành 1 hay nhiều khu vực vẽ, các khu vực vẽ này được gọi là pad. Trong ROOT, nếu canvas không được khai báo trước khi vẽ hình, chương trình sẽ mặc định tạo ra canvas có tên là c1, và pad tương ứng cũng có cùng tên với canvas này. Một pad có thể nằm trong 1 canvas hoặc nằm trong 1 pad khác. Cú pháp khai báo canvas như sau: TCanvas * = new TCanvas("", "", , ) hoặc TCanvas * = new TCanvas("", "", form) với

form form form form form

\= = = = =

1 2 3 4 5

kích kích kích kích kích

thước thước thước thước thước

700 × 500 500 × 500 500 × 500 500 × 500 500 × 500

tại tại tại tại tại

(10,10) (20,20) (30,30) (40,40) (50,50)

Cú pháp khai báo pad như sau: TPad * = new TPad("", "", xlow, ylow, xup, yup, color, bordersize, bordermode) Trong đó: xlow ylow xup yup

vị trí của điểm dưới bên trái của pad đang khai báo tọa độ y của điểm đó vị trí của điểm trên bên phải của pad đang khai báo tọa độ y của điểm đó 46

CHƯƠNG 5. ĐỒ THỊ

color bordersize bordermode bordermode bordermode

Đặng Nguyên Phương

kí hiệu màu của pad (xem Phụ lục B) kích thước biên của pad (tính theo pixel) hiệu ứng biên chìm xuống (= −1) không có hiệu ứng (= 0) hiệu ứng biên nổi lên (= 1)

Một số lệnh liên quan đến canvas và pad: (xem thêm tại http://root.cern.ch/root/html/TPad.html và http://root.cern.ch/ root/html/TCanvas.html) • Divide(nx,ny): chia canvas/pad ra làm nhiều phần theo trục x và y, các pad nhỏ bên trong sẽ được đánh số từ 1 đến nx*ny • cd(i): chọn pad nhỏ thứ i, mặc định cd() = cd(0) tức là chọn chính canvas/pad đó • GetPad(i): chọn pad thứ i (trường hợp nằm trong một pad khác) • SetCanvasSize(w,h): chỉnh kích thước cho canvas • SetBorderSize(): chỉnh kích thước cho biên • SetBorderMode(): chỉnh kiểu cho biên • SetLogx(), SetLogy(), SetLogz(): vẽ trục x,y,z theo thang log • SetGrid(), SetGridx(), SetGridy(): vẽ lưới cho trục tọa độ • SetTicks(), SetTickx(), SetTicky(): đánh dấu các khoảng chia cho trục tọa độ • Print("file"): lưu nội dung trong hình vẽ ra file • SaveAs("file"): tương tự Print Ví dụ 1: (xem Hình 5.1) { TH1F ∗h1 = new TH1F ( "h1" , " 1D Gaussian " , 1 0 0 , −100 , 1 0 0 ) ; TH2F ∗h2 = new TH2F ( "h2" , " 2D Gaussian " , 100 , −100 , 1 0 0 , 1 0 0 , −100 , 100) ; h1−>Sumw2 ( ) ; h2−>Sumw2 ( ) ; Float_t mean = 0 , sigma = 2 0 ; f o r ( Int_t i = 0 ; i < 1 0 0 0 0 ; i++) { h1−>Fill ( gRandom−>Gaus ( mean , sigma ) ) ; h2−>Fill ( gRandom−>Gaus ( mean , sigma ) , gRandom−>Gaus ( mean , sigma ) ) ; }

47

CHƯƠNG 5. ĐỒ THỊ

Đặng Nguyên Phương

TCanvas ∗c = new TCanvas ( " c " , " Gaussian " , 1 2 0 0 , 8 0 0 ) ;

// t a o

canvas co k i c h thuoc 1200 x800 c−>Divide ( 2 , 2 ) ; c−>cd ( 1 ) ;

// c h i a canvas thanh 4 pad nho

// chon pad thu 1

h1−>Draw ( " h i s t o " ) ; c−>cd ( 2 ) ;

// chon pad thu 2

h1−>Fit ( " gaus " ) ; c−>cd ( 3 ) ;

// lam khop va ve h1

// chon pad thu 3

h2−>Draw ( " s u r f 2 " ) ; c−>cd ( 4 ) ;

// ve h1 t h e o dang h i s t o g r a m

// ve h2 t h e o dang s u r f a c e

// chon pad thu 4

h2−>Draw ( " c o l " ) ;

// ve h2 t h e o dang c o l o r

}

Hình 5.1: Đồ thị phân bố ngẫu nhiên dạng Gauss 1 chiều và 2 chiều Ví dụ 2: (xem Hình 5.2) { TH1F ∗h1 = new TH1F ( "h1" , " 1D Gaussian " , 1 0 0 , −100 , 1 0 0 ) ; h1−>Sumw2 ( ) ; Float_t mean = 0 , sigma = 2 0 ; f o r ( Int_t i = 0 ; i < 1 0 0 0 0 ; i++) { h1−>Fill ( gRandom−>Gaus ( mean , sigma ) ) ; } TCanvas ∗c = new TCanvas ( " c " , " Gaussian " , 6 0 0 , 3 0 0 ) ;

48

CHƯƠNG 5. ĐỒ THỊ

Đặng Nguyên Phương

c−>Divide ( 2 , 1 ) ; c−>cd ( 1 )−>SetLogy ( ) ;

// chon thang l o g cho t r u c y

h1−>Draw ( ) ; c−>cd ( 2 )−>SetGrid ( ) ; // ve l u o i cho x va y h1−>Draw ( " h i s t o " ) ; }

Hình 5.2: Đồ thị phân bố ngẫu nhiên dạng Gauss 1 chiều

5.2

Bảng chú giải

Cú pháp khai báo bảng chú giải như sau: = new TLegend(x1, y1, x2, y2, , option) Trong đó x1, y1, x2, y2 là tọa độ của bảng chú giải trong pad. Một số lệnh liên quan đến bảng chú giải: (xem thêm tại http://root.cern.ch/root/html/TLegend.html) • AddEntry(h," "): gán nội dung cho histogram h • SetBorderMode(), SetBorderSize(): chọn kiểu và bề dày cho khung của bảng chú giải • SetTextFont(), SetTextSize(), SetTextColor(): chọn font chữ và cỡ chữ, màu chữ hển thị • SetFillColor(): chọn màu cho bảng chú giải • Draw(): vẽ bảng chú giải

49

CHƯƠNG 5. ĐỒ THỊ

Đặng Nguyên Phương

Lưu ý: trong một số trường hợp sau khi sử dụng lệnh Draw(), nếu bảng chú giải (thậm chí là trục tọa độ) không hiển thị như được chỉnh sửa thì nên gõ thêm lệnh gPad->RedrawAxis() sau khi chỉnh sửa. Ví dụ: So sánh 2 dạng phân bố Gauss và Landau (xem Hình 5.3) { TH1F ∗h1 = new TH1F ( "h1" , "So sanh " , 5 0 , 0 , 1 0 0 ) ; TH1F ∗h2 = new TH1F ( "h2" , "So sanh " , 5 0 , 0 , 1 0 0 ) ; h1−>Sumw2 ( ) ; h2−>Sumw2 ( ) ; Float_t mean = 2 0 , sigma = 4 ; f o r ( Int_t i = 0 ; i < 1 0 0 0 0 ; i++) { h1−>Fill ( gRandom−>Gaus ( mean , sigma ) ) ; h2−>Fill ( gRandom−>Landau ( mean , sigma ) ) ;

// phan bo Gauss // phan bo Landau

} // Chuan dinh cua h a i phan bo ve 1 h1−>Scale ( 1 . / h1−>GetMaximum ( ) ) ; h2−>Scale ( 1 . / h2−>GetMaximum ( ) ) ; // Ve c a c phan bo h1−>SetLineColor ( kRed ) ; h2−>SetLineColor ( kBlack ) ; h1−>SetLineWidth ( 2 ) ; h2−>SetLineWidth ( 2 ) ; h1−>Draw ( " h i s t o " ) ; h2−>Draw ( "same h i s t o " ) ; // Chon thong s o cho bang chu g i a i gStyle−>SetOptStat ( 0 ) ;

// an bang thong t i n h i s t o g r a m

leg = new TLegend ( 0 . 7 , 0 . 7 , 0 . 9 , 0 . 8 5 ) ; leg−>SetTextSize ( 0 . 0 4 ) ;

// chon co chu

leg−>SetTextColor ( kBlue ) ; leg−>SetFillColor ( 0 ) ; leg−>SetBorderSize ( 0 ) ;

// chon mau chu

// chon mau t o // khong ve khung bang chu g i a i

leg−>AddEntry ( h1 , " Gaussian " ) ; leg−>AddEntry ( h2 , "Landau" ) ; leg−>Draw ( ) ;

// k h a i bao bang chu g i a i

// dat chu g i a i cho h i s t o g r a m h1 // dat chu g i a i cho h i s t o g r a m h2

// ve bang chu g i a i

}

50

CHƯƠNG 5. ĐỒ THỊ

Đặng Nguyên Phương

Hình 5.3: So sánh dạng phân bố Gauss và Landau

5.3

Graph

Graph là một dạng đồ thị được tạo thành bởi hai mảng X và Y tương ứng nhau. Cú pháp khai báo graph như sau: = new TGraph(n, x, y) Trong đó n là số điểm, x và y la hai mảng có n điểm tương ứng, hoặc = new TGraph(h) với h là tên histogram Một số lệnh liên quan đến graph: (xem thêm tại http://root.cern.ch/root/html/TGraph.html) • RemovePoint(i): xóa điểm thứ i • CompareX(g,i,j), CompareY(g,i,j): so sánh giá trị của hai điểm thứ i và j trong graph g • Sort(): sắp xếp lại các điểm Ví dụ: (xem Hình 5.4) { Double_t x [ 2 0 ] , y [ 2 0 ] ; Int_t n = 2 0 ; f o r ( Int_t i=0; i < n ; i++) { x [ i ] = cos ( i +0.5) ; y [ i ] = 3∗ sin ( i−2) ; }

51

CHƯƠNG 5. ĐỒ THỊ

Đặng Nguyên Phương

gr = new TGraph ( n , x , y ) ; gr−>Draw ( "AC∗" ) ; }

Hình 5.4: Đồ thị phần ví dụ cho graph

5.4

GraphError

GraphError là một dạng đồ thị được tạo thành bởi hai mảng X và Y tương ứng có sai số đi kèm. Cú pháp khai báo GraphError như sau: = new TGraphErrors(n, x, y, ex, ey) Trong đó n là số điểm, x và y la hai mảng có n điểm tương ứng, ex và ey là hai mảng chứa sai số của x và y Một số lệnh liên quan đến GraphError: (xem thêm tại http://root.cern.ch/root/html/TGraphErrors.html) • GetErrorX(i), GetErrorY(i): sai số theo trục x và y tại bin thứ i • Apply(f): áp dụng hàm f(x,y) cho tất cả các điểm Ví dụ: (xem Hình 5.5) { Int_t n = 1 0 ; Double_t x [ n ] = { −0.2 , 0 . 1 , 0 . 3 , 0 . 4 , 0 . 7 , 0 . 8 , 1 . 0 , 1 . 6 , 2 . 4 , 2.7};

52

CHƯƠNG 5. ĐỒ THỊ

Đặng Nguyên Phương

Double_t y [ n ] = { 1 . 2 , 2 . 3 , 4 . 0 , 5 . 1 , 7 . 7 , 8 . 7 , 6 . 5 , 4 . 5 , 2 . 7 , −1.3}; Double_t ex [ n ] = { 0 . 0 2 , 0 . 0 3 , 0 . 0 5 , 0 . 0 5 , 0 . 0 7 , 0 . 0 4 , 0 . 0 5 , 0 . 0 6 , 0.04 , 0.01}; Double_t ey [ n ] = { 0 . 6 , 0 . 1 , 0 . 8 , 0 . 6 , 0 . 9 , 0 . 7 , 1 . 0 , 0 . 5 , 0 . 5 , 0.2}; gr = new TGraphErrors ( n , x , y , ex , ey ) ; gr−>SetMarkerStyle ( 2 1 ) ; gr−>SetMarkerColor ( 4 ) ; gr−>Draw ( "ALP" ) ; }

Hình 5.5: Đồ thị phần ví dụ cho GraphError

5.5

MultiGraph

MultiGraph tạo một tập hợp các đồ thị. Cú pháp khai báo MultiGraph như sau: = new TMultiGraph("", "") Một số lệnh liên quan đến MultiGraph: (xem thêm tại http://root.cern.ch/root/html/TMultiGraph.html) • Add(): thêm đồ thị vào multigraph • Draw(): vẽ các đồ thị Ví dụ: (xem Hình 5.6) 53

CHƯƠNG 5. ĐỒ THỊ

Đặng Nguyên Phương

{ TMultiGraph ∗mg = new TMultiGraph ( ) ; Int_t n1 = 1 0 , n2 = 1 0 ; Double_t x1 [ ]

\= { −0.1 , 0 . 0 5 , 0 . 2 5 , 0 . 3 5 , 0 . 5 ,

0.61 ,0.7 ,0.85 ,0.89 ,0.95}; Double_t y1 [ ]

\= { −1 ,2.9 ,5.6 ,7.4 ,9 ,9.6 ,8.7 ,6.3 ,4.5 ,1};

Double_t ex1 [ ] = { . 0 5 , . 1 , . 0 7 , . 0 7 , . 0 4 , . 0 5 , . 0 6 , . 0 7 , . 0 8 , . 0 5 } ; Double_t ey1 [ ] = { . 8 , . 7 , . 6 , . 5 , . 4 , . 4 , . 5 , . 6 , . 7 , . 8 } ; TGraphErrors ∗ gr1 = new TGraphErrors ( n1 , x1 , y1 , ex1 , ey1 ) ; gr1−>SetMarkerColor ( kBlue ) ; gr1−>SetMarkerStyle ( 2 1 ) ; mg−>Add ( gr1 ) ; Float_t x2 [ ]

\= { −0.28 , 0 . 0 0 5 , 0 . 1 9 , 0 . 2 9 , 0 . 4 5 ,

0.56 ,0.65 ,0.80 ,0.90 ,1.01}; Float_t y2 [ ]

\= {2.1 ,3.86 ,7 ,9 ,10 ,10.55 ,9.64 ,7.26 ,5.42 ,2};

Float_t ex2 [ ] = { . 0 4 , . 1 2 , . 0 8 , . 0 6 , . 0 5 , . 0 4 , . 0 7 , . 0 6 , . 0 8 , . 0 4 } ; Float_t ey2 [ ] = { . 6 , . 8 , . 7 , . 4 , . 3 , . 3 , . 4 , . 5 , . 6 , . 7 } ; TGraphErrors ∗ gr2 = new TGraphErrors ( n2 , x2 , y2 , ex2 , ey2 ) ; gr2−>SetMarkerColor ( kRed ) ; gr2−>SetMarkerStyle ( 2 0 ) ; mg−>Add ( gr2 ) ; mg−>Draw ( "APL" ) ; }

5.6

Các tùy chỉnh vẽ đồ thị

Khi vẽ đồ thị bằng lệnh Draw(), ta có thể sữ dụng các tùy chỉnh để vẽ các dạng đồ thị khác nhau của cùng một histogram. Bảng 5.1 trình bày một số tùy chỉnh thường sử dụng cho các histogram 1D và 2D.

Một số tùy chỉnh cho điểm đánh dấu (marker), đường (line) và chế độ tô màu (fill) • Chọn màu: SetMarkerColor(), SetLineColor(), SetFillColor() • Chọn kiểu vẽ: SetMarkerStyle(), SetLineStyle(), SetFillStyle() • Chọn bề dày: SetMarkerWidth(), SetLineWidth() 54

CHƯƠNG 5. ĐỒ THỊ

Đặng Nguyên Phương

Hình 5.6: Đồ thị ví dụ cho MultiGraph Phụ lục B trình bày các bảng kí hiệu màu, kiểu đường và kiểu marker có trong ROOT. Ví dụ: (xem Hình 5.7) { TH1F ∗h1 = new TH1F ( "h1" , " 1D Gaussian " , 1 0 0 , −100 , 1 0 0 ) ; Float_t mean = 0 , sigma = 2 0 ; f o r ( Int_t i = 0 ; i < 1 0 0 0 0 ; i++) { h1−>Fill ( gRandom−>Gaus ( mean , sigma ) ) ; } h1−>SetFillColor ( kBlue ) ; h1−>SetLineColor ( kRed ) ; h1−>SetLineWidth ( 3 ) ;

// chon mau t o mau xanh // chon mau l i n e mau do

// chon be day l i n e bang 3

h1−>Draw ( " h i s t o " ) ; h1−>SetMarkerStyle ( 2 0 ) ;

/ chon kieu marker 20

h1−>SetMarkerColor ( kGreen ) ; h1−>SetMarkerSize ( 1 ) ;

// chon mau marker xanh l a

// chon k i c h thuoc marker bang 1

h1−>Draw ( "same p" ) ; }

Một số tùy chỉnh cho trục đồ thị (axis) Để tiến hành hiệu chỉnh các trục đồ thị, ta sử dụng các lệnh GetXaxis(), GetYaxis(), GetZaxis() để chọn các trục x,y,z tương ứng. (Xem thêm tại http://root.cern.ch/root/htmldoc/TAxis.html) • SetTitle(" "): đặt tiêu đề cho trục đồ thị 55

CHƯƠNG 5. ĐỒ THỊ

Đặng Nguyên Phương

Bảng 5.1: Các tùy chỉnh của lệnh Draw() cho các histogram 1D và 2D (Xem thêm tại http://root.cern.ch/root/html/THistPainter.html ) 1D & 2D SAME Vẽ trên cùng 1 đồ thị E Vẽ các thanh sai số HIST Vẽ dạng histogram TEXT Ghi giá trị của điểm trên đồ thị LEGO Vẽ dạng lego có loại bỏ các đường bị ẩn LEGO1 Vẽ dạng lego có loại bỏ các mặt bị ẩn LEGO2 Vẽ dạng lego có sử dụng màu để hiển thị giá trị 1D B Vẽ biểu đồ cột C Vẽ đường làm trơn qua các điểm L Vẽ đường nối các điểm P Vẽ các điểm đánh dấu P0 Vẽ các điểm đánh dấu kể cả cho các bin không có giá trị E0 Vẽ thanh sai số E1 Vẽ thanh sai số có vạch ngang vuông góc với thanh sai số E2 Vẽ thanh sai số có khung chữ nhật E3 Vẽ thanh sai số và tô phần diện tích thanh theo trục tung E4 Vẽ thanh sai số và tô diện tích đã được làm trơn E5 Tương tự E3 nhưng bỏ qua các giá trị 0 E6 Tương tự E4 nhưng bỏ qua các giá trị 0 2D CYL Vẽ trên trục tọa độ trụ POL Vẽ trên trục tọa độ cực SPH Vẽ trên trục tọa độ cầu PSR Vẽ trên trục tọa độ pseudorapidity/phi BOX Vẽ dạng hộp COL Vẽ dạng hộp có tô màu COLZ Tương tự như COL nhưng có thêm thang màu CONT Vẽ đường contour (tương tự CONT0) CONT0 Vẽ đường contour có màu CONT1 Vẽ đường contour có phân biệt kiểu đường CONT2 Vẽ đường contour với cùng kiểu đường CONT3 Vẽ đường contour có tô màu CONT4 Vẽ đường contour có sử dụng màu của mặt CONT5 Vẽ đường contour có sử dụng tam giác Delaunay SURF Vẽ dạng mặt SURF1 Vẽ dạng mặt SURF2 Vẽ dạng mặt có sử dụng màu để hiển thị giá trị SURF3 Tương tự SURF, có thêm đường contour phía trên SURF4 Vẽ dạng mặt được làm trơn (Gouraud shading) SURF5 Tương tự SURF3, có đường contour màu SCAT Vẽ dạng chấm điểm • SetRangeUser(a,b): chọn khoảng vẽ từ a đến b • SetTitleSize(), SetTitleFont(), SetTitleOffset(): chọn cỡ chữ và font chữ và 56

CHƯƠNG 5. ĐỒ THỊ

Đặng Nguyên Phương

Hình 5.7: Đồ thị phân bố ngẫu nhiên dạng Gauss 1 chiều offset cho tiêu đề trên trục • SetLabelSize(), SetLabelFont(): chọn cỡ chữ và font chữ hiển thị trên trục Ví dụ: (xem Hình 5.8) { TH1F ∗h1 = new TH1F ( "h1" , " 1D Gaussian " , 1 0 0 , −100 , 1 0 0 ) ; Float_t mean = 0 , sigma = 2 0 ; f o r ( Int_t i = 0 ; i < 1 0 0 0 0 ; i++) { h1−>Fill ( gRandom−>Gaus ( mean , sigma ) ) ; } h1−>SetTitle ( "Do t h i Gaussian " ) ; // dat t i e u de h1−>GetXaxis ( )−>SetTitle ( "X[m] " ) ; // g i a t r i cua t r u c x h1−>GetYaxis ( )−>SetTitle ( " Counts " ) ; // g i a t r i cua t r u c y h1−>GetXaxis ( )−>SetRangeUser ( −50 ,50) ; // khoang ve h1−>Draw ( ) ; }

5.7

Cách tạo văn bản và biểu thức toán học

Các đoạn văn bản (text) được đưa vào trong pad có thể được nằm trong các khung được gọi là pave (lớp TPaveLabel) hoặc là nằm tự do. Các đoạn văn bản hiển thị tiêu đề đồ thị hay các trục có thể được khai báo một cách trực tiếp. Tất cả các văn bản, công thức 57

CHƯƠNG 5. ĐỒ THỊ

Đặng Nguyên Phương

Hình 5.8: Ví dụ chỉnh các trục cho đồ thị toán học hiển thị trong hình vẽ đều là các đối tượng thuộc lớp TText và tuân theo cú pháp viết văn bản latex (lớp TLatex). Phụ lục C trình bày cách viết một số kí hiệu latex đơn giản được sử dụng trong ROOT. Ví dụ: (xem Hình 5.9) { TLatex l ; l−>SetTextAlign ( 1 2 ) ; l−>SetTextSize ( 0 . 0 4 ) ; l−>DrawLatex ( 0 . 1 , 0 . 8 , " 1 ) C( x ) = d

s q r t{# f r a c {2}{

lambdaD}}

i n t ^{x}_{0} c o s (# f r a c {

p i }{2} t ^{2}) dt " ) ; l−>DrawLatex ( 0 . 1 , 0 . 6 , " 2 ) C( x ) = d

s q r t{# f r a c {2}{

lambdaD}}

i n t ^{x} c o s (# f r a c {

p i }{2} t {2}) dt " ) ; l−>DrawLatex ( 0 . 1 , 0 . 4 , " 3 ) R = |A| { 2 } =

f r a c {1}{2}(#[]{# f r a c {1}{2}+C(V) }{2}+ #[]{# f r a c {1}{2}+S (V) }{2}) " ) ; l−>DrawLatex ( 0 . 1 , 0 . 2 , " 4 ) F( t ) =

sum_{ i= −

i n f t y }^{# i n f t y }A( i ) c o s #[]{# f r a c { i }{ t+i }} " ) ; }

58

CHƯƠNG 5. ĐỒ THỊ

Đặng Nguyên Phương

Hình 5.9: Ví dụ công thức latex

5.8

Graphics Editor

Bên cạnh việc hiệu chỉnh các hình vẽ bằng câu lệnh, ROOT cũng xây dựng các lớp GUI (Graphics User Interface) nhằm giúp cho việc hiệu chỉnh hình vẽ được thuận tiện hơn. Để khởi động phần Graphics Editor ta có thể nhấp vào mục View → Editor như trong Hình 5.10. Để hiệu chỉnh cho đối tượng nào trong hình vẽ (canvas, pad, axis,...) ta chỉ cần nhấp vào đối tượng đó trên hình. Các hiệu chỉnh bằng Graph Editor cũng tương đương với các hiệu chỉnh bằng câu lệnh. Ngoài ra, thay vì mở Graph Editor trực tiếp, ta có thể hiệu chỉnh hình vẽ bằng cách nhấp chuột phải vào các đối tượng cần chỉnh và chọn các lệnh tương ứng như trong Hình 5.11.

5.9

Bài tập

1. Một sinh viên tiến hành thí nghiệm đo hệ số suy giảm của tia gamma qua hai loại vật liệu A và B. Bảng 5.2 trình bày số đếm thu được ứng với các bề dày khác nhau của hai vật liệu A và B. Hãy tính hệ số suy giảm của gamma đối với hai loại vật liệu này và vẽ trên cùng 1 đồ thị. 2. Một phần bộ số liệu mô phỏng phân bố liều trong phantom nước được chiếu bởi chùm tia gamma (phân bố trên mặt phẳng kích thước 4 × 4 cm2 ) được cho tại http: //nmtp.wikispaces.com/file/detail/dose_distribution.txt. Hãy vẽ phân bố này theo các dạng col, cont, lego và surf. 59

CHƯƠNG 5. ĐỒ THỊ

Đặng Nguyên Phương

Hình 5.10: Cách chọn Graphics Editor

Hình 5.11: Cách chỉnh sửa thứ 2 Bảng 5.2: Bề dày (cm) A B

Số đếm theo khoảng cách 1 2 3 4 5 6 7 452 199 94 45 14 5 5 904 276 81 30 7 2 4

60

CHƯƠNG 5. ĐỒ THỊ

Đặng Nguyên Phương

3. Một detector ghi nhận vết của 1 hạt mang điện chuyển động dưới tác động của từ trường hướng theo trục z. Hạt chuyển động trong mặt phẳng xy, các vị trí có tín hiệu ghi nhận hạt được cho trong file: http://nmtp.wikispaces.com/file/ detail/track_hits.txt Xác định xung lượng của hạt biết cường độ từ trường là B = 1T và điện tích của hạt là |q| = e. Gợi ý: xung lượng ngang của hạt có điện tích e chuyển động dưới tác động của từ trường được xác định theo công thức pT [GeV ] = 0.3 × B[T ] × R[m], với R là bán kính quỹ đạo chuyển động của hạt.

61

Chương 6 Các thư viện toán học 6.1

Các hàm toán học

TMath là lớp chứa các hàm toán học được định nghĩa sắn trong ROOT (xem thêm tại http://root.cern.ch/root/html/TMath.html). Một số hàm thông dụng: • Abs(): hàm trị tuyệt đối • Sqrt(): hàm khai căn • ASin(), ACos(): các hàm arcsin(), arccos(),... • Gaus(): hàm Gaussian • E(), Pi(): các giá trị e, π Ngoài ra, trong ROOT cũng có hai thư viện toán học: • Thư viện MathCore: cung cấp các lớp và hàm cho các tính toán số, thư viện này bao gồm các hàm toán học, thống kê và một số thuật toán cơ bản. • Thư viện MathMore: cung cấp các hàm và thuật toán nâng cao dựa trên nền tảng thư viện GNU Scientific Library (GSL). Ví dụ: (xem Hình 6.1) { gSystem−>Load ( " libMathMore " ) ; TLegend ∗ leg = new TLegend ( 0 . 7 5 , 0 . 7 , 0 . 8 9 , 0 . 8 9 ) ; int n = 5; TF1 ∗ JBessel [ 5 ] ; f o r ( i n t nu = 0 ; nu < n ; nu++) {

62

CHƯƠNG 6. CÁC THƯ VIỆN TOÁN HỌC

Đặng Nguyên Phương

JBessel [ nu]= new TF1 ( "J_0" , "ROOT: : Math : : c y l _ b e s s e l _ j ( [ 0 ] , x ) " , 0 , 10) ; JBessel [ nu]−>SetParameters ( nu , 0 . ) ; JBessel [ nu]−>SetTitle ( " " ) ; JBessel [ nu]−>SetLineStyle ( 1 ) ; JBessel [ nu]−>SetLineWidth ( 3 ) ; JBessel [ nu]−>SetLineColor ( nu+1) ; } leg−>SetFillColor ( 0 ) ; leg−>AddEntry ( JBessel [0]−> DrawCopy ( ) , " J_0 ( x ) " , " l " ) ; leg−>AddEntry ( JBessel [1]−> DrawCopy ( "same" ) , " J_1 ( x ) " , " l " ) ; leg−>AddEntry ( JBessel [2]−> DrawCopy ( "same" ) , " J_2 ( x ) " , " l " ) ; leg−>AddEntry ( JBessel [3]−> DrawCopy ( "same" ) , " J_3 ( x ) " , " l " ) ; leg−>AddEntry ( JBessel [4]−> DrawCopy ( "same" ) , " J_4 ( x ) " , " l " ) ; leg−>Draw ( ) ; }

Hình 6.1: Các hàm Bessel J

6.2

Số ngẫu nhiên

TRandom là lớp tạo số ngẫu nhiên cơ bản (chu kì 109 ) (xem thêm tại http://root.cern. ch/root/html/TRandom.html). Ngoài ra còn có các lớp TRandom1 tạo số ngẫu nhiên dựa

63

CHƯƠNG 6. CÁC THƯ VIỆN TOÁN HỌC

Đặng Nguyên Phương

trên thuật toán RANLUX (chu kì 10171 ), TRandom2 dựa trên thuật toán Tausworthe (chu kì 1026 ) và TRandom3 dựa trên thuật toán Mersenne Twister (chu kì 106000 ). Một số phân bố ngẫu nhiên được định nghĩa sẵn trong ROOT: • Exp(X): phân bố exp(−x/X) • Integer(max): số nguyên ngẫu nhiên từ 0 đến max−1 • Gaus(mean,sigma): phân bố Gauss • Rndm(): phân bố ngẫu nhiên từ 0 đến 1 • Uniform(x): phân bố ngẫu nhiên trong khoảng từ 0 đến x • Landau(mean,sigma): phân bố Landau • Poisson(mean): phân bố Poisson • Binomial(n,p): phân bố nhị thức • BreitWigner(mean,gamma): phân bố Breit − Wigner Ngoài ra ta còn có thể gieo số ngẫu nhiêu theo một phân bố tự định nghĩa thông qua lệnh GetRandom(). Ví dụ: (xem Hình 6.2) { TH1F ∗h = new TH1F ( "h" , " abs ( s i n ( x ) /x ) " , 5 0 , 0 , 1 0 ) ; h−>Sumw2 ( ) ; TF1 ∗f = new TF1 ( " f " , " abs ( s i n ( x ) /x ) " , 0 , 1 0 ) ;

// dinh n g h i a ham f

f o r ( Int_t i = 0 ; i < 1 0 0 0 0 ; i++) { h−>Fill ( f−>GetRandom ( ) ) ;

// g i e o ngau n h i e n t h e o phan bo ham f

} h−>Draw ( ) ; }

6.3

Ma trận

Để xây dựng vào thực hiện tính toán ma trận trong ROOT ta có thể sử dụng các lớp ma trận cơ bản như TMatrixF, TMatrixD, TMatrixT, hoặc các ma trận đối xứng (TMatrixFSym, TMatrixDSym, TMatrixTSym),... (xem thêm tại http://root.cern.ch/ root/html/MATH_MATRIX_Index.html). Một số lệnh dành cho ma trận:

64

CHƯƠNG 6. CÁC THƯ VIỆN TOÁN HỌC

Đặng Nguyên Phương

Hình 6.2: Phân bố ngẫu nhiên theo hàm |sin(x)/x| • Print(): xuất ra giá trị của ma trận • Determinant(): tính định thức • Invert(): tính định thức • Transpose(): tính định thức • Plus(a,b): tổng hai ma trận • Minus(a,b): hiệu hai ma trận • Mult(a,b): tích hai ma trận Ví dụ: Tính định thức và ma trận nghịch đảo của một ma trận cho trước {

include Double_t x [ ] = { 3 , 4 , 0 , 1 } ; // Tao ma t r a n n k i c h thuoc 2 x2 tu mang x TMatrixD n ( 2 , 2 , x ) ; // Tinh dinh thuc cua ma t r a n n cout ls ( ) ; TFile ∗∗

histogram . root Histograms f o r ROOT c l a s s

TFile ∗

histogram . root Histograms f o r ROOT c l a s s

KEY : TH1F hist1 ; 1 Function to be fit KEY : TH1F hist2 ; 1 Another function to be fit root [ 2 ] . q

Một số đặc điểm của ROOT file • Khi ROOT file được mở, nó trở thành thư mục hiện hành. • Tất cả các hisotgram và tree sẽ được tự động lưu vào file. • Khi file đóng, tất cả các histogram, tree, đối tượng liên quan đều sẽ bị xóa bỏ. • Tất cả các đối tượng có xuất xứ từ TObject đều có thể được ghi trên file.

7.2

Tree

Trong quá trình xử lý, dữ liệu có thể được tổ chức theo nhiều cách khác nhau. Tuy nhiên, trong các trường hợp thông thường, dữ liệu được lưu dưới dạng tuyến tính (record ) và cuối cùng được tổ chức dưới dạng các bảng (table). Tất nhiên cách tổ chức dữ liệu này cũng được chấp nhận trong ROOT. Các bảng này được gọi là các n-tuple, các record được gọi là event và các tiêu đề cột được gọi là các biến (variable). Chúng ta có thể lưu các n-tuple trong ROOT theo hai cách. Các thứ nhất là lưu theo một chuỗi các event, đây cũng là cách lưu dữ liệu thông thường. Tuy nhiên, khi người sử dụng chỉ quan tâm đến một bộ số liệu nhỏ hơn nhiều so với cấu trúc dữ liệu được lưu thì hiệu quả xử lý sẽ không được cao do phải di chuyển từ bộ số liệu của event này đến bộ số liệu của event kế tiếp. Do đó, thay vì lưu trữ theo chuỗi các event, ROOT sẽ chia tách mỗi event theo các biến và xây dựng một tập tin bằng cách đặt cùng tất cả các cột. Điều này tạo ra hai ưu điểm: thứ nhất, mỗi cột là một chuỗi đồng nhất của cùng một biến, do đó sẽ cho kích thước file nhỏ hơn nhiều so với trường hợp thông thường. Thứ hai, khi người sử dụng chỉ quan tâm đến một vài biến cụ thể của mỗi event, thời gian truy xuất dữ liệu nhỏ hơn nhiều do không phải quét toàn bộ dữ liệu trong file.

73

CHƯƠNG 7. FILE

Đặng Nguyên Phương

Trong ROOT, lớp TTree được thiết kế để lưu trữ dữ liệu theo cách thứ hai, làm giảm không gian lưu trữ và tăng tốc độ truy cập dữ liệu.

7.2.1

TNtuple

Lớp TNtuple là một phiên bản đơn giản của lớp TTree, chỉ chứa các dòng số liệu. Cú pháp khai báo Ntuple như sau: TNtuple = new TNtuple("", "", các biến, kích thước)

Một số lệnh dành cho Ntuple • Fill(*x): lưu giá trị của mảng vào ntuple • Fill(x0, x1, x2,...): lưu các giá trị vào ntuple • GetArgs(): số lượng các biến • GetNvar(): số các cột • Scan(): xuất ra bảng giá trị • Print(): in ra bảng thông tin Ví dụ: { TNtuple ∗ ntuple = new TNtuple ( " n t u p l e " , " n t u p l e " , "x : y" ) ; f o r ( Int_t i = 0 ; i < 1 0 0 ; i++) { x=gRandom−>Gaus ( 4 0 , 1 0 ) ; y=gRandom−>Gaus ( 1 0 , 3 0 ) ; ntuple−>Fill ( x , y ) ; } ntuple−>Scan ( ) ; }

Kết quả in ra như sau: ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗

Row

x ∗

y ∗

∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗

0 ∗ 4 9 . 9 8 9 3 2 6 ∗ −3.042931 ∗

1 ∗ 47.817962 ∗ 9.0984172 ∗

2 ∗ 48.242637 ∗ 8.2984800 ∗

3 ∗ 30.991239 ∗ 7.7588658 ∗

74

CHƯƠNG 7. FILE

Đặng Nguyên Phương

4 ∗ 4 0 . 0 7 9 1 2 0 ∗ −2.322895 ∗

5 ∗ 5 3 . 9 1 1 9 4 1 ∗ −19.55198 ∗

6 ∗ 3 9 . 5 1 0 5 9 3 ∗ −33.30006 ∗

7 ∗ 2 9 . 3 9 3 2 9 5 ∗ −31.64893 ∗

8 ∗ 4 7 . 6 7 3 9 6 5 ∗ −12.08088 ∗

9 ∗ 4 5 . 7 9 7 2 1 4 ∗ −1.464032 ∗

10 ∗ 6 0 . 6 0 9 0 2 0 ∗ −27.04453 ∗

11 ∗ 5 1 . 6 5 3 3 6 9 ∗ −3.626074 ∗

12 ∗ 3 8 . 6 5 2 2 8 6 ∗ −4.989183 ∗

13 ∗ 3 8 . 1 7 5 6 4 0 ∗ 6 5 . 3 2 9 3 9 1 ∗

14 ∗ 3 7 . 5 7 1 5 2 1 ∗ 6 9 . 9 0 5 8 3 8 ∗

15 ∗ 4 0 . 0 4 8 0 6 1 ∗ −2.665381 ∗

16 ∗ 5 5 . 4 0 5 3 1 5 ∗ 1 2 . 8 4 2 2 8 4 ∗

17 ∗ 5 5 . 2 4 6 9 2 1 ∗ 4 6 . 5 0 2 5 7 4 ∗

18 ∗ 3 8 . 6 3 6 9 0 9 ∗ 4 . 0 2 3 5 2 8 1 ∗

19 ∗ 3 7 . 0 6 2 3 5 5 ∗ 6 . 4 4 9 2 5 2 1 ∗

20 ∗ 2 8 . 3 9 7 0 6 4 ∗ 1 0 . 3 7 0 8 6 3 ∗

21 ∗ 4 0 . 2 2 0 6 4 2 ∗ 7 . 8 6 2 4 1 8 6 ∗

22 ∗ 2 6 . 7 8 3 8 2 3 ∗ 6 2 . 3 2 9 8 1 1 ∗

23 ∗ 3 6 . 6 7 6 2 2 7 ∗ 2 . 5 8 1 8 1 9 3 ∗

24 ∗ 2 8 . 1 9 7 8 4 7 ∗ −25.71282 ∗

Type to c o n t i n u e o r q to quit ==>

7.2.2

TTree

Lớp TTree khác với lớp TNtuple ở chỗ là lớp TNtuple chỉ giới hạn trong việc chứa dữ liệu dạng số trong khi lớp TTree có thể chứa mọi loại dữ liệu chẳng hạn như các đối tượng (object) hoặc các mảng. Cú pháp khai báo Tree như sau: TTree = new TTree("", splitlevel)

Một số lệnh dành cho Tree • CloneTree(): copy tree • Fill(): lưu tất cả các branch • AddBranchToCache(), DropBranchFromCache(): thêm, loại bỏ branch trong tree • GetEntries(): trả về tổng số entry • Merge(list): hợp nhất tất cả các tree có trong list • Show(entry): liệt kê tất cả các giá trị của leaf trong entry 75

CHƯƠNG 7. FILE

Đặng Nguyên Phương

• Process(): thực thi code đối với mỗi event • Print(): in ra bảng tóm tắt nội dung của tree • Scan(): in ra tất cả các entry vượt qua selection • StartViewer(): khởi động giao diện TreeViewer Ví dụ: (xem Hình 7.1) { TFile f ( " 1 1 6 9 4 4 . r o o t " ) ; TTree ∗t = ( TTree ∗ ) t−>Get ( "HWWTree_e" ) ; t−>StartViewer ( ) ; f−>Close ( ) ; }

Hình 7.1: Cấu trúc của tree

7.2.3

Cấu trúc của tree

Một tree có thể chứa các branch (nhánh), các branch này có thể là các biến, các object hoặc bao gồm cả tree khác. Cuối mỗi branch luôn là một biến, được gọi là leaf (lá). Thông thường, các tree đều được chia thành các branch khi được lưu vào một file ROOT. Bởi vì cấu trúc tree phức tạp hơn so với cấu trúc bảng, nên mức độ chia tách có thể được điều 76

CHƯƠNG 7. FILE

Đặng Nguyên Phương

chỉnh để phù hợp với nhu cầu của người sử dụng. Hình 7.2 trình bày cấu trúc của một tree. Các tree có thể được lưu trữ trên nhiều file khác nhau và có thể được nối tiếp với nhau trong quá trình xử lý thông qua một đối tượng duy nhất gọi là chain.

Hình 7.2: Cấu trúc của tree

7.3 7.3.1

Cách tạo và truy xuất dữ liệu từ file root Cách tạo file root

Các bước để tạo một file root như sau: 1. Tạo một file VD: TFile *file = new TFile("file.root","RECREATE"); 2. Tạo một tree VD: TTree *tree = new TTree("Tree","Tree");

77

CHƯƠNG 7. FILE

Đặng Nguyên Phương

Nếu muốn tạo tree với thư mục bên trong ta có thể làm như sau: TTree tree("Tree", "/folder") 3. Thêm branch vào tree VD: Event *event = new Event(); tree->Branch("EventBranch","Event",&event); 4. Lưu dữ liệu vào tree VD: tree->Fill(); 5. Lưu vào file VD: file->Write(); Ví dụ: { TFile f ( " example . r o o t " , " r e c r e a t e " ) ; TTree ∗t = new TTree ( " t r e e " , " t r e e " ) ; Float_t px , py , pz ; t−>Branch ( "px" ,&px , "px/F" ) ; t−>Branch ( "py" ,&py , "py/F" ) ; t−>Branch ( " pz " ,&pz , " pz /F" ) ; f o r ( Int_t i=0; i Rannor ( px , py ) ; pz = px∗px + py∗py ; t−>Fill ( ) ; } t−>Write ( ) ; }

7.3.2

Cách truy xuất file root

Các bước để truy xuất một file root như sau: 1. Mở một file VD: TFile file("file.root"); 2. Đọc tree VD: TTree * tree = (TTree*) file->FindObject("tree") 3. Tạo các biến để lưu giữ liệu VD: Float_t a, b, c; 78

CHƯƠNG 7. FILE

Đặng Nguyên Phương

4. Liên kết branch với các biến VD: tree->SetBranchAddress("a", &a) 5. Đọc entry và lấy giá trị của biến VD: tree->GetEntry(i); cout « a « endl; Ví dụ: (xem Hình 7.3) { TFile ∗f = new TFile ( " example . r o o t " ) ; TTree ∗t = ( TTree ∗ ) f−>Get ( " t r e e " ) ; Float_t px , py , pz ; t−>SetBranchAddress ( " pz " ,&pz ) ; TH1F ∗ hpz

\= new TH1F ( " hpz " , " pz " , 1 0 0 , 0 , 1 0 ) ;

Long64_t nentries = t−>GetEntries ( ) ; f o r ( Long64_t i=0; iGetEntry ( i ) ; hpz−>Fill ( pz ) ; } hpz−>Draw ( ) ; }

Hình 7.3: Ví dụ file root Trong trường hợp muốn xem nhanh histogram của một vài biến, ta có thể sử dụng lệnh Draw(). 79

CHƯƠNG 7. FILE

Đặng Nguyên Phương

Ví dụ: Câu lệnh vẽ histogram của sqrt(x) với các giá trị x > 0, histogram được đặt tên là histo tree−>Draw ( " s q r t ( x ) >> h i s t " , "x>0" ) ;

Ngoài ra, trong trường hợp tree được chia thành nhiều file, ta có thể dùng TChain để nối các file lại. Ví dụ: TChain chain ( " t r e e " ) ; chain−>Add ( " f i l e 1 . r o o t " ) ; chain−>Add ( " f i l e 2 . r o o t " ) ; ...

7.4

Xử lý số liệu có cấu trúc dạng tree

Quy trình xử lý số liệu có cấu trúc dạng tree hoặc ntuple thông thường bao gồm ba bước sau • Mở file số liệu, khai báo các biến, hitogram,... • Tạo vòng lặp trên tất cả các dữ liệu (entry) chứa trong file, tiến hành tính toán giá trị, áp dụng các ngưỡng cắt, lưu giá trị vào histogram,... • Lưu kết quả, biểu diễn kết quả,... Để tiến hành xử lý dữ liệu có cấu trúc dạng tree hoặc ntuple chứa trong các file ROOT, việc đầu tiên ta cần làm là tạo ra một lớp xử lý (analysis class). Bộ khung sườn (skeleton) của lớp này được tạo ra thông qua lệnh MakeClass(). root [ 0 ] TFile myFile ( " data . r o o t " ) root [ 1 ] tree−>MakeClass ( " MyAnalysis " )

// g i a su d o i tuong thuoc

l o p TTree co t e n l a t r e e

Lệnh MakeClass() sẽ tạo ra hai file MyAnalysis.h và MyAnalysis.C tương ứng với tên của lớp mà ta muốn tạo ra. File MyAnalysis.h là file header chứa các khai báo cho lớp mà ta tạo, trong file này cũng chứa danh sách các biến có trong file ROOT mà ta muốn xử lý. Ví dụ: MyAnalysis.h c l a s s MyAnalysis { public : // Con t r o d o i tuong thuoc l o p TTree hay TChain TTree

∗ fChain ;

80

CHƯƠNG 7. FILE

Đặng Nguyên Phương

// Tree h i e n t a i t r o n g TChain fCurrent ;

Int_t // Cac b i e n UInt_t

fUniqueID ;

UInt_t

fBits ;

Char_t

fType [ 2 0 ] ;

Int_t

fNtrack ;

Int_t

fNseg ;

Int_t

fNvertex ;

UInt_t

fFlag ;

// Cac nhanh ( branch ) TBranch

∗ b_fUniqueID ;

TBranch

∗ b_fBits ;

TBranch

∗ b_fType ;

TBranch

∗ b_fNtrack ;

TBranch

∗ b_fNseg ;

TBranch

∗ b_fNvertex ;

TBranch

∗ b_fFlag ;

... MyClass ( TTree ∗ tree=0) ; ~MyClass ( ) ; Int_t

Cut ( Int_t entry ) ;

Int_t

GetEntry ( Int_t entry ) ;

Int_t

LoadTree ( Int_t entry ) ;

void

Init ( TTree ∗ tree ) ;

void

Loop ( ) ;

Bool_t Notify ( ) ; void

Show ( Int_t entry = −1) ;

};

Một số thành phần quan trọng trong lớp này gồm có: • fChain: trỏ tới tree hay chain gốc (là tree hay chain mà lớp này được tạo ra từ đó). • fCurrent: trỏ tới tree hay chain hiện tại đang xử lý, đặc biệt trong trường hợp xử lý nhiều tree liên kết lại với nhau qua TChain. • void Init(TTree *tree): khởi tạo tree để chuẩn bị đọc dữ liệu. • Int_t GetEntry(Int_t entry): đọc entry tương ứng, ví dụ GetEntry(9) sẽ đọc sự kiện thứ 10 ở trong tree (sự kiện đầu tiên có chỉ số là 0). • void Loop(): hàm chứa các lệnh xử lý, hàm này sẽ lặp trên tất cả dữ liệu trong tree hay chain và áp các lệnh xử lý vào từng dữ liệu. 81

CHƯƠNG 7. FILE

Đặng Nguyên Phương

Ví dụ: MyAnalysis.C (trong day quan trong nhat la ham Loop()) v o i d MyAnalysis : : Loop ( ) //

{

In a ROOT s e s s i o n , you can do :

//

Root > . L MyClass . C

//

Root > MyClass t

//

Root > t . GetEntry ( 1 2 ) ; // F i l l t data members with e n t r y number 12

//

Root > t . Show ( ) ;

// Show v a l u e s o f e n t r y 12

//

Root > t . Show ( 1 6 ) ;

// Read and show v a l u e s o f e n t r y 16

//

Root > t . Loop ( ) ;

// Loop on a l l e n t r i e s

// //

This i s t h e l o o p s k e l e t o n where :

//

j e n t r y i s t h e g l o b a l e n t r y number i n t h e c h a i n

//

i e n t r y i s t h e e n t r y number i n t h e c u r r e n t Tree

//

Note t h a t t h e argument t o GetEntry must be :

//

j e n t r y f o r TChain : : GetEntry

//

i e n t r y f o r TTree : : GetEntry and TBranch : : GetEntry

// //

To r e a d o n l y s e l e c t e d branches , I n s e r t s t a t e m e n t s l i k e :

// METHOD1: //

fChain−>S e t B r a n c h S t a t u s ( " ∗ " , 0 ) ;

//

fChain−>S e t B r a n c h S t a t u s ( " branchname " , 1 ) ;

// d i s a b l e a l l b r a n c h e s // a c t i v a t e

branchname // METHOD2: r e p l a c e l i n e //

fChain−>GetEntry ( j e n t r y ) ;

// by

b_branchname−>GetEntry ( i e n t r y ) ; // r e a d o n l y t h i s branch

//

// r e a d a l l b r a n c h e s

gROOT−>Reset ( ) ;

i f ( fChain == 0 ) r e t u r n ; /∗ Cac k h a i bao v i e t o day ∗/ // Tong s o e n t r y t r o n g c h a i n Int_t nentries = Int_t ( fChain−>GetEntries ( ) ) ; // Lap t r e n t a t ca e n t r y Int_t nbytes = 0 , nb = 0 ; f o r ( Int_t jentry =0; jentryGetEntry ( jentry ) ;

nbytes += nb ;

// i f ( Cut ( i e n t r y ) < 0 ) c o n t i n u e ; /∗ Doan code xu l y v i e t o day ∗/ } /∗ Doan code l u u va t r i n h bay k e t qua xu l y ∗/ }

File MyAnalysis.C chứa các nội dung tương ứng với các hàm được khai báo trong MyAnalysis.h. Các xử lý số liệu đều được thực hiện trong hàm Loop(), các khai báo và lệnh tương ứng được đặt tại các vị trí như được chỉ ra trong ví dụ bên trên. Ví dụ: v o i d Ana : : Loop ( )

{

i f ( fChain == 0 ) r e t u r n ; Int_t nentries = Int_t ( fChain−>GetEntries ( ) ) ; TH1F ∗ hist

\= new TH1F ( " " , " " , 1 0 0 , 0 , 1 0 0 0 0 ) ;

Int_t nbytes = 0 , nb = 0 ; f o r ( Int_t jentry =0; jentryGetEntry ( jentry ) ;

nbytes += nb ;

f o r ( Int_t itrack =0; itracksize ( ) ;++itrack ) { i f ( TrackP−>at ( itrack ) > 1 0 0 0 ) hist−>Fill ( TrackP−>at ( itrack ) ) ; } } hist−>Draw ( ) ; }

Để thực thi file xử lý, ta thực hiện như sau root [ 0 ] . L MyAnalysis . C root [ 1 ] MyAnalysis a root [ 2 ] a . Loop ( )

83

CHƯƠNG 7. FILE

7.5

Đặng Nguyên Phương

Bài tập

1. Bộ số liệu mô phỏng phân bố liều trong phantom nước (kích thước 4 × 4 × 4 cm3 ) được chiếu bởi chùm tia gamma được cho tại http://nmtp.wikispaces.com/file/ detail/dose_phantom.txt. Hãy tạo một file root có tên là dose.root, có chứa 1 tree có tên là DoseDistribution. Lưu bộ số liệu này vào trong root file theo các biến tọa độ x, y, z. 2. Đọc file root được tạo ra trong bài tập trước, vẽ các phân bố liều: • Theo trục x, y, z đi qua tâm của phantom. • Trên mặt phẳng xy, yz, xz đi qua tâm của phantom. • Trên mặt phẳng xy, yz, xz tại biên của phantom.

84

Lời kết Tài liệu này được biên soạn với mục đích cung cấp cho người đọc một cái nhìn khái quát cùng những kiến thức căn bản nhất trong việc sử dụng ROOT trong công việc phân tích và xử lý số liệu. Mặc dù vẫn còn rất nhiều chủ đề chưa được đề cập đến trong tài liệu, tuy nhiên với những gì được trình bày, hi vọng các bạn sẽ nắm bắt được phần nào những kiến thức nền tảng của ROOT để từ đó có thể tìm hiểu sâu hơn về chương trình này thông qua các tài liệu phổ biến trên mạng internet. Đặc biệt đối với những bạn có định hướng nghiên cứu về lĩnh vực thực nghiệm hạt cơ bản, đây gần như là một công cụ không thể thiếu trong công việc của các bạn sau này. Mặc dù đã rất cố gắng, nhưng do thời gian hạn hẹp nên chắc chắn tài liệu này vẫn còn nhiều thiếu sót về nội dung cũng như hình thức trình bày. Rất mong nhận được sự đóng góp ý kiến của các bạn để việc biên soạn tài liệu ngày càng tốt hơn.

85

Tài liệu tham khảo [1] René Brun, Fons Rademakers, ROOT – An Object Oriented Data Analysis Framework, Nuclear Instruments and Methods in Physics Research A389, p.81-86, 1997. [2] I. Antcheva et al, ROOT − A C++ framework for petabyte data storage, statistical analysis and visualization, Computer Physics Communications, Vol.180, p.2499-2512, 2009. [3] René Brun et al, ROOT Overview, CERN, 1997. [4] Danilo Piparo, G¨ unter Quast, A ROOT Guide for Student "Diving Into ROOT", Karlsruhe Institute of Technology, 2011. [5] W.G. Seligman, Basic Data Analysis Using ROOT, 2013. http://www.nevis.columbia.edu/~seligman/root-class/RootClass2013.pdf [6] http://root.cern.ch/drupal/content/users-guide [7] http://root.cern.ch/drupal/content/reference-guide [8] http://atlas.fis.utfsm.cl/atlas/tutorial.root.utfsm.html

86

Phụ lục A

Cách cài đặt ROOT cho HĐH Linux Đối với hệ điều hành Linux, cách tốt nhất là biên dịch từ mã nguồn (source code). Đầu tiên ta cần download mã nguồn từ địa chỉ http://root.cern.ch/drupal/content/ downloading-root (Hình 1.3). Tuy nhiên, thay vì download file msi để cài đặt cho Windows thì ta sẽ vào phần Source và nhấp vào đường link ROOT 5.xx.yy complete source tree để donwload file mã nguồn (có dạng root_v5.xx.yy.source.tar.gz). Trước khi tiến hành biên dịch mã nguồn, ta cần phải đảm bảo rằng trong hệ thống đã có sẵn một số gói ứng dụng (package) cần thiết cho quá trình biên dịch. Mỗi một hệ điều hành sẽ đòi hỏi các gói ứng dụng khác nhau, ta có thể kiểm tra các gói cho hệ điều hành tương ứng tại http://root.cern.ch/drupal/content/build-prerequisites. Để cài đặt các gói ứng dụng này, ta sử dụng các lệnh sau • Đối với Fedora $ yum install . . .

• Đối với Ubuntu $ sudo apt−get install . . .

• Đối với openSUSE $ sudo zypper install . . .

• Đối với AIX $ rpm −Uvh . . .

Sau khi đã download mã nguồn và các gói ứng dụng cần thiết, ta tiến hành giải nén file mã nguồn bằng lệnh $ tar −zxvf root_v5 . xx . yy . source . tar . gz

Sau khi giải nén, một thư mục root/ sẽ được tạo ra tại vị trí đặt file mã nguồn. Ta di chuyển vào bên trong thư mục root/ này để thực hiện việc cài đặt $ cd root

87

PHỤ LỤC A. CÁCH CÀI ĐẶT ROOT CHO HĐH LINUX

Đặng Nguyên Phương

Ở đây có hai phương thức cài đặt: cài đặt vị trí không cố định và cài đặt với vị trí cố định. Phương thức thứ nhất thích hợp với mục đích cài đặt ROOT để sử dụng cho cá nhân, phương thức thứ hai thích hợp với mục đích cài đặt cho toàn hệ thống. • Để cài đặt theo phương thức thứ nhất, ta gõ các lệnh sau $ . / configure $ make

• Để cài đặt theo phương thức thứ hai, ta gõ các lệnh sau $ . / configure −−prefix=/usr / local $ make $ sudo make install

Đến đây là quá trình cài đặt ROOT đã kết thúc, tuy nhiên để có thể sử dụng được ROOT, ta cần phải khai báo đường dẫn của thư mục ROOT vào trong các biến môi trường PATH (tới thư mục bin/ ) và LD_LIBRARY_PATH (tới thư mục lib/ ) để chương trình có thể tìm được các file thực thi và thư viện của ROOT. Để làm được điều đó ta có thể sử dụng một trong các cách sau • Cách 1: sử dụng lệnh export $ e x p o r t ROOTSYS= $ e x p o r t PATH=$ROOTSYS / bin : $PATH $ e x p o r t LD_LIBRARY_PATH=$ROOTSYS / lib : $LD_LIBRARY_PATH

• Cách 2: sử dụng script có sẵn của ROOT, tại thư mục root/ ta gõ $ . bin / thisroot . sh

hoặc $ source bin / thisroot . csh

• Cách 3: cập nhật cache bằng cách gõ lệnh (trong trường hợp cài theo phương thức thứ hai) $ ldconfig

Hai cách đầu tiên phải được thực hiện mỗi lần khởi động terminal. Để thuận tiện cho việc sử dụng ROOT mà không cần phải khai báo nhiều lần, ta có thể mở file ∼/.bashrc tại thư mục gốc và thêm các lệnh trên vào trong file này (ở cách 2 cần khai báo đường dẫn đầy đủ của các script). Với cách này, chương trình sẽ tự động thực hiện các lệnh trên mỗi khi khởi động một terminal mới.