i. In the preamble of the macro (where the event loop will be performed), i.e. the
.C
file created after using the
TTree::MakeClass
function, add the following:
#include "modules/ttz2los_base.C"
#include "modules/ttz2los_eventdisplaytools.C"
ii. Then in the 'Loop()' function, you have to define a few things that will be used in the event loop:
eventDisplay thisEventDisplay;
thisEventDisplay.SetDPGMode(false);
thisEventDisplay.SetupCanvas();
TString eventType;
TString eventTypeExtended;
TString outputDir;
eventType = "ttZ";
eventTypeExtended = "ttZ_ee";
outputDir = "ttZ/ee"; // assumes this directory exists as mentioned above (i.e. you'll also have to create it if it's not there)
TString zDecayType_true = "el"; // this can be changed to "mu" or "tau" based on the truth info in the event from the Z decay
TString zDecayType_identified = "el"; // also this should be evaluated dynamically (but ignore for now)
vector<float> *v_eventDisplay_values = new vector<float>; // vector of floats that contain kinematic info (to set values before the various objects are drawn on the canvas)
vector<TLorentzVector>* v_recoJets = new vector<TLorentzVector>;
vector<float>* v_recoJets_MV2c10 = new vector<float>;
vector<TLorentzVector>* v_partons = new vector<TLorentzVector>; // bqqbqq quarks at parton level from ttbar decay
vector<TLorentzVector>* v_zDaughters = new vector<TLorentzVector>;
vector<int>* v_partons_pdgId = new vector<int>;
vector<int>* v_zDaughters_pdgId = new vector<int>;
TLorentzVector Z,l1,l2; // Z boson, lepton1, lepton2
TLorentzVector W1,W2; // W bosons
TLorentzVector b1,b2; // b/bbar
TLorentzVector q1,q2; // ---> where W1->q1q2
TLorentzVector q3,q4; // ---> where W2->q3q4
TLorentzVector reco4V;
float q1_mass,q2_mass,q3_mass,q4_mass; // in case of light-flavour quarks or leptons to avoid negative mass values from E^2-p^2 floating point precision
int q1_pdgId,q2_pdgId; // quarks from W 1
int q3_pdgId,q4_pdgId; // quarks from W 2
int l1_pdgId,l2_pdgId; // generator-level leptons from Z decay
TLorentzVector top1_beforeFSR,top2_beforeFSR; // top quarks (before FSR)
TLorentzVector top1_afterFSR,top2_afterFSR; // top quarks (after FSR)
TLorentzVector recoTop1,recoTop2,recoW1,recoW2,recoZ; // these need to be built from reco jets or leptons (usually based on a reco algorithm)
vector<TLorentzVector>* v_recoEl = new vector<TLorentzVector>;
vector<TLorentzVector>* v_recoMu = new vector<TLorentzVector>;
vector<int> v_recoJets_recoIndices_minChi2; // output from reconstruction algorithm with MinChi2
vector<int> v_recoLeptons_recoIndices;
iii. Finally within the event loop itself, set the relevant values of quantities or fill vectors of lorentz vectors, then draw the final canvas based on the event display class (final output should be a .pdf). There are a few variables not defined below, but the comments should make it clear what they are (so you'll have to replace them with however you access the quantities).
// Set the kinematic quantities of the quarks, tops, reco jets, etc.
q1_pdgId = MC_Wdecay1_from_t_pdgId;
q2_pdgId = MC_Wdecay2_from_t_pdgId;
q3_pdgId = MC_Wdecay1_from_tbar_pdgId;
q4_pdgId = MC_Wdecay2_from_tbar_pdgId;
l1_pdgId = MC_Zdecay1_pdgId;
l2_pdgId = MC_Zdecay2_pdgId;
q1_mass = ReturnCorrectedMass(abs(q1_pdgId), MC_Wdecay1_from_t_m);
q2_mass = ReturnCorrectedMass(abs(q2_pdgId), MC_Wdecay2_from_t_m);
q3_mass = ReturnCorrectedMass(abs(q3_pdgId), MC_Wdecay1_from_tbar_m);
q4_mass = ReturnCorrectedMass(abs(q4_pdgId), MC_Wdecay2_from_tbar_m);
W1.SetPtEtaPhiM(MC_W_from_t_pt/1.e3,MC_W_from_t_eta,MC_W_from_t_phi,MC_W_from_t_m/1.e3);
W2.SetPtEtaPhiM(MC_W_from_tbar_pt/1.e3,MC_W_from_tbar_eta,MC_W_from_tbar_phi,MC_W_from_tbar_m/1.e3);
b1.SetPtEtaPhiM(MC_b_from_t_pt/1.e3,MC_b_from_t_eta,MC_b_from_t_phi,MC_b_from_t_m/1.e3);
b2.SetPtEtaPhiM(MC_b_from_tbar_pt/1.e3,MC_b_from_tbar_eta,MC_b_from_tbar_phi,MC_b_from_tbar_m/1.e3);
Z.SetPtEtaPhiM(MC_Z_pt/1.e3,MC_Z_eta,MC_Z_phi,MC_Z_m/1.e3);
q1.SetPtEtaPhiM(MC_Wdecay1_from_t_pt/1.e3,MC_Wdecay1_from_t_eta,MC_Wdecay1_from_t_phi,q1_mass/1.e3);
q2.SetPtEtaPhiM(MC_Wdecay2_from_t_pt/1.e3,MC_Wdecay2_from_t_eta,MC_Wdecay2_from_t_phi,q2_mass/1.e3);
q3.SetPtEtaPhiM(MC_Wdecay1_from_tbar_pt/1.e3,MC_Wdecay1_from_tbar_eta,MC_Wdecay1_from_tbar_phi,q3_mass/1.e3);
q4.SetPtEtaPhiM(MC_Wdecay2_from_tbar_pt/1.e3,MC_Wdecay2_from_tbar_eta,MC_Wdecay2_from_tbar_phi,q4_mass/1.e3);
l1.SetPtEtaPhiM(MC_Zdecay1_pt/1.e3,MC_Zdecay1_eta,MC_Zdecay1_phi,ReturnCorrectedMass(abs(l1_pdgId),MC_Zdecay1_m)/1.e3);
l2.SetPtEtaPhiM(MC_Zdecay2_pt/1.e3,MC_Zdecay2_eta,MC_Zdecay2_phi,ReturnCorrectedMass(abs(l2_pdgId),MC_Zdecay2_m)/1.e3);
if(abs(l1_pdgId)==11) zDecayType_true = "el";
else if(abs(l1_pdgId)==13) zDecayType_true = "mu";
else zDecayType_true = "tau";
v_zDaughters->push_back(l1);
v_zDaughters_pdgId->push_back(MC_Zdecay1_pdgId);
v_zDaughters->push_back(l2);
v_zDaughters_pdgId->push_back(MC_Zdecay2_pdgId);
// NOTE: order matters here for the parton vector
v_partons->push_back(b1); v_partons_recoIndices->push_back(1); v_partons_pdgId->push_back(5);
v_partons->push_back(b2); v_partons_recoIndices->push_back(-1); v_partons_pdgId->push_back(-5);
v_partons->push_back(q1); v_partons_recoIndices->push_back(2); v_partons_pdgId->push_back(q1_pdgId);
v_partons->push_back(q2); v_partons_recoIndices->push_back(2); v_partons_pdgId->push_back(q2_pdgId);
v_partons->push_back(q3); v_partons_recoIndices->push_back(-2); v_partons_pdgId->push_back(q3_pdgId);
v_partons->push_back(q4); v_partons_recoIndices->push_back(-2); v_partons_pdgId->push_back(q4_pdgId);
for(unsigned int i = 0; i < reco_jet_pt->size(); ++i) {
reco4V.SetPtEtaPhiE(reco_jet_pt->at(i)/1.e3, reco_jet_eta->at(i), reco_jet_phi->at(i), reco_jet_e->at(i)/1.e3);
v_recoJets->push_back(reco4V);
v_recoJets_MV2c10->push_back(reco_jet_mv2c10->at(i));
}
for(unsigned int i = 0; i < reco_el_pt->size(); ++i) {
reco4V.SetPtEtaPhiE(reco_el_pt->at(i)/1.e3, reco_el_eta->at(i), reco_el_phi->at(i), reco_el_e->at(i)/1.e3);
v_recoEl->push_back(reco4V);
}
for(unsigned int i = 0; i < reco_mu_pt->size(); ++i) {
reco4V.SetPtEtaPhiE(reco_mu_pt->at(i)/1.e3, reco_mu_eta->at(i), reco_mu_phi->at(i), reco_mu_e->at(i)/1.e3);
v_recoMu->push_back(reco4V);
}
thisEventDisplay.ResetCanvas();
thisEventDisplay.SetEventType(eventType);
v_eventDisplay_values->push_back(reco_jet_n); // int: number of reco jets in the event
v_eventDisplay_values->push_back(reco_bjet_n); // int: number of b-tagged reco jets in the event
v_eventDisplay_values->push_back(reco_el_n); // int: number of reco electrons
v_eventDisplay_values->push_back(reco_mu_n); // int: number of reco muons
v_eventDisplay_values->push_back(minChi2Terms[4]); // float: output min chi2 value from the reco algorithm (for now only designed for this reco algorithm but could be BDT value)
v_eventDisplay_values->push_back(reco_met_met/1.e3); // float: met in GeV
v_eventDisplay_values->push_back(recoTop1.Mag()); // float: reco top 1 mass in GeV
v_eventDisplay_values->push_back(recoW1.Mag()); // float: reco W 1 mass in GeV
v_eventDisplay_values->push_back(recoTop2.Mag());
v_eventDisplay_values->push_back(recoW2.Mag());
v_eventDisplay_values->push_back(recoZ.Mag()); // float: reco Z mass in GeV
thisEventDisplay.SetMarkerColours(true, zDecayType_true);
thisEventDisplay.PrintEventLevelInfo(eventNumber, *v_eventDisplay_values); // int: eventNumber should be added here
// thisEventDisplay.PrintRecoPurityBoxes(recoZPC,recoTop1PC,recoTop2PC,recoW1PC,recoW2PC); // ignore this for now (requires additional functionality to see if reco objects are correct - ask me if you want this)
thisEventDisplay.PrintPartonLevel4VectorInfo(*v_zDaughters, *v_zDaughters_pdgId, "Z");
thisEventDisplay.PrintPartonLevel4VectorInfo(*v_partons, *v_partons_pdgId, "Top1");
thisEventDisplay.PrintPartonLevel4VectorInfo(*v_partons, *v_partons_pdgId, "Top2");
thisEventDisplay.PrintPreFSRTop4VectorInfo(top1_beforeFSR, top2_beforeFSR);
thisEventDisplay.EvaluateThrust(Z,top1_beforeFSR,top2_beforeFSR,top1_afterFSR,top2_afterFSR);
thisEventDisplay.PrintThrustPlot();
thisEventDisplay.PrintMainEventDisplay(*v_recoJets, *v_partons, *v_partons_pdgId, *v_recoEl, *v_recoMu, *v_zDaughters, *v_zDaughters_pdgId,
reco_met_phi, v_recoJets_recoIndices_minChi2, v_recoLeptons_recoIndices, zDecayType_identified);
v_eventDisplay_values->clear(); // for next event
thisEventDisplay.SetOutputDirectory(outputDir);
thisEventDisplay.SaveEventDisplay(".pdf");
// Clear values for next event
v_recoJets->clear();
v_recoJets_MV2c10->clear();
v_partons->clear();
v_partons_pdgId->clear();
v_zDaughters->clear();
v_zDaughters_pdgId->clear();
v_recoEl->clear();
v_recoMu->clear();
v_recoMu_charge->clear();