Changes between Version 1 and Version 2 of WritingAnalyses


Ignore:
Timestamp:
Jul 9, 2015, 8:46:59 AM (9 years ago)
Author:
Jory Sonneveld
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • WritingAnalyses

    v1 v2  
    1 blabla
     1
     2= Writing your own analysis =
     3Here we will write our own CAT-UED-16-013 analysis. More detailed documentation about how to do this and accessible variables and functions can be found in [http://arxiv.org/abs/1405.3982 arXiv:1405.3982].
     4This assumes that you have [https://madanalysis.irmp.ucl.ac.be/wiki/Ma5PadStepByStep properly installed MadAnalysis5 at Reco level].
     5You may want to start with [https://madanalysis.irmp.ucl.ac.be/wiki/UsingMa5Pad using an implemented analysis in MA5] first before writing your own.
     6Many observables and functions are already implemented in [http://inspirehep.net/record/1301484/ the MA5 implementation of CMS-SUS-13-011], which can be used as an example.
     7
     8== Creating the directory ==
     9This proceeds as for [https://madanalysis.irmp.ucl.ac.be/wiki/using_ma5pad using an implemented analysis in MA5].
     10Again, we will create a directory from within the interactive !MadAnalysis mode:
     11{{{
     12./bin/ma5 -R -E
     13}}}
     14We will call the analysis directory MINE.
     15The name of the analysis is asked. We will call it cat_ued_16_013.
     16A directory my_analysis is created with these files:
     17{{{
     18MINE/Build/SampleAnalyzer/User/Analyzer/cat_ued_16_013.cpp
     19MINE/Build/SampleAnalyzer/User/Analyzer/cat_ued_16_013.h
     20}}}
     21The cat_ued_13_016.h file can stay as is.
     22We will now edit the .cpp file to write our own analysis.
     23
     24== Defining signal regions and cuts ==
     25We will now edit cat_ued_13_016.cpp to write our own analysis CAT-UED-16-013.
     26In this file, you can find an Initialize, Finalize, and Execute part.
     27
     28In the Initialize part, we will define our signal regions and cuts.
     29
     30In the Execute part, we will write our code.
     31
     32
     33=== Signal regions ===
     34Suppose that our CAT-UED-16-013 contains signal regions in MET and MHT with 200 < MET < 500, MET > 500 and 100 < HT < 500, HT > 500.
     35This results in 4 signal regions.
     36These are defined with the syntax
     37{{{
     38Manager()->AddRegionSelection("signal_region_name")
     39}}}
     40in the cat_ued_16_013.cpp file in the initialize part, that is, it will look like:
     41{{{
     42// -----------------------------------------------------------------------------
     43// Initialize
     44// function called one time at the beginning of the analysis
     45// -----------------------------------------------------------------------------
     46bool cat_ued_16_013::Initialize(const MA5::Configuration& cfg, const std::map<std::string,std::string>& parameters)
     47{
     48  cout << "BEGIN Initialization" << endl;
     49  // initialize variables, histos
     50  // Initialize signal regions
     51  Manager()->AddRegionSelection("200<MET<500,100<HT<500"); // SR1
     52  Manager()->AddRegionSelection("MET>500,100<HT<500"); // SR2
     53  Manager()->AddRegionSelection("200<MET<500,HT>500"); // SR3
     54  Manager()->AddRegionSelection("MET>500,HT>500"); // SR4
     55}}}
     56
     57=== Cuts ===
     58In this same initialize block, so immediately after, we define the cuts.
     59Note that the order in which the cuts are defined, is the order in which the cuts will appear in the cutflow. If this does not match the order in which the cuts are applied, the names of cuts in the cutflow results will be wrong!
     60
     61Here we differentiate between baseline cuts and signal region specific cuts.
     62The baseline cuts in this case are:
     63 * HT > 100 GeV;
     64 * MET > 200 GeV;
     65 * a lepton veto for leptons with pT > 10 GeV;
     66 * jets must have a pT > 20 GeV.
     67Furthermore, we have the region specific cuts, namely those that define the signal regions.
     68The baseline cuts are defined as follows:
     69{{{
     70  // Baseline cuts
     71  Manager()->AddCut("nolepton");
     72  Manager()->AddCut("MET>200");
     73  Manager()->AddCut("HT>100");
     74}}}
     75The signal-region specific cuts are defined as:
     76{{{
     77  // Signal-region specific cuts
     78  // MET < 500 for signal regions 1 and 3:
     79  string SR_1_3[] = {"200<MET<500,100<HT<500", "200<MET<500,HT>500"};
     80  Manager()->AddCut("MET<500", SR_1_3);
     81
     82  // HT < 500 applies to signal regions 1 and 2:
     83  string SR_1_2[] = {"200<MET<500,100<HT<500", "MET>500,100<HT<500"};
     84  Manager()->AddCut("HT<500", SR_1_2);
     85
     86  // HT > 500 applies to signal regions 3 and 4:
     87  string SR_3_4[] = {"200<MET<500,HT>500", "MET>500,HT>500"};
     88  Manager()->AddCut("HT>500", SR_3_4);
     89
     90  // MET > 500 for signal regions 2 and 4:
     91  string SR_2_4[] = {"MET>500,100<HT<500", "MET>500,HT>500"};
     92  Manager()->AddCut("MET>500", SR_2_4);
     93}}}
     94
     95== The code ==
     96Now that we have defined everything we need in the Initialize part of cat_ued_16_013.cpp, we will write the code in the Execute part.
     97
     98=== Define objects ===
     99First, we will select objects, in this case leptons (electrons and muons) and jets.
     100This is done in the Execute block. Since we now work with a ROOT file, not an STDHEP file (as is shown in the example in the file, after the start of the Execute block:
     101{{{
     102// -----------------------------------------------------------------------------
     103// Execute
     104// function called each time one event is read
     105// -----------------------------------------------------------------------------
     106bool cat_ued_16_013::Execute(SampleFormat& sample, const EventFormat& event)
     107{
     108}}}
     109we will remove all code and write the following for events at the reconstructed level:
     110{{{
     111  // ***************************************************************************
     112  // Example of analysis with reconstructed particles
     113  // Concerned samples : ROOT
     114  // ***************************************************************************
     115
     116  double myEventWeight;
     117  if(Configuration().IsNoEventWeight()) myEventWeight=1.;
     118  else if(event.mc()->weight()!=0.) myEventWeight=event.mc()->weight();
     119  else
     120    {
     121      INFO << "Found one event with a zero weight. Skipping...\n";
     122      return false;
     123    }
     124  Manager()->InitializeForNewEvent(myEventWeight);
     125
     126  if (event.rec()!=0)
     127    {
     128    cout << "---------------NEW EVENT-------------------" << endl;
     129
     130}}}
     131Most notably, here we changed the event.mc() to event.rec().
     132Immediately after the above lines, we declare the jet and lepton objects needed for our analysis. These are reconstructed objects that can be read from the Delphes ROOT file:
     133{{{
     134    // =====first declare the empty containers:=====¬
     135    vector<const RecLeptonFormat*> electron, muon;
     136    vector<const RecJetFormat*> jet;
     137}}}
     138Now collect the electrons with a pT greater than 10 GeV:
     139{{{
     140     // =====fill the electrons container:=====
     141    for(unsigned int e=0; e<event.rec()->electrons().size(); e++)
     142    {
     143      const RecLeptonFormat *CurrentElectron = &(event.rec()->electrons()[e]);
     144      double pt = CurrentElectron->momentum().Pt();
     145      if(!(pt>10)) continue;
     146      electron.push_back(CurrentElectron);
     147    }
     148}}}
     149Collect the muons:
     150{{{
     151    // =====fill the muons container:=====
     152    for(unsigned int m=0; m<event.rec()->muons().size(); m++)
     153    {
     154      const RecLeptonFormat *CurrentMuon = &(event.rec()->muons()[m]);
     155      double pt = CurrentMuon->momentum().Pt();
     156      if(!(pt>10)) continue;
     157      muon.push_back(CurrentMuon);
     158    }
     159}}}
     160and collect jets, calculating HT on the way:
     161{{{
     162    // =====define HT======
     163    double HT = 0;
     164    // =====fill the jet containers and order=====
     165    for(unsigned int j=0; j<event.rec()->jets().size(); j++)
     166    {
     167      const RecJetFormat *CurrentJet = &(event.rec()->jets()[j]);
     168      double pt = CurrentJet->momentum().Pt();
     169      if(!(pt > 20)) continue;
     170      // Add pt to HT:
     171      HT += pt;
     172      jet.push_back(CurrentJet);
     173    }
     174}}}
     175Define the missing energy MET:
     176{{{
     177   // =====Get the missing ET=====
     178    TLorentzVector pTmiss = event.rec()->MET().momentum();
     179    double MET = pTmiss.Pt();
     180}}}
     181In this same block, we now apply the cuts.
     182
     183=== Apply cuts ===
     184Very important: In order to have the names in the cutflow results (that are given per region) match the corresponding cut, the cuts MUST be applied in the same order as they are defined!
     185
     186First, we apply the lepton veto:
     187{{{
     188    // =====Apply no-lepton cut========
     189    if(!Manager()->ApplyCut((electron.size()+muon.size() == 0),"nolepton")) return true;
     190}}}
     191the same for the other baseline cuts:
     192{{{
     193    // =====Apply HT100 cut============
     194    if(!Manager()->ApplyCut((HT > 100),"HT>100")) return true;
     195
     196    // =====Apply MET200 cut===========
     197    if(!Manager()->ApplyCut((MET > 200),"MET>200")) return true;
     198}}}
     199Finally, apply the signal-region specific cuts:
     200{{{
     201    // =====Apply signal region cuts=======
     202    Manager()->ApplyCut(MET < 500, "MET<500"); // SR1, SR3
     203    Manager()->ApplyCut(MET >= 500, "MET>500"); // SR2, SR4
     204    Manager()->ApplyCut(HT < 500, "HT<500"); // SR1, SR2
     205    Manager()->ApplyCut(HT>=500, "HT>500"); // SR3, SR4
     206}}}
     207and close the block and end the file with:
     208{{{
     209    // =====finished=====
     210    return true;
     211  }
     212}
     213}}}
     214You can also find the [http://phys.onmybike.nl/ma5/cat_ued_16_013.cpp CAT-UED-16-013 C++ analysis file here].
     215For testing, you can use [http://phys.onmybike.nl/ma5/testfile.root this rootfile].
     216
     217== The signal region information ==
     218The cat_ued_16_013.info file contains the information about observed and numbers of background events in our signal regions. This is needed when one wants to compute confidence levels or upper limits using exclusion_CLs.py from the !RecastingTools package.
     219
     220For our analysis we have a luminosity of 20fb-1, and four each of the four signal regions we have observed numbers of events (nobs), estimated backgrounds (nb), and background errors (deltanb) as follows:
     221 * Signal region 1, 200<MET<500,100<HT<500: nobs=6159, nb=6090.0, deltanb=670.0
     222 * Signal region 2, MET>500,100<HT<500: nobs=2305, nb=2280.0, deltanb=270.0
     223 * Signal region 3, 200<MET<500,HT>500: nobs=451, nb=418.0, deltanb=66.0
     224 * Signal region 4, MET>500,100<HT<500: nobs=62, nb=57.4, deltanb=11.4
     225From this we create the following cat_ued_16_013.info
     226{{{
     227<!--
     228this XML file serves for the statistical interpretation of the MA5 simulation.
     229it lists the number of observed events <nobs>, number of expected backgrounds <nb>
     230and number of background uncertainty <deltanb> in each of the regions 
     231-->
     232
     233<!--
     234to be put in the same directory as the analysis code,
     235i.e. Build/SampleAnalyzer/Analyzer/
     236-->
     237
     238<analysis id="cat_ued_16_013">
     239  <lumi>20.0</lumi> <!-- in fb^-1 -->
     240
     241  <!-- first, the signal regions targeting stop -> t neutralino -->
     242
     243  <!--
     244     region definition: the attribute "id" has to match the name of the region
     245     as defined in the analysis code;
     246     the attribute "type" can be "signal" or "control" and is optional (default=signal)
     247  -->
     248
     249  <region type="signal" id="200<MET<500,100<HT<500">
     250    <nobs>6159</nobs>
     251    <nb>6090.0</nb>
     252    <deltanb>670.0</deltanb>
     253  </region>
     254
     255  <region type="signal" id="MET>500,100<HT<500">
     256    <nobs>2305</nobs>
     257    <nb>2280.0</nb>
     258    <deltanb>270.0</deltanb>
     259  </region>
     260
     261  <region type="signal" id="200<MET<500,HT>500">
     262    <nobs>454</nobs>
     263    <nb>418.0</nb>
     264    <deltanb>66.0</deltanb>
     265  </region>
     266
     267  <region type="signal" id="MET>500,100<HT<500">
     268    <nobs>62</nobs>
     269    <nb>57.4</nb>
     270    <deltanb>11.2</deltanb>
     271  </region>
     272</analysis>
     273}}}