Открыть файл с данными
f = TFile::Open("root://eospublic.cern.ch//eos/opendata/cms/derived-data/AOD2NanoAODOutreachTool/Run2012BC_DoubleMuParked_Muons.root")
Здесь есть дерево Events
.
Дерево содержит следующие поля
Поле | Тип | Описание |
---|---|---|
nMuon |
unsigned int |
Number of muons in this event |
Muon_pt |
float[nMuon] |
Transverse momentum of the muons (stored as an array of size nMuon ) |
Muon_eta |
float[nMuon] |
Pseudorapidity of the muons |
Muon_phi |
float[nMuon] |
Azimuth of the muons |
Muon_mass |
float[nMuon] |
Mass of the muons |
Muon_charge |
int[nMuon] |
Charge of the muons (either 1 or -1) |
Events->GetEntries() //событий в дереве
$X \to \mu^+ \mu^-$
Условия отбора: ищем события с
Картинка: построим инвариантную массу пары $\mu^+\mu^-$
Пишем вспомогательную функцию, которая вернёт инвариантную массу пары мюонов
Double_t InvariantMass(Float_t pt0, Float_t eta0, Float_t phi0, Float_t mass0, Float_t pt1, Float_t eta1, Float_t phi1, Float_t mass1){
ROOT::Math::PtEtaPhiMVector m1(pt0, eta0, phi0, mass0);
ROOT::Math::PtEtaPhiMVector m2(pt1, eta1, phi1, mass1);
return (m1+m2).mass();
}
Создаю гистограмму
invMass_hist = new TH1D("hist", "InvMass", 10000, 0, 120)
Теперь нужно пройти по нашему дереву Events
и вытащить оттуда события, удовлетворяющие критериям отбора, вычислить их инвариантную массу и записать в гистограмму
Проход по дереву осуществляется с помощью TTreeReader
TTreeReader reader("Events", f);
Ему дополнительно нужно показать ветки дерева, которые мы будем использовать
TTreeReaderArray<Float_t> pt(reader, "Muon_pt");
TTreeReaderArray<Float_t> eta(reader, "Muon_eta");
TTreeReaderArray<Float_t> phi(reader, "Muon_phi");
TTreeReaderArray<Float_t> m(reader, "Muon_mass");
TTreeReaderArray<int> ch(reader, "Muon_charge");
TTreeReaderValue<unsigned int> num(reader, "nMuon");
Пара вспомогательных переменных
int i=0;
double mass;
Пример: пройти по дереву и выписать поперечные импульсы треков в событиях с nMuon==1
и Muon_phi<0.1
while(reader.Next()){
if((*num==1)&&(phi[0]<0.1)){
cout << "MOM: " << pt[0] << endl;
}
}
Теперь по нашему анализу
Задача: исправьте ошибки в следующем блоке
invMass_hist->Reset(); //на всякий случай чищу гистограмму
reader.Restart();//на всякий случай сбрасываю reader
i = 0;
while(reader.Next()){
if((*num==2)&&(ch[0]==ch[1])&&(phi[0]*phi[1]<0)){
mass = InvariantMass(eta[0], phi[0], m[0], pt[0], pt[1], eta[1], phi[1], m[1]);
hist->Fill(mass);
i++;
if(i%1000==0)
cout << i << '\t' << mass << endl;
}
if(i==10000) //дерево гигантское, поэтому если мы не хотим ждать сутки, то лучше остановиться пораньше
break;
}
Задача: постройте гистограмму с инвариантной массой двух мюонов, подпишите оси, добавьте заголовок
TCanvas c1("can1", "Canvas", 600, 600);
//код
c1.Draw()
Задача: постройте гистограмму в окне c2
в логарифмическом масштабе по оси x, уберите окно со статистикой, добавьте сетку
TCanvas c2("can2", "Canvas", 1000, 600);
//код
c2.Draw()
Вы видите что-то необычное? Например пик от $Z$-бозона где-то около 90 ГэВ?
Теперь наша глобальная задача будет определить массу $Z$-бозона
Клонируем нашу гистограмму в новую гистограмму hist_Z
для дальнейшейшей работы
hist_Z = (TH1D*)(invMass_hist->Clone())
Задача: сфокусировать гистограмму на Z-бозоне, построить её в окне c3
p.s: если событий мало, то перебинируйте гистограмму hist_Z->Rebin(2);
(можно несколько раз, или вставьте другое число)
TCanvas c3("can3", "Canvas", 1000, 600);
hist_Z->Draw(); //добавьте свой код сюда
c3.Draw()
Задача:
c3
, добавить окно со статистикойdata_dist = new TF1("sig_bkg", "", 80, 100); //напишите ваш код
data_dist->SetParameters //не забудьте выставить начальные параметры
//добавьте код